diff --git a/inc/AwlDBDialect.php b/inc/AwlDBDialect.php deleted file mode 100644 index fc982029..00000000 --- a/inc/AwlDBDialect.php +++ /dev/null @@ -1,361 +0,0 @@ - -* @copyright Morphoss Ltd -* @license http://gnu.org/copyleft/gpl.html GNU GPL v3 or later -* @compatibility Requires PHP 5.1 or later -*/ - -if ( !defined('E_USER_ERROR') ) define('E_USER_ERROR',256); - -/** -* The AwlDBDialect class handles support for different SQL dialects -* -* This subpackage provides dialect specific support for PostgreSQL, and -* may, over time, be extended to provide support for other SQL dialects. -* -* If you are looking for the place to add support for other SQL dialects, -* this is the class that you should be looking at. You might also look at -* the AwlDatabase class which extends this one, but these are the core -* capabilities which most probably need attention. -* -* @package awl -*/ -class AwlDBDialect { - /**#@+ - * @access private - */ - - /** - * Holds the name of the database dialect - */ - protected $dialect; - - /** - * Holds the PDO database connection - */ - protected $db; - - /** - * Holds the version - */ - private $version; - - /**#@-*/ - - - /** - * Parses the connection string to ascertain the database dialect. Returns true if the dialect is supported - * and fails if the dialect is not supported. All code to support any given database should be within in an - * external include. - * - * The database will be opened. - * - * @param string $connection_string The PDO connection string, in all it's glory - * @param string $dbuser The database username to connect as - * @param string $dbpass The database password to connect with - * @param array $options An array of driver options - */ - function __construct( $connection_string, $dbuser=null, $dbpass=null, $options=null ) { - if ( preg_match( '/^(pgsql):/', $connection_string, $matches ) ) { - $this->dialect = $matches[1]; - } - else { - trigger_error("Unsupported database connection '".$connection_string."'",E_USER_ERROR); - } - try { - $this->db = new PDO( $connection_string, $dbuser, $dbpass, $options ); - } catch (PDOException $e) { - trigger_error("PDO connection error '".$connection_string."': ".$e->getMessage(),E_USER_ERROR); - } - } - - - - /** - * Sets the current search path for the database. - */ - function SetSearchPath( $search_path = null ) { - if ( !isset($this->dialect) ) { - trigger_error("Unsupported database dialect",E_USER_ERROR); - } - - switch ( $this->dialect ) { - case 'pgsql': - if ( $search_path == null ) $search_path = 'public'; - $sql = "SET search_path TO " . $this->Quote( $search_path, 'identifier' ); - return $sql; - } - } - - - /** - * Sets the current search path for the database. - * @param handle $pdo A handle to an opened database - */ - function GetVersion( ) { - if ( isset($this->version) ) return $this->version; - if ( !isset($this->dialect) ) { - trigger_error("Unsupported database dialect", E_USER_ERROR); - } - - $version = $this->dialect.':'; - - switch ( $this->dialect ) { - case 'pgsql': - $sql = "SELECT version()"; - if ( $sth = $this->db->query($sql) ) { - $row = $sth->fetch(PDO::FETCH_NUM); - $version .= preg_replace( '/^PostgreSQL (\d+\.\d+)\..*$/i', '$1', $row[0]); - } - break; - default: - return null; - } - $this->version = $version; - return $version; - } - - - /** - * Returns the SQL for the current database dialect which will return a two-column resultset containing a - * list of fields and their associated data types. - * @param string $tablename_string The name of the table we want fields from - */ - function GetFields( $tablename_string ) { - if ( !isset($this->dialect) ) { - trigger_error("Unsupported database dialect", E_USER_ERROR); - } - - switch ( $this->dialect ) { - case 'pgsql': - $tablename_string = $this->Quote($tablename_string, 'identifier'); - $sql = "SELECT f.attname, t.typname FROM pg_attribute f "; - $sql .= "JOIN pg_class c ON ( f.attrelid = c.oid ) "; - $sql .= "JOIN pg_type t ON ( f.atttypid = t.oid ) "; - $sql .= "WHERE relname = $tablename_string AND attnum >= 0 order by f.attnum;"; - return $sql; - } - } - - - /** - * Translates the given SQL string into a form that will hopefully work for this database dialect. This hook - * is intended to be used by developers to provide support for differences in database operation by translating - * the query string in an arbitrary way, such as through a file or database lookup. - * - * The actual translation to other SQL dialects will be application-specific, so that any routines - * called by this will be external to this library, or will use resources loaded from some source - * external to this library. - * - * The application developer is expected to use this functionality to solve harder translation problems, - * but is less likely to call this directly, hopefully switching ->Prepare to ->PrepareTranslated in those - * cases, and then adding that statement to whatever SQL translation infrastructure is in place. - */ - function TranslateSQL( $sql_string ) { - // Noop for the time being... - return $sql_string; - } - - - - /** - * Returns $value escaped in an appropriate way for this database dialect. - * @param mixed $value The value to be escaped - * @param string $value_type The type of escaping desired. If blank this will - * be worked out from the type of the $value. The special type - * of 'identifier' can also be used for escaping of SQL identifiers. - */ - function Quote( $value, $value_type = null ) { - if ( isset($value_type) && $value_type == 'identifier' ) { - if ( $this->dialect == 'mysql' ) { - /** @TODO: Someone should confirm this is correct for MySql */ - $rv = '`' . str_replace('`', '\\`', $value ) . '`'; - } - else { - $rv = '"' . str_replace('"', '\\"', $value ) . '"'; - } - return $rv; - } - - if ( !isset($value_type) ) { - if ( !isset($value) ) $value_type = PDO::PARAM_NULL; - elseif ( is_bool($value) ) $value_type = PDO::PARAM_BOOL; - elseif ( is_float($value) ) $value_type = PDO::PARAM_INT; - elseif ( is_numeric($value)) { - if ( preg_match('{^(19|20)\d\d(0[1-9]|1[012])([012]\d|30|31)$}', $value) ) - $value_type = PDO::PARAM_STR; // YYYYMMDD - elseif ( preg_match('{^[0-9+-]+e[0-9+-]+$}i', $value) ) - $value_type = PDO::PARAM_STR; // 72e57650 could easily be a string - else - $value_type = PDO::PARAM_INT; - } - else - $value_type = PDO::PARAM_STR; - } - - if ( is_string($value_type) ) { - switch( $value_type ) { - case 'null': - $value_type = PDO::PARAM_NULL; - break; - case 'integer': - case 'double' : - $value_type = PDO::PARAM_INT; - break; - case 'boolean': - $value_type = PDO::PARAM_BOOL; - break; - case 'string': - $value_type = PDO::PARAM_STR; - break; - } - } - - switch ( $value_type ) { - case PDO::PARAM_NULL: - $rv = 'NULL'; - break; - case PDO::PARAM_INT: - $rv = $value; - break; - case PDO::PARAM_BOOL: - $rv = ($value ? 'TRUE' : 'FALSE'); - break; - case PDO::PARAM_STR: - default: - /** - * PDO handling of \ seems unreliable. We can't use $$string$$ syntax because it also doesn't - * work. We need to replace ':' so no other named parameters accidentally rewrite the content - * inside this string(!), and since we're using ' to delimit the string we need SQL92-compliant - * '' to replace it. - */ - $rv = "'".str_replace("'", "''", str_replace(':', '\\x3a', str_replace('\\', '\\x5c', $value)))."'"; - - if ( $this->dialect == 'pgsql' && strpos( $rv, '\\' ) !== false ) { - /** - * PostgreSQL wants to know when a string might contain escapes, and if this - * happens old versions of PHP::PDO need the ? escaped as well... - */ - $rv = 'E'.str_replace('?', '\\x3f', $rv); - } - - } - - return $rv; - - } - - - /** - * Replaces query parameters with appropriately escaped substitutions. - * - * The function takes a variable number of arguments, the first is the - * SQL string, with replaceable '?' characters (a la DBI). The subsequent - * parameters being the values to replace into the SQL string. - * - * The values passed to the routine are analyzed for type, and quoted if - * they appear to need quoting. This can go wrong for (e.g.) NULL or - * other special SQL values which are not straightforwardly identifiable - * as needing quoting (or not). In such cases the parameter can be forced - * to be inserted unquoted by passing it as "array( 'plain' => $param )". - * - * @param string The query string with replacable '?' characters. - * @param mixed The values to replace into the SQL string. - * @return The built query string - */ - function ReplaceParameters() { - $argc = func_num_args(); - $args = func_get_args(); - - if ( is_array($args[0]) ) { - /** - * If the first argument is an array we treat that as our arguments instead - */ - $args = $args[0]; - $argc = count($args); - } - $qry = array_shift($args); - - if ( is_array($args[0]) ) { - $args = $args[0]; - $argc = count($args); - } - - if ( ! isset($args[0]) ) return $this->ReplaceNamedParameters($qry,$args); - - /** - * We only split into a maximum of $argc chunks. Any leftover ? will remain in - * the string and may be replaced at Exec rather than Prepare. Scary! - */ - $parts = explode( '?', $qry, $argc + 1 ); - $querystring = $parts[0]; - $z = count($parts); - - for( $i = 0; $i < $argc; $i++ ) { - $arg = $args[$i]; - $querystring .= $this->Quote($arg); //parameter - $z = $i+1; - if ( isset($parts[$z]) ) $querystring .= $parts[$z]; - } - - return $querystring; - } - - /** - * Replaces named query parameters of the form :name with appropriately - * escaped substitutions. - * - * The function takes a variable number of arguments, the first is the - * SQL string, with replaceable ':name' characters (a la DBI). The - * subsequent parameters being the values to replace into the SQL string. - * - * The values passed to the routine are analyzed for type, and quoted if - * they appear to need quoting. This can go wrong for (e.g.) NULL or - * other special SQL values which are not straightforwardly identifiable - * as needing quoting (or not). - * - * @param string The query string with replacable ':name' identifiers - * @param mixed A ':name' => 'value' hash of values to replace into the - * SQL string. - * @return The built query string - */ - function ReplaceNamedParameters() { - $argc = func_num_args(); - $args = func_get_args(); - - if ( is_array($args[0]) ) { - /** - * If the first argument is an array we treat that as our arguments instead - */ - $args = $args[0]; - $argc = count($args); - } - $querystring = array_shift($args); - - if ( is_array($args[0]) ) { - $args = $args[0]; - $argc = count($args); - } - - foreach( $args AS $name => $value ) { - if ( substr($name, 0, 1) != ':' ) { - dbg_error_log( "ERROR", "AwlDBDialect: Named parameter '%s' does not begin with a colon.", $name); - } - $replacement = str_replace('$', '\\$', $this->Quote($value)); // No positional replacement in $replacement! - $querystring = preg_replace( '{\Q'.$name.'\E\b}s', $replacement, $querystring ); - } - - return $querystring; - } - -} diff --git a/inc/AwlDatabase.php b/inc/AwlDatabase.php deleted file mode 100644 index fb92ffca..00000000 --- a/inc/AwlDatabase.php +++ /dev/null @@ -1,178 +0,0 @@ -pdo_connect. -* -* We will die if the database is not currently connected and we fail to find -* a working connection. -* -* @package awl -* @subpackage AwlDatabase -* @author Andrew McMillan -* @copyright Morphoss Ltd -* @license http://gnu.org/copyleft/gpl.html GNU GPL v3 or later -* @compatibility Requires PHP 5.1 or later -*/ - -if ( !class_exists('AwlDBDialect') ) require('AwlDBDialect.php'); - -if ( !defined('E_USER_ERROR') ) define('E_USER_ERROR',256); - - -/** -* Methods in the AwlDBDialect class which we inherit, include: -* __construct() -* SetSearchPath( $search_path ) -* GetVersion() -* GetFields( $tablename_string ) -* TranslateSQL( $sql_string ) -* Quote( $value, $value_type = null ) -* ReplaceParameters( $query_string [, param [, ...]] ) -*/ - - -/** -* Typically there will only be a single instance of the database level class in an application. -* @package awl -*/ -class AwlDatabase extends AwlDBDialect { - /**#@+ - * @access private - */ - - /** - * Holds the state of the transaction 0 = not started, 1 = in progress, -1 = error pending rollback/commit - */ - protected $txnstate = 0; - - /** - * Holds whether we are translating all statements. - */ - protected $translate_all = false; - - /**#@-*/ - - /** - * Returns a PDOStatement object created using this database, the supplied SQL string, and any parameters given. - * @param string $sql_query_string The SQL string containing optional variable replacements - * @param array $driver_options PDO driver options to the prepare statement, commonly to do with cursors - */ - function prepare( $statement, $driver_options = array() ) { - if ( isset($this->translate_all) && $this->translate_all ) { - $statement = $this->TranslateSQL( $statement ); - } - return $this->db->prepare( $statement, $driver_options ); - } - - - /** - * Returns a PDOStatement object created using this database, the supplied SQL string, and any parameters given. - * @param string $sql_query_string The SQL string containing optional variable replacements - * @param mixed ... Subsequent arguments are positionally replaced into the $sql_query_string - */ - function query( $statement ) { - return $this->db->query( $statement ); - } - - - /** - * Begin a transaction. - */ - function Begin() { - if ( $this->txnstate == 0 ) { - $this->db->beginTransaction(); - $this->txnstate = 1; - } - else { - trigger_error("Cannot begin a transaction while a transaction is already active.",E_USER_ERROR); - } - return true; - } - - - /** - * Complete a transaction. - */ - function Commit() { - if ( $this->txnstate != 0 ) { - $this->db->commit(); - $this->txnstate = 0; - } - return true; - } - - - /** - * Cancel a transaction in progress. - */ - function Rollback() { - if ( $this->txnstate != 0 ) { - $this->db->rollBack(); - $this->txnstate = 0; - } - else { - trigger_error("Cannot rollback unless a transaction is already active.",E_USER_ERROR); - } - return true; - } - - - /** - * Returns the current state of a transaction, indicating if we have begun a transaction, whether the transaction - * has failed, or if we are not in a transaction. - */ - function TransactionState() { - return $this->txnstate; - } - - - /** - * Operates identically to AwlDatabase::Prepare, except that $this->Translate() will be called on the query - * before any processing. - */ - function PrepareTranslated( $statement, $driver_options = array() ) { - $statement = $this->TranslateSQL( $statement ); - return $this->prepare( $statement, $driver_options ); - } - - - /** - * Switches on or off the processing flag controlling whether subsequent calls to AwlDatabase::Prepare are translated - * as if PrepareTranslated() had been called. - */ - function TranslateAll( $onoff_boolean ) { - $this->translate_all = $onoff_boolean; - return $onoff_boolean; - } - - - /** - * - */ - function ErrorInfo() { - return $this->db->errorInfo(); - } - -} - - diff --git a/inc/AwlQuery.php b/inc/AwlQuery.php deleted file mode 100644 index 45f4abb5..00000000 --- a/inc/AwlQuery.php +++ /dev/null @@ -1,606 +0,0 @@ - -* @copyright Morphoss Ltd -* @license http://gnu.org/copyleft/gpl.html GNU GPL v3 or later -* @compatibility Requires PHP 5.1 or later -*/ - -require_once('AwlDatabase.php'); - -/** -* Database query class and associated functions -* -* This subpackage provides some functions that are useful around database -* activity and an AwlQuery class to simplify handling of database queries. -* -* The class is intended to be a very lightweight wrapper with no pretentions -* towards database independence, but it does include some features that have -* proved useful in developing and debugging web-based applications: -* - All queries are timed, and an expected time can be provided. -* - Parameters replaced into the SQL will be escaped correctly in order to -* minimise the chances of SQL injection errors. -* - Queries which fail, or which exceed their expected execution time, will -* be logged for potential further analysis. -* - Debug logging of queries may be enabled globally, or restricted to -* particular sets of queries. -* - Simple syntax for iterating through a result set. -* -* This class is intended as a transitional mechanism for moving from the -* PostgreSQL-specific Pg Query class to something which uses PDO in a more -* replaceable manner. -* -*/ - -/** -* Connect to the database defined in the $c->db_connect[] (or $c->pg_connect) arrays -*/ -function _awl_connect_configured_database() { - global $c, $_awl_dbconn; - - /** - * Attempt to connect to the configured connect strings - */ - $_awl_dbconn = false; - - if ( isset($c->db_connect) ) { - $connection_strings = $c->db_connect; - } - elseif ( isset($c->pg_connect) ) { - $connection_strings = $c->pg_connect; - } - - foreach( $connection_strings AS $k => $v ) { - $dbuser = null; - $dbpass = null; - if ( is_array($v) ) { - $dsn = $v['dsn']; - if ( isset($v['dbuser']) ) $dbuser = $v['dbuser']; - if ( isset($v['dbpass']) ) $dbpass = $v['dbpass']; - } - elseif ( preg_match( '/^(\S+:)?(.*)( user=(\S+))?( password=(\S+))?$/', $v, $matches ) ) { - $dsn = $matches[2]; - if ( isset($matches[1]) && $matches[1] != '' ) { - $dsn = $matches[1] . $dsn; - } - else { - $dsn = 'pgsql:' . $dsn; - } - if ( isset($matches[4]) && $matches[4] != '' ) $dbuser = $matches[4]; - if ( isset($matches[6]) && $matches[6] != '' ) $dbpass = $matches[6]; - } - if ( $_awl_dbconn = new AwlDatabase( $dsn, $dbuser, $dbpass, (isset($c->use_persistent) && $c->use_persistent ? array(PDO::ATTR_PERSISTENT => true) : null) ) ) break; - } - - if ( ! $_awl_dbconn ) { - echo <<Database Connection Failure -

