Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. /*
  3. Copyright 2011 Aldo Gonzalez. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without modification, are
  5. permitted provided that the following conditions are met:
  6. 1. Redistributions of source code must retain the above copyright notice, this list of
  7. conditions and the following disclaimer.
  8. 2. Redistributions in binary form must reproduce the above copyright notice, this list
  9. of conditions and the following disclaimer in the documentation and/or other materials
  10. provided with the distribution.
  11. THIS SOFTWARE IS PROVIDED BY Aldo Gonzalez ''AS IS'' AND ANY EXPRESS OR IMPLIED
  12. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  13. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <copyright HOLDER> OR
  14. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  15. CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  16. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  17. ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  18. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  19. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  20. The views and conclusions contained in the software and documentation are those of the
  21. authors and should not be interpreted as representing official policies, either expressed
  22. or implied, of Aldo Gonzalez.
  23. */
  24. /**
  25. * Extends PDO to ensure compatibility with some used functionality from PEAR::MDB2
  26. *
  27. * @package Poweradmin
  28. * @copyright 2011 Aldo Gonzalez
  29. * @license http://opensource.org/licenses/BSD-2-Clause BSD
  30. */
  31. /**
  32. * MDB2 over PDO
  33. */
  34. class PDOStatementCommon {
  35. /**
  36. * Internal resource
  37. * @var mixed
  38. */
  39. private $pdoStatement;
  40. /**
  41. * Class constructor
  42. *
  43. * @param mixed $obj
  44. */
  45. public function __construct($obj) {
  46. $this->pdoStatement = $obj;
  47. }
  48. /**
  49. * Returns the number of rows in a result object
  50. *
  51. * @return int
  52. */
  53. public function numRows() {
  54. // NOTE: Doesn't work properly with PDO and SQLite3
  55. return $this->pdoStatement->rowCount();
  56. }
  57. /**
  58. * Fetch and return a row of data
  59. *
  60. * @param int $fetch_style
  61. * @return mixed
  62. */
  63. public function fetch($fetch_style = PDO::FETCH_ASSOC) {
  64. return $this->pdoStatement->fetch($fetch_style);
  65. }
  66. /**
  67. * Fetch and return a row of data
  68. *
  69. * @param int $fetch_style
  70. * @return mixed
  71. */
  72. public function fetchRow($fetch_style = PDO::FETCH_ASSOC) {
  73. $row = $this->pdoStatement->fetch($fetch_style);
  74. return $row;
  75. }
  76. }
  77. /**
  78. * Implements common PDO methods
  79. */
  80. class PDOCommon extends PDO {
  81. /**
  82. * result limit used in the next query
  83. * @var int
  84. */
  85. private $limit = 0;
  86. /**
  87. * result offset used in the next query
  88. * @var int
  89. */
  90. private $from = 0;
  91. /**
  92. * PDOCommon constructor
  93. *
  94. * @param string $dsn
  95. * @param string $username
  96. * @param string $password
  97. * @param array $driver_options
  98. * @param boolean $isQuiet
  99. */
  100. public function __construct($dsn, $username = '', $password = '', $driver_options = array(), $isQuiet = false) {
  101. try {
  102. parent::__construct($dsn, $username, $password, $driver_options);
  103. } catch (Exception $e) {
  104. error_log($e->getMessage());
  105. if ($isQuiet) {
  106. die();
  107. } else {
  108. die("Unable to connect to the database server. " .
  109. "Please report the problem to an Administrator.");
  110. }
  111. }
  112. $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  113. // only allow one statement per query
  114. // should check that this attribute is only set on
  115. // mysql databases
  116. if ($this->getAttribute(PDO::ATTR_DRIVER_NAME) == "mysql") {
  117. $this->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, false);
  118. }
  119. }
  120. /**
  121. * Send a query to the database and return any results
  122. *
  123. * @param string $str
  124. * @return \PDOStatementCommon
  125. */
  126. public function query($str) {
  127. // check if limit has been specified. if so, modify the query
  128. if (!empty($this->limit)) {
  129. $str .= " LIMIT " . $this->limit;
  130. if (!empty($this->from)) {
  131. $str .= " OFFSET " . $this->from;
  132. }
  133. // after a query is executed the limits are reset, so that
  134. // other queries may be performed with the same object
  135. $this->limit = 0;
  136. $this->from = 0;
  137. }
  138. try {
  139. $obj_pdoStatement = parent::query($str);
  140. } catch (Exception $e) {
  141. error_log("[* SQL ERROR MESSAGE FOLLOWS:\n" .
  142. $e->getTraceAsString() .
  143. "\n" . $e->getMessage() .
  144. "\nFull SQL Statement:" . $str .
  145. "\n*]");
  146. die("<b>An error occurred while executing the SQL statement. " .
  147. "Please contact an Administrator and report the problem.</b>" .
  148. "<br /><hr />The following query generated an error:<br />" .
  149. "<pre>" .
  150. $this->formatSQLforHTML($str) .
  151. "\n\n" . $e->getMessage() .
  152. "</pre>");
  153. }
  154. $obj_pdoStatementCommon = new PDOStatementCommon($obj_pdoStatement);
  155. return $obj_pdoStatementCommon;
  156. }
  157. /**
  158. * Return an HTML formatted SQL string
  159. *
  160. * @param string $str
  161. * @return string
  162. */
  163. protected function formatSQLforHTML($str) {
  164. $Keyword = array("SELECT ", "WHERE ", " ON ", "AND ", "OR ",
  165. "FROM ", "LIMIT ", "UNION ",
  166. "INNER ", "LEFT ", "RIGHT ", "JOIN ", ",",
  167. "GROUP BY ", "ORDER BY ", "HAVING ");
  168. foreach ($Keyword as $key => $value) {
  169. if ($value == ",") {
  170. $Replace[$key] = "<b>" . $value . "</b>\n";
  171. } else {
  172. $Replace[$key] = "\n<b>" . $value . "</b>";
  173. }
  174. }
  175. return str_replace($Keyword, $Replace, $str);
  176. }
  177. /**
  178. * Execute the specified query, fetch the value from the first column of
  179. * the the first result row
  180. *
  181. * @param string $str
  182. * @return array
  183. */
  184. public function queryOne($str) {
  185. $result = $this->query($str);
  186. $row = $result->fetch(PDO::FETCH_NUM);
  187. return $row[0];
  188. }
  189. /**
  190. * Execute the specified query, fetch values from first result row
  191. *
  192. * @param string $str
  193. * @return mixed
  194. */
  195. public function queryRow($str) {
  196. $obj_pdoStatement = parent::query($str);
  197. return $obj_pdoStatement->fetch(PDO::FETCH_ASSOC);
  198. }
  199. /**
  200. * Set the range of the next query
  201. *
  202. * @param int $limit
  203. * @param int $from
  204. */
  205. public function setLimit($limit, $from = 0) {
  206. $this->limit = $limit;
  207. $this->from = $from;
  208. }
  209. /**
  210. * Quotes a string so it can be safely used in a query.
  211. *
  212. * @param string $str
  213. * @return string
  214. */
  215. public function escape($str) {
  216. return $this->quote($str);
  217. }
  218. }