Skip to content

Commit f5dcf7e

Browse files
support query builder
1 parent 1288b7f commit f5dcf7e

File tree

7 files changed

+113
-21
lines changed

7 files changed

+113
-21
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ User::where('votes', '>', 100)
2323
// "select * from `users` where `votes` > 100 or (`name` = 'Abigail' and `votes` > 50)"
2424
```
2525

26+
```php
27+
DB::table('users')
28+
->whereBetween('votes', [1, 100])
29+
->toRawSql();
30+
31+
// "select * from `users` where `votes` between 1 and 100"
32+
```
33+
2634
## Why?
2735
`toSql()` doesn't bind values to it. Instead, it returns the raw SQL representation of the query as a string, including placeholders for any bound values.
2836

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace PyaeSoneAung\ToRawSql\Concerns;
4+
5+
use Illuminate\Database\Eloquent\Builder;
6+
use PyaeSoneAung\ToRawSql\Services\BuilderToRawSqlService;
7+
8+
trait EloquentBuilderMacros
9+
{
10+
public function registerEloquentBuilderMacros()
11+
{
12+
Builder::macro('toRawSql', function (): string {
13+
/**
14+
* @var \Illuminate\Database\Eloquent\Builder $this
15+
*/
16+
return (new BuilderToRawSqlService($this))->toRawSql();
17+
});
18+
}
19+
}

src/Concerns/QueryBuilderMacros.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace PyaeSoneAung\ToRawSql\Concerns;
4+
5+
use Illuminate\Database\Query\Builder;
6+
use PyaeSoneAung\ToRawSql\Services\BuilderToRawSqlService;
7+
8+
trait QueryBuilderMacros
9+
{
10+
public function registerQueryBuilderMacros()
11+
{
12+
Builder::macro('toRawSql', function (): string {
13+
/**
14+
* @var \Illuminate\Database\Query\Builder $this
15+
*/
16+
return (new BuilderToRawSqlService($this))->toRawSql();
17+
});
18+
}
19+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace PyaeSoneAung\ToRawSql\Services;
4+
5+
use DateTimeInterface;
6+
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
7+
use Illuminate\Database\Query\Builder as QueryBuilder;
8+
use Illuminate\Support\Str;
9+
10+
class BuilderToRawSqlService
11+
{
12+
public function __construct(
13+
public EloquentBuilder|QueryBuilder $builder
14+
) {
15+
}
16+
17+
public function toRawSql(): string
18+
{
19+
$bindings = $this->builder->getBindings();
20+
foreach ($bindings as $key => $value) {
21+
if ($value instanceof DateTimeInterface) {
22+
$bindings[$key] = "'{$value->format('Y-m-d H:i:s')}'";
23+
} elseif (is_string($value)) {
24+
$bindings[$key] = "'{$value}'";
25+
} elseif (is_bool($value)) {
26+
$bindings[$key] = (int) $value;
27+
}
28+
}
29+
30+
return Str::replaceArray('?', $bindings, $this->builder->toSql());
31+
}
32+
}

src/ToRawSqlServiceProvider.php

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,19 @@
22

33
namespace PyaeSoneAung\ToRawSql;
44

5-
use DateTimeInterface;
6-
use Illuminate\Database\Eloquent\Builder;
7-
use Illuminate\Support\Str;
5+
use PyaeSoneAung\ToRawSql\Concerns\EloquentBuilderMacros;
6+
use PyaeSoneAung\ToRawSql\Concerns\QueryBuilderMacros;
87
use Spatie\LaravelPackageTools\Package;
98
use Spatie\LaravelPackageTools\PackageServiceProvider;
109

1110
class ToRawSqlServiceProvider extends PackageServiceProvider
1211
{
12+
use EloquentBuilderMacros, QueryBuilderMacros;
13+
1314
public function boot(): void
1415
{
15-
Builder::macro('toRawSql', function (): string {
16-
/**
17-
* @var \Illuminate\Database\Eloquent\Builder $this
18-
*/
19-
$bindings = $this->getBindings();
20-
foreach ($bindings as $key => $value) {
21-
if ($value instanceof DateTimeInterface) {
22-
$bindings[$key] = "'{$value->format('Y-m-d H:i:s')}'";
23-
} elseif (is_bool($value)) {
24-
$bindings[$key] = (int) $value;
25-
} elseif (is_string($value)) {
26-
$bindings[$key] = "'{$value}'";
27-
}
28-
}
29-
30-
return Str::replaceArray('?', $bindings, $this->toSql());
31-
});
16+
$this->registerEloquentBuilderMacros();
17+
$this->registerQueryBuilderMacros();
3218
}
3319

3420
public function configurePackage(Package $package): void

tests/Pest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
use Illuminate\Support\Facades\DB;
34
use PyaeSoneAung\ToRawSql\Tests\TestCase;
45

56
uses(TestCase::class)->in(__DIR__);
@@ -11,3 +12,8 @@ function users()
1112
protected $table = 'users';
1213
};
1314
}
15+
16+
function usersTbl()
17+
{
18+
return DB::table('users');
19+
}

tests/ToRawSqlTest.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
it('can execute toRawSql', function () {
3+
it('can execute toRawSql from eloquent builder', function () {
44
expect(
55
users()
66
->where('votes', '>', 100)
@@ -21,3 +21,25 @@
2121
->toRawSql()
2222
)->toBe("select * from `users` where `votes` > 100 or (`name` = 'Abigail' and `votes` > 50) and `created_at` = '2023-02-10 13:22:38'");
2323
});
24+
25+
it('can execute toRawSql from query builder', function () {
26+
expect(
27+
usersTbl()
28+
->where('votes', '>', 100)
29+
->orWhere(function ($query) {
30+
$query->where('name', 'Abigail')
31+
->where('votes', '>', 50);
32+
})
33+
->where(
34+
'created_at',
35+
now()
36+
->setYear(2023)
37+
->setMonth(02)
38+
->setDay(10)
39+
->setHour(13)
40+
->setMinute(22)
41+
->setSecond(38)
42+
)
43+
->toRawSql()
44+
)->toBe("select * from `users` where `votes` > 100 or (`name` = 'Abigail' and `votes` > 50) and `created_at` = '2023-02-10 13:22:38'");
45+
});

0 commit comments

Comments
 (0)