You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

220 lines
6.5 KiB

12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
  1. <?php
  2. /**
  3. * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace OC\DB;
  9. use Doctrine\DBAL\DBALException;
  10. use Doctrine\DBAL\Driver;
  11. use Doctrine\DBAL\Configuration;
  12. use Doctrine\DBAL\Cache\QueryCacheProfile;
  13. use Doctrine\Common\EventManager;
  14. use OCP\IDBConnection;
  15. class Connection extends \Doctrine\DBAL\Connection implements IDBConnection {
  16. /**
  17. * @var string $tablePrefix
  18. */
  19. protected $tablePrefix;
  20. /**
  21. * @var \OC\DB\Adapter $adapter
  22. */
  23. protected $adapter;
  24. public function connect() {
  25. try {
  26. return parent::connect();
  27. } catch (DBALException $e) {
  28. // throw a new exception to prevent leaking info from the stacktrace
  29. throw new DBALException($e->getMessage(), $e->getCode());
  30. }
  31. }
  32. /**
  33. * @return string
  34. */
  35. public function getPrefix() {
  36. return $this->tablePrefix;
  37. }
  38. /**
  39. * Initializes a new instance of the Connection class.
  40. *
  41. * @param array $params The connection parameters.
  42. * @param \Doctrine\DBAL\Driver $driver
  43. * @param \Doctrine\DBAL\Configuration $config
  44. * @param \Doctrine\Common\EventManager $eventManager
  45. * @throws \Exception
  46. */
  47. public function __construct(array $params, Driver $driver, Configuration $config = null,
  48. EventManager $eventManager = null)
  49. {
  50. if (!isset($params['adapter'])) {
  51. throw new \Exception('adapter not set');
  52. }
  53. if (!isset($params['tablePrefix'])) {
  54. throw new \Exception('tablePrefix not set');
  55. }
  56. parent::__construct($params, $driver, $config, $eventManager);
  57. $this->adapter = new $params['adapter']($this);
  58. $this->tablePrefix = $params['tablePrefix'];
  59. }
  60. /**
  61. * Prepares an SQL statement.
  62. *
  63. * @param string $statement The SQL statement to prepare.
  64. * @param int $limit
  65. * @param int $offset
  66. * @return \Doctrine\DBAL\Driver\Statement The prepared statement.
  67. */
  68. public function prepare( $statement, $limit=null, $offset=null ) {
  69. if ($limit === -1) {
  70. $limit = null;
  71. }
  72. if (!is_null($limit)) {
  73. $platform = $this->getDatabasePlatform();
  74. $statement = $platform->modifyLimitQuery($statement, $limit, $offset);
  75. }
  76. $statement = $this->replaceTablePrefix($statement);
  77. $statement = $this->adapter->fixupStatement($statement);
  78. if(\OC_Config::getValue( 'log_query', false)) {
  79. \OC_Log::write('core', 'DB prepare : '.$statement, \OC_Log::DEBUG);
  80. }
  81. return parent::prepare($statement);
  82. }
  83. /**
  84. * Executes an, optionally parametrized, SQL query.
  85. *
  86. * If the query is parametrized, a prepared statement is used.
  87. * If an SQLLogger is configured, the execution is logged.
  88. *
  89. * @param string $query The SQL query to execute.
  90. * @param array $params The parameters to bind to the query, if any.
  91. * @param array $types The types the previous parameters are in.
  92. * @param \Doctrine\DBAL\Cache\QueryCacheProfile|null $qcp The query cache profile, optional.
  93. *
  94. * @return \Doctrine\DBAL\Driver\Statement The executed statement.
  95. *
  96. * @throws \Doctrine\DBAL\DBALException
  97. */
  98. public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null)
  99. {
  100. $query = $this->replaceTablePrefix($query);
  101. $query = $this->adapter->fixupStatement($query);
  102. return parent::executeQuery($query, $params, $types, $qcp);
  103. }
  104. /**
  105. * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
  106. * and returns the number of affected rows.
  107. *
  108. * This method supports PDO binding types as well as DBAL mapping types.
  109. *
  110. * @param string $query The SQL query.
  111. * @param array $params The query parameters.
  112. * @param array $types The parameter types.
  113. *
  114. * @return integer The number of affected rows.
  115. *
  116. * @throws \Doctrine\DBAL\DBALException
  117. */
  118. public function executeUpdate($query, array $params = array(), array $types = array())
  119. {
  120. $query = $this->replaceTablePrefix($query);
  121. $query = $this->adapter->fixupStatement($query);
  122. return parent::executeUpdate($query, $params, $types);
  123. }
  124. /**
  125. * Returns the ID of the last inserted row, or the last value from a sequence object,
  126. * depending on the underlying driver.
  127. *
  128. * Note: This method may not return a meaningful or consistent result across different drivers,
  129. * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY
  130. * columns or sequences.
  131. *
  132. * @param string $seqName Name of the sequence object from which the ID should be returned.
  133. * @return string A string representation of the last inserted ID.
  134. */
  135. public function lastInsertId($seqName = null)
  136. {
  137. if ($seqName) {
  138. $seqName = $this->replaceTablePrefix($seqName);
  139. }
  140. return $this->adapter->lastInsertId($seqName);
  141. }
  142. // internal use
  143. public function realLastInsertId($seqName = null)
  144. {
  145. return parent::lastInsertId($seqName);
  146. }
  147. /**
  148. * Insert a row if a matching row doesn't exists.
  149. * @param string $table. The table to insert into in the form '*PREFIX*tableName'
  150. * @param array $input. An array of fieldname/value pairs
  151. * @throws \OC\HintException
  152. * @return bool The return value from execute()
  153. */
  154. public function insertIfNotExist($table, $input, $compare = null) {
  155. return $this->adapter->insertIfNotExist($table, $input, $compare);
  156. }
  157. /**
  158. * returns the error code and message as a string for logging
  159. * works with DoctrineException
  160. * @return string
  161. */
  162. public function getError() {
  163. $msg = $this->errorCode() . ': ';
  164. $errorInfo = $this->errorInfo();
  165. if (is_array($errorInfo)) {
  166. $msg .= 'SQLSTATE = '.$errorInfo[0] . ', ';
  167. $msg .= 'Driver Code = '.$errorInfo[1] . ', ';
  168. $msg .= 'Driver Message = '.$errorInfo[2];
  169. }
  170. return $msg;
  171. }
  172. /**
  173. * Drop a table from the database if it exists
  174. *
  175. * @param string $table table name without the prefix
  176. */
  177. public function dropTable($table) {
  178. $table = $this->tablePrefix . trim($table);
  179. $schema = $this->getSchemaManager();
  180. if($schema->tablesExist(array($table))) {
  181. $schema->dropTable($table);
  182. }
  183. }
  184. /**
  185. * Check if a table exists
  186. *
  187. * @param string $table table name without the prefix
  188. * @return bool
  189. */
  190. public function tableExists($table){
  191. $table = $this->tablePrefix . trim($table);
  192. $schema = $this->getSchemaManager();
  193. return $schema->tablesExist(array($table));
  194. }
  195. // internal use
  196. /**
  197. * @param string $statement
  198. * @return string
  199. */
  200. protected function replaceTablePrefix($statement) {
  201. return str_replace( '*PREFIX*', $this->tablePrefix, $statement );
  202. }
  203. }