Skip to content

Commit ebde4c0

Browse files
authored
Merge branch 'master' into master
2 parents 3811c65 + 828982f commit ebde4c0

File tree

9 files changed

+341
-54
lines changed

9 files changed

+341
-54
lines changed

.github/workflows/build-ci.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ${{matrix.os}}
1212
strategy:
1313
matrix:
14-
php: ['7.1', '7.2', '7.3', '7.4']
14+
php: ['7.2', '7.3', '7.4']
1515
os: ['ubuntu-latest']
1616
mongodb: ['3.6', '4.0', '4.2']
1717
services:
@@ -30,9 +30,16 @@ jobs:
3030
name: PHP v${{ matrix.php }} with Mongo v${{ matrix.mongodb }}
3131

3232
steps:
33-
- uses: actions/checkout@v1
33+
- uses: actions/checkout@v2
34+
- name: "Installing php"
35+
uses: shivammathur/setup-php@v2
36+
with:
37+
php-version: ${{ matrix.php }}
38+
extensions: curl,mbstring,xdebug
39+
coverage: xdebug
40+
tools: composer
3441
- name: Show PHP version
35-
run: php${{ matrix.php }} -v && composer -V
42+
run: php -v && composer -V
3643
- name: Show Docker version
3744
run: if [[ "$DEBUG" == "true" ]]; then docker version && env; fi
3845
env:

