Skip to content

Commit b9c7f4d

Browse files
committed
Fix Mongo cursor pagination, SQL tenant-per-document pre-filter, and revert deferred relationships
- Mongo: set batchSize and iterate with getMore to handle >101 existing UIDs - SQL: group by per-document tenant in pre-filter when tenantPerDocument is true - Revert deferred relationship creation — createDocumentRelationships must run before INSERT to prepare the document structure
1 parent 9653052 commit b9c7f4d

2 files changed

Lines changed: 47 additions & 9 deletions

File tree

src/Database/Adapter/Mongo.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,16 +1492,28 @@ public function createDocuments(Document $collection, array $documents, bool $ig
14921492
if ($ignore && !empty($records)) {
14931493
$uids = \array_filter(\array_map(fn ($r) => $r['_uid'] ?? null, $records));
14941494
if (!empty($uids)) {
1495-
$findOptions = $this->getTransactionOptions(['projection' => ['_uid' => 1]]);
1496-
$filters = ['_uid' => ['$in' => \array_values($uids)]];
1495+
$uidValues = \array_values(\array_unique($uids));
1496+
$findOptions = $this->getTransactionOptions([
1497+
'projection' => ['_uid' => 1],
1498+
'batchSize' => \count($uidValues),
1499+
]);
1500+
$filters = ['_uid' => ['$in' => $uidValues]];
14971501
if ($this->sharedTables) {
14981502
$filters['_tenant'] = $this->getTenantFilters($collection->getId());
14991503
}
1500-
$result = $this->client->find($name, $filters, $findOptions);
1504+
$response = $this->client->find($name, $filters, $findOptions);
15011505
$existingUids = [];
1502-
foreach ($result->cursor->firstBatch ?? [] as $doc) {
1506+
foreach ($response->cursor->firstBatch ?? [] as $doc) {
15031507
$existingUids[$doc->_uid] = true;
15041508
}
1509+
$cursorId = $response->cursor->id ?? null;
1510+
while ($cursorId && $cursorId !== 0) {
1511+
$more = $this->client->getMore((int)$cursorId, $name, \count($uidValues));
1512+
foreach ($more->cursor->nextBatch ?? [] as $doc) {
1513+
$existingUids[$doc->_uid] = true;
1514+
}
1515+
$cursorId = (int)($more->cursor->id ?? 0);
1516+
}
15051517

15061518
if (!empty($existingUids)) {
15071519
$filteredRecords = [];

src/Database/Adapter/SQL.php

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,11 +2495,26 @@ public function createDocuments(Document $collection, array $documents, bool $ig
24952495

24962496
$tenantFilter = '';
24972497
if ($this->sharedTables) {
2498-
$tenantFilter = ' AND _tenant = :_dup_tenant';
2499-
$binds[':_dup_tenant'] = $this->getTenant();
2498+
if ($this->tenantPerDocument) {
2499+
// In tenant-per-document mode, check against all distinct tenants in the batch
2500+
$tenants = \array_values(\array_unique(\array_filter(
2501+
\array_map(fn (Document $doc) => $doc->getTenant(), $documents)
2502+
)));
2503+
$tenantPlaceholders = [];
2504+
foreach ($tenants as $j => $tenant) {
2505+
$tKey = ':_dup_tenant_' . $j;
2506+
$tenantPlaceholders[] = $tKey;
2507+
$binds[$tKey] = $tenant;
2508+
}
2509+
$tenantFilter = ' AND _tenant IN (' . \implode(', ', $tenantPlaceholders) . ')';
2510+
} else {
2511+
$tenantFilter = ' AND _tenant = :_dup_tenant';
2512+
$binds[':_dup_tenant'] = $this->getTenant();
2513+
}
25002514
}
25012515

2502-
$sql = 'SELECT _uid FROM ' . $this->getSQLTable($name)
2516+
$tenantSelect = $this->sharedTables && $this->tenantPerDocument ? ', _tenant' : '';
2517+
$sql = 'SELECT _uid' . $tenantSelect . ' FROM ' . $this->getSQLTable($name)
25032518
. ' WHERE _uid IN (' . \implode(', ', $placeholders) . ')'
25042519
. $tenantFilter;
25052520

@@ -2508,10 +2523,21 @@ public function createDocuments(Document $collection, array $documents, bool $ig
25082523
$stmt->bindValue($k, $v, $this->getPDOType($v));
25092524
}
25102525
$stmt->execute();
2511-
$existingUids = \array_flip(\array_column($stmt->fetchAll(), '_uid'));
2526+
$rows = $stmt->fetchAll();
25122527
$stmt->closeCursor();
25132528

2514-
if (!empty($existingUids)) {
2529+
if ($this->sharedTables && $this->tenantPerDocument) {
2530+
// Build composite keys for tenant-per-document lookups
2531+
$existingKeys = [];
2532+
foreach ($rows as $row) {
2533+
$existingKeys[$row['_tenant'] . ':' . $row['_uid']] = true;
2534+
}
2535+
$documents = \array_values(\array_filter(
2536+
$documents,
2537+
fn (Document $doc) => !isset($existingKeys[$doc->getTenant() . ':' . $doc->getId()])
2538+
));
2539+
} else {
2540+
$existingUids = \array_flip(\array_column($rows, '_uid'));
25152541
$documents = \array_values(\array_filter(
25162542
$documents,
25172543
fn (Document $doc) => !isset($existingUids[$doc->getId()])

0 commit comments

Comments
 (0)