#!/usr/bin/env php '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; } ?>