Changeset 4573 in subversion


Ignore:
Timestamp:
Feb 25, 2011 11:37:22 AM (2 years ago)
Author:
thomasb
Message:

Create interactive update script with improved DB schema check; udated installer with new features and styles

Location:
trunk/roundcubemail
Files:
4 added
3 deleted
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/CHANGELOG

    r4569 r4573  
    22=========================== 
    33 
     4- Interactive update script with improved DB schema check 
    45- jQuery 1.5.1 
    56- Fix problem with contactgroupmembers table creation on MySQL 4.x, add index on contact_id column 
  • trunk/roundcubemail/SQL/mssql.upgrade.sql

    r4567 r4573  
    9898GO 
    9999 
    100 -- Updates from version 0.5.x 
     100-- Updates from version 0.5.1 
    101101 
    102102ALTER TABLE [dbo].[contacts] ADD [words] [text] COLLATE Latin1_General_CI_AI NULL  
  • trunk/roundcubemail/SQL/mysql.update.sql

    r4567 r4573  
    134134TRUNCATE TABLE `messages`; 
    135135 
    136 -- Updates from version 0.5.* 
     136-- Updates from version 0.5.1 
    137137 
    138138ALTER TABLE `contacts` ADD `words` TEXT NULL AFTER `vcard`; 
  • trunk/roundcubemail/SQL/postgres.update.sql

    r4567 r4573  
    9191TRUNCATE messages; 
    9292 
    93 -- Updates from version 0.5.x 
     93-- Updates from version 0.5.1 
    9494 
    9595ALTER TABLE contacts ADD words TEXT NULL; 
  • trunk/roundcubemail/SQL/sqlite.update.sql

    r4567 r4573  
    184184 
    185185 
    186 -- Updates from version 0.5.x 
     186-- Updates from version 0.5.1 
    187187 
    188188CREATE TABLE contacts_tmp ( 
  • trunk/roundcubemail/UPGRADING

    r3490 r4573  
    55of Roundcube Webmail. We recommend to carefully backup the existing 
    66installation as well as the database before executig the following steps. 
     7 
     8Using the update script 
     9----------------------- 
     10There is a shell script (for unix based systems) that does the job for you. 
     11To use it, unpack the archive of the new Roundcube version to a temporary location (don't replace the Roundcube installation you want to update) 
     12and cd into that directory. From there, run the following command in a shell: 
     13 
     14  ./bin/installto.sh <TARGET-FOLDER> 
     15 
     16For <TARGET-FOLDER> you specify the path to the Roundcube installation  
     17which should be updated. The update script will then copy all new files to the  
     18target location and check and update the configuration and database schema. 
     19After all is done, the temporary folder with the new Roundcube files can be  
     20removed again. 
     21 
     22 
     23Updating manually 
     24----------------- 
     25If you don't have shell access to the Roundcube instalaltion or if not running  
     26it on a unix system, you need to do the following operations by hand: 
    727 
    8281. Replace index.php and all files in 
     
    15352. Run ./bin/update.sh from the commandline OR 
    1636   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 true 
    18    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. 
    19393. 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. 
     414. Make sure 'enable_installer' is set to false again. 
     425. Check .htaccess settings (some php settings could become required) 
    2643 
    2744 
  • trunk/roundcubemail/bin/update.sh

    r4338 r4573  
    11#!/usr/bin/env php 
    22<?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 
    322if (php_sapi_name() != 'cli') { 
    423    die('Not on the "shell" (php-cli).'); 
     
    625define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' ); 
    726 
    8 require_once INSTALL_PATH . 'program/include/iniset.php'; 
     27require_once INSTALL_PATH . 'program/include/clisetup.php'; 
    928require_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 
     34if (!$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 
     40if ($opts['version'] && version_compare($opts['version'], RCMAIL_VERSION, '>')) 
     41  die("Nothing to be done here. Bye!\n"); 
     42 
    1043 
    1144$RCI = rcube_install::get_instance(); 
     
    89122      } 
    90123      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"; 
    92125      } 
    93126    } 
     
    114147      $success = false; 
    115148    } 
    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'; 
    119151      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"; 
    121153      $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"; 
    122165    } 
    123166  } 
  • trunk/roundcubemail/installer/check.php

    r4416 r4573  
    2323    'MDB2'      => 'MDB2.php', 
    2424    'Net_SMTP'  => 'Net/SMTP.php', 
     25    'Net_IDNA2' => 'Net/IDNA2.php', 
    2526    'Mail_mime' => 'Mail/mime.php', 
    2627); 
  • trunk/roundcubemail/installer/index.php

    r3989 r4573  
    6969 
    7070<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> 
    7978 
    8079<div id="content"> 
     
    121120 
    122121<div id="footer"> 
    123   Installer by the Roundcube Dev Team. Copyright &copy; 2008 - Published under the GNU Public License;&nbsp; 
     122  Installer by the Roundcube Dev Team. Copyright &copy; 2008-2011 - Published under the GNU Public License;&nbsp; 
    124123  Icons by <a href="http://famfamfam.com">famfamfam</a> 
    125124</div> 
  • trunk/roundcubemail/installer/rcube_install.php

    r4410 r4573  
    3030  var $configured = false; 
    3131  var $last_error = null; 
     32  var $db_map = array('pgsql' => 'postgres', 'mysqli' => 'mysql', 'sqlsrv' => 'mssql'); 
    3233  var $email_pattern = '([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9])'; 
    3334  var $bool_config_props = array(); 
    3435 
    35   var $obsolete_config = array('db_backend'); 
     36  var $obsolete_config = array('db_backend', 'double_auth'); 
    3637  var $replaced_config = array( 
    3738    'skin_path' => 'skin', 
     
    4344   
    4445  // 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  ); 
    4650   
    4751  /** 
     
    295299    $this->load_defaults(); 
    296300     
    297     foreach ($this->replaced_config as $prop => $replacement) 
     301    foreach ($this->replaced_config as $prop => $replacement) { 
    298302      if (isset($current[$prop])) { 
    299303        if ($prop == 'skin_path') 
     
    303307        else 
    304308          $this->config[$replacement] = $current[$prop]; 
    305          
    306         unset($current[$prop]); 
     309      } 
     310      unset($current[$prop]); 
    307311    } 
    308312     
     
    321325    } 
    322326     
     327    if ($current['keep_alive'] && $current['session_lifetime'] < $current['keep_alive']) 
     328      $current['session_lifetime'] = max(10, ceil($current['keep_alive'] / 60) * 2); 
     329     
    323330    $this->config  = array_merge($this->config, $current); 
    324331     
     
    340347      return false; 
    341348     
    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'); 
    354351    $errors = array(); 
    355352     
     
    359356    foreach ($db_schema as $table => $cols) { 
    360357      $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      } 
    364367    } 
    365368     
    366369    return !empty($errors) ? $errors : false; 
    367370  } 
     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   
    368395   
    369396  /** 
     
    475502  } 
    476503   
     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   
    477514   
    478515  /** 
     
    593630  function init_db($DB) 
    594631  { 
    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; 
    597633     
    598634    // 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); 
    614638    } 
    615639    else { 
     
    626650  } 
    627651   
     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   
    628724  /** 
    629725   * Handler for Roundcube errors 
  • trunk/roundcubemail/installer/styles.css

    r1933 r4573  
    1  
    21body { 
    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; 
    117} 
    128 
    139#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; 
    3737} 
    3838 
    3939#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; 
    4643} 
    4744 
    4845#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; 
    5647} 
    5748 
    5849#content { 
    59   margin: 8px 20px; 
     50        margin: 2em 20px; 
    6051} 
    6152 
  • trunk/roundcubemail/installer/test.php

    r4009 r4573  
    157157} 
    158158 
     159else 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 
    159167// test database 
    160168if ($db_working) { 
     
    165173        $db_working = false; 
    166174    } 
    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']))) { 
    168176        $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() . '&nbsp;<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>'; 
    173182        $db_working = false; 
    174183    } 
     
    413422After completing the installation and the final tests please <b>remove</b> the whole 
    414423installer folder from the document root of the webserver or make sure that 
    415 enable_installer option in main.inc.php is disabled.<br /> 
     424<tt>enable_installer</tt> option in config/main.inc.php is disabled.<br /> 
    416425<br /> 
    417426 
  • trunk/roundcubemail/program/include/rcube_mdb2.php

    r4410 r4573  
    414414 
    415415    /** 
     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    /** 
    416433     * Formats input so it can be safely used in a query 
    417434     * 
  • trunk/roundcubemail/program/lib/MDB2/Driver/Reverse/sqlite.php

    r3354 r4573  
    9696                'unexpected empty table column definition list', __FUNCTION__); 
    9797        } 
    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'; 
    9999        $regexp2 = '/^\s*([^ ]+) +(PRIMARY|UNIQUE|CHECK)$/i'; 
    100100        for ($i=0, $j=0; $i<$count; ++$i) { 
Note: See TracChangeset for help on using the changeset viewer.