Changeset 4573 in subversion
- Timestamp:
- Feb 25, 2011 11:37:22 AM (2 years ago)
- Location:
- trunk/roundcubemail
- Files:
-
- 4 added
- 3 deleted
- 14 edited
-
CHANGELOG (modified) (1 diff)
-
SQL/mssql.upgrade.sql (modified) (1 diff)
-
SQL/mysql.update.sql (modified) (1 diff)
-
SQL/postgres.update.sql (modified) (1 diff)
-
SQL/sqlite.update.sql (modified) (1 diff)
-
UPGRADING (modified) (2 diffs)
-
bin/installto.sh (added)
-
bin/update.sh (modified) (4 diffs)
-
installer/check.php (modified) (1 diff)
-
installer/images/banner_bg.gif (deleted)
-
installer/images/banner_gradient.gif (added)
-
installer/images/banner_logo.gif (deleted)
-
installer/images/banner_right.gif (deleted)
-
installer/images/banner_schraffur.gif (added)
-
installer/images/rcube_logo.gif (added)
-
installer/index.php (modified) (2 diffs)
-
installer/rcube_install.php (modified) (10 diffs)
-
installer/styles.css (modified) (1 diff)
-
installer/test.php (modified) (3 diffs)
-
program/include/rcube_mdb2.php (modified) (1 diff)
-
program/lib/MDB2/Driver/Reverse/sqlite.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/roundcubemail/CHANGELOG
r4569 r4573 2 2 =========================== 3 3 4 - Interactive update script with improved DB schema check 4 5 - jQuery 1.5.1 5 6 - Fix problem with contactgroupmembers table creation on MySQL 4.x, add index on contact_id column -
trunk/roundcubemail/SQL/mssql.upgrade.sql
r4567 r4573 98 98 GO 99 99 100 -- Updates from version 0.5. x100 -- Updates from version 0.5.1 101 101 102 102 ALTER TABLE [dbo].[contacts] ADD [words] [text] COLLATE Latin1_General_CI_AI NULL -
trunk/roundcubemail/SQL/mysql.update.sql
r4567 r4573 134 134 TRUNCATE TABLE `messages`; 135 135 136 -- Updates from version 0.5. *136 -- Updates from version 0.5.1 137 137 138 138 ALTER TABLE `contacts` ADD `words` TEXT NULL AFTER `vcard`; -
trunk/roundcubemail/SQL/postgres.update.sql
r4567 r4573 91 91 TRUNCATE messages; 92 92 93 -- Updates from version 0.5. x93 -- Updates from version 0.5.1 94 94 95 95 ALTER TABLE contacts ADD words TEXT NULL; -
trunk/roundcubemail/SQL/sqlite.update.sql
r4567 r4573 184 184 185 185 186 -- Updates from version 0.5. x186 -- Updates from version 0.5.1 187 187 188 188 CREATE TABLE contacts_tmp ( -
trunk/roundcubemail/UPGRADING
r3490 r4573 5 5 of Roundcube Webmail. We recommend to carefully backup the existing 6 6 installation as well as the database before executig the following steps. 7 8 Using the update script 9 ----------------------- 10 There is a shell script (for unix based systems) that does the job for you. 11 To use it, unpack the archive of the new Roundcube version to a temporary location (don't replace the Roundcube installation you want to update) 12 and cd into that directory. From there, run the following command in a shell: 13 14 ./bin/installto.sh <TARGET-FOLDER> 15 16 For <TARGET-FOLDER> you specify the path to the Roundcube installation 17 which should be updated. The update script will then copy all new files to the 18 target location and check and update the configuration and database schema. 19 After all is done, the temporary folder with the new Roundcube files can be 20 removed again. 21 22 23 Updating manually 24 ----------------- 25 If you don't have shell access to the Roundcube instalaltion or if not running 26 it on a unix system, you need to do the following operations by hand: 7 27 8 28 1. Replace index.php and all files in … … 15 35 2. Run ./bin/update.sh from the commandline OR 16 36 open http://url-to-roundcube/installer/ in a browser and choose "3 Test config". 17 To enable the latter one, you have to temporary set 'enable_installer' to true18 in your local config/main.inc.php file.37 To enable the latter one, you have to temporary set 'enable_installer' 38 to true in your local config/main.inc.php file. 19 39 3. Let the update script/installer check your configuration and 20 update your config files as suggested by the updater. 21 4. If suggested by the update script, run all commands in 22 ./SQL/[yourdbtype].update.sql that are superscribed with the 23 currently installed version number. 24 5. Make sure 'enable_installer' is set to false again. 25 6. Check .htaccess settings (some php settings could become required) 40 update your config files and database schema as suggested by the updater. 41 4. Make sure 'enable_installer' is set to false again. 42 5. Check .htaccess settings (some php settings could become required) 26 43 27 44 -
trunk/roundcubemail/bin/update.sh
r4338 r4573 1 1 #!/usr/bin/env php 2 2 <?php 3 /* 4 +-----------------------------------------------------------------------+ 5 | bin/update.sh | 6 | | 7 | This file is part of the Roundcube Webmail client | 8 | Copyright (C) 2010-2011, The Roundcube Dev Team | 9 | Licensed under the GNU GPL | 10 | | 11 | PURPOSE: | 12 | Check local configuration and database schema after upgrading | 13 | to a new version | 14 +-----------------------------------------------------------------------+ 15 | Author: Thomas Bruederli <roundcube@gmail.com> | 16 +-----------------------------------------------------------------------+ 17 18 $Id$ 19 20 */ 21 3 22 if (php_sapi_name() != 'cli') { 4 23 die('Not on the "shell" (php-cli).'); … … 6 25 define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' ); 7 26 8 require_once INSTALL_PATH . 'program/include/ iniset.php';27 require_once INSTALL_PATH . 'program/include/clisetup.php'; 9 28 require_once INSTALL_PATH . 'installer/rcube_install.php'; 29 30 // get arguments 31 $opts = get_opt(array('v' => 'version')); 32 33 // ask user if no version is specified 34 if (!$opts['version']) { 35 echo "What version are you upgrading from? Type '?' if you don't know.\n"; 36 if (($input = trim(fgets(STDIN))) && preg_match('/^[0-9.]+[a-z-]*$/', $input)) 37 $opts['version'] = $input; 38 } 39 40 if ($opts['version'] && version_compare($opts['version'], RCMAIL_VERSION, '>')) 41 die("Nothing to be done here. Bye!\n"); 42 10 43 11 44 $RCI = rcube_install::get_instance(); … … 89 122 } 90 123 else { 91 echo "Please update your config files manually according to the above messages.\n ";124 echo "Please update your config files manually according to the above messages.\n\n"; 92 125 } 93 126 } … … 114 147 $success = false; 115 148 } 116 else if ($RCI->db_schema_check($DB, false)) { 117 $db_map = array('pgsql' => 'postgres', 'mysqli' => 'mysql', 'sqlsrv' => 'mssql'); 118 $updatefile = INSTALL_PATH . 'SQL/' . (isset($db_map[$DB->db_provider]) ? $db_map[$DB->db_provider] : $DB->db_provider) . '.update.sql'; 149 else if ($err = $RCI->db_schema_check($DB, false)) { 150 $updatefile = INSTALL_PATH . 'SQL/' . (isset($RCI->db_map[$DB->db_provider]) ? $RCI->db_map[$DB->db_provider] : $DB->db_provider) . '.update.sql'; 119 151 echo "WARNING: Database schema needs to be updated!\n"; 120 echo "Open $updatefile and execute all queries that are superscribed with the currently installed version number\n";152 echo join("\n", $err) . "\n\n"; 121 153 $success = false; 154 155 if ($opts['version']) { 156 echo "Do you want to run the update queries to get the schmea fixed? (y/N)\n"; 157 $input = trim(fgets(STDIN)); 158 if (strtolower($input) == 'y') { 159 $success = $RCI->update_db($DB, $opts['version']); 160 } 161 } 162 163 if (!$success) 164 echo "Open $updatefile and execute all queries below the comment with the currently installed version number.\n"; 122 165 } 123 166 } -
trunk/roundcubemail/installer/check.php
r4416 r4573 23 23 'MDB2' => 'MDB2.php', 24 24 'Net_SMTP' => 'Net/SMTP.php', 25 'Net_IDNA2' => 'Net/IDNA2.php', 25 26 'Mail_mime' => 'Mail/mime.php', 26 27 ); -
trunk/roundcubemail/installer/index.php
r3989 r4573 69 69 70 70 <div id="banner"> 71 <div id="header"> 72 <div class="banner-logo"><a href="http://www.roundcube.net"><img src="images/banner_logo.gif" width="200" height="56" border="0" alt="Roundcube Webmal Project" /></a></div> 73 <div class="banner-right"><img src="images/banner_right.gif" width="10" height="56" alt="" /></div> 74 </div> 75 <div id="topnav"> 76 <a href="http://trac.roundcube.net/wiki/Howto_Install">How-to Wiki</a> 77 </div> 78 </div> 71 <div class="banner-bg"></div> 72 <div class="banner-logo"><a href="http://roundcube.net"><img src="images/rcube_logo.gif" width="210" height="55" border="0" alt="Roundcube - Open source webmail project" /></a></div> 73 </div> 74 75 <div id="topnav"> 76 <a href="http://trac.roundcube.net/wiki/Howto_Install">How-to Wiki</a> 77 </div> 79 78 80 79 <div id="content"> … … 121 120 122 121 <div id="footer"> 123 Installer by the Roundcube Dev Team. Copyright © 2008 - Published under the GNU Public License; 122 Installer by the Roundcube Dev Team. Copyright © 2008-2011 - Published under the GNU Public License; 124 123 Icons by <a href="http://famfamfam.com">famfamfam</a> 125 124 </div> -
trunk/roundcubemail/installer/rcube_install.php
r4410 r4573 30 30 var $configured = false; 31 31 var $last_error = null; 32 var $db_map = array('pgsql' => 'postgres', 'mysqli' => 'mysql', 'sqlsrv' => 'mssql'); 32 33 var $email_pattern = '([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9])'; 33 34 var $bool_config_props = array(); 34 35 35 var $obsolete_config = array('db_backend' );36 var $obsolete_config = array('db_backend', 'double_auth'); 36 37 var $replaced_config = array( 37 38 'skin_path' => 'skin', … … 43 44 44 45 // these config options are required for a working system 45 var $required_config = array('db_dsnw', 'db_table_contactgroups', 'db_table_contactgroupmembers', 'des_key'); 46 var $required_config = array( 47 'db_dsnw', 'db_table_contactgroups', 'db_table_contactgroupmembers', 48 'des_key', 'session_lifetime', 49 ); 46 50 47 51 /** … … 295 299 $this->load_defaults(); 296 300 297 foreach ($this->replaced_config as $prop => $replacement) 301 foreach ($this->replaced_config as $prop => $replacement) { 298 302 if (isset($current[$prop])) { 299 303 if ($prop == 'skin_path') … … 303 307 else 304 308 $this->config[$replacement] = $current[$prop]; 305 306 unset($current[$prop]);309 } 310 unset($current[$prop]); 307 311 } 308 312 … … 321 325 } 322 326 327 if ($current['keep_alive'] && $current['session_lifetime'] < $current['keep_alive']) 328 $current['session_lifetime'] = max(10, ceil($current['keep_alive'] / 60) * 2); 329 323 330 $this->config = array_merge($this->config, $current); 324 331 … … 340 347 return false; 341 348 342 // simple ad hand-made db schema 343 $db_schema = array( 344 'users' => array(), 345 'identities' => array(), 346 'contacts' => array(), 347 'contactgroups' => array(), 348 'contactgroupmembers' => array(), 349 'cache' => array(), 350 'messages' => array(), 351 'session' => array(), 352 ); 353 349 // read reference schema from mysql.initial.sql 350 $db_schema = $this->db_read_schema(INSTALL_PATH . 'SQL/mysql.initial.sql'); 354 351 $errors = array(); 355 352 … … 359 356 foreach ($db_schema as $table => $cols) { 360 357 $table = !empty($this->config['db_table_'.$table]) ? $this->config['db_table_'.$table] : $table; 361 if (!in_array($table, $existing_tables)) 362 $errors[] = "Missing table ".$table; 363 // TODO: check cols and indices 358 if (!in_array($table, $existing_tables)) { 359 $errors[] = "Missing table '".$table."'"; 360 } 361 else { // compare cols 362 $db_cols = $DB->list_cols($table); 363 $diff = array_diff(array_keys($cols), $db_cols); 364 if (!empty($diff)) 365 $errors[] = "Missing columns in table '$table': " . join(',', $diff); 366 } 364 367 } 365 368 366 369 return !empty($errors) ? $errors : false; 367 370 } 371 372 /** 373 * Utility function to read database schema from an .sql file 374 */ 375 private function db_read_schema($schemafile) 376 { 377 $lines = file($schemafile); 378 $table_block = false; 379 $schema = array(); 380 foreach ($lines as $line) { 381 if (preg_match('/^\s*create table `?([a-z0-9_]+)`?/i', $line, $m)) { 382 $table_block = $m[1]; 383 } 384 else if ($table_block && preg_match('/^\s*`?([a-z0-9_-]+)`?\s+([a-z]+)/', $line, $m)) { 385 $col = $m[1]; 386 if (!in_array(strtoupper($col), array('PRIMARY','KEY','INDEX','UNIQUE','CONSTRAINT','REFERENCES','FOREIGN'))) { 387 $schema[$table_block][$col] = $m[2]; 388 } 389 } 390 } 391 392 return $schema; 393 } 394 368 395 369 396 /** … … 475 502 } 476 503 504 /** 505 * Create a HTML dropdown to select a previous version of Roundcube 506 */ 507 function versions_select($attrib = array()) 508 { 509 $select = new html_select($attrib); 510 $select->add(array('0.1-stable', '0.1.1', '0.2-alpha', '0.2-beta', '0.2-stable', '0.3-stable', '0.3.1', '0.4-beta', '0.4.2', '0.5-beta', '0.5', '0.5.1')); 511 return $select; 512 } 513 477 514 478 515 /** … … 593 630 function init_db($DB) 594 631 { 595 $db_map = array('pgsql' => 'postgres', 'mysqli' => 'mysql'); 596 $engine = isset($db_map[$DB->db_provider]) ? $db_map[$DB->db_provider] : $DB->db_provider; 632 $engine = isset($this->db_map[$DB->db_provider]) ? $this->db_map[$DB->db_provider] : $DB->db_provider; 597 633 598 634 // read schema file from /SQL/* 599 $fname = "../SQL/$engine.initial.sql"; 600 if ($lines = @file($fname, FILE_SKIP_EMPTY_LINES)) { 601 $buff = ''; 602 foreach ($lines as $i => $line) { 603 if (preg_match('/^--/', $line)) 604 continue; 605 606 $buff .= $line . "\n"; 607 if (preg_match('/;$/', trim($line))) { 608 $DB->query($buff); 609 $buff = ''; 610 if ($this->get_error()) 611 break; 612 } 613 } 635 $fname = INSTALL_PATH . "SQL/$engine.initial.sql"; 636 if ($sql = @file_get_contents($fname)) { 637 $this->exec_sql($sql, $DB); 614 638 } 615 639 else { … … 626 650 } 627 651 652 653 /** 654 * Update database with SQL statements from SQL/*.update.sql 655 * 656 * @param object rcube_db Database connection 657 * @param string Version to update from 658 * @return boolen True on success, False on error 659 */ 660 function update_db($DB, $version) 661 { 662 $version = strtolower($version); 663 $engine = isset($this->db_map[$DB->db_provider]) ? $this->db_map[$DB->db_provider] : $DB->db_provider; 664 665 // read schema file from /SQL/* 666 $fname = INSTALL_PATH . "SQL/$engine.update.sql"; 667 if ($lines = @file($fname, FILE_SKIP_EMPTY_LINES)) { 668 $from = false; $sql = ''; 669 foreach ($lines as $line) { 670 $is_comment = preg_match('/^--/', $line); 671 if (!$from && $is_comment && preg_match('/from version\s([0-9.]+[a-z-]*)/', $line, $m)) { 672 $v = strtolower($m[1]); 673 if ($v == $version || version_compare($version, $v, '<=')) 674 $from = true; 675 } 676 if ($from && !$is_comment) 677 $sql .= $line. "\n"; 678 } 679 680 if ($sql) 681 $this->exec_sql($sql, $DB); 682 } 683 else { 684 $this->fail('DB Schema', "Cannot read the update file: $fname"); 685 return false; 686 } 687 688 if ($err = $this->get_error()) { 689 $this->fail('DB Schema', "Error updating database: $err"); 690 return false; 691 } 692 693 return true; 694 } 695 696 697 /** 698 * Execute the given SQL queries on the database connection 699 * 700 * @param string SQL queries to execute 701 * @param object rcube_db Database connection 702 * @return boolen True on success, False on error 703 */ 704 function exec_sql($sql, $DB) 705 { 706 $buff = ''; 707 foreach (explode("\n", $sql) as $line) { 708 if (preg_match('/^--/', $line) || trim($line) == '') 709 continue; 710 711 $buff .= $line . "\n"; 712 if (preg_match('/(;|^GO)$/', trim($line))) { 713 $DB->query($buff); 714 $buff = ''; 715 if ($DB->is_error()) 716 break; 717 } 718 } 719 720 return !$DB->is_error(); 721 } 722 723 628 724 /** 629 725 * Handler for Roundcube errors -
trunk/roundcubemail/installer/styles.css
r1933 r4573 1 2 1 body { 3 margin: 1em 2em 2em 2em; 4 background-color: #fff; 5 } 6 7 body, td, th, div, p { 8 font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; 9 font-size: small; 10 color: #000; 2 background: white; 3 font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; 4 font-size: small; 5 color: black; 6 margin: 0; 11 7 } 12 8 13 9 #banner { 14 position: relative; 15 } 16 17 #header { 18 position: relative; 19 height: 56px; 20 background: url('images/banner_bg.gif') top left repeat-x #fff; 21 } 22 23 #header div.banner-logo { 24 position: absolute; 25 top: 0px; 26 left: 0px; 27 width: 200px; 28 height: 56px; 29 } 30 31 #header div.banner-right { 32 position: absolute; 33 right: 0px; 34 top: 0px; 35 width: 10px; 36 height: 56px; 10 position: relative; 11 height: 58px; 12 margin: 0 0 1em 0; 13 padding: 10px 20px; 14 background: url('images/banner_gradient.gif') top left repeat-x #d8edfd; 15 overflow: hidden; 16 } 17 18 #banner .banner-bg { 19 position: absolute; 20 top: 0; 21 right: 0; 22 width: 630px; 23 height: 78px; 24 background: url('images/banner_schraffur.gif') top right no-repeat; 25 z-index: 0; 26 } 27 28 #banner .banner-logo { 29 position: absolute; 30 top: 10px; 31 left: 20px; 32 z-index: 4; 33 } 34 35 #banner .banner-logo a { 36 border: 0; 37 37 } 38 38 39 39 #topnav { 40 position: absolute; 41 right: 20px; 42 bottom: 8px; 43 text-align: right; 44 color: #ebebeb; 45 font-size: smaller; 40 position: absolute; 41 top: 3.6em; 42 right: 20px; 46 43 } 47 44 48 45 #topnav a { 49 color: #ebebeb; 50 font-size: 11px; 51 text-decoration: none; 52 } 53 54 #topnav a:hover { 55 text-decoration: underline; 46 color: #666; 56 47 } 57 48 58 49 #content { 59 margin: 8px20px;50 margin: 2em 20px; 60 51 } 61 52 -
trunk/roundcubemail/installer/test.php
r4009 r4573 157 157 } 158 158 159 else if ($db_working && $_POST['updatedb']) { 160 if (!($success = $RCI->update_db($DB, $_POST['version']))) { 161 $updatefile = INSTALL_PATH . 'SQL/' . (isset($RCI->db_map[$DB->db_provider]) ? $RCI->db_map[$DB->db_provider] : $DB->db_provider) . '.update.sql'; 162 echo '<p class="warning">Please manually execute the SQL statements from '.$updatefile.' on your database.<br/>'; 163 echo 'See comments in the file and execute queries below the comment with the currently installed version number.</p>'; 164 } 165 } 166 159 167 // test database 160 168 if ($db_working) { … … 165 173 $db_working = false; 166 174 } 167 else if ($ RCI->db_schema_check($DB, $update = !empty($_POST['updatedb']))) {175 else if ($err = $RCI->db_schema_check($DB, $update = !empty($_POST['updatedb']))) { 168 176 $RCI->fail('DB Schema', "Database schema differs"); 169 $db_map = array('pgsql' => 'postgres', 'mysqli' => 'mysql', 'sqlsrv' => 'mssql'); 170 $updatefile = INSTALL_PATH . 'SQL/' . (isset($db_map[$DB->db_provider]) ? $db_map[$DB->db_provider] : $DB->db_provider) . '.update.sql'; 171 echo '<p class="warning">Please manually execute the SQL statements from '.$updatefile.' on your database.<br/>'; 172 echo 'See comments in the file and execute queries that are superscribed with the currently installed version number.</p>'; 177 echo '<ul style="margin:0"><li>' . join("</li>\n<li>", $err) . "</li></ul>"; 178 $select = $RCI->versions_select(array('name' => 'version')); 179 echo '<p class="suggestion">You should run the update queries to get the schmea fixed.<br/><br/>Version to update from: ' . $select->show() . ' <input type="submit" name="updatedb" value="Update" /></p>'; 180 // echo '<p class="warning">Please manually execute the SQL statements from '.$updatefile.' on your database.<br/>'; 181 // echo 'See comments in the file and execute queries that are superscribed with the currently installed version number.</p>'; 173 182 $db_working = false; 174 183 } … … 413 422 After completing the installation and the final tests please <b>remove</b> the whole 414 423 installer folder from the document root of the webserver or make sure that 415 enable_installer option inmain.inc.php is disabled.<br />424 <tt>enable_installer</tt> option in config/main.inc.php is disabled.<br /> 416 425 <br /> 417 426 -
trunk/roundcubemail/program/include/rcube_mdb2.php
r4410 r4573 414 414 415 415 /** 416 * Wrapper for SHOW COLUMNS command 417 * 418 * @param string Table name 419 * @return array List of table cols 420 */ 421 function list_cols($table) 422 { 423 $this->db_handle->loadModule('Manager'); 424 if (!PEAR::isError($result = $this->db_handle->listTableFields($table))) { 425 return $result; 426 } 427 428 return null; 429 } 430 431 432 /** 416 433 * Formats input so it can be safely used in a query 417 434 * -
trunk/roundcubemail/program/lib/MDB2/Driver/Reverse/sqlite.php
r3354 r4573 96 96 'unexpected empty table column definition list', __FUNCTION__); 97 97 } 98 $regexp = '/^\s*([^\s]+) +(CHAR|VARCHAR|VARCHAR2|TEXT|BOOLEAN|SMALLINT|INT|INTEGER|DECIMAL| BIGINT|DOUBLE|FLOAT|DATETIME|DATE|TIME|LONGTEXT|LONGBLOB)( ?\(([1-9][0-9]*)(:([1-9][0-9]*))?\))?( NULL| NOT NULL)?( UNSIGNED)?( NULL| NOT NULL)?( PRIMARY KEY)?( DEFAULT (\'[^\']*\'|[^ ]+))?( NULL| NOT NULL)?( PRIMARY KEY)?(\s*\-\-.*)?$/i';98 $regexp = '/^\s*([^\s]+) +(CHAR|VARCHAR|VARCHAR2|TEXT|BOOLEAN|SMALLINT|INT|INTEGER|DECIMAL|TINYINT|BIGINT|DOUBLE|FLOAT|DATETIME|DATE|TIME|LONGTEXT|LONGBLOB)( ?\(([1-9][0-9]*)(:([1-9][0-9]*))?\))?( NULL| NOT NULL)?( UNSIGNED)?( NULL| NOT NULL)?( PRIMARY KEY)?( DEFAULT (\'[^\']*\'|[^ ]+))?( NULL| NOT NULL)?( PRIMARY KEY)?(\s*\-\-.*)?$/i'; 99 99 $regexp2 = '/^\s*([^ ]+) +(PRIMARY|UNIQUE|CHECK)$/i'; 100 100 for ($i=0, $j=0; $i<$count; ++$i) {
Note: See TracChangeset
for help on using the changeset viewer.
