Fix bug with handling boolean values in set() method in BaseBuilder and Model class

This commit is contained in:
michalsn 2021-07-04 10:20:59 +02:00 committed by John Paul E. Balandan, CPA
parent 68a9a353a3
commit ef2c3b4400
9 changed files with 123 additions and 7 deletions

View File

@ -1339,12 +1339,12 @@ class BaseBuilder
* Allows key/value pairs to be set for insert(), update() or replace().
*
* @param array|object|string $key Field name, or an array of field/value pairs
* @param string|null $value Field value, if $key is a single field
* @param mixed $value Field value, if $key is a single field
* @param bool|null $escape Whether to escape values and identifiers
*
* @return $this
*/
public function set($key, ?string $value = '', ?bool $escape = null)
public function set($key, $value = '', ?bool $escape = null)
{
$key = $this->objectToArray($key);

View File

@ -349,6 +349,10 @@ class Forge extends BaseForge
$attributes['TYPE'] = 'DATETIME';
break;
case 'BOOLEAN':
$attributes['TYPE'] = 'BIT';
break;
default:
break;
}

View File

@ -198,6 +198,10 @@ class Forge extends BaseForge
$attributes['TYPE'] = 'TEXT';
break;
case 'BOOLEAN':
$attributes['TYPE'] = 'INT';
break;
default:
break;
}

View File

@ -557,13 +557,13 @@ class Model extends BaseModel
* data here. This allows it to be used with any of the other
* builder methods and still get validated data, like replace.
*
* @param array|string $key Field name, or an array of field/value pairs
* @param string|null $value Field value, if $key is a single field
* @param bool|null $escape Whether to escape values and identifiers
* @param mixed $key Field name, or an array of field/value pairs
* @param mixed $value Field value, if $key is a single field
* @param bool|null $escape Whether to escape values and identifiers
*
* @return $this
*/
public function set($key, ?string $value = '', ?bool $escape = null)
public function set($key, $value = '', ?bool $escape = null)
{
$data = is_array($key) ? $key : [$key => $value];

View File

@ -70,6 +70,7 @@ class Migration_Create_test_tables extends Migration
'type_double' => ['type' => 'DOUBLE', 'null' => true],
'type_decimal' => ['type' => 'DECIMAL', 'constraint' => '18,4', 'null' => true],
'type_blob' => ['type' => 'BLOB', 'null' => true],
'type_boolean' => ['type' => 'BOOLEAN', 'null' => true],
];
if ($this->db->DBDriver === 'Postgre') {

View File

@ -106,6 +106,7 @@ class CITestSeeder extends Seeder
'type_datetime' => '2020-06-18T05:12:24.000+02:00',
'type_timestamp' => '2019-07-18T21:53:21.000+02:00',
'type_bigint' => 2342342,
'type_boolean' => 1,
],
],
];
@ -119,7 +120,8 @@ class CITestSeeder extends Seeder
}
if ($this->db->DBDriver === 'Postgre') {
$data['type_test'][0]['type_time'] = '15:22:00';
$data['type_test'][0]['type_time'] = '15:22:00';
$data['type_test'][0]['type_boolean'] = true;
unset(
$data['type_test'][0]['type_enum'],
$data['type_test'][0]['type_set'],

View File

@ -99,6 +99,80 @@ final class UpdateTest extends CIUnitTestCase
$this->assertSame($expectedBinds, $builder->getBinds());
}
public function testUpdateWithSetAsInt()
{
$builder = new BaseBuilder('jobs', $this->db);
$builder->testMode()->set('age', 22)->where('id', 1)->update(null, null, null);
$expectedSQL = 'UPDATE "jobs" SET "age" = 22 WHERE "id" = 1';
$expectedBinds = [
'age' => [
22,
true,
],
'id' => [
1,
true,
],
];
$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledUpdate()));
$this->assertSame($expectedBinds, $builder->getBinds());
}
public function testUpdateWithSetAsBoolean()
{
$builder = new BaseBuilder('jobs', $this->db);
$builder->testMode()->set('manager', true)->where('id', 1)->update(null, null, null);
$expectedSQL = 'UPDATE "jobs" SET "manager" = 1 WHERE "id" = 1';
$expectedBinds = [
'manager' => [
true,
true,
],
'id' => [
1,
true,
],
];
$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledUpdate()));
$this->assertSame($expectedBinds, $builder->getBinds());
}
public function testUpdateWithSetAsArray()
{
$builder = new BaseBuilder('jobs', $this->db);
$builder->testMode()->set(['name' => 'Programmer', 'age' => 22, 'manager' => true])->where('id', 1)->update(null, null, null);
$expectedSQL = 'UPDATE "jobs" SET "name" = \'Programmer\', "age" = 22, "manager" = 1 WHERE "id" = 1';
$expectedBinds = [
'name' => [
'Programmer',
true,
],
'age' => [
22,
true,
],
'manager' => [
true,
true,
],
'id' => [
1,
true,
],
];
$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledUpdate()));
$this->assertSame($expectedBinds, $builder->getBinds());
}
public function testUpdateThrowsExceptionWithNoData()
{
$builder = new BaseBuilder('jobs', $this->db);

View File

@ -211,4 +211,23 @@ final class UpdateTest extends CIUnitTestCase
'description' => 'Developer',
]);
}
public function testSetWithBoolean()
{
$this->db->table('type_test')
->set('type_boolean', false)
->update();
$this->seeInDatabase('type_test', [
'type_boolean' => false,
]);
$this->db->table('type_test')
->set('type_boolean', true)
->update();
$this->seeInDatabase('type_test', [
'type_boolean' => true,
]);
}
}

View File

@ -0,0 +1,12 @@
#############################
Upgrading from 4.1.3 to 4.2.0
#############################
**Changes for set() method in BaseBuilder and Model class**
The casting for the ``$value`` parameter has been removed to fix a bug where passing parameters as array and string
to the ``set()`` method were handled differently. If you extended the ``BaseBuilder`` class or ``Model`` class yourself
and modified the ``set()`` method, then you need to change its definition from
``public function set($key, ?string $value = '', ?bool $escape = null)`` to
``public function set($key, $value = '', ?bool $escape = null)``.