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

release-0.6
thomascube 13 years ago
parent b8f14ce744
commit e6bb836e05

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Interactive update script with improved DB schema check
- jQuery 1.5.1
- Fix problem with contactgroupmembers table creation on MySQL 4.x, add index on contact_id column
- Add LDAP SASL bind and proxy authentication (#1486692)

@ -97,7 +97,7 @@ GO
ALTER TABLE [dbo].[contacts] ALTER COLUMN [email] [varchar] (255) COLLATE Latin1_General_CI_AI NOT NULL
GO
-- Updates from version 0.5.x
-- Updates from version 0.5.1
ALTER TABLE [dbo].[contacts] ADD [words] [text] COLLATE Latin1_General_CI_AI NULL
GO

@ -133,7 +133,7 @@ ALTER TABLE `contacts` MODIFY `email` varchar(255) NOT NULL;
TRUNCATE TABLE `messages`;
-- Updates from version 0.5.*
-- Updates from version 0.5.1
ALTER TABLE `contacts` ADD `words` TEXT NULL AFTER `vcard`;
ALTER TABLE `contactgroupmembers` ADD INDEX `contactgroupmembers_contact_index` (`contact_id`);

@ -90,7 +90,7 @@ ALTER TABLE contacts ALTER email TYPE varchar(255);
TRUNCATE messages;
-- Updates from version 0.5.x
-- Updates from version 0.5.1
ALTER TABLE contacts ADD words TEXT NULL;
CREATE INDEX contactgroupmembers_contact_id_idx ON contactgroupmembers (contact_id);

@ -183,7 +183,7 @@ DROP TABLE contacts_tmp;
DELETE FROM messages;
-- Updates from version 0.5.x
-- Updates from version 0.5.1
CREATE TABLE contacts_tmp (
contact_id integer NOT NULL PRIMARY KEY,

@ -5,6 +5,26 @@ Follow these instructions if upgrading from a previous version
of Roundcube Webmail. We recommend to carefully backup the existing
installation as well as the database before executig the following steps.
Using the update script
-----------------------
There is a shell script (for unix based systems) that does the job for you.
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)
and cd into that directory. From there, run the following command in a shell:
./bin/installto.sh <TARGET-FOLDER>
For <TARGET-FOLDER> you specify the path to the Roundcube installation
which should be updated. The update script will then copy all new files to the
target location and check and update the configuration and database schema.
After all is done, the temporary folder with the new Roundcube files can be
removed again.
Updating manually
-----------------
If you don't have shell access to the Roundcube instalaltion or if not running
it on a unix system, you need to do the following operations by hand:
1. Replace index.php and all files in
- ./bin/
- ./SQL/
@ -14,14 +34,11 @@ installation as well as the database before executig the following steps.
- ./plugins/
2. Run ./bin/update.sh from the commandline OR
open http://url-to-roundcube/installer/ in a browser and choose "3 Test config".
To enable the latter one, you have to temporary set 'enable_installer' to true
in your local config/main.inc.php file.
To enable the latter one, you have to temporary set 'enable_installer'
to true in your local config/main.inc.php file.
3. Let the update script/installer check your configuration and
update your config files as suggested by the updater.
4. If suggested by the update script, run all commands in
./SQL/[yourdbtype].update.sql that are superscribed with the
currently installed version number.
5. Make sure 'enable_installer' is set to false again.
6. Check .htaccess settings (some php settings could become required)
update your config files and database schema as suggested by the updater.
4. Make sure 'enable_installer' is set to false again.
5. Check .htaccess settings (some php settings could become required)

@ -0,0 +1,73 @@
#!/usr/bin/env php
<?php
/*
+-----------------------------------------------------------------------+
| bin/installto.sh |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2011, The Roundcube Dev Team |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
| Update an existing Roundcube installation with files from |
| this version |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
$Id$
*/
if (php_sapi_name() != 'cli') {
die('Not on the "shell" (php-cli).');
}
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
require_once INSTALL_PATH . 'program/include/iniset.php';
$target_dir = unslashify($_SERVER['argv'][1]);
if (empty($target_dir) || !is_dir(realpath($target_dir)))
die("Invalid target: not a directory\nUsage: installto.sh <TARGET>\n");
// read version from iniset.php
$iniset = @file_get_contents($target_dir . '/program/include/iniset.php');
if (!preg_match('/define\(.RCMAIL_VERSION.,\s*.([0-9.]+[a-z-]*)/', $iniset, $m))
die("No valid Roundcube installation found at $target_dir\n");
$oldversion = $m[1];
if (version_compare($oldversion, RCMAIL_VERSION, '>='))
die("Installation at target location is up-to-date!\n");
echo "Upgrading from $oldversion. Do you want to continue? (y/N)\n";
$input = trim(fgets(STDIN));
if (strtolower($input) == 'y') {
$err = false;
echo "Copying files to target location...";
foreach (array('program','installer','bin','SQL','plugins','skins/default') as $dir) {
if (!system("rsync -avuC " . INSTALL_PATH . "$dir/* $target_dir/$dir/")) {
$err = true;
break;
}
}
foreach (array('index.php','.htaccess','config/main.inc.php.dist','config/db.inc.php.dist','CHANGELOG','README','UPGRADING') as $file) {
if (!system("rsync -avu " . INSTALL_PATH . "$file $target_dir/$file")) {
$err = true;
break;
}
}
echo "done.\n\n";
if (!$err) {
echo "Running update script at target...\n";
system("cd $target_dir && bin/update.sh --version=$oldversion");
echo "All done.\n";
}
}
else
echo "Update cancelled. See ya!\n";
?>

@ -1,13 +1,46 @@
#!/usr/bin/env php
<?php
/*
+-----------------------------------------------------------------------+
| bin/update.sh |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2010-2011, The Roundcube Dev Team |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
| Check local configuration and database schema after upgrading |
| to a new version |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
$Id$
*/
if (php_sapi_name() != 'cli') {
die('Not on the "shell" (php-cli).');
}
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
require_once INSTALL_PATH . 'program/include/iniset.php';
require_once INSTALL_PATH . 'program/include/clisetup.php';
require_once INSTALL_PATH . 'installer/rcube_install.php';
// get arguments
$opts = get_opt(array('v' => 'version'));
// ask user if no version is specified
if (!$opts['version']) {
echo "What version are you upgrading from? Type '?' if you don't know.\n";
if (($input = trim(fgets(STDIN))) && preg_match('/^[0-9.]+[a-z-]*$/', $input))
$opts['version'] = $input;
}
if ($opts['version'] && version_compare($opts['version'], RCMAIL_VERSION, '>'))
die("Nothing to be done here. Bye!\n");
$RCI = rcube_install::get_instance();
$RCI->load_config();
@ -88,7 +121,7 @@ if ($RCI->configured) {
}
}
else {
echo "Please update your config files manually according to the above messages.\n";
echo "Please update your config files manually according to the above messages.\n\n";
}
}
@ -113,12 +146,22 @@ if ($RCI->configured) {
echo "Error connecting to database: $db_error_msg\n";
$success = false;
}
else if ($RCI->db_schema_check($DB, false)) {
$db_map = array('pgsql' => 'postgres', 'mysqli' => 'mysql', 'sqlsrv' => 'mssql');
$updatefile = INSTALL_PATH . 'SQL/' . (isset($db_map[$DB->db_provider]) ? $db_map[$DB->db_provider] : $DB->db_provider) . '.update.sql';
else if ($err = $RCI->db_schema_check($DB, false)) {
$updatefile = INSTALL_PATH . 'SQL/' . (isset($RCI->db_map[$DB->db_provider]) ? $RCI->db_map[$DB->db_provider] : $DB->db_provider) . '.update.sql';
echo "WARNING: Database schema needs to be updated!\n";
echo "Open $updatefile and execute all queries that are superscribed with the currently installed version number\n";
echo join("\n", $err) . "\n\n";
$success = false;
if ($opts['version']) {
echo "Do you want to run the update queries to get the schmea fixed? (y/N)\n";
$input = trim(fgets(STDIN));
if (strtolower($input) == 'y') {
$success = $RCI->update_db($DB, $opts['version']);
}
}
if (!$success)
echo "Open $updatefile and execute all queries below the comment with the currently installed version number.\n";
}
}

