0
|
1 #!/usr/bin/env php
|
|
2 <?php
|
|
3
|
|
4 define('INSTALL_PATH', getcwd() . '/' );
|
|
5
|
|
6 require_once INSTALL_PATH . 'program/include/clisetup.php';
|
|
7
|
|
8 // get arguments
|
|
9 $opts = rcube_utils::get_opt(array(
|
|
10 'd' => 'dir',
|
|
11 'p' => 'package',
|
|
12 ));
|
|
13
|
|
14 if (empty($opts['dir'])) {
|
|
15 rcube::raise_error("Database schema directory not specified (--dir).", false, true);
|
|
16 }
|
|
17 if (empty($opts['package'])) {
|
|
18 rcube::raise_error("Database schema package name not specified (--package).", false, true);
|
|
19 }
|
|
20
|
|
21 // Check if directory exists
|
|
22 if (!file_exists($opts['dir'])) {
|
|
23 rcube::raise_error("Specified database schema directory doesn't exist.", false, true);
|
|
24 }
|
|
25
|
|
26 $RC = rcube::get_instance();
|
|
27 $DB = rcube_db::factory($RC->config->get('db_dsnw'));
|
|
28
|
|
29 // Connect to database
|
|
30 $DB->db_connect('w');
|
|
31 if (!$DB->is_connected()) {
|
|
32 rcube::raise_error("Error connecting to database: " . $DB->is_error(), false, true);
|
|
33 }
|
|
34
|
|
35 $opts['dir'] = rtrim($opts['dir'], DIRECTORY_SEPARATOR);
|
|
36 $file = $opts['dir'] . DIRECTORY_SEPARATOR . $DB->db_provider . '.initial.sql';
|
|
37 if (!file_exists($file)) {
|
|
38 rcube::raise_error("No DDL file found for " . $DB->db_provider . " driver.", false, true);
|
|
39 }
|
|
40
|
|
41 $package = $opts['package'];
|
|
42 $error = false;
|
|
43
|
|
44 // read DDL file
|
|
45 if ($lines = file($file)) {
|
|
46 $sql = '';
|
|
47 foreach ($lines as $line) {
|
|
48 if (preg_match('/^--/', $line) || trim($line) == '')
|
|
49 continue;
|
|
50
|
|
51 $sql .= $line . "\n";
|
|
52 if (preg_match('/(;|^GO)$/', trim($line))) {
|
|
53 @$DB->query(fix_table_names($sql));
|
|
54 $sql = '';
|
|
55 if ($error = $DB->is_error()) {
|
|
56 break;
|
|
57 }
|
|
58 }
|
|
59 }
|
|
60 }
|
|
61
|
|
62 if (!$error) {
|
|
63 $version = date('Ymd00');
|
|
64 $system_table = $DB->quote_identifier($DB->table_name('system'));
|
|
65 $name_col = $DB->quote_identifier('name');
|
|
66 $value_col = $DB->quote_identifier('value');
|
|
67 $package_version = $package . '-version';
|
|
68
|
|
69 $DB->query("SELECT * FROM $system_table WHERE $name_col=?",
|
|
70 $package_version);
|
|
71
|
|
72 if ($DB->fetch_assoc()) {
|
|
73 $DB->query("UPDATE $system_table SET $value_col=? WHERE $name_col=?",
|
|
74 $version, $package_version);
|
|
75 }
|
|
76 else {
|
|
77 $DB->query("INSERT INTO $system_table ($name_col, $value_col) VALUES (?, ?)",
|
|
78 $package_version, $version);
|
|
79 }
|
|
80
|
|
81 $error = $DB->is_error();
|
|
82 }
|
|
83
|
|
84 if ($error) {
|
|
85 echo "[FAILED]\n";
|
|
86 rcube::raise_error("Error in DDL schema $file: $error", false, true);
|
|
87 }
|
|
88 echo "[OK]\n";
|
|
89
|
|
90
|
|
91 function fix_table_names($sql)
|
|
92 {
|
|
93 global $DB, $RC;
|
|
94
|
|
95 $prefix = $RC->config->get('db_prefix');
|
|
96 $engine = $DB->db_provider;
|
|
97
|
|
98 if (empty($prefix)) {
|
|
99 return $sql;
|
|
100 }
|
|
101
|
|
102 $tables = array();
|
|
103 $sequences = array();
|
|
104
|
|
105 // find table names
|
|
106 if (preg_match_all('/CREATE TABLE (\[dbo\]\.|IF NOT EXISTS )?[`"\[\]]*([^`"\[\] \r\n]+)/i', $sql, $matches)) {
|
|
107 foreach ($matches[2] as $table) {
|
|
108 $tables[$table] = $prefix . $table;
|
|
109 }
|
|
110 }
|
|
111 // find sequence names
|
|
112 if ($engine == 'postgres' && preg_match_all('/CREATE SEQUENCE (IF NOT EXISTS )?"?([^" \n\r]+)/i', $sql, $matches)) {
|
|
113 foreach ($matches[2] as $sequence) {
|
|
114 $sequences[$sequence] = $prefix . $sequence;
|
|
115 }
|
|
116 }
|
|
117
|
|
118 // replace table names
|
|
119 foreach ($tables as $table => $real_table) {
|
|
120 $sql = preg_replace("/([^a-zA-Z0-9_])$table([^a-zA-Z0-9_])/", "\\1$real_table\\2", $sql);
|
|
121 }
|
|
122 // replace sequence names
|
|
123 foreach ($sequences as $sequence => $real_sequence) {
|
|
124 $sql = preg_replace("/([^a-zA-Z0-9_])$sequence([^a-zA-Z0-9_])/", "\\1$real_sequence\\2", $sql);
|
|
125 }
|
|
126
|
|
127 return $sql;
|
|
128 }
|
|
129
|
|
130 ?>
|