Index: update.php =================================================================== RCS file: /cvs/drupal/drupal/update.php,v retrieving revision 1.204 diff -u -F^f -r1.204 update.php --- update.php 8 Sep 2006 23:05:22 -0000 1.204 +++ update.php 13 Sep 2006 19:44:39 -0000 @@ -195,6 +195,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'); @@ -220,6 +224,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)); } @@ -240,6 +247,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'); @@ -269,6 +279,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); @@ -594,6 +607,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)"); @@ -618,6 +635,7 @@ function update_fix_access_table() { } break; case 'pgsql': + case 'sqlite': return; } @@ -730,27 +748,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.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 15 Sep 2006 11:47:50 -0000 @@ -0,0 +1,812 @@ +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; + } + + $url = explode("@", $url); + $connection = sqlite_open($url[1]); + // get database filename + // $url = substr($url,9); + //$connection = sqlite_open($url); + //$cache_db = sqlite_open('database/cache.sqlite'); + + // 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 + + // 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); + 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($fate)); +} + +function _sqlite_month($date) { + return date("m", strtotime($fate)); +} + +//YYYY-MM-DD HH:MM:SS +function _sqlite_from_unix_timestamp($timestamp) { + return date("Y-m-d G:i:s", $timestamp); +} + +/** + * 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); +} + +/** + * Route to _sqlite_set_query() + * + * @return + * string + */ +function _sqlite_get_query() { + return _sqlite_set_query(); +} + +/** + * Query caching + * + * @param $query + * string + * @return + * string + */ +function _sqlite_set_query($query=NULL) { + static $query_cache; + if ($query) $query_cache = $query; + return $query_cache; +} + +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; +} + +/** + * Helper function for db_query(). + * + * @param $query + * string + * @param $debug + * integer + * @return + * result + */ +function _db_query($query, $debug = 0) { + global $active_db, $cache_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 { + $result = 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) { + global $active_db; + + if ($result && sqlite_has_more($result)) { + $object = (object)sqlite_fetch_array($result, SQLITE_ASSOC); + return $object; + } +} + +/** + * 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)) { + $array = sqlite_fetch_array($result, SQLITE_ASSOC); + return $array; + } +} + +/** + * Determine how many result rows were found by the preceding query. + * + * @param $result + * A database query result resource, as returned from db_query(). + * @return + * The number of result rows. + */ +function db_num_rows($result) { + if ($result) { + return sqlite_num_rows($result); + } +} + +/** + * 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); + } +} + +/** + * Determine whether the previous query caused an error. + * + * @return + * string + */ +function db_error() { + global $active_db; + return sqlite_last_error($active_db); +} + +/** + * Return a new unique ID in the given sequence. + * For compatibility reasons, Drupal does not use auto-numbered fields in its + * database tables. Instead, this function is used to return a new unique ID + * of the type requested. If necessary, a new sequence with the given name + * will be created. + * + * @param $name + * string + * @return + * integer + */ +function db_next_id($name) { + $name = db_prefix_tables($name); + db_lock_table("{sequences}"); + $id = db_result(db_query("SELECT id FROM {sequences} WHERE name = '%s'", $name)) + 1; + db_query("REPLACE INTO {sequences} VALUES ('%s', %d)", $name, $id); + db_unlock_tables(); + return $id; +} + +/** + * 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 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) { + 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'); +} + +/** + * Executes the alter table statement. + * This is executer in 6 steps: + * 1. create a temporaty table with the schema identical to the original table + * 2. copy the data over + * -- alter the original table schema + * 3. drop the original table + * 4. create the new table, also recreate all indicies + * 5. copy the data from the temp table to the new table + * 6. drop the temporaty table + * + * @param $table + * string - name of table to alter + * @param $alterdef + * string - the part of alter table statement, without the "ALTER TABLE -tablename-" part + */ +function altertable($table, $alterdef) { + global $active_db; + if($alterdefs != '') { + $schema = _sqlite_get_table_schema($table); + if($schema['columns']) { + + // create an exact copy of the original table + $tmpname = 't'. time(); + $createtemptableSQL = 'CREATE TEMPORARY TABLE '. $tmpname . ' (' . implode(",", _build_cols_sql($schema)) . ')'; + + $prevword = $table; + $newcols = array(); + $replace = array(); + + $oldcols = _sqlite_get_columns($table); + foreach ($oldcols as $inner_field) { + $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['pk'][$npk] = $npk; + } + break; + } + + array_shift($defparts); + + if(sizeof($defparts) <= 2) { + trigger_error('near "'. $defparts[0].($defparts[1] ? ' '. $defparts[1] : '') .'": syntax error', E_USER_WARNING); + return false; + } + + $default = ''; + if (strstr($defparts[2], "NOT")) { + $notnull = 1; + } + else if (strstr($defparts[2], "DEFAULT")) { + $default = $defparts[3]; + + if (strstr($defparts[4], "NOT")) { + $notnull = 1; + } + } + + $schema['columns'][] = array('cid' => '99', + 'name' => $defparts[0], + 'type' => $defparts[1], + 'notnull' => $notnull ? 99 : 0, + 'dflt_value' => $default, + ); + break; + + case 'change': + if(sizeof($defparts) < 3){ + trigger_error('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('unknown column "'. $defparts[1] .'" in "'. $table .'"', E_USER_WARNING); + return false; + } + + if (strstr($defparts[3], "NOT")) { + $notnull = 1; + } + else if (strstr($defparts[3], "DEFAULT")) { + $default = $defparts[4]; + + if (strstr($defparts[5], "NOT")) { + $notnull = 1; + } + } + + $schema['columns'][$defparts[0]]['name'] = $defparts[1]; + $schema['columns'][$defparts[0]]['type'] = $defparts[2]; + $schema['columns'][$defparts[0]]['notnull'] = $notnull ? 99 : 0; + $schema['columns'][$defparts[0]]['dflt_value'] = $default; + + // update mappings + $newcols[$defparts[0]] = $defparts[1]; + } + else{ + trigger_error('unknown column "'. $defparts[1] .'" in "'. $table .'"', E_USER_WARNING); + return false; + } + break; + + case 'drop': + if(sizeof($defparts) < 2){ + trigger_error('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['pk']); + break; + } + else { + // dropping a column + if($schema['columns'][$defparts[1]]){ + // update mappings + unset($schema['columns'][$defparts[1]]); + unset($schema['pk'][$defparts[1]]); + unset($newcols[$defparts[1]]); + _remove_col_index($schema, $defparts[1]); + } + else{ + trigger_error('unknown column "'. $defparts[1] .'" in "'. $table .'"', E_USER_WARNING); + return false; + } + } + break; + + default: + trigger_error('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 + $newColsSQL = implode(",", _build_cols_sql($schema)); + $createtesttableSQL = 'CREATE TABLE '. $tmpname . ' (' . $newColsSQL . ')'; + + sqlite_query($active_db, $createtesttableSQL); + if($error_code = sqlite_last_error($active_db)) { + echo sqlite_error_string($error_code); + 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 . ' (' . $newColsSQL . ')'; + $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); + } + + // recreate indices + $sqls = _get_indices_sql($schema); + foreach($sqls as $index_sql) { + if (variable_get('dev_query', 0)) { + $queries[] = array($index_sql, -1); + } + sqlite_query($active_db, $index_sql); + } + + 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('no such table: '. 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('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 _build_cols_sql($schema) { + $out_sql = array(); + foreach ($schema['columns'] as $col => $defs) { + $notnull = $defs['notnull'] ? 'NOT NULL' : ''; + $dflt_value = " DEFAULT '" . $defs['dflt_value'] . "'"; + $sql = $defs['name'] . " " . $defs['type'] . " " . $notnull . $dflt_value; + + $out_sql[] = $sql; + } + if (count($schema['pk']) > 0) { + $out_sql[] = "PRIMARY KEY (". implode(",", $schema['pk']) . ")"; + } + return $out_sql; +} + +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'] = $tbl_name; + $schema['columns'] = array(); + $schema['pk'] = array(); + while ($result && sqlite_has_more($result)) { + $col = sqlite_fetch_array($result, SQLITE_ASSOC); + $schema['columns'][$col['name']] = $col; + if ($col[pk]) { + $schema['pk'][$col['name']] = $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); + $entry = array(); + if (count($matches)) { + $expl = explode(",", $matches[1]); + if (count($expl)) { + foreach ($expl as $col_name) { + $entry['cols'][] = trim($col_name); + } + } + else { + $entry['cols'][] = trim($matches[1]); + } + } + $entry['unique'] = strstr($index['sql'], "UNIQUE") ? 1 : 0; + $entry['name'] = $index['name']; + $entry['sql'] = $index['sql']; + $schema['indices'][] = $entry; + } + return $schema; +} + +function _get_indices_sql($schema) { + $sql = array(); + foreach ($schema['indices'] as $index) { + $unique = $index['unique'] ? 'UNIQUE ' : ''; + $sql[] = 'CREATE '. $unique . 'INDEX ' . $index['name'] . ' ON ' . $schema['tbl_name'] . " (" . implode(",", $index['cols']) . ");"; + } + return $sql; +} + +function _remove_col_index(&$schema, $column) { + foreach ($schema['indices'] as $key => $index) { + if (isset($index['cols']) && $key = array_search($column, $index['cols']) !== FALSE) { + unset($index['cols'][$key]); + if (count($index['cols']) == 0) { + unset($schema['indices'][$key]); + } + } + } +} + +/** + * @} End of "ingroup database". + */ Index: includes/install.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/install.inc,v retrieving revision 1.22 diff -u -F^f -r1.22 install.inc --- includes/install.inc 7 Sep 2006 08:23:54 -0000 1.22 +++ includes/install.inc 14 Sep 2006 21:58:20 -0000 @@ -143,7 +143,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 14 Sep 2006 22:05:14 -0000 @@ -0,0 +1,122 @@ + $query, '%error' => $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. We tried inserting a value with the command %query and SQLite reported the following error: %error.', array('%query' => $query, '%error' => $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. We tried updating a value with the command %query and SQLite reported the following error: %error.', array('%query' => $query, '%error' => $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. We tried deleting a value with the command %query and SQLite reported the following error: %error.', array('%query' => $query, '%error' => $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. We tried dropping a table with the command %query and SQLite reported the following error %error.', array('%query' => $query, '%error' => $error)), 'error'); + $err = TRUE; + } + else { + $success[] = 'DROP'; + } + + if ($err) { + return FALSE; + } + + sqlite_close($connection); + return TRUE; +} + +function sqlite_settings_form_basic($profile, $install_locale, $settings_file, $db_url, $db_type, $db_prefix, $db_user, $db_pass, $db_host, $db_port, $db_path) { + // Database name + $form['db_path'] = array( + '#type' => 'textfield', + '#title' => st('Database path'), + '#default_value' => $db_path, + '#size' => 45, + '#maxlength' => 45, + '#required' => TRUE, + '#description' => st('The filename of the database your @drupal data will be stored in. The directory must exist, but the file will be automatically generated before @drupal is installed.', array('@drupal' => drupal_install_profile_name())), + ); + return $form; +} + +function sqlite_settings_form_validate($db_prefix, $db_type, $db_user, $db_pass, $db_host, $db_port, $db_path, $settings_file, $form = NULL) { + global $db_url; + echo $db_path; + $db_url = $db_type .'://'. $db_path; +} + +?> Index: modules/aggregator/aggregator.install =================================================================== RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.install,v retrieving revision 1.7 diff -u -F^f -r1.7 aggregator.install --- modules/aggregator/aggregator.install 1 Sep 2006 07:40:07 -0000 1.7 +++ modules/aggregator/aggregator.install 15 Sep 2006 11:30:31 -0000 @@ -113,6 +113,56 @@ function aggregator_install() { db_query("CREATE INDEX {aggregator_item}_fid_idx ON {aggregator_item} (fid)"); break; + case 'sqlite': + db_query("BEGIN"); + db_query("CREATE TABLE {aggregator_category} ( + cid INTEGER PRIMARY KEY, + title varchar(255) NOT NULL default '', + description longtext NOT NULL, + block tinyint(2) NOT NULL default '0', + UNIQUE (title) + );"); + + db_query("CREATE TABLE {aggregator_category_feed} ( + fid int(10) NOT NULL default '0', + cid int(10) NOT NULL default '0', + PRIMARY KEY (fid,cid) + );"); + + db_query("CREATE TABLE {aggregator_category_item} ( + iid int(10) NOT NULL default '0', + cid int(10) NOT NULL default '0', + PRIMARY KEY (iid,cid) + );"); + + db_query("CREATE TABLE {aggregator_feed} ( + fid INTEGER PRIMARY KEY, + title varchar(255) NOT NULL default '', + url varchar(255) NOT NULL default '', + refresh int(10) NOT NULL default '0', + checked int(10) NOT NULL default '0', + link varchar(255) NOT NULL default '', + description longtext NOT NULL default '', + image longtext NOT NULL default '', + etag varchar(255) NOT NULL default '', + modified int(10) NOT NULL default '0', + block tinyint(2) NOT NULL default '0', + UNIQUE (url), + UNIQUE (title) + );"); + + db_query("CREATE TABLE {aggregator_item} ( + iid INTEGER PRIMARY KEY, + fid int(10) NOT NULL default '0', + title varchar(255) NOT NULL default '', + link varchar(255) NOT NULL default '', + author varchar(255) NOT NULL default '', + description longtext NOT NULL, + timestamp int(11) default NULL + );"); + db_query("CREATE INDEX {aggregator_item}_fid ON {aggregator_item} (fid)"); + db_query("COMMIT"); + break; } } Index: modules/book/book.install =================================================================== RCS file: /cvs/drupal/drupal/modules/book/book.install,v retrieving revision 1.6 diff -u -F^f -r1.6 book.install --- modules/book/book.install 1 Sep 2006 07:40:08 -0000 1.6 +++ modules/book/book.install 15 Sep 2006 11:30:24 -0000 @@ -29,6 +29,19 @@ function book_install() { db_query("CREATE INDEX {book}_nid_idx ON {book} (nid)"); db_query("CREATE INDEX {book}_parent_idx ON {book} (parent)"); break; + case 'sqlite': + db_query("BEGIN"); + db_query("CREATE TABLE {book} ( + vid int(10) NOT NULL default '0', + nid int(10) NOT NULL default '0', + parent int(10) NOT NULL default '0', + weight tinyint(3) NOT NULL default '0', + PRIMARY KEY (vid) + );"); + db_query("CREATE INDEX {book}_nid ON {book}(nid);"); + db_query("CREATE INDEX {book}_parent ON {book}(parent);"); + db_query("COMMIT"); + break; } } Index: modules/contact/contact.install =================================================================== RCS file: /cvs/drupal/drupal/modules/contact/contact.install,v retrieving revision 1.5 diff -u -F^f -r1.5 contact.install --- modules/contact/contact.install 1 Sep 2006 07:40:08 -0000 1.5 +++ modules/contact/contact.install 15 Sep 2006 11:17:13 -0000 @@ -31,6 +31,17 @@ function contact_install() { UNIQUE (category) )"); break; + case 'sqlite': + db_query("CREATE TABLE {contact} ( + cid INTEGER PRIMARY KEY, + category varchar(255) NOT NULL default '', + recipients longtext NOT NULL default '', + reply longtext NOT NULL default '', + weight tinyint(3) NOT NULL default '0', + selected tinyint(1) NOT NULL default '0', + UNIQUE (category) + );"); + break; } } Index: modules/drupal/drupal.install =================================================================== RCS file: /cvs/drupal/drupal/modules/drupal/drupal.install,v retrieving revision 1.5 diff -u -F^f -r1.5 drupal.install --- modules/drupal/drupal.install 1 Sep 2006 07:40:08 -0000 1.5 +++ modules/drupal/drupal.install 15 Sep 2006 11:30:17 -0000 @@ -53,6 +53,31 @@ function drupal_install() { PRIMARY KEY (cid,name) )"); break; + + case 'sqlite': + db_query("BEGIN"); + db_query("CREATE TABLE {client} ( + cid INTEGER PRIMARY KEY, + link varchar(255) NOT NULL default '', + name varchar(128) NOT NULL default '', + mail varchar(128) NOT NULL default '', + slogan longtext NOT NULL, + mission longtext NOT NULL, + users int(10) NOT NULL default '0', + nodes int(10) NOT NULL default '0', + version varchar(35) NOT NULL default'', + created int(11) NOT NULL default '0', + changed int(11) NOT NULL default '0' + );"); + + db_query("CREATE TABLE {client_system} ( + cid int(10) NOT NULL default '0', + name varchar(255) NOT NULL default '', + type varchar(255) NOT NULL default '', + PRIMARY KEY (cid,name) + );"); + db_query("COMMIT"); + break; } } Index: modules/forum/forum.install =================================================================== RCS file: /cvs/drupal/drupal/modules/forum/forum.install,v retrieving revision 1.6 diff -u -F^f -r1.6 forum.install --- modules/forum/forum.install 1 Sep 2006 07:40:08 -0000 1.6 +++ modules/forum/forum.install 15 Sep 2006 11:30:13 -0000 @@ -27,6 +27,16 @@ function forum_install() { db_query("CREATE INDEX {forum}_nid_idx ON {forum} (nid)"); db_query("CREATE INDEX {forum}_tid_idx ON {forum} (tid)"); break; + case 'sqlite': + db_query("CREATE TABLE {forum} ( + nid int(10) NOT NULL default '0', + vid int(10) NOT NULL default '0', + tid int(10) NOT NULL default '0', + PRIMARY KEY (vid) + );"); + db_query("CREATE INDEX {forum}_tid ON {forum}(tid);"); + db_query("CREATE INDEX {forum}_nid ON {forum}(nid);"); + break; } } Index: modules/locale/locale.install =================================================================== RCS file: /cvs/drupal/drupal/modules/locale/locale.install,v retrieving revision 1.6 diff -u -F^f -r1.6 locale.install --- modules/locale/locale.install 1 Sep 2006 07:40:08 -0000 1.6 +++ modules/locale/locale.install 15 Sep 2006 11:30:01 -0000 @@ -69,6 +69,36 @@ function locale_install() { db_query("CREATE INDEX {locales_target}_plural_idx ON {locales_target} (plural)"); db_query("CREATE INDEX {locales_source}_source_idx ON {locales_source} (source)"); break; + case 'sqlite': + db_query("BEGIN"); + db_query("CREATE TABLE {locales_meta} ( + locale varchar(12) NOT NULL default '', + name varchar(64) NOT NULL default '', + enabled int(2) NOT NULL default '0', + isdefault int(2) NOT NULL default '0', + plurals int(1) NOT NULL default '0', + formula varchar(128) NOT NULL default '', + PRIMARY KEY (locale) + );"); + db_query("CREATE TABLE {locales_source} ( + lid INTEGER PRIMARY KEY, + location varchar(255) NOT NULL default '', + source blob NOT NULL + );"); + db_query("CREATE INDEX {locales_source}_source ON {locales_source} (source)"); + db_query("CREATE TABLE {locales_target} ( + lid int(11) NOT NULL default '0', + translation blob NOT NULL, + locale varchar(12) NOT NULL default '', + plid int(11) NOT NULL default '0', + plural int(1) NOT NULL default '0' + );"); + db_query("CREATE INDEX {locales_target}_lid ON {locales_target}(lid);"); + db_query("CREATE INDEX {locales_target}_locale ON {locales_target}(locale);"); + db_query("CREATE INDEX {locales_target}_plid ON {locales_target}(plid);"); + db_query("CREATE INDEX {locales_target}_plural ON {locales_target}(plural);"); + db_query("COMMIT"); + break; } db_query("INSERT INTO {locales_meta} (locale, name, enabled, isdefault) VALUES ('en', 'English', '1', '1')"); } Index: modules/poll/poll.install =================================================================== RCS file: /cvs/drupal/drupal/modules/poll/poll.install,v retrieving revision 1.7 diff -u -F^f -r1.7 poll.install --- modules/poll/poll.install 1 Sep 2006 07:40:08 -0000 1.7 +++ modules/poll/poll.install 15 Sep 2006 11:29:58 -0000 @@ -64,6 +64,35 @@ function poll_install() { )"); db_query("CREATE INDEX {poll_choices}_nid_idx ON {poll_choices} (nid)"); break; + case 'sqlite': + db_query("BEGIN"); + db_query("CREATE TABLE {poll} ( + nid int(10) NOT NULL default '0', + runtime int(10) NOT NULL default '0', + active int(2) NOT NULL default '0', + PRIMARY KEY (nid) + );"); + + db_query("CREATE TABLE {poll_votes} ( + nid int(10) NOT NULL, + uid int(10) NOT NULL default 0, + hostname varchar(128) NOT NULL default '' + );"); + + db_query("CREATE INDEX {poll_votes}_nid ON {poll_votes}(nid);"); + db_query("CREATE INDEX {poll_votes}_uid ON {poll_votes}(uid);"); + db_query("CREATE INDEX {poll_votes}_hostname ON {poll_votes}(hostname);"); + + db_query("CREATE TABLE {poll_choices} ( + chid INTEGER PRIMARY KEY, + nid int(10) NOT NULL default '0', + chtext varchar(128) NOT NULL default '', + chvotes int(6) NOT NULL default '0', + chorder int(2) NOT NULL default '0' + );"); + db_query("CREATE INDEX {poll_choices}_nid ON {poll_choices}(nid);"); + db_query("COMMIT"); + break; } } Index: modules/profile/profile.install =================================================================== RCS file: /cvs/drupal/drupal/modules/profile/profile.install,v retrieving revision 1.7 diff -u -F^f -r1.7 profile.install --- modules/profile/profile.install 1 Sep 2006 07:40:08 -0000 1.7 +++ modules/profile/profile.install 15 Sep 2006 11:29:51 -0000 @@ -64,6 +64,36 @@ function profile_install() { db_query("CREATE INDEX {profile_values}_uid_idx ON {profile_values} (uid)"); db_query("CREATE INDEX {profile_values}_fid_idx ON {profile_values} (fid)"); break; + + case 'sqlite': + db_query("BEGIN"); + db_query("CREATE TABLE {profile_fields} ( + fid INTEGER PRIMARY KEY, + title varchar(255) default NULL, + name varchar(128) default NULL, + explanation TEXT default NULL, + category varchar(255) default NULL, + page varchar(255) default NULL, + type varchar(128) default NULL, + weight tinyint(1) DEFAULT '0' NOT NULL, + required tinyint(1) DEFAULT '0' NOT NULL, + register tinyint(1) DEFAULT '0' NOT NULL, + visibility tinyint(1) DEFAULT '0' NOT NULL, + autocomplete tinyint(1) DEFAULT '0' NOT NULL, + options text, + UNIQUE (name) + );"); + db_query("CREATE INDEX {profile_fields_category} ON {profile_fields}(category);"); + + db_query("CREATE TABLE {profile_values ( + fid int(10) default '0', + uid int(10) default '0', + value text + );"); + db_query("CREATE INDEX {profile_values}_uid ON {profile_values}(uid);"); + db_query("CREATE INDEX {profile_values}_fid ON {profile_values}(fid);"); + db_query("COMMIT"); + break; } } Index: modules/search/search.install =================================================================== RCS file: /cvs/drupal/drupal/modules/search/search.install,v retrieving revision 1.6 diff -u -F^f -r1.6 search.install --- modules/search/search.install 1 Sep 2006 07:40:08 -0000 1.6 +++ modules/search/search.install 15 Sep 2006 11:29:47 -0000 @@ -59,6 +59,35 @@ function search_install() { PRIMARY KEY (word) )"); break; + + case 'sqlite': + db_query("BEGIN"); + db_query("CREATE TABLE {search_dataset} ( + sid int(10) NOT NULL default '0', + type varchar(16) default NULL, + data longtext NOT NULL + );"); + db_query("CREATE INDEX {search_dataset}_sid ON {search_dataset}(sid, type);"); + + db_query("CREATE TABLE {search_index} ( + word varchar(50) NOT NULL default '', + sid int(10) NOT NULL default '0', + type varchar(16) default NULL, + fromsid int(10) NOT NULL default '0', + fromtype varchar(16) default NULL, + score float default NULL + );"); + db_query("CREATE INDEX {search_index}_sid ON {search_index}(sid);"); + db_query("CREATE INDEX {search_index}_fromsid ON {search_index}(fromsid);"); + db_query("CREATE INDEX {search_index}_word ON {search_index}(word);"); + + db_query("CREATE TABLE {search_total} ( + word varchar(50) NOT NULL default '', + count float default NULL, + PRIMARY KEY (word) + );"); + db_query("COMMIT"); + break; } } Index: modules/statistics/statistics.install =================================================================== RCS file: /cvs/drupal/drupal/modules/statistics/statistics.install,v retrieving revision 1.6 diff -u -F^f -r1.6 statistics.install --- modules/statistics/statistics.install 1 Sep 2006 07:40:08 -0000 1.6 +++ modules/statistics/statistics.install 15 Sep 2006 11:28:16 -0000 @@ -37,6 +37,21 @@ function statistics_install() { )"); db_query("CREATE INDEX {accesslog}_accesslog_timestamp_idx ON {accesslog} (timestamp)"); break; + + case 'sqlite': + db_query("CREATE TABLE {accesslog} ( + aid INTEGER PRIMARY KEY, + sid varchar(32) NOT NULL default '', + title varchar(255) default NULL, + path varchar(255) default NULL, + url varchar(255) default NULL, + hostname varchar(128) default NULL, + uid int(10) default '0', + timer int(10) NOT NULL default '0', + timestamp int(11) NOT NULL default '0' + );"); + db_query("CREATE INDEX {accesslog_timestamp} ON {accesslog}(timestamp ASC);"); + break; } } Index: modules/system/system.install =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.install,v retrieving revision 1.29 diff -u -F^f -r1.29 system.install --- modules/system/system.install 11 Sep 2006 06:29:03 -0000 1.29 +++ modules/system/system.install 15 Sep 2006 11:25:35 -0000 @@ -975,6 +975,425 @@ function system_install() { PRIMARY KEY (wid) )"); break; + + case 'sqlite': + db_query("BEGIN"); + db_query("CREATE TABLE {access} ( + aid INTEGER PRIMARY KEY, + mask varchar(255) NOT NULL default '', + type varchar(255) NOT NULL default '', + status tinyint(2) NOT NULL default '0' + );"); + + db_query("CREATE TABLE {authmap} ( + aid INTEGER PRIMARY KEY, + uid int(10) NOT NULL default '0', + authname varchar(128) NOT NULL default '', + module varchar(128) NOT NULL default '' + );"); + db_query("CREATE UNIQUE INDEX authmap_authname ON {authmap} (authname);"); + + db_query("CREATE TABLE {blocks} ( + module varchar(64) DEFAULT '' NOT NULL, + delta varchar(32) NOT NULL default '0', + theme varchar(255) NOT NULL default '', + status tinyint(2) DEFAULT '0' NOT NULL, + weight tinyint(1) DEFAULT '0' NOT NULL, + region varchar(64) DEFAULT 'left' NOT NULL, + custom tinyint(2) DEFAULT '0' NOT NULL, + throttle tinyint(1) DEFAULT '0' NOT NULL, + visibility tinyint(1) DEFAULT '0' NOT NULL, + pages text DEFAULT '' NOT NULL, + title varchar(64) DEFAULT '' NOT NULL + );"); + + db_query("CREATE TABLE {boxes} ( + bid INTEGER PRIMARY KEY, + title varchar(64) NOT NULL default '', + body longtext, + info varchar(128) NOT NULL default '', + format int(4) NOT NULL default '0' + );"); + db_query("CREATE UNIQUE INDEX boxes_info ON {boxes} (info);"); + + db_query("CREATE TABLE {cache} ( + cid varchar(255) NOT NULL default '', + data longblob, + expire int(11) NOT NULL default '0', + created int(11) NOT NULL default '0', + headers text, + PRIMARY KEY (cid) + );"); + db_query("CREATE INDEX {cache}_expire ON {cache}(expire);"); + + db_query("CREATE TABLE {cache_filter} ( + cid varchar(255) NOT NULL default '', + data longblob, + expire int NOT NULL default '0', + created int NOT NULL default '0', + headers text, + PRIMARY KEY (cid) + )"); + db_query("CREATE INDEX {cache_filter}_expire ON {cache_filter}(expire);"); + + db_query("CREATE TABLE {cache_menu} ( + cid varchar(255) NOT NULL default '', + data longblob, + expire int NOT NULL default '0', + created int NOT NULL default '0', + headers text, + PRIMARY KEY (cid) + )"); + db_query("CREATE INDEX {cache_menu}_expire ON {cache_menu}(expire);"); + + db_query("CREATE TABLE {cache_page} ( + cid varchar(255) NOT NULL default '', + data longblob, + expire int NOT NULL default '0', + created int NOT NULL default '0', + headers text, + PRIMARY KEY (cid) + )"); + db_query("CREATE INDEX {cache_page}_expire ON {cache_page}(expire);"); + + db_query("CREATE TABLE {comments} ( + cid INTEGER PRIMARY KEY, + pid int(10) NOT NULL default '0', + nid int(10) NOT NULL default '0', + uid int(10) NOT NULL default '0', + subject varchar(64) NOT NULL default '', + comment longtext NOT NULL, + hostname varchar(128) NOT NULL default '', + timestamp int(11) NOT NULL default '0', + score mediumint(9) NOT NULL default '0', + status tinyint(3) NOT NULL default '0', + format int(4) NOT NULL default '0', + thread varchar(255) NOT NULL, + users longtext, + name varchar(60) default NULL, + mail varchar(64) default NULL, + homepage varchar(255) default NULL + );"); + db_query("CREATE INDEX {comments}_nid ON {comments}(nid);"); + + db_query("CREATE TABLE {node_comment_statistics} ( + nid INTEGER PRIMARY KEY, + last_comment_timestamp int(11) NOT NULL default '0', + last_comment_name varchar(60) default NULL, + last_comment_uid int(10) NOT NULL default '0', + comment_count int(10) NOT NULL default '0' + );"); + db_query("CREATE INDEX node_comment_timestamp ON {node_comment_statistics}(last_comment_timestamp);"); + + db_query("CREATE TABLE {files} ( + fid int(10) NOT NULL default 0, + nid int(10) NOT NULL default 0, + filename varchar(255) NOT NULL default '', + filepath varchar(255) NOT NULL default '', + filemime varchar(255) NOT NULL default '', + filesize int(10) NOT NULL default 0, + PRIMARY KEY (fid) + );"); + + db_query("CREATE TABLE {file_revisions} ( + fid int(10) NOT NULL default 0, + vid int(10) NOT NULL default 0, + description varchar(255) NOT NULL default '', + list tinyint(1) NOT NULL default 0, + PRIMARY KEY (fid, vid) + );"); + db_query("CREATE INDEX {file_revisions}_vid ON {file_revisions}(vid);"); + + db_query("CREATE TABLE {filter_formats} ( + format INTEGER PRIMARY KEY, + name varchar(255) NOT NULL default '', + roles varchar(255) NOT NULL default '', + cache tinyint(2) NOT NULL default '0', + UNIQUE (name) + );"); + + db_query("CREATE TABLE {filters} ( + format int(4) NOT NULL default '0', + module varchar(64) NOT NULL default '', + delta tinyint(2) DEFAULT '0' NOT NULL, + weight tinyint(2) DEFAULT '0' NOT NULL + );"); + db_query("CREATE INDEX {filters}_weight ON {filters}(weight);"); + + db_query("CREATE TABLE {flood} ( + event varchar(64) NOT NULL default '', + hostname varchar(128) NOT NULL default '', + timestamp int(11) NOT NULL default '0' + );"); + + db_query("CREATE TABLE {history} ( + uid int(10) NOT NULL default '0', + nid int(10) NOT NULL default '0', + timestamp int(11) NOT NULL default '0', + PRIMARY KEY (uid,nid) + );"); + + db_query("CREATE TABLE {menu} ( + mid int(10) NOT NULL default '0', + pid int(10) NOT NULL default '0', + path varchar(255) NOT NULL default '', + title varchar(255) NOT NULL default '', + description varchar(255) NOT NULL default '', + weight tinyint(4) NOT NULL default '0', + type int(2) NOT NULL default '0', + PRIMARY KEY (mid) + );"); + + db_query("CREATE TABLE {node} ( + nid INTEGER, + vid int(10) NOT NULL default '0', + type varchar(32) NOT NULL default '', + title varchar(128) NOT NULL default '', + uid int(10) NOT NULL default '0', + status int(4) NOT NULL default '1', + created int(11) NOT NULL default '0', + changed int(11) NOT NULL default '0', + comment int(2) NOT NULL default '0', + promote int(2) NOT NULL default '0', + moderate int(2) NOT NULL default '0', + sticky int(2) NOT NULL default '0', + PRIMARY KEY (nid, vid), + UNIQUE (vid) + );"); + db_query("CREATE INDEX {node}_nid ON {node}(nid);"); + db_query("CREATE INDEX {node}_type_idx ON {node}(type);"); + db_query("CREATE INDEX {node}_title_type ON {node}(title,type);"); + db_query("CREATE INDEX {node}_status ON {node}(status);"); + db_query("CREATE INDEX {node}_uid ON {node}(uid);"); + db_query("CREATE INDEX {node}_moderate ON {node}(moderate);"); + db_query("CREATE INDEX {node}_promote__status ON {node}(promote, status);"); + db_query("CREATE INDEX {node}_created ON {node}(created);"); + db_query("CREATE INDEX {node}_changed ON {node}(changed);"); + db_query("CREATE INDEX {node}_status__type__nid ON {node}(status, type, nid);"); + + db_query("CREATE TABLE {node_access} ( + nid int(10) NOT NULL default '0', + gid int(10) NOT NULL default '0', + realm varchar(255) NOT NULL default '', + grant_view tinyint(1) NOT NULL default '0', + grant_update tinyint(1) NOT NULL default '0', + grant_delete tinyint(1) NOT NULL default '0', + PRIMARY KEY (nid,gid,realm) + );"); + + db_query("CREATE TABLE {node_revisions} ( + nid int(10) NOT NULL, + vid int(10) NOT NULL, + uid int(10) NOT NULL default '0', + title varchar(128) NOT NULL default '', + body longtext NOT NULL default '', + teaser longtext NOT NULL default '', + log longtext NOT NULL default '', + timestamp int(11) NOT NULL default '0', + format int(4) NOT NULL default '0', + PRIMARY KEY (vid) + );"); + db_query("CREATE INDEX {node_revisions}_nid ON {node_revisions}(nid);"); + db_query("CREATE INDEX {node_revisions}_uid ON {node_revisions}(uid);"); + + db_query("CREATE TABLE {node_type} ( + type varchar(32) NOT NULL, + name varchar(255) NOT NULL default '', + module varchar(255) NOT NULL, + description mediumtext NOT NULL, + help mediumtext NOT NULL, + has_title tinyint NOT NULL, + title_label varchar(255) NOT NULL default '', + has_body tinyint NOT NULL, + body_label varchar(255) NOT NULL default '', + min_word_count smallint NOT NULL, + custom tinyint NOT NULL DEFAULT '0', + modified tinyint NOT NULL DEFAULT '0', + locked tinyint NOT NULL DEFAULT '0', + orig_type varchar(255) NOT NULL default '', + PRIMARY KEY (type) + )"); + + db_query("CREATE TABLE {url_alias} ( + pid INTEGER PRIMARY KEY, + src varchar(128) NOT NULL default '', + dst varchar(128) NOT NULL default '', + UNIQUE (dst) + );"); + db_query("CREATE INDEX url_alias_src ON url_alias(src);"); + + db_query("CREATE TABLE {permission} ( + rid int(10) NOT NULL default '0', + perm longtext, + tid int(10) NOT NULL default '0' + );"); + db_query("CREATE INDEX {permission}_rid ON {permission}(rid);"); + + + db_query("CREATE TABLE {role} ( + rid INTEGER PRIMARY KEY, + name varchar(32) NOT NULL default '', + UNIQUE (name) + );"); + + db_query("CREATE TABLE {blocks_roles} ( + module varchar(64) NOT NULL, + delta varchar(32) NOT NULL, + rid int NOT NULL, + PRIMARY KEY (module, delta, rid) + )"); + + db_query("CREATE TABLE {sessions} ( + uid int(10) NOT NULL, + sid varchar(32) NOT NULL default '', + hostname varchar(128) NOT NULL default '', + timestamp int(11) NOT NULL default '0', + cache int(11) NOT NULL default '0', + session longtext, + PRIMARY KEY (sid) + );"); + db_query("CREATE INDEX {session}_uid ON {sessions}(uid);"); + db_query("CREATE INDEX {session}_timestamp ON {sessions}(timestamp);"); + + db_query("CREATE TABLE {sequences} ( + name varchar(255) NOT NULL default '', + id int(10) NOT NULL default '0', + PRIMARY KEY (name) + );"); + + db_query("CREATE TABLE {node_counter} ( + nid int(10) NOT NULL default '0', + totalcount bigint(20) NOT NULL default '0', + daycount mediumint(8) NOT NULL default '0', + timestamp int(11) NOT NULL default '0', + PRIMARY KEY (nid) + );"); + db_query("CREATE INDEX {node_counter}_totalcount ON {node_counter}(totalcount);"); + db_query("CREATE INDEX {node_counter}_daycount ON {node_counter}(daycount);"); + db_query("CREATE INDEX {node_counter}_timestamp ON {node_counter}(timestamp);"); + + db_query("CREATE TABLE {system} ( + filename varchar(255) NOT NULL default '', + name varchar(255) NOT NULL default '', + type varchar(255) NOT NULL default '', + description varchar(255) NOT NULL default '', + status int(2) NOT NULL default '0', + throttle tinyint(1) DEFAULT '0' NOT NULL, + bootstrap int(2) NOT NULL default '0', + schema_version smallint(3) NOT NULL default -1, + weight int(2) NOT NULL default '0', + PRIMARY KEY (filename) + );"); + db_query("CREATE INDEX {system}_weight on {system}(weight);"); + + db_query("CREATE TABLE {term_data} ( + tid INTEGER PRIMARY KEY, + vid int(10) NOT NULL default '0', + name varchar(255) NOT NULL default '', + description longtext, + weight tinyint(4) NOT NULL default '0' + );"); + db_query("CREATE INDEX term_data_vid ON term_data(vid);"); + + db_query("CREATE TABLE {term_hierarchy} ( + tid int(10) NOT NULL default '0', + parent int(10) NOT NULL default '0', + PRIMARY KEY (tid, parent) + );"); + db_query("CREATE INDEX {term_hierarchy}_tid ON {term_hierarchy}(tid);"); + db_query("CREATE INDEX {term_hierarchy}_parent ON {term_hierarchy}(parent);"); + + db_query("CREATE TABLE {term_node} ( + nid int(10) NOT NULL default '0', + tid int(10) NOT NULL default '0', + PRIMARY KEY (tid,nid) + );"); + db_query("CREATE INDEX {term_node}_nid ON {term_node}(nid);"); + db_query("CREATE INDEX {term_node}_tid ON {term_node}(tid);"); + + db_query("CREATE TABLE {term_relation} ( + tid1 int(10) NOT NULL default '0', + tid2 int(10) NOT NULL default '0' + );"); + db_query("CREATE INDEX {term_relation}_tid1 ON {term_relation}(tid1);"); + db_query("CREATE INDEX {term_relation}_tid2 ON {term_relation}(tid2);"); + + db_query("CREATE TABLE {term_synonym} ( + tid int(10) NOT NULL default '0', + name varchar(255) NOT NULL default '' + );"); + db_query("CREATE INDEX {term_synonym}_tid ON {term_synonym}(tid);"); + db_query("CREATE INDEX {term_synonym}_name ON {term_synonym}(name);"); + + db_query("CREATE TABLE {users} ( + uid INTEGER PRIMARY KEY, + name varchar(60) NOT NULL default '', + pass varchar(32) NOT NULL default '', + mail varchar(64) default '', + mode tinyint(1) NOT NULL default '0', + sort tinyint(1) default '0', + threshold tinyint(1) default '0', + theme varchar(255) NOT NULL default '', + signature varchar(255) NOT NULL default '', + created int(11) NOT NULL default '0', + access int(11) NOT NULL default '0', + login int(11) NOT NULL default '0', + status tinyint(4) NOT NULL default '0', + timezone varchar(8) default NULL, + language varchar(12) NOT NULL default '', + picture varchar(255) NOT NULL DEFAULT '', + init varchar(64) default '', + data longtext, + UNIQUE (name) + );"); + db_query("CREATE INDEX {users}_access_idx ON {users} (access);"); + + db_query("CREATE TABLE {users_roles} ( + uid int(10) NOT NULL default '0', + rid int(10) NOT NULL default '0', + PRIMARY KEY (uid, rid) + );"); + + db_query("CREATE TABLE {variable} ( + name varchar(48) NOT NULL default '', + value longtext NOT NULL, + PRIMARY KEY (name) + );"); + + db_query("CREATE TABLE {vocabulary} ( + vid INTEGER PRIMARY KEY, + name varchar(255) NOT NULL default '', + description longtext, + help varchar(255) NOT NULL default '', + relations tinyint(3) NOT NULL default '0', + hierarchy tinyint(3) NOT NULL default '0', + multiple tinyint(3) NOT NULL default '0', + required tinyint(3) NOT NULL default '0', + tags tinyint(3) NOT NULL default '0', + module varchar(255) NOT NULL default '', + weight tinyint(4) NOT NULL default '0' + );"); + + db_query("CREATE TABLE {vocabulary_node_types} ( + vid int(10) NOT NULL DEFAULT '0', + type varchar(32) NOT NULL DEFAULT '', + PRIMARY KEY (vid, type) + );"); + + db_query("CREATE TABLE {watchdog} ( + wid INTEGER PRIMARY KEY, + uid int(10) NOT NULL default '0', + type varchar(16) NOT NULL default '', + message longtext NOT NULL, + severity tinyint(3) NOT NULL default '0', + link varchar(255) NOT NULL default '', + location varchar(128) NOT NULL default '', + referer varchar(128) NOT NULL default '', + hostname varchar(128) NOT NULL default '', + timestamp int(11) NOT NULL default '0' + );"); + db_query("COMMIT"); + break; } db_query("INSERT INTO {system} (filename, name, type, description, status, throttle, bootstrap, schema_version) VALUES ('themes/engines/phptemplate/phptemplate.engine', 'phptemplate', 'theme_engine', '', 1, 0, 0, 0)");