Source for file database-defs.php

Documentation is available at database-defs.php

  1. <?php
  2. /* ******************************************************************** */
  3. /* CATALYST PHP Source Code */
  4. /* -------------------------------------------------------------------- */
  5. /* This program is free software; you can redistribute it and/or modify */
  6. /* it under the terms of the GNU General Public License as published by */
  7. /* the Free Software Foundation; either version 2 of the License, or */
  8. /* (at your option) any later version. */
  9. /* */
  10. /* This program is distributed in the hope that it will be useful, */
  11. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  12. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  13. /* GNU General Public License for more details. */
  14. /* */
  15. /* You should have received a copy of the GNU General Public License */
  16. /* along with this program; if not, write to: */
  17. /* The Free Software Foundation, Inc., 59 Temple Place, Suite 330, */
  18. /* Boston, MA 02111-1307 USA */
  19. /* -------------------------------------------------------------------- */
  20. /* */
  21. /* Filename: database-defs.php */
  22. /* Author: Paul Waite */
  23. /* Description: Definitions for managing DATABASES */
  24. /* */
  25. /* ******************************************************************** */
  26. /** @package database */
  27. include_once("timer-defs.php");
  28.  
  29. /** Connect persistent to DB */
  30. ("PERSISTENT", true);
  31.  
  32. /** Connect non-persistent to DB */
  33. ("NOT_PERSISTENT", false);
  34.  
  35. /** Default datasource for queries @see add_database() */
  36. ("DEFAULT_DATASOURCE", true);
  37.  
  38. // ----------------------------------------------------------------------
  39. /**
  40. * Datasources
  41. * A datasources class is just a bunch of databases. If you want
  42. * to access a database, register it in here first, then you
  43. * can select it to perform queries on later.
  44. * @package database
  45. */
  46. class datasources {
  47. /** An array of database objects. All databases we can use as datasources */
  48.  
  49. var $database;
  50. /** Default database name */
  51.  
  52. var $db_name_default = "";
  53. /** Name of currently selected database */
  54.  
  55. var $db_name_selected = "";
  56. // ....................................................................
  57. /** Constructor */
  58.  
  59. function datasources() { }
  60. // ....................................................................
  61. /**
  62. * Constructor
  63. * Add a new base to our list of datasources. The dbtype and the name
  64. * are the only mandatory parameters.
  65. * @param string $dbtype The type of database eg: 'postgres', 'mssql' etc.
  66. * @param string $name The name of the database
  67. * @param string $user Name of a user who can access the database
  68. * @param string $passwd The password the user can access the database with
  69. * @param string $host The hostname of the machine running the database (TCP/IP)
  70. * @param integer $port The port number of the database server
  71. * @param string $enc The database character encoding
  72. * @param string $datestyle The database date style
  73. * @param boolean $default True if the database is the default database
  74. */
  75. function add_database(
  76. $dbtype,
  77. $name, $user="", $passwd="",
  78. $host="", $port=0,
  79. $enc="", $datestyle="",
  80. $default=false)
  81. {
  82. switch ($dbtype) {
  83. case "postgres":
  84. include_once("db-postgres.php");
  85. $this->database[$name] = new db_postgres($name, $user, $passwd, $host, $port, $enc, $datestyle);
  86. break;
  87. case "odbc":
  88. include_once("db-odbc.php");
  89. $this->database[$name] = new db_odbc($name, $user, $passwd, $host, $port, $enc, $datestyle);
  90. break;
  91. case "mssql_server":
  92. include_once("db-mssql-server.php");
  93. $this->database[$name] = new db_mssql_server($name, $user, $passwd, $host, $port, $enc, $datestyle);
  94. break;
  95. case "mysql":
  96. include_once("db-mysql.php");
  97. $this->database[$name] = new db_mysql($name, $user, $passwd, $host, $port, $enc, $datestyle);
  98. break;
  99. case "oracle":
  100. include_once("db-oracle.php");
  101. $this->database[$name] = new db_oracle($name, $user, $passwd, $host, $port, $enc, $datestyle);
  102. break;
  103. }
  104. // Make sure the default database is selected..
  105. if ($default) {
  106. // Select the default DB. This tries to
  107. // connect to it..
  108. $this->set_default($name);
  109. $this->select($name);
  110.  
  111. // It is a fatal application error if the default
  112. // database cannot be connected..
  113. if (!$this->connected($name)) {
  114. $errmsg = "APPFATAL: " . APP_NAME . ": Default database not connected. Exit stage left.";
  115. error_log($errmsg, 0);
  116. die($errmsg);
  117. }
  118. }
  119. return $this;
  120. } // add_database
  121. // ....................................................................
  122. /**
  123. * This will connect it if it isn't already connected. Calling this
  124. * with no database name will select the default one. Returns the
  125. * database unique identifier, or false if none was selected.
  126. * @param string $db_name The name of the database to select
  127. * @return resource The database resource ID
  128. */
  129. function select($db_name="") {
  130. global $RESPONSE;
  131. global $HTTP_HOST;
  132. $dbid = false;
  133. if ($db_name == "") {
  134. $db_name = $this->db_name_default;
  135. }
  136. if (isset($this->database[$db_name])) {
  137. $db = $this->database[$db_name];
  138. $this->db_name_selected = $db_name;
  139. if (!$db->connected) {
  140. // Check if we should connect persistently..
  141. if (isset($RESPONSE) && $RESPONSE->InPersistentHostsList($HTTP_HOST)) {
  142. $connmode = PERSISTENT;
  143. }
  144. else {
  145. $connmode = NOT_PERSISTENT;
  146. }
  147. $db->connect($connmode);
  148. $this->database[$db_name] = $db;
  149. }
  150. if ($db->connected) {
  151. $dbid = $db->dbid;
  152. }
  153. }
  154. return $dbid;
  155. } // select
  156. // ....................................................................
  157. /**
  158. * Internal function to set the name of the default database.
  159. * The database must exist as a defined database already.
  160. * @param string $db_name The name of the database
  161. */
  162. function set_default($db_name) {
  163. if (isset($this->database[$db_name])) {
  164. $this->db_name_default = $db_name;
  165. return $this;
  166. }
  167. } // set_default
  168. // ....................................................................
  169. /**
  170. * Returns the database resource ID of the given database name.
  171. * If dbname is not given, returns ID of currently selected DB.
  172. * @param string $db_name The name of the database
  173. * @return resource Database resource ID
  174. */
  175. function dbid($db_name="") {
  176. $res = false;
  177. if ($db_name == "") {
  178. $db_name = $this->db_name_selected;
  179. }
  180. if (isset($this->database[$db_name])) {
  181. $res = $this->database[$db_name]->dbid;
  182. }
  183. return $res;
  184. } // dbid
  185. // ....................................................................
  186. /**
  187. * Returns the database type of the given database name.
  188. * If dbname is not given, returns type of DB currently selected.
  189. * @param string $db_name The name of the database
  190. * @return string Database type string
  191. */
  192. // Returns the database type of the selected database.
  193. function dbtype($db_name="") {
  194. $res = false;
  195. if ($db_name == "") {
  196. $db_name = $this->db_name_selected;
  197. }
  198. if (isset($this->database[$db_name])) {
  199. $res = $this->database[$db_name]->type;
  200. }
  201. return $res;
  202. } // dbtype
  203. // ....................................................................
  204. /**
  205. * Returns connected status of named database, or the currently
  206. * selected one if no name given.
  207. * @param string $db_name The name of the database
  208. * @return boolean Database connection status true or false
  209. */
  210. function connected($db_name="") {
  211. $res = false;
  212. if ($db_name == "") {
  213. $db_name = $this->db_name_selected;
  214. }
  215. if (isset($this->database[$db_name])) {
  216. $res = $this->database[$db_name]->connected;
  217. }
  218. return $res;
  219. } // connected
  220. // ....................................................................
  221. /**
  222. * Connects to the database which has been selected in the mode
  223. * specified, or non-peristent otherwise.
  224. * @param boolean $persistent Whether to connect persistently or not
  225. * @return boolean Whether database connection was successful
  226. */
  227. function connect($persistent=NOT_PERSISTENT) {
  228. $connected = false;
  229. if (isset($this->database[$this->db_name_selected])) {
  230. $this->database[$this->db_name_selected]->connect($persistent);
  231. if ($this->database[$this->db_name_selected]->connected) {
  232. $connected = true;
  233. }
  234. else {
  235. $errmsg = "Failed to connect to database '" . $this->name . "' ";
  236. $errmsg .= "type='" . $this->type . "' ";
  237. $errmsg .= "host='" . $this->host . "' ";
  238. $errmsg .= "port='" . $this->port . "' ";
  239. $errmsg .= "user='" . $this->user . "' ";
  240. $errmsg .= "passwd=" . ($this->passwd != "") ? "xxxx" : "(none) ";
  241. if ($persistent) $errmsg .= "persistent=yes";
  242. else $errmsg .= "persistent=no";
  243. error_log("CONNFAIL: $errmsg");
  244. }
  245. }
  246. return $connected;
  247. } // connect
  248. // ....................................................................
  249. /**
  250. * Disconnect the currently selected database.
  251. */
  252. function disconnect() {
  253. if (isset($this->database[$this->db_name_selected])) {
  254. $this->database[$this->db_name_selected]->disconnect();
  255. }
  256. } // disconnect
  257. // ....................................................................
  258. /**
  259. * Execute a query on the connected database.
  260. * @param string $sql The SQL query to execute on the database
  261. * @return resource A database query resource ID, or false if query failed
  262. */
  263. function query($sql) {
  264. $rid = false;
  265. if (isset($this->database[$this->db_name_selected])) {
  266. $rid = $this->database[$this->db_name_selected]->query($sql);
  267. }
  268. return $rid;
  269. } // query
  270. // ....................................................................
  271. /**
  272. * Returns SQL statement most recently executed on the current DB.
  273. * NB: the format and/or content of this SQL may differ from the SQL
  274. * originally submitted, due to database-dependent transformations,
  275. * hence the usefulness of this method.
  276. * @return string The SQL statement last executed on current database.
  277. */
  278. function get_last_sql() {
  279. $sql = "";
  280. if (isset($this->database[$this->db_name_selected])) {
  281. $sql = $this->database[$this->db_name_selected]->last_sql;
  282. }
  283. return $sql;
  284. } // get_last_sql
  285. // ....................................................................
  286. /**
  287. * Return the number of rows returned by a SELECT query.
  288. * @param resource $rid The resource ID for the executed query
  289. * @return integer The number of rows returned by the query
  290. */
  291. function numrows($rid) {
  292. $rows = 0;
  293. if (isset($this->database[$this->db_name_selected])) {
  294. $db = $this->database[$this->db_name_selected];
  295. $rows = ($rid !== false) ? $db->numrows($rid) : 0;
  296. }
  297. return $rows;
  298. } // numrows
  299. // ....................................................................
  300. /**
  301. * Return the number of rows affected by a query.
  302. * @param resource $rid The resource ID for the executed query
  303. * @return integer The number of rows affected by the query
  304. */
  305. function affectedrows($rid) {
  306. $rows = 0;
  307. if (isset($this->database[$this->db_name_selected])) {
  308. $db = $this->database[$this->db_name_selected];
  309. $rows = ($rid !== false) ? $db->affectedrows($rid) : 0;
  310. }
  311. return $rows;
  312. } // affectedrows
  313. // ....................................................................
  314. /**
  315. * Free the result of a query
  316. * @param resource $rid The query resource ID
  317. */
  318. function freeresult($rid) {
  319. if (isset($this->database[$this->db_name_selected]) && $rid !== false) {
  320. $this->database[$this->db_name_selected]->freeresult($rid);
  321. }
  322. } // freeresult
  323. // ....................................................................
  324. /**
  325. * Return the last error message.
  326. * @return string The last error message which was generated
  327. */
  328. function errormessage() {
  329. $errmsg = "";
  330. if (isset($this->database[$this->db_name_selected])) {
  331. $errmsg = $this->database[$this->db_name_selected]->errormessage();
  332. }
  333. return $errmsg;
  334. } // errormessage
  335. // ....................................................................
  336. /**
  337. * Return the specified row, as a standard (enumerated) array of
  338. * field values.
  339. * @param resource $rid The resource ID for the executed query
  340. * @param integer $rowno Row number (zero-based) of row to return
  341. * @return array Enumerated array of field values
  342. */
  343. function fetch_row($rid, $rowno) {
  344. $rows = false;
  345. if (isset($this->database[$this->db_name_selected]) && $rid !== false) {
  346. $rows = $this->database[$this->db_name_selected]->fetch_row($rid, $rowno);
  347. }
  348. return $rows;
  349. } // fetch_row
  350. // ....................................................................
  351. /**
  352. * Return the specified row, as an associative array of fields
  353. * in a fieldname => value format.
  354. * @param resource $rid The resource ID for the executed query
  355. * @param integer $rowno Row number (zero-based) of row to return
  356. * @return array Associative array of field values
  357. */
  358. function fetch_array($rid, $rowno) {
  359. $arr = false;
  360. if (isset($this->database[$this->db_name_selected]) && $rid !== false) {
  361. $arr = $this->database[$this->db_name_selected]->fetch_array($rid, $rowno);
  362. }
  363. return $arr;
  364. } // fetch_array
  365. // ....................................................................
  366. /**
  367. * Start a database transaction
  368. * @return boolean Flag indicating successful start of transaction
  369. */
  370. function begin_transaction() {
  371. $res = false;
  372. if (isset($this->database[$this->db_name_selected])) {
  373. $res = $this->database[$this->db_name_selected]->begin_transaction();
  374. }
  375. return $res;
  376. } // begin_transaction
  377. // ....................................................................
  378. /**
  379. * Commit open database transaction
  380. * @return boolean Flag indicating successful commit of transaction
  381. */
  382. function commit() {
  383. $res = false;
  384. if (isset($this->database[$this->db_name_selected])) {
  385. $res = $this->database[$this->db_name_selected]->commit();
  386. }
  387. return $res;
  388. } // commit
  389. // ....................................................................
  390. /**
  391. * Roll back the current database transaction. All queries executed
  392. * as part of the open transaction will be rolled back.
  393. * @return boolean Flag indicating successful rollback of transaction
  394. */
  395. function rollback() {
  396. $res = false;
  397. if (isset($this->database[$this->db_name_selected])) {
  398. $res = $this->database[$this->db_name_selected]->rollback();
  399. }
  400. return $res;
  401. } // rollback
  402. // ....................................................................
  403. /**
  404. * Return a Php boolean from a database field value. The database field
  405. * is expected to be a container of some form of logical value. Here
  406. * is where we convert it according to the current database.
  407. * @param mixed $dbvalue The value from the database field to convert
  408. * @return boolean The boolean value derived from the field value
  409. */
  410. function bool_from_db_value($dbvalue) {
  411. $res = false;
  412. if (isset($this->database[$this->db_name_selected])) {
  413. $res = $this->database[$this->db_name_selected]->bool_from_db_value($dbvalue);
  414. }
  415. return $res;
  416. } // bool_from_db_value
  417. // ....................................................................
  418. /**
  419. * Return a suitable database field value to contain the value for
  420. * the given boolean.
  421. * @param boolean $boolvalue The boolean value to convert
  422. * @return mixed The value suitable for the database field
  423. */
  424. function db_value_from_bool($boolvalue) {
  425. $res = false;
  426. if (isset($this->database[$this->db_name_selected])) {
  427. $res = $this->database[$this->db_name_selected]->db_value_from_bool($boolvalue);
  428. }
  429. return $res;
  430. } // db_value_from_bool
  431. // ....................................................................
  432. /**
  433. * Return the current sequence value, given a sequence name, the table
  434. * and the field it applies to.
  435. * @param string $sequencename The name of the sequence to use
  436. * @param string $table The name of the table the sequence is for
  437. * @param string $column The name of the table column the sequence is for
  438. * @return integer The current sequence value
  439. */
  440. function current_sequencevalue($sequencename, $table, $column) {
  441. $res = 0;
  442. if (isset($this->database[$this->db_name_selected])) {
  443. $res = $this->database[$this->db_name_selected]->current_sequencevalue($sequencename, $table, $column);
  444. }
  445. return $res;
  446. } // current_sequencevalue
  447. // ....................................................................
  448. /**
  449. * Return the next sequence value, given a sequence name, the table
  450. * and the field it applies to.
  451. * @param string $sequencename The name of the sequence to use
  452. * @param string $table The name of the table the sequence is for
  453. * @param string $column The name of the table column the sequence is for
  454. * @return integer The next sequence value
  455. */
  456. function next_sequencevalue($sequencename, $table, $column) {
  457. $res = 0;
  458. if (isset($this->database[$this->db_name_selected])) {
  459. $res = $this->database[$this->db_name_selected]->next_sequencevalue($sequencename, $table, $column);
  460. }
  461. return $res;
  462. } // next_sequencevalue
  463. // ....................................................................
  464. /**
  465. * Set the sequence value, given a sequence name, the table
  466. * and the field it applies to.
  467. * @param integer $newval The sequence value to set
  468. * @param string $sequencename The name of the sequence to use
  469. * @param string $table The name of the table the sequence is for
  470. * @param string $column The name of the table column the sequence is for
  471. * @return boolean Whether the assignment succeeded or not
  472. */
  473. function set_sequencevalue($newval, $sequencename, $table, $column) {
  474. $res = false;
  475. if (isset($this->database[$this->db_name_selected])) {
  476. $res = $this->database[$this->db_name_selected]->set_sequencevalue($newval, $sequencename, $table, $column);
  477. }
  478. return $res;
  479. } // set_sequencevalue
  480. // ....................................................................
  481. /**
  482. * Set the database date style. This affect the format that dates will
  483. * be displayed in, and the format they are submitted in.
  484. * @param string $datestyle The date style code to set
  485. * @return boolean Whether the setting succeeded or not
  486. */
  487. function set_datestyle($datestyle) {
  488. $res = false;
  489. if (isset($this->database[$this->db_name_selected])) {
  490. $res = $this->database[$this->db_name_selected]->set_datestyle($datestyle);
  491. }
  492. return $res;
  493. } // set_datestyle
  494. // ....................................................................
  495. /**
  496. * Set the database character encoding. This affects the encoding of
  497. * characters in the database.
  498. * @param string $encoding The character encoding to set
  499. * @return boolean Whether the setting succeeded or not
  500. */
  501. function set_char_encoding($encoding) {
  502. $res = false;
  503. if (isset($this->database[$this->db_name_selected])) {
  504. $res = $this->database[$this->db_name_selected]->set_char_encoding($encoding);
  505. }
  506. return $res;
  507. } // set_char_encoding
  508. // ....................................................................
  509. /**
  510. * General-purpose lock method. We pass the elements of the lock, which
  511. * is the list of tables to lock, and the lock-mode. The latter mode is
  512. * database-specific, and therefore flexible.
  513. * @param string $tablelist List of tables to lock, comma-delimited
  514. * @param string $mode Databes-specific locking-mode or type
  515. * @return boolean Whether the setting succeeded or not
  516. */
  517. function lock($tablelist, $mode) {
  518. $res = false;
  519. if (isset($this->database[$this->db_name_selected])) {
  520. $res = $this->database[$this->db_name_selected]->lock($tablelist, $mode);
  521. }
  522. return $res;
  523. } // lock
  524. // ....................................................................
  525. /**
  526. * Used to escape particular characters (typically the single quote) so
  527. * that they can form part of the database data, rather than being
  528. * interpreted as command syntax.
  529. * @param string $str
  530. * @return string The same string with appropriate chars escaped.
  531. */
  532. function escape_string($str="") {
  533. if (isset($this->database[$this->db_name_selected])) {
  534. $str = $this->database[$this->db_name_selected]->escape_string($str);
  535. }
  536. return $str;
  537. } // escape_string
  538. // ....................................................................
  539. /**
  540. * Used to unescape escaped characters (typically the single quote) so
  541. * that they are as they were before having the escape_string() method
  542. * applied.
  543. * Note that some databases do not need this to be done - they
  544. * unescape escaped content when data is returned.
  545. * @param string $str
  546. * @return string The same string with escaped chars UN-escaped.
  547. */
  548. function unescape_string($str="") {
  549. if (isset($this->database[$this->db_name_selected])) {
  550. $str = $this->database[$this->db_name_selected]->unescape_string($str);
  551. }
  552. return $str;
  553. } // unescape_string
  554. // ....................................................................
  555. /**
  556. * Given an Axyl SQL query object, build the SQL string from it
  557. * in suitable format for the currently connected database server.
  558. * @param object $sqlquery An Axyl query object
  559. * @return string The SQL string built from the query object
  560. */
  561. function SQL($sqlquery) {
  562. $res = false;
  563. if (isset($this->database[$this->db_name_selected])) {
  564. $res = $this->database[$this->db_name_selected]->SQL($sqlquery);
  565. }
  566. return $res;
  567. } // SQL
  568.  
  569.  
  570.  
  571. } // datasources class
  572. // ----------------------------------------------------------------------
  573.  
  574. /**
  575. * Define a database. This is a parent class to all of the supported
  576. * database flavours. It holds the main data describing a database
  577. * and it's connection. The actual functionality to connect to a
  578. * physical database and access its data is defined in the child
  579. * classes of this one. For example, see file 'db-postgres.php'.
  580. *
  581. * Normal users of the system should not have to deal with this
  582. * class directly.
  583. *
  584. * The datasources class is a container for multiple 'databases' or
  585. * instances of this class.
  586. * @package database
  587. */
  588. class database {
  589. // Public
  590. /** Type of database eg: "postgres", "mssql_server".. */
  591.  
  592. var $type = "";
  593. /** Name of this database */
  594.  
  595. var $name = "";
  596. /** Host server of this database */
  597.  
  598. var $host = "";
  599. /** Port to access it via TCP */
  600.  
  601. var $port = 0;
  602. /** Default user to connect as */
  603.  
  604. var $user = "";
  605. /** Default password to connect as */
  606.  
  607. var $passwd = "";
  608. /** The database internal date format/style */
  609.  
  610. var $datestyle = "UNICODE";
  611. /** The database character encoding */
  612.  
  613. var $enc = "";
  614. /** Flag true if database was connected ok */
  615.  
  616. var $connected = false;
  617.  
  618. // Private
  619. /** True if we want a persistent connection
  620. @access private */
  621. var $persistent = false;
  622. /** Unique identifier for database access
  623. @access private */
  624. var $dbid = false;
  625. /** The SQL statement last executed on this database. This
  626. value is set in the underlying DB module, query() method.
  627. @access private */
  628. var $executable_sql = "";
  629. /** The result ID last returned by a query on this DB. Also
  630. set in the underlying DB module query()
  631. @access private */
  632. var $rid;
  633. /** Microtimer for query execute timing
  634. @access private */
  635. var $timer;
  636. // ....................................................................
  637. /**
  638. * Constructor
  639. * @param string $name The database name
  640. * @param string $user The username of user who can access the database
  641. * @param string $passwd The user password which can access the database
  642. * @param string $host The hostname of the machine running the database
  643. * @param integer $port The port number of the database server
  644. * @param string $enc The database character encoding (database dependent)
  645. * @param string $datestyle The database date style (eg. 'ISO')
  646. */
  647. function database($name="", $user="", $passwd="", $host="", $port=0, $enc="", $datestyle="") {
  648. $this->name = $name;
  649.  
  650. // If host and port ar not specified, then
  651. // we assume the database is local..
  652. $this->host = $host;
  653. $this->port = $port;
  654.  
  655. // These can be used as defaults..
  656. $this->user = $user;
  657. $this->passwd = $passwd;
  658.  
  659. // Database dates and chars..
  660. $this->enc = $enc;
  661. $this->datestyle = $datestyle;
  662.  
  663. // Timer..
  664. $this->timer = new microtimer();
  665. } // database
  666.  
  667. // ....................................................................
  668. /** This method must be defined in the child class.
  669. * @abstract
  670. */
  671. function connect($persistent) {
  672. return false;
  673. }
  674. // ....................................................................
  675. /** This method must be defined in the child class.
  676. * @abstract
  677. */
  678. function disconnect() {
  679. }
  680. // ....................................................................
  681. /** This method must be defined in the child class.
  682. * @abstract
  683. */
  684. function query($sql) {
  685. return false;
  686. }
  687. // ....................................................................
  688. /**
  689. * This method is usually called after the underlying DB module query()
  690. * method has executed the query. It examines the returned code and
  691. * if debugging is enabled it reports the query & stats accordingly.
  692. * Usually an internally executed method only.
  693. * @access private
  694. */
  695. function query_report() {
  696. global $SQL_EXEC_THRESHOLD, $RESPONSE;
  697. // Now examine the result..
  698. if ($this->rid != false) {
  699. if (debugging()) {
  700. $errstr = "QOK: $this->executable_sql";
  701. $errstr .= " (Time: " . $this->timer->formatted_millisecs() . "mS)";
  702. debugbr($errstr, DBG_SQL);
  703. }
  704. // Log excessive query execution times to syslog..
  705. if (isset($SQL_EXEC_THRESHOLD) && $SQL_EXEC_THRESHOLD > 0) {
  706. if ($this->timer->millisecs() > $SQL_EXEC_THRESHOLD) {
  707. $errstr = APP_NAME . ": " . $this->timer->formatted_millisecs() . "mS ";
  708. $errstr .= "Exceeds Threshold ($SQL_EXEC_THRESHOLD): $this->executable_sql";
  709. error_log($errstr);
  710. }
  711. }
  712. }
  713. else {
  714. // Log the failed query..
  715. $errstr = "QFAIL: " . APP_NAME . ": $this->executable_sql";
  716. error_log($errstr, 0);
  717. $db_err = $RESPONSE->datasource->errormessage();
  718. if ($db_err) $errstr .= " DBSERVER: $db_err";
  719. $this->last_errormsg = $errstr;
  720. if (debugging()) {
  721. debugbr($errstr, DBG_SQL);
  722. }
  723. // Set failed status for any open transaction..
  724. if ($global_tran->open) {
  725. $global_tran->failed = true;
  726. $global_tran->failed_msg = $errstr;
  727. }
  728. }
  729. } // query_report
  730. // ....................................................................
  731. /** This method must be defined in the child class.
  732. * @abstract
  733. */
  734. function numrows($rid) {
  735. return 0;
  736. }
  737. // ....................................................................
  738. /** This method must be defined in the child class.
  739. * @abstract
  740. */
  741. function affectedrows($rid) {
  742. return 0;
  743. }
  744. // ....................................................................
  745. /** This method must be defined in the child class.
  746. * @abstract
  747. */
  748. function freeresult($rid) {
  749. }
  750. // ....................................................................
  751. /** This method must be defined in the child class.
  752. * @abstract
  753. */
  754. function errormessage($rid) {
  755. return "";
  756. }
  757. // ....................................................................
  758. /** This method must be defined in the child class.
  759. * @abstract
  760. */
  761. function fetch_row($rid, $rowno) {
  762. return false;
  763. }
  764. // ....................................................................
  765. /** This method must be defined in the child class.
  766. * @abstract
  767. */
  768. function fetch_array($rid, $rowno) {
  769. return false;
  770. }
  771. // ....................................................................
  772. /**
  773. * Start a new database transaction.
  774. * @return boolean Whether transaction was started or not
  775. */
  776. function begin_transaction() {
  777. return $this->query("BEGIN");
  778. }
  779. // ....................................................................
  780. /**
  781. * Commit the currently open database transaction.
  782. * @return boolean Whether the commit succeeded or not
  783. */
  784. function commit() {
  785. return $this->query("COMMIT");
  786. }
  787. // ....................................................................
  788. /**
  789. * Rollback the currently open database transaction.
  790. * @return boolean Whether the rollback succeeded or not
  791. */
  792. function rollback() {
  793. return $this->query("ROLLBACK");
  794. }
  795. // ....................................................................
  796. /**
  797. * Return a Php boolean from a database field value. The database field
  798. * is expected to be a container of some form of logical value. Here
  799. * is where we convert it according to the current database.
  800. * @param mixed $dbvalue The value from the database field to convert
  801. * @return boolean The boolean value derived from the field value
  802. */
  803. function bool_from_db_value($dbvalue) {
  804. return ($dbvalue == 1);
  805. }
  806. // ....................................................................
  807. /**
  808. * Return a suitable database field value to contain the value for
  809. * the given boolean.
  810. * @param boolean $boolvalue The boolean value to convert
  811. * @return mixed The value suitable for the database field
  812. */
  813. function db_value_from_bool($boolvalue) {
  814. return $boolvalue ? 1 : 0;
  815. }
  816. // ....................................................................
  817. /**
  818. * Return the current sequence value, given a sequence name, the table
  819. * and the field it applies to.
  820. * @param string $sequencename The name of the sequence to use
  821. * @param string $table The name of the table the sequence is for
  822. * @param string $column The name of the table column the sequence is for
  823. * @return integer The current sequence value
  824. */
  825. function current_sequencevalue($sequencename, $table, $column) {
  826. $seq = 0;
  827. $rid = $this->query("SELECT MAX($column) FROM $table" );
  828. if ($rid !== false) {
  829. $row = $this->fetch_row($rid, 0);
  830. $seq = $row[0];
  831. }
  832. return $seq;
  833. }
  834. // ....................................................................
  835. /**
  836. * Return the next sequence value, given a sequence name, the table
  837. * and the field it applies to.
  838. * @param string $sequencename The name of the sequence to use
  839. * @param string $table The name of the table the sequence is for
  840. * @param string $column The name of the table column the sequence is for
  841. * @return integer The next sequence value
  842. */
  843. function next_sequencevalue($sequencename, $table, $column) {
  844. return (1 + $this->current_sequencevalue($sequencename, $table, $column));
  845. }
  846. // ....................................................................
  847. /** This method must be defined in the child class.
  848. * @abstract
  849. */
  850. function set_sequencevalue($newval, $sequencename, $table, $column) {
  851. return true;
  852. }
  853. // ....................................................................
  854. /** This method must be defined in the child class.
  855. * @abstract
  856. */
  857. function set_datestyle($datestyle) {
  858. return true;
  859. }
  860. // ....................................................................
  861. /** This method must be defined in the child class.
  862. * @abstract
  863. */
  864. function set_char_encoding($encoding) {
  865. return true;
  866. }
  867. // ....................................................................
  868. /** This method must be defined in the child class.
  869. * @abstract
  870. */
  871. function lock($tablelist, $mode) {
  872. return true;
  873. }
  874. // ....................................................................
  875. /** This method may be over-ridden in the child class. The default is
  876. * to apply a rather simplistic SQL-standard transformation of single
  877. * quote to doubled-up single-quote ' --> ''.
  878. */
  879. function escape_string($str) {
  880. if (is_string($str)) {
  881. $str = str_replace("'", "''", $str);
  882. }
  883. return $str;
  884. }
  885. // ....................................................................
  886. /** This method may be over-ridden in the child class. The default
  887. * action is to simply do nothing.
  888. */
  889. function unescape_string($str) {
  890. return $str;
  891. }
  892. // ....................................................................
  893. /**
  894. * Given an Axyl SQL query object, build the SQL string from it
  895. * in suitable format for the currently connected database server.
  896. * @param pointer $sqlquery Pointer to an Axyl query object
  897. * @return string The SQL string built from the query object
  898. */
  899. function SQL($sqlquery) {
  900. $sql = "";
  901. switch (strtoupper($sqlquery->type)) {
  902. case "SELECT":
  903. $sql .= "SELECT ";
  904. if ($sqlquery->fields->total == 0) $sql .= "*";
  905. else $sql .= $sqlquery->fields->listed();
  906. $sql .= " FROM ";
  907. $sql .= $sqlquery->tables->listed();
  908. if ($sqlquery->where->total > 0) {
  909. $sql .= " WHERE ";
  910. $sql .= $sqlquery->where->listed(" ");
  911. }
  912. if ($sqlquery->groupby->total > 0) {
  913. $sql .= " GROUP BY ";
  914. $sql .= $sqlquery->groupby->listed();
  915. }
  916. if ($sqlquery->orderby->total > 0) {
  917. $sql .= " ORDER BY ";
  918. $sql .= $sqlquery->orderby->listed();
  919. }
  920. break;
  921.  
  922. case "INSERT":
  923. $sql .= "INSERT INTO ";
  924. $sql .= $sqlquery->tables->listed();
  925. if ($sqlquery->fields->total > 0) {
  926. $sql .= " (" . $sqlquery->fields->listed() . ")";
  927. }
  928. $sql .= " VALUES ";
  929. $sql .= "(" . $sqlquery->fields->values() . ")";
  930. break;
  931.  
  932. case "DELETE":
  933. $sql .= "DELETE FROM ";
  934. $sql .= $sqlquery->tables->listed();
  935. if ($sqlquery->where->total > 0) {
  936. $sql .= " WHERE ";
  937. $sql .= $sqlquery->where->listed(" ");
  938. }
  939. break;
  940.  
  941. case "UPDATE":
  942. $sql .= "UPDATE ";
  943. $sql .= $sqlquery->tables->listed();
  944. $sql .= " SET ";
  945. $sql .= $sqlquery->fields->equated();
  946. if ($sqlquery->where->total > 0) {
  947. $sql .= " WHERE ";
  948. $sql .= $sqlquery->where->listed(" ");
  949. }
  950. break;
  951. }
  952. // Render any NULL values..
  953. $sql = str_replace("'".NULLVALUE."'", "NULL", $sql);
  954.  
  955. // Return SQL we have built..
  956. return $sql;
  957. }
  958. // ....................................................................
  959. /**
  960. * Make conversions of boolean syntax found in the SQL string and
  961. * return the 'standardised' SQL. This assumes that Axyl SQL will
  962. * be written in the form 'WHERE foo=TRUE'.
  963. * @param string $sql SQL string to make conversions in
  964. * @return string The converted SQL string
  965. */
  966. function convert_boolean_syntax($sql) {
  967. $fixsql = $sql;
  968. // Quick check is more efficient then regexes..
  969. if (stristr($sql, "TRUE") || stristr($sql, "FALSE")) {
  970. $fixsql = preg_replace("/( WHERE.*?[\S]+=)TRUE/ie", "'\\1'.'1'", $sql);
  971. $fixsql = preg_replace("/( WHERE.*?[\S]+=)FALSE/ie", "'\\1'.'0'", $fixsql);
  972. }
  973. return $fixsql;
  974. }
  975. } // database class
  976. // ----------------------------------------------------------------------
  977.  
  978. ?>

Documentation generated by phpDocumentor 1.3.0RC3