@ -22,6 +22,7 @@ $required_libs = array(
'PEAR' => 'PEAR.php',
'MDB2' => 'MDB2.php',
'Net_SMTP' => 'Net/SMTP.php',
'Net_IDNA2' => 'Net/IDNA2.php',
'Mail_mime' => 'Mail/mime.php',
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 587 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

@ -68,14 +68,13 @@ if ($RCI->configured && empty($_REQUEST['_step'])) {
<body>
<div id="banner">
<div id="header">
<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>
<div class="banner-right"><img src="images/banner_right.gif" width="10" height="56" alt="" /></div>
</div>
<div id="topnav">
<a href="http://trac.roundcube.net/wiki/Howto_Install">How-to Wiki</a>
</div>
</div>
<div class="banner-bg"></div>
<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>
</div>
<div id="topnav">
<a href="http://trac.roundcube.net/wiki/Howto_Install">How-to Wiki</a>
</div>
<div id="content">
@ -120,7 +119,7 @@ else {
</div>
<div id="footer">
Installer by the Roundcube Dev Team. Copyright &copy; 2008 - Published under the GNU Public License;&nbsp;
Installer by the Roundcube Dev Team. Copyright &copy; 2008-2011 - Published under the GNU Public License;&nbsp;
Icons by <a href="http://famfamfam.com">famfamfam</a>
</div>
</body>

@ -29,10 +29,11 @@ class rcube_install
var $config = array();
var $configured = false;
var $last_error = null;
var $db_map = array('pgsql' => 'postgres', 'mysqli' => 'mysql', 'sqlsrv' => 'mssql');
var $email_pattern = '([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9])';
var $bool_config_props = array();
var $obsolete_config = array('db_backend');
var $obsolete_config = array('db_backend', 'double_auth');
var $replaced_config = array(
'skin_path' => 'skin',
'locale_string' => 'language',
@ -42,7 +43,10 @@ class rcube_install
);
// these config options are required for a working system
var $required_config = array('db_dsnw', 'db_table_contactgroups', 'db_table_contactgroupmembers', 'des_key');
var $required_config = array(
'db_dsnw', 'db_table_contactgroups', 'db_table_contactgroupmembers',
'des_key', 'session_lifetime',
);
/**
* Constructor
@ -294,7 +298,7 @@ class rcube_install
$this->config = array();
$this->load_defaults();
foreach ($this->replaced_config as $prop => $replacement)
foreach ($this->replaced_config as $prop => $replacement) {
if (isset($current[$prop])) {
if ($prop == 'skin_path')
$this->config[$replacement] = preg_replace('#skins/(\w+)/?$#', '\\1', $current[$prop]);
@ -302,8 +306,8 @@ class rcube_install
$this->config[$replacement] = $current[$prop] ? 2 : 0;
else
$this->config[$replacement] = $current[$prop];
unset($current[$prop]);
}
unset($current[$prop]);
}
foreach ($this->obsolete_config as $prop) {
@ -320,6 +324,9 @@ class rcube_install
}
}
if ($current['keep_alive'] && $current['session_lifetime'] < $current['keep_alive'])
$current['session_lifetime'] = max(10, ceil($current['keep_alive'] / 60) * 2);
$this->config = array_merge($this->config, $current);
foreach ((array)$current['ldap_public'] as $key => $values) {
@ -339,18 +346,8 @@ class rcube_install
if (!$this->configured)
return false;
// simple ad hand-made db schema
$db_schema = array(
'users' => array(),
'identities' => array(),
'contacts' => array(),
'contactgroups' => array(),
'contactgroupmembers' => array(),
'cache' => array(),
'messages' => array(),
'session' => array(),
);
// read reference schema from mysql.initial.sql
$db_schema = $this->db_read_schema(INSTALL_PATH . 'SQL/mysql.initial.sql');
$errors = array();
// check list of tables
@ -358,13 +355,43 @@ class rcube_install
foreach ($db_schema as $table => $cols) {
$table = !empty($this->config['db_table_'.$table]) ? $this->config['db_table_'.$table] : $table;
if (!in_array($table, $existing_tables))
$errors[] = "Missing table ".$table;
// TODO: check cols and indices
if (!in_array($table, $existing_tables)) {
$errors[] = "Missing table '".$table."'";
}
else { // compare cols
$db_cols = $DB->list_cols($table);
$diff = array_diff(array_keys($cols), $db_cols);
if (!empty($diff))
$errors[] = "Missing columns in table '$table': " . join(',', $diff);
}
}
return !empty($errors) ? $errors : false;
}
/**
* Utility function to read database schema from an .sql file
*/
private function db_read_schema($schemafile)
{
$lines = file($schemafile);
$table_block = false;
$schema = array();
foreach ($lines as $line) {
if (preg_match('/^\s*create table `?([a-z0-9_]+)`?/i', $line, $m)) {
$table_block = $m[1];
}
else if ($table_block && preg_match('/^\s*`?([a-z0-9_-]+)`?\s+([a-z]+)/', $line, $m)) {
$col = $m[1];
if (!in_array(strtoupper($col), array('PRIMARY','KEY','INDEX','UNIQUE','CONSTRAINT','REFERENCES','FOREIGN'))) {
$schema[$table_block][$col] = $m[2];
}
}
}
return $schema;
}
/**
* Compare the local database schema with the reference schema
@ -474,6 +501,16 @@ class rcube_install
return $out;
}
/**
* Create a HTML dropdown to select a previous version of Roundcube
*/
function versions_select($attrib = array())
{
$select = new html_select($attrib);
$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'));
return $select;
}
/**
* Display OK status
@ -592,39 +629,98 @@ class rcube_install
*/
function init_db($DB)
{
$db_map = array('pgsql' => 'postgres', 'mysqli' => 'mysql');
$engine = isset($db_map[$DB->db_provider]) ? $db_map[$DB->db_provider] : $DB->db_provider;
$engine = isset($this->db_map[$DB->db_provider]) ? $this->db_map[$DB->db_provider] : $DB->db_provider;
// read schema file from /SQL/*
$fname = "../SQL/$engine.initial.sql";
$fname = INSTALL_PATH . "SQL/$engine.initial.sql";
if ($sql = @file_get_contents($fname)) {
$this->exec_sql($sql, $DB);
}
else {
$this->fail('DB Schema', "Cannot read the schema file: $fname");
return false;
}
if ($err = $this->get_error()) {
$this->fail('DB Schema', "Error creating database schema: $err");
return false;
}
return true;
}
/**
* Update database with SQL statements from SQL/*.update.sql
*
* @param object rcube_db Database connection
* @param string Version to update from
* @return boolen True on success, False on error
*/
function update_db($DB, $version)
{
$version = strtolower($version);
$engine = isset($this->db_map[$DB->db_provider]) ? $this->db_map[$DB->db_provider] : $DB->db_provider;
// read schema file from /SQL/*
$fname = INSTALL_PATH . "SQL/$engine.update.sql";
if ($lines = @file($fname, FILE_SKIP_EMPTY_LINES)) {
$buff = '';
foreach ($lines as $i => $line) {
if (preg_match('/^--/', $line))
continue;
$buff .= $line . "\n";
if (preg_match('/;$/', trim($line))) {
$DB->query($buff);
$buff = '';
if ($this->get_error())
break;
$from = false; $sql = '';
foreach ($lines as $line) {
$is_comment = preg_match('/^--/', $line);
if (!$from && $is_comment && preg_match('/from version\s([0-9.]+[a-z-]*)/', $line, $m)) {
$v = strtolower($m[1]);
if ($v == $version || version_compare($version, $v, '<='))
$from = true;
}
if ($from && !$is_comment)
$sql .= $line. "\n";
}
if ($sql)
$this->exec_sql($sql, $DB);
}
else {
$this->fail('DB Schema', "Cannot read the schema file: $fname");
$this->fail('DB Schema', "Cannot read the update file: $fname");
return false;
}
if ($err = $this->get_error()) {
$this->fail('DB Schema', "Error creating database schema: $err");
$this->fail('DB Schema', "Error updating database: $err");
return false;
}
return true;
}
/**
* Execute the given SQL queries on the database connection
*
* @param string SQL queries to execute
* @param object rcube_db Database connection
* @return boolen True on success, False on error
*/
function exec_sql($sql, $DB)
{
$buff = '';
foreach (explode("\n", $sql) as $line) {
if (preg_match('/^--/', $line) || trim($line) == '')
continue;
$buff .= $line . "\n";
if (preg_match('/(;|^GO)$/', trim($line))) {
$DB->query($buff);
$buff = '';
if ($DB->is_error())
break;
}
}
return !$DB->is_error();
}
/**
* Handler for Roundcube errors
*/

@ -1,62 +1,53 @@
body {
margin: 1em 2em 2em 2em;
background-color: #fff;
}
body, td, th, div, p {
font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
font-size: small;
color: #000;
background: white;
font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
font-size: small;
color: black;
margin: 0;
}
#banner {
position: relative;
position: relative;
height: 58px;
margin: 0 0 1em 0;
padding: 10px 20px;
background: url('images/banner_gradient.gif') top left repeat-x #d8edfd;
overflow: hidden;
}
#header {
position: relative;
height: 56px;
background: url('images/banner_bg.gif') top left repeat-x #fff;
#banner .banner-bg {
position: absolute;
top: 0;
right: 0;
width: 630px;
height: 78px;
background: url('images/banner_schraffur.gif') top right no-repeat;
z-index: 0;
}
#header div.banner-logo {
position: absolute;
top: 0px;
left: 0px;
width: 200px;
height: 56px;
#banner .banner-logo {
position: absolute;
top: 10px;
left: 20px;
z-index: 4;
}
#header div.banner-right {
position: absolute;
right: 0px;
top: 0px;
width: 10px;
height: 56px;
#banner .banner-logo a {
border: 0;
}
#topnav {
position: absolute;
right: 20px;
bottom: 8px;
text-align: right;
color: #ebebeb;
font-size: smaller;
position: absolute;
top: 3.6em;
right: 20px;
}
#topnav a {
color: #ebebeb;
font-size: 11px;
text-decoration: none;
}
#topnav a:hover {
text-decoration: underline;
color: #666;
}
#content {
margin: 8px 20px;
margin: 2em 20px;
}
#footer {

