Skip to content

Commit

Permalink
Use snake case for item attribute names (ease migration from Yii 2) (#63
Browse files Browse the repository at this point in the history
)
  • Loading branch information
arogachev committed Jan 22, 2024
1 parent 354e645 commit ac56329
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 100 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -34,6 +34,7 @@
- Chg #59: Add customizable separator for joining and splitting item names (@arogachev)
- Enh #60: Use migrations (@arogachev)
- Enh #43: Remove duplicate code in `ItemsStorage::add()` (@arogachev)
- Enh #53: Use snake case for item attribute names (ease migration from Yii 2) (@arogachev)c

## 1.0.0 April 20, 2023

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -25,7 +25,7 @@
"yiisoft/db": "^1.2",
"yiisoft/db-migration": "^1.1",
"yiisoft/friendly-exception": "^1.1",
"yiisoft/rbac": "dev-master#cba39d8471677970282fdad302271c858f5c7912"
"yiisoft/rbac": "dev-master"
},
"require-dev": {
"ext-pdo_sqlite": "*",
Expand Down
Expand Up @@ -26,10 +26,10 @@ private function createAssignmentsTable(MigrationBuilder $b): void
$b->createTable(
self::ASSIGNMENTS_TABLE,
[
'itemName' => 'string(128) NOT NULL',
'userId' => 'string(128) NOT NULL',
'createdAt' => 'integer NOT NULL',
'PRIMARY KEY ([[itemName]], [[userId]])',
'item_name' => 'string(128) NOT NULL',
'user_id' => 'string(128) NOT NULL',
'created_at' => 'integer NOT NULL',
'PRIMARY KEY ([[item_name]], [[user_id]])',
],
);
}
Expand Down
6 changes: 3 additions & 3 deletions migrations/items/M240118192500CreateItemsTables.php
Expand Up @@ -32,9 +32,9 @@ private function createItemsTable(MigrationBuilder $b): void
'name' => 'string(128) NOT NULL PRIMARY KEY',
'type' => 'string(10) NOT NULL',
'description' => 'string(191)',
'ruleName' => 'string(64)',
'createdAt' => 'integer NOT NULL',
'updatedAt' => 'integer NOT NULL',
'rule_name' => 'string(64)',
'created_at' => 'integer NOT NULL',
'updated_at' => 'integer NOT NULL',
],
);
$b->createIndex(self::ITEMS_TABLE, 'idx-' . self::ITEMS_TABLE . '-type', 'type');
Expand Down
68 changes: 34 additions & 34 deletions src/AssignmentsStorage.php
Expand Up @@ -15,9 +15,9 @@
* Storage for RBAC assignments in the form of database table. Operations are performed using Yii Database.
*
* @psalm-type RawAssignment = array{
* itemName: string,
* userId: string,
* createdAt: int|string,
* item_name: string,
* user_id: string,
* created_at: int|string,
* }
*/
final class AssignmentsStorage implements AssignmentsStorageInterface
Expand All @@ -43,10 +43,10 @@ public function getAll(): array

