Download the PHP package vuthaihoc/laravel-db-portable without Composer

On this page you can find all versions of the php package vuthaihoc/laravel-db-portable. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-db-portable

Laravel DB Portable

Query builder helpers that compile for PostgreSQL / CockroachDB, MySQL / MariaDB / MatrixOne and SQLite, plus three Artisan commands for switching an application from one database to another:

It grew out of moving a Laravel application from CockroachDB to MatrixOne. Most of the changes that move needed were raw SQL written for one database (plan_data->>'amount', ::bigint, NULLS LAST, jsonb_set), and integer columns that were wider on the old database than on the new one.

Installation

Requires PHP 8.2+ and Laravel 12 or 13. The service provider is discovered automatically. The package works with Laravel's own drivers (PostgreSQL, MySQL, MariaDB, SQLite) and with these third-party drivers:

Database Driver Install
MatrixOne vuthaihoc/laravel-matrixone composer require vuthaihoc/laravel-matrixone
CockroachDB vuthaihoc/cockroachdb-laravel composer require vuthaihoc/cockroachdb-laravel

The API may still change before 1.0: pin a minor version (^0.3).

Laravel already covers a lot

Prefer Laravel's own methods where they exist. They compile for every database:

Instead of Write
whereRaw("flags->>'device' = ?", [$d]) where('flags->device', $d)
whereRaw("(flags->>'sync')::bool is true") where('flags->sync', true)
whereRaw("jsonb_array_length(meta->'tags') > 0") whereJsonLength('meta->tags', '>', 0)
whereRaw("meta @> ?", [...]) whereJsonContains('meta', [...])
update(['meta' => DB::raw("jsonb_set(...)")]) with a fixed value update(['meta->key' => $value])
whereRaw('tags::text like ?'), ilike whereLike('tags', $pattern) (case-insensitive by default)

Query builder macros

Laravel reads JSON keys as text, so numbers compare and sort as strings on PostgreSQL ("10" < "2", sum(text) fails). These macros cast per database:

The macros are registered on the query builder and on Eloquent builders. Through Eloquent, incrementJson() also updates updated_at, like increment().

What they compile to:

Macro PostgreSQL / CockroachDB MySQL / MariaDB / MatrixOne SQLite
JSON number (col->>'k')::numeric cast(json_unquote(json_extract(col, '$."k"')) as double) cast(json_extract(col, '$."k"') as real)
JSON boolean (col->>'k')::boolean json_unquote(json_extract(...)) = 'true' json_extract(...) = 1
desc nulls last x desc nulls last x desc (NULLs already last) x desc nulls last
asc nulls last x asc nulls last (x) is null, x asc x asc nulls last
JSON increment jsonb_set(<col if object, else '{}'>, '{k}', to_jsonb(... + n), true) json_set(<col if object, else json_object()>, '$."k"', ... + n) json_set(<col if object, else '{}'>, '$."k"', ... + n)

Dashboards: conditional aggregates and subtotals

PostgreSQL CockroachDB, SQLite MySQL, MariaDB, MatrixOne
selectCountWhere() / selectSumWhere() / selectAggregateWhere() count(case when … then 1 end), sum(case when … then col end) same same
rollup() group by rollup (…) union all of one query per grouping level group by … with rollup

On CockroachDB and SQLite, rollup() cannot be combined with having(), limit() or offset(), and the groupBy() columns must be selected by name.

Stale and historical reads

Named by intent; the drivers compile them:

CockroachDB MatrixOne PostgreSQL, MySQL, MariaDB SQLite
readStale() follower read (AS OF SYSTEM TIME follower_read_timestamp(), about 4.8 s old) no change: reads do not contend with writes no change: Laravel already reads from the read connection when one is configured no change
asOfTime($time) AS OF SYSTEM TIME {as of timestamp '...'} (in the connection's time zone) skipped with a warning (throws with db-portable.strict) same
readCurrent() removes it removes it no change no change

They need the drivers' historical reads: vuthaihoc/cockroachdb-laravel 2.2.2+ and vuthaihoc/laravel-matrixone. CockroachDB does not accept them in subqueries or inside a transaction (the driver then reads current data). The time read must be after the table was created, and within the database's history retention (MatrixOne: PITR or garbage-collection window).

For raw query parts, Portable returns the same expressions:

Search boxes and full-text relevance

suggest() returns values starting with the search and, from 3 characters, values containing it (or similar to it, with trigrams): prefix matches first, then the most similar, then the shortest.

CockroachDB PostgreSQL MatrixOne MySQL, MariaDB SQLite
whereStartsWith(), whereContains() ilike, trigram index ilike, trigram index ilike like (the _ci collation) like (ASCII case only)
unaccent: true unaccent(lower(col)) unaccent() (extension) no effect: accents count the collation decides no effect
whereSimilar(), orderBySimilarity() % and similarity() (driver) % and similarity() (pg_trgm) contains; score 1 prefix / 0.5 contains (warning) same as MatrixOne same as MatrixOne
searchFullText(), *FullTextRelevance() ts_rank (driver) ts_rank match ... against (driver) match ... against no whereFullText(); relevance 0 (warning)

The drivers (cockroachdb-laravel 2.3+, laravel-matrixone 1.1+) implement these methods themselves; the macros cover the other databases. MatrixOne has no typo-tolerant search: its ngram parser splits only CJK text into n-grams. The trigram threshold of % is the session's pg_trgm.similarity_threshold (0.3): set it with the connection's variables option on CockroachDB.

Migrations

Blueprint macros for schema features that differ between databases. When a database has no equivalent, the macro skips the feature and logs a warning. Set config(['db-portable.strict' => true]) to throw instead.

Macro PostgreSQL / CockroachDB MySQL MariaDB MatrixOne SQLite
jsonWithDefault() default '[]' default ('[]') default ('[]') skipped: the column is nullable, set the default in the model's $attributes default '[]'
jsonIndex() using gin (use jsonb() on PostgreSQL) skipped skipped skipped skipped
descIndex() (col desc) (col desc) (col desc) accepted, built ascending (col desc)
jsonKeyIndex() ((col->>'key')) functional index ((cast(... as char(255)) collate utf8mb4_bin)) (8.0.13+) skipped skipped (no expression indexes) ((json_extract(...)))
coveringIndex() (cols) include (extra) (CockroachDB's STORING) plain index on cols plain index on cols plain index on cols plain index on cols
trigramIndex() using gin (col gin_trgm_ops); unaccent: true: (unaccent(lower(col)) gin_trgm_ops) on CockroachDB, the column on PostgreSQL (warning) fulltext with parser ngram fulltext fulltext with parser ngram (CJK n-grams, whole words otherwise) skipped
partialIndex() (cols) where ... plain index, condition dropped plain index, condition dropped plain index, condition dropped (cols) where ...

Skipped features and dropped conditions log a warning (or throw with db-portable.strict). forDriver() runs the callback of the connection's driver or family and emits nothing by itself.

The where condition of partialIndex() is raw SQL: keep it portable (deleted_at is null, status = 'active').

Search indexes for Scout models

db-portable:search-indexes reads the Scout attributes of your models and checks that their tables have the indexes the database engines need (SCOUT_DRIVER=database, crdb or matrixone), or writes a migration creating them:

Declared on toSearchableArray() CockroachDB / PostgreSQL MatrixOne MySQL SQLite
#[SearchUsingFullText(cols, ['language' => ...])] fullText(cols)->language(...), matching whereFullText() fullText(cols): required, MATCH fails without it fullText(cols) none
#[SearchUsingFuzzy(cols, unaccent: ...)] (cockroachdb-laravel 2.4) trigramIndex(col, unaccent: ...) none (no trigram similarity) none none
#[SearchUsingPrefix(cols)] trigramIndex(col) (serves ilike 'x%') index(col) index(col) index(col)
other columns, with --like trigramIndex(col) none (LIKE '%x%' cannot use an index) none none
toSearchableEmbedding() vectorIndex(embedding) vectorIndex(embedding) none none

Switching databases

A suggested workflow, e.g. from CockroachDB (crdb) to MatrixOne (matrixone):

  1. Scan the code for SQL the new database will reject, and rewrite it with the methods above.
  2. Migrate the new database: php artisan migrate --database=matrixone.
  3. Audit the data against the new schema, and widen the columns it reports.
  4. Copy the data.
  5. Point DB_CONNECTION at the new database and run your test suite.

Scan

The scanner reads the string literals of your PHP files (not comments or code) and reports each construct with the families it breaks on and a replacement:

Targets: mysql (MySQL, MariaDB), matrixone, pgsql (PostgreSQL, CockroachDB), sqlite. Code that already branches per driver is still reported, because the scanner cannot tell which branch runs.

Audit

It reports tables and columns missing from the target, integers outside the target column's range, and strings longer than the target varchar(n). It runs one min/max query per table on the source.

Copy

Testing

The Unit suite needs no server. The Conformance suite runs the same assertions on SQLite (in memory), MatrixOne and CockroachDB, and skips a server that is not reachable:

Override the servers with MATRIXONE_HOST, MATRIXONE_PORT, CRDB_HOST, CRDB_PORT (see phpunit.xml.dist). To test against local checkouts of the drivers, add path repositories to a local copy of composer.json ("repositories": [{"type": "path", "url": "../laravel-matrixone"}]) and require them as @dev.

License

MIT. See LICENSE.


All versions of laravel-db-portable with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
illuminate/console Version ^12.0 || ^13.0
illuminate/database Version ^12.0 || ^13.0
illuminate/support Version ^12.0 || ^13.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package vuthaihoc/laravel-db-portable contains the following files

Loading the files please wait ...