@@ -3242,4 +3242,266 @@ public function testSchemalessMongoDotNotationIndexes(): void
32423242
32433243 $ database ->deleteCollection ($ col );
32443244 }
3245+
3246+ public function testQueryWithDatetime (): void
3247+ {
3248+ /** @var Database $database */
3249+ $ database = static ::getDatabase ();
3250+
3251+ if ($ database ->getAdapter ()->getSupportForAttributes ()) {
3252+ $ this ->expectNotToPerformAssertions ();
3253+ return ;
3254+ }
3255+
3256+ $ col = uniqid ('sl_query_datetime ' );
3257+ $ database ->createCollection ($ col );
3258+
3259+ $ permissions = [
3260+ Permission::read (Role::any ()),
3261+ Permission::write (Role::any ()),
3262+ Permission::update (Role::any ()),
3263+ Permission::delete (Role::any ())
3264+ ];
3265+
3266+ // Documents with datetime field (ISO 8601) for query tests
3267+ // Dates: Jan 15 2024, Feb 20 2024, Mar 25 2024, Jun 15 2024, Dec 31 2024
3268+ $ docs = [
3269+ new Document ([
3270+ '$id ' => 'dt1 ' ,
3271+ '$permissions ' => $ permissions ,
3272+ 'name ' => 'January ' ,
3273+ 'datetime ' => '2024-01-15T10:30:00.000+00:00 '
3274+ ]),
3275+ new Document ([
3276+ '$id ' => 'dt2 ' ,
3277+ '$permissions ' => $ permissions ,
3278+ 'name ' => 'February ' ,
3279+ 'datetime ' => '2024-02-20T14:45:30.123Z '
3280+ ]),
3281+ new Document ([
3282+ '$id ' => 'dt3 ' ,
3283+ '$permissions ' => $ permissions ,
3284+ 'name ' => 'March ' ,
3285+ // Use a valid extended ISO 8601 datetime that will be normalized
3286+ // to MongoDB UTCDateTime for comparison queries.
3287+ 'datetime ' => '2024-03-25T08:15:45.000+00:00 '
3288+ ]),
3289+ new Document ([
3290+ '$id ' => 'dt4 ' ,
3291+ '$permissions ' => $ permissions ,
3292+ 'name ' => 'June ' ,
3293+ 'datetime ' => '2024-06-15T12:00:00.000Z '
3294+ ]),
3295+ new Document ([
3296+ '$id ' => 'dt5 ' ,
3297+ '$permissions ' => $ permissions ,
3298+ 'name ' => 'December ' ,
3299+ 'datetime ' => '2024-12-31T23:59:59.999+00:00 '
3300+ ]),
3301+ ];
3302+
3303+ $ createdCount = $ database ->createDocuments ($ col , $ docs );
3304+ $ this ->assertEquals (5 , $ createdCount );
3305+
3306+ // Query: equal - find document with exact datetime (Jan 15 2024)
3307+ $ equalResults = $ database ->find ($ col , [
3308+ Query::equal ('datetime ' , ['2024-01-15T10:30:00.000+00:00 ' ])
3309+ ]);
3310+ $ this ->assertCount (1 , $ equalResults );
3311+ $ this ->assertEquals ('dt1 ' , $ equalResults [0 ]->getId ());
3312+ $ this ->assertEquals ('January ' , $ equalResults [0 ]->getAttribute ('name ' ));
3313+
3314+ // Query: greaterThan - datetimes after 2024-03-01 (dt3, dt4, dt5)
3315+ $ greaterResults = $ database ->find ($ col , [
3316+ Query::greaterThan ('datetime ' , '2024-03-01T00:00:00.000Z ' )
3317+ ]);
3318+ $ this ->assertCount (3 , $ greaterResults );
3319+ $ greaterIds = array_map (fn ($ d ) => $ d ->getId (), $ greaterResults );
3320+ $ this ->assertContains ('dt3 ' , $ greaterIds );
3321+ $ this ->assertContains ('dt4 ' , $ greaterIds );
3322+ $ this ->assertContains ('dt5 ' , $ greaterIds );
3323+
3324+ // Query: lessThan - datetimes before 2024-03-01 (dt1, dt2)
3325+ $ lessResults = $ database ->find ($ col , [
3326+ Query::lessThan ('datetime ' , '2024-03-01T00:00:00.000Z ' )
3327+ ]);
3328+ $ this ->assertCount (2 , $ lessResults );
3329+ $ lessIds = array_map (fn ($ d ) => $ d ->getId (), $ lessResults );
3330+ $ this ->assertContains ('dt1 ' , $ lessIds );
3331+ $ this ->assertContains ('dt2 ' , $ lessIds );
3332+
3333+ // Query: greaterThanEqual - datetimes on or after 2024-02-20 (dt2, dt3, dt4, dt5)
3334+ $ gteResults = $ database ->find ($ col , [
3335+ Query::greaterThanEqual ('datetime ' , '2024-02-20T14:45:30.123Z ' )
3336+ ]);
3337+ $ this ->assertCount (4 , $ gteResults );
3338+ $ gteIds = array_map (fn ($ d ) => $ d ->getId (), $ gteResults );
3339+ $ this ->assertContains ('dt2 ' , $ gteIds );
3340+ $ this ->assertContains ('dt3 ' , $ gteIds );
3341+ $ this ->assertContains ('dt4 ' , $ gteIds );
3342+ $ this ->assertContains ('dt5 ' , $ gteIds );
3343+
3344+ // Query: lessThanEqual - datetimes on or before 2024-06-15 (dt1, dt2, dt3, dt4)
3345+ $ lteResults = $ database ->find ($ col , [
3346+ Query::lessThanEqual ('datetime ' , '2024-06-15T12:00:00.000Z ' )
3347+ ]);
3348+ $ this ->assertCount (4 , $ lteResults );
3349+ $ lteIds = array_map (fn ($ d ) => $ d ->getId (), $ lteResults );
3350+ $ this ->assertContains ('dt1 ' , $ lteIds );
3351+ $ this ->assertContains ('dt2 ' , $ lteIds );
3352+ $ this ->assertContains ('dt3 ' , $ lteIds );
3353+ $ this ->assertContains ('dt4 ' , $ lteIds );
3354+
3355+ // Query: between - datetimes in range [2024-02-01, 2024-07-01) (dt2, dt3, dt4)
3356+ $ betweenResults = $ database ->find ($ col , [
3357+ Query::between ('datetime ' , '2024-02-01T00:00:00.000Z ' , '2024-07-01T00:00:00.000Z ' )
3358+ ]);
3359+ $ this ->assertCount (3 , $ betweenResults );
3360+ $ betweenIds = array_map (fn ($ d ) => $ d ->getId (), $ betweenResults );
3361+ $ this ->assertContains ('dt2 ' , $ betweenIds );
3362+ $ this ->assertContains ('dt3 ' , $ betweenIds );
3363+ $ this ->assertContains ('dt4 ' , $ betweenIds );
3364+
3365+ // Query: equal with no match
3366+ $ noneResults = $ database ->find ($ col , [
3367+ Query::equal ('datetime ' , ['2020-01-01T00:00:00.000Z ' ])
3368+ ]);
3369+ $ this ->assertCount (0 , $ noneResults );
3370+
3371+ $ database ->deleteCollection ($ col );
3372+ }
3373+
3374+ public function testSchemalessCreatedAndUpdatedAtQuery (): void
3375+ {
3376+ /** @var Database $database */
3377+ $ database = static ::getDatabase ();
3378+
3379+ if ($ database ->getAdapter ()->getSupportForAttributes ()) {
3380+ $ this ->expectNotToPerformAssertions ();
3381+ return ;
3382+ }
3383+
3384+ // Create a simple schemaless collection and one document.
3385+ $ database ->createCollection ('schemaless_time ' , permissions: [
3386+ Permission::read (Role::any ()),
3387+ Permission::create (Role::any ()),
3388+ Permission::update (Role::any ()),
3389+ Permission::delete (Role::any ()),
3390+ ]);
3391+
3392+ $ database ->createDocument ('schemaless_time ' , new Document ([
3393+ '$id ' => ID ::unique (),
3394+ '$permissions ' => [Permission::read (Role::any ())],
3395+ 'name ' => 'Schemaless Movie ' ,
3396+ ]));
3397+
3398+ $ futureDate = '2050-01-01T00:00:00.000Z ' ;
3399+ $ pastDate = '1900-01-01T00:00:00.000Z ' ;
3400+ $ recentPastDate = '2020-01-01T00:00:00.000Z ' ;
3401+ $ nearFutureDate = '2025-01-01T00:00:00.000Z ' ;
3402+
3403+ // --- createdBefore ---
3404+ $ documents = $ database ->find ('schemaless_time ' , [
3405+ Query::createdBefore ($ futureDate ),
3406+ Query::limit (1 ),
3407+ ]);
3408+ $ this ->assertGreaterThan (0 , count ($ documents ));
3409+
3410+ $ documents = $ database ->find ('schemaless_time ' , [
3411+ Query::createdBefore ($ pastDate ),
3412+ Query::limit (1 ),
3413+ ]);
3414+ $ this ->assertEquals (0 , count ($ documents ));
3415+
3416+ // --- createdAfter ---
3417+ $ documents = $ database ->find ('schemaless_time ' , [
3418+ Query::createdAfter ($ pastDate ),
3419+ Query::limit (1 ),
3420+ ]);
3421+ $ this ->assertGreaterThan (0 , count ($ documents ));
3422+
3423+ $ documents = $ database ->find ('schemaless_time ' , [
3424+ Query::createdAfter ($ futureDate ),
3425+ Query::limit (1 ),
3426+ ]);
3427+ $ this ->assertEquals (0 , count ($ documents ));
3428+
3429+ // --- updatedBefore ---
3430+ $ documents = $ database ->find ('schemaless_time ' , [
3431+ Query::updatedBefore ($ futureDate ),
3432+ Query::limit (1 ),
3433+ ]);
3434+ $ this ->assertGreaterThan (0 , count ($ documents ));
3435+
3436+ $ documents = $ database ->find ('schemaless_time ' , [
3437+ Query::updatedBefore ($ pastDate ),
3438+ Query::limit (1 ),
3439+ ]);
3440+ $ this ->assertEquals (0 , count ($ documents ));
3441+
3442+ // --- updatedAfter ---
3443+ $ documents = $ database ->find ('schemaless_time ' , [
3444+ Query::updatedAfter ($ pastDate ),
3445+ Query::limit (1 ),
3446+ ]);
3447+ $ this ->assertGreaterThan (0 , count ($ documents ));
3448+
3449+ $ documents = $ database ->find ('schemaless_time ' , [
3450+ Query::updatedAfter ($ futureDate ),
3451+ Query::limit (1 ),
3452+ ]);
3453+ $ this ->assertEquals (0 , count ($ documents ));
3454+
3455+ // --- createdBetween ---
3456+ $ documents = $ database ->find ('schemaless_time ' , [
3457+ Query::createdBetween ($ pastDate , $ futureDate ),
3458+ Query::limit (25 ),
3459+ ]);
3460+ $ this ->assertGreaterThan (0 , count ($ documents ));
3461+
3462+ $ documents = $ database ->find ('schemaless_time ' , [
3463+ Query::createdBetween ($ pastDate , $ pastDate ),
3464+ Query::limit (25 ),
3465+ ]);
3466+ $ this ->assertEquals (0 , count ($ documents ));
3467+
3468+ $ documents = $ database ->find ('schemaless_time ' , [
3469+ Query::createdBetween ($ recentPastDate , $ nearFutureDate ),
3470+ Query::limit (25 ),
3471+ ]);
3472+ $ count = count ($ documents );
3473+
3474+ $ documents = $ database ->find ('schemaless_time ' , [
3475+ Query::createdBetween ($ pastDate , $ nearFutureDate ),
3476+ Query::limit (25 ),
3477+ ]);
3478+ $ this ->assertGreaterThanOrEqual ($ count , count ($ documents ));
3479+
3480+ // --- updatedBetween ---
3481+ $ documents = $ database ->find ('schemaless_time ' , [
3482+ Query::updatedBetween ($ pastDate , $ futureDate ),
3483+ Query::limit (25 ),
3484+ ]);
3485+ $ this ->assertGreaterThan (0 , count ($ documents ));
3486+
3487+ $ documents = $ database ->find ('schemaless_time ' , [
3488+ Query::updatedBetween ($ pastDate , $ pastDate ),
3489+ Query::limit (25 ),
3490+ ]);
3491+ $ this ->assertEquals (0 , count ($ documents ));
3492+
3493+ $ documents = $ database ->find ('schemaless_time ' , [
3494+ Query::updatedBetween ($ recentPastDate , $ nearFutureDate ),
3495+ Query::limit (25 ),
3496+ ]);
3497+ $ count = count ($ documents );
3498+
3499+ $ documents = $ database ->find ('schemaless_time ' , [
3500+ Query::updatedBetween ($ pastDate , $ nearFutureDate ),
3501+ Query::limit (25 ),
3502+ ]);
3503+ $ this ->assertGreaterThanOrEqual ($ count , count ($ documents ));
3504+
3505+ $ database ->deleteCollection ('schemaless_time ' );
3506+ }
32453507}
0 commit comments