$assignments = [];
foreach ($rows as $row) {
$assignments[$row['userId']][$row['itemName']] = new Assignment(
$row['userId'],
$row['itemName'],
(int) $row['createdAt'],
$assignments[$row['user_id']][$row['item_name']] = new Assignment(
$row['user_id'],
$row['item_name'],
(int) $row['created_at'],
);
}

Expand All @@ -55,18 +55,18 @@ public function getAll(): array

public function getByUserId(string $userId): array
{
/** @psalm-var list<array{itemName: string, createdAt: int|string}> $rawAssignments */
/** @psalm-var list<array{item_name: string, created_at: int|string}> $rawAssignments */
$rawAssignments = (new Query($this->database))
->select(['itemName', 'createdAt'])
->select(['item_name', 'created_at'])
->from($this->tableName)
->where(['userId' => $userId])
->where(['user_id' => $userId])
->all();
$assignments = [];
foreach ($rawAssignments as $rawAssignment) {
$assignments[$rawAssignment['itemName']] = new Assignment(
$assignments[$rawAssignment['item_name']] = new Assignment(
$userId,
$rawAssignment['itemName'],
(int) $rawAssignment['createdAt'],
$rawAssignment['item_name'],
(int) $rawAssignment['created_at'],
);
}

Expand All @@ -82,14 +82,14 @@ public function getByItemNames(array $itemNames): array
/** @psalm-var RawAssignment[] $rawAssignments */
$rawAssignments = (new Query($this->database))
->from($this->tableName)
->where(['itemName' => $itemNames])
->where(['item_name' => $itemNames])
->all();
$assignments = [];
foreach ($rawAssignments as $rawAssignment) {
$assignments[] = new Assignment(
$rawAssignment['userId'],
$rawAssignment['itemName'],
(int) $rawAssignment['createdAt'],
$rawAssignment['user_id'],
$rawAssignment['item_name'],
(int) $rawAssignment['created_at'],
);
}

Expand All @@ -104,19 +104,19 @@ public function get(string $itemName, string $userId): ?Assignment
* - ArrayItemRemoval, select.
*/
$row = (new Query($this->database))
->select(['createdAt'])
->select(['created_at'])
->from($this->tableName)
->where(['itemName' => $itemName, 'userId' => $userId])
->where(['item_name' => $itemName, 'user_id' => $userId])
->one();

return $row === null ? null : new Assignment($userId, $itemName, (int) $row['createdAt']);
return $row === null ? null : new Assignment($userId, $itemName, (int) $row['created_at']);
}

public function exists(string $itemName, string $userId): bool
{
return (new Query($this->database))
->from($this->tableName)
->where(['itemName' => $itemName, 'userId' => $userId])
->where(['item_name' => $itemName, 'user_id' => $userId])
->exists();
}

Expand All @@ -128,20 +128,20 @@ public function userHasItem(string $userId, array $itemNames): bool

return (new Query($this->database))
->from($this->tableName)
->where(['userId' => $userId, 'itemName' => $itemNames])
->where(['user_id' => $userId, 'item_name' => $itemNames])
->exists();
}

public function filterUserItemNames(string $userId, array $itemNames): array
{
/** @var array{itemName: string} $rows */
/** @var array{item_name: string} $rows */
$rows = (new Query($this->database))
->select('itemName')
->select('item_name')
->from($this->tableName)
->where(['userId' => $userId, 'itemName' => $itemNames])
->where(['user_id' => $userId, 'item_name' => $itemNames])
->all();

return array_column($rows, 'itemName');
return array_column($rows, 'item_name');
}

public function add(Assignment $assignment): void
Expand All @@ -152,9 +152,9 @@ public function add(Assignment $assignment): void
->insert(
$this->tableName,
[
'itemName' => $assignment->getItemName(),
'userId' => $assignment->getUserId(),
'createdAt' => $assignment->getCreatedAt(),
'item_name' => $assignment->getItemName(),
'user_id' => $assignment->getUserId(),
'created_at' => $assignment->getCreatedAt(),
],
)
->execute();
Expand All @@ -164,7 +164,7 @@ public function hasItem(string $name): bool
{
return (new Query($this->database))
->from($this->tableName)
->where(['itemName' => $name])
->where(['item_name' => $name])
->exists();
}

Expand All @@ -173,7 +173,7 @@ public function renameItem(string $oldName, string $newName): void
$this
->database
->createCommand()
->update($this->tableName, columns: ['itemName' => $newName], condition: ['itemName' => $oldName])
->update($this->tableName, columns: ['item_name' => $newName], condition: ['item_name' => $oldName])
->execute();
}

Expand All @@ -182,7 +182,7 @@ public function remove(string $itemName, string $userId): void
$this
->database
->createCommand()
->delete($this->tableName, ['itemName' => $itemName, 'userId' => $userId])
->delete($this->tableName, ['item_name' => $itemName, 'user_id' => $userId])
->execute();
}

Expand All @@ -191,7 +191,7 @@ public function removeByUserId(string $userId): void
$this
->database
->createCommand()
->delete($this->tableName, ['userId' => $userId])
->delete($this->tableName, ['user_id' => $userId])
->execute();
}

Expand All @@ -200,7 +200,7 @@ public function removeByItemName(string $itemName): void
$this
->database
->createCommand()
->delete($this->tableName, ['itemName' => $itemName])
->delete($this->tableName, ['item_name' => $itemName])
->execute();
}

Expand Down
6 changes: 3 additions & 3 deletions src/ItemTreeTraversal/ItemTreeTraversalInterface.php
Expand Up @@ -17,9 +17,9 @@
* type: Item::TYPE_*,
* name: string,
* description: string|null,
* ruleName: string|null,
* createdAt: int|string,
* updatedAt: int|string,
* rule_name: string|null,
* created_at: int|string,
* updated_at: int|string,
* children: string|null
* }>
*
Expand Down
64 changes: 26 additions & 38 deletions src/ItemsStorage.php
Expand Up @@ -27,25 +27,25 @@
* type: Item::TYPE_*,
* name: string,
* description: string|null,
* ruleName: string|null,
* createdAt: int|string,
* updatedAt: int|string
* rule_name: string|null,
* created_at: int|string,
* updated_at: int|string
* }
* @psalm-type RawRole = array{
* type: Item::TYPE_ROLE,
* name: string,
* description: string|null,
* ruleName: string|null,
* createdAt: int|string,
* updatedAt: int|string
* rule_name: string|null,
* created_at: int|string,
* updated_at: int|string
* }
* @psalm-type RawPermission = array{
* type: Item::TYPE_PERMISSION,
* name: string,
* description: string|null,
* ruleName: string|null,
* createdAt: int|string,
* updatedAt: int|string
* rule_name: string|null,
* created_at: int|string,
* updated_at: int|string
* }
*/
final class ItemsStorage implements ItemsStorageInterface
Expand Down Expand Up @@ -130,7 +130,7 @@ public function get(string $name): Permission|Role|null
->where(['name' => $name])
->one();

