2017-04-21 16:20:31 +08:00
< ? php
function init_db_schema () {
try {
global $pdo ;
2019-10-11 22:47:39 +08:00
$db_version = " 1102019_1040 " ;
2017-04-21 16:20:31 +08:00
2017-11-15 02:54:31 +08:00
$stmt = $pdo -> query ( " SHOW TABLES LIKE 'versions' " );
2017-04-21 16:20:31 +08:00
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
2019-08-10 21:57:07 +08:00
$stmt = $pdo -> query ( " SELECT `version` FROM `versions` WHERE `application` = 'db_schema' " );
2017-04-21 16:20:31 +08:00
if ( $stmt -> fetch ( PDO :: FETCH_ASSOC )[ 'version' ] == $db_version ) {
return true ;
}
}
$views = array (
" grouped_mail_aliases " => " CREATE VIEW grouped_mail_aliases (username, aliases) AS
SELECT goto , IFNULL ( GROUP_CONCAT ( address SEPARATOR ' ' ), '' ) AS address FROM alias
WHERE address != goto
AND active = '1'
2019-09-22 21:10:56 +08:00
AND sogo_visible = '1'
2017-04-21 16:20:31 +08:00
AND address NOT LIKE '@%'
GROUP BY goto ; " ,
2019-09-22 21:10:56 +08:00
// START
2019-09-02 17:11:41 +08:00
// Unused at the moment - we cannot allow to show a foreign mailbox as sender address in SOGo, as SOGo does not like this
// We need to create delegation in SOGo AND set a sender_acl in mailcow to allow to send as user X
2018-02-17 16:50:39 +08:00
" grouped_sender_acl " => " CREATE VIEW grouped_sender_acl (username, send_as_acl) AS
SELECT logged_in_as , IFNULL ( GROUP_CONCAT ( send_as SEPARATOR ' ' ), '' ) AS send_as_acl FROM sender_acl
WHERE send_as NOT LIKE '@%'
GROUP BY logged_in_as ; " ,
2019-10-07 00:56:24 +08:00
// END
2019-09-02 17:11:41 +08:00
" grouped_sender_acl_external " => " CREATE VIEW grouped_sender_acl_external (username, send_as_acl) AS
SELECT logged_in_as , IFNULL ( GROUP_CONCAT ( send_as SEPARATOR ' ' ), '' ) AS send_as_acl FROM sender_acl
WHERE send_as NOT LIKE '@%' AND external = '1'
GROUP BY logged_in_as ; " ,
2017-04-21 16:20:31 +08:00
" grouped_domain_alias_address " => " CREATE VIEW grouped_domain_alias_address (username, ad_alias) AS
SELECT username , IFNULL ( GROUP_CONCAT ( local_part , '@' , alias_domain SEPARATOR ' ' ), '' ) AS ad_alias FROM mailbox
2018-01-21 21:58:16 +08:00
LEFT OUTER JOIN alias_domain ON target_domain = domain
GROUP BY username ; " ,
2017-11-04 03:37:24 +08:00
" sieve_before " => " CREATE VIEW sieve_before (id, username, script_name, script_data) AS
2017-11-15 04:11:36 +08:00
SELECT md5 ( script_data ), username , script_name , script_data FROM sieve_filters
2017-11-04 03:37:24 +08:00
WHERE filter_type = 'prefilter' ; " ,
" sieve_after " => " CREATE VIEW sieve_after (id, username, script_name, script_data) AS
2017-11-15 04:11:36 +08:00
SELECT md5 ( script_data ), username , script_name , script_data FROM sieve_filters
2017-11-04 03:37:24 +08:00
WHERE filter_type = 'postfilter' ; "
2017-04-21 16:20:31 +08:00
);
$tables = array (
" versions " => array (
" cols " => array (
" application " => " VARCHAR(255) NOT NULL " ,
" version " => " VARCHAR(100) NOT NULL " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
),
" keys " => array (
" primary " => array (
" " => array ( " application " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" admin " => array (
" cols " => array (
" username " => " VARCHAR(255) NOT NULL " ,
" password " => " VARCHAR(255) NOT NULL " ,
" superadmin " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE NOW(0) " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '1' "
),
" keys " => array (
" primary " => array (
" " => array ( " username " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2018-07-12 04:14:07 +08:00
" _sogo_static_view " => array (
" cols " => array (
" c_uid " => " VARCHAR(255) NOT NULL " ,
" domain " => " VARCHAR(255) NOT NULL " ,
" c_name " => " VARCHAR(255) NOT NULL " ,
" c_password " => " VARCHAR(255) NOT NULL DEFAULT '' " ,
" c_cn " => " VARCHAR(255) " ,
" mail " => " VARCHAR(255) NOT NULL " ,
// TODO -> use TEXT and check if SOGo login breaks on empty aliases
2018-08-16 18:42:12 +08:00
" aliases " => " TEXT NOT NULL " ,
2018-07-12 04:14:07 +08:00
" ad_aliases " => " VARCHAR(6144) NOT NULL DEFAULT '' " ,
2019-09-02 17:11:41 +08:00
" ext_acl " => " VARCHAR(6144) NOT NULL DEFAULT '' " ,
2018-07-12 04:14:07 +08:00
" kind " => " VARCHAR(100) NOT NULL DEFAULT '' " ,
" multiple_bookings " => " INT NOT NULL DEFAULT -1 "
),
" keys " => array (
" primary " => array (
" " => array ( " c_uid " )
),
" key " => array (
" domain " => array ( " domain " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-07-23 02:39:54 +08:00
" relayhosts " => array (
" cols " => array (
" id " => " INT NOT NULL AUTO_INCREMENT " ,
" hostname " => " VARCHAR(255) NOT NULL " ,
" username " => " VARCHAR(255) NOT NULL " ,
" password " => " VARCHAR(255) NOT NULL " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '1' "
),
" keys " => array (
" primary " => array (
" " => array ( " id " )
),
" key " => array (
" hostname " => array ( " hostname " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2018-12-20 18:23:35 +08:00
" transports " => array (
" cols " => array (
" id " => " INT NOT NULL AUTO_INCREMENT " ,
" destination " => " VARCHAR(255) NOT NULL " ,
" nexthop " => " VARCHAR(255) NOT NULL " ,
" username " => " VARCHAR(255) NOT NULL " ,
" password " => " VARCHAR(255) NOT NULL " ,
2019-08-25 22:02:58 +08:00
" lookup_mx " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
2018-12-20 18:23:35 +08:00
" active " => " TINYINT(1) NOT NULL DEFAULT '1' "
),
" keys " => array (
" primary " => array (
" " => array ( " id " )
),
" key " => array (
" destination " => array ( " destination " ),
" nexthop " => array ( " nexthop " ),
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-04-21 16:20:31 +08:00
" alias " => array (
" cols " => array (
2018-08-14 05:20:40 +08:00
" id " => " INT NOT NULL AUTO_INCREMENT " ,
2017-04-21 16:20:31 +08:00
" address " => " VARCHAR(255) NOT NULL " ,
" goto " => " TEXT NOT NULL " ,
" domain " => " VARCHAR(255) NOT NULL " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE CURRENT_TIMESTAMP " ,
2019-01-29 07:20:39 +08:00
" private_comment " => " TEXT " ,
" public_comment " => " TEXT " ,
2019-09-22 21:10:56 +08:00
" sogo_visible " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
2017-04-21 16:20:31 +08:00
" active " => " TINYINT(1) NOT NULL DEFAULT '1' "
),
" keys " => array (
" primary " => array (
2018-08-14 05:20:40 +08:00
" " => array ( " id " )
),
" unique " => array (
" address " => array ( " address " )
2017-04-21 16:20:31 +08:00
),
" key " => array (
" domain " => array ( " domain " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-12-09 20:17:15 +08:00
" api " => array (
" cols " => array (
" api_key " => " VARCHAR(255) NOT NULL " ,
" allow_from " => " VARCHAR(512) NOT NULL " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE NOW(0) " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '1' "
),
" keys " => array (
" primary " => array (
2018-10-11 17:59:23 +08:00
" " => array ( " api_key " )
2017-12-09 20:17:15 +08:00
),
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-04-21 16:20:31 +08:00
" sender_acl " => array (
" cols " => array (
2018-06-24 05:50:22 +08:00
" id " => " INT NOT NULL AUTO_INCREMENT " ,
2017-04-21 16:20:31 +08:00
" logged_in_as " => " VARCHAR(255) NOT NULL " ,
2019-09-02 17:11:41 +08:00
" send_as " => " VARCHAR(255) NOT NULL " ,
" external " => " TINYINT(1) NOT NULL DEFAULT '0' "
2017-04-21 16:20:31 +08:00
),
2018-06-24 05:50:22 +08:00
" keys " => array (
" primary " => array (
" " => array ( " id " )
)
),
2017-04-21 16:20:31 +08:00
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" domain " => array (
2019-01-17 06:41:02 +08:00
// Todo: Move some attributes to json
2017-04-21 16:20:31 +08:00
" cols " => array (
" domain " => " VARCHAR(255) NOT NULL " ,
" description " => " VARCHAR(255) " ,
" aliases " => " INT(10) NOT NULL DEFAULT '0' " ,
" mailboxes " => " INT(10) NOT NULL DEFAULT '0' " ,
2019-05-11 17:16:40 +08:00
" defquota " => " BIGINT(20) NOT NULL DEFAULT '3072' " ,
" maxquota " => " BIGINT(20) NOT NULL DEFAULT '102400' " ,
2017-05-04 00:05:35 +08:00
" quota " => " BIGINT(20) NOT NULL DEFAULT '102400' " ,
2017-07-23 02:39:54 +08:00
" relayhost " => " VARCHAR(255) NOT NULL DEFAULT '0' " ,
2017-04-21 16:20:31 +08:00
" backupmx " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
2019-01-17 06:41:02 +08:00
" gal " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
2017-04-21 16:20:31 +08:00
" relay_all_recipients " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE CURRENT_TIMESTAMP " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '1' "
),
" keys " => array (
" primary " => array (
" " => array ( " domain " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2018-10-04 20:38:12 +08:00
" tls_policy_override " => array (
" cols " => array (
" id " => " INT NOT NULL AUTO_INCREMENT " ,
" dest " => " VARCHAR(255) NOT NULL " ,
" policy " => " ENUM('none', 'may', 'encrypt', 'dane', 'dane-only', 'fingerprint', 'verify', 'secure') NOT NULL " ,
" parameters " => " VARCHAR(255) DEFAULT '' " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE CURRENT_TIMESTAMP " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '1' "
),
" keys " => array (
" primary " => array (
" " => array ( " id " )
),
" unique " => array (
" dest " => array ( " dest " )
),
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2018-02-17 18:46:34 +08:00
" quarantine " => array (
2017-12-09 20:17:15 +08:00
" cols " => array (
" id " => " INT NOT NULL AUTO_INCREMENT " ,
" qid " => " VARCHAR(30) NOT NULL " ,
2019-01-16 17:50:34 +08:00
" subject " => " VARCHAR(500) " ,
2017-12-09 20:17:15 +08:00
" score " => " FLOAT(8,2) " ,
2019-01-18 05:00:18 +08:00
" ip " => " VARCHAR(50) " ,
2017-12-09 20:17:15 +08:00
" action " => " CHAR(20) NOT NULL DEFAULT 'unknown' " ,
" symbols " => " JSON " ,
" sender " => " VARCHAR(255) NOT NULL DEFAULT 'unknown' " ,
" rcpt " => " VARCHAR(255) " ,
" msg " => " LONGTEXT " ,
" domain " => " VARCHAR(255) " ,
2019-01-29 07:20:39 +08:00
" notified " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
2017-12-09 20:17:15 +08:00
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" user " => " VARCHAR(255) NOT NULL DEFAULT 'unknown' " ,
),
" keys " => array (
" primary " => array (
" " => array ( " id " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-09-10 19:48:53 +08:00
" mailbox " => array (
" cols " => array (
" username " => " VARCHAR(255) NOT NULL " ,
" password " => " VARCHAR(255) NOT NULL " ,
" name " => " VARCHAR(255) " ,
2018-11-12 17:03:50 +08:00
// mailbox_path_prefix is followed by domain/local_part/
" mailbox_path_prefix " => " VARCHAR(150) DEFAULT '/var/vmail/' " ,
2017-09-10 19:48:53 +08:00
" quota " => " BIGINT(20) NOT NULL DEFAULT '102400' " ,
" local_part " => " VARCHAR(255) NOT NULL " ,
" domain " => " VARCHAR(255) NOT NULL " ,
2018-02-17 17:18:07 +08:00
" attributes " => " JSON " ,
2017-09-10 19:48:53 +08:00
" kind " => " VARCHAR(100) NOT NULL DEFAULT '' " ,
2018-05-07 03:51:00 +08:00
" multiple_bookings " => " INT NOT NULL DEFAULT -1 " ,
2017-09-10 19:48:53 +08:00
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE CURRENT_TIMESTAMP " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '1' "
),
" keys " => array (
" primary " => array (
" " => array ( " username " )
),
" key " => array (
" domain " => array ( " domain " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-11-04 03:37:24 +08:00
" sieve_filters " => array (
" cols " => array (
" id " => " INT NOT NULL AUTO_INCREMENT " ,
" username " => " VARCHAR(255) NOT NULL " ,
" script_desc " => " VARCHAR(255) NOT NULL " ,
" script_name " => " ENUM('active','inactive') " ,
" script_data " => " TEXT NOT NULL " ,
" filter_type " => " ENUM('postfilter','prefilter') " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE CURRENT_TIMESTAMP "
),
" keys " => array (
" primary " => array (
" " => array ( " id " )
),
" key " => array (
" username " => array ( " username " ),
" script_desc " => array ( " script_desc " )
),
" fkey " => array (
" fk_username_sieve_global_before " => array (
" col " => " username " ,
" ref " => " mailbox.username " ,
" delete " => " CASCADE " ,
" update " => " NO ACTION "
)
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-08-19 04:18:14 +08:00
" user_acl " => array (
" cols " => array (
" username " => " VARCHAR(255) NOT NULL " ,
" spam_alias " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
" tls_policy " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
" spam_score " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
" spam_policy " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
" delimiter_action " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
" syncjobs " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
2019-09-29 02:00:04 +08:00
" eas_reset " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
2018-10-24 03:14:57 +08:00
" sogo_profile_reset " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
2018-02-17 18:46:34 +08:00
" quarantine " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
2019-01-29 07:20:39 +08:00
" quarantine_attachments " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
" quarantine_notification " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
2018-02-17 16:50:39 +08:00
),
2017-08-19 04:18:14 +08:00
" keys " => array (
2018-05-06 15:15:12 +08:00
" primary " => array (
" " => array ( " username " )
),
2017-08-19 04:18:14 +08:00
" fkey " => array (
" fk_username " => array (
" col " => " username " ,
" ref " => " mailbox.username " ,
" delete " => " CASCADE " ,
" update " => " NO ACTION "
)
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-04-21 16:20:31 +08:00
" alias_domain " => array (
" cols " => array (
" alias_domain " => " VARCHAR(255) NOT NULL " ,
" target_domain " => " VARCHAR(255) NOT NULL " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE CURRENT_TIMESTAMP " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '1' "
),
" keys " => array (
" primary " => array (
" " => array ( " alias_domain " )
),
" key " => array (
" active " => array ( " active " ),
" target_domain " => array ( " target_domain " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" spamalias " => array (
" cols " => array (
" address " => " VARCHAR(255) NOT NULL " ,
" goto " => " TEXT NOT NULL " ,
" validity " => " INT(11) NOT NULL "
),
" keys " => array (
" primary " => array (
" " => array ( " address " )
),
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" filterconf " => array (
" cols " => array (
" object " => " VARCHAR(255) NOT NULL DEFAULT '' " ,
" option " => " VARCHAR(50) NOT NULL DEFAULT '' " ,
" value " => " VARCHAR(100) NOT NULL DEFAULT '' " ,
2018-06-24 05:50:22 +08:00
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE CURRENT_TIMESTAMP " ,
2017-04-21 16:20:31 +08:00
" prefid " => " INT(11) NOT NULL AUTO_INCREMENT "
),
" keys " => array (
" primary " => array (
" " => array ( " prefid " )
),
" key " => array (
" object " => array ( " object " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2018-06-24 05:50:22 +08:00
" settingsmap " => array (
" cols " => array (
" id " => " INT NOT NULL AUTO_INCREMENT " ,
" desc " => " VARCHAR(255) NOT NULL " ,
" content " => " LONGTEXT NOT NULL " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE CURRENT_TIMESTAMP " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '0' "
),
" keys " => array (
" primary " => array (
" " => array ( " id " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2018-08-04 02:31:33 +08:00
" logs " => array (
" cols " => array (
" id " => " INT NOT NULL AUTO_INCREMENT " ,
2018-08-14 05:20:40 +08:00
" task " => " CHAR(32) NOT NULL DEFAULT '000000' " ,
2018-08-04 02:31:33 +08:00
" type " => " VARCHAR(32) DEFAULT '' " ,
" msg " => " TEXT " ,
" call " => " TEXT " ,
" user " => " VARCHAR(64) NOT NULL " ,
" role " => " VARCHAR(32) NOT NULL " ,
2018-08-19 16:07:44 +08:00
" remote " => " VARCHAR(39) NOT NULL " ,
2018-08-04 02:31:33 +08:00
" time " => " INT(11) NOT NULL "
),
" keys " => array (
" primary " => array (
" " => array ( " id " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-04-21 16:20:31 +08:00
" quota2 " => array (
" cols " => array (
" username " => " VARCHAR(255) NOT NULL " ,
" bytes " => " BIGINT(20) NOT NULL DEFAULT '0' " ,
" messages " => " BIGINT(20) NOT NULL DEFAULT '0' "
),
" keys " => array (
" primary " => array (
" " => array ( " username " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" domain_admins " => array (
" cols " => array (
2018-06-24 05:50:22 +08:00
" id " => " INT NOT NULL AUTO_INCREMENT " ,
2017-04-21 16:20:31 +08:00
" username " => " VARCHAR(255) NOT NULL " ,
" domain " => " VARCHAR(255) NOT NULL " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '1' "
),
" keys " => array (
2018-06-24 05:50:22 +08:00
" primary " => array (
" " => array ( " id " )
),
2017-11-14 20:29:02 +08:00
" key " => array (
2017-11-14 19:37:08 +08:00
" username " => array ( " username " )
2017-04-21 16:20:31 +08:00
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2018-09-10 22:23:08 +08:00
" da_acl " => array (
" cols " => array (
" username " => " VARCHAR(255) NOT NULL " ,
" syncjobs " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
" quarantine " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
" login_as " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
2019-10-05 23:29:16 +08:00
" sogo_access " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
2018-09-10 22:23:08 +08:00
" bcc_maps " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
" filters " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
" ratelimit " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
" spam_policy " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
2019-09-02 17:11:41 +08:00
" extend_sender_acl " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
2019-03-31 02:14:24 +08:00
" unlimited_quota " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
2018-11-14 15:20:56 +08:00
" alias_domains " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
2018-09-10 22:23:08 +08:00
),
" keys " => array (
" primary " => array (
" " => array ( " username " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-04-21 16:20:31 +08:00
" imapsync " => array (
" cols " => array (
" id " => " INT NOT NULL AUTO_INCREMENT " ,
" user2 " => " VARCHAR(255) NOT NULL " ,
" host1 " => " VARCHAR(255) NOT NULL " ,
" authmech1 " => " ENUM('PLAIN','LOGIN','CRAM-MD5') DEFAULT 'PLAIN' " ,
" regextrans2 " => " VARCHAR(255) DEFAULT '' " ,
" authmd51 " => " TINYINT(1) NOT NULL DEFAULT 0 " ,
" domain2 " => " VARCHAR(255) NOT NULL DEFAULT '' " ,
" subfolder2 " => " VARCHAR(255) NOT NULL DEFAULT '' " ,
" user1 " => " VARCHAR(255) NOT NULL " ,
" password1 " => " VARCHAR(255) NOT NULL " ,
" exclude " => " VARCHAR(500) NOT NULL DEFAULT '' " ,
" maxage " => " SMALLINT NOT NULL DEFAULT '0' " ,
2018-01-24 19:59:04 +08:00
" mins_interval " => " VARCHAR(50) NOT NULL DEFAULT '0' " ,
" maxbytespersecond " => " VARCHAR(50) NOT NULL DEFAULT '0' " ,
2017-04-21 16:20:31 +08:00
" port1 " => " SMALLINT NOT NULL " ,
" enc1 " => " ENUM('TLS','SSL','PLAIN') DEFAULT 'TLS' " ,
" delete2duplicates " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
2017-05-01 22:20:21 +08:00
" delete1 " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
2017-08-31 16:36:10 +08:00
" delete2 " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
2018-01-24 19:59:04 +08:00
" automap " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
" skipcrossduplicates " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
2018-07-28 04:19:59 +08:00
" custom_params " => " VARCHAR(512) NOT NULL DEFAULT '' " ,
" timeout1 " => " SMALLINT NOT NULL DEFAULT '600' " ,
" timeout2 " => " SMALLINT NOT NULL DEFAULT '600' " ,
" subscribeall " => " TINYINT(1) NOT NULL DEFAULT '1' " ,
2017-11-08 18:07:32 +08:00
" is_running " => " TINYINT(1) NOT NULL DEFAULT '0' " ,
2019-05-04 18:13:51 +08:00
" returned_text " => " LONGTEXT " ,
2017-04-21 16:20:31 +08:00
" last_run " => " TIMESTAMP NULL DEFAULT NULL " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE CURRENT_TIMESTAMP " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '0' "
),
" keys " => array (
" primary " => array (
" " => array ( " id " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-11-19 22:13:43 +08:00
" bcc_maps " => array (
" cols " => array (
" id " => " INT NOT NULL AUTO_INCREMENT " ,
" local_dest " => " VARCHAR(255) NOT NULL " ,
" bcc_dest " => " VARCHAR(255) NOT NULL " ,
" domain " => " VARCHAR(255) NOT NULL " ,
" type " => " ENUM('sender','rcpt') " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE CURRENT_TIMESTAMP " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '0' "
),
" keys " => array (
" primary " => array (
" " => array ( " id " )
),
" key " => array (
" local_dest " => array ( " local_dest " ),
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2018-01-24 02:59:06 +08:00
" recipient_maps " => array (
" cols " => array (
" id " => " INT NOT NULL AUTO_INCREMENT " ,
" old_dest " => " VARCHAR(255) NOT NULL " ,
" new_dest " => " VARCHAR(255) NOT NULL " ,
" created " => " DATETIME(0) NOT NULL DEFAULT NOW(0) " ,
" modified " => " DATETIME ON UPDATE CURRENT_TIMESTAMP " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '0' "
),
" keys " => array (
" primary " => array (
" " => array ( " id " )
),
" key " => array (
" local_dest " => array ( " old_dest " ),
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-04-21 16:20:31 +08:00
" tfa " => array (
" cols " => array (
" id " => " INT NOT NULL AUTO_INCREMENT " ,
2017-05-01 23:03:47 +08:00
" key_id " => " VARCHAR(255) NOT NULL " ,
2017-04-21 16:20:31 +08:00
" username " => " VARCHAR(255) NOT NULL " ,
" authmech " => " ENUM('yubi_otp', 'u2f', 'hotp', 'totp') " ,
" secret " => " VARCHAR(255) DEFAULT NULL " ,
" keyHandle " => " VARCHAR(255) DEFAULT NULL " ,
" publicKey " => " VARCHAR(255) DEFAULT NULL " ,
" counter " => " INT NOT NULL DEFAULT '0' " ,
" certificate " => " TEXT " ,
" active " => " TINYINT(1) NOT NULL DEFAULT '0' "
),
" keys " => array (
" primary " => array (
" " => array ( " id " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-04-23 00:13:58 +08:00
" forwarding_hosts " => array (
" cols " => array (
" host " => " VARCHAR(255) NOT NULL " ,
2017-05-07 14:50:28 +08:00
" source " => " VARCHAR(255) NOT NULL " ,
" filter_spam " => " TINYINT(1) NOT NULL DEFAULT '0' "
2017-04-23 00:13:58 +08:00
),
" keys " => array (
" primary " => array (
" " => array ( " host " )
),
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
2017-04-21 16:20:31 +08:00
" sogo_acl " => array (
" cols " => array (
2018-06-24 05:50:22 +08:00
" id " => " INT NOT NULL AUTO_INCREMENT " ,
2017-04-21 16:20:31 +08:00
" c_folder_id " => " INT NOT NULL " ,
" c_object " => " VARCHAR(255) NOT NULL " ,
" c_uid " => " VARCHAR(255) NOT NULL " ,
" c_role " => " VARCHAR(80) NOT NULL "
),
" keys " => array (
2018-06-24 05:50:22 +08:00
" primary " => array (
" " => array ( " id " )
),
2017-04-21 16:20:31 +08:00
" key " => array (
" sogo_acl_c_folder_id_idx " => array ( " c_folder_id " ),
" sogo_acl_c_uid_idx " => array ( " c_uid " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" sogo_alarms_folder " => array (
" cols " => array (
2018-06-24 05:50:22 +08:00
" id " => " INT NOT NULL AUTO_INCREMENT " ,
2017-04-21 16:20:31 +08:00
" c_path " => " VARCHAR(255) NOT NULL " ,
" c_name " => " VARCHAR(255) NOT NULL " ,
" c_uid " => " VARCHAR(255) NOT NULL " ,
" c_recurrence_id " => " INT(11) DEFAULT NULL " ,
" c_alarm_number " => " INT(11) NOT NULL " ,
" c_alarm_date " => " INT(11) NOT NULL "
),
2018-06-24 05:50:22 +08:00
" keys " => array (
" primary " => array (
" " => array ( " id " )
)
),
2017-04-21 16:20:31 +08:00
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" sogo_cache_folder " => array (
" cols " => array (
" c_uid " => " VARCHAR(255) NOT NULL " ,
" c_path " => " VARCHAR(255) NOT NULL " ,
" c_parent_path " => " VARCHAR(255) DEFAULT NULL " ,
" c_type " => " TINYINT(3) unsigned NOT NULL " ,
" c_creationdate " => " INT(11) NOT NULL " ,
" c_lastmodified " => " INT(11) NOT NULL " ,
" c_version " => " INT(11) NOT NULL DEFAULT '0' " ,
" c_deleted " => " TINYINT(4) NOT NULL DEFAULT '0' " ,
" c_content " => " LONGTEXT "
),
" keys " => array (
" primary " => array (
" " => array ( " c_uid " , " c_path " )
),
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" sogo_folder_info " => array (
" cols " => array (
" c_folder_id " => " BIGINT(20) unsigned NOT NULL AUTO_INCREMENT " ,
" c_path " => " VARCHAR(255) NOT NULL " ,
" c_path1 " => " VARCHAR(255) NOT NULL " ,
" c_path2 " => " VARCHAR(255) DEFAULT NULL " ,
" c_path3 " => " VARCHAR(255) DEFAULT NULL " ,
" c_path4 " => " VARCHAR(255) DEFAULT NULL " ,
" c_foldername " => " VARCHAR(255) NOT NULL " ,
2017-09-15 13:55:23 +08:00
" c_location " => " VARCHAR(2048) DEFAULT NULL " ,
2017-04-21 16:20:31 +08:00
" c_quick_location " => " VARCHAR(2048) DEFAULT NULL " ,
" c_acl_location " => " VARCHAR(2048) DEFAULT NULL " ,
" c_folder_type " => " VARCHAR(255) NOT NULL "
),
" keys " => array (
" primary " => array (
" " => array ( " c_path " )
),
" unique " => array (
" c_folder_id " => array ( " c_folder_id " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" sogo_quick_appointment " => array (
" cols " => array (
" c_folder_id " => " INT NOT NULL " ,
" c_name " => " VARCHAR(255) NOT NULL " ,
" c_uid " => " VARCHAR(255) NOT NULL " ,
" c_startdate " => " INT " ,
" c_enddate " => " INT " ,
" c_cycleenddate " => " INT " ,
" c_title " => " VARCHAR(1000) NOT NULL " ,
" c_participants " => " TEXT " ,
" c_isallday " => " INT " ,
" c_iscycle " => " INT " ,
" c_cycleinfo " => " TEXT " ,
" c_classification " => " INT NOT NULL " ,
" c_isopaque " => " INT NOT NULL " ,
" c_status " => " INT NOT NULL " ,
" c_priority " => " INT " ,
" c_location " => " VARCHAR(255) " ,
" c_orgmail " => " VARCHAR(255) " ,
" c_partmails " => " TEXT " ,
" c_partstates " => " TEXT " ,
" c_category " => " VARCHAR(255) " ,
" c_sequence " => " INT " ,
" c_component " => " VARCHAR(10) NOT NULL " ,
" c_nextalarm " => " INT " ,
" c_description " => " TEXT "
),
" keys " => array (
" primary " => array (
" " => array ( " c_folder_id " , " c_name " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" sogo_quick_contact " => array (
" cols " => array (
" c_folder_id " => " INT NOT NULL " ,
" c_name " => " VARCHAR(255) NOT NULL " ,
" c_givenname " => " VARCHAR(255) " ,
" c_cn " => " VARCHAR(255) " ,
" c_sn " => " VARCHAR(255) " ,
" c_screenname " => " VARCHAR(255) " ,
" c_l " => " VARCHAR(255) " ,
2018-01-03 01:17:27 +08:00
" c_mail " => " TEXT " ,
2017-04-21 16:20:31 +08:00
" c_o " => " VARCHAR(255) " ,
" c_ou " => " VARCHAR(255) " ,
" c_telephonenumber " => " VARCHAR(255) " ,
" c_categories " => " VARCHAR(255) " ,
2018-01-03 01:17:27 +08:00
" c_component " => " VARCHAR(10) NOT NULL " ,
" c_hascertificate " => " INT4 DEFAULT 0 "
2017-04-21 16:20:31 +08:00
),
" keys " => array (
" primary " => array (
" " => array ( " c_folder_id " , " c_name " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" sogo_sessions_folder " => array (
" cols " => array (
" c_id " => " VARCHAR(255) NOT NULL " ,
" c_value " => " VARCHAR(255) NOT NULL " ,
" c_creationdate " => " INT(11) NOT NULL " ,
" c_lastseen " => " INT(11) NOT NULL "
),
" keys " => array (
" primary " => array (
" " => array ( " c_id " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" sogo_store " => array (
" cols " => array (
" c_folder_id " => " INT NOT NULL " ,
" c_name " => " VARCHAR(255) NOT NULL " ,
" c_content " => " MEDIUMTEXT NOT NULL " ,
" c_creationdate " => " INT NOT NULL " ,
" c_lastmodified " => " INT NOT NULL " ,
" c_version " => " INT NOT NULL " ,
" c_deleted " => " INT "
),
" keys " => array (
" primary " => array (
" " => array ( " c_folder_id " , " c_name " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" sogo_user_profile " => array (
" cols " => array (
" c_uid " => " VARCHAR(255) NOT NULL " ,
2018-01-03 01:17:27 +08:00
" c_defaults " => " LONGTEXT " ,
" c_settings " => " LONGTEXT "
2017-04-21 16:20:31 +08:00
),
" keys " => array (
" primary " => array (
" " => array ( " c_uid " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
2019-09-29 02:00:04 +08:00
),
" oauth_clients " => array (
" cols " => array (
" id " => " INT NOT NULL AUTO_INCREMENT " ,
" client_id " => " VARCHAR(80) NOT NULL " ,
" client_secret " => " VARCHAR(80) " ,
" redirect_uri " => " VARCHAR(2000) " ,
" grant_types " => " VARCHAR(80) " ,
" scope " => " VARCHAR(4000) " ,
" user_id " => " VARCHAR(80) "
),
" keys " => array (
" primary " => array (
" " => array ( " client_id " )
),
" unique " => array (
" id " => array ( " id " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" oauth_access_tokens " => array (
" cols " => array (
" access_token " => " VARCHAR(40) NOT NULL " ,
" client_id " => " VARCHAR(80) NOT NULL " ,
" user_id " => " VARCHAR(80) " ,
" expires " => " TIMESTAMP NOT NULL " ,
" scope " => " VARCHAR(4000) "
),
" keys " => array (
" primary " => array (
" " => array ( " access_token " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" oauth_authorization_codes " => array (
" cols " => array (
" authorization_code " => " VARCHAR(40) NOT NULL " ,
" client_id " => " VARCHAR(80) NOT NULL " ,
" user_id " => " VARCHAR(80) " ,
" redirect_uri " => " VARCHAR(2000) " ,
" expires " => " TIMESTAMP NOT NULL " ,
" scope " => " VARCHAR(4000) " ,
" id_token " => " VARCHAR(1000) "
),
" keys " => array (
" primary " => array (
" " => array ( " authorization_code " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
),
" oauth_refresh_tokens " => array (
" cols " => array (
" refresh_token " => " VARCHAR(40) NOT NULL " ,
" client_id " => " VARCHAR(80) NOT NULL " ,
" user_id " => " VARCHAR(80) " ,
" expires " => " TIMESTAMP NOT NULL " ,
" scope " => " VARCHAR(4000) "
),
" keys " => array (
" primary " => array (
" " => array ( " refresh_token " )
)
),
" attr " => " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC "
2017-04-21 16:20:31 +08:00
)
);
foreach ( $tables as $table => $properties ) {
2018-02-17 16:50:39 +08:00
// Migrate to quarantine
2018-02-09 03:13:36 +08:00
if ( $table == 'quarantine' ) {
$stmt = $pdo -> query ( " SHOW TABLES LIKE 'quarantaine' " );
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
2018-02-11 22:59:58 +08:00
$stmt = $pdo -> query ( " SHOW TABLES LIKE 'quarantine' " );
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results == 0 ) {
$pdo -> query ( " RENAME TABLE `quarantaine` TO `quarantine` " );
}
2018-02-09 03:13:36 +08:00
}
}
2018-02-17 17:18:07 +08:00
// Migrate tls_enforce_* options
if ( $table == 'mailbox' ) {
$stmt = $pdo -> query ( " SHOW TABLES LIKE 'mailbox' " );
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
2019-10-07 00:56:24 +08:00
$stmt = $pdo -> query ( " SHOW COLUMNS FROM `mailbox` LIKE '%tls_enforce%' " );
2018-02-17 17:18:07 +08:00
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$stmt = $pdo -> query ( " SELECT `username`, `tls_enforce_in`, `tls_enforce_out` FROM `mailbox` " );
$tls_options_rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $tls_options_rows )) {
$tls_options [ $row [ 'username' ]] = array ( 'tls_enforce_in' => $row [ 'tls_enforce_in' ], 'tls_enforce_out' => $row [ 'tls_enforce_out' ]);
}
}
}
}
2019-10-07 00:56:24 +08:00
$stmt = $pdo -> query ( " SHOW TABLES LIKE ' " . $table . " ' " );
2017-04-21 16:20:31 +08:00
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
2017-10-02 21:58:55 +08:00
$stmt = $pdo -> prepare ( " SELECT CONCAT('ALTER TABLE ', `table_schema`, '.', `table_name`, ' DROP FOREIGN KEY ', `constraint_name`, ';') AS `FKEY_DROP` FROM `information_schema`.`table_constraints`
WHERE `constraint_type` = 'FOREIGN KEY' AND `table_name` = : table ; " );
$stmt -> execute ( array ( ':table' => $table ));
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
while ( $row = array_shift ( $rows )) {
$pdo -> query ( $row [ 'FKEY_DROP' ]);
}
2017-04-21 16:20:31 +08:00
foreach ( $properties [ 'cols' ] as $column => $type ) {
2019-10-07 00:56:24 +08:00
$stmt = $pdo -> query ( " SHOW COLUMNS FROM ` " . $table . " ` LIKE ' " . $column . " ' " );
2017-04-21 16:20:31 +08:00
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results == 0 ) {
2018-06-24 05:50:22 +08:00
if ( strpos ( $type , 'AUTO_INCREMENT' ) !== false ) {
$type = $type . ' PRIMARY KEY ' ;
2018-08-15 20:16:55 +08:00
// Adding an AUTO_INCREMENT key, need to drop primary keys first, if exists
$stmt = $pdo -> query ( " SHOW KEYS FROM ` " . $table . " ` WHERE Key_name = 'PRIMARY' " );
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$pdo -> query ( " ALTER TABLE ` " . $table . " ` DROP PRIMARY KEY " );
}
2018-06-24 05:50:22 +08:00
}
2017-04-21 16:20:31 +08:00
$pdo -> query ( " ALTER TABLE ` " . $table . " ` ADD ` " . $column . " ` " . $type );
}
else {
$pdo -> query ( " ALTER TABLE ` " . $table . " ` MODIFY COLUMN ` " . $column . " ` " . $type );
}
}
foreach ( $properties [ 'keys' ] as $key_type => $key_content ) {
if ( strtolower ( $key_type ) == 'primary' ) {
foreach ( $key_content as $key_values ) {
$fields = " ` " . implode ( " `, ` " , $key_values ) . " ` " ;
2019-10-07 00:56:24 +08:00
$stmt = $pdo -> query ( " SHOW KEYS FROM ` " . $table . " ` WHERE Key_name = 'PRIMARY' " );
2017-04-21 16:20:31 +08:00
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
$is_drop = ( $num_results != 0 ) ? " DROP PRIMARY KEY, " : " " ;
$pdo -> query ( " ALTER TABLE ` " . $table . " ` " . $is_drop . " ADD PRIMARY KEY ( " . $fields . " ) " );
}
}
if ( strtolower ( $key_type ) == 'key' ) {
foreach ( $key_content as $key_name => $key_values ) {
$fields = " ` " . implode ( " `, ` " , $key_values ) . " ` " ;
2019-10-07 00:56:24 +08:00
$stmt = $pdo -> query ( " SHOW KEYS FROM ` " . $table . " ` WHERE Key_name = ' " . $key_name . " ' " );
2017-04-21 16:20:31 +08:00
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
$is_drop = ( $num_results != 0 ) ? " DROP INDEX ` " . $key_name . " `, " : " " ;
$pdo -> query ( " ALTER TABLE ` " . $table . " ` " . $is_drop . " ADD KEY ` " . $key_name . " ` ( " . $fields . " ) " );
}
}
if ( strtolower ( $key_type ) == 'unique' ) {
foreach ( $key_content as $key_name => $key_values ) {
2019-10-07 00:59:54 +08:00
$fields = " ` " . implode ( " `, ` " , $key_values ) . " ` " ;
2019-10-05 23:29:16 +08:00
$stmt = $pdo -> query ( " SHOW KEYS FROM ` " . $table . " ` WHERE Key_name = ' " . $key_name . " ' " );
2017-04-21 16:20:31 +08:00
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
$is_drop = ( $num_results != 0 ) ? " DROP INDEX ` " . $key_name . " `, " : " " ;
$pdo -> query ( " ALTER TABLE ` " . $table . " ` " . $is_drop . " ADD UNIQUE KEY ` " . $key_name . " ` ( " . $fields . " ) " );
}
}
2017-08-19 04:18:14 +08:00
if ( strtolower ( $key_type ) == 'fkey' ) {
foreach ( $key_content as $key_name => $key_values ) {
2019-10-07 00:59:54 +08:00
$fields = " ` " . implode ( " `, ` " , $key_values ) . " ` " ;
2019-10-05 23:29:16 +08:00
$stmt = $pdo -> query ( " SHOW KEYS FROM ` " . $table . " ` WHERE Key_name = ' " . $key_name . " ' " );
2017-08-19 04:18:14 +08:00
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
2017-10-02 21:58:55 +08:00
$pdo -> query ( " ALTER TABLE ` " . $table . " ` DROP INDEX ` " . $key_name . " ` " );
2017-08-19 04:18:14 +08:00
}
@ list ( $table_ref , $field_ref ) = explode ( '.' , $key_values [ 'ref' ]);
$pdo -> query ( " ALTER TABLE ` " . $table . " ` ADD FOREIGN KEY ` " . $key_name . " ` ( " . $key_values [ 'col' ] . " ) REFERENCES ` " . $table_ref . " ` (` " . $field_ref . " `)
ON DELETE " . $key_values['delete'] . " ON UPDATE " . $key_values['update'] );
}
}
2017-04-21 16:20:31 +08:00
}
// Drop all vanished columns
2019-10-07 00:56:24 +08:00
$stmt = $pdo -> query ( " SHOW COLUMNS FROM ` " . $table . " ` " );
$cols_in_table = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
2017-04-21 16:20:31 +08:00
while ( $row = array_shift ( $cols_in_table )) {
if ( ! array_key_exists ( $row [ 'Field' ], $properties [ 'cols' ])) {
$pdo -> query ( " ALTER TABLE ` " . $table . " ` DROP COLUMN ` " . $row [ 'Field' ] . " `; " );
}
}
// Step 1: Get all non-primary keys, that currently exist and those that should exist
2019-10-07 00:56:24 +08:00
$stmt = $pdo -> query ( " SHOW KEYS FROM ` " . $table . " ` WHERE `Key_name` != 'PRIMARY' " );
$keys_in_table = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
2017-04-21 16:20:31 +08:00
$keys_to_exist = array ();
if ( isset ( $properties [ 'keys' ][ 'unique' ]) && is_array ( $properties [ 'keys' ][ 'unique' ])) {
foreach ( $properties [ 'keys' ][ 'unique' ] as $key_name => $key_values ) {
$keys_to_exist [] = $key_name ;
}
}
if ( isset ( $properties [ 'keys' ][ 'key' ]) && is_array ( $properties [ 'keys' ][ 'key' ])) {
foreach ( $properties [ 'keys' ][ 'key' ] as $key_name => $key_values ) {
$keys_to_exist [] = $key_name ;
}
}
2017-08-19 04:18:14 +08:00
// Index for foreign key must exist
if ( isset ( $properties [ 'keys' ][ 'fkey' ]) && is_array ( $properties [ 'keys' ][ 'fkey' ])) {
foreach ( $properties [ 'keys' ][ 'fkey' ] as $key_name => $key_values ) {
$keys_to_exist [] = $key_name ;
}
}
2017-04-21 16:20:31 +08:00
// Step 2: Drop all vanished indexes
while ( $row = array_shift ( $keys_in_table )) {
if ( ! in_array ( $row [ 'Key_name' ], $keys_to_exist )) {
2017-10-02 21:58:55 +08:00
$pdo -> query ( " ALTER TABLE ` " . $table . " ` DROP INDEX ` " . $row [ 'Key_name' ] . " ` " );
2017-04-21 16:20:31 +08:00
}
}
// Step 3: Drop all vanished primary keys
if ( ! isset ( $properties [ 'keys' ][ 'primary' ])) {
2019-10-07 00:56:24 +08:00
$stmt = $pdo -> query ( " SHOW KEYS FROM ` " . $table . " ` WHERE Key_name = 'PRIMARY' " );
2017-04-21 16:20:31 +08:00
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results != 0 ) {
$pdo -> query ( " ALTER TABLE ` " . $table . " ` DROP PRIMARY KEY " );
}
}
}
else {
// Create table if it is missing
$sql = " CREATE TABLE IF NOT EXISTS ` " . $table . " ` ( " ;
foreach ( $properties [ 'cols' ] as $column => $type ) {
2018-05-06 15:15:12 +08:00
$sql .= " ` " . $column . " ` " . $type . " , " ;
2017-04-21 16:20:31 +08:00
}
foreach ( $properties [ 'keys' ] as $key_type => $key_content ) {
if ( strtolower ( $key_type ) == 'primary' ) {
foreach ( $key_content as $key_values ) {
$fields = " ` " . implode ( " `, ` " , $key_values ) . " ` " ;
$sql .= " PRIMARY KEY ( " . $fields . " ) " . " , " ;
}
}
elseif ( strtolower ( $key_type ) == 'key' ) {
foreach ( $key_content as $key_name => $key_values ) {
$fields = " ` " . implode ( " `, ` " , $key_values ) . " ` " ;
$sql .= " KEY ` " . $key_name . " ` ( " . $fields . " ) " . " , " ;
}
}
elseif ( strtolower ( $key_type ) == 'unique' ) {
foreach ( $key_content as $key_name => $key_values ) {
$fields = " ` " . implode ( " `, ` " , $key_values ) . " ` " ;
$sql .= " UNIQUE KEY ` " . $key_name . " ` ( " . $fields . " ) " . " , " ;
}
}
2017-08-19 04:18:14 +08:00
elseif ( strtolower ( $key_type ) == 'fkey' ) {
foreach ( $key_content as $key_name => $key_values ) {
@ list ( $table_ref , $field_ref ) = explode ( '.' , $key_values [ 'ref' ]);
$fields = " ` " . implode ( " `, ` " , $key_values ) . " ` " ;
$sql .= " FOREIGN KEY ` " . $key_name . " ` ( " . $key_values [ 'col' ] . " ) REFERENCES ` " . $table_ref . " ` (` " . $field_ref . " `)
ON DELETE " . $key_values['delete'] . " ON UPDATE " . $key_values['update'] . " , " ;
}
}
2017-04-21 16:20:31 +08:00
}
$sql = rtrim ( $sql , " , " );
$sql .= " ) " . $properties [ 'attr' ];
$pdo -> query ( $sql );
}
// Reset table attributes
$pdo -> query ( " ALTER TABLE ` " . $table . " ` " . $properties [ 'attr' ] . " ; " );
2018-02-17 17:40:20 +08:00
2017-04-21 16:20:31 +08:00
}
// Recreate SQL views
foreach ( $views as $view => $create ) {
$pdo -> query ( " DROP VIEW IF EXISTS ` " . $view . " `; " );
$pdo -> query ( $create );
}
2017-12-09 20:17:15 +08:00
// Create events to clean database
$events [] = ' DROP EVENT IF EXISTS clean_spamalias ;
DELIMITER //
2019-10-07 00:56:24 +08:00
CREATE EVENT clean_spamalias
ON SCHEDULE EVERY 1 DAY DO
2017-12-09 20:17:15 +08:00
BEGIN
DELETE FROM spamalias WHERE validity < UNIX_TIMESTAMP ();
END ;
//
2019-10-03 01:00:36 +08:00
DELIMITER ; ' ;
$events [] = ' DROP EVENT IF EXISTS clean_oauth2 ;
DELIMITER //
2019-10-07 00:56:24 +08:00
CREATE EVENT clean_oauth2
ON SCHEDULE EVERY 1 DAY DO
2019-10-03 01:00:36 +08:00
BEGIN
DELETE FROM oauth_refresh_tokens WHERE expires < NOW ();
DELETE FROM oauth_access_tokens WHERE expires < NOW ();
DELETE FROM oauth_authorization_codes WHERE expires < NOW ();
END ;
//
2017-12-09 20:17:15 +08:00
DELIMITER ; ' ;
foreach ( $events as $event ) {
$pdo -> exec ( $event );
}
2017-04-21 16:20:31 +08:00
// Inject admin if not exists
2019-10-07 00:56:24 +08:00
$stmt = $pdo -> query ( " SELECT NULL FROM `admin` " );
2017-09-15 04:45:17 +08:00
$num_results = count ( $stmt -> fetchAll ( PDO :: FETCH_ASSOC ));
if ( $num_results == 0 ) {
2017-04-21 16:20:31 +08:00
$stmt = $pdo -> query ( " INSERT INTO `admin` (`username`, `password`, `superadmin`, `created`, `modified`, `active`)
2017-09-15 04:45:17 +08:00
VALUES ( 'admin' , '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk' , 1 , NOW (), NOW (), 1 ) " );
2017-04-21 16:20:31 +08:00
$stmt = $pdo -> query ( " INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
SELECT `username` , 'ALL' , NOW (), 1 FROM `admin`
2017-05-20 22:56:53 +08:00
WHERE superadmin = '1' AND `username` NOT IN ( SELECT `username` FROM `domain_admins` ); " );
$stmt = $pdo -> query ( " DELETE FROM `admin` WHERE `username` NOT IN (SELECT `username` FROM `domain_admins`); " );
2017-09-15 04:45:17 +08:00
}
2017-04-21 16:20:31 +08:00
// Insert new DB schema version
2019-10-07 00:56:24 +08:00
$stmt = $pdo -> query ( " REPLACE INTO `versions` (`application`, `version`) VALUES ('db_schema', ' " . $db_version . " '); " );
2017-04-21 16:20:31 +08:00
2019-10-11 14:25:23 +08:00
// Fix dangling domain admins
$stmt = $pdo -> query ( " DELETE FROM `admin` WHERE `superadmin` = 0 AND `username` NOT IN (SELECT `username`FROM `domain_admins`); " );
2019-10-11 22:47:39 +08:00
$stmt = $pdo -> query ( " DELETE FROM `da_acl` WHERE `username` NOT IN (SELECT `username`FROM `domain_admins`); " );
2019-10-11 14:25:23 +08:00
2018-11-12 17:03:50 +08:00
// Migrate attributes
2018-11-27 19:51:42 +08:00
$stmt = $pdo -> query ( " UPDATE `mailbox` SET `attributes` = ' { }' WHERE `attributes` = '' OR `attributes` IS NULL; " );
2018-10-24 03:14:57 +08:00
$stmt = $pdo -> query ( " UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, ' $ .force_pw_update', \" 0 \" ) WHERE JSON_EXTRACT(`attributes`, ' $ .force_pw_update') IS NULL; " );
$stmt = $pdo -> query ( " UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, ' $ .sogo_access', \" 1 \" ) WHERE JSON_EXTRACT(`attributes`, ' $ .sogo_access') IS NULL; " );
2018-11-12 17:03:50 +08:00
$stmt = $pdo -> query ( " UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, ' $ .mailbox_format', \" maildir: \" ) WHERE JSON_EXTRACT(`attributes`, ' $ .mailbox_format') IS NULL; " );
2019-01-29 07:20:39 +08:00
$stmt = $pdo -> query ( " UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, ' $ .quarantine_notification', \" never \" ) WHERE JSON_EXTRACT(`attributes`, ' $ .quarantine_notification') IS NULL; " );
2018-02-17 17:40:20 +08:00
foreach ( $tls_options as $tls_user => $tls_options ) {
$stmt = $pdo -> prepare ( " UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, ' $ .tls_enforce_in', :tls_enforce_in),
`attributes` = JSON_SET ( `attributes` , '$.tls_enforce_out' , : tls_enforce_out )
WHERE `username` = : username " );
$stmt -> execute ( array ( ':tls_enforce_in' => $tls_options [ 'tls_enforce_in' ], ':tls_enforce_out' => $tls_options [ 'tls_enforce_out' ], ':username' => $tls_user ));
}
2018-11-12 17:03:50 +08:00
// Set tls_enforce_* if still missing (due to deleted attrs for example)
$stmt = $pdo -> query ( " UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, ' $ .tls_enforce_out', \" 1 \" ) WHERE JSON_EXTRACT(`attributes`, ' $ .tls_enforce_out') IS NULL; " );
$stmt = $pdo -> query ( " UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, ' $ .tls_enforce_in', \" 1 \" ) WHERE JSON_EXTRACT(`attributes`, ' $ .tls_enforce_in') IS NULL; " );
// Fix ACL
$stmt = $pdo -> query ( " INSERT INTO `user_acl` (`username`) SELECT `username` FROM `mailbox` WHERE `kind` = '' AND NOT EXISTS (SELECT `username` FROM `user_acl`); " );
$stmt = $pdo -> query ( " INSERT INTO `da_acl` (`username`) SELECT DISTINCT `username` FROM `domain_admins` WHERE `username` != 'admin' AND NOT EXISTS (SELECT `username` FROM `da_acl`); " );
// Fix domain_admins
$stmt = $pdo -> query ( " DELETE FROM `domain_admins` WHERE `domain` = 'ALL'; " );
2018-10-11 17:59:23 +08:00
if ( php_sapi_name () == " cli " ) {
echo " DB initialization completed " . PHP_EOL ;
} else {
$_SESSION [ 'return' ][] = array (
'type' => 'success' ,
'log' => array ( __FUNCTION__ ),
'msg' => 'db_init_complete'
);
}
2017-04-21 16:20:31 +08:00
}
catch ( PDOException $e ) {
2018-10-11 17:59:23 +08:00
if ( php_sapi_name () == " cli " ) {
echo " DB initialization failed: " . print_r ( $e , true ) . PHP_EOL ;
} else {
$_SESSION [ 'return' ][] = array (
'type' => 'danger' ,
'log' => array ( __FUNCTION__ ),
'msg' => array ( 'mysql_error' , $e )
);
}
2017-04-21 16:20:31 +08:00
}
}
2018-10-11 17:59:23 +08:00
if ( php_sapi_name () == " cli " ) {
include '/web/inc/vars.inc.php' ;
2018-11-12 17:03:50 +08:00
// $now = new DateTime();
// $mins = $now->getOffset() / 60;
// $sgn = ($mins < 0 ? -1 : 1);
// $mins = abs($mins);
// $hrs = floor($mins / 60);
// $mins -= $hrs * 60;
// $offset = sprintf('%+d:%02d', $hrs*$sgn, $mins);
2018-10-11 17:59:23 +08:00
$dsn = $database_type . " :unix_socket= " . $database_sock . " ;dbname= " . $database_name ;
$opt = [
PDO :: ATTR_ERRMODE => PDO :: ERRMODE_EXCEPTION ,
PDO :: ATTR_DEFAULT_FETCH_MODE => PDO :: FETCH_ASSOC ,
PDO :: ATTR_EMULATE_PREPARES => false ,
2018-11-12 17:03:50 +08:00
//PDO::MYSQL_ATTR_INIT_COMMAND => "SET time_zone = '" . $offset . "', group_concat_max_len = 3423543543;",
2018-10-11 17:59:23 +08:00
];
$pdo = new PDO ( $dsn , $database_user , $database_pass , $opt );
2018-10-29 03:57:21 +08:00
$stmt = $pdo -> query ( " SELECT COUNT('OK') AS OK_C FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sogo_view' OR TABLE_NAME = '_sogo_static_view'; " );
$res = $stmt -> fetch ( PDO :: FETCH_ASSOC );
if ( intval ( $res [ 'OK_C' ]) === 2 ) {
2018-11-12 17:03:50 +08:00
// Be more precise when replacing into _sogo_static_view, col orders may change
2018-11-28 03:00:54 +08:00
try {
$stmt = $pdo -> query ( " REPLACE INTO _sogo_static_view (`c_uid`, `domain`, `c_name`, `c_password`, `c_cn`, `mail`, `aliases`, `ad_aliases`, `kind`, `multiple_bookings`)
SELECT `c_uid` , `domain` , `c_name` , `c_password` , `c_cn` , `mail` , `aliases` , `ad_aliases` , `kind` , `multiple_bookings` from sogo_view " );
$stmt = $pdo -> query ( " DELETE FROM _sogo_static_view WHERE `c_uid` NOT IN (SELECT `username` FROM `mailbox` WHERE `active` = '1'); " );
echo " Fixed _sogo_static_view " . PHP_EOL ;
}
catch ( Exception $e ) {
// Dunno
}
2018-10-25 04:32:05 +08:00
}
try {
$m = new Memcached ();
$m -> addServer ( 'memcached' , 11211 );
$m -> flush ();
2018-10-29 03:57:21 +08:00
echo " Cleaned up memcached " . PHP_EOL ;
2018-10-25 04:32:05 +08:00
}
catch ( Exception $e ) {
// Dunno
}
2018-10-11 17:59:23 +08:00
init_db_schema ();
}