I ve installed datasource plugin Array. It do NOT use db tables as source of data. Its an array (source). When i try to bake using cake bake (or something) it doesnt recognize the array source used, only the tables of my database.
I would like to bake all the crud actions as done for datasource database tables as my array datasource. how can i acomplish that ?
ty advance
After you setup your DataSources. If you running the bake command from your root directory where you can see bin folder.
This will give you list of tables
sudo bin/cake bake.bake model --connection OTHER_DATABASE_NAME
Let's say we want to bake for Users table
Bake a model
sudo bin/cake bake.bake model TABLE_NAME --connection OTHER_DATABASE_NAME
In cakephp 3.x
If you want to do it manually you can create your Entity class and Table class as normal. and then in UsersTable.php add this function:
public static function defaultConnectionName()
{
return 'OTHER_DATABASE_NAME';
}
When you use Cake Bake ( and i think other console commands ) cake will look at the default value in your DATABASE_CONFIG unless you use the "-c" option. It lets you choose a different data connection. You probably default set to your database and a different one for the array datasource.
try edit yout file app.php:
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'aws.amazon-br.service',
//'port' => 'non_standard_port_number',
'username' => 'username',
'password' => 'passaword',
'database' => 'wp_my_site',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
'quoteIdentifiers' => false,
'log' => false,
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
'url' => env('DATABASE_TEST_URL', null),
],
/**
* The test connection is used during the test suite.
*/
'my_system_db' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'hostgator.dbsource.manager',
//'port' => 'non_standard_port_number',
'username' => 'my_systen',
'password' => 'secret_password',
'database' => 'my_system',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
'quoteIdentifiers' => false,
'log' => false,
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
'url' => env('DATABASE_TEST_URL', null),
],
],
After saving the app.php file, go to yout pronpt and use the bake command this format:
cake bake all name_table -c name_your_connect
Example:
cake bake all users -c my_system_db
Related
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.
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.
(Laravel Config::set Persist Through Requests?)
After getting the answer below, I tried it out...
'default' => 'mysql_main',
'connections' => [
'mysql_main' => [
'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' => false,
'engine' => null,
],
'mysql_company' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '3306'),
'database' => Auth::user()->club->db_name,
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
],
However, upon doing this inside the database.php folder under config I receive the following error...
Fatal error: Class 'Auth' not found in F:\trapstats_v5\config\database.php on line 73.
Is there another way to do dynamic database connections, based on the user, that will save through requests instead of doing config([database.connections.mysql_company.database' => Auth::user()->club->db_name]) every time I want to access the dynamic connection?
This question is similar to the answer of Dynamic database connection in Laravel. And if I do this answer as well I get the same sort of error except this time it is called Session instead of Auth.
In your config files doing
'database' => Auth::user()->club->db_name,
Is dangerous because Auth is probably not setup at the point your configuration files are read by Laravel, it needs your configuration files to lots of other things, so it should read them fist. What you can do, in, lets say a ServiceProvider, or some other helper class is to:
config('database.connections.mysql_company', ['database' => Auth::user()->club->db_name]);
After doing some more reading and going around and asking many questions I have come up with a solution.
What I ended up doing was creating a middleware called Database that ran AFTER every other middleware finished. This allowed for use of all of the typical Laravel services (like Auth::user());
Database
class Database
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (!Auth::guest()) {
config(['database.connections.club.database' => Auth::user()->club->db_name]);
}
return $next($request);
}
}
And then for the route group I assign this middleware to it.
I am trying to load some data from a plugin model which uses a different database. I have added an entry in my config/app.php as follows:
/**
* The test connection is used during the test suite.
*/
'alternate1' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
//'port' => 'non_standard_port_number',
'username' => 'alt_user',
'password' => '********',
'database' => 'secondary_db',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
'quoteIdentifiers' => false,
'log' => false,
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
'url' => env('DATABASE_TEST_URL', null),
],
In my plugin /plugins/Importer/src/Model/LogsTable.php class, I've added
public static function defaultConnectionName() {
return 'alternate1';
}
Now, I'd like to be able to access this data from my main applications controllers, so I tried this:
in /src/Controllers/ReviewController.php
$this->loadModel('Importer.Logs');
$logCount = $this->Logs->find('all')->count();
If I check the model like this:
print_r($this->Logs);
I see that it is still using the 'default' connection, and not the 'alternate1' connection.
Cake\ORM\Table Object ( [registryAlias] => Importer.Logs [table] => logs [alias] => Logs [entityClass] => \Cake\ORM\Entity [associations] => Array ( ) [behaviors] => Array ( ) [defaultConnection] => default [connectionName] => default )
I have also tried TableRegistry::get('Importer.Logs') and a few other variations, but in the end I am unable to get Cake to properly load the correct data connection.
I'm missing something simple here, I just know it. This answer: CakePHP 3 defaultConnectionName in plugin model doesn't work seems to be what I want, but it's not correct. I'm already using the Namespace.Model format.
I'm searching a way to create a variable database in Cakephp.
I'm creating a website in wich the database setting (user, pass, db) depends of the user who logg's in. The database settings come from another database.
Thanks in advance,
AƤron
-- ANSWER
Thanks for your quick reply.
I know how to switch between databases, but the database settings have to be variable.
Example
$db = $this->DB_SET['DB_SET']['db']; //from model DB_SET the database
$db_login= $this->DB_SET['DB_SET']['login'];
$db_host= $this->DB_SET['DB_SET']['host'];
$db_pass= $this->DB_SET['DB_SET']['pass'];
var $db2 = array(
'driver' => 'mysql',
'persistent' => false,
'host' => $db_host,
'login' => $db_login,
'password' => $db_pass,
'database' => $db,
'prefix' => '',
'encoding' => 'UTF8',
'port' => '',
);
If you're looking to create database connections on the fly, you may want to use ConnectionManager::create().
// get logged in user's id and create a connection for them
$id = $this->Auth->user('id');
ConnectionManager::create("user_$id_db", array(
'driver' => 'mysql',
'persistent' => false,
'host' => $db_host,
'login' => $db_login,
'password' => $db_pass,
'database' => $db,
'prefix' => '',
'encoding' => 'UTF8',
'port' => '',
));
Then set your models to use it when you're ready.
// get logged in user's id and use their connection
$id = $this->Auth->user('id');
$this->Model->setDataSource("user_$id_db");