]> source.dussan.org Git - nextcloud-server.git/commitdiff
make PDOStatementWrapper return number of updated rows on INSERT, UPDATE or DELETE...
authorJörn Friedrich Dreyer <jfd@butonic.de>
Thu, 20 Jun 2013 12:46:22 +0000 (14:46 +0200)
committerJörn Friedrich Dreyer <jfd@butonic.de>
Mon, 24 Jun 2013 14:29:58 +0000 (16:29 +0200)
lib/db.php

index a6b81aaba69afd943091274ce2fe72390eefe808..984c2bcf14994e7b072cfe63a789d63d105c545c 100644 (file)
@@ -330,7 +330,7 @@ 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, $isManipulation = null) {
 
                if (!is_null($limit) && $limit != -1) {
                        if (self::$backend == self::BACKEND_MDB2) {
@@ -367,12 +367,23 @@ class OC_DB {
                        OC_Log::write('core', 'DB prepare : '.$query, OC_Log::DEBUG);
                }
                self::connect();
+               
+               if ($isManipulation === null) {
+                       //try to guess, so we return the number of rows on manipulations
+                       $isManipulation = self::isManipulation($query);
+               }
+               
                // return the result
                if(self::$backend==self::BACKEND_MDB2) {
-                       $result = self::$connection->prepare( $query );
+                       // differentiate between query and manipulation
+                       if ($isManipulation) {
+                               $result = self::$connection->prepare( $query, null, MDB2_PREPARE_MANIP );
+                       } else {
+                               $result = self::$connection->prepare( $query, null, MDB2_PREPARE_RESULT );
+                       }
 
                        // Die if we have an error (error means: bad query, not 0 results!)
-                       if( PEAR::isError($result)) {
+                       if( self::isError($result)) {
                                throw new DatabaseException($result->getMessage(), $query);
                        }
                }else{
@@ -381,7 +392,12 @@ class OC_DB {
                        }catch(PDOException $e) {
                                throw new DatabaseException($e->getMessage(), $query);
                        }
-                       $result=new PDOStatementWrapper($result);
+                       // differentiate between query and manipulation
+                       if ($isManipulation) {
+                               $result=new PDOStatementWrapper($result, true);
+                       } else {
+                               $result=new PDOStatementWrapper($result, false);
+                       }
                }
                if ((is_null($limit) || $limit == -1) and self::$cachingEnabled ) {
                        $type = OC_Config::getValue( "dbtype", "sqlite" );
@@ -391,7 +407,33 @@ class OC_DB {
                }
                return $result;
        }
-
+       
+       /**
+        * tries to guess the type of statement based on the first 10 characters
+        * the current check allows some whitespace but does not work with IF EXISTS or other more complex statements
+        * 
+        * @param string $sql
+        */
+       static public function isManipulation( $sql ) {
+               $selectOccurence = stripos ($sql, "SELECT");
+               if ($selectOccurence !== false && $selectOccurence < 10) {
+                       return false;
+               }
+               $insertOccurence = stripos ($sql, "INSERT");
+               if ($insertOccurence !== false && $insertOccurence < 10) {
+                       return true;
+               }
+               $updateOccurence = stripos ($sql, "UPDATE");
+               if ($updateOccurence !== false && $updateOccurence < 10) {
+                       return true;
+               }
+               $deleteOccurance = stripos ($sql, "DELETE");
+               if ($deleteOccurance !== false && $deleteOccurance < 10) {
+                       return true;
+               }
+               return false;
+       }
+       
        /**
         * @brief execute a prepared statement, on error write log and throw exception
         * @param mixed $stmt PDOStatementWrapper | MDB2_Statement_Common ,
@@ -718,6 +760,9 @@ class OC_DB {
                } catch(PDOException $e) {
                        OC_Template::printExceptionErrorPage( $e );
                }
+               if ($result === 0) {
+                       return true;
+               }
 
                return $result;
        }
@@ -919,7 +964,7 @@ class OC_DB {
         * @return bool
         */
        public static function isError($result) {
-               if(!$result) {
+               if(self::$backend==self::BACKEND_PDO and $result === false) {
                        return true;
                }elseif(self::$backend==self::BACKEND_MDB2 and PEAR::isError($result)) {
                        return true;
@@ -997,11 +1042,13 @@ class PDOStatementWrapper{
        /**
         * @var PDOStatement
         */
-       private $statement=null;
-       private $lastArguments=array();
+       private $statement = null;
+       private $isManipulation = false;
+       private $lastArguments = array();
 
-       public function __construct($statement) {
-               $this->statement=$statement;
+       public function __construct($statement, $isManipulation = false) {
+               $this->statement = $statement;
+               $this->isManipulation = $isManipulation;
        }
 
        /**
@@ -1023,16 +1070,19 @@ class PDOStatementWrapper{
                                $input = $this->tryFixSubstringLastArgumentDataForMSSQL($input);
                        }
 
-                       $result=$this->statement->execute($input);
+                       $result = $this->statement->execute($input);
                } else {
-                       $result=$this->statement->execute();
+                       $result = $this->statement->execute();
                }
                
-               if ($result) {
-                       return $this;
-               } else {
+               if ($result === false) {
                        return false;
                }
+               if ($this->isManipulation) {
+                       return $this->statement->rowCount();
+               } else {
+                       return $this;
+               }
        }
 
        private function tryFixSubstringLastArgumentDataForMSSQL($input) {