Skip to content

Commit d110371

Browse files
committed
fix: remove strict index naming rule
1 parent 4e276e2 commit d110371

4 files changed

Lines changed: 30 additions & 42 deletions

File tree

compose.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ services:
3838
DYNAMODB_TABLE_ATTRIBUTE_DEFINITIONS: "AttributeName=PK,AttributeType=S AttributeName=SK,AttributeType=S"
3939
DYNAMODB_TABLE_INDEX_NAME: test-table-index
4040
DYNAMODB_TABLE_INDEX_KEY_SCHEMA: "AttributeName=PK,KeyType=HASH AttributeName=SK,KeyType=RANGE"
41-
DYNAMODB_TABLE_INDEX_ATTRIBUTE_DEFINITIONS: 'AttributeName=PK,AttributeType=S AttributeName=SK,AttributeType=S AttributeName=GSI1_PK,AttributeType=S AttributeName=GSI1_SK,AttributeType=S AttributeName=LSI1_SK,AttributeType=S'
42-
DYNAMODB_TABLE_INDEX_LSI_DEFINITIONS: '[{"IndexName":"LSI1","KeySchema":[{"AttributeName":"PK","KeyType":"HASH"}, {"AttributeName":"LSI1_SK","KeyType":"RANGE"}],"Projection":{"ProjectionType":"ALL"}}]'
43-
DYNAMODB_TABLE_INDEX_GSI_DEFINITIONS: '[{"IndexName":"GSI1","KeySchema":[{"AttributeName":"GSI1_PK","KeyType":"HASH"}, {"AttributeName":"GSI1_SK","KeyType":"RANGE"}],"Projection":{"ProjectionType":"ALL"},"ProvisionedThroughput":{"ReadCapacityUnits":5,"WriteCapacityUnits":5}}]'
41+
DYNAMODB_TABLE_INDEX_ATTRIBUTE_DEFINITIONS: 'AttributeName=PK,AttributeType=S AttributeName=SK,AttributeType=S AttributeName=name,AttributeType=S AttributeName=type,AttributeType=S AttributeName=creationDateId,AttributeType=S'
42+
DYNAMODB_TABLE_INDEX_LSI_DEFINITIONS: '[{"IndexName":"LSI1","KeySchema":[{"AttributeName":"PK","KeyType":"HASH"}, {"AttributeName":"name","KeyType":"RANGE"}],"Projection":{"ProjectionType":"ALL"}}]'
43+
DYNAMODB_TABLE_INDEX_GSI_DEFINITIONS: '[{"IndexName":"GSI1","KeySchema":[{"AttributeName":"type","KeyType":"HASH"}, {"AttributeName":"creationDateId","KeyType":"RANGE"}], "Projection":{"ProjectionType":"ALL"},"ProvisionedThroughput":{"ReadCapacityUnits":5,"WriteCapacityUnits":5}}, {"IndexName":"GSI2","KeySchema":[{"AttributeName":"type","KeyType":"HASH"}, {"AttributeName":"name","KeyType":"RANGE"}], "Projection":{"ProjectionType":"ALL"},"ProvisionedThroughput":{"ReadCapacityUnits":5,"WriteCapacityUnits":5}}]'
4444
DYNAMODB_SHARE_DB: 1
4545
volumes:
4646
- .docker/localstack/init-aws.sh:/etc/localstack/init/ready.d/init-aws.sh

