Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sql To Laravel Laravel Package

itul/sql-to-laravel

Convert raw SQL into Laravel query builder or Eloquent code. Paste a SQL query and generate equivalent Laravel syntax to speed up refactoring, debugging, and migrating legacy database logic into your application.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is not on Packagist and has no releases, stars, or dependents, so treat it as an unmaintained source dump you are vendoring rather than a library you can composer require by name. Add the Bitbucket repo as a VCS repository and pin to a specific commit — never dev-master, since nothing guarantees the branch stays buildable:

"repositories": [
  { "type": "vcs", "url": "https://bitbucket.org/bmooreitul/sql-to-laravel.git" }
],
"require": {
  "itul/sql-to-laravel": "dev-master#<full-commit-sha>"
}

If the repo has no composer.json with a valid name/autoload block, you will have to copy src/ into your app namespace manually — check for that first before fighting Composer.

Where to look first, in order:

  1. src/ — find the single converter class and note whether it returns a Query\Builder (->toBase() style) or an Eloquent\Builder. This determines almost everything downstream.
  2. composer.json — the illuminate/database constraint tells you which Laravel versions this can possibly work with. If it's absent or pinned to ^5.x, assume you are patching it.
  3. src/*ServiceProvider.php and any facade — copy the accessor name; if there is no extra.laravel.providers block you must register it manually in config/app.php.
  4. tests/ — likely empty. If so, write your own harness before writing any features (see below).

The first use case to try is one real, boring, read-only report query from your legacy app: a SELECT ... FROM a LEFT JOIN b ON ... WHERE ... AND (...) ORDER BY ... LIMIT. Run it through the converter, then call ->toSql() and ->getBindings() and eyeball the diff against the original. Do not start with a query that has subqueries, UNION, or window functions.

Implementation Patterns

Wrap it behind your own adapter. Because this package will not be maintained, isolate it immediately:

interface SqlConverter { public function toBuilder(string $sql, array $bindings = []): Builder; }

final class LegacySqlConverter implements SqlConverter
{
    public function toBuilder(string $sql, array $bindings = []): Builder
    {
        return app(\Itul\SqlToLaravel\...::class)->convert($sql, $bindings);
    }
}

Bind the interface in a service provider and never reference the package class elsewhere. When you fork or replace it, one binding changes.

Golden-path testing is non-negotiable. For every query you convert, assert equivalence against the source of truth:

$raw    = DB::select($legacySql, $bindings);
$built  = DB::query()->fromSub($converter->toBuilder($legacySql, $bindings), 'q')->get();
// compare sorted, normalised arrays — column order and types will differ

Run these against a seeded test database, not production. This catches silent partial conversions (a dropped WHERE clause returns more rows, not an error).

Repository / scope integration. Once converted, the builder composes normally — you can add ->when($request->filled('region'), fn($q) => $q->where('region', $request->region)) on top. This is the main payoff: a legacy query becomes dynamic without string concatenation.

Migration workflow for a legacy codebase. Build an inventory of raw SQL strings (grep for DB::select, mysqli_query, ->query(), classify each as simple SELECT-with-joins vs. everything else, and convert in that order. Keep the original SQL in the docblock above the converted method — six months later, it is the only spec you have.

Static conversion for reporting layers. If the SQL is fixed, convert once at boot and cache the builder's toSql()/bindings pair, or memoise the converter call. There is no reason to re-parse the same string on every request.

Prefer it for reads. Convert SELECT statements and leave INSERT/UPDATE/DELETE alone unless the package explicitly handles them; write-side bugs are far more expensive than a slightly uglier DB::statement.

Gotchas and Tips

  • Dialect leakage. A SQL-string parser written against MySQL will hardcode backtick quoting, IFNULL, DATE_FORMAT, LIMIT x, y, and GROUP_CONCAT. On PostgreSQL these either produce invalid SQL or, worse, valid-but-different semantics. Grep the source for backticks and IFNULL before trusting it on another driver.
  • Parenthesised boolean groups. WHERE a AND (b OR c) must become a nested closure (->where(fn($q) => ...)). This is the single most common silent-corruption bug in converters of this type: the query runs, returns plausible rows, and is wrong. Add a test with mixed AND/OR explicitly.
  • Bindings vs. named parameters. Check whether :name placeholders are supported or only ?. If only positional, your binding array order must survive any reordering the parser does internally — getBindings() is the only way to be sure.
  • Unsupported constructs fail quietly. UNION, CTEs (WITH), correlated subqueries in the SELECT list, HAVING, window functions, and CASE expressions are typical gaps. Look for a throw in the source; if there isn't one, the parser is likely dropping tokens. Wrap the converter call in your adapter and assert on toSql() length or clause presence if nothing better is available.
  • toSql() is not proof. It shows the compiled string but does not validate semantics, and it interpolates differently from getBindings(). Compare both.
  • Laravel version drift. The query builder's where/join signatures have shifted across majors. If the package pins illuminate/database to an old major, you will hit BadMethodCallException on newer Laravel — fork it, bump the constraint, and run your golden tests.
  • Debugging aid worth ten minutes of setup: log the original SQL, the converted toSql(), and both binding arrays at debug level inside your adapter. When a report number is wrong, this is the artifact you want.
  • Extension point. The converter is almost certainly a plain class with no interface — that is your leverage. Subclass it or, better, fork the repo into your own namespace and add the missing constructs (HAVING, subquery support) as you encounter them, rather than special-casing at call sites.
  • Licence check. With no Packagist listing there may be no LICENSE file. If you are vendoring this into a commercial codebase, confirm terms with the repo owner before it goes anywhere near production.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console