I am maintaining a system with many databases. One “central" db, and many other “client” dbs. Each time a client registers, we create a client db using an SQL file. The system is using Propel + PHP + MySQL.
Now the problem is, there are changes when we do version-up. It’s possible to use Propel migration for central db, but there are MANY client dbs, and in propel.yaml/ propel-config.php we only have ONE connection string for client like this:
$manager = new \Propel\Runtime\Connection\ConnectionManagerSingle();
$manager->setConfiguration(array(
'classname' => 'Propel\\Runtime\\Connection\\ConnectionWrapper',
'dsn' => 'mysql:host=127.0.0.1;dbname=' . $shopDbName . ';charset=UTF8',
'user' => 'dba',
'password' => ‘******',
'attributes' =>
array(
'ATTR_EMULATE_PREPARES' => false,
),
));
in which $shopDbName is the global variable identified by a string sent from client devices.
So, how can I automate the process of migration for client dbs in this case, please?
Related
we am using Predis to connect to a Redis instance hosted on AWS (Elasticache). We are experiencing performance issues and after having tried other scaling-related solutions, we would like to experiment with adding read replicas in our cluster (with cluster mode disabled, no sharding, just read replicas). Elasticache offers this feature out of the box, but it the documentation of Predis is not very clear on how to use different write/read endpoints.
We currently initialize RedisClient in this way
$redisClient = new RedisClient(['host' => 'the primary endpoint']);
How can we add a read replica endpoint in constructor?
The documentation of PRedis was a bit vague (or outdated). This is how we managed to make it work, in case someone is facing the same issue:
$parameters = [
['host' => $primaryEndpoint, 'role' => 'master', 'alias' => 'master'],
['host' => $replicaEndpoint, 'role' => 'slave', 'alias' => 'slave'],
];
$this->redis = new RedisClient($parameters,
['replication' => true, 'throw_error' => true, 'async' => true]);
The role and alias properties are important.
According to PRedis docs, the replication option should be set as 'replication' => 'predis' but this did not work. Using 'replication' => true did.
I've created a rather simple multi-tenant application using separate schemas in a Postgresql database. I keep a public schema, which only a few model use and then the rest of my models use the tenant. I determine the Client from the subdomain through a middleware then, call the following function on my Client model to set the credentials for the connection.
public function logInAsClient()
{
$settings = $this->settings;
// set tenant db
config([
'client' => $settings,
'client.id' => $this->id,
'database.connections.tenant.schema' => $this->schema,
'schema' => $this->schema,
'domain' => $this->domain,
]);
DB::disconnect('tenant');
DB::reconnect('tenant');
return true;
}
It's working great in normal functions, but I have several tasks which require me to queue up hundreds of jobs at a time. Since they are all running on the same app, I pass the client_id to each job and then at the start of the handle run:
Client::find($this->client_id)->logInAsClient();
However, when running this code I get the following error:
PDOException: SQLSTATE[08006] [7] FATAL: sorry, too many clients already
FATAL: sorry, too many clients already
I don't there there is any other part of my app where I am connecting or reconnecting to databases so I'm not sure where else this issue might be coming from. If there are any hints on how to debug an issue like this it would be greatly appreciated.
I want use Yii and MS Access together, but I don't know how..
I can use ODBC without Yii like this
$link = odbc_connect($name, $user, $pass)
but now i need it in Yii, like MySQL:
'db'=>array(
'connectionString' => 'mysql:host=localhost;dbname=ex1c',
'emulatePrepare' => true,
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'tablePrefix' => 'ex1c_',
)
what should i write in connection string
may be need something software setup in computer
how to set it?
If I'm understanding your question right, you have one set of data that you want to be able to reference from a YII application and from MS Access. The best approach I can think of here is to:
Put the data into a MySQL database
Have YII access it directly as you illustrate above
Set up the MySQL ODBC driver on the Windows machine where you are running access, and point Access at MySQL via that driver
Here is a pointer to MyODBC, which will provide the critical linkage between Access and MySQL:
http://dev.mysql.com/downloads/connector/odbc/
I am a new to yii although i have worked a lot with codeigniter and was just trying to convert my code from codeigniter to yii
But the CDbconnection is taking more than 1 second to execute i have attached a screenshot.
also the sql code i am using.
$criteria = new CDbCriteria();
$criteria->select = "total_photos";
$data = array( 'Gallerys' => Gallerynames::model()->findAll($criteria));
Please look into it
Edit:
Here is my db config
'db'=>array(
'class' => 'system.db.CDbConnection',
'connectionString' => 'mysql:host=localhost;dbname=yiiwiki',
'emulatePrepare' => true,
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'enableProfiling' => true,
'schemaCachingDuration' => 3600,
),
From yii guide
Because ActiveRecord relies on the metadata about tables to determine
the column information, it takes time to read the metadata and analyze
it. This may not be a problem during development stage, but for an
application running in production mode, it is a total waste of time if
the database schema does not change.
so set the schemaCachingDuration of the db application component a value greater than zero.
'db'=>array(
'class'=>'system.db.CDbConnection',
'connectionString'=>'sqlite:/wwwroot/blog/protected/data/blog.db',
'schemaCachingDuration'=>3600,
),
Keep in mind that you should specify a valid cache in the application config
EDIT
It seems your problem is not due to the schema. Refering to this changing localhost to 127.0.0.1 will fix it
I'm hosting a Yii app on shared-host with some my friend, and keep database in private MySQL server. As you knew, database info can be found so very easy in protected\config\main.php by another host owner (my friend and more):
'db'=>array(
'connectionString' => 'mysql:host=211.113.2.45;dbname=FamilyBook',
'emulatePrepare' => true,
'username' => root,
'password' => 'xcute445',
'charset' => 'utf8',
),
Is there any solution to conceal connection information as IP mySQL server, username, password?
May MySQL server provide RSA mechanism to protect database info?
Example, any people can see as below but cannot understand or use:
'db'=>array(
'connectionString' => '57bf064b2166366a5ea61109006b8d5c',
'emulatePrepare' => true,
'username' => '63a9f0ea7bb98050796b649e85481845',
'password' => 'e04ccf211208f8c97e4a36e584926e60',
'charset' => 'utf8',
), // value by MD5 function, example only
No, you cannot conceal the credentials from someone who has access to your source as long as you are using native MySql authentication. That's because your code needs to pass the credentials as cleartext¹ to the server, so it needs to be able to "decrypt" them before connecting. Someone who has access to your source can follow the same procedure and decrypt them as well.
You could secure your system by relying on some type of PAM authentication instead of user-supplied credentials, but Yii does not support such.
¹note: This is not actually true. The client passes a hash to the server, but it needs to have access to the original password in order to hash it. This means that for the purposes of this discussion it makes no difference (it would make a difference for someone who is listening on the network).
Using Yii 1.x I did it using below method.
create a class, DbConnection inside protected/components extending from CDbConnection
class DbConnection extends CDbConnection
{
public function createPdoInstance()
{
// Decrypt the password used in config file
// e.g.: $this->password = mydecrypt($this->password);
return parent::createPdoInstance();
}
}
Adjust the config file (protected/config/main.php)
'db' => array(
'class' => 'DbConnection', // Use above classname
'password' => 'encryptedpassword',
),