Translation update done using Pootle.
[phpmyadmin/madhuracj.git] / libraries / dbi / drizzle-wrappers.lib.php
blob844128529d405a4d163eafece08ca700e46b7426
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Wrappers for Drizzle extension classes
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.
10 * @package PhpMyAdmin-DBI-Drizzle
13 // TODO: drizzle module segfaults while freeing resources, often. This allows at least for some development
14 function _drizzle_shutdown_flush() {
15 flush();
17 register_shutdown_function('_drizzle_shutdown_flush');
19 function _dlog_argstr($args)
21 $r = array();
22 foreach ($args as $arg) {
23 if (is_object($arg)) {
24 $r[] = get_class($arg);
25 } elseif (is_bool($arg)) {
26 $r[] = $arg ? 'true' : 'false';
27 } elseif (is_null($arg)) {
28 $r[] = 'null';
29 } else {
30 $r[] = $arg;
33 return implode(', ', $r);
36 function _dlog($end = false)
39 static $fp = null;
41 if (!$fp) {
42 $fp = fopen('./drizzle_log.log', 'a');
43 flock($fp, LOCK_EX);
44 fwrite($fp, "\r\n[" . date('H:i:s') . "]\t" . $_SERVER['REQUEST_URI'] . "\r\n");
45 register_shutdown_function(function() use ($fp) {
46 fwrite($fp, '[' . date('H:i:s') . "]\tEND\r\n\r\n");
47 });
49 if ($end) {
50 fwrite($fp, '[' . date('H:i:s') . "]\tok\r\n");
51 } else {
52 $bt = debug_backtrace(true);
53 $caller = (isset($bt[1]['class']) ? $bt[1]['class'] . '::' : '') . $bt[1]['function'];
54 if ($bt[1]['function'] == '__call') {
55 $caller .= '^' . $bt[1]['args'][0];
56 $args = _dlog_argstr($bt[1]['args'][1]);
57 } else {
58 $args = _dlog_argstr($bt[1]['args']);
60 fwrite($fp, '[' . date('H:i:s') . "]\t" . $caller . "\t" . $args . "\r\n");
61 for ($i = 2; $i <= count($bt)-1; $i++) {
62 if (!isset($bt[$i])) {
63 break;
65 $caller = (isset($bt[$i]['class']) ? $bt[$i]['class'] . '::' : '') . $bt[$i]['function'];
66 $caller .= ' (' . $bt[$i]['file'] . ':' . $bt[$i]['line'] . ')';
67 fwrite($fp, str_repeat(' ', 20) . $caller . "\r\n");
70 //*/
73 /**
74 * Wrapper for Drizzle class
76 class PMA_Drizzle extends Drizzle
78 /**
79 * Fetch mode: result rows contain column names
81 const FETCH_ASSOC = 1;
82 /**
83 * Fetch mode: result rows contain only numeric indices
85 const FETCH_NUM = 2;
86 /**
87 * Fetch mode: result rows have both column names and numeric indices
89 const FETCH_BOTH = 3;
91 /**
92 * Result buffering: entire result set is buffered upon execution
94 const BUFFER_RESULT = 1;
95 /**
96 * Result buffering: buffering occurs only on row level
98 const BUFFER_ROW = 2;
101 * Constructor
103 public function __construct()
104 {_dlog();
105 parent::__construct();
109 * Creates a new database conection using TCP
111 * @param $host
112 * @param $port
113 * @param $user
114 * @param $password
115 * @param $db
116 * @param $options
117 * @return PMA_DrizzleCon
119 public function addTcp($host, $port, $user, $password, $db, $options)
120 {_dlog();
121 $dcon = parent::addTcp($host, $port, $user, $password, $db, $options);
122 return $dcon instanceof DrizzleCon
123 ? new PMA_DrizzleCon($dcon)
124 : $dcon;
128 * Creates a new connection using unix domain socket
130 * @param $uds
131 * @param $user
132 * @param $password
133 * @param $db
134 * @param $options
135 * @return PMA_DrizzleCon
137 public function addUds($uds, $user, $password, $db, $options)
138 {_dlog();
139 $dcon = parent::addUds($uds, $user, $password, $db, $options);
140 return $dcon instanceof DrizzleCon
141 ? new PMA_DrizzleCon($dcon)
142 : $dcon;
147 * Wrapper around DrizzleCon class
149 * Its main task is to wrap results with PMA_DrizzleResult class
151 class PMA_DrizzleCon
154 * Instance of DrizzleCon class
155 * @var DrizzleCon
157 private $dcon;
160 * Result of the most recent query
161 * @var PMA_DrizzleResult
163 private $lastResult;
166 * Constructor
168 * @param DrizzleCon $dcon
170 public function __construct(DrizzleCon $dcon)
171 {_dlog();
172 $this->dcon = $dcon;
176 * Executes given query. Opens database connection if not already done.
178 * @param string $query
179 * @param int $bufferMode PMA_Drizzle::BUFFER_RESULT, PMA_Drizzle::BUFFER_ROW
180 * @param int $fetchMode PMA_Drizzle::FETCH_ASSOC, PMA_Drizzle::FETCH_NUM or PMA_Drizzle::FETCH_BOTH
181 * @return PMA_DrizzleResult
183 public function query($query, $bufferMode = PMA_Drizzle::BUFFER_RESULT, $fetchMode = PMA_Drizzle::FETCH_ASSOC)
184 {_dlog();
185 $result = $this->dcon->query($query);
186 if ($result instanceof DrizzleResult) {
187 _dlog(true);
188 $this->lastResult = new PMA_DrizzleResult($result, $bufferMode, $fetchMode);
189 return $this->lastResult;
191 return $result;
195 * Returns the number of rows affected by last query
197 * @return int|false
199 public function affectedRows()
201 return $this->lastResult
202 ? $this->lastResult->affectedRows()
203 : false;
207 * Pass calls of undefined methods to DrizzleCon object
209 * @param $method
210 * @param $args
211 * @return mixed
213 public function __call($method, $args)
214 {_dlog();
215 return call_user_func_array(array($this->dcon, $method), $args);
219 * Returns original Drizzle connection object
221 * @return DrizzleCon
223 public function getConnectionObject()
224 {_dlog();
225 return $this->dcon;
230 * Wrapper around DrizzleResult. Allows for reading result rows as an associative array
231 * and hides complexity behind buffering.
233 class PMA_DrizzleResult
236 * Instamce of DrizzleResult class
237 * @var DrizzleResult
239 private $dresult;
241 * Fetch mode
242 * @var int
244 private $fetchMode;
246 * Buffering mode
247 * @var int
249 private $bufferMode;
252 * Cached column data
253 * @var DrizzleColumn[]
255 private $columns = null;
257 * Cached column names
258 * @var string[]
260 private $columnNames = null;
263 * Constructor
265 * @param DrizzleResult $dresult
266 * @param int $bufferMode
267 * @param int $fetchMode
269 public function __construct(DrizzleResult $dresult, $bufferMode, $fetchMode)
270 {_dlog();
271 $this->dresult = $dresult;
272 $this->bufferMode = $bufferMode;
273 $this->fetchMode = $fetchMode;
275 if ($this->bufferMode == PMA_Drizzle::BUFFER_RESULT) {
276 $this->dresult->buffer();
281 * Sets fetch mode
283 * @param int $fetchMode
285 public function setFetchMode($fetchMode)
286 {_dlog();
287 $this->fetchMode = $fetchMode;
291 * Reads information about columns contained in current result set into {@see $columns} and {@see $columnNames} arrays
293 private function _readColumns()
294 {_dlog();
295 $this->columns = array();
296 $this->columnNames = array();
297 if ($this->bufferMode == PMA_Drizzle::BUFFER_RESULT) {
298 while (($column = $this->dresult->columnNext()) !== null) {
299 $this->columns[] = $column;
300 $this->columnNames[] = $column->name();
302 } else {
303 while (($column = $this->dresult->columnRead()) !== null) {
304 $this->columns[] = $column;
305 $this->columnNames[] = $column->name();
311 * Returns columns in current result
313 * @return DrizzleColumn[]
315 public function getColumns()
316 {_dlog();
317 if (!$this->columns) {
318 $this->_readColumns();
320 return $this->columns;
324 * Returns number if columns in result
326 * @return int
328 public function numColumns()
329 {_dlog();
330 return $this->dresult->columnCount();
334 * Transforms result row to conform to current fetch mode
336 * @param mixed &$row
337 * @param int $fetchMode
339 private function _transformResultRow(&$row, $fetchMode)
341 if (!$row) {
342 return;
345 switch ($fetchMode) {
346 case PMA_Drizzle::FETCH_ASSOC:
347 $row = array_combine($this->columnNames, $row);
348 break;
349 case PMA_Drizzle::FETCH_BOTH:
350 $length = count($row);
351 for ($i = 0; $i < $length; $i++) {
352 $row[$this->columnNames[$i]] = $row[$i];
354 break;
355 default:
356 break;
361 * Fetches next for from this result set
363 * @param int $fetchMode fetch mode to use, if none given the default one is used
364 * @return array|null
366 public function fetchRow($fetchMode = null)
367 {_dlog();
368 // read column names on first fetch, only buffered results allow for reading it later
369 if (!$this->columns) {
370 $this->_readColumns();
372 if ($fetchMode === null) {
373 $fetchMode = $this->fetchMode;
375 $row = null;
376 switch ($this->bufferMode) {
377 case PMA_Drizzle::BUFFER_RESULT:
378 $row = $this->dresult->rowNext();
379 break;
380 case PMA_Drizzle::BUFFER_ROW:
381 $row = $this->dresult->rowBuffer();
382 break;
384 $this->_transformResultRow($row, $fetchMode);
385 return $row;
389 * Adjusts the result pointer to an arbitrary row in buffered result
391 * @param $row_index
392 * @return bool
394 public function seek($row_index)
395 {_dlog();
396 if ($this->bufferMode != PMA_Drizzle::BUFFER_RESULT) {
397 trigger_error("Can't seek in an unbuffered result set", E_USER_WARNING);
398 return false;
400 // rowSeek always returns NULL (drizzle extension v.0.5, API v.7)
401 if ($row_index >= 0 && $row_index < $this->dresult->rowCount()) {
402 $this->dresult->rowSeek($row_index);
403 return true;
405 return false;
409 * Returns the number of rows in buffered result set
411 * @return int|false
413 public function numRows()
414 {_dlog();
415 if ($this->bufferMode != PMA_Drizzle::BUFFER_RESULT) {
416 trigger_error("Can't count rows in an unbuffered result set", E_USER_WARNING);
417 return false;
419 return $this->dresult->rowCount();
423 * Returns the number of rows affected by query
425 * @return int|false
427 public function affectedRows()
428 {_dlog();
429 return $this->dresult->affectedRows();
433 * Frees resources taken by this result
435 public function free()
436 {_dlog();
437 unset($this->columns);
438 unset($this->columnNames);
439 drizzle_result_free($this->dresult);
440 unset($this->dresult);