diff options
Diffstat (limited to 'lib/db.php')
-rw-r--r-- | lib/db.php | 266 |
1 files changed, 133 insertions, 133 deletions
diff --git a/lib/db.php b/lib/db.php index 4214451c85f..ee69e5f8299 100644 --- a/lib/db.php +++ b/lib/db.php @@ -27,7 +27,7 @@ class OC_DB { const BACKEND_PDO=0; const BACKEND_MDB2=1; - + static private $connection; //the prefered connection to use, either PDO or MDB2 static private $backend=null; static private $MDB2=false; @@ -41,35 +41,36 @@ class OC_DB { * check which backend we should use * @return BACKEND_MDB2 or BACKEND_PDO */ - private static function getDBBackend(){ - if(class_exists('PDO') && OC_Config::getValue('installed', false)){//check if we can use PDO, else use MDB2 (installation always needs to be done my mdb2) + private static function getDBBackend() { + //check if we can use PDO, else use MDB2 (installation always needs to be done my mdb2) + if(class_exists('PDO') && OC_Config::getValue('installed', false)) { $type = OC_Config::getValue( "dbtype", "sqlite" ); if($type=='oci') { //oracle also always needs mdb2 return self::BACKEND_MDB2; } if($type=='sqlite3') $type='sqlite'; $drivers=PDO::getAvailableDrivers(); - if(array_search($type,$drivers)!==false){ + if(array_search($type, $drivers)!==false) { return self::BACKEND_PDO; } } return self::BACKEND_MDB2; } - + /** * @brief connects to the database * @returns true if connection can be established or nothing (die()) * * Connects to the database as specified in config.php */ - public static function connect($backend=null){ - if(self::$connection){ + public static function connect($backend=null) { + if(self::$connection) { return; } - if(is_null($backend)){ + if(is_null($backend)) { $backend=self::getDBBackend(); } - if($backend==self::BACKEND_PDO){ + if($backend==self::BACKEND_PDO) { self::connectPDO(); self::$connection=self::$PDO; self::$backend=self::BACKEND_PDO; @@ -83,9 +84,9 @@ class OC_DB { /** * connect to the database using pdo */ - public static function connectPDO(){ - if(self::$connection){ - if(self::$backend==self::BACKEND_MDB2){ + public static function connectPDO() { + if(self::$connection) { + if(self::$backend==self::BACKEND_MDB2) { self::disconnect(); }else{ return; @@ -97,18 +98,18 @@ class OC_DB { $user = OC_Config::getValue( "dbuser", "" ); $pass = OC_Config::getValue( "dbpassword", "" ); $type = OC_Config::getValue( "dbtype", "sqlite" ); - if(strpos($host,':')){ - list($host,$port)=explode(':',$host,2); + if(strpos($host, ':')) { + list($host, $port)=explode(':', $host,2); }else{ $port=false; } $opts = array(); $datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' ); - + // do nothing if the connection already has been established - if(!self::$PDO){ + if(!self::$PDO) { // Add the dsn according to the database type - switch($type){ + switch($type) { case 'sqlite': $dsn='sqlite2:'.$datadir.'/'.$name.'.db'; break; @@ -116,7 +117,7 @@ class OC_DB { $dsn='sqlite:'.$datadir.'/'.$name.'.db'; break; case 'mysql': - if($port){ + if($port) { $dsn='mysql:dbname='.$name.';host='.$host.';port='.$port; }else{ $dsn='mysql:dbname='.$name.';host='.$host; @@ -124,7 +125,7 @@ class OC_DB { $opts[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES 'UTF8'"; break; case 'pgsql': - if($port){ + if($port) { $dsn='pgsql:dbname='.$name.';host='.$host.';port='.$port; }else{ $dsn='pgsql:dbname='.$name.';host='.$host; @@ -139,32 +140,32 @@ class OC_DB { /** END OF FIX***/ break; case 'oci': // Oracle with PDO is unsupported - if ($port) { - $dsn = 'oci:dbname=//' . $host . ':' . $port . '/' . $name; - } else { - $dsn = 'oci:dbname=//' . $host . '/' . $name; - } - break; + if ($port) { + $dsn = 'oci:dbname=//' . $host . ':' . $port . '/' . $name; + } else { + $dsn = 'oci:dbname=//' . $host . '/' . $name; + } + break; } try{ - self::$PDO=new PDO($dsn,$user,$pass,$opts); - }catch(PDOException $e){ + self::$PDO=new PDO($dsn, $user, $pass, $opts); + }catch(PDOException $e) { echo( '<b>can not connect to database, using '.$type.'. ('.$e->getMessage().')</center>'); die(); } // We always, really always want associative arrays - self::$PDO->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC); - self::$PDO->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); + self::$PDO->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); + self::$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } return true; } - + /** * connect to the database using mdb2 */ - public static function connectMDB2(){ - if(self::$connection){ - if(self::$backend==self::BACKEND_PDO){ + public static function connectMDB2() { + if(self::$connection) { + if(self::$backend==self::BACKEND_PDO) { self::disconnect(); }else{ return; @@ -180,9 +181,9 @@ class OC_DB { $datadir=OC_Config::getValue( "datadirectory", "$SERVERROOT/data" ); // do nothing if the connection already has been established - if(!self::$MDB2){ + if(!self::$MDB2) { // Require MDB2.php (not required in the head of the file so we only load it when needed) - require_once('MDB2.php'); + require_once 'MDB2.php'; // Prepare options array $options = array( @@ -193,7 +194,7 @@ class OC_DB { 'quote_identifier' => true ); // Add the dsn according to the database type - switch($type){ + switch($type) { case 'sqlite': case 'sqlite3': $dsn = array( @@ -234,22 +235,22 @@ class OC_DB { } break; } - + // Try to establish connection self::$MDB2 = MDB2::factory( $dsn, $options ); - + // Die if we could not connect - if( PEAR::isError( self::$MDB2 )){ + if( PEAR::isError( self::$MDB2 )) { echo( '<b>can not connect to database, using '.$type.'. ('.self::$MDB2->getUserInfo().')</center>'); - OC_Log::write('core',self::$MDB2->getUserInfo(),OC_Log::FATAL); - OC_Log::write('core',self::$MDB2->getMessage(),OC_Log::FATAL); + OC_Log::write('core', self::$MDB2->getUserInfo(), OC_Log::FATAL); + OC_Log::write('core', self::$MDB2->getMessage(), OC_Log::FATAL); die( $error ); } - + // We always, really always want associative arrays self::$MDB2->setFetchMode(MDB2_FETCHMODE_ASSOC); } - + // we are done. great! return true; } @@ -261,8 +262,8 @@ class OC_DB { * * SQL query via MDB2 prepare(), needs to be execute()'d! */ - static public function prepare( $query , $limit=null, $offset=null ){ - + static public function prepare( $query , $limit=null, $offset=null ) { + if (!is_null($limit) && $limit != -1) { if (self::$backend == self::BACKEND_MDB2) { //MDB2 uses or emulates limits & offset internally @@ -290,24 +291,24 @@ class OC_DB { self::connect(); // return the result - if(self::$backend==self::BACKEND_MDB2){ + if(self::$backend==self::BACKEND_MDB2) { $result = self::$connection->prepare( $query ); // Die if we have an error (error means: bad query, not 0 results!) if( PEAR::isError($result)) { $entry = 'DB Error: "'.$result->getMessage().'"<br />'; $entry .= 'Offending command was: '.$query.'<br />'; - OC_Log::write('core',$entry,OC_Log::FATAL); + OC_Log::write('core', $entry,OC_Log::FATAL); error_log('DB error: '.$entry); die( $entry ); } }else{ try{ $result=self::$connection->prepare($query); - }catch(PDOException $e){ + }catch(PDOException $e) { $entry = 'DB Error: "'.$e->getMessage().'"<br />'; $entry .= 'Offending command was: '.$query.'<br />'; - OC_Log::write('core',$entry,OC_Log::FATAL); + OC_Log::write('core', $entry,OC_Log::FATAL); error_log('DB error: '.$entry); die( $entry ); } @@ -326,9 +327,9 @@ class OC_DB { * Call this method right after the insert command or other functions may * cause trouble! */ - public static function insertid($table=null){ + public static function insertid($table=null) { self::connect(); - if($table !== null){ + if($table !== null) { $prefix = OC_Config::getValue( "dbtableprefix", "oc_" ); $suffix = OC_Config::getValue( "dbsequencesuffix", "_id_seq" ); $table = str_replace( '*PREFIX*', $prefix, $table ); @@ -342,10 +343,10 @@ class OC_DB { * * This is good bye, good bye, yeah! */ - public static function disconnect(){ + public static function disconnect() { // Cut connection if required - if(self::$connection){ - if(self::$backend==self::BACKEND_MDB2){ + if(self::$connection) { + if(self::$backend==self::BACKEND_MDB2) { self::$connection->disconnect(); } self::$connection=false; @@ -363,7 +364,7 @@ class OC_DB { * * TODO: write more documentation */ - public static function getDbStructure( $file ,$mode=MDB2_SCHEMA_DUMP_STRUCTURE){ + public static function getDbStructure( $file ,$mode=MDB2_SCHEMA_DUMP_STRUCTURE) { self::connectScheme(); // write the scheme @@ -385,7 +386,7 @@ class OC_DB { * * TODO: write more documentation */ - public static function createDbFromStructure( $file ){ + public static function createDbFromStructure( $file ) { $CONFIG_DBNAME = OC_Config::getValue( "dbname", "owncloud" ); $CONFIG_DBTABLEPREFIX = OC_Config::getValue( "dbtableprefix", "oc_" ); $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" ); @@ -394,7 +395,7 @@ class OC_DB { // read file $content = file_get_contents( $file ); - + // Make changes and save them to an in-memory file $file2 = 'static://db_scheme'; $content = str_replace( '*dbname*', $CONFIG_DBNAME, $content ); @@ -405,45 +406,46 @@ class OC_DB { * http://www.postgresql.org/docs/8.1/static/functions-datetime.html * http://www.sqlite.org/lang_createtable.html * http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions037.htm + */ - if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite doesn't + if( $CONFIG_DBTYPE == 'pgsql' ) { //mysql support it too but sqlite doesn't $content = str_replace( '<default>0000-00-00 00:00:00</default>', '<default>CURRENT_TIMESTAMP</default>', $content ); } - */ + file_put_contents( $file2, $content ); // Try to create tables $definition = self::$schema->parseDatabaseDefinitionFile( $file2 ); - + //clean up memory unlink( $file2 ); // Die in case something went wrong - if( $definition instanceof MDB2_Schema_Error ){ + if( $definition instanceof MDB2_Schema_Error ) { die( $definition->getMessage().': '.$definition->getUserInfo()); } - if(OC_Config::getValue('dbtype','sqlite')==='oci'){ + if(OC_Config::getValue('dbtype', 'sqlite')==='oci') { unset($definition['charset']); //or MDB2 tries SHUTDOWN IMMEDIATE $oldname = $definition['name']; $definition['name']=OC_Config::getValue( "dbuser", $oldname ); } - + $ret=self::$schema->createDatabase( $definition ); // Die in case something went wrong - if( $ret instanceof MDB2_Error ){ + if( $ret instanceof MDB2_Error ) { echo (self::$MDB2->getDebugOutput()); die ($ret->getMessage() . ': ' . $ret->getUserInfo()); } return true; } - + /** * @brief update the database scheme * @param $file file to read structure from */ - public static function updateDbFromStructure($file){ + public static function updateDbFromStructure($file) { $CONFIG_DBTABLEPREFIX = OC_Config::getValue( "dbtableprefix", "oc_" ); $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" ); @@ -451,11 +453,11 @@ class OC_DB { // read file $content = file_get_contents( $file ); - + $previousSchema = self::$schema->getDefinitionFromDatabase(); if (PEAR::isError($previousSchema)) { $error = $previousSchema->getMessage(); - OC_Log::write('core','Failed to get existing database structure for upgrading ('.$error.')',OC_Log::FATAL); + OC_Log::write('core', 'Failed to get existing database structure for upgrading ('.$error.')', OC_Log::FATAL); return false; } @@ -469,20 +471,20 @@ class OC_DB { * http://www.postgresql.org/docs/8.1/static/functions-datetime.html * http://www.sqlite.org/lang_createtable.html * http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions037.htm - if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite doesn't + if( $CONFIG_DBTYPE == 'pgsql' ) { //mysql support it too but sqlite doesn't $content = str_replace( '<default>0000-00-00 00:00:00</default>', '<default>CURRENT_TIMESTAMP</default>', $content ); } */ file_put_contents( $file2, $content ); $op = self::$schema->updateDatabase($file2, $previousSchema, array(), false); - + //clean up memory unlink( $file2 ); - + if (PEAR::isError($op)) { $error = $op->getMessage(); $detail = $op->getDebugInfo(); - OC_Log::write('core','Failed to update database structure ('.$error.', '.$detail.')',OC_Log::FATAL); + OC_Log::write('core', 'Failed to update database structure ('.$error.', '.$detail.')', OC_Log::FATAL); return false; } return true; @@ -494,15 +496,15 @@ class OC_DB { * * Connects to a MDB2 database scheme */ - private static function connectScheme(){ + private static function connectScheme() { // We need a mdb2 database connection self::connectMDB2(); self::$MDB2->loadModule('Manager'); self::$MDB2->loadModule('Reverse'); // Connect if this did not happen before - if(!self::$schema){ - require_once('MDB2/Schema.php'); + if(!self::$schema) { + require_once 'MDB2/Schema.php'; self::$schema=MDB2_Schema::factory(self::$MDB2); } @@ -517,29 +519,29 @@ class OC_DB { * This function replaces *PREFIX* with the value of $CONFIG_DBTABLEPREFIX * and replaces the ` woth ' or " according to the database driver. */ - private static function processQuery( $query ){ + private static function processQuery( $query ) { self::connect(); // We need Database type and table prefix - if(is_null(self::$type)){ + if(is_null(self::$type)) { self::$type=OC_Config::getValue( "dbtype", "sqlite" ); } $type = self::$type; - if(is_null(self::$prefix)){ + if(is_null(self::$prefix)) { self::$prefix=OC_Config::getValue( "dbtableprefix", "oc_" ); } $prefix = self::$prefix; - + // differences in escaping of table names ('`' for mysql) and getting the current timestamp - if( $type == 'sqlite' || $type == 'sqlite3' ){ + if( $type == 'sqlite' || $type == 'sqlite3' ) { $query = str_replace( '`', '"', $query ); - $query = str_replace( 'NOW()', 'datetime(\'now\')', $query ); - $query = str_replace( 'now()', 'datetime(\'now\')', $query ); - }elseif( $type == 'pgsql' ){ + $query = str_ireplace( 'NOW()', 'datetime(\'now\')', $query ); + $query = str_ireplace( 'UNIX_TIMESTAMP()', 'strftime(\'%s\',\'now\')', $query ); + }elseif( $type == 'pgsql' ) { $query = str_replace( '`', '"', $query ); - }elseif( $type == 'oci' ){ + $query = str_ireplace( 'UNIX_TIMESTAMP()', 'cast(extract(epoch from current_timestamp) as integer)', $query ); + }elseif( $type == 'oci' ) { $query = str_replace( '`', '"', $query ); - $query = str_replace( 'NOW()', 'CURRENT_TIMESTAMP', $query ); - $query = str_replace( 'now()', 'CURRENT_TIMESTAMP', $query ); + $query = str_ireplace( 'NOW()', 'CURRENT_TIMESTAMP', $query ); } // replace table name prefix @@ -547,22 +549,22 @@ class OC_DB { return $query; } - + /** * @brief drop a table * @param string $tableNamme the table to drop */ - public static function dropTable($tableName){ + public static function dropTable($tableName) { self::connectMDB2(); self::$MDB2->loadModule('Manager'); self::$MDB2->dropTable($tableName); } - + /** * remove all tables defined in a database structure xml file * @param string $file the xml file describing the tables */ - public static function removeDBStructure($file){ + public static function removeDBStructure($file) { $CONFIG_DBNAME = OC_Config::getValue( "dbname", "owncloud" ); $CONFIG_DBTABLEPREFIX = OC_Config::getValue( "dbtableprefix", "oc_" ); self::connectScheme(); @@ -578,42 +580,41 @@ class OC_DB { // get the tables $definition = self::$schema->parseDatabaseDefinitionFile( $file2 ); - + // Delete our temporary file unlink( $file2 ); $tables=array_keys($definition['tables']); - foreach($tables as $table){ + foreach($tables as $table) { self::dropTable($table); } } - + /** * @brief replaces the owncloud tables with a new set * @param $file string path to the MDB2 xml db export file */ - public static function replaceDB( $file ){ - $apps = OC_App::getAllApps(); - self::beginTransaction(); - // Delete the old tables - self::removeDBStructure( OC::$SERVERROOT . '/db_structure.xml' ); - - foreach($apps as $app){ - $path = OC_App::getAppPath($app).'/appinfo/database.xml'; - if(file_exists($path)){ - self::removeDBStructure( $path ); - } - } - - // Create new tables - self::createDBFromStructure( $file ); - self::commit(); - - } - + public static function replaceDB( $file ) { + $apps = OC_App::getAllApps(); + self::beginTransaction(); + // Delete the old tables + self::removeDBStructure( OC::$SERVERROOT . '/db_structure.xml' ); + + foreach($apps as $app) { + $path = OC_App::getAppPath($app).'/appinfo/database.xml'; + if(file_exists($path)) { + self::removeDBStructure( $path ); + } + } + + // Create new tables + self::createDBFromStructure( $file ); + self::commit(); + } + /** * Start a transaction */ - public static function beginTransaction(){ + public static function beginTransaction() { self::connect(); if (self::$backend==self::BACKEND_MDB2 && !self::$connection->supports('transactions')) { return false; @@ -625,9 +626,9 @@ class OC_DB { /** * Commit the database changes done during a transaction that is in progress */ - public static function commit(){ + public static function commit() { self::connect(); - if(!self::$inTransaction){ + if(!self::$inTransaction) { return false; } self::$connection->commit(); @@ -639,10 +640,10 @@ class OC_DB { * @param mixed $result * @return bool */ - public static function isError($result){ - if(!$result){ + public static function isError($result) { + if(!$result) { return true; - }elseif(self::$backend==self::BACKEND_MDB2 and PEAR::isError($result)){ + }elseif(self::$backend==self::BACKEND_MDB2 and PEAR::isError($result)) { return true; }else{ return false; @@ -657,31 +658,31 @@ class PDOStatementWrapper{ private $statement=null; private $lastArguments=array(); - public function __construct($statement){ + public function __construct($statement) { $this->statement=$statement; } - + /** * make execute return the result instead of a bool */ - public function execute($input=array()){ + public function execute($input=array()) { $this->lastArguments=$input; - if(count($input)>0){ + if(count($input)>0) { $result=$this->statement->execute($input); }else{ $result=$this->statement->execute(); } - if($result){ + if($result) { return $this; }else{ return false; } } - + /** * provide numRows */ - public function numRows(){ + public function numRows() { $regex = '/^SELECT\s+(?:ALL\s+|DISTINCT\s+)?(?:.*?)\s+FROM\s+(.*)$/i'; if (preg_match($regex, $this->statement->queryString, $output) > 0) { $query = OC_DB::prepare("SELECT COUNT(*) FROM {$output[1]}", PDO::FETCH_NUM); @@ -690,28 +691,27 @@ class PDOStatementWrapper{ return $this->statement->rowCount(); } } - + /** * provide an alias for fetch */ - public function fetchRow(){ + public function fetchRow() { return $this->statement->fetch(); } - + /** * pass all other function directly to the PDOStatement */ - public function __call($name,$arguments){ - return call_user_func_array(array($this->statement,$name),$arguments); + public function __call($name,$arguments) { + return call_user_func_array(array($this->statement,$name), $arguments); } - + /** * Provide a simple fetchOne. * fetch single column from the next row * @param int $colnum the column number to fetch */ - public function fetchOne($colnum = 0){ + public function fetchOne($colnum = 0) { return $this->statement->fetchColumn($colnum); } } - |