src/Serializer/EntityNormalizer.php

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,12 @@ public function __construct(
3636
public function normalize(object $entity, bool $includePrimaryKey = true): array
3737
{
3838
$primaryKey = $includePrimaryKey ? $this->normalizePrimaryKey($entity) : [];
39-
$attributes = $this->normalizeAttributes($entity);
40-
$indexes = $this->normalizeIndexesFromEntity($entity);
4139

42-
$item = [...$primaryKey, ...$attributes];
43-
44-
$overlappingIndexFields = array_intersect_key($indexes, $item);
45-
46-
if (false === empty($overlappingIndexFields)) {
47-
throw new InvalidEntityException(
48-
sprintf(
49-
'Index attributes cannot have overlap other item attributes: %s',
50-
json_encode(array_keys($overlappingIndexFields))
51-
)
52-
);
53-
}
54-
55-
return [...$item, ...$indexes];
40+
return [
41+
...$primaryKey,
42+
...$this->normalizeAttributes($entity),
43+
...$this->normalizeIndexesFromEntity($entity),
44+
];
5645
}
5746

5847
/**
@@ -371,19 +360,10 @@ protected function normalizeIndexesFromEntity(object $entity): array
371360
$normalized = [];
372361

373362
foreach ($indexes as $index) {
374-
$currentNormalized = $this->normalizeIndexFromEntity($entity, $index);
375-
$overlappingKeys = array_intersect_key($currentNormalized, $normalized);
376-
377-
if (false === empty($overlappingKeys)) {
378-
throw new InvalidEntityException(
379-
sprintf(
380-
'Index attributes cannot overlap other index attributes: %s',
381-
json_encode(array_keys($overlappingKeys))
382-
)
383-
);
384-
}
385-
386-
$normalized = [...$normalized, ...$currentNormalized];
363+
$normalized = [
364+
...$normalized,
365+
...$this->normalizeIndexFromEntity($entity, $index),
366+
];
387367
}
388368

389369
return $normalized;

tests/Integration/ODM/EntityManagerTest.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use EduardoMarques\DynamoPHP\Tests\Integration\Stubs\EntityA;
1414
use EduardoMarques\DynamoPHP\Tests\Integration\Stubs\EntityB;
1515
use EduardoMarques\DynamoPHP\Tests\Integration\Stubs\EntityC;
16+
use EduardoMarques\DynamoPHP\Tests\Integration\Stubs\EnumA;
1617
use PHPUnit\Framework\Attributes\Test;
1718
use PHPUnit\Framework\TestCase;
1819

@@ -169,10 +170,11 @@ public function itQueriesEntitiesOnLocalIndex(): void
169170

170171
$queryArgs = (new QueryArgs())
171172
->indexName('LSI1')
172-
->keyConditionExpression('PK = :pk AND begins_with(LSI1_SK, :sk)')
173+
->keyConditionExpression('PK = :pk AND begins_with(#name, :name)')
174+
->expressionAttributeNames(['#name' => 'name'])
173175
->expressionAttributeValues([
174176
':pk' => $id1,
175-
':sk' => 'J',
177+
':name' => 'J',
176178
]);
177179

178180
$result = self::$entityManager->query(EntityC::class, $queryArgs);
@@ -195,10 +197,11 @@ public function itQueriesEntitiesOnGlobalIndex(): void
195197

196198
$queryArgs = (new QueryArgs())
197199
->indexName('GSI1')
198-
->keyConditionExpression('GSI1_PK = :pk AND begins_with(GSI1_SK, :sk)')
200+
->keyConditionExpression('#type = :type AND begins_with(creationDateId, :creationDateId)')
201+
->expressionAttributeNames(['#type' => 'type'])
199202
->expressionAttributeValues([
200-
':pk' => 'John Doe',
201-
':sk' => '879',
203+
':type' => EnumA::TYPE_A,
204+
':creationDateId' => '2025',
202205
]);
203206

204207
$result = self::$entityManager->query(EntityC::class, $queryArgs);

tests/Integration/Stubs/EntityC.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@
2020
indexes: [
2121
new GlobalIndex(
2222
name: 'GSI1',
23-
partitionKey: new PartitionKey(fields: ['name'], name: 'GSI1_PK'),
24-
sortKey: new SortKey(fields: ['id'], name: 'GSI1_SK')
23+
partitionKey: new PartitionKey(fields: ['type'], name: 'type'),
24+
sortKey: new SortKey(fields: ['creationDate', 'id'], name: 'creationDateId')
2525
),
26-
new LocalIndex(name: 'LSI1', sortKey: new SortKey(fields: ['name'], name: 'LSI1_SK')),
26+
new GlobalIndex(
27+
name: 'GSI2',
28+
partitionKey: new PartitionKey(fields: ['type'], name: 'type'),
29+
sortKey: new SortKey(fields: ['name'], name: 'name')
30+
),
31+
new LocalIndex(name: 'LSI1', sortKey: new SortKey(fields: ['name'], name: 'name')),
2732
]
2833
)]
2934
final class EntityC
@@ -32,8 +37,8 @@ final class EntityC
3237
#[SerializedName('fullName')]
3338
public string $name;
3439

35-
#[Attribute(name: 'type')]
36-
public EnumA $enumA = EnumA::TYPE_A;
40+
#[Attribute]
41+
public EnumA $type = EnumA::TYPE_A;
3742

3843
public EntityB $b;
3944

0 commit comments

Comments
 (0)