Skip to content

Commit ab71e4f

Browse files
authored
Merge pull request #8979 from ducng99/feat/add_foundrows_mysqli_config
feat: add `foundRows` option for MySQLi config
2 parents 24544d6 + 9efac84 commit ab71e4f

File tree

6 files changed

+190
-0
lines changed

6 files changed

+190
-0
lines changed

app/Config/Database.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class Database extends Config
4343
'failover' => [],
4444
'port' => 3306,
4545
'numberNative' => false,
46+
'foundRows' => false,
4647
'dateFormat' => [
4748
'date' => 'Y-m-d',
4849
'datetime' => 'Y-m-d H:i:s',

phpstan-baseline.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13339,6 +13339,12 @@
1333913339
'count' => 2,
1334013340
'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/NumberNativeTest.php',
1334113341
];
13342+
$ignoreErrors[] = [
13343+
// identifier: property.notFound
13344+
'message' => '#^Access to an undefined property CodeIgniter\\\\Database\\\\BaseConnection\\:\\:\\$foundRows\\.$#',
13345+
'count' => 2,
13346+
'path' => __DIR__ . '/tests/system/Database/Live/MySQLi/FoundRowsTest.php',
13347+
];
1334213348
$ignoreErrors[] = [
1334313349
// identifier: missingType.property
1334413350
'message' => '#^Property CodeIgniter\\\\Database\\\\Live\\\\MySQLi\\\\NumberNativeTest\\:\\:\\$tests has no type specified\\.$#',

system/Database/MySQLi/Connection.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ class Connection extends BaseConnection
8181
*/
8282
public $numberNative = false;
8383

84+
/**
85+
* Use MYSQLI_CLIENT_FOUND_ROWS
86+
*
87+
* Whether affectedRows() should return number of rows found,
88+
* or number of rows changed, after an UPDATE query.
89+
*
90+
* @var bool
91+
*/
92+
public $foundRows = false;
93+
8494
/**
8595
* Connect to the database.
8696
*
@@ -182,6 +192,10 @@ public function connect(bool $persistent = false)
182192
$clientFlags += MYSQLI_CLIENT_SSL;
183193
}
184194

195+
if ($this->foundRows) {
196+
$clientFlags += MYSQLI_CLIENT_FOUND_ROWS;
197+
}
198+
185199
try {
186200
if ($this->mysqli->real_connect(
187201
$hostname,
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <[email protected]>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\Database\Live\MySQLi;
15+
16+
use CodeIgniter\Test\CIUnitTestCase;
17+
use CodeIgniter\Test\DatabaseTestTrait;
18+
use Config\Database;
19+
use PHPUnit\Framework\Attributes\Group;
20+
use Tests\Support\Database\Seeds\CITestSeeder;
21+
22+
/**
23+
* @internal
24+
*/
25+
#[Group('DatabaseLive')]
26+
final class FoundRowsTest extends CIUnitTestCase
27+
{
28+
use DatabaseTestTrait;
29+
30+
/**
31+
* Database config for tests
32+
*
33+
* @var array<string, mixed>
34+
*/
35+
private $tests;
36+
37+
protected $refresh = true;
38+
protected $seed = CITestSeeder::class;
39+
40+
protected function setUp(): void
41+
{
42+
$config = config('Database');
43+
44+
$this->tests = $config->tests;
45+
46+
if ($this->tests['DBDriver'] !== 'MySQLi') {
47+
$this->markTestSkipped('Only MySQLi can complete this test.');
48+
}
49+
50+
parent::setUp();
51+
}
52+
53+
public function testEnableFoundRows(): void
54+
{
55+
$this->tests['foundRows'] = true;
56+
57+
$db1 = Database::connect($this->tests);
58+
59+
$this->assertTrue($db1->foundRows);
60+
}
61+
62+
public function testDisableFoundRows(): void
63+
{
64+
$this->tests['foundRows'] = false;
65+
66+
$db1 = Database::connect($this->tests);
67+
68+
$this->assertFalse($db1->foundRows);
69+
}
70+
71+
public function testAffectedRowsAfterEnableFoundRowsWithNoChange(): void
72+
{
73+
$this->tests['foundRows'] = true;
74+
75+
$db1 = Database::connect($this->tests);
76+
77+
$db1->table('db_user')
78+
->set('country', 'US')
79+
->where('country', 'US')
80+
->update();
81+
82+
$affectedRows = $db1->affectedRows();
83+
84+
$this->assertSame($affectedRows, 2);
85+
}
86+
87+
public function testAffectedRowsAfterDisableFoundRowsWithNoChange(): void
88+
{
89+
$this->tests['foundRows'] = false;
90+
91+
$db1 = Database::connect($this->tests);
92+
93+
$db1->table('db_user')
94+
->set('country', 'US')
95+
->where('country', 'US')
96+
->update();
97+
98+
$affectedRows = $db1->affectedRows();
99+
100+
$this->assertSame($affectedRows, 0);
101+
}
102+
103+
public function testAffectedRowsAfterEnableFoundRowsWithChange(): void
104+
{
105+
$this->tests['foundRows'] = true;
106+
107+
$db1 = Database::connect($this->tests);
108+
109+
$db1->table('db_user')
110+
->set('country', 'NZ')
111+
->where('country', 'US')
112+
->update();
113+
114+
$affectedRows = $db1->affectedRows();
115+
116+
$this->assertSame($affectedRows, 2);
117+
}
118+
119+
public function testAffectedRowsAfterDisableFoundRowsWithChange(): void
120+
{
121+
$this->tests['foundRows'] = false;
122+
123+
$db1 = Database::connect($this->tests);
124+
125+
$db1->table('db_user')
126+
->set('country', 'NZ')
127+
->where('country', 'US')
128+
->update();
129+
130+
$affectedRows = $db1->affectedRows();
131+
132+
$this->assertSame($affectedRows, 2);
133+
}
134+
135+
public function testAffectedRowsAfterEnableFoundRowsWithPartialChange(): void
136+
{
137+
$this->tests['foundRows'] = true;
138+
139+
$db1 = Database::connect($this->tests);
140+
141+
$db1->table('db_user')
142+
->set('name', 'Derek Jones')
143+
->where('country', 'US')
144+
->update();
145+
146+
$affectedRows = $db1->affectedRows();
147+
148+
$this->assertSame($affectedRows, 2);
149+
}
150+
151+
public function testAffectedRowsAfterDisableFoundRowsWithPartialChange(): void
152+
{
153+
$this->tests['foundRows'] = false;
154+
155+
$db1 = Database::connect($this->tests);
156+
157+
$db1->table('db_user')
158+
->set('name', 'Derek Jones')
159+
->where('country', 'US')
160+
->update();
161+
162+
$affectedRows = $db1->affectedRows();
163+
164+
$this->assertSame($affectedRows, 1);
165+
}
166+
}

user_guide_src/source/changelogs/v4.6.0.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ Forge
133133
Others
134134
------
135135

136+
- Added a new configuration ``foundRows`` for MySQLi to use ``MYSQLI_CLIENT_FOUND_ROWS``.
137+
136138
Model
137139
=====
138140

user_guide_src/source/database/configuration.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ Description of Values
179179
To enforce Foreign Key constraint, set this config item to true.
180180
**busyTimeout** (``SQLite3`` only) milliseconds (int) - Sleeps for a specified amount of time when a table is locked.
181181
**numberNative** (``MySQLi`` only) true/false (boolean) - Whether to enable MYSQLI_OPT_INT_AND_FLOAT_NATIVE.
182+
**foundRows** (``MySQLi`` only) true/false (boolean) - Whether to enable MYSQLI_CLIENT_FOUND_ROWS.
182183
**dateFormat** The default date/time formats as PHP's `DateTime format`_.
183184
* ``date`` - date format
184185
* ``datetime`` - date and time format

0 commit comments

Comments
 (0)