Skip to content

Commit

Permalink
Merge pull request #8460 from kenjis/fix-sqlite3-getFieldData-primary…
Browse files Browse the repository at this point in the history
…_key

fix: [SQLite3] getFieldData() returns incorrect `primary_key` values
  • Loading branch information
kenjis authored Jan 30, 2024
2 parents aaef1de + 4a949b3 commit 057bcbd
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 22 deletions.
13 changes: 8 additions & 5 deletions system/Database/SQLite3/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,14 @@ protected function _fieldData(string $table): array
for ($i = 0, $c = count($query); $i < $c; $i++) {
$retVal[$i] = new stdClass();

$retVal[$i]->name = $query[$i]->name;
$retVal[$i]->type = $query[$i]->type;
$retVal[$i]->max_length = null;
$retVal[$i]->default = $query[$i]->dflt_value;
$retVal[$i]->primary_key = isset($query[$i]->pk) && (bool) $query[$i]->pk;
$retVal[$i]->name = $query[$i]->name;
$retVal[$i]->type = $query[$i]->type;
$retVal[$i]->max_length = null;
$retVal[$i]->default = $query[$i]->dflt_value;
// "pk" (either zero for columns that are not part of the primary key,
// or the 1-based index of the column within the primary key).
// https://www.sqlite.org/pragma.html#pragma_table_info
$retVal[$i]->primary_key = ($query[$i]->pk === 0) ? 0 : 1;
$retVal[$i]->nullable = isset($query[$i]->notnull) && ! (bool) $query[$i]->notnull;
}

Expand Down
8 changes: 4 additions & 4 deletions tests/system/Database/Live/ForgeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -986,31 +986,31 @@ public function testAddFields(): void
'type' => 'INTEGER',
'max_length' => null,
'default' => null,
'primary_key' => true,
'primary_key' => 1,
'nullable' => true,
],
1 => [
'name' => 'username',
'type' => 'VARCHAR',
'max_length' => null,
'default' => null,
'primary_key' => false,
'primary_key' => 0,
'nullable' => false,
],
2 => [
'name' => 'name',
'type' => 'VARCHAR',
'max_length' => null,
'default' => null,
'primary_key' => false,
'primary_key' => 0,
'nullable' => true,
],
3 => [
'name' => 'active',
'type' => 'INTEGER',
'max_length' => null,
'default' => '0',
'primary_key' => false,
'primary_key' => 0,
'nullable' => false,
],
];
Expand Down
73 changes: 66 additions & 7 deletions tests/system/Database/Live/SQLite3/GetFieldDataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,55 +47,114 @@ public function testGetFieldData(): void
'type' => 'INTEGER',
'max_length' => null,
'default' => null, // The default value is not defined.
'primary_key' => true,
'primary_key' => 1,
'nullable' => true,
],
(object) [
'name' => 'text_not_null',
'type' => 'VARCHAR',
'max_length' => null,
'default' => null, // The default value is not defined.
'primary_key' => false,
'primary_key' => 0,
'nullable' => false,
],
(object) [
'name' => 'text_null',
'type' => 'VARCHAR',
'max_length' => null,
'default' => null, // The default value is not defined.
'primary_key' => false,
'primary_key' => 0,
'nullable' => true,
],
(object) [
'name' => 'int_default_0',
'type' => 'INT',
'max_length' => null,
'default' => '0', // int 0
'primary_key' => false,
'primary_key' => 0,
'nullable' => false,
],
(object) [
'name' => 'text_default_null',
'type' => 'VARCHAR',
'max_length' => null,
'default' => 'NULL', // NULL value
'primary_key' => false,
'primary_key' => 0,
'nullable' => true,
],
(object) [
'name' => 'text_default_text_null',
'type' => 'VARCHAR',
'max_length' => null,
'default' => "'null'", // string "null"
'primary_key' => false,
'primary_key' => 0,
'nullable' => false,
],
(object) [
'name' => 'text_default_abc',
'type' => 'VARCHAR',
'max_length' => null,
'default' => "'abc'", // string "abc"
'primary_key' => false,
'primary_key' => 0,
'nullable' => false,
],
]),
json_encode($fields)
);
}

protected function createTableCompositePrimaryKey()
{
$this->forge->dropTable('test1', true);

$this->forge->addField([
'pk1' => [
'type' => 'VARCHAR',
'constraint' => 64,
],
'pk2' => [
'type' => 'VARCHAR',
'constraint' => 64,
],
'text' => [
'type' => 'VARCHAR',
'constraint' => 64,
],
]);
$this->forge->addPrimaryKey(['pk1', 'pk2']);
$this->forge->createTable('test1');
}

public function testGetFieldDataCompositePrimaryKey(): void
{
$this->createTableCompositePrimaryKey();

$fields = $this->db->getFieldData('test1');

$this->assertJsonStringEqualsJsonString(
json_encode([
(object) [
'name' => 'pk1',
'type' => 'VARCHAR',
'max_length' => null,
'default' => null,
'primary_key' => 1,
'nullable' => false,
],
(object) [
'name' => 'pk2',
'type' => 'VARCHAR',
'max_length' => null,
'default' => null,
'primary_key' => 1,
'nullable' => false,
],
(object) [
'name' => 'text',
'type' => 'VARCHAR',
'max_length' => null,
'default' => null,
'primary_key' => 0,
'nullable' => false,
],
]),
Expand Down
12 changes: 6 additions & 6 deletions user_guide_src/source/database/metadata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,12 @@ supplying the table name:
The following data is available from this function if supported by your
database:

- name - column name
- type - the type of the column
- max_length - maximum length of the column
- primary_key - integer ``1`` if the column is a primary key (all integer ``1``, even if there are multiple primary keys), otherwise integer ``0`` (This field is currently only available for MySQL and SQLite3)
- nullable - boolean ``true`` if the column is nullable, otherwise boolean ``false``
- default - the default value
- ``name`` - column name
- ``type`` - the type of the column
- ``max_length`` - maximum length of the column
- ``primary_key`` - integer ``1`` if the column is a primary key (all integer ``1``, even if there are multiple primary keys), otherwise integer ``0`` (This field is currently only available for ``MySQLi`` and ``SQLite3``)
- ``nullable`` - boolean ``true`` if the column is nullable, otherwise boolean ``false``
- ``default`` - the default value

.. note:: Since v4.4.0, SQLSRV supported ``nullable``.

Expand Down

0 comments on commit 057bcbd

Please sign in to comment.