return $row === null ? null : $this->createItem(...$row);
return $row === null ? null : $this->createItem($row);
}

public function exists(string $name): bool
Expand Down Expand Up @@ -295,7 +295,7 @@ public function getAccessTree(string $name): array
? explode($this->namesSeparator, $data['children'])
: [];
unset($data['children']);
$tree[$data['name']] = ['item' => $this->createItem(...$data)];
$tree[$data['name']] = ['item' => $this->createItem($data)];
}

foreach ($tree as $index => $_item) {
Expand Down Expand Up @@ -460,43 +460,31 @@ private function getItemByTypeAndName(string $type, string $name): Permission|Ro
->where(['type' => $type, 'name' => $name])
->one();

return $row === null ? null : $this->createItem(...$row);
return $row === null ? null : $this->createItem($row);
}

/**
* A factory method for creating single item with all attributes filled.
*
* @param string $type Either {@see Item::TYPE_ROLE} or {@see Item::TYPE_PERMISSION}.
* @psalm-param Item::TYPE_* $type
*
* @param string $name Unique name.
* @param int|string $createdAt UNIX timestamp for creation time.
* @param int|string $updatedAt UNIX timestamp for updating time.
* @param string|null $description Optional description.
* @param string|null $ruleName Optional associated rule name.
* @psalm-param RawPermission|RawRole $rawItem
*
* @return Permission|Role Either role or permission, depending on initial type specified.
* @psalm-return ($type is Item::TYPE_PERMISSION ? Permission : Role)
*/
private function createItem(
string $type,
string $name,
int|string $createdAt,
int|string $updatedAt,
string|null $description = null,
string|null $ruleName = null,
): Permission|Role {
private function createItem(array $rawItem): Permission|Role
{
$item = $this
->createItemByTypeAndName($type, $name)
->withCreatedAt((int) $createdAt)
->withUpdatedAt((int) $updatedAt);

if ($description !== null) {
$item = $item->withDescription($description);
->createItemByTypeAndName($rawItem['type'], $rawItem['name'])
->withDescription($rawItem['description'] ?? '')
->withRuleName($rawItem['rule_name'] ?? null)
->withCreatedAt((int) $rawItem['created_at'])
->withUpdatedAt((int) $rawItem['updated_at']);

if ($rawItem['description'] !== null) {
$item = $item->withDescription($rawItem['description']);
}

if ($ruleName !== null) {
$item = $item->withRuleName($ruleName);
if ($rawItem['rule_name'] !== null) {

Check warning on line 486 in src/ItemsStorage.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "NotIdentical": --- Original +++ New @@ @@ if ($rawItem['description'] !== null) { $item = $item->withDescription($rawItem['description']); } - if ($rawItem['rule_name'] !== null) { + if ($rawItem['rule_name'] === null) { $item = $item->withRuleName($rawItem['rule_name']); } return $item;
$item = $item->withRuleName($rawItem['rule_name']);
}

return $item;
Expand Down Expand Up @@ -607,7 +595,7 @@ private function getItemsIndexedByName(array $rawItems): array
$items = [];

foreach ($rawItems as $rawItem) {
$items[$rawItem['name']] = $this->createItem(...$rawItem);
$items[$rawItem['name']] = $this->createItem($rawItem);
}

return $items;
Expand Down
4 changes: 2 additions & 2 deletions tests/Base/AssignmentsStorageTest.php
Expand Up @@ -35,7 +35,7 @@ protected function populateItemsStorage(): void
->createCommand()
->batchInsert(
self::$itemsTable,
['name', 'type', 'createdAt', 'updatedAt'],
['name', 'type', 'created_at', 'updated_at'],
$this->getFixtures()['items'],
)
->execute();
Expand All @@ -47,7 +47,7 @@ protected function populateAssignmentsStorage(): void
->createCommand()
->batchInsert(
self::$assignmentsTable,
['itemName', 'userId', 'createdAt'],
['item_name', 'user_id', 'created_at'],
$this->getFixtures()['assignments'],
)
->execute();
Expand Down
2 changes: 1 addition & 1 deletion tests/Base/ItemsStorageTest.php
Expand Up @@ -159,7 +159,7 @@ protected function populateItemsStorage(): void
$this
->getDatabase()
->createCommand()
->batchInsert(self::$itemsTable, ['name', 'type', 'createdAt', 'updatedAt'], $fixtures['items'])
->batchInsert(self::$itemsTable, ['name', 'type', 'created_at', 'updated_at'], $fixtures['items'])
->execute();
$this
->getDatabase()
Expand Down

0 comments on commit ac56329

Please sign in to comment.