Skip to content

Commit e7a932d

Browse files
committed
Insert / Ignore / Update support from SQLite
1 parent cf933ab commit e7a932d

File tree

5 files changed

+137
-12
lines changed

5 files changed

+137
-12
lines changed

Tests/Unit/InsertTest.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,82 @@ public function testStringNullInsert() : void
216216
$this->assertEquals('default', $insertedTest->stringDefaultNotNull);
217217
$this->assertTrue($transaction->rollBack());
218218
}
219+
220+
public function testInsertOrUpdate() : void
221+
{
222+
$transaction = new \PHPFUI\ORM\Transaction();
223+
$customerTable = new \Tests\App\Table\Customer();
224+
$this->assertEquals(29, $customerTable->count());
225+
226+
$customer = new \Tests\App\Record\Customer();
227+
$customer->address = '123 Broadway';
228+
$customer->business_phone = '212-987-6543';
229+
$customer->city = 'New York';
230+
$customer->company = 'PHPFUI';
231+
$customer->country_region = 'USA';
232+
$customer->email_address = 'bruce@phpfui.com';
233+
$customer->fax_number = '212-345-6789';
234+
$customer->first_name = 'Bruce';
235+
$customer->home_phone = '987-654-3210';
236+
$customer->job_title = 'Head Honcho';
237+
$customer->last_name = 'Wells';
238+
$customer->mobile_phone = '123-456-7890';
239+
$customer->state_province = 'NY';
240+
$customer->web_page = 'http://www.phpfui.com';
241+
$customer->zip_postal_code = '12345';
242+
$id = $customer->insertOrUpdate();
243+
$this->assertGreaterThan(0, $id);
244+
$this->assertEquals(30, $customerTable->count());
245+
246+
$newCustomer = new \Tests\App\Record\Customer($id);
247+
$this->assertEquals('12345', $newCustomer->zip_postal_code);
248+
$newCustomer->zip_postal_code = '54321';
249+
$result = $newCustomer->insertOrUpdate();
250+
$this->assertGreaterThan(0, $result);
251+
$this->assertEquals(30, $customerTable->count());
252+
253+
$updatedCustomer = new \Tests\App\Record\Customer($id);
254+
$this->assertEquals('54321', $updatedCustomer->zip_postal_code);
255+
$this->assertTrue($transaction->rollBack());
256+
$this->assertEquals(29, $customerTable->count());
257+
}
258+
259+
public function testInsertOrIgnore() : void
260+
{
261+
$transaction = new \PHPFUI\ORM\Transaction();
262+
$customerTable = new \Tests\App\Table\Customer();
263+
$this->assertEquals(29, $customerTable->count());
264+
265+
$customer = new \Tests\App\Record\Customer();
266+
$customer->address = '123 Broadway';
267+
$customer->business_phone = '212-987-6543';
268+
$customer->city = 'New York';
269+
$customer->company = 'PHPFUI';
270+
$customer->country_region = 'USA';
271+
$customer->email_address = 'bruce@phpfui.com';
272+
$customer->fax_number = '212-345-6789';
273+
$customer->first_name = 'Bruce';
274+
$customer->home_phone = '987-654-3210';
275+
$customer->job_title = 'Head Honcho';
276+
$customer->last_name = 'Wells';
277+
$customer->mobile_phone = '123-456-7890';
278+
$customer->state_province = 'NY';
279+
$customer->web_page = 'http://www.phpfui.com';
280+
$customer->zip_postal_code = '12345';
281+
$id = $customer->insertOrIgnore();
282+
$this->assertGreaterThan(0, $id);
283+
$this->assertEquals(30, $customerTable->count());
284+
285+
$newCustomer = new \Tests\App\Record\Customer($id);
286+
$this->assertEquals('12345', $newCustomer->zip_postal_code);
287+
$newCustomer->zip_postal_code = '54321';
288+
$result = $newCustomer->insertOrIgnore();
289+
$this->assertEquals(0, $result);
290+
$this->assertEmpty(\PHPFUI\ORM::getLastError());
291+
292+
$updatedCustomer = new \Tests\App\Record\Customer($id);
293+
$this->assertEquals('12345', $updatedCustomer->zip_postal_code);
294+
$this->assertTrue($transaction->rollBack());
295+
$this->assertEquals(29, $customerTable->count());
296+
}
219297
}

docs/10. Miscellaneous.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
# PHPFUI\ORM Miscellaneous
22

