PageRenderTime 52ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/jelix/db/jDbConnection.class.php

https://github.com/foxmask/Booster
PHP | 386 lines | 139 code | 44 blank | 203 comment | 13 complexity | b32c018e21265dcc7d0efc3c498090cb MD5 | raw file
  1. <?php
  2. /**
  3. * @package jelix
  4. * @subpackage db
  5. * @author Laurent Jouanneau
  6. * @contributor Julien Issler
  7. * @copyright 2005-2011 Laurent Jouanneau
  8. * @copyright 2007-2009 Julien Issler
  9. *
  10. * This class was get originally from the Copix project (CopixDbConnection, Copix 2.3dev20050901, http://www.copix.org)
  11. * However only few lines of code are still copyrighted 2001-2005 CopixTeam (LGPL licence).
  12. * Initial authors of this Copix classes are Gerald Croes and Laurent Jouanneau,
  13. * and this class was adapted/improved for Jelix by Laurent Jouanneau
  14. *
  15. * @link http://www.jelix.org
  16. * @licence http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public Licence, see LICENCE file
  17. */
  18. /**
  19. * @package jelix
  20. * @subpackage db
  21. */
  22. abstract class jDbConnection {
  23. const FETCH_OBJ = 5;
  24. const FETCH_CLASS = 8;
  25. const FETCH_INTO = 9;
  26. const ATTR_AUTOCOMMIT = 0;
  27. const ATTR_PREFETCH = 1;
  28. const ATTR_TIMEOUT = 2;
  29. const ATTR_ERRMODE = 3;
  30. const ATTR_SERVER_VERSION = 4;
  31. const ATTR_SERVER_INFO = 6;
  32. const ATTR_CLIENT_VERSION = 5;
  33. const ATTR_CONNECTION_STATUS = 7;
  34. const ATTR_CASE = 8;
  35. const ATTR_CURSOR = 10;
  36. const ATTR_ORACLE_NULLS = 11;
  37. const ATTR_PERSISTENT = 12;
  38. const ATTR_DRIVER_NAME = 16;
  39. const CURSOR_FWDONLY = 0;
  40. const CURSOR_SCROLL = 1;
  41. /**
  42. * profile properties used by the connector
  43. * @var array
  44. */
  45. public $profile;
  46. /**
  47. * The database type name (mysql, pgsql ...)
  48. * @var string
  49. */
  50. public $dbms;
  51. /**
  52. * The last error message if any
  53. * @var string
  54. */
  55. public $msgError = '';
  56. /**
  57. * last executed query
  58. */
  59. public $lastQuery;
  60. /**
  61. * Are we using an automatic commit ?
  62. * @var boolean
  63. */
  64. private $_autocommit = true;
  65. /**
  66. * the internal connection.
  67. */
  68. protected $_connection = null;
  69. /**
  70. * do a connection to the database, using properties of the given profile
  71. * @param array $profile profile properties
  72. */
  73. function __construct($profile) {
  74. $this->profile = & $profile;
  75. $this->dbms = $profile['driver'];
  76. $this->_connection = $this->_connect();
  77. }
  78. function __destruct() {
  79. if ($this->_connection !== null) {
  80. $this->_disconnect ();
  81. }
  82. }
  83. /**
  84. * Launch a SQL Query which returns rows (typically, a SELECT statement)
  85. * @param string $queryString the SQL query
  86. * @param integer $fetchmode FETCH_OBJ, FETCH_CLASS or FETCH_INTO
  87. * @param string|object $param class name if FETCH_CLASS, an object if FETCH_INTO. else null.
  88. * @param array $ctoargs arguments for the constructor if FETCH_CLASS
  89. * @return jDbResultSet|boolean False if the query has failed.
  90. */
  91. public function query ($queryString, $fetchmode = self::FETCH_OBJ, $arg1 = null, $ctoargs = null) {
  92. $this->lastQuery = $queryString;
  93. $log = new jSQLLogMessage($queryString);
  94. $result = $this->_doQuery ($queryString);
  95. $log->endQuery();
  96. jLog::log($log,'sql');
  97. if ($fetchmode != self::FETCH_OBJ) {
  98. $result->setFetchMode($fetchmode, $arg1, $ctoargs);
  99. }
  100. return $result;
  101. }
  102. /**
  103. * Launch a SQL Query with limit parameter, so it returns only a subset of a result
  104. * @param string $queryString the SQL query
  105. * @param integer $limitOffset the offset of the first row to return
  106. * @param integer $limitCount the maximum of number of rows to return
  107. * @return jDbResultSet|boolean SQL Select. False if the query has failed.
  108. */
  109. public function limitQuery ($queryString, $limitOffset, $limitCount){
  110. $this->lastQuery = $queryString;
  111. $log = new jSQLLogMessage($queryString);
  112. $result = $this->_doLimitQuery ($queryString, intval($limitOffset), intval($limitCount));
  113. $log->endQuery();
  114. $log->setRealQuery($this->lastQuery);
  115. jLog::log($log,'sql');
  116. return $result;
  117. }
  118. /**
  119. * Launch a SQL Query (update, delete..) which doesn't return rows
  120. * @param string $query the SQL query
  121. * @return integer the number of affected rows. False if the query has failed.
  122. */
  123. public function exec ($query) {
  124. $this->lastQuery = $query;
  125. $log = new jSQLLogMessage($query);
  126. $result = $this->_doExec ($query);
  127. $log->endQuery();
  128. jLog::log($log,'sql');
  129. return $result;
  130. }
  131. /**
  132. * Escape and quotes strings.
  133. * @param string $text string to quote
  134. * @param int $parameter_type unused, just for compatibility with PDO
  135. * @return string escaped string
  136. */
  137. public function quote ($text, $parameter_type = 0) {
  138. // for compatibility with older jelix version
  139. if ($parameter_type === false || $parameter_type === true)
  140. trigger_error("signature of jDbConnection::quote has changed, you should use quote2()", E_USER_WARNING);
  141. return "'".$this->_quote($text, false)."'";
  142. }
  143. /**
  144. * Escape and quotes strings. if null, will only return the text "NULL"
  145. * @param string $text string to quote
  146. * @param boolean $checknull if true, check if $text is a null value, and then return NULL
  147. * @param boolean $binary set to true if $text contains a binary string
  148. * @return string escaped string
  149. * @since 1.2
  150. */
  151. public function quote2 ($text, $checknull=true, $binary=false) {
  152. if ($checknull)
  153. return (is_null ($text) ? 'NULL' : "'".$this->_quote($text, $binary)."'");
  154. else
  155. return "'".$this->_quote($text, $binary)."'";
  156. }
  157. /**
  158. * enclose the field name
  159. * @param string $fieldName the field name
  160. * @return string the enclosed field name
  161. * @since 1.1.1
  162. */
  163. public function encloseName ($fieldName) {
  164. return $fieldName;
  165. }
  166. /**
  167. * @deprecated since 1.1.2
  168. * @see encloseName
  169. */
  170. public function encloseFieldName ($fieldName) {
  171. return $this->encloseName($fieldName);
  172. }
  173. /**
  174. * Prefix the given table with the prefix specified in the connection's profile
  175. * If there's no prefix for the connection's profile, return the table's name unchanged.
  176. *
  177. * @param string $table the table's name
  178. * @return string the prefixed table's name
  179. * @author Julien Issler
  180. * @since 1.0
  181. */
  182. public function prefixTable($table_name){
  183. if(!isset($this->profile['table_prefix']))
  184. return $table_name;
  185. return $this->profile['table_prefix'].$table_name;
  186. }
  187. /**
  188. * Check if the current connection has a table prefix set
  189. *
  190. * @return boolean
  191. * @author Julien Issler
  192. * @since 1.0
  193. */
  194. public function hasTablePrefix(){
  195. return (isset($this->profile['table_prefix']) && $this->profile['table_prefix'] != '');
  196. }
  197. /**
  198. * sets the autocommit state
  199. * @param boolean $state the status of autocommit
  200. */
  201. public function setAutoCommit($state=true){
  202. $this->_autocommit = $state;
  203. $this->_autoCommitNotify ($this->_autocommit);
  204. }
  205. /**
  206. * begin a transaction. Call it before query, limitQuery, exec
  207. * And then commit() or rollback()
  208. */
  209. abstract public function beginTransaction ();
  210. /**
  211. * validate all queries and close a transaction
  212. */
  213. abstract public function commit ();
  214. /**
  215. * cancel all queries of a transaction and close the transaction
  216. */
  217. abstract public function rollback ();
  218. /**
  219. * prepare a query
  220. * @param string $query a sql query with parameters
  221. * @return statement a statement
  222. */
  223. abstract public function prepare ($query);
  224. /**
  225. * @return string the last error description
  226. */
  227. abstract public function errorInfo();
  228. /**
  229. * @return integer the last error code
  230. */
  231. abstract public function errorCode();
  232. /**
  233. * return the id value of the last inserted row.
  234. * Some driver need a sequence name, so give it at first parameter
  235. * @param string $fromSequence the sequence name
  236. * @return integer the id value
  237. */
  238. abstract public function lastInsertId($fromSequence='');
  239. /**
  240. *
  241. * @param integer $id the attribut id
  242. * @return string the attribute value
  243. * @see PDO::getAttribute()
  244. */
  245. abstract public function getAttribute($id);
  246. /**
  247. *
  248. * @param integer $id the attribut id
  249. * @param string $value the attribute value
  250. * @see PDO::setAttribute()
  251. */
  252. abstract public function setAttribute($id, $value);
  253. /**
  254. * return the maximum value of the given primary key in a table
  255. * @param string $fieldName the name of the primary key
  256. * @param string $tableName the name of the table
  257. * @return integer the maximum value
  258. */
  259. public function lastIdInTable($fieldName, $tableName){
  260. $rs = $this->query ('SELECT MAX('.$fieldName.') as ID FROM '.$tableName);
  261. if (($rs !== null) && $r = $rs->fetch ()){
  262. return $r->ID;
  263. }
  264. return 0;
  265. }
  266. /**
  267. * Notify the changes on autocommit
  268. * Drivers may overload this
  269. * @param boolean $state the new state of autocommit
  270. */
  271. abstract protected function _autoCommitNotify ($state);
  272. /**
  273. * return a connection identifier or false/null if there is an error
  274. * @return integer connection identifier
  275. */
  276. abstract protected function _connect ();
  277. /**
  278. * do a disconnection
  279. * (no need to do a test on the connection id)
  280. */
  281. abstract protected function _disconnect ();
  282. /**
  283. * do a query which return results
  284. * @return jDbResultSet/boolean
  285. */
  286. abstract protected function _doQuery ($queryString);
  287. /**
  288. * do a query which return nothing
  289. * @return jDbResultSet/boolean
  290. */
  291. abstract protected function _doExec ($queryString);
  292. /**
  293. * do a query which return a limited number of results
  294. * @return jDbResultSet/boolean
  295. */
  296. abstract protected function _doLimitQuery ($queryString, $offset, $number);
  297. /**
  298. * do the escaping of a string.
  299. * you should override it into the driver
  300. * @param string $text the text to escape
  301. * @param boolean $binary true if the content of the string is a binary content
  302. */
  303. protected function _quote($text, $binary){
  304. return addslashes($text);
  305. }
  306. /**
  307. * @var jDbTools
  308. * @since 1.2
  309. */
  310. protected $_tools = null;
  311. /**
  312. * @return jDbTools
  313. * @since 1.2
  314. */
  315. public function tools () {
  316. if (!$this->_tools) {
  317. global $gJConfig;
  318. require_once($gJConfig->_pluginsPathList_db[$this->dbms].$this->dbms.'.dbtools.php');
  319. $class = $this->dbms.'DbTools';
  320. $this->_tools = new $class($this);
  321. }
  322. return $this->_tools;
  323. }
  324. /**
  325. * @var jDbSchema
  326. * @since 1.2
  327. */
  328. protected $_schema = null;
  329. /**
  330. * @return jDbSchema
  331. * @since 1.2
  332. */
  333. public function schema () {
  334. if (!$this->_schema) {
  335. global $gJConfig;
  336. require_once($gJConfig->_pluginsPathList_db[$this->dbms].$this->dbms.'.dbschema.php');
  337. $class = $this->dbms.'DbSchema';
  338. $this->_schema = new $class($this);
  339. }
  340. return $this->_schema;
  341. }
  342. }