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

Fix create table if not exists when indexes already exist #6249

Merged
merged 5 commits into from
Jul 14, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion phpstan-baseline.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ parameters:

-
message: "#^Access to an undefined property CodeIgniter\\\\Database\\\\BaseConnection\\:\\:\\$schema\\.$#"
count: 14
count: 13
path: system/Database/SQLSRV/Forge.php

-
Expand Down
34 changes: 10 additions & 24 deletions system/Database/Forge.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ class Forge
* CREATE TABLE IF statement
*
* @var bool|string
*
* @deprecated This is no longer used.
*/
protected $createTableIfStr = 'CREATE TABLE IF NOT EXISTS';
sclubricants marked this conversation as resolved.
Show resolved Hide resolved

Expand Down Expand Up @@ -495,21 +497,15 @@ public function createTable(string $table, bool $ifNotExists = false, array $att
throw new RuntimeException('Field information is required.');
}

$sql = $this->_createTable($table, $ifNotExists, $attributes);

if (is_bool($sql)) {
// If table exists lets stop here
if ($ifNotExists === true && $this->db->tableExists($table)) {
$this->reset();
if ($sql === false) {
if ($this->db->DBDebug) {
throw new DatabaseException('This feature is not available for the database you are using.');
}

return false;
}

return true;
}

$sql = $this->_createTable($table, false, $attributes);

if (($result = $this->db->query($sql)) !== false) {
if (isset($this->db->dataCache['table_names']) && ! in_array($table, $this->db->dataCache['table_names'], true)) {
$this->db->dataCache['table_names'][] = $table;
Expand All @@ -529,22 +525,12 @@ public function createTable(string $table, bool $ifNotExists = false, array $att
}

/**
* @return bool|string
* @return string
*
* @deprecated $ifNotExists is no longer used, and will be removed.
*/
protected function _createTable(string $table, bool $ifNotExists, array $attributes)
{
// For any platforms that don't support Create If Not Exists...
if ($ifNotExists === true && $this->createTableIfStr === false) {
if ($this->db->tableExists($table)) {
return true;
}

$ifNotExists = false;
}

$sql = ($ifNotExists) ? sprintf($this->createTableIfStr, $this->db->escapeIdentifiers($table))
: 'CREATE TABLE';

$columns = $this->_processFields(true);

for ($i = 0, $c = count($columns); $i < $c; $i++) {
Expand All @@ -566,7 +552,7 @@ protected function _createTable(string $table, bool $ifNotExists, array $attribu

return sprintf(
$this->createTableStr . '%s',
$sql,
'CREATE TABLE',
$this->db->escapeIdentifiers($table),
$columns,
$this->_createTableAttributes($attributes)
Expand Down
2 changes: 2 additions & 0 deletions system/Database/OCI8/Forge.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class Forge extends BaseForge
* CREATE TABLE IF statement
*
* @var false
*
* @deprecated This is no longer used.
*/
protected $createTableIfStr = false;

Expand Down
10 changes: 2 additions & 8 deletions system/Database/SQLSRV/Forge.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ class Forge extends BaseForge
* CREATE TABLE IF statement
*
* @var string
*
* @deprecated This is no longer used.
*/
protected $createTableIfStr;

Expand All @@ -101,14 +103,6 @@ public function __construct(BaseConnection $db)
{
parent::__construct($db);

$this->createTableIfStr = 'IF NOT EXISTS'
. '(SELECT t.name, s.name as schema_name, t.type_desc '
. 'FROM sys.tables t '
. 'INNER JOIN sys.schemas s on s.schema_id = t.schema_id '
. "WHERE s.name=N'" . $this->db->schema . "' "
. "AND t.name=REPLACE(N'%s', '\"', '') "
. "AND t.type_desc='USER_TABLE')\nCREATE TABLE ";

$this->createTableStr = '%s ' . $this->db->escapeIdentifiers($this->db->schema) . ".%s (%s\n) ";
$this->renameTableStr = 'EXEC sp_rename [' . $this->db->escapeIdentifiers($this->db->schema) . '.%s] , %s ;';

Expand Down
3 changes: 1 addition & 2 deletions system/Database/SQLite3/Forge.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ public function __construct(BaseConnection $db)
parent::__construct($db);

if (version_compare($this->db->getVersion(), '3.3', '<')) {
$this->createTableIfStr = false;
$this->dropTableIfStr = false;
$this->dropTableIfStr = false;
}
}

Expand Down
3 changes: 1 addition & 2 deletions user_guide_src/source/dbmgmt/forge.rst
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,7 @@ with

.. literalinclude:: forge/014.php

An optional second parameter set to true adds an ``IF NOT EXISTS`` clause
into the definition
An optional second parameter set to true will create the table only if it doesn't already exist.

.. literalinclude:: forge/015.php

Expand Down
2 changes: 1 addition & 1 deletion user_guide_src/source/dbmgmt/forge/015.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php

$forge->createTable('table_name', true);
// gives CREATE TABLE IF NOT EXISTS table_name
// creates table only if table does not exist
50 changes: 50 additions & 0 deletions user_guide_src/source/installation/upgrade_422.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#############################
Upgrading from 4.2.1 to 4.2.2
#############################

Please refer to the upgrade instructions corresponding to your installation method.

- :ref:`Composer Installation App Starter Upgrading <app-starter-upgrading>`
- :ref:`Composer Installation Adding CodeIgniter4 to an Existing Project Upgrading <adding-codeigniter4-upgrading>`
- :ref:`Manual Installation Upgrading <installing-manual-upgrading>`

.. contents::
:local:
:depth: 2

Mandatory File Changes
**********************


Breaking Changes
****************

- The method ``Forge::createTable()`` no longer executes a ``CREATE TABLE IF NOT EXISTS``. If table is not found in ``$db->tableExists($table)`` then ``CREATE TABLE`` is executed.
- The second parameter ``$ifNotExists`` of ``Forge::_createTable()`` is deprecated. It is no longer used and will be removed in a future release.

Breaking Enhancements
*********************


Project Files
*************

Numerous files in the **project space** (root, app, public, writable) received updates. Due to
these files being outside of the **system** scope they will not be changed without your intervention.
There are some third-party CodeIgniter modules available to assist with merging changes to
the project space: `Explore on Packagist <https://packagist.org/explore/?query=codeigniter4%20updates>`_.

.. note:: Except in very rare cases for bug fixes, no changes made to files for the project space
will break your application. All changes noted here are optional until the next major version,
and any mandatory changes will be covered in the sections above.

Content Changes
===============


All Changes
===========

This is a list of all files in the **project space** that received changes;
many will be simple comments or formatting that have no effect on the runtime: