-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch between multiple databases #59
Comments
You can try changing $config in model. |
The only way we we're able to solve this:
class DatabaseDynamic extends \Purekid\Mongodm\MongoDB
{
/**
* @param string $name name
* @param array $config config
*/
protected function __construct($name, array $config)
{
$this->_name = $name;
$this->_config = $config;
/* Store the database instance */
static::$instances[$name] = $this;
}
/**
* Connect to MongoDB, select database
*
* @throws \Exception
* @return bool
*/
public function connect()
{
if ($this->_connection) {
return true;
}
$config = $this->_config['connection'];
$result = parent::connect();
$this->_config['connection'] = $config;
return $result;
}
/**
* Load instance
*
* @param string $name name
* @param array|null $config config
*
* @static
*
* @return MongoDB
*/
public static function instance($name = 'default', array $config = null)
{
if (!isset(static::$instances[$name])) {
if ($config === null) {
// Load the configuration for this database
$config = static::config($name);
}
static::$instances[$name] = new static($name, $config);
}
return static::$instances[$name];
}
public function updateConfigDB($db)
{
// Extract Db from connection
if (empty($this->_config['connection'])) {
throw new \Exception('No Config Specified In MongoDB');
}
$this->_config['connection']['database'] = $db;
}
/**
* @param string $db
*
* @throws \Exception
* @return null
*/
public function selectDB($db)
{
$this->updateConfigDB($db);
if (!$this->_connection) {
return;
}
$this->_db = $this->_connection->selectDB($db);
if (!$this->_db instanceof \MongoDB) {
throw new \Exception('Unable to connect to database :: $_db is ' . gettype($this->_db));
}
}
/**
* @param array $config config
*
* @return null
*/
public static function setConfig($config)
{
static::$config = $config;
}
/**
* @param string $block block
* @param array $config config
*
* @return null
*/
public static function setConfigBlock($block = 'default', $config = array())
{
static::$config[$block] = $config;
}
/**
* @param string $config_block config_block
*
* @throws \Exception
* @return array
*/
public static function config($config_block)
{
if (!empty(static::$config)) {
return static::$config[$config_block];
}
else {
throw new \Exception("database config section '{$config_block}' not exist!");
}
}
}
abstract class ModelDynamic extends \Purekid\Mongodm\Model
{
protected static $database = null;
/**
* Get database name
*
* @return string
*/
public static function databaseName()
{
$class = get_called_class();
$database = $class::$database;
return $database;
}
private function useDatabaseDynamicPrivate()
{
$this->_connection->selectDB(static::databaseName());
}
public static function useDatabaseDynamic()
{
static::connection()->selectDB(static::databaseName());
}
/**
* Model
*
* @param array $data data
* @param bool $mapFields map the field names
* @param bool $exists record exists in DB
*/
public function __construct($data = array(), $mapFields = false, $exists = false)
{
if ($mapFields === true) {
$data = static::mapFields($data, true);
}
if (is_null($this->_connection)) {
if (isset($this::$config)) {
$config = $this::$config;
} else {
$config = static::$config;
}
$this->_connection = DatabaseDynamic::instance($config);
}
$this->update($data, true);
if ($exists) {
$this->exist = true;
} else {
$this->initAttrs();
}
$this->initTypes();
$this->__init();
}
/**
* Mutate data by direct query
*
* @param array $updateQuery update query
* @param array $options options
*
* @throws \Exception
* @return boolean
*/
public function mutate($updateQuery, $options = array())
{
$this->useDatabaseDynamicPrivate();
return parent::mutate($updateQuery, $options);
}
/**
* Delete this record
*
* @param array $options options
*
* @return boolean
*/
public function delete($options = array())
{
$this->useDatabaseDynamicPrivate();
return parent::delete($options);
}
/**
* Save to database
*
* @param array $options options
*
* @return array
*/
public function save($options = array())
{
$this->useDatabaseDynamicPrivate();
return parent::save($options);
}
/**
* Retrieve a record
*
* @param array $criteria criteria
* @param array $fields fields
*
* @return Model
*/
public static function one($criteria = array(), $fields = array())
{
static::useDatabaseDynamic();
return parent::one($criteria, $fields);
}
/**
* Retrieve records
*
* @param array $criteria criteria
* @param array $sort sort
* @param array $fields fields
* @param int $limit limit
* @param int $skip skip
*
* @return Collection
*/
public static function find($criteria = array(), $sort = array(), $fields = array(), $limit = null, $skip = null)
{
static::useDatabaseDynamic();
return parent::find($criteria, $sort, $fields, $limit, $skip);
}
/**
* group
*
* @param array $keys keys
* @param array $query query
* @param mixed $initial initial
* @param mixed $reduce reduce
*
* @return mixed
*/
public static function group(array $keys, array $query, $initial = null, $reduce = null)
{
static::useDatabaseDynamic();
return parent::group($keys, $query, $initial, $reduce);
}
/**
* aggreate
*
* @param array $query query
*
* @return array
*/
public static function aggregate($query)
{
static::useDatabaseDynamic();
return parent::aggregate($query);
}
/**
* Distinct records
*
* @param string $key key distinct key
* @param array $criteria criteria
*
* @return string Records
*/
public static function distinct($key, $criteria = array())
{
static::useDatabaseDynamic();
return parent::distinct($key, $criteria);
}
/**
* Has record
*
* A optimized way to see if a record exists in the database. Helps
* the developer to avoid the extra latency of FindOne by using Find
* and a limit of 1.
*
* @link https://blog.serverdensity.com/checking-if-a-document-exists-mongodb-slow-findone-vs-find/
*
* @param array $criteria criteria
*
* @return boolean
*/
public static function has($criteria = array())
{
static::useDatabaseDynamic();
return parent::has($criteria);
}
/**
* Count of records
*
* @param array $criteria
*
* @return integer
*/
public static function count($criteria = array())
{
static::useDatabaseDynamic();
return parent::count($criteria);
}
/**
* Drop the collection
*
* @return boolean
*/
public static function drop()
{
static::useDatabaseDynamic();
return parent::drop();
}
/**
* Ensure index
*
* @param mixed $keys keys
* @param array $options options
*
* @return boolean
*/
public static function ensure_index($keys, $options = array())
{
static::useDatabaseDynamic();
return parent::ensure_index($keys, $options);
}
/**
* Return the connection
*
* @return MongoDB|null
*/
public function _getConnection()
{
$this->useDatabaseDynamicPrivate();
return $this->_connection;
}
/**
* Get Mongodb connection instance
*
* @return MongoDB
*/
protected static function connection()
{
$class = get_called_class();
$config = $class::$config;
return DatabaseDynamic::instance($config);
}
/**
* Get current database name
*
* @return string
*/
protected function dbName()
{
$dbName = "default";
$config = $this::$config;
$configs = DatabaseDynamic::config($config);
if ($configs) {
$dbName = $configs['connection']['database'];
}
return $dbName;
}
}
class Model extends ModelDynamic
{
/**
* @var string
*/
static $connection = 'default';
/**
* @var string
*/
static $database = 'core';
/**
* @var string
*/
static $collection = 'language';
/**
* @var array
*/
static $attrs = [
'name' => ['type' => 'string'],
'isActive' => ['type' => 'boolean', 'default' => false],
];
}
_\Model\DatabaseDynamic::setConfigBlock('default', [
'connection' => [
'hostnames' => '10.10.2.111:27017',
'database' => 'core'
]
]); Changing all self:: to static or passing an optional $database name on every __call would have made this much simpler... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
great package! is there an easy option to switch between different database using the same connection? preferably, have a $database complement $collection in the Model definition.
The text was updated successfully, but these errors were encountered: