Skip to content

Commit 9b924f9

Browse files
committed
Implement Builder::toSql using JSON representation of the MQL
1 parent f93aaa7 commit 9b924f9

File tree

4 files changed

+58
-35
lines changed

4 files changed

+58
-35
lines changed

src/Eloquent/Builder.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class Builder extends EloquentBuilder
5555
'raw',
5656
'sum',
5757
'tomql',
58+
'tosql',
59+
'torawsql',
5860
];
5961

6062
/**

src/Query/Builder.php

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use InvalidArgumentException;
1919
use LogicException;
2020
use MongoDB\BSON\Binary;
21+
use MongoDB\BSON\Document;
2122
use MongoDB\BSON\ObjectID;
2223
use MongoDB\BSON\Regex;
2324
use MongoDB\BSON\UTCDateTime;
@@ -1446,16 +1447,26 @@ public function __call($method, $parameters)
14461447
return parent::__call($method, $parameters);
14471448
}
14481449

1449-
/** @internal This method is not supported by MongoDB. */
1450+
/**
1451+
* Return the JSON representation of the MongoDB Query.
1452+
* Naming is inherited and used for compatibility with third-party packages.
1453+
*
1454+
* @internal
1455+
*/
14501456
public function toSql()
14511457
{
1452-
throw new BadMethodCallException('This method is not supported by MongoDB. Try "toMql()" instead.');
1458+
return Document::fromPHP($this->toMql())->toCanonicalExtendedJSON();
14531459
}
14541460

1455-
/** @internal This method is not supported by MongoDB. */
1461+
/**
1462+
* Return the JSON representation of the MongoDB Query.
1463+
* Naming is inherited and used for compatibility with third-party packages.
1464+
*
1465+
* @internal
1466+
*/
14561467
public function toRawSql()
14571468
{
1458-
throw new BadMethodCallException('This method is not supported by MongoDB. Try "toMql()" instead.');
1469+
return $this->toSql();
14591470
}
14601471

14611472
/** @internal This method is not supported by MongoDB. */
@@ -1535,4 +1546,10 @@ public function orWhereIntegerNotInRaw($column, $values, $boolean = 'and')
15351546
{
15361547
throw new BadMethodCallException('This method is not supported by MongoDB');
15371548
}
1549+
1550+
/** @internal This method is not supported by MongoDB. */
1551+
public function insertUsing(array $columns, $query)
1552+
{
1553+
throw new BadMethodCallException('This method is not supported by MongoDB');
1554+
}
15381555
}

tests/Eloquent/CallBuilderTest.php

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,34 +24,36 @@ protected function tearDown(): void
2424
}
2525

2626
#[Dataprovider('provideFunctionNames')]
27-
public function testCallingABuilderMethodDoesNotReturnTheBuilderInstance(string $method, string $className, $parameters = []): void
27+
public function testCallingABuilderMethodDoesNotReturnTheBuilderInstance(string $method, $parameters = []): void
2828
{
2929
$builder = User::query()->newQuery();
3030
assert($builder instanceof Builder);
3131

32-
self::assertNotInstanceOf(expected: $className, actual: $builder->{$method}(...$parameters));
32+
self::assertNotInstanceOf(Builder::class, $builder->{$method}(...$parameters));
3333
}
3434

3535
public static function provideFunctionNames(): Generator
3636
{
37-
yield 'does not exist' => ['doesntExist', Builder::class];
38-
yield 'get bindings' => ['getBindings', Builder::class];
39-
yield 'get connection' => ['getConnection', Builder::class];
40-
yield 'get grammar' => ['getGrammar', Builder::class];
41-
yield 'insert get id' => ['insertGetId', Builder::class, [['user' => 'foo']]];
42-
yield 'to Mql' => ['toMql', Builder::class];
43-
yield 'average' => ['average', Builder::class, ['name']];
44-
yield 'avg' => ['avg', Builder::class, ['name']];
45-
yield 'count' => ['count', Builder::class, ['name']];
46-
yield 'exists' => ['exists', Builder::class];
47-
yield 'insert' => ['insert', Builder::class, [['name']]];
48-
yield 'max' => ['max', Builder::class, ['name']];
49-
yield 'min' => ['min', Builder::class, ['name']];
50-
yield 'pluck' => ['pluck', Builder::class, ['name']];
51-
yield 'pull' => ['pull', Builder::class, ['name']];
52-
yield 'push' => ['push', Builder::class, ['name']];
53-
yield 'raw' => ['raw', Builder::class];
54-
yield 'sum' => ['sum', Builder::class, ['name']];
37+
yield 'does not exist' => ['doesntExist'];
38+
yield 'get bindings' => ['getBindings'];
39+
yield 'get connection' => ['getConnection'];
40+
yield 'get grammar' => ['getGrammar'];
41+
yield 'insert get id' => ['insertGetId', [['user' => 'foo']]];
42+
yield 'to Mql' => ['toMql'];
43+
yield 'to Sql' => ['toSql'];
44+
yield 'to Raw Sql' => ['toRawSql'];
45+
yield 'average' => ['average', ['name']];
46+
yield 'avg' => ['avg', ['name']];
47+
yield 'count' => ['count', ['name']];
48+
yield 'exists' => ['exists'];
49+
yield 'insert' => ['insert', [['name']]];
50+
yield 'max' => ['max', ['name']];
51+
yield 'min' => ['min', ['name']];
52+
yield 'pluck' => ['pluck', ['name']];
53+
yield 'pull' => ['pull', ['name']];
54+
yield 'push' => ['push', ['name']];
55+
yield 'raw' => ['raw'];
56+
yield 'sum' => ['sum', ['name']];
5557
}
5658

5759
#[Test]
@@ -79,14 +81,7 @@ public static function provideUnsupportedMethods(): Generator
7981
yield 'insert using' => [
8082
'insertUsing',
8183
BadMethodCallException::class,
82-
'This method is not supported by MongoDB. Try "toMql()" instead',
83-
[[['name' => 'Jane']], fn (QueryBuilder $builder) => $builder],
84-
];
85-
86-
yield 'to sql' => [
87-
'toSql',
88-
BadMethodCallException::class,
89-
'This method is not supported by MongoDB. Try "toMql()" instead',
84+
'This method is not supported by MongoDB',
9085
[[['name' => 'Jane']], fn (QueryBuilder $builder) => $builder],
9186
];
9287
}

tests/Query/BuilderTest.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,18 @@ public static function provideExceptions(): iterable
13961396
];
13971397
}
13981398

1399+
public function testToSql()
1400+
{
1401+
$builder = self::getBuilder();
1402+
$builder
1403+
->where('foo', 'bar')
1404+
->limit(10);
1405+
1406+
$expected = '{ "find" : [ { "foo" : "bar" }, { "limit" : { "$numberInt" : "10" }, "typeMap" : { "root" : "array", "document" : "array" } } ] }';
1407+
$this->assertSame($expected, $builder->toSql());
1408+
$this->assertSame($expected, $builder->toRawSql());
1409+
}
1410+
13991411
/** @dataProvider getEloquentMethodsNotSupported */
14001412
public function testEloquentMethodsNotSupported(Closure $callback)
14011413
{
@@ -1412,9 +1424,6 @@ public static function getEloquentMethodsNotSupported()
14121424
// Most of this methods can be implemented using aggregation framework
14131425
// whereInRaw, whereNotInRaw, orWhereInRaw, orWhereNotInRaw, whereBetweenColumns
14141426

1415-
yield 'toSql' => [fn (Builder $builder) => $builder->toSql()];
1416-
yield 'toRawSql' => [fn (Builder $builder) => $builder->toRawSql()];
1417-
14181427
/** @see DatabaseQueryBuilderTest::testBasicWhereColumn() */
14191428
/** @see DatabaseQueryBuilderTest::testArrayWhereColumn() */
14201429
yield 'whereColumn' => [fn (Builder $builder) => $builder->whereColumn('first_name', 'last_name')];

0 commit comments

Comments
 (0)