Beispiel #1
0
 /**
  * Executes the statement in buffered mode
  * 
  * @internal
  * 
  * @param  fResult $result     The object to place the result into
  * @param  array   $params     The parameters for the statement
  * @param  mixed   &$extra     A variable to place extra information needed by some database extensions
  * @param  boolean $different  If this statement is different than the last statement run on the fDatabase instance
  * @return void
  */
 public function executeQuery($result, $params, &$extra, $different)
 {
     if ($different && $this->used) {
         $this->regenerateStatement();
     }
     $this->used = TRUE;
     $extension = $this->database->getExtension();
     $connection = $this->database->getConnection();
     $statement = $this->statement;
     $params = $this->prepareParams($params);
     switch ($extension) {
         case 'ibm_db2':
             $extra = $statement;
             if (db2_execute($statement, $params)) {
                 $rows = array();
                 while ($row = db2_fetch_assoc($statement)) {
                     $rows[] = $row;
                 }
                 $result->setResult($rows);
                 unset($rows);
             } else {
                 $result->setResult(FALSE);
             }
             break;
         case 'mssql':
             $result->setResult(mssql_query($this->database->escape($statement, $params), $connection));
             break;
         case 'mysql':
             $result->setResult(mysql_query($this->database->escape($statement, $params), $connection));
             break;
         case 'mysqli':
             $extra = $this->statement;
             if ($statement->execute()) {
                 $rows = array();
                 $meta = $statement->result_metadata();
                 if ($meta) {
                     $row_references = array();
                     while ($field = $meta->fetch_field()) {
                         $row_references[] =& $row[$field->name];
                     }
                     call_user_func_array(array($statement, 'bind_result'), $row_references);
                     while ($statement->fetch()) {
                         $copied_row = array();
                         foreach ($row as $key => $val) {
                             $copied_row[$key] = $val;
                         }
                         $rows[] = $copied_row;
                     }
                 }
                 $result->setResult($rows);
                 $statement->free_result();
             } else {
                 $result->setResult(FALSE);
             }
             break;
         case 'oci8':
             $extra = $this->statement;
             if (oci_execute($extra, $this->database->isInsideTransaction() ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS)) {
                 oci_fetch_all($extra, $rows, 0, -1, OCI_FETCHSTATEMENT_BY_ROW + OCI_ASSOC);
                 $result->setResult($rows);
                 unset($rows);
             } else {
                 $result->setResult(FALSE);
             }
             break;
         case 'odbc':
             $extra = $this->statement;
             if (odbc_execute($statement, $params)) {
                 $rows = array();
                 // Allow up to 1MB of binary data
                 odbc_longreadlen($statement, 1048576);
                 odbc_binmode($statement, ODBC_BINMODE_CONVERT);
                 while ($row = odbc_fetch_array($statement)) {
                     $rows[] = $row;
                 }
                 $result->setResult($rows);
                 unset($rows);
             } else {
                 $result->setResult(FALSE);
             }
             break;
         case 'pgsql':
             $result->setResult(pg_execute($connection, $this->identifier, $params));
             break;
         case 'sqlite':
             $result->setResult(sqlite_query($connection, $this->database->escape($statement, $params), SQLITE_ASSOC, $extra));
             break;
         case 'sqlsrv':
             $extra = $statement;
             if (sqlsrv_execute($statement)) {
                 $rows = array();
                 while ($row = sqlsrv_fetch_array($statement, SQLSRV_FETCH_ASSOC)) {
                     $rows[] = $row;
                 }
                 $result->setResult($rows);
                 unset($rows);
             } else {
                 $result->setResult(FALSE);
             }
             break;
         case 'pdo':
             $extra = $this->statement;
             if (preg_match('#^\\s*CREATE(\\s+OR\\s+REPLACE)?\\s+TRIGGER#i', $result->getSQL())) {
                 $extra->execute();
                 $returned_rows = array();
             } else {
                 if (!$extra->execute()) {
                     $returned_rows = FALSE;
                 } else {
                     $returned_rows = $extra->fetchAll(PDO::FETCH_ASSOC);
                     // The pdo_pgsql driver likes to return empty rows equal to the number of affected rows for insert and deletes
                     if ($this->database->getType() == 'postgresql' && $returned_rows && $returned_rows[0] == array()) {
                         $returned_rows = array();
                     }
                 }
             }
             $result->setResult($returned_rows);
             break;
     }
     return $result;
 }
 /**
  * Sets the number of rows affected by the query
  * 
  * @param  fResult $result    The result object for the query
  * @param  mixed   $resource  Only applicable for `ibm_db2`, `pdo`, `oci8` and `sqlsrv` extentions or `mysqli` prepared statements - this is either the `PDOStatement` object, `mysqli_stmt` object or the `oci8` or `sqlsrv` resource
  * @return void
  */
 private function setAffectedRows($result, $resource = NULL)
 {
     if ($this->extension == 'ibm_db2') {
         $insert_update_delete = preg_match('#^\\s*(INSERT|UPDATE|DELETE)\\b#i', $result->getSQL());
         $result->setAffectedRows(!$insert_update_delete ? 0 : db2_num_rows($resource));
     } elseif ($this->extension == 'mssql') {
         $affected_rows_result = mssql_query('SELECT @@ROWCOUNT AS rows', $this->connection);
         $result->setAffectedRows((int) mssql_result($affected_rows_result, 0, 'rows'));
     } elseif ($this->extension == 'mysql') {
         $result->setAffectedRows(mysql_affected_rows($this->connection));
     } elseif ($this->extension == 'mysqli') {
         if (is_object($resource)) {
             $result->setAffectedRows($resource->affected_rows);
         } else {
             $result->setAffectedRows(mysqli_affected_rows($this->connection));
         }
     } elseif ($this->extension == 'oci8') {
         $result->setAffectedRows(oci_num_rows($resource));
     } elseif ($this->extension == 'pgsql') {
         $result->setAffectedRows(pg_affected_rows($result->getResult()));
     } elseif ($this->extension == 'sqlite') {
         $result->setAffectedRows(sqlite_changes($this->connection));
     } elseif ($this->extension == 'sqlsrv') {
         $result->setAffectedRows(sqlsrv_rows_affected($resource));
     } elseif ($this->extension == 'pdo') {
         // This fixes the fact that rowCount is not reset for non INSERT/UPDATE/DELETE statements
         try {
             if (!$resource || !$resource->fetch()) {
                 throw new PDOException();
             }
             $result->setAffectedRows(0);
         } catch (PDOException $e) {
             // The SQLite PDO driver seems to return 1 when no rows are returned from a SELECT statement
             if ($this->type == 'sqlite' && $this->extension == 'pdo' && preg_match('#^\\s*SELECT#i', $result->getSQL())) {
                 $result->setAffectedRows(0);
             } elseif (!$resource) {
                 $result->setAffectedRows(0);
             } else {
                 $result->setAffectedRows($resource->rowCount());
             }
         }
     }
 }
