diff options
author | Roeland Jago Douma <rullzer@owncloud.com> | 2016-04-15 19:46:34 +0200 |
---|---|---|
committer | Roeland Jago Douma <rullzer@owncloud.com> | 2016-04-15 19:46:34 +0200 |
commit | d09f835dcac66347204ada3def3b8ea9d837f0ab (patch) | |
tree | 2cf5d5de1c1ef98313b80cc0251945926bfa0302 /lib/private/db | |
parent | bb71fd6d02fd829542277129e022ef4dae840e1d (diff) | |
download | nextcloud-server-d09f835dcac66347204ada3def3b8ea9d837f0ab.tar.gz nextcloud-server-d09f835dcac66347204ada3def3b8ea9d837f0ab.zip |
Move \OC\DB to PSR-4
Besides the statement wrapper that is moved to the legacy folder
(namepsace of shame folder)
Diffstat (limited to 'lib/private/db')
31 files changed, 0 insertions, 4573 deletions
diff --git a/lib/private/db/adapter.php b/lib/private/db/adapter.php deleted file mode 100644 index 9522f768c88..00000000000 --- a/lib/private/db/adapter.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php -/** - * @author Bart Visscher <bartv@thisnet.nl> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Jonny007-MKD <1-23-4-5@web.de> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - -/** - * This handles the way we use to write queries, into something that can be - * handled by the database abstraction layer. - */ -class Adapter { - - /** - * @var \OC\DB\Connection $conn - */ - protected $conn; - - public function __construct($conn) { - $this->conn = $conn; - } - - /** - * @param string $table name - * @return int id of last insert statement - */ - public function lastInsertId($table) { - return $this->conn->realLastInsertId($table); - } - - /** - * @param string $statement that needs to be changed so the db can handle it - * @return string changed statement - */ - public function fixupStatement($statement) { - return $statement; - } - - /** - * Insert a row if the matching row does not exists. - * - * @param string $table The table name (will replace *PREFIX* with the actual prefix) - * @param array $input data that should be inserted into the table (column name => value) - * @param array|null $compare List of values that should be checked for "if not exists" - * If this is null or an empty array, all keys of $input will be compared - * Please note: text fields (clob) must not be used in the compare array - * @return int number of inserted rows - * @throws \Doctrine\DBAL\DBALException - */ - public function insertIfNotExist($table, $input, array $compare = null) { - if (empty($compare)) { - $compare = array_keys($input); - } - $query = 'INSERT INTO `' .$table . '` (`' - . implode('`,`', array_keys($input)) . '`) SELECT ' - . str_repeat('?,', count($input)-1).'? ' // Is there a prettier alternative? - . 'FROM `' . $table . '` WHERE '; - - $inserts = array_values($input); - foreach($compare as $key) { - $query .= '`' . $key . '`'; - if (is_null($input[$key])) { - $query .= ' IS NULL AND '; - } else { - $inserts[] = $input[$key]; - $query .= ' = ? AND '; - } - } - $query = substr($query, 0, strlen($query) - 5); - $query .= ' HAVING COUNT(*) = 0'; - - return $this->conn->executeUpdate($query, $inserts); - } -} diff --git a/lib/private/db/adaptermysql.php b/lib/private/db/adaptermysql.php deleted file mode 100644 index ab87c589747..00000000000 --- a/lib/private/db/adaptermysql.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/** - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\DB; - -class AdapterMySQL extends Adapter { - public function fixupStatement($statement) { - $statement = str_replace(' ILIKE ', ' COLLATE utf8_general_ci LIKE ', $statement); - return $statement; - } -} diff --git a/lib/private/db/adapteroci8.php b/lib/private/db/adapteroci8.php deleted file mode 100644 index 970d3eefa4d..00000000000 --- a/lib/private/db/adapteroci8.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/** - * @author Bart Visscher <bartv@thisnet.nl> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\DB; - -class AdapterOCI8 extends Adapter { - public function lastInsertId($table) { - if (is_null($table)) { - throw new \InvalidArgumentException('Oracle requires a table name to be passed into lastInsertId()'); - } - if ($table !== null) { - $suffix = '_SEQ'; - $table = '"' . $table . $suffix . '"'; - } - return $this->conn->realLastInsertId($table); - } - - const UNIX_TIMESTAMP_REPLACEMENT = "(cast(sys_extract_utc(systimestamp) as date) - date'1970-01-01') * 86400"; - - public function fixupStatement($statement) { - $statement = preg_replace('( LIKE \?)', '$0 ESCAPE \'\\\'', $statement); - $statement = preg_replace('/`(\w+)` ILIKE \?/', 'REGEXP_LIKE(`$1`, \'^\' || REPLACE(?, \'%\', \'.*\') || \'$\', \'i\')', $statement); - $statement = str_replace('`', '"', $statement); - $statement = str_ireplace('NOW()', 'CURRENT_TIMESTAMP', $statement); - $statement = str_ireplace('UNIX_TIMESTAMP()', self::UNIX_TIMESTAMP_REPLACEMENT, $statement); - return $statement; - } -} diff --git a/lib/private/db/adapterpgsql.php b/lib/private/db/adapterpgsql.php deleted file mode 100644 index a7d9377a0bf..00000000000 --- a/lib/private/db/adapterpgsql.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * @author Bart Visscher <bartv@thisnet.nl> - * @author Morris Jobke <hey@morrisjobke.de> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\DB; - -class AdapterPgSql extends Adapter { - public function lastInsertId($table) { - return $this->conn->fetchColumn('SELECT lastval()'); - } - - const UNIX_TIMESTAMP_REPLACEMENT = 'cast(extract(epoch from current_timestamp) as integer)'; - public function fixupStatement($statement) { - $statement = str_replace( '`', '"', $statement ); - $statement = str_ireplace( 'UNIX_TIMESTAMP()', self::UNIX_TIMESTAMP_REPLACEMENT, $statement ); - return $statement; - } -} diff --git a/lib/private/db/adaptersqlite.php b/lib/private/db/adaptersqlite.php deleted file mode 100644 index d7769238abc..00000000000 --- a/lib/private/db/adaptersqlite.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * @author Bart Visscher <bartv@thisnet.nl> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - - -namespace OC\DB; - -class AdapterSqlite extends Adapter { - public function fixupStatement($statement) { - $statement = preg_replace('( I?LIKE \?)', '$0 ESCAPE \'\\\'', $statement); - $statement = preg_replace('/`(\w+)` ILIKE \?/', 'LOWER($1) LIKE LOWER(?)', $statement); - $statement = str_replace( '`', '"', $statement ); - $statement = str_ireplace( 'NOW()', 'datetime(\'now\')', $statement ); - $statement = str_ireplace( 'UNIX_TIMESTAMP()', 'strftime(\'%s\',\'now\')', $statement ); - return $statement; - } - - /** - * Insert a row if the matching row does not exists. - * - * @param string $table The table name (will replace *PREFIX* with the actual prefix) - * @param array $input data that should be inserted into the table (column name => value) - * @param array|null $compare List of values that should be checked for "if not exists" - * If this is null or an empty array, all keys of $input will be compared - * Please note: text fields (clob) must not be used in the compare array - * @return int number of inserted rows - * @throws \Doctrine\DBAL\DBALException - */ - public function insertIfNotExist($table, $input, array $compare = null) { - if (empty($compare)) { - $compare = array_keys($input); - } - $fieldList = '`' . implode('`,`', array_keys($input)) . '`'; - $query = "INSERT INTO `$table` ($fieldList) SELECT " - . str_repeat('?,', count($input)-1).'? ' - . " WHERE NOT EXISTS (SELECT 1 FROM `$table` WHERE "; - - $inserts = array_values($input); - foreach($compare as $key) { - $query .= '`' . $key . '`'; - if (is_null($input[$key])) { - $query .= ' IS NULL AND '; - } else { - $inserts[] = $input[$key]; - $query .= ' = ? AND '; - } - } - $query = substr($query, 0, strlen($query) - 5); - $query .= ')'; - - return $this->conn->executeUpdate($query, $inserts); - } -} diff --git a/lib/private/db/connection.php b/lib/private/db/connection.php deleted file mode 100644 index 7904fab0726..00000000000 --- a/lib/private/db/connection.php +++ /dev/null @@ -1,373 +0,0 @@ -<?php -/** - * @author Bart Visscher <bartv@thisnet.nl> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; -use Doctrine\DBAL\DBALException; -use Doctrine\DBAL\Driver; -use Doctrine\DBAL\Configuration; -use Doctrine\DBAL\Cache\QueryCacheProfile; -use Doctrine\Common\EventManager; -use OC\DB\QueryBuilder\QueryBuilder; -use OCP\DB\QueryBuilder\IQueryBuilder; -use OCP\IDBConnection; -use OCP\PreconditionNotMetException; - -class Connection extends \Doctrine\DBAL\Connection implements IDBConnection { - /** - * @var string $tablePrefix - */ - protected $tablePrefix; - - /** - * @var \OC\DB\Adapter $adapter - */ - protected $adapter; - - public function connect() { - try { - return parent::connect(); - } catch (DBALException $e) { - // throw a new exception to prevent leaking info from the stacktrace - throw new DBALException('Failed to connect to the database: ' . $e->getMessage(), $e->getCode()); - } - } - - /** - * Returns a QueryBuilder for the connection. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder - */ - public function getQueryBuilder() { - return new QueryBuilder($this); - } - - /** - * Gets the QueryBuilder for the connection. - * - * @return \Doctrine\DBAL\Query\QueryBuilder - * @deprecated please use $this->getQueryBuilder() instead - */ - public function createQueryBuilder() { - $backtrace = $this->getCallerBacktrace(); - \OC::$server->getLogger()->debug('Doctrine QueryBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]); - return parent::createQueryBuilder(); - } - - /** - * Gets the ExpressionBuilder for the connection. - * - * @return \Doctrine\DBAL\Query\Expression\ExpressionBuilder - * @deprecated please use $this->getQueryBuilder()->expr() instead - */ - public function getExpressionBuilder() { - $backtrace = $this->getCallerBacktrace(); - \OC::$server->getLogger()->debug('Doctrine ExpressionBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]); - return parent::getExpressionBuilder(); - } - - /** - * Get the file and line that called the method where `getCallerBacktrace()` was used - * - * @return string - */ - protected function getCallerBacktrace() { - $traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); - - // 0 is the method where we use `getCallerBacktrace` - // 1 is the target method which uses the method we want to log - if (isset($traces[1])) { - return $traces[1]['file'] . ':' . $traces[1]['line']; - } - - return ''; - } - - /** - * @return string - */ - public function getPrefix() { - return $this->tablePrefix; - } - - /** - * Initializes a new instance of the Connection class. - * - * @param array $params The connection parameters. - * @param \Doctrine\DBAL\Driver $driver - * @param \Doctrine\DBAL\Configuration $config - * @param \Doctrine\Common\EventManager $eventManager - * @throws \Exception - */ - public function __construct(array $params, Driver $driver, Configuration $config = null, - EventManager $eventManager = null) - { - if (!isset($params['adapter'])) { - throw new \Exception('adapter not set'); - } - if (!isset($params['tablePrefix'])) { - throw new \Exception('tablePrefix not set'); - } - parent::__construct($params, $driver, $config, $eventManager); - $this->adapter = new $params['adapter']($this); - $this->tablePrefix = $params['tablePrefix']; - - parent::setTransactionIsolation(parent::TRANSACTION_READ_COMMITTED); - } - - /** - * Prepares an SQL statement. - * - * @param string $statement The SQL statement to prepare. - * @param int $limit - * @param int $offset - * @return \Doctrine\DBAL\Driver\Statement The prepared statement. - */ - public function prepare( $statement, $limit=null, $offset=null ) { - if ($limit === -1) { - $limit = null; - } - if (!is_null($limit)) { - $platform = $this->getDatabasePlatform(); - $statement = $platform->modifyLimitQuery($statement, $limit, $offset); - } - $statement = $this->replaceTablePrefix($statement); - $statement = $this->adapter->fixupStatement($statement); - - if(\OC::$server->getSystemConfig()->getValue( 'log_query', false)) { - \OCP\Util::writeLog('core', 'DB prepare : '.$statement, \OCP\Util::DEBUG); - } - return parent::prepare($statement); - } - - /** - * Executes an, optionally parametrized, SQL query. - * - * If the query is parametrized, a prepared statement is used. - * If an SQLLogger is configured, the execution is logged. - * - * @param string $query The SQL query to execute. - * @param array $params The parameters to bind to the query, if any. - * @param array $types The types the previous parameters are in. - * @param \Doctrine\DBAL\Cache\QueryCacheProfile|null $qcp The query cache profile, optional. - * - * @return \Doctrine\DBAL\Driver\Statement The executed statement. - * - * @throws \Doctrine\DBAL\DBALException - */ - public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null) - { - $query = $this->replaceTablePrefix($query); - $query = $this->adapter->fixupStatement($query); - return parent::executeQuery($query, $params, $types, $qcp); - } - - /** - * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters - * and returns the number of affected rows. - * - * This method supports PDO binding types as well as DBAL mapping types. - * - * @param string $query The SQL query. - * @param array $params The query parameters. - * @param array $types The parameter types. - * - * @return integer The number of affected rows. - * - * @throws \Doctrine\DBAL\DBALException - */ - public function executeUpdate($query, array $params = array(), array $types = array()) - { - $query = $this->replaceTablePrefix($query); - $query = $this->adapter->fixupStatement($query); - return parent::executeUpdate($query, $params, $types); - } - - /** - * Returns the ID of the last inserted row, or the last value from a sequence object, - * depending on the underlying driver. - * - * Note: This method may not return a meaningful or consistent result across different drivers, - * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY - * columns or sequences. - * - * @param string $seqName Name of the sequence object from which the ID should be returned. - * @return string A string representation of the last inserted ID. - */ - public function lastInsertId($seqName = null) { - if ($seqName) { - $seqName = $this->replaceTablePrefix($seqName); - } - return $this->adapter->lastInsertId($seqName); - } - - // internal use - public function realLastInsertId($seqName = null) { - return parent::lastInsertId($seqName); - } - - /** - * Insert a row if the matching row does not exists. - * - * @param string $table The table name (will replace *PREFIX* with the actual prefix) - * @param array $input data that should be inserted into the table (column name => value) - * @param array|null $compare List of values that should be checked for "if not exists" - * If this is null or an empty array, all keys of $input will be compared - * Please note: text fields (clob) must not be used in the compare array - * @return int number of inserted rows - * @throws \Doctrine\DBAL\DBALException - */ - public function insertIfNotExist($table, $input, array $compare = null) { - return $this->adapter->insertIfNotExist($table, $input, $compare); - } - - private function getType($value) { - if (is_bool($value)) { - return IQueryBuilder::PARAM_BOOL; - } else if (is_int($value)) { - return IQueryBuilder::PARAM_INT; - } else { - return IQueryBuilder::PARAM_STR; - } - } - - /** - * Insert or update a row value - * - * @param string $table - * @param array $keys (column name => value) - * @param array $values (column name => value) - * @param array $updatePreconditionValues ensure values match preconditions (column name => value) - * @return int number of new rows - * @throws \Doctrine\DBAL\DBALException - * @throws PreconditionNotMetException - */ - public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []) { - try { - $insertQb = $this->getQueryBuilder(); - $insertQb->insert($table) - ->values( - array_map(function($value) use ($insertQb) { - return $insertQb->createNamedParameter($value, $this->getType($value)); - }, array_merge($keys, $values)) - ); - return $insertQb->execute(); - } catch (\Doctrine\DBAL\Exception\ConstraintViolationException $e) { - // value already exists, try update - $updateQb = $this->getQueryBuilder(); - $updateQb->update($table); - foreach ($values as $name => $value) { - $updateQb->set($name, $updateQb->createNamedParameter($value, $this->getType($value))); - } - $where = $updateQb->expr()->andx(); - $whereValues = array_merge($keys, $updatePreconditionValues); - foreach ($whereValues as $name => $value) { - $where->add($updateQb->expr()->eq( - $name, - $updateQb->createNamedParameter($value, $this->getType($value)), - $this->getType($value) - )); - } - $updateQb->where($where); - $affected = $updateQb->execute(); - - if ($affected === 0 && !empty($updatePreconditionValues)) { - throw new PreconditionNotMetException(); - } - - return 0; - } - } - - /** - * returns the error code and message as a string for logging - * works with DoctrineException - * @return string - */ - public function getError() { - $msg = $this->errorCode() . ': '; - $errorInfo = $this->errorInfo(); - if (is_array($errorInfo)) { - $msg .= 'SQLSTATE = '.$errorInfo[0] . ', '; - $msg .= 'Driver Code = '.$errorInfo[1] . ', '; - $msg .= 'Driver Message = '.$errorInfo[2]; - } - return $msg; - } - - /** - * Drop a table from the database if it exists - * - * @param string $table table name without the prefix - */ - public function dropTable($table) { - $table = $this->tablePrefix . trim($table); - $schema = $this->getSchemaManager(); - if($schema->tablesExist(array($table))) { - $schema->dropTable($table); - } - } - - /** - * Check if a table exists - * - * @param string $table table name without the prefix - * @return bool - */ - public function tableExists($table){ - $table = $this->tablePrefix . trim($table); - $schema = $this->getSchemaManager(); - return $schema->tablesExist(array($table)); - } - - // internal use - /** - * @param string $statement - * @return string - */ - protected function replaceTablePrefix($statement) { - return str_replace( '*PREFIX*', $this->tablePrefix, $statement ); - } - - /** - * Check if a transaction is active - * - * @return bool - * @since 8.2.0 - */ - public function inTransaction() { - return $this->getTransactionNestingLevel() > 0; - } - - /** - * Espace a parameter to be used in a LIKE query - * - * @param string $param - * @return string - */ - public function escapeLikeParameter($param) { - return addcslashes($param, '\\_%'); - } -} diff --git a/lib/private/db/connectionfactory.php b/lib/private/db/connectionfactory.php deleted file mode 100644 index 0856d8d19c0..00000000000 --- a/lib/private/db/connectionfactory.php +++ /dev/null @@ -1,184 +0,0 @@ -<?php -/** - * @author Andreas Fischer <bantu@owncloud.com> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; -use Doctrine\DBAL\Event\Listeners\OracleSessionInit; -use Doctrine\DBAL\Event\Listeners\SQLSessionInit; -use Doctrine\DBAL\Event\Listeners\MysqlSessionInit; - -/** -* Takes care of creating and configuring Doctrine connections. -*/ -class ConnectionFactory { - /** - * @var array - * - * Array mapping DBMS type to default connection parameters passed to - * \Doctrine\DBAL\DriverManager::getConnection(). - */ - protected $defaultConnectionParams = array( - 'mysql' => array( - 'adapter' => '\OC\DB\AdapterMySQL', - 'charset' => 'UTF8', - 'driver' => 'pdo_mysql', - 'wrapperClass' => 'OC\DB\Connection', - ), - 'oci' => array( - 'adapter' => '\OC\DB\AdapterOCI8', - 'charset' => 'AL32UTF8', - 'driver' => 'oci8', - 'wrapperClass' => 'OC\DB\OracleConnection', - ), - 'pgsql' => array( - 'adapter' => '\OC\DB\AdapterPgSql', - 'driver' => 'pdo_pgsql', - 'wrapperClass' => 'OC\DB\Connection', - ), - 'sqlite3' => array( - 'adapter' => '\OC\DB\AdapterSqlite', - 'driver' => 'pdo_sqlite', - 'wrapperClass' => 'OC\DB\Connection', - ), - ); - - /** - * @brief Get default connection parameters for a given DBMS. - * @param string $type DBMS type - * @throws \InvalidArgumentException If $type is invalid - * @return array Default connection parameters. - */ - public function getDefaultConnectionParams($type) { - $normalizedType = $this->normalizeType($type); - if (!isset($this->defaultConnectionParams[$normalizedType])) { - throw new \InvalidArgumentException("Unsupported type: $type"); - } - $result = $this->defaultConnectionParams[$normalizedType]; - // \PDO::MYSQL_ATTR_FOUND_ROWS may not be defined, e.g. when the MySQL - // driver is missing. In this case, we won't be able to connect anyway. - if ($normalizedType === 'mysql' && defined('\PDO::MYSQL_ATTR_FOUND_ROWS')) { - $result['driverOptions'] = array( - \PDO::MYSQL_ATTR_FOUND_ROWS => true, - ); - } - return $result; - } - - /** - * @brief Get default connection parameters for a given DBMS. - * @param string $type DBMS type - * @param array $additionalConnectionParams Additional connection parameters - * @return \OC\DB\Connection - */ - public function getConnection($type, $additionalConnectionParams) { - $normalizedType = $this->normalizeType($type); - $eventManager = new \Doctrine\Common\EventManager(); - switch ($normalizedType) { - case 'mysql': - // Send "SET NAMES utf8". Only required on PHP 5.3 below 5.3.6. - // See http://stackoverflow.com/questions/4361459/php-pdo-charset-set-names#4361485 - $eventManager->addEventSubscriber(new MysqlSessionInit); - $eventManager->addEventSubscriber( - new SQLSessionInit("SET SESSION AUTOCOMMIT=1")); - break; - case 'oci': - $eventManager->addEventSubscriber(new OracleSessionInit); - break; - case 'sqlite3': - $journalMode = $additionalConnectionParams['sqlite.journal_mode']; - $additionalConnectionParams['platform'] = new OCSqlitePlatform(); - $eventManager->addEventSubscriber(new SQLiteSessionInit(true, $journalMode)); - break; - } - $connection = \Doctrine\DBAL\DriverManager::getConnection( - array_merge($this->getDefaultConnectionParams($type), $additionalConnectionParams), - new \Doctrine\DBAL\Configuration(), - $eventManager - ); - return $connection; - } - - /** - * @brief Normalize DBMS type - * @param string $type DBMS type - * @return string Normalized DBMS type - */ - public function normalizeType($type) { - return $type === 'sqlite' ? 'sqlite3' : $type; - } - - /** - * @brief Checks whether the specified DBMS type is valid. - * @return bool - */ - public function isValidType($type) { - $normalizedType = $this->normalizeType($type); - return isset($this->defaultConnectionParams[$normalizedType]); - } - - /** - * Create the connection parameters for the config - * - * @param \OC\SystemConfig $config - * @return array - */ - public function createConnectionParams($config) { - $type = $config->getValue('dbtype', 'sqlite'); - - $connectionParams = array( - 'user' => $config->getValue('dbuser', ''), - 'password' => $config->getValue('dbpassword', ''), - ); - $name = $config->getValue('dbname', 'owncloud'); - - if ($this->normalizeType($type) === 'sqlite3') { - $dataDir = $config->getValue("datadirectory", \OC::$SERVERROOT . '/data'); - $connectionParams['path'] = $dataDir . '/' . $name . '.db'; - } else { - $host = $config->getValue('dbhost', ''); - if (strpos($host, ':')) { - // Host variable may carry a port or socket. - list($host, $portOrSocket) = explode(':', $host, 2); - if (ctype_digit($portOrSocket)) { - $connectionParams['port'] = $portOrSocket; - } else { - $connectionParams['unix_socket'] = $portOrSocket; - } - } - $connectionParams['host'] = $host; - $connectionParams['dbname'] = $name; - } - - $connectionParams['tablePrefix'] = $config->getValue('dbtableprefix', 'oc_'); - $connectionParams['sqlite.journal_mode'] = $config->getValue('sqlite.journal_mode', 'WAL'); - - //additional driver options, eg. for mysql ssl - $driverOptions = $config->getValue('dbdriveroptions', null); - if ($driverOptions) { - $connectionParams['driverOptions'] = $driverOptions; - } - - return $connectionParams; - } -} diff --git a/lib/private/db/mdb2schemamanager.php b/lib/private/db/mdb2schemamanager.php deleted file mode 100644 index f73f6b4351a..00000000000 --- a/lib/private/db/mdb2schemamanager.php +++ /dev/null @@ -1,178 +0,0 @@ -<?php -/** - * @author Bart Visscher <bartv@thisnet.nl> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Roeland Jago Douma <rullzer@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Vincent Petry <pvince81@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - -use Doctrine\DBAL\Platforms\MySqlPlatform; -use Doctrine\DBAL\Platforms\OraclePlatform; -use Doctrine\DBAL\Platforms\PostgreSqlPlatform; -use Doctrine\DBAL\Platforms\SqlitePlatform; -use OCP\IDBConnection; - -class MDB2SchemaManager { - /** @var \OC\DB\Connection $conn */ - protected $conn; - - /** - * @param IDBConnection $conn - */ - public function __construct($conn) { - $this->conn = $conn; - } - - /** - * saves database scheme to xml file - * @param string $file name of file - * @return bool - * - * TODO: write more documentation - */ - public function getDbStructure($file) { - return \OC\DB\MDB2SchemaWriter::saveSchemaToFile($file, $this->conn); - } - - /** - * Creates tables from XML file - * @param string $file file to read structure from - * @return bool - * - * TODO: write more documentation - */ - public function createDbFromStructure($file) { - $schemaReader = new MDB2SchemaReader(\OC::$server->getConfig(), $this->conn->getDatabasePlatform()); - $toSchema = $schemaReader->loadSchemaFromFile($file); - return $this->executeSchemaChange($toSchema); - } - - /** - * @return \OC\DB\Migrator - */ - public function getMigrator() { - $random = \OC::$server->getSecureRandom(); - $platform = $this->conn->getDatabasePlatform(); - $config = \OC::$server->getConfig(); - $dispatcher = \OC::$server->getEventDispatcher(); - if ($platform instanceof SqlitePlatform) { - return new SQLiteMigrator($this->conn, $random, $config, $dispatcher); - } else if ($platform instanceof OraclePlatform) { - return new OracleMigrator($this->conn, $random, $config, $dispatcher); - } else if ($platform instanceof MySqlPlatform) { - return new MySQLMigrator($this->conn, $random, $config, $dispatcher); - } else if ($platform instanceof PostgreSqlPlatform) { - return new Migrator($this->conn, $random, $config, $dispatcher); - } else { - return new NoCheckMigrator($this->conn, $random, $config, $dispatcher); - } - } - - /** - * Reads database schema from file - * - * @param string $file file to read from - * @return \Doctrine\DBAL\Schema\Schema - */ - private function readSchemaFromFile($file) { - $platform = $this->conn->getDatabasePlatform(); - $schemaReader = new MDB2SchemaReader(\OC::$server->getConfig(), $platform); - return $schemaReader->loadSchemaFromFile($file); - } - - /** - * update the database scheme - * @param string $file file to read structure from - * @param bool $generateSql only return the sql needed for the upgrade - * @return string|boolean - */ - public function updateDbFromStructure($file, $generateSql = false) { - $toSchema = $this->readSchemaFromFile($file); - $migrator = $this->getMigrator(); - - if ($generateSql) { - return $migrator->generateChangeScript($toSchema); - } else { - $migrator->migrate($toSchema); - return true; - } - } - - /** - * update the database scheme - * @param string $file file to read structure from - * @return boolean - */ - public function simulateUpdateDbFromStructure($file) { - $toSchema = $this->readSchemaFromFile($file); - $this->getMigrator()->checkMigrate($toSchema); - return true; - } - - /** - * @param \Doctrine\DBAL\Schema\Schema $schema - * @return string - */ - public function generateChangeScript($schema) { - $migrator = $this->getMigrator(); - return $migrator->generateChangeScript($schema); - } - - /** - * remove all tables defined in a database structure xml file - * - * @param string $file the xml file describing the tables - */ - public function removeDBStructure($file) { - $schemaReader = new MDB2SchemaReader(\OC::$server->getConfig(), $this->conn->getDatabasePlatform()); - $fromSchema = $schemaReader->loadSchemaFromFile($file); - $toSchema = clone $fromSchema; - /** @var $table \Doctrine\DBAL\Schema\Table */ - foreach ($toSchema->getTables() as $table) { - $toSchema->dropTable($table->getName()); - } - $comparator = new \Doctrine\DBAL\Schema\Comparator(); - $schemaDiff = $comparator->compare($fromSchema, $toSchema); - $this->executeSchemaChange($schemaDiff); - } - - /** - * @param \Doctrine\DBAL\Schema\Schema|\Doctrine\DBAL\Schema\SchemaDiff $schema - * @return bool - */ - private function executeSchemaChange($schema) { - $this->conn->beginTransaction(); - foreach ($schema->toSql($this->conn->getDatabasePlatform()) as $sql) { - $this->conn->query($sql); - } - $this->conn->commit(); - - if ($this->conn->getDatabasePlatform() instanceof SqlitePlatform) { - $this->conn->close(); - $this->conn->connect(); - } - return true; - } -} diff --git a/lib/private/db/mdb2schemareader.php b/lib/private/db/mdb2schemareader.php deleted file mode 100644 index 375fec185cb..00000000000 --- a/lib/private/db/mdb2schemareader.php +++ /dev/null @@ -1,359 +0,0 @@ -<?php -/** - * @author Bart Visscher <bartv@thisnet.nl> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Oliver Gasser <oliver.gasser@gmail.com> - * @author Robin Appelman <icewind@owncloud.com> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Victor Dubiniuk <dubiniuk@owncloud.com> - * @author Vincent Petry <pvince81@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - -use Doctrine\DBAL\Platforms\AbstractPlatform; -use Doctrine\DBAL\Schema\SchemaConfig; -use OCP\IConfig; - -class MDB2SchemaReader { - /** - * @var string $DBNAME - */ - protected $DBNAME; - - /** - * @var string $DBTABLEPREFIX - */ - protected $DBTABLEPREFIX; - - /** - * @var \Doctrine\DBAL\Platforms\AbstractPlatform $platform - */ - protected $platform; - - /** @var \Doctrine\DBAL\Schema\SchemaConfig $schemaConfig */ - protected $schemaConfig; - - /** - * @param \OCP\IConfig $config - * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform - */ - public function __construct(IConfig $config, AbstractPlatform $platform) { - $this->platform = $platform; - $this->DBNAME = $config->getSystemValue('dbname', 'owncloud'); - $this->DBTABLEPREFIX = $config->getSystemValue('dbtableprefix', 'oc_'); - - // Oracle does not support longer index names then 30 characters. - // We use this limit for all DBs to make sure it does not cause a - // problem. - $this->schemaConfig = new SchemaConfig(); - $this->schemaConfig->setMaxIdentifierLength(30); - } - - /** - * @param string $file - * @return \Doctrine\DBAL\Schema\Schema - * @throws \DomainException - */ - public function loadSchemaFromFile($file) { - $schema = new \Doctrine\DBAL\Schema\Schema(); - $loadEntities = libxml_disable_entity_loader(false); - $xml = simplexml_load_file($file); - libxml_disable_entity_loader($loadEntities); - foreach ($xml->children() as $child) { - /** - * @var \SimpleXMLElement $child - */ - switch ($child->getName()) { - case 'name': - case 'create': - case 'overwrite': - case 'charset': - break; - case 'table': - $this->loadTable($schema, $child); - break; - default: - throw new \DomainException('Unknown element: ' . $child->getName()); - - } - } - return $schema; - } - - /** - * @param \Doctrine\DBAL\Schema\Schema $schema - * @param \SimpleXMLElement $xml - * @throws \DomainException - */ - private function loadTable($schema, $xml) { - $table = null; - foreach ($xml->children() as $child) { - /** - * @var \SimpleXMLElement $child - */ - switch ($child->getName()) { - case 'name': - $name = (string)$child; - $name = str_replace('*dbprefix*', $this->DBTABLEPREFIX, $name); - $name = $this->platform->quoteIdentifier($name); - $table = $schema->createTable($name); - $table->addOption('collate', 'utf8_bin'); - $table->setSchemaConfig($this->schemaConfig); - break; - case 'create': - case 'overwrite': - case 'charset': - break; - case 'declaration': - if (is_null($table)) { - throw new \DomainException('Table declaration before table name'); - } - $this->loadDeclaration($table, $child); - break; - default: - throw new \DomainException('Unknown element: ' . $child->getName()); - - } - } - } - - /** - * @param \Doctrine\DBAL\Schema\Table $table - * @param \SimpleXMLElement $xml - * @throws \DomainException - */ - private function loadDeclaration($table, $xml) { - foreach ($xml->children() as $child) { - /** - * @var \SimpleXMLElement $child - */ - switch ($child->getName()) { - case 'field': - $this->loadField($table, $child); - break; - case 'index': - $this->loadIndex($table, $child); - break; - default: - throw new \DomainException('Unknown element: ' . $child->getName()); - - } - } - } - - /** - * @param \Doctrine\DBAL\Schema\Table $table - * @param \SimpleXMLElement $xml - * @throws \DomainException - */ - private function loadField($table, $xml) { - $options = array( 'notnull' => false ); - foreach ($xml->children() as $child) { - /** - * @var \SimpleXMLElement $child - */ - switch ($child->getName()) { - case 'name': - $name = (string)$child; - $name = $this->platform->quoteIdentifier($name); - break; - case 'type': - $type = (string)$child; - switch ($type) { - case 'text': - $type = 'string'; - break; - case 'clob': - $type = 'text'; - break; - case 'timestamp': - $type = 'datetime'; - break; - case 'numeric': - $type = 'decimal'; - break; - } - break; - case 'length': - $length = (string)$child; - $options['length'] = $length; - break; - case 'unsigned': - $unsigned = $this->asBool($child); - $options['unsigned'] = $unsigned; - break; - case 'notnull': - $notnull = $this->asBool($child); - $options['notnull'] = $notnull; - break; - case 'autoincrement': - $autoincrement = $this->asBool($child); - $options['autoincrement'] = $autoincrement; - break; - case 'default': - $default = (string)$child; - $options['default'] = $default; - break; - case 'comments': - $comment = (string)$child; - $options['comment'] = $comment; - break; - case 'primary': - $primary = $this->asBool($child); - $options['primary'] = $primary; - break; - case 'precision': - $precision = (string)$child; - $options['precision'] = $precision; - break; - case 'scale': - $scale = (string)$child; - $options['scale'] = $scale; - break; - default: - throw new \DomainException('Unknown element: ' . $child->getName()); - - } - } - if (isset($name) && isset($type)) { - if (isset($options['default']) && empty($options['default'])) { - if (empty($options['notnull']) || !$options['notnull']) { - unset($options['default']); - $options['notnull'] = false; - } else { - $options['default'] = ''; - } - if ($type == 'integer' || $type == 'decimal') { - $options['default'] = 0; - } elseif ($type == 'boolean') { - $options['default'] = false; - } - if (!empty($options['autoincrement']) && $options['autoincrement']) { - unset($options['default']); - } - } - if ($type === 'integer' && isset($options['default'])) { - $options['default'] = (int)$options['default']; - } - if ($type === 'integer' && isset($options['length'])) { - $length = $options['length']; - if ($length < 4) { - $type = 'smallint'; - } else if ($length > 4) { - $type = 'bigint'; - } - } - if ($type === 'boolean' && isset($options['default'])) { - $options['default'] = $this->asBool($options['default']); - } - if (!empty($options['autoincrement']) - && !empty($options['notnull']) - ) { - $options['primary'] = true; - } - $table->addColumn($name, $type, $options); - if (!empty($options['primary']) && $options['primary']) { - $table->setPrimaryKey(array($name)); - } - } - } - - /** - * @param \Doctrine\DBAL\Schema\Table $table - * @param \SimpleXMLElement $xml - * @throws \DomainException - */ - private function loadIndex($table, $xml) { - $name = null; - $fields = array(); - foreach ($xml->children() as $child) { - /** - * @var \SimpleXMLElement $child - */ - switch ($child->getName()) { - case 'name': - $name = (string)$child; - break; - case 'primary': - $primary = $this->asBool($child); - break; - case 'unique': - $unique = $this->asBool($child); - break; - case 'field': - foreach ($child->children() as $field) { - /** - * @var \SimpleXMLElement $field - */ - switch ($field->getName()) { - case 'name': - $field_name = (string)$field; - $field_name = $this->platform->quoteIdentifier($field_name); - $fields[] = $field_name; - break; - case 'sorting': - break; - default: - throw new \DomainException('Unknown element: ' . $field->getName()); - - } - } - break; - default: - throw new \DomainException('Unknown element: ' . $child->getName()); - - } - } - if (!empty($fields)) { - if (isset($primary) && $primary) { - if ($table->hasPrimaryKey()) { - return; - } - $table->setPrimaryKey($fields, $name); - } else { - if (isset($unique) && $unique) { - $table->addUniqueIndex($fields, $name); - } else { - $table->addIndex($fields, $name); - } - } - } else { - throw new \DomainException('Empty index definition: ' . $name . ' options:' . print_r($fields, true)); - } - } - - /** - * @param \SimpleXMLElement|string $xml - * @return bool - */ - private function asBool($xml) { - $result = (string)$xml; - if ($result == 'true') { - $result = true; - } elseif ($result == 'false') { - $result = false; - } - return (bool)$result; - } - -} diff --git a/lib/private/db/mdb2schemawriter.php b/lib/private/db/mdb2schemawriter.php deleted file mode 100644 index 7dc3bd223a7..00000000000 --- a/lib/private/db/mdb2schemawriter.php +++ /dev/null @@ -1,178 +0,0 @@ -<?php -/** - * @author Bart Visscher <bartv@thisnet.nl> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Morris Jobke <hey@morrisjobke.de> - * @author tbelau666 <thomas.belau@gmx.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - -use Doctrine\DBAL\Schema\Column; -use Doctrine\DBAL\Schema\Index; - -class MDB2SchemaWriter { - - /** - * @param string $file - * @param \OC\DB\Connection $conn - * @return bool - */ - static public function saveSchemaToFile($file, \OC\DB\Connection $conn) { - $config = \OC::$server->getConfig(); - - $xml = new \SimpleXMLElement('<database/>'); - $xml->addChild('name', $config->getSystemValue('dbname', 'owncloud')); - $xml->addChild('create', 'true'); - $xml->addChild('overwrite', 'false'); - $xml->addChild('charset', 'utf8'); - - // FIX ME: bloody work around - if ($config->getSystemValue('dbtype', 'sqlite') === 'oci') { - $filterExpression = '/^"' . preg_quote($conn->getPrefix()) . '/'; - } else { - $filterExpression = '/^' . preg_quote($conn->getPrefix()) . '/'; - } - $conn->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression); - - foreach ($conn->getSchemaManager()->listTables() as $table) { - self::saveTable($table, $xml->addChild('table')); - } - file_put_contents($file, $xml->asXML()); - return true; - } - - /** - * @param \Doctrine\DBAL\Schema\Table $table - * @param \SimpleXMLElement $xml - */ - private static function saveTable($table, $xml) { - $xml->addChild('name', $table->getName()); - $declaration = $xml->addChild('declaration'); - foreach($table->getColumns() as $column) { - self::saveColumn($column, $declaration->addChild('field')); - } - foreach($table->getIndexes() as $index) { - if ($index->getName() == 'PRIMARY') { - $autoincrement = false; - foreach($index->getColumns() as $column) { - if ($table->getColumn($column)->getAutoincrement()) { - $autoincrement = true; - } - } - if ($autoincrement) { - continue; - } - } - self::saveIndex($index, $declaration->addChild('index')); - } - } - - /** - * @param Column $column - * @param \SimpleXMLElement $xml - */ - private static function saveColumn($column, $xml) { - $xml->addChild('name', $column->getName()); - switch($column->getType()) { - case 'SmallInt': - case 'Integer': - case 'BigInt': - $xml->addChild('type', 'integer'); - $default = $column->getDefault(); - if (is_null($default) && $column->getAutoincrement()) { - $default = '0'; - } - $xml->addChild('default', $default); - $xml->addChild('notnull', self::toBool($column->getNotnull())); - if ($column->getAutoincrement()) { - $xml->addChild('autoincrement', '1'); - } - if ($column->getUnsigned()) { - $xml->addChild('unsigned', 'true'); - } - $length = '4'; - if ($column->getType() == 'SmallInt') { - $length = '2'; - } - elseif ($column->getType() == 'BigInt') { - $length = '8'; - } - $xml->addChild('length', $length); - break; - case 'String': - $xml->addChild('type', 'text'); - $default = trim($column->getDefault()); - if ($default === '') { - $default = false; - } - $xml->addChild('default', $default); - $xml->addChild('notnull', self::toBool($column->getNotnull())); - $xml->addChild('length', $column->getLength()); - break; - case 'Text': - $xml->addChild('type', 'clob'); - $xml->addChild('notnull', self::toBool($column->getNotnull())); - break; - case 'Decimal': - $xml->addChild('type', 'decimal'); - $xml->addChild('default', $column->getDefault()); - $xml->addChild('notnull', self::toBool($column->getNotnull())); - $xml->addChild('length', '15'); - break; - case 'Boolean': - $xml->addChild('type', 'integer'); - $xml->addChild('default', $column->getDefault()); - $xml->addChild('notnull', self::toBool($column->getNotnull())); - $xml->addChild('length', '1'); - break; - case 'DateTime': - $xml->addChild('type', 'timestamp'); - $xml->addChild('default', $column->getDefault()); - $xml->addChild('notnull', self::toBool($column->getNotnull())); - break; - - } - } - - /** - * @param Index $index - * @param \SimpleXMLElement $xml - */ - private static function saveIndex($index, $xml) { - $xml->addChild('name', $index->getName()); - if ($index->isPrimary()) { - $xml->addChild('primary', 'true'); - } - elseif ($index->isUnique()) { - $xml->addChild('unique', 'true'); - } - foreach($index->getColumns() as $column) { - $field = $xml->addChild('field'); - $field->addChild('name', $column); - $field->addChild('sorting', 'ascending'); - - } - } - - private static function toBool($bool) { - return $bool ? 'true' : 'false'; - } -} diff --git a/lib/private/db/migrationexception.php b/lib/private/db/migrationexception.php deleted file mode 100644 index 57e4c5b8334..00000000000 --- a/lib/private/db/migrationexception.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - - -class MigrationException extends \Exception { - private $table; - - public function __construct($table, $message) { - $this->table = $table; - parent::__construct($message); - } - - /** - * @return string - */ - public function getTable() { - return $this->table; - } -} diff --git a/lib/private/db/migrator.php b/lib/private/db/migrator.php deleted file mode 100644 index 8b8a34d9865..00000000000 --- a/lib/private/db/migrator.php +++ /dev/null @@ -1,292 +0,0 @@ -<?php -/** - * @author martin-rueegg <martin.rueegg@metaworx.ch> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author tbelau666 <thomas.belau@gmx.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Victor Dubiniuk <dubiniuk@owncloud.com> - * @author Vincent Petry <pvince81@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - -use \Doctrine\DBAL\DBALException; -use \Doctrine\DBAL\Schema\Index; -use \Doctrine\DBAL\Schema\Table; -use \Doctrine\DBAL\Schema\Schema; -use \Doctrine\DBAL\Schema\SchemaConfig; -use \Doctrine\DBAL\Schema\Comparator; -use OCP\IConfig; -use OCP\Security\ISecureRandom; -use Symfony\Component\EventDispatcher\EventDispatcher; -use Symfony\Component\EventDispatcher\GenericEvent; - -class Migrator { - - /** - * @var \Doctrine\DBAL\Connection $connection - */ - protected $connection; - - /** - * @var ISecureRandom - */ - private $random; - - /** @var IConfig */ - protected $config; - - /** @var EventDispatcher */ - private $dispatcher; - - /** @var bool */ - private $noEmit = false; - - /** - * @param \Doctrine\DBAL\Connection|Connection $connection - * @param ISecureRandom $random - * @param IConfig $config - * @param EventDispatcher $dispatcher - */ - public function __construct(\Doctrine\DBAL\Connection $connection, - ISecureRandom $random, - IConfig $config, - EventDispatcher $dispatcher = null) { - $this->connection = $connection; - $this->random = $random; - $this->config = $config; - $this->dispatcher = $dispatcher; - } - - /** - * @param \Doctrine\DBAL\Schema\Schema $targetSchema - */ - public function migrate(Schema $targetSchema) { - $this->noEmit = true; - $this->applySchema($targetSchema); - } - - /** - * @param \Doctrine\DBAL\Schema\Schema $targetSchema - * @return string - */ - public function generateChangeScript(Schema $targetSchema) { - $schemaDiff = $this->getDiff($targetSchema, $this->connection); - - $script = ''; - $sqls = $schemaDiff->toSql($this->connection->getDatabasePlatform()); - foreach ($sqls as $sql) { - $script .= $this->convertStatementToScript($sql); - } - - return $script; - } - - /** - * @param Schema $targetSchema - * @throws \OC\DB\MigrationException - */ - public function checkMigrate(Schema $targetSchema) { - $this->noEmit = true; - /**@var \Doctrine\DBAL\Schema\Table[] $tables */ - $tables = $targetSchema->getTables(); - $filterExpression = $this->getFilterExpression(); - $this->connection->getConfiguration()-> - setFilterSchemaAssetsExpression($filterExpression); - $existingTables = $this->connection->getSchemaManager()->listTableNames(); - - $step = 0; - foreach ($tables as $table) { - if (strpos($table->getName(), '.')) { - list(, $tableName) = explode('.', $table->getName()); - } else { - $tableName = $table->getName(); - } - $this->emitCheckStep($tableName, $step++, count($tables)); - // don't need to check for new tables - if (array_search($tableName, $existingTables) !== false) { - $this->checkTableMigrate($table); - } - } - } - - /** - * Create a unique name for the temporary table - * - * @param string $name - * @return string - */ - protected function generateTemporaryTableName($name) { - return $this->config->getSystemValue('dbtableprefix', 'oc_') . $name . '_' . $this->random->generate(13, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS); - } - - /** - * Check the migration of a table on a copy so we can detect errors before messing with the real table - * - * @param \Doctrine\DBAL\Schema\Table $table - * @throws \OC\DB\MigrationException - */ - protected function checkTableMigrate(Table $table) { - $name = $table->getName(); - $tmpName = $this->generateTemporaryTableName($name); - - $this->copyTable($name, $tmpName); - - //create the migration schema for the temporary table - $tmpTable = $this->renameTableSchema($table, $tmpName); - $schemaConfig = new SchemaConfig(); - $schemaConfig->setName($this->connection->getDatabase()); - $schema = new Schema(array($tmpTable), array(), $schemaConfig); - - try { - $this->applySchema($schema); - $this->dropTable($tmpName); - } catch (DBALException $e) { - // pgsql needs to commit it's failed transaction before doing anything else - if ($this->connection->isTransactionActive()) { - $this->connection->commit(); - } - $this->dropTable($tmpName); - throw new MigrationException($table->getName(), $e->getMessage()); - } - } - - /** - * @param \Doctrine\DBAL\Schema\Table $table - * @param string $newName - * @return \Doctrine\DBAL\Schema\Table - */ - protected function renameTableSchema(Table $table, $newName) { - /** - * @var \Doctrine\DBAL\Schema\Index[] $indexes - */ - $indexes = $table->getIndexes(); - $newIndexes = array(); - foreach ($indexes as $index) { - if ($index->isPrimary()) { - // do not rename primary key - $indexName = $index->getName(); - } else { - // avoid conflicts in index names - $indexName = $this->config->getSystemValue('dbtableprefix', 'oc_') . $this->random->generate(13, ISecureRandom::CHAR_LOWER); - } - $newIndexes[] = new Index($indexName, $index->getColumns(), $index->isUnique(), $index->isPrimary()); - } - - // foreign keys are not supported so we just set it to an empty array - return new Table($newName, $table->getColumns(), $newIndexes, array(), 0, $table->getOptions()); - } - - protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) { - $filterExpression = $this->getFilterExpression(); - $this->connection->getConfiguration()-> - setFilterSchemaAssetsExpression($filterExpression); - $sourceSchema = $connection->getSchemaManager()->createSchema(); - - // remove tables we don't know about - /** @var $table \Doctrine\DBAL\Schema\Table */ - foreach ($sourceSchema->getTables() as $table) { - if (!$targetSchema->hasTable($table->getName())) { - $sourceSchema->dropTable($table->getName()); - } - } - // remove sequences we don't know about - foreach ($sourceSchema->getSequences() as $table) { - if (!$targetSchema->hasSequence($table->getName())) { - $sourceSchema->dropSequence($table->getName()); - } - } - - $comparator = new Comparator(); - return $comparator->compare($sourceSchema, $targetSchema); - } - - /** - * @param \Doctrine\DBAL\Schema\Schema $targetSchema - * @param \Doctrine\DBAL\Connection $connection - */ - protected function applySchema(Schema $targetSchema, \Doctrine\DBAL\Connection $connection = null) { - if (is_null($connection)) { - $connection = $this->connection; - } - - $schemaDiff = $this->getDiff($targetSchema, $connection); - - $connection->beginTransaction(); - $sqls = $schemaDiff->toSql($connection->getDatabasePlatform()); - $step = 0; - foreach ($sqls as $sql) { - $this->emit($sql, $step++, count($sqls)); - $connection->query($sql); - } - $connection->commit(); - } - - /** - * @param string $sourceName - * @param string $targetName - */ - protected function copyTable($sourceName, $targetName) { - $quotedSource = $this->connection->quoteIdentifier($sourceName); - $quotedTarget = $this->connection->quoteIdentifier($targetName); - - $this->connection->exec('CREATE TABLE ' . $quotedTarget . ' (LIKE ' . $quotedSource . ')'); - $this->connection->exec('INSERT INTO ' . $quotedTarget . ' SELECT * FROM ' . $quotedSource); - } - - /** - * @param string $name - */ - protected function dropTable($name) { - $this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($name)); - } - - /** - * @param $statement - * @return string - */ - protected function convertStatementToScript($statement) { - $script = $statement . ';'; - $script .= PHP_EOL; - $script .= PHP_EOL; - return $script; - } - - protected function getFilterExpression() { - return '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/'; - } - - protected function emit($sql, $step, $max) { - if ($this->noEmit) { - return; - } - if(is_null($this->dispatcher)) { - return; - } - $this->dispatcher->dispatch('\OC\DB\Migrator::executeSql', new GenericEvent($sql, [$step+1, $max])); - } - - private function emitCheckStep($tableName, $step, $max) { - if(is_null($this->dispatcher)) { - return; - } - $this->dispatcher->dispatch('\OC\DB\Migrator::checkTable', new GenericEvent($tableName, [$step+1, $max])); - } -} diff --git a/lib/private/db/mysqlmigrator.php b/lib/private/db/mysqlmigrator.php deleted file mode 100644 index 1b3f70a817d..00000000000 --- a/lib/private/db/mysqlmigrator.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -/** - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - -use Doctrine\DBAL\Schema\Schema; - -class MySQLMigrator extends Migrator { - /** - * @param Schema $targetSchema - * @param \Doctrine\DBAL\Connection $connection - * @return \Doctrine\DBAL\Schema\SchemaDiff - */ - protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) { - $platform = $connection->getDatabasePlatform(); - $platform->registerDoctrineTypeMapping('enum', 'string'); - $platform->registerDoctrineTypeMapping('bit', 'string'); - - $schemaDiff = parent::getDiff($targetSchema, $connection); - - // identifiers need to be quoted for mysql - foreach ($schemaDiff->changedTables as $tableDiff) { - $tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name); - foreach ($tableDiff->changedColumns as $column) { - $column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName); - } - } - - return $schemaDiff; - } -} diff --git a/lib/private/db/nocheckmigrator.php b/lib/private/db/nocheckmigrator.php deleted file mode 100644 index 23afae11816..00000000000 --- a/lib/private/db/nocheckmigrator.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - -use Doctrine\DBAL\Schema\Schema; - -/** - * migrator for database platforms that don't support the upgrade check - * - * @package OC\DB - */ -class NoCheckMigrator extends Migrator { - /** - * @param \Doctrine\DBAL\Schema\Schema $targetSchema - * @throws \OC\DB\MigrationException - */ - public function checkMigrate(Schema $targetSchema) {} -} diff --git a/lib/private/db/ocsqliteplatform.php b/lib/private/db/ocsqliteplatform.php deleted file mode 100644 index fe68bc3cc91..00000000000 --- a/lib/private/db/ocsqliteplatform.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/** - * @author Robin Appelman <icewind@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - -class OCSqlitePlatform extends \Doctrine\DBAL\Platforms\SqlitePlatform { - /** - * {@inheritDoc} - */ - public function getColumnDeclarationSQL($name, array $field) { - $def = parent::getColumnDeclarationSQL($name, $field); - if (!empty($field['autoincrement'])) { - $def .= ' PRIMARY KEY AUTOINCREMENT'; - } - return $def; - } - - /** - * {@inheritDoc} - */ - protected function _getCreateTableSQL($name, array $columns, array $options = array()){ - // if auto increment is set the column is already defined as primary key - foreach ($columns as $column) { - if (!empty($column['autoincrement'])) { - $options['primary'] = null; - } - } - return parent::_getCreateTableSQL($name, $columns, $options); - } -} diff --git a/lib/private/db/oracleconnection.php b/lib/private/db/oracleconnection.php deleted file mode 100644 index a95f37a8e6c..00000000000 --- a/lib/private/db/oracleconnection.php +++ /dev/null @@ -1,93 +0,0 @@ -<?php -/** - * @author Bart Visscher <bartv@thisnet.nl> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - -class OracleConnection extends Connection { - /** - * Quote the keys of the array - */ - private function quoteKeys(array $data) { - $return = array(); - foreach($data as $key => $value) { - $return[$this->quoteIdentifier($key)] = $value; - } - return $return; - } - - /** - * {@inheritDoc} - */ - public function insert($tableName, array $data, array $types = array()) { - $tableName = $this->quoteIdentifier($tableName); - $data = $this->quoteKeys($data); - return parent::insert($tableName, $data, $types); - } - - /** - * {@inheritDoc} - */ - public function update($tableName, array $data, array $identifier, array $types = array()) { - $tableName = $this->quoteIdentifier($tableName); - $data = $this->quoteKeys($data); - $identifier = $this->quoteKeys($identifier); - return parent::update($tableName, $data, $identifier, $types); - } - - /** - * {@inheritDoc} - */ - public function delete($tableExpression, array $identifier, array $types = array()) { - $tableName = $this->quoteIdentifier($tableExpression); - $identifier = $this->quoteKeys($identifier); - return parent::delete($tableName, $identifier); - } - - /** - * Drop a table from the database if it exists - * - * @param string $table table name without the prefix - */ - public function dropTable($table) { - $table = $this->tablePrefix . trim($table); - $table = $this->quoteIdentifier($table); - $schema = $this->getSchemaManager(); - if($schema->tablesExist(array($table))) { - $schema->dropTable($table); - } - } - - /** - * Check if a table exists - * - * @param string $table table name without the prefix - * @return bool - */ - public function tableExists($table){ - $table = $this->tablePrefix . trim($table); - $table = $this->quoteIdentifier($table); - $schema = $this->getSchemaManager(); - return $schema->tablesExist(array($table)); - } -} diff --git a/lib/private/db/oraclemigrator.php b/lib/private/db/oraclemigrator.php deleted file mode 100644 index ceb89cf64d4..00000000000 --- a/lib/private/db/oraclemigrator.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - -use Doctrine\DBAL\Schema\Schema; - -class OracleMigrator extends NoCheckMigrator { - /** - * @param Schema $targetSchema - * @param \Doctrine\DBAL\Connection $connection - * @return \Doctrine\DBAL\Schema\SchemaDiff - */ - protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) { - $schemaDiff = parent::getDiff($targetSchema, $connection); - - // oracle forces us to quote the identifiers - foreach ($schemaDiff->changedTables as $tableDiff) { - $tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name); - foreach ($tableDiff->changedColumns as $column) { - $column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName); - } - } - - return $schemaDiff; - } - - /** - * @param string $name - * @return string - */ - protected function generateTemporaryTableName($name) { - return 'oc_' . uniqid(); - } - - /** - * @param $statement - * @return string - */ - protected function convertStatementToScript($statement) { - if (substr($statement, -1) === ';') { - return $statement . PHP_EOL . '/' . PHP_EOL; - } - $script = $statement . ';'; - $script .= PHP_EOL; - $script .= PHP_EOL; - return $script; - } - - protected function getFilterExpression() { - return '/^"' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/'; - } - -} diff --git a/lib/private/db/pgsqltools.php b/lib/private/db/pgsqltools.php deleted file mode 100644 index e9e507551e6..00000000000 --- a/lib/private/db/pgsqltools.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php -/** - * @author Andreas Fischer <bantu@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author tbelau666 <thomas.belau@gmx.de> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; -use OCP\IConfig; - -/** -* Various PostgreSQL specific helper functions. -*/ -class PgSqlTools { - - /** @var \OCP\IConfig */ - private $config; - - /** - * @param \OCP\IConfig $config - */ - public function __construct(IConfig $config) { - $this->config = $config; - } - - /** - * @brief Resynchronizes all sequences of a database after using INSERTs - * without leaving out the auto-incremented column. - * @param \OC\DB\Connection $conn - * @return null - */ - public function resynchronizeDatabaseSequences(Connection $conn) { - $filterExpression = '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/'; - $databaseName = $conn->getDatabase(); - $conn->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression); - - foreach ($conn->getSchemaManager()->listSequences() as $sequence) { - $sequenceName = $sequence->getName(); - $sqlInfo = 'SELECT table_schema, table_name, column_name - FROM information_schema.columns - WHERE column_default = ? AND table_catalog = ?'; - $sequenceInfo = $conn->fetchAssoc($sqlInfo, array( - "nextval('$sequenceName'::regclass)", - $databaseName - )); - $tableName = $sequenceInfo['table_name']; - $columnName = $sequenceInfo['column_name']; - $sqlMaxId = "SELECT MAX($columnName) FROM $tableName"; - $sqlSetval = "SELECT setval('$sequenceName', ($sqlMaxId))"; - $conn->executeQuery($sqlSetval); - } - } -} diff --git a/lib/private/db/querybuilder/compositeexpression.php b/lib/private/db/querybuilder/compositeexpression.php deleted file mode 100644 index 927dfe38378..00000000000 --- a/lib/private/db/querybuilder/compositeexpression.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB\QueryBuilder; - -use OCP\DB\QueryBuilder\ICompositeExpression; - -class CompositeExpression implements ICompositeExpression, \Countable { - /** @var \Doctrine\DBAL\Query\Expression\CompositeExpression */ - protected $compositeExpression; - - /** - * Constructor. - * - * @param \Doctrine\DBAL\Query\Expression\CompositeExpression $compositeExpression - */ - public function __construct(\Doctrine\DBAL\Query\Expression\CompositeExpression $compositeExpression) { - $this->compositeExpression = $compositeExpression; - } - - /** - * Adds multiple parts to composite expression. - * - * @param array $parts - * - * @return \OCP\DB\QueryBuilder\ICompositeExpression - */ - public function addMultiple(array $parts = array()) { - $this->compositeExpression->addMultiple($parts); - - return $this; - } - - /** - * Adds an expression to composite expression. - * - * @param mixed $part - * - * @return \OCP\DB\QueryBuilder\ICompositeExpression - */ - public function add($part) { - $this->compositeExpression->add($part); - - return $this; - } - - /** - * Retrieves the amount of expressions on composite expression. - * - * @return integer - */ - public function count() { - return $this->compositeExpression->count(); - } - - /** - * Returns the type of this composite expression (AND/OR). - * - * @return string - */ - public function getType() { - return $this->compositeExpression->getType(); - } - - /** - * Retrieves the string representation of this composite expression. - * - * @return string - */ - public function __toString() - { - return (string) $this->compositeExpression; - } -} diff --git a/lib/private/db/querybuilder/expressionbuilder/expressionbuilder.php b/lib/private/db/querybuilder/expressionbuilder/expressionbuilder.php deleted file mode 100644 index ce98816c42d..00000000000 --- a/lib/private/db/querybuilder/expressionbuilder/expressionbuilder.php +++ /dev/null @@ -1,370 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB\QueryBuilder\ExpressionBuilder; - -use Doctrine\DBAL\Query\Expression\ExpressionBuilder as DoctrineExpressionBuilder; -use OC\DB\QueryBuilder\CompositeExpression; -use OC\DB\QueryBuilder\Literal; -use OC\DB\QueryBuilder\QueryFunction; -use OC\DB\QueryBuilder\QuoteHelper; -use OCP\DB\QueryBuilder\IExpressionBuilder; -use OCP\IDBConnection; - -class ExpressionBuilder implements IExpressionBuilder { - /** @var \Doctrine\DBAL\Query\Expression\ExpressionBuilder */ - protected $expressionBuilder; - - /** @var QuoteHelper */ - protected $helper; - - /** - * Initializes a new <tt>ExpressionBuilder</tt>. - * - * @param \OCP\IDBConnection $connection - */ - public function __construct(IDBConnection $connection) { - $this->helper = new QuoteHelper(); - $this->expressionBuilder = new DoctrineExpressionBuilder($connection); - } - - /** - * Creates a conjunction of the given boolean expressions. - * - * Example: - * - * [php] - * // (u.type = ?) AND (u.role = ?) - * $expr->andX('u.type = ?', 'u.role = ?')); - * - * @param mixed $x Optional clause. Defaults = null, but requires - * at least one defined when converting to string. - * - * @return \OCP\DB\QueryBuilder\ICompositeExpression - */ - public function andX($x = null) { - $arguments = func_get_args(); - $compositeExpression = call_user_func_array([$this->expressionBuilder, 'andX'], $arguments); - return new CompositeExpression($compositeExpression); - } - - /** - * Creates a disjunction of the given boolean expressions. - * - * Example: - * - * [php] - * // (u.type = ?) OR (u.role = ?) - * $qb->where($qb->expr()->orX('u.type = ?', 'u.role = ?')); - * - * @param mixed $x Optional clause. Defaults = null, but requires - * at least one defined when converting to string. - * - * @return \OCP\DB\QueryBuilder\ICompositeExpression - */ - public function orX($x = null) { - $arguments = func_get_args(); - $compositeExpression = call_user_func_array([$this->expressionBuilder, 'orX'], $arguments); - return new CompositeExpression($compositeExpression); - } - - /** - * Creates a comparison expression. - * - * @param mixed $x The left expression. - * @param string $operator One of the IExpressionBuilder::* constants. - * @param mixed $y The right expression. - * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility - * - * @return string - */ - public function comparison($x, $operator, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return $this->expressionBuilder->comparison($x, $operator, $y); - } - - /** - * Creates an equality comparison expression with the given arguments. - * - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a <left expr> = <right expr>. Example: - * - * [php] - * // u.id = ? - * $expr->eq('u.id', '?'); - * - * @param mixed $x The left expression. - * @param mixed $y The right expression. - * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility - * - * @return string - */ - public function eq($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return $this->expressionBuilder->eq($x, $y); - } - - /** - * Creates a non equality comparison expression with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a <left expr> <> <right expr>. Example: - * - * [php] - * // u.id <> 1 - * $q->where($q->expr()->neq('u.id', '1')); - * - * @param mixed $x The left expression. - * @param mixed $y The right expression. - * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility - * - * @return string - */ - public function neq($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return $this->expressionBuilder->neq($x, $y); - } - - /** - * Creates a lower-than comparison expression with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a <left expr> < <right expr>. Example: - * - * [php] - * // u.id < ? - * $q->where($q->expr()->lt('u.id', '?')); - * - * @param mixed $x The left expression. - * @param mixed $y The right expression. - * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility - * - * @return string - */ - public function lt($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return $this->expressionBuilder->lt($x, $y); - } - - /** - * Creates a lower-than-equal comparison expression with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a <left expr> <= <right expr>. Example: - * - * [php] - * // u.id <= ? - * $q->where($q->expr()->lte('u.id', '?')); - * - * @param mixed $x The left expression. - * @param mixed $y The right expression. - * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility - * - * @return string - */ - public function lte($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return $this->expressionBuilder->lte($x, $y); - } - - /** - * Creates a greater-than comparison expression with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a <left expr> > <right expr>. Example: - * - * [php] - * // u.id > ? - * $q->where($q->expr()->gt('u.id', '?')); - * - * @param mixed $x The left expression. - * @param mixed $y The right expression. - * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility - * - * @return string - */ - public function gt($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return $this->expressionBuilder->gt($x, $y); - } - - /** - * Creates a greater-than-equal comparison expression with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a <left expr> >= <right expr>. Example: - * - * [php] - * // u.id >= ? - * $q->where($q->expr()->gte('u.id', '?')); - * - * @param mixed $x The left expression. - * @param mixed $y The right expression. - * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility - * - * @return string - */ - public function gte($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return $this->expressionBuilder->gte($x, $y); - } - - /** - * Creates an IS NULL expression with the given arguments. - * - * @param string $x The field in string format to be restricted by IS NULL. - * - * @return string - */ - public function isNull($x) { - $x = $this->helper->quoteColumnName($x); - return $this->expressionBuilder->isNull($x); - } - - /** - * Creates an IS NOT NULL expression with the given arguments. - * - * @param string $x The field in string format to be restricted by IS NOT NULL. - * - * @return string - */ - public function isNotNull($x) { - $x = $this->helper->quoteColumnName($x); - return $this->expressionBuilder->isNotNull($x); - } - - /** - * Creates a LIKE() comparison expression with the given arguments. - * - * @param string $x Field in string format to be inspected by LIKE() comparison. - * @param mixed $y Argument to be used in LIKE() comparison. - * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility - * - * @return string - */ - public function like($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return $this->expressionBuilder->like($x, $y); - } - - /** - * Creates a ILIKE() comparison expression with the given arguments. - * - * @param string $x Field in string format to be inspected by ILIKE() comparison. - * @param mixed $y Argument to be used in ILIKE() comparison. - * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility - * - * @return string - * @since 9.0.0 - */ - public function iLike($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return $this->expressionBuilder->comparison("LOWER($x)", 'LIKE', "LOWER($y)"); - } - - /** - * Creates a NOT LIKE() comparison expression with the given arguments. - * - * @param string $x Field in string format to be inspected by NOT LIKE() comparison. - * @param mixed $y Argument to be used in NOT LIKE() comparison. - * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility - * - * @return string - */ - public function notLike($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return $this->expressionBuilder->notLike($x, $y); - } - - /** - * Creates a IN () comparison expression with the given arguments. - * - * @param string $x The field in string format to be inspected by IN() comparison. - * @param string|array $y The placeholder or the array of values to be used by IN() comparison. - * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility - * - * @return string - */ - public function in($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnNames($y); - return $this->expressionBuilder->in($x, $y); - } - - /** - * Creates a NOT IN () comparison expression with the given arguments. - * - * @param string $x The field in string format to be inspected by NOT IN() comparison. - * @param string|array $y The placeholder or the array of values to be used by NOT IN() comparison. - * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility - * - * @return string - */ - public function notIn($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnNames($y); - return $this->expressionBuilder->notIn($x, $y); - } - - /** - * Quotes a given input parameter. - * - * @param mixed $input The parameter to be quoted. - * @param mixed|null $type One of the IQueryBuilder::PARAM_* constants - * - * @return Literal - */ - public function literal($input, $type = null) { - return new Literal($this->expressionBuilder->literal($input, $type)); - } - - /** - * Returns a IQueryFunction that casts the column to the given type - * - * @param string $column - * @param mixed $type One of IQueryBuilder::PARAM_* - * @return string - */ - public function castColumn($column, $type) { - return new QueryFunction( - $this->helper->quoteColumnName($column) - ); - } -} diff --git a/lib/private/db/querybuilder/expressionbuilder/mysqlexpressionbuilder.php b/lib/private/db/querybuilder/expressionbuilder/mysqlexpressionbuilder.php deleted file mode 100644 index 0d34787d26a..00000000000 --- a/lib/private/db/querybuilder/expressionbuilder/mysqlexpressionbuilder.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB\QueryBuilder\ExpressionBuilder; - - -use OC\DB\QueryBuilder\QueryFunction; -use OCP\DB\QueryBuilder\IQueryBuilder; - -class MySqlExpressionBuilder extends ExpressionBuilder { - - /** - * @inheritdoc - */ - public function iLike($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return $this->expressionBuilder->comparison($x, ' COLLATE utf8_general_ci LIKE', $y); - } - -} diff --git a/lib/private/db/querybuilder/expressionbuilder/ociexpressionbuilder.php b/lib/private/db/querybuilder/expressionbuilder/ociexpressionbuilder.php deleted file mode 100644 index 5d615ae52e8..00000000000 --- a/lib/private/db/querybuilder/expressionbuilder/ociexpressionbuilder.php +++ /dev/null @@ -1,163 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB\QueryBuilder\ExpressionBuilder; - - -use OC\DB\QueryBuilder\QueryFunction; -use OCP\DB\QueryBuilder\ILiteral; -use OCP\DB\QueryBuilder\IParameter; -use OCP\DB\QueryBuilder\IQueryBuilder; -use OCP\DB\QueryBuilder\IQueryFunction; - -class OCIExpressionBuilder extends ExpressionBuilder { - - /** - * @param mixed $column - * @param mixed|null $type - * @return array|IQueryFunction|string - */ - protected function prepareColumn($column, $type) { - if ($type === IQueryBuilder::PARAM_STR && !is_array($column) && !($column instanceof IParameter) && !($column instanceof ILiteral)) { - $column = $this->castColumn($column, $type); - } else { - $column = $this->helper->quoteColumnNames($column); - } - return $column; - } - - /** - * @inheritdoc - */ - public function comparison($x, $operator, $y, $type = null) { - $x = $this->prepareColumn($x, $type); - $y = $this->prepareColumn($y, $type); - - return $this->expressionBuilder->comparison($x, $operator, $y); - } - - /** - * @inheritdoc - */ - public function eq($x, $y, $type = null) { - $x = $this->prepareColumn($x, $type); - $y = $this->prepareColumn($y, $type); - - return $this->expressionBuilder->eq($x, $y); - } - - /** - * @inheritdoc - */ - public function neq($x, $y, $type = null) { - $x = $this->prepareColumn($x, $type); - $y = $this->prepareColumn($y, $type); - - return $this->expressionBuilder->neq($x, $y); - } - - /** - * @inheritdoc - */ - public function lt($x, $y, $type = null) { - $x = $this->prepareColumn($x, $type); - $y = $this->prepareColumn($y, $type); - - return $this->expressionBuilder->lt($x, $y); - } - - /** - * @inheritdoc - */ - public function lte($x, $y, $type = null) { - $x = $this->prepareColumn($x, $type); - $y = $this->prepareColumn($y, $type); - - return $this->expressionBuilder->lte($x, $y); - } - - /** - * @inheritdoc - */ - public function gt($x, $y, $type = null) { - $x = $this->prepareColumn($x, $type); - $y = $this->prepareColumn($y, $type); - - return $this->expressionBuilder->gt($x, $y); - } - - /** - * @inheritdoc - */ - public function gte($x, $y, $type = null) { - $x = $this->prepareColumn($x, $type); - $y = $this->prepareColumn($y, $type); - - return $this->expressionBuilder->gte($x, $y); - } - - /** - * @inheritdoc - */ - public function in($x, $y, $type = null) { - $x = $this->prepareColumn($x, $type); - $y = $this->prepareColumn($y, $type); - - return $this->expressionBuilder->in($x, $y); - } - - /** - * @inheritdoc - */ - public function notIn($x, $y, $type = null) { - $x = $this->prepareColumn($x, $type); - $y = $this->prepareColumn($y, $type); - - return $this->expressionBuilder->notIn($x, $y); - } - - /** - * Returns a IQueryFunction that casts the column to the given type - * - * @param string $column - * @param mixed $type One of IQueryBuilder::PARAM_* - * @return IQueryFunction - */ - public function castColumn($column, $type) { - if ($type === IQueryBuilder::PARAM_STR) { - $column = $this->helper->quoteColumnName($column); - return new QueryFunction('to_char(' . $column . ')'); - } - - return parent::castColumn($column, $type); - } - - /** - * @inheritdoc - */ - public function iLike($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return new QueryFunction('REGEXP_LIKE('.$x.', \'^\' || REPLACE('.$y.', \'%\', \'.*\') || \'$\', \'i\')'); - } -} diff --git a/lib/private/db/querybuilder/expressionbuilder/pgsqlexpressionbuilder.php b/lib/private/db/querybuilder/expressionbuilder/pgsqlexpressionbuilder.php deleted file mode 100644 index a8f1af87a45..00000000000 --- a/lib/private/db/querybuilder/expressionbuilder/pgsqlexpressionbuilder.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB\QueryBuilder\ExpressionBuilder; - - -use OC\DB\QueryBuilder\QueryFunction; -use OCP\DB\QueryBuilder\IQueryBuilder; - -class PgSqlExpressionBuilder extends ExpressionBuilder { - - /** - * Returns a IQueryFunction that casts the column to the given type - * - * @param string $column - * @param mixed $type One of IQueryBuilder::PARAM_* - * @return string - */ - public function castColumn($column, $type) { - if ($type === IQueryBuilder::PARAM_INT) { - $column = $this->helper->quoteColumnName($column); - return new QueryFunction('CAST(' . $column . ' AS INT)'); - } - - return parent::castColumn($column, $type); - } - - /** - * @inheritdoc - */ - public function iLike($x, $y, $type = null) { - $x = $this->helper->quoteColumnName($x); - $y = $this->helper->quoteColumnName($y); - return $this->expressionBuilder->comparison($x, 'ILIKE', $y); - } - -} diff --git a/lib/private/db/querybuilder/literal.php b/lib/private/db/querybuilder/literal.php deleted file mode 100644 index 0cc96ab48b4..00000000000 --- a/lib/private/db/querybuilder/literal.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB\QueryBuilder; - -use OCP\DB\QueryBuilder\ILiteral; - -class Literal implements ILiteral{ - /** @var mixed */ - protected $literal; - - public function __construct($literal) { - $this->literal = $literal; - } - - /** - * @return string - */ - public function __toString() { - return (string) $this->literal; - } -} diff --git a/lib/private/db/querybuilder/parameter.php b/lib/private/db/querybuilder/parameter.php deleted file mode 100644 index 1c233c83f1d..00000000000 --- a/lib/private/db/querybuilder/parameter.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB\QueryBuilder; - -use OCP\DB\QueryBuilder\IParameter; - -class Parameter implements IParameter { - /** @var mixed */ - protected $name; - - public function __construct($name) { - $this->name = $name; - } - - /** - * @return string - */ - public function __toString() { - return (string) $this->name; - } -} diff --git a/lib/private/db/querybuilder/querybuilder.php b/lib/private/db/querybuilder/querybuilder.php deleted file mode 100644 index bb463e43a75..00000000000 --- a/lib/private/db/querybuilder/querybuilder.php +++ /dev/null @@ -1,1124 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB\QueryBuilder; - -use Doctrine\DBAL\Platforms\MySqlPlatform; -use Doctrine\DBAL\Platforms\PostgreSqlPlatform; -use OC\DB\OracleConnection; -use OC\DB\QueryBuilder\ExpressionBuilder\ExpressionBuilder; -use OC\DB\QueryBuilder\ExpressionBuilder\MySqlExpressionBuilder; -use OC\DB\QueryBuilder\ExpressionBuilder\OCIExpressionBuilder; -use OC\DB\QueryBuilder\ExpressionBuilder\PgSqlExpressionBuilder; -use OCP\DB\QueryBuilder\IQueryBuilder; -use OCP\DB\QueryBuilder\IQueryFunction; -use OCP\DB\QueryBuilder\IParameter; -use OCP\IDBConnection; - -class QueryBuilder implements IQueryBuilder { - - /** @var \OCP\IDBConnection */ - private $connection; - - /** @var \Doctrine\DBAL\Query\QueryBuilder */ - private $queryBuilder; - - /** @var QuoteHelper */ - private $helper; - - /** @var bool */ - private $automaticTablePrefix = true; - - /** @var string */ - protected $lastInsertedTable; - - /** - * Initializes a new QueryBuilder. - * - * @param \OCP\IDBConnection $connection - */ - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - $this->queryBuilder = new \Doctrine\DBAL\Query\QueryBuilder($this->connection); - $this->helper = new QuoteHelper(); - } - - /** - * Enable/disable automatic prefixing of table names with the oc_ prefix - * - * @param bool $enabled If set to true table names will be prefixed with the - * owncloud database prefix automatically. - * @since 8.2.0 - */ - public function automaticTablePrefix($enabled) { - $this->automaticTablePrefix = (bool) $enabled; - } - - /** - * Gets an ExpressionBuilder used for object-oriented construction of query expressions. - * This producer method is intended for convenient inline usage. Example: - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u') - * ->from('users', 'u') - * ->where($qb->expr()->eq('u.id', 1)); - * </code> - * - * For more complex expression construction, consider storing the expression - * builder object in a local variable. - * - * @return \OCP\DB\QueryBuilder\IExpressionBuilder - */ - public function expr() { - if ($this->connection instanceof OracleConnection) { - return new OCIExpressionBuilder($this->connection); - } else if ($this->connection->getDatabasePlatform() instanceof PostgreSqlPlatform) { - return new PgSqlExpressionBuilder($this->connection); - } else if ($this->connection->getDatabasePlatform() instanceof MySqlPlatform) { - return new MySqlExpressionBuilder($this->connection); - } else { - return new ExpressionBuilder($this->connection); - } - } - - /** - * Gets the type of the currently built query. - * - * @return integer - */ - public function getType() { - return $this->queryBuilder->getType(); - } - - /** - * Gets the associated DBAL Connection for this query builder. - * - * @return \OCP\IDBConnection - */ - public function getConnection() { - return $this->connection; - } - - /** - * Gets the state of this query builder instance. - * - * @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN. - */ - public function getState() { - return $this->queryBuilder->getState(); - } - - /** - * Executes this query using the bound parameters and their types. - * - * Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate} - * for insert, update and delete statements. - * - * @return \Doctrine\DBAL\Driver\Statement|int - */ - public function execute() { - return $this->queryBuilder->execute(); - } - - /** - * Gets the complete SQL string formed by the current specifications of this QueryBuilder. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u') - * ->from('User', 'u') - * echo $qb->getSQL(); // SELECT u FROM User u - * </code> - * - * @return string The SQL query string. - */ - public function getSQL() { - return $this->queryBuilder->getSQL(); - } - - /** - * Sets a query parameter for the query being constructed. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u') - * ->from('users', 'u') - * ->where('u.id = :user_id') - * ->setParameter(':user_id', 1); - * </code> - * - * @param string|integer $key The parameter position or name. - * @param mixed $value The parameter value. - * @param string|null $type One of the IQueryBuilder::PARAM_* constants. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function setParameter($key, $value, $type = null) { - $this->queryBuilder->setParameter($key, $value, $type); - - return $this; - } - - /** - * Sets a collection of query parameters for the query being constructed. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u') - * ->from('users', 'u') - * ->where('u.id = :user_id1 OR u.id = :user_id2') - * ->setParameters(array( - * ':user_id1' => 1, - * ':user_id2' => 2 - * )); - * </code> - * - * @param array $params The query parameters to set. - * @param array $types The query parameters types to set. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function setParameters(array $params, array $types = array()) { - $this->queryBuilder->setParameters($params, $types); - - return $this; - } - - /** - * Gets all defined query parameters for the query being constructed indexed by parameter index or name. - * - * @return array The currently defined query parameters indexed by parameter index or name. - */ - public function getParameters() { - return $this->queryBuilder->getParameters(); - } - - /** - * Gets a (previously set) query parameter of the query being constructed. - * - * @param mixed $key The key (index or name) of the bound parameter. - * - * @return mixed The value of the bound parameter. - */ - public function getParameter($key) { - return $this->queryBuilder->getParameter($key); - } - - /** - * Gets all defined query parameter types for the query being constructed indexed by parameter index or name. - * - * @return array The currently defined query parameter types indexed by parameter index or name. - */ - public function getParameterTypes() { - return $this->queryBuilder->getParameterTypes(); - } - - /** - * Gets a (previously set) query parameter type of the query being constructed. - * - * @param mixed $key The key (index or name) of the bound parameter type. - * - * @return mixed The value of the bound parameter type. - */ - public function getParameterType($key) { - return $this->queryBuilder->getParameterType($key); - } - - /** - * Sets the position of the first result to retrieve (the "offset"). - * - * @param integer $firstResult The first result to return. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function setFirstResult($firstResult) { - $this->queryBuilder->setFirstResult($firstResult); - - return $this; - } - - /** - * Gets the position of the first result the query object was set to retrieve (the "offset"). - * Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder. - * - * @return integer The position of the first result. - */ - public function getFirstResult() { - return $this->queryBuilder->getFirstResult(); - } - - /** - * Sets the maximum number of results to retrieve (the "limit"). - * - * NOTE: Setting max results to "0" will cause mixed behaviour. While most - * of the databases will just return an empty result set, Oracle will return - * all entries. - * - * @param integer $maxResults The maximum number of results to retrieve. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function setMaxResults($maxResults) { - $this->queryBuilder->setMaxResults($maxResults); - - return $this; - } - - /** - * Gets the maximum number of results the query object was set to retrieve (the "limit"). - * Returns NULL if {@link setMaxResults} was not applied to this query builder. - * - * @return integer The maximum number of results. - */ - public function getMaxResults() { - return $this->queryBuilder->getMaxResults(); - } - - /** - * Specifies an item that is to be returned in the query result. - * Replaces any previously specified selections, if any. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u.id', 'p.id') - * ->from('users', 'u') - * ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id'); - * </code> - * - * @param mixed $select The selection expressions. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function select($select = null) { - $selects = is_array($select) ? $select : func_get_args(); - - $this->queryBuilder->select( - $this->helper->quoteColumnNames($selects) - ); - - return $this; - } - - /** - * Specifies an item that is to be returned with a different name in the query result. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->selectAlias('u.id', 'user_id') - * ->from('users', 'u') - * ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id'); - * </code> - * - * @param mixed $select The selection expressions. - * @param string $alias The column alias used in the constructed query. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function selectAlias($select, $alias) { - - $this->queryBuilder->addSelect( - $this->helper->quoteColumnName($select) . ' AS ' . $this->helper->quoteColumnName($alias) - ); - - return $this; - } - - /** - * Specifies an item that is to be returned uniquely in the query result. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->selectDistinct('type') - * ->from('users'); - * </code> - * - * @param mixed $select The selection expressions. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function selectDistinct($select) { - - $this->queryBuilder->addSelect( - 'DISTINCT ' . $this->helper->quoteColumnName($select) - ); - - return $this; - } - - /** - * Adds an item that is to be returned in the query result. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u.id') - * ->addSelect('p.id') - * ->from('users', 'u') - * ->leftJoin('u', 'phonenumbers', 'u.id = p.user_id'); - * </code> - * - * @param mixed $select The selection expression. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function addSelect($select = null) { - $selects = is_array($select) ? $select : func_get_args(); - - $this->queryBuilder->addSelect( - $this->helper->quoteColumnNames($selects) - ); - - return $this; - } - - /** - * Turns the query being built into a bulk delete query that ranges over - * a certain table. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->delete('users', 'u') - * ->where('u.id = :user_id'); - * ->setParameter(':user_id', 1); - * </code> - * - * @param string $delete The table whose rows are subject to the deletion. - * @param string $alias The table alias used in the constructed query. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function delete($delete = null, $alias = null) { - $this->queryBuilder->delete( - $this->getTableName($delete), - $alias - ); - - return $this; - } - - /** - * Turns the query being built into a bulk update query that ranges over - * a certain table - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->update('users', 'u') - * ->set('u.password', md5('password')) - * ->where('u.id = ?'); - * </code> - * - * @param string $update The table whose rows are subject to the update. - * @param string $alias The table alias used in the constructed query. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function update($update = null, $alias = null) { - $this->queryBuilder->update( - $this->getTableName($update), - $alias - ); - - return $this; - } - - /** - * Turns the query being built into an insert query that inserts into - * a certain table - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->insert('users') - * ->values( - * array( - * 'name' => '?', - * 'password' => '?' - * ) - * ); - * </code> - * - * @param string $insert The table into which the rows should be inserted. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function insert($insert = null) { - $this->queryBuilder->insert( - $this->getTableName($insert) - ); - - $this->lastInsertedTable = $insert; - - return $this; - } - - /** - * Creates and adds a query root corresponding to the table identified by the - * given alias, forming a cartesian product with any existing query roots. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u.id') - * ->from('users', 'u') - * </code> - * - * @param string $from The table. - * @param string|null $alias The alias of the table. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function from($from, $alias = null) { - $this->queryBuilder->from( - $this->getTableName($from), - $alias - ); - - return $this; - } - - /** - * Creates and adds a join to the query. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u.name') - * ->from('users', 'u') - * ->join('u', 'phonenumbers', 'p', 'p.is_primary = 1'); - * </code> - * - * @param string $fromAlias The alias that points to a from clause. - * @param string $join The table name to join. - * @param string $alias The alias of the join table. - * @param string $condition The condition for the join. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function join($fromAlias, $join, $alias, $condition = null) { - $this->queryBuilder->join( - $fromAlias, - $this->getTableName($join), - $alias, - $condition - ); - - return $this; - } - - /** - * Creates and adds a join to the query. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u.name') - * ->from('users', 'u') - * ->innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1'); - * </code> - * - * @param string $fromAlias The alias that points to a from clause. - * @param string $join The table name to join. - * @param string $alias The alias of the join table. - * @param string $condition The condition for the join. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function innerJoin($fromAlias, $join, $alias, $condition = null) { - $this->queryBuilder->innerJoin( - $fromAlias, - $this->getTableName($join), - $alias, - $condition - ); - - return $this; - } - - /** - * Creates and adds a left join to the query. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u.name') - * ->from('users', 'u') - * ->leftJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1'); - * </code> - * - * @param string $fromAlias The alias that points to a from clause. - * @param string $join The table name to join. - * @param string $alias The alias of the join table. - * @param string $condition The condition for the join. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function leftJoin($fromAlias, $join, $alias, $condition = null) { - $this->queryBuilder->leftJoin( - $fromAlias, - $this->getTableName($join), - $alias, - $condition - ); - - return $this; - } - - /** - * Creates and adds a right join to the query. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u.name') - * ->from('users', 'u') - * ->rightJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1'); - * </code> - * - * @param string $fromAlias The alias that points to a from clause. - * @param string $join The table name to join. - * @param string $alias The alias of the join table. - * @param string $condition The condition for the join. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function rightJoin($fromAlias, $join, $alias, $condition = null) { - $this->queryBuilder->rightJoin( - $fromAlias, - $this->getTableName($join), - $alias, - $condition - ); - - return $this; - } - - /** - * Sets a new value for a column in a bulk update query. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->update('users', 'u') - * ->set('u.password', md5('password')) - * ->where('u.id = ?'); - * </code> - * - * @param string $key The column to set. - * @param string $value The value, expression, placeholder, etc. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function set($key, $value) { - $this->queryBuilder->set( - $this->helper->quoteColumnName($key), - $this->helper->quoteColumnName($value) - ); - - return $this; - } - - /** - * Specifies one or more restrictions to the query result. - * Replaces any previously specified restrictions, if any. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u.name') - * ->from('users', 'u') - * ->where('u.id = ?'); - * - * // You can optionally programatically build and/or expressions - * $qb = $conn->getQueryBuilder(); - * - * $or = $qb->expr()->orx(); - * $or->add($qb->expr()->eq('u.id', 1)); - * $or->add($qb->expr()->eq('u.id', 2)); - * - * $qb->update('users', 'u') - * ->set('u.password', md5('password')) - * ->where($or); - * </code> - * - * @param mixed $predicates The restriction predicates. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function where($predicates) { - call_user_func_array( - [$this->queryBuilder, 'where'], - func_get_args() - ); - - return $this; - } - - /** - * Adds one or more restrictions to the query results, forming a logical - * conjunction with any previously specified restrictions. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u') - * ->from('users', 'u') - * ->where('u.username LIKE ?') - * ->andWhere('u.is_active = 1'); - * </code> - * - * @param mixed $where The query restrictions. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - * - * @see where() - */ - public function andWhere($where) { - call_user_func_array( - [$this->queryBuilder, 'andWhere'], - func_get_args() - ); - - return $this; - } - - /** - * Adds one or more restrictions to the query results, forming a logical - * disjunction with any previously specified restrictions. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u.name') - * ->from('users', 'u') - * ->where('u.id = 1') - * ->orWhere('u.id = 2'); - * </code> - * - * @param mixed $where The WHERE statement. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - * - * @see where() - */ - public function orWhere($where) { - call_user_func_array( - [$this->queryBuilder, 'orWhere'], - func_get_args() - ); - - return $this; - } - - /** - * Specifies a grouping over the results of the query. - * Replaces any previously specified groupings, if any. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u.name') - * ->from('users', 'u') - * ->groupBy('u.id'); - * </code> - * - * @param mixed $groupBy The grouping expression. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function groupBy($groupBy) { - $groupBys = is_array($groupBy) ? $groupBy : func_get_args(); - - call_user_func_array( - [$this->queryBuilder, 'groupBy'], - $this->helper->quoteColumnNames($groupBys) - ); - - return $this; - } - - /** - * Adds a grouping expression to the query. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->select('u.name') - * ->from('users', 'u') - * ->groupBy('u.lastLogin'); - * ->addGroupBy('u.createdAt') - * </code> - * - * @param mixed $groupBy The grouping expression. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function addGroupBy($groupBy) { - $groupBys = is_array($groupBy) ? $groupBy : func_get_args(); - - call_user_func_array( - [$this->queryBuilder, 'addGroupBy'], - $this->helper->quoteColumnNames($groupBys) - ); - - return $this; - } - - /** - * Sets a value for a column in an insert query. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->insert('users') - * ->values( - * array( - * 'name' => '?' - * ) - * ) - * ->setValue('password', '?'); - * </code> - * - * @param string $column The column into which the value should be inserted. - * @param string $value The value that should be inserted into the column. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function setValue($column, $value) { - $this->queryBuilder->setValue( - $this->helper->quoteColumnName($column), - $value - ); - - return $this; - } - - /** - * Specifies values for an insert query indexed by column names. - * Replaces any previous values, if any. - * - * <code> - * $qb = $conn->getQueryBuilder() - * ->insert('users') - * ->values( - * array( - * 'name' => '?', - * 'password' => '?' - * ) - * ); - * </code> - * - * @param array $values The values to specify for the insert query indexed by column names. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function values(array $values) { - $quotedValues = []; - foreach ($values as $key => $value) { - $quotedValues[$this->helper->quoteColumnName($key)] = $value; - } - - $this->queryBuilder->values($quotedValues); - - return $this; - } - - /** - * Specifies a restriction over the groups of the query. - * Replaces any previous having restrictions, if any. - * - * @param mixed $having The restriction over the groups. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function having($having) { - call_user_func_array( - [$this->queryBuilder, 'having'], - func_get_args() - ); - - return $this; - } - - /** - * Adds a restriction over the groups of the query, forming a logical - * conjunction with any existing having restrictions. - * - * @param mixed $having The restriction to append. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function andHaving($having) { - call_user_func_array( - [$this->queryBuilder, 'andHaving'], - func_get_args() - ); - - return $this; - } - - /** - * Adds a restriction over the groups of the query, forming a logical - * disjunction with any existing having restrictions. - * - * @param mixed $having The restriction to add. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function orHaving($having) { - call_user_func_array( - [$this->queryBuilder, 'orHaving'], - func_get_args() - ); - - return $this; - } - - /** - * Specifies an ordering for the query results. - * Replaces any previously specified orderings, if any. - * - * @param string $sort The ordering expression. - * @param string $order The ordering direction. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function orderBy($sort, $order = null) { - $this->queryBuilder->orderBy( - $this->helper->quoteColumnName($sort), - $order - ); - - return $this; - } - - /** - * Adds an ordering to the query results. - * - * @param string $sort The ordering expression. - * @param string $order The ordering direction. - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function addOrderBy($sort, $order = null) { - $this->queryBuilder->addOrderBy( - $this->helper->quoteColumnName($sort), - $order - ); - - return $this; - } - - /** - * Gets a query part by its name. - * - * @param string $queryPartName - * - * @return mixed - */ - public function getQueryPart($queryPartName) { - return $this->queryBuilder->getQueryPart($queryPartName); - } - - /** - * Gets all query parts. - * - * @return array - */ - public function getQueryParts() { - return $this->queryBuilder->getQueryParts(); - } - - /** - * Resets SQL parts. - * - * @param array|null $queryPartNames - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function resetQueryParts($queryPartNames = null) { - $this->queryBuilder->resetQueryParts($queryPartNames); - - return $this; - } - - /** - * Resets a single SQL part. - * - * @param string $queryPartName - * - * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. - */ - public function resetQueryPart($queryPartName) { - $this->queryBuilder->resetQueryPart($queryPartName); - - return $this; - } - - /** - * Creates a new named parameter and bind the value $value to it. - * - * This method provides a shortcut for PDOStatement::bindValue - * when using prepared statements. - * - * The parameter $value specifies the value that you want to bind. If - * $placeholder is not provided bindValue() will automatically create a - * placeholder for you. An automatic placeholder will be of the name - * ':dcValue1', ':dcValue2' etc. - * - * For more information see {@link http://php.net/pdostatement-bindparam} - * - * Example: - * <code> - * $value = 2; - * $q->eq( 'id', $q->bindValue( $value ) ); - * $stmt = $q->executeQuery(); // executed with 'id = 2' - * </code> - * - * @license New BSD License - * @link http://www.zetacomponents.org - * - * @param mixed $value - * @param mixed $type - * @param string $placeHolder The name to bind with. The string must start with a colon ':'. - * - * @return IParameter the placeholder name used. - */ - public function createNamedParameter($value, $type = IQueryBuilder::PARAM_STR, $placeHolder = null) { - return new Parameter($this->queryBuilder->createNamedParameter($value, $type, $placeHolder)); - } - - /** - * Creates a new positional parameter and bind the given value to it. - * - * Attention: If you are using positional parameters with the query builder you have - * to be very careful to bind all parameters in the order they appear in the SQL - * statement , otherwise they get bound in the wrong order which can lead to serious - * bugs in your code. - * - * Example: - * <code> - * $qb = $conn->getQueryBuilder(); - * $qb->select('u.*') - * ->from('users', 'u') - * ->where('u.username = ' . $qb->createPositionalParameter('Foo', IQueryBuilder::PARAM_STR)) - * ->orWhere('u.username = ' . $qb->createPositionalParameter('Bar', IQueryBuilder::PARAM_STR)) - * </code> - * - * @param mixed $value - * @param integer $type - * - * @return IParameter - */ - public function createPositionalParameter($value, $type = IQueryBuilder::PARAM_STR) { - return new Parameter($this->queryBuilder->createPositionalParameter($value, $type)); - } - - /** - * Creates a new parameter - * - * Example: - * <code> - * $qb = $conn->getQueryBuilder(); - * $qb->select('u.*') - * ->from('users', 'u') - * ->where('u.username = ' . $qb->createParameter('name')) - * ->setParameter('name', 'Bar', IQueryBuilder::PARAM_STR)) - * </code> - * - * @param string $name - * - * @return IParameter - */ - public function createParameter($name) { - return new Parameter(':' . $name); - } - - /** - * Creates a new function - * - * Attention: Column names inside the call have to be quoted before hand - * - * Example: - * <code> - * $qb = $conn->getQueryBuilder(); - * $qb->select($qb->createFunction('COUNT(*)')) - * ->from('users', 'u') - * echo $qb->getSQL(); // SELECT COUNT(*) FROM `users` u - * </code> - * <code> - * $qb = $conn->getQueryBuilder(); - * $qb->select($qb->createFunction('COUNT(`column`)')) - * ->from('users', 'u') - * echo $qb->getSQL(); // SELECT COUNT(`column`) FROM `users` u - * </code> - * - * @param string $call - * - * @return IQueryFunction - */ - public function createFunction($call) { - return new QueryFunction($call); - } - - /** - * Used to get the id of the last inserted element - * @return int - * @throws \BadMethodCallException When being called before an insert query has been run. - */ - public function getLastInsertId() { - if ($this->getType() === \Doctrine\DBAL\Query\QueryBuilder::INSERT && $this->lastInsertedTable) { - // lastInsertId() needs the prefix but no quotes - $table = $this->prefixTableName($this->lastInsertedTable); - return (int) $this->connection->lastInsertId($table); - } - - throw new \BadMethodCallException('Invalid call to getLastInsertId without using insert() before.'); - } - - /** - * Returns the table name quoted and with database prefix as needed by the implementation - * - * @param string $table - * @return string - */ - public function getTableName($table) { - $table = $this->prefixTableName($table); - return $this->helper->quoteColumnName($table); - } - - /** - * Returns the table name with database prefix as needed by the implementation - * - * @param string $table - * @return string - */ - protected function prefixTableName($table) { - if ($this->automaticTablePrefix === false || strpos($table, '*PREFIX*') === 0) { - return $table; - } - - return '*PREFIX*' . $table; - } - - /** - * Returns the column name quoted and with table alias prefix as needed by the implementation - * - * @param string $column - * @param string $tableAlias - * @return string - */ - public function getColumnName($column, $tableAlias = '') { - if ($tableAlias !== '') { - $tableAlias .= '.'; - } - - return $this->helper->quoteColumnName($tableAlias . $column); - } -} diff --git a/lib/private/db/querybuilder/queryfunction.php b/lib/private/db/querybuilder/queryfunction.php deleted file mode 100644 index ac6d73f3cbf..00000000000 --- a/lib/private/db/querybuilder/queryfunction.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB\QueryBuilder; - -use OCP\DB\QueryBuilder\IQueryFunction; - -class QueryFunction implements IQueryFunction { - /** @var string */ - protected $function; - - public function __construct($function) { - $this->function = $function; - } - - /** - * @return string - */ - public function __toString() { - return (string) $this->function; - } -} diff --git a/lib/private/db/querybuilder/quotehelper.php b/lib/private/db/querybuilder/quotehelper.php deleted file mode 100644 index fda243a3786..00000000000 --- a/lib/private/db/querybuilder/quotehelper.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB\QueryBuilder; - -use OCP\DB\QueryBuilder\ILiteral; -use OCP\DB\QueryBuilder\IParameter; -use OCP\DB\QueryBuilder\IQueryFunction; - -class QuoteHelper { - /** - * @param array|string|ILiteral|IParameter|IQueryFunction $strings string, Literal or Parameter - * @return array|string - */ - public function quoteColumnNames($strings) { - if (!is_array($strings)) { - return $this->quoteColumnName($strings); - } - - $return = []; - foreach ($strings as $string) { - $return[] = $this->quoteColumnName($string); - } - - return $return; - } - - /** - * @param string|ILiteral|IParameter|IQueryFunction $string string, Literal or Parameter - * @return string - */ - public function quoteColumnName($string) { - if ($string instanceof IParameter || $string instanceof ILiteral || $string instanceof IQueryFunction) { - return (string) $string; - } - - if ($string === null || $string === 'null' || $string === '*') { - return $string; - } - - if (!is_string($string)) { - throw new \InvalidArgumentException('Only strings, Literals and Parameters are allowed'); - } - - if (substr_count($string, '.')) { - list($alias, $columnName) = explode('.', $string, 2); - - if ($columnName === '*') { - return $string; - } - - return $alias . '.`' . $columnName . '`'; - } - - return '`' . $string . '`'; - } -} diff --git a/lib/private/db/sqlitemigrator.php b/lib/private/db/sqlitemigrator.php deleted file mode 100644 index 8ea32581011..00000000000 --- a/lib/private/db/sqlitemigrator.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php -/** - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Victor Dubiniuk <dubiniuk@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - -use Doctrine\DBAL\DBALException; -use Doctrine\DBAL\Schema\Schema; - -class SQLiteMigrator extends Migrator { - - /** - * @param \Doctrine\DBAL\Schema\Schema $targetSchema - * @throws \OC\DB\MigrationException - * - * For sqlite we simple make a copy of the entire database, and test the migration on that - */ - public function checkMigrate(\Doctrine\DBAL\Schema\Schema $targetSchema) { - $dbFile = $this->connection->getDatabase(); - $tmpFile = $this->buildTempDatabase(); - copy($dbFile, $tmpFile); - - $connectionParams = array( - 'path' => $tmpFile, - 'driver' => 'pdo_sqlite', - ); - $conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams); - try { - $this->applySchema($targetSchema, $conn); - $conn->close(); - unlink($tmpFile); - } catch (DBALException $e) { - $conn->close(); - unlink($tmpFile); - throw new MigrationException('', $e->getMessage()); - } - } - - /** - * @return string - */ - private function buildTempDatabase() { - $dataDir = $this->config->getSystemValue("datadirectory", \OC::$SERVERROOT . '/data'); - $tmpFile = uniqid("oc_"); - return "$dataDir/$tmpFile.db"; - } - - /** - * @param Schema $targetSchema - * @param \Doctrine\DBAL\Connection $connection - * @return \Doctrine\DBAL\Schema\SchemaDiff - */ - protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) { - $platform = $connection->getDatabasePlatform(); - $platform->registerDoctrineTypeMapping('tinyint unsigned', 'integer'); - $platform->registerDoctrineTypeMapping('smallint unsigned', 'integer'); - $platform->registerDoctrineTypeMapping('varchar ', 'string'); - - return parent::getDiff($targetSchema, $connection); - } -} diff --git a/lib/private/db/sqlitesessioninit.php b/lib/private/db/sqlitesessioninit.php deleted file mode 100644 index 0683c47d08e..00000000000 --- a/lib/private/db/sqlitesessioninit.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php -/** - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OC\DB; - -use Doctrine\DBAL\Event\ConnectionEventArgs; -use Doctrine\DBAL\Events; -use Doctrine\Common\EventSubscriber; - -class SQLiteSessionInit implements EventSubscriber { - /** - * @var bool - */ - private $caseSensitiveLike; - - /** - * @var string - */ - private $journalMode; - - /** - * Configure case sensitive like for each connection - * - * @param bool $caseSensitiveLike - * @param string $journalMode - */ - public function __construct($caseSensitiveLike, $journalMode) { - $this->caseSensitiveLike = $caseSensitiveLike; - $this->journalMode = $journalMode; - } - - /** - * @param ConnectionEventArgs $args - * @return void - */ - public function postConnect(ConnectionEventArgs $args) { - $sensitive = ($this->caseSensitiveLike) ? 'true' : 'false'; - $args->getConnection()->executeUpdate('PRAGMA case_sensitive_like = ' . $sensitive); - $args->getConnection()->executeUpdate('PRAGMA journal_mode = ' . $this->journalMode); - } - - public function getSubscribedEvents() { - return array(Events::postConnect); - } -} diff --git a/lib/private/db/statementwrapper.php b/lib/private/db/statementwrapper.php deleted file mode 100644 index 6422d8d5f1b..00000000000 --- a/lib/private/db/statementwrapper.php +++ /dev/null @@ -1,122 +0,0 @@ -<?php -/** - * @author Arthur Schiwon <blizzz@owncloud.com> - * @author Bart Visscher <bartv@thisnet.nl> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -/** - * small wrapper around \Doctrine\DBAL\Driver\Statement to make it behave, more like an MDB2 Statement - * - * @method boolean bindValue(mixed $param, mixed $value, integer $type = null); - * @method string errorCode(); - * @method array errorInfo(); - * @method integer rowCount(); - * @method array fetchAll(integer $fetchMode = null); - */ -class OC_DB_StatementWrapper { - /** - * @var \Doctrine\DBAL\Driver\Statement - */ - private $statement = null; - private $isManipulation = false; - private $lastArguments = array(); - - /** - * @param boolean $isManipulation - */ - public function __construct($statement, $isManipulation) { - $this->statement = $statement; - $this->isManipulation = $isManipulation; - } - - /** - * pass all other function directly to the \Doctrine\DBAL\Driver\Statement - */ - public function __call($name,$arguments) { - return call_user_func_array(array($this->statement,$name), $arguments); - } - - /** - * make execute return the result instead of a bool - * - * @param array $input - * @return \OC_DB_StatementWrapper|int - */ - public function execute($input=array()) { - if(\OC::$server->getSystemConfig()->getValue( "log_query", false)) { - $params_str = str_replace("\n", " ", var_export($input, true)); - \OCP\Util::writeLog('core', 'DB execute with arguments : '.$params_str, \OCP\Util::DEBUG); - } - $this->lastArguments = $input; - if (count($input) > 0) { - $result = $this->statement->execute($input); - } else { - $result = $this->statement->execute(); - } - - if ($result === false) { - return false; - } - if ($this->isManipulation) { - $count = $this->statement->rowCount(); - return $count; - } else { - return $this; - } - } - - /** - * provide an alias for fetch - * - * @return mixed - */ - public function fetchRow() { - return $this->statement->fetch(); - } - - /** - * Provide a simple fetchOne. - * - * fetch single column from the next row - * @param int $column the column number to fetch - * @return string - */ - public function fetchOne($column = 0) { - return $this->statement->fetchColumn($column); - } - - /** - * Binds a PHP variable to a corresponding named or question mark placeholder in the - * SQL statement that was use to prepare the statement. - * - * @param mixed $column Either the placeholder name or the 1-indexed placeholder index - * @param mixed $variable The variable to bind - * @param integer|null $type one of the PDO::PARAM_* constants - * @param integer|null $length max length when using an OUT bind - * @return boolean - */ - public function bindParam($column, &$variable, $type = null, $length = null){ - return $this->statement->bindParam($column, $variable, $type, $length); - } -} |