From 41a48ecb70d6eed238cdd37b8b4c8052fe62ebfe Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 27 Mar 2024 11:34:22 +0900 Subject: [PATCH] fix: add SQLSRV\Forge::createDatabase() --- system/Database/SQLSRV/Forge.php | 51 +++++++++++++++++++++++- tests/system/Database/Live/ForgeTest.php | 15 +++---- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/system/Database/SQLSRV/Forge.php b/system/Database/SQLSRV/Forge.php index dc5567433215..cae4eda2a4f5 100755 --- a/system/Database/SQLSRV/Forge.php +++ b/system/Database/SQLSRV/Forge.php @@ -14,7 +14,9 @@ namespace CodeIgniter\Database\SQLSRV; use CodeIgniter\Database\BaseConnection; +use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Database\Forge as BaseForge; +use Throwable; /** * Forge for SQLSRV @@ -42,7 +44,7 @@ class Forge extends BaseForge * * @var string */ - protected $createDatabaseIfStr = "DECLARE @DBName VARCHAR(255) = '%s'\nDECLARE @SQL VARCHAR(max) = 'IF DB_ID( ''' + @DBName + ''' ) IS NULL CREATE DATABASE ' + @DBName\nEXEC( @SQL )"; + protected $createDatabaseIfStr = "DECLARE @DBName VARCHAR(255) = '%s'\nDECLARE @SQL VARCHAR(max) = 'IF DB_ID( ''' + @DBName + ''' ) IS NULL CREATE DATABASE %s'\nEXEC( @SQL )"; /** * CREATE DATABASE IF statement @@ -119,6 +121,53 @@ public function __construct(BaseConnection $db) $this->dropIndexStr = 'DROP INDEX %s ON ' . $this->db->escapeIdentifiers($this->db->schema) . '.%s'; } + /** + * Create database + * + * @param bool $ifNotExists Whether to add IF NOT EXISTS condition + * + * @throws DatabaseException + */ + public function createDatabase(string $dbName, bool $ifNotExists = false): bool + { + if ($ifNotExists) { + $sql = sprintf( + $this->createDatabaseIfStr, + $dbName, + $this->db->escapeIdentifier($dbName) + ); + } else { + $sql = sprintf( + $this->createDatabaseStr, + $this->db->escapeIdentifier($dbName) + ); + } + + try { + if (! $this->db->query($sql)) { + // @codeCoverageIgnoreStart + if ($this->db->DBDebug) { + throw new DatabaseException('Unable to create the specified database.'); + } + + return false; + // @codeCoverageIgnoreEnd + } + + if (isset($this->db->dataCache['db_names'])) { + $this->db->dataCache['db_names'][] = $dbName; + } + + return true; + } catch (Throwable $e) { + if ($this->db->DBDebug) { + throw new DatabaseException('Unable to create the specified database.', 0, $e); + } + + return false; // @codeCoverageIgnore + } + } + /** * CREATE TABLE attributes */ diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php index e7c1e63a5879..cdab38096b1b 100644 --- a/tests/system/Database/Live/ForgeTest.php +++ b/tests/system/Database/Live/ForgeTest.php @@ -155,17 +155,14 @@ public function testDropDatabase(): void public function testCreateDatabaseExceptionNoCreateStatement(): void { - $this->setPrivateProperty($this->forge, 'createDatabaseStr', false); + if ($this->db->DBDriver !== 'OCI8') { + $this->markTestSkipped($this->db->DBDriver . ' does support drop database.'); + } - if ($this->db->DBDriver === 'SQLite3') { - $databaseCreated = $this->forge->createDatabase('test_forge_database'); - $this->assertTrue($databaseCreated); - } else { - $this->expectException(DatabaseException::class); - $this->expectExceptionMessage('This feature is not available for the database you are using.'); + $this->expectException(DatabaseException::class); + $this->expectExceptionMessage('This feature is not available for the database you are using.'); - $this->forge->createDatabase('test_forge_database'); - } + $this->forge->createDatabase('test_forge_database'); } public function testDropDatabaseExceptionNoDropStatement(): void