131 lines
3.5 KiB
Bash
Executable File
131 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env php
|
|
<?php
|
|
|
|
define('INSTALL_PATH', getcwd() . '/' );
|
|
|
|
require_once INSTALL_PATH . 'program/include/clisetup.php';
|
|
|
|
// get arguments
|
|
$opts = rcube_utils::get_opt(array(
|
|
'd' => 'dir',
|
|
'p' => 'package',
|
|
));
|
|
|
|
if (empty($opts['dir'])) {
|
|
rcube::raise_error("Database schema directory not specified (--dir).", false, true);
|
|
}
|
|
if (empty($opts['package'])) {
|
|
rcube::raise_error("Database schema package name not specified (--package).", false, true);
|
|
}
|
|
|
|
// Check if directory exists
|
|
if (!file_exists($opts['dir'])) {
|
|
rcube::raise_error("Specified database schema directory doesn't exist.", false, true);
|
|
}
|
|
|
|
$RC = rcube::get_instance();
|
|
$DB = rcube_db::factory($RC->config->get('db_dsnw'));
|
|
|
|
// Connect to database
|
|
$DB->db_connect('w');
|
|
if (!$DB->is_connected()) {
|
|
rcube::raise_error("Error connecting to database: " . $DB->is_error(), false, true);
|
|
}
|
|
|
|
$opts['dir'] = rtrim($opts['dir'], DIRECTORY_SEPARATOR);
|
|
$file = $opts['dir'] . DIRECTORY_SEPARATOR . $DB->db_provider . '.initial.sql';
|
|
if (!file_exists($file)) {
|
|
rcube::raise_error("No DDL file found for " . $DB->db_provider . " driver.", false, true);
|
|
}
|
|
|
|
$package = $opts['package'];
|
|
$error = false;
|
|
|
|
// read DDL file
|
|
if ($lines = file($file)) {
|
|
$sql = '';
|
|
foreach ($lines as $line) {
|
|
if (preg_match('/^--/', $line) || trim($line) == '')
|
|
continue;
|
|
|
|
$sql .= $line . "\n";
|
|
if (preg_match('/(;|^GO)$/', trim($line))) {
|
|
@$DB->query(fix_table_names($sql));
|
|
$sql = '';
|
|
if ($error = $DB->is_error()) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
$version = date('Ymd00');
|
|
$system_table = $DB->quote_identifier($DB->table_name('system'));
|
|
$name_col = $DB->quote_identifier('name');
|
|
$value_col = $DB->quote_identifier('value');
|
|
$package_version = $package . '-version';
|
|
|
|
$DB->query("SELECT * FROM $system_table WHERE $name_col=?",
|
|
$package_version);
|
|
|
|
if ($DB->fetch_assoc()) {
|
|
$DB->query("UPDATE $system_table SET $value_col=? WHERE $name_col=?",
|
|
$version, $package_version);
|
|
}
|
|
else {
|
|
$DB->query("INSERT INTO $system_table ($name_col, $value_col) VALUES (?, ?)",
|
|
$package_version, $version);
|
|
}
|
|
|
|
$error = $DB->is_error();
|
|
}
|
|
|
|
if ($error) {
|
|
echo "[FAILED]\n";
|
|
rcube::raise_error("Error in DDL schema $file: $error", false, true);
|
|
}
|
|
echo "[OK]\n";
|
|
|
|
|
|
function fix_table_names($sql)
|
|
{
|
|
global $DB, $RC;
|
|
|
|
$prefix = $RC->config->get('db_prefix');
|
|
$engine = $DB->db_provider;
|
|
|
|
if (empty($prefix)) {
|
|
return $sql;
|
|
}
|
|
|
|
$tables = array();
|
|
$sequences = array();
|
|
|
|
// find table names
|
|
if (preg_match_all('/CREATE TABLE (\[dbo\]\.|IF NOT EXISTS )?[`"\[\]]*([^`"\[\] \r\n]+)/i', $sql, $matches)) {
|
|
foreach ($matches[2] as $table) {
|
|
$tables[$table] = $prefix . $table;
|
|
}
|
|
}
|
|
// find sequence names
|
|
if ($engine == 'postgres' && preg_match_all('/CREATE SEQUENCE (IF NOT EXISTS )?"?([^" \n\r]+)/i', $sql, $matches)) {
|
|
foreach ($matches[2] as $sequence) {
|
|
$sequences[$sequence] = $prefix . $sequence;
|
|
}
|
|
}
|
|
|
|
// replace table names
|
|
foreach ($tables as $table => $real_table) {
|
|
$sql = preg_replace("/([^a-zA-Z0-9_])$table([^a-zA-Z0-9_])/", "\\1$real_table\\2", $sql);
|
|
}
|
|
// replace sequence names
|
|
foreach ($sequences as $sequence => $real_sequence) {
|
|
$sql = preg_replace("/([^a-zA-Z0-9_])$sequence([^a-zA-Z0-9_])/", "\\1$real_sequence\\2", $sql);
|
|
}
|
|
|
|
return $sql;
|
|
}
|
|
|
|
?>
|