From 6c09d9e0f8a22c77ff6ebf83e4e44de3aeb6be3e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 12 Nov 2011 18:06:07 +0100 Subject: [PATCH 01/10] some fixes in the sqlite3 driver --- lib/MDB2/Driver/Manager/sqlite3.php | 2 +- lib/MDB2/Driver/Reverse/sqlite3.php | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/MDB2/Driver/Manager/sqlite3.php b/lib/MDB2/Driver/Manager/sqlite3.php index c5c19a90fb..7e30755fc3 100644 --- a/lib/MDB2/Driver/Manager/sqlite3.php +++ b/lib/MDB2/Driver/Manager/sqlite3.php @@ -798,7 +798,7 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common return $db; } - $query = "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL ORDER BY name"; + $query = "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL AND name!='sqlite_sequence' ORDER BY name"; $table_names = $db->queryCol($query); if (PEAR::isError($table_names)) { return $table_names; diff --git a/lib/MDB2/Driver/Reverse/sqlite3.php b/lib/MDB2/Driver/Reverse/sqlite3.php index d5595da84c..33e5b59026 100644 --- a/lib/MDB2/Driver/Reverse/sqlite3.php +++ b/lib/MDB2/Driver/Reverse/sqlite3.php @@ -69,7 +69,7 @@ class MDB2_Driver_Reverse_sqlite3 extends MDB2_Driver_Reverse_Common return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, 'unexpected empty table column definition list', __FUNCTION__); } - $regexp = '/^\s*([^\s]+) +(CHAR|VARCHAR|VARCHAR2|TEXT|BOOLEAN|SMALLINT|INT|INTEGER|DECIMAL|BIGINT|DOUBLE|FLOAT|DATETIME|DATE|TIME|LONGTEXT|LONGBLOB)( ?\(([1-9][0-9]*)(:([1-9][0-9]*))?\))?( NULL| NOT NULL)?( UNSIGNED)?( NULL| NOT NULL)?( PRIMARY KEY)?( DEFAULT (\'[^\']*\'|[^ ]+))?( NULL| NOT NULL)?( PRIMARY KEY)?(\s*\-\-.*)?$/i'; + $regexp = '/^\s*([^\s]+) +(CHAR|VARCHAR|VARCHAR2|TEXT|BOOLEAN|SMALLINT|INT|INTEGER|DECIMAL|BIGINT|DOUBLE|FLOAT|DATETIME|DATE|TIME|LONGTEXT|LONGBLOB)( ?\(([1-9][0-9]*)(:([1-9][0-9]*))?\))?( NULL| NOT NULL)?( UNSIGNED)?( NULL| NOT NULL)?( PRIMARY KEY)?( AUTOINCREMENT)?( DEFAULT (\'[^\']*\'|[^ ]+))?( NULL| NOT NULL)?( PRIMARY KEY)?(\s*\-\-.*)?$/i'; $regexp2 = '/^\s*([^ ]+) +(PRIMARY|UNIQUE|CHECK)$/i'; for ($i=0, $j=0; $i<$count; ++$i) { if (!preg_match($regexp, trim($column_sql[$i]), $matches)) { @@ -90,11 +90,16 @@ class MDB2_Driver_Reverse_sqlite3 extends MDB2_Driver_Reverse_Common if (isset($matches[8]) && strlen($matches[8])) { $columns[$j]['unsigned'] = true; } - if (isset($matches[9]) && strlen($matches[9])) { + if (isset($matches[10]) && strlen($matches[10])) { $columns[$j]['autoincrement'] = true; + $columns[$j]['notnull']=true; } - if (isset($matches[12]) && strlen($matches[12])) { - $default = $matches[12]; + if (isset($matches[10]) && strlen($matches[10])) { + $columns[$j]['autoincrement'] = true; + $columns[$j]['notnull']=true; + } + if (isset($matches[13]) && strlen($matches[13])) { + $default = $matches[13]; if (strlen($default) && $default[0]=="'") { $default = str_replace("''", "'", substr($default, 1, strlen($default)-2)); } @@ -107,8 +112,8 @@ class MDB2_Driver_Reverse_sqlite3 extends MDB2_Driver_Reverse_Common $columns[$j]['notnull'] = ($matches[7] === ' NOT NULL'); } else if (isset($matches[9]) && strlen($matches[9])) { $columns[$j]['notnull'] = ($matches[9] === ' NOT NULL'); - } else if (isset($matches[13]) && strlen($matches[13])) { - $columns[$j]['notnull'] = ($matches[13] === ' NOT NULL'); + } else if (isset($matches[14]) && strlen($matches[14])) { + $columns[$j]['notnull'] = ($matches[14] === ' NOT NULL'); } ++$j; } From 91a9688d0742b5c1af7d0b52da7a57e49e1e3e45 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 13 Nov 2011 16:06:29 +0100 Subject: [PATCH 02/10] minor changes to mysql setup --- lib/setup.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/setup.php b/lib/setup.php index b53c626c9a..d454c17599 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -160,8 +160,8 @@ class OC_Setup { //add prefix to the postgresql user name to prevent collissions $dbusername='oc_'.$username; - //hash the password so we don't need to store the admin config in the config file - $dbpassword=md5(time().$password); + //create a new password so we don't need to store the admin config in the config file + $dbpassword=md5(time()); self::pg_createDBUser($dbusername, $dbpassword, $connection); @@ -221,7 +221,7 @@ class OC_Setup { } public static function createDatabase($name,$user,$connection) { - //we cant user OC_BD functions here because we need to connect as the administrative user. + //we cant use OC_BD functions here because we need to connect as the administrative user. $query = "CREATE DATABASE IF NOT EXISTS `$name`"; $result = mysql_query($query, $connection); if(!$result) { @@ -243,7 +243,7 @@ class OC_Setup { } public static function pg_createDatabase($name,$user,$connection) { - //we cant user OC_BD functions here because we need to connect as the administrative user. + //we cant use OC_BD functions here because we need to connect as the administrative user. $query = "CREATE DATABASE $name OWNER $user"; $result = pg_query($connection, $query); if(!$result) { From 9a4e37483b9c6d7c6e287a9c95a408fc0249e8f9 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 13 Nov 2011 16:08:47 +0100 Subject: [PATCH 03/10] small fix in sqlite3 driver --- lib/MDB2/Driver/Manager/sqlite3.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/MDB2/Driver/Manager/sqlite3.php b/lib/MDB2/Driver/Manager/sqlite3.php index 7e30755fc3..71b9597d20 100644 --- a/lib/MDB2/Driver/Manager/sqlite3.php +++ b/lib/MDB2/Driver/Manager/sqlite3.php @@ -168,9 +168,6 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common if (PEAR::isError($query_fields)) { return $query_fields; } - if (!empty($options['primary'])) { - $query_fields.= ', PRIMARY KEY ('.implode(', ', array_keys($options['primary'])).')'; - } if (!empty($options['foreign_keys'])) { foreach ($options['foreign_keys'] as $fkname => $fkdef) { if (empty($fkdef)) { From ecf6f2ca2f74abbfdc72788c502ef5a015dc890a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 13 Nov 2011 16:16:21 +0100 Subject: [PATCH 04/10] automatically upgrade the main database on version number increase (doesnt work with sqlite for now) --- lib/base.php | 10 ++++++++-- lib/db.php | 9 ++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/base.php b/lib/base.php index 0954e3615b..803c0118e2 100644 --- a/lib/base.php +++ b/lib/base.php @@ -152,6 +152,12 @@ class OC{ } } + $installedVersion=OC_Config::getValue('version','0.0.0'); + $currentVersion=implode('.',OC_Util::getVersion()); + if (version_compare($currentVersion, $installedVersion, '>')) { + OC_DB::updateDbFromStructure('../db_structure.xml'); + } + ini_set('session.cookie_httponly','1;'); session_start(); @@ -230,8 +236,6 @@ if( !isset( $RUNTIME_NOAPPS )){ $RUNTIME_NOAPPS = false; } -OC::init(); - if(!function_exists('get_temp_dir')) { function get_temp_dir() { if( $temp=ini_get('upload_tmp_dir') ) return $temp; @@ -247,6 +251,8 @@ if(!function_exists('get_temp_dir')) { } } +OC::init(); + require_once('fakedirstream.php'); diff --git a/lib/db.php b/lib/db.php index c7085a975e..05ed8398b7 100644 --- a/lib/db.php +++ b/lib/db.php @@ -338,7 +338,6 @@ class OC_DB { * @param $file file to read structure from */ public static function updateDbFromStructure($file){ - $CONFIG_DBNAME = OC_Config::getValue( "dbname", "owncloud" ); $CONFIG_DBTABLEPREFIX = OC_Config::getValue( "dbtableprefix", "oc_" ); $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" ); @@ -347,17 +346,17 @@ class OC_DB { // read file $content = file_get_contents( $file ); + $previousSchema = self::$schema->getDefinitionFromDatabase(); + // Make changes and save them to a temporary file $file2 = tempnam( get_temp_dir(), 'oc_db_scheme_' ); - $content = str_replace( '*dbname*', $CONFIG_DBNAME, $content ); + $content = str_replace( '*dbname*', $previousSchema['name'], $content ); $content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content ); if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite doesn't $content = str_replace( '0000-00-00 00:00:00', 'CURRENT_TIMESTAMP', $content ); } file_put_contents( $file2, $content ); - $previousSchema = self::$schema->getDefinitionFromDatabase(); - $op = $schema->updateDatabase($file2, $previousSchema, array(), false); - + $op = self::$schema->updateDatabase($file2, $previousSchema, array(), false); if (PEAR::isError($op)) { $error = $op->getMessage(); OC_Log::write('core','Failed to update database structure ('.$error.')',OC_Log::FATAL); From 09a53170a309677b344b25d9820ef038a0e87929 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 15 Nov 2011 15:58:12 +0100 Subject: [PATCH 05/10] fixes in the sqlite manager driver --- lib/MDB2/Driver/Manager/sqlite3.php | 72 ++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/lib/MDB2/Driver/Manager/sqlite3.php b/lib/MDB2/Driver/Manager/sqlite3.php index 71b9597d20..a6fde69d6c 100644 --- a/lib/MDB2/Driver/Manager/sqlite3.php +++ b/lib/MDB2/Driver/Manager/sqlite3.php @@ -531,9 +531,26 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common return MDB2_OK; } + if (empty($changes['remove']) and empty($changes['rename']) and empty($changes['change']) ){//if only rename or add changes are required, we can use ALTER TABLE + $query = ''; + if (!empty($changes['name'])) { + $change_name = $db->quoteIdentifier($changes['name'], true); + $query = 'RENAME TO ' . $change_name; + $db->exec("ALTER TABLE $name $query"); + } + + if (!empty($changes['add']) && is_array($changes['add'])) { + foreach ($changes['add'] as $field_name => $field) { + $query= 'ADD ' . $db->getDeclaration($field['type'], $field_name, $field); + $db->exec("ALTER TABLE $name $query"); + } + } + return MDB2_OK; + } + $db->loadModule('Reverse', null, true); - // actually sqlite 2.x supports no ALTER TABLE at all .. so we emulate it + // for other operations we need to emulate them with sqlite3 $fields = $db->manager->listTableFields($name); if (PEAR::isError($fields)) { return $fields; @@ -633,16 +650,10 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common } } + //rename the old table so we can create the new one + $db->exec("ALTER TABLE $name RENAME TO __$name"); $data = null; - if (!empty($select_fields)) { - $query = 'SELECT '.implode(', ', $select_fields).' FROM '.$db->quoteIdentifier($name, true); - $data = $db->queryAll($query, null, MDB2_FETCHMODE_ORDERED); - } - $result = $this->dropTable($name); - if (PEAR::isError($result)) { - return $result; - } $result = $this->createTable($name_new, $fields, $options); if (PEAR::isError($result)) { @@ -657,20 +668,35 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common $this->createConstraint($name_new, $constraint, $definition); } - if (!empty($select_fields) && !empty($data)) { - $query = 'INSERT INTO '.$db->quoteIdentifier($name_new, true); - $query.= '('.implode(', ', array_slice(array_keys($fields), 0, count($select_fields))).')'; - $query.=' VALUES (?'.str_repeat(', ?', (count($select_fields) - 1)).')'; - $stmt =$db->prepare($query, null, MDB2_PREPARE_MANIP); - if (PEAR::isError($stmt)) { - return $stmt; - } - foreach ($data as $row) { - $result = $stmt->execute($row); - if (PEAR::isError($result)) { - return $result; - } - } + //fill the new table with data from the old one + if (!empty($select_fields)) { + $query = 'INSERT INTO '.$db->quoteIdentifier($name_new, true); + $query.= '('.implode(', ', array_slice(array_keys($fields), 0, count($select_fields))).')'; + $query .= ' SELECT '.implode(', ', $select_fields).' FROM '.$db->quoteIdentifier('__'.$name, true); + $db->exec($query); + } + +// if (!empty($select_fields) && !empty($data)) { +// $query = 'INSERT INTO '.$db->quoteIdentifier($name_new, true); +// $query.= '('.implode(', ', array_slice(array_keys($fields), 0, count($select_fields))).')'; +// $query.=' VALUES (?'.str_repeat(', ?', (count($select_fields) - 1)).')'; +// $stmt =$db->prepare($query, null, MDB2_PREPARE_MANIP); +// if (PEAR::isError($stmt)) { +// return $stmt; +// } +// foreach ($data as $row) { +// $result = $stmt->execute($row); +// if (PEAR::isError($result)) { +// return $result; +// } +// } +// } + echo "changes $name"; + + //remove the old table + $result = $this->dropTable('__'.$name); + if (PEAR::isError($result)) { + return $result; } return MDB2_OK; } From c6aa0f9854a2e598c6bb2cd2d0b6ffce7a9c6e64 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 15 Nov 2011 15:59:01 +0100 Subject: [PATCH 06/10] set the installed version after updating the database --- lib/base.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/base.php b/lib/base.php index 803c0118e2..7b42d56f52 100644 --- a/lib/base.php +++ b/lib/base.php @@ -156,6 +156,7 @@ class OC{ $currentVersion=implode('.',OC_Util::getVersion()); if (version_compare($currentVersion, $installedVersion, '>')) { OC_DB::updateDbFromStructure('../db_structure.xml'); + OC_Config::setValue('version',implode('.',OC_Util::getVersion())); } ini_set('session.cookie_httponly','1;'); From 001d06f2ff4a641ff76b4d67a3a33cbdbf5b2bb5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 15 Nov 2011 16:08:08 +0100 Subject: [PATCH 07/10] fix errors during database migration --- lib/MDB2/Driver/Manager/sqlite3.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/MDB2/Driver/Manager/sqlite3.php b/lib/MDB2/Driver/Manager/sqlite3.php index a6fde69d6c..8f4e1312eb 100644 --- a/lib/MDB2/Driver/Manager/sqlite3.php +++ b/lib/MDB2/Driver/Manager/sqlite3.php @@ -660,13 +660,15 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common return $result; } - foreach ($indexes as $index => $definition) { - $this->createIndex($name_new, $index, $definition); - } + //these seem to only give errors - foreach ($constraints as $constraint => $definition) { - $this->createConstraint($name_new, $constraint, $definition); - } +// foreach ($indexes as $index => $definition) { +// $this->createIndex($name_new, $index, $definition); +// } + +// foreach ($constraints as $constraint => $definition) { +// $this->createConstraint($name_new, $constraint, $definition); +// } //fill the new table with data from the old one if (!empty($select_fields)) { @@ -691,7 +693,6 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common // } // } // } - echo "changes $name"; //remove the old table $result = $this->dropTable('__'.$name); From fea68e08b4f0aa52ebd051e4428ff5abd8284f5c Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 11 Dec 2011 22:08:01 +0100 Subject: [PATCH 08/10] update apps when their version number increases --- lib/app.php | 29 +++++++++++++++++++++++++++++ lib/base.php | 2 ++ 2 files changed, 31 insertions(+) diff --git a/lib/app.php b/lib/app.php index 1873e1136c..6b35cdffec 100644 --- a/lib/app.php +++ b/lib/app.php @@ -371,4 +371,33 @@ class OC_App{ } return $apps; } + + /** + * check if any apps need updating and update those + */ + public static function updateApps(){ + // The rest comes here + $apps = OC_Appconfig::getApps(); + foreach( $apps as $app ){ + $installedVersion=OC_Appconfig::getValue($app,'installed_version'); + $appInfo=OC_App::getAppInfo($app); + $currentVersion=$appInfo['version']; + if (version_compare($currentVersion, $installedVersion, '>')) { + OC_App::updateApp($app); + } + } + } + + /** + * update the database for the app and call the update script + * @param string appid + */ + public static function updateApp($appid){ + if(file_exists(OC::$SERVERROOT.'/apps/'.$file.'/appinfo/database.xml')){ + OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/apps/'.$file.'/appinfo/database.xml'); + } + if(file_exists(OC::$SERVERROOT.'/apps/'.$file.'/appinfo/update.php')){ + include OC::$SERVERROOT.'/apps/'.$file.'/appinfo/update.php'; + } + } } diff --git a/lib/base.php b/lib/base.php index 7b42d56f52..c3965c9cd3 100644 --- a/lib/base.php +++ b/lib/base.php @@ -159,6 +159,8 @@ class OC{ OC_Config::setValue('version',implode('.',OC_Util::getVersion())); } + OC_App::updateApps(); + ini_set('session.cookie_httponly','1;'); session_start(); From 010bfa11e363928f4c3a6d8518cbab0e79e28149 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 1 Jan 2012 16:58:51 -0500 Subject: [PATCH 09/10] Fix updateApp() and add extra check to updateApps() --- lib/app.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/app.php b/lib/app.php index 6b35cdffec..13c4cef32b 100644 --- a/lib/app.php +++ b/lib/app.php @@ -381,9 +381,11 @@ class OC_App{ foreach( $apps as $app ){ $installedVersion=OC_Appconfig::getValue($app,'installed_version'); $appInfo=OC_App::getAppInfo($app); - $currentVersion=$appInfo['version']; - if (version_compare($currentVersion, $installedVersion, '>')) { - OC_App::updateApp($app); + if (isset($appInfo['version'])) { + $currentVersion=$appInfo['version']; + if (version_compare($currentVersion, $installedVersion, '>')) { + OC_App::updateApp($app); + } } } } @@ -393,11 +395,11 @@ class OC_App{ * @param string appid */ public static function updateApp($appid){ - if(file_exists(OC::$SERVERROOT.'/apps/'.$file.'/appinfo/database.xml')){ - OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/apps/'.$file.'/appinfo/database.xml'); + if(file_exists(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/database.xml')){ + OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/database.xml'); } - if(file_exists(OC::$SERVERROOT.'/apps/'.$file.'/appinfo/update.php')){ - include OC::$SERVERROOT.'/apps/'.$file.'/appinfo/update.php'; + if(file_exists(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/update.php')){ + include OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/update.php'; } } } From 034cf19159c828d242fbb3128fda6db815a75ca6 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 8 Jan 2012 02:57:52 +0100 Subject: [PATCH 10/10] allow changing database backends between PDO and MDB2 --- lib/db.php | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/db.php b/lib/db.php index 05ed8398b7..58a478ba0c 100644 --- a/lib/db.php +++ b/lib/db.php @@ -71,7 +71,14 @@ class OC_DB { /** * connect to the database using pdo */ - private static function connectPDO(){ + public static function connectPDO(){ + if(self::$connection){ + if(self::$backend==self::BACKEND_MDB2){ + self::disconnect(); + }else{ + return; + } + } // The global data we need $name = OC_Config::getValue( "dbname", "owncloud" ); $host = OC_Config::getValue( "dbhost", "" ); @@ -113,7 +120,14 @@ class OC_DB { /** * connect to the database using mdb2 */ - static private function connectMDB2(){ + public static function connectMDB2(){ + if(self::$connection){ + if(self::$backend==self::BACKEND_PDO){ + self::disconnect(); + }else{ + return; + } + } // The global data we need $name = OC_Config::getValue( "dbname", "owncloud" ); $host = OC_Config::getValue( "dbhost", "" ); @@ -255,8 +269,8 @@ class OC_DB { self::$connection->disconnect(); } self::$connection=false; - self::$mdb2=false; - self::$pdo=false; + self::$MDB2=false; + self::$PDO=false; } return true; @@ -374,6 +388,7 @@ class OC_DB { private static function connectScheme(){ // We need a mdb2 database connection self::connectMDB2(); + self::$MDB2->loadModule('Manager'); // Connect if this did not happen before if(!self::$schema){