summaryrefslogtreecommitdiffstats
path: root/lib/base.php
diff options
context:
space:
mode:
authorJakob Sack <kde@jakobsack.de>2011-04-08 16:53:17 +0200
committerJakob Sack <kde@jakobsack.de>2011-04-08 16:53:17 +0200
commit908e377246cd770b7a3f9f2f4d929e29ffb22f25 (patch)
treeffdf51237727174ffbc13dc49acebc7ddf9aeed0 /lib/base.php
parentd3502315bda8e21e3daa29e5a4dbb2031e7ba522 (diff)
downloadnextcloud-server-908e377246cd770b7a3f9f2f4d929e29ffb22f25.tar.gz
nextcloud-server-908e377246cd770b7a3f9f2f4d929e29ffb22f25.zip
Refactoring of OC_DB
Diffstat (limited to 'lib/base.php')
-rw-r--r--lib/base.php414
1 files changed, 218 insertions, 196 deletions
diff --git a/lib/base.php b/lib/base.php
index e38b76fff90..3bf74e233a5 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -350,18 +350,23 @@ class OC_HOOK{
}
/**
- * Class for database access
- *
+ * This class manages the access to the database. It basically is a wrapper for
+ * MDB2 with some adaptions.
*/
class OC_DB {
static private $DBConnection=false;
static private $schema=false;
static private $affected=0;
static private $result=false;
+
/**
- * connect to the datbase if not already connected
- */
- public static function connect(){
+ * @brief connects to the database
+ * @returns true if connection can be established or nothing (die())
+ *
+ * Connects to the database as specified in config.php
+ */
+ static public function connect(){
+ // The global data we need
global $CONFIG_DBNAME;
global $CONFIG_DBHOST;
global $CONFIG_DBUSER;
@@ -369,8 +374,13 @@ class OC_DB {
global $CONFIG_DBTYPE;
global $DOCUMENTROOT;
global $SERVERROOT;
+
+ // do nothing if the connection already has been established
if(!self::$DBConnection){
+ // Require MDB2.php (TODO: why here not in head of file?)
@oc_require_once('MDB2.php');
+
+ // Prepare options array
$options = array(
'portability' => MDB2_PORTABILITY_ALL,
'log_line_break' => '<br>',
@@ -378,249 +388,261 @@ class OC_DB {
'debug' => true,
'quote_identifier' => true,
);
+
+ // Add the dsn according to the database type
if($CONFIG_DBTYPE=='sqlite'){
+ // sqlite
$dsn = array(
- 'phptype' => 'sqlite',
- 'database' => $SERVERROOT.'/'.$CONFIG_DBNAME,
- 'mode' => '0644',
- );
- }elseif($CONFIG_DBTYPE=='mysql'){
+ 'phptype' => 'sqlite',
+ 'database' => "$SERVERROOT/$CONFIG_DBNAME",
+ 'mode' => '0644' );
+ }
+ elseif($CONFIG_DBTYPE=='mysql'){
+ // MySQL
$dsn = array(
- 'phptype' => 'mysql',
- 'username' => $CONFIG_DBUSER,
- 'password' => $CONFIG_DBPASSWORD,
- 'hostspec' => $CONFIG_DBHOST,
- 'database' => $CONFIG_DBNAME,
- );
- }elseif($CONFIG_DBTYPE=='pgsql'){
+ 'phptype' => 'mysql',
+ 'username' => $CONFIG_DBUSER,
+ 'password' => $CONFIG_DBPASSWORD,
+ 'hostspec' => $CONFIG_DBHOST,
+ 'database' => $CONFIG_DBNAME );
+ }
+ elseif($CONFIG_DBTYPE=='pgsql'){
+ // PostgreSQL
$dsn = array(
- 'phptype' => 'pgsql',
- 'username' => $CONFIG_DBUSER,
- 'password' => $CONFIG_DBPASSWORD,
- 'hostspec' => $CONFIG_DBHOST,
- 'database' => $CONFIG_DBNAME,
- );
+ 'phptype' => 'pgsql',
+ 'username' => $CONFIG_DBUSER,
+ 'password' => $CONFIG_DBPASSWORD,
+ 'hostspec' => $CONFIG_DBHOST,
+ 'database' => $CONFIG_DBNAME );
}
- self::$DBConnection=MDB2::factory($dsn,$options);
-
- if (PEAR::isError(self::$DBConnection)) {
- echo('<b>can not connect to database, using '.$CONFIG_DBTYPE.'. ('.self::$DBConnection->getUserInfo().')</center>');
- $error=self::$DBConnection->getMessage();
- error_log("$error");
- error_log(self::$DBConnection->getUserInfo());
- die($error);
+
+ // Try to establish connection
+ self::$DBConnection = MDB2::factory( $dsn, $options );
+
+ // Die if we could not connect
+ if( PEAR::isError( self::$DBConnection )){
+ echo( '<b>can not connect to database, using '.$CONFIG_DBTYPE.'. ('.self::$DBConnection->getUserInfo().')</center>');
+ $error = self::$DBConnection->getMessage();
+ error_log( $error);
+ error_log( self::$DBConnection->getUserInfo());
+ die( $error );
}
+
+ // We always, really always want associative arrays
self::$DBConnection->setFetchMode(MDB2_FETCHMODE_ASSOC);
}
- }
- public static function connectScheme(){
- self::connect();
- if(!self::$schema){
- @oc_require_once('MDB2/Schema.php');
- self::$schema=&MDB2_Schema::factory(self::$DBConnection);
- }
+ // we are done. great!
+ return true;
}
/**
- * executes a query on the database
+ * @brief SQL query
+ * @param $query Query string
+ * @returns result as MDB2_Result
*
- * @param string $cmd
- * @return result-set
+ * SQL query via MDB2 query()
*/
- static function query($cmd){
- global $CONFIG_DBTYPE;
- if(!trim($cmd)){
- return false;
- }
- OC_DB::connect();
- //fix differences between sql versions
+ static public function query( $query ){
+ // Optimize the query
+ $query = self::processQuery( $query );
- //differences in escaping of table names (` for mysql)
- if($CONFIG_DBTYPE=='sqlite'){
- $cmd=str_replace('`','\'',$cmd);
- }elseif($CONFIG_DBTYPE=='pgsql'){
- $cmd=str_replace('`','"',$cmd);
- }
- $result=self::$DBConnection->exec($cmd);
- if (PEAR::isError($result)) {
- $entry='DB Error: "'.$result->getMessage().'"<br />';
- $entry.='Offending command was: '.$cmd.'<br />';
- error_log($entry);
- die($entry);
- }else{
- self::$affected=$result;
- }
- self::$result=$result;
- return $result;
- }
+ self::connect();
+ //fix differences between sql versions
- /**
- * executes a query on the database and returns the result in an array
- *
- * @param string $cmd
- * @return result-set
- */
- static function select($cmd){
- OC_DB::connect();
- global $CONFIG_DBTYPE;
- //fix differences between sql versions
+ // return the result
+ $result = self::$DBConnection->exec( $query );
- //differences in escaping of table names (` for mysql)
- if($CONFIG_DBTYPE=='sqlite'){
- $cmd=str_replace('`','\'',$cmd);
- }elseif($CONFIG_DBTYPE=='pgsql'){
- $cmd=str_replace('`','"',$cmd);
- }
- $result=self::$DBConnection->queryAll($cmd);
- if (PEAR::isError($result)){
- $entry='DB Error: "'.$result->getMessage().'"<br />';
- $entry.='Offending command was: '.$cmd.'<br />';
- die($entry);
+ // 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: '.$cmd.'<br />';
+ error_log( $entry );
+ die( $entry );
}
+
return $result;
}
/**
- * executes multiply queries on the database
- *
- * @param string $cmd
- * @return result-set
- */
- static function multiquery($cmd) {
- $queries=explode(';',$cmd);
- foreach($queries as $query){
- OC_DB::query($query);
- }
- return true;
- }
-
+ * @brief Prepare a SQL query
+ * @param $query Query string
+ * @returns prepared SQL query
+ *
+ * SQL query via MDB2 prepare(), needs to be execute()'d!
+ */
+ static public function prepare( $query ){
+ // Optimize the query
+ $query = self::processQuery( $query );
- /**
- * closing a db connection
- *
- * @return bool
- */
- static function close() {
- self::$DBConnection->disconnect();
- self::$DBConnection=false;
- }
+ self::connect();
+ //fix differences between sql versions
+ // return the result
+ $result = self::$DBConnection->prepare( $query );
- /**
- * Returning primarykey if last statement was an insert.
- *
- * @return primarykey
- */
- static function insertid() {
- $id=self::$DBConnection->lastInsertID();
- return $id;
- }
+ // 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: '.$cmd.'<br />';
+ error_log( $entry );
+ die( $entry );
+ }
- /**
- * Returning number of rows in a result
- *
- * @param resultset $result
- * @return int
- */
- static function numrows($result) {
- $result->numRows();
- }
- /**
- * Returning number of affected rows
- *
- * @return int
- */
- static function affected_rows() {
- return self::$affected;
- }
-
- /**
- * get a field from the resultset
- *
- * @param resultset $result
- * @param int $i
- * @param int $field
- * @return unknown
- */
- static function result($result, $i, $field) {
- $tmp=$result->fetchRow(MDB2_FETCHMODE_ASSOC,$i);
- $tmp=$tmp[$field];
- return($tmp);
+ return $result;
}
/**
- * get data-array from resultset
- *
- * @param resultset $result
- * @return data
- */
- static function fetch_assoc($result){
- return $result->fetchRow(MDB2_FETCHMODE_ASSOC);
+ * @brief gets last value of autoincrement
+ * @returns id
+ *
+ * MDB2 lastInsertID()
+ *
+ * Call this method right after the insert command or other functions may
+ * cause trouble!
+ */
+ public static function insertid(){
+ self::connect();
+ return self::$DBConnection->lastInsertID();
}
/**
- * Freeing resultset (performance)
- *
- * @param unknown_type $result
- * @return bool
- */
- static function free_result() {
- if(self::$result){
- self::$result->free();
- self::$result=false;
- }
- }
-
- static public function disconnect(){
+ * @brief Disconnect
+ * @returns true/false
+ *
+ * This is good bye, good bye, yeah!
+ */
+ public static function disconnect(){
+ // Cut connection if required
if(self::$DBConnection){
self::$DBConnection->disconnect();
self::$DBConnection=false;
}
+
+ return true;
}
/**
- * escape strings so they can be used in queries
- *
- * @param string string
- * @return string
- */
- static function escape($string){
- OC_DB::connect();
- return self::$DBConnection->escape($string);
- }
-
- static function getDbStructure($file){
- OC_DB::connectScheme();
+ * @brief Escapes bad characters
+ * @param $string string with dangerous characters
+ * @returns escaped string
+ *
+ * MDB2 escape()
+ */
+ public static function escape( $string ){
+ self::connect();
+ return self::$DBConnection->escape( $string );
+ }
+
+ /**
+ * @brief saves database scheme to xml file
+ * @param $file name of file
+ * @returns true/false
+ *
+ * TODO: write more documentation
+ */
+ public static function getDbStructure( $file ){
+ self::connectScheme();
+
+ // write the scheme
$definition = self::$schema->getDefinitionFromDatabase();
$dump_options = array(
'output_mode' => 'file',
'output' => $file,
'end_of_line' => "\n"
);
- self::$schema->dumpDatabase($definition, $dump_options, MDB2_SCHEMA_DUMP_STRUCTURE);
+ self::$schema->dumpDatabase( $definition, $dump_options, MDB2_SCHEMA_DUMP_STRUCTURE );
+
+ return true;
}
- static function createDbFromStructure($file){
- OC_DB::connectScheme();
+ /**
+ * @brief Creates tables from XML file
+ * @param $file file to read structure from
+ * @returns true/false
+ *
+ * TODO: write more documentation
+ */
+ public static function createDbFromStructure( $file ){
global $CONFIG_DBNAME;
global $CONFIG_DBTABLEPREFIX;
- $content=file_get_contents($file);
- $file2=tempnam(sys_get_temp_dir(),'oc_db_scheme_');
- $content=str_replace('*dbname*',$CONFIG_DBNAME,$content);
- $content=str_replace('*dbprefix*',$CONFIG_DBTABLEPREFIX,$content);
- file_put_contents($file2,$content);
- $definition=@self::$schema->parseDatabaseDefinitionFile($file2);
- unlink($file2);
- if($definition instanceof MDB2_Schema_Error){
- die($definition->getMessage() . ': ' . $definition->getUserInfo());
+
+ self::connectScheme();
+
+ // read file
+ $content = file_get_contents( $file );
+
+ // Make changes and save them to a temporary file
+ $file2 = tempnam( sys_get_temp_dir(), 'oc_db_scheme_' );
+ $content = str_replace( '*dbname*', $CONFIG_DBNAME, $content );
+ $content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content );
+ file_put_contents( $file2, $content );
+
+ // Try to create tables
+ $definition = @self::$schema->parseDatabaseDefinitionFile( $file2 );
+
+ // Delete our temporary file
+ unlink( $file2 );
+
+ // Die in case something went wrong
+ if( $definition instanceof MDB2_Schema_Error ){
+ die( $definition->getMessage().': '.$definition->getUserInfo());
}
- $ret=@self::$schema->createDatabase($definition);
- if($ret instanceof MDB2_Error) {
+ $ret=@self::$schema->createDatabase( $definition );
+
+ // Die in case something went wrong
+ if( $ret instanceof MDB2_Error ){
die ($ret->getMessage() . ': ' . $ret->getUserInfo());
- }else{
- return true;
}
+
+ return true;
+ }
+
+ /**
+ * @brief connects to a MDB2 database scheme
+ * @returns true/false
+ *
+ * Connects to a MDB2 database scheme
+ */
+ private static function connectScheme(){
+ // We need a database connection
+ self::connect();
+
+ // Connect if this did not happen before
+ if(!self::$schema){
+ @oc_require_once('MDB2/Schema.php');
+ self::$schema=&MDB2_Schema::factory(self::$DBConnection);
+ }
+
+ return true;
+ }
+
+ /**
+ * @brief does minor chages to query
+ * @param $query Query string
+ * @returns corrected query string
+ *
+ * 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 ){
+ // We need Database type and table prefix
+ global $CONFIG_DBTYPE;
+ global $CONFIG_DBTABLEPREFIX;
+
+ // differences in escaping of table names (` for mysql)
+ // Problem: what if there is a ` in the value we want to insert?
+ if( $CONFIG_DBTYPE == 'sqlite' ){
+ $query = str_replace( '`', '\'', $query );
+ }
+ elseif( $CONFIG_DBTYPE == 'pgsql' ){
+ $query = str_replace( '`', '"', $query );
+ }
+
+ // replace table names
+ $query = str_replace( '*PREFIX*', $CONFIG_DBTABLEPREFIX, $query );
+
+ return $query;
}
}