3-
## SQLite Support
4-
While this library is tested against SQLite, there are differences between MySQL/MariaDB syntax and SQLite syntax. Most notabliy is insertOrUpdate() and insertOrIgnore() which are not supported for SQLite. Use the custom SQL query support below instead.
5-
63
## Custom SQL Queries
74
**PHFUI\ORM** supports raw string queries for special cases or complex queries. The following static methods of [\PHPFUI\ORM](http://phpfui.com/?n=PHPFUI&c=ORM) are supported:
85

src/PHPFUI/ORM/PDOInstance.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ class PDOInstance extends \PDO
66
{
77
public readonly bool $postGre;
88

9+
public readonly bool $sqlite;
10+
911
/** @var array<string> */
1012
private array $lastError = [];
1113

@@ -25,6 +27,7 @@ class PDOInstance extends \PDO
2527
public function __construct(private string $dsn, ?string $username = null, ?string $password = null, ?array $options = null)
2628
{
2729
$this->postGre = \str_starts_with($dsn, 'pgsql');
30+
$this->sqlite = \str_starts_with($dsn, 'sqlite');
2831
parent::__construct($dsn, $username, $password, $options);
2932
}
3033

@@ -38,6 +41,18 @@ public function beginTransaction() : bool
3841
return parent::beginTransaction();
3942
}
4043

44+
/**
45+
* Clears an existing errors
46+
*/
47+
public function clearErrors() : void
48+
{
49+
$this->lastError = [];
50+
$this->lastErrorCode = 0;
51+
$this->lastErrors = [];
52+
$this->lastParameters = [];
53+
$this->lastSql = '';
54+
}
55+
4156
/**
4257
* @return array<\PHPFUI\ORM\Schema\Field>
4358
*/

src/PHPFUI/ORM/Record.php

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,19 @@ public function insert() : int | bool
399399
*/
400400
public function insertOrIgnore() : int | bool
401401
{
402-
return $this->privateInsert(false, 'ignore ');
402+
$pdo = \PHPFUI\ORM::pdo();
403+
if (! $pdo->sqlite)
404+
{
405+
return $this->privateInsert(false, 'ignore ');
406+
}
407+
408+
$id = $this->privateInsert(false);
409+
if (! $id)
410+
{
411+
\PHPFUI\ORM::getInstance()->clearErrors();
412+
}
413+
414+
return $id;
403415
}
404416

405417
/**
@@ -409,7 +421,26 @@ public function insertOrIgnore() : int | bool
409421
*/
410422
public function insertOrUpdate() : int | bool
411423
{
412-
return $this->privateInsert(true);
424+
$pdo = \PHPFUI\ORM::pdo();
425+
if (! $pdo->sqlite)
426+
{
427+
return $this->privateInsert(true);
428+
}
429+
430+
$id = $this->privateInsert(false);
431+
if ($id === false)
432+
{
433+
\PHPFUI\ORM::getInstance()->clearErrors();
434+
435+
$id = $this->update();
436+
$keys = $this->getPrimaryKeyValues();
437+
if (count($keys) == 1)
438+
{
439+
$id = array_shift($keys);
440+
}
441+
}
442+
443+
return $id;
413444
}
414445

415446
/**
@@ -905,17 +936,20 @@ private function privateInsert(bool $updateOnDuplicate, string $ignore = '') : i
905936

906937
$returnValue = \PHPFUI\ORM::execute($sql, $input);
907938

908-
if (static::$autoIncrement && $returnValue)
939+
if ($returnValue)
909940
{
910-
$returnValue = (int)\PHPFUI\ORM::lastInsertId(static::$primaryKeys[0], $table);
911-
912-
if ($returnValue)
941+
if (static::$autoIncrement)
913942
{
914-
$this->current[static::$primaryKeys[0]] = $returnValue;
943+
$returnValue = (int)\PHPFUI\ORM::lastInsertId(static::$primaryKeys[0], $table);
944+
945+
if ($returnValue)
946+
{
947+
$this->current[static::$primaryKeys[0]] = $returnValue;
948+
}
915949
}
916-
}
917950

918-
$this->loaded = true; // record is effectively read from the database now
951+
$this->loaded = true; // record is effectively read from the database now
952+
}
919953

920954
return $returnValue;
921955
}

testConfig.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
return ['dsn' => 'sqlite::memory:', 'name' => '', 'key' => ''];
44
//return ['dsn' => 'sqlite:' . __DIR__ . '/testdata.sqlite', 'name' => '', 'key' => '']; // *.sqlite is in .gitignore
55
//return ['dsn' => 'mysql:host=localhost;dbname=phpfui;port=3306;charset=utf8mb4;collation=utf8mb4_general_ci', 'name' => 'root', 'key' => ''];
6+
//return ['dsn' => 'mysql:host=localhost;dbname=phpfui;port=3307;charset=utf8mb4;collation=utf8mb4_general_ci', 'name' => 'root', 'key' => ''];
67

78

0 commit comments

Comments
 (0)