Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Added validation on exists database before created for MySQLi… #2100

Merged
merged 7 commits into from
Oct 17, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 57 additions & 8 deletions system/Database/Forge.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ class Forge
*/
protected $createDatabaseStr = 'CREATE DATABASE %s';

/**
* CREATE DATABASE IF statement
*
* @var string
*/
protected $createDatabaseIfStr = null;

/**
* CHECK DATABASE EXIST statement
*
* @var string
*/
protected $checkDatabaseExistStr = null;

/**
* DROP DATABASE statement
*
Expand Down Expand Up @@ -199,13 +213,23 @@ public function getConnection()
/**
* Create database
*
* @param string $db_name
* @param string $dbName
* @param boolean $ifNotExists Whether to add IF NOT EXISTS condition
*
* @return boolean
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
public function createDatabase(string $db_name): bool
public function createDatabase(string $dbName, bool $ifNotExists = false): bool
{
if ($ifNotExists && $this->createDatabaseIfStr === null)
{
if ($this->databaseExists($dbName))
{
return true;
}
$ifNotExists = false;
}

if ($this->createDatabaseStr === false)
{
if ($this->db->DBDebug)
Expand All @@ -215,7 +239,7 @@ public function createDatabase(string $db_name): bool

return false;
}
elseif (! $this->db->query(sprintf($this->createDatabaseStr, $db_name, $this->db->charset, $this->db->DBCollat))
elseif (! $this->db->query(sprintf($ifNotExists ? $this->createDatabaseIfStr : $this->createDatabaseStr, $dbName, $this->db->charset, $this->db->DBCollat))
)
{
if ($this->db->DBDebug)
Expand All @@ -228,23 +252,48 @@ public function createDatabase(string $db_name): bool

if (! empty($this->db->dataCache['db_names']))
{
$this->db->dataCache['db_names'][] = $db_name;
$this->db->dataCache['db_names'][] = $dbName;
}

return true;
}

//--------------------------------------------------------------------

/**
* Determine if a database exists
*
* @param string $dbName
*
* @return boolean
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
private function databaseExists(string $dbName): bool
{
if ($this->checkDatabaseExistStr === null)
{
if ($this->db->DBDebug)
{
throw new DatabaseException('This feature is not available for the database you are using.');
}

return false;
}

return $this->db->query(sprintf($this->checkDatabaseExistStr, $this->db->escape($dbName)))->getRow() !== null;
oleg1540 marked this conversation as resolved.
Show resolved Hide resolved
}

//--------------------------------------------------------------------

/**
* Drop database
*
* @param string $db_name
* @param string $dbName
*
* @return boolean
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
public function dropDatabase(string $db_name): bool
public function dropDatabase(string $dbName): bool
{
if ($this->dropDatabaseStr === false)
{
Expand All @@ -255,7 +304,7 @@ public function dropDatabase(string $db_name): bool

return false;
}
elseif (! $this->db->query(sprintf($this->dropDatabaseStr, $db_name)))
elseif (! $this->db->query(sprintf($this->dropDatabaseStr, $dbName)))
{
if ($this->db->DBDebug)
{
Expand All @@ -267,7 +316,7 @@ public function dropDatabase(string $db_name): bool

if (! empty($this->db->dataCache['db_names']))
{
$key = array_search(strtolower($db_name), array_map('strtolower', $this->db->dataCache['db_names']), true);
$key = array_search(strtolower($dbName), array_map('strtolower', $this->db->dataCache['db_names']), true);
if ($key !== false)
{
unset($this->db->dataCache['db_names'][$key]);
Expand Down
7 changes: 7 additions & 0 deletions system/Database/MySQLi/Forge.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ class Forge extends \CodeIgniter\Database\Forge
*/
protected $createDatabaseStr = 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s';

/**
* CREATE DATABASE IF statement
*
* @var string
*/
protected $createDatabaseIfStr = 'CREATE DATABASE IF NOT EXISTS %s CHARACTER SET %s COLLATE %s';

/**
* DROP CONSTRAINT statement
*
Expand Down
9 changes: 8 additions & 1 deletion system/Database/Postgre/Forge.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@
class Forge extends \CodeIgniter\Database\Forge
{

/**
* CHECK DATABASE EXIST statement
*
* @var string
*/
protected $checkDatabaseExistStr = 'SELECT 1 FROM pg_database WHERE datname = %s';

