Laravel 5 using 2 db connections join 2 tables - laravel

How can I join 2 tables which are located on 2 different servers.
I setup db configs:
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
'options' => [
\PDO::ATTR_EMULATE_PREPARES => true
]
],
'mysql2' => [
'driver' => 'mysql',
'host' => '132.133.22.9',
'port' => '3306',
'database' => 'contracts',
'username' => 'asdsdsa',
'password' => 'asdsad',
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
'options' => [
\PDO::ATTR_EMULATE_PREPARES => true
]
],
I'm able to access only one like DB::connection('mysql')->table('elements')->get();
How can I use leftJoin for two tables on two different servers?
lets say I have:
elements (server1):
id, class_id
classes (server2)
id, name

You can use
database one (test) include elements table and database two (test2) include classes table .
$result= DB::table('elements')
->leftjoin('test2.classes', 'elements.class_id', '=', 'classes.id')
->get();
dd($result);
you don't really need to specify first DB connection. It's by default.

test it :
for exammple i have two databases and one connection :
database one (test) include elements table and database two (test2) include classes table .
$result= DB::connection('mysql')->table('elements')
->join('test2.classes', 'elements.class_id', '=', 'classes.id')
->get();
dd($result);

Related

How to join tables on different databases from different servers

[Laravel 6]
I'm trying to join 2 tables from different server databases.
Here's the database configuration :
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'db1'),
'username' => env('DB_USERNAME', 'table1'),
'password' => env('DB_PASSWORD', 'password'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'external' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('EXTERNAL_HOST', '123.456.789.2'),
'port' => env('EXTERNAL_PORT', '3306'),
'database' => env('EXTERNAL_DATABASE', 'db2'),
'username' => env('EXTERNAL_USERNAME', 'table2'),
'password' => env('EXTERNAL_PASSWORD', 'password'),
'unix_socket' => env('EXTERNAL_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
Here's the query :
return $query->join('db2.table2', function($join) {
$join->on('table1.gateway', '=', 'db2.table2.gateway');
$join->on('table1.prefixlen', '=', 'db2.table2.prefixlen');
$join->on('table1.vlan', '=', 'db2.table2.vlan');
})->select('table1.*');
But I received this error message :
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'db2.table2' doesn't exist (SQL: select count(*) as aggregate from table1 inner join db2.table2 on table1.gateway = db2.table2.gateway and table1.prefixlen = db2.table2.prefixlen and table1.vlan = db2.table2.vlan)
I've tried googling around in the last couple days, but I couldn't figure out the right way to do it.
Any clues would be much appreciated.

how do you request on a table with multi database

When i had one database i did :
$data=DB::table('data')->select(...)
How do I it with
$data=DB::connection('foo')->select(...);
Do it that way:
$data = DB::connection('foo')->table('data')->select(...);
Good luck!
You can just configure your as many database you want in config/database.php file,
'custom_db1' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => false,
'engine' => null,
]
And Use it in eloquent Model like
protected $table = "custom_db1.table1";

How to change table prefix when a user logs in to account?

I am in new laravel, In my application When a user logs into his account I want to change the default database prefix from the env file. I setup wildcard subdomain for every users. When every user logs in I want to change the database prefix according to the sub domain.
So is it possible to change the laravel prefix globally if a user logs in Laravel?. Please suggest me if there is any solution. Thanks is advance.
Of course you can:
config/database.php
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
'mysql_earth' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_EARTH_DATABASE', 'earth'),
'username' => env('DB_EARTH_USERNAME', 'earth'),
'password' => env('DB_EARTH_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
'mysql_moon' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_MOON_DATABASE', 'moon'),
'username' => env('DB_MOON_USERNAME', 'moon'),
'password' => env('DB_MOON_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=forge
DB_USERNAME=forge
DB_PASSWORD=forgepw
DB_EARTH_DATABASE=earth
DB_EARTH_USERNAME=erth
DB_EARTH_PASSWORD=earthpw
DB_MOON_DATABASE=moon
DB_MOON_USERNAME=moon
DB_MOON_PASSWORD=moonpw
Use in your Controller example put your conditions on the connection and then you can have the query in each database:
$db = \DB::connection('mysql');
$db = \DB::connection('mysql_earth');
$db = \DB::connection('mysql_moon');
$products = $db->table('products')
->distinct()
->select("*" )
->orderBy('products.id','asc')
->get();

Laravel - Using multi connection in single query

I have use multiple database in my project. But is that possible to use multiple connection in single query in laravel? This is my connection config.
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
'mysql_pdd' => [
'driver' => 'mysql',
'host' => env('DB_PDD_HOST', '127.0.0.1'),
'port' => env('DB_PDD_PORT', '3306'),
'database' => env('DB_PDD_DATABASE', 'forge'),
'username' => env('DB_PDD_USERNAME', 'forge'),
'password' => env('DB_PDD_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
I want to join a tabel in my mysql connection to mysql_pdd table. Is that possible?
Yes, you can but for that you need to put condition, when you want to connect 'mysql' and when 'msql_pdd'.
if (mysql_connection){
$mysql =DB:: reconnect('mysql');
}else if(mysql_pdd_connection){
$mysql_pdd =DB:: reconnect('mysql_pdd');
}
Using $mysql & $mysql_pdd you can perform joins as well by code not by query.

Laravel - How to add new connection to database.php

I need to use several databases in laravel, and i'm trying to create a form to add a new db connection to connections array in config/database.php.
I don't want to add connections manually, but throught a form.
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
],
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'prefer',
],
],
Thanks
You simple add as many databases to the array as you require then add the connection values to you .env file or to the array valyes like so:
return array(
'default' => 'my_first_db',
'connections' => array(
# Our primary database connection
'my_first_db' => array(
'driver' => 'mysql',
'host' => 'host1',
'database' => 'database1',
'username' => 'user1',
'password' => 'pass1'
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
# Our secondary database connection
'my_second_db' => array(
'driver' => 'mysql',
'host' => 'host2',
'database' => 'database2',
'username' => 'user2',
'password' => 'pass2'
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
),
);
Schema::connection('my_second_db')->create('a_new_table', function($table)
{
$table->increments('id'):
});
$users = DB::connection('my_second_db')->select('users');
To add connections through a form you would need to post the data to a template similar to the above and then write to the server, This is a bit of a security risk doing that and would need to be carefull in what you do and how you go about doing it, Posting database data in a request and then just saving the database data to a file is a bit overboard.
You could either setup a config file that has 10 databases pre-defined with PDO and then you could overwrite the settings or save to one of the config files that have no settings assigned.
You can use the config helper and set the config dynamically:
config([
'database.connections.mysql.database' => $dynamicDB,
'database.connections.mysql.username' => $dbUsername,
'database.connections.mysql.password' => $dbPassword,
// Any other dynamically set variables
]);
You could store the parameters in the session and default them to your config file:
config([
'database.connections.mysql.database' => session('db_database', config('database.connections.mysql.database')),
'database.connections.mysql.username' => session('db_username', config('database.connections.mysql.username')),
'database.connections.mysql.password' => session('db_password', config('database.connections.mysql.password')),
// Any other dynamically set variables
]);
Doing this in middleware would give you a little more control over where/when these parameters are being set and used.

Resources