diff --git a/dibi.compact/dibi.compact.php b/dibi.compact/dibi.compact.php
index f8f6940d..0a8ff342 100644
--- a/dibi.compact/dibi.compact.php
+++ b/dibi.compact/dibi.compact.php
@@ -13,21 +13,22 @@
* @license GNU GENERAL PUBLIC LICENSE
* @package dibi
* @category Database
- * @version 0.6 $Revision: 6 $ $Date: 2006-06-07 17:50:32 +0200 (st, 07 VI 2006) $
- */define('DIBI','Version 0.6 $Revision: 6 $');if(version_compare(PHP_VERSION,'5.0.3','<'))die('dibi needs PHP 5.0.3 or newer');
+ * @version 0.6 $Revision: 7 $ $Date: 2006-06-07 21:02:24 +0200 (st, 07 VI 2006) $
+ */define('DIBI','Version 0.6 $Revision: 7 $');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;public function parse($driver,$args){$this->driver=$driver;$mod=&$this->modifier;$mod=false;$this->hasError=false;$command=null;static$condKeys=array('if'=>1,'else'=>1,'end'=>1);$cond=true;$conds=array();$sql=array();$count=count($args);$i=-1;while(++$i<$count){$arg=$args[$i];if(is_string($arg)&&!$mod){$toSkip=strcspn($arg,'`[\'"%');if($toSkip!=strlen($arg))$arg=substr($arg,0,$toSkip).preg_replace_callback('/
+ 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();$count=count($args);$i=-1;while(++$i<$count){$arg=$args[$i];if(is_string($arg)&&!$mod){$toSkip=strcspn($arg,'`[\'"%');if($toSkip==strlen($arg)){$sql[]=$arg;}else{$sql[]=substr($arg,0,$toSkip).preg_replace_callback('/
(?=`|\[|\'|"|%) ## speed-up
(?:
`(.+?)`| ## 1) `identifier`
\[(.+?)\]| ## 2) [identifier]
(\')((?:\'\'|[^\'])*)\'| ## 3,4) string
(")((?:""|[^"])*)"| ## 5,6) "string"
- %([a-zA-Z]{1,4})$| ## 7) right modifier
- (\'|") ## 8) lone-quote
- )/xs',array($this,'callback'),substr($arg,$toSkip));if($cond)$sql[]=$arg;if(isset($condKeys[$mod])){switch($mod){case'if':$conds[]=$cond;$cond=(bool)$args[++$i];break;case'else':if($conds){$cond=!$cond;break;}case'end':if($conds){$cond=array_pop($conds);break;}$this->hasError=true;$sql[]="**Unexpected condition $mod**";}$mod=false;}continue;}if(!$cond)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[]=$this->formatValue($arg,$mod);$mod=false;}$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':return(string)$value;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->driver->escape(strtr($matches[4],array("''"=>"'")),true);if($matches[5])return$this->driver->escape(strtr($matches[6],array('""'=>'"')),true);if($matches[7]){$this->modifier=$matches[7];return'';}if($matches[8]){return'**Alone quote**';$this->hasError=true;}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 public function dump($sql){static$highlight=array('ALL','DISTINCT','AS','ON','INTO','AND','OR','AS',);static$newline=array('SELECT','UPDATE','INSERT','DELETE','FROM','WHERE','HAVING','GROUP BY','ORDER BY','LIMIT','SET','VALUES','LEFT JOIN','INNER JOIN',);foreach($newline as$word)$sql=preg_replace('#\b'.$word.'\b#',"\n\$0",$sql);$sql=trim($sql);$sql=wordwrap($sql,100);$sql=htmlSpecialChars($sql);$sql=strtr($sql,array("\n"=>'
'));foreach($newline as$word)$sql=preg_replace('#\b'.$word.'\b#','$0',$sql);foreach($highlight as$word)$sql=preg_replace('#\b'.$word.'\b#','$0',$sql);$sql=preg_replace('#\*\*.+?\*\*#','$0',$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'
';}}
+ %([a-zA-Z]{1,2})$| ## 7) right modifier
+ %(else|end)| ## 8) conditional SQL
+ (\'|") ## 9) lone-quote
+ )/xs',array($this,'callback'),substr($arg,$toSkip));if($mod=='if'){$mod=FALSE;$this->ifLevel++;if(!$args[++$i]&&!$comment){$sql[]='/*';$this->ifLevelStart=$this->ifLevel;$comment=TRUE;}}}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':return(string)$value;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]){$this->modifier=$matches[7];return'';}if($matches[8]){if(!$this->ifLevel){$this->hasError=TRUE;return"**Unexpected condition $mod**";}if($matches[8]=='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[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'];}}}
diff --git a/dibi/dibi.php b/dibi/dibi.php
index 0b30a08f..13d6040d 100644
--- a/dibi/dibi.php
+++ b/dibi/dibi.php
@@ -347,6 +347,22 @@ class dibi
+ static private function dumpHighlight($matches)
+ {
+ if (!empty($matches[1])) // comment
+ return ''.$matches[1].'';
+
+ if (!empty($matches[2])) // error
+ return ''.$matches[2].'';
+
+ if (!empty($matches[3])) // most important keywords
+ return ''.$matches[3].'';
+
+ if (!empty($matches[4])) // other keywords
+ return ''.$matches[4].'';
+ }
+
+
/**
* Prints out a syntax highlighted version of the SQL command
*
@@ -354,12 +370,11 @@ class dibi
* @return void
*/
static public function dump($sql) {
- static $highlight = array ('ALL', 'DISTINCT', 'AS', 'ON', 'INTO', 'AND', 'OR', 'AS', );
- static $newline = array ('SELECT', 'UPDATE', 'INSERT', 'DELETE', 'FROM', 'WHERE', 'HAVING', 'GROUP BY', 'ORDER BY', 'LIMIT', 'SET', 'VALUES', 'LEFT JOIN', 'INNER JOIN',);
+ 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';
// insert new lines
- foreach ($newline as $word)
- $sql = preg_replace('#\b'.$word.'\b#', "\n\$0", $sql);
+ $sql = preg_replace("#\\b(?:$keywords1)\\b#", "\n\$0", $sql);
$sql = trim($sql);
// reduce spaces
@@ -369,13 +384,8 @@ class dibi
$sql = htmlSpecialChars($sql);
$sql = strtr($sql, array("\n" => '
'));
- foreach ($newline as $word)
- $sql = preg_replace('#\b'.$word.'\b#', '$0', $sql);
-
- foreach ($highlight as $word)
- $sql = preg_replace('#\b'.$word.'\b#', '$0', $sql);
-
- $sql = preg_replace('#\*\*.+?\*\*#', '$0', $sql);
+ // syntax highlight
+ $sql = preg_replace_callback("#(/\*.+?\*/)|(\*\*.+?\*\*)|\\b($keywords1)\\b|\\b($keywords2)\\b#", array('dibi', 'dumpHighlight'), $sql);
echo '', $sql, '
';
}
diff --git a/dibi/libs/parser.php b/dibi/libs/parser.php
index d7aabb2f..f02e354a 100644
--- a/dibi/libs/parser.php
+++ b/dibi/libs/parser.php
@@ -30,7 +30,9 @@ class DibiParser
private
$modifier,
$hasError,
- $driver;
+ $driver,
+ $ifLevel,
+ $ifLevelStart;
/**
@@ -42,15 +44,15 @@ class DibiParser
public function parse($driver, $args)
{
$this->driver = $driver;
- $mod = & $this->modifier; // shortcut
- $mod = false;
- $this->hasError = false;
+ $this->hasError = FALSE;
$command = null;
+ $mod = & $this->modifier; // shortcut
+ $mod = FALSE;
// conditional sql
- static $condKeys = array('if'=>1, 'else'=>1, 'end'=>1);
- $cond = true;
- $conds = array();
+ $this->ifLevel = $this->ifLevelStart = 0;
+ $comment = & $this->comment;
+ $comment = FALSE;
// iterate
$sql = array();
@@ -65,8 +67,10 @@ class DibiParser
// speed-up - is regexp required?
$toSkip = strcspn($arg, '`[\'"%');
- if ($toSkip != strlen($arg)) // need be translated?
- $arg = substr($arg, 0, $toSkip)
+ if ($toSkip == strlen($arg)) { // need be translated?
+ $sql[] = $arg;
+ } else {
+ $sql[] = substr($arg, 0, $toSkip)
. preg_replace_callback('/
(?=`|\[|\'|"|%) ## speed-up
(?:
@@ -74,50 +78,29 @@ class DibiParser
\[(.+?)\]| ## 2) [identifier]
(\')((?:\'\'|[^\'])*)\'| ## 3,4) string
(")((?:""|[^"])*)"| ## 5,6) "string"
- %([a-zA-Z]{1,4})$| ## 7) right modifier
- (\'|") ## 8) lone-quote
+ %([a-zA-Z]{1,2})$| ## 7) right modifier
+ %(else|end)| ## 8) conditional SQL
+ (\'|") ## 9) lone-quote
)/xs',
array($this, 'callback'),
substr($arg, $toSkip)
);
-
- // add to SQL
- if ($cond) $sql[] = $arg;
-
- // conditional sequence
- if (isset($condKeys[$mod])) {
- switch ($mod) {
- case 'if':
- $conds[] = $cond;
- $cond = (bool) $args[++$i];
- break;
-
- case 'else':
- if ($conds) {
- $cond = !$cond;
- break;
- }
- // no break!
-
- case 'end':
- if ($conds) {
- $cond = array_pop($conds);
- break;
- }
-
- $this->hasError = true;
- $sql[] = "**Unexpected condition $mod**";
- } // switch
- $mod = false;
- } // if cond comments
-
+ if ($mod == 'if') {
+ $mod = FALSE;
+ $this->ifLevel++;
+ if (!$args[++$i] && !$comment) {
+ // open comment
+ $sql[] = '/*';
+ $this->ifLevelStart = $this->ifLevel;
+ $comment = TRUE;
+ }
+ }
+ } // if
+
continue;
}
-
- // conditional sql (!!! or not?)
- if (!$cond) continue;
-
+
// array processing without modifier - autoselect between SET or VALUES
if (is_array($arg) && !$mod && is_string(key($arg))) {
@@ -128,10 +111,14 @@ class DibiParser
}
// default processing
- $sql[] = $this->formatValue($arg, $mod);
- $mod = false;
+ $sql[] = $comment
+ ? '...'
+ : $this->formatValue($arg, $mod);
+ $mod = FALSE;
} // for
+ if ($comment) $sql[] = '*/';
+
$sql = implode(' ', $sql);
if ($this->hasError)
@@ -184,7 +171,7 @@ class DibiParser
return $value->toSql($this->driver, $modifier);
if (!is_scalar($value) && !is_null($value)) { // array is already processed
- $this->hasError = true;
+ $this->hasError = TRUE;
return '**Unexpected '.gettype($value).'**';
}
@@ -208,7 +195,7 @@ class DibiParser
case 'p': // preserve as SQL
return (string) $value;
default:
- $this->hasError = true;
+ $this->hasError = TRUE;
return "**Unknown modifier %$modifier**";
}
}
@@ -231,7 +218,7 @@ class DibiParser
if ($value instanceof IDibiVariable)
return $value->toSql($this->driver);
- $this->hasError = true;
+ $this->hasError = TRUE;
return '**Unexpected '.gettype($value).'**';
}
@@ -253,7 +240,8 @@ class DibiParser
// [5] => "
// [6] => string
// [7] => right modifier
- // [8] => lone-quote
+ // [8] => %else | %end
+ // [9] => lone-quote
if ($matches[1]) // SQL identifiers: `ident`
return $this->driver->quoteName($matches[1]);
@@ -262,19 +250,53 @@ class DibiParser
return $this->driver->quoteName($matches[2]);
if ($matches[3]) // SQL strings: '....'
- return $this->driver->escape( strtr($matches[4], array("''" => "'")), true);
+ return $this->comment
+ ? '...'
+ : $this->driver->escape( strtr($matches[4], array("''" => "'")), TRUE);
if ($matches[5]) // SQL strings: "..."
- return $this->driver->escape( strtr($matches[6], array('""' => '"')), true);
+ return $this->comment
+ ? '...'
+ : $this->driver->escape( strtr($matches[6], array('""' => '"')), TRUE);
if ($matches[7]) { // modifier
$this->modifier = $matches[7];
return '';
}
- if ($matches[8]) { // string quote
+ if ($matches[8]) { // %end | %else
+ if (!$this->ifLevel) {
+ $this->hasError = TRUE;
+ return "**Unexpected condition $mod**";
+ }
+
+ if ($matches[8] == 'end') {
+ $this->ifLevel--;
+ if ($this->ifLevelStart == $this->ifLevel + 1) {
+ // close comment
+ $this->ifLevelStart = 0;
+ $this->comment = FALSE;
+ return '*/';
+ }
+ return '';
+ }
+
+ // else
+ 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[9]) { // string quote
+ $this->hasError = TRUE;
return '**Alone quote**';
- $this->hasError = true;
}
die('this should be never executed');
diff --git a/examples/logging.php b/examples/logger.php
similarity index 89%
rename from examples/logging.php
rename to examples/logger.php
index 77aefe7a..df624f01 100644
--- a/examples/logging.php
+++ b/examples/logger.php
@@ -4,7 +4,7 @@
require_once '../dibi/dibi.php';
-// enable logging to this file
+// enable log to this file
dibi::$logfile = 'log.sql';
diff --git a/examples/sql-condition.php b/examples/sql-condition.php
index c2efd54a..a49be006 100644
--- a/examples/sql-condition.php
+++ b/examples/sql-condition.php
@@ -17,30 +17,24 @@ dibi::connect(array(
));
-$user = NULL;
-// or
-$user = 'Jesus';
+$cond1 = rand(0,2) < 1;
+$cond2 = rand(0,2) < 1;
+
+
+$user = $cond1 ? 'Davidek' : NULL;
dibi::test('
SELECT *
-FROM [test]
-WHERE %if', isset($user), 'user=%s', $user, '%end' // last end is optional
+FROM [table]
+%if', isset($user), 'WHERE [user]=%s', $user, '%end'
);
-$cond = rand(0,2) < 1;
-
+// last end is optional
dibi::test('
SELECT *
-FROM %if', $cond, '[one_table]', '%else', '[second_table]', '%end'
-);
-
-
-// shorter way
-dibi::test('
-SELECT *
-FROM %if', $cond, '[one_table] %else', '[second_table] %end'
+FROM %if', $cond1, '[one_table] %else [second_table]'
);
@@ -49,9 +43,9 @@ dibi::test('
SELECT *
FROM [test]
WHERE
- %if', isset($user), 'user=%s', $user, '
- %if', $cond, 'AND [admin]=1 %end', '
- AND [visible]=1 %end'
+ %if', isset($user), '[user]=%s', $user, '
+ %if', $cond2, 'AND [admin]=1 %end
+ %else LIMIT 10 %end'
);
?>