mirror of
https://github.com/postfixadmin/postfixadmin.git
synced 2024-09-20 03:36:20 +02:00
support for displaying quota (dovecot 1.1 and 1.2 format)
upgrade.php - create quota and quota2 table (upgrade_729) - create the triggers required by dovecot (upgrade_730_pgsql) list-virtual.php - updated to work with both quota tables Patch by Varren Volz, https://sourceforge.net/tracker/?func=detail&aid=2867629&group_id=191583&atid=937966 - changed query for 1.1 quota table to WHERE [...] AND ( $table_quota.path='quota/storage' OR $table_quota.path IS NULL ) This fixes https://sourceforge.net/tracker/?func=detail&aid=2794247&group_id=191583&atid=937964 (users not shown when initial email is not sent) config.inc.php, functions.php - new config option $CONF['new_quota_table'] (YES means dovecot 1.2 format) - set variables for new quota2 table DOCUMENTS/DOVECOT.txt - added note that quota table is automatically created - added note about different quota tables for dovecot 1.0/1.1 and >= 1.2 git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@730 a1433add-5e2c-0410-b055-b7f2511e0802
This commit is contained in:
parent
246a793a7d
commit
04b272472d
@ -117,16 +117,15 @@ username_field = username
|
|||||||
|
|
||||||
|
|
||||||
Create database in Mysql:
|
Create database in Mysql:
|
||||||
|
(This is automatically done by postfixadmin's setup.php)
|
||||||
create table quota (
|
|
||||||
username varchar(255) /*!40100 CHARACTER SET latin1 */ not null,
|
|
||||||
path varchar(100) /*!40100 CHARACTER SET latin1 */ not null,
|
|
||||||
current integer,
|
|
||||||
primary key (username, path)
|
|
||||||
) TYPE=MyISAM ;
|
|
||||||
|
|
||||||
|
|
||||||
Enable quota support in Postfixadmin config.inc.php:
|
Enable quota support in Postfixadmin config.inc.php:
|
||||||
|
|
||||||
$CONF['used_quotas'] = 'YES';
|
$CONF['used_quotas'] = 'YES';
|
||||||
$CONF['quota'] = 'YES';
|
$CONF['quota'] = 'YES';
|
||||||
|
|
||||||
|
Note: The above text describes the configuration for dovecot 1.0 & 1.1 quota table format.
|
||||||
|
|
||||||
|
If you use dovecot 1.2 or newer,
|
||||||
|
- use the 'quota2' table (also created by setup.php)
|
||||||
|
- set $CONF['new_quota_table'] = 'YES'
|
||||||
|
@ -74,6 +74,7 @@ $CONF['database_tables'] = array (
|
|||||||
'vacation' => 'vacation',
|
'vacation' => 'vacation',
|
||||||
'vacation_notification' => 'vacation_notification',
|
'vacation_notification' => 'vacation_notification',
|
||||||
'quota' => 'quota',
|
'quota' => 'quota',
|
||||||
|
'quota2' => 'quota2',
|
||||||
);
|
);
|
||||||
|
|
||||||
// Site Admin
|
// Site Admin
|
||||||
@ -362,7 +363,11 @@ $CONF['create_mailbox_subdirs_prefix']='INBOX.';
|
|||||||
// See: DOCUMENTATION/DOVECOT.txt
|
// See: DOCUMENTATION/DOVECOT.txt
|
||||||
// http://wiki.dovecot.org/Quota/Dict
|
// http://wiki.dovecot.org/Quota/Dict
|
||||||
//
|
//
|
||||||
// $CONF['used_quotas'] = 'YES';
|
$CONF['used_quotas'] = 'NO';
|
||||||
|
|
||||||
|
// if you use dovecot >= 1.2, set this to yes.
|
||||||
|
// Note about dovecot config: table "quota" is for 1.0 & 1.1, table "quota2" is for dovecot 1.2 and newer
|
||||||
|
$CONF['new_quota_table'] = 'NO';
|
||||||
|
|
||||||
//
|
//
|
||||||
// Normally, the TCP port number does not have to be specified.
|
// Normally, the TCP port number does not have to be specified.
|
||||||
|
@ -2352,4 +2352,5 @@ $table_mailbox = table_by_key ('mailbox');
|
|||||||
$table_vacation = table_by_key ('vacation');
|
$table_vacation = table_by_key ('vacation');
|
||||||
$table_vacation_notification = table_by_key('vacation_notification');
|
$table_vacation_notification = table_by_key('vacation_notification');
|
||||||
$table_quota = table_by_key ('quota');
|
$table_quota = table_by_key ('quota');
|
||||||
|
$table_quota2 = table_by_key ('quota2');
|
||||||
/* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */
|
/* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */
|
||||||
|
@ -158,29 +158,60 @@ if ($result['rows'] > 0)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# TODO: reduce number of different queries by not depending on too much config options
|
||||||
|
# (it probably won't hurt to include a field in the resultset that is not displayed later)
|
||||||
if ($CONF['vacation_control_admin'] == 'YES')
|
if ($CONF['vacation_control_admin'] == 'YES')
|
||||||
{
|
{
|
||||||
if (boolconf('used_quotas'))
|
if (boolconf('used_quotas'))
|
||||||
|
{
|
||||||
|
if (boolconf('new_quota_table'))
|
||||||
|
{
|
||||||
|
$query = "SELECT $table_mailbox.*, $table_vacation.active AS v_active, $table_quota2.bytes FROM $table_mailbox
|
||||||
|
LEFT JOIN $table_vacation ON $table_mailbox.username=$table_vacation.email
|
||||||
|
LEFT JOIN $table_quota2 ON $table_mailbox.username=$table_quota2.username
|
||||||
|
WHERE $table_mailbox.domain='$fDomain'
|
||||||
|
ORDER BY $table_mailbox.username LIMIT $page_size OFFSET $fDisplay";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$query = "SELECT $table_mailbox.*, $table_vacation.active AS v_active, $table_quota.current FROM $table_mailbox
|
$query = "SELECT $table_mailbox.*, $table_vacation.active AS v_active, $table_quota.current FROM $table_mailbox
|
||||||
LEFT JOIN $table_vacation ON $table_mailbox.username=$table_vacation.email
|
LEFT JOIN $table_vacation ON $table_mailbox.username=$table_vacation.email
|
||||||
LEFT JOIN $table_quota ON $table_mailbox.username=$table_quota.username
|
LEFT JOIN $table_quota ON $table_mailbox.username=$table_quota.username
|
||||||
WHERE $table_mailbox.domain='$fDomain'
|
WHERE $table_mailbox.domain='$fDomain' AND
|
||||||
|
( $table_quota.path='quota/storage' OR $table_quota.path IS NULL )
|
||||||
ORDER BY $table_mailbox.username LIMIT $page_size OFFSET $fDisplay";
|
ORDER BY $table_mailbox.username LIMIT $page_size OFFSET $fDisplay";
|
||||||
// AND $table_quota.path='quota/storage'
|
}
|
||||||
else
|
}
|
||||||
|
else # $CONF[used_quotas] = NO
|
||||||
|
{
|
||||||
$query = "SELECT $table_mailbox.*, $table_vacation.active AS v_active FROM $table_mailbox
|
$query = "SELECT $table_mailbox.*, $table_vacation.active AS v_active FROM $table_mailbox
|
||||||
LEFT JOIN $table_vacation ON $table_mailbox.username=$table_vacation.email
|
LEFT JOIN $table_vacation ON $table_mailbox.username=$table_vacation.email
|
||||||
WHERE $table_mailbox.domain='$fDomain' ORDER BY $table_mailbox.username LIMIT $page_size OFFSET $fDisplay";
|
WHERE $table_mailbox.domain='$fDomain' ORDER BY $table_mailbox.username LIMIT $page_size OFFSET $fDisplay";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else # $CONF['vacation_control_admin'] == 'NO'
|
||||||
|
{
|
||||||
|
if (boolconf('used_quotas'))
|
||||||
|
{
|
||||||
|
if (boolconf('new_quota_table'))
|
||||||
|
{
|
||||||
|
$query = "SELECT $table_mailbox.*, $table_quota2.bytes as current FROM $table_mailbox
|
||||||
|
LEFT JOIN $table_quota2 ON $table_mailbox.username=$table_quota2.username
|
||||||
|
WHERE $table_mailbox.domain='$fDomain' ORDER BY $table_mailbox.username LIMIT $page_size OFFSET $fDisplay";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
$query = "SELECT $table_mailbox.*, $table_quota.current FROM $table_mailbox
|
||||||
$query = "SELECT * FROM $table_mailbox WHERE domain='$fDomain' ORDER BY username LIMIT $fDisplay, $page_size";
|
LEFT JOIN $table_quota ON $table_mailbox.username=$table_quota.username
|
||||||
if ('pgsql'==$CONF['database_type'])
|
WHERE $table_mailbox.domain='$fDomain' AND
|
||||||
{
|
( $table_quota.path='quota/storage' OR $table_quota.path IS NULL )
|
||||||
$query = "SELECT *,extract(epoch from created) as uts_created,extract(epoch from modified) as uts_modified FROM $table_mailbox WHERE domain='$fDomain' ORDER BY username LIMIT $page_size OFFSET $fDisplay";
|
ORDER BY $table_mailbox.username LIMIT $page_size OFFSET $fDisplay";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else # $CONF[used_quotas] = NO
|
||||||
|
{
|
||||||
|
$query = "SELECT * FROM $table_mailbox WHERE domain='$fDomain' ORDER BY username LIMIT $page_size OFFSET $fDisplay";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
$result = db_query ($query);
|
$result = db_query ($query);
|
||||||
if ($result['rows'] > 0)
|
if ($result['rows'] > 0)
|
||||||
|
93
upgrade.php
93
upgrade.php
@ -171,6 +171,7 @@ function db_query_parsed($sql, $ignore_errors = 0, $attach_mysql = "") {
|
|||||||
'{RENAME_COLUMN}' => 'CHANGE COLUMN',
|
'{RENAME_COLUMN}' => 'CHANGE COLUMN',
|
||||||
'{MYISAM}' => 'ENGINE=MyISAM',
|
'{MYISAM}' => 'ENGINE=MyISAM',
|
||||||
'{INNODB}' => 'ENGINE=InnoDB',
|
'{INNODB}' => 'ENGINE=InnoDB',
|
||||||
|
'{BIGINT}' => 'bigint',
|
||||||
);
|
);
|
||||||
$sql = "$sql $attach_mysql";
|
$sql = "$sql $attach_mysql";
|
||||||
|
|
||||||
@ -187,6 +188,7 @@ function db_query_parsed($sql, $ignore_errors = 0, $attach_mysql = "") {
|
|||||||
'{RENAME_COLUMN}' => 'ALTER COLUMN', # PgSQL : ALTER TABLE x RENAME x TO y
|
'{RENAME_COLUMN}' => 'ALTER COLUMN', # PgSQL : ALTER TABLE x RENAME x TO y
|
||||||
'{MYISAM}' => '',
|
'{MYISAM}' => '',
|
||||||
'{INNODB}' => '',
|
'{INNODB}' => '',
|
||||||
|
'{BIGINT}' => 'bigint',
|
||||||
'int(1)' => 'int',
|
'int(1)' => 'int',
|
||||||
'int(10)' => 'int',
|
'int(10)' => 'int',
|
||||||
'int(11)' => 'int',
|
'int(11)' => 'int',
|
||||||
@ -1086,3 +1088,94 @@ function upgrade_655() {
|
|||||||
db_query_parsed(_add_index('mailbox', 'domain', 'domain'));
|
db_query_parsed(_add_index('mailbox', 'domain', 'domain'));
|
||||||
db_query_parsed(_add_index('alias', 'domain', 'domain'));
|
db_query_parsed(_add_index('alias', 'domain', 'domain'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function upgrade_729() {
|
||||||
|
$table_quota = table_by_key('quota');
|
||||||
|
$table_quota2 = table_by_key('quota2');
|
||||||
|
|
||||||
|
# table for dovecot v1.0 & 1.1
|
||||||
|
db_query_parsed("
|
||||||
|
CREATE TABLE {IF_NOT_EXISTS} $table_quota (
|
||||||
|
username VARCHAR(255) {LATIN1} NOT NULL,
|
||||||
|
path VARCHAR(100) {LATIN1} NOT NULL,
|
||||||
|
current {BIGINT},
|
||||||
|
PRIMARY KEY (username, path)
|
||||||
|
) {MYISAM} ;
|
||||||
|
");
|
||||||
|
|
||||||
|
# table for dovecot >= 1.2
|
||||||
|
db_query_parsed("
|
||||||
|
CREATE TABLE {IF_NOT_EXISTS} $table_quota2 (
|
||||||
|
username VARCHAR(100) {LATIN1} NOT NULL,
|
||||||
|
bytes {BIGINT} NOT NULL DEFAULT 0,
|
||||||
|
messages integer NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (username)
|
||||||
|
) {MYISAM} ;
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
|
function upgrade_730_pgsql() {
|
||||||
|
$table_quota = table_by_key('quota');
|
||||||
|
$table_quota2 = table_by_key('quota2');
|
||||||
|
|
||||||
|
# trigger for dovecot v1.0 & 1.1 quota table
|
||||||
|
# taken from http://wiki.dovecot.org/Quota/Dict
|
||||||
|
db_query_parsed("
|
||||||
|
CREATE OR REPLACE FUNCTION merge_quota() RETURNS TRIGGER AS \$merge_quota\$
|
||||||
|
BEGIN
|
||||||
|
UPDATE $table_quota SET current = NEW.current + current WHERE username = NEW.username AND path = NEW.path;
|
||||||
|
IF found THEN
|
||||||
|
RETURN NULL;
|
||||||
|
ELSE
|
||||||
|
RETURN NEW;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
\$merge_quota\$ LANGUAGE plpgsql;
|
||||||
|
");
|
||||||
|
db_query_parsed("
|
||||||
|
CREATE TRIGGER mergequota BEFORE INSERT ON $table_quota FOR EACH ROW EXECUTE PROCEDURE merge_quota();
|
||||||
|
");
|
||||||
|
|
||||||
|
# trigger for dovecot >= 1.2 quota table
|
||||||
|
# taken from http://wiki.dovecot.org/Quota/Dict, table/trigger name changed to quota2 naming
|
||||||
|
db_query_parsed("
|
||||||
|
CREATE OR REPLACE FUNCTION merge_quota2() RETURNS TRIGGER AS \$\$
|
||||||
|
BEGIN
|
||||||
|
IF NEW.messages < 0 OR NEW.messages IS NULL THEN
|
||||||
|
-- ugly kludge: we came here from this function, really do try to insert
|
||||||
|
IF NEW.messages IS NULL THEN
|
||||||
|
NEW.messages = 0;
|
||||||
|
ELSE
|
||||||
|
NEW.messages = -NEW.messages;
|
||||||
|
END IF;
|
||||||
|
return NEW;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
LOOP
|
||||||
|
UPDATE $table_quota2 SET bytes = bytes + NEW.bytes,
|
||||||
|
messages = messages + NEW.messages
|
||||||
|
WHERE username = NEW.username;
|
||||||
|
IF found THEN
|
||||||
|
RETURN NULL;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
IF NEW.messages = 0 THEN
|
||||||
|
INSERT INTO $table_quota2 (bytes, messages, username) VALUES (NEW.bytes, NULL, NEW.username);
|
||||||
|
ELSE
|
||||||
|
INSERT INTO $table_quota2 (bytes, messages, username) VALUES (NEW.bytes, -NEW.messages, NEW.username);
|
||||||
|
END IF;
|
||||||
|
return NULL;
|
||||||
|
EXCEPTION WHEN unique_violation THEN
|
||||||
|
-- someone just inserted the record, update it
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
\$\$ LANGUAGE plpgsql;
|
||||||
|
");
|
||||||
|
|
||||||
|
db_query_parsed("
|
||||||
|
CREATE TRIGGER mergequota2 BEFORE INSERT ON $table_quota2
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE merge_quota2();
|
||||||
|
");
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user