Index: install.php =================================================================== RCS file: /cvs/drupal/drupal/install.php,v retrieving revision 1.86 diff -u -p -r1.86 install.php --- install.php 6 Nov 2007 09:00:30 -0000 1.86 +++ install.php 8 Nov 2007 19:13:53 -0000 @@ -271,75 +271,85 @@ function install_settings_form(&$form_st } } - // Database name - $form['basic_options']['db_path'] = array( - '#type' => 'textfield', - '#title' => st('Database name'), - '#default_value' => $db_path, - '#size' => 45, - '#maxlength' => 45, - '#required' => TRUE, - '#description' => $db_path_description - ); - - // Database username - $form['basic_options']['db_user'] = array( - '#type' => 'textfield', - '#title' => st('Database username'), - '#default_value' => $db_user, - '#size' => 45, - '#maxlength' => 45, - '#required' => TRUE, - ); - - // Database username - $form['basic_options']['db_pass'] = array( - '#type' => 'password', - '#title' => st('Database password'), - '#default_value' => $db_pass, - '#size' => 45, - '#maxlength' => 45, - ); - - $form['advanced_options'] = array( - '#type' => 'fieldset', - '#title' => st('Advanced options'), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - '#description' => st("These options are only necessary for some sites. If you're not sure what you should enter here, leave the default settings or check with your hosting provider.") - ); - - // Database host - $form['advanced_options']['db_host'] = array( - '#type' => 'textfield', - '#title' => st('Database host'), - '#default_value' => $db_host, - '#size' => 45, - '#maxlength' => 45, - '#required' => TRUE, - '#description' => st('If your database is located on a different server, change this.'), - ); - - // Database port - $form['advanced_options']['db_port'] = array( - '#type' => 'textfield', - '#title' => st('Database port'), - '#default_value' => $db_port, - '#size' => 45, - '#maxlength' => 45, - '#description' => st('If your database server is listening to a non-standard port, enter its number.'), - ); - - // Table prefix + if (count($db_types) > 1 || $db_types[0] != 'sqlite') { + // Database name + $form['basic_options']['db_path'] = array( + '#type' => 'textfield', + '#title' => st('Database name'), + '#default_value' => $db_path, + '#size' => 45, + '#maxlength' => 45, + '#description' => $db_path_description, + '#prefix' => '
', + '#suffix' => '
', + ); + + // Database username + $form['basic_options']['db_user'] = array( + '#type' => 'textfield', + '#title' => st('Database username'), + '#default_value' => $db_user, + '#size' => 45, + '#maxlength' => 45, + '#prefix' => '
', + '#suffix' => '
', + ); + + // Database username + $form['basic_options']['db_pass'] = array( + '#type' => 'password', + '#title' => st('Database password'), + '#default_value' => $db_pass, + '#size' => 45, + '#maxlength' => 45, + '#prefix' => '
', + '#suffix' => '
', + ); + + $form['advanced_options'] = array( + '#type' => 'fieldset', + '#title' => st('Advanced options'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#prefix' => '
', + '#suffix' => '
', + '#description' => st("These options are only necessary for some sites. If you're not sure what you should enter here, leave the default settings or check with your hosting provider.") + ); + + // Database host + $form['advanced_options']['db_host'] = array( + '#type' => 'textfield', + '#title' => st('Database host'), + '#default_value' => $db_host, + '#size' => 45, + '#maxlength' => 45, + '#required' => TRUE, + '#description' => st('If your database is located on a different server, change this.'), + ); + + // Database port + $form['advanced_options']['db_port'] = array( + '#type' => 'textfield', + '#title' => st('Database port'), + '#default_value' => $db_port, + '#size' => 45, + '#maxlength' => 45, + '#description' => st('If your database server is listening to a non-standard port, enter its number.'), + ); + + // Table prefix $prefix = ($profile == 'default') ? 'drupal_' : $profile .'_'; - $form['advanced_options']['db_prefix'] = array( - '#type' => 'textfield', - '#title' => st('Table prefix'), - '#default_value' => $db_prefix, - '#size' => 45, - '#maxlength' => 45, + $form['advanced_options']['db_prefix'] = array( + '#type' => 'textfield', + '#title' => st('Table prefix'), + '#default_value' => $db_prefix, + '#size' => 45, + '#maxlength' => 45, '#description' => st('If more than one application will be sharing this database, enter a table prefix such as %prefix for your @drupal site here.', array('@drupal' => drupal_install_profile_name(), '%prefix' => $prefix)), - ); + ); + + drupal_add_js('misc/install.js'); + } $form['save'] = array( '#type' => 'submit', @@ -368,21 +378,45 @@ function install_settings_form_validate( */ function _install_settings_form_validate($db_prefix, $db_type, $db_user, $db_pass, $db_host, $db_port, $db_path, $settings_file, &$form_state, $form = NULL) { global $db_url; - - // Verify the table prefix - if (!empty($db_prefix) && is_string($db_prefix) && !preg_match('/^[A-Za-z0-9_.]+$/', $db_prefix)) { - form_set_error('db_prefix', st('The database table prefix you have entered, %db_prefix, is invalid. The table prefix can only contain alphanumeric characters, underscores or dots.', array('%db_prefix' => $db_prefix)), 'error'); - } - - if (!empty($db_port) && !is_numeric($db_port)) { - form_set_error('db_port', st('Database port must be a number.')); - } - // Check database type if (!isset($form)) { $_db_url = is_array($db_url) ? $db_url['default'] : $db_url; $db_type = substr($_db_url, 0, strpos($_db_url, '://')); } + + if ($db_type != 'sqlite') { + // Check for default username/password + if ($db_user == 'username' && $db_pass == 'password') { + form_set_error('db_user', st('You have configured @drupal to use the default username and password. This is not allowed for security reasons.', array('@drupal' => drupal_install_profile_name()))); + } + + // Verify the table prefix + if (!empty($db_prefix) && is_string($db_prefix) && !preg_match('/^[A-Za-z0-9_.]+$/', $db_prefix)) { + form_set_error('db_prefix', st('The database table prefix you have entered, %db_prefix, is invalid. The table prefix can only contain alphanumeric characters, underscores or dots.', array('%db_prefix' => $db_prefix)), 'error'); + } + + if (!empty($db_port) && !is_numeric($db_port)) { + form_set_error('db_port', st('Database port must be a number.')); + } + + if (empty($db_path)) { + form_set_error('db_path', st('Path is a requred field for MySQL and Postgres databases.')); + } + + if (empty($db_user)) { + form_set_error('db_user', st('User is a requred field for MySQL and Postgres databases.')); + } + } + else { + if ($db_user != 'dummy') { + $db_user = 'dummy'; + // get current site path + $db_host = conf_path(); + // Take a random starting point in the randomly + // generated string, not going any higher then 24 + $db_path = $i . 'database-'.substr(md5(time()), rand(0, 24), 8).'.php'; + } + } + $databases = drupal_detect_database_types(); if (!in_array($db_type, $databases)) { form_set_error('db_type', st("In your %settings_file file you have configured @drupal to use a %db_type server, however your PHP installation currently does not support this database type.", array('%settings_file' => $settings_file, '@drupal' => drupal_install_profile_name(), '%db_type' => $db_type))); Index: update.php =================================================================== RCS file: /cvs/drupal/drupal/update.php,v retrieving revision 1.236 diff -u -p -r1.236 update.php --- update.php 20 Oct 2007 21:57:49 -0000 1.236 +++ update.php 8 Nov 2007 19:11:30 -0000 @@ -189,6 +189,10 @@ function update_fix_schema_version() { case 'mysqli': db_query('ALTER TABLE {system} ADD schema_version smallint(3) not null default -1'); break; + + case 'sqlite': + db_query("ALTER TABLE {system} ADD schema_version INTEGER NOT NULL default '-1'"); + break; } // Set all enabled (contrib) modules to schema version 0 (installed) db_query('UPDATE {system} SET schema_version = 0 WHERE status = 1'); @@ -214,6 +218,9 @@ function update_fix_sessions() { if ($GLOBALS['db_type'] == 'mysql') { db_query("ALTER TABLE {sessions} ADD cache int(11) NOT NULL default '0' AFTER timestamp"); } + else if ($GLOBALS['db_type'] == 'sqlite') { + db_query("ALTER TABLE {sessions} ADD cache INTEGER NOT NULL default '0'"); + } elseif ($GLOBALS['db_type'] == 'pgsql') { db_add_column($ret, 'sessions', 'cache', 'int', array('default' => 0, 'not null' => TRUE)); } @@ -234,6 +241,9 @@ function update_fix_watchdog_115() { if ($GLOBALS['db_type'] == 'mysql') { $ret[] = update_sql("ALTER TABLE {watchdog} ADD severity tinyint(3) unsigned NOT NULL default '0'"); } + else if ($GLOBALS['db_type'] == 'sqlite') { + $ret[] = update_sql("ALTER TABLE {watchdog} ADD severity INTEGER NOT NULL default '0'"); + } else if ($GLOBALS['db_type'] == 'pgsql') { $ret[] = update_sql('ALTER TABLE {watchdog} ADD severity smallint'); $ret[] = update_sql('UPDATE {watchdog} SET severity = 0'); @@ -263,6 +273,9 @@ function update_fix_watchdog() { case 'mysqli': db_query("ALTER TABLE {watchdog} ADD COLUMN referer varchar(128) NOT NULL"); break; + case 'sqlite': + db_query("ALTER TABLE {watchdog} ADD referer varchar(128) NOT NULL DEFAULT ''"); + break; } variable_set('update_watchdog_fixed', TRUE); @@ -515,6 +528,10 @@ function update_fix_system_table() { db_add_column($ret, 'system', 'weight', 'smallint', array('not null' => TRUE, 'default' => 0)); $ret[] = update_sql('CREATE INDEX {system}_weight_idx ON {system} (weight)'); break; + case 'sqlite': + $ret[] = update_sql("ALTER TABLE {system} ADD weight INTEGER default '0' NOT NULL)"); + $ret[] = update_sql('CREATE INDEX {system}_weight_idx ON {system} (weight)'); + break; case 'mysql': case 'mysqli': $ret[] = update_sql("ALTER TABLE {system} ADD weight tinyint(2) default '0' NOT NULL, ADD KEY (weight)"); @@ -539,6 +556,7 @@ function update_fix_access_table() { } break; case 'pgsql': + case 'sqlite': return; } @@ -651,27 +669,56 @@ function update_create_cache_tables() { created int NOT NULL default '0', headers text, PRIMARY KEY (cid) - )"); - $ret[] = update_sql("CREATE TABLE {cache_menu} ( - cid varchar(255) NOT NULL default '', - data bytea, - expire int NOT NULL default '0', - created int NOT NULL default '0', - headers text, - PRIMARY KEY (cid) - )"); - $ret[] = update_sql("CREATE TABLE {cache_page} ( - cid varchar(255) NOT NULL default '', - data bytea, - expire int NOT NULL default '0', - created int NOT NULL default '0', - headers text, - PRIMARY KEY (cid) - )"); - $ret[] = update_sql("CREATE INDEX {cache_filter}_expire_idx ON {cache_filter} (expire)"); - $ret[] = update_sql("CREATE INDEX {cache_menu}_expire_idx ON {cache_menu} (expire)"); - $ret[] = update_sql("CREATE INDEX {cache_page}_expire_idx ON {cache_page} (expire)"); - break; + )"); + $ret[] = update_sql("CREATE TABLE {cache_menu} ( + cid varchar(255) NOT NULL default '', + data bytea, + expire int NOT NULL default '0', + created int NOT NULL default '0', + headers text, + PRIMARY KEY (cid) + )"); + $ret[] = update_sql("CREATE TABLE {cache_page} ( + cid varchar(255) NOT NULL default '', + data bytea, + expire int NOT NULL default '0', + created int NOT NULL default '0', + headers text, + PRIMARY KEY (cid) + )"); + $ret[] = update_sql("CREATE INDEX {cache_filter}_expire_idx ON {cache_filter} (expire)"); + $ret[] = update_sql("CREATE INDEX {cache_menu}_expire_idx ON {cache_menu} (expire)"); + $ret[] = update_sql("CREATE INDEX {cache_page}_expire_idx ON {cache_page} (expire)"); + break; + case 'sqlite': + $ret[] = update_sql("CREATE TABLE {cache_filter} ( + cid varchar(255) NOT NULL default '', + data blob, + expire int NOT NULL default '0', + created int NOT NULL default '0', + headers text, + PRIMARY KEY (cid) + )"); + $ret[] = update_sql("CREATE TABLE {cache_menu} ( + cid varchar(255) NOT NULL default '', + data blob, + expire int NOT NULL default '0', + created int NOT NULL default '0', + headers text, + PRIMARY KEY (cid) + )"); + $ret[] = update_sql("CREATE TABLE {cache_page} ( + cid varchar(255) NOT NULL default '', + data blob, + expire int NOT NULL default '0', + created int NOT NULL default '0', + headers text, + PRIMARY KEY (cid) + )"); + $ret[] = update_sql("CREATE INDEX {cache_filter}_expire_idx ON {cache_filter} (expire)"); + $ret[] = update_sql("CREATE INDEX {cache_menu}_expire_idx ON {cache_menu} (expire)"); + $ret[] = update_sql("CREATE INDEX {cache_page}_expire_idx ON {cache_page} (expire)"); + break; } return $ret; } Index: includes/database.sqlite-altertable.inc =================================================================== RCS file: includes/database.sqlite-altertable.inc diff -N includes/database.sqlite-altertable.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ includes/database.sqlite-altertable.inc 8 Nov 2007 17:57:24 -0000 @@ -0,0 +1,333 @@ + $def) { + $newcols[$inner_field] = $inner_field; + } + + // copy the data from the original table to ist temporary copy + $cols = implode(", ", $newcols); + $copytotempsql = 'INSERT INTO '.$tmpname.'('.$cols.') SELECT '.$cols.' FROM '.$table; + + // split the ALTER sentence + // this cuold be done, by extracting the first substring till ' ' + $defparts = preg_split("/[\s]+/", $alterdef, -1, PREG_SPLIT_NO_EMPTY); + $action = strtolower($defparts[0]); + + switch($action) { + case 'add': + if ($defparts[1] == 'PRIMARY' && $defparts[2] == 'KEY') { + $defparts[3] = str_replace("(", "", $defparts[3]); + $defparts[3] = str_replace(")", "", $defparts[3]); + // new primary keys + foreach (explode(",", $defparts[3]) as $npk) { + $schema[$table]['primary key'][] = $npk; + } + break; + } + + array_shift($defparts); + + if(sizeof($defparts) <= 2) { + trigger_error(check_plain('near "'. $defparts[0].($defparts[1] ? ' '. $defparts[1] : '') .'": syntax error'), E_USER_WARNING); + return false; + } + + $def = array(); + $def['type'] = $defparts[1]; + + $default = ''; + if (strstr($defparts[2], "NOT")) { + $def['not null'] = TRUE; + } + else if (strstr($defparts[2], "DEFAULT")) { + $def['default'] = $default; + + if (strstr($defparts[4], "NOT")) { + $def['not null'] = TRUE; + } + } + $schema[$table]['fields'][$defparts[0]] = $def; + break; + + case 'change': + if(sizeof($defparts) < 3){ + trigger_error(check_plain('near "' .$defparts[0].($defparts[1] ? ' '. $defparts[1] : '').($defparts[2] ? ' '. $defparts[2] : '').'": syntax error'), E_USER_WARNING); + return false; + } + if($schema['columns'][$defparts[1]]){ + array_shift($defparts); + + if($newcols[$defparts[0]] != $defparts[0]){ + trigger_error(check_plain('unknown column "'. $defparts[1] .'" in "'. $table .'"'), E_USER_WARNING); + return false; + } + + $notnull = FALSE; + $default = null; + if (strstr($defparts[3], "NOT")) { + $notnull = TRUE; + } + else if (strstr($defparts[3], "DEFAULT")) { + $default = $defparts[4]; + + if (strstr($defparts[5], "NOT")) { + $notnull = TRUE; + } + } + + $schema[$table]['fields'][$defparts[0]]['name'] = $defparts[1]; + $schema[$table]['fields'][$defparts[0]]['type'] = $defparts[2]; + + if (isset($schema[$table]['fields'][$defparts[0]]['not null']) && !$notnull) + unset($schema[$table]['fields'][$defparts[0]]['not null']); + + if ($notnull) + $schema[$table]['fields'][$defparts[0]]['not null'] = TRUE; + + if (isset($schema[$table]['fields'][$defparts[0]]['default']) && ($default == null)) + unset($schema[$table]['fields'][$defparts[0]]['default']); + + if ($default != null) + $schema[$table]['fields'][$defparts[0]]['default'] = $default; + + // update mappings + $newcols[$defparts[0]] = $defparts[1]; + } + else{ + trigger_error(check_plain('unknown column "'. $defparts[1] .'" in "'. $table .'"'), E_USER_WARNING); + return false; + } + break; + + case 'drop': + if(sizeof($defparts) < 2){ + trigger_error(check_plain('near "'. $defparts[0] . ($defparts[1] ? ' ' . $defparts[1] : '') .'": syntax error'), E_USER_WARNING); + return false; + } + + // are we dropping the primary key + if ($defparts[1] == 'PRIMARY' && $defparts[2] == 'KEY') { + unset($schema[$table]['primary key']); + break; + } + else { + // dropping a column + if($schema[$table]['fields'][$defparts[1]]){ + // update mappings + unset($schema[$table]['fields'][$defparts[1]]); + unset($schema[$table]['primary key'][$defparts[1]]); + unset($newcols[$defparts[1]]); + _sqlite_remove_col_index($table, $schema, $defparts[1]); + } + else{ + trigger_error(check_plain('unknown column "'. $defparts[1] .'" in "'. $table .'"'), E_USER_WARNING); + return false; + } + } + break; + + default: + trigger_error(check_plain('near "'. $prevword .'": syntax error modifying table '. $table), E_USER_WARNING); + return false; + } + $prevword = $defparts[sizeof($defparts)-1]; + + //this block of code generates a test table simply to verify that the columns specifed are valid in an sql statement + //this ensures that no reserved words are used as columns, for example + $colsSql = _sqlite_build_cols_sql($tmpname, $schema[$table]); + $indexSql = implode(" ", _sqlite_build_index_sql($table, $schema[$table])); + $testsql = "CREATE TABLE ". $tmpname. "(". $colsSql .");"; + $testsql .= $indexSql; + sqlite_query($active_db, $testsql); + if($error_code = sqlite_last_error($active_db)) { + trigger_error(check_plain('near "'. $prevword .'": ' . sqlite_error_string($error_code). ' -> syntax error modifying table '. $table), E_USER_WARNING); + return false; + } + $droptempsql = 'DROP TABLE '. $tmpname; + // in the end drop the original table + $dropoldsql = 'DROP TABLE '.$table; + sqlite_query($active_db, $droptempsql); + //end block + + $createnewtableSQL = "CREATE TABLE ". $table. "(". $colsSql .");"; + $createnewtableSQL .= $indexSql; + + $newcolumns = ''; + $oldcolumns = ''; + reset($newcols); + while(list($key,$val) = each($newcols)) { + $newcolumns .= ($newcolumns?', ':'').$val; + $oldcolumns .= ($oldcolumns?', ':'').$key; + } + $copytonewsql = 'INSERT INTO '. $table .'('. $newcolumns .') SELECT '. $oldcolumns .' FROM '. $tmpname; + + sqlite_query($active_db, "BEGIN TRANSACTION"); + sqlite_query($active_db, $createtemptableSQL); //create temp table + sqlite_query($active_db, $copytotempsql); //copy to table + sqlite_query($active_db, $dropoldsql); //drop old table + sqlite_query($active_db, $createnewtableSQL); //recreate original table + + // all timings will be accounted in the _db_query, this is just to log + // which queries are actualli being executed, hence diff = -1; + if (variable_get('dev_query', 0)) { + $queries[] = array($createtemptableSQL, -1); + $queries[] = array($copytotempsql, -1); + $queries[] = array($dropoldsql, -1); + $queries[] = array($createnewtableSQL, -1); + } + + sqlite_query($active_db, $copytonewsql); //copy back to original table + sqlite_query($active_db, $droptempsql); //drop temp table? + + if (variable_get('dev_query', 0)) { + $queries[] = array($copytonewsql, -1); + $queries[] = array($droptempsql, -1); + } + + if($error_code = sqlite_last_error($active_db)) { + trigger_error(check_plain('error executing altertable statement: '. sqlite_error_string($error_code)), E_USER_WARNING); + sqlite_query($active_db, "ROLLBACK"); + return false; + } + else { + sqlite_query($active_db, "COMMIT"); + return true; + } + } + else{ + trigger_error(check_plain('no such table: '. $table), E_USER_WARNING); + return false; + } + return true; + } +} + +function _sqlite_get_columns($table) { + global $active_db; + + $result = sqlite_query($active_db, "SELECT * FROM $table LIMIT 1"); + $num = sqlite_num_fields($result); + + for ($i=0; $i < $num; $i++) { + $cols[] = sqlite_field_name ($result, $i); + } + return $cols; +} + +function _sqlite_remove_col_index($table, &$schema, $column) { + foreach ($schema[$table]['indexes'] as $name => $collist) { + foreach ($collist as $i => $colname) { + if (is_array($colname)) { + if ($colname[0] == $column) + unset($collist[$i]); + } + else { + if ($colname == $column) + unset($collist[$i]); + } + } + if (count($collist) == 0) + unset($schema[$table]['indexes'][$name]); + } +} + +function _sqlite_get_table_schema($tbl_name) { + global $active_db; + + $result = sqlite_unbuffered_query($active_db, "PRAGMA table_info('".$tbl_name."')"); + $schema = array(); + $schema[$tbl_name] = array(); + $schema[$tbl_name]['fields'] = array(); + $schema[$tbl_name]['primary key'] = array(); + $schema[$tbl_name]['unique keys'] = array(); + $schema[$tbl_name]['indexes'] = array(); + while ($result && sqlite_has_more($result)) { + $col = sqlite_fetch_array($result, SQLITE_ASSOC); + //array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE) + $schema[$tbl_name]['fields'][$col['name']] = $col; + if ($col['pk']) { + $schema[$tbl_name]['primary key'][] = $col['name']; + } + } + + // build index info, so we can recreate them + $schema['indices'] = array(); + $query = "SELECT * FROM sqlite_master WHERE tbl_name ='".$tbl_name."' AND type='index'"; + $result = sqlite_unbuffered_query($active_db, $query); + while ($result && sqlite_has_more($result)) { + $index = sqlite_fetch_array($result, SQLITE_ASSOC); + // we don't need to create autoindices + if (strstr($index['name'], 'autoindex')) { + continue; + } + preg_match("/\((.+)\)/", $index['sql'], $matches); + $indexcols = array(); + if (count($matches)) { + $expl = explode(",", $matches[1]); + if (count($expl)) { + foreach ($expl as $col_name) { + $indexcols[] = trim($col_name); + } + } + else { + $indexcols[] = trim($matches[1]); + } + } + if (strstr($index['sql'], "UNIQUE")) { + $schema[$tbl_name]['unique keys'][$index['name']] = $indexcols; + } + else { + $schema[$tbl_name]['indexes'][$index['name']] = $indexcols; + } + } + return $schema; +} + +/** + * @} End of "ingroup database". + */ \ No newline at end of file Index: includes/database.sqlite.inc =================================================================== RCS file: includes/database.sqlite.inc diff -N includes/database.sqlite.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ includes/database.sqlite.inc 8 Nov 2007 18:37:55 -0000 @@ -0,0 +1,971 @@ + $t('SQLite database'), + 'value' => $version, + ); + + if (version_compare($version, DRUPAL_MINIMUM_SQLITE) < 0) { + $form['sqlite']['severity'] = REQUIREMENT_ERROR; + $form['sqlite']['description'] = $t('Your SQLite library is too old. Drupal requires at least SQLite %version.', array('%version' => DRUPAL_MINIMUM_SQLITE)); + } + + return $form; +} + +/** + * Returns the version of the database server currently in use. + * + * @return Database server version + */ +function db_version() { + list($version) = explode('-', sqlite_libversion()); + return $version; +} + +/** + * Initialize a database connection. + * + * @param $url + * URL + * @return + * connection + */ +function db_connect($url) { + // Check if Sqlite support is present in PHP + if (!function_exists('sqlite_open')) { + // Redirect to installer if using default DB credentials + if ($url['user'] == 'username' && $url['pass'] == 'password') { + include_once 'includes/install.inc'; + install_goto('install.php'); + } + drupal_maintenance_theme(); + drupal_set_title('PHP SQLITE support not enabled'); + print theme('maintenance_page', '

