Location: PHPKode > projects > AModules3 > amodules-3.0.1/lib/DBlite/dsql.php
<?

if (!defined('DTP')) define('DTP','');

class DBlite_dsql  {
    var $db;

    var $my=array(null,null);
    var $saved=array(null,null);
    /*
     * Array containing arguments
     */
    var $args;
    var $debug;

    function __call($function,$args){
        /*
         * This call wrapper implements the following function:
         * do_select, do_insert, do_etc
         */
        if(substr($function,0,3)=='do_'){
            // do_select, do_insert combine functionality of generating insert/select and executing it
            $fnname = substr($function,3);
            $query = call_user_func_array(array($this,$fnname),$args);
            if(substr($function,3,3)=='get'){
                // we need those values saved, before we run our query
                $this->db->fatal("I do not know how to handle this function call :((((");
            }
            return $this->query($query);
        }
        if(substr($function,0,3)=='get'){
            $tmp=array($this->db->cursor,$this->db->found_rows);
            $this->db->cursor=$this->cursor;
            $this->db->found_rows=$this->found_rows;
            $result = call_user_func_array(array($this->db,$function),$args);
            list($this->db->cursor,$this->db->found_rows)=$tmp;
            return $result;
        }
        return $this->db->fatal("Call to undefined DQ::$function");
    }

    function fatal($msg,$lev=null){
        $this->db->fatal($msg,$lev+4);
    }

    function foundRows(){
        return $this->my[1];
    }
    ////// Speed-access functions 
    function s(){
        /*
         * We are willing to preserve existing state of associated database.
         * That's why we save some of it's data in a local valiable, and
         * restore those after execution.
         */
        $this->saved=array($this->db->cursor,$this->db->found_rows,$this->db->calc_found_rows);
        list($this->db->cursor,$this->db->found_rows,$this->db->calc_found_rows) = $this->my;
    }
    function l($a=null){
        $this->my=array($this->db->cursor,$this->db->found_rows,$this->db->calc_found_rows);
        list($this->db->cursor,$this->db->found_rows,$this->db->calc_found_rows) = $this->saved;
        return $a;
    }
    function do_getHash($f=null){ 
        $this->s(); 
        return $this->l($this->db->getHash($this->select(),$f)); 
    }
    function do_getAll($f=null){ 
        $this->s(); 
        return $this->l($this->db->getAll($this->select(),$f)); 
    }
    function do_getAllHash($f=null){ 
        $this->s(); 
        return $this->l($this->db->getAllHash($this->select(),$f)); 
    }
    function do_getRow($f=null){ 
        $this->s(); 
        return $this->l($this->db->getRow($this->select(),$f)); 
    }
    function do_getOne(){ 
        $this->s(); 
        return $this->l($this->db->getOne($this->select())); 
    }
    function do_getAssoc(){ 
        $this->s(); 
        return $this->l($this->db->getAssoc($this->select())); 
    }
    function do_select(){ 
        $this->s(); 
        $r=$this->db->query($this->select());
        return $this->l($this);
    }
    /*
     * temporary disabled, those do not work as they should
    function do_select(){ return $this->query($this->select()); }
    function do_delete(){ return $this->query($this->select()); }
    */
    function do_insert(){ $this->__call('do_insert',array()); return $this->db->lastID(); }
    function do_replace(){ $this->__call('do_replace',array()); return $this->db->lastID(); }
    //function do_select(){ $this->__call('do_select',array()); return $this; }
    function query($str){
        $this->s();
        return $this->l($this->db->query($str));
    }
    function do_fetchRow($l=null){ 
        $this->s(); 
        return $this->l($this->db->fetchRow($l)); 
    }
    function do_fetchHash($l=null){ 
        $this->s(); 
        return $this->l($this->db->fetchHash($l)); 
    }

    function debug(){
        $this->debug=1;
        return $this;
    }
    /*
    function query($q,$param1=null){
        $this->db->query($q,$param1);
        $this->cursor=$this->db->cursor;
        $this->found_rows=$this->db->found_rows;
    }
    */