Beispiel #3
0
 /**
  * Executes the statement in buffered mode
  * 
  * @internal
  * 
  * @param  fResult $result     The object to place the result into
  * @param  array   $params     The parameters for the statement
  * @param  mixed   &$extra     A variable to place extra information needed by some database extensions
  * @param  boolean $different  If this statement is different than the last statement run on the fDatabase instance
  * @return void
  */
 public function executeQuery($result, $params, &$extra, $different)
 {
     if (is_array($params) && count($params) == 1 && is_array($params[0]) && count($this->placeholders) > 1) {
         $params = $params[0];
     }
     if ($different && $this->used) {
         $this->regenerateStatement();
     }
     $this->used = TRUE;
     $extension = $this->database->getExtension();
     if ($extension == 'pdo' && $this->database->getType() == 'mssql') {
         $extension = 'pdo_dblib';
     }
     $connection = $this->database->getConnection();
     $statement = $this->statement;
     $params = $this->prepareParams($params);
     switch ($extension) {
         case 'ibm_db2':
             $extra = $statement;
             if (db2_execute($statement, $params)) {
                 $rows = array();
                 while ($row = db2_fetch_assoc($statement)) {
                     $rows[] = $row;
                 }
                 $result->setResult($rows);
                 unset($rows);
             } else {
                 $result->setResult(FALSE);
             }
             break;
         case 'mssql':
             $result->setResult(mssql_query($this->database->escape($statement, $params), $connection));
             break;
         case 'mysql':
             $result->setResult(mysql_query($this->database->escape($statement, $params), $connection));
             break;
         case 'mysqli':
             $extra = $this->statement;
             if ($statement->execute()) {
                 $statement->store_result();
                 $rows = array();
                 $meta = $statement->result_metadata();
                 if ($meta) {
                     $row_references = array();
                     while ($field = $meta->fetch_field()) {
                         $row_references[] =& $row[$field->name];
                     }
                     call_user_func_array(array($statement, 'bind_result'), $row_references);
                     while ($statement->fetch()) {
                         $copied_row = array();
                         foreach ($row as $key => $val) {
                             $copied_row[$key] = $val;
                         }
                         $rows[] = $copied_row;
                     }
                     unset($row_references);
                     $meta->free_result();
                 }
                 $result->setResult($rows);
                 $statement->free_result();
             } else {
                 $result->setResult(FALSE);
             }
             break;
         case 'oci8':
             $extra = $this->statement;
             if (oci_execute($extra, $this->database->isInsideTransaction() ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS)) {
                 // oci8 complains if you try to fetch results multiple times from a prepared statement
                 // if the statement does not returns any rows, so we ignore easy-to-detect non-selects
                 if (!preg_match('#\\s*(INSERT|UPDATE|DELETE)\\s+#i', $this->sql)) {
                     oci_fetch_all($extra, $rows, 0, -1, OCI_FETCHSTATEMENT_BY_ROW + OCI_ASSOC);
                 } else {
                     $rows = array();
                 }
                 $result->setResult($rows);
                 unset($rows);
             } else {
                 $result->setResult(FALSE);
             }
             break;
         case 'pgsql':
             $result->setResult(pg_execute($connection, $this->identifier, $params));
             break;
         case 'sqlite':
             $result->setResult(sqlite_query($connection, $this->database->escape($statement, $params), SQLITE_ASSOC, $extra));
             break;
         case 'sqlsrv':
             $extra = $statement;
             if (sqlsrv_execute($statement)) {
                 $rows = array();
                 while ($row = sqlsrv_fetch_array($statement, SQLSRV_FETCH_ASSOC)) {
                     $rows[] = $row;
                 }
                 $result->setResult($rows);
                 unset($rows);
             } else {
                 $result->setResult(FALSE);
             }
             break;
         case 'pdo':
             $extra = $this->statement;
             if (preg_match('#^\\s*CREATE(\\s+OR\\s+REPLACE)?\\s+TRIGGER#i', $result->getSQL())) {
                 $extra->execute();
                 $returned_rows = array();
             } else {
                 if (!$extra->execute()) {
                     $returned_rows = FALSE;
                 } else {
                     // This fixes a segfault issue with blobs and fetchAll() for pdo_ibm
                     if ($this->database->getType() == 'db2') {
                         $returned_rows = array();
                         $scanned_for_blobs = FALSE;
                         $blob_columns = array();
                         while (($row = $extra->fetch(PDO::FETCH_ASSOC)) !== FALSE) {
                             if (!$scanned_for_blobs) {
                                 foreach ($row as $key => $value) {
                                     if (is_resource($value)) {
                                         $blob_columns[] = $key;
                                     }
                                 }
                             }
                             foreach ($blob_columns as $blob_column) {
                                 $row[$blob_column] = stream_get_contents($row[$blob_column]);
                             }
                             $returned_rows[] = $row;
                         }
                     } else {
                         $returned_rows = $extra->fetchAll(PDO::FETCH_ASSOC);
                     }
                     // The pdo_pgsql driver likes to return empty rows equal to the number of affected rows for insert and deletes
                     if ($this->database->getType() == 'postgresql' && $returned_rows && $returned_rows[0] == array()) {
                         $returned_rows = array();
                     }
                 }
             }
             $result->setResult($returned_rows);
             break;
         case 'pdo_dblib':
             $extra = $connection->query($this->database->escape($statement, $params));
             $returned_rows = is_object($extra) ? $extra->fetchAll(PDO::FETCH_ASSOC) : $extra;
             $result->setResult($returned_rows);
             break;
     }
     return $result;
 }