change default db in cakephp3 - cakephp

In a controller I want to change the default database so i can access the new db (db2) from anywhere in the website. The db2 database has the same models but just different data. My code just accesses the other database but doesnt set the new default database to db2 which can be accessed anywhere in the website. I didnt get the answer from the below posts.
This is my controller :
$connection = ConnectionManager::get('db2'); // 'db2' where my second database is configured
$results = $connection->execute('SELECT * FROM tutors')->fetchAll('assoc');
//this works but doesnt set the default database to db2 everywhere
This is my app.php :
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
//'port' => 'non_standard_port_number',
'username' => 'root',
'password' => '',
'database' => 'aptutori_test',
'encoding' => 'utf8',
'timezone' => '+11:00',
'flags' => [],
'cacheMetadata' => true,
'log' => false,
'quoteIdentifiers' => false,
'url' => env('DATABASE_URL', null),
],
'db2' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
//'port' => 'non_standard_port_number',
'username' => 'root',
'password' => '',
'database' => 'aptutori_testbak',
'encoding' => 'utf8',
'timezone' => '+11:00',
'flags' => [],
'cacheMetadata' => true,
'log' => false,
'quoteIdentifiers' => false,
'url' => env('DATABASE_URL', null),
],
Dynamically change database connection in cakephp 3
http://mark-story.com/posts/view/using-cakephp-and-a-horizontally-sharded-database

Use ConnectionManager::alias():
http://api.cakephp.org/3.0/class-Cake.Datasource.ConnectionManager.html#_alias
Fore example this will make all tables that require the default connection to use db2:
ConnectionManager::alias('db2', 'default');

You could do this application wide in a Middleware in > cake 3.3, opposed to using a DispatcherFilter, like described in http://mark-story.com/posts/view/using-cakephp-and-a-horizontally-sharded-database.
<?php
namespace App\Middleware;
use Cake\Datasource\ConnectionManager;
class TenantShardMiddleware
{
public function __invoke($request, $response, $next)
{
$tenant = $request->getHeader('MY-tenant');
ConnectionManager::alias($tenant[0], 'default');
$response = $next($request, $response);
return $response;
}
}
In my example above I'm using a special Request Header to switch databases.

Related

databse not configured error while insert record in laravel

I configured second database in laravel with name Test. but when i used to insert data in second database's table. It shows me an error, database not configured please help me to find where is my mistake?
I already make configuration to add new database in project. i changed .env file and database.php file in config folder. but nothing can help me.
database.php
'mysql2' => [
'driver' => 'mysql',
'host' => 'localhost',
'port' => '3306',
'database' => 'Test',
'username' => 'root',
'password' => '',
'unix_socket' => '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
.env
DB_CONNECTION_SECOND=mysql2
DB_HOST_SECOND=127.0.0.1
DB_PORT_SECOND=3306
DB_DATABASE_SECOND=Test
DB_USERNAME_SECOND=root
DB_PASSWORD_SECOND=
SellerSelectProduct.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class SellerSelectProduct extends Model
{
protected $connection = 'Test';
protected $fillable = ['product_id'];
public function product(){
return $this->belongsTo(Product::class);
}
}
SellerBaseController.php
<?php
namespace App\Http\Controllers;
use App\Category;
use Illuminate\Http\Request;
use App\SellerSelectProduct;
class SellerBaseController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function someMethod()
{
$someModel = new SellerSelectProduct;
$someModel->setConnection('Test');
$something = $someModel->find(1);
return $something;
}
}
SellerProductController.php
<?php
namespace App\Http\Controllers;
use App\City;
use App\State;
use Illuminate\Http\Request;
use App\SellerSelectProduct;
class SellerProductController extends SellerBaseController
{
public function someMethod()
{
$someModel = new SellerSelectProduct;
$someModel->setConnection('Test');
$something = $someModel->find(1);
return $something;
}
public function index(State $state)
{
return $state->Cities;
}
public function addproducts(Request $request){
SellerSelectProduct::insert($request->data);
return response()->json([
'message' => 'Selected product list updated successfully'
]);
}
}
a sample of a second conection.
.env
DB_CONNECTION=mysql2
DB_HOST2=127.0.0.1
DB_PORT2=3306
DB_DATABASE2=
DB_USERNAME2=
DB_PASSWORD2=
database.php
'mysql2' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST2', ''),
'port' => env('DB_PORT2', '3306'),
'database' => env('DB_DATABASE2', 'forge'),
'username' => env('DB_USERNAME2', 'forge'),
'password' => env('DB_PASSWORD2', ''),
'unix_socket' => env('DB_SOCKET2', ''),
'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'),
]) : [],
],
To have an effect on clean or cache changes with or optimize handmade php command.

Call Config::set to change database in Lumen 5.4? (Using Eloquent)