Database Error

-

Could not connect to database

- - -EOERRMSG; - exit; - } - - if ( isset($c->db_schema) && $c->db_schema != '' ) { - $_awl_dbconn->SetSearchPath( $c->db_schema . ',public' ); - } - - $c->_awl_dbversion = $_awl_dbconn->GetVersion(); -} - - -/** -* The AwlQuery Class. -* -* This class builds and executes SQL Queries and traverses the -* set of results returned from the query. -* -* Example usage -* -* $sql = "SELECT * FROM mytable WHERE mytype = ?"; -* $qry = new AwlQuery( $sql, $myunsanitisedtype ); -* if ( $qry->Exec("typeselect", __line__, __file__ ) -* && $qry->rows > 0 ) -* { -* while( $row = $qry->Fetch() ) { -* do_something_with($row); -* } -* } -* -* -* @package awl -*/ -class AwlQuery -{ - /**#@+ - * @access private - */ - /** - * Our database connection, normally copied from a global one - * @var resource - */ - protected $connection; - - /** - * The original query string - * @var string - */ - protected $querystring; - - /** - * The actual query string, after we've replaced parameters in it - * @var string - */ - protected $bound_querystring; - - /** - * The current array of bound parameters - * @var array - */ - protected $bound_parameters; - - /** - * The PDO statement handle, or null if we don't have one yet. - * @var string - */ - protected $sth; - - /** - * Result of the last execution - * @var resource - */ - protected $result; - - /** - * number of current row - use accessor to get/set - * @var int - */ - protected $rownum = null; - - /** - * number of rows from pg_numrows - use accessor to get value - * @var int - */ - protected $rows; - - /** - * The Database error information, if the query fails. - * @var string - */ - protected $error_info; - - /** - * Stores the query execution time - used to deal with long queries. - * should be read-only - * @var string - */ - protected $execution_time; - - /**#@-*/ - - /**#@+ - * @access public - */ - /** - * Where we called this query from so we can find it in our code! - * Debugging may also be selectively enabled for a $location. - * @var string - */ - public $location; - - /** - * How long the query should take before a warning is issued. - * - * This is writable, but a method to set it might be a better interface. - * The default is 0.3 seconds. - * @var double - */ - public $query_time_warning = 0.3; - /**#@-*/ - - - /** - * Constructor - * @param string The query string in PDO syntax with replacable '?' characters or bindable parameters. - * @param mixed The values to replace into the SQL string. - * @return The AwlQuery object - */ - function __construct() { - global $_awl_dbconn; - $this->rows = null; - $this->execution_time = 0; - $this->error_info = null; - $this->rownum = -1; - if ( isset($_awl_dbconn) ) $this->connection = $_awl_dbconn; - else $this->connection = null; - - $argc = func_num_args(); - $args = func_get_args(); - - $this->querystring = array_shift($args); - if ( 1 < $argc ) { - if ( is_array($args[0]) ) - $this->bound_parameters = $args[0]; - else - $this->bound_parameters = $args; - } - - return $this; - } - - - /** - * Use a different database connection for this query - * @param resource $new_connection The database connection to use. - */ - function SetConnection( $new_connection, $options = null ) { - if ( is_string($new_connection) || is_array($new_connection) ) { - $dbuser = null; - $dbpass = null; - if ( is_array($new_connection) ) { - $dsn = $new_connection['dsn']; - if ( isset($new_connection['dbuser']) ) $dbuser = $new_connection['dbuser']; - if ( isset($new_connection['dbpass']) ) $dbpass = $new_connection['dbpass']; - } - elseif ( preg_match( '/^(\S+:)?(.*)( user=(\S+))?( password=(\S+))?$/', $new_connection, $matches ) ) { - $dsn = $matches[2]; - if ( isset($matches[1]) && $matches[1] != '' ) { - $dsn = $matches[1] . $dsn; - } - else { - $dsn = 'pgsql:' . $dsn; - } - if ( isset($matches[4]) && $matches[4] != '' ) $dbuser = $matches[4]; - if ( isset($matches[6]) && $matches[6] != '' ) $dbpass = $matches[6]; - } - if ( $new_connection = new AwlDatabase( $dsn, $dbuser, $dbpass, $options ) ) break; - } - $this->connection = $new_connection; - return $new_connection; - } - - - - - /** - * Log query, optionally with file and line location of the caller. - * - * This function should not really be used outside of AwlQuery. For a more - * useful generic logging interface consider calling dbg_error_log(...); - * - * @param string $locn A string identifying the calling location. - * @param string $tag A tag string, e.g. identifying the type of event. - * @param string $string The information to be logged. - * @param int $line The line number where the logged event occurred. - * @param string $file The file name where the logged event occurred. - */ - function _log_query( $locn, $tag, $string, $line = 0, $file = "") { - // replace more than one space with one space - $string = preg_replace('/\s+/', ' ', $string); - - if ( ($tag == 'QF' || $tag == 'SQ') && ( $line != 0 && $file != "" ) ) { - dbg_error_log( "LOG-$locn", " Query: %s: %s in '%s' on line %d", ($tag == 'QF' ? 'Error' : 'Possible slow query'), $tag, $file, $line ); - } - - while( strlen( $string ) > 0 ) { - dbg_error_log( "LOG-$locn", " Query: %s: %s", $tag, substr( $string, 0, 240) ); - $string = substr( "$string", 240 ); - } - } - - - /** - * Quote the given string so it can be safely used within string delimiters - * in a query. To be avoided, in general. - * - * @param mixed $str Data to be converted to a string suitable for including as a value in SQL. - * @return string NULL, TRUE, FALSE, a plain number, or the original string quoted and with ' and \ characters escaped - */ - function quote($str = null) { - if ( !isset($this->connection) ) { - _awl_connect_configured_database(); - $this->connection = $GLOBALS['_awl_dbconn']; - } - return $this->connection->Quote($str); - } - - - /** - * Bind some parameters. This can be called in three ways: - * 1) As Bind(':key','value), when using named parameters - * 2) As Bind('value'), when using ? placeholders - * 3) As Bind(array()), to overwrite the existing bound parameters. The array may - * be ':name' => 'value' pairs or ordinal values, depending on whether the SQL - * is using ':name' or '?' style placeholders. - * - * @param mixed $args See details above. - */ - function Bind() { - $argc = func_num_args(); - $args = func_get_args(); - - if ( $argc == 1 ) { - if ( gettype($args[0]) == 'array' ) { - $this->bound_parameters = $args[0]; - } - else { - $this->bound_parameters[] = $args[0]; - } - } - else { - $this->bound_parameters[$args[0]] = $args[1]; - } - } - - - /** - * Tell the database to prepare the query that we will execute - */ - function Prepare() { - global $c; - - if ( isset($this->sth) ) return; // Already prepared - if ( isset($c->expand_pdo_parameters) && $c->expand_pdo_parameters ) return; // No-op if we're expanding internally - - if ( !isset($this->connection) ) { - _awl_connect_configured_database(); - $this->connection = $GLOBALS['_awl_dbconn']; - } - - $this->sth = $this->connection->prepare( $this->querystring ); - - if ( ! $this->sth ) { - $this->error_info = $this->connection->errorInfo(); - } - else $this->error_info = null; - } - - - /** - * Tell the database to execute the query - */ - function Execute() { - global $c; - - if ( !isset($this->connection) ) { - _awl_connect_configured_database(); - $this->connection = $GLOBALS['_awl_dbconn']; - } - - if ( isset($c->expand_pdo_parameters) && $c->expand_pdo_parameters ) { - if ( isset($this->bound_parameters) ) { - $this->bound_querystring = $this->connection->ReplaceParameters($this->querystring,$this->bound_parameters); -// printf( "\n=============================================================== OQ\n%s\n", $this->querystring); -// printf( "\n=============================================================== QQ\n%s\n", $this->bound_querystring); -// print_r( $this->bound_parameters ); - } - else { - $this->bound_querystring = $this->querystring; - } - } - - $t1 = microtime(true); // get start time - if ( isset($this->bound_querystring) ) { - $this->sth = $this->connection->query($this->bound_querystring); - $this->bound_querystring = null; - if ( ! $this->sth ) { - $this->error_info = $this->connection->errorInfo(); - return false; - } - } - else { - if ( ! $this->sth->execute( $this->bound_parameters ) ) { - $this->error_info = $this->sth->errorInfo(); - return false; - } - } - - $this->rows = $this->sth->rowCount(); - $i_took = microtime(true) - $t1; - $c->total_query_time += $i_took; - $this->execution_time = sprintf( "%2.06lf", $i_took); - - $this->error_info = null; - return true; - } - - - /** - * Return the query string we are planning to execute - */ - function QueryString() { - return $this->querystring; - } - - - /** - * Return the parameters we are planning to substitute into the query string - */ - function Parameters() { - return $this->bound_parameters; - } - - - /** - * Return the count of rows retrieved/affected - */ - function rows() { - return $this->rows; - } - - - /** - * Wrap the parent DB class Begin() so we can $qry->Begin() sometime before we $qry->Exec() - */ - public function Begin() { - global $_awl_dbconn; - if ( !isset($this->connection) ) { - if ( !isset($_awl_dbconn) ) _awl_connect_configured_database(); - $this->connection = $_awl_dbconn; - } - return $this->connection->Begin(); - } - - - /** - * Wrap the parent DB class Commit() so we can $qry->Commit() sometime after we $qry->Exec() - */ - public function Commit() { - if ( !isset($this->connection) ) { - trigger_error("Cannot commit a transaction without an active statement.", E_USER_ERROR); - } - return $this->connection->Commit(); - } - - - /** - * Wrap the parent DB class Rollback() so we can $qry->Rollback() sometime after we $qry->Exec() - */ - public function Rollback() { - if ( !isset($this->connection) ) { - trigger_error("Cannot rollback a transaction without an active statement.", E_USER_ERROR); - } - return $this->connection->Rollback(); - } - - - /** - * Simple SetSql() class which will reset the object with the querystring from the first argument. - * @param string The query string in PDO syntax with replacable '?' characters or bindable parameters. - */ - public function SetSql( $sql ) { - $this->rows = null; - $this->execution_time = 0; - $this->error_info = null; - $this->rownum = -1; - $this->bound_parameters = null; - $this->bound_querystring = null; - $this->sth = null; - - $this->querystring = $sql; - } - - - /** - * Simple QDo() class which will re-use this query for whatever was passed in, and execute it - * returning the result of the Exec() call. We can't call it Do() since that's a reserved word... - * @param string The query string in PDO syntax with replacable '?' characters or bindable parameters. - * @param mixed The values to replace into the SQL string. - * @return boolean Success (true) or Failure (false) - */ - public function QDo() { - $argc = func_num_args(); - $args = func_get_args(); - - $this->SetSql( array_shift($args) ); - if ( 1 < $argc ) { - if ( is_array($args[0]) ) - $this->bound_parameters = $args[0]; - else - $this->bound_parameters = $args; - } - - return $this->Exec(); - } - - - /** - * Execute the query, logging any debugging. - * - * Example - * So that you can nicely enable/disable the queries for a particular class, you - * could use some of PHPs magic constants in your call. - * - * $qry->Exec(__CLASS__, __LINE__, __FILE__); - * - * - * - * @param string $location The name of the location for enabling debugging or just - * to help our children find the source of a problem. - * @param int $line The line number where Exec was called - * @param string $file The file where Exec was called - * @return boolean Success (true) or Failure (false) - */ - function Exec( $location = null, $line = null, $file = null ) { - global $c; - if ( isset($location) ) $this->location = trim($location); - if ( !isset($this->location) || $this->location == "" ) $this->location = substr($_SERVER['PHP_SELF'],1); - - if ( isset($line) ) $this->location_line = intval($line); - else if ( isset($this->location_line) ) $line = $this->location_line; - - if ( isset($file) ) $this->location_file = trim($file); - else if ( isset($this->location_file) ) $file = $this->location_file; - - if ( isset($c->dbg['querystring']) || isset($c->dbg['ALL']) ) { - $this->_log_query( $this->location, 'DBGQ', $this->querystring, $line, $file ); - if ( isset($this->bound_parameters) && !isset($this->sth) ) { - foreach( $this->bound_parameters AS $k => $v ) { - $this->_log_query( $this->location, 'DBGQ', sprintf(' "%s" => "%s"', $k, $v), $line, $file ); - } - } - } - - if ( isset($this->bound_parameters) ) { - $this->Prepare(); - } - - $success = $this->Execute(); - - if ( ! $success ) { - // query failed - $this->errorstring = sprintf( 'SQL error "%s" - %s"', $this->error_info[0], (isset($this->error_info[2]) ? $this->error_info[2] : '')); - if ( isset($c->dbg['print_query_errors']) && $c->dbg['print_query_errors'] ) { - printf( "\n=====================\n" ); - printf( "%s[%d] QF: %s\n", $file, $line, $this->errorstring); - printf( "%s\n", $this->querystring ); - foreach( $this->bound_parameters AS $k => $v ) { - printf( " %-18s \t=> '%s'\n", "'$k'", $v ); - } - printf( ".....................\n" ); - } - $this->_log_query( $this->location, 'QF', $this->errorstring, $line, $file ); - $this->_log_query( $this->location, 'QF', $this->querystring, $line, $file ); - if ( isset($this->bound_parameters) && ! ( isset($c->dbg['querystring']) || isset($c->dbg['ALL']) ) ) { - foreach( $this->bound_parameters AS $k => $v ) { - dbg_error_log( 'LOG-'.$this->location, ' Query: QF: "%s" => "%s"', $k, $v); - } - } - } - elseif ( $this->execution_time > $this->query_time_warning ) { - // if execution time is too long - $this->_log_query( $this->location, 'SQ', "Took: $this->execution_time for $this->querystring", $line, $file ); // SQ == Slow Query :-) - } - elseif ( isset($c->dbg['querystring']) || isset($c->dbg[strtolower($this->location)]) || isset($c->dbg['ALL']) ) { - // query successful, but we're debugging and want to know how long it took anyway - $this->_log_query( $this->location, 'DBGQ', "Took: $this->execution_time to find $this->rows rows.", $line, $file ); - } - - return $success; - } - - - /** - * Fetch the next row from the query results - * @param boolean $as_array True if thing to be returned is array - * @return mixed query row - */ - function Fetch($as_array = false) { - - if ( ! $this->sth || $this->rows == 0 ) return false; // no results - if ( $this->rownum == null ) $this->rownum = -1; - if ( ($this->rownum + 1) >= $this->rows ) return false; // reached the end of results - - $this->rownum++; - $row = $this->sth->fetch( ($as_array ? PDO::FETCH_NUM : PDO::FETCH_OBJ) ); - - return $row; - } - - -} - diff --git a/inc/AwlUpgrader.php b/inc/AwlUpgrader.php deleted file mode 100644 index b5cf9584..00000000 --- a/inc/AwlUpgrader.php +++ /dev/null @@ -1,39 +0,0 @@ - -* @copyright Morphoss Ltd -* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU LGPL version 3 or later -* @compatibility Requires PHP 5.1 or later -*/ - -require_once('AwlQuery.php'); - -/** -* Database upgrader class and associated functions -* -* This subpackage provides some functions that are useful around database -* schema creation and changes. -* -*/ - -/** -* The AwlUpgrader Class. -* -* This class updates an Awl database to a newer schema version. -* -* -* @package awl -*/ -class AwlUpgrader -{ - /** - * Constructor - * @return The AwlUpgrader object - */ - function __construct() { - return $this; - } -} -