1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180:
<?php
/**
* AwlDatabase query/statement class and associated functions
*
* This subpackage provides some functions that are useful around database
* activity and a AwlDBDialect, AwlDatabase and AwlStatement classes to simplify
* handling of database queries and provide some access for a limited
* ability to handle varying database dialects.
*
* The class is intended to be a very lightweight wrapper with 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.
*
* See http://wiki.davical.org/w/AwlDatabase for design and usage information.
*
* If not already connected, AwlDatabase will attempt to connect to the database,
* successively applying connection parameters from the array in $c->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 <andrew@morphoss.com>
* @copyright Morphoss Ltd
* @license http://gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @compatibility Requires PHP 5.1 or later
*/
require_once('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 {
fatal("Cannot begin a transaction while a transaction is already active.");
}
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 {
throw new Exception("Cannot rollback unless a transaction is already active.");
}
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.
* @return int 0 = not started, 1 = in progress, -1 = error pending rollback/commit
*/
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();
}
}