Skip to content

Commit 59a314a

Browse files
authored
Merge pull request #2100 from oleg1540/check_db_exists
WIP Added validation on exists database before created for MySQLi…
2 parents 4b5d922 + 48b0411 commit 59a314a

6 files changed

Lines changed: 120 additions & 19 deletions

File tree

system/Database/Forge.php

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,20 @@ class Forge
104104
*/
105105
protected $createDatabaseStr = 'CREATE DATABASE %s';
106106

107+
/**
108+
* CREATE DATABASE IF statement
109+
*
110+
* @var string
111+
*/
112+
protected $createDatabaseIfStr = null;
113+
114+
/**
115+
* CHECK DATABASE EXIST statement
116+
*
117+
* @var string
118+
*/
119+
protected $checkDatabaseExistStr = null;
120+
107121
/**
108122
* DROP DATABASE statement
109123
*
@@ -199,13 +213,23 @@ public function getConnection()
199213
/**
200214
* Create database
201215
*
202-
* @param string $db_name
216+
* @param string $dbName
217+
* @param boolean $ifNotExists Whether to add IF NOT EXISTS condition
203218
*
204219
* @return boolean
205220
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
206221
*/
207-
public function createDatabase(string $db_name): bool
222+
public function createDatabase(string $dbName, bool $ifNotExists = false): bool
208223
{
224+
if ($ifNotExists && $this->createDatabaseIfStr === null)
225+
{
226+
if ($this->databaseExists($dbName))
227+
{
228+
return true;
229+
}
230+
$ifNotExists = false;
231+
}
232+
209233
if ($this->createDatabaseStr === false)
210234
{
211235
if ($this->db->DBDebug)
@@ -215,7 +239,7 @@ public function createDatabase(string $db_name): bool
215239

216240
return false;
217241
}
218-
elseif (! $this->db->query(sprintf($this->createDatabaseStr, $db_name, $this->db->charset, $this->db->DBCollat))
242+
elseif (! $this->db->query(sprintf($ifNotExists ? $this->createDatabaseIfStr : $this->createDatabaseStr, $dbName, $this->db->charset, $this->db->DBCollat))
219243
)
220244
{
221245
if ($this->db->DBDebug)
@@ -228,23 +252,48 @@ public function createDatabase(string $db_name): bool
228252

229253
if (! empty($this->db->dataCache['db_names']))
230254
{
231-
$this->db->dataCache['db_names'][] = $db_name;
255+
$this->db->dataCache['db_names'][] = $dbName;
232256
}
233257

234258
return true;
235259
}
236260

237261
//--------------------------------------------------------------------
238262

263+
/**
264+
* Determine if a database exists
265+
*
266+
* @param string $dbName
267+
*
268+
* @return boolean
269+
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
270+
*/
271+
private function databaseExists(string $dbName): bool
272+
{
273+
if ($this->checkDatabaseExistStr === null)
274+
{
275+
if ($this->db->DBDebug)
276+
{
277+
throw new DatabaseException('This feature is not available for the database you are using.');
278+
}
279+
280+
return false;
281+
}
282+
283+
return $this->db->query($this->checkDatabaseExistStr, $dbName)->getRow() !== null;
284+
}
285+
286+
//--------------------------------------------------------------------
287+
239288
/**
240289
* Drop database
241290
*
242-
* @param string $db_name
291+
* @param string $dbName
243292
*
244293
* @return boolean
245294
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
246295
*/
247-
public function dropDatabase(string $db_name): bool
296+
public function dropDatabase(string $dbName): bool
248297
{
249298
if ($this->dropDatabaseStr === false)
250299
{
@@ -255,7 +304,7 @@ public function dropDatabase(string $db_name): bool
255304

256305
return false;
257306
}
258-
elseif (! $this->db->query(sprintf($this->dropDatabaseStr, $db_name)))
307+
elseif (! $this->db->query(sprintf($this->dropDatabaseStr, $dbName)))
259308
{
260309
if ($this->db->DBDebug)
261310
{
@@ -267,7 +316,7 @@ public function dropDatabase(string $db_name): bool
267316

268317
if (! empty($this->db->dataCache['db_names']))
269318
{
270-
$key = array_search(strtolower($db_name), array_map('strtolower', $this->db->dataCache['db_names']), true);
319+
$key = array_search(strtolower($dbName), array_map('strtolower', $this->db->dataCache['db_names']), true);
271320
if ($key !== false)
272321
{
273322
unset($this->db->dataCache['db_names'][$key]);

system/Database/MySQLi/Forge.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ class Forge extends \CodeIgniter\Database\Forge
5151
*/
5252
protected $createDatabaseStr = 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s';
5353

54+
/**
55+
* CREATE DATABASE IF statement
56+
*
57+
* @var string
58+
*/
59+
protected $createDatabaseIfStr = 'CREATE DATABASE IF NOT EXISTS %s CHARACTER SET %s COLLATE %s';
60+
5461
/**
5562
* DROP CONSTRAINT statement
5663
*

system/Database/Postgre/Forge.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@
4444
class Forge extends \CodeIgniter\Database\Forge
4545
{
4646

47+
/**
48+
* CHECK DATABASE EXIST statement
49+
*
50+
* @var string
51+
*/
52+
protected $checkDatabaseExistStr = 'SELECT 1 FROM pg_database WHERE datname = ?';
53+
4754
/**
4855
* DROP CONSTRAINT statement
4956
*
@@ -74,7 +81,7 @@ class Forge extends \CodeIgniter\Database\Forge
7481
* @var string
7582
*/
7683
protected $_null = 'NULL';
77-
84+
7885
//--------------------------------------------------------------------
7986

8087
/**

system/Database/SQLite3/Forge.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,12 @@ public function __construct(ConnectionInterface $db)
8484
/**
8585
* Create database
8686
*
87-
* @param string $db_name
87+
* @param string $dbName
88+
* @param boolean $ifNotExists Whether to add IF NOT EXISTS condition
8889
*
8990
* @return boolean
9091
*/
91-
public function createDatabase(string $db_name): bool
92+
public function createDatabase(string $dbName, bool $ifNotExists = false): bool
9293
{
9394
// In SQLite, a database is created when you connect to the database.
9495
// We'll return TRUE so that an error isn't generated.
@@ -100,15 +101,15 @@ public function createDatabase(string $db_name): bool
100101
/**
101102
* Drop database
102103
*
103-
* @param string $db_name
104+
* @param string $dbName
104105
*
105106
* @return boolean
106107
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
107108
*/
108-
public function dropDatabase(string $db_name): bool
109+
public function dropDatabase(string $dbName): bool
109110
{
110111
// In SQLite, a database is dropped when we delete a file
111-
if (! is_file($db_name))
112+
if (! is_file($dbName))
112113
{
113114
if ($this->db->DBDebug)
114115
{
@@ -120,7 +121,7 @@ public function dropDatabase(string $db_name): bool
120121

121122
// We need to close the pseudo-connection first
122123
$this->db->close();
123-
if (! @unlink($db_name))
124+
if (! @unlink($dbName))
124125
{
125126
if ($this->db->DBDebug)
126127
{
@@ -132,7 +133,7 @@ public function dropDatabase(string $db_name): bool
132133

133134
if (! empty($this->db->dataCache['db_names']))
134135
{
135-
$key = array_search(strtolower($db_name), array_map('strtolower', $this->db->dataCache['db_names']), true);
136+
$key = array_search(strtolower($dbName), array_map('strtolower', $this->db->dataCache['db_names']), true);
136137
if ($key !== false)
137138
{
138139
unset($this->db->dataCache['db_names'][$key]);

tests/system/Database/Live/ForgeTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,33 @@ public function testCreateDatabase()
3030
$this->assertTrue($database_created);
3131
}
3232

33+
public function testCreateDatabaseIfNotExists()
34+
{
35+
$dbName = 'test_forge_database_exist';
36+
37+
$databaseCreateIfNotExists = $this->forge->createDatabase($dbName, true);
38+
if ($this->db->DBDriver !== 'SQLite3')
39+
{
40+
$this->forge->dropDatabase($dbName);
41+
}
42+
43+
$this->assertTrue($databaseCreateIfNotExists);
44+
}
45+
46+
public function testCreateDatabaseIfNotExistsWithDb()
47+
{
48+
$dbName = 'test_forge_database_exist';
49+
50+
$this->forge->createDatabase($dbName);
51+
$databaseExists = $this->forge->createDatabase($dbName, true);
52+
if ($this->db->DBDriver !== 'SQLite3')
53+
{
54+
$this->forge->dropDatabase($dbName);
55+
}
56+
57+
$this->assertTrue($databaseExists);
58+
}
59+
3360
public function testDropDatabase()
3461
{
3562
if ($this->db->DBDriver === 'SQLite3')

user_guide_src/source/dbmgmt/forge.rst

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ Returns TRUE/FALSE based on success or failure::
4141
echo 'Database created!';
4242
}
4343

44+
An optional second parameter set to TRUE will add IF EXISTS statement
45+
or will check if a database exists before create it (depending on DBMS).
46+
47+
::
48+
49+
$forge->createDatabase('my_db', TRUE);
50+
// gives CREATE DATABASE IF NOT EXISTS my_db
51+
// or will check if a database exists
52+
4453
**$forge->dropDatabase('db_name')**
4554

4655
Permits you to drop the database specified in the first parameter.
@@ -384,9 +393,10 @@ Class Reference
384393

385394
Adds a unique key to the set that will be used to create a table. Usage: See `Adding Keys`_.
386395

387-
.. php:method:: createDatabase($db_name)
396+
.. php:method:: createDatabase($dbName[, $ifNotExists = FALSE])
388397
389398
:param string $db_name: Name of the database to create
399+
:param string $ifNotExists: Set to TRUE to add an 'IF NOT EXISTS' clause or check if database exists
390400
:returns: TRUE on success, FALSE on failure
391401
:rtype: bool
392402

@@ -411,9 +421,9 @@ Class Reference
411421

412422
Drops a column from a table. Usage: See `Dropping a Column From a Table`_.
413423

414-
.. php:method:: dropDatabase($db_name)
424+
.. php:method:: dropDatabase($dbName)
415425
416-
:param string $db_name: Name of the database to drop
426+
:param string $dbName: Name of the database to drop
417427
:returns: TRUE on success, FALSE on failure
418428
:rtype: bool
419429

0 commit comments

Comments
 (0)