1#!/usr/bin/env php 2<?php 3 4define('INSTALL_PATH', getcwd() . '/' ); 5 6require_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 14if (empty($opts['dir'])) { 15 rcube::raise_error("Database schema directory not specified (--dir).", false, true); 16} 17if (empty($opts['package'])) { 18 rcube::raise_error("Database schema package name not specified (--package).", false, true); 19} 20 21// Check if directory exists 22if (!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'); 31if (!$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'; 37if (!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 45if ($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 62if (!$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 84if ($error) { 85 echo "[FAILED]\n"; 86 rcube::raise_error("Error in DDL schema $file: $error", false, true); 87} 88echo "[OK]\n"; 89 90 91function 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?> 131