PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/libraries/joomla/database/driver/oracle.php

https://bitbucket.org/pastor399/newcastleunifc
PHP | 596 lines | 273 code | 77 blank | 246 comment | 15 complexity | 3d084243d13f61361d4e160d3616391d MD5 | raw file
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Database
  5. *
  6. * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. /**
  11. * Oracle database driver
  12. *
  13. * @package Joomla.Platform
  14. * @subpackage Database
  15. * @see http://php.net/pdo
  16. * @since 12.1
  17. */
  18. class JDatabaseDriverOracle extends JDatabaseDriverPdo
  19. {
  20. /**
  21. * The name of the database driver.
  22. *
  23. * @var string
  24. * @since 12.1
  25. */
  26. public $name = 'oracle';
  27. /**
  28. * The character(s) used to quote SQL statement names such as table names or field names,
  29. * etc. The child classes should define this as necessary. If a single character string the
  30. * same character is used for both sides of the quoted name, else the first character will be
  31. * used for the opening quote and the second for the closing quote.
  32. *
  33. * @var string
  34. * @since 12.1
  35. */
  36. protected $nameQuote = '"';
  37. /**
  38. * Returns the current dateformat
  39. *
  40. * @var string
  41. * @since 12.1
  42. */
  43. protected $dateformat;
  44. /**
  45. * Returns the current character set
  46. *
  47. * @var string
  48. * @since 12.1
  49. */
  50. protected $charset;
  51. /**
  52. * Constructor.
  53. *
  54. * @param array $options List of options used to configure the connection
  55. *
  56. * @since 12.1
  57. */
  58. public function __construct($options)
  59. {
  60. $options['driver'] = 'oci';
  61. $options['charset'] = (isset($options['charset'])) ? $options['charset'] : 'AL32UTF8';
  62. $options['dateformat'] = (isset($options['dateformat'])) ? $options['dateformat'] : 'RRRR-MM-DD HH24:MI:SS';
  63. $this->charset = $options['charset'];
  64. $this->dateformat = $options['dateformat'];
  65. // Finalize initialisation
  66. parent::__construct($options);
  67. }
  68. /**
  69. * Destructor.
  70. *
  71. * @since 12.1
  72. */
  73. public function __destruct()
  74. {
  75. $this->freeResult();
  76. unset($this->connection);
  77. }
  78. /**
  79. * Connects to the database if needed.
  80. *
  81. * @return void Returns void if the database connected successfully.
  82. *
  83. * @since 12.1
  84. * @throws RuntimeException
  85. */
  86. public function connect()
  87. {
  88. if ($this->connection)
  89. {
  90. return;
  91. }
  92. parent::connect();
  93. if (isset($this->options['schema']))
  94. {
  95. $this->setQuery('ALTER SESSION SET CURRENT_SCHEMA = ' . $this->quoteName($this->options['schema']))->execute();
  96. }
  97. $this->setDateFormat($this->dateformat);
  98. }
  99. /**
  100. * Disconnects the database.
  101. *
  102. * @return void
  103. *
  104. * @since 12.1
  105. */
  106. public function disconnect()
  107. {
  108. // Close the connection.
  109. $this->freeResult();
  110. unset($this->connection);
  111. }
  112. /**
  113. * Drops a table from the database.
  114. *
  115. * Note: The IF EXISTS flag is unused in the Oracle driver.
  116. *
  117. * @param string $tableName The name of the database table to drop.
  118. * @param boolean $ifExists Optionally specify that the table must exist before it is dropped.
  119. *
  120. * @return JDatabaseDriverOracle Returns this object to support chaining.
  121. *
  122. * @since 12.1
  123. */
  124. public function dropTable($tableName, $ifExists = true)
  125. {
  126. $this->connect();
  127. $query = $this->getQuery(true)
  128. ->setQuery('DROP TABLE :tableName');
  129. $query->bind(':tableName', $tableName);
  130. $this->setQuery($query);
  131. $this->execute();
  132. return $this;
  133. }
  134. /**
  135. * Method to get the database collation in use by sampling a text field of a table in the database.
  136. *
  137. * @return mixed The collation in use by the database or boolean false if not supported.
  138. *
  139. * @since 12.1
  140. */
  141. public function getCollation()
  142. {
  143. return $this->charset;
  144. }
  145. /**
  146. * Get a query to run and verify the database is operational.
  147. *
  148. * @return string The query to check the health of the DB.
  149. *
  150. * @since 12.2
  151. */
  152. public function getConnectedQuery()
  153. {
  154. return 'SELECT 1 FROM dual';
  155. }
  156. /**
  157. * Returns the current date format
  158. * This method should be useful in the case that
  159. * somebody actually wants to use a different
  160. * date format and needs to check what the current
  161. * one is to see if it needs to be changed.
  162. *
  163. * @return string The current date format
  164. *
  165. * @since 12.1
  166. */
  167. public function getDateFormat()
  168. {
  169. return $this->dateformat;
  170. }
  171. /**
  172. * Shows the table CREATE statement that creates the given tables.
  173. *
  174. * Note: You must have the correct privileges before this method
  175. * will return usable results!
  176. *
  177. * @param mixed $tables A table name or a list of table names.
  178. *
  179. * @return array A list of the create SQL for the tables.
  180. *
  181. * @since 12.1
  182. * @throws RuntimeException
  183. */
  184. public function getTableCreate($tables)
  185. {
  186. $this->connect();
  187. $result = array();
  188. $query = $this->getQuery(true)
  189. ->select('dbms_metadata.get_ddl(:type, :tableName)')
  190. ->from('dual')
  191. ->bind(':type', 'TABLE');
  192. // Sanitize input to an array and iterate over the list.
  193. settype($tables, 'array');
  194. foreach ($tables as $table)
  195. {
  196. $query->bind(':tableName', $table);
  197. $this->setQuery($query);
  198. $statement = (string) $this->loadResult();
  199. $result[$table] = $statement;
  200. }
  201. return $result;
  202. }
  203. /**
  204. * Retrieves field information about a given table.
  205. *
  206. * @param string $table The name of the database table.
  207. * @param boolean $typeOnly True to only return field types.
  208. *
  209. * @return array An array of fields for the database table.
  210. *
  211. * @since 12.1
  212. * @throws RuntimeException
  213. */
  214. public function getTableColumns($table, $typeOnly = true)
  215. {
  216. $this->connect();
  217. $columns = array();
  218. $query = $this->getQuery(true);
  219. $fieldCasing = $this->getOption(PDO::ATTR_CASE);
  220. $this->setOption(PDO::ATTR_CASE, PDO::CASE_UPPER);
  221. $table = strtoupper($table);
  222. $query->select('*')
  223. ->from('ALL_TAB_COLUMNS')
  224. ->where('table_name = :tableName');
  225. $prefixedTable = str_replace('#__', strtoupper($this->tablePrefix), $table);
  226. $query->bind(':tableName', $prefixedTable);
  227. $this->setQuery($query);
  228. $fields = $this->loadObjectList();
  229. if ($typeOnly)
  230. {
  231. foreach ($fields as $field)
  232. {
  233. $columns[$field->COLUMN_NAME] = $field->DATA_TYPE;
  234. }
  235. }
  236. else
  237. {
  238. foreach ($fields as $field)
  239. {
  240. $columns[$field->COLUMN_NAME] = $field;
  241. $columns[$field->COLUMN_NAME]->Default = null;
  242. }
  243. }
  244. $this->setOption(PDO::ATTR_CASE, $fieldCasing);
  245. return $columns;
  246. }
  247. /**
  248. * Get the details list of keys for a table.
  249. *
  250. * @param string $table The name of the table.
  251. *
  252. * @return array An array of the column specification for the table.
  253. *
  254. * @since 12.1
  255. * @throws RuntimeException
  256. */
  257. public function getTableKeys($table)
  258. {
  259. $this->connect();
  260. $query = $this->getQuery(true);
  261. $fieldCasing = $this->getOption(PDO::ATTR_CASE);
  262. $this->setOption(PDO::ATTR_CASE, PDO::CASE_UPPER);
  263. $table = strtoupper($table);
  264. $query->select('*')
  265. ->from('ALL_CONSTRAINTS')
  266. ->where('table_name = :tableName')
  267. ->bind(':tableName', $table);
  268. $this->setQuery($query);
  269. $keys = $this->loadObjectList();
  270. $this->setOption(PDO::ATTR_CASE, $fieldCasing);
  271. return $keys;
  272. }
  273. /**
  274. * Method to get an array of all tables in the database (schema).
  275. *
  276. * @param string $databaseName The database (schema) name
  277. * @param boolean $includeDatabaseName Whether to include the schema name in the results
  278. *
  279. * @return array An array of all the tables in the database.
  280. *
  281. * @since 12.1
  282. * @throws RuntimeException
  283. */
  284. public function getTableList($databaseName = null, $includeDatabaseName = false)
  285. {
  286. $this->connect();
  287. $query = $this->getQuery(true);
  288. $tables = array();
  289. if ($includeDatabaseName)
  290. {
  291. $query->select('owner, table_name');
  292. }
  293. else
  294. {
  295. $query->select('table_name');
  296. }
  297. $query->from('all_tables');
  298. if ($databaseName)
  299. {
  300. $query->where('owner = :database')
  301. ->bind(':database', $databaseName);
  302. }
  303. $query->order('table_name');
  304. $this->setQuery($query);
  305. if ($includeDatabaseName)
  306. {
  307. $tables = $this->loadAssocList();
  308. }
  309. else
  310. {
  311. $tables = $this->loadResultArray();
  312. }
  313. return $tables;
  314. }
  315. /**
  316. * Get the version of the database connector.
  317. *
  318. * @return string The database connector version.
  319. *
  320. * @since 12.1
  321. */
  322. public function getVersion()
  323. {
  324. $this->connect();
  325. $this->setQuery("select value from nls_database_parameters where parameter = 'NLS_RDBMS_VERSION'");
  326. return $this->loadResult();
  327. }
  328. /**
  329. * Select a database for use.
  330. *
  331. * @param string $database The name of the database to select for use.
  332. *
  333. * @return boolean True if the database was successfully selected.
  334. *
  335. * @since 12.1
  336. * @throws RuntimeException
  337. */
  338. public function select($database)
  339. {
  340. $this->connect();
  341. return true;
  342. }
  343. /**
  344. * Sets the Oracle Date Format for the session
  345. * Default date format for Oracle is = DD-MON-RR
  346. * The default date format for this driver is:
  347. * 'RRRR-MM-DD HH24:MI:SS' since it is the format
  348. * that matches the MySQL one used within most Joomla
  349. * tables.
  350. *
  351. * @param string $dateFormat Oracle Date Format String
  352. *
  353. * @return boolean
  354. *
  355. * @since 12.1
  356. */
  357. public function setDateFormat($dateFormat = 'DD-MON-RR')
  358. {
  359. $this->connect();
  360. $this->setQuery("ALTER SESSION SET NLS_DATE_FORMAT = '$dateFormat'");
  361. $this->setQuery("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = '$dateFormat'");
  362. if (!$this->execute())
  363. {
  364. return false;
  365. }
  366. $this->dateformat = $dateFormat;
  367. return true;
  368. }
  369. /**
  370. * Set the connection to use UTF-8 character encoding.
  371. *
  372. * Returns false automatically for the Oracle driver since
  373. * you can only set the character set when the connection
  374. * is created.
  375. *
  376. * @return boolean True on success.
  377. *
  378. * @since 12.1
  379. */
  380. public function setUTF()
  381. {
  382. return false;
  383. }
  384. /**
  385. * Locks a table in the database.
  386. *
  387. * @param string $table The name of the table to unlock.
  388. *
  389. * @return JDatabaseDriverOracle Returns this object to support chaining.
  390. *
  391. * @since 12.1
  392. * @throws RuntimeException
  393. */
  394. public function lockTable($table)
  395. {
  396. $this->setQuery('LOCK TABLE ' . $this->quoteName($table) . ' IN EXCLUSIVE MODE')->execute();
  397. return $this;
  398. }
  399. /**
  400. * Renames a table in the database.
  401. *
  402. * @param string $oldTable The name of the table to be renamed
  403. * @param string $newTable The new name for the table.
  404. * @param string $backup Not used by Oracle.
  405. * @param string $prefix Not used by Oracle.
  406. *
  407. * @return JDatabaseDriverOracle Returns this object to support chaining.
  408. *
  409. * @since 12.1
  410. * @throws RuntimeException
  411. */
  412. public function renameTable($oldTable, $newTable, $backup = null, $prefix = null)
  413. {
  414. $this->setQuery('RENAME ' . $oldTable . ' TO ' . $newTable)->execute();
  415. return $this;
  416. }
  417. /**
  418. * Unlocks tables in the database.
  419. *
  420. * @return JDatabaseDriverOracle Returns this object to support chaining.
  421. *
  422. * @since 12.1
  423. * @throws RuntimeException
  424. */
  425. public function unlockTables()
  426. {
  427. $this->setQuery('COMMIT')->execute();
  428. return $this;
  429. }
  430. /**
  431. * Test to see if the PDO ODBC connector is available.
  432. *
  433. * @return boolean True on success, false otherwise.
  434. *
  435. * @since 12.1
  436. */
  437. public static function isSupported()
  438. {
  439. return class_exists('PDO') && in_array('oci', PDO::getAvailableDrivers());
  440. }
  441. /**
  442. * This function replaces a string identifier <var>$prefix</var> with the string held is the
  443. * <var>tablePrefix</var> class variable.
  444. *
  445. * @param string $query The SQL statement to prepare.
  446. * @param string $prefix The common table prefix.
  447. *
  448. * @return string The processed SQL statement.
  449. *
  450. * @since 11.1
  451. */
  452. public function replacePrefix($query, $prefix = '#__')
  453. {
  454. $escaped = false;
  455. $startPos = 0;
  456. $quoteChar = "'";
  457. $literal = '';
  458. $query = trim($query);
  459. $n = strlen($query);
  460. while ($startPos < $n)
  461. {
  462. $ip = strpos($query, $prefix, $startPos);
  463. if ($ip === false)
  464. {
  465. break;
  466. }
  467. $j = strpos($query, "'", $startPos);
  468. if ($j === false)
  469. {
  470. $j = $n;
  471. }
  472. $literal .= str_replace($prefix, $this->tablePrefix, substr($query, $startPos, $j - $startPos));
  473. $startPos = $j;
  474. $j = $startPos + 1;
  475. if ($j >= $n)
  476. {
  477. break;
  478. }
  479. // Quote comes first, find end of quote
  480. while (true)
  481. {
  482. $k = strpos($query, $quoteChar, $j);
  483. $escaped = false;
  484. if ($k === false)
  485. {
  486. break;
  487. }
  488. $l = $k - 1;
  489. while ($l >= 0 && $query{$l} == '\\')
  490. {
  491. $l--;
  492. $escaped = !$escaped;
  493. }
  494. if ($escaped)
  495. {
  496. $j = $k + 1;
  497. continue;
  498. }
  499. break;
  500. }
  501. if ($k === false)
  502. {
  503. // Error in the query - no end quote; ignore it
  504. break;
  505. }
  506. $literal .= substr($query, $startPos, $k - $startPos + 1);
  507. $startPos = $k + 1;
  508. }
  509. if ($startPos < $n)
  510. {
  511. $literal .= substr($query, $startPos, $n - $startPos);
  512. }
  513. return $literal;
  514. }
  515. }