README.md

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ This package adds functionalities to the Eloquent model and Query builder for Mo
4242
- [Cross-Database Relationships](#cross-database-relationships)
4343
- [Authentication](#authentication)
4444
- [Queues](#queues)
45+
- [Laravel specific](#laravel-specific)
46+
- [Lumen specific](#Lumen-specific)
4547
- [Upgrading](#upgrading)
4648
- [Upgrading from version 2 to 3](#upgrading-from-version-2-to-3)
4749

@@ -230,6 +232,18 @@ class Book extends Model
230232
}
231233
```
232234

235+
### Extending the Authenticable base model
236+
This package includes a MongoDB Authenticatable Eloquent class `Jenssegers\Mongodb\Auth\User` that you can use to replace the default Authenticatable class `Illuminate\Foundation\Auth\User` for your `User` model.
237+
238+
```php
239+
use Jenssegers\Mongodb\Auth\User as Authenticatable;
240+
241+
class User extends Authenticatable
242+
{
243+
244+
}
245+
```
246+
233247
### Soft Deletes
234248

235249
When soft deleting a model, it is not actually removed from your database. Instead, a deleted_at timestamp is set on the record.
@@ -1067,6 +1081,8 @@ If you want to use MongoDB as your database backend, change the driver in `confi
10671081
'connections' => [
10681082
'database' => [
10691083
'driver' => 'mongodb',
1084+
// You can also specify your jobs specific database created on config/database.php
1085+
'connection' => 'mongodb-job',
10701086
'table' => 'jobs',
10711087
'queue' => 'default',
10721088
'expire' => 60,
@@ -1078,23 +1094,31 @@ If you want to use MongoDB to handle failed jobs, change the database in `config
10781094

10791095
```php
10801096
'failed' => [
1081-
'driver' => env('QUEUE_FAILED_DRIVER', 'database'),
1082-
'database' => env('DB_CONNECTION', 'mongodb'),
1097+
'driver' => 'mongodb',
1098+
// You can also specify your jobs specific database created on config/database.php
1099+
'database' => 'mongodb-job',
10831100
'table' => 'failed_jobs',
10841101
],
10851102
```
10861103

1087-
Or simply set your own `QUEUE_FAILED_DRIVER` environment variable to `mongodb`
1088-
```env
1089-
QUEUE_FAILED_DRIVER=mongodb
1090-
```
1104+
#### Laravel specific
10911105

1092-
Last, add the service provider in `config/app.php`:
1106+
Add the service provider in `config/app.php`:
10931107

10941108
```php
10951109
Jenssegers\Mongodb\MongodbQueueServiceProvider::class,
10961110
```
10971111

1112+
#### Lumen specific
1113+
1114+
With [Lumen](http://lumen.laravel.com), add the service provider in `bootstrap/app.php`. You must however ensure that you add the following **after** the `MongodbServiceProvider` registration.
1115+
1116+
```php
1117+
$app->make('queue');
1118+
1119+
$app->register(Jenssegers\Mongodb\MongodbQueueServiceProvider::class);
1120+
```
1121+
10981122
Upgrading
10991123
---------
11001124

src/Jenssegers/Mongodb/Collection.php

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -41,34 +41,32 @@ public function __call($method, $parameters)
4141
$start = microtime(true);
4242
$result = call_user_func_array([$this->collection, $method], $parameters);
4343

44-
if ($this->connection->logging()) {
45-
// Once we have run the query we will calculate the time that it took to run and
46-
// then log the query, bindings, and execution time so we will report them on
47-
// the event that the developer needs them. We'll log time in milliseconds.
48-
$time = $this->connection->getElapsedTime($start);
44+
// Once we have run the query we will calculate the time that it took to run and
45+
// then log the query, bindings, and execution time so we will report them on
46+
// the event that the developer needs them. We'll log time in milliseconds.
47+
$time = $this->connection->getElapsedTime($start);
4948

50-
$query = [];
49+
$query = [];
5150

52-
// Convert the query parameters to a json string.
53-
array_walk_recursive($parameters, function (&$item, $key) {
54-
if ($item instanceof ObjectID) {
55-
$item = (string) $item;
56-
}
57-
});
51+
// Convert the query parameters to a json string.
52+
array_walk_recursive($parameters, function (&$item, $key) {
53+
if ($item instanceof ObjectID) {
54+
$item = (string) $item;
55+
}
56+
});
5857

59-
// Convert the query parameters to a json string.
60-
foreach ($parameters as $parameter) {
61-
try {
62-
$query[] = json_encode($parameter);
63-
} catch (Exception $e) {
64-
$query[] = '{...}';
65-
}
58+
// Convert the query parameters to a json string.
59+
foreach ($parameters as $parameter) {
60+
try {
61+
$query[] = json_encode($parameter);
62+
} catch (Exception $e) {
63+
$query[] = '{...}';
6664
}
65+
}
6766

68-
$queryString = $this->collection->getCollectionName() . '.' . $method . '(' . implode(',', $query) . ')';
67+
$queryString = $this->collection->getCollectionName() . '.' . $method . '(' . implode(',', $query) . ')';
6968

70-
$this->connection->logQuery($queryString, [], $time);
71-
}
69+
$this->connection->logQuery($queryString, [], $time);
7270

7371
return $result;
7472
}

src/Jenssegers/Mongodb/Eloquent/Model.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,13 @@ protected function asDateTime($value)
9999
{
100100
// Convert UTCDateTime instances.
101101
if ($value instanceof UTCDateTime) {
102-
return Date::createFromTimestampMs($value->toDateTime()->format('Uv'));
102+
$date = $value->toDateTime();
103+
104+
$seconds = $date->format('U');
105+
$milliseconds = abs($date->format('v'));
106+
$timestampMs = sprintf('%d%03d', $seconds, $milliseconds);
107+
108+
return Date::createFromTimestampMs($timestampMs);
103109
}
104110

105111
return parent::asDateTime($value);

src/Jenssegers/Mongodb/Query/Builder.php

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,24 @@
88
use Illuminate\Database\Query\Expression;
99
use Illuminate\Support\Arr;
1010
use Illuminate\Support\Collection;
11+
use Illuminate\Support\LazyCollection;
1112
use Illuminate\Support\Str;
1213
use Jenssegers\Mongodb\Connection;
13-
use MongoCollection;
1414
use MongoDB\BSON\Binary;
1515
use MongoDB\BSON\ObjectID;
1616
use MongoDB\BSON\Regex;
1717
use MongoDB\BSON\UTCDateTime;
18+
use RuntimeException;
1819

20+
/**
21+
* Class Builder
22+
* @package Jenssegers\Mongodb\Query
23+
*/
1924
class Builder extends BaseBuilder
2025
{
2126
/**
2227
* The database collection.
23-
* @var MongoCollection
28+
* @var \MongoDB\Collection
2429
*/
2530
protected $collection;
2631

@@ -209,12 +214,25 @@ public function get($columns = [])
209214
return $this->getFresh($columns);
210215
}
211216

217+
/**
218+
* @inheritdoc
219+
*/
220+
public function cursor($columns = [])
221+
{
222+
$result = $this->getFresh($columns, true);
223+
if ($result instanceof LazyCollection) {
224+
return $result;
225+
}
226+
throw new RuntimeException("Query not compatible with cursor");
227+
}
228+
212229
/**
213230
* Execute the query as a fresh "select" statement.
214231
* @param array $columns
215-
* @return array|static[]|Collection
232+
* @param bool $returnLazy
233+
* @return array|static[]|Collection|LazyCollection
216234
*/
217-
public function getFresh($columns = [])
235+
public function getFresh($columns = [], $returnLazy = false)
218236
{
219237
// If no columns have been specified for the select statement, we will set them
220238
// here to either the passed columns, or the standard default of retrieving
@@ -402,6 +420,14 @@ public function getFresh($columns = [])
402420
// Execute query and get MongoCursor
403421
$cursor = $this->collection->find($wheres, $options);
404422

423+
if ($returnLazy) {
424+
return LazyCollection::make(function () use ($cursor) {
425+
foreach ($cursor as $item) {
426+
yield $item;
427+
}
428+
});
429+
}
430+
405431
// Return results as an array with numeric keys
406432
$results = iterator_to_array($cursor, false);
407433
return $this->useCollections ? new Collection($results) : $results;
@@ -698,15 +724,11 @@ public function from($collection, $as = null)
698724
/**
699725
* @inheritdoc
700726
*/
701-
public function truncate()
727+
public function truncate(): bool
702728
{
703-
$options = [
704-
'typeMap' => ['root' => 'object', 'document' => 'object'],
705-
];
706-
707-
$result = $this->collection->drop($options);
729+
$result = $this->collection->deleteMany([]);
708730

709-
return (1 == (int) $result->ok);
731+
return (1 === (int) $result->isAcknowledged());
710732
}
711733

712734
/**
@@ -993,6 +1015,7 @@ protected function compileWhereAll(array $where)
9931015
protected function compileWhereBasic(array $where)
9941016
{
9951017
extract($where);
1018+
$is_numeric = false;
9961019

9971020
// Replace like or not like with a Regex instance.
9981021
if (in_array($operator, ['like', 'not like'])) {
@@ -1004,15 +1027,21 @@ protected function compileWhereBasic(array $where)
10041027

10051028
// Convert to regular expression.
10061029
$regex = preg_replace('#(^|[^\\\])%#', '$1.*', preg_quote($value));
1030+
$plain_value = $value;
10071031

10081032
// Convert like to regular expression.
10091033
if (!Str::startsWith($value, '%')) {
10101034
$regex = '^' . $regex;
1035+
} else {
1036+
$plain_value = Str::replaceFirst('%', null, $plain_value);
10111037
}
10121038
if (!Str::endsWith($value, '%')) {
10131039
$regex .= '$';
1040+
} else {
1041+
$plain_value = Str::replaceLast('%', null, $plain_value);
10141042
}
10151043

1044+
$is_numeric = is_numeric($plain_value);
10161045
$value = new Regex($regex, 'i');
10171046
} // Manipulate regexp operations.
10181047
elseif (in_array($operator, ['regexp', 'not regexp', 'regex', 'not regex'])) {
@@ -1032,7 +1061,11 @@ protected function compileWhereBasic(array $where)
10321061
}
10331062

10341063
if (!isset($operator) || $operator == '=') {
1035-
$query = [$column => $value];
1064+
if ($is_numeric) {
1065+
$query = ['$where' => '/^'.$value->getPattern().'/.test(this.'.$column.')'];
1066+
} else {
1067+
$query = [$column => $value];
1068+
}
10361069
} elseif (array_key_exists($operator, $this->conversion)) {
10371070
$query = [$column => [$this->conversion[$operator] => $value]];
10381071
} else {

tests/CollectionTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ public function testExecuteMethodCall()
2323
$mongoCollection->expects($this->once())->method('getCollectionName')->willReturn('name-collection');
2424

2525
$connection = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock();
26-
$connection->expects($this->once())->method('logging')->willReturn(true);
2726
$connection->expects($this->once())->method('getElapsedTime')->willReturn($time);
2827
$connection->expects($this->once())->method('logQuery')->with($queryString, [], $time);
2928

0 commit comments

Comments
 (0)