PageRenderTime 264ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/php/DB/QueryTool/Query.php

https://bitbucket.org/adarshj/convenient_website
PHP | 2395 lines | 957 code | 235 blank | 1203 comment | 159 complexity | 756e9ed11d2a04d0dce5dade121c5330 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

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

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * Contains the DB_QueryTool_Query class
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * LICENSE: This source file is subject to version 3.0 of the PHP license
  9. * that is available through the world-wide-web at the following URI:
  10. * http://www.php.net/license/3_0.txt. If you did not receive a copy of
  11. * the PHP License and are unable to obtain it through the web, please
  12. * send a note to license@php.net so we can mail you a copy immediately.
  13. *
  14. * @category Database
  15. * @package DB_QueryTool
  16. * @author Wolfram Kriesing <wk@visionp.de>
  17. * @author Paolo Panto <wk@visionp.de>
  18. * @author Lorenzo Alberton <l dot alberton at quipo dot it>
  19. * @copyright 2003-2005 Wolfram Kriesing, Paolo Panto, Lorenzo Alberton
  20. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  21. * @version CVS: $Id: Query.php,v 1.57 2005/02/27 19:13:19 quipo Exp $
  22. * @link http://pear.php.net/package/DB_QueryTool
  23. */
  24. /**
  25. * require the PEAR and DB classes
  26. */
  27. require_once 'PEAR.php';
  28. require_once 'DB.php';
  29. /**
  30. * DB_QueryTool_Query class
  31. *
  32. * This class should be extended
  33. *
  34. * @category Database
  35. * @package DB_QueryTool
  36. * @author Wolfram Kriesing <wk@visionp.de>
  37. * @author Paolo Panto <wk@visionp.de>
  38. * @author Lorenzo Alberton <l dot alberton at quipo dot it>
  39. * @copyright 2003-2005 Wolfram Kriesing, Paolo Panto, Lorenzo Alberton
  40. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  41. * @link http://pear.php.net/package/DB_QueryTool
  42. */
  43. class DB_QueryTool_Query
  44. {
  45. // {{{ class vars
  46. /**
  47. * @var string the name of the primary column
  48. */
  49. var $primaryCol = 'id';
  50. /**
  51. * @var string the current table the class works on
  52. */
  53. var $table = '';
  54. /**
  55. * @var string the name of the sequence for this table
  56. */
  57. var $sequenceName = null;
  58. /**
  59. * @var object the db-object, a PEAR::DB instance
  60. */
  61. var $db = null;
  62. /**
  63. * @var string the where condition
  64. * @access private
  65. */
  66. var $_where = '';
  67. /**
  68. * @var string the order condition
  69. * @access private
  70. */
  71. var $_order = '';
  72. /**
  73. * @var string the having definition
  74. * @access private
  75. */
  76. var $_having = '';
  77. /**
  78. * @var array contains the join content
  79. * the key is the join type, for now we have 'default' and 'left'
  80. * inside each key 'table' contains the table
  81. * key 'where' contains the where clause for the join
  82. * @access private
  83. */
  84. var $_join = array();
  85. /**
  86. * @var string which column to index the result by
  87. * @access private
  88. */
  89. var $_index = null;
  90. /**
  91. * @var string the group-by clause
  92. * @access private
  93. */
  94. var $_group = '';
  95. /**
  96. * @var array the limit
  97. * @access private
  98. */
  99. var $_limit = array();
  100. /**
  101. * @var string type of result to return
  102. * @access private
  103. */
  104. var $_resultType = 'none';
  105. /**
  106. * @var array the metadata temporary saved
  107. * @access private
  108. */
  109. var $_metadata = array();
  110. /**
  111. * @var string
  112. * @access private
  113. */
  114. var $_lastQuery = null;
  115. /**
  116. * @var string the rows that shall be selected
  117. * @access private
  118. */
  119. var $_select = '*';
  120. /**
  121. * @var string the rows that shall not be selected
  122. * @access private
  123. */
  124. var $_dontSelect = '';
  125. /**
  126. * @var array this array saves different modes in which this class works
  127. * i.e. 'raw' means no quoting before saving/updating data
  128. * @access private
  129. */
  130. var $options = array(
  131. 'raw' => false,
  132. 'verbose' => true, // set this to false in a productive environment
  133. // it will produce error-logs if set to true
  134. 'useCache' => false,
  135. 'logFile' => false,
  136. );
  137. /**
  138. * this array contains information about the tables
  139. * those are
  140. * - 'name' => the real table name
  141. * - 'shortName' => the short name used, so that when moving the table i.e.
  142. * onto a provider's db and u have to rename the tables to
  143. * longer names this name will be relevant, i.e. when
  144. * autoJoining, i.e. a table name on your local machine is:
  145. * 'user' but online it has to be 'applName_user' then the
  146. * shortName will be used to determine if a column refers to
  147. * another table, if the colName is 'user_id', it knows the
  148. * shortName 'user' refers to the table 'applName_user'
  149. */
  150. var $tableSpec = array();
  151. /**
  152. * this is the regular expression that shall be used to find a table's shortName
  153. * in a column name, the string found by using this regular expression will be removed
  154. * from the column name and it will be checked if it is a table name
  155. * i.e. the default '/_id$/' would find the table name 'user' from the column name 'user_id'
  156. */
  157. var $_tableNameToShortNamePreg = '/^.*_/';
  158. /**
  159. * @var array this array caches queries that have already been built once
  160. * to reduce the execution time
  161. */
  162. var $_queryCache = array();
  163. /**
  164. * The object that contains the log-instance
  165. */
  166. var $_logObject = null;
  167. /**
  168. * Some internal data the logging needs
  169. */
  170. var $_logData = array();
  171. // }}}
  172. // {{{ __construct()
  173. /**
  174. * this is the constructor, as it will be implemented in ZE2 (php5)
  175. *
  176. * @version 2002/04/02
  177. * @access public
  178. * @author Wolfram Kriesing <wk@visionp.de>
  179. * @param object db-object
  180. */
  181. /*
  182. function __construct($dsn=false, $options=array())
  183. {
  184. if (!isset($options['autoConnect'])) {
  185. $autoConnect = true;
  186. } else {
  187. $autoConnect = $options['autoConnect'];
  188. }
  189. if (isset($options['errorCallback'])) {
  190. $this->setErrorCallback($options['errorCallback']);
  191. }
  192. if (isset($options['errorSetCallback'])) {
  193. $this->setErrorSetCallback($options['errorSetCallback']);
  194. }
  195. if (isset($options['errorLogCallback'])) {
  196. $this->setErrorLogCallback($options['errorLogCallback']);
  197. }
  198. if ($autoConnect && $dsn) {
  199. $this->connect($dsn, $options);
  200. }
  201. //we would need to parse the dsn first ... i dont feel like now :-)
  202. // oracle has all column names in upper case
  203. //FIXXXME make the class work only with upper case when we work with oracle
  204. //if ($this->db->phptype=='oci8' && !$this->primaryCol) {
  205. // $this->primaryCol = 'ID';
  206. //}
  207. if ($this->sequenceName == null) {
  208. $this->sequenceName = $this->table;
  209. }
  210. }
  211. */
  212. // }}}
  213. // {{{ DB_QueryTool_Query()
  214. /**
  215. * @version 2002/04/02
  216. * @access public
  217. * @author Wolfram Kriesing <wk@visionp.de>
  218. * @param mixed $dsn DSN string, DSN array or DB object
  219. * @param array $options
  220. */
  221. function DB_QueryTool_Query($dsn=false, $options=array())
  222. {
  223. //$this->__construct($dsn, $options);
  224. if (!isset($options['autoConnect'])) {
  225. $autoConnect = true;
  226. } else {
  227. $autoConnect = $options['autoConnect'];
  228. unset($options['autoConnect']);
  229. }
  230. if (isset($options['errorCallback'])) {
  231. $this->setErrorCallback($options['errorCallback']);
  232. unset($options['errorCallback']);
  233. }
  234. if (isset($options['errorSetCallback'])) {
  235. $this->setErrorSetCallback($options['errorSetCallback']);
  236. unset($options['errorSetCallback']);
  237. }
  238. if (isset($options['errorLogCallback'])) {
  239. $this->setErrorLogCallback($options['errorLogCallback']);
  240. unset($options['errorLogCallback']);
  241. }
  242. if ($autoConnect && $dsn) {
  243. $this->connect($dsn, $options);
  244. }
  245. if (is_null($this->sequenceName)) {
  246. $this->sequenceName = $this->table;
  247. }
  248. }
  249. // }}}
  250. // {{{ connect()
  251. /**
  252. * use this method if you want to connect manually
  253. * @param mixed $dsn DSN string, DSN array or MDB object
  254. * @param array $options
  255. */
  256. function connect($dsn, $options=array())
  257. {
  258. if (is_object($dsn)) {
  259. $res = $this->db =& $dsn;
  260. } else {
  261. $res = $this->db = DB::connect($dsn, $options);
  262. }
  263. if (DB::isError($res)) {
  264. // FIXXME what shall we do here?
  265. $this->_errorLog($res->getUserInfo());
  266. } else {
  267. $this->db->setFetchMode(DB_FETCHMODE_ASSOC);
  268. }
  269. }
  270. // }}}
  271. // {{{ getDbInstance()
  272. /**
  273. * @return reference to current DB instance
  274. */
  275. function &getDbInstance()
  276. {
  277. return $this->db;
  278. }
  279. // }}}
  280. // {{{ setDbInstance()
  281. /**
  282. * Setup using an existing connection.
  283. * this also sets the DB_FETCHMODE_ASSOC since this class
  284. * needs this to be set!
  285. *
  286. * @param object a reference to an existing DB-object
  287. * @return void
  288. */
  289. function setDbInstance(&$dbh)
  290. {
  291. $this->db =& $dbh;
  292. $this->db->setFetchMode(DB_FETCHMODE_ASSOC);
  293. }
  294. // }}}
  295. // {{{ get()
  296. /**
  297. * get the data of a single entry
  298. * if the second parameter is only one column the result will be returned
  299. * directly not as an array!
  300. *
  301. * @version 2002/03/05
  302. * @access public
  303. * @author Wolfram Kriesing <wk@visionp.de>
  304. * @param integer the id of the element to retrieve
  305. * @param string if this is given only one row shall be returned, directly, not an array
  306. * @return mixed (1) an array of the retrieved data
  307. * (2) if the second parameter is given and its only one column,
  308. * only this column's data will be returned
  309. * (3) false in case of failure
  310. */
  311. function get($id, $column='')
  312. {
  313. $table = $this->table;
  314. $getMethod = 'getRow';
  315. if ($column && !strpos($column, ',')) { // if only one column shall be selected
  316. $getMethod = 'getOne';
  317. }
  318. // we dont use 'setSelect' here, since this changes the setup of the class, we
  319. // build the query directly
  320. // if $column is '' then _buildSelect selects '*' anyway, so that's the same behaviour as before
  321. $query['select'] = $this->_buildSelect($column);
  322. $query['where'] = $this->_buildWhere($this->table.'.'.$this->primaryCol.'='.$id);
  323. $queryString = $this->_buildSelectQuery($query);
  324. return $this->returnResult($this->execute($queryString,$getMethod));
  325. }
  326. // }}}
  327. // {{{ getMultiple()
  328. /**
  329. * gets the data of the given ids
  330. *
  331. * @version 2002/04/23
  332. * @access public
  333. * @author Wolfram Kriesing <wk@visionp.de>
  334. * @param array this is an array of ids to retreive
  335. * @param string the column to search in for
  336. * @return mixed an array of the retreived data, or false in case of failure
  337. * when failing an error is set in $this->_error
  338. */
  339. function getMultiple($ids, $column='')
  340. {
  341. $col = $this->primaryCol;
  342. if ($column) {
  343. $col = $column;
  344. }
  345. // FIXXME if $ids has no table.col syntax and we are using joins, the table better be put in front!!!
  346. $ids = $this->_quoteArray($ids);
  347. $query['where'] = $this->_buildWhere($col.' IN ('.implode(',', $ids).')');
  348. $queryString = $this->_buildSelectQuery($query);
  349. return $this->returnResult($this->execute($queryString));
  350. }
  351. // }}}
  352. // {{{ getAll()
  353. /**
  354. * get all entries from the DB
  355. * for sorting use setOrder!!!, the last 2 parameters are deprecated
  356. *
  357. * @version 2002/03/05
  358. * @access public
  359. * @author Wolfram Kriesing <wk@visionp.de>
  360. * @param int to start from
  361. * @param int the number of rows to show
  362. * @param string the DB-method to use, i dont know if we should leave this param here ...
  363. * @return mixed an array of the retreived data, or false in case of failure
  364. * when failing an error is set in $this->_error
  365. */
  366. function getAll($from=0,$count=0,$method='getAll')
  367. {
  368. $query = array();
  369. if ($count) {
  370. $query = array('limit' => array($from, $count));
  371. }
  372. return $this->returnResult($this->execute($this->_buildSelectQuery($query), $method));
  373. }
  374. // }}}
  375. // {{{ getCol()
  376. /**
  377. * this method only returns one column, so the result will be a one dimensional array
  378. * this does also mean that using setSelect() should be set to *one* column, the one you want to
  379. * have returned a most common use case for this could be:
  380. * $table->setSelect('id');
  381. * $ids = $table->getCol();
  382. * OR
  383. * $ids = $table->getCol('id');
  384. * so ids will be an array with all the id's
  385. *
  386. * @version 2003/02/25
  387. * @access public
  388. * @author Wolfram Kriesing <wk@visionp.de>
  389. * @param string the column that shall be retreived
  390. * @param int to start from
  391. * @param int the number of rows to show
  392. * @return mixed an array of the retreived data, or false in case of failure
  393. * when failing an error is set in $this->_error
  394. */
  395. function getCol($column=null, $from=0, $count=0)
  396. {
  397. $query = array();
  398. if (!is_null($column)) {
  399. // by using _buildSelect() i can be sure that the table name will not be ambigious
  400. // i.e. in a join, where all the joined tables have a col 'id'
  401. // _buildSelect() will put the proper table name in front in case there is none
  402. $query['select'] = $this->_buildSelect($column);
  403. }
  404. if ($count) {
  405. $query['limit'] = array($from,$count);
  406. }
  407. return $this->returnResult($this->execute($this->_buildSelectQuery($query), 'getCol'));
  408. }
  409. // }}}
  410. // {{{ getCount()
  411. /**
  412. * get the number of entries
  413. *
  414. * @version 2002/04/02
  415. * @access public
  416. * @author Wolfram Kriesing <wk@visionp.de>
  417. * @param
  418. * @return mixed an array of the retreived data, or false in case of failure
  419. * when failing an error is set in $this->_error
  420. */
  421. function getCount()
  422. {
  423. /* the following query works on mysql
  424. SELECT count(DISTINCT image.id) FROM image2tree
  425. RIGHT JOIN image ON image.id = image2tree.image_id
  426. the reason why this is needed - i just wanted to get the number of rows that do exist if the result is grouped by image.id
  427. the following query is what i tried first, but that returns the number of rows that have been grouped together
  428. for each image.id
  429. SELECT count(*) FROM image2tree
  430. RIGHT JOIN image ON image.id = image2tree.image_id GROUP BY image.id
  431. so that's why we do the following, i am not sure if that is standard SQL and absolutley correct!!!
  432. */
  433. //FIXXME see comment above if this is absolutely correct!!!
  434. if ($group = $this->_buildGroup()) {
  435. $query['select'] = 'COUNT(DISTINCT '.$group.')';
  436. $query['group'] = '';
  437. } else {
  438. $query['select'] = 'COUNT(*)';
  439. }
  440. $query['order'] = ''; // order is not of importance and might freak up the special group-handling up there, since the order-col is not be known
  441. /*# FIXXME use the following line, but watch out, then it has to be used in every method, or this
  442. # value will be used always, simply try calling getCount and getAll afterwards, getAll will return the count :-)
  443. # if getAll doesn't use setSelect!!!
  444. */
  445. //$this->setSelect('count(*)');
  446. $queryString = $this->_buildSelectQuery($query, true);
  447. return ($res = $this->execute($queryString, 'getOne')) ? $res : 0;
  448. }
  449. // }}}
  450. // {{{ getDefaultValues()
  451. /**
  452. * return an empty element where all the array elements do already exist
  453. * corresponding to the columns in the DB
  454. *
  455. * @version 2002/04/05
  456. * @access public
  457. * @author Wolfram Kriesing <wk@visionp.de>
  458. * @return array an empty, or pre-initialized element
  459. */
  460. function getDefaultValues()
  461. {
  462. $ret = array();
  463. // here we read all the columns from the DB and initialize them
  464. // with '' to prevent PHP-warnings in case we use error_reporting=E_ALL
  465. foreach ($this->metadata() as $aCol=>$x) {
  466. $ret[$aCol] = '';
  467. }
  468. return $ret;
  469. }
  470. // }}}
  471. // {{{ getEmptyElement()
  472. /**
  473. * this is just for BC
  474. * @deprecated
  475. */
  476. function getEmptyElement()
  477. {
  478. $this->getDefaultValues();
  479. }
  480. // }}}
  481. // {{{ getQueryString()
  482. /**
  483. * Render the current query and return it as a string.
  484. *
  485. * @return string the current query
  486. */
  487. function getQueryString()
  488. {
  489. $ret = $this->_buildSelectQuery();
  490. if (is_string($ret)) {
  491. $ret = trim($ret);
  492. }
  493. return $ret;
  494. }
  495. // }}}
  496. // {{{ save()
  497. /**
  498. * save data, calls either update or add
  499. * if the primaryCol is given in the data this method knows that the
  500. * data passed to it are meant to be updated (call 'update'), otherwise it will
  501. * call the method 'add'.
  502. * If you dont like this behaviour simply stick with the methods 'add'
  503. * and 'update' and ignore this one here.
  504. * This method is very useful when you have validation checks that have to
  505. * be done for both adding and updating, then you can simply overwrite this
  506. * method and do the checks in here, and both cases will be validated first.
  507. *
  508. * @version 2002/03/11
  509. * @access public
  510. * @author Wolfram Kriesing <wk@visionp.de>
  511. * @param array contains the new data that shall be saved in the DB
  512. * @return mixed the data returned by either add or update-method
  513. */
  514. function save($data)
  515. {
  516. if (!empty($data[$this->primaryCol])) {
  517. return $this->update($data);
  518. }
  519. return $this->add($data);
  520. }
  521. // }}}
  522. // {{{ update()
  523. /**
  524. * update the member data of a data set
  525. *
  526. * @version 2002/03/06
  527. * @access public
  528. * @author Wolfram Kriesing <wk@visionp.de>
  529. * @param array contains the new data that shall be saved in the DB
  530. * the id has to be given in the field with the key 'ID'
  531. * @return mixed true on success, or false otherwise
  532. */
  533. function update($newData)
  534. {
  535. $query = array();
  536. // do only set the 'where' part in $query, if a primary column is given
  537. // if not the default 'where' clause is used
  538. if (isset($newData[$this->primaryCol])) {
  539. $query['where'] = $this->primaryCol.'='.$newData[$this->primaryCol];
  540. }
  541. $newData = $this->_checkColumns($newData, 'update');
  542. $values = array();
  543. $raw = $this->getOption('raw');
  544. foreach ($newData as $key => $aData) { // quote the data
  545. //$values[] = "{$this->table}.$key=". ($raw ? $aData : $this->db->quote($aData));
  546. $values[] = "$key=". ($raw ? $aData : $this->db->quote($aData));
  547. }
  548. $query['set'] = implode(',', $values);
  549. //FIXXXME _buildUpdateQuery() seems to take joins into account, whcih is bullshit here
  550. $updateString = $this->_buildUpdateQuery($query);
  551. #print '$updateString = '.$updateString;
  552. return $this->execute($updateString, 'query') ? true : false;
  553. }
  554. // }}}
  555. // {{{ add()
  556. /**
  557. * add a new member in the DB
  558. *
  559. * @version 2002/04/02
  560. * @access public
  561. * @author Wolfram Kriesing <wk@visionp.de>
  562. * @param array contains the new data that shall be saved in the DB
  563. * @return mixed the inserted id on success, or false otherwise
  564. */
  565. function add($newData)
  566. {
  567. // if no primary col is given, get next sequence value
  568. if (empty($newData[$this->primaryCol])) {
  569. if ($this->primaryCol) { // do only use the sequence if a primary column is given
  570. // otherwise the data are written as given
  571. $id = $this->db->nextId($this->sequenceName);
  572. $newData[$this->primaryCol] = (int)$id;
  573. } else {
  574. // if no primary col is given return true on success
  575. $id = true;
  576. }
  577. } else {
  578. $id = $newData[$this->primaryCol];
  579. }
  580. //unset($newData[$this->primaryCol]);
  581. $newData = $this->_checkColumns($newData, 'add');
  582. $newData = $this->_quoteArray($newData);
  583. $query = sprintf( 'INSERT INTO %s (%s) VALUES (%s)',
  584. $this->table,
  585. implode(', ', array_keys($newData)),
  586. implode(', ', $newData)
  587. );
  588. return $this->execute($query, 'query') ? $id : false;
  589. }
  590. // }}}
  591. // {{{ addMultiple()
  592. /**
  593. * adds multiple new members in the DB
  594. *
  595. * @version 2002/07/17
  596. * @access public
  597. * @author Wolfram Kriesing <wk@visionp.de>
  598. * @param array contains an array of new data that shall be saved in the DB
  599. * the key-value pairs have to be the same for all the data!!!
  600. * @return mixed the inserted ids on success, or false otherwise
  601. */
  602. function addMultiple($data)
  603. {
  604. if (!sizeof($data)) {
  605. return false;
  606. }
  607. // the inserted ids which will be returned or if no primaryCol is given
  608. // we return true by default
  609. $retIds = $this->primaryCol ? array() : true;
  610. $allData = array(); // each row that will be inserted
  611. foreach ($data as $key => $aData) {
  612. $aData = $this->_checkColumns($aData, 'add');
  613. $aData = $this->_quoteArray($aData);
  614. if (empty($aData[$this->primaryCol])) {
  615. if ($this->primaryCol) { // do only use the sequence if a primary column is given
  616. // otherwise the data are written as given
  617. $retIds[] = $id = (int)$this->db->nextId($this->sequenceName);
  618. $aData[$this->primaryCol] = $id;
  619. }
  620. } else {
  621. $retIds[] = $aData[$this->primaryCol];
  622. }
  623. $allData[] = '('.implode(', ', $aData).')';
  624. }
  625. $query = sprintf( 'INSERT INTO %s (%s) VALUES %s',
  626. $this->table,
  627. implode(', ', array_keys($aData)), // use the keys of the last element built
  628. implode(', ', $allData)
  629. );
  630. return $this->execute($query, 'query') ? $retIds : false;
  631. }
  632. // }}}
  633. // {{{ remove()
  634. /**
  635. * removes a member from the DB
  636. *
  637. * @version 2002/04/08
  638. * @access public
  639. * @author Wolfram Kriesing <wk@visionp.de>
  640. * @param mixed integer/string - the value of the column that shall be removed
  641. * array - multiple columns that shall be matched, the second parameter will be ignored
  642. * @param string the column to match the data against, only if $data is not an array
  643. * @return boolean
  644. */
  645. function remove($data, $whereCol='')
  646. {
  647. $raw = $this->getOption('raw');
  648. if (is_array($data)) {
  649. //FIXXME check $data if it only contains columns that really exist in the table
  650. $wheres = array();
  651. foreach ($data as $key => $val) {
  652. $wheres[] = $key.'='. ($raw ? $val : $this->db->quote($val));
  653. }
  654. $whereClause = implode(' AND ',$wheres);
  655. } else {
  656. if (empty($whereCol)) {
  657. $whereCol = $this->primaryCol;
  658. }
  659. $whereClause = $whereCol.'='. ($raw ? $data : $this->db->quote($data));
  660. }
  661. $query = sprintf( 'DELETE FROM %s WHERE %s',
  662. $this->table,
  663. $whereClause
  664. );
  665. return $this->execute($query, 'query') ? true : false;
  666. // i think this method should return the ID's that it removed, this way we could simply use the result
  667. // for further actions that depend on those id ... or? make stuff easier, see ignaz::imail::remove
  668. }
  669. // }}}
  670. // {{{ removeAll()
  671. /**
  672. * empty a table
  673. *
  674. * @version 2002/06/17
  675. * @access public
  676. * @author Wolfram Kriesing <wk@visionp.de>
  677. * @return
  678. */
  679. function removeAll()
  680. {
  681. $query = 'DELETE FROM '.$this->table;
  682. return $this->execute($query, 'query') ? true : false;
  683. }
  684. // }}}
  685. // {{{ removeMultiple()
  686. /**
  687. * remove the datasets with the given ids
  688. *
  689. * @version 2002/04/24
  690. * @access public
  691. * @author Wolfram Kriesing <wk@visionp.de>
  692. * @param array the ids to remove
  693. * @return
  694. */
  695. function removeMultiple($ids, $colName='')
  696. {
  697. if (empty($colName)) {
  698. $colName = $this->primaryCol;
  699. }
  700. $ids = $this->_quoteArray($ids);
  701. $query = sprintf( 'DELETE FROM %s WHERE %s IN (%s)',
  702. $this->table,
  703. $colName,
  704. implode(',', $ids)
  705. );
  706. return $this->execute($query, 'query') ? true : false;
  707. }
  708. // }}}
  709. // {{{ removePrimary()
  710. /**
  711. * removes a member from the DB and calls the remove methods of the given objects
  712. * so all rows in another table that refer to this table are erased too
  713. *
  714. * @version 2002/04/08
  715. * @access public
  716. * @author Wolfram Kriesing <wk@visionp.de>
  717. * @param integer the value of the primary key
  718. * @param string the column name of the tables with the foreign keys
  719. * @param object just for convinience, so nobody forgets to call this method
  720. * with at least one object as a parameter
  721. * @return boolean
  722. */
  723. function removePrimary($id, $colName, $atLeastOneObject)
  724. {
  725. $argCounter = 2; // we have 2 parameters that need to be given at least
  726. // func_get_arg returns false and a warning if there are no more parameters, so
  727. // we suppress the warning and check for false
  728. while ($object = @func_get_arg($argCounter++)) {
  729. //FIXXXME let $object also simply be a table name
  730. if (!$object->remove($id, $colName)) {
  731. //FIXXXME do this better
  732. $this->_errorSet("Error removing '$colName=$id' from table {$object->table}.");
  733. return false;
  734. }
  735. }
  736. return ($this->remove($id) ? true : false);
  737. }
  738. // }}}
  739. // {{{ setLimit()
  740. /**
  741. * @param integer $from
  742. * @param integer $count
  743. */
  744. function setLimit($from=0, $count=0)
  745. {
  746. if ($from==0 && $count==0) {
  747. $this->_limit = array();
  748. } else {
  749. $this->_limit = array($from, $count);
  750. }
  751. }
  752. // }}}
  753. // {{{ getLimit()
  754. /**
  755. * @return array
  756. */
  757. function getLimit()
  758. {
  759. return $this->_limit;
  760. }
  761. // }}}
  762. // {{{ setWhere()
  763. /**
  764. * sets the where condition which is used for the current instance
  765. *
  766. * @version 2002/04/16
  767. * @access public
  768. * @author Wolfram Kriesing <wk@visionp.de>
  769. * @param string the where condition, this can be complete like 'X=7 AND Y=8'
  770. */
  771. function setWhere($whereCondition='')
  772. {
  773. $this->_where = $whereCondition;
  774. //FIXXME parse the where condition and replace ambigious column names, such as "name='Deutschland'" with "country.name='Deutschland'"
  775. // then the users dont have to write that explicitly and can use the same name as in the setOrder i.e. setOrder('name,_net_name,_netPrefix_prefix');
  776. }
  777. // }}}
  778. // {{{ getWhere()
  779. /**
  780. * gets the where condition which is used for the current instance
  781. *
  782. * @version 2002/04/22
  783. * @access public
  784. * @author Wolfram Kriesing <wk@visionp.de>
  785. * @return string the where condition, this can be complete like 'X=7 AND Y=8'
  786. */
  787. function getWhere()
  788. {
  789. return $this->_where;
  790. }
  791. // }}}
  792. // {{{ addWhere()
  793. /**
  794. * only adds a string to the where clause
  795. *
  796. * @version 2002/07/22
  797. * @access public
  798. * @author Wolfram Kriesing <wk@visionp.de>
  799. * @param string the where clause to add to the existing one
  800. * @param string the condition for how to concatenate the new where clause
  801. * to the existing one
  802. */
  803. function addWhere($where, $condition='AND')
  804. {
  805. if ($this->getWhere()) {
  806. $where = $this->getWhere().' '.$condition.' '.$where;
  807. }
  808. $this->setWhere($where);
  809. }
  810. // }}}
  811. // {{{ addWhereSearch()
  812. /**
  813. * add a where-like clause which works like a search for the given string
  814. * i.e. calling it like this:
  815. * $this->addWhereSearch('name', 'otto hans')
  816. * produces a where clause like this one
  817. * LOWER(name) LIKE "%otto%hans%"
  818. * so the search finds the given string
  819. *
  820. * @version 2002/08/14
  821. * @access public
  822. * @author Wolfram Kriesing <wk@visionp.de>
  823. * @param string the column to search in for
  824. * @param string the string to search for
  825. */
  826. function addWhereSearch($column, $string, $condition='AND')
  827. {
  828. // if the column doesn't contain a tablename use the current table name
  829. // in case it is a defined column to prevent ambiguous rows
  830. if (strpos($column, '.') === false) {
  831. $meta = $this->metadata();
  832. if (isset($meta[$column])) {
  833. $column = $this->table.".$column";
  834. }
  835. }
  836. $string = $this->db->quote('%'.str_replace(' ', '%', strtolower($string)).'%');
  837. $this->addWhere("LOWER($column) LIKE $string", $condition);
  838. }
  839. // }}}
  840. // {{{ setOrder()
  841. /**
  842. * sets the order condition which is used for the current instance
  843. *
  844. * @version 2002/05/16
  845. * @access public
  846. * @author Wolfram Kriesing <wk@visionp.de>
  847. * @param string the where condition, this can be complete like 'X=7 AND Y=8'
  848. * @param boolean sorting order (TRUE => ASC, FALSE => DESC)
  849. */
  850. function setOrder($orderCondition='', $desc=false)
  851. {
  852. $this->_order = $orderCondition .($desc ? ' DESC' : '');
  853. }
  854. // }}}
  855. // {{{ addOrder()
  856. /**
  857. * Add a order parameter to the query.
  858. *
  859. * @version 2003/05/28
  860. * @access public
  861. * @author Wolfram Kriesing <wk@visionp.de>
  862. * @param string the where condition, this can be complete like 'X=7 AND Y=8'
  863. * @param boolean sorting order (TRUE => ASC, FALSE => DESC)
  864. */
  865. function addOrder($orderCondition='', $desc=false)
  866. {
  867. $order = $orderCondition .($desc ? ' DESC' : '');
  868. if ($this->_order) {
  869. $this->_order = $this->_order.','.$order;
  870. } else {
  871. $this->_order = $order;
  872. }
  873. }
  874. // }}}
  875. // {{{ getOrder()
  876. /**
  877. * gets the order condition which is used for the current instance
  878. *
  879. * @version 2002/05/16
  880. * @access public
  881. * @author Wolfram Kriesing <wk@visionp.de>
  882. * @return string the order condition, this can be complete like 'ID,TIMESTAMP DESC'
  883. */
  884. function getOrder()
  885. {
  886. return $this->_order;
  887. }
  888. // }}}
  889. // {{{ setHaving()
  890. /**
  891. * sets the having definition
  892. *
  893. * @version 2003/06/05
  894. * @access public
  895. * @author Johannes Schaefer <johnschaefer@gmx.de>
  896. * @param string the having definition
  897. */
  898. function setHaving($having='')
  899. {
  900. $this->_having = $having;
  901. }
  902. // }}}
  903. // {{{ getHaving()
  904. /**
  905. * gets the having definition which is used for the current instance
  906. *
  907. * @version 2003/06/05
  908. * @access public
  909. * @author Johannes Schaefer <johnschaefer@gmx.de>
  910. * @return string the having definition
  911. */
  912. function getHaving()
  913. {
  914. return $this->_having;
  915. }
  916. // }}}
  917. // {{{ addHaving()
  918. /**
  919. * Extend the current having clause. This is very useful, when you are building
  920. * this clause from different places and don't want to overwrite the currently
  921. * set having clause, but extend it.
  922. *
  923. * @param string this is a having clause, i.e. 'column' or 'table.column' or 'MAX(column)'
  924. * @param string the connection string, which usually stays the default, which is ',' (a comma)
  925. */
  926. function addHaving($what='*', $connectString=' AND ')
  927. {
  928. if ($this->_having) {
  929. $this->_having = $this->_having.$connectString.$what;
  930. } else {
  931. $this->_having = $what;
  932. }
  933. }
  934. // }}}
  935. // {{{ setJoin()
  936. /**
  937. * sets a join-condition
  938. *
  939. * @version 2002/06/10
  940. * @access public
  941. * @author Wolfram Kriesing <wk@visionp.de>
  942. * @param mixed either a string or an array that contains
  943. * the table(s) to join on the current table
  944. * @param string the where clause for the join
  945. */
  946. function setJoin($table=null, $where=null, $joinType='default')
  947. {
  948. //FIXXME make it possible to pass a table name as a string like this too 'user u'
  949. // where u is the string that can be used to refer to this table in a where/order
  950. // or whatever condition
  951. // this way it will be possible to join tables with itself, like setJoin(array('user u','user u1'))
  952. // this wouldnt work yet, but for doing so we would need to change the _build methods too!!!
  953. // because they use getJoin('tables') and this simply returns all the tables in use
  954. // but don't take care of the mentioned syntax
  955. if (is_null($table) || is_null($where)) { // remove the join if not sufficient parameters are given
  956. $this->_join[$joinType] = array();
  957. return;
  958. }
  959. /* this causes problems if we use the order-by, since it doenst know the name to order it by ... :-)
  960. // replace the table names with the internal name used for the join
  961. // this way we can also join one table multiple times if it will be implemented one day
  962. $this->_join[$table] = preg_replace('/'.$table.'/','j1',$where);
  963. */
  964. $this->_join[$joinType][$table] = $where;
  965. }
  966. // }}}
  967. // {{{ setJoin()
  968. /**
  969. * if you do a left join on $this->table you will get all entries
  970. * from $this->table, also if there are no entries for them in the joined table
  971. * if both parameters are not given the left-join will be removed
  972. * NOTE: be sure to only use either a right or a left join
  973. *
  974. * @version 2002/07/22
  975. * @access public
  976. * @author Wolfram Kriesing <wk@visionp.de>
  977. * @param string the table(s) to be left-joined
  978. * @param string the where clause for the join
  979. */
  980. function setLeftJoin($table=null, $where=null)
  981. {
  982. $this->setJoin($table, $where, 'left');
  983. }
  984. // }}}
  985. // {{{ addLeftJoin()
  986. /**
  987. * @param string the table to be left-joined
  988. * @param string the where clause for the join
  989. * @param string the join type
  990. */
  991. function addLeftJoin($table, $where, $type='left')
  992. {
  993. // init value, to prevent E_ALL-warning
  994. if (!isset($this->_join[$type]) || !$this->_join[$type]) {
  995. $this->_join[$type] = array();
  996. }
  997. $this->_join[$type][$table] = $where;
  998. }
  999. // }}}
  1000. // {{{ setRightJoin()
  1001. /**
  1002. * see setLeftJoin for further explaination on what a left/right join is
  1003. * NOTE: be sure to only use either a right or a left join
  1004. //FIXXME check if the above sentence is necessary and if sql doesnt allow the use of both
  1005. *
  1006. * @see setLeftJoin()
  1007. * @version 2002/09/04
  1008. * @access public
  1009. * @author Wolfram Kriesing <wk@visionp.de>
  1010. * @param string the table(s) to be right-joined
  1011. * @param string the where clause for the join
  1012. */
  1013. function setRightJoin($table=null, $where=null)
  1014. {
  1015. $this->setJoin($table, $where, 'right');
  1016. }
  1017. // }}}
  1018. // {{{ getJoin()
  1019. /**
  1020. * gets the join-condition
  1021. *
  1022. * @access public
  1023. * @param string [null|''|'table'|'tables'|'right'|'left']
  1024. * @return array gets the join parameters
  1025. */
  1026. function getJoin($what=null)
  1027. {
  1028. // if the user requests all the join data or if the join is empty, return it
  1029. if (is_null($what) || empty($this->_join)) {
  1030. return $this->_join;
  1031. }
  1032. $ret = array();
  1033. switch (strtolower($what)) {
  1034. case 'table':
  1035. case 'tables':
  1036. foreach ($this->_join as $aJoin) {
  1037. if (count($aJoin)) {
  1038. $ret = array_merge($ret, array_keys($aJoin));
  1039. }
  1040. }
  1041. break;
  1042. case 'right': // return right-join data only
  1043. case 'left': // return left join data only
  1044. if (count($this->_join[$what])) {
  1045. $ret = array_merge($ret, $this->_join[$what]);
  1046. }
  1047. break;
  1048. }
  1049. return $ret;
  1050. }
  1051. // }}}
  1052. // {{{ addJoin()
  1053. /**
  1054. * adds a table and a where clause that shall be used for the join
  1055. * instead of calling
  1056. * setJoin(array(table1,table2),'<where clause1> AND <where clause2>')
  1057. * you can also call
  1058. * setJoin(table1,'<where clause1>')
  1059. * addJoin(table2,'<where clause2>')
  1060. * or where it makes more sense is to build a query which is made out of a
  1061. * left join and a standard join
  1062. * setLeftJoin(table1,'<where clause1>')
  1063. * // results in ... FROM $this->table LEFT JOIN table ON <where clause1>
  1064. * addJoin(table2,'<where clause2>')
  1065. * // results in ... FROM $this->table,table2 LEFT JOIN table ON <where clause1> WHERE <where clause2>
  1066. *
  1067. * @access public
  1068. * @param string the table to be joined
  1069. * @param string the where clause for the join
  1070. * @param string the join type
  1071. */
  1072. function addJoin($table, $where, $type='default')
  1073. {
  1074. if ($table == $this->table) {
  1075. return; //skip. Self joins are not supported.
  1076. }
  1077. // init value, to prevent E_ALL-warning
  1078. if (!isset($this->_join[$type]) || !$this->_join[$type]) {
  1079. $this->_join[$type] = array();
  1080. }
  1081. $this->_join[$type][$table] = $where;
  1082. }
  1083. // }}}
  1084. // {{{ setTable()
  1085. /**
  1086. * sets the table this class is currently working on
  1087. *
  1088. * @version 2002/07/11
  1089. * @access public
  1090. * @author Wolfram Kriesing <wk@visionp.de>
  1091. * @param string the table name
  1092. */
  1093. function setTable($table)
  1094. {
  1095. $this->table = $table;
  1096. }
  1097. // }}}
  1098. // {{{ getTable()
  1099. /**
  1100. * gets the table this class is currently working on
  1101. *
  1102. * @version 2002/07/11
  1103. * @access public
  1104. * @author Wolfram Kriesing <wk@visionp.de>
  1105. * @return string the table name
  1106. */
  1107. function getTable()
  1108. {
  1109. return $this->table;
  1110. }
  1111. // }}}
  1112. // {{{ setGroup()
  1113. /**
  1114. * sets the group-by condition
  1115. *
  1116. * @version 2002/07/22
  1117. * @access public
  1118. * @author Wolfram Kriesing <wk@visionp.de>
  1119. * @param string the group condition
  1120. */
  1121. function setGroup($group='')
  1122. {
  1123. $this->_group = $group;
  1124. //FIXXME parse the condition and replace ambigious column names, such as "name='Deutschland'" with "country.name='Deutschland'"
  1125. // then the users dont have to write that explicitly and can use the same name as in the setOrder i.e. setOrder('name,_net_name,_netPrefix_prefix');
  1126. }
  1127. // }}}
  1128. // {{{ getGroup()
  1129. /**
  1130. * gets the group condition which is used for the current instance
  1131. *
  1132. * @version 2002/07/22
  1133. * @access public
  1134. * @author Wolfram Kriesing <wk@visionp.de>
  1135. * @return string the group condition
  1136. */
  1137. function getGroup()
  1138. {
  1139. return $this->_group;
  1140. }
  1141. // }}}
  1142. // {{{ setSelect()
  1143. /**
  1144. * limit the result to return only the columns given in $what
  1145. * @param string fields that shall be selected
  1146. */
  1147. function setSelect($what='*')
  1148. {
  1149. $this->_select = $what;
  1150. }
  1151. // }}}
  1152. // {{{ addSelect()
  1153. /**
  1154. * add a string to the select part of the query
  1155. *
  1156. * add a string to the select-part of the query and connects it to an existing
  1157. * string using the $connectString, which by default is a comma.
  1158. * (SELECT xxx FROM - xxx is the select-part of a query)
  1159. *
  1160. * @version 2003/01/08
  1161. * @access public
  1162. * @author Wolfram Kriesing <wk@visionp.de>
  1163. * @param string the string that shall be added to the select-part
  1164. * @param string the string to connect the new string with the existing one
  1165. * @return void
  1166. */
  1167. function addSelect($what='*', $connectString=',')
  1168. {
  1169. // if the select string is not empty add the string, otherwise simply set it
  1170. if ($this->_select) {
  1171. $this->_select = $this->_select.$connectString.$what;
  1172. } else {
  1173. $this->_select = $what;
  1174. }
  1175. }
  1176. // }}}
  1177. // {{{ getSelect()
  1178. /**
  1179. * @return string
  1180. */
  1181. function getSelect()
  1182. {
  1183. return $this->_select;
  1184. }
  1185. // }}}
  1186. // {{{ setDontSelect()
  1187. /**
  1188. * @param string
  1189. */
  1190. function setDontSelect($what='')
  1191. {
  1192. $this->_dontSelect = $what;
  1193. }
  1194. // }}}
  1195. // {{{ getDontSelect()
  1196. /**
  1197. * @return string
  1198. */
  1199. function getDontSelect()
  1200. {
  1201. return $this->_dontSelect;
  1202. }
  1203. // }}}
  1204. // {{{ reset()
  1205. /**
  1206. * reset all the set* settings; with no parameter given, it resets them all
  1207. *
  1208. * @version 2002/09/16
  1209. * @access public
  1210. * @author Wolfram Kriesing <wk@visionp.de>
  1211. * @return void
  1212. */
  1213. function reset($what=array())
  1214. {
  1215. if (!sizeof($what)) {
  1216. $what = array(
  1217. 'select',
  1218. 'dontSelect',
  1219. 'group',
  1220. 'having',
  1221. 'limit',
  1222. 'where',
  1223. 'index',
  1224. 'order',
  1225. 'join',
  1226. 'leftJoin',
  1227. 'rightJoin'
  1228. );
  1229. }
  1230. foreach ($what as $aReset) {
  1231. $this->{'set'.ucfirst($aReset)}();
  1232. }
  1233. }
  1234. // }}}
  1235. // {{{ setOption()
  1236. /**
  1237. * set mode the class shall work in
  1238. * currently we have the modes:
  1239. * 'raw' does not quote the data before building the query
  1240. *
  1241. * @version 2002/09/17
  1242. * @access public
  1243. * @author Wolfram Kriesing <wk@visionp.de>
  1244. * @param string the mode to be set
  1245. * @param mixed the value of the mode
  1246. * @return void
  1247. */
  1248. function setOption($option, $value)
  1249. {
  1250. $this->options[strtolower($option)] = $value;
  1251. }
  1252. // }}}
  1253. // {{{ getOption()
  1254. /**
  1255. * @return string
  1256. */
  1257. function getOption($option)
  1258. {
  1259. return $this->options[strtolower($option)];
  1260. }
  1261. // }}}
  1262. // {{{ _quoteArray()
  1263. /**
  1264. * quotes all the data in this array if we are not in raw mode!
  1265. * @param array
  1266. */
  1267. function _quoteArray($data)
  1268. {
  1269. if (!$this->getOption('raw')) {
  1270. foreach ($data as $key => $val) {
  1271. $data[$key] = $this->db->quote($val);
  1272. }
  1273. }
  1274. return $data;
  1275. }
  1276. // }}}
  1277. // {{{ _checkColumns()
  1278. /**
  1279. * checks if the columns which are given as the array's indexes really exist
  1280. * if not it will be unset anyway
  1281. *
  1282. * @version 2002/04/16
  1283. * @access public
  1284. * @author Wolfram Kriesing <wk@visionp.de>
  1285. * @param string the actual message, first word should always be the method name,
  1286. * to build the message like this: className::methodname
  1287. * @param integer the line number
  1288. */
  1289. function _checkColumns($newData, $method='unknown')
  1290. {
  1291. if (!$meta = $this->metadata()) { // if no metadata available, return data as given
  1292. return $newData;
  1293. }
  1294. foreach ($newData as $colName => $x) {
  1295. if (!isset($meta[$colName])) {
  1296. $this->_errorLog("$method, column {$this->table}.$colName doesnt exist, value was removed before '$method'",__LINE__);
  1297. unset($newData[$colName]);
  1298. } else {
  1299. // if the current column exists, check the length too, not to write content that is too long
  1300. // prevent DB-errors here
  1301. // do only check the data length if this field is given
  1302. if (isset($meta[$colName]['len']) && ($meta[$colName]['len'] != -1) &&
  1303. ($oldLength=strlen($newData[$colName])) > $meta[$colName]['len']
  1304. ) {
  1305. $this->_errorLog("_checkColumns, had to trim column '$colName' from $oldLength to ".
  1306. $meta[$colName]['DATA_LENGTH'].' characters.', __LINE__);
  1307. $newData[$colName] = substr($newData[$colName], 0, $meta[$colName]['len']);
  1308. }
  1309. }
  1310. }
  1311. return $newData;
  1312. }
  1313. // }}}
  1314. // {{{ debug()
  1315. /**
  1316. * overwrite this method and i.e. print the query $string
  1317. * to see the final query
  1318. *
  1319. * @param string the query mostly
  1320. */
  1321. function debug($string){}
  1322. //
  1323. //
  1324. // ONLY ORACLE SPECIFIC, not very nice since it is DB dependent, but we need it!!!
  1325. //
  1326. //
  1327. // }}}
  1328. // {{{ metadata()
  1329. /**
  1330. * !!!! query COPIED FROM db_oci8.inc - from PHPLIB !!!!
  1331. *
  1332. * @access public
  1333. * @see
  1334. * @version 2001/09
  1335. * @author PHPLIB
  1336. * @param
  1337. * @return
  1338. */
  1339. function metadata($table='')
  1340. {
  1341. // is there an alias in the table name, then we have something like this: 'user ua'
  1342. // cut of the alias and return the table name
  1343. if (strpos($table, ' ') !== false) {
  1344. $split = explode(' ', trim($table));
  1345. $table = $split[0];
  1346. }
  1347. $full = false;
  1348. if (empty($table)) {
  1349. $table = $this->table;
  1350. }
  1351. // to prevent multiple selects for the same metadata
  1352. if (isset($this->_metadata[$table])) {
  1353. return $this->_metadata[$table];
  1354. }
  1355. // FIXXXME use oci8 implementation of newer PEAR::DB-version
  1356. if ($this->db->phptype == 'oci8') {
  1357. $count = 0;
  1358. $id = 0;
  1359. $res = array();
  1360. //# This is a RIGHT OUTER JOIN: "(+)", if you want to see, what
  1361. //# this query results try the following:
  1362. //// $table = new Table; $this->db = new my_DB_Sql; // you have to make
  1363. //// // your own class
  1364. //// $table->show_results($this->db->query(see query vvvvvv))
  1365. ////
  1366. $res = $this->db->getAll("SELECT T.column_name,T.table_name,T.data_type,".
  1367. "T.data_length,T.data_precision,T.data_scale,T.nullable,".
  1368. "T.char_col_decl_length,I.index_name".
  1369. " FROM ALL_TAB_COLUMNS T,ALL_IND_COLUMNS I".
  1370. " WHERE T.column_name=I.column_name (+)".
  1371. " AND T.table_name=I.table_name (+)".
  1372. " AND T.table_name=UPPER('$table') ORDER BY T.column_id");
  1373. if (DB::isError($res)) {
  1374. //$this->_errorSet($res->getMessage());
  1375. // i think we only need to log here, since this method is never used
  1376. // directly for the user's functionality, which means if it fails it
  1377. // is most probably an appl error
  1378. $this->_errorLog($res->getUserInfo());
  1379. return false;
  1380. }
  1381. foreach ($res as $key=>$val) {
  1382. $res[$key]['name'] = $val['COLUMN_NAME'];
  1383. }
  1384. } else {
  1385. if (!is_object($this->db)) {
  1386. return false;
  1387. }
  1388. $res = $this->db->tableinfo($table);
  1389. if (DB::isError($res)) {
  1390. $this->_errorSet($res->getUserInfo());
  1391. return false;
  1392. }
  1393. }
  1394. $ret = array();
  1395. foreach ($res as $key => $val) {
  1396. $ret[$val['name']] = $val;
  1397. }
  1398. $this->_metadata[$table] = $ret;
  1399. return $ret;
  1400. }
  1401. //
  1402. // methods for building the query
  1403. //
  1404. // }}}
  1405. // {{{ _buildFrom()
  1406. /**
  1407. * build the from string
  1408. *
  1409. * @access private
  1410. * @return string the string added after FROM
  1411. */
  1412. function _buildFrom()
  1413. {
  1414. $from = $this->table;
  1415. $join = $this->getJoin();
  1416. if (!$join) { // no join set
  1417. return $from;

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