We were unable to use the SQLITE database because the SQLITE extension for PHP is not installed. Check your PHP.ini to see how you can enable it.

+

If you are unsure what these terms mean you should probably contact your hosting provider.

'); + exit; + } + + // get database filename + $url = explode("@", $url); + $connection = sqlite_open(urldecode($url[1])); + + // did it connect successfully ? + if (!$connection) { + drupal_maintenance_theme(); + drupal_set_title('Unable to open the database'); + print theme('maintenance_page', '

This either means that the database path in your settings.php file is incorrect or you have insufficient privileges to access the database file.

+

Currently, the database path is '. theme('placeholder', $url) .'.

+

If you are unsure what these terms mean you should probably contact your hosting provider.

'); + exit; + } + + sqlite_query($connection, "PRAGMA synchronous = OFF;"); // equivalent to MyISAM in MySQL + sqlite_query($connection, "PRAGMA short_column_names = 1;"); // no more rewrites + sqlite_query($connection, "PRAGMA temp_store = MEMORY;"); + sqlite_query($connection, "PRAGMA cache_size = 5000"); + sqlite_query($connection, "PRAGMA count_changes=OFF;"); // no need for that (insert/update returning number of changes as result) + + // register functions which are not buil-in sqlite + sqlite_create_function($connection, 'concat', '_sqlite_concat'); + sqlite_create_function($connection, 'greatest', '_sqlite_greatest'); + sqlite_create_function($connection, 'rand', '_sqlite_rand'); + sqlite_create_function($connection, 'if', '_sqlite_if', 3); + sqlite_create_function($connection, 'year', '_sqlite_year', 1); + sqlite_create_function($connection, 'month', '_sqlite_month', 1); + sqlite_create_function($connection, 'FROM_UNIXTIME', '_sqlite_from_unix_timestamp', 1); + sqlite_create_function($connection, 'pow', '_sqlite_pow', 2); + return $connection; +} + +/** + * A user defined function to replace the CONCAT in MYSQL + * sqlite_udf_encode_binary in the PHP manual says sg. about first byte should not be 0x01 and there should not be 0x00 chars. + * But we can safely assume only UTF-8 strings will be CONCATed, no problem with that. + * + * @return + * string + */ +function _sqlite_concat() { + $a = func_get_args(); + return implode('', $a); +} + +function _sqlite_year($date) { + return date("Y", strtotime($date)); +} + +function _sqlite_month($date) { + return date("m", strtotime($date)); +} + +//YYYY-MM-DD HH:MM:SS +function _sqlite_from_unix_timestamp($timestamp) { + return date("Y-m-d G:i:s", $timestamp); +} + +function _sqlite_pow($num, $exp) { + return pow($num, $exp); +} + +/** + * A user defined function to replace the GREATEST in MYSQL + * + * @return + * int + */ +function _sqlite_greatest() { + $a = func_get_args(); + return max($a); +} + +function _sqlite_rand() { + return rand(); +} + +/** + * A user defined function to replace the IF in MYSQL + * + * @param $expr + * Boolean expression to evaluate + * @param $true_part + * What should be returned if $expr evaluates to true + * @param $false_part + * What should be returned if $expr evaluates to false + * @return + * true_part if true, false_part else + */ +function _sqlite_if($expr, $true_part, $false_part) { + if ($expr) + return ($true_part); + else + return ($false_part); +} + + +function _sqlite_rewrite_query($query) { + $old_query = $query; + + $query = preg_replace('/^SELECT COUNT\(DISTINCT\(([^.)]+\.)?([^\)]+)\)\)( AS [^ ]+)? FROM(.+)$/i', + 'SELECT COUNT(\2)\3 FROM (SELECT DISTINCT \1\2 FROM\4)', + $query); + + return $query; +} + +/** + * Runs a basic query in the active database. + * + * User-supplied arguments to the query should be passed in as separate + * parameters so that they can be properly escaped to avoid SQL injection + * attacks. + * + * @param $query + * A string containing an SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. Instead of a variable number of query arguments, + * you may also pass a single array containing the query arguments. + * + * Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose + * in '') and %%. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @return + * A database query result resource, or FALSE if the query was not + * executed correctly. + */ +function db_query($query) { + $args = func_get_args(); + array_shift($args); + $query = db_prefix_tables($query); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + _db_query_callback($args, TRUE); + $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query); + return _db_query($query); +} + +/** + * Helper function for db_query(). + * + * @param $query + * string + * @param $debug + * integer + * @return + * result + */ +function _db_query($query, $debug = 0) { + global $active_db, $queries; + + if (variable_get('dev_query', 0)) { + list($usec, $sec) = explode(' ', microtime()); + $timer = (float)$usec + (float)$sec; + } + + // special call for ALTER TABLE queries + if(strtolower(substr(ltrim($query), 0, 5)) == 'alter') { + $queryparts = preg_split("/[\s]+/", $query, 4, PREG_SPLIT_NO_EMPTY); + $tablename = $queryparts[2]; + $alterdefs = $queryparts[3]; + + if(strtolower($queryparts[1]) != 'table' || $queryparts[2] == '') { + trigger_error (check_plain('near "'.$queryparts[0] . '": syntax error'), E_USER_WARNING); + } + else { + require_once './includes/database.sqlite-altertable.inc'; + $result = _sqlite_altertable($tablename, $alterdefs); + } + } + // this rewrites the TRUNCATE table clause + else if (strtolower(substr(ltrim($query), 0, 8)) == 'truncate') { + $queryparts = preg_split("/[\s]+/", $query, 3, PREG_SPLIT_NO_EMPTY); + $tablename = $queryparts[2]; + + if(strtolower($queryparts[1]) != 'table' || $queryparts[2] == '') { + trigger_error (check_plain('near "'.$queryparts[0] . '": syntax error'), E_USER_WARNING); + } + else { + $result = sqlite_query($active_db, "DELETE FROM ". $tablename); + } + } + // compatible queries + else { + $old_query = $query; + + $query = _sqlite_rewrite_query($query); + + $result = sqlite_query($active_db, $query); + } + + if (variable_get('dev_query', 0)) { + $bt = debug_backtrace(); + $query = $bt[2]['function'] . "\n" . $query; + list($usec, $sec) = explode(' ', microtime()); + $stop = (float)$usec + (float)$sec; + $diff = $stop - $timer; + $queries[] = array($query, $diff); + } + + if ($debug != 0) + print '

