Skip to content

Commit 77e1515

Browse files
committed
Rewrite logic to two keyed lock
1 parent 788962f commit 77e1515

File tree

3 files changed

+99
-38
lines changed

3 files changed

+99
-38
lines changed

README.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ PHP application-level database locking mechanisms to implement concurrency contr
1313

1414
Supported drivers:
1515

16-
- Postgres
16+
- Postgres[PostgreSQL Advisory Locks Documentation](https://www.postgresql.org/docs/current/explicit-locking.html#ADVISORY-LOCKS)
1717

1818
## Installation
1919

@@ -33,12 +33,13 @@ composer require cybercog/php-db-locker
3333
$dbConnection = new PDO($dsn, $username, $password);
3434

3535
$postgresLocker = new \Cog\DbLocker\Locker\PostgresAdvisoryLocker();
36-
$postgresLockId = \Cog\DbLocker\LockId\PostgresLockId::fromLockId(
37-
new LockId('user', '4'),
38-
);
36+
$postgresLockId = \Cog\DbLocker\LockId\PostgresLockId::fromKeyValue('user', '4');
3937

4038
$dbConnection->beginTransaction();
41-
$isLockAcquired = $postgresLocker->acquireLockWithinTransaction($dbConnection, $postgresLockId);
39+
$isLockAcquired = $postgresLocker->acquireLockWithinTransaction(
40+
$dbConnection,
41+
$postgresLockId,
42+
);
4243
if ($isLockAcquired) {
4344
// Execute logic if lock was successful
4445
} else {
@@ -53,11 +54,12 @@ $dbConnection->commit();
5354
$dbConnection = new PDO($dsn, $username, $password);
5455

5556
$postgresLocker = new \Cog\DbLocker\Locker\PostgresAdvisoryLocker();
56-
$postgresLockId = \Cog\DbLocker\LockId\PostgresLockId::fromLockId(
57-
new LockId('user', '4'),
58-
);
57+
$postgresLockId = \Cog\DbLocker\LockId\PostgresLockId::fromKeyValue('user', '4');
5958

60-
$isLockAcquired = $postgresLocker->acquireLock($dbConnection, $postgresLockId);
59+
$isLockAcquired = $postgresLocker->acquireLock(
60+
$dbConnection,
61+
$postgresLockId,
62+
);
6163
if ($isLockAcquired) {
6264
// Execute logic if lock was successful
6365
} else {

src/LockId/PostgresLockId.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ classId: self::convertStringToSignedInt32($lockId->key),
4949
);
5050
}
5151

52+
public static function fromKeyValue(
53+
string $key,
54+
string $value = '',
55+
): self {
56+
return self::fromLockId(
57+
new LockId(
58+
$key,
59+
$value,
60+
),
61+
);
62+
}
63+
5264
/**
5365
* Generates a deterministic signed 32-bit integer ID
5466
* from a string for use as a Postgres advisory lock key.

test/Unit/LockId/PostgresLockIdTest.php

Lines changed: 76 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,55 +16,102 @@
1616
use Cog\DbLocker\LockId\LockId;
1717
use Cog\DbLocker\LockId\PostgresLockId;
1818
use Cog\Test\DbLocker\Unit\AbstractUnitTestCase;
19+
use PHPUnit\Framework\Attributes\DataProvider;
1920

2021
final class PostgresLockIdTest extends AbstractUnitTestCase
2122
{
2223
private const DB_INT32_VALUE_MIN = -2_147_483_648;
2324
private const DB_INT32_VALUE_MAX = 2_147_483_647;
2425

25-
public function test_it_can_create_postgres_lock_id_with_min_class_id(): void
26-
{
27-
$lockId = new PostgresLockId(self::DB_INT32_VALUE_MIN, 0);
26+
#[DataProvider('provideItCanCreatePostgresLockIdData')]
27+
public function testItCanCreatePostgresLockId(
28+
int $classId,
29+
int $objectId,
30+
): void {
31+
$lockId = new PostgresLockId($classId, $objectId);
2832

29-
$this->assertSame(self::DB_INT32_VALUE_MIN, $lockId->classId);
33+
$this->assertSame($classId, $lockId->classId);
34+
$this->assertSame($objectId, $lockId->objectId);
3035
}
3136

32-
public function test_it_can_create_postgres_lock_id_with_max_class_id(): void
37+
public static function provideItCanCreatePostgresLockIdData(): array
3338
{
34-
$lockId = new PostgresLockId(self::DB_INT32_VALUE_MAX, 0);
35-
36-
$this->assertSame(self::DB_INT32_VALUE_MAX, $lockId->classId);
39+
return [
40+
'min class_id' => [
41+
self::DB_INT32_VALUE_MIN,
42+
0,
43+
],
44+
'max class_id' => [
45+
self::DB_INT32_VALUE_MAX,
46+
0,
47+
],
48+
'min object_id' => [
49+
0,
50+
self::DB_INT32_VALUE_MIN,
51+
],
52+
'max object_id' => [
53+
0,
54+
self::DB_INT32_VALUE_MAX,
55+
],
56+
];
3757
}
3858

39-
public function test_it_can_create_postgres_lock_id_with_min_object_id(): void
40-
{
41-
$lockId = new PostgresLockId(0, self::DB_INT32_VALUE_MIN);
59+
#[DataProvider('provideItCanCreatePostgresLockIdFromLockIdData')]
60+
public function testItCanCreatePostgresLockIdFromLockId(
61+
LockId $lockId,
62+
int $expectedClassId,
63+
int $expectedObjectId,
64+
): void {
65+
$postgresLockId = PostgresLockId::fromLockId($lockId);
4266

43-
$this->assertSame(self::DB_INT32_VALUE_MIN, $lockId->objectId);
67+
$this->assertSame($expectedClassId, $postgresLockId->classId);
68+
$this->assertSame($expectedObjectId, $postgresLockId->objectId);
4469
}
4570

46-
public function test_it_can_create_postgres_lock_id_with_max_object_id(): void
71+
public static function provideItCanCreatePostgresLockIdFromLockIdData(): array
4772
{
48-
$lockId = new PostgresLockId(0, self::DB_INT32_VALUE_MAX);
49-
50-
$this->assertSame(self::DB_INT32_VALUE_MAX, $lockId->objectId);
73+
return [
74+
'key only' => [
75+
new LockId('test'),
76+
-662733300,
77+
0,
78+
],
79+
'key + value' => [
80+
new LockId('test', '1'),
81+
-662733300,
82+
-2082672713,
83+
],
84+
];
5185
}
5286

53-
public function test_it_can_create_postgres_lock_id_from_lock_id(): void
54-
{
55-
$lockId = new LockId('test');
56-
57-
$postgresLockId = PostgresLockId::fromLockId($lockId);
58-
59-
$this->assertSame(-662733300, $postgresLockId->classId);
87+
#[DataProvider('provideItCanCreatePostgresLockIdFromKeyValueData')]
88+
public function testItCanCreatePostgresLockIdFromKeyValue(
89+
string $key,
90+
string $value,
91+
int $expectedClassId,
92+
int $expectedObjectId,
93+
): void {
94+
$postgresLockId = PostgresLockId::fromKeyValue($key, $value);
95+
96+
$this->assertSame($expectedClassId, $postgresLockId->classId);
97+
$this->assertSame($expectedObjectId, $postgresLockId->objectId);
6098
}
6199

62-
public function test_it_can_create_postgres_lock_id_from_lock_id_with_value(): void
100+
public static function provideItCanCreatePostgresLockIdFromKeyValueData(): array
63101
{
64-
$lockId = new LockId('test', '1');
65-
66-
$postgresLockId = PostgresLockId::fromLockId($lockId);
67-
68-
$this->assertSame(-662733300, $postgresLockId->classId);
102+
return [
103+
'key + empty value' => [
104+
'test',
105+
'',
106+
-662733300,
107+
0,
108+
],
109+
'key + value' => [
110+
'test',
111+
'1',
112+
-662733300,
113+
-2082672713,
114+
],
115+
];
69116
}
70117
}

0 commit comments

Comments
 (0)