PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/common/libraries/plugin/pear/MDB2/Driver/Datatype/Common.php

https://bitbucket.org/cbenelug/chamilo
PHP | 1990 lines | 879 code | 216 blank | 895 comment | 122 complexity | 508b6271cbf07d3dd11628cbd0751b6a MD5 | raw file
Possible License(s): GPL-3.0, MIT, GPL-2.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PHP versions 4 and 5 |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1998-2007 Manuel Lemos, Tomas V.V.Cox, |
  6. // | Stig. S. Bakken, Lukas Smith |
  7. // | All rights reserved. |
  8. // +----------------------------------------------------------------------+
  9. // | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
  10. // | API as well as database abstraction for PHP applications. |
  11. // | This LICENSE is in the BSD license style. |
  12. // | |
  13. // | Redistribution and use in source and binary forms, with or without |
  14. // | modification, are permitted provided that the following conditions |
  15. // | are met: |
  16. // | |
  17. // | Redistributions of source code must retain the above copyright |
  18. // | notice, this list of conditions and the following disclaimer. |
  19. // | |
  20. // | Redistributions in binary form must reproduce the above copyright |
  21. // | notice, this list of conditions and the following disclaimer in the |
  22. // | documentation and/or other materials provided with the distribution. |
  23. // | |
  24. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
  25. // | Lukas Smith nor the names of his contributors may be used to endorse |
  26. // | or promote products derived from this software without specific prior|
  27. // | written permission. |
  28. // | |
  29. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
  30. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
  31. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
  32. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
  33. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
  34. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  35. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  36. // | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
  37. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
  38. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  39. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
  40. // | POSSIBILITY OF SUCH DAMAGE. |
  41. // +----------------------------------------------------------------------+
  42. // | Author: Lukas Smith <smith@pooteeweet.org> |
  43. // +----------------------------------------------------------------------+
  44. //
  45. // $Id: Common.php 137 2009-11-09 13:24:37Z vanpouckesven $
  46. require_once 'MDB2/LOB.php';
  47. /**
  48. * @package MDB2
  49. * @category Database
  50. * @author Lukas Smith <smith@pooteeweet.org>
  51. */
  52. /**
  53. * MDB2_Driver_Common: Base class that is extended by each MDB2 driver
  54. *
  55. * To load this module in the MDB2 object:
  56. * $mdb->loadModule('Datatype');
  57. *
  58. * @package MDB2
  59. * @category Database
  60. * @author Lukas Smith <smith@pooteeweet.org>
  61. */
  62. class MDB2_Driver_Datatype_Common extends MDB2_Module_Common
  63. {
  64. var $valid_default_values = array('text' => '', 'boolean' => true, 'integer' => 0, 'decimal' => 0.0,
  65. 'float' => 0.0, 'timestamp' => '1970-01-01 00:00:00', 'time' => '00:00:00', 'date' => '1970-01-01',
  66. 'clob' => '', 'blob' => '');
  67. /**
  68. * contains all LOB objects created with this MDB2 instance
  69. * @var array
  70. * @access protected
  71. */
  72. var $lobs = array();
  73. // }}}
  74. // {{{ getValidTypes()
  75. /**
  76. * Get the list of valid types
  77. *
  78. * This function returns an array of valid types as keys with the values
  79. * being possible default values for all native datatypes and mapped types
  80. * for custom datatypes.
  81. *
  82. * @return mixed array on success, a MDB2 error on failure
  83. * @access public
  84. */
  85. function getValidTypes()
  86. {
  87. $types = $this->valid_default_values;
  88. $db = & $this->getDBInstance();
  89. if (PEAR :: isError($db))
  90. {
  91. return $db;
  92. }
  93. if (! empty($db->options['datatype_map']))
  94. {
  95. foreach ($db->options['datatype_map'] as $type => $mapped_type)
  96. {
  97. if (array_key_exists($mapped_type, $types))
  98. {
  99. $types[$type] = $types[$mapped_type];
  100. }
  101. elseif (! empty($db->options['datatype_map_callback'][$type]))
  102. {
  103. $parameter = array('type' => $type, 'mapped_type' => $mapped_type);
  104. $default = call_user_func_array($db->options['datatype_map_callback'][$type], array(&$db,
  105. __FUNCTION__, $parameter));
  106. $types[$type] = $default;
  107. }
  108. }
  109. }
  110. return $types;
  111. }
  112. // }}}
  113. // {{{ checkResultTypes()
  114. /**
  115. * Define the list of types to be associated with the columns of a given
  116. * result set.
  117. *
  118. * This function may be called before invoking fetchRow(), fetchOne()
  119. * fetchCole() and fetchAll() so that the necessary data type
  120. * conversions are performed on the data to be retrieved by them. If this
  121. * function is not called, the type of all result set columns is assumed
  122. * to be text, thus leading to not perform any conversions.
  123. *
  124. * @param array $types array variable that lists the
  125. * data types to be expected in the result set columns. If this array
  126. * contains less types than the number of columns that are returned
  127. * in the result set, the remaining columns are assumed to be of the
  128. * type text. Currently, the types clob and blob are not fully
  129. * supported.
  130. * @return mixed MDB2_OK on success, a MDB2 error on failure
  131. * @access public
  132. */
  133. function checkResultTypes($types)
  134. {
  135. $types = is_array($types) ? $types : array($types);
  136. foreach ($types as $key => $type)
  137. {
  138. if (! isset($this->valid_default_values[$type]))
  139. {
  140. $db = & $this->getDBInstance();
  141. if (PEAR :: isError($db))
  142. {
  143. return $db;
  144. }
  145. if (empty($db->options['datatype_map'][$type]))
  146. {
  147. return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, $type . ' for ' . $key . ' is not a supported column type', __FUNCTION__);
  148. }
  149. }
  150. }
  151. return $types;
  152. }
  153. // }}}
  154. // {{{ _baseConvertResult()
  155. /**
  156. * General type conversion method
  157. *
  158. * @param mixed $value reference to a value to be converted
  159. * @param string $type specifies which type to convert to
  160. * @param boolean $rtrim [optional] when TRUE [default], apply rtrim() to text
  161. * @return object an MDB2 error on failure
  162. * @access protected
  163. */
  164. function _baseConvertResult($value, $type, $rtrim = true)
  165. {
  166. switch ($type)
  167. {
  168. case 'text' :
  169. if ($rtrim)
  170. {
  171. $value = rtrim($value);
  172. }
  173. return $value;
  174. case 'integer' :
  175. return intval($value);
  176. case 'boolean' :
  177. return ! empty($value);
  178. case 'decimal' :
  179. return $value;
  180. case 'float' :
  181. return doubleval($value);
  182. case 'date' :
  183. return $value;
  184. case 'time' :
  185. return $value;
  186. case 'timestamp' :
  187. return $value;
  188. case 'clob' :
  189. case 'blob' :
  190. $this->lobs[] = array('buffer' => null, 'position' => 0, 'lob_index' => null, 'endOfLOB' => false,
  191. 'resource' => $value, 'value' => null, 'loaded' => false);
  192. end($this->lobs);
  193. $lob_index = key($this->lobs);
  194. $this->lobs[$lob_index]['lob_index'] = $lob_index;
  195. return fopen('MDB2LOB://' . $lob_index . '@' . $this->db_index, 'r+');
  196. }
  197. $db = & $this->getDBInstance();
  198. if (PEAR :: isError($db))
  199. {
  200. return $db;
  201. }
  202. return $db->raiseError(MDB2_ERROR_INVALID, null, null, 'attempt to convert result value to an unknown type :' . $type, __FUNCTION__);
  203. }
  204. // }}}
  205. // {{{ convertResult()
  206. /**
  207. * Convert a value to a RDBMS indipendent MDB2 type
  208. *
  209. * @param mixed $value value to be converted
  210. * @param string $type specifies which type to convert to
  211. * @param boolean $rtrim [optional] when TRUE [default], apply rtrim() to text
  212. * @return mixed converted value
  213. * @access public
  214. */
  215. function convertResult($value, $type, $rtrim = true)
  216. {
  217. if (is_null($value))
  218. {
  219. return null;
  220. }
  221. $db = & $this->getDBInstance();
  222. if (PEAR :: isError($db))
  223. {
  224. return $db;
  225. }
  226. if (! empty($db->options['datatype_map'][$type]))
  227. {
  228. $type = $db->options['datatype_map'][$type];
  229. if (! empty($db->options['datatype_map_callback'][$type]))
  230. {
  231. $parameter = array('type' => $type, 'value' => $value, 'rtrim' => $rtrim);
  232. return call_user_func_array($db->options['datatype_map_callback'][$type], array(&$db, __FUNCTION__,
  233. $parameter));
  234. }
  235. }
  236. return $this->_baseConvertResult($value, $type, $rtrim);
  237. }
  238. // }}}
  239. // {{{ convertResultRow()
  240. /**
  241. * Convert a result row
  242. *
  243. * @param array $types
  244. * @param array $row specifies the types to convert to
  245. * @param boolean $rtrim [optional] when TRUE [default], apply rtrim() to text
  246. * @return mixed MDB2_OK on success, an MDB2 error on failure
  247. * @access public
  248. */
  249. function convertResultRow($types, $row, $rtrim = true)
  250. {
  251. $keys = array_keys($row);
  252. if (is_int($keys[0]))
  253. $types = $this->_sortResultFieldTypes($keys, $types);
  254. foreach ($row as $key => $value)
  255. {
  256. if (empty($types[$key]))
  257. {
  258. continue;
  259. }
  260. $value = $this->convertResult($row[$key], $types[$key], $rtrim);
  261. if (PEAR :: isError($value))
  262. {
  263. return $value;
  264. }
  265. $row[$key] = $value;
  266. }
  267. return $row;
  268. }
  269. // }}}
  270. // {{{ _sortResultFieldTypes()
  271. /**
  272. * convert a result row
  273. *
  274. * @param array $types
  275. * @param array $row specifies the types to convert to
  276. * @param bool $rtrim if to rtrim text values or not
  277. * @return mixed MDB2_OK on success, a MDB2 error on failure
  278. * @access public
  279. */
  280. function _sortResultFieldTypes($columns, $types)
  281. {
  282. $n_cols = count($columns);
  283. $n_types = count($types);
  284. if ($n_cols > $n_types)
  285. {
  286. for($i = $n_cols - $n_types; $i >= 0; $i --)
  287. {
  288. $types[] = null;
  289. }
  290. }
  291. $sorted_types = array();
  292. foreach ($columns as $col)
  293. {
  294. $sorted_types[$col] = null;
  295. }
  296. foreach ($types as $name => $type)
  297. {
  298. if (array_key_exists($name, $sorted_types))
  299. {
  300. $sorted_types[$name] = $type;
  301. unset($types[$name]);
  302. }
  303. }
  304. // if there are left types in the array, fill the null values of the
  305. // sorted array with them, in order.
  306. if (count($types))
  307. {
  308. reset($types);
  309. foreach (array_keys($sorted_types) as $k)
  310. {
  311. if (is_null($sorted_types[$k]))
  312. {
  313. $sorted_types[$k] = current($types);
  314. next($types);
  315. }
  316. }
  317. }
  318. return $sorted_types;
  319. }
  320. // }}}
  321. // {{{ getDeclaration()
  322. /**
  323. * Obtain DBMS specific SQL code portion needed to declare
  324. * of the given type
  325. *
  326. * @param string $type type to which the value should be converted to
  327. * @param string $name name the field to be declared.
  328. * @param string $field definition of the field
  329. * @return string DBMS specific SQL code portion that should be used to
  330. * declare the specified field.
  331. * @access public
  332. */
  333. function getDeclaration($type, $name, $field)
  334. {
  335. $db = & $this->getDBInstance();
  336. if (PEAR :: isError($db))
  337. {
  338. return $db;
  339. }
  340. if (! empty($db->options['datatype_map'][$type]))
  341. {
  342. $type = $db->options['datatype_map'][$type];
  343. if (! empty($db->options['datatype_map_callback'][$type]))
  344. {
  345. $parameter = array('type' => $type, 'name' => $name, 'field' => $field);
  346. return call_user_func_array($db->options['datatype_map_callback'][$type], array(&$db, __FUNCTION__,
  347. $parameter));
  348. }
  349. $field['type'] = $type;
  350. }
  351. if (! method_exists($this, "_get{$type}Declaration"))
  352. {
  353. return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, 'type not defined: ' . $type, __FUNCTION__);
  354. }
  355. return $this->{"_get{$type}Declaration"}($name, $field);
  356. }
  357. // }}}
  358. // {{{ getTypeDeclaration()
  359. /**
  360. * Obtain DBMS specific SQL code portion needed to declare an text type
  361. * field to be used in statements like CREATE TABLE.
  362. *
  363. * @param array $field associative array with the name of the properties
  364. * of the field being declared as array indexes. Currently, the types
  365. * of supported field properties are as follows:
  366. *
  367. * length
  368. * Integer value that determines the maximum length of the text
  369. * field. If this argument is missing the field should be
  370. * declared to have the longest length allowed by the DBMS.
  371. *
  372. * default
  373. * Text value to be used as default for this field.
  374. *
  375. * notnull
  376. * Boolean flag that indicates whether this field is constrained
  377. * to not be set to null.
  378. * @return string DBMS specific SQL code portion that should be used to
  379. * declare the specified field.
  380. * @access public
  381. */
  382. function getTypeDeclaration($field)
  383. {
  384. $db = & $this->getDBInstance();
  385. if (PEAR :: isError($db))
  386. {
  387. return $db;
  388. }
  389. switch ($field['type'])
  390. {
  391. case 'text' :
  392. $length = ! empty($field['length']) ? $field['length'] : $db->options['default_text_field_length'];
  393. $fixed = ! empty($field['fixed']) ? $field['fixed'] : false;
  394. return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(' . $db->options['default_text_field_length'] . ')') : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
  395. case 'clob' :
  396. return 'TEXT';
  397. case 'blob' :
  398. return 'TEXT';
  399. case 'integer' :
  400. return 'INT';
  401. case 'boolean' :
  402. return 'INT';
  403. case 'date' :
  404. return 'CHAR (' . strlen('YYYY-MM-DD') . ')';
  405. case 'time' :
  406. return 'CHAR (' . strlen('HH:MM:SS') . ')';
  407. case 'timestamp' :
  408. return 'CHAR (' . strlen('YYYY-MM-DD HH:MM:SS') . ')';
  409. case 'float' :
  410. return 'TEXT';
  411. case 'decimal' :
  412. return 'TEXT';
  413. }
  414. return '';
  415. }
  416. // }}}
  417. // {{{ _getDeclaration()
  418. /**
  419. * Obtain DBMS specific SQL code portion needed to declare a generic type
  420. * field to be used in statements like CREATE TABLE.
  421. *
  422. * @param string $name name the field to be declared.
  423. * @param array $field associative array with the name of the properties
  424. * of the field being declared as array indexes. Currently, the types
  425. * of supported field properties are as follows:
  426. *
  427. * length
  428. * Integer value that determines the maximum length of the text
  429. * field. If this argument is missing the field should be
  430. * declared to have the longest length allowed by the DBMS.
  431. *
  432. * default
  433. * Text value to be used as default for this field.
  434. *
  435. * notnull
  436. * Boolean flag that indicates whether this field is constrained
  437. * to not be set to null.
  438. * charset
  439. * Text value with the default CHARACTER SET for this field.
  440. * collation
  441. * Text value with the default COLLATION for this field.
  442. * @return string DBMS specific SQL code portion that should be used to
  443. * declare the specified field, or a MDB2_Error on failure
  444. * @access protected
  445. */
  446. function _getDeclaration($name, $field)
  447. {
  448. $db = & $this->getDBInstance();
  449. if (PEAR :: isError($db))
  450. {
  451. return $db;
  452. }
  453. $name = $db->quoteIdentifier($name, true);
  454. $declaration_options = $db->datatype->_getDeclarationOptions($field);
  455. if (PEAR :: isError($declaration_options))
  456. {
  457. return $declaration_options;
  458. }
  459. return $name . ' ' . $this->getTypeDeclaration($field) . $declaration_options;
  460. }
  461. // }}}
  462. // {{{ _getDeclarationOptions()
  463. /**
  464. * Obtain DBMS specific SQL code portion needed to declare a generic type
  465. * field to be used in statement like CREATE TABLE, without the field name
  466. * and type values (ie. just the character set, default value, if the
  467. * field is permitted to be NULL or not, and the collation options).
  468. *
  469. * @param array $field associative array with the name of the properties
  470. * of the field being declared as array indexes. Currently, the types
  471. * of supported field properties are as follows:
  472. *
  473. * default
  474. * Text value to be used as default for this field.
  475. * notnull
  476. * Boolean flag that indicates whether this field is constrained
  477. * to not be set to null.
  478. * charset
  479. * Text value with the default CHARACTER SET for this field.
  480. * collation
  481. * Text value with the default COLLATION for this field.
  482. * @return string DBMS specific SQL code portion that should be used to
  483. * declare the specified field's options.
  484. * @access protected
  485. */
  486. function _getDeclarationOptions($field)
  487. {
  488. $charset = empty($field['charset']) ? '' : ' ' . $this->_getCharsetFieldDeclaration($field['charset']);
  489. $notnull = empty($field['notnull']) ? '' : ' NOT NULL';
  490. $default = '';
  491. if (array_key_exists('default', $field))
  492. {
  493. if ($field['default'] === '')
  494. {
  495. $db = & $this->getDBInstance();
  496. if (PEAR :: isError($db))
  497. {
  498. return $db;
  499. }
  500. $valid_default_values = $this->getValidTypes();
  501. $field['default'] = $valid_default_values[$field['type']];
  502. if ($field['default'] === '' && ($db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL))
  503. {
  504. $field['default'] = ' ';
  505. }
  506. }
  507. if (! is_null($field['default']))
  508. {
  509. $default = ' DEFAULT ' . $this->quote($field['default'], $field['type']);
  510. }
  511. }
  512. $collation = empty($field['collation']) ? '' : ' ' . $this->_getCollationFieldDeclaration($field['collation']);
  513. return $charset . $default . $notnull . $collation;
  514. }
  515. // }}}
  516. // {{{ _getCharsetFieldDeclaration()
  517. /**
  518. * Obtain DBMS specific SQL code portion needed to set the CHARACTER SET
  519. * of a field declaration to be used in statements like CREATE TABLE.
  520. *
  521. * @param string $charset name of the charset
  522. * @return string DBMS specific SQL code portion needed to set the CHARACTER SET
  523. * of a field declaration.
  524. */
  525. function _getCharsetFieldDeclaration($charset)
  526. {
  527. return '';
  528. }
  529. // }}}
  530. // {{{ _getCollationFieldDeclaration()
  531. /**
  532. * Obtain DBMS specific SQL code portion needed to set the COLLATION
  533. * of a field declaration to be used in statements like CREATE TABLE.
  534. *
  535. * @param string $collation name of the collation
  536. * @return string DBMS specific SQL code portion needed to set the COLLATION
  537. * of a field declaration.
  538. */
  539. function _getCollationFieldDeclaration($collation)
  540. {
  541. return '';
  542. }
  543. // }}}
  544. // {{{ _getIntegerDeclaration()
  545. /**
  546. * Obtain DBMS specific SQL code portion needed to declare an integer type
  547. * field to be used in statements like CREATE TABLE.
  548. *
  549. * @param string $name name the field to be declared.
  550. * @param array $field associative array with the name of the properties
  551. * of the field being declared as array indexes. Currently, the types
  552. * of supported field properties are as follows:
  553. *
  554. * unsigned
  555. * Boolean flag that indicates whether the field should be
  556. * declared as unsigned integer if possible.
  557. *
  558. * default
  559. * Integer value to be used as default for this field.
  560. *
  561. * notnull
  562. * Boolean flag that indicates whether this field is constrained
  563. * to not be set to null.
  564. * @return string DBMS specific SQL code portion that should be used to
  565. * declare the specified field.
  566. * @access protected
  567. */
  568. function _getIntegerDeclaration($name, $field)
  569. {
  570. if (! empty($field['unsigned']))
  571. {
  572. $db = & $this->getDBInstance();
  573. if (PEAR :: isError($db))
  574. {
  575. return $db;
  576. }
  577. $db->warnings[] = "unsigned integer field \"$name\" is being declared as signed integer";
  578. }
  579. return $this->_getDeclaration($name, $field);
  580. }
  581. // }}}
  582. // {{{ _getTextDeclaration()
  583. /**
  584. * Obtain DBMS specific SQL code portion needed to declare an text type
  585. * field to be used in statements like CREATE TABLE.
  586. *
  587. * @param string $name name the field to be declared.
  588. * @param array $field associative array with the name of the properties
  589. * of the field being declared as array indexes. Currently, the types
  590. * of supported field properties are as follows:
  591. *
  592. * length
  593. * Integer value that determines the maximum length of the text
  594. * field. If this argument is missing the field should be
  595. * declared to have the longest length allowed by the DBMS.
  596. *
  597. * default
  598. * Text value to be used as default for this field.
  599. *
  600. * notnull
  601. * Boolean flag that indicates whether this field is constrained
  602. * to not be set to null.
  603. * @return string DBMS specific SQL code portion that should be used to
  604. * declare the specified field.
  605. * @access protected
  606. */
  607. function _getTextDeclaration($name, $field)
  608. {
  609. return $this->_getDeclaration($name, $field);
  610. }
  611. // }}}
  612. // {{{ _getCLOBDeclaration()
  613. /**
  614. * Obtain DBMS specific SQL code portion needed to declare an character
  615. * large object type field to be used in statements like CREATE TABLE.
  616. *
  617. * @param string $name name the field to be declared.
  618. * @param array $field associative array with the name of the properties
  619. * of the field being declared as array indexes. Currently, the types
  620. * of supported field properties are as follows:
  621. *
  622. * length
  623. * Integer value that determines the maximum length of the large
  624. * object field. If this argument is missing the field should be
  625. * declared to have the longest length allowed by the DBMS.
  626. *
  627. * notnull
  628. * Boolean flag that indicates whether this field is constrained
  629. * to not be set to null.
  630. * @return string DBMS specific SQL code portion that should be used to
  631. * declare the specified field.
  632. * @access public
  633. */
  634. function _getCLOBDeclaration($name, $field)
  635. {
  636. $db = & $this->getDBInstance();
  637. if (PEAR :: isError($db))
  638. {
  639. return $db;
  640. }
  641. $notnull = empty($field['notnull']) ? '' : ' NOT NULL';
  642. $name = $db->quoteIdentifier($name, true);
  643. return $name . ' ' . $this->getTypeDeclaration($field) . $notnull;
  644. }
  645. // }}}
  646. // {{{ _getBLOBDeclaration()
  647. /**
  648. * Obtain DBMS specific SQL code portion needed to declare an binary large
  649. * object type field to be used in statements like CREATE TABLE.
  650. *
  651. * @param string $name name the field to be declared.
  652. * @param array $field associative array with the name of the properties
  653. * of the field being declared as array indexes. Currently, the types
  654. * of supported field properties are as follows:
  655. *
  656. * length
  657. * Integer value that determines the maximum length of the large
  658. * object field. If this argument is missing the field should be
  659. * declared to have the longest length allowed by the DBMS.
  660. *
  661. * notnull
  662. * Boolean flag that indicates whether this field is constrained
  663. * to not be set to null.
  664. * @return string DBMS specific SQL code portion that should be used to
  665. * declare the specified field.
  666. * @access protected
  667. */
  668. function _getBLOBDeclaration($name, $field)
  669. {
  670. $db = & $this->getDBInstance();
  671. if (PEAR :: isError($db))
  672. {
  673. return $db;
  674. }
  675. $notnull = empty($field['notnull']) ? '' : ' NOT NULL';
  676. $name = $db->quoteIdentifier($name, true);
  677. return $name . ' ' . $this->getTypeDeclaration($field) . $notnull;
  678. }
  679. // }}}
  680. // {{{ _getBooleanDeclaration()
  681. /**
  682. * Obtain DBMS specific SQL code portion needed to declare a boolean type
  683. * field to be used in statements like CREATE TABLE.
  684. *
  685. * @param string $name name the field to be declared.
  686. * @param array $field associative array with the name of the properties
  687. * of the field being declared as array indexes. Currently, the types
  688. * of supported field properties are as follows:
  689. *
  690. * default
  691. * Boolean value to be used as default for this field.
  692. *
  693. * notnullL
  694. * Boolean flag that indicates whether this field is constrained
  695. * to not be set to null.
  696. * @return string DBMS specific SQL code portion that should be used to
  697. * declare the specified field.
  698. * @access protected
  699. */
  700. function _getBooleanDeclaration($name, $field)
  701. {
  702. return $this->_getDeclaration($name, $field);
  703. }
  704. // }}}
  705. // {{{ _getDateDeclaration()
  706. /**
  707. * Obtain DBMS specific SQL code portion needed to declare a date type
  708. * field to be used in statements like CREATE TABLE.
  709. *
  710. * @param string $name name the field to be declared.
  711. * @param array $field associative array with the name of the properties
  712. * of the field being declared as array indexes. Currently, the types
  713. * of supported field properties are as follows:
  714. *
  715. * default
  716. * Date value to be used as default for this field.
  717. *
  718. * notnull
  719. * Boolean flag that indicates whether this field is constrained
  720. * to not be set to null.
  721. * @return string DBMS specific SQL code portion that should be used to
  722. * declare the specified field.
  723. * @access protected
  724. */
  725. function _getDateDeclaration($name, $field)
  726. {
  727. return $this->_getDeclaration($name, $field);
  728. }
  729. // }}}
  730. // {{{ _getTimestampDeclaration()
  731. /**
  732. * Obtain DBMS specific SQL code portion needed to declare a timestamp
  733. * field to be used in statements like CREATE TABLE.
  734. *
  735. * @param string $name name the field to be declared.
  736. * @param array $field associative array with the name of the properties
  737. * of the field being declared as array indexes. Currently, the types
  738. * of supported field properties are as follows:
  739. *
  740. * default
  741. * Timestamp value to be used as default for this field.
  742. *
  743. * notnull
  744. * Boolean flag that indicates whether this field is constrained
  745. * to not be set to null.
  746. * @return string DBMS specific SQL code portion that should be used to
  747. * declare the specified field.
  748. * @access protected
  749. */
  750. function _getTimestampDeclaration($name, $field)
  751. {
  752. return $this->_getDeclaration($name, $field);
  753. }
  754. // }}}
  755. // {{{ _getTimeDeclaration()
  756. /**
  757. * Obtain DBMS specific SQL code portion needed to declare a time
  758. * field to be used in statements like CREATE TABLE.
  759. *
  760. * @param string $name name the field to be declared.
  761. * @param array $field associative array with the name of the properties
  762. * of the field being declared as array indexes. Currently, the types
  763. * of supported field properties are as follows:
  764. *
  765. * default
  766. * Time value to be used as default for this field.
  767. *
  768. * notnull
  769. * Boolean flag that indicates whether this field is constrained
  770. * to not be set to null.
  771. * @return string DBMS specific SQL code portion that should be used to
  772. * declare the specified field.
  773. * @access protected
  774. */
  775. function _getTimeDeclaration($name, $field)
  776. {
  777. return $this->_getDeclaration($name, $field);
  778. }
  779. // }}}
  780. // {{{ _getFloatDeclaration()
  781. /**
  782. * Obtain DBMS specific SQL code portion needed to declare a float type
  783. * field to be used in statements like CREATE TABLE.
  784. *
  785. * @param string $name name the field to be declared.
  786. * @param array $field associative array with the name of the properties
  787. * of the field being declared as array indexes. Currently, the types
  788. * of supported field properties are as follows:
  789. *
  790. * default
  791. * Float value to be used as default for this field.
  792. *
  793. * notnull
  794. * Boolean flag that indicates whether this field is constrained
  795. * to not be set to null.
  796. * @return string DBMS specific SQL code portion that should be used to
  797. * declare the specified field.
  798. * @access protected
  799. */
  800. function _getFloatDeclaration($name, $field)
  801. {
  802. return $this->_getDeclaration($name, $field);
  803. }
  804. // }}}
  805. // {{{ _getDecimalDeclaration()
  806. /**
  807. * Obtain DBMS specific SQL code portion needed to declare a decimal type
  808. * field to be used in statements like CREATE TABLE.
  809. *
  810. * @param string $name name the field to be declared.
  811. * @param array $field associative array with the name of the properties
  812. * of the field being declared as array indexes. Currently, the types
  813. * of supported field properties are as follows:
  814. *
  815. * default
  816. * Decimal value to be used as default for this field.
  817. *
  818. * notnull
  819. * Boolean flag that indicates whether this field is constrained
  820. * to not be set to null.
  821. * @return string DBMS specific SQL code portion that should be used to
  822. * declare the specified field.
  823. * @access protected
  824. */
  825. function _getDecimalDeclaration($name, $field)
  826. {
  827. return $this->_getDeclaration($name, $field);
  828. }
  829. // }}}
  830. // {{{ compareDefinition()
  831. /**
  832. * Obtain an array of changes that may need to applied
  833. *
  834. * @param array $current new definition
  835. * @param array $previous old definition
  836. * @return array containing all changes that will need to be applied
  837. * @access public
  838. */
  839. function compareDefinition($current, $previous)
  840. {
  841. $type = ! empty($current['type']) ? $current['type'] : null;
  842. if (! method_exists($this, "_compare{$type}Definition"))
  843. {
  844. $db = & $this->getDBInstance();
  845. if (PEAR :: isError($db))
  846. {
  847. return $db;
  848. }
  849. if (! empty($db->options['datatype_map_callback'][$type]))
  850. {
  851. $parameter = array('current' => $current, 'previous' => $previous);
  852. $change = call_user_func_array($db->options['datatype_map_callback'][$type], array(&$db, __FUNCTION__,
  853. $parameter));
  854. return $change;
  855. }
  856. return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, 'type "' . $current['type'] . '" is not yet supported', __FUNCTION__);
  857. }
  858. if (empty($previous['type']) || $previous['type'] != $type)
  859. {
  860. return $current;
  861. }
  862. $change = $this->{"_compare{$type}Definition"}($current, $previous);
  863. if ($previous['type'] != $type)
  864. {
  865. $change['type'] = true;
  866. }
  867. $previous_notnull = ! empty($previous['notnull']) ? $previous['notnull'] : false;
  868. $notnull = ! empty($current['notnull']) ? $current['notnull'] : false;
  869. if ($previous_notnull != $notnull)
  870. {
  871. $change['notnull'] = true;
  872. }
  873. $previous_default = array_key_exists('default', $previous) ? $previous['default'] : ($previous_notnull ? '' : null);
  874. $default = array_key_exists('default', $current) ? $current['default'] : ($notnull ? '' : null);
  875. if ($previous_default !== $default)
  876. {
  877. $change['default'] = true;
  878. }
  879. return $change;
  880. }
  881. // }}}
  882. // {{{ _compareIntegerDefinition()
  883. /**
  884. * Obtain an array of changes that may need to applied to an integer field
  885. *
  886. * @param array $current new definition
  887. * @param array $previous old definition
  888. * @return array containing all changes that will need to be applied
  889. * @access protected
  890. */
  891. function _compareIntegerDefinition($current, $previous)
  892. {
  893. $change = array();
  894. $previous_unsigned = ! empty($previous['unsigned']) ? $previous['unsigned'] : false;
  895. $unsigned = ! empty($current['unsigned']) ? $current['unsigned'] : false;
  896. if ($previous_unsigned != $unsigned)
  897. {
  898. $change['unsigned'] = true;
  899. }
  900. $previous_autoincrement = ! empty($previous['autoincrement']) ? $previous['autoincrement'] : false;
  901. $autoincrement = ! empty($current['autoincrement']) ? $current['autoincrement'] : false;
  902. if ($previous_autoincrement != $autoincrement)
  903. {
  904. $change['autoincrement'] = true;
  905. }
  906. return $change;
  907. }
  908. // }}}
  909. // {{{ _compareTextDefinition()
  910. /**
  911. * Obtain an array of changes that may need to applied to an text field
  912. *
  913. * @param array $current new definition
  914. * @param array $previous old definition
  915. * @return array containing all changes that will need to be applied
  916. * @access protected
  917. */
  918. function _compareTextDefinition($current, $previous)
  919. {
  920. $change = array();
  921. $previous_length = ! empty($previous['length']) ? $previous['length'] : 0;
  922. $length = ! empty($current['length']) ? $current['length'] : 0;
  923. if ($previous_length != $length)
  924. {
  925. $change['length'] = true;
  926. }
  927. $previous_fixed = ! empty($previous['fixed']) ? $previous['fixed'] : 0;
  928. $fixed = ! empty($current['fixed']) ? $current['fixed'] : 0;
  929. if ($previous_fixed != $fixed)
  930. {
  931. $change['fixed'] = true;
  932. }
  933. return $change;
  934. }
  935. // }}}
  936. // {{{ _compareCLOBDefinition()
  937. /**
  938. * Obtain an array of changes that may need to applied to an CLOB field
  939. *
  940. * @param array $current new definition
  941. * @param array $previous old definition
  942. * @return array containing all changes that will need to be applied
  943. * @access protected
  944. */
  945. function _compareCLOBDefinition($current, $previous)
  946. {
  947. return $this->_compareTextDefinition($current, $previous);
  948. }
  949. // }}}
  950. // {{{ _compareBLOBDefinition()
  951. /**
  952. * Obtain an array of changes that may need to applied to an BLOB field
  953. *
  954. * @param array $current new definition
  955. * @param array $previous old definition
  956. * @return array containing all changes that will need to be applied
  957. * @access protected
  958. */
  959. function _compareBLOBDefinition($current, $previous)
  960. {
  961. return $this->_compareTextDefinition($current, $previous);
  962. }
  963. // }}}
  964. // {{{ _compareDateDefinition()
  965. /**
  966. * Obtain an array of changes that may need to applied to an date field
  967. *
  968. * @param array $current new definition
  969. * @param array $previous old definition
  970. * @return array containing all changes that will need to be applied
  971. * @access protected
  972. */
  973. function _compareDateDefinition($current, $previous)
  974. {
  975. return array();
  976. }
  977. // }}}
  978. // {{{ _compareTimeDefinition()
  979. /**
  980. * Obtain an array of changes that may need to applied to an time field
  981. *
  982. * @param array $current new definition
  983. * @param array $previous old definition
  984. * @return array containing all changes that will need to be applied
  985. * @access protected
  986. */
  987. function _compareTimeDefinition($current, $previous)
  988. {
  989. return array();
  990. }
  991. // }}}
  992. // {{{ _compareTimestampDefinition()
  993. /**
  994. * Obtain an array of changes that may need to applied to an timestamp field
  995. *
  996. * @param array $current new definition
  997. * @param array $previous old definition
  998. * @return array containing all changes that will need to be applied
  999. * @access protected
  1000. */
  1001. function _compareTimestampDefinition($current, $previous)
  1002. {
  1003. return array();
  1004. }
  1005. // }}}
  1006. // {{{ _compareBooleanDefinition()
  1007. /**
  1008. * Obtain an array of changes that may need to applied to an boolean field
  1009. *
  1010. * @param array $current new definition
  1011. * @param array $previous old definition
  1012. * @return array containing all changes that will need to be applied
  1013. * @access protected
  1014. */
  1015. function _compareBooleanDefinition($current, $previous)
  1016. {
  1017. return array();
  1018. }
  1019. // }}}
  1020. // {{{ _compareFloatDefinition()
  1021. /**
  1022. * Obtain an array of changes that may need to applied to an float field
  1023. *
  1024. * @param array $current new definition
  1025. * @param array $previous old definition
  1026. * @return array containing all changes that will need to be applied
  1027. * @access protected
  1028. */
  1029. function _compareFloatDefinition($current, $previous)
  1030. {
  1031. return array();
  1032. }
  1033. // }}}
  1034. // {{{ _compareDecimalDefinition()
  1035. /**
  1036. * Obtain an array of changes that may need to applied to an decimal field
  1037. *
  1038. * @param array $current new definition
  1039. * @param array $previous old definition
  1040. * @return array containing all changes that will need to be applied
  1041. * @access protected
  1042. */
  1043. function _compareDecimalDefinition($current, $previous)
  1044. {
  1045. return array();
  1046. }
  1047. // }}}
  1048. // {{{ quote()
  1049. /**
  1050. * Convert a text value into a DBMS specific format that is suitable to
  1051. * compose query statements.
  1052. *
  1053. * @param string $value text string value that is intended to be converted.
  1054. * @param string $type type to which the value should be converted to
  1055. * @param bool $quote determines if the value should be quoted and escaped
  1056. * @param bool $escape_wildcards if to escape escape wildcards
  1057. * @return string text string that represents the given argument value in
  1058. * a DBMS specific format.
  1059. * @access public
  1060. */
  1061. function quote($value, $type = null, $quote = true, $escape_wildcards = false)
  1062. {
  1063. $db = & $this->getDBInstance();
  1064. if (PEAR :: isError($db))
  1065. {
  1066. return $db;
  1067. }
  1068. if (is_null($value) || ($value === '' && $db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL))
  1069. {
  1070. if (! $quote)
  1071. {
  1072. return null;
  1073. }
  1074. return 'NULL';
  1075. }
  1076. if (is_null($type))
  1077. {
  1078. switch (gettype($value))
  1079. {
  1080. case 'integer' :
  1081. $type = 'integer';
  1082. break;
  1083. case 'double' :
  1084. // todo: default to decimal as float is quite unusual
  1085. // $type = 'float';
  1086. $type = 'decimal';
  1087. break;
  1088. case 'boolean' :
  1089. $type = 'boolean';
  1090. break;
  1091. case 'array' :
  1092. $value = serialize($value);
  1093. case 'object' :
  1094. $type = 'text';
  1095. break;
  1096. default :
  1097. if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/', $value))
  1098. {
  1099. $type = 'timestamp';
  1100. }
  1101. elseif (preg_match('/^\d{2}:\d{2}$/', $value))
  1102. {
  1103. $type = 'time';
  1104. }
  1105. elseif (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value))
  1106. {
  1107. $type = 'date';
  1108. }
  1109. else
  1110. {
  1111. $type = 'text';
  1112. }
  1113. break;
  1114. }
  1115. }
  1116. elseif (! empty($db->options['datatype_map'][$type]))
  1117. {
  1118. $type = $db->options['datatype_map'][$type];
  1119. if (! empty($db->options['datatype_map_callback'][$type]))
  1120. {
  1121. $parameter = array('type' => $type, 'value' => $value, 'quote' => $quote,
  1122. 'escape_wildcards' => $escape_wildcards);
  1123. return call_user_func_array($db->options['datatype_map_callback'][$type], array(&$db, __FUNCTION__,
  1124. $parameter));
  1125. }
  1126. }
  1127. if (! method_exists($this, "_quote{$type}"))
  1128. {
  1129. return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, 'type not defined: ' . $type, __FUNCTION__);
  1130. }
  1131. $value = $this->{"_quote{$type}"}($value, $quote, $escape_wildcards);
  1132. if ($quote && $escape_wildcards && $db->string_quoting['escape_pattern'] && $db->string_quoting['escape'] !== $db->string_quoting['escape_pattern'])
  1133. {
  1134. $value .= $this->patternEscapeString();
  1135. }
  1136. return $value;
  1137. }
  1138. // }}}
  1139. // {{{ _quoteInteger()
  1140. /**
  1141. * Convert a text value into a DBMS specific format that is suitable to
  1142. * compose query statements.
  1143. *
  1144. * @param string $value text string value that is intended to be converted.
  1145. * @param bool $quote determines if the value should be quoted and escaped
  1146. * @param bool $escape_wildcards if to escape escape wildcards
  1147. * @return string text string that represents the given argument value in
  1148. * a DBMS specific format.
  1149. * @access protected
  1150. */
  1151. function _quoteInteger($value, $quote, $escape_wildcards)
  1152. {
  1153. return (int) $value;
  1154. }
  1155. // }}}
  1156. // {{{ _quoteText()
  1157. /**
  1158. * Convert a text value into a DBMS specific format that is suitable to
  1159. * compose query statements.
  1160. *
  1161. * @param string $value text string value that is intended to be converted.
  1162. * @param bool $quote determines if the value should be quoted and escaped
  1163. * @param bool $escape_wildcards if to escape escape wildcards
  1164. * @return string text string that already contains any DBMS specific
  1165. * escaped character sequences.
  1166. * @access protected
  1167. */
  1168. function _quoteText($value, $quote, $escape_wildcards)
  1169. {
  1170. if (! $quote)
  1171. {
  1172. return $value;
  1173. }
  1174. $db = & $this->getDBInstance();
  1175. if (PEAR :: isError($db))
  1176. {
  1177. return $db;
  1178. }
  1179. $value = $db->escape($value, $escape_wildcards);
  1180. if (PEAR :: isError($value))
  1181. {
  1182. return $value;
  1183. }
  1184. return "'" . $value . "'";
  1185. }
  1186. // }}}
  1187. // {{{ _readFile()
  1188. /**
  1189. * Convert a text value into a DBMS specific format that is suitable to
  1190. * compose query statements.
  1191. *
  1192. * @param string $value text string value that is intended to be converted.
  1193. * @return string text string that represents the given argument value in
  1194. * a DBMS specific format.
  1195. * @access protected
  1196. */
  1197. function _readFile($value)
  1198. {
  1199. $close = false;
  1200. if (preg_match('/^(\w+:\/\/)(.*)$/', $value, $match))
  1201. {
  1202. $close = true;
  1203. if ($match[1] == 'file://')
  1204. {
  1205. $value = $match[2];
  1206. }
  1207. $value = @fopen($value, 'r');
  1208. }
  1209. if (is_resource($value))
  1210. {
  1211. $db = & $this->getDBInstance();
  1212. if (PEAR :: isError($db))
  1213. {
  1214. return $db;
  1215. }
  1216. $fp = $value;
  1217. $value = '';
  1218. while (! @feof($fp))
  1219. {
  1220. $value .= @fread($fp, $db->options['lob_buffer_length']);
  1221. }
  1222. if ($close)
  1223. {
  1224. @fclose($fp);
  1225. }
  1226. }
  1227. return $value;
  1228. }
  1229. // }}}
  1230. // {{{ _quoteLOB()
  1231. /**
  1232. * Convert a text value into a DBMS specific format that is suitable to
  1233. * compose query statements.
  1234. *
  1235. * @param string $value text string value that is intended to be converted.
  1236. * @param bool $quote determines if the value should be quoted and escaped
  1237. * @param bool $escape_wildcards if to escape escape wildcards
  1238. * @return string text string that represents the given argument value in
  1239. * a DBMS specific format.
  1240. * @access protected
  1241. */
  1242. function _quoteLOB($value, $quote, $escape_wildcards)
  1243. {
  1244. $value = $this->_readFile($value);
  1245. if (PEAR :: isError($value))
  1246. {
  1247. return $value;
  1248. }
  1249. return $this->_quoteText($value, $quote, $escape_wildcards);
  1250. }
  1251. // }}}
  1252. // {{{ _quoteCLOB()
  1253. /**
  1254. * Convert a text value into a DBMS specific format that is suitable to
  1255. * compose query statements.
  1256. *
  1257. * @param string $value text string value that is intended to be converted.
  1258. * @param bool $quote determines if the value should be quoted and escaped
  1259. * @param bool $escape_wildcards if to escape escape wildcards
  1260. * @return string text string that represents the given argument value in
  1261. * a DBMS specific format.
  1262. * @access protected
  1263. */
  1264. function _quoteCLOB($value, $quote, $escape_wildcards)
  1265. {
  1266. return $this->_quoteLOB($value, $quote, $escape_wildcards);
  1267. }
  1268. // }}}
  1269. // {{{ _quoteBLOB()
  1270. /**
  1271. * Convert a text value into a DBMS specific format that is suitable to
  1272. * compose query statements.
  1273. *
  1274. * @param string $value text string value that is intended to be converted.
  1275. * @param bool $quote determines if the value should be quoted and escaped
  1276. * @param bool $escape_wildcards if to escape escape wildcards
  1277. * @return string text string that represents the given argument value in
  1278. * a DBMS specific format.
  1279. * @access protected
  1280. */
  1281. function _quoteBLOB($value, $quote, $escape_wildcards)
  1282. {
  1283. return $this->_quoteLOB($value, $quote, $escape_wildcards);
  1284. }
  1285. // }}}
  1286. // {{{ _quoteBoolean()
  1287. /**
  1288. * Convert a text value into a DBMS specific format that is suitable to
  1289. * compose query statements.
  1290. *
  1291. * @param string $value text string value that is intended to be converted.
  1292. * @param bool $quote determines if the value should be quoted and escaped
  1293. * @param bool $escape_wildcards if to escape escape wildcards
  1294. * @return string text string that represents the given argument value in
  1295. * a DBMS specific format.
  1296. * @access protected
  1297. */
  1298. function _quoteBoolean($value, $quote, $escape_wildcards)
  1299. {
  1300. return ($value ? 1 : 0);
  1301. }
  1302. // }}}
  1303. // {{{ _quoteDate()
  1304. /**
  1305. * Convert a text value into a DBMS specific format that is suitable to
  1306. * compose query stat…

Large files files are truncated, but you can click here to view the full file