Skip to content

Commit 057bcbd

Browse files
authored
Merge pull request #8460 from kenjis/fix-sqlite3-getFieldData-primary_key
fix: [SQLite3] getFieldData() returns incorrect `primary_key` values
2 parents aaef1de + 4a949b3 commit 057bcbd

4 files changed

Lines changed: 84 additions & 22 deletions

File tree

system/Database/SQLite3/Connection.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -269,11 +269,14 @@ protected function _fieldData(string $table): array
269269
for ($i = 0, $c = count($query); $i < $c; $i++) {
270270
$retVal[$i] = new stdClass();
271271

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

tests/system/Database/Live/ForgeTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -986,31 +986,31 @@ public function testAddFields(): void
986986
'type' => 'INTEGER',
987987
'max_length' => null,
988988
'default' => null,
989-
'primary_key' => true,
989+
'primary_key' => 1,
990990
'nullable' => true,
991991
],
992992
1 => [
993993
'name' => 'username',
994994
'type' => 'VARCHAR',
995995
'max_length' => null,
996996
'default' => null,
997-
'primary_key' => false,
997+
'primary_key' => 0,
998998
'nullable' => false,
999999
],
10001000
2 => [
10011001
'name' => 'name',
10021002
'type' => 'VARCHAR',
10031003
'max_length' => null,
10041004
'default' => null,
1005-
'primary_key' => false,
1005+
'primary_key' => 0,
10061006
'nullable' => true,
10071007
],
10081008
3 => [
10091009
'name' => 'active',
10101010
'type' => 'INTEGER',
10111011
'max_length' => null,
10121012
'default' => '0',
1013-
'primary_key' => false,
1013+
'primary_key' => 0,
10141014
'nullable' => false,
10151015
],
10161016
];

tests/system/Database/Live/SQLite3/GetFieldDataTest.php

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,55 +47,114 @@ public function testGetFieldData(): void
4747
'type' => 'INTEGER',
4848
'max_length' => null,
4949
'default' => null, // The default value is not defined.
50-
'primary_key' => true,
50+
'primary_key' => 1,
5151
'nullable' => true,
5252
],
5353
(object) [
5454
'name' => 'text_not_null',
5555
'type' => 'VARCHAR',
5656
'max_length' => null,
5757
'default' => null, // The default value is not defined.
58-
'primary_key' => false,
58+
'primary_key' => 0,
5959
'nullable' => false,
6060
],
6161
(object) [
6262
'name' => 'text_null',
6363
'type' => 'VARCHAR',
6464
'max_length' => null,
6565
'default' => null, // The default value is not defined.
66-
'primary_key' => false,
66+
'primary_key' => 0,
6767
'nullable' => true,
6868
],
6969
(object) [
7070
'name' => 'int_default_0',
7171
'type' => 'INT',
7272
'max_length' => null,
7373
'default' => '0', // int 0
74-
'primary_key' => false,
74+
'primary_key' => 0,
7575
'nullable' => false,
7676
],
7777
(object) [
7878
'name' => 'text_default_null',
7979
'type' => 'VARCHAR',
8080
'max_length' => null,
8181
'default' => 'NULL', // NULL value
82-
'primary_key' => false,
82+
'primary_key' => 0,
8383
'nullable' => true,
8484
],
8585
(object) [
8686
'name' => 'text_default_text_null',
8787
'type' => 'VARCHAR',
8888
'max_length' => null,
8989
'default' => "'null'", // string "null"
90-
'primary_key' => false,
90+
'primary_key' => 0,
9191
'nullable' => false,
9292
],
9393
(object) [
9494
'name' => 'text_default_abc',
9595
'type' => 'VARCHAR',
9696
'max_length' => null,
9797
'default' => "'abc'", // string "abc"
98-
'primary_key' => false,
98+
'primary_key' => 0,
99+
'nullable' => false,
100+
],
101+
]),
102+
json_encode($fields)
103+
);
104+
}
105+
106+
protected function createTableCompositePrimaryKey()
107+
{
108+
$this->forge->dropTable('test1', true);
109+
110+
$this->forge->addField([
111+
'pk1' => [
112+
'type' => 'VARCHAR',
113+
'constraint' => 64,
114+
],
115+
'pk2' => [
116+
'type' => 'VARCHAR',
117+
'constraint' => 64,
118+
],
119+
'text' => [
120+
'type' => 'VARCHAR',
121+
'constraint' => 64,
122+
],
123+
]);
124+
$this->forge->addPrimaryKey(['pk1', 'pk2']);
125+
$this->forge->createTable('test1');
126+
}
127+
128+
public function testGetFieldDataCompositePrimaryKey(): void
129+
{
130+
$this->createTableCompositePrimaryKey();
131+
132+
$fields = $this->db->getFieldData('test1');
133+
134+
$this->assertJsonStringEqualsJsonString(
135+
json_encode([
136+
(object) [
137+
'name' => 'pk1',
138+
'type' => 'VARCHAR',
139+
'max_length' => null,
140+
'default' => null,
141+
'primary_key' => 1,
142+
'nullable' => false,
143+
],
144+
(object) [
145+
'name' => 'pk2',
146+
'type' => 'VARCHAR',
147+
'max_length' => null,
148+
'default' => null,
149+
'primary_key' => 1,
150+
'nullable' => false,
151+
],
152+
(object) [
153+
'name' => 'text',
154+
'type' => 'VARCHAR',
155+
'max_length' => null,
156+
'default' => null,
157+
'primary_key' => 0,
99158
'nullable' => false,
100159
],
101160
]),

user_guide_src/source/database/metadata.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,12 @@ supplying the table name:
102102
The following data is available from this function if supported by your
103103
database:
104104

105-
- name - column name
106-
- type - the type of the column
107-
- max_length - maximum length of the column
108-
- 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)
109-
- nullable - boolean ``true`` if the column is nullable, otherwise boolean ``false``
110-
- default - the default value
105+
- ``name`` - column name
106+
- ``type`` - the type of the column
107+
- ``max_length`` - maximum length of the column
108+
- ``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``)
109+
- ``nullable`` - boolean ``true`` if the column is nullable, otherwise boolean ``false``
110+
- ``default`` - the default value
111111

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

0 commit comments

Comments
 (0)