88use Illuminate \Database \Query \Expression ;
99use Illuminate \Support \Arr ;
1010use Illuminate \Support \Collection ;
11+ use Illuminate \Support \LazyCollection ;
1112use Illuminate \Support \Str ;
1213use Jenssegers \Mongodb \Connection ;
1314use MongoCollection ;
1415use MongoDB \BSON \Binary ;
1516use MongoDB \BSON \ObjectID ;
1617use MongoDB \BSON \Regex ;
1718use MongoDB \BSON \UTCDateTime ;
19+ use RuntimeException ;
1820
21+ /**
22+ * Class Builder
23+ * @package Jenssegers\Mongodb\Query
24+ */
1925class Builder extends BaseBuilder
2026{
2127 /**
@@ -209,12 +215,25 @@ public function get($columns = [])
209215 return $ this ->getFresh ($ columns );
210216 }
211217
218+ /**
219+ * @inheritdoc
220+ */
221+ public function cursor ($ columns = [])
222+ {
223+ $ result = $ this ->getFresh ($ columns , true );
224+ if ($ result instanceof LazyCollection) {
225+ return $ result ;
226+ }
227+ throw new RuntimeException ("Query not compatible with cursor " );
228+ }
229+
212230 /**
213231 * Execute the query as a fresh "select" statement.
214232 * @param array $columns
215- * @return array|static[]|Collection
233+ * @param bool $returnLazy
234+ * @return array|static[]|Collection|LazyCollection
216235 */
217- public function getFresh ($ columns = [])
236+ public function getFresh ($ columns = [], $ returnLazy = false )
218237 {
219238 // If no columns have been specified for the select statement, we will set them
220239 // here to either the passed columns, or the standard default of retrieving
@@ -294,7 +313,7 @@ public function getFresh($columns = [])
294313 }
295314 }
296315 }
297-
316+
298317 // The _id field is mandatory when using grouping.
299318 if ($ group && empty ($ group ['_id ' ])) {
300319 $ group ['_id ' ] = null ;
@@ -402,6 +421,14 @@ public function getFresh($columns = [])
402421 // Execute query and get MongoCursor
403422 $ cursor = $ this ->collection ->find ($ wheres , $ options );
404423
424+ if ($ returnLazy ) {
425+ return LazyCollection::make (function () use ($ cursor ) {
426+ foreach ($ cursor as $ item ) {
427+ yield $ item ;
428+ }
429+ });
430+ }
431+
405432 // Return results as an array with numeric keys
406433 $ results = iterator_to_array ($ cursor , false );
407434 return $ this ->useCollections ? new Collection ($ results ) : $ results ;
@@ -930,18 +957,18 @@ protected function compileWheres()
930957 if (is_array ($ where ['value ' ])) {
931958 array_walk_recursive ($ where ['value ' ], function (&$ item , $ key ) {
932959 if ($ item instanceof DateTime) {
933- $ item = new UTCDateTime ($ item ->getTimestamp () * 1000 );
960+ $ item = new UTCDateTime ($ item ->format ( ' Uv ' ) );
934961 }
935962 });
936963 } else {
937964 if ($ where ['value ' ] instanceof DateTime) {
938- $ where ['value ' ] = new UTCDateTime ($ where ['value ' ]->getTimestamp () * 1000 );
965+ $ where ['value ' ] = new UTCDateTime ($ where ['value ' ]->format ( ' Uv ' ) );
939966 }
940967 }
941968 } elseif (isset ($ where ['values ' ])) {
942969 array_walk_recursive ($ where ['values ' ], function (&$ item , $ key ) {
943970 if ($ item instanceof DateTime) {
944- $ item = new UTCDateTime ($ item ->getTimestamp () * 1000 );
971+ $ item = new UTCDateTime ($ item ->format ( ' Uv ' ) );
945972 }
946973 });
947974 }
@@ -993,6 +1020,7 @@ protected function compileWhereAll(array $where)
9931020 protected function compileWhereBasic (array $ where )
9941021 {
9951022 extract ($ where );
1023+ $ is_numeric = false ;
9961024
9971025 // Replace like or not like with a Regex instance.
9981026 if (in_array ($ operator , ['like ' , 'not like ' ])) {
@@ -1004,15 +1032,21 @@ protected function compileWhereBasic(array $where)
10041032
10051033 // Convert to regular expression.
10061034 $ regex = preg_replace ('#(^|[^ \\\])%# ' , '$1.* ' , preg_quote ($ value ));
1035+ $ plain_value = $ value ;
10071036
10081037 // Convert like to regular expression.
10091038 if (!Str::startsWith ($ value , '% ' )) {
10101039 $ regex = '^ ' . $ regex ;
1040+ } else {
1041+ $ plain_value = Str::replaceFirst ('% ' , null , $ plain_value );
10111042 }
10121043 if (!Str::endsWith ($ value , '% ' )) {
10131044 $ regex .= '$ ' ;
1045+ } else {
1046+ $ plain_value = Str::replaceLast ('% ' , null , $ plain_value );
10141047 }
10151048
1049+ $ is_numeric = is_numeric ($ plain_value );
10161050 $ value = new Regex ($ regex , 'i ' );
10171051 } // Manipulate regexp operations.
10181052 elseif (in_array ($ operator , ['regexp ' , 'not regexp ' , 'regex ' , 'not regex ' ])) {
@@ -1032,7 +1066,11 @@ protected function compileWhereBasic(array $where)
10321066 }
10331067
10341068 if (!isset ($ operator ) || $ operator == '= ' ) {
1035- $ query = [$ column => $ value ];
1069+ if ($ is_numeric ) {
1070+ $ query = ['$where ' => '/^ ' .$ value ->getPattern ().'/.test(this. ' .$ column .') ' ];
1071+ } else {
1072+ $ query = [$ column => $ value ];
1073+ }
10361074 } elseif (array_key_exists ($ operator , $ this ->conversion )) {
10371075 $ query = [$ column => [$ this ->conversion [$ operator ] => $ value ]];
10381076 } else {
0 commit comments