I have a small application in Lumen which should handle multiple databases based on the request URL. To make this possible in the first place I've created a folder /config/ and a config-file called /config/database.php. Here is the code and I added some comments to show what I exactly need to do.
<?php
return [
'migrations' => 'home',
'default' => 'home',
'connections' => [
// This is the default option and its needed to check if the "client" exists.
'home' => [
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'home',
'username' => 'root',
'password' => 'password',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
// When the client is found in the "home" connection, I'd like to continue with this database settings as default.
'client' => [
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'client_', // There is one database per client which in the end will look like this: "client_******", so I have to add this using Config:set...
'username' => 'root',
'password' => 'password',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
],
];
I have to call Config::set to change these settings but it doesnt seem to be available on Lumen. How can i change these settings (the default database connection and its database)
I hope there is a way to make this possible. Thanks a lot :)
I found the solution.
To set and edit your configuration use the "config" helper method with an array as argument.
Example:
config(['database.default' => 'your_connection']);
In a query you can use as follows:
$connectionClient = DB::connections('client');
$connectionHome = DB::connections('home');
I hope have helped.

Working with Events and Listeners in multiple databases in Laravel

I have main database with some tables and for every client we have different databases.While using events and listeners where do I specify the connection string to use.For model and controller I have used Config:set to change my connection string dynamically for one request.I added the same in the listeners handle method,but that isn't working and the events shows as failed.
Thanks in advance.
The Listener method.
public function handle(ApplicationAssociated $event)
{
echo "Hi";
$client_id=$event->client_id;
echo 'hiii'.$client_id;
$dbconnections=DBConnection::where('client_id',$client_id)->get();
if($client_id>0)
{
foreach($dbconnections as $dbconnection)
{
echo "in if the db name is".$dbconnection->mysql_database;
echo "break";
if($dbconnection->mysql_password==NULL)
{
$password="";
}
else
{
$password=$dbconnection->password;
}
\Config::set([
'database.connections.mysql1.host' => $dbconnection->mysql_host,
'database.connections.mysql1.database' => $dbconnection->mysql_database,
'database.connections.mysql1.username' => $dbconnection->mysql_username,
'database.connections.mysql1.password' => $password,
]);
}
}
echo \Config::get('database.connections.mysql1.database');
Application::where('id',21)
->update(['name' =>'Testing eventing']);
echo "LAST";
}
try this out.
config/database.php
'mysql2' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE2', 'forge'),
'username' => env('DB_USERNAME2', 'forge'),
'password' => env('DB_PASSWORD2', ''),
'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'),
]) : [],
],
.env file
DB_DATABASE2=ichuztowork
DB_USERNAME2=root
DB_PASSWORD2=
Anywhere in your application you can set the connection string in this way
$user = (new \App\User(['name'=>'My Name', 'email'=>'myEmail#email.com']))-
>setConnection('foreignDB');
$user->save();
// or if you don't need to use the model, then just
(new \App\User(['name'=>'My Name', 'email'=>'myEmail#email.com']))-
>setConnection('foreignDB')->save();

Connect multiple database in one controller cakephp 2

Hello I am new to cakephp 2. I want to know, how to connect to database in one controller and loop for each. Please help me with details.
I have already set the following in the database config:
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'db_one',
'prefix' => '',
//'encoding' => 'utf8',
);
public $database2 = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'db_announcement',
'prefix' => '',
//'encoding' => 'utf8',
);
You should research bit more in google before asking question here.
Anyways, CakePHP takes default database connection which is there in database.php in core folder, so all your queries which you execute in the database which is defined in default vairable in database.php and if you want to connect multiple database than you can try something like this.
In your database configuration file:
public $database2 = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => '*******',
'database' => '*****',
'prefix' => '',
'encoding' => 'utf8',
);
And in your controller you can have connection in this way:
$db = ConnectionManager::getDataSource('user');
$list = $db->rawQuery('your query'); or customized CakePHP queries can work here too
I hope you will get your answer from this.
Thanks
$i=0;
$total=$list->fetchAll(PDO::FETCH_ASSOC);
instead of getDataSource method I would suggest to use $this->ModelName->setDataSource('mongo');
E.g If you want to fetch the data from User model of 'mongo' database source , which you have mentioned in database.php, then to set that it would look like.
$this->User->setDataSource('mongo')
in database.php you are having following code
public $mongo = array(
'datasource' => 'Mongodb.MongodbSource',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => 'root',
'database' => 'mongo_data',
'prefix' => '',
'encoding' => 'utf8',
);

Cakephp How to change database connection

I have 2 controllers, ContentController for general user and ManageController for administrator. I need to change the connection from default to admin and I have this code in my database.php
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'user',
'password' => '',
'database' => 'ComputerScience',
'prefix' => '',
'encoding' => 'utf8',
);
public $admin = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'admin',
'password' => '',
'database' => 'ComputerScience',
'prefix' => '',
'encoding' => 'utf8',
);
}
Thank you
So, inside your Model, you would use the useDbConfig Attribute:
class Example extends AppModel {
public $useDbConfig = 'admin';
}
Inside your Controller, simply use:
$this->ModelName->useDbConfig = 'admin';
Thats all.
I would use Model::setDataSource() rather than just setting the database config var. This is because there are other possible changes that come with changing the datasource:
$this->Model->setDataSource('admin');

Resources