/** * Runs a single statement and times it, removes any old unbuffered queries before starting * * @param string|fStatement $statement The SQL statement or prepared statement to execute * @param string $result_type The type of result object to return, fResult or fUnbufferedResult * @return fResult|fUnbufferedResult The result for the query */ private function run($statement, $result_type = NULL, $params = array()) { if ($this->unbuffered_result) { $this->unbuffered_result->__destruct(); $this->unbuffered_result = NULL; } $start_time = microtime(TRUE); if (is_object($statement)) { $sql = $statement->getSQL(); } else { $sql = $statement; } if (!($result = $this->handleTransactionQueries($sql, $result_type))) { if ($result_type) { $result = new $result_type($this, $this->type == 'mssql' ? $this->schema_info['character_set'] : NULL); $result->setSQL($sql); if ($result_type == 'fResult') { $this->performQuery($statement, $result, $params); } else { $this->performUnbufferedQuery($statement, $result, $params); } } else { $this->perform($statement, $params); } } // Write some debugging info $query_time = microtime(TRUE) - $start_time; $this->query_time += $query_time; if (fCore::getDebug($this->debug)) { fCore::debug(self::compose('Query time was %1$s seconds for:%2$s', $query_time, "\n" . $sql), $this->debug); } if ($this->hook_callbacks['run']) { foreach ($this->hook_callbacks['run'] as $callback) { $callback_params = array($this, is_object($statement) ? array($statement, $params) : $sql, $query_time, $result); call_user_func_array($callback, $callback_params); } } if ($result_type) { return $result; } }
/** * Runs a single query and times it, removes any old unbuffered queries before starting * * @param string $sql The SQL statement to execute * @param string $result_type The type of result object to return, fResult or fUnbufferedResult * @return fResult|fUnbufferedResult The result for the query */ private function runQuery($sql, $result_type) { if ($this->unbuffered_result) { $this->unbuffered_result->__destruct(); $this->unbuffered_result = NULL; } $start_time = microtime(TRUE); if (!($result = $this->handleTransactionQueries($sql, $result_type))) { $result = new $result_type($this, $this->type == 'mssql' ? $this->schema_info['character_set'] : NULL); $result->setSQL($sql); if ($result_type == 'fResult') { $this->executeQuery($result); } else { $this->executeUnbufferedQuery($result); } } // Write some debugging info $query_time = microtime(TRUE) - $start_time; $this->query_time += $query_time; fCore::debug(self::compose('Query time was %1$s seconds for:%2$s', $query_time, "\n" . $result->getSQL()), $this->debug); if ($this->slow_query_threshold && $query_time > $this->slow_query_threshold) { trigger_error(self::compose('The following query took %1$s milliseconds, which is above the slow query threshold of %2$s:%3$s', $query_time, $this->slow_query_threshold, "\n" . $result->getSQL()), E_USER_WARNING); } return $result; }
/** * Executes the statement in unbuffered mode (if possible) * * @internal * * @param fUnbufferedResult $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 executeUnbufferedQuery($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); // For the extensions that require the statement be passed to the result // object, we store it in a stdClass object so the result object knows // not to free it when done $statement_holder = new stdClass(); $statement_holder->statement = NULL; switch ($extension) { case 'ibm_db2': $extra = $statement; if (db2_execute($statement, $params)) { $statement_holder->statement = $statement; } else { $result->setResult(FALSE); } break; case 'mssql': $result->setResult(mssql_query($result->getSQL(), $this->connection, 20)); break; case 'mysql': $result->setResult(mysql_unbuffered_query($result->getSQL(), $this->connection)); break; case 'mysqli': $extra = $this->statement; if ($statement->execute()) { $statement_holder->statement = $statement; } else { $result->setResult(FALSE); } break; case 'oci8': $result->setResult(oci_execute($statement, $this->database->isInsideTransaction() ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS)); break; case 'odbc': $extra = odbc_execute($statement, $params); if ($extra) { odbc_longreadlen($statement, 1048576); odbc_binmode($statement, ODBC_BINMODE_CONVERT); $statement_holder->statement = $statement; } else { $result->setResult($extra); } break; case 'pgsql': $result->setResult(pg_execute($connection, $this->identifier, $params)); break; case 'sqlite': $result->setResult(sqlite_unbuffered_query($connection, $this->database->escape($statement, $params), SQLITE_ASSOC, $extra)); break; case 'sqlsrv': $extra = sqlsrv_execute($statement); if ($extra) { $statement_holder->statement = $statement; } else { $result->setResult($extra); } break; case 'pdo': $extra = $statement->execute(); if ($extra) { $result->setResult($statement); } else { $result->setResult($extra); } break; } if ($statement_holder->statement) { $result->setResult($statement_holder); } return $result; }
/** * Turns off notices about broken database extensions much as the MSSQL DBLib driver * * @return void */ public static function silenceNotices() { self::$silence_notices = TRUE; }
/** * Executes the statement in unbuffered mode (if possible) * * @internal * * @param fUnbufferedResult $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 executeUnbufferedQuery($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); // For the extensions that require the statement be passed to the result // object, we store it in a stdClass object so the result object knows // not to free it when done $statement_holder = new stdClass(); $statement_holder->statement = NULL; switch ($extension) { case 'ibm_db2': $extra = $statement; if (db2_execute($statement, $params)) { $statement_holder->statement = $statement; } else { $result->setResult(FALSE); } break; case 'mssql': $result->setResult(mssql_query($result->getSQL(), $this->connection, 20)); break; case 'mysql': $result->setResult(mysql_unbuffered_query($result->getSQL(), $this->connection)); break; case 'mysqli': $extra = $this->statement; if ($statement->execute()) { $statement_holder->statement = $statement; } else { $result->setResult(FALSE); } break; case 'oci8': $result->setResult(oci_execute($statement, $this->database->isInsideTransaction() ? OCI_DEFAULT : OCI_COMMIT_ON_SUCCESS)); break; case 'pgsql': $result->setResult(pg_execute($connection, $this->identifier, $params)); break; case 'sqlite': $result->setResult(sqlite_unbuffered_query($connection, $this->database->escape($statement, $params), SQLITE_ASSOC, $extra)); break; case 'sqlsrv': $extra = sqlsrv_execute($statement); if ($extra) { $statement_holder->statement = $statement; } else { $result->setResult($extra); } break; case 'pdo': $extra = $statement->execute(); if ($extra) { $result->setResult($statement); } else { $result->setResult($extra); } break; case 'pdo_dblib': $sql = $this->database->escape($statement, $params); $result->setResult($res = $connection->query($sql)); break; } if ($statement_holder->statement) { $result->setResult($statement_holder); } return $result; }