PHP的PostgreSQL數據庫訪問類

jopen 13年前發布 | 26K 次閱讀 PostgreSQL 數據庫服務器

<?php defined('SYSPATH') or die('No direct script access.');
/**

  • The generic DB access Class, Entry of all DB Access
  • Only PG is supported -- 201210 *
  • @author Anthony
  • 2010-2012 reserved */

class DB {

// Query types
const SELECT =  1;
const INSERT =  2;
const UPDATE =  3;
const DELETE =  4;
/**
 * True Value
 */
const T = 't';
/**
 * False Value
 */
const F = 'f';
/**
 * Null Value 
 */
const N = 'N/A'; //NULL Value


/**
 * Specilize the value;
 * 'f' as False, 't' as TRUE, 'N/A' as NULL value
 *
 * @param String $s, Orignal Value
 *
 * @return String, specilized value
 */
public static function specializeValue($s){
    if($s === self::N){
        return NULL;
    }

    if($s === self::T){
        return True;
    }

    if($s === self::F){
        return False;
    }
    return $s;
}



/**
 * Batch insert into table
 * @param String $table_name Table Name
 * @param Array $cols columns of table
 * @param Array $values, values array of data
 * @param String/Array $return_cols Return column[s], 'id' is return by default,Array for multi Column
 * @param String $db Instance name of DB Connection
 *
 * @return Resultset return result set of return_cols 
 */
public static function insert_batch($table_name,$cols,$values,$return_cols='id',$db='default'){
    $_sql = 'insert into '.self::quote_table($table_name,$db).'('.self::quote_column($cols,$db).') values ';
    $_vsql = array();
    foreach ($values as $value){
        $_vsql[] = '('.self::quote($value).')';
    }

    $_sql .= implode(',',$_vsql);

    $_sql .= ' returning '.self::quote_column($return_cols);

    return self::query(self::SELECT,$_sql)->execute($db)->as_array();
}

/**
 * Insert into table from Array Data, and return column[s], ID is return by default
 *
 * @param String $table_name Table Name
 * @param Array $data Array Data Of key value pairs.
 * @param String/Array $return_cols Return column[s], 'id' is return by default,Array for multi Column
 * @param String $db Instance name of DB Connection
 *
 * @return Boolean/Resultset  True if success without return column, False if failed, value of column[s] if return_cols presented.
 */
public static function insert_table($table_name,$data,$return_cols='id',$db='default'){
    if (!is_array($data)){
        return false;
    }

    if (is_null($return_cols)){
        $_sql = 'insert into '.self::quote_table($table_name,$db).'('.self::quote_column(array_keys($data),$db).') values ('.
            self::quote(array_values($data),$db).')';
        return self::query(self::INSERT,$_sql)->execute($db);
    }

    //Specialize value 
    $data = array_map('self::specializeValue',$data);

    if (is_string($return_cols)){
        $_sql = 'insert into '.self::quote_table($table_name,$db).'('.self::quote_column(array_keys($data),$db).') values ('.
            self::quote(array_values($data),$db).')'." returning ".$return_cols;

        $id = self::query(self::SELECT,$_sql)->execute($db)->get($return_cols);
        return $id;
    }else{
        if (is_array($return_cols)){
            $ids = implode(',',$return_cols);
            $_sql = 'insert into '.self::quote_table($table_name,$db).'('.self::quote_column(array_keys($data),$db).') values ('.
                self::quote(array_values($data),$db).')'." returning ".$ids;
            $r_ids = self::query(self::SELECT,$_sql)->execute($db)->current();
            return $r_ids;
        }
    }

    return false;
}


/**
 * Update Table data, and compare with reference data
 *
 * @param String $table_name Table Name
 * @param Integer $id ID of data
 * @param Array $data Array Data Of key value pairs.
 * @param Array $refdata Reference data 
 * @param String $id_name Column name of ID
 * @param String $db Instance name of DB Connection
 *
 * @return Integer Affected Rows,False if failed!
 */
public static function update_data($table_name,$id,$data,$refdata,$id_name='id',$db='default'){
    if (!is_array($data)){
        throw new exception('Data should be col=>val pairs array');
    }
    foreach($data as $k => $v){
        if(is_array($refdata)){
            if(isset($refdata[$k])){
                if($v == $refdata[$k]){
                    unset($data[$k]);
                }
            }
        }elseif(is_object($refdata)){
            if(isset($refdata->$k)){
                if($v == $refdata->$k){
                    unset($data[$k]);
                }
            }
        }else{
            throw new exception('refdata type error');
        }
    }   

    //Specialize value 
    $data = array_map('self::specializeValue',$data);

    if(count($data)>0){
        return self::update_table($table_name,$id,$data,'id',$db);
    }else{
        return 0;
    }
}

/**
 * Update table with data without checking the referenced Data
 *
 * @param String $table_name Table Name
 * @param Integer $id ID of data
 * @param Array $data Array Data Of key value pairs.
 * @param String $id_name Column name of ID
 * @param String $db Instance name of DB Connection
 *
 * @return Integer Affected Rows,False if failed!
 */
public static function update_table($table_name,$id,$data,$id_name='id',$db='default'){
    if (!is_array($data)){
        return false;
    }

    $_sql = 'update '.self::quote_table($table_name,$db).' set '.self::quote_assoicate($data,'=',',',$db).' where '.
        self::quote_column($id_name,$db).'='.self::quote($id,$db);
    return self::query(self::UPDATE,$_sql)->execute($db);
}

/**
 * quote key value pair of col => values
 *
 * @param Array $data, col=>value pairs
 * @param String $concat, default '='
 * @param String Delimiter, default ','
 * @param String Database instance
 *
 * @return String 
 */
public static function quote_assoicate($data,$concat='=',$delimiter=',',$db='default'){
    $_sql = '';
    $_sqlArray = array();
    foreach ($data as $k => $v){
        $_sqlArray[] = self::quote_column($k,$db).$concat.self::quote($v,$db);
    }

    $_sql = implode($delimiter,$_sqlArray);
    return $_sql;
}

/**
 * Quote cols
 *
 * @param String $value, The column[s] name
 * @param String $db, Database Instance Name
 */
public static function quote_column($value,$db='default'){
    if(!is_array($value)){
        return self::quote_identifier($value,$db);
    }else{ //quote_column array and implode
        $_qs = array();
        foreach ($value as $ele){
            $_qs[] = self::quote_column($ele,$db);
        }

        $_quote_column_String = implode(',',$_qs);
        return $_quote_column_String;
    }
}
/**
 * Quote the values to escape
 *
 * @param Scalar/Array  $value
 *
 * @return quote string or array
 */
public static function quote($value,$db='default'){
    if(!is_array($value)){
        return Database::instance($db)->quote($value);
    }else{ //Quote array and implode
        $_qs = array();
        foreach ($value as $ele){
            $_qs[] = self::quote($ele,$db);
        }

        $_quoteString = implode(',',$_qs);
        return $_quoteString;
    }
}

/**
 * Escape string of DB
 *
 * @param string $s table name
 * @param String $db Database instance name
 *
 * @return String
 */
public static function escape($s,$db='default'){
    return Database::instance($db)->escape($s);
}

/**
 * Quote Table name
 *
 * @param string $s table name
 * @param String $db Database instance name
 * 
 * @return String
 */
public static function quote_table($s,$db='default'){
    return Database::instance($db)->quote_table($s);
}

/**
 * Quote a database identifier, such as a column name. 
 *
 *     $column = DB::quote_identifier($column,'default');
 *
 * You can also use SQL methods within identifiers.
 *
 *     // The value of "column" will be quoted
 *     $column = DB::quote_identifier('COUNT("column")');
 *
 * Objects passed to this function will be converted to strings.
 * [Database_Query] objects will be compiled and converted to a sub-query.
 * All other objects will be converted using the '__toString' method.
 *
 * @param  mixed $value   any identifier
 * @param String $db, Database instance
 * @return  string
 */
public static function quote_identifier($value,$db='default'){
    return Database::instance($db)->quote_identifier($value);
}

/**
 * Get Connection for Database instance
 *
 * @param String $db Database Instance name
 *
 * @return Connection of Databse
 */
public static function getConnection($db = 'default'){
    return Database::instance($db)->getConnection();
}

/**
 * Get Children of current record 
 *
 * @param String $table Table name
 * @param Bollean $returnSql 
 * @param Integer $pid Parent Id of table record
 * @param String $idname ID column name 
 * @param String $pidname Parent ID column name
 * @param String $db Database Instance name
 *
 * @return Records of Children
 */

public static function getChildren($table,$returnSql = false ,$pid= '0',$idname='id',$pidname='pid' ,$db='default'){
    $_sql = 'select * from '.self::quote_table($table,$db).' where '.$pidname.'='.self::quote($pid,$db).
        " and $idname <>".self::quote($pid,$db); 
    if($returnSql){
        return $_sql;
    }

    $_res = self::query(self::SELECT,$_sql,true)->execute($db)->as_array();
    if($_res){
        return $_res;
    }else{
        return false;
    }
}

/**
 * Tree query for connect by,traverse all the child records of Data 
 *
 * @param String $tableName Tablename
 * @param Boolean  $returnSql Return SQL String if TURE
 * @param String $startWith Begin valueof traverse
 * @param String   $idCol ID Column name
 * @param String  $pidCol   Parent ID Column name
 * @param String $orderCol  Order Column  
 * @param Integer $maxDepth     Depth of traverse, 
 * @param Integer $level   Start Level 
 * @param String $delimiter     Delimiter of branch 
 * @param String $db  Database configuration instance
 *
 * @return Record/String  Return Record array or String of SQL 
 */
public static function getTree($tableName,$returnSql=false,$startWith='0',$idCol='id',$pidCol='pid', $orderCol='id', $maxDepth=0,$level = 0,$delimiter = ';',$db='default'){
    $_funcParas = array();
    $_funcParas[] = self::quote($tableName,$db); //Table|View 
    $_funcParas[] = self::quote($idCol,$db); //ID column
    $_funcParas[] = self::quote($pidCol,$db); //Parent ID Column
    $_funcParas[] = self::quote($orderCol,$db); //Default Order by ASC
    $_funcParas[] = self::quote($startWith,$db); //Begin ID
    $_funcParas[] = self::quote($maxDepth,$db); //Depth of traverse
    $_funcParas[] = self::quote($delimiter,$db); //Delimitor of Branch,default ';'

    $_sql = 'select * from connectby('
        .implode(',',$_funcParas).')'
        .' as t(id int, pid int, level int, branch text, pos int)';
    if($level > 0){
        $_sql .= ' where level >='.self::quote($level,$db);
    }

    if($returnSql) return $_sql;
    $_res = self::query(self::SELECT,$_sql,true)->execute($db)->as_array();
    if($_res){
        return $_res;
    }else{
        return false;
    }
}

/**
 * Start transaction
 *
 * @param String $db  Instance name of DB
 *
 * @return Result set
 */
public static function begin($db='default'){
    return DB::query(self::UPDATE, "BEGIN")->execute($db);
}

/**
 * Define Savepoint
 *
 * @param String $savepoint 
 *
 * @param String $db 
 */
public static function savepoint($savepoint, $db='default'){
    return DB::query(self::UPDATE, "SAVEPOINT ".$savepoint)->execute($db);
}

/**
 * Rollback to Savepoint
 *
 * @param String $savepoint 
 *
 * @param String $db Database Instance name 
 */

public static function rollpoint($savepoint, $db='default'){
    return DB::query(self::UPDATE, "ROLLBACK TO ".$savepoint)->execute($db);
}

/**
 * Commit an transaction
 * @param String DB connection
 */

public static function commit($db='default'){
    return DB::query(self::UPDATE, "COMMIT")->execute($db);
}

public static function rollback($db='default'){
    return DB::query(self::UPDATE, "ROLLBACK")->execute($db);
}


/**
 * Create a new [Database_Query] of the given type.
 *
 *     // Create a new SELECT query
 *     $query = DB::query(self::SELECT, 'SELECT * FROM users');
 *
 *     // Create a new DELETE query
 *     $query = DB::query(self::DELETE, 'DELETE FROM users WHERE id = 5');
 *
 * Specifying the type changes the returned result. When using
 * self::SELECT, a [Database_Query_Result] will be returned.
 * self::INSERT queries will return the insert id and number of rows.
 * For all other queries, the number of affected rows is returned.
 *
 * @param   integer  type: self::SELECT, self::UPDATE, etc
 * @param   string   SQL statement
 * @param   Boolean $as_object Return Result set as Object if true, default FALSE
 * @param   Array $params  Query parameters of SQL, default array()
 * @param   String $stmt_name The query is Prepared Statement if TRUE, 
 *          Execute Prepared Statement when $param is Not NULL
 *          Prepare Statement when $param is NULL
 *
 * @return  Database_Query
 */
public static function query($type, $sql = NULL ,$as_object = false,$params = array(),$stmt_name = NULL)
{
    return new Database_Query($type, $sql,$as_object,$params,$stmt_name);
}


/**
 * Gettting paginated page from Orignal SQL
 *
 * @param String $sql SQL query
 * @param UTL Object &$page UTL object of tempalte
 * @param String $orderBy Order by column, default 'updated desc'
 * @param String $dataPro Data Property Name, default 'data'
 * @param String $pagePro Pagnation Frament property Name, default 'pagination'
 * @param Array $config  Pagination Configuration Array overider
 * @param String $db Database Instance Name, default 'default'
 * @param Boolean $as_object Populate Data as Object if TRUE, default TRUE
 * @param String $_paginClass Class Name of pagination 
 * @return True if success
 */
public static function getPage($_sql,&$page,$orderBy ='updated desc', $dataPro='data',$pagePro = 'pagination',
    $config = NULL,$db = 'default',$as_object= true,$_paginClass='Pagination'){

        $_csql = 'select count(1) as c from ('.$_sql.') st'; 
        $_c  = DB::query(self::SELECT,$_csql)->execute($db)->get('c');

        if($config){
            $config['total_items'] = $_c;
            $_pagination = new $_paginClass($config);
        }else{
            $config = array();
            $config['total_items'] = $_c;
            $_pagination = new $_paginClass($config);
        }

        $_sql .= ' order by '.$orderBy;

        if($_pagination->offset){
            $_sql .= ' offset '.$_pagination->offset;
        }
        $_sql .= ' limit '.$_pagination->items_per_page;

        $_data = DB::query(self::SELECT,$_sql,$as_object)->execute($db)->as_array();
        if(!$_data){
            $page->{$dataPro} = false;
            $page->{$pagePro} = false;
            return false;   
        }

        $page->{$dataPro} = $_data;
        $page->{$pagePro} = $_pagination;
        return true;
    }

/**
 * Get All roles of subordinate
 *
 * @param Integer $role_id Integer User Role ID
 * @param Boolean $quote  Quote the SQL if ture, reutrn orignal SQL if false 
 * @param String $role_table Table of role hierarchy
 * @param Integer $level Start Level of tree traverse
 * @param String $db Database Instance name
 * @return SQL String
 */

public static function getRoleTreeSql($role_id,$quote = false,$role_table,$level=0,$db='default'){
    $_sql = 'select id from ('.self::getTree($role_table,true,$role_id,'id','pid','id',
        0, //Maxdepth
        $level, //Level
        ';',$db).') utree';
    if(!$quote) return $_sql;
    else return '('.$_sql.')';
}

/**
 * Getting SQL String to query Objects of subordinate and owned objects
 * Child User Role Tree[CURT]
 *
 * @param integer $role_id  Role ID of user
 * @param integer $user_id  User ID
 * @param String $role_table Table of Role 
 * @param Boolean $quote Quote the SQL if ture, reutrn orignal SQL if false
 * @param String $roleCol Role ID column name  
 * @param String $ownerCol Owner ID column name
 * @param String $db Database instance name
 * @return SQL String
 */
public static function getCURTreeSql($role_id,$user_id,$role_table,$quote = true,
    $roleCol='role_id',$ownerCol = 'owner_id' ,$db='default'){
        $_sql = ' '.$roleCol.' in '.self::getRoleTreeSql($role_id,true,$role_table,
            1, //Level start with 1
            $db). ' or '.$ownerCol.'='.self::quote($user_id,$db);
        if(!$quote) return $_sql;
        else return '('.$_sql.')';
    }


/**
 * Array from tree query to tree
 *
 * @param Array $eles , the record set from self::getTree
 * @param String $elename, element name of node
 * @param String $cldname, Child node name
 * @param String $delimiter, The delimiter of branch
 *
 * @return Object , Tree object of data
 */
public static function array2tree($eles,$elename,$cldname,$delimiter=';'){
    if($elename == $cldname){
        throw new Exception('Ele name equals cldname!');
    }
    $rtree = array();
    foreach ($eles as $ele){
        $_branch = $ele->branch;
        //Log::debug('branch='.$_branch);
        //The depth in the array
        $_depths = explode($delimiter,$_branch);
        if(count($_depths == 1)){
            $_root = $_depths[0];
        }
        $_cur = &$rtree;
        foreach ($_depths as $depth){
            //Create NODE
            if(!isset($_cur[$cldname])){
                $_cur[$cldname] = array();
            }

            if(!isset($_cur[$cldname][$depth])){
                $_cur[$cldname][$depth] = array();
                $_cur = &$_cur[$cldname][$depth];
            }else{
                $_cur = &$_cur[$cldname][$depth];
            }
        }
        $_cur[$elename] = $ele;
    }
    return $rtree[$cldname][$_root];
}

}</pre>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!