<?php
/**
* dao.class.php
*
* Contains the DAO class from the GiMb framework.
* @author Georgi Momchilov
* @version 1.1
* @package GiMb
* @link gmomchilov(at)gmail(dot)com
*/
/**
* DAO class
*
* Data Access class capable of connecting to different DB servers (probably in a db farm) <br /> of different types (so far - MySQL, msSQL, InterBase, PostgreSQL).<br />
* Example:
* <code>
* include_once('alerter.class.php');
* include_once('dao.class.php');
* $dao = new dao('ibase');
* $dao->db_logfile = '/path/to/logfile';
*
* //example1:
* $dao->connect('master');
* $dao->query("INSERT into `table` SET `field1` = 'value1', `field2` = 'value2'");
* $dao->commit();
* $dao->rollback();
*
* //example2:
* $slave = $dao->getSlave();
* $dao->connect($slave);
* $dao->query("SELECT * FROM `table`");
* while( $myrow = $dao->fetchAssoc() )
* echo $dao->db_pointer.' - '.var_dump( $myrow ).'<br />';
*
* //example3:
* $dao->connect('master');
* $dao->queueSQL('DELETE FROM `table`', 'path/to/queuefile');
* $dao->executeQueue('path/to/queuefile');
*</code>
* @uses Alerter
* @author Georgi Momchilov <hide@address.com> - Edynamo LTD.
* @version 1.2
* @package GiMb
*/
class DAO {
/**
* @var array use your master server for INSERT, DELETE and UPDATE and your slaves - for SELECT. keep the load of the
* master to a minimum
*/
var $db_servers =
array(
'master' => array(
'type' => 'master',
'host' => '127.0.0.1',
'username' => 'root',
'password' => '',
'database' => 'test',
'logfile' => 'test.log'
)
);
var $db_pointer = 0;
var $db_logfile = false;
var $db_conn = false;
var $db_result = false;
var $engine = false;
var $sql;
var $error = array();
/**
* Constructor
*
* Instantiate the DB engine object - must be te same as the .php file ( 'mysql' would mean mysql.class.php )
* @param string $db_type
* @return void
*/
function DAO( $db_type = 'mysql' ){
if ( !@include_once( $db_type.'.class.php') )
$this->_setError( 'Database server '.$db_type.' is not yet supported' );
else{
$this->engine = new $db_type;
//$this->connect();
}
}
/**
* Error handler
*
* The class uses this function to throw | log errors - uses Alerter class
* @param string $msg Error message
* @param bool $silent Whether or not to show the error (maybe just log it)
* @return void
*/
function _setError( $msg, $silent = false ){
$alerter = &getInstance('alerter');
$alerter->setError( $msg );
}
/**
* Connector
*
* Connects to the database server from $db_servers using the DB engine object
* @param string $server The server to try to connect to
* @return bool
*/
function connect( $server = 'master' ){
$server = $this->db_servers[$server];
if( !$this->db_logfile )
$this->setLogfile( $server['logfile'] );
if( !is_resource( $this->db_conn ) ){
$conn = $this->engine->connect( $server );
if( !$conn )
$this->_setError( 'Could not establish DB connection' );
else
$this->db_conn = $conn;
}
return $this->db_conn;
}
/**
* Sets the logfile
*
* @param file $logfile
* @return bool
*/
function setLogfile( $logfile ){
/* if( $handle = fopen( $logfile, 'a' ) ) {
$this->db_logfile = $logfile;
fclose( $handle );
return true;
}
else {
$this->_setError( $logfile.' is not writable!' );
return false;
} */
}
/**
* Gets the best slave
*
* Tries all servers in $db_servers and returns the optimal one - uses the DB engine object
* @return array
*/
function getSlave() {
$this->engine->getSlave();
}
/**
* Commits transaction
*
* @return bool
*/
function commit() {
$this->engine->commit();
}
/**
* Rollbacks transcation transaction
*
* @return bool
*/
function rollback() {
$this->engine->rollback();
}
/**
* Gets numbers of rows in the query resource
*
* @return int
*/
function getNumRows() {
$this->engine->getNumRows();;
}
/**
* Get current position of the pointer in the query resource
*
* @return int
*/
function getPointer() {
return $this->db_pointer;
}
/**
* Smart quoting
*
* @param string $string SQL query string
* @access static
* @return string
*/
function quoteSmart( $string ){
if ( get_magic_quotes_gpc() )
$value = stripslashes( $string );
if ( !is_numeric( $string ) )
$string = "'" . mysql_real_escape_string( $string ) . "'";
return $string;
}
/**
* Executes query
*
* @param string $sql SQL query string
* @param bool $log Whether or not to log the query results
* @return bool
*/
function query( $sql, $log = false ){
if( $sql !== $this->sql ){
$this->sql = $sql;
$this->db_result = $this->engine->query( $sql );
$this->db_pointer = 0;
}
//return bool if we have insert, update or delete
if( !is_resource( $this->db_result ) )
return $this->db_result;
$res = $this->fetchAssoc();
//log the queries if specified
if( $this->db_logfile && $log ){
if( $res )
$this->_setError('Query ('.$sql.') was successful', true);
else
$this->_setError('Query ('.$sql.') was unsuccessful', true);
}
if( !$this->db_result )
$this->_setError('Query ('.$sql.') could not be executed', true);
return $res;
}
/**
* Fetches associative array from the current query resource
*
* @return array
*/
function fetchAssoc(){
$result = false;
$result = $this->engine->fetchAssoc( $this->db_result );
//move pointer
if( is_array( $result ) || $result == true )
$this->db_pointer++;
return $result;
}
/**
* Queue some sql statements into a external file for later execution - use with INSERT, DELETE or UPDATE
*
* @param string $sql
* @param file $queuefile
* @return bool
*/
function queueSQL( $sql, $queuefile ){
$handle = fopen( $queuefile, 'a' );
fwrite( $handle, $sql."\n");
fclose( $handle );
return true;
}
/**
* Execute queued statements from file
*
* @param file $queuefile Queue file
* @return bool
*/
function executeQueue( $queuefile ){
$queries = file( $queuefile );
if( is_array( $queries ) ){
foreach( $queries as $query ){
if( $this->query( $query ) )
unset( $queries[$query] );
else
$this->_setError('Warning!!! Some queued queries could NOT be executed! They were kept intact into the queue file.', true);
}
//save uncompleted queries back to the queue file
$handle = fopen( $queuefile, 'w' );
fwrite( $handle, implode( "\n", $queries ) );
fclose( $handle );
return true;
}
else
$this->_setError('Queue could not be loaded', true);
return false;
}
}
?>