diff --git a/dibi.compact/dibi.compact.php b/dibi.compact/dibi.compact.php
index 39dd71e1..6f72b717 100644
--- a/dibi.compact/dibi.compact.php
+++ b/dibi.compact/dibi.compact.php
@@ -16,8 +16,8 @@
* @version 0.6 $Revision: 8 $ $Date: 2006-06-07 23:33:46 +0200 (st, 07 VI 2006) $
*/define('DIBI','Version 0.6 $Revision: 8 $');if(version_compare(PHP_VERSION,'5.0.3','<'))die('dibi needs PHP 5.0.3 or newer');
if(!defined('DIBI'))die();abstract class DibiDriver{protected$config;public$formats=array('NULL'=>"NULL",'TRUE'=>"1",'FALSE'=>"0",'date'=>"'Y-m-d'",'datetime'=>"'Y-m-d H:i:s'",);abstract static public function connect($config);protected function __construct($config){$this->config=$config;}public function getConfig(){return$this->config;}abstract public function query($sql);abstract public function affectedRows();abstract public function insertId();abstract public function begin();abstract public function commit();abstract public function rollback();abstract public function escape($value,$appendQuotes=FALSE);abstract public function quoteName($value);abstract public function getMetaData();}
- if(!defined('DIBI'))die();if(!interface_exists('Countable',false)){interface Countable{function count();}}abstract class DibiResult implements IteratorAggregate,Countable{const FIELD_TEXT='s',FIELD_BINARY='b',FIELD_BOOL='l',FIELD_INTEGER='i',FIELD_FLOAT='f',FIELD_DATE='d',FIELD_DATETIME='t',FIELD_UNKNOWN='?',FIELD_COUNTER='c';protected$convert;abstract public function seek($row);abstract public function rowCount();abstract public function getFields();abstract public function getMetaData($field);abstract protected function detectTypes();abstract protected function free();abstract protected function doFetch();final public function fetch(){$rec=$this->doFetch();if(!is_array($rec))return FALSE;if($t=$this->convert){foreach($rec as$key=>$value){if(isset($t[$key]))$rec[$key]=$this->convert($value,$t[$key]);}}return$rec;}final function fetchSingle(){$rec=$this->doFetch();if(!is_array($rec))return FALSE;if($t=$this->convert){$value=reset($rec);$key=key($rec);return isset($t[$key])?$this->convert($value,$t[$key]):$value;}return reset($rec);}final function fetchAll(){@$this->seek(0);$rec=$this->fetch();if(!$rec)return array();$assocBy=func_get_args();$arr=array();if(!$assocBy){$value=count($rec)==1?key($rec):NULL;do{$arr[]=$value===NULL?$rec:$rec[$value];}while($rec=$this->fetch());return$arr;}do{foreach($assocBy as$n=>$assoc){$val[$n]=$rec[$assoc];unset($rec[$assoc]);}foreach($assocBy as$n=>$assoc){if($n==0)$tmp=&$arr[$val[$n]];else$tmp=&$tmp[$assoc][$val[$n]];if($tmp===NULL)$tmp=$rec;}}while($rec=$this->fetch());return$arr;}final function fetchPairs($key,$value){@$this->seek(0);$rec=$this->fetch();if(!$rec)return array();$arr=array();do{$arr[$rec[$key]]=$rec[$value];}while($rec=$this->fetch());return$arr;}public function __destruct(){@$this->free();}public function setType($field,$type=NULL){if($field===TRUE)$this->detectTypes();elseif(is_array($field))$this->convert=$field;else$this->convert[$field]=$type;}public function getType($field){return isset($this->convert[$field])?$this->convert[$field]:NULL;}public function convert($value,$type){if($value===NULL||$value===FALSE)return$value;static$conv=array(self::FIELD_TEXT=>'string',self::FIELD_BINARY=>'string',self::FIELD_BOOL=>'bool',self::FIELD_INTEGER=>'int',self::FIELD_FLOAT=>'float',self::FIELD_COUNTER=>'int',);if(isset($conv[$type])){settype($value,$conv[$type]);return$value;}if($type==self::FIELD_DATE)return strtotime($value);if($type==self::FIELD_DATETIME)return strtotime($value);return$value;}public function getIterator($offset=NULL,$count=NULL){return new DibiResultIterator($this,$offset,$count);}public function count(){return$this->rowCount();}}class DibiResultIterator implements Iterator{private$result,$offset,$count,$record,$row;public function __construct(DibiResult$result,$offset=NULL,$count=NULL){$this->result=$result;$this->offset=(int)$offset;$this->count=$count===NULL?2147483647:(int)$count;}public function rewind(){$this->row=0;@$this->result->seek($this->offset);$this->record=$this->result->fetch();}public function key(){return$this->row;}public function current(){return$this->record;}public function next(){$this->record=$this->result->fetch();$this->row++;}public function valid(){return is_array($this->record)&&($this->row<$this->count);}}
- if(!defined('DIBI'))die();class DibiParser{private$modifier,$hasError,$driver,$ifLevel,$ifLevelStart;public function parse($driver,$args){$this->driver=$driver;$this->hasError=FALSE;$command=null;$mod=&$this->modifier;$mod=FALSE;$this->ifLevel=$this->ifLevelStart=0;$comment=&$this->comment;$comment=FALSE;$sql=array();foreach($args as$arg){if($mod=='if'){$mod=FALSE;$this->ifLevel++;if(!$comment&&!$arg){$sql[]='/*';$this->ifLevelStart=$this->ifLevel;$comment=TRUE;}continue;}if(is_string($arg)&&!$mod){$sql[]=$this->formatValue($arg,'p');continue;}if(is_array($arg)&&!$mod&&is_string(key($arg))){if(!$command)$command=strtoupper(substr(ltrim($args[0]),0,6));$mod=($command=='INSERT'||$command=='REPLAC')?'V':'S';}$sql[]=$comment?'...':$this->formatValue($arg,$mod);$mod=FALSE;}if($comment)$sql[]='*/';$sql=implode(' ',$sql);if($this->hasError)return new DibiException('Errors during generating SQL',array('sql'=>$sql));return$sql;}private function formatValue($value,$modifier){if(is_array($value)){$vx=$kx=array();switch($modifier){case'S':foreach($value as$k=>$v){list($k,$mod)=explode('%',$k.'%',3);$vx[]=$this->driver->quoteName($k).'='.$this->formatValue($v,$mod);}return implode(', ',$vx);case'V':foreach($value as$k=>$v){list($k,$mod)=explode('%',$k.'%',3);$kx[]=$this->driver->quoteName($k);$vx[]=$this->formatValue($v,$mod);}return'('.implode(', ',$kx).') VALUES ('.implode(', ',$vx).')';default:foreach($value as$v)$vx[]=$this->formatValue($v,$modifier);return implode(', ',$vx);}}if($modifier){if($value instanceof IDibiVariable)return$value->toSql($this->driver,$modifier);if(!is_scalar($value)&&!is_null($value)){$this->hasError=TRUE;return'**Unexpected '.gettype($value).'**';}switch($modifier){case"s":return$this->driver->escape($value,TRUE);case'b':return$value?$this->driver->formats['TRUE']:$this->driver->formats['FALSE'];case'i':case'u':case'd':return(string)(int)$value;case'f':return(string)(float)$value;case'D':return date($this->driver->formats['date'],is_string($value)?strtotime($value):$value);case'T':return date($this->driver->formats['datetime'],is_string($value)?strtotime($value):$value);case'n':return$this->driver->quoteName($value);case'p':$value=(string)$value;$toSkip=strcspn($value,'`[\'"%');if($toSkip==strlen($value))return$value;return substr($value,0,$toSkip).preg_replace_callback('/
+ if(!defined('DIBI'))die();if(!interface_exists('Countable',false)){interface Countable{function count();}}abstract class DibiResult implements IteratorAggregate,Countable{protected$convert;abstract public function seek($row);abstract public function rowCount();abstract public function getFields();abstract public function getMetaData($field);abstract protected function detectTypes();abstract protected function free();abstract protected function doFetch();final public function fetch(){$rec=$this->doFetch();if(!is_array($rec))return FALSE;if($t=$this->convert){foreach($rec as$key=>$value){if(isset($t[$key]))$rec[$key]=$this->convert($value,$t[$key]);}}return$rec;}final function fetchSingle(){$rec=$this->doFetch();if(!is_array($rec))return FALSE;if($t=$this->convert){$value=reset($rec);$key=key($rec);return isset($t[$key])?$this->convert($value,$t[$key]):$value;}return reset($rec);}final function fetchAll(){@$this->seek(0);$rec=$this->fetch();if(!$rec)return array();$assocBy=func_get_args();$arr=array();if(!$assocBy){$value=count($rec)==1?key($rec):NULL;do{$arr[]=$value===NULL?$rec:$rec[$value];}while($rec=$this->fetch());return$arr;}do{foreach($assocBy as$n=>$assoc){$val[$n]=$rec[$assoc];unset($rec[$assoc]);}foreach($assocBy as$n=>$assoc){if($n==0)$tmp=&$arr[$val[$n]];else$tmp=&$tmp[$assoc][$val[$n]];if($tmp===NULL)$tmp=$rec;}}while($rec=$this->fetch());return$arr;}final function fetchPairs($key,$value){@$this->seek(0);$rec=$this->fetch();if(!$rec)return array();$arr=array();do{$arr[$rec[$key]]=$rec[$value];}while($rec=$this->fetch());return$arr;}public function __destruct(){@$this->free();}public function setType($field,$type=NULL){if($field===TRUE)$this->detectTypes();elseif(is_array($field))$this->convert=$field;else$this->convert[$field]=$type;}public function getType($field){return isset($this->convert[$field])?$this->convert[$field]:NULL;}public function convert($value,$type){if($value===NULL||$value===FALSE)return$value;static$conv=array(dibi::FIELD_TEXT=>'string',dibi::FIELD_BINARY=>'string',dibi::FIELD_BOOL=>'bool',dibi::FIELD_INTEGER=>'int',dibi::FIELD_FLOAT=>'float',dibi::FIELD_COUNTER=>'int',);if(isset($conv[$type])){settype($value,$conv[$type]);return$value;}if($type==dibi::FIELD_DATE)return strtotime($value);if($type==dibi::FIELD_DATETIME)return strtotime($value);return$value;}public function getIterator($offset=NULL,$count=NULL){return new DibiResultIterator($this,$offset,$count);}public function count(){return$this->rowCount();}}class DibiResultIterator implements Iterator{private$result,$offset,$count,$record,$row;public function __construct(DibiResult$result,$offset=NULL,$count=NULL){$this->result=$result;$this->offset=(int)$offset;$this->count=$count===NULL?2147483647:(int)$count;}public function rewind(){$this->row=0;@$this->result->seek($this->offset);$this->record=$this->result->fetch();}public function key(){return$this->row;}public function current(){return$this->record;}public function next(){$this->record=$this->result->fetch();$this->row++;}public function valid(){return is_array($this->record)&&($this->row<$this->count);}}
+ if(!defined('DIBI'))die();class DibiParser{private$modifier,$hasError,$driver,$ifLevel,$ifLevelStart;public function parse($driver,$args){$this->driver=$driver;$this->hasError=FALSE;$command=null;$mod=&$this->modifier;$mod=FALSE;$this->ifLevel=$this->ifLevelStart=0;$comment=&$this->comment;$comment=FALSE;$sql=array();foreach($args as$arg){if('if'==$mod){$mod=FALSE;$this->ifLevel++;if(!$comment&&!$arg){$sql[]='/*';$this->ifLevelStart=$this->ifLevel;$comment=TRUE;}continue;}if(is_string($arg)&&(!$mod||'p'==$mod)){$mod=FALSE;$sql[]=$this->formatValue($arg,'p');continue;}if(!$mod&&is_array($arg)&&is_string(key($arg))){if(!$command)$command=strtoupper(substr(ltrim($args[0]),0,6));$mod=('INSERT'==$command||'REPLAC'==$command)?'V':'S';}$sql[]=$comment?'...':$this->formatValue($arg,$mod);$mod=FALSE;}if($comment)$sql[]='*/';$sql=implode(' ',$sql);if($this->hasError)return new DibiException('Errors during generating SQL',array('sql'=>$sql));return$sql;}private function formatValue($value,$modifier){if(is_array($value)){$vx=$kx=array();switch($modifier){case'S':foreach($value as$k=>$v){$pair=explode('%',$k,2);if(isset($pair[1])){$mod=$pair[1];if(isset($mod[0])&&'?'==$mod[0]){if(NULL===$v)continue;$mod=substr($mod,1);}}else$mod=FALSE;$vx[]=$this->driver->quoteName($pair[0]).'='.$this->formatValue($v,$mod);}return implode(', ',$vx);case'V':foreach($value as$k=>$v){$pair=explode('%',$k,2);if(isset($pair[1])){$mod=$pair[1];if(isset($mod[0])&&'?'==$mod[0]){if($v===NULL)continue;$mod=substr($mod,1);}}else$mod=FALSE;$kx[]=$this->driver->quoteName($pair[0]);$vx[]=$this->formatValue($v,$mod);}return'('.implode(', ',$kx).') VALUES ('.implode(', ',$vx).')';default:foreach($value as$v)$vx[]=$this->formatValue($v,$modifier);return implode(', ',$vx);}}if($modifier){if($value instanceof IDibiVariable)return$value->toSql($this->driver,$modifier);if(!is_scalar($value)&&!is_null($value)){$this->hasError=TRUE;return'**Unexpected '.gettype($value).'**';}switch($modifier){case"s":return$this->driver->escape($value,TRUE);case'b':return$value?$this->driver->formats['TRUE']:$this->driver->formats['FALSE'];case'i':case'u':case'd':return(string)(int)$value;case'f':return(string)(float)$value;case'D':return date($this->driver->formats['date'],is_string($value)?strtotime($value):$value);case't':case'T':return date($this->driver->formats['datetime'],is_string($value)?strtotime($value):$value);case'n':return$this->driver->quoteName($value);case'p':$value=(string)$value;$toSkip=strcspn($value,'`[\'"%');if(strlen($value)==$toSkip)return$value;return substr($value,0,$toSkip).preg_replace_callback('/
(?=`|\[|\'|"|%) ## speed-up
(?:
`(.+?)`| ## 1) `identifier`
@@ -27,9 +27,9 @@
%(else|end)| ## 7) conditional SQL
%([a-zA-Z]{1,2})$| ## 8) right modifier
(\'|") ## 9) lone-quote
- )/xs',array($this,'callback'),substr($value,$toSkip));case'S':case'V':$this->hasError=TRUE;return"**Unexpected ".gettype($value)."**";case'if':$this->hasError=TRUE;return"**The %$modifier is not allowed here**";default:$this->hasError=TRUE;return"**Unknown modifier %$modifier**";}}if(is_string($value))return$this->driver->escape($value,TRUE);if(is_int($value)||is_float($value))return(string)$value;if(is_bool($value))return$value?$this->driver->formats['TRUE']:$this->driver->formats['FALSE'];if(is_null($value))return$this->driver->formats['NULL'];if($value instanceof IDibiVariable)return$value->toSql($this->driver);$this->hasError=TRUE;return'**Unexpected '.gettype($value).'**';}private function callback($matches){if($matches[1])return$this->driver->quoteName($matches[1]);if($matches[2])return$this->driver->quoteName($matches[2]);if($matches[3])return$this->comment?'...':$this->driver->escape(strtr($matches[4],array("''"=>"'")),TRUE);if($matches[5])return$this->comment?'...':$this->driver->escape(strtr($matches[6],array('""'=>'"')),TRUE);if($matches[7]){if(!$this->ifLevel){$this->hasError=TRUE;return"**Unexpected condition $matches[8]**";}if($matches[7]=='end'){$this->ifLevel--;if($this->ifLevelStart==$this->ifLevel+1){$this->ifLevelStart=0;$this->comment=FALSE;return'*/';}return'';}if($this->ifLevelStart==$this->ifLevel){$this->ifLevelStart=0;$this->comment=FALSE;return'*/';}elseif(!$this->comment){$this->ifLevelStart=$this->ifLevel;$this->comment=TRUE;return'/*';}}if($matches[8]){$this->modifier=$matches[8];return'';}if($matches[9]){$this->hasError=TRUE;return'**Alone quote**';}die('this should be never executed');}}
- if(!defined('DIBI'))die();class DibiException extends Exception{private$info;public function __construct($message,$info=NULL){$this->info=$info;if(isset($info['message']))$message="$message: $info[message]";parent::__construct($message);}public function getSql(){return@$this->info['sql'];}}function is_error($var){return($var===FALSE)||($var instanceof Exception);} if(function_exists('date_default_timezone_set'))date_default_timezone_set('Europe/Prague');interface IDibiVariable{public function toSQL($driver,$modifier=NULL);}class dibi{static private$registry=array();static private$conn;static private$parser;static public$sql;static public$error;static public$logfile;static public$debug=false;static private$query=array();static public function connect($config,$name='def'){if(!self::$parser)self::$parser=new DibiParser();if(isset(self::$registry[$name]))return new DibiException("Connection named '$name' already exists.");if(empty($config['driver']))return new DibiException('Driver is not specified.');$className="Dibi$config[driver]Driver"; if(!class_exists($className))return new DibiException("Unable to create instance of dibi driver class '$className'.");$conn=call_user_func(array($className,'connect'),$config);if(self::$logfile!=NULL){if(is_error($conn))$msg="Can't connect to DB '$config[driver]': ".$conn->getMessage();else$msg="Successfully connected to DB '$config[driver]'";$f=fopen(self::$logfile,'a');fwrite($f,"$msg\r\n\r\n");fclose($f);}if(is_error($conn)){if(self::$debug)echo'[dibi error] '.$conn->getMessage();return$conn;}self::$conn=self::$registry[$name]=$conn;return TRUE;}static public function isConnected(){return(bool)self::$conn;}static public function getConnection($name=NULL){return$name===NULL?self::$conn:@self::$registry[$name];}static public function activate($name){if(!isset(self::$registry[$name]))return FALSE;self::$conn=self::$registry[$name];return TRUE;}static public function query(){if(!self::$conn)return new DibiException('Dibi is not connected to DB');$args=func_num_args()?func_get_args():self::$query;self::$query=array();self::$sql=self::$parser->parse(self::$conn,$args);if(is_error(self::$sql))return self::$sql;$timer=-microtime(true);$res=self::$conn->query(self::$sql);$timer+=microtime(true);if(is_error($res)){if(self::$debug){echo'[dibi error] '.$res->getMessage();self::dump(self::$sql);}self::$error=$res;}else{self::$error=FALSE;}if(self::$logfile!=NULL){if(is_error($res))$msg=$res->getMessage();elseif($res instanceof DibiResult)$msg='object('.get_class($res).') rows: '.$res->rowCount();else$msg='OK';$f=fopen(self::$logfile,'a');fwrite($f,self::$sql.";\r\n-- Result: $msg"."\r\n-- Takes: ".sprintf('%0.3f',$timer*1000).' ms'."\r\n\r\n");fclose($f);}return$res;}static public function test(){if(!self::$conn)return FALSE;$args=func_num_args()?func_get_args():self::$query;self::$query=array();$sql=self::$parser->parse(self::$conn,$args);if(is_error($sql)){self::dump($sql->getSql());return$sql->getSql();}else{self::dump($sql);return$sql;}}static public function insertId(){if(!self::$conn)return FALSE;return self::$conn->insertId();}static public function affectedRows(){if(!self::$conn)return FALSE;return self::$conn->affectedRows();}static private function dumpHighlight($matches){if(!empty($matches[1]))return''.$matches[1].'';if(!empty($matches[2]))return''.$matches[2].'';if(!empty($matches[3]))return''.$matches[3].'';if(!empty($matches[4]))return''.$matches[4].'';}static public function dump($sql){static$keywords2='ALL|DISTINCT|AS|ON|INTO|AND|OR|AS';static$keywords1='SELECT|UPDATE|INSERT|DELETE|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN';$sql=preg_replace("#\\b(?:$keywords1)\\b#","\n\$0",$sql);$sql=trim($sql);$sql=wordwrap($sql,100);$sql=htmlSpecialChars($sql);$sql=strtr($sql,array("\n"=>'
'));$sql=preg_replace_callback("#(/\*.+?\*/)|(\*\*.+?\*\*)|\\b($keywords1)\\b|\\b($keywords2)\\b#",array('dibi','dumpHighlight'),$sql);echo'
',$sql,'
';}static public function dumpResult(DibiResult$res){echo'';echo'Row | ';$fieldCount=$res->fieldCount();for($i=0;$i<$fieldCount;$i++){$info=$res->fieldMeta($i);echo''.htmlSpecialChars($info['name']).' | ';}echo'
';foreach($res as$row=>$fields){echo'',$row,' | ';foreach($fields as$field){if(is_object($field))$field=$field->__toString();echo'',htmlSpecialChars($field),' | ';}echo'
';}echo'
';}}
- if(!defined('DIBI'))die();class DibiMySqlDriver extends DibiDriver{private$conn,$insertId=FALSE,$affectedRows=FALSE;public$formats=array('NULL'=>"NULL",'TRUE'=>"1",'FALSE'=>"0",'date'=>"'Y-m-d'",'datetime'=>"'Y-m-d H:i:s'",);public static function connect($config){if(!extension_loaded('mysql'))return new DibiException("PHP extension 'mysql' is not loaded");if(empty($config['host']))$config['host']='localhost';if(@$config['protocol']==='unix')$host=':'.$config['host'];else$host=$config['host'].(empty($config['port'])?'':$config['port']);if(function_exists('ini_set'))$save=ini_set('track_errors',TRUE);$php_errormsg='';if(empty($config['persistent']))$conn=@mysql_connect($host,@$config['username'],@$config['password']);else$conn=@mysql_pconnect($host,@$config['username'],@$config['password']);if(function_exists('ini_set'))ini_set('track_errors',$save);if(!is_resource($conn))return new DibiException("Connecting error",array('message'=>mysql_error()?mysql_error():$php_errormsg,'code'=>mysql_errno(),));if(!empty($config['charset'])){$succ=@mysql_query('SET CHARACTER SET '.$config['charset'],$conn);}if(!empty($config['database'])){if(!@mysql_select_db($config['database'],$conn))return new DibiException("Connecting error",array('message'=>mysql_error($conn),'code'=>mysql_errno($conn),));}$obj=new self($config);$obj->conn=$conn;return$obj;}public function query($sql){$this->insertId=$this->affectedRows=FALSE;$res=@mysql_query($sql,$this->conn);if(is_resource($res))return new DibiMySqlResult($res);if($res===FALSE)return new DibiException("Query error",array('message'=>mysql_error($this->conn),'code'=>mysql_errno($this->conn),'sql'=>$sql,));$this->affectedRows=mysql_affected_rows($this->conn);if($this->affectedRows<0)$this->affectedRows=FALSE;$this->insertId=mysql_insert_id($this->conn);if($this->insertId<1)$this->insertId=FALSE;return TRUE;}public function affectedRows(){return$this->affectedRows;}public function insertId(){return$this->insertId;}public function begin(){return mysql_query('BEGIN',$this->conn);}public function commit(){return mysql_query('COMMIT',$this->conn);}public function rollback(){return mysql_query('ROLLBACK',$this->conn);}public function escape($value,$appendQuotes=FALSE){return$appendQuotes?"'".mysql_real_escape_string($value,$this->conn)."'":mysql_real_escape_string($value,$this->conn);}public function quoteName($value){return'`'.strtr($value,array('.'=>'`.`')).'`';}public function getMetaData(){trigger_error('Meta is not implemented yet.',E_USER_WARNING);}}class DibiMySqlResult extends DibiResult{private$resource,$meta;public function __construct($resource){$this->resource=$resource;}public function rowCount(){return mysql_num_rows($this->resource);}protected function doFetch(){return mysql_fetch_assoc($this->resource);}public function seek($row){return mysql_data_seek($this->resource,$row);}protected function free(){mysql_free_result($this->resource);}public function getFields(){if($this->meta===NULL)$this->createMeta();return array_keys($this->meta);}protected function detectTypes(){if($this->meta===NULL)$this->createMeta();}public function getMetaData($field){if($this->meta===NULL)$this->createMeta();return isset($this->meta[$field])?$this->meta[$field]:FALSE;}private function createMeta(){static$types=array('ENUM'=>self::FIELD_TEXT,'SET'=>self::FIELD_TEXT,'CHAR'=>self::FIELD_TEXT,'VARCHAR'=>self::FIELD_TEXT,'STRING'=>self::FIELD_TEXT,'TINYTEXT'=>self::FIELD_TEXT,'TEXT'=>self::FIELD_TEXT,'MEDIUMTEXT'=>self::FIELD_TEXT,'LONGTEXT'=>self::FIELD_TEXT,'BINARY'=>self::FIELD_BINARY,'VARBINARY'=>self::FIELD_BINARY,'TINYBLOB'=>self::FIELD_BINARY,'BLOB'=>self::FIELD_BINARY,'MEDIUMBLOB'=>self::FIELD_BINARY,'LONGBLOB'=>self::FIELD_BINARY,'DATE'=>self::FIELD_DATE,'DATETIME'=>self::FIELD_DATETIME,'TIMESTAMP'=>self::FIELD_DATETIME,'TIME'=>self::FIELD_DATETIME,'BIT'=>self::FIELD_BOOL,'YEAR'=>self::FIELD_INTEGER,'TINYINT'=>self::FIELD_INTEGER,'SMALLINT'=>self::FIELD_INTEGER,'MEDIUMINT'=>self::FIELD_INTEGER,'INT'=>self::FIELD_INTEGER,'INTEGER'=>self::FIELD_INTEGER,'BIGINT'=>self::FIELD_INTEGER,'FLOAT'=>self::FIELD_FLOAT,'DOUBLE'=>self::FIELD_FLOAT,'REAL'=>self::FIELD_FLOAT,'DECIMAL'=>self::FIELD_FLOAT,'NUMERIC'=>self::FIELD_FLOAT,);$count=mysql_num_fields($this->resource);$this->meta=$this->convert=array();for($index=0;$index<$count;$index++){$info['native']=$native=strtoupper(mysql_field_type($this->resource,$index));$info['flags']=explode(' ',mysql_field_flags($this->resource,$index));$info['length']=mysql_field_len($this->resource,$index);$info['table']=mysql_field_table($this->resource,$index);if(in_array('auto_increment',$info['flags']))$info['type']=self::FIELD_COUNTER;else{$info['type']=isset($types[$native])?$types[$native]:self::FIELD_UNKNOWN;}$name=mysql_field_name($this->resource,$index);$this->meta[$name]=$info;$this->convert[$name]=$info['type'];}}}
- if(!defined('DIBI'))die();class DibiMySqliDriver extends DibiDriver{private$conn,$insertId=FALSE,$affectedRows=FALSE;public$formats=array('NULL'=>"NULL",'TRUE'=>"1",'FALSE'=>"0",'date'=>"'Y-m-d'",'datetime'=>"'Y-m-d H:i:s'",);public static function connect($config){if(!extension_loaded('mysqli'))return new DibiException("PHP extension 'mysqli' is not loaded");if(empty($config['host']))$config['host']='localhost';$conn=@mysqli_connect($config['host'],@$config['username'],@$config['password'],@$config['database'],@$config['port']);if(!$conn)return new DibiException("Connecting error",array('message'=>mysqli_connect_error(),'code'=>mysqli_connect_errno(),));if(!empty($config['charset']))mysqli_query($conn,'SET CHARACTER SET '.$config['charset']);$obj=new self($config);$obj->conn=$conn;return$obj;}public function query($sql){$this->insertId=$this->affectedRows=FALSE;$res=@mysqli_query($this->conn,$sql);if(is_object($res))return new DibiMySqliResult($res);if($res===FALSE)return new DibiException("Query error",$this->errorInfo($sql));$this->affectedRows=mysqli_affected_rows($this->conn);if($this->affectedRows<0)$this->affectedRows=FALSE;$this->insertId=mysqli_insert_id($this->conn);if($this->insertId<1)$this->insertId=FALSE;return TRUE;}public function affectedRows(){return$this->affectedRows;}public function insertId(){return$this->insertId;}public function begin(){return mysqli_autocommit($this->conn,FALSE);}public function commit(){$ok=mysqli_commit($this->conn);mysqli_autocommit($this->conn,TRUE);return$ok;}public function rollback(){$ok=mysqli_rollback($this->conn);mysqli_autocommit($this->conn,TRUE);return$ok;}private function errorInfo($sql=NULL){return array('message'=>mysqli_error($this->conn),'code'=>mysqli_errno($this->conn),'sql'=>$sql,);}public function escape($value,$appendQuotes=FALSE){return$appendQuotes?"'".mysqli_real_escape_string($this->conn,$value)."'":mysqli_real_escape_string($this->conn,$value);}public function quoteName($value){return'`'.strtr($value,array('.'=>'`.`')).'`';}public function getMetaData(){trigger_error('Meta is not implemented yet.',E_USER_WARNING);}}class DibiMySqliResult extends DibiResult{private$resource,$meta;public function __construct($resource){$this->resource=$resource;}public function rowCount(){return mysqli_num_rows($this->resource);}protected function doFetch(){return mysqli_fetch_assoc($this->resource);}public function seek($row){return mysqli_data_seek($this->resource,$row);}protected function free(){mysqli_free_result($this->resource);}public function getFields(){if($this->meta===NULL)$this->createMeta();return array_keys($this->meta);}protected function detectTypes(){if($this->meta===NULL)$this->createMeta();}public function getMetaData($field){if($this->meta===NULL)$this->createMeta();return isset($this->meta[$field])?$this->meta[$field]:FALSE;}private function createMeta(){static$types=array(MYSQLI_TYPE_FLOAT=>self::FIELD_FLOAT,MYSQLI_TYPE_DOUBLE=>self::FIELD_FLOAT,MYSQLI_TYPE_DECIMAL=>self::FIELD_FLOAT,MYSQLI_TYPE_TINY=>self::FIELD_INTEGER,MYSQLI_TYPE_SHORT=>self::FIELD_INTEGER,MYSQLI_TYPE_LONG=>self::FIELD_INTEGER,MYSQLI_TYPE_LONGLONG=>self::FIELD_INTEGER,MYSQLI_TYPE_INT24=>self::FIELD_INTEGER,MYSQLI_TYPE_YEAR=>self::FIELD_INTEGER,MYSQLI_TYPE_GEOMETRY=>self::FIELD_INTEGER,MYSQLI_TYPE_DATE=>self::FIELD_DATE,MYSQLI_TYPE_NEWDATE=>self::FIELD_DATE,MYSQLI_TYPE_TIMESTAMP=>self::FIELD_DATETIME,MYSQLI_TYPE_TIME=>self::FIELD_DATETIME,MYSQLI_TYPE_DATETIME=>self::FIELD_DATETIME,MYSQLI_TYPE_ENUM=>self::FIELD_TEXT,MYSQLI_TYPE_SET=>self::FIELD_TEXT,MYSQLI_TYPE_STRING=>self::FIELD_TEXT,MYSQLI_TYPE_VAR_STRING=>self::FIELD_TEXT,MYSQLI_TYPE_TINY_BLOB=>self::FIELD_BINARY,MYSQLI_TYPE_MEDIUM_BLOB=>self::FIELD_BINARY,MYSQLI_TYPE_LONG_BLOB=>self::FIELD_BINARY,MYSQLI_TYPE_BLOB=>self::FIELD_BINARY,);$count=mysqli_num_fields($this->resource);$this->meta=$this->convert=array();for($index=0;$index<$count;$index++){$info=(array)mysqli_fetch_field_direct($this->resource,$index);$native=$info['native']=$info['type'];if($info['flags']&MYSQLI_AUTO_INCREMENT_FLAG)$info['type']=self::FIELD_COUNTER;else{$info['type']=isset($types[$native])?$types[$native]:self::FIELD_UNKNOWN;}$this->meta[$info['name']]=$info;$this->convert[$info['name']]=$info['type'];}}}
- if(!defined('DIBI'))die();class DibiOdbcDriver extends DibiDriver{private$conn,$affectedRows=FALSE;public$formats=array('NULL'=>"NULL",'TRUE'=>"-1",'FALSE'=>"0",'date'=>"#m/d/Y#",'datetime'=>"#m/d/Y H:i:s#",);public static function connect($config){if(!extension_loaded('odbc'))return new DibiException("PHP extension 'odbc' is not loaded");if(@$config['persistent'])$conn=@odbc_pconnect($config['database'],$config['username'],$config['password']);else$conn=@odbc_connect($config['database'],$config['username'],$config['password']);if(!is_resource($conn))return new DibiException("Connecting error",array('message'=>odbc_errormsg(),'code'=>odbc_error(),));$obj=new self($config);$obj->conn=$conn;return$obj;}public function query($sql){$this->affectedRows=FALSE;$res=@odbc_exec($this->conn,$sql);if(is_resource($res))return new DibiOdbcResult($res);if($res===FALSE)return new DibiException("Query error",$this->errorInfo($sql));$this->affectedRows=odbc_num_rows($this->conn);if($this->affectedRows<0)$this->affectedRows=FALSE;return TRUE;}public function affectedRows(){return$this->affectedRows;}public function insertId(){return FALSE;}public function begin(){return odbc_autocommit($this->conn,FALSE);}public function commit(){$ok=odbc_commit($this->conn);odbc_autocommit($this->conn,TRUE);return$ok;}public function rollback(){$ok=odbc_rollback($this->conn);odbc_autocommit($this->conn,TRUE);return$ok;}private function errorInfo($sql=NULL){return array('message'=>odbc_errormsg($this->conn),'code'=>odbc_error($this->conn),'sql'=>$sql,);}public function escape($value,$appendQuotes=FALSE){$value=str_replace("'","''",$value);return$appendQuotes?"'".$value."'":$value;}public function quoteName($value){return'['.strtr($value,array('.'=>'].[')).']';}public function getMetaData(){trigger_error('Meta is not implemented yet.',E_USER_WARNING);}}class DibiOdbcResult extends DibiResult{private$resource,$meta,$row=0;public function __construct($resource){$this->resource=$resource;}public function rowCount(){return odbc_num_rows($this->resource);}protected function doFetch(){return odbc_fetch_array($this->resource,$this->row++);}public function seek($row){$this->row=$row;}protected function free(){odbc_free_result($this->resource);}public function getFields(){if($this->meta===NULL)$this->createMeta();return array_keys($this->meta);}protected function detectTypes(){if($this->meta===NULL)$this->createMeta();}public function getMetaData($field){if($this->meta===NULL)$this->createMeta();return isset($this->meta[$field])?$this->meta[$field]:FALSE;}private function createMeta(){if($this->meta!==NULL)return$this->meta;static$types=array('CHAR'=>self::FIELD_TEXT,'COUNTER'=>self::FIELD_COUNTER,'VARCHAR'=>self::FIELD_TEXT,'LONGCHAR'=>self::FIELD_TEXT,'INTEGER'=>self::FIELD_INTEGER,'DATETIME'=>self::FIELD_DATETIME,'CURRENCY'=>self::FIELD_FLOAT,'BIT'=>self::FIELD_BOOL,'LONGBINARY'=>self::FIELD_BINARY,'SMALLINT'=>self::FIELD_INTEGER,'BYTE'=>self::FIELD_INTEGER,'BIGINT'=>self::FIELD_INTEGER,'INT'=>self::FIELD_INTEGER,'TINYINT'=>self::FIELD_INTEGER,'REAL'=>self::FIELD_FLOAT,'DOUBLE'=>self::FIELD_FLOAT,'DECIMAL'=>self::FIELD_FLOAT,'NUMERIC'=>self::FIELD_FLOAT,'MONEY'=>self::FIELD_FLOAT,'SMALLMONEY'=>self::FIELD_FLOAT,'FLOAT'=>self::FIELD_FLOAT,'YESNO'=>self::FIELD_BOOL,);$count=odbc_num_fields($this->resource);$this->meta=$this->convert=array();for($index=1;$index<=$count;$index++){$native=strtoupper(odbc_field_type($this->resource,$index));$name=odbc_field_name($this->resource,$index);$this->meta[$name]=array('type'=>isset($types[$native])?$types[$native]:self::FIELD_UNKNOWN,'native'=>$native,'length'=>odbc_field_len($this->resource,$index),'scale'=>odbc_field_scale($this->resource,$index),'precision'=>odbc_field_precision($this->resource,$index),);$this->convert[$name]=$this->meta[$name]['type'];}}}
- if(!defined('DIBI'))die();class DibiSqliteDriver extends DibiDriver{private$conn,$insertId=FALSE,$affectedRows=FALSE;public$formats=array('NULL'=>"NULL",'TRUE'=>"1",'FALSE'=>"0",'date'=>"'Y-m-d'",'datetime'=>"'Y-m-d H:i:s'",);public static function connect($config){if(!extension_loaded('sqlite'))return new DibiException("PHP extension 'sqlite' is not loaded");if(empty($config['database']))return new DibiException("Database must be specified");$errorMsg='';if(empty($config['persistent']))$conn=@sqlite_open($config['database'],@$config['mode'],$errorMsg);else$conn=@sqlite_popen($config['database'],@$config['mode'],$errorMsg);if(!$conn)return new DibiException("Connecting error",array('message'=>$errorMsg,));$obj=new self($config);$obj->conn=$conn;return$obj;}public function query($sql){$this->insertId=$this->affectedRows=FALSE;$errorMsg='';$res=@sqlite_query($this->conn,$sql,SQLITE_ASSOC,$errorMsg);if($res===FALSE)return new DibiException("Query error",array('message'=>$errorMsg,'sql'=>$sql,));if(is_resource($res))return new DibiSqliteResult($res);$this->affectedRows=sqlite_changes($this->conn);if($this->affectedRows<0)$this->affectedRows=FALSE;$this->insertId=sqlite_last_insert_rowid($this->conn);if($this->insertId<1)$this->insertId=FALSE;return TRUE;}public function affectedRows(){return$this->affectedRows;}public function insertId(){return$this->insertId;}public function begin(){return sqlite_query($this->conn,'BEGIN');}public function commit(){return sqlite_query($this->conn,'COMMIT');}public function rollback(){return sqlite_query($this->conn,'ROLLBACK');}public function escape($value,$appendQuotes=FALSE){return$appendQuotes?"'".sqlite_escape_string($value)."'":sqlite_escape_string($value);}public function quoteName($value){return$value;}public function getMetaData(){trigger_error('Meta is not implemented yet.',E_USER_WARNING);}}class DibiSqliteResult extends DibiResult{private$resource,$meta;public function __construct($resource){$this->resource=$resource;}public function rowCount(){return sqlite_num_rows($this->resource);}protected function doFetch(){return sqlite_fetch_array($this->resource,SQLITE_ASSOC);}public function seek($row){return sqlite_seek($this->resource,$row);}protected function free(){}public function getFields(){if($this->meta===NULL)$this->createMeta();return array_keys($this->meta);}protected function detectTypes(){if($this->meta===NULL)$this->createMeta();}public function getMetaData($field){if($this->meta===NULL)$this->createMeta();return isset($this->meta[$field])?$this->meta[$field]:FALSE;}private function createMeta(){$count=sqlite_num_fields($this->resource);$this->meta=$this->convert=array();for($index=0;$index<$count;$index++){$name=sqlite_field_name($this->resource,$index);$this->meta[$name]=array('type'=>self::FIELD_UNKNOWN);$this->convert[$name]=self::FIELD_UNKNOWN;}}}?>
\ No newline at end of file
+ )/xs',array($this,'callback'),substr($value,$toSkip));case'S':case'V':$this->hasError=TRUE;return"**Unexpected ".gettype($value)."**";case'if':$this->hasError=TRUE;return"**The %$modifier is not allowed here**";default:$this->hasError=TRUE;return"**Unknown modifier %$modifier**";}}if(is_string($value))return$this->driver->escape($value,TRUE);if(is_int($value)||is_float($value))return(string)$value;if(is_bool($value))return$value?$this->driver->formats['TRUE']:$this->driver->formats['FALSE'];if(is_null($value))return$this->driver->formats['NULL'];if($value instanceof IDibiVariable)return$value->toSql($this->driver);$this->hasError=TRUE;return'**Unexpected '.gettype($value).'**';}private function callback($matches){if($matches[1])return$this->driver->quoteName($matches[1]);if($matches[2])return$this->driver->quoteName($matches[2]);if($matches[3])return$this->comment?'...':$this->driver->escape(strtr($matches[4],array("''"=>"'")),TRUE);if($matches[5])return$this->comment?'...':$this->driver->escape(strtr($matches[6],array('""'=>'"')),TRUE);if($matches[7]){if(!$this->ifLevel){$this->hasError=TRUE;return"**Unexpected condition $matches[8]**";}if('end'==$matches[7]){$this->ifLevel--;if($this->ifLevelStart==$this->ifLevel+1){$this->ifLevelStart=0;$this->comment=FALSE;return'*/';}return'';}if($this->ifLevelStart==$this->ifLevel){$this->ifLevelStart=0;$this->comment=FALSE;return'*/';}elseif(!$this->comment){$this->ifLevelStart=$this->ifLevel;$this->comment=TRUE;return'/*';}}if($matches[8]){$this->modifier=$matches[8];return'';}if($matches[9]){$this->hasError=TRUE;return'**Alone quote**';}die('this should be never executed');}}
+ if(!defined('DIBI'))die();class DibiException extends Exception{private$info;public function __construct($message,$info=NULL){$this->info=$info;if(isset($info['message']))$message="$message: $info[message]";parent::__construct($message);}public function getSql(){return@$this->info['sql'];}}function is_error($var){return($var===FALSE)||($var instanceof Exception);} if(function_exists('date_default_timezone_set'))date_default_timezone_set('Europe/Prague');interface IDibiVariable{public function toSQL($driver,$modifier=NULL);}class dibi{const FIELD_TEXT='s',FIELD_BINARY='b',FIELD_BOOL='l',FIELD_INTEGER='i',FIELD_FLOAT='f',FIELD_DATE='d',FIELD_DATETIME='t',FIELD_UNKNOWN='?',FIELD_COUNTER='c';static private$registry=array();static private$conn;static private$parser;static public$sql;static public$error;static public$logfile;static public$debug=false;static private$query=array();static public function connect($config,$name='def'){if(!self::$parser)self::$parser=new DibiParser();if(isset(self::$registry[$name]))return new DibiException("Connection named '$name' already exists.");if(empty($config['driver']))return new DibiException('Driver is not specified.');$className="Dibi$config[driver]Driver"; if(!class_exists($className))return new DibiException("Unable to create instance of dibi driver class '$className'.");$conn=call_user_func(array($className,'connect'),$config);if(self::$logfile!=NULL){if(is_error($conn))$msg="Can't connect to DB '$config[driver]': ".$conn->getMessage();else$msg="Successfully connected to DB '$config[driver]'";$f=fopen(self::$logfile,'a');fwrite($f,"$msg\r\n\r\n");fclose($f);}if(is_error($conn)){if(self::$debug)echo'[dibi error] '.$conn->getMessage();return$conn;}self::$conn=self::$registry[$name]=$conn;return TRUE;}static public function isConnected(){return(bool)self::$conn;}static public function getConnection($name=NULL){return NULL===$name?self::$conn:@self::$registry[$name];}static public function activate($name){if(!isset(self::$registry[$name]))return FALSE;self::$conn=self::$registry[$name];return TRUE;}static public function query(){if(!self::$conn)return new DibiException('Dibi is not connected to DB');$args=func_num_args()?func_get_args():self::$query;self::$query=array();self::$sql=self::$parser->parse(self::$conn,$args);if(is_error(self::$sql))return self::$sql;$timer=-microtime(true);$res=self::$conn->query(self::$sql);$timer+=microtime(true);if(is_error($res)){if(self::$debug){echo'[dibi error] '.$res->getMessage();self::dump(self::$sql);}self::$error=$res;}else{self::$error=FALSE;}if(self::$logfile!=NULL){if(is_error($res))$msg=$res->getMessage();elseif($res instanceof DibiResult)$msg='object('.get_class($res).') rows: '.$res->rowCount();else$msg='OK';$f=fopen(self::$logfile,'a');fwrite($f,self::$sql.";\r\n-- Result: $msg"."\r\n-- Takes: ".sprintf('%0.3f',$timer*1000).' ms'."\r\n\r\n");fclose($f);}return$res;}static public function test(){if(!self::$conn)return FALSE;$args=func_num_args()?func_get_args():self::$query;self::$query=array();$sql=self::$parser->parse(self::$conn,$args);if(is_error($sql)){self::dump($sql->getSql());return$sql->getSql();}else{self::dump($sql);return$sql;}}static public function insertId(){if(!self::$conn)return FALSE;return self::$conn->insertId();}static public function affectedRows(){if(!self::$conn)return FALSE;return self::$conn->affectedRows();}static private function dumpHighlight($matches){if(!empty($matches[1]))return''.$matches[1].'';if(!empty($matches[2]))return''.$matches[2].'';if(!empty($matches[3]))return''.$matches[3].'';if(!empty($matches[4]))return''.$matches[4].'';}static public function dump($sql){static$keywords2='ALL|DISTINCT|AS|ON|INTO|AND|OR|AS';static$keywords1='SELECT|UPDATE|INSERT|DELETE|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN';$sql=preg_replace("#\\b(?:$keywords1)\\b#","\n\$0",$sql);$sql=trim($sql);$sql=wordwrap($sql,100);$sql=htmlSpecialChars($sql);$sql=strtr($sql,array("\n"=>'
'));$sql=preg_replace_callback("#(/\*.+?\*/)|(\*\*.+?\*\*)|\\b($keywords1)\\b|\\b($keywords2)\\b#",array('dibi','dumpHighlight'),$sql);echo'',$sql,'
';}static public function dumpResult(DibiResult$res){echo'';echo'Row | ';$fieldCount=$res->fieldCount();for($i=0;$i<$fieldCount;$i++){$info=$res->fieldMeta($i);echo''.htmlSpecialChars($info['name']).' | ';}echo'
';foreach($res as$row=>$fields){echo'',$row,' | ';foreach($fields as$field){if(is_object($field))$field=$field->__toString();echo'',htmlSpecialChars($field),' | ';}echo'
';}echo'
';}}
+ if(!defined('DIBI'))die();class DibiMySqlDriver extends DibiDriver{private$conn,$insertId=FALSE,$affectedRows=FALSE;public$formats=array('NULL'=>"NULL",'TRUE'=>"1",'FALSE'=>"0",'date'=>"'Y-m-d'",'datetime'=>"'Y-m-d H:i:s'",);public static function connect($config){if(!extension_loaded('mysql'))return new DibiException("PHP extension 'mysql' is not loaded");if(empty($config['host']))$config['host']='localhost';if(@$config['protocol']==='unix')$host=':'.$config['host'];else$host=$config['host'].(empty($config['port'])?'':$config['port']);if(function_exists('ini_set'))$save=ini_set('track_errors',TRUE);$php_errormsg='';if(empty($config['persistent']))$conn=@mysql_connect($host,@$config['username'],@$config['password']);else$conn=@mysql_pconnect($host,@$config['username'],@$config['password']);if(function_exists('ini_set'))ini_set('track_errors',$save);if(!is_resource($conn))return new DibiException("Connecting error",array('message'=>mysql_error()?mysql_error():$php_errormsg,'code'=>mysql_errno(),));if(!empty($config['charset'])){$succ=@mysql_query('SET CHARACTER SET '.$config['charset'],$conn);}if(!empty($config['database'])){if(!@mysql_select_db($config['database'],$conn))return new DibiException("Connecting error",array('message'=>mysql_error($conn),'code'=>mysql_errno($conn),));}$obj=new self($config);$obj->conn=$conn;return$obj;}public function query($sql){$this->insertId=$this->affectedRows=FALSE;$res=@mysql_query($sql,$this->conn);if(is_resource($res))return new DibiMySqlResult($res);if($res===FALSE)return new DibiException("Query error",array('message'=>mysql_error($this->conn),'code'=>mysql_errno($this->conn),'sql'=>$sql,));$this->affectedRows=mysql_affected_rows($this->conn);if($this->affectedRows<0)$this->affectedRows=FALSE;$this->insertId=mysql_insert_id($this->conn);if($this->insertId<1)$this->insertId=FALSE;return TRUE;}public function affectedRows(){return$this->affectedRows;}public function insertId(){return$this->insertId;}public function begin(){return mysql_query('BEGIN',$this->conn);}public function commit(){return mysql_query('COMMIT',$this->conn);}public function rollback(){return mysql_query('ROLLBACK',$this->conn);}public function escape($value,$appendQuotes=FALSE){return$appendQuotes?"'".mysql_real_escape_string($value,$this->conn)."'":mysql_real_escape_string($value,$this->conn);}public function quoteName($value){return'`'.strtr($value,array('.'=>'`.`')).'`';}public function getMetaData(){trigger_error('Meta is not implemented yet.',E_USER_WARNING);}}class DibiMySqlResult extends DibiResult{private$resource,$meta;public function __construct($resource){$this->resource=$resource;}public function rowCount(){return mysql_num_rows($this->resource);}protected function doFetch(){return mysql_fetch_assoc($this->resource);}public function seek($row){return mysql_data_seek($this->resource,$row);}protected function free(){mysql_free_result($this->resource);}public function getFields(){if($this->meta===NULL)$this->createMeta();return array_keys($this->meta);}protected function detectTypes(){if($this->meta===NULL)$this->createMeta();}public function getMetaData($field){if($this->meta===NULL)$this->createMeta();return isset($this->meta[$field])?$this->meta[$field]:FALSE;}private function createMeta(){static$types=array('ENUM'=>dibi::FIELD_TEXT,'SET'=>dibi::FIELD_TEXT,'CHAR'=>dibi::FIELD_TEXT,'VARCHAR'=>dibi::FIELD_TEXT,'STRING'=>dibi::FIELD_TEXT,'TINYTEXT'=>dibi::FIELD_TEXT,'TEXT'=>dibi::FIELD_TEXT,'MEDIUMTEXT'=>dibi::FIELD_TEXT,'LONGTEXT'=>dibi::FIELD_TEXT,'BINARY'=>dibi::FIELD_BINARY,'VARBINARY'=>dibi::FIELD_BINARY,'TINYBLOB'=>dibi::FIELD_BINARY,'BLOB'=>dibi::FIELD_BINARY,'MEDIUMBLOB'=>dibi::FIELD_BINARY,'LONGBLOB'=>dibi::FIELD_BINARY,'DATE'=>dibi::FIELD_DATE,'DATETIME'=>dibi::FIELD_DATETIME,'TIMESTAMP'=>dibi::FIELD_DATETIME,'TIME'=>dibi::FIELD_DATETIME,'BIT'=>dibi::FIELD_BOOL,'YEAR'=>dibi::FIELD_INTEGER,'TINYINT'=>dibi::FIELD_INTEGER,'SMALLINT'=>dibi::FIELD_INTEGER,'MEDIUMINT'=>dibi::FIELD_INTEGER,'INT'=>dibi::FIELD_INTEGER,'INTEGER'=>dibi::FIELD_INTEGER,'BIGINT'=>dibi::FIELD_INTEGER,'FLOAT'=>dibi::FIELD_FLOAT,'DOUBLE'=>dibi::FIELD_FLOAT,'REAL'=>dibi::FIELD_FLOAT,'DECIMAL'=>dibi::FIELD_FLOAT,'NUMERIC'=>dibi::FIELD_FLOAT,);$count=mysql_num_fields($this->resource);$this->meta=$this->convert=array();for($index=0;$index<$count;$index++){$info['native']=$native=strtoupper(mysql_field_type($this->resource,$index));$info['flags']=explode(' ',mysql_field_flags($this->resource,$index));$info['length']=mysql_field_len($this->resource,$index);$info['table']=mysql_field_table($this->resource,$index);if(in_array('auto_increment',$info['flags']))$info['type']=dibi::FIELD_COUNTER;else{$info['type']=isset($types[$native])?$types[$native]:dibi::FIELD_UNKNOWN;}$name=mysql_field_name($this->resource,$index);$this->meta[$name]=$info;$this->convert[$name]=$info['type'];}}}
+ if(!defined('DIBI'))die();class DibiMySqliDriver extends DibiDriver{private$conn,$insertId=FALSE,$affectedRows=FALSE;public$formats=array('NULL'=>"NULL",'TRUE'=>"1",'FALSE'=>"0",'date'=>"'Y-m-d'",'datetime'=>"'Y-m-d H:i:s'",);public static function connect($config){if(!extension_loaded('mysqli'))return new DibiException("PHP extension 'mysqli' is not loaded");if(empty($config['host']))$config['host']='localhost';$conn=@mysqli_connect($config['host'],@$config['username'],@$config['password'],@$config['database'],@$config['port']);if(!$conn)return new DibiException("Connecting error",array('message'=>mysqli_connect_error(),'code'=>mysqli_connect_errno(),));if(!empty($config['charset']))mysqli_query($conn,'SET CHARACTER SET '.$config['charset']);$obj=new self($config);$obj->conn=$conn;return$obj;}public function query($sql){$this->insertId=$this->affectedRows=FALSE;$res=@mysqli_query($this->conn,$sql);if(is_object($res))return new DibiMySqliResult($res);if($res===FALSE)return new DibiException("Query error",$this->errorInfo($sql));$this->affectedRows=mysqli_affected_rows($this->conn);if($this->affectedRows<0)$this->affectedRows=FALSE;$this->insertId=mysqli_insert_id($this->conn);if($this->insertId<1)$this->insertId=FALSE;return TRUE;}public function affectedRows(){return$this->affectedRows;}public function insertId(){return$this->insertId;}public function begin(){return mysqli_autocommit($this->conn,FALSE);}public function commit(){$ok=mysqli_commit($this->conn);mysqli_autocommit($this->conn,TRUE);return$ok;}public function rollback(){$ok=mysqli_rollback($this->conn);mysqli_autocommit($this->conn,TRUE);return$ok;}private function errorInfo($sql=NULL){return array('message'=>mysqli_error($this->conn),'code'=>mysqli_errno($this->conn),'sql'=>$sql,);}public function escape($value,$appendQuotes=FALSE){return$appendQuotes?"'".mysqli_real_escape_string($this->conn,$value)."'":mysqli_real_escape_string($this->conn,$value);}public function quoteName($value){return'`'.strtr($value,array('.'=>'`.`')).'`';}public function getMetaData(){trigger_error('Meta is not implemented yet.',E_USER_WARNING);}}class DibiMySqliResult extends DibiResult{private$resource,$meta;public function __construct($resource){$this->resource=$resource;}public function rowCount(){return mysqli_num_rows($this->resource);}protected function doFetch(){return mysqli_fetch_assoc($this->resource);}public function seek($row){return mysqli_data_seek($this->resource,$row);}protected function free(){mysqli_free_result($this->resource);}public function getFields(){if($this->meta===NULL)$this->createMeta();return array_keys($this->meta);}protected function detectTypes(){if($this->meta===NULL)$this->createMeta();}public function getMetaData($field){if($this->meta===NULL)$this->createMeta();return isset($this->meta[$field])?$this->meta[$field]:FALSE;}private function createMeta(){static$types=array(MYSQLI_TYPE_FLOAT=>dibi::FIELD_FLOAT,MYSQLI_TYPE_DOUBLE=>dibi::FIELD_FLOAT,MYSQLI_TYPE_DECIMAL=>dibi::FIELD_FLOAT,MYSQLI_TYPE_TINY=>dibi::FIELD_INTEGER,MYSQLI_TYPE_SHORT=>dibi::FIELD_INTEGER,MYSQLI_TYPE_LONG=>dibi::FIELD_INTEGER,MYSQLI_TYPE_LONGLONG=>dibi::FIELD_INTEGER,MYSQLI_TYPE_INT24=>dibi::FIELD_INTEGER,MYSQLI_TYPE_YEAR=>dibi::FIELD_INTEGER,MYSQLI_TYPE_GEOMETRY=>dibi::FIELD_INTEGER,MYSQLI_TYPE_DATE=>dibi::FIELD_DATE,MYSQLI_TYPE_NEWDATE=>dibi::FIELD_DATE,MYSQLI_TYPE_TIMESTAMP=>dibi::FIELD_DATETIME,MYSQLI_TYPE_TIME=>dibi::FIELD_DATETIME,MYSQLI_TYPE_DATETIME=>dibi::FIELD_DATETIME,MYSQLI_TYPE_ENUM=>dibi::FIELD_TEXT,MYSQLI_TYPE_SET=>dibi::FIELD_TEXT,MYSQLI_TYPE_STRING=>dibi::FIELD_TEXT,MYSQLI_TYPE_VAR_STRING=>dibi::FIELD_TEXT,MYSQLI_TYPE_TINY_BLOB=>dibi::FIELD_BINARY,MYSQLI_TYPE_MEDIUM_BLOB=>dibi::FIELD_BINARY,MYSQLI_TYPE_LONG_BLOB=>dibi::FIELD_BINARY,MYSQLI_TYPE_BLOB=>dibi::FIELD_BINARY,);$count=mysqli_num_fields($this->resource);$this->meta=$this->convert=array();for($index=0;$index<$count;$index++){$info=(array)mysqli_fetch_field_direct($this->resource,$index);$native=$info['native']=$info['type'];if($info['flags']&MYSQLI_AUTO_INCREMENT_FLAG)$info['type']=dibi::FIELD_COUNTER;else{$info['type']=isset($types[$native])?$types[$native]:dibi::FIELD_UNKNOWN;}$this->meta[$info['name']]=$info;$this->convert[$info['name']]=$info['type'];}}}
+ if(!defined('DIBI'))die();class DibiOdbcDriver extends DibiDriver{private$conn,$affectedRows=FALSE;public$formats=array('NULL'=>"NULL",'TRUE'=>"-1",'FALSE'=>"0",'date'=>"#m/d/Y#",'datetime'=>"#m/d/Y H:i:s#",);public static function connect($config){if(!extension_loaded('odbc'))return new DibiException("PHP extension 'odbc' is not loaded");if(@$config['persistent'])$conn=@odbc_pconnect($config['database'],$config['username'],$config['password']);else$conn=@odbc_connect($config['database'],$config['username'],$config['password']);if(!is_resource($conn))return new DibiException("Connecting error",array('message'=>odbc_errormsg(),'code'=>odbc_error(),));$obj=new self($config);$obj->conn=$conn;return$obj;}public function query($sql){$this->affectedRows=FALSE;$res=@odbc_exec($this->conn,$sql);if(is_resource($res))return new DibiOdbcResult($res);if($res===FALSE)return new DibiException("Query error",$this->errorInfo($sql));$this->affectedRows=odbc_num_rows($this->conn);if($this->affectedRows<0)$this->affectedRows=FALSE;return TRUE;}public function affectedRows(){return$this->affectedRows;}public function insertId(){return FALSE;}public function begin(){return odbc_autocommit($this->conn,FALSE);}public function commit(){$ok=odbc_commit($this->conn);odbc_autocommit($this->conn,TRUE);return$ok;}public function rollback(){$ok=odbc_rollback($this->conn);odbc_autocommit($this->conn,TRUE);return$ok;}private function errorInfo($sql=NULL){return array('message'=>odbc_errormsg($this->conn),'code'=>odbc_error($this->conn),'sql'=>$sql,);}public function escape($value,$appendQuotes=FALSE){$value=str_replace("'","''",$value);return$appendQuotes?"'".$value."'":$value;}public function quoteName($value){return'['.strtr($value,array('.'=>'].[')).']';}public function getMetaData(){trigger_error('Meta is not implemented yet.',E_USER_WARNING);}}class DibiOdbcResult extends DibiResult{private$resource,$meta,$row=0;public function __construct($resource){$this->resource=$resource;}public function rowCount(){return odbc_num_rows($this->resource);}protected function doFetch(){return odbc_fetch_array($this->resource,$this->row++);}public function seek($row){$this->row=$row;}protected function free(){odbc_free_result($this->resource);}public function getFields(){if($this->meta===NULL)$this->createMeta();return array_keys($this->meta);}protected function detectTypes(){if($this->meta===NULL)$this->createMeta();}public function getMetaData($field){if($this->meta===NULL)$this->createMeta();return isset($this->meta[$field])?$this->meta[$field]:FALSE;}private function createMeta(){if($this->meta!==NULL)return$this->meta;static$types=array('CHAR'=>dibi::FIELD_TEXT,'COUNTER'=>dibi::FIELD_COUNTER,'VARCHAR'=>dibi::FIELD_TEXT,'LONGCHAR'=>dibi::FIELD_TEXT,'INTEGER'=>dibi::FIELD_INTEGER,'DATETIME'=>dibi::FIELD_DATETIME,'CURRENCY'=>dibi::FIELD_FLOAT,'BIT'=>dibi::FIELD_BOOL,'LONGBINARY'=>dibi::FIELD_BINARY,'SMALLINT'=>dibi::FIELD_INTEGER,'BYTE'=>dibi::FIELD_INTEGER,'BIGINT'=>dibi::FIELD_INTEGER,'INT'=>dibi::FIELD_INTEGER,'TINYINT'=>dibi::FIELD_INTEGER,'REAL'=>dibi::FIELD_FLOAT,'DOUBLE'=>dibi::FIELD_FLOAT,'DECIMAL'=>dibi::FIELD_FLOAT,'NUMERIC'=>dibi::FIELD_FLOAT,'MONEY'=>dibi::FIELD_FLOAT,'SMALLMONEY'=>dibi::FIELD_FLOAT,'FLOAT'=>dibi::FIELD_FLOAT,'YESNO'=>dibi::FIELD_BOOL,);$count=odbc_num_fields($this->resource);$this->meta=$this->convert=array();for($index=1;$index<=$count;$index++){$native=strtoupper(odbc_field_type($this->resource,$index));$name=odbc_field_name($this->resource,$index);$this->meta[$name]=array('type'=>isset($types[$native])?$types[$native]:dibi::FIELD_UNKNOWN,'native'=>$native,'length'=>odbc_field_len($this->resource,$index),'scale'=>odbc_field_scale($this->resource,$index),'precision'=>odbc_field_precision($this->resource,$index),);$this->convert[$name]=$this->meta[$name]['type'];}}}
+ if(!defined('DIBI'))die();class DibiSqliteDriver extends DibiDriver{private$conn,$insertId=FALSE,$affectedRows=FALSE;public$formats=array('NULL'=>"NULL",'TRUE'=>"1",'FALSE'=>"0",'date'=>"'Y-m-d'",'datetime'=>"'Y-m-d H:i:s'",);public static function connect($config){if(!extension_loaded('sqlite'))return new DibiException("PHP extension 'sqlite' is not loaded");if(empty($config['database']))return new DibiException("Database must be specified");$errorMsg='';if(empty($config['persistent']))$conn=@sqlite_open($config['database'],@$config['mode'],$errorMsg);else$conn=@sqlite_popen($config['database'],@$config['mode'],$errorMsg);if(!$conn)return new DibiException("Connecting error",array('message'=>$errorMsg,));$obj=new self($config);$obj->conn=$conn;return$obj;}public function query($sql){$this->insertId=$this->affectedRows=FALSE;$errorMsg='';$res=@sqlite_query($this->conn,$sql,SQLITE_ASSOC,$errorMsg);if($res===FALSE)return new DibiException("Query error",array('message'=>$errorMsg,'sql'=>$sql,));if(is_resource($res))return new DibiSqliteResult($res);$this->affectedRows=sqlite_changes($this->conn);if($this->affectedRows<0)$this->affectedRows=FALSE;$this->insertId=sqlite_last_insert_rowid($this->conn);if($this->insertId<1)$this->insertId=FALSE;return TRUE;}public function affectedRows(){return$this->affectedRows;}public function insertId(){return$this->insertId;}public function begin(){return sqlite_query($this->conn,'BEGIN');}public function commit(){return sqlite_query($this->conn,'COMMIT');}public function rollback(){return sqlite_query($this->conn,'ROLLBACK');}public function escape($value,$appendQuotes=FALSE){return$appendQuotes?"'".sqlite_escape_string($value)."'":sqlite_escape_string($value);}public function quoteName($value){return$value;}public function getMetaData(){trigger_error('Meta is not implemented yet.',E_USER_WARNING);}}class DibiSqliteResult extends DibiResult{private$resource,$meta;public function __construct($resource){$this->resource=$resource;}public function rowCount(){return sqlite_num_rows($this->resource);}protected function doFetch(){return sqlite_fetch_array($this->resource,SQLITE_ASSOC);}public function seek($row){return sqlite_seek($this->resource,$row);}protected function free(){}public function getFields(){if($this->meta===NULL)$this->createMeta();return array_keys($this->meta);}protected function detectTypes(){if($this->meta===NULL)$this->createMeta();}public function getMetaData($field){if($this->meta===NULL)$this->createMeta();return isset($this->meta[$field])?$this->meta[$field]:FALSE;}private function createMeta(){$count=sqlite_num_fields($this->resource);$this->meta=$this->convert=array();for($index=0;$index<$count;$index++){$name=sqlite_field_name($this->resource,$index);$this->meta[$name]=array('type'=>dibi::FIELD_UNKNOWN);$this->convert[$name]=dibi::FIELD_UNKNOWN;}}}?>
\ No newline at end of file
diff --git a/dibi/dibi.php b/dibi/dibi.php
index 13d6040d..8b3a3348 100644
--- a/dibi/dibi.php
+++ b/dibi/dibi.php
@@ -67,6 +67,23 @@ interface IDibiVariable
*/
class dibi
{
+ /**
+ * Column type in relation to PHP native type
+ */
+ const
+ FIELD_TEXT = 's', // as 'string'
+ FIELD_BINARY = 'b',
+ FIELD_BOOL = 'l', // as 'logical'
+ FIELD_INTEGER = 'i',
+ FIELD_FLOAT = 'f',
+ FIELD_DATE = 'd',
+ FIELD_DATETIME = 't',
+ FIELD_UNKNOWN = '?',
+
+ // special
+ FIELD_COUNTER = 'c'; // counter or autoincrement, is integer
+
+
/**
* Connection registry storage for DibiDriver objects
* @var array
@@ -191,7 +208,7 @@ class dibi
*/
static public function getConnection($name = NULL)
{
- return $name === NULL
+ return NULL === $name
? self::$conn
: @self::$registry[$name];
}
diff --git a/dibi/drivers/mysql.php b/dibi/drivers/mysql.php
index 5bf66d8c..e5f2dabc 100644
--- a/dibi/drivers/mysql.php
+++ b/dibi/drivers/mysql.php
@@ -273,38 +273,38 @@ class DibiMySqlResult extends DibiResult
private function createMeta()
{
static $types = array(
- 'ENUM' => self::FIELD_TEXT, // eventually self::FIELD_INTEGER
- 'SET' => self::FIELD_TEXT, // eventually self::FIELD_INTEGER
- 'CHAR' => self::FIELD_TEXT,
- 'VARCHAR' => self::FIELD_TEXT,
- 'STRING' => self::FIELD_TEXT,
- 'TINYTEXT' => self::FIELD_TEXT,
- 'TEXT' => self::FIELD_TEXT,
- 'MEDIUMTEXT'=> self::FIELD_TEXT,
- 'LONGTEXT' => self::FIELD_TEXT,
- 'BINARY' => self::FIELD_BINARY,
- 'VARBINARY' => self::FIELD_BINARY,
- 'TINYBLOB' => self::FIELD_BINARY,
- 'BLOB' => self::FIELD_BINARY,
- 'MEDIUMBLOB'=> self::FIELD_BINARY,
- 'LONGBLOB' => self::FIELD_BINARY,
- 'DATE' => self::FIELD_DATE,
- 'DATETIME' => self::FIELD_DATETIME,
- 'TIMESTAMP' => self::FIELD_DATETIME,
- 'TIME' => self::FIELD_DATETIME,
- 'BIT' => self::FIELD_BOOL,
- 'YEAR' => self::FIELD_INTEGER,
- 'TINYINT' => self::FIELD_INTEGER,
- 'SMALLINT' => self::FIELD_INTEGER,
- 'MEDIUMINT' => self::FIELD_INTEGER,
- 'INT' => self::FIELD_INTEGER,
- 'INTEGER' => self::FIELD_INTEGER,
- 'BIGINT' => self::FIELD_INTEGER,
- 'FLOAT' => self::FIELD_FLOAT,
- 'DOUBLE' => self::FIELD_FLOAT,
- 'REAL' => self::FIELD_FLOAT,
- 'DECIMAL' => self::FIELD_FLOAT,
- 'NUMERIC' => self::FIELD_FLOAT,
+ 'ENUM' => dibi::FIELD_TEXT, // eventually dibi::FIELD_INTEGER
+ 'SET' => dibi::FIELD_TEXT, // eventually dibi::FIELD_INTEGER
+ 'CHAR' => dibi::FIELD_TEXT,
+ 'VARCHAR' => dibi::FIELD_TEXT,
+ 'STRING' => dibi::FIELD_TEXT,
+ 'TINYTEXT' => dibi::FIELD_TEXT,
+ 'TEXT' => dibi::FIELD_TEXT,
+ 'MEDIUMTEXT'=> dibi::FIELD_TEXT,
+ 'LONGTEXT' => dibi::FIELD_TEXT,
+ 'BINARY' => dibi::FIELD_BINARY,
+ 'VARBINARY' => dibi::FIELD_BINARY,
+ 'TINYBLOB' => dibi::FIELD_BINARY,
+ 'BLOB' => dibi::FIELD_BINARY,
+ 'MEDIUMBLOB'=> dibi::FIELD_BINARY,
+ 'LONGBLOB' => dibi::FIELD_BINARY,
+ 'DATE' => dibi::FIELD_DATE,
+ 'DATETIME' => dibi::FIELD_DATETIME,
+ 'TIMESTAMP' => dibi::FIELD_DATETIME,
+ 'TIME' => dibi::FIELD_DATETIME,
+ 'BIT' => dibi::FIELD_BOOL,
+ 'YEAR' => dibi::FIELD_INTEGER,
+ 'TINYINT' => dibi::FIELD_INTEGER,
+ 'SMALLINT' => dibi::FIELD_INTEGER,
+ 'MEDIUMINT' => dibi::FIELD_INTEGER,
+ 'INT' => dibi::FIELD_INTEGER,
+ 'INTEGER' => dibi::FIELD_INTEGER,
+ 'BIGINT' => dibi::FIELD_INTEGER,
+ 'FLOAT' => dibi::FIELD_FLOAT,
+ 'DOUBLE' => dibi::FIELD_FLOAT,
+ 'REAL' => dibi::FIELD_FLOAT,
+ 'DECIMAL' => dibi::FIELD_FLOAT,
+ 'NUMERIC' => dibi::FIELD_FLOAT,
);
$count = mysql_num_fields($this->resource);
@@ -317,12 +317,12 @@ class DibiMySqlResult extends DibiResult
$info['table'] = mysql_field_table($this->resource, $index);
if (in_array('auto_increment', $info['flags'])) // or 'primary_key' ?
- $info['type'] = self::FIELD_COUNTER;
+ $info['type'] = dibi::FIELD_COUNTER;
else {
- $info['type'] = isset($types[$native]) ? $types[$native] : self::FIELD_UNKNOWN;
+ $info['type'] = isset($types[$native]) ? $types[$native] : dibi::FIELD_UNKNOWN;
-// if ($info['type'] == self::FIELD_TEXT && $info['length'] > 255)
-// $info['type'] = self::FIELD_LONG_TEXT;
+// if ($info['type'] == dibi::FIELD_TEXT && $info['length'] > 255)
+// $info['type'] = dibi::FIELD_LONG_TEXT;
}
$name = mysql_field_name($this->resource, $index);
diff --git a/dibi/drivers/mysqli.php b/dibi/drivers/mysqli.php
index feaa22c1..54ab590c 100644
--- a/dibi/drivers/mysqli.php
+++ b/dibi/drivers/mysqli.php
@@ -233,31 +233,31 @@ class DibiMySqliResult extends DibiResult
private function createMeta()
{
static $types = array(
- MYSQLI_TYPE_FLOAT => self::FIELD_FLOAT,
- MYSQLI_TYPE_DOUBLE => self::FIELD_FLOAT,
- MYSQLI_TYPE_DECIMAL => self::FIELD_FLOAT,
- // MYSQLI_TYPE_NEWDECIMAL=> self::FIELD_FLOAT,
- // MYSQLI_TYPE_BIT => self::FIELD_INTEGER,
- MYSQLI_TYPE_TINY => self::FIELD_INTEGER,
- MYSQLI_TYPE_SHORT => self::FIELD_INTEGER,
- MYSQLI_TYPE_LONG => self::FIELD_INTEGER,
- MYSQLI_TYPE_LONGLONG => self::FIELD_INTEGER,
- MYSQLI_TYPE_INT24 => self::FIELD_INTEGER,
- MYSQLI_TYPE_YEAR => self::FIELD_INTEGER,
- MYSQLI_TYPE_GEOMETRY => self::FIELD_INTEGER,
- MYSQLI_TYPE_DATE => self::FIELD_DATE,
- MYSQLI_TYPE_NEWDATE => self::FIELD_DATE,
- MYSQLI_TYPE_TIMESTAMP => self::FIELD_DATETIME,
- MYSQLI_TYPE_TIME => self::FIELD_DATETIME,
- MYSQLI_TYPE_DATETIME => self::FIELD_DATETIME,
- MYSQLI_TYPE_ENUM => self::FIELD_TEXT, // eventually self::FIELD_INTEGER
- MYSQLI_TYPE_SET => self::FIELD_TEXT, // eventually self::FIELD_INTEGER
- MYSQLI_TYPE_STRING => self::FIELD_TEXT,
- MYSQLI_TYPE_VAR_STRING=> self::FIELD_TEXT,
- MYSQLI_TYPE_TINY_BLOB => self::FIELD_BINARY,
- MYSQLI_TYPE_MEDIUM_BLOB=> self::FIELD_BINARY,
- MYSQLI_TYPE_LONG_BLOB => self::FIELD_BINARY,
- MYSQLI_TYPE_BLOB => self::FIELD_BINARY,
+ MYSQLI_TYPE_FLOAT => dibi::FIELD_FLOAT,
+ MYSQLI_TYPE_DOUBLE => dibi::FIELD_FLOAT,
+ MYSQLI_TYPE_DECIMAL => dibi::FIELD_FLOAT,
+ // MYSQLI_TYPE_NEWDECIMAL=> dibi::FIELD_FLOAT,
+ // MYSQLI_TYPE_BIT => dibi::FIELD_INTEGER,
+ MYSQLI_TYPE_TINY => dibi::FIELD_INTEGER,
+ MYSQLI_TYPE_SHORT => dibi::FIELD_INTEGER,
+ MYSQLI_TYPE_LONG => dibi::FIELD_INTEGER,
+ MYSQLI_TYPE_LONGLONG => dibi::FIELD_INTEGER,
+ MYSQLI_TYPE_INT24 => dibi::FIELD_INTEGER,
+ MYSQLI_TYPE_YEAR => dibi::FIELD_INTEGER,
+ MYSQLI_TYPE_GEOMETRY => dibi::FIELD_INTEGER,
+ MYSQLI_TYPE_DATE => dibi::FIELD_DATE,
+ MYSQLI_TYPE_NEWDATE => dibi::FIELD_DATE,
+ MYSQLI_TYPE_TIMESTAMP => dibi::FIELD_DATETIME,
+ MYSQLI_TYPE_TIME => dibi::FIELD_DATETIME,
+ MYSQLI_TYPE_DATETIME => dibi::FIELD_DATETIME,
+ MYSQLI_TYPE_ENUM => dibi::FIELD_TEXT, // eventually dibi::FIELD_INTEGER
+ MYSQLI_TYPE_SET => dibi::FIELD_TEXT, // eventually dibi::FIELD_INTEGER
+ MYSQLI_TYPE_STRING => dibi::FIELD_TEXT,
+ MYSQLI_TYPE_VAR_STRING=> dibi::FIELD_TEXT,
+ MYSQLI_TYPE_TINY_BLOB => dibi::FIELD_BINARY,
+ MYSQLI_TYPE_MEDIUM_BLOB=> dibi::FIELD_BINARY,
+ MYSQLI_TYPE_LONG_BLOB => dibi::FIELD_BINARY,
+ MYSQLI_TYPE_BLOB => dibi::FIELD_BINARY,
);
$count = mysqli_num_fields($this->resource);
@@ -267,11 +267,11 @@ class DibiMySqliResult extends DibiResult
$native = $info['native'] = $info['type'];
if ($info['flags'] & MYSQLI_AUTO_INCREMENT_FLAG) // or 'primary_key' ?
- $info['type'] = self::FIELD_COUNTER;
+ $info['type'] = dibi::FIELD_COUNTER;
else {
- $info['type'] = isset($types[$native]) ? $types[$native] : self::FIELD_UNKNOWN;
-// if ($info['type'] == self::FIELD_TEXT && $info['length'] > 255)
-// $info['type'] = self::FIELD_LONG_TEXT;
+ $info['type'] = isset($types[$native]) ? $types[$native] : dibi::FIELD_UNKNOWN;
+// if ($info['type'] == dibi::FIELD_TEXT && $info['length'] > 255)
+// $info['type'] = dibi::FIELD_LONG_TEXT;
}
$this->meta[$info['name']] = $info;
diff --git a/dibi/drivers/odbc.php b/dibi/drivers/odbc.php
index 96962f15..849503e9 100644
--- a/dibi/drivers/odbc.php
+++ b/dibi/drivers/odbc.php
@@ -230,28 +230,28 @@ class DibiOdbcResult extends DibiResult
return $this->meta;
static $types = array(
- 'CHAR' => self::FIELD_TEXT,
- 'COUNTER' => self::FIELD_COUNTER,
- 'VARCHAR' => self::FIELD_TEXT,
- 'LONGCHAR' => self::FIELD_TEXT,
- 'INTEGER' => self::FIELD_INTEGER,
- 'DATETIME' => self::FIELD_DATETIME,
- 'CURRENCY' => self::FIELD_FLOAT,
- 'BIT' => self::FIELD_BOOL,
- 'LONGBINARY'=> self::FIELD_BINARY,
- 'SMALLINT' => self::FIELD_INTEGER,
- 'BYTE' => self::FIELD_INTEGER,
- 'BIGINT' => self::FIELD_INTEGER,
- 'INT' => self::FIELD_INTEGER,
- 'TINYINT' => self::FIELD_INTEGER,
- 'REAL' => self::FIELD_FLOAT,
- 'DOUBLE' => self::FIELD_FLOAT,
- 'DECIMAL' => self::FIELD_FLOAT,
- 'NUMERIC' => self::FIELD_FLOAT,
- 'MONEY' => self::FIELD_FLOAT,
- 'SMALLMONEY'=> self::FIELD_FLOAT,
- 'FLOAT' => self::FIELD_FLOAT,
- 'YESNO' => self::FIELD_BOOL,
+ 'CHAR' => dibi::FIELD_TEXT,
+ 'COUNTER' => dibi::FIELD_COUNTER,
+ 'VARCHAR' => dibi::FIELD_TEXT,
+ 'LONGCHAR' => dibi::FIELD_TEXT,
+ 'INTEGER' => dibi::FIELD_INTEGER,
+ 'DATETIME' => dibi::FIELD_DATETIME,
+ 'CURRENCY' => dibi::FIELD_FLOAT,
+ 'BIT' => dibi::FIELD_BOOL,
+ 'LONGBINARY'=> dibi::FIELD_BINARY,
+ 'SMALLINT' => dibi::FIELD_INTEGER,
+ 'BYTE' => dibi::FIELD_INTEGER,
+ 'BIGINT' => dibi::FIELD_INTEGER,
+ 'INT' => dibi::FIELD_INTEGER,
+ 'TINYINT' => dibi::FIELD_INTEGER,
+ 'REAL' => dibi::FIELD_FLOAT,
+ 'DOUBLE' => dibi::FIELD_FLOAT,
+ 'DECIMAL' => dibi::FIELD_FLOAT,
+ 'NUMERIC' => dibi::FIELD_FLOAT,
+ 'MONEY' => dibi::FIELD_FLOAT,
+ 'SMALLMONEY'=> dibi::FIELD_FLOAT,
+ 'FLOAT' => dibi::FIELD_FLOAT,
+ 'YESNO' => dibi::FIELD_BOOL,
// and many others?
);
@@ -261,7 +261,7 @@ class DibiOdbcResult extends DibiResult
$native = strtoupper(odbc_field_type($this->resource, $index));
$name = odbc_field_name($this->resource, $index);
$this->meta[$name] = array(
- 'type' => isset($types[$native]) ? $types[$native] : self::FIELD_UNKNOWN,
+ 'type' => isset($types[$native]) ? $types[$native] : dibi::FIELD_UNKNOWN,
'native' => $native,
'length' => odbc_field_len($this->resource, $index),
'scale' => odbc_field_scale($this->resource, $index),
diff --git a/dibi/drivers/sqlite.php b/dibi/drivers/sqlite.php
index 0a13f218..c23ddd82 100644
--- a/dibi/drivers/sqlite.php
+++ b/dibi/drivers/sqlite.php
@@ -226,8 +226,8 @@ class DibiSqliteResult extends DibiResult
$this->meta = $this->convert = array();
for ($index = 0; $index < $count; $index++) {
$name = sqlite_field_name($this->resource, $index);
- $this->meta[$name] = array('type' => self::FIELD_UNKNOWN);
- $this->convert[$name] = self::FIELD_UNKNOWN;
+ $this->meta[$name] = array('type' => dibi::FIELD_UNKNOWN);
+ $this->convert[$name] = dibi::FIELD_UNKNOWN;
}
}
diff --git a/dibi/libs/parser.php b/dibi/libs/parser.php
index e5bc3c0b..72229198 100644
--- a/dibi/libs/parser.php
+++ b/dibi/libs/parser.php
@@ -57,9 +57,9 @@ class DibiParser
// iterate
$sql = array();
foreach ($args as $arg)
- {
- // %if was opened
- if ($mod == 'if') {
+ {
+ // %if was opened
+ if ('if' == $mod) {
$mod = FALSE;
$this->ifLevel++;
if (!$comment && !$arg) {
@@ -72,17 +72,19 @@ class DibiParser
}
// simple string means SQL
- if (is_string($arg) && !$mod) {
- $sql[] = $this->formatValue($arg, 'p'); // preserve it
+ if (is_string($arg) && (!$mod || 'p'==$mod)) {
+ $mod = FALSE;
+ // will generate new mod
+ $sql[] = $this->formatValue($arg, 'p');
continue;
}
- // array without modifier - autoselect between SET or VALUES
- if (is_array($arg) && !$mod && is_string(key($arg))) {
+ // associative array without modifier - autoselect between SET or VALUES
+ if (!$mod && is_array($arg) && is_string(key($arg))) {
if (!$command)
$command = strtoupper(substr(ltrim($args[0]), 0, 6));
- $mod = ($command == 'INSERT' || $command == 'REPLAC') ? 'V' : 'S';
+ $mod = ('INSERT' == $command || 'REPLAC' == $command) ? 'V' : 'S';
}
// default processing
@@ -116,20 +118,44 @@ class DibiParser
switch ($modifier) {
case 'S': // SET
foreach ($value as $k => $v) {
- list($k, $mod) = explode('%', $k.'%', 3); // split modifier
- $vx[] = $this->driver->quoteName($k) . '=' . $this->formatValue($v, $mod);
+ // split into identifier & modifier
+ $pair = explode('%', $k, 2);
+
+ if (isset($pair[1])) {
+ $mod = $pair[1];
+ // %? skips NULLS
+ if (isset($mod[0]) && '?' == $mod[0]) {
+ if (NULL === $v) continue;
+ $mod = substr($mod, 1);
+ }
+ } else $mod = FALSE;
+
+ // generate array
+ $vx[] = $this->driver->quoteName($pair[0]) . '=' . $this->formatValue($v, $mod);
}
-
return implode(', ', $vx);
+
case 'V': // VALUES
foreach ($value as $k => $v) {
- list($k, $mod) = explode('%', $k.'%', 3); // split modifier
- $kx[] = $this->driver->quoteName($k);
+ // split into identifier & modifier
+ $pair = explode('%', $k, 2);
+
+ if (isset($pair[1])) {
+ $mod = $pair[1];
+ // %m? skips NULLS
+ if (isset($mod[0]) && '?' == $mod[0]) {
+ if ($v === NULL) continue;
+ $mod = substr($mod, 1);
+ }
+ } else $mod = FALSE;
+
+ // generate arrays
+ $kx[] = $this->driver->quoteName($pair[0]);
$vx[] = $this->formatValue($v, $mod);
}
-
return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')';
+
default: // LIST
foreach ($value as $v)
@@ -154,7 +180,9 @@ class DibiParser
case "s": // string
return $this->driver->escape($value, TRUE);
case 'b': // boolean
- return $value ? $this->driver->formats['TRUE'] : $this->driver->formats['FALSE'];
+ return $value
+ ? $this->driver->formats['TRUE']
+ : $this->driver->formats['FALSE'];
case 'i':
case 'u': // unsigned int
case 'd': // signed int
@@ -162,9 +190,14 @@ class DibiParser
case 'f': // float
return (string) (float) $value; // something like -9E-005 is accepted by SQL
case 'D': // date
- return date($this->driver->formats['date'], is_string($value) ? strtotime($value) : $value);
+ return date($this->driver->formats['date'], is_string($value)
+ ? strtotime($value)
+ : $value);
+ case 't': // datetime
case 'T': // datetime
- return date($this->driver->formats['datetime'], is_string($value) ? strtotime($value) : $value);
+ return date($this->driver->formats['datetime'], is_string($value)
+ ? strtotime($value)
+ : $value);
case 'n': // identifier name
return $this->driver->quoteName($value);
case 'p': // preserve as SQL
@@ -173,7 +206,7 @@ class DibiParser
// speed-up - is regexp required?
$toSkip = strcspn($value, '`[\'"%');
- if ($toSkip == strlen($value)) // needn't be translated
+ if (strlen($value) == $toSkip) // needn't be translated
return $value;
// note: only this can change $this->modifier
@@ -245,8 +278,8 @@ class DibiParser
// [4] => string
// [5] => "
// [6] => string
- // [7] => right modifier
- // [8] => %else | %end
+ // [7] => %else | %end
+ // [8] => right modifier
// [9] => lone-quote
if ($matches[1]) // SQL identifiers: `ident`
@@ -271,7 +304,7 @@ class DibiParser
return "**Unexpected condition $matches[8]**";
}
- if ($matches[7] == 'end') {
+ if ('end' == $matches[7]) {
$this->ifLevel--;
if ($this->ifLevelStart == $this->ifLevel + 1) {
// close comment
diff --git a/dibi/libs/resultset.php b/dibi/libs/resultset.php
index 19825853..57720445 100644
--- a/dibi/libs/resultset.php
+++ b/dibi/libs/resultset.php
@@ -45,23 +45,6 @@ if (!interface_exists('Countable', false)) {
*/
abstract class DibiResult implements IteratorAggregate, Countable
{
- /**
- * Column type in relation to PHP native type
- */
- const
- FIELD_TEXT = 's', // as 'string'
- FIELD_BINARY = 'b',
- FIELD_BOOL = 'l', // as 'logical'
- FIELD_INTEGER = 'i',
- FIELD_FLOAT = 'f',
- FIELD_DATE = 'd',
- FIELD_DATETIME = 't',
- FIELD_UNKNOWN = '?',
-
- // special
- FIELD_COUNTER = 'c'; // counter or autoincrement, is integer
-
-
/**
* Describes columns types
* @var array
@@ -270,12 +253,12 @@ abstract class DibiResult implements IteratorAggregate, Countable
return $value;
static $conv = array(
- self::FIELD_TEXT => 'string',
- self::FIELD_BINARY => 'string',
- self::FIELD_BOOL => 'bool',
- self::FIELD_INTEGER => 'int',
- self::FIELD_FLOAT => 'float',
- self::FIELD_COUNTER => 'int',
+ dibi::FIELD_TEXT => 'string',
+ dibi::FIELD_BINARY => 'string',
+ dibi::FIELD_BOOL => 'bool',
+ dibi::FIELD_INTEGER => 'int',
+ dibi::FIELD_FLOAT => 'float',
+ dibi::FIELD_COUNTER => 'int',
);
if (isset($conv[$type])) {
@@ -283,10 +266,10 @@ abstract class DibiResult implements IteratorAggregate, Countable
return $value;
}
- if ($type == self::FIELD_DATE)
+ if ($type == dibi::FIELD_DATE)
return strtotime($value); // !!! not good
- if ($type == self::FIELD_DATETIME)
+ if ($type == dibi::FIELD_DATETIME)
return strtotime($value); // !!! not good
return $value;
diff --git a/examples/metatypes.php b/examples/metatypes.php
index a1e602ca..eba646ac 100644
--- a/examples/metatypes.php
+++ b/examples/metatypes.php
@@ -21,7 +21,7 @@ if (is_error($res))
// auto-convert this field to integer
-$res->setType('inumber', DibiResult::FIELD_INTEGER);
+$res->setType('inumber', Dibi::FIELD_INTEGER);
$record = $res->fetch();
var_dump($record);
diff --git a/examples/sql-builder.php b/examples/sql-builder.php
index 74d6e7fb..c1961470 100644
--- a/examples/sql-builder.php
+++ b/examples/sql-builder.php
@@ -26,10 +26,11 @@ $arr3 = array(
'col3' => 'three',
);
$arr4 = array(
- 'a' => 12,
- 'b' => NULL,
- 'c%T' => time(), // modifier 'T' means datetime
- 'd' => 'any string',
+ 'a' => 12,
+ 'b' => NULL,
+ 'c%?' => NULL,
+ 'd%T' => time(), // modifier 'T' means datetime
+ 'e' => 'any string',
);
$arr5 = array('RAND()', '[col1] > [col2]');