    ///////////////////// Dynamic SQL functions ////////////////
    function table($table){
        /*
         * Specify table for a query
         */
        $this->args['table']=DTP.$table;
        return $this;
    }
    function field($field,$table=null) {
        /*
         * Add new field to a query
         */
        if(isset($table)){
            $field=DTP.$table.'.'.$field;
        }
        if(is_array($field)){
            $this->args['fields']=safe_array_merge($this->args['fields'],$field);
        }else{
            $this->args['fields'][]=$field;
        }
        return $this;
    }
    function set($set,$val=array()) {
        /*
         * Set value for update. You can use this function in a several ways. First
         * of all you can just simply call:
         *  $this->set($field, $value);
         * which will result update of the field in a next query. 2nd form is
         * when you call
         *  $this->set($hash);
         * in which case all keys of hash will be set to apropritate values.
         *
         * Value will be quoted, if you want to avoid that - use one-argument form.
         *
         * You can use this with array too like:
         *  set(array(
         *   'a'=>'213',
         *   'b'=>'foobar',
         *   'password=password("foo")'     // one-argument way
         *   ));
         */
        if(is_array($set)){
            foreach($set as $_key=>$_val){
                if(is_numeric($_key)){
                    $this->set($_val);
                }elseif(is_null($_val)){
                    continue;
                }else{
                    $this->set($_key,$_val);
                }
            }
        }else{
            if($val===array()){
                if($set===null)return $this;
                // if 1 argument is specified and is not array, then use it
                // as-is
                $this->args['set'][]=$set;
            }elseif(is_null($val)){
                $this->args['set'][$set]="NULL";
            }else{
                $this->args['set'][$set]="'".addslashes($val)."'";
            }
        }
        return $this;
    }
    function setDate($field='ts',$value=null){
        if(is_null($value))$value=time();
        return $this->set($field,date('Y-m-d H:i:s',$value));
    }
    function where($where,$equals=false){
        if(!is_array($where)){
            if($equals!==false){
                if(is_null($equals)){
                    $where.=" is null";
                }else{
                    if(substr($where,-1,1)==' ')$where=substr($where,0,-1);
                    // let's see if there is a sign, so we don't put there anything
                    $c=substr($where,-1,1);
                    if($c=='<' || $c=='>' || $c=='='){
                        // no need to add sign, it's already there
                        $where.=" '".addslashes($equals)."'";
                    }elseif(substr($where,-5,5)==' like'){
                        $where.=" '".addslashes($equals)."'";
                    }else{
                        $where.=" = '".addslashes($equals)."'";
                    }
                }
            }
            $where = array($where);
        }
        $this->args['where'] = safe_array_merge($this->args['where'], $where);
        return $this;
    }
    function clear_args($arg_name){
    	unset($this->args[$arg_name]);
    	return $this;
    }
    function having($having,$equals=false){
        if(!is_array($having)){
            if($equals!==false){
                if(is_null($equals)){
                    $having.=" is null";
                }else{
                    if(substr($having,-1,1)==' ')$having=substr($having,0,-1);
                    // let's see if there is a sign, so we don't put there anything
                    $c=substr($having,-1,1);
                    if($c=='<' || $c=='>' || $c=='='){
                        // no need to add sign, it's already there
                        $having.=" '".addslashes($equals)."'";
                    }elseif(substr($having,-5,5)==' like'){
                        $having.=" '".addslashes($equals)."'";
                    }else{
                        $having.=" = '".addslashes($equals)."'";
                    }
                }
            }
            $having = array($having);
        }
        $this->args['having'] = safe_array_merge($this->args['having'], $having);
        return $this;
    }
    function join ($table,$on,$type='inner'){
        $this->args['join'][]="$type join ".DTP.$table." on $on";
        return $this;
    }
    function order($order,$desc=null,$prepend=null){
        if($desc)$order.=" desc";
        if($prepend){
            array_unshift($this->args['order'], $order);
        }else{
            $this->args['order'][]=$order;
        }
        return $this;
    }
    function limit($cnt,$shift=0){
        $this->args['limit']=array(
                'cnt'=>$cnt,
                'shift'=>$shift
                );
        return $this;
    }
    function group($group,$prepend=null) {
        /*
         * Set group
         */
        if($prepend){
            array_unshift($this->args['group'], $group);
        }else{
            $this->args['group'][]=$group;
        }
        return $this;
    }
    function select(){
        return $this->parseTemplate("select [options] [field] from [table] [join] [where] [group] [having] [order] [limit]");
    }
    function update(){
        return $this->parseTemplate("update [table] set [set] [where]");
    }
    function insert(){
        return $this->parseTemplate("insert [options] into [table] ([set_field]) values ([set_value])");
    }
    function replace(){
        return $this->parseTemplate("replace [options] into [table] ([set_field]) values ([set_value])");
    }
    function delete(){
        return $this->parseTemplate("delete from [table] [where]");
    }
    function getArgs($required){
        /*
         * This function generates actual value for the arguments, which
         * will be placed into template
         */
        if(isset($required['field'])) {
            // comma separated fields, such as for select
            $fields=array();
            if(!is_array($this->args['fields'])){
                $this->fatal('Before generating query you should call $dq->field() several times, otherwise I do not know what fields you need',2);
            }
            foreach($this->args['fields'] as $field) {
                $fields[]=$field;
            }
            $args['field']=join(', ', $fields);
        }
        if(isset($required['options'])&&$this->args['options']){
            $args['options']=join(' ',$this->args['options']);
        }

        if(isset($required['set'])) {
            $set = array();
            if(!$this->args['set']) {
                return $this->fatal('You should call $dq->set() before requesting update');
            }
            foreach($this->args['set'] as $key=>$val) {
                if(is_int($key)) {
                    $set[]="$val";
                }else{
                    $set[]="`$key`=$val";
                }
            }
            $args['set']=join(', ', $set);
        }

        if(isset($required['set_field']) || isset($required['set_value'])) {
            $sf = $sv = array();
            if(!$this->args['set']) {
                return $this->fatal('You should call $dq->set() before requesting update',2);
            }
            foreach($this->args['set'] as $key=>$val) {
                if(is_numeric($key)){
                    list($sf[],$sv[])=split('=',$val,2);
                    continue;
                }
                $sf[]="`$key`";
                $sv[]=$val;
            }
            $args['set_field']=join(', ', $sf);
            $args['set_value']=join(', ', $sv);
        }

        if(isset($required['table'])) {
            $args['table']=$this->args['table'];
        }

        if(isset($required['join'])) {
            if(isset($this->args['join'])) {
                $args['join']=join(' ', $this->args['join']);
            }
        }

        if(isset($required['where'])) {
            if($this->args['where']) {
                $args['where'] = "where (".join(') and (', $this->args['where']).")";
            }
        }

        if(isset($required['having'])) {
            if($this->args['having']) {
                $args['having'] = "having (".join(') and (', $this->args['having']).")";
            }
        }

        if(isset($required['order'])) {
            if($this->args['order']) {
                $args['order'] = "order by ".join(', ', $this->args['order']);
            }
        }

        if(isset($required['group'])) {
            if($this->args['group']) {
                $args['group'] = "group by ".join(',',$this->args['group']);
            }
        }

        if(isset($required['limit'])) {
            if($this->args['limit']) {
                $args['limit'] = "limit ".$this->args['limit']['shift'].", ".$this->args['limit']['cnt'];
            }
        }


        return $args;
    }
    function parseTemplate($template) {
        /*
         * When given query template, this method will get required arguments
         * for it and place them inside returning ready to use query.
         */
        $parts = split('\[', $template);
        $required = array();

        // 1st part is not a variable
        $result = array(array_shift($parts));
        foreach($parts as $part) {
            list($keyword, $rest)=split('\]', $part);
            $result[] = array($keyword); $required[$keyword]=true;
            $result[] = $rest;
        }
        // now parts array contains strings and array of string, let's request
        // for required arguments

        $args = $this->getArgs($required);

        // now when we know all data, let's assemble resulting string
        foreach($result as $key => $part) {
            if(is_array($part)) {
                $result[$key]=$args[$part[0]];
            }
        }
        if($this->debug){
            echo '<font color=blue>'.join('',$result).'</font>';
        }
        return join('', $result);
    }
    function calc_found_rows(){
        $this->option("SQL_CALC_FOUND_ROWS");
        $this->my[2]=true;
    }
    function option($option){
        if(!is_array($option))$option=array($option);
        $this->args['options']=safe_array_merge($this->args['options'],$option);
        return $this;
    }
}
if(!function_exists('safe_array_merge')){
    // array_merge gives us an error when one of arguments is null. This function
    // acts the same as array_merge, but without warnings
    function safe_array_merge($a,$b=null){
        if(is_null($a)){
            $a=$b;
            $b=null;
        }
        if(is_null($b))return $a;
        return array_merge($a,$b);
    }
}
Return current item: AModules3