Skip to content

Commit 84cbadf

Browse files
added document mutation fix for the creaetDocuments and tests for schemaless dates operation
1 parent 0c12424 commit 84cbadf

File tree

2 files changed

+230
-6
lines changed

2 files changed

+230
-6
lines changed

src/Database/Database.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4049,17 +4049,17 @@ public function createDocuments(
40494049

40504050
$batch = $this->adapter->getSequences($collection->getId(), $batch);
40514051

4052-
foreach ($batch as $document) {
4053-
$document = $this->adapter->castingAfter($collection, $document);
4052+
foreach ($batch as $doc) {
4053+
$doc = $this->adapter->castingAfter($collection, $doc);
40544054
if ($this->resolveRelationships) {
4055-
$document = $this->silent(fn () => $this->populateDocumentRelationships($collection, $document));
4055+
$doc = $this->silent(fn () => $this->populateDocumentRelationships($collection, $doc));
40564056
}
40574057

4058-
$document = $this->casting($collection, $document);
4059-
$document = $this->decode($collection, $document);
4058+
$doc = $this->casting($collection, $doc);
4059+
$doc = $this->decode($collection, $doc);
40604060

40614061
try {
4062-
$onNext && $onNext($document);
4062+
$onNext && $onNext($doc);
40634063
} catch (\Throwable $e) {
40644064
$onError ? $onError($e) : throw $e;
40654065
}

tests/e2e/Adapter/Scopes/SchemalessTests.php

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,4 +964,228 @@ public function testSchemalessInternalAttributes(): void
964964
$database->deleteCollection($col);
965965
Authorization::cleanRoles();
966966
}
967+
968+
public function testSchemalessDates(): void
969+
{
970+
/** @var Database $database */
971+
$database = static::getDatabase();
972+
973+
if ($database->getAdapter()->getSupportForAttributes()) {
974+
$this->expectNotToPerformAssertions();
975+
return;
976+
}
977+
978+
$col = uniqid('sl_dates');
979+
$database->createCollection($col);
980+
981+
$permissions = [
982+
Permission::read(Role::any()),
983+
Permission::write(Role::any()),
984+
Permission::update(Role::any()),
985+
Permission::delete(Role::any())
986+
];
987+
988+
// Seed deterministic date strings
989+
$createdAt1 = '2000-01-01T10:00:00.000+00:00';
990+
$updatedAt1 = '2000-01-02T11:11:11.000+00:00';
991+
$curDate1 = '2000-01-05T05:05:05.000+00:00';
992+
993+
// createDocument with preserved dates
994+
$doc1 = $database->withPreserveDates(function () use ($database, $col, $permissions, $createdAt1, $updatedAt1, $curDate1) {
995+
return $database->createDocument($col, new Document([
996+
'$id' => 'd1',
997+
'$permissions' => $permissions,
998+
'$createdAt' => $createdAt1,
999+
'$updatedAt' => $updatedAt1,
1000+
'curDate' => $curDate1,
1001+
'counter' => 0,
1002+
]));
1003+
});
1004+
1005+
$this->assertEquals('d1', $doc1->getId());
1006+
$this->assertTrue(is_string($doc1->getAttribute('curDate')));
1007+
$this->assertEquals($curDate1, $doc1->getAttribute('curDate'));
1008+
$this->assertTrue(is_string($doc1->getAttribute('$createdAt')));
1009+
$this->assertTrue(is_string($doc1->getAttribute('$updatedAt')));
1010+
$this->assertEquals($createdAt1, $doc1->getAttribute('$createdAt'));
1011+
$this->assertEquals($updatedAt1, $doc1->getAttribute('$updatedAt'));
1012+
1013+
$fetched1 = $database->getDocument($col, 'd1');
1014+
$this->assertEquals($curDate1, $fetched1->getAttribute('curDate'));
1015+
$this->assertTrue(is_string($fetched1->getAttribute('curDate')));
1016+
$this->assertTrue(is_string($fetched1->getAttribute('$createdAt')));
1017+
$this->assertTrue(is_string($fetched1->getAttribute('$updatedAt')));
1018+
$this->assertEquals($createdAt1, $fetched1->getAttribute('$createdAt'));
1019+
$this->assertEquals($updatedAt1, $fetched1->getAttribute('$updatedAt'));
1020+
1021+
// createDocuments with preserved dates
1022+
$createdAt2 = '2001-02-03T04:05:06.000+00:00';
1023+
$updatedAt2 = '2001-02-04T04:05:07.000+00:00';
1024+
$curDate2 = '2001-02-05T06:07:08.000+00:00';
1025+
1026+
$createdAt3 = '2002-03-04T05:06:07.000+00:00';
1027+
$updatedAt3 = '2002-03-05T05:06:08.000+00:00';
1028+
$curDate3 = '2002-03-06T07:08:09.000+00:00';
1029+
1030+
$countCreated = $database->withPreserveDates(function () use ($database, $col, $permissions, $createdAt2, $updatedAt2, $curDate2, $createdAt3, $updatedAt3, $curDate3) {
1031+
return $database->createDocuments($col, [
1032+
new Document([
1033+
'$id' => 'd2',
1034+
'$permissions' => $permissions,
1035+
'$createdAt' => $createdAt2,
1036+
'$updatedAt' => $updatedAt2,
1037+
'curDate' => $curDate2,
1038+
]),
1039+
new Document([
1040+
'$id' => 'd3',
1041+
'$permissions' => $permissions,
1042+
'$createdAt' => $createdAt3,
1043+
'$updatedAt' => $updatedAt3,
1044+
'curDate' => $curDate3,
1045+
]),
1046+
]);
1047+
});
1048+
$this->assertEquals(2, $countCreated);
1049+
1050+
$fetched2 = $database->getDocument($col, 'd2');
1051+
$this->assertEquals($curDate2, $fetched2->getAttribute('curDate'));
1052+
$this->assertEquals($createdAt2, $fetched2->getAttribute('$createdAt'));
1053+
$this->assertEquals($updatedAt2, $fetched2->getAttribute('$updatedAt'));
1054+
1055+
$fetched3 = $database->getDocument($col, 'd3');
1056+
$this->assertEquals($curDate3, $fetched3->getAttribute('curDate'));
1057+
$this->assertEquals($createdAt3, $fetched3->getAttribute('$createdAt'));
1058+
$this->assertEquals($updatedAt3, $fetched3->getAttribute('$updatedAt'));
1059+
1060+
// updateDocument with preserved $updatedAt and custom date field
1061+
$newCurDate1 = '2000-02-01T00:00:00.000+00:00';
1062+
$newUpdatedAt1 = '2000-02-02T02:02:02.000+00:00';
1063+
$updated1 = $database->withPreserveDates(function () use ($database, $col, $newCurDate1, $newUpdatedAt1) {
1064+
return $database->updateDocument($col, 'd1', new Document([
1065+
'curDate' => $newCurDate1,
1066+
'$updatedAt' => $newUpdatedAt1,
1067+
]));
1068+
});
1069+
$this->assertEquals($newCurDate1, $updated1->getAttribute('curDate'));
1070+
$this->assertEquals($newUpdatedAt1, $updated1->getAttribute('$updatedAt'));
1071+
$refetched1 = $database->getDocument($col, 'd1');
1072+
$this->assertEquals($newCurDate1, $refetched1->getAttribute('curDate'));
1073+
$this->assertEquals($newUpdatedAt1, $refetched1->getAttribute('$updatedAt'));
1074+
1075+
// updateDocuments with preserved $updatedAt over a subset
1076+
$bulkCurDate = '2001-01-01T00:00:00.000+00:00';
1077+
$bulkUpdatedAt = '2001-01-02T00:00:00.000+00:00';
1078+
$updatedCount = $database->withPreserveDates(function () use ($database, $col, $bulkCurDate, $bulkUpdatedAt) {
1079+
return $database->updateDocuments(
1080+
$col,
1081+
new Document([
1082+
'curDate' => $bulkCurDate,
1083+
'$updatedAt' => $bulkUpdatedAt,
1084+
]),
1085+
[Query::equal('$id', ['d2', 'd3'])]
1086+
);
1087+
});
1088+
$this->assertEquals(2, $updatedCount);
1089+
$afterBulk2 = $database->getDocument($col, 'd2');
1090+
$afterBulk3 = $database->getDocument($col, 'd3');
1091+
$this->assertEquals($bulkCurDate, $afterBulk2->getAttribute('curDate'));
1092+
$this->assertEquals($bulkUpdatedAt, $afterBulk2->getAttribute('$updatedAt'));
1093+
$this->assertEquals($bulkCurDate, $afterBulk3->getAttribute('curDate'));
1094+
$this->assertEquals($bulkUpdatedAt, $afterBulk3->getAttribute('$updatedAt'));
1095+
1096+
// upsertDocument: create new then update existing with preserved dates
1097+
$createdAt4 = '2003-03-03T03:03:03.000+00:00';
1098+
$updatedAt4 = '2003-03-04T04:04:04.000+00:00';
1099+
$curDate4 = '2003-03-05T05:05:05.000+00:00';
1100+
$up1 = $database->withPreserveDates(function () use ($database, $col, $permissions, $createdAt4, $updatedAt4, $curDate4) {
1101+
return $database->upsertDocument($col, new Document([
1102+
'$id' => 'd4',
1103+
'$permissions' => $permissions,
1104+
'$createdAt' => $createdAt4,
1105+
'$updatedAt' => $updatedAt4,
1106+
'curDate' => $curDate4,
1107+
]));
1108+
});
1109+
$this->assertEquals('d4', $up1->getId());
1110+
$this->assertEquals($curDate4, $up1->getAttribute('curDate'));
1111+
$this->assertEquals($createdAt4, $up1->getAttribute('$createdAt'));
1112+
$this->assertEquals($updatedAt4, $up1->getAttribute('$updatedAt'));
1113+
1114+
$updatedAt4b = '2003-03-06T06:06:06.000+00:00';
1115+
$curDate4b = '2003-03-07T07:07:07.000+00:00';
1116+
$up2 = $database->withPreserveDates(function () use ($database, $col, $updatedAt4b, $curDate4b) {
1117+
return $database->upsertDocument($col, new Document([
1118+
'$id' => 'd4',
1119+
'curDate' => $curDate4b,
1120+
'$updatedAt' => $updatedAt4b,
1121+
]));
1122+
});
1123+
$this->assertEquals($curDate4b, $up2->getAttribute('curDate'));
1124+
$this->assertEquals($updatedAt4b, $up2->getAttribute('$updatedAt'));
1125+
$refetched4 = $database->getDocument($col, 'd4');
1126+
$this->assertEquals($curDate4b, $refetched4->getAttribute('curDate'));
1127+
$this->assertEquals($updatedAt4b, $refetched4->getAttribute('$updatedAt'));
1128+
1129+
// upsertDocuments: mix create and update with preserved dates
1130+
$createdAt5 = '2004-04-01T01:01:01.000+00:00';
1131+
$updatedAt5 = '2004-04-02T02:02:02.000+00:00';
1132+
$curDate5 = '2004-04-03T03:03:03.000+00:00';
1133+
$updatedAt2b = '2001-02-08T08:08:08.000+00:00';
1134+
$curDate2b = '2001-02-09T09:09:09.000+00:00';
1135+
1136+
$upCount = $database->withPreserveDates(function () use ($database, $col, $permissions, $createdAt5, $updatedAt5, $curDate5, $updatedAt2b, $curDate2b) {
1137+
return $database->upsertDocuments($col, [
1138+
new Document([
1139+
'$id' => 'd5',
1140+
'$permissions' => $permissions,
1141+
'$createdAt' => $createdAt5,
1142+
'$updatedAt' => $updatedAt5,
1143+
'curDate' => $curDate5,
1144+
]),
1145+
new Document([
1146+
'$id' => 'd2',
1147+
'$updatedAt' => $updatedAt2b,
1148+
'curDate' => $curDate2b,
1149+
]),
1150+
]);
1151+
});
1152+
$this->assertEquals(2, $upCount);
1153+
1154+
$fetched5 = $database->getDocument($col, 'd5');
1155+
$this->assertEquals($curDate5, $fetched5->getAttribute('curDate'));
1156+
$this->assertEquals($createdAt5, $fetched5->getAttribute('$createdAt'));
1157+
$this->assertEquals($updatedAt5, $fetched5->getAttribute('$updatedAt'));
1158+
1159+
$fetched2b = $database->getDocument($col, 'd2');
1160+
$this->assertEquals($curDate2b, $fetched2b->getAttribute('curDate'));
1161+
$this->assertEquals($updatedAt2b, $fetched2b->getAttribute('$updatedAt'));
1162+
1163+
// increase/decrease should not affect date types; ensure they remain strings
1164+
$afterInc = $database->increaseDocumentAttribute($col, 'd1', 'counter', 5);
1165+
$this->assertEquals(5, $afterInc->getAttribute('counter'));
1166+
$this->assertTrue(is_string($afterInc->getAttribute('curDate')));
1167+
$this->assertTrue(is_string($afterInc->getAttribute('$createdAt')));
1168+
$this->assertTrue(is_string($afterInc->getAttribute('$updatedAt')));
1169+
1170+
$afterIncFetched = $database->getDocument($col, 'd1');
1171+
$this->assertEquals(5, $afterIncFetched->getAttribute('counter'));
1172+
$this->assertTrue(is_string($afterIncFetched->getAttribute('curDate')));
1173+
$this->assertTrue(is_string($afterIncFetched->getAttribute('$createdAt')));
1174+
$this->assertTrue(is_string($afterIncFetched->getAttribute('$updatedAt')));
1175+
1176+
$afterDec = $database->decreaseDocumentAttribute($col, 'd1', 'counter', 2);
1177+
$this->assertEquals(3, $afterDec->getAttribute('counter'));
1178+
$this->assertTrue(is_string($afterDec->getAttribute('curDate')));
1179+
$this->assertTrue(is_string($afterDec->getAttribute('$createdAt')));
1180+
$this->assertTrue(is_string($afterDec->getAttribute('$updatedAt')));
1181+
1182+
$afterDecFetched = $database->getDocument($col, 'd1');
1183+
$this->assertEquals(3, $afterDecFetched->getAttribute('counter'));
1184+
$this->assertTrue(is_string($afterDecFetched->getAttribute('curDate')));
1185+
$this->assertTrue(is_string($afterDecFetched->getAttribute('$createdAt')));
1186+
$this->assertTrue(is_string($afterDecFetched->getAttribute('$updatedAt')));
1187+
1188+
$database->deleteCollection($col);
1189+
}
1190+
9671191
}

0 commit comments

Comments
 (0)