* @author Florian Wolf * @copyright Jens-Andre Koch (2005-$LastChangedDate$), Florian Wolf (2006-2007) * * @link http://www.clansuite.com * @link http://gna.org/projects/clansuite * @since File available since Release 0.1 * * @version SVN: $Id$ */ /** * Security Handler */ if (!defined('IN_CS')){ die('You are not allowed to view this page.' );} /** * This Clansuite Core Class for PDO Database Handler * * PDO is not an database-abstraction layer, it doesn't rewrite SQL or emulate missing features! * * It's an data-access abstraction layer, regardless which database you're using, * you use the same functions to issue queries and fetch data. * This means that you have to watch out and take care, which functions are * avaiable on all db-systems or only on some. * * PDO gives data-access to the following Databases: * * DBLIB FreeTDS / Microsoft SQL Server / Sybase * FIREBIRD Firebird/Interbase 6 * INFORMIX IBM Informix Dynamic Server * MYSQL MySQL 3.x/4.x * OCI Oracle Call Interface * ODBC ODBC v3 (IBM DB2, unixODBC and win32 ODBC) * PGSQL PostgreSQL * SQLITE SQLite 3 and SQLite 2 * * @link http://wiki.cc/php/PDO_Basics * * Clansuite Core Class - Db * * @author Jens-Andre Koch * @author Florian Wolf * @copyright Jens-Andre Koch (2005-$LastChangedDate$), Florian Wolf (2006-2007) * @since Class available since Release 0.1 * * @package clansuite * @category core * @subpackage db */ class db { /** * @var $db * @access protected */ protected $db; /** * Number of performed statements * @var integer */ public $query_counter = 0; public $exec_counter = 0; public $stmt_counter = 0; /** * Queries Array * @var array */ public $queries = array(); /** * Exec's Array * @var array */ public $execs = array(); /** * Prepare Statements Array * @var array */ public $prepares = array(); /** * Active Queries to prevent buffering failures * @var integer */ public $query_active = 0; /** * The active PDOStatement as reference * @var object * @todo is variable type right? */ public $query_active_reference; /** * Last SQL * @var string? * @todo is variable type right? */ public $last_sql; /** * CONSTRUCTOR * * Create the DB Object * Set db related counters to zero * * @param string * @param string * @param string * @param string * @global $lang * @global $tpl * @global $error * @global $cfg * @todo correct var types */ public function __construct($dsn, $user=NULL, $pass=NULL, $driver_options=NULL) { global $lang, $tpl, $error, $cfg; /** * try, try, try to set up PDO :) */ try { /** * Create PDO object @ $db */ $this->db = new PDO($dsn, $user, $pass, $driver_options); /** * Set the Error Attribute */ $this->db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); /** * Table-names in lower-case */ $this->db->setAttribute(PDO::ATTR_CASE,PDO::CASE_LOWER); /** * Fetch Mode * UNQUOTE ON PHP 5.2 !!! * @todo note by vain: what's this, why unquote?? note it here!! else no one will know. */ /** * $this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC); */ if ( $cfg->db_type == 'mysql' ) { /** * Buffering */ $this->db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); /** * Unicode (mysql) */ $this->exec('SET CHARACTER SET utf8'); } } /** * In case Database Error occurs catch exception and show Error */ catch (PDOException $e) { $error->show( $lang->t('DB Connection Failure'), $lang->t('The Database Connection could not be established.') . '
Error : ' . $e->getMessage() . '
'); die(); } } /** * CALL * It's a forward to $db * * @param $func * @param $args */ public function __call( $func, $args ) { return call_user_func_array(array($this->db, $func), $args); } /** * Prepare a statement * * @param string * @global $error * @global $lang */ public function prepare( $sql='' ) { global $error, $lang; if( is_object($this->query_active_reference) ) { $this->query_active_reference->closeCursor(); $this->query_active_reference = NULL; } $this->last_sql = $sql; $this->prepares[] = $sql; $res = $this->db->prepare( $sql ); if( $res ) { return new db_statements( $res ); } else { $error->show( $lang->t('DB Prepare Error'), $lang->t('Could not prepare the following statement:') . '
' . $sql, 1); die(); } } /** * This method is a Simple Query with closeCursor() ! * * - It sets the last_sql to the current sql query string. * - prepares the query * - executes * - and closescursor finally * - return result * * @param string * @param array * @return $res */ public function simple_query($sql='', $args = array() ) { $this->last_sql = $sql; $res = $this->prepare( $sql ); $benchmark->timemarker('db_begin', 'Database Simple_Query | Query No.'. $this->query_counter); $res->execute( $args ); $benchmark->timemarker('db_end', 'Database Simple_Query | Query No.'. $this->query_counter); $res->closeCursor(); $res = NULL; return $res; } /** * Deliver query to DB * Increase counter * * @param string */ public function query( $sql='' ) { $this->last_sql = $sql; if( is_object($this->query_active_reference) ) { $this->query_active_reference->closeCursor(); $this->query_active_reference = NULL; } $this->query_counter++; $this->queries[] = $sql; $benchmark->timemarker('db_begin', 'Database Query | Query No.'. $this->query_counter); $res = $this->db->query($sql); $benchmark->timemarker('db_end', 'Database Query | Query No.'. $this->query_counter); if ( $res ) { $db->query_active_reference = $res; return $res; } return $res; } /** * Performs a Select returning the total number of rows found by a SELECT query * * At first it tries to get the total number of rows by * a mysql specific command "SQL_CALC_FOUND_ROWS". * If that fails an additional "found_rows" query is executed. * * Usage: $db->select * * Example Call: * (notice the chopped SQL, so don't use a "SELECT" in your sql-query) * * $count = -1; #reset counter * $stmt = $db->select( '* FROM foo WHERE bar < 40 LIMIT 4 OFFSET 2', $c, 4); * var_dump($stmt->fetchAll()); # Normal dump of found data * var_dump($count); # The number of rows found, at most 4. * * Function is fetched from the PHP Database Mailing List * @author Rob C [ Mi, 09 November 2005 19:18 ] * * @param string * @param integer * @param integer * @global $error * @global $lang * @return $res * @todo note by vain: is this still needed or deprecated? * i think the limit was placed here because of the need for limiting the pagination * but as far as i know it's handled there */ public function select( $sql='', &$count = NULL, $limit = NULL) { global $error, $lang; $sql = 'SELECT '.(!is_null($count)?'SQL_CALC_FOUND_ROWS ':'').$sql; $this->last_sql = $sql; /** * try, try, try to prepare the PDO Query :) */ try { $res = $this->db->prepare($sql); $res->execute(); /** * Problem ! -> How to assign Vars for the ? in the sql.. * @todo note by vain: deprecated?? */ if (!is_null($count)) { $rows = $this->db->prepare('SELECT found_rows() AS rows'); $rows->execute(); $rows_array = $rows->fetch(PDO::FETCH_NUM); $rows->closeCursor(); $count = $rows_array[0]; if (!is_null($limit) && $count > $limit) { $count = $limit; } } } /** * In case Database Error occurs catch exception and show Error */ catch (PDOException $e) { $error->show( $lang->t('DB SELECT with COUNT OF ROWS Error'), $lang->t('Could not select and count the rows of following statement:') . '
' . $sql, 1); die(); } return $res; } /** * Query Exec * Increase counter * * @param string */ public function exec( $sql='' ) { global $benchmark; $this->exec_counter++; $this->last_sql = $sql; if( is_object($this->query_active_reference) ) { $this->query_active_reference->closeCursor(); $this->query_active_reference = NULL; } $benchmark->timemarker('db_begin', 'Database Exec | No.'. $this->exec_counter); $res = $this->db->exec($sql ); $benchmark->timemarker('db_end', 'Database Exec | No.'. $this->exec_counter); $this->execs[] = $sql; return $res; } } /** * Clansuite Core Class - Db Statements Wrapper * * This is a simply substitution of the original PDO Statements Class * simply needed to place a db-query-counter in the execution of statements. * * @author Jens-Andre Koch * @author Florian Wolf * @copyright Jens-Andre Koch (2005-$LastChangedDate$), Florian Wolf (2006-2007) * @since Class available since Release 0.1 * * @package clansuite * @category core * @subpackage db_statements * */ class db_statements { public $db_statement; /** * CONSTRUCTOR * * $param object */ function __construct($db_pre_s) { $this->db_statement = $db_pre_s; } /** * This is the Callback function for the Non-existing methods in this class * * @param array * @param array */ function __call($func, $args) { return call_user_func_array(array($this->db_statement, $func), $args); } /** * This method is used for execution of statements * $stmt->execute * * @param array * @global $db * @return $res */ function execute( $args = array() ) { global $db, $benchmark; if ( is_object( $db->query_active_reference ) ) { $db->query_active_reference->closeCursor(); $db->query_active_reference = NULL; } $db->queries[] = $this->db_statement->queryString; $db->stmt_counter++; if( count($args) > 0 ) { $benchmark->timemarker('db_begin', 'Database Statement | No.'. $db->stmt_counter); $res = $this->db_statement->execute($args); $benchmark->timemarker('db_end', 'Database Statement | No.'. $db->stmt_counter); } else { /** * in case $args is empty execute!! */ $benchmark->timemarker('db_begin', 'Database Statement | No.'. $db->stmt_counter); $res = $this->db_statement->execute(); $benchmark->timemarker('db_end', 'Database Statement | No.'. $db->stmt_counter); } if ( $res ) { $db->query_active_reference = $this; return $res; } return $res; } } ?>