Skip to content

Commit

Permalink
added ability to have text based primary keys
Browse files Browse the repository at this point in the history
  • Loading branch information
n0nag0n committed Apr 27, 2024
1 parent 4ef962a commit f6cab54
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/ActiveRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -451,12 +451,17 @@ public function insert(): ActiveRecord
]);
$this->values = new Expressions(['operator' => 'VALUES', 'target' => new WrapExpressions(['target' => $value])]);

$intentionallyAssignedPrimaryKey = $this->dirty[$this->primaryKey] ?? null;

$this->execute($this->buildSql(['insert', 'values']), $this->params);
$this->{$this->primaryKey} = $this->databaseConnection->lastInsertId();

$this->{$this->primaryKey} = $intentionallyAssignedPrimaryKey ?: $this->databaseConnection->lastInsertId();

$this->processEvent([ 'afterInsert', 'afterSave' ], [ $this ]);

return $this->dirty()->resetQueryData();
$this->isHydrated = true;

return $this->dirty();
}
/**
* function to build update SQL, and update current record in database, just write the dirty data into database.
Expand Down Expand Up @@ -486,7 +491,7 @@ public function update(): ActiveRecord
*/
public function save(): ActiveRecord
{
if ($this->{$this->primaryKey}) {
if ($this->{$this->primaryKey} !== null && $this->isHydrated() === true) {
$record = $this->update();
} else {
$record = $this->insert();
Expand Down
53 changes: 53 additions & 0 deletions tests/ActiveRecordPdoIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public function tearDown(): void
{
$this->ActiveRecord->execute("DROP TABLE IF EXISTS contact;");
$this->ActiveRecord->execute("DROP TABLE IF EXISTS user;");
$this->ActiveRecord->execute("DROP TABLE IF EXISTS my_text_table;");
}

public function testInsert()
Expand Down Expand Up @@ -550,4 +551,56 @@ public function testRelationWithProtectedKeyword()
$this->expectExceptionMessage('group is a protected keyword and cannot be used as a relation name');
$contact->group->id;
}

public function testTextBasedPrimaryKey() {
$this->ActiveRecord->execute("CREATE TABLE IF NOT EXISTS my_text_table (
my_pk TEXT NOT NULL PRIMARY KEY,
data INTEGER, name TEXT
)");

$myTextTable = new class (new PDO('sqlite:test.db'), 'my_text_table', [ 'primaryKey' => 'my_pk' ]) extends ActiveRecord {
};

$my_pk = time();
$myTextTable->my_pk = $my_pk;
$myTextTable->data = 12345;

$this->assertTrue($myTextTable->isDirty());
$myTextTable->save();

$this->assertTrue($myTextTable->isHydrated());

$myTextTable->reset();

$myTextTable->find($my_pk);

$this->assertEquals($my_pk, $myTextTable->my_pk);
$this->assertEquals(12345, $myTextTable->data);
$this->assertTrue($myTextTable->isHydrated());
}

public function testTextBasedPrimaryKeyDuplicateKey() {
$this->ActiveRecord->execute("CREATE TABLE IF NOT EXISTS my_text_table (
my_pk TEXT NOT NULL PRIMARY KEY,
data INTEGER, name TEXT
)");

$myTextTable = new class (new PDO('sqlite:test.db'), 'my_text_table', [ 'primaryKey' => 'my_pk' ]) extends ActiveRecord {
};

$my_pk = time();
$myTextTable->my_pk = $my_pk;
$myTextTable->data = 12345;
$myTextTable->save();

$myTextTable2 = new class (new PDO('sqlite:test.db'), 'my_text_table', [ 'primaryKey' => 'my_pk' ]) extends ActiveRecord {
};

$myTextTable2->my_pk = $my_pk;
$myTextTable2->data = 12345;

$this->expectException(\Exception::class);
$this->expectExceptionMessage('UNIQUE constraint failed: my_text_table.my_pk');
$myTextTable2->save();
}
}

0 comments on commit f6cab54

Please sign in to comment.