Advertisement
Snoop-Dogg

pdo db script

Dec 8th, 2020
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.85 KB | None | 0 0
  1. <?php
  2.  
  3. // CubicleSoft generic database base class.
  4. // (C) 2015 CubicleSoft. All Rights Reserved.
  5.  
  6. class PDODB
  7. {
  8. protected $numqueries, $totaltime, $dbobj, $origdbobj, $debug, $transaction, $currdb;
  9. private $available_status;
  10. private $mdsn, $musername, $mpassword, $moptions;
  11.  
  12. public static function ConvertToDBDate($ts, $gmt = true)
  13. {
  14. return ($gmt ? gmdate("Y-m-d", $ts) : date("Y-m-d", $ts)) . " 00:00:00";
  15. }
  16.  
  17. public static function ConvertToDBTime($ts, $gmt = true)
  18. {
  19. return ($gmt ? gmdate("Y-m-d H:i:s", $ts) : date("Y-m-d H:i:s", $ts));
  20. }
  21.  
  22. public static function ConvertFromDBTime($field, $gmt = true)
  23. {
  24. $field = array_pad(explode(" ", preg_replace('/\s+/', " ", preg_replace('/[^0-9]/', " ", $field))), 6, 0);
  25. $year = (int)$field[0];
  26. $month = (int)$field[1];
  27. $day = (int)$field[2];
  28. $hour = (int)$field[3];
  29. $min = (int)$field[4];
  30. $sec = (int)$field[5];
  31.  
  32. return ($gmt ? gmmktime($hour, $min, $sec, $month, $day, $year) : mktime($hour, $min, $sec, $month, $day, $year));
  33. }
  34.  
  35. public function IsAvailable()
  36. {
  37. return false;
  38. }
  39.  
  40. public function GetDisplayName()
  41. {
  42. return "";
  43. }
  44.  
  45. public function __construct($dsn = "", $username = "", $password = "")
  46. {
  47. $this->numqueries = 0;
  48. $this->totaltime = 0;
  49. $this->dbobj = false;
  50. $this->origdbobj = false;
  51. $this->debug = false;
  52. $this->transaction = 0;
  53. $this->mdsn = false;
  54. $this->currdb = false;
  55. $this->available_status = $this->IsAvailable();
  56.  
  57. if ($dsn != "") $this->Connect($dsn, $username, $password);
  58. }
  59.  
  60. public function __destruct()
  61. {
  62. $this->Disconnect();
  63. }
  64.  
  65. public function SetDebug($debug)
  66. {
  67. $this->debug = $debug;
  68. }
  69.  
  70. protected function AssertPDOAvailable($checkdb)
  71. {
  72. if (!is_string($this->available_status))
  73. {
  74. throw new Exception(PDODB::DB_Translate("The driver is not available."));
  75. exit();
  76. }
  77.  
  78. if ($checkdb && $this->dbobj === false)
  79. {
  80. throw new Exception(PDODB::DB_Translate("Not connected to a database."));
  81. exit();
  82. }
  83. }
  84.  
  85. public function BeginTransaction()
  86. {
  87. $this->AssertPDOAvailable(true);
  88.  
  89. if (!$this->transaction)
  90. {
  91. $this->dbobj->beginTransaction();
  92.  
  93. if (is_resource($this->debug)) fwrite($this->debug, "BEGIN transaction.\n----------\n");
  94. }
  95.  
  96. $this->transaction++;
  97. }
  98.  
  99. public function Commit()
  100. {
  101. $this->AssertPDOAvailable(true);
  102.  
  103. if ($this->transaction)
  104. {
  105. $this->transaction--;
  106. if (!$this->transaction)
  107. {
  108. $this->dbobj->commit();
  109.  
  110. if (is_resource($this->debug)) fwrite($this->debug, "COMMIT transaction.\n----------\n");
  111. }
  112. }
  113. }
  114.  
  115. public function Rollback()
  116. {
  117. $this->AssertPDOAvailable(true);
  118.  
  119. if ($this->transaction)
  120. {
  121. $this->transaction = 0;
  122. $this->dbobj->rollBack();
  123.  
  124. if (is_resource($this->debug)) fwrite($this->debug, "ROLLBACK transaction.\n----------\n");
  125. }
  126. }
  127.  
  128. public function Connect($dsn, $username = false, $password = false, $options = array())
  129. {
  130. $this->AssertPDOAvailable(false);
  131.  
  132. $this->origdbobj = $this->dbobj;
  133. $this->dbobj = false;
  134. $this->mdsn = false;
  135.  
  136. $startts = microtime(true);
  137.  
  138. if (is_array($dsn))
  139. {
  140. foreach ($dsn as $key => $val) $dsn[$key] = $key . "=" . $val;
  141. $dsn = $this->available_status . ":" . implode(";", $dsn);
  142. }
  143.  
  144. $pos = strpos($dsn, ":");
  145. $driver = substr($dsn, 0, $pos);
  146. if ($driver !== $this->available_status)
  147. {
  148. throw new Exception(PDODB::DB_Translate("The driver '%s' is invalid. Must be '%s'.", htmlspecialchars($driver), htmlspecialchars($this->available_status)));
  149. exit();
  150. }
  151.  
  152. try
  153. {
  154. if ($password !== false) $this->dbobj = new PDO($dsn, $username, $password);
  155. else if ($username !== false) $this->dbobj = new PDO($dsn, $username);
  156. else $this->dbobj = new PDO($dsn);
  157. }
  158. catch (Exception $e)
  159. {
  160. if (is_resource($this->debug)) fwrite($this->debug, "The connection to the database server failed. " . $e->getMessage() . "\n----------\n");
  161.  
  162. if (is_resource($this->debug) || $this->debug) throw new Exception(PDODB::DB_Translate("The connection to the database server failed. %s", $e->getMessage()));
  163. else throw new Exception(PDODB::DB_Translate("The connection to the database server failed."));
  164. exit();
  165. }
  166.  
  167. if (is_resource($this->debug)) fwrite($this->debug, "Connected to '" . $dsn . "'.\n----------\n");
  168.  
  169. $this->totaltime += (microtime(true) - $startts);
  170.  
  171. return true;
  172. }
  173.  
  174. public function SetMaster($dsn, $username = false, $password = false, $options = array())
  175. {
  176. $this->mdsn = $dsn;
  177. $this->musername = $username;
  178. $this->mpassword = $password;
  179. $this->moptions = $options;
  180. }
  181.  
  182. public function Disconnect()
  183. {
  184. $startts = microtime(true);
  185.  
  186. while ($this->transaction) $this->Commit();
  187.  
  188. if ($this->dbobj !== false)
  189. {
  190. unset($this->dbobj);
  191. $this->dbobj = false;
  192. }
  193. if ($this->origdbobj !== false)
  194. {
  195. unset($this->origdbobj);
  196. $this->origdbobj = false;
  197. }
  198.  
  199. $this->totaltime += (microtime(true) - $startts);
  200.  
  201. if (is_resource($this->debug)) fwrite($this->debug, "Disconnected from database.\n\nTotal query time: " . sprintf("%.03f", $this->totaltime) . " seconds\n----------\n");
  202.  
  203. return true;
  204. }
  205.  
  206. public function Query()
  207. {
  208. $params = func_get_args();
  209. return $this->InternalQuery($params);
  210. }
  211.  
  212. public function GetRow()
  213. {
  214. $params = func_get_args();
  215. $dbresult = $this->InternalQuery($params);
  216. if ($dbresult === false) return false;
  217. $row = $dbresult->NextRow();
  218. unset($dbresult);
  219.  
  220. return $row;
  221. }
  222.  
  223. public function GetRowArray()
  224. {
  225. $params = func_get_args();
  226. $dbresult = $this->InternalQuery($params);
  227. if ($dbresult === false) return false;
  228. $row = $dbresult->NextRow(PDO::FETCH_BOTH);
  229. unset($dbresult);
  230.  
  231. return $row;
  232. }
  233.  
  234. public function GetCol()
  235. {
  236. $result = array();
  237.  
  238. $params = func_get_args();
  239. $dbresult = $this->InternalQuery($params);
  240. if ($dbresult === false) return false;
  241. while ($row = $dbresult->NextRow(PDO::FETCH_NUM))
  242. {
  243. $result[] = $row[0];
  244. }
  245.  
  246. return $result;
  247. }
  248.  
  249. public function GetOne()
  250. {
  251. $params = func_get_args();
  252. $dbresult = $this->InternalQuery($params);
  253. if ($dbresult === false) return false;
  254. $row = $dbresult->NextRow(PDO::FETCH_NUM);
  255. unset($dbresult);
  256. if ($row === false) return false;
  257.  
  258. return $row[0];
  259. }
  260.  
  261. public function GetVersion()
  262. {
  263. return "";
  264. }
  265.  
  266. public function GetInsertID($name = null)
  267. {
  268. return $this->dbobj->lastInsertId($name);
  269. }
  270.  
  271. public function TableExists($name)
  272. {
  273. return false;
  274. }
  275.  
  276. public function LargeResults($enable)
  277. {
  278. }
  279.  
  280. public function NumQueries()
  281. {
  282. return $this->numqueries;
  283. }
  284.  
  285. // Execution time with microsecond precision.
  286. public function ExecutionTime()
  287. {
  288. return $this->totaltime;
  289. }
  290.  
  291. private function InternalQuery($params)
  292. {
  293. $startts = microtime(true);
  294.  
  295. $cmd = array_shift($params);
  296. if ($cmd !== false) $cmd = strtoupper($cmd);
  297. $queryinfo = array_shift($params);
  298. if (count($params) == 1 && is_array($params[0])) $params = $params[0];
  299.  
  300. if ($cmd === false)
  301. {
  302. $master = true;
  303. $sqls = array((string)$queryinfo);
  304. $opts = array($params);
  305. $filteropts = false;
  306. }
  307. else
  308. {
  309. $master = false;
  310. $sqls = "";
  311. $opts = array();
  312. $result = $this->GenerateSQL($master, $sqls, $opts, $cmd, $queryinfo, $params, false);
  313. $filteropts = (isset($result["filter_opts"]) ? $result["filter_opts"] : false);
  314. if (!$result["success"])
  315. {
  316. if ($result["errorcode"] == "skip_sql_query") return new PDODB_PDO_Statement($this, false, $filteropts);
  317.  
  318. if (is_resource($this->debug)) fwrite($this->debug, "Error generating '" . $cmd . "' SQL query. " . $result["error"] . " (" . $result["errorcode"] . ")\n\n" . (is_string($sqls) ? $sqls : var_export($sqls, true)) . "\n----------\n");
  319.  
  320. throw new Exception(PDODB::DB_Translate("Error generating '%s' SQL query. %s (%s)", $cmd, $result["error"], $result["errorcode"]));
  321. exit();
  322. }
  323.  
  324. if ($cmd == "USE") $this->currdb = $queryinfo;
  325. }
  326.  
  327. // Switch to master database.
  328. if ($master && $this->mdsn !== false)
  329. {
  330. $numcommit = $this->transaction;
  331. while ($this->transaction) $this->Commit();
  332.  
  333. if (!$this->Connect($this->mdsn, $this->musername, $this->mpassword, $this->moptions))
  334. {
  335. throw new Exception(PDODB::DB_Translate("The connection to the master database failed."));
  336. exit();
  337. }
  338.  
  339. if (is_resource($this->debug)) fwrite($this->debug, "Connection to master database succeeded.\n----------\n");
  340.  
  341. if ($this->currdb !== false) $this->Query("USE", $this->currdb);
  342.  
  343. while ($this->transaction < $numcommit) $this->BeginTransaction();
  344. }
  345.  
  346. $prepareopts = (isset($result["prepare_opts"]) ? $result["prepare_opts"] : array());
  347.  
  348. if (is_string($sqls))
  349. {
  350. $sqls = array($sqls);
  351. $opts = array($opts);
  352. }
  353. foreach ($sqls as $num => $sql)
  354. {
  355. $opts2 = $opts[$num];
  356.  
  357. $result = $this->dbobj->prepare($sql, $prepareopts);
  358. if ($result === false)
  359. {
  360. $info = $this->dbobj->errorInfo();
  361.  
  362. if (is_resource($this->debug)) fwrite($this->debug, $info[0] . " " . $info[2] . " (" . $info[1] . ").\nError preparing SQL query:\n\n" . $sql . "\n\n" . var_export($opts2, true) . "\n----------\n");
  363.  
  364. if (is_resource($this->debug) || $this->debug) throw new Exception(PDODB::DB_Translate("%s %s (%s). Error preparing SQL query: %s %s", $info[0], $info[2], $info[1], $sql, var_export($opts2, true)));
  365. else throw new Exception(PDODB::DB_Translate("Error preparing SQL query. %s %s (%s)", $info[0], $info[2], $info[1]));
  366. exit();
  367. }
  368. if (!$result->execute($opts2))
  369. {
  370. $info = $result->errorInfo();
  371.  
  372. if (is_resource($this->debug)) fwrite($this->debug, $info[0] . " " . $info[2] . " (" . $info[1] . ").\nError executing SQL query:\n\n" . $sql . "\n\n" . var_export($opts2, true) . "\n----------\n");
  373.  
  374. if (is_resource($this->debug) || $this->debug) throw new Exception(PDODB::DB_Translate("%s %s (%s). Error executing SQL query: %s %s", $info[0], $info[2], $info[1], $sql, var_export($opts2, true)));
  375. else throw new Exception(PDODB::DB_Translate("Error executing SQL query. %s %s (%s)", $info[0], $info[2], $info[1]));
  376. exit();
  377. }
  378.  
  379. $this->numqueries++;
  380.  
  381. $diff = (microtime(true) - $startts);
  382. $this->totaltime += $diff;
  383.  
  384. if (is_resource($this->debug))
  385. {
  386. ob_start();
  387. debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
  388. $info = ob_get_contents();
  389. ob_end_clean();
  390. fwrite($this->debug, "Query #" . $this->numqueries . "\n\n" . $sql . "\n\n" . var_export($opts2, true) . "\n\n" . $info . "\nCommand: " . $cmd . "\n\n" . sprintf("%.03f", $diff) . " seconds (" . sprintf("%.03f", $this->totaltime) . " total)\n----------\n");
  391. }
  392.  
  393. if ($filteropts !== false) $this->RunStatementFilter($result, $filteropts);
  394. }
  395.  
  396. return new PDODB_PDO_Statement($this, $result, $filteropts);
  397. }
  398.  
  399. public function Quote($str, $type = PDO::PARAM_STR)
  400. {
  401. if (is_bool($str) && !$str) return "NULL";
  402.  
  403. return $this->dbobj->quote((string)$str, $type);
  404. }
  405.  
  406. public function QuoteIdentifier($str)
  407. {
  408. return "";
  409. }
  410.  
  411. protected function ProcessSubqueries(&$result, &$master, $subqueries)
  412. {
  413. foreach ($subqueries as $num => $subquery)
  414. {
  415. $sql2 = "";
  416. $opts2 = array();
  417. $queryinfo2 = array_shift($subquery);
  418. if (count($subquery) == 1 && is_array($subquery[0])) $subquery = $subquery[0];
  419. $result = $this->GenerateSQL($master, $sql2, $opts2, "SELECT", $queryinfo2, $subquery, true);
  420. if (!$result["success"]) return $result;
  421.  
  422. $result = str_replace("{" . $num . "}", "(" . $sql2 . ")", $result);
  423. }
  424.  
  425. return array("success" => true);
  426. }
  427.  
  428. // Derived classes implement this function.
  429. protected function GenerateSQL(&$master, &$sql, &$opts, $cmd, $queryinfo, $args, $subquery)
  430. {
  431. return array("success" => false, "error" => PDODB::DB_Translate("The base class GenerateSQL() was called."), "errorcode" => "wrong_class_used");
  432. }
  433.  
  434. protected function RunStatementFilter(&$stmt, &$filteropts)
  435. {
  436. }
  437.  
  438. // Can't be a 'protected' function since this is called from PDODB_PDO_Statement.
  439. public function RunRowFilter(&$row, &$filteropts, &$fetchnext)
  440. {
  441. if ($row === false) return;
  442.  
  443. switch ($filteropts["mode"])
  444. {
  445. case "SHOW DATABASES":
  446. case "SHOW TABLES":
  447. {
  448. if (isset($row->name) && isset($filteropts["queryinfo"]) && isset($filteropts["queryinfo"][0]))
  449. {
  450. if (stripos($row->name, $filteropts["queryinfo"][0]) === false) $fetchnext = true;
  451. }
  452.  
  453. break;
  454. }
  455. case "SELECT EXPORT":
  456. {
  457. if ($row !== false)
  458. {
  459. $opts = array($filteropts["table"], array());
  460. foreach ($row as $key => $val)
  461. {
  462. $opts[1][$key] = $val;
  463. unset($row->$key);
  464. }
  465.  
  466. $row->cmd = "INSERT";
  467. $row->opts = $opts;
  468. }
  469.  
  470. break;
  471. }
  472. }
  473. }
  474.  
  475. protected function ProcessColumnDefinition($info)
  476. {
  477. return array("success" => false, "error" => PDODB::DB_Translate("The base class ProcessColumnDefinition() was called."), "errorcode" => "wrong_class_used");
  478. }
  479.  
  480. protected function ProcessKeyDefinition($info)
  481. {
  482. return array("success" => false, "error" => PDODB::DB_Translate("The base class ProcessKeyDefinition() was called."), "errorcode" => "wrong_class_used");
  483. }
  484.  
  485. // Not intended to be overridden, just accessible to the parent.
  486. protected function ProcessSELECT(&$master, &$sql, &$opts, $queryinfo, $args, $subquery, $supported)
  487. {
  488. $sql = "SELECT";
  489. foreach ($supported["PRECOLUMN"] as $key => $mode)
  490. {
  491. if ($key != "SUBQUERIES" && isset($queryinfo[$key]))
  492. {
  493. if ($mode == "bool" && $queryinfo[$key]) $sql .= " " . $key;
  494. }
  495. }
  496.  
  497. if (is_array($queryinfo[0]))
  498. {
  499. foreach ($queryinfo[0] as $num => $col) $queryinfo[0][$num] = $this->QuoteIdentifier($col);
  500. $queryinfo[0] = implode(", ", $queryinfo[0]);
  501. }
  502.  
  503. if ($supported["PRECOLUMN"]["SUBQUERIES"] && isset($queryinfo["SUBQUERIES"]))
  504. {
  505. $result = $this->ProcessSubqueries($queryinfo[0], $master, $queryinfo["SUBQUERIES"]);
  506. if (!$result["success"]) return $result;
  507. }
  508.  
  509. $sql .= " " . $queryinfo[0];
  510.  
  511. if (isset($queryinfo["FROM"])) $queryinfo[1] = $queryinfo["FROM"];
  512.  
  513. if (isset($queryinfo[1]))
  514. {
  515. $prefix = (isset($supported["DBPREFIX"]) ? $supported["DBPREFIX"] : "");
  516.  
  517. $pos = strpos($queryinfo[1], "?");
  518. while ($pos !== false)
  519. {
  520. $queryinfo[1] = substr($queryinfo[1], 0, $pos) . $this->QuoteIdentifier($prefix . array_shift($args)) . substr($queryinfo[1], $pos + 1);
  521.  
  522. $pos = strpos($queryinfo[1], "?");
  523. }
  524.  
  525. if ($supported["FROM"]["SUBQUERIES"] && isset($queryinfo["SUBQUERIES"]))
  526. {
  527. $result = $this->ProcessSubqueries($queryinfo[1], $master, $queryinfo["SUBQUERIES"]);
  528. if (!$result["success"]) return $result;
  529. }
  530.  
  531. $sql .= " FROM " . $queryinfo[1];
  532. }
  533.  
  534. if (isset($queryinfo["WHERE"]))
  535. {
  536. if ($supported["WHERE"]["SUBQUERIES"] && isset($queryinfo["SUBQUERIES"]))
  537. {
  538. $result = $this->ProcessSubqueries($queryinfo["WHERE"], $master, $queryinfo["SUBQUERIES"]);
  539. if (!$result["success"]) return $result;
  540. }
  541.  
  542. $sql .= " WHERE " . $queryinfo["WHERE"];
  543. }
  544.  
  545. if (isset($supported["GROUP BY"]) && $supported["GROUP BY"] && isset($queryinfo["GROUP BY"])) $sql .= " GROUP BY " . $queryinfo["GROUP BY"];
  546. if (isset($supported["HAVING"]) && $supported["HAVING"] && isset($queryinfo["HAVING"])) $sql .= " HAVING " . $queryinfo["HAVING"];
  547. if (isset($supported["ORDER BY"]) && $supported["ORDER BY"] && isset($queryinfo["ORDER BY"])) $sql .= " ORDER BY " . $queryinfo["ORDER BY"];
  548. if (isset($supported["LIMIT"]) && $supported["LIMIT"] !== false && !$subquery && isset($queryinfo["LIMIT"]))
  549. {
  550. if (is_array($queryinfo["LIMIT"])) $queryinfo["LIMIT"] = implode($supported["LIMIT"], $queryinfo["LIMIT"]);
  551. $sql .= " LIMIT " . $queryinfo["LIMIT"];
  552. }
  553.  
  554. $opts = $args;
  555.  
  556. if (isset($queryinfo["EXPORT ROWS"])) return array("success" => true, "filter_opts" => array("mode" => "SELECT EXPORT", "table" => $queryinfo["EXPORT ROWS"]));
  557.  
  558. return array("success" => true);
  559. }
  560.  
  561. protected function ProcessINSERT(&$master, &$sql, &$opts, $queryinfo, $args, $subquery, $supported)
  562. {
  563. $master = true;
  564.  
  565. $sql = "INSERT";
  566. foreach ($supported["PREINTO"] as $key => $mode)
  567. {
  568. if (isset($queryinfo[$key]))
  569. {
  570. if ($mode == "bool" && $queryinfo[$key]) $sql .= " " . $key;
  571. }
  572. }
  573. $prefix = (isset($supported["DBPREFIX"]) ? $supported["DBPREFIX"] : "");
  574. $sql .= " INTO " . $this->QuoteIdentifier($prefix . $queryinfo[0]);
  575.  
  576. if (isset($queryinfo["FROM"])) $queryinfo[1] = $queryinfo["FROM"];
  577.  
  578. if (isset($queryinfo["SELECT"]))
  579. {
  580. if (!$supported["SELECT"]) return array("success" => false, PDODB::DB_Translate("INSERT INTO SELECT not supported."), "insert_select_unsupported");
  581.  
  582. if (isset($queryinfo[1]) && is_array($queryinfo[1]) && count($queryinfo[1]))
  583. {
  584. $keys = array();
  585. foreach ($queryinfo[1] as $key) $keys[] = $this->QuoteIdentifier($key);
  586. $sql .= " (" . implode(", ", $keys) . ")";
  587. }
  588.  
  589. $sql2 = "";
  590. $opts2 = array();
  591. $queryinfo2 = array_shift($queryinfo["SELECT"]);
  592. if (count($queryinfo["SELECT"]) == 1 && is_array($queryinfo["SELECT"][0])) $queryinfo["SELECT"] = $queryinfo["SELECT"][0];
  593. $result = $this->GenerateSQL($master, $sql2, $opts2, "SELECT", $queryinfo2, $queryinfo["SELECT"], false);
  594. if (!$result["success"]) return $result;
  595. $sql .= " " . $sql2;
  596. }
  597. else if (isset($queryinfo[1]) && is_array($queryinfo[1]) && count($queryinfo[1]))
  598. {
  599. $keys = array();
  600. $vals = array();
  601. foreach ($queryinfo[1] as $key => $val)
  602. {
  603. $keys[] = $this->QuoteIdentifier($key);
  604. $vals[] = "?";
  605. $args[] = $val;
  606. }
  607.  
  608. // Avoid this if possible.
  609. if (isset($queryinfo[2]))
  610. {
  611. foreach ($queryinfo[2] as $key => $val)
  612. {
  613. $keys[] = $this->QuoteIdentifier($key);
  614. $vals[] = $val;
  615. }
  616. }
  617. $sql .= " (" . implode(", ", $keys) . ") VALUES ";
  618. $origsql = $sql;
  619. $sql .= "(" . implode(", ", $vals) . ")";
  620.  
  621. // Handle bulk inserts.
  622. if (isset($queryinfo[3]) && isset($queryinfo[4]))
  623. {
  624. $bulkinsert = (isset($supported["BULKINSERT"]) && $supported["BULKINSERT"]);
  625. $bulkinsertlimit = (isset($supported["BULKINSERTLIMIT"]) ? $supported["BULKINSERTLIMIT"] : false);
  626. $sql = array($sql);
  627. $args = array($args);
  628. $lastpos = 0;
  629. for ($x = 3; isset($queryinfo[$x]) && isset($queryinfo[$x + 1]); $x += 2)
  630. {
  631. if (!$bulkinsert || ($bulkinsertlimit !== false && count($args[$lastpos]) + count($queryinfo[$x]) + count($queryinfo[$x + 1]) >= $bulkinsertlimit))
  632. {
  633. $sql[] = $origsql;
  634. $args[] = array();
  635. $lastpos++;
  636. }
  637. else
  638. {
  639. $sql[$lastpos] .= ", ";
  640. }
  641.  
  642. $vals = array();
  643. foreach ($queryinfo[$x] as $key => $val)
  644. {
  645. $vals[] = "?";
  646. $args[$lastpos][] = $val;
  647. }
  648.  
  649. // Avoid this if possible.
  650. foreach ($queryinfo[$x + 1] as $key => $val) $vals[] = $val;
  651.  
  652. $sql[$lastpos] .= "(" . implode(", ", $vals) . ")";
  653. }
  654. }
  655.  
  656. if (isset($supported["POSTVALUES"]) && !isset($queryinfo[3]))
  657. {
  658. foreach ($supported["POSTVALUES"] as $key => $mode)
  659. {
  660. if (isset($queryinfo[$key]))
  661. {
  662. if ($mode == "key_identifier" && isset($queryinfo[$key])) $sql .= " " . $key . " " . $this->QuoteIdentifier($queryinfo[$key]);
  663. }
  664. }
  665. }
  666. }
  667. else return array("success" => false, "error" => PDODB::DB_Translate("INSERT command is missing required option or parameter."), "errorcode" => "missing_option_or_parameter");
  668.  
  669. $opts = $args;
  670.  
  671. return array("success" => true);
  672. }
  673.  
  674. protected function ProcessUPDATE(&$master, &$sql, &$opts, $queryinfo, $args, $subquery, $supported)
  675. {
  676. $master = true;
  677.  
  678. $sql = "UPDATE";
  679. foreach ($supported["PRETABLE"] as $key => $mode)
  680. {
  681. if (isset($queryinfo[$key]))
  682. {
  683. if ($mode == "bool" && $queryinfo[$key]) $sql .= " " . $key;
  684. }
  685. }
  686. $prefix = (isset($supported["DBPREFIX"]) ? $supported["DBPREFIX"] : "");
  687. $sql .= " " . $this->QuoteIdentifier($prefix . $queryinfo[0]);
  688.  
  689. $set = array();
  690. $vals = array();
  691. foreach ($queryinfo[1] as $key => $val)
  692. {
  693. $set[] = $this->QuoteIdentifier($key) . " = " . (is_bool($val) ? ($val ? "DEFAULT" : "NULL") : "?");
  694. if (!is_bool($val)) $vals[] = $val;
  695. }
  696. $args = array_merge($vals, $args);
  697.  
  698. // Avoid this if possible.
  699. if (isset($queryinfo[2]))
  700. {
  701. foreach ($queryinfo[2] as $key => $val)
  702. {
  703. $set[] = $this->QuoteIdentifier($key) . " = " . $val;
  704. }
  705. }
  706.  
  707. $sql .= " SET " . implode(", ", $set);
  708.  
  709. if (isset($queryinfo["WHERE"]))
  710. {
  711. if ($supported["WHERE"]["SUBQUERIES"] && isset($queryinfo["SUBQUERIES"]))
  712. {
  713. $result = $this->ProcessSubqueries($queryinfo["WHERE"], $master, $queryinfo["SUBQUERIES"]);
  714. if (!$result["success"]) return $result;
  715. }
  716.  
  717. $sql .= " WHERE " . $queryinfo["WHERE"];
  718. }
  719. else
  720. {
  721. // Attempt to detect accidental 'WHERE = ...' clauses.
  722. foreach ($queryinfo as $key => $val)
  723. {
  724. if (is_int($key) && is_string($val) && strtoupper(substr($val, 0, 5)) === "WHERE") return array("success" => false, "error" => PDODB::DB_Translate("UPDATE command appears to have a WHERE in a value instead of a key. Query blocked to avoid an unintentional change to the entire table. Did you write 'WHERE something = ...' instead of 'WHERE' => 'something = ...'?"), "errorcode" => "query_blocked_where_clause");
  725. }
  726. }
  727.  
  728. if (isset($supported["ORDER BY"]) && $supported["ORDER BY"] && isset($queryinfo["ORDER BY"])) $sql .= " ORDER BY " . $queryinfo["ORDER BY"];
  729. if (isset($supported["LIMIT"]) && $supported["LIMIT"] !== false && !$subquery && isset($queryinfo["LIMIT"]))
  730. {
  731. if (is_array($queryinfo["LIMIT"])) $queryinfo["LIMIT"] = implode($supported["LIMIT"], $queryinfo["LIMIT"]);
  732. $sql .= " LIMIT " . $queryinfo["LIMIT"];
  733. }
  734.  
  735. $opts = $args;
  736.  
  737. return array("success" => true);
  738. }
  739.  
  740. protected function ProcessDELETE(&$master, &$sql, &$opts, $queryinfo, $args, $subquery, $supported)
  741. {
  742. $master = true;
  743.  
  744. $sql = "DELETE";
  745. foreach ($supported["PREFROM"] as $key => $mode)
  746. {
  747. if (isset($queryinfo[$key]))
  748. {
  749. if ($mode == "bool" && $queryinfo[$key]) $sql .= " " . $key;
  750. }
  751. }
  752. $prefix = (isset($supported["DBPREFIX"]) ? $supported["DBPREFIX"] : "");
  753. $sql .= " FROM " . $this->QuoteIdentifier($prefix . $queryinfo[0]);
  754.  
  755. if (isset($queryinfo["WHERE"]))
  756. {
  757. if ($supported["WHERE"]["SUBQUERIES"] && isset($queryinfo["SUBQUERIES"]))
  758. {
  759. $result = $this->ProcessSubqueries($queryinfo["WHERE"], $master, $queryinfo["SUBQUERIES"]);
  760. if (!$result["success"]) return $result;
  761. }
  762.  
  763. $sql .= " WHERE " . $queryinfo["WHERE"];
  764. }
  765. else
  766. {
  767. // Attempt to detect accidental 'WHERE = ...' clauses.
  768. foreach ($queryinfo as $key => $val)
  769. {
  770. if (is_int($key) && is_string($val) && strtoupper(substr($val, 0, 5)) === "WHERE") return array("success" => false, "error" => PDODB::DB_Translate("DELETE command appears to have a WHERE in a value instead of a key. Query blocked to avoid an unintentional deletion of all records in the entire table. Did you write 'WHERE something = ...' instead of 'WHERE' => 'something = ...'?"), "errorcode" => "query_blocked_where_clause");
  771. }
  772. }
  773.  
  774. if (isset($supported["ORDER BY"]) && $supported["ORDER BY"] && isset($queryinfo["ORDER BY"])) $sql .= " ORDER BY " . $queryinfo["ORDER BY"];
  775. if (isset($supported["LIMIT"]) && $supported["LIMIT"] !== false && !$subquery && isset($queryinfo["LIMIT"]))
  776. {
  777. if (is_array($queryinfo["LIMIT"])) $queryinfo["LIMIT"] = implode($supported["LIMIT"], $queryinfo["LIMIT"]);
  778. $sql .= " LIMIT " . $queryinfo["LIMIT"];
  779. }
  780.  
  781. $opts = $args;
  782.  
  783. return array("success" => true);
  784. }
  785.  
  786. protected function ProcessCREATE_TABLE(&$master, &$sql, &$opts, $queryinfo, $args, $subquery, $supported)
  787. {
  788. $master = true;
  789.  
  790. if (isset($supported["TEMPORARY"]) && isset($queryinfo["TEMPORARY"]) && $queryinfo["TEMPORARY"]) $cmd = $supported["TEMPORARY"];
  791. else $cmd = "CREATE TABLE";
  792. $prefix = (isset($supported["DBPREFIX"]) ? $supported["DBPREFIX"] : "");
  793. $sql = $cmd . " " . $this->QuoteIdentifier($prefix . $queryinfo[0]);
  794.  
  795. if (isset($queryinfo["SELECT"]))
  796. {
  797. if (!isset($supported["AS_SELECT"]) || !$supported["AS_SELECT"]) return array("success" => false, PDODB::DB_Translate("CREATE TABLE AS SELECT not supported."), "create_table_select_unsupported");
  798.  
  799. $sql2 = "";
  800. $opts2 = array();
  801. $queryinfo2 = array_shift($queryinfo["SELECT"]);
  802. if (count($queryinfo["SELECT"]) == 1 && is_array($queryinfo["SELECT"][0])) $queryinfo["SELECT"] = $queryinfo["SELECT"][0];
  803. $result = $this->GenerateSQL($master, $sql2, $opts2, "SELECT", $queryinfo2, $queryinfo["SELECT"], false);
  804. if (!$result["success"]) return $result;
  805.  
  806. if (isset($supported["PRE_AS"]))
  807. {
  808. foreach ($supported["PRE_AS"] as $key => $mode)
  809. {
  810. if (isset($queryinfo[$key]))
  811. {
  812. if ($mode == "bool" && $queryinfo[$key]) $sql .= " " . $key;
  813. }
  814. }
  815. }
  816.  
  817. $sql .= " AS " . $sql2;
  818. }
  819. else
  820. {
  821. $sql2 = array();
  822. foreach ($queryinfo[1] as $key => $info)
  823. {
  824. $sql3 = $this->QuoteIdentifier($key);
  825. $result = $this->ProcessColumnDefinition($info);
  826. if (!$result["success"]) return $result;
  827.  
  828. $sql2[] = $sql3 . $result["sql"];
  829. }
  830.  
  831. if (isset($supported["PROCESSKEYS"]) && $supported["PROCESSKEYS"] && isset($queryinfo[2]) && is_array($queryinfo[2]))
  832. {
  833. foreach ($queryinfo[2] as $info)
  834. {
  835. $result = $this->ProcessKeyDefinition($info);
  836. if (!$result["success"]) return $result;
  837.  
  838. if ($result["sql"] != "") $sql2[] = $result["sql"];
  839. }
  840. }
  841.  
  842. $sql .= " (\n";
  843. if (count($sql2)) $sql .= "\t" . implode(",\n\t", $sql2) . "\n";
  844. $sql .= ")";
  845. foreach ($supported["POSTCREATE"] as $key => $mode)
  846. {
  847. if (isset($queryinfo[$key]))
  848. {
  849. if ($mode == "bool" && $queryinfo[$key]) $sql .= " " . $key;
  850. else if ($mode == "string") $sql .= " " . $key . " " . $queryinfo[$key];
  851. }
  852. }
  853. }
  854.  
  855. $opts = $args;
  856.  
  857. return array("success" => true);
  858. }
  859.  
  860. protected function ProcessReferenceDefinition($info)
  861. {
  862. foreach ($info[1] as $num => $colname) $info[1][$num] = $this->QuoteIdentifier($colname);
  863. $sql = $this->QuoteIdentifier($info[0]) . " (" . implode(", ", $info[1]) . ")";
  864. if (isset($info["MATCH FULL"]) && $info["MATCH FULL"]) $sql .= " MATCH FULL";
  865. else if (isset($info["MATCH PARTIAL"]) && $info["MATCH PARTIAL"]) $sql .= " MATCH PARTIAL";
  866. else if (isset($info["MATCH SIMPLE"]) && $info["MATCH SIMPLE"]) $sql .= " MATCH SIMPLE";
  867. if (isset($info["ON DELETE"])) $sql .= " ON DELETE " . $info["ON DELETE"];
  868. if (isset($info["ON UPDATE"])) $sql .= " ON UPDATE " . $info["ON UPDATE"];
  869.  
  870. return $sql;
  871. }
  872.  
  873. protected static function DB_Translate()
  874. {
  875. $args = func_get_args();
  876. if (!count($args)) return "";
  877.  
  878. return call_user_func_array((defined("CS_TRANSLATE_FUNC") && function_exists(CS_TRANSLATE_FUNC) ? CS_TRANSLATE_FUNC : "sprintf"), $args);
  879. }
  880. }
  881.  
  882. class PDODB_PDO_Statement
  883. {
  884. private $db, $stmt, $filteropts;
  885.  
  886. function __construct($db, $stmt, $filteropts)
  887. {
  888. $this->db = $db;
  889. $this->stmt = $stmt;
  890. $this->filteropts = $filteropts;
  891. }
  892.  
  893. function __destruct()
  894. {
  895. $this->Free();
  896. }
  897.  
  898. function Free()
  899. {
  900. if ($this->stmt === false) return false;
  901.  
  902. $this->stmt = false;
  903.  
  904. return true;
  905. }
  906.  
  907. function NextRow($fetchtype = PDO::FETCH_OBJ)
  908. {
  909. if ($this->stmt === false && $this->filteropts === false) return false;
  910.  
  911. do
  912. {
  913. $fetchnext = false;
  914. $result = ($this->stmt !== false ? $this->stmt->fetch($this->filteropts === false ? $fetchtype : PDO::FETCH_OBJ) : false);
  915. if ($this->filteropts !== false) $this->db->RunRowFilter($result, $this->filteropts, $fetchnext);
  916. } while ($result !== false && $fetchnext);
  917.  
  918. if ($result === false) $this->Free();
  919. else if ($this->filteropts !== false && $fetchtype != PDO::FETCH_OBJ)
  920. {
  921. $result2 = array();
  922. foreach ($result as $key => $val)
  923. {
  924. if ($fetchtype == PDO::FETCH_NUM || $fetchtype == PDO::FETCH_BOTH) $result2[] = $val;
  925. if ($fetchtype == PDO::FETCH_ASSOC || $fetchtype == PDO::FETCH_BOTH) $result2[$key] = $val;
  926. }
  927.  
  928. $result = $result2;
  929. }
  930.  
  931. return $result;
  932. }
  933. }
  934. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement