A simple strategy for handling dynamic databases of varying types
You can install the package via composer:
composer require envor/laravel-datastore
You can publish and run the migrations with:
php artisan vendor:publish --tag="datastore-migrations"
php artisan migrate
You can publish the config file with:
php artisan vendor:publish --tag="datastore-config"
This is the contents of the published config file:
return [
'model' => \Envor\Datastore\Models\Datastore::class,
'create_databases' => env('DATASTORE_CREATE_DATABASES', true),
];
You actually don't need to use the model or even run migrations. You can use the factory directly like so:
use Envor\Datastore\DatabaseFactory;
$sqlite = DatabaseFactory::newDatabase('mydb', 'sqlite');
// Envor\Datastore\Databases\SQLite {#2841 ...
$sqlite->create();
// true
$sqlite->name;
// ...storage/app/datastore/mydb.sqlite
$sqlite->connection;
// mydb
$sqlite->migrate();
// INFO Preparing database.
// Creating migration table ................ 9.55ms DONE
$sqlite->configure();
config('database.default');
// "mydb"
config('database.connections.mydb');
// [
// "driver" => "sqlite",
// "url" => null,
// "database" => "...storage/app/datastore/mydb.sqlite",
// "prefix" => "",
// "foreign_key_constraints" => true,
// "name" => "mydb",
// ]
/**
* Create a newly registered user.
*
* @param array<string, string> $input
*/
public function create(array $input): User
{
$create = function () use ($input) {
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => $this->passwordRules(),
'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['accepted', 'required'] : '',
])->validate();
return DB::transaction(function () use ($input) {
return tap(User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]), function (User $user) {
$this->createTeam($user);
});
});
};
SQLite::make(database_path('my_backup.sqlite'))
->create()
->migratePath('database/migrations/platform')
->migrate()
->run($create)
->disconnect();
MariaDB::make('backup')
->create()
->migratePath('database/migrations/platform')
->migrate()
->run($create)
->disconnect();
return MariaDB::make('datastore')
->create()
->migratePath('database/migrations/platform')
->migrate()
->run($create)
->return();
}
You can use the 'datastore.context' middleware to get the app to behave in the context of the current datastore;
Route::get('/contexed', fn() => 'OK')->middleware('datastore.context');
// or
Route::get('/contexed', fn() => 'OK')->middleware(\Envor\Datastore\DatastoreContextMiddleware::class);
// will use the authenticated user to configure a database
Your user must implement the HasDatastoreContext
interface in order for this to work.
...
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements \Envor\Datastore\Contracts\HasDatastoreContex
{
use \Envor\Datastore\Concerns\BelongsToDatastore
public function datastoreContext(): \Envor\Datastore\Contracts\ConfiguresDatastore;
{
return $this->datastore;
}
}
Here are the relevant interfaces:
interface HasDatastoreContext
{
public function datastoreContext(): ?\Envor\Datastore\Contracts\ConfiguresDatastore;
}
interface ConfiguresDatastore
{
public function configure();
public function use();
public function database(): ?\Envor\Datastore\Datastore;
}
composer test
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.