首頁 > 後端開發 > php教程 > Postgresql DB的存取類

Postgresql DB的存取類

WBOY
發布: 2016-07-25 09:01:45
原創
1004 人瀏覽過
程式碼不是用來直接使用, 只是提供一個思路. 對PG的各種特性, 包括不限於 樹子查詢, prepared statements, batch insert的各種支援:

程式碼經過了相當長時間的不斷修正, 最終定稿, 將來相當長的時間內, 都不會去修改這個玩意了.
  1. /**
  2. * 通用資料庫存取類,所有資料庫存取的入口
  3. * 僅支援 PG -- 201210
  4. *
  5. * @author Anthony
  6. * 2010-2012 保留
  7. */
  8. class DB {
  9. // 查詢型別
  10. const SELECT = 1;
  11. const INSERT = 2;
  12. const UPDATE = 3;
  13. const DELETE = 4;
  14. / **
  15. * 真實值
  16. */
  17. const T = 't';
  18. /**
  19. * 錯誤值
  20. */
  21. const F = 'f';
  22. /**
  23. * 空值
  24. */
  25. const N = 'N/A'; //NULL 值
  26. /**
  27. * 指定值;
  28. * 'f' 為False,'t' 為TRUE,'N/A' 為NULL 值
  29. *
  30. * @param String $s,原始值
  31. *
  32. * @return 字串,指定值
  33. */
  34. public static functionspecializeValue($s){
  35. if($s === self::N){
  36. return NULL;
  37. }
  38. if($s === self::T){
  39. return True;
  40. }
  41. if($s == = self::F){
  42. return False;
  43. }
  44. return $s;
  45. }
  46. }
  47. /**
  48. * 批次插入表
  49. * @param String $table_name 表名
  50. * @param Array $cols 表的欄位
  51. * @param Array $values,資料值陣列
  52. * @ param String /Array $return_cols 回傳列[s],預設回傳'id',多列數組
  53. * @param String $db DB Connection 實例名稱
  54. *
  55. * @return 結果集傳回return_cols
  56. 的結果集*/
  57. 公共靜態函數insert_batch($table_name,$cols,$values,$return_cols='id',$db='default'){
  58. $_sql = '插入'. self::quote_table($table_name,$ db).'('.self::quote_column($cols,$db).') 值';
  59. $_vsql = array();
  60. foreach ($values as $value){
  61. $ _vsql[] = '('.self::quote($value).')';
  62. }
  63. $_sql .= implode(',', $_vsql);
  64. $_sql .= ' 回傳'.self::quote_column($return_cols);
  65. return self::query(self::SELECT,$_sql)->execute ($db)->as_array ();
  66. }
  67. /**
  68. * 從Array Data插入表,回傳列[s],預設回傳ID
  69. *
  70. * @param String $table_name 表名
  71. * @param Array $data Array Data Of鍵值對。
  72. * @param String/Array $return_cols 回傳列[s],預設回傳'id',多列的陣列
  73. * @param String $db DB Connection 實例名稱
  74. *
  75. * @return Boolean/Resultset 如果成功但沒有回傳列則為True,如果失敗則為False,如果存在return_cols,則為列[s] 的值。
  76. */
  77. 公用靜態函數insert_table($table_name,$data,$return_cols='id',$ db='default'){
  78. if (!is_array($data)){
  79. return false;
  80. }
  81. if (is_null($return_cols)){
  82. $sql_ = '插入'.self ::quote_table($table_name,$db).'('.self::quote_column(array_keys($data),$db).') 值('.
  83. self::quote( array_values($data), $db).')';
  84. return self::query(self::INSERT,$_sql)->execute($db);
  85. }
  86. / /特殊化值
  87. $data = array_map('self::specializeValue',$data);
  88. if (is_string($return_cols)){
  89. $_sql = '插入'.self: :quote_table($table_name ,$db).'('.self::quote_column(array_keys($data),$db).') 值('.
  90. self::quote(array_values($data),$ db).') '." 回傳".$return_cols;
  91. $id = self::query(self::SELECT,$_sql)->execute($db)->get($return_cols) ;
  92. return $id;
  93. }else{
  94. if (is_array($return_cols)){
  95. $ids = implode(',',$return_cols);
  96. $_sql = '插入'. self::quote_table($table_name,$db).'('.self::quote_column(array_keys($data),$db).') 值('.
  97. self::quote(array_values($ data) ,$db).')'." 回傳".$ids;
  98. $r_ids = self::query(self::SELECT,$_sql)->execute($db)->current();
  99. return $r_ids;
  100. }
  101. }
  102. return false;
  103. }
  104. /**
  105. * 更新表數據,並與參考資料進行比較
  106. *
  107. * @param String $table_name 表名
  108. * @param Integer $id 數據ID
  109. * @param Array $data Array鍵值對的資料。
  110. * @param Array $refdata 參考資料
  111. * @param String $id_name ID 的列名
  112. * @param String $db DB Connection 的實例名稱
  113. *
  114. * @return 受影響的整數行,如果失敗則回傳False!
  115. */ publicstatic function update_data($table_name,$id,$data,$refdata,$id_name='id',$db='default'){
  116. if (!is_array($data)){
  117. 拋出新異常( '資料應該是col=>val 對數組');
  118. }
  119. foreach($data as $k =>; $v){
  120. if(is_array($refdata)){
  121. if(isset($refdata[$k])){
  122. if($v == $refdata[$k]){
  123. unset($data[$k]);
  124. }
  125. }
  126. }elseif(is_object($refdata)){
  127. if(isset($refdata->$k)){
  128. if($v == $refdata->$k){
  129. unset($data[$k]);
  130. }
  131. }
  132. }else{ 拋出新的例外('引用資料型別錯誤'); } }
  133. // 特化值
  134. $data = array_map('self::specializeValue',$data);
  135. if(count($data)>0){
  136. return self::update_table($table_name,$id,$data,'id',$db);
  137. }else{
  138. return 0;
  139. }
  140. }
  141. / **
  142. * 使用資料更新表,而不檢查引用的資料
  143. *
  144. * @param String $table_name 表名稱
  145. * @param Integer $id 資料ID
  146. * @param Array $data Array鍵值對的資料。
  147. * @param String $id_name ID
  148. 的列名* @param String $db 資料庫連線的實例名稱
  149. *
  150. * @return Integer 受影響的行,如果失敗則為False !
  151. */
  152. 公共靜態函數update_table($table_name,$id,$data,$id_name='id',$db='default'){
  153. if (!is_array($data) ){
  154. return false;
  155. }
  156. $_sql = 'update '.self::quote_table($table_name,$db).' 設定'.self::quote_assoicate($data,' =',',',$db)。 '其中'.
  157. self::quote_column($id_name,$db).'='.self::quote($id,$db);
  158. return self::query(self::UPDATE,$_sql )->execute($db);
  159. }
  160. /**
  161. * 引用col 的鍵值對=>值
  162. *
  163. * @param Array $data, col=>值對
  164. * @param String $concat,預設'='
  165. * @param 字串分隔符,預設','
  166. * @param String 資料庫實例
  167. *
  168. * @return String
  169. */
  170. 公共靜態函數quote_assoicate($data,>*/
  171. 公共靜態函數quote_assoicate($data, $concat='=',$delimiter=' ,',$db='default'){
  172. $_sql = '';
  173. $_sqlArray = array();
  174. foreach ($data as $ k => $v){
  175. $_sqlArray[] = self::quote_column($k,$db).$concat.self::quote($v,$db);
  176. }
  177. $_sql = implode($delimiter, $_sqlArray);
  178. return $_sql;
  179. }
  180. /**
  181. * 引用 cols
  182. *
  183. * @param String $value,列名稱
  184. * @param String $db,資料庫實例名稱
  185. */
  186. 公共靜態函式$db='default'){
  187. if(!is_array($value)){
  188. return self::quote_identifier($value,$db);
  189. }else{ //quote_column 記憶體並內爆
  190. $_qs = array();
  191. foreach ($value as $ele){
  192. $_qs[] = self::quote_column($ele,$db);
  193. }
  194. $_quote_column_String = implode(',', $_qs);
  195. return $_quote_column_String;
  196. }
  197. }
  198. /**
  199. * 引用要轉義的值
  200. *
  201. * @param Scalar/Array $value
  202. *
  203. * @return 引用字串或陣列
  204. */
  205. * DB 的轉義字串
  206. *
  207. * @param string $s 表名
  208. * @param String $db 資料庫實例名稱
  209. *
  210. * @return String
  211. 公用函數value,$db='default'){
  212. if(!is_array($value)){
  213. return Database::instance($db)->quote($value);
  214. }else{ / /引用數組並內爆
  215. $_qs = array();
  216. foreach ($value as $ele){
  217. $_qs[] = self::quote($ele,$db);
  218. }
  219. $_quoteString = implode(',',$_qs);
  220. return $_quoteString;
  221. }
  222. }
  223. /**
  224. * Quote 表名稱
  225. *
  226. * @param string $s 表名稱
  227. * @param String $db 資料庫實例名稱
  228. *
  229. * @return String
  230. */🎝>*/
  231. public static function escape($s, $db='default'){
  232. return Database::instance($db)->escape($s);
  233. }
  234. / **
  235. * 引用資料庫標識符,例如列名。
  236. *
  237. * $column = DB::quote_identifier($column,'default');
  238. *
  239. * 您也可以在識別碼中使用 SQL 方法。
  240. *
  241. * / / "column" 的值將被引用
  242. * $column = DB::quote_identifier('COUNT("column")');
  243. *
  244. * 傳遞給此函數的物件將轉換為字串.
  245. * [Database_Query] 物件將被編譯並轉換為子查詢。
  246. * 所有其他物件將使用 '__toString' 方法進行轉換。
  247. *
  248. * @param mix $value任何識別碼
  249. * @param String $db,資料庫實例
  250. * @return string
  251. */
  252. public static function quote_table($s,$db='default'){
  253. return Database::instance($db)->quote_table($s);
  254. }
  255. /**
  256. * 取得資料庫執行個體的連線
  257. *
  258. * @param String $db 資料庫執行個體名稱
  259. *
  260. * @return 資料庫連線
  261. */
  262. public static function quote_identifier($value,$db='default'){
  263. return Database::instance($db)->quote_identifier($ value);
  264. }
  265. /***/
  266. public static function getConnection($db = 'default'){
  267. return Database::instance($db)- >getConnection();
  268. }
  269. /**
  270. * 取得目前記錄的子項
  271. *
  272. * @param String $table 表名稱
  273. * @param Bollean $returnSql
  274. * @param Integer $pid 表記錄的父ID
  275. * @param String $idname ID 欄位名稱
  276. * @param String $pidname 父級ID 欄位名稱
  277. * @param String $db 資料庫實例名稱
  278. *
  279. * @return 子級記錄
  280. */
  281. 公共靜態函數getChildren($table,$returnSql = false ,$pid= '0',$idname='id',$pidname= 'pid' ,$db='default'){
  282. $_sql = '從'.self::quote_table($table,$db) 選擇*。 '其中'.$pidname.'='.self::quote($pid,$db).
  283. " 和$idname ".self::quote($pid,$db);
  284. if ($returnSql){
  285. return $_sql;
  286. }
  287. $_res = self::query(self::SELECT,$_sql,true)->execute($ db)->as_array ();
  288. if($_res){
  289. return $_res;
  290. }else{
  291. return false;
  292. }
  293. }
  294. /**
  295. * 連接方式的樹形查詢,遍歷Data 的所有子記錄
  296. *
  297. * @param String $tableName 表名
  298. * @param Boolean $returnSql 如果TURE
  299. 傳回SQL 字串* @ param String $startWith 遍歷開始值
  300. * @param String $idCol ID 欄位名稱
  301. * @param String $pidCol 父親ID 欄位名稱
  302. * @param String $orderCol 訂單列
  303. * @ param Integer $maxDepth 遍歷深度,
  304. * @param Integer $level 起始等級
  305. * @param String $delimiter 分支分隔符號
  306. * @param String $db 資料庫設定實例
  307. *
  308. *
  309. *
  310. * @傳回記錄/字串傳回SQL 的記錄數組或字串
  311. */
  312. 公共靜態函數getTree($tableName,$returnSql=false,$startWith='0',$idCol='id',$pidCol='pid', $orderCol=' id', $maxDepth= 0,$level = 0,$delimiter = ';',$db='default'){
  313. $_funcParas = array();
  314. $_funcParas[] = self::quote ($表名,$ db); //表格|檢視
  315. $_funcParas[] = self::quote($idCol,$db); //ID欄位
  316. $_funcParas[] = self::quote($pidCol,$db ); //父ID欄位
  317. $_funcParas[] = self::quote($orderCol,$db); //預設順序ASC
  318. $_funcParas[] = self::quote($startWith,$db ); //開始ID
  319. $_funcParas[] = self::quote($maxDepth,$db); //遍歷深度
  320. $_funcParas[] = self::quote($delimiter,$db); //分支分隔符,預設';'
  321. $_sql = 'select * from connectby('
  322. .implode(',',$_funcParas).')'
  323. .' as t (id int, pid int, level int,branch text, pos int)';
  324. if($level > 0){
  325. $_sql .= ' where level >='.self:: quote($level ,$db);
  326. }
  327. if($returnSql) return $_sql;
  328. $_res = self::query(self::SELECT,$_sql,true)- >execute($ db)->as_array();
  329. if($_res){
  330. return $_res;
  331. }else{
  332. return false;
  333. }
  334. }
  335. /**
  336. * 開始交易
  337. *
  338. * @param String $db DB 實例名稱
  339. *
  340. * @return 結果集
  341. */
  342. public static function begin($db='default'){
  343. return DB::query(self::UPDATE, "BEGIN")-> ;execute($db) ;
  344. }
  345. /**
  346. * 定義保存點
  347. *
  348. * @param String $savepoint
  349. *
  350. * @param String $db
  351. */
  352. 公共靜態函數savepoint($savepoint, $db='default'){
  353. 回傳DB: :query(self:: UPDATE, "SAVEPOINT ".$savepoint)->execute($db);
  354. }
  355. /**
  356. * 回滾到保存點
  357. *
  358. * @param String $savepoint
  359. *
  360. * @param String $db 資料庫實例名稱
  361. */
  362. public static function rollpoint($saveave, $ db='default'){
  363. return DB::query(self::UPDATE, "ROLLBACK TO ".$savepoint)->execute($db);
  364. }
  365. /**
  366. * 提交交易 * @param String 資料庫連線*/ 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") ->執行($db); }
  367. /**
  368. * 建立給定類型的新 [Database_Query]。
  369. *
  370. * // 建立新的SELECT 查詢
  371. * $query = DB::query(self::SELECT, 'SELECT * FROM users');
  372. *
  373. * //建立一個新的DELETE 查詢
  374. * $query = DB::query(self::DELETE, 'DELETE FROM users WHERE id = 5');
  375. *
  376. * 指定類型會改變傳回的結果。當使用
  377. * self::SELECT 時,將會傳回 [Database_Query_Result]。
  378. * self::INSERT 查詢將傳回插入 id 和行數。
  379. * 對於所有其他查詢,將傳回插入的行數。傳回受影響的行。
  380. *
  381. * @param 整數類型:self::SELECT、self::UPDATE 等
  382. * @param string SQL 語句
  383. * @param Boolean $as_object 傳回結果集as Object if true, 預設FALSE
  384. * @param Array $params SQL 的查詢參數,默認array()
  385. * @param String $stmt_name 查詢為Prepared Statement if TRUE,
  386. * 執行Prepared Statement when $param is Not NULL
  387. * 當$param 為NULL 時準備語句
  388. *
  389. * @return Database_Query
  390. */
  391. 公共靜態函數查詢($type, $sql = NULL ,$as_object = false,$params = array(),$stmt_name = NULL)
  392. {
  393. return new Database_Query($type, $sql,$as_object,$params,$stmt_name);
  394. }
  395. /**
  396. * 從原始SQL 取得分頁頁面
  397. *
  398. * @param String $sql SQL 查詢
  399. * @param UTL 物件&$page UTL 範本物件
  400. * @param String $orderBy Order按列,預設'updated desc'
  401. * @param String $dataPro 資料屬性名稱,預設'data'
  402. * @param String $pagePro Pagnation Frament 屬性名稱,預設'pagination'
  403. * @param Array $ config 分頁配置數組overider
  404. * @param String $db 資料庫實例名稱,預設'default'
  405. * @param Boolean $as_object 如果為TRUE,則將資料填入對象,預設為TRUE
  406. * @ param String $_paginClass分頁的類別名稱
  407. * @return 如果成功則回傳True
  408. */
  409. * 取得下屬的所有角色
  410. *
  411. * @param Integer $role_id Integer 使用者角色ID
  412. * @param Boolean $quote 如果為true則引用SQL,如果為false則傳回原SQL
  413. * @param String $role_table 角色層級表
  414. * @param Integer $level 樹遍歷的起始層級
  415. * @param String $db 資料庫實例名稱
  416. * @return SQL String
  417. */
  418. public static function getPage($_sql,&$page,$orderBy ='更新的desc', $dataPro='data',$pagePro = '分頁',
  419. $config = NULL,$db = 'default' , $as_object= true,$_paginClass='分頁'){
  420. $_csql = '從('.$_sql.') st 選擇count(1) as c';
  421. $_c = DB::query(self::SELECT,$_csql)->execute($db)->get('c');
  422. if($config){
  423. $config['total_items'] = $_c;
  424. $_pagination = new $_paginClass($config);
  425. }else{
  426. $config = array();
  427. $config[' Total_items' ] = $_c;
  428. $_pagination = new $_paginClass($config);
  429. }
  430. $_sql .= ' order by '.$orderBy;
  431. if ($ _pagination->offset){
  432. $_sql .= 'offset'.$_pagination->offset;
  433. }
  434. $_sql .= 'limit'.$_pagination->items_per_page;
  435. $_data = DB::query(self::SELECT,$_sql,$as_object)->execute($db)->as_array();
  436. if(!$_data){
  437. $page->{ $dataPro} = false;
  438. $page->{$pagePro} = false;
  439. 回傳false;
  440. }
  441. $page->{$dataPro} = $_data;
  442. $page->{$pagePro} = $_pagination;
  443. 回傳 true;
  444. }
  445. /**
  446. * 取得SQL 字串來查詢從屬物件和擁有物件的物件
  447. * 子使用者角色樹[CURT]
  448. *
  449. * @param integer $role_id 使用者的角色ID
  450. * @ param integer $user_id 使用者ID
  451. * @param String $role_table 角色表
  452. * @param Boolean $quote 如果為ture,則引用SQL,如果為false,則傳回原始SQL
  453. * @param String $ roleCol 角色ID 欄位名稱
  454. * @param String $ownerCol 擁有者ID 欄位名稱
  455. * @param String $db 資料庫執行個體名稱
  456. * @return SQL String
  457. */
  458. 公共靜態函數getRoleTreeSql($role_id,$quote = false,$role_table,$level=0,$db='default'){
  459. $ _sql = 'select id from ('.self::getTree($role_table,true,$role_id,'id','pid','id',
  460. 0, //最大深度
  461. $level, / /Level
  462. ';',$db).') utree';
  463. if(!$quote) return $_sql;
  464. else return '('.$_sql.')';
  465. }
  466. /***/
  467. 公用靜態函式getCURTreeSql($role_id,$user_id,$role_table,$quote = true,
  468. $roleCol='role_id',$owner =id',$owner = 'owner_id' ,$db='default'){
  469. $_sql = ' '.$roleCol.'在'.self::getRoleTreeSql($role_id,true,$role_table,
  470. 1, //等級從1 開始
  471. $db)。 '('.$_sql.') ';
  472. }
  473. /**
  474. * 樹查詢到樹
  475. 的陣列*
  476. * @param Array $eles ,來自self::getTree
  477. 的記錄集* @param String $elename,節點
  478. 的元素名稱* @param String $cldname, 子節點名稱
  479. * @param String $delimiter, 分支分隔符號
  480. *
  481. * @return Object , 資料的Tree物件
  482. */
  483. public static function array2tree($eles,$elename,$cldname,$delimiter=';'){
  484. if($elename = = $cldname){
  485. throw new Exception('Ele 名稱等於cldname!');
  486. }
  487. $rtree = array();
  488. foreach ($eles as $ele){
  489. $_branch = $ele->branch;
  490. //Log::debug('branch='.$_branch);
  491. //陣列中的深度
  492. $_depths =explode($delimiter, $_branch );
  493. if(count($_depths == 1)){
  494. $_root = $_depths[0];
  495. }
  496. $_cur = &$rtree;
  497. foreach ( $_深度為$深度){
  498. //建立NODE
  499. if(!isset($_cur[$cldname])){
  500. $_cur[$cldname] = array();
  501. }
  502. if(!isset($_cur[$cldname][$深度])){
  503. $_cur[$cldname][$深度] = array();
  504. $_cur = &$_cur [ $cldname][$深度];
  505. }else{
  506. $_cur = &$_cur[$cldname][$深度];
  507. }
  508. }
  509. $_cur[$elename] = $ele;
  510. }
  511. return $rtree[$cldname][$_root];
  512. }
  513. }
複製代碼


相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板