PageRenderTime 60ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/phpmyadmin/libraries/dbi/drizzle-wrappers.lib.php

https://bitbucket.org/adarshj/convenient_website
PHP | 442 lines | 208 code | 29 blank | 205 comment | 19 complexity | 39b20081100b008253179e9d9eee08f1 MD5 | raw file
Possible License(s): Apache-2.0, MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-2-Clause, GPL-2.0, LGPL-3.0
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Wrappers for Drizzle extension classes
  5. *
  6. * Drizzle extension exposes libdrizzle functions and requires user to have it in mind while using them.
  7. * This wrapper is not complete and hides a lot of original functionality, but allows for easy usage
  8. * of the drizzle PHP extension.
  9. *
  10. * @package PhpMyAdmin-DBI-Drizzle
  11. */
  12. // TODO: drizzle module segfaults while freeing resources, often. This allows at least for some development
  13. function _drizzle_shutdown_flush() {
  14. flush();
  15. }
  16. register_shutdown_function('_drizzle_shutdown_flush');
  17. function _dlog_argstr($args)
  18. {
  19. $r = array();
  20. foreach ($args as $arg) {
  21. if (is_object($arg)) {
  22. $r[] = get_class($arg);
  23. } elseif (is_bool($arg)) {
  24. $r[] = $arg ? 'true' : 'false';
  25. } elseif (is_null($arg)) {
  26. $r[] = 'null';
  27. } else {
  28. $r[] = $arg;
  29. }
  30. }
  31. return implode(', ', $r);
  32. }
  33. function _dlog($end = false)
  34. {
  35. /*
  36. static $fp = null;
  37. if (!$fp) {
  38. $fp = fopen('./drizzle_log.log', 'a');
  39. flock($fp, LOCK_EX);
  40. fwrite($fp, "\r\n[" . date('H:i:s') . "]\t" . $_SERVER['REQUEST_URI'] . "\r\n");
  41. register_shutdown_function(function() use ($fp) {
  42. fwrite($fp, '[' . date('H:i:s') . "]\tEND\r\n\r\n");
  43. });
  44. }
  45. if ($end) {
  46. fwrite($fp, '[' . date('H:i:s') . "]\tok\r\n");
  47. } else {
  48. $bt = debug_backtrace(true);
  49. $caller = (isset($bt[1]['class']) ? $bt[1]['class'] . '::' : '') . $bt[1]['function'];
  50. if ($bt[1]['function'] == '__call') {
  51. $caller .= '^' . $bt[1]['args'][0];
  52. $args = _dlog_argstr($bt[1]['args'][1]);
  53. } else {
  54. $args = _dlog_argstr($bt[1]['args']);
  55. }
  56. fwrite($fp, '[' . date('H:i:s') . "]\t" . $caller . "\t" . $args . "\r\n");
  57. for ($i = 2; $i <= count($bt)-1; $i++) {
  58. if (!isset($bt[$i])) {
  59. break;
  60. }
  61. $caller = (isset($bt[$i]['class']) ? $bt[$i]['class'] . '::' : '') . $bt[$i]['function'];
  62. $caller .= ' (' . $bt[$i]['file'] . ':' . $bt[$i]['line'] . ')';
  63. fwrite($fp, str_repeat(' ', 20) . $caller . "\r\n");
  64. }
  65. }
  66. //*/
  67. }
  68. /**
  69. * Wrapper for Drizzle class
  70. */
  71. class PMA_Drizzle extends Drizzle
  72. {
  73. /**
  74. * Fetch mode: result rows contain column names
  75. */
  76. const FETCH_ASSOC = 1;
  77. /**
  78. * Fetch mode: result rows contain only numeric indices
  79. */
  80. const FETCH_NUM = 2;
  81. /**
  82. * Fetch mode: result rows have both column names and numeric indices
  83. */
  84. const FETCH_BOTH = 3;
  85. /**
  86. * Result buffering: entire result set is buffered upon execution
  87. */
  88. const BUFFER_RESULT = 1;
  89. /**
  90. * Result buffering: buffering occurs only on row level
  91. */
  92. const BUFFER_ROW = 2;
  93. /**
  94. * Constructor
  95. */
  96. public function __construct()
  97. {_dlog();
  98. parent::__construct();
  99. }
  100. /**
  101. * Creates a new database conection using TCP
  102. *
  103. * @param $host
  104. * @param $port
  105. * @param $user
  106. * @param $password
  107. * @param $db
  108. * @param $options
  109. * @return PMA_DrizzleCon
  110. */
  111. public function addTcp($host, $port, $user, $password, $db, $options)
  112. {_dlog();
  113. $dcon = parent::addTcp($host, $port, $user, $password, $db, $options);
  114. return $dcon instanceof DrizzleCon
  115. ? new PMA_DrizzleCon($dcon)
  116. : $dcon;
  117. }
  118. /**
  119. * Creates a new connection using unix domain socket
  120. *
  121. * @param $uds
  122. * @param $user
  123. * @param $password
  124. * @param $db
  125. * @param $options
  126. * @return PMA_DrizzleCon
  127. */
  128. public function addUds($uds, $user, $password, $db, $options)
  129. {_dlog();
  130. $dcon = parent::addUds($uds, $user, $password, $db, $options);
  131. return $dcon instanceof DrizzleCon
  132. ? new PMA_DrizzleCon($dcon)
  133. : $dcon;
  134. }
  135. }
  136. /**
  137. * Wrapper around DrizzleCon class
  138. *
  139. * Its main task is to wrap results with PMA_DrizzleResult class
  140. */
  141. class PMA_DrizzleCon
  142. {
  143. /**
  144. * Instance of DrizzleCon class
  145. * @var DrizzleCon
  146. */
  147. private $dcon;
  148. /**
  149. * Result of the most recent query
  150. * @var PMA_DrizzleResult
  151. */
  152. private $lastResult;
  153. /**
  154. * Constructor
  155. *
  156. * @param DrizzleCon $dcon
  157. */
  158. public function __construct(DrizzleCon $dcon)
  159. {_dlog();
  160. $this->dcon = $dcon;
  161. }
  162. /**
  163. * Executes given query. Opens database connection if not already done.
  164. *
  165. * @param string $query
  166. * @param int $bufferMode PMA_Drizzle::BUFFER_RESULT, PMA_Drizzle::BUFFER_ROW
  167. * @param int $fetchMode PMA_Drizzle::FETCH_ASSOC, PMA_Drizzle::FETCH_NUM or PMA_Drizzle::FETCH_BOTH
  168. * @return PMA_DrizzleResult
  169. */
  170. public function query($query, $bufferMode = PMA_Drizzle::BUFFER_RESULT, $fetchMode = PMA_Drizzle::FETCH_ASSOC)
  171. {_dlog();
  172. $result = $this->dcon->query($query);
  173. if ($result instanceof DrizzleResult) {
  174. _dlog(true);
  175. $this->lastResult = new PMA_DrizzleResult($result, $bufferMode, $fetchMode);
  176. return $this->lastResult;
  177. }
  178. return $result;
  179. }
  180. /**
  181. * Returns the number of rows affected by last query
  182. *
  183. * @return int|false
  184. */
  185. public function affectedRows()
  186. {
  187. return $this->lastResult
  188. ? $this->lastResult->affectedRows()
  189. : false;
  190. }
  191. /**
  192. * Pass calls of undefined methods to DrizzleCon object
  193. *
  194. * @param $method
  195. * @param $args
  196. * @return mixed
  197. */
  198. public function __call($method, $args)
  199. {_dlog();
  200. return call_user_func_array(array($this->dcon, $method), $args);
  201. }
  202. /**
  203. * Returns original Drizzle connection object
  204. *
  205. * @return DrizzleCon
  206. */
  207. public function getConnectionObject()
  208. {_dlog();
  209. return $this->dcon;
  210. }
  211. }
  212. /**
  213. * Wrapper around DrizzleResult. Allows for reading result rows as an associative array
  214. * and hides complexity behind buffering.
  215. */
  216. class PMA_DrizzleResult
  217. {
  218. /**
  219. * Instamce of DrizzleResult class
  220. * @var DrizzleResult
  221. */
  222. private $dresult;
  223. /**
  224. * Fetch mode
  225. * @var int
  226. */
  227. private $fetchMode;
  228. /**
  229. * Buffering mode
  230. * @var int
  231. */
  232. private $bufferMode;
  233. /**
  234. * Cached column data
  235. * @var DrizzleColumn[]
  236. */
  237. private $columns = null;
  238. /**
  239. * Cached column names
  240. * @var string[]
  241. */
  242. private $columnNames = null;
  243. /**
  244. * Constructor
  245. *
  246. * @param DrizzleResult $dresult
  247. * @param int $bufferMode
  248. * @param int $fetchMode
  249. */
  250. public function __construct(DrizzleResult $dresult, $bufferMode, $fetchMode)
  251. {_dlog();
  252. $this->dresult = $dresult;
  253. $this->bufferMode = $bufferMode;
  254. $this->fetchMode = $fetchMode;
  255. if ($this->bufferMode == PMA_Drizzle::BUFFER_RESULT) {
  256. $this->dresult->buffer();
  257. }
  258. }
  259. /**
  260. * Sets fetch mode
  261. *
  262. * @param int $fetchMode
  263. */
  264. public function setFetchMode($fetchMode)
  265. {_dlog();
  266. $this->fetchMode = $fetchMode;
  267. }
  268. /**
  269. * Reads information about columns contained in current result set into {@see $columns} and {@see $columnNames} arrays
  270. */
  271. private function _readColumns()
  272. {_dlog();
  273. $this->columns = array();
  274. $this->columnNames = array();
  275. if ($this->bufferMode == PMA_Drizzle::BUFFER_RESULT) {
  276. while (($column = $this->dresult->columnNext()) !== null) {
  277. $this->columns[] = $column;
  278. $this->columnNames[] = $column->name();
  279. }
  280. } else {
  281. while (($column = $this->dresult->columnRead()) !== null) {
  282. $this->columns[] = $column;
  283. $this->columnNames[] = $column->name();
  284. }
  285. }
  286. }
  287. /**
  288. * Returns columns in current result
  289. *
  290. * @return DrizzleColumn[]
  291. */
  292. public function getColumns()
  293. {_dlog();
  294. if (!$this->columns) {
  295. $this->_readColumns();
  296. }
  297. return $this->columns;
  298. }
  299. /**
  300. * Returns number if columns in result
  301. *
  302. * @return int
  303. */
  304. public function numColumns()
  305. {_dlog();
  306. return $this->dresult->columnCount();
  307. }
  308. /**
  309. * Transforms result row to conform to current fetch mode
  310. *
  311. * @param mixed &$row
  312. * @param int $fetchMode
  313. */
  314. private function _transformResultRow(&$row, $fetchMode)
  315. {
  316. if (!$row) {
  317. return;
  318. }
  319. switch ($fetchMode) {
  320. case PMA_Drizzle::FETCH_ASSOC:
  321. $row = array_combine($this->columnNames, $row);
  322. break;
  323. case PMA_Drizzle::FETCH_BOTH:
  324. $length = count($row);
  325. for ($i = 0; $i < $length; $i++) {
  326. $row[$this->columnNames[$i]] = $row[$i];
  327. }
  328. break;
  329. default:
  330. break;
  331. }
  332. }
  333. /**
  334. * Fetches next for from this result set
  335. *
  336. * @param int $fetchMode fetch mode to use, if none given the default one is used
  337. * @return array|null
  338. */
  339. public function fetchRow($fetchMode = null)
  340. {_dlog();
  341. // read column names on first fetch, only buffered results allow for reading it later
  342. if (!$this->columns) {
  343. $this->_readColumns();
  344. }
  345. if ($fetchMode === null) {
  346. $fetchMode = $this->fetchMode;
  347. }
  348. $row = null;
  349. switch ($this->bufferMode) {
  350. case PMA_Drizzle::BUFFER_RESULT:
  351. $row = $this->dresult->rowNext();
  352. break;
  353. case PMA_Drizzle::BUFFER_ROW:
  354. $row = $this->dresult->rowBuffer();
  355. break;
  356. }
  357. $this->_transformResultRow($row, $fetchMode);
  358. return $row;
  359. }
  360. /**
  361. * Adjusts the result pointer to an arbitrary row in buffered result
  362. *
  363. * @param $row_index
  364. * @return bool
  365. */
  366. public function seek($row_index)
  367. {_dlog();
  368. if ($this->bufferMode != PMA_Drizzle::BUFFER_RESULT) {
  369. trigger_error("Can't seek in an unbuffered result set", E_USER_WARNING);
  370. return false;
  371. }
  372. // rowSeek always returns NULL (drizzle extension v.0.5, API v.7)
  373. if ($row_index >= 0 && $row_index < $this->dresult->rowCount()) {
  374. $this->dresult->rowSeek($row_index);
  375. return true;
  376. }
  377. return false;
  378. }
  379. /**
  380. * Returns the number of rows in buffered result set
  381. *
  382. * @return int|false
  383. */
  384. public function numRows()
  385. {_dlog();
  386. if ($this->bufferMode != PMA_Drizzle::BUFFER_RESULT) {
  387. trigger_error("Can't count rows in an unbuffered result set", E_USER_WARNING);
  388. return false;
  389. }
  390. return $this->dresult->rowCount();
  391. }
  392. /**
  393. * Returns the number of rows affected by query
  394. *
  395. * @return int|false
  396. */
  397. public function affectedRows()
  398. {_dlog();
  399. return $this->dresult->affectedRows();
  400. }
  401. /**
  402. * Frees resources taken by this result
  403. */
  404. public function free()
  405. {_dlog();
  406. unset($this->columns);
  407. unset($this->columnNames);
  408. drizzle_result_free($this->dresult);
  409. unset($this->dresult);
  410. }
  411. }