Dynamic database connection in Laravel - php

I know that in Laravel you can use multiple database connections by specifying them in the config/database.php file, then using DB::connection('my_conn_name'), but is there anyway to use a connection that is not specified in the config/database.php file?
I am writing an archiving application, so the user can specify what connection they would like to use for the process (host, user and password), and I am hoping that I can return the results from show databases for the supplied connection.

After the user has specified the db parameters you could store it in a session to populate a custom connection at config/database.php:
'connections' => [
'mysql' => [
'...'
],
'testing' => [
'...'
],
'custom' => [
'driver' => 'mysql',
'host' => session()->get()->db_host,
'database' => session()->get()->db_database,
'username' => session()->get()->db_username,
'password' => session()->get()->db_password,
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
]
]

Related

Laravel validation 'exist' not working in master-slave DB configuration?

I am moving the project to Master-Slave configuration and got a problem, that validation related to DB stopped working for me. Any ideas what I'm missing?
so here is validation part:
$request->validate([
'property_id' => 'required|exists:mysql.property,p_id',
... other validations not related to DB ...
], $error_messages);
file config\database.php :
'mysql' => [
'driver' => 'mysql',
'write' => [
'host' => '196.168.56.211',
],
'read' => [
'host' => '192.168.56.222',
],
'port' => '3306',
'database' => 'project_db',
'username' => 'db_user',
'password' => 'pass123',
'unix_socket' => env('DB_SOCKET'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
\PDO::ATTR_EMULATE_PREPARES => true,
],
this is what i'm reciving:
in file \vendor\laravel\framework\src\Illuminate\Database\Connection.php [663]:
catch (Exception $e) {
throw new QueryException(
$query, $this->prepareBindings($bindings), $e
);
}
SQLSTATE[HY000] [2002] An attempt to establish a connection was
unsuccessful, because The required response was not received from the
other computer within the required time, or the already established
connection was terminated due to the incorrect response of the already
connected computer. (SQL: select count(*) as aggregate from
property where p_id = 2444)
and this is happens when laravel try to connect to 'write' database.
But from MySQL workbench - connecting & editing records fine.
any ideas?
change your config to
'mysql' => [
'write' => [
'host' => '196.168.56.211'
],
'read' => [
'host' => '192.168.56.222',
],
'sticky' => true,
'driver' => 'mysql',
'database' => 'project_db',
'username' => 'db_user',
'password' => 'pass123',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
],
This ensures that any data written during the request cycle can be immediately read back from the database during that same request
official document read for more info

Illuminate Database connectivity with mysql router

I'm using Laravel's illuminate database library outside laravel with jessengers mongodb.
My requirement is multiple database connectivity through illuminate database.
Currently, I've added two connection one mysql and one mongodb.
To split the database load, I need to connect to mysql router instead of mysql db server directly. Also, in that I want one only for Read operation and one for Read/Write operation.
Kindly help me out on this.
Thanks in advance.
Current connections
$db = new Capsule;
$db->addConnection([
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => 'test',
'username' => 'test',
'password' => 'test#123#',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
], "default");
$db->addConnection([
'driver' => 'mongodb',
'host' => '127.0.0.1',
'port' => 27017,
'database' => 'test',
'username' => null,
'password' => null,
'options' => []
], "mongodb");
$db->getDatabaseManager()->extend('mongodb', function ($config) {
return new Connection($config);
});
$db->setEventDispatcher(new Dispatcher(new Container));
$db->setAsGlobal();
$db->bootEloquent();
I need to replace one mysql connection with two mysql connection for Read and Read/Write operation through mysql router.
You can define read/write options separately with either mysql host or mysql router host and port
$db->addConnection([
'driver' => 'mysql',
'read' => [
'host' => '<mysql_router_host_ip>',
'port' => '<mysql_router_host_port>'
],
'write' => [
'host' => '<mysql_router_host_ip>',
'port' => '<mysql_router_host_port>'
],
'database' => '<mysql_database>',
'username' => '<mysql_database_user>',
'password' => '<mysql_database_password>',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
], "mysql");

Configuration error with MongoDB laravel

I am planning to use MongoDb along with my Laravel project. I am using the jensseger/mongodb extension for it.
I have configured everything. I am getting an error saying mongodb not configured.
This is how my database.php file looks like:
'connections' => [
# Our primary database connection
'mongodb' => [
'driver' => 'mongodb',
'host' => env('DB_HOST'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
Double check your configuration in config/database.php
Also make sure that you fire php artisan config:cache after doing the changes.
Be sure to have DB_CONNECTION=mongodb set in your .env file or just replace 'default' => env('DB_CONNECTION', 'mysql') with 'default' => 'mongodb'. I would go with the former, as it's safer to rely only on the .env, rather than hardcoding your default database connection.
'mongodb' => [
'driver' => 'mongodb',
'host' => env('MONGO_DB_HOST', 'localhost'),
'port' => env('MONGO_DB_PORT', 27017),
'database' => env('MONGO_DB_DATABASE'),
'username' => env('MONGO_DB_USERNAME'),
'password' => env('MONGO_DB_PASSWORD'),
'options' => ['database' => 'Database_Name']
],
After clear cache "php artisan config:cache"
go to .env
Add these lines:
MONGO_DB_HOST=127.0.0.1
MONGO_DB_PORT=27017
MONGO_DB_DATABASE=your database name
MONGO_DB_USERNAME=your database username if you have
MONGO_DB_PASSWORD=your database password if you have

Laravel 4.2 Session Database Driver Read / Write Host

I configured the way I separate the database to read and write.
'mysql' => [
'read' => [
'host' => '192.168.1.1',
],
'write' => [
'host' => '196.168.1.2'
],
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
],
But now, I want to change the database driver in the session and I want to be able to read and write operations to a single host of the session value.
How can I only run on a single host in the session process without disturbing the above structure?
I think I found a solution.
We are adding a new connection into the first database.php connections.
'session' => array(
'host' => "HOST_NAME",
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
then we give the name of the connection a little bit before we install the connection value in session.php file.
'connection' => "session",
Thats it.

Seeding tenant database in Laravel 5

I am working on building a system using a main database and multiple tenant databases in laravel 5. I have a database migration and seed for the main database no problem, using php artisan migrate:refresh --seed.
Tenants then get their own database upon registration. I need to run a migration and seed on the tenants database.
The tenant migration files are stored in a separate folder. The migration runs (unfortunately on the main database) with the following command
\Artisan::call('migrate', [
'--path' => "database/migrations_system"
);
However I need the migration to occur on the tenant database, say DB_1.
I read the following should work
\Artisan::call('migrate', [
'--path' => "database/migrations_system",
'--database' => 'db_1'
]);
However I end up with an error
InvalidArgumentException in DatabaseManager.php line 238:
Database [db_1] not configured.
Stuck.... How can I specify the migration to run on a specific database?
UPDATE:
I have found that changing config/database.php and adding db_1 gets me past this error....
'db_1' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => 'db_1',
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', 'pass'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'port' => '3306'
],
However this connection is unknown and needs to be done on the fly, which I am also stuck on how to accomplish....
UPDATE Again and working solution.... Modify the config on the fly...
$connections = \Config::get('database.connections');
$tenant_database = 'db_1'; //assign from your main database
$tenant_connection = [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => $tenant_database ,
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'port' => '3306'
];
$connections['tenant'] = $tenant_connection;
\Config::set('database.connections', $connections);
\Artisan::call('migrate', [
'--path' => "database/migrations_system",
'--database' => 'tenant'
]);
So it looks like I have answered my own question, however maybe some can comment on this procedure.
I'll put my own solution down....
1) Create the database name
For example I name the new database db_1 where 1 represents the ID of the system in the main database. I have considered storing a unique scrambled name in the main database. In the end that seemed like overkill.
2) Create the connection - for this I use the exact same name as the new database.
public function createConnection()
{
$connections = \Config::get('database.connections');
if(!isset($connections[$this->getSystemName()]))
{
$tenant_connection = [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => $this->getSystemName(),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'port' => '3306'
];
$connections[$this->getSystemName()] = $tenant_connection;
\Config::set('database.connections', $connections);
//dd(\Config::get('database.connections'));
}
}
3) Create the database, which you do using your main connection
$sql = "CREATE DATABASE " . $this->tenant_name;
DB::connection('main_db')->statement($sql);
4)run the migration
$r = \Artisan::call('migrate', [
'--path' => "database/migrations_tenant",
'--database' => $this->tenant_name
]);
5) finally you can seed test data or load some default data. Access the connection like
DB::connection($this->system_name)->table($table)->insert($csv);

Categories