/**
* DROP CONSTRAINT statement
*
Expand Down Expand Up @@ -74,7 +81,7 @@ class Forge extends \CodeIgniter\Database\Forge
* @var string
*/
protected $_null = 'NULL';

//--------------------------------------------------------------------

/**
Expand Down
15 changes: 8 additions & 7 deletions system/Database/SQLite3/Forge.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,12 @@ public function __construct(ConnectionInterface $db)
/**
* Create database
*
* @param string $db_name
* @param string $dbName
* @param boolean $ifNotExists Whether to add IF NOT EXISTS condition
*
* @return boolean
*/
public function createDatabase(string $db_name): bool
public function createDatabase(string $dbName, bool $ifNotExists = false): bool
{
// In SQLite, a database is created when you connect to the database.
// We'll return TRUE so that an error isn't generated.
Expand All @@ -100,15 +101,15 @@ public function createDatabase(string $db_name): bool
/**
* Drop database
*
* @param string $db_name
* @param string $dbName
*
* @return boolean
* @throws \CodeIgniter\Database\Exceptions\DatabaseException
*/
public function dropDatabase(string $db_name): bool
public function dropDatabase(string $dbName): bool
{
// In SQLite, a database is dropped when we delete a file
if (! is_file($db_name))
if (! is_file($dbName))
{
if ($this->db->DBDebug)
{
Expand All @@ -120,7 +121,7 @@ public function dropDatabase(string $db_name): bool

// We need to close the pseudo-connection first
$this->db->close();
if (! @unlink($db_name))
if (! @unlink($dbName))
{
if ($this->db->DBDebug)
{
Expand All @@ -132,7 +133,7 @@ public function dropDatabase(string $db_name): bool

if (! empty($this->db->dataCache['db_names']))
{
$key = array_search(strtolower($db_name), array_map('strtolower', $this->db->dataCache['db_names']), true);
$key = array_search(strtolower($dbName), array_map('strtolower', $this->db->dataCache['db_names']), true);
if ($key !== false)
{
unset($this->db->dataCache['db_names'][$key]);
Expand Down
31 changes: 31 additions & 0 deletions tests/system/Database/Live/ForgeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,37 @@ public function testCreateDatabase()
$this->assertTrue($database_created);
}

public function testCreateDatabaseIfNotExists()
{
if ($this->db->DBDriver === 'SQLite3')
{
$this->markTestSkipped('SQLite3 skips create database and requires file path to drop database');
}

$dbName = 'test_forge_database_exist';

$databaseCreateIfNotExists = $this->forge->createDatabase($dbName, true);
$this->forge->dropDatabase($dbName);

$this->assertTrue($databaseCreateIfNotExists);
}

public function testCreateDatabaseIfNotExistsWithDb()
{
if ($this->db->DBDriver === 'SQLite3')
{
$this->markTestSkipped('SQLite3 skips create database and requires file path to drop database');
}

$dbName = 'test_forge_database_exist';

$this->forge->createDatabase($dbName);
$databaseExists = $this->forge->createDatabase($dbName, true);
$this->forge->dropDatabase($dbName);

$this->assertTrue($databaseExists);
}

public function testDropDatabase()
{
if ($this->db->DBDriver === 'SQLite3')
Expand Down
16 changes: 13 additions & 3 deletions user_guide_src/source/dbmgmt/forge.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ Returns TRUE/FALSE based on success or failure::
echo 'Database created!';
}

An optional second parameter set to TRUE will add IF EXISTS statement
or will check if a database exists before create it (depending on DBMS).

::

$forge->createDatabase('my_db', TRUE);
// gives CREATE DATABASE IF NOT EXISTS my_db
// or will check if a database exists

**$forge->dropDatabase('db_name')**

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

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

.. php:method:: createDatabase($db_name)
.. php:method:: createDatabase($dbName[, $ifNotExists = FALSE])

:param string $db_name: Name of the database to create
:param string $ifNotExists: Set to TRUE to add an 'IF NOT EXISTS' clause or check if database exists
:returns: TRUE on success, FALSE on failure
:rtype: bool

Expand All @@ -411,9 +421,9 @@ Class Reference

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

.. php:method:: dropDatabase($db_name)
.. php:method:: dropDatabase($dbName)

:param string $db_name: Name of the database to drop
:param string $dbName: Name of the database to drop
:returns: TRUE on success, FALSE on failure
:rtype: bool

Expand Down