このコードは直接使用するためのものではなく、ツリー サブクエリ、プリペアド ステートメント、バッチ挿入など、PG のさまざまな機能のさまざまなサポートを提供するためのものです。
コードは長い間継続的に改訂されており、今後も長期間変更されることはありません。
- /**
- * 汎用 DB アクセス クラス、すべての DB アクセスのエントリ
- * PG のみがサポートされています -- 201210
- *
- * @author Anthony
- * 2010-2012 予約済み
- */
- class DB {
- // クエリタイプ
- const SELECT = 1;
- const INSERT = 2;
- const UPDATE = 3;
- const DELETE = 4;
- /**
- * 真の価値
- */
- const T = 't';
- /**
- * 誤った値
- */
- const F = 'f';
- /**
- * Null 値
- */
- const N = 'N/A'; //NULL 値
- /**
- * 値を指定します。
- * 'f' は False、't' は TRUE、'N/A' は NULL 値です
- *
- * @param String $s、元の値
- *
- * @return String、指定された値
- */
- public static functionspecializeValue($s){
- if($s === self::N){
- return NULL;
- }
- if($ s === self::T){
- return True;
- }
- if($s === self::F){
- return False;
- }
- return $s;
- }
- /* *
- * テーブルへのバッチ挿入
- * @param String $table_name テーブル名
- * @param Array $cols テーブルの列
- * @param Array $values、values のデータ配列
- * @param String/Array $return_cols 戻り列[s] ]、デフォルトでは 'id' が返されます。複数列の配列
- * @param String $db DB 接続のインスタンス名
- *
- * @return Resultsset 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).') 値 ';
- $_vsql = array();
- foreach ($values as $value){
- $_vsql[ ] = '('.self::quote($value).')';
- }
- $_sql .= implode(',',$_vsql);
- $_sql .= ' '.self:: を返しますquote_column($return_cols);
- return self::query(self::SELECT,$_sql)->execute($db)->as_array();
- }
- /**
- * 配列データからテーブルに挿入し、列[s]を返します。ID はデフォルトで返されます
- *
- * @param String $table_name テーブル名
- * @param Array $data キーと値のペアの配列データ
- * @param String/Array $return_cols 戻り列[s]、デフォルトでは 'id' が返されます、複数の列の配列
- * @param String $db DB 接続のインスタンス名
- *
- * @return Boolean/Resultset 戻り列なしで成功した場合は True 、失敗した場合は False、return_cols が提示された場合は列[s]の値。*/
- 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 = '.self::quote_table($table_name,$db).'('.self::quote_column(array_keys($data),$db).') 値 ('.
- self::quote(array_values($data),$db).')';
- return self::query(self::INSERT,$_sql)->execute($db);
- }
- //値を特殊化する
- $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).') 値 ('.
- self::quote(array_values($data),$db).')'." を返します。 $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 = '.self::quote_table($table_name,$db) に挿入します。'('.self::quote_column (array_keys($data),$db).') 値 ('.
- self::quote(array_values($data),$db).')'." を返します ".$ids;
- $r_ids = self: :query(self::SELECT,$_sql)->execute($db)->current();
- return $r_ids;
- }
- }
- return false;
- }
- /**
- * テーブルのデータを更新し、参照データと比較します
- *
- * @param String $table_name テーブル名
- * @param Integer $id データのID
- * @param Array $data キーと値のペアの配列データ
- * @param配列 $refdata 参照データ
- * @param String $id_name IDのカラム名
- * @param String $db DB接続のインスタンス名
- *
- * @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('データはcol=>valペア配列である必要があります');
- }
- 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 newException('refdata type error');
- }
- }
-
- //値を特殊化します
- $data = array_map('self::specializeValue',$data);
-
- if(count($data)>0){
- return self::update_table($table_name,$id, $data,'id',$db);
- }else{
- return 0;
- }
- }
-
- /**
- * 参照先のデータをチェックせずにテーブルをデータで更新します
- *
- * @param String $table_name テーブル名
- * @param Integer $id データのID
- * @param Array $data キーと値のペアの配列データ
- * @param String $id_name ID のカラム名
- * @param String $db DB 接続のインスタンス名
- *
- * @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) 。」 '.self::quote_assoicate($data,'=',',',$db)' を設定します。 where '.
- self::quote_column($id_name,$db).'='.self::quote($id,$db);
- return self::query(self::UPDATE,$_sql)-> execute($db);
- }
-
- /**
- *col => のキーと値のペアを引用符で囲みます。値
- *
- * @param 配列 $data、col=>値のペア
- * @param 文字列 $concat、デフォルト '='
- * @param 文字列区切り文字、デフォルト ','
- * @param 文字列データベース インスタンス
- *
- * @return 文字列
- */
- 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;
- }
-
- /**
- * Cols を引用
- *
- * @param String $value、列の名前
- * @param String $db、データベース インスタンス名
- */
- public static function quote_column ($value,$db='default'){
- if(!is_array($value)){
- return self::quote_identifier($value,$db);
- }else{ //quote_column 配列と内部分解
- $_qs = array();
- foreach ($value as $ele){
- $_qs[] = self::quote_column($ele,$db);
- }
-
- $_quote_column_String = implode(',',$_qs);
- return $_quote_column_String;
- }
- }
- /**
- * エスケープする値を引用符で囲みます
- *
- * @param Scalar/Array $value
- *
- * @return 引用符文字列または配列
- */
- public static function quote($value,$db='default'){
- if(!is_array($value)){
- return データベース: :instance($db)->quote($value);
- }else{ //配列を引用符で囲んで内部展開します
- $_qs = array();
- foreach ($value as $ele){
- $_qs[] = self ::quote($ele,$db);
- }
-
- $_quoteString = implode(',',$_qs);
- return $_quoteString;
- }
- }
-
- /**
- * DBのエスケープ文字列
- *
- * @param string $s テーブル名
- * @param String $db データベースインスタンス名
- *
- * @return String
- */
- public static functionscape($s,$db='default'){
- return Database::instance($db)->escape($s);
- }
-
- /**
- * テーブル名を引用
- *
- * @param string $s テーブル名
- * @param String $db データベースインスタンス名
- *
- * @return String
- */
- public static function quote_table ($s,$db='default'){
- return Database::instance($db)->quote_table($s);
- }
-
- /**
- * 列名などのデータベース識別子を引用符で囲みます。
- *
- * $column = DB::quote_identifier($column,'default');
- *
- * 識別子内で SQL メソッドを使用することもできます。
- *
- * // "column" の値は引用符で囲まれます
- * $column = DB::quote_identifier('COUNT("column")');
- *
- * この関数に渡されたオブジェクトは文字列に変換されます。
- * [Database_Query] オブジェクトはコンパイルされ、サブクエリに変換されます。
- * 他のすべてのオブジェクトは、「__toString」メソッドを使用して変換されます。
- *
- * @parammixed $value 任意の識別子
- * @param String $db、データベース インスタンス
- * @return string
- */
- public static function quote_identifier($ value,$db='default'){
- return Database::instance($db)->quote_identifier($value);
- }
-
- /**
- * データベースインスタンスの接続を取得
- *
- * @param String $db データベースインスタンス名
- *
- * @return データベースの接続
- */
- public static function getConnection($db = 'デフォルト'){
- return Database::instance($db)->getConnection();
- }
-
- /**
- * 現在のレコードの子を取得します
- *
- * @param String $table テーブル名
- * @param Bollian $returnSql
- * @param Integer $pid テーブルレコードの親 ID
- * @param String $idname ID カラム名
- * @ param String $pidname 親 ID 列名
- * @param String $db データベース インスタンス名
- *
- * @return 子のレコード
- */
-
- public static function getChildren($table,$returnSql = false ,$pid= '0',$idname='id',$pidname='pid' ,$db='デフォルト'){
- $_sql = 'select * from '.self::quote_table($table,$db)'。 where '.$pidname.'='.self::quote($pid,$db).
- " と $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;
- }
- }
-
- /**
- * Data のすべての子レコードをトラバースするためのツリー クエリ
- *
- * @param String $tableName Tablename
- * @param Boolean $returnSql Return SQL String if TURE
- * @param String $startWith Begin valueof traverse
- * @ param String $idCol ID 列名
- * @param String $pidCol 親 ID 列名
- * @param String $orderCol 順序列
- * @param Integer $maxDepth トラバースの深さ、
- * @param Integer $level 開始レベル
- * @ param String $delimiter ブランチの区切り文字
- * @param String $db データベース構成インスタンス
- *
- * @return Record/String レコード配列または 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); //テーブル|ビュー
- $_funcParas[] = self::quote($idCol,$db); //ID列
- $_funcParas[] = self::quote($pidCol,$db); //親ID列
- $_funcParas[] = self::quote($orderCol,$db); //デフォルトの ASC による順序
- $_funcParas[] = self::quote($startWith,$db); // ID の開始
- $_funcParas[] = self::quote($maxDepth,$db); //トラバースの深さ
- $_funcParas[] = self::quote($delimiter,$db); //分岐の区切り文字,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;
- }
- }
-
- /**
- * トランザクション開始
- *
- * @param String $db DBのインスタンス名
- *
- * @return 結果セット
- */
- public static function begin($db='default'){
- return DB::query(self::UPDATE, "BEGIN")->execute($db);
- }
-
- /**
- * セーブポイントを定義します
- *
- * @param String $savepoint
- *
- * @param String $db
- */
- public static function savepoint($savepoint, $db='デフォルト'){
- return DB::query(self::UPDATE, "SAVEPOINT ".$savepoint)->execute($db);
- }
-
- /**
- * セーブポイントへのロールバック
- *
- * @param String $savepoint
- *
- * @param String $db データベース インスタンス名
- */
-
- public static function rollpoint ($savepoint, $db='default'){
- return DB::query(self::UPDATE, "ROLLBACK TO ".$savepoint)->execute($db);
- }
-
- /**
- * トランザクションをコミットします
- * @param String DB 接続
- */
-
- 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);
- }
-
-
- /**
- * 指定されたタイプの新しい [Database_Query] を作成します。
- *
- * // 新しい SELECT クエリを作成します
- * $query = DB::query(self::SELECT, 'SELECT * FROM users');
- *
- * // 新しい DELETE クエリを作成します
- * $query = DB::query(self::DELETE, 'DELETE FROM users WHERE id = 5');
- *
- * 型を指定すると、返される結果が変わります。
- * self::SELECT を使用すると、[Database_Query_Result] が返されます。
- * self::INSERT クエリは、挿入 ID と行数を返します。
- * 他のすべてのクエリについては、影響を受ける行の数が返されます。
- *
- * @param 整数型: self::SELECT、self::UPDATE など
- * @param string SQL ステートメント
- * @param Boolean $as_object true の場合は結果セットをオブジェクトとして返し、デフォルトは FALSE
- * @param Array $params SQLのクエリパラメータ、デフォルトのarray()
- * @param String $stmt_name クエリはTRUEの場合プリペアドステートメントです、
- * $paramがNULLでない場合にプリペアドステートメントを実行
- * $paramがNULLの場合プリペアドステートメント
- *
- * @returnデータベース_クエリ
- */
- 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);
- }
-
-
- /**
- * 元の SQL からページ分割されたページを取得します
- *
- * @param String $sql SQL クエリ
- * @param UTL オブジェクト &$page tempalte の UTL オブジェクト
- * @param String $orderBy 列順に並べ替え、デフォルトは「更新された説明」
- * @param String $dataPro データ プロパティ名、デフォルト 'data'
- * @param String $pagePro Pagnation Framement プロパティ名、デフォルト 'pagination'
- * @param Array $config ページネーション設定配列オーバーライダー
- * @param String $db データベース インスタンス名、デフォルトは 'default'
- * @param Boolean $as_object TRUE の場合はデータをオブジェクトとして取り込み、デフォルトは TRUE
- * @param String $_paginClass ページネーションのクラス名
- * @return 成功した場合は True
- */
- public static function getPage($_sql,&$page,$orderBy ='更新された説明', $ dataPro='data',$pagePro = 'ページネーション',
- $config = NULL,$db = 'default',$as_object= true,$_paginClass='ページネーション'){
-
- $_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 .= ' 制限 '.$_pagination->items_per_page;
-
- $_data = DB::query(self::SELECT,$_sql,$as_object)->execute($db)->as_array() ;
- if(!$_data){
- $page->gt;{$dataPro} = false;
- $page->gt;{$pagePro} = false;
- return false;
- }
-
- $page->gt;{$dataPro} = $_data;
- $page->gt;{$pagePro} = $_pagination;
- return true;
- }
-
- /**
- * 部下のすべてのロールを取得します
- *
- * @param Integer $role_id Integer ユーザーロール ID
- * @param Boolean $quote 正しい場合は SQL を引用し、false の場合は元の SQL を返します
- * @param String $role_table ロール階層のテーブル
- * @param Integer $level ツリートラバースの開始レベル
- * @param String $db データベースインスタンス名
- * @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, //Max Depth
- $level, //Level
- ';',$db).') utree';
- if(!$quote) return $ _sql;
- else return '('.$_sql.')';
- }
-
- /**
- * 従属オブジェクトと所有オブジェクトのオブジェクトをクエリするための SQL 文字列を取得します
- * 子ユーザー ロール ツリー[CURT]
- *
- * @param integer $role_id ユーザーのロール ID
- * @param integer $user_id ユーザー ID
- * @param String $ role_table ロールのテーブル
- * @param Boolean $quote 正しい場合は SQL を引用し、false の場合は元の SQL を返す
- * @param String $roleCol ロール ID 列名
- * @param String $ownerCol オーナー ID 列名
- * @param String $ db データベースインスタンス名
- * @return SQL 文字列
- */
- 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, //レベルは 1 から始まります
- $db)。 ' または '.$ownerCol.'='.self::quote($user_id,$db);
- if(!$quote) return $_sql;
- else return '('.$_sql.')';
- }
-
-
- /**
- * ツリークエリからツリーへの配列
- *
- * @param Array $eles 、self::getTree から設定されたレコード
- * @param String $elename、ノードの要素名
- * @param String $cldname、子ノード名
- * @param String $delimiter、ブランチの区切り文字
- *
- * @return Object、データのツリーオブジェクト
- */
- public static function array2tree($eles,$elename,$cldname,$delimiter=';'){
- if($elename == $cldname){
- throw new Exception( 'Ele 名は cldname と等しい!');
- }
- $rtree = array();
- foreach ($eles as $ele){
- $_branch = $ele->branch;
- //Log::debug('branch ='.$_branch);
- //配列内の深さ
- $_ Depths =explode($delimiter,$_branch);
- if(count($_ Depths == 1)){
- $_root = $_ Depths[0] ;
- }
- $_cur = &$rtree;
- foreach ($_ Depths as $ Depth){
- //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];
- }
-
- }
-
复制發
|