Skip to content

Commit e6c819a

Browse files
committed
update documents
1 parent 907a7e4 commit e6c819a

File tree

5 files changed

+93
-76
lines changed

5 files changed

+93
-76
lines changed

src/Database/Adapter/MariaDB.php

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,6 +1380,10 @@ public function updateDocument(string $collection, string $id, Document $documen
13801380
*/
13811381
public function updateDocuments(string $collection, Document $updates, array $documents): int
13821382
{
1383+
if (empty($documents)) {
1384+
return 0;
1385+
}
1386+
13831387
$attributes = $updates->getAttributes();
13841388

13851389
if (!empty($updates->getUpdatedAt())) {
@@ -1396,24 +1400,13 @@ public function updateDocuments(string $collection, Document $updates, array $do
13961400

13971401
$name = $this->filter($collection);
13981402

1399-
$columns = '';
1400-
1401-
$where = [];
1402-
1403-
$ids = \array_map(fn ($document) => $document->getId(), $documents);
1404-
$where[] = "_uid IN (" . \implode(', ', \array_map(fn ($index) => ":_id_{$index}", \array_keys($ids))) . ")";
1405-
1406-
if ($this->sharedTables) {
1407-
$where[] = "_tenant = :_tenant";
1408-
}
1409-
1410-
$sqlWhere = 'WHERE ' . implode(' AND ', $where);
1403+
$internalIds = \array_map(fn ($document) => $document->getInternalId(), $documents);
14111404

14121405
$bindIndex = 0;
1406+
$columns = '';
14131407
foreach ($attributes as $attribute => $value) {
14141408
$column = $this->filter($attribute);
1415-
$bindKey = 'key_' . $bindIndex;
1416-
$columns .= "`{$column}`" . '=:' . $bindKey;
1409+
$columns .= "{$this->quote($column)} = :key_{$bindIndex}";
14171410

14181411
if ($attribute !== \array_key_last($attributes)) {
14191412
$columns .= ',';
@@ -1425,22 +1418,24 @@ public function updateDocuments(string $collection, Document $updates, array $do
14251418
$sql = "
14261419
UPDATE {$this->getSQLTable($name)}
14271420
SET {$columns}
1428-
{$sqlWhere}
1421+
WHERE _id IN (" . \implode(', ', \array_map(fn ($index) => ":_id_{$index}", \array_keys($internalIds))) . ")
1422+
{$this->getTenantQuery($collection)}
14291423
";
1430-
1424+
var_dump($this->sharedTables);
1425+
var_dump($sql);
14311426
$sql = $this->trigger(Database::EVENT_DOCUMENTS_UPDATE, $sql);
14321427
$stmt = $this->getPDO()->prepare($sql);
14331428

14341429
if ($this->sharedTables) {
14351430
$stmt->bindValue(':_tenant', $this->tenant);
14361431
}
14371432

1438-
foreach ($ids as $id => $value) {
1433+
foreach ($internalIds as $id => $value) {
14391434
$stmt->bindValue(":_id_{$id}", $value);
14401435
}
14411436

14421437
$attributeIndex = 0;
1443-
foreach ($attributes as $attribute => $value) {
1438+
foreach ($attributes as $value) {
14441439
if (is_array($value)) {
14451440
$value = json_encode($value);
14461441
}
@@ -2678,4 +2673,9 @@ public function getSupportForSchemaAttributes(): bool
26782673
return true;
26792674
}
26802675

2676+
protected function quote(string $string): string
2677+
{
2678+
return "`{$string}`";
2679+
}
2680+
26812681
}

src/Database/Adapter/Postgres.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,4 +2452,9 @@ public function getConnectionId(): string
24522452
$stmt = $this->getPDO()->query("SELECT pg_backend_pid();");
24532453
return $stmt->fetchColumn();
24542454
}
2455+
2456+
protected function quote(string $string): string
2457+
{
2458+
return "\"{$string}\"";
2459+
}
24552460
}

src/Database/Adapter/SQL.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,4 +1287,10 @@ public function deleteDocuments(string $collection, array $internalIds, array $p
12871287

12881288
return $stmt->rowCount();
12891289
}
1290+
1291+
/**
1292+
* @param string $string
1293+
* @return string
1294+
*/
1295+
abstract protected function quote(string $string): string;
12901296
}

src/Database/Database.php

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4165,78 +4165,76 @@ public function updateDocuments(string $collection, Document $updates, array $qu
41654165
throw new StructureException($validator->getDescription());
41664166
}
41674167

4168-
$documents = $this->withTransaction(function () use ($collection, $queries, $batchSize, $updates, $limit, $cursor, $authorization, $skipAuth) {
4169-
$documents = [];
4170-
$originalLimit = $limit;
4171-
$lastDocument = $cursor;
4172-
4173-
// Resolve and update relationships
4174-
while (true) {
4175-
if ($limit && $limit < $batchSize) {
4176-
$batchSize = $limit;
4177-
} elseif (!empty($limit)) {
4178-
$limit -= $batchSize;
4179-
}
4168+
$documents = [];
4169+
$originalLimit = $limit;
4170+
$lastDocument = $cursor;
41804171

4181-
$new = [
4182-
Query::limit($batchSize)
4183-
];
4172+
// Resolve and update relationships
4173+
while (true) {
4174+
if ($limit && $limit < $batchSize) {
4175+
$batchSize = $limit;
4176+
} elseif (!empty($limit)) {
4177+
$limit -= $batchSize;
4178+
}
41844179

4185-
if (! empty($lastDocument)) {
4186-
$new[] = Query::cursorAfter($lastDocument);
4187-
}
4180+
$new = [
4181+
Query::limit($batchSize)
4182+
];
41884183

4189-
$affectedDocuments = $this->silent(fn () => $this->find(
4190-
$collection->getId(),
4191-
array_merge($new, $queries),
4192-
forPermission: Database::PERMISSION_UPDATE
4193-
));
4184+
if (! empty($lastDocument)) {
4185+
$new[] = Query::cursorAfter($lastDocument);
4186+
}
41944187

4195-
if (empty($affectedDocuments)) {
4196-
break;
4197-
}
4188+
$affectedDocuments = $this->silent(fn () => $this->find(
4189+
$collection->getId(),
4190+
array_merge($new, $queries),
4191+
forPermission: Database::PERMISSION_UPDATE
4192+
));
41984193

4199-
foreach ($affectedDocuments as $document) {
4200-
if ($this->resolveRelationships) {
4201-
$newDocument = new Document(array_merge($document->getArrayCopy(), $updates->getArrayCopy()));
4202-
$this->silent(fn () => $this->updateDocumentRelationships($collection, $document, $newDocument));
4203-
$documents[] = $newDocument;
4204-
}
4194+
if (empty($affectedDocuments)) {
4195+
break;
4196+
}
42054197

4206-
// Check if document was updated after the request timestamp
4207-
try {
4208-
$oldUpdatedAt = new \DateTime($document->getUpdatedAt());
4209-
} catch (Exception $e) {
4210-
throw new DatabaseException($e->getMessage(), $e->getCode(), $e);
4211-
}
4198+
foreach ($affectedDocuments as $document) {
4199+
if ($this->resolveRelationships) {
4200+
$newDocument = new Document(array_merge($document->getArrayCopy(), $updates->getArrayCopy()));
4201+
$this->silent(fn () => $this->updateDocumentRelationships($collection, $document, $newDocument));
4202+
$documents[] = $newDocument;
4203+
}
42124204

4213-
if (!is_null($this->timestamp) && $oldUpdatedAt > $this->timestamp) {
4214-
throw new ConflictException('Document was updated after the request timestamp');
4215-
}
4205+
// Check if document was updated after the request timestamp
4206+
try {
4207+
$oldUpdatedAt = new \DateTime($document->getUpdatedAt());
4208+
} catch (Exception $e) {
4209+
throw new DatabaseException($e->getMessage(), $e->getCode(), $e);
42164210
}
42174211

4212+
if (!is_null($this->timestamp) && $oldUpdatedAt > $this->timestamp) {
4213+
throw new ConflictException('Document was updated after the request timestamp');
4214+
}
4215+
}
4216+
4217+
$this->withTransaction(function () use ($collection, $updates, $authorization, $skipAuth, $affectedDocuments) {
42184218
$getResults = fn () => $this->adapter->updateDocuments(
42194219
$collection->getId(),
42204220
$updates,
42214221
$affectedDocuments
42224222
);
42234223

42244224
$skipAuth ? $authorization->skip($getResults) : $getResults();
4225+
});
42254226

4226-
if (count($affectedDocuments) < $batchSize) {
4227-
break;
4228-
} elseif ($originalLimit && count($documents) == $originalLimit) {
4229-
break;
4230-
}
4231-
4232-
$lastDocument = end($affectedDocuments);
4227+
foreach ($documents as $document) {
4228+
$this->purgeCachedDocument($collection->getId(), $document->getId());
42334229
}
42344230

4235-
return $documents;
4236-
});
4231+
if (count($affectedDocuments) < $batchSize) {
4232+
break;
4233+
} elseif ($originalLimit && count($documents) == $originalLimit) {
4234+
break;
4235+
}
42374236

4238-
foreach ($documents as $document) {
4239-
$this->purgeCachedDocument($collection->getId(), $document->getId());
4237+
$lastDocument = end($affectedDocuments);
42404238
}
42414239

42424240
$this->trigger(self::EVENT_DOCUMENTS_UPDATE, new Document([

tests/e2e/Adapter/Base.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16206,6 +16206,9 @@ public function testSharedTables(): void
1620616206
* Default mode already tested, we'll test 'schema' and 'table' isolation here
1620716207
*/
1620816208
$database = static::getDatabase();
16209+
$sharedTables = $database->getSharedTables();
16210+
$namespace = $database->getNamespace();
16211+
$schema = $database->getDatabase();
1620916212

1621016213
if (!$database->getAdapter()->getSupportForSchemas()) {
1621116214
$this->expectNotToPerformAssertions();
@@ -16373,14 +16376,18 @@ public function testSharedTables(): void
1637316376
}
1637416377

1637516378
// Reset state
16376-
$database->setSharedTables(false);
16377-
$database->setNamespace(static::$namespace);
16378-
$database->setDatabase($this->testDatabase);
16379+
$database
16380+
->setSharedTables($sharedTables)
16381+
->setNamespace($namespace)
16382+
->setDatabase($schema);
1637916383
}
1638016384

1638116385
public function testSharedTablesDuplicates(): void
1638216386
{
1638316387
$database = static::getDatabase();
16388+
$sharedTables = $database->getSharedTables();
16389+
$namespace = $database->getNamespace();
16390+
$schema = $database->getDatabase();
1638416391

1638516392
if (!$database->getAdapter()->getSupportForSchemas()) {
1638616393
$this->expectNotToPerformAssertions();
@@ -16433,9 +16440,10 @@ public function testSharedTablesDuplicates(): void
1643316440
$this->assertEquals(1, \count($collection->getAttribute('attributes')));
1643416441
$this->assertEquals(1, \count($collection->getAttribute('indexes')));
1643516442

16436-
$database->setSharedTables(false);
16437-
$database->setNamespace(static::$namespace);
16438-
$database->setDatabase($this->testDatabase);
16443+
$database
16444+
->setSharedTables($sharedTables)
16445+
->setNamespace($namespace)
16446+
->setDatabase($schema);
1643916447
}
1644016448

1644116449
public function testSharedTablesTenantPerDocument(): void

0 commit comments

Comments
 (0)