@ -156,6 +156,14 @@ if ($db_working && $_POST['initdb']) {
}
}
else if ($db_working && $_POST['updatedb']) {
if (!($success = $RCI->update_db($DB, $_POST['version']))) {
$updatefile = INSTALL_PATH . 'SQL/' . (isset($RCI->db_map[$DB->db_provider]) ? $RCI->db_map[$DB->db_provider] : $DB->db_provider) . '.update.sql';
echo '<p class="warning">Please manually execute the SQL statements from '.$updatefile.' on your database.<br/>';
echo 'See comments in the file and execute queries below the comment with the currently installed version number.</p>';
}
}
// test database
if ($db_working) {
$db_read = $DB->query("SELECT count(*) FROM {$RCI->config['db_table_users']}");
@ -164,12 +172,13 @@ if ($db_working) {
echo '<p><input type="submit" name="initdb" value="Initialize database" /></p>';
$db_working = false;
}
else if ($RCI->db_schema_check($DB, $update = !empty($_POST['updatedb']))) {
else if ($err = $RCI->db_schema_check($DB, $update = !empty($_POST['updatedb']))) {
$RCI->fail('DB Schema', "Database schema differs");
$db_map = array('pgsql' => 'postgres', 'mysqli' => 'mysql', 'sqlsrv' => 'mssql');
$updatefile = INSTALL_PATH . 'SQL/' . (isset($db_map[$DB->db_provider]) ? $db_map[$DB->db_provider] : $DB->db_provider) . '.update.sql';
echo '<p class="warning">Please manually execute the SQL statements from '.$updatefile.' on your database.<br/>';
echo 'See comments in the file and execute queries that are superscribed with the currently installed version number.</p>';
echo '<ul style="margin:0"><li>' . join("</li>\n<li>", $err) . "</li></ul>";
$select = $RCI->versions_select(array('name' => 'version'));
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>';
// echo '<p class="warning">Please manually execute the SQL statements from '.$updatefile.' on your database.<br/>';
// echo 'See comments in the file and execute queries that are superscribed with the currently installed version number.</p>';
$db_working = false;
}
else {
@ -412,7 +421,7 @@ if (isset($_POST['imaptest']) && !empty($_POST['_host']) && !empty($_POST['_user
After completing the installation and the final tests please <b>remove</b> the whole
installer folder from the document root of the webserver or make sure that
enable_installer option in main.inc.php is disabled.<br />
<tt>enable_installer</tt> option in config/main.inc.php is disabled.<br />
<br />
These files may expose sensitive configuration data like server passwords and encryption keys

@ -412,6 +412,23 @@ class rcube_mdb2
}
/**
* Wrapper for SHOW COLUMNS command
*
* @param string Table name
* @return array List of table cols
*/
function list_cols($table)
{
$this->db_handle->loadModule('Manager');
if (!PEAR::isError($result = $this->db_handle->listTableFields($table))) {
return $result;
}
return null;
}
/**
* Formats input so it can be safely used in a query
*

@ -95,7 +95,7 @@ class MDB2_Driver_Reverse_sqlite extends MDB2_Driver_Reverse_Common
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
'unexpected empty table column definition list', __FUNCTION__);
}
$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';
$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';
$regexp2 = '/^\s*([^ ]+) +(PRIMARY|UNIQUE|CHECK)$/i';
for ($i=0, $j=0; $i<$count; ++$i) {
if (!preg_match($regexp, trim($column_sql[$i]), $matches)) {

Loading…
Cancel
Save