update INSTALL and UPGRADE file
[phpfspot.git] / phpfspot_db.php
index fba87b3dc818b4eb172067fb9a0f610709c274a2..339e02350719fbf44ecf2aeab925886c9eac5cfe 100644 (file)
@@ -2,8 +2,9 @@
 
 /***************************************************************************
  *
- * Copyright (c) by Andreas Unterkircher, unki@netshadow.at
- * All rights reserved
+ * phpfspot, presents your F-Spot photo collection in Web browsers.
+ *
+ * Copyright (c) by Andreas Unterkircher
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *
  ***************************************************************************/
 
+/**
+ * PHPFSPOT_DB class
+ *
+ * @package phpfspot
+ */
 class PHPFSPOT_DB {
 
    private $db;
@@ -28,6 +34,7 @@ class PHPFSPOT_DB {
    private $parent;
    private $is_connected;
    private $last_error;
+   private $last_query;
 
    /**
     * PHPFSPOT_DB class constructor
@@ -36,13 +43,15 @@ class PHPFSPOT_DB {
     */
    public function __construct($parent, $db_path)
    {
-      $this->parent = $parent;
+      global $phpfspot;
+
+      $this->parent = $phpfspot;
       $this->db_path = $db_path;
 
       /* We are starting disconnected */
       $this->setConnStatus(false);
 
-      /* Connect to MySQL Database */
+      /* Connect to database */
       $this->db_connect();
 
    } // __construct()
@@ -61,18 +70,34 @@ class PHPFSPOT_DB {
    /**
     * PHPFSPOT_DB database connect
     *
-    * This function will connect to the database via MDB2
+    * This function will connect to the database
     */
    private function db_connect()
    {
-      if(($this->db = sqlite3_open($this->db_path)) === false) {
+      switch($this->parent->cfg->db_access) {
+         case 'native':
+            if(($this->db = sqlite3_open($this->db_path)) === false) {
+               $this->throwError("Unable to connect to database:" . $this->getLastError());
+               $this->setConnStatus(false);
+            }
+            else {
+               sqlite3_create_function($this->db, 'basename', 1, 'basename');
+               $this->setConnStatus(true);
+            }
+            break;
+         case 'pdo':
+            try {
+               $this->db =  new PDO("sqlite:".$this->db_path);
+               $this->setConnStatus(true);
+            }
+            catch (Exception $e) {
+               $this->throwError("Unable to connect to database:" . $e->getMessage());
+               $this->setConnStatus(false);
+            }
+            break;
 
-         $this->throwError("Unable to connect to database:" . $this->getLastError());
-         $this->setConnStatus(false);
       }
 
-      $this->setConnStatus(true);
-
    } // db_connect()
 
    /**
@@ -82,8 +107,15 @@ class PHPFSPOT_DB {
     */
    private function db_disconnect()
    {
-      if($this->getConnStatus())
-         sqlite3_close($this->db);
+      switch($this->parent->cfg->db_access) {
+         case 'native':
+            if($this->getConnStatus())
+               sqlite3_close($this->db);
+            break;
+         case 'pdo':
+            $this->db = NULL;
+            break;
+      }
 
    } // db_disconnect()
 
@@ -95,15 +127,30 @@ class PHPFSPOT_DB {
     */
    public function db_query($query = "")
    {
-      if($this->getConnStatus()) {
+      if(!$this->getConnStatus())
+         return false;
+   
+      $this->last_query = $query;
+
+      switch($this->parent->cfg->db_access) {
+         case 'native':
+            if(($result = sqlite3_query($this->db, $query)) === false)
+               $this->ThrowError($this->getLastError());
+            break;
+         case 'pdo':
+            try{
+               $result = $this->db->query($query);
+               return $result;
+            }
+            catch (Exception $e) {
+               $this->ThrowError($e->getMessage());
+               $result= NULL;
+            }
+            break;
 
-         if(($result = sqlite3_query($this->db, $query)) === false)
-            $this->ThrowError($this->getLastError());
-       
-         return $result;
       }
-      else 
-         $this->ThrowError("Can't execute query - we are not connected!");
+
+      return $result;
 
    } // db_query()
 
@@ -114,20 +161,41 @@ class PHPFSPOT_DB {
     */
    public function db_exec($query = "")
    {
-      if($this->getConnStatus()) {
-
-         if(($result = sqlite3_exec($this->db, $query)) === false)
-            $this->ThrowError($this->getLastError());
+      if(!$this->getConnStatus())
+         return false;
 
+      $this->last_query = $query;
+
+      switch($this->parent->cfg->db_access) {
+         case 'native':
+            if(($result = sqlite3_exec($this->db, $query)) === false) {
+               $this->ThrowError($this->getLastError());
+               return false;
+            }
+            break;
+         case 'pdo':
+            try {
+               $result = $this->db->query($query);
+            }
+            catch (Exception $e){
+               $this->ThrowError($e->getLMessage());
+               return false;
+            }
+            break;
       }
-      else 
-         $this->ThrowError("Can't execute query - we are not connected!");
+
+      return true;
 
    } // db_exec()
 
-   public function db_fetch_object(&$resource)
+   public function db_fetch_object($resource)
    {
-      return sqlite3_fetch_array($resource);
+      switch($this->parent->cfg->db_access) {
+         case 'native':
+            return sqlite3_fetch_array($resource);
+         case 'pdo':
+            return $resource->fetch();
+      }
 
    } // db_fetch_object
 
@@ -139,14 +207,19 @@ class PHPFSPOT_DB {
     */
    public function db_fetchSingleRow($query = "") 
    {
-      if($this->getConnStatus()) {
+      if(!$this->getConnStatus())
+         return false;
 
-         $result = $this->db_query($query);
-         $row = $result->fetchRow();
-         return $row;
+      $result = $this->db_query($query);
+      switch($this->parent->cfg->db_access) {
+         case 'native':
+            $row = $this->db_fetch_object($result);
+            break;
+         case 'pdo':
+            $row = $result->fetch();
+            break;
       }
-      else 
-         $this->ThrowError("Can't fetch row - we are not connected!");
+      return $row;
       
    } // db_fetchSingleRow()
 
@@ -169,19 +242,6 @@ class PHPFSPOT_DB {
 
    } // db_getNumRows()
 
-   /**
-    * PHPFSPOT_DB get primary key
-    *
-    * This function returns the primary key of the last
-    * operated insert SQL query.
-    */
-   public function db_getid()
-   {
-      /* Get the last primary key ID from execute query */
-      return mysql_insert_id($this->db->connection);
-      
-   } // db_getid()
-
    /**
     * PHPFSPOT_DB check table exists
     *
@@ -192,20 +252,63 @@ class PHPFSPOT_DB {
     */
    public function db_check_table_exists($table_name = "")
    {
-      if($this->getConnStatus()) {
-
-         $result = $this->db_query("SELECT name FROM sqlite_master WHERE type='table'");
-         while($table = $this->db_fetch_object($result)) {
-            if($table['name'] == $table_name)
-               return true;
-         }
+      if(!$this->getConnStatus())
          return false;
-      }
-      else
-         $this->ThrowError("Can't check table - we are not connected!");
+
+      $result = $this->db_query("SELECT name FROM sqlite_master WHERE type='table'");
+      switch($this->parent->cfg->db_access) {
+         case 'native':
+            while($table = $this->db_fetch_object($result)) {
+               if($table['name'] == $table_name)
+                  return true;
+            }
+            break;
+         case 'pdo':
+            foreach($result as $table ){
+               if($table['NAME'] == $table_name)
+                  return true;
+            }
+            break;
+       }
+
+      return false;
         
    } // db_check_table_exists()
 
+   /**
+    * PHPFSPOT_DB check column exist
+    *
+    * This function checks if the given column exists within
+    * the specified table.
+    */
+   public function db_check_column_exists($table_name, $column)
+   {
+      if(!$this->getConnStatus())
+         return false;
+
+      $result = $this->db_query("
+         SELECT sql
+         FROM
+            (SELECT * FROM sqlite_master UNION ALL
+             SELECT * FROM sqlite_temp_master)
+         WHERE
+            tbl_name LIKE '". $table_name ."'
+         AND type!='meta'
+         AND sql NOT NULL
+         AND name NOT LIKE 'sqlite_%'
+         ORDER BY substr(type,2,1), name
+      ");
+
+      while($row = $this->db_fetch_object($result)) {
+         /* CREATE TABLE xx ( col1 int, col2 bool, col3 ...) */
+         if(strstr($row['sql'], " ". $column ." ") !== false)
+               return true;
+      }
+
+      return false;
+
+   } // db_check_column_exists()
+
    /**
     * PHPFSPOT_DB get connection status
     *
@@ -237,6 +340,7 @@ class PHPFSPOT_DB {
    private function ThrowError($string)
    {
       if(!defined('DB_NOERROR'))  {
+         print "Error during query: ". $this->last_query ."<br /><br />\n";
          print "<br /><br />". $string ."<br /><br />\n";
          try {
             throw new Exception;
@@ -251,10 +355,83 @@ class PHPFSPOT_DB {
 
    private function getLastError()
    {
-      return sqlite3_error($this->db);
+      switch($this->parent->cfg->db_access) {
+         case 'native':
+            return sqlite3_error($this->db);
+         case 'pdo':
+            return "". $this->db->errorInfo();
+      }
 
    } // getLastError()
 
-}
+   /**
+    * start transaction
+    *
+    * this will start a transaction on ACID-supporting database
+    * systems.
+    *
+    * @return bool
+    */
+   public function db_start_transaction()
+   {
+      if(!$this->getConnStatus())
+         return false;
+
+      $result = $this->db_exec("BEGIN");
+
+      /* Errors? */
+      if(PEAR::isError($result))
+         $this->throwError($result->getMessage() .' - '. $result->getUserInfo());
+
+      return true;
+
+   } // db_start_transaction()
+
+   /**
+    * commit transaction
+    *
+    * this will commit an ongoing transaction on ACID-supporting
+    * database systems
+    *
+    * @return bool
+    */
+   public function db_commit_transaction()
+   {
+      if(!$this->getConnStatus())
+         return false;
+
+      $result = $this->db_exec("COMMIT");
+
+      /* Errors? */
+      if(PEAR::isError($result))
+         $this->throwError($result->getMessage() .' - '. $result->getUserInfo());
+
+      return true;
+
+   } // db_commit_transaction()
+
+   /**
+    * rollback transaction()
+    *
+    * this function aborts a on going transaction
+    *
+    * @return bool
+    */
+   public function db_rollback_transaction()
+   {
+      if(!$this->getConnStatus())
+         return false;
+
+      $result = $this->db_exec("ROLLBACK");
+
+      /* Errors? */
+      if(PEAR::isError($result))
+         $this->throwError($result->getMessage() .' - '. $result->getUserInfo());
+
+      return true;
+
+   } // db_rollback_transaction()
+
+} // PHPFSPOT_DB
 
 ?>