query: '. $query .'
error:'. sqlite_last_error($active_db) .'

'; + + if (!($error_code = sqlite_last_error($active_db))) { + return $result; + } + else { + trigger_error(check_plain(sqlite_error_string($error_code) ."\nquery: ". htmlspecialchars($query)), E_USER_WARNING); + } +} + +/** + * Fetch one result row from the previous query as an object. + * + * @param $result + * A database query result resource, as returned from db_query(). + * @return + * An object representing the next row of the result. The attributes of this + * object are the table fields selected by the query. + */ +function db_fetch_object($result) { + if ($result && sqlite_has_more($result)) { + return (object)sqlite_fetch_array($result, SQLITE_ASSOC); + } +} + +/** + * Fetch one result row from the previous query as an array. + * + * @param $result + * A database query result resource, as returned from db_query(). + * @return + * An associative array representing the next row of the result. The keys of + * this object are the names of the table fields selected by the query, and + * the values are the field values for this result row. + */ +function db_fetch_array($result) { + if ($result && sqlite_has_more($result)) { + return sqlite_fetch_array($result, SQLITE_ASSOC); + } +} + + +/** + * Return an individual result field from the previous query. + * Only use this function if exactly one field is being selected; otherwise, + * use db_fetch_object() or db_fetch_array(). + * + * @param $result + * A database query result resource, as returned from db_query(). + * @param $row + * The index of the row whose result is needed. + * @return + * The resulting field. + */ +function db_result($result, $row = 0) { + if ($result && sqlite_num_rows($result) > $row) { + sqlite_seek($result, $row); + return sqlite_fetch_single($result); + } + return FALSE; +} + +/** + * Determine whether the previous query caused an error. + * + * @return + * string + */ +function db_error() { + global $active_db; + return sqlite_last_error($active_db); +} + +/** + * Determine the number of rows changed by the preceding query. + * + * @return + * integer + */ +function db_affected_rows() { + global $active_db; + return sqlite_changes($active_db); +} + +/** + * Runs a limited-range query in the active database. + * Use this as a substitute for db_query() when a subset of the query is to be + * returned. + * User-supplied arguments to the query should be passed in as separate parameters + * so that they can be properly escaped to avoid SQL injection attacks. + * @param $query + * A string containing an SQL query. + * @param ... + * A variable number of arguments which are substituted into the query using + * printf() syntax. + * @param $from + * The first result row to return. + * @param $count + * The maximum number of result rows to return. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_range($query) { + $args = func_get_args(); + $count = array_pop($args); + $from = array_pop($args); + + array_shift($args); + + $query = db_prefix_tables($query); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + _db_query_callback($args, TRUE); + $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query); + $query .= ' LIMIT '. (int)$count .' OFFSET '. (int)$from ; + return _db_query($query); +} + + +/** + * Runs a SELECT query and stores its results in a temporary table. + * + * Use this as a substitute for db_query() when the results need to stored + * in a temporary table. Temporary tables exist for the duration of the page + * request. + * User-supplied arguments to the query should be passed in as separate parameters + * so that they can be properly escaped to avoid SQL injection attacks. + * + * Note that if you need to know how many results were returned, you should do + * a SELECT COUNT(*) on the temporary table afterwards. db_num_rows() and + * db_affected_rows() do not give consistent result across different database + * types in this case. + * + * @param $query + * A string containing a normal SELECT SQL query. + * @param ... + * A variable number of arguments which are substituted into the query + * using printf() syntax. The query arguments can be enclosed in one + * array instead. + * Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose + * in '') and %%. + * + * NOTE: using this syntax will cast NULL and FALSE values to decimal 0, + * and TRUE values to decimal 1. + * + * @param $table + * The name of the temporary table to select into. This name will not be + * prefixed as there is no risk of collision. + * @return + * A database query result resource, or FALSE if the query was not executed + * correctly. + */ +function db_query_temporary($query) { + $args = func_get_args(); + $tablename = array_pop($args); + array_shift($args); + + $query = preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE '. $tablename .' AS SELECT', db_prefix_tables($query)); + if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax + $args = $args[0]; + } + _db_query_callback($args, TRUE); + $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query); + return _db_query($query); +} + +/** + * Returns the last insert id. + * + * @param $table + * The name of the table you inserted into. + * @param $field + * The name of the autoincrement field. + */ +function db_last_insert_id($table, $field) { + global $active_db; + return sqlite_last_insert_rowid($active_db); +} + +function _sqlite_create_temp_sql($schema, &$tmpname) { + $tmpname = 't'. time(); + $sql = "CREATE TEMPORARY TABLE {". $tmpname ."} (\n"; + $sql .= _sqlite_build_cols_sql($schema); + return $sql; +} + +function _sqlite_create_copy_sql($src_table, $dst_table, $fields) { + $cols = implode(", ", $fields); + return 'INSERT INTO '.$dst_table.'('.$cols.') SELECT '.$cols.' FROM '.$src_table; +} + +/** + * Returns a properly formatted Binary Large OBject value. + * + * @param $data + * Data to encode. + * @return + * Encoded data. + */ +function db_encode_blob($data) { + return "'". sqlite_udf_encode_binary(sqlite_escape_string($data)) ."'"; +} + +/** + * Returns text from a Binary Large OBject value. + * + * @param $data + * Data to decode. + * @return + * Decoded data. + */ +function db_decode_blob($data) { + return sqlite_udf_decode_binary($data); +} + +/** + * Prepare user input for use in a database query, preventing SQL injection attacks. + * + * @param $text + * String to escape + * @return + * Escaped string + */ +function db_escape_string($text) { + if (is_array($text)) + return sqlite_escape_string($text[0]); + else + return sqlite_escape_string($text); +} + +/** + * Lock a table. + * + * @param $table + * string + */ +function db_lock_table($table) { + db_query('BEGIN'); +} + +/** + * Unlock all locked tables. + */ +function db_unlock_tables() { + db_query('COMMIT'); +} + +/** + * Check if a table exists. + */ +function db_table_exists($table) { + global $active_db; + $result = sqlite_unbuffered_query($active_db, "SELECT * FROM sqlite_master WHERE tbl_name = '".$table."'"); + return sqlite_has_more($result); +} + +/** + * Check if a column exists in the given table. + */ +function db_column_exists($table, $column) { + global $active_db; + $result = sqlite_unbuffered_query($active_db, "PRAGMA table_info('".$tbl_name."')"); + while ($result && sqlite_has_more($result)) { + $col = sqlite_fetch_array($result, SQLITE_ASSOC); + if ($col['name'] == $column) + return TRUE; + } + return FALSE; +} + +/** + * @} End of "ingroup database". + */ + +/** + * @ingroup schemaapi + * @{ + */ + + +/** + * Generate SQL to create a new table from a Drupal schema definition. + * + * @param $table + * A valid Drupal table definition array. + * @return + * An array of SQL statements to create the table. + */ +function db_create_table_sql($name, $table) { + $sql = array(); + $sql[] = "CREATE TABLE {". $name ."} (\n". _sqlite_build_cols_sql($name, $table) ."\n);\n"; + return array_merge($sql, _sqlite_build_index_sql($name, $table)); +} + +function _sqlite_build_index_sql($tablename, $schema) { + $sql = array(); + if (!empty($schema['unique keys'])) { + foreach ($schema['unique keys'] as $key => $fields) { + $sql[] = "CREATE UNIQUE INDEX ". $tablename ."_". $key ." ON ". $tablename ." (". _db_create_key_sql($fields) ."); \n"; + } + } + if (!empty($schema['indexes'])) { + foreach ($schema['indexes'] as $index => $fields) { + $sql[] = "CREATE INDEX ". $tablename ."_". $index ." ON ". $tablename ." (". _db_create_key_sql($fields) ."); \n"; + } + } + return $sql; +} + +function _sqlite_build_cols_sql($tablename, $schema) { + $sql = ""; + + // Add the SQL statement for each field. + foreach ($schema['fields'] as $name => $field) { + if ($field['type'] == 'serial') { + if (($key = array_search($name, $schema['primary key'])) !== false) { + unset($schema['primary key'][$key]); + } + } + $sql .= _db_create_field_sql($name, _db_process_field($field)) .", \n"; + } + + // Process keys. + if (!empty($schema['primary key'])) { + $sql .= " PRIMARY KEY (". _db_create_key_sql($schema['primary key']) ."), \n"; + } + + // Remove the last comma and space. + $sql = substr($sql, 0, -3); + return $sql; +} + +function _db_create_key_sql($fields) { + $ret = array(); + foreach ($fields as $field) { + if (is_array($field)) { + $ret[] = $field[0]; + } + else { + $ret[] = $field; + } + } + return implode(', ', $ret); +} + +/** + * Set database-engine specific properties for a field. + * + * @param $field + * A field description array, as specified in the schema documentation. + */ +function _db_process_field($field) { + + if (!isset($field['size'])) { + $field['size'] = 'normal'; + } + + // Set the correct database-engine specific datatype. + if (!isset($field['sqlite_type'])) { + $map = db_type_map(); + $field['sqlite_type'] = $map[$field['type'] .':'. $field['size']]; + } + + if ($field['type'] == 'serial') { // this should check if field is a primary key + $field['auto_increment'] = TRUE; + } + + return $field; +} + +/** + * Create an SQL string for a field to be used in table creation or alteration. + * + * Before passing a field out of a schema definition into this function it has + * to be processed by _db_process_field(). + * + * @param $name + * Name of the field. + * @param $spec + * The field specification, as per the schema data structure format. + */ +function _db_create_field_sql($name, $spec) { + + if (!empty($spec['auto_increment'])) { + $sql = "". $name ." INTEGER PRIMARY KEY"; + } + else { + $sql = "". $name ." ". $spec['sqlite_type']; + + if (isset($spec['length'])) { + $sql .= '('. $spec['length'] .')'; + } + //TODO: does scale apply for sqlite ?? + elseif (isset($spec['precision']) && isset($spec['scale'])) { + $sql .= '('. $spec['scale'] .', '. $spec['precision'] .')'; + } + + if (!empty($spec['not null'])) { + $sql .= ' NOT NULL'; + } + + if (isset($spec['default'])) { + if (is_string($spec['default'])) { + $spec['default'] = "'". $spec['default'] ."'"; + } + $sql .= ' DEFAULT '. $spec['default']; + } + + if (empty($spec['not null']) && !isset($spec['default'])) { + $sql .= ' DEFAULT NULL'; + } + } + return $sql; +} + +/** + * This maps a generic data type in combination with its data size + * to the engine-specific data type. + */ +function db_type_map() { + // Put :normal last so it gets preserved by array_flip. This makes + // it much easier for modules (such as schema.module) to map + // database types back into schema types. + /* + a VARCHAR(10), + b NVARCHAR(15), + c TEXT, + d INTEGER, + e FLOAT, + f BOOLEAN, + g CLOB, + h BLOB, + i TIMESTAMP, + j NUMERIC(10,5) + k VARYING CHARACTER (24), + l NATIONAL VARYING CHARACTER(16) + */ + $map = array( + 'varchar:normal' => 'VARCHAR', + + 'text:tiny' => 'TEXT', + 'text:small' => 'TEXT', + 'text:medium' => 'TEXT', + 'text:big' => 'TEXT', + 'text:normal' => 'TEXT', + + 'serial:tiny' => 'INTEGER', + 'serial:small' => 'INTEGER', + 'serial:medium' => 'INTEGER', + 'serial:big' => 'INTEGER', + 'serial:normal' => 'INTEGER', + + 'int:tiny' => 'INTEGER', + 'int:small' => 'INTEGER', + 'int:medium' => 'INTEGER', + 'int:big' => 'INTEGER', + 'int:normal' => 'INTEGER', + + 'float:tiny' => 'FLOAT', + 'float:small' => 'FLOAT', + 'float:medium' => 'FLOAT', + 'float:big' => 'FLOAT', + 'float:normal' => 'FLOAT', + + 'numeric:normal' => 'NUMERIC', + + 'blob:big' => 'BLOB', + 'blob:normal' => 'BLOB', + + 'datetime:normal' => 'TIMESTAMP', + ); + return $map; +} + + +/** + * Rename a table. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * The table to be renamed. + * @param $new_name + * The new name for the table. + */ +function db_rename_table(&$ret, $table, $new_name) { + $ret[] = update_sql('ALTER TABLE {'. $table .'} RENAME TO {'. $new_name .'}'); +} + +/** + * Drop a table. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * The table to be dropped. + */ +function db_drop_table(&$ret, $table) { + $ret[] = update_sql('DROP TABLE {'. $table .'}'); +} + +/** + * Add a new field to a table. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * Name of the table to be altered. + * @param $field + * Name of the field to be added. + * @param $spec + * The field specification array, as taken from a schema definition + */ +function db_add_field(&$ret, $table, $field, $spec) { + $query = 'ALTER TABLE {'. $table .'} ADD '; + $query .= _db_create_field_sql($field, _db_process_field($spec)); + $ret[] = update_sql($query); +} + +/** + * Drop a field. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * The table to be altered. + * @param $field + * The field to be dropped. + */ +function db_drop_field(&$ret, $table, $field) { + $ret[] = update_sql('ALTER TABLE {'. $table .'} DROP '. $field); +} + +/** + * Set the default value for a field. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * The table to be altered. + * @param $field + * The field to be altered. + * @param $default + * Default value to be set. NULL for 'default NULL'. + */ +function db_field_set_default(&$ret, $table, $field, $default) { + if ($default == NULL) { + $default = 'NULL'; + } + else { + $default = is_string($default) ? "'$default'" : $default; + } + + $ret[] = update_sql('ALTER TABLE {'. $table .'} CHANGE '. $field .' SET DEFAULT '. $default); +} + +/** + * Set a field to have no default value. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * The table to be altered. + * @param $field + * The field to be altered. + */ +function db_field_set_no_default(&$ret, $table, $field) { + $ret[] = update_sql('ALTER TABLE {'. $table .'} CHANGE '. $field .' DROP DEFAULT'); +} + +/** + * Add a primary key. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * The table to be altered. + * @param $fields + * Fields for the primary key. + */ +function db_add_primary_key(&$ret, $table, $fields) { + $ret[] = update_sql('ALTER TABLE {'. $table .'} ADD PRIMARY KEY ('. + _db_create_key_sql($fields) .')'); +} + +/** + * Drop the primary key. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * The table to be altered. + */ +function db_drop_primary_key(&$ret, $table) { + $ret[] = update_sql('ALTER TABLE {'. $table .'} DROP PRIMARY KEY'); +} + +/** + * Add a unique key. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * The table to be altered. + * @param $name + * The name of the key. + * @param $fields + * An array of field names. + */ +function db_add_unique_key(&$ret, $table, $name, $fields) { + $ret[] = update_sql('CREATE UNIQUE INDEX '. $name .' ON {'. $table .'}('. _db_create_key_sql($fields) .')'); +} + +/** + * Drop a unique key. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * The table to be altered. + * @param $name + * The name of the key. + */ +function db_drop_unique_key(&$ret, $table, $name) { + $ret[] = update_sql('DROP INDEX '. $name); +} + +/** + * Add an index. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * The table to be altered. + * @param $name + * The name of the index. + * @param $fields + * An array of field names. + */ +function db_add_index(&$ret, $table, $name, $fields) { + $ret[] = update_sql('CREATE INDEX '. $name .' ON {'. $table .'}(' . implode($fields, ', ') . ')'); +} + +/** + * Drop an index. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * The table to be altered. + * @param $name + * The name of the index. + */ +function db_drop_index(&$ret, $table, $name) { + $ret[] = update_sql('DROP INDEX '. $name); +} + +/** + * Change a field definition. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * Name of the table. + * @param $field + * Name of the field to change. + * @param $field_new + * New name for the field (set to the same as $field if you don't want to change the name). + * @param $spec + * The field specification for the new field. + */ +function db_change_field(&$ret, $table, $field, $field_new, $spec) { + $ret[] = update_sql("ALTER TABLE {". $table ."} CHANGE $field ". + _db_create_field_sql($field_new, _db_process_field($spec))); +} + +/** + * Update a field definition to match its schema. If the field is + * involved in any keys or indexes, recreate them. + * + * @param $ret + * Array to which query results will be added. + * @param $table + * Name of the table. + * @param $field + * Name of the field to update. + */ +function db_update_field(&$ret, $table, $field) { + $spec = drupal_get_schema($table); + db_change_field($ret, $table, $field, $field, $spec['fields'][$field]); +} + + /** + * @} End of "ingroup schemaapi". + */ \ No newline at end of file Index: includes/install.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/install.inc,v retrieving revision 1.48 diff -u -p -r1.48 install.inc --- includes/install.inc 7 Sep 2007 10:48:24 -0000 1.48 +++ includes/install.inc 8 Nov 2007 19:11:31 -0000 @@ -144,7 +144,7 @@ function drupal_detect_baseurl($file = ' function drupal_detect_database_types() { $databases = array(); - foreach (array('mysql', 'mysqli', 'pgsql') as $type) { + foreach (array('mysql', 'mysqli', 'pgsql', 'sqlite') as $type) { if (file_exists('./includes/install.'. $type .'.inc')) { include_once './includes/install.'. $type .'.inc'; $function = $type .'_is_available'; Index: includes/install.sqlite.inc =================================================================== RCS file: includes/install.sqlite.inc diff -N includes/install.sqlite.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ includes/install.sqlite.inc 5 Apr 2007 22:36:26 -0000 @@ -0,0 +1,100 @@ +If you are unsure what these terms mean you should probably contact your hosting provider.', array('%error' => sqlite_error_string($error))), 'error'); + return FALSE; + } + + $success = array('CONNECT'); + + // Test CREATE. + $query = 'CREATE TABLE drupal_install_test (id int NULL)'; + $result = sqlite_query($connection, $query); + if ($error = sqlite_last_error($connection)) { + drupal_set_message(st('We were unable to create a test table on your SQLite database server with the command %query. SQLite reports the following message: %error.
For more help, see the Installation and upgrading handbook. If you are unsure what these terms mean you should probably contact your hosting provider.', array('%query' => $query, '%error' => sqlite_error_string($error))), 'error'); + return FALSE; + } + $err = FALSE; + $success[] = 'SELECT'; + $success[] = 'CREATE'; + + // Test INSERT. + $query = 'INSERT INTO drupal_install_test (id) VALUES (1)'; + $result = sqlite_query($connection, $query); + if ($error = sqlite_last_error($connection)) { + drupal_set_message(st('We were unable to insert a value into a test table on your SQLite database server. We tried inserting a value with the command %query and SQLite reported the following error: %error.', array('%query' => $query, '%error' => sqlite_error_string($error))), 'error'); + $err = TRUE; + } + else { + $success[] = 'INSERT'; + } + + // Test UPDATE. + $query = 'UPDATE drupal_install_test SET id = 2'; + $result = sqlite_query($connection, $query); + if ($error = sqlite_last_error($connection)) { + drupal_set_message(st('We were unable to update a value in a test table on your SQLite database server. We tried updating a value with the command %query and SQLite reported the following error: %error.', array('%query' => $query, '%error' => sqlite_error_string($error))), 'error'); + $err = TRUE; + } + else { + $success[] = 'UPDATE'; + } + + // Test DELETE. + $query = 'DELETE FROM drupal_install_test'; + $result = sqlite_query($connection, $query); + if ($error = sqlite_last_error($connection)) { + drupal_set_message(st('We were unable to delete a value from a test table on your SQLite database server. We tried deleting a value with the command %query and SQLite reported the following error: %error.', array('%query' => $query, '%error' => sqlite_error_string($error))), 'error'); + $err = TRUE; + } + else { + $success[] = 'DELETE'; + } + + // Test DROP. + $query = 'DROP TABLE drupal_install_test'; + $result = sqlite_query($connection, $query); + if ($error = sqlite_last_error($connection)) { + drupal_set_message(st('We were unable to drop a test table from your SQLite database server. We tried dropping a table with the command %query and SQLite reported the following error %error.', array('%query' => $query, '%error' => sqlite_error_string($error))), 'error'); + $err = TRUE; + } + else { + $success[] = 'DROP'; + } + + if ($err) { + return FALSE; + } + + sqlite_close($connection); + return TRUE; +} + +?> Index: misc/install.js =================================================================== RCS file: misc/install.js diff -N misc/install.js --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ misc/install.js 7 Mar 2007 08:13:12 -0000 @@ -0,0 +1,20 @@ +// Global Killswitch +if (Drupal.jsEnabled) { + $(document).ready( + function(){ + if ($("input[@value='sqlite'][@checked]").val() == 'sqlite') { + $("#db_path,#db_user,#db_pass,#advanced_options").hide(); + } + $("input[@name='db_type']").click(function(){ + if ($("input[@value='sqlite'][@checked]").val() == null) { + if ($("#advanced_options").css("display") == 'none') { + $("#db_path,#db_user,#db_pass,#advanced_options").show(); + } + } + else { + $("#db_path,#db_user,#db_pass,#advanced_options").hide(); + } + }); + } + ); +} \ No newline at end of file Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.550 diff -u -p -r1.550 system.module --- modules/system/system.module 7 Nov 2007 20:21:33 -0000 1.550 +++ modules/system/system.module 8 Nov 2007 19:11:35 -0000 @@ -13,6 +13,7 @@ define('DRUPAL_MINIMUM_PHP', '4.3.3') define('DRUPAL_MINIMUM_MYSQL', '4.1.0'); // If using MySQL define('DRUPAL_MINIMUM_PGSQL', '7.4'); // If using PostgreSQL define('DRUPAL_MINIMUM_APACHE', '1.3'); // If using Apache +define('DRUPAL_MINIMUM_SQLITE', '2.7.0'); // If using SQLite // Maximum age of temporary files in seconds. define('DRUPAL_MAXIMUM_TEMP_FILE_AGE', 1440);