Migrating existing cakephp 3.0 database to postgres from mysql - php

I am in the process of migrating a cakephp 3.0 database from mysql to postgress. I used this tool for the database migration and it worked beautifully. After that I changed the config file as shown below.
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Postgres',
'persistent' => false,
'host' => 'localhost',
'port' => '5432',
'username' => 'postgres',
'password' => 'mypass',
'database' => 'cake_bookmarks',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
'log' => false,
'quoteIdentifiers' => false,
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
],
The root folder in localhost also shows "successfully connected to database". However when i run my application, it shows an error:
Cannot describe mytable. It has 0 columns. Cake\Database\Exception
I can't make sure if this is because of not connecting to the database (which i think is unlikely as the root page shows as connected) or cakephp being unable to use my database.
If so, how can I fix the issue. I am quite new to cakephp too, just confguring and doing basic stuff.

Try the following (test after each step):
Check if the table is present in the database
Check if the expected columns are defined into the table
Clear the Cake cache (if is FileCache is enough to delete files under tmp/cache/persistent tmp/cache/models and tmp/cache/views
Check the permissions of the specific user on the database cake_bookmarks (maybe via phppgadmin)
Hope to help!

Related

laravel redis database parameter

'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', 'redis'),
'password' => env('REDIS_PASSWORD', 'secret'),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
'session' => [
'host' => env('REDIS_HOST', 'redis'),
'password' => env('REDIS_PASSWORD', 'secret'),
'port' => env('REDIS_PORT', 6379),
'database' => 1,
],
Can anyone explain the database parameter in config/database.php file , I am clueless regarding this parameter as it is not stated in the docs .
According to another website , to set up session to use the redis driver , need to add another redis database and this parameter is set to 1 but it points to the same redis instance. I'm quite confused .
Thank you
EDIT
Based on more digging through redis docs I've come to a conclusion . Please do correct me if i'm wrong .
The database parameter indicates that to place in which redis database . According to the docs , Redis has by default 16 databases.
CONFIG GET databases
1) "databases"
2) "16"
And by placing the parameter database , we are indicating which database to use , for example place all the session keys to database 1 instead of database 0 which we can access by using the
SELECT db_number E.g SELECT 1
Please let me know if my conclusion is correct or wrong . Thank you =)
A redis instance has multiple databases as you stated.
The database parameter tells redis which database to use inside the instance.
The instance is defined in "host".
You don't need to select database in code level with "select" since you have declared the database in config.
If you omit the "database" param, then the default "0" database will be used.
If you want to use multiple databases (e.g cache to one db, sessions to another) then you need to create multiple connections in your config.

How can I move my codigniter databse to google cloud sql?

I want to move my codeigniter project database to google cloud sql but I didn't see phpmyadmin.
How can i export my database to google and where do i get myconnection details, host,password,user and dbname just like I have on my local server?
The documentation is not very clear to someone who is not familiar with that environment. Thanks
This is my database config file
$active_group = 'default';
$query_builder = TRUE;
$db['default'] = array(
'dsn' => '',
'hostname' => '104.197.147.157',
'username' => 'mylasttestingaccount',
'password' => '',
'database' => 'mydatabase',
/*
'username' => 'develope_prakash',
'password' => '[REDACTED]',
'database' => 'develope_ubah',
*/
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => FALSE,
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array(),
'save_queries' => TRUE
);
This is a multipart question, so I'll answer the questions as I understand them.
NOTE: Cloud SQL instances are not managed using phpmyadmin, but they are managed mainly using the Cloud Console. This also means that whatever changes you want to make (such as adding users) needs to be done using the Cloud Console, or from one of the other management tools such as the gcloud command line tool.
1) You'll need to create an instance first. I highly advise a 2nd gen instance.
2) Adding a user can be done from the Console or the gcloud command line tool. Both are described in the same article.
3) As for importing data from another database, there's a separate article on this. There's some conditions that need to be met before you can successfully import data. The export needs to be created in a certain way. This is described in detail in this article. After getting the export you can import it using the steps described in the first article I linked in this paragraph.
To wrap it up, I highly advise you to read through the documentation about Cloud SQL. Any of the ones I linked have a list of articles on the left side which contains just about everything you need to know about Cloud SQL.
One additional note, NEVER provide passwords for anything on a public site like SO.

Use Redis and MongoDB ActiveRecords together in Yii2

I have MongoDB Active Records (models) and I'm wondering if it's possible to use Redis to automatically set/get/delete the models from Redis's storage.
For example, if I was to run:
MyModel::find()->where(["id" => 1])->one();
is there a way to make Redis store the result and return it the next time I run that same code?
Also, if I was to update the model with id = 1, I'd expect Redis to invalidate the cache.
Is all that possible?
It doesn't matter which DB to use. It is about how to implement them. Yii have those two components to set in the config file:
db: a database connection to be used where needed like an Active Record class to represent a model or Query Builders or ...
cache: designed to cache things from HTML pages and HTTP requests to database queries related data.
The good thing about MongoDB and Redis is that both can be used as a database connection or as a cache component. You may have those configs for example:
'components' => [
'db' => [
'class' => '\yii\mongodb\Connection',
'dsn' => 'mongodb://developer:password#localhost:27017/mydatabase',
],
'cache' => [
'class' => 'yii\redis\Cache',
'redis' => [
'hostname' => 'localhost',
'port' => 6379,
'database' => 0,
]
],
],
Here, while MongoDB is set as your default database, Redis is only used as a cache component and because all cache components have the same base class yii\caching\Cache they only support those APIs. Which should be fine if you are using it for caching proposes only.
Check the Yii2 Caching Guide to see all what you can do with a cache component. A quick example of what you are trying to do may be seen within #Blizz answer here where he did set an SQL query as a dependency to check if cached data should be used or invalidated instead.
In case you need to use the Redis database for more than just caching then you may have those configs instead:
'components' => [
'mongodb' => [
'class' => '\yii\mongodb\Connection',
'dsn' => 'mongodb://developer:password#localhost:27017/mydatabase',
],
'redis' => [
'class' => 'yii\redis\Connection',
'hostname' => 'localhost',
'port' => 6379,
'database' => 0,
],
'cache' => [
'class' => 'yii\redis\Cache',
'redis' => 'redis' // id of the connection application component
],
],
Here we defined 2 databases and selected one of them to be also used as a cache component. It should work the exact same way except that you can also use the Redis database inside your app as a Redis ActiveRecord or a Redis ActiveQuery class. You will just need to set which DB to be used inside each model class as it is done in this example.

How to use orchestral/tenanti in Laravel 5 to build a multi tenant application with multiple databases?

I am trying to build and application using Laravel 5. It is supposed to be a multi tenant database architecture using multiple databases. My employer requires this for security purposes.
I have tried manually managing the main DB migrations and the Tenant migrations but failed. So I decided to take the help of a Laravel specific package which is supposedly what I require.
Tenanti provides a way to have my purpose solved but the problem is that me being a novice developer, am not able to fully understand how to use it in my application.
I have installed it correctly I believe doing:
composer require "orchestra/tenanti=~3.0"
Adding these providers and aliases in the config app file:
'providers' => [
// ...
Orchestra\Tenanti\TenantiServiceProvider::class,
Orchestra\Tenanti\CommandServiceProvider::class,
],
'aliases' => [
'Tenanti' => Orchestra\Support\Facades\Tenanti::class,
],
Finally publishing the config and tweaking it according to the documentation for multiple databases:
php artisan vendor:publish
return [
'drivers' => [
'user' => [
'model' => App\User::class,
'migration' => 'tenant_migrations',
'path' => database_path('tenanti/user'),
],
],
];
At this point I am still blurry what to do next?
My doubts are as follows:
Where will the migration files be generated and stored? I mean there are two kinds of databases in my application obviously. One set of files is for the main DB which will store all the tenant information and the other files will be for the tenant DB. So how and where will these be stored?
I see the word 'driver' a lot in the documentation but I am not sure what driver is exactly.
How will I handle the authentication for the application? I mean whenever a tenant logs in, I will have to make sure the connection to the database changes dynamically. How will I accomplish this?
I tried to go through the repository of the package itself and make sense of the code inside but in vain. I am not very good when it comes to design patters like facades, command bus, service provider and so on, which is why I am not able to understand the flow of the package or make sense of it.
I tried to run some of the artisan commands which come with the package like:
php artisan tenanti:install {driver}
php artisan tenanti:make {driver} {name}
But I am getting an error like so:
[InvalidArgumentException] Database connection
[tenants] is not available.
Where can I find the resources to understand how to proceed with this?
+1 to #morphatic answer, it quiet accurate on most of the stuff.
Migration
One set of files is for the main DB which will store all the tenant information and the other files will be for the tenant DB. So how and where will these be stored?
For your main database you should be able to use the default database/migration and utilize php artisan make:migration and php artisan migrate.
Tenanti however will use the migration path set under the "driver" configuration. e.g:
'path' => database_path('tenanti/user'),
In this case the migration will be created/migrated from database/tenanti/user (you can choose other folder and it will use that folder). Once you set this up you can create new migration file for the user tenant via php artisan tenanti:make user create_blogs_table (as an example) and run migration via php artisan tenanti:migrate user (see the similarity between Laravel migration command and Tenanti?).
Driver
Driver is just the grouping of a tenant, you maybe grouping it by users, companies, or team etc. And there is possibility that you may require more than one type of group per project, otherwise most of the time you only be using single "group" or "driver".
Authentication or Accessing DB
How will I handle the authentication for the application? I mean whenever a tenant logs in, I will have to make sure the connection to the database changes dynamically. How will I accomplish this?
First of all, you need to consider how you're planning to distinguish each tenant. Most of the time I would see people tend to opt for subdomain. So in this case you need to check if the subdomain belongs to any of the user (by querying the main database) using a middleware and then connect to the database that belongs to the user.
Tenanti doesn't manage that part of the process, because everyone has different style on that aspect, but we do provide a code to dynamically connect to your database tenant from a base database configuration.
Let say you have the following config:
<?php
return [
'fetch' => PDO::FETCH_CLASS,
'default' => 'primary',
'connections' => [
'primary' => [
//
],
'tenants' => [
'driver' => 'mysql',
'host' => 'dbhost', // for user with id=1
'username' => 'dbusername', // for user with id=1
'password' => 'dbpassword', // for user with id=1
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
],
],
'migrations' => 'migrations',
'redis' => [ ... ],
];
You can follow the step available in https://github.com/orchestral/tenanti#multi-database-connection-setup and add the following code.
<?php namespace App\Providers;
use Orchestra\Support\Facades\Tenanti;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Tenanti::setupMultiDatabase('tenants', function (User $entity, array $template) {
$template['database'] = "tenant_{$entity->getKey()}";
return $template;
});
}
}
This would ensure that you be using tenant_1 database for user=1, tenant_2 database for user=2 and so on.
So how does Tenanti detect which user if active?
This is where you need to add logic in your middleware.
$user = App\User::whereSubdomain($request->route()->parameter('tenant'))->first();
Tenanti::driver('user')->asDefaultDatabase($user, 'tenants_{id}');
I've never used this package, but using the code you submitted above here's what I think is probably close to the right solution. You will probably still need to play with some of these values to get them correct:
Migration Paths
Since you're using the multi-database configuration, I believe you should be able to keep your migrations in the normal location, i.e. database/migrations. Tenanti will then create an exact replica of the database for each tenant in a different database. However, when you run php artisan tenanti:install user it might actually create a folder under database/ that indicates where you should put your migrations.
What is a "driver"?
The driver describes whether Tenanti will use a single or multiple databases, what models to use for determining different tenants, and where to store migrations. It is what you identified in the Tenanti config file you used above.
Database Connection Selection
You need to update config/database.php as follows. In a normal Laravel app, you would have the DB connection setup as follows:
<?php
return [
'fetch' => PDO::FETCH_CLASS,
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'sqlite' => [ ...DB connection info... ],
'mysql' => [ ...DB connection info... ],
'pgsql' => [ ...DB connection info... ],
'sqlsrv' => [ ...DB connection info... ],
],
'migrations' => 'migrations',
'redis' => [ ... ],
];
However, in the case of Tenanti multi-database setup, you need to add in different connection info for each tenant's database. To do this you would add a new level to your database.php config file (this example assumes you're using mysql, but you could use any DB, or even different database engines for different tenants):
<?php
return [
'fetch' => PDO::FETCH_CLASS,
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'tenants' => [
'user_1' => [
'driver' => 'mysql',
'host' => 'dbhost', // for user with id=1
'database' => 'dbname', // for user with id=1
'username' => 'dbusername', // for user with id=1
'password' => 'dbpassword', // for user with id=1
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
'user_2' => [
'driver' => 'mysql',
'host' => 'dbhost', // for user with id=2
'database' => 'dbname', // for user with id=2
'username' => 'dbusername', // for user with id=2
'password' => 'dbpassword', // for user with id=2
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
],
],
'migrations' => 'migrations',
'redis' => [ ... ],
];
As you can see, each tenant has its own database instance that can be located on a different host and have a different username/password. Tenanti needs to be told how to figure out which database to use. This is what the documentation on Database Connection Resolver describes. In their example, they've named their tenant databases using acme_{$user->id} whereas in my example above I used user_{$user->id}.
Like I said, I've never actually set this up myself, but these are my best guesses based on the docs, and having used other packages by this same developer. Hope this helps!

Problems loading Zends Session in bootstrap

I am having trouble getting Zend to store my session in MySQL table. I have followed the Zend Framework guide step by step, and am not sure if is where am putting the code in my bootstrap file, but once the code snippet is in place and I load my site Apache just crashes. Literally crashes. My logs don't say anyhing.
Here is my code:
$db = Zend_Db::factory( 'Pdo_Mysql', array(
'host' => 'localhost',
'username' => 'root',
'password' => '*****',
'dbname' => 'drecords'
));
Zend_Db_Table_Abstract::setDefaultAdapter( $db );
$config = array(
'name' => 'sessions',
'primary' => 'id',
'modifiedColumn' => 'modified',
'dataColumn' => 'data',
'lifetimeColumn' => 'lifetime'
);
Zend_Session::setSaveHandler( new Zend_Session_SaveHandler_DbTable( $config ) );
//start your session!
Zend_Session::start();
I am running this code right after at the end of my Bootstrap file.
My question is what am I doing wrong if am following Zends documentation? Is there something I need to know like an extra configuration option in my MySQL or PHP.ini that am not aware of?
Did you create the table in MySQL?
your user have insert/update/delete privileges on the table
do your php setups output errors, what environment are your running production/development
I think the code should probably output some error but if your disabled the output of those you cannot see them.

Categories