Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Table of contents
* [Eloquent](#eloquent)
* [Optional: Alias](#optional-alias)
* [Query Builder](#query-builder)
* [`toSql()`](#to-sql)
Copy link
Contributor

@jenssegers jenssegers Jan 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can put this under a category called "debugging" or "inspecting queries".

If I remember correctly there was also a way to get the mongodb query. That could also fit under that category. Will also be nice to be able to send this link to people having issues.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add else info about DB::getQueryLog()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It old feature but getQueryLog() return original query struncture to mongodb

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jenssegers maybe fix this after #1917

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Smolevich i will look into it as soon as i get home

Copy link
Contributor

@Smolevich Smolevich Jan 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rennokki what about to add info about using DB::getQueryLog()
For example

DB::enableQueryLog();
$user = factory(User::class)->create();
$query = DB::connection()->table(config('auth.passwords.users.table'));
dd(DB::getQueryLog());

Example of element of array that function getQueryLog returned

0 => array:3 [
    "query" => "users.insertOne({"name":"Mr. Jayden Cremin Sr.","email":"[email protected]","email_verified_at":{"$date":{"$numberLong":"1579992655000"}},"password":"$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC\/.og\/at2.uheWG\/igi","remember_token":"r6HicH5d78","updated_at":{"$date":{"$numberLong":"1579992655901"}},"created_at":{"$date":{"$numberLong":"1579992655901"}}})"
    "bindings" => []
    "time" => 48.52
  ]
1 => array:3 [
    "query" => "users.find({"email":"[email protected]"},{"limit":1,"typeMap":{"root":"array","document":"array"}})"
    "bindings" => []
    "time" => 4.49
  ]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scope of this PR was to be able to get the query string before the actual query was executed, so i can be able to add cache query-by-query.

I can add the query log thing in the readme, because that's useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Smolevich @Giacomo92

So far, the single issue here is that the basic get() and the aggregate and groups are treated differently. This means that the final query is split into two methods rather than a single get() one.

I repeat - the purpose of this PR was to get the string for each query, so I can be able to query the cache query-by-query.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Smolevich I think $options and $pipeline has to be attributes in the class and be passed to the generateCacheKey method.

* [Schema](#schema)
* [Extensions](#extensions)
* [Examples](#examples)
Expand Down Expand Up @@ -240,6 +241,20 @@ $user = DB::connection('mongodb')->collection('users')->get();

Read more about the query builder on http://laravel.com/docs/queries

->toSql()
-------------
Hence we are in a NoSQL driver, it is counter-intuitive to use `toSql()` to output the string that will be executed.

However, if you still need the string that looks like the sql for some inspection, you can use the `toSql()` method:
```php
User::where('some_field', '>', 300)
->whereRaw(['age' => ['$gt' => 30, '$lt' => 40]])
->toSql();

// output
"select * from "users" where "some_field" > ? and {"age":{"$gt":30,"$lt":40}}"
```

Schema
------

Expand Down
15 changes: 15 additions & 0 deletions src/Jenssegers/Mongodb/Query/Grammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,19 @@

class Grammar extends BaseGrammar
{
/**
* {@inheritdoc}
Copy link
Contributor

@Smolevich Smolevich Jan 26, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add param doc for argument $query and for return type please

*/
protected function compileWheresToArray($query)
{
return collect($query->wheres)->map(function ($where) use ($query) {
$baseWhere = $this->{"where{$where['type']}"}($query, $where);

if (isset($where['sql']) && is_array($where['sql'])) {
$baseWhere = json_encode($baseWhere);
}

return $where['boolean'].' '.$baseWhere;
})->all();
}
}
13 changes: 12 additions & 1 deletion tests/ModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ public function testCarbonDateMockingWorks()

Carbon::setTestNow($fakeDate);
$item = Item::create(['name' => 'sword']);

$this->assertLessThan(1, $fakeDate->diffInSeconds($item->created_at));
}

Expand Down Expand Up @@ -572,4 +572,15 @@ public function testChunkById(): void

$this->assertEquals(3, $count);
}

public function toSqlTest(): void
{
$this->assertTrue(
is_string(User::where('age', 30)->toSql())
);

$this->assertTrue(
is_string(User::whereRaw(['age' => ['$gt' => 30, '$lt' => 40]])->toSql())
);
}
}