From c90c292629ed18245e3e2ff1bbe11bb118eb12af Mon Sep 17 00:00:00 2001 From: Dmitry Khomutov Date: Sun, 29 Jan 2017 09:49:43 +0700 Subject: [PATCH] Improved DB + PostgreSQL support --- app/config.example.yml | 10 ++-- src/B8Framework/Database.php | 40 ++++++++++----- src/B8Framework/Store.php | 32 ++++++------ src/PHPCensor/Command/InstallCommand.php | 50 ++++++++++++++++--- src/PHPCensor/Console/Application.php | 5 +- .../20140730143702_fix_database_columns.php | 12 ----- .../20150131075425_archive_project.php | 2 +- .../20150203105015_fix_column_types.php | 5 +- .../20150308074509_add_user_providers.php | 5 +- .../20151008140800_add_project_groups.php | 8 +-- ...0151009100610_remove_unique_name_index.php | 4 +- .../20151014091859_errors_table.php | 3 +- .../20160623100223_project_table_defaults.php | 8 +-- src/PHPCensor/Plugin/Codeception.php | 1 - .../Store/Base/BuildErrorStoreBase.php | 8 +-- .../Store/Base/BuildMetaStoreBase.php | 12 ++--- src/PHPCensor/Store/Base/BuildStoreBase.php | 12 ++--- .../Store/Base/ProjectGroupStoreBase.php | 4 +- src/PHPCensor/Store/Base/ProjectStoreBase.php | 12 ++--- src/PHPCensor/Store/Base/UserStoreBase.php | 17 +++---- src/PHPCensor/Store/BuildErrorStore.php | 11 ++-- src/PHPCensor/Store/BuildMetaStore.php | 8 +-- src/PHPCensor/Store/BuildStore.php | 30 +++++------ src/PHPCensor/Store/ProjectStore.php | 12 ++--- tests/B8Framework/DatabaseTest.php | 18 +++++-- .../PHPCensor/Command/InstallCommandTest.php | 4 +- 26 files changed, 186 insertions(+), 147 deletions(-) diff --git a/app/config.example.yml b/app/config.example.yml index c7c05952..48e920eb 100644 --- a/app/config.example.yml +++ b/app/config.example.yml @@ -1,9 +1,13 @@ b8: database: servers: - read: localhost - write: localhost - port: 3306 + read: + - host: localhost + port: 3306 + write: + - host: localhost + port: 3306 + type: mysql name: php-censor-db username: php-censor-user password: php-censor-password diff --git a/src/B8Framework/Database.php b/src/B8Framework/Database.php index 07f5cd9a..f11b61b8 100644 --- a/src/B8Framework/Database.php +++ b/src/B8Framework/Database.php @@ -17,9 +17,11 @@ class Database extends \PDO self::$servers['read'] = $settings['servers']['read']; self::$servers['write'] = $settings['servers']['write']; + self::$details['type'] = $settings['type']; self::$details['db'] = $settings['name']; self::$details['user'] = $settings['username']; self::$details['pass'] = $settings['password']; + self::$initialised = true; } @@ -42,14 +44,9 @@ class Database extends \PDO } if (is_null(self::$connections[$type])) { - if (is_array(self::$servers[$type])) { - // Shuffle, so we pick a random server: - $servers = self::$servers[$type]; - shuffle($servers); - } else { - // Only one server was specified - $servers = [self::$servers[$type]]; - } + // Shuffle, so we pick a random server: + $servers = self::$servers[$type]; + shuffle($servers); $connection = null; @@ -58,14 +55,16 @@ class Database extends \PDO // Pull the next server: $server = array_shift($servers); - if (stristr($server, ':')) { - list($host, $port) = explode(':', $server); - $server = $host . ';port=' . $port; + $dns = self::$details['type'] . ':host=' . $server['host']; + if (isset($server['port'])) { + $dns .= ';port=' . $server['port']; } + $dns .= ';dbname=' . self::$details['db']; // Try to connect: try { - $connection = new self('mysql:host=' . $server . ';dbname=' . self::$details['db'], + $connection = new self( + $dns, self::$details['user'], self::$details['pass'], [ @@ -73,7 +72,8 @@ class Database extends \PDO \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, \PDO::ATTR_TIMEOUT => 2, \PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'', - ]); + ] + ); } catch (\PDOException $ex) { $connection = false; } @@ -107,4 +107,18 @@ class Database extends \PDO self::$lastUsed = ['read' => null, 'write' => null]; self::$initialised = false; } + + public function prepareCommon($statement, array $driver_options = []) + { + $quote = ''; + if ('mysql' === self::$details['type']) { + $quote = '`'; + } elseif ('pgsql' === self::$details['type']) { + $quote = '"'; + } + + $statement = preg_replace('/{{(.*?)}}/', ($quote . '\1' . $quote), $statement); + + return parent::prepare($statement, $driver_options); + } } diff --git a/src/B8Framework/Store.php b/src/B8Framework/Store.php index f2542645..f14ed532 100644 --- a/src/B8Framework/Store.php +++ b/src/B8Framework/Store.php @@ -27,8 +27,8 @@ abstract class Store $manualWheres = [], $whereType = 'AND' ) { - $query = 'SELECT ' . $this->tableName . '.* FROM ' . $this->tableName; - $countQuery = 'SELECT COUNT(*) AS cnt FROM ' . $this->tableName; + $query = 'SELECT * FROM {{' . $this->tableName . '}}'; + $countQuery = 'SELECT COUNT(*) AS {{count}} FROM {{' . $this->tableName . '}}'; $wheres = []; $params = []; @@ -70,7 +70,7 @@ abstract class Store } } else { $params[] = $item; - $ors[] = $this->fieldCheck($key) . ' ' . $value['operator'] . ' ?'; + $ors[] = $key . ' ' . $value['operator'] . ' ?'; } } $wheres[] = '(' . implode(' OR ', $ors) . ')'; @@ -98,16 +98,15 @@ abstract class Store } } } else { - $wheres[] = $key . ' IN (' . implode(', ', - array_map([Database::getConnection('read'), 'quote'], $value)) . ')'; + $wheres[] = $key . ' IN (' . implode(', ', array_map([Database::getConnection('read'), 'quote'], $value)) . ')'; } } } if (count($joins)) { foreach ($joins as $table => $join) { - $query .= ' LEFT JOIN ' . $table . ' ' . $join['alias'] . ' ON ' . $join['on'] . ' '; - $countQuery .= ' LEFT JOIN ' . $table . ' ' . $join['alias'] . ' ON ' . $join['on'] . ' '; + $query .= ' LEFT JOIN {{' . $table . '}} AS ' . $join['alias'] . ' ON ' . $join['on'] . ' '; + $countQuery .= ' LEFT JOIN {{' . $table . '}} AS ' . $join['alias'] . ' ON ' . $join['on'] . ' '; } } @@ -173,16 +172,16 @@ abstract class Store } try { - $stmt = Database::getConnection('read')->prepare($countQuery); + $stmt = Database::getConnection('read')->prepareCommon($countQuery); $stmt->execute($params); $res = $stmt->fetch(\PDO::FETCH_ASSOC); - $count = (int)$res['cnt']; + $count = (int)$res['count']; } catch (\PDOException $ex) { $count = 0; } try { - $stmt = Database::getConnection('read')->prepare($query); + $stmt = Database::getConnection('read')->prepareCommon($query); $stmt->execute($params); $res = $stmt->fetchAll(\PDO::FETCH_ASSOC); $rtn = []; @@ -232,8 +231,8 @@ abstract class Store } if (count($updates)) { - $qs = 'UPDATE ' . $this->tableName . ' SET ' . implode(', ', $updates) . ' WHERE ' . $this->primaryKey . ' = :primaryKey'; - $q = Database::getConnection('write')->prepare($qs); + $qs = 'UPDATE {{' . $this->tableName . '}} SET ' . implode(', ', $updates) . ' WHERE {{' . $this->primaryKey . '}} = :primaryKey'; + $q = Database::getConnection('write')->prepareCommon($qs); foreach ($update_params as $update_param) { $q->bindValue(':' . $update_param[0], $update_param[1]); @@ -266,9 +265,9 @@ abstract class Store } if (count($cols)) { - $qs = 'INSERT INTO ' . $this->tableName . ' (' . implode(', ', $cols) . ') VALUES (' . implode(', ', + $qs = 'INSERT INTO {{' . $this->tableName . '}} (' . implode(', ', $cols) . ') VALUES (' . implode(', ', $values) . ')'; - $q = Database::getConnection('write')->prepare($qs); + $q = Database::getConnection('write')->prepareCommon($qs); if ($q->execute($qParams)) { $id = !empty($data[$this->primaryKey]) ? $data[$this->primaryKey] : Database::getConnection('write')->lastInsertId(); @@ -291,16 +290,13 @@ abstract class Store $data = $obj->getDataArray(); - $q = Database::getConnection('write')->prepare('DELETE FROM ' . $this->tableName . ' WHERE ' . $this->primaryKey . ' = :primaryKey'); + $q = Database::getConnection('write')->prepareCommon('DELETE FROM {{' . $this->tableName . '}} WHERE {{' . $this->primaryKey . '}} = :primaryKey'); $q->bindValue(':primaryKey', $data[$this->primaryKey]); $q->execute(); return true; } - /** - * - */ protected function fieldCheck($field) { if (empty($field)) { diff --git a/src/PHPCensor/Command/InstallCommand.php b/src/PHPCensor/Command/InstallCommand.php index 8bbfbbd3..7c3c728a 100644 --- a/src/PHPCensor/Command/InstallCommand.php +++ b/src/PHPCensor/Command/InstallCommand.php @@ -15,6 +15,7 @@ use PDO; use b8\Config; use b8\Store\Factory; use PHPCensor\Helper\Lang; +use PHPCensor\Model\ProjectGroup; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputInterface; @@ -43,6 +44,7 @@ class InstallCommand extends Command $this ->setName('php-censor:install') ->addOption('url', null, InputOption::VALUE_OPTIONAL, Lang::get('installation_url')) + ->addOption('db-type', null, InputOption::VALUE_OPTIONAL, Lang::get('db_host')) ->addOption('db-host', null, InputOption::VALUE_OPTIONAL, Lang::get('db_host')) ->addOption('db-port', null, InputOption::VALUE_OPTIONAL, Lang::get('db_port')) ->addOption('db-name', null, InputOption::VALUE_OPTIONAL, Lang::get('db_name')) @@ -104,8 +106,11 @@ class InstallCommand extends Command $this->writeConfigFile($conf); $this->setupDatabase($output); + $admin = $this->getAdminInformation($input, $output); $this->createAdminUser($admin, $output); + + $this->createDefaultGroup($output); } /** @@ -127,7 +132,7 @@ class InstallCommand extends Command } // Check required extensions are present: - $requiredExtensions = ['PDO', 'pdo_mysql']; + $requiredExtensions = ['PDO']; foreach ($requiredExtensions as $extension) { if (!extension_loaded($extension)) { @@ -300,6 +305,11 @@ class InstallCommand extends Command /** @var $helper QuestionHelper */ $helper = $this->getHelperSet()->get('question'); + if (!$dbType = $input->getOption('db-type')) { + $questionType = new Question(Lang::get('enter_db_type'), 'mysql'); + $dbType = $helper->ask($input, $output, $questionType); + } + if (!$dbHost = $input->getOption('db-host')) { $questionHost = new Question(Lang::get('enter_db_host'), 'localhost'); $dbHost = $helper->ask($input, $output, $questionHost); @@ -327,12 +337,18 @@ class InstallCommand extends Command $dbPass = $helper->ask($input, $output, $questionPass); } - $db['servers']['read'] = $dbHost; - $db['servers']['write'] = $dbHost; - $db['port'] = $dbPort; - $db['name'] = $dbName; - $db['username'] = $dbUser; - $db['password'] = $dbPass; + $db['servers']['read'] = [[ + 'host' => $dbHost, + 'port' => $dbPort, + ]]; + $db['servers']['write'] = [[ + 'host' => $dbHost, + 'port' => $dbPort, + ]]; + $db['type'] = $dbType; + $db['name'] = $dbName; + $db['username'] = $dbUser; + $db['password'] = $dbPass; return $db; } @@ -347,7 +363,7 @@ class InstallCommand extends Command { try { $pdo = new PDO( - 'mysql:host='.$db['servers']['write'].';port='.$db['port'].'dbname='.$db['name'], + $db['type'] . ':host=' . $db['servers']['write'][0]['host'] . ';port=' . $db['servers']['write'][0]['host'] . 'dbname=' . $db['name'], $db['username'], $db['password'], [ @@ -413,6 +429,24 @@ class InstallCommand extends Command } } + /** + * @param OutputInterface $output + */ + protected function createDefaultGroup($output) + { + try { + $group = new ProjectGroup(); + $group->setTitle('Projects'); + + Factory::getStore('ProjectGroup')->save($group); + + $output->writeln(''.Lang::get('default_group_created').''); + } catch (\Exception $ex) { + $output->writeln(''.Lang::get('default_group_failed_to_create').''); + $output->writeln('' . $ex->getMessage() . ''); + } + } + protected function reloadConfig() { $config = Config::getInstance(); diff --git a/src/PHPCensor/Console/Application.php b/src/PHPCensor/Console/Application.php index 5df1c378..6e2e409f 100644 --- a/src/PHPCensor/Console/Application.php +++ b/src/PHPCensor/Console/Application.php @@ -33,8 +33,9 @@ class Application extends BaseApplication 'default_migration_table' => 'migration', 'default_database' => 'php-censor', 'php-censor' => [ - 'adapter' => 'mysql', - 'host' => $databaseSettings['servers']['write'], + 'adapter' => $databaseSettings['type'], + 'host' => $databaseSettings['servers']['write'][0]['host'], + 'port' => $databaseSettings['servers']['write'][0]['port'], 'name' => $databaseSettings['name'], 'user' => $databaseSettings['username'], 'pass' => $databaseSettings['password'], diff --git a/src/PHPCensor/Migrations/20140730143702_fix_database_columns.php b/src/PHPCensor/Migrations/20140730143702_fix_database_columns.php index 9a65c367..11b3540d 100644 --- a/src/PHPCensor/Migrations/20140730143702_fix_database_columns.php +++ b/src/PHPCensor/Migrations/20140730143702_fix_database_columns.php @@ -6,13 +6,6 @@ class FixDatabaseColumns extends AbstractMigration { public function up() { - $dbAdapter = $this->getAdapter(); - - if ($dbAdapter instanceof \Phinx\Db\Adapter\PdoAdapter) { - $pdo = $dbAdapter->getConnection(); - $pdo->exec('SET foreign_key_checks = 0'); - } - $build = $this->table('build'); $build->changeColumn('project_id', 'integer', ['null' => false]); @@ -53,11 +46,6 @@ class FixDatabaseColumns extends AbstractMigration $user->changeColumn('hash', 'string', ['limit' => 250, 'null' => false]); $user->changeColumn('is_admin', 'integer', ['null' => false, 'default' => 0]); $user->changeColumn('name', 'string', ['limit' => 250, 'null' => false]); - - if ($dbAdapter instanceof \Phinx\Db\Adapter\PdoAdapter) { - $pdo = $dbAdapter->getConnection(); - $pdo->exec('SET foreign_key_checks = 1'); - } } public function down() diff --git a/src/PHPCensor/Migrations/20150131075425_archive_project.php b/src/PHPCensor/Migrations/20150131075425_archive_project.php index 3da41cc8..4d8bbfe3 100644 --- a/src/PHPCensor/Migrations/20150131075425_archive_project.php +++ b/src/PHPCensor/Migrations/20150131075425_archive_project.php @@ -9,7 +9,7 @@ class ArchiveProject extends AbstractMigration $project = $this->table('project'); if (!$project->hasColumn('archived')) { - $project->addColumn('archived', 'boolean', ['default' => 0])->save(); + $project->addColumn('archived', 'boolean', ['default' => false])->save(); } } diff --git a/src/PHPCensor/Migrations/20150203105015_fix_column_types.php b/src/PHPCensor/Migrations/20150203105015_fix_column_types.php index 0387b066..f13442b5 100644 --- a/src/PHPCensor/Migrations/20150203105015_fix_column_types.php +++ b/src/PHPCensor/Migrations/20150203105015_fix_column_types.php @@ -1,7 +1,6 @@ table('build'); - $build->changeColumn('log', 'text', ['null' => true, 'limit' => MysqlAdapter::TEXT_MEDIUM]); + $build->changeColumn('log', 'text', ['null' => true]); $buildMeta = $this->table('build_meta'); - $buildMeta->changeColumn('meta_value', 'text', ['null' => false, 'limit' => MysqlAdapter::TEXT_MEDIUM]); + $buildMeta->changeColumn('meta_value', 'text', ['null' => false]); } public function down() diff --git a/src/PHPCensor/Migrations/20150308074509_add_user_providers.php b/src/PHPCensor/Migrations/20150308074509_add_user_providers.php index a01c626b..f9b52012 100644 --- a/src/PHPCensor/Migrations/20150308074509_add_user_providers.php +++ b/src/PHPCensor/Migrations/20150308074509_add_user_providers.php @@ -1,6 +1,5 @@ addColumn('provider_key', 'string', [ 'default' => 'internal', - 'limit' => MysqlAdapter::TEXT_SMALL + 'limit' => 255 ]) // A data used by the provider ->addColumn('provider_data', 'string', [ 'null' => true, - 'limit' => MysqlAdapter::TEXT_SMALL + 'limit' => 255 ]) ->save(); } diff --git a/src/PHPCensor/Migrations/20151008140800_add_project_groups.php b/src/PHPCensor/Migrations/20151008140800_add_project_groups.php index 1751202b..6cafa6b2 100644 --- a/src/PHPCensor/Migrations/20151008140800_add_project_groups.php +++ b/src/PHPCensor/Migrations/20151008140800_add_project_groups.php @@ -13,12 +13,14 @@ class AddProjectGroups extends AbstractMigration } if (!$table->hasColumn('title')) { - $table->addColumn('title', 'string', ['limit' => 100, 'null' => false])->save(); + $table + ->addColumn('title', 'string', ['limit' => 100, 'null' => false]) + ->save(); - $group = new \PHPCensor\Model\ProjectGroup(); +/* $group = new \PHPCensor\Model\ProjectGroup(); $group->setTitle('Projects'); - \b8\Store\Factory::getStore('ProjectGroup')->save($group); + \b8\Store\Factory::getStore('ProjectGroup')->save($group);*/ } $table = $this->table('project'); diff --git a/src/PHPCensor/Migrations/20151009100610_remove_unique_name_index.php b/src/PHPCensor/Migrations/20151009100610_remove_unique_name_index.php index 764debe4..72c56a8a 100644 --- a/src/PHPCensor/Migrations/20151009100610_remove_unique_name_index.php +++ b/src/PHPCensor/Migrations/20151009100610_remove_unique_name_index.php @@ -9,11 +9,11 @@ class RemoveUniqueNameIndex extends AbstractMigration $user = $this->table('user'); if ($user->hasIndex('name', ['unique' => true])) { - $user->removeIndex('name', ['unique' => true])->save(); + $user->removeIndex(['name'], ['unique' => true])->save(); } if (!$user->hasIndex('name', ['unique' => true])) { - $user->addIndex('name', ['unique' => false])->save(); + $user->addIndex(['name'], ['unique' => false])->save(); } } } diff --git a/src/PHPCensor/Migrations/20151014091859_errors_table.php b/src/PHPCensor/Migrations/20151014091859_errors_table.php index d383e396..6a8922d6 100644 --- a/src/PHPCensor/Migrations/20151014091859_errors_table.php +++ b/src/PHPCensor/Migrations/20151014091859_errors_table.php @@ -1,7 +1,6 @@ hasColumn('severity')) { - $table->addColumn('severity', 'integer', ['signed' => false, 'limit' => MysqlAdapter::INT_TINY])->save(); + $table->addColumn('severity', 'integer', ['signed' => false, 'limit' => 255])->save(); } if (!$table->hasColumn('message')) { diff --git a/src/PHPCensor/Migrations/20160623100223_project_table_defaults.php b/src/PHPCensor/Migrations/20160623100223_project_table_defaults.php index 5b2f88d0..a25b9937 100644 --- a/src/PHPCensor/Migrations/20160623100223_project_table_defaults.php +++ b/src/PHPCensor/Migrations/20160623100223_project_table_defaults.php @@ -1,17 +1,13 @@ table('project') - ->changeColumn('build_config', MysqlAdapter::PHINX_TYPE_TEXT, ['null' => true]) - ->changeColumn('archived', MysqlAdapter::PHINX_TYPE_INTEGER, [ - 'length' => MysqlAdapter::INT_TINY, - 'default' => 0, - ])->save(); + ->changeColumn('build_config', 'text', ['null' => true]) + ->save(); } } diff --git a/src/PHPCensor/Plugin/Codeception.php b/src/PHPCensor/Plugin/Codeception.php index a0fec023..c4cf0d5e 100644 --- a/src/PHPCensor/Plugin/Codeception.php +++ b/src/PHPCensor/Plugin/Codeception.php @@ -16,7 +16,6 @@ use PHPCensor\Plugin\Util\TestResultParsers\Codeception as Parser; use PHPCensor\Plugin; use Symfony\Component\Yaml\Parser as YamlParser; use PHPCensor\ZeroConfigPluginInterface; -use Psr\Log\LogLevel; /** * Codeception Plugin - Enables full acceptance, unit, and functional testing. diff --git a/src/PHPCensor/Store/Base/BuildErrorStoreBase.php b/src/PHPCensor/Store/Base/BuildErrorStoreBase.php index 308a77bc..2bc31f9b 100644 --- a/src/PHPCensor/Store/Base/BuildErrorStoreBase.php +++ b/src/PHPCensor/Store/Base/BuildErrorStoreBase.php @@ -38,8 +38,8 @@ class BuildErrorStoreBase extends Store throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $query = 'SELECT * FROM `build_error` WHERE `id` = :id LIMIT 1'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{build_error}} WHERE {{id}} = :id LIMIT 1'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':id', $value); if ($stmt->execute()) { @@ -62,8 +62,8 @@ class BuildErrorStoreBase extends Store } - $query = 'SELECT * FROM `build_error` WHERE `build_id` = :build_id LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{build_error}} WHERE {{build_id}} = :build_id LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':build_id', $value); $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); diff --git a/src/PHPCensor/Store/Base/BuildMetaStoreBase.php b/src/PHPCensor/Store/Base/BuildMetaStoreBase.php index 5ab7d829..6410732b 100644 --- a/src/PHPCensor/Store/Base/BuildMetaStoreBase.php +++ b/src/PHPCensor/Store/Base/BuildMetaStoreBase.php @@ -38,8 +38,8 @@ class BuildMetaStoreBase extends Store throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $query = 'SELECT * FROM `build_meta` WHERE `id` = :id LIMIT 1'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{build_meta}} WHERE {{id}} = :id LIMIT 1'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':id', $value); if ($stmt->execute()) { @@ -62,8 +62,8 @@ class BuildMetaStoreBase extends Store } - $query = 'SELECT * FROM `build_meta` WHERE `project_id` = :project_id LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{build_meta}} WHERE {{project_id}} = :project_id LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':project_id', $value); $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); @@ -94,8 +94,8 @@ class BuildMetaStoreBase extends Store } - $query = 'SELECT * FROM `build_meta` WHERE `build_id` = :build_id LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{build_meta}} WHERE {{build_id}} = :build_id LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':build_id', $value); $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); diff --git a/src/PHPCensor/Store/Base/BuildStoreBase.php b/src/PHPCensor/Store/Base/BuildStoreBase.php index 6d0941ac..442c79eb 100644 --- a/src/PHPCensor/Store/Base/BuildStoreBase.php +++ b/src/PHPCensor/Store/Base/BuildStoreBase.php @@ -38,8 +38,8 @@ class BuildStoreBase extends Store throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $query = 'SELECT * FROM `build` WHERE `id` = :id LIMIT 1'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{build}} WHERE {{id}} = :id LIMIT 1'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':id', $value); if ($stmt->execute()) { @@ -62,8 +62,8 @@ class BuildStoreBase extends Store } - $query = 'SELECT * FROM `build` WHERE `project_id` = :project_id LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{build}} WHERE {{project_id}} = :project_id LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':project_id', $value); $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); @@ -94,8 +94,8 @@ class BuildStoreBase extends Store } - $query = 'SELECT * FROM `build` WHERE `status` = :status LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{build}} WHERE {{status}} = :status LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':status', $value); $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); diff --git a/src/PHPCensor/Store/Base/ProjectGroupStoreBase.php b/src/PHPCensor/Store/Base/ProjectGroupStoreBase.php index 10ffd7df..c4c2b393 100644 --- a/src/PHPCensor/Store/Base/ProjectGroupStoreBase.php +++ b/src/PHPCensor/Store/Base/ProjectGroupStoreBase.php @@ -38,8 +38,8 @@ class ProjectGroupStoreBase extends Store throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $query = 'SELECT * FROM `project_group` WHERE `id` = :id LIMIT 1'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{project_group}} WHERE {{id}} = :id LIMIT 1'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':id', $value); if ($stmt->execute()) { diff --git a/src/PHPCensor/Store/Base/ProjectStoreBase.php b/src/PHPCensor/Store/Base/ProjectStoreBase.php index cf310548..50992bfb 100644 --- a/src/PHPCensor/Store/Base/ProjectStoreBase.php +++ b/src/PHPCensor/Store/Base/ProjectStoreBase.php @@ -38,8 +38,8 @@ class ProjectStoreBase extends Store throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $query = 'SELECT * FROM `project` WHERE `id` = :id LIMIT 1'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{project}} WHERE {{id}} = :id LIMIT 1'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':id', $value); if ($stmt->execute()) { @@ -62,8 +62,8 @@ class ProjectStoreBase extends Store } - $query = 'SELECT * FROM `project` WHERE `title` = :title LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{project}} WHERE {{title}} = :title LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':title', $value); $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); @@ -94,8 +94,8 @@ class ProjectStoreBase extends Store } - $query = 'SELECT * FROM `project` WHERE `group_id` = :group_id LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{project}} WHERE {{group_id}} = :group_id LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':group_id', $value); $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); diff --git a/src/PHPCensor/Store/Base/UserStoreBase.php b/src/PHPCensor/Store/Base/UserStoreBase.php index fee5fe24..edbbb507 100644 --- a/src/PHPCensor/Store/Base/UserStoreBase.php +++ b/src/PHPCensor/Store/Base/UserStoreBase.php @@ -38,8 +38,8 @@ class UserStoreBase extends Store throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $query = 'SELECT * FROM `user` WHERE `id` = :id LIMIT 1'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{user}} WHERE {{id}} = :id LIMIT 1'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':id', $value); if ($stmt->execute()) { @@ -67,8 +67,8 @@ class UserStoreBase extends Store throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $query = 'SELECT * FROM `user` WHERE `email` = :email LIMIT 1'; - $stmt = Database::getConnection()->prepare($query); + $query = 'SELECT * FROM {{user}} WHERE {{email}} = :email LIMIT 1'; + $stmt = Database::getConnection()->prepareCommon($query); $stmt->bindValue(':email', $value); if ($stmt->execute()) { @@ -96,8 +96,8 @@ class UserStoreBase extends Store throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - $query = 'SELECT * FROM `user` WHERE `email` = :value OR `name` = :value LIMIT 1'; - $stmt = Database::getConnection()->prepare($query); + $query = 'SELECT * FROM {{user}} WHERE {{email}} = :value OR {{name}} = :value LIMIT 1'; + $stmt = Database::getConnection()->prepareCommon($query); $stmt->bindValue(':value', $value); if ($stmt->execute()) { @@ -119,9 +119,8 @@ class UserStoreBase extends Store throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.'); } - - $query = 'SELECT * FROM `user` WHERE `name` = :name LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{user}} WHERE {{name}} = :name LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':name', $value); $stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT); diff --git a/src/PHPCensor/Store/BuildErrorStore.php b/src/PHPCensor/Store/BuildErrorStore.php index 963b5e0b..5e937382 100644 --- a/src/PHPCensor/Store/BuildErrorStore.php +++ b/src/PHPCensor/Store/BuildErrorStore.php @@ -24,8 +24,7 @@ class BuildErrorStore extends BuildErrorStoreBase */ public function getErrorsForBuild($buildId, $since = null) { - $query = 'SELECT * FROM build_error - WHERE build_id = :build'; + $query = 'SELECT * FROM {{build_error}} WHERE {{build_id}} = :build'; if (!is_null($since)) { $query .= ' AND created_date > :since'; @@ -33,7 +32,7 @@ class BuildErrorStore extends BuildErrorStoreBase $query .= ' LIMIT 15000'; - $stmt = Database::getConnection('read')->prepare($query); + $stmt = Database::getConnection('read')->prepareCommon($query); $stmt->bindValue(':build', $buildId, \PDO::PARAM_INT); @@ -63,10 +62,10 @@ class BuildErrorStore extends BuildErrorStoreBase */ public function getErrorTotalForBuild($buildId) { - $query = 'SELECT COUNT(*) AS total FROM build_error - WHERE build_id = :build'; + $query = 'SELECT COUNT(*) AS {{total}} FROM {{build_error}} + WHERE {{build_id}} = :build'; - $stmt = Database::getConnection('read')->prepare($query); + $stmt = Database::getConnection('read')->prepareCommon($query); $stmt->bindValue(':build', $buildId, \PDO::PARAM_INT); diff --git a/src/PHPCensor/Store/BuildMetaStore.php b/src/PHPCensor/Store/BuildMetaStore.php index 79a65294..269f726d 100644 --- a/src/PHPCensor/Store/BuildMetaStore.php +++ b/src/PHPCensor/Store/BuildMetaStore.php @@ -28,11 +28,11 @@ class BuildMetaStore extends BuildMetaStoreBase */ public function getErrorsForUpgrade($limit) { - $query = 'SELECT * FROM build_meta - WHERE meta_key IN (\'phpmd-data\', \'phpcs-data\', \'phpdoccheck-data\', \'technical_debt - data\') - ORDER BY id ASC LIMIT :limit'; + $query = 'SELECT * FROM {{build_meta}} + WHERE {{meta_key}} IN (\'phpmd-data\', \'phpcs-data\', \'phpdoccheck-data\', \'technical_debt - data\') + ORDER BY {{id}} ASC LIMIT :limit'; - $stmt = Database::getConnection('read')->prepare($query); + $stmt = Database::getConnection('read')->prepareCommon($query); $stmt->bindValue(':limit', $limit, \PDO::PARAM_INT); diff --git a/src/PHPCensor/Store/BuildStore.php b/src/PHPCensor/Store/BuildStore.php index f3d5284a..246ab902 100644 --- a/src/PHPCensor/Store/BuildStore.php +++ b/src/PHPCensor/Store/BuildStore.php @@ -30,12 +30,12 @@ class BuildStore extends BuildStoreBase public function getLatestBuilds($projectId = null, $limit = 5) { if (!is_null($projectId)) { - $query = 'SELECT * FROM build WHERE `project_id` = :pid ORDER BY id DESC LIMIT :limit'; + $query = 'SELECT * FROM {{build}} WHERE {{project_id}} = :pid ORDER BY {{id}} DESC LIMIT :limit'; } else { - $query = 'SELECT * FROM build ORDER BY id DESC LIMIT :limit'; + $query = 'SELECT * FROM {{build}} ORDER BY {{id}} DESC LIMIT :limit'; } - $stmt = Database::getConnection('read')->prepare($query); + $stmt = Database::getConnection('read')->prepareCommon($query); if (!is_null($projectId)) { $stmt->bindValue(':pid', $projectId); @@ -65,8 +65,8 @@ class BuildStore extends BuildStoreBase */ public function getLastBuildByStatus($projectId = null, $status = Build::STATUS_SUCCESS) { - $query = 'SELECT * FROM build WHERE project_id = :pid AND status = :status ORDER BY id DESC LIMIT 1'; - $stmt = Database::getConnection('read')->prepare($query); + $query = 'SELECT * FROM {{build}} WHERE {{project_id}} = :pid AND {{status}} = :status ORDER BY {{id}} DESC LIMIT 1'; + $stmt = Database::getConnection('read')->prepareCommon($query); $stmt->bindValue(':pid', $projectId); $stmt->bindValue(':status', $status); @@ -87,8 +87,8 @@ class BuildStore extends BuildStoreBase */ public function getByProjectAndCommit($projectId, $commitId) { - $query = 'SELECT * FROM `build` WHERE `project_id` = :project_id AND `commit_id` = :commit_id'; - $stmt = Database::getConnection('read')->prepare($query); + $query = 'SELECT * FROM {{build}} WHERE {{project_id}} = :project_id AND {{commit_id}} = :commit_id'; + $stmt = Database::getConnection('read')->prepareCommon($query); $stmt->bindValue(':project_id', $projectId); $stmt->bindValue(':commit_id', $commitId); @@ -116,8 +116,8 @@ class BuildStore extends BuildStoreBase */ public function getBuildBranches($projectId) { - $query = 'SELECT DISTINCT `branch` FROM `build` WHERE `project_id` = :project_id'; - $stmt = Database::getConnection('read')->prepare($query); + $query = 'SELECT DISTINCT {{branch}} FROM {{build}} WHERE {{project_id}} = :project_id'; + $stmt = Database::getConnection('read')->prepareCommon($query); $stmt->bindValue(':project_id', $projectId); if ($stmt->execute()) { @@ -140,8 +140,8 @@ class BuildStore extends BuildStoreBase public function getMeta($key, $projectId, $buildId = null, $branch = null, $numResults = 1) { $query = 'SELECT bm.build_id, bm.meta_key, bm.meta_value - FROM build_meta AS bm - LEFT JOIN build b ON b.id = bm.build_id + FROM {{build_meta}} AS {{bm}} + LEFT JOIN {{build}} AS {{b}} ON b.id = bm.build_id WHERE bm.meta_key = :key AND bm.project_id = :projectId'; @@ -160,7 +160,7 @@ class BuildStore extends BuildStoreBase $query .= ' ORDER BY bm.id DESC LIMIT :numResults'; - $stmt = Database::getConnection('read')->prepare($query); + $stmt = Database::getConnection('read')->prepareCommon($query); $stmt->bindValue(':key', $key, \PDO::PARAM_STR); $stmt->bindValue(':projectId', (int)$projectId, \PDO::PARAM_INT); $stmt->bindValue(':buildId', (int)$buildId, \PDO::PARAM_INT); @@ -199,10 +199,10 @@ class BuildStore extends BuildStoreBase */ public function setMeta($projectId, $buildId, $key, $value) { - $cols = '`project_id`, `build_id`, `meta_key`, `meta_value`'; - $query = 'REPLACE INTO build_meta ('.$cols.') VALUES (:projectId, :buildId, :key, :value)'; + $cols = '{{project_id}}, {{build_id}}, {{meta_key}}, {{meta_value}}'; + $query = 'INSERT INTO {{build_meta}} ('.$cols.') VALUES (:projectId, :buildId, :key, :value)'; - $stmt = Database::getConnection('read')->prepare($query); + $stmt = Database::getConnection('read')->prepareCommon($query); $stmt->bindValue(':key', $key, \PDO::PARAM_STR); $stmt->bindValue(':projectId', (int)$projectId, \PDO::PARAM_INT); $stmt->bindValue(':buildId', (int)$buildId, \PDO::PARAM_INT); diff --git a/src/PHPCensor/Store/ProjectStore.php b/src/PHPCensor/Store/ProjectStore.php index 03c39f79..fe22bbe2 100644 --- a/src/PHPCensor/Store/ProjectStore.php +++ b/src/PHPCensor/Store/ProjectStore.php @@ -28,8 +28,8 @@ class ProjectStore extends ProjectStoreBase */ public function getKnownBranches($projectId) { - $query = 'SELECT DISTINCT branch from build WHERE project_id = :pid'; - $stmt = Database::getConnection('read')->prepare($query); + $query = 'SELECT DISTINCT {{branch}} from {{build}} WHERE {{project_id}} = :pid'; + $stmt = Database::getConnection('read')->prepareCommon($query); $stmt->bindValue(':pid', $projectId); if ($stmt->execute()) { @@ -57,8 +57,8 @@ class ProjectStore extends ProjectStoreBase { $archived = (integer)$archived; - $query = 'SELECT * FROM `project` WHERE `archived` = :archived ORDER BY `title` ASC'; - $stmt = Database::getConnection('read')->prepare($query); + $query = 'SELECT * FROM {{project}} WHERE {{archived}} = :archived ORDER BY {{title}} ASC'; + $stmt = Database::getConnection('read')->prepareCommon($query); $stmt->bindValue(':archived', $archived); @@ -98,8 +98,8 @@ class ProjectStore extends ProjectStoreBase } $archived = (integer)$archived; - $query = 'SELECT * FROM `project` WHERE `group_id` = :group_id AND `archived` = :archived ORDER BY title LIMIT :limit'; - $stmt = Database::getConnection($useConnection)->prepare($query); + $query = 'SELECT * FROM {{project}} WHERE {{group_id}} = :group_id AND {{archived}} = :archived ORDER BY {{title}} LIMIT :limit'; + $stmt = Database::getConnection($useConnection)->prepareCommon($query); $stmt->bindValue(':group_id', $value); $stmt->bindValue(':archived', $archived); diff --git a/tests/B8Framework/DatabaseTest.php b/tests/B8Framework/DatabaseTest.php index 4d1ea57c..636555e0 100755 --- a/tests/B8Framework/DatabaseTest.php +++ b/tests/B8Framework/DatabaseTest.php @@ -13,9 +13,14 @@ class DatabaseTest extends \PHPUnit_Framework_TestCase 'b8' => [ 'database' => [ 'servers' => [ - 'read' => 'localhost', - 'write' => 'localhost', + 'read' => [ + ['host' => 'localhost'], + ], + 'write' => [ + ['host' => 'localhost'], + ], ], + 'type' => 'mysql', 'name' => 'b8_test', 'username' => 'root', 'password' => 'root', @@ -69,9 +74,14 @@ class DatabaseTest extends \PHPUnit_Framework_TestCase 'b8' => [ 'database' => [ 'servers' => [ - 'read' => 'localhost', - 'write' => 'localhost', + 'read' => [ + ['host' => 'localhost'], + ], + 'write' => [ + ['host' => 'localhost'], + ], ], + 'type' => 'mysql', 'name' => 'b8_test_2', 'username' => '', 'password' => '', diff --git a/tests/PHPCensor/Command/InstallCommandTest.php b/tests/PHPCensor/Command/InstallCommandTest.php index a9e827e4..9c57e920 100644 --- a/tests/PHPCensor/Command/InstallCommandTest.php +++ b/tests/PHPCensor/Command/InstallCommandTest.php @@ -144,8 +144,8 @@ class InstallCommandTest extends \PHPUnit_Framework_TestCase $this->executeWithoutParam('--db-host', $dialog); // Check that specified arguments are correctly loaded. - $this->assertEquals('testedvalue', $this->config['b8']['database']['servers']['read']); - $this->assertEquals('testedvalue', $this->config['b8']['database']['servers']['write']); + $this->assertEquals('testedvalue', $this->config['b8']['database']['servers']['read'][0]['host']); + $this->assertEquals('testedvalue', $this->config['b8']['database']['servers']['write'][0]['host']); } public function testDatabaseNameConfig()