renoki-co/laravel-thermite

Laravel Thermite is an extended PostgreSQL Laravel database driver to connect to a CockroachDB cluster.

1.0.0 2022-02-09 22:40 UTC

README

CI codecov StyleCI Latest Stable Version Total Downloads Monthly Downloads License

Laravel Thermite is an extended PostgreSQL Laravel database driver to connect to a CockroachDB cluster.

🤝 Supporting

If you are using one or more Renoki Co. open-source packages in your production apps, in presentation demos, hobby projects, school projects or so, sponsor our work with Github Sponsors. 📦

🚀 Installation

You can install the package via composer:

composer require renoki-co/laravel-thermite

🙌 Usage

The driver is based on Postgres, most of the features from Laravel's first-party Postgres driver are available in CockroachDB.

// config/database.php

return [
    // ...

    'connections' => [
        // ...

        'cockroachdb' => [
            'driver' => 'cockroachdb',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '26257'),
            'database' => env('DB_DATABASE', 'defaultdb'),
            'username' => env('DB_USERNAME', 'root'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'prefix' => '',
            'prefix_indexes' => true,
            'schema' => 'public',
            'sslmode' => 'prefer',
        ],

    ],
];

✨ Caveats

Primary Keys are not incremental

Postgres supports incrementing keys, but since CockroachDB is based on a global multi-master architecture, having increments may lead to transaction contention.

This way, this extended driver leverages you with two functions that you may call in your migrations to generate performant, unique IDs. The differences between the methods can be found here.

The ->id() method got replaced to generate a random UUID as primary key with gen_random_uuid() instead of an incremental primary key. The downside is that is not orderable, opposed to uniqueRowId():

use RenokiCo\LaravelThermite\Database\Blueprint;

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
});

class User extends Model
{
    // Make sure to set key type as string.
    protected $keyType = 'string';
}

With uniqueRowId(), it uses unique_rowid()-generated primary key. This is highly-orderable, being sequentially generated. The only minor downsides are the throttling upon insert, which are limited by one node.

use RenokiCo\LaravelThermite\Database\Blueprint;

Schema::create('users', function (Blueprint $table) {
    $table->uniqueRowId();
    $table->string('name');
});

class User extends Model
{
    // Do not set the $keyType to string, as it is an integer.
}

Foreign keys associated with Primary Keys

To represent the primary key constraints in other tables, like passing relational fields, consider using ->uuid():

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
});

Schema::create('books', function (Blueprint $table) {
    $table->id();
    $table->uuid('user_id')->index();
    $table->string('name');
});

$book = $user->books()->create(['name' => 'The Great Gatsby']);

Other caveats

Being based on Postgres, CockroachDB borrowed functionalities from its code. Consider reading about CockroachDB-Postgres compatibilities when it comes to schema capabilities and counter-patterns that may affect your implementation and see further caveats that are CockroachDB-only.

🐛 Testing

vendor/bin/phpunit

🤝 Contributing

Please see CONTRIBUTING for details.

🔒 Security

If you discover any security related issues, please email alex@renoki.org instead of using the issue tracker.

🎉 Credits