Предшествующий любой доступ к базе данных с определенной командой в CakePHP - PullRequest
2 голосов
/ 13 октября 2011

Я новичок в CakePHP и использую версию 1.3.

Как я могу динамически изменить свойство схемы, найденное в DATABASE_CONFIG, перед любой операцией базы данных?Что это за класс, в котором я мог использовать команду postgres "set search_path to 'schema_xyz'", выполняемую перед любым взаимодействием с базой данных?

Я хочу использовать способность Postgres для поддержки нескольких различных пространств имен (иначе схема в postgresв одной базе данных для реализации многопользовательского режима в моем приложении.То есть каждое пространство имен будет содержать один и тот же набор таблиц, но, очевидно, с различным содержанием.Здесь важно понимать схему не как значение метаданные таблицы , а как концепцию пространства имен , специфичную для postgres , где схема является контейнером для таблиц.Точная команда Postgres не важна.Что это, это механизм, с помощью которого он может быть вызван, и устранение типичного значения Cake описания таблицы, как видно из SchemaShell.Единственное место, которое я нашел, где Cake раскрывает концепцию пространства имен, - это файл database.php, который затем используется при первом установлении соединения с БД.См .: api13.cakephp.org/view_source/dbo-postgres/#line-113 (ограничение ссылки на нового пользователя, извините)

    if ($this->connection) {
      $this->connected = true;
      $this->_execute("SET search_path TO " . $config['schema']);

Я хочу установить этот search_path перед запросами ВСЕХ БД, а не только при соединениивремя, как это делается в настоящее время.

В качестве подтверждения концепции я попытался установить $ useDbConfig в своих моделях, но в соответствии с выводом отладки, где выводятся команды SQL, кажется, что это влияет только на подмножество всехзапросы.Я переместил это в app_model.php с тем же результатом.Как и при добавлении, создавая экземпляр db_config на лету и передавая в ConnectionManager через loadDataSource.Возможно, мне следует добавить этот код во все разновидности методов before ...

Я видел много постов в Интернете, где люди обсуждают использование одной из нескольких конфигураций БД в файле database.php, чтобы использовать разные базы данных для dev, lab ипроизводственные среды.Но у меня есть одна база данных с несколькими пространствами имен / схемами.Кроме того, мое количество таких пространств имен будет слишком большим и динамичным, чтобы сделать практичным жесткое кодирование новой переменной в database.php.

Таким образом, где находится место в CakePHP, где я мог бы вставить что-то для установки search_path долюбая команда базы данных?Я займусь оптимизацией позже.Помните, что я новичок в Cake, поэтому постарайтесь быть как можно более конкретным.Дайте мне знать, если я смогу уточнить этот вопрос.

Заранее спасибо.Вот частично работающий фрагмент кода:

class AppModel extends Model {
  function beforeFind($queryData)
  {
    App::import("ConnectionManager");
    $cm = &ConnectionManager::getInstance();

    $namespace = 'xyz_namespace';            //name of the new schema/namespace/search path 
    $new_db_config_name = 'new_config';      //name for the new DB config to be used in the ConnectionManager
    $new_db_config = $cm->config->default; //copy the 'default' DB config into an array
    $new_db_config['schema'] = $namespace; //change/add the new schema/namespace/search path

    $cm->create($new_db_config_name, $new_db_config);   //turn the array into a DbConfig object
    $cm->loadDataSource($new_db_config_name);           //load the new DbConfig into the ConnectionManager
    $this->useDbConfig = $new_db_config_name;       //tell the model to new use the Db Config


    return $queryData;
  } 
}

Ответы [ 2 ]

1 голос
/ 14 октября 2011

В PostgreSQL есть очень простой способ, если вы хотите переключить схему для каждой роли входа в систему:

ALTER ROLE foo SET search_path=bar, public;
ALTER ROLE baz SET search_path=bam, public;

Таким образом, для соединения, инициированного этой ролью, этот search_path устанавливается автоматически.
Если ваши логины совпадают с желаемыми именами схем, есть еще более простой способ, я цитирую прекрасное руководство :

Если одним из элементов списка является специальное значение $ user, тогда схема имя, возвращаемое SESSION_USER, заменяется, если есть такая схема. (Если нет, $ user игнорируется.)

Но имейте в виду, что - прекрасное руководство еще раз:

Настройки переменных для конкретной роли вступают в силу только при входе в систему; УСТАНОВИТЬ РОЛЬ и SET SESSION AUTHORIZATION не обрабатывают ролевую переменную Настройки.

0 голосов
/ 14 октября 2011

Если я правильно понимаю ваш вопрос (потерпите меня, я мало знаю о Postgres, но в основном, я думаю, вы имеете в виду, перезагружая схему всякий раз, когда изменяется перспектива таблицы?), Как динамически переключать схемы в вашем контроллере: *

// Model::getDataSource()->configKeyName holds whichever db config you're using
if ($this->Model->getDataSource()->configKeyName != 'default') {
    // do something...
    $this->loadModel("Special")
    $this->Model->table = "extras";
    $this->Model->schema(true);
} else {
    // predictably, Model::setDataSource($configKey) changes configs
    $this->Model->setDataSource("offsite"); // this could be a string variable
}

Или от модели, $this->getDataSource()->configKeyName и $this->schema(true) и так далее. Примечание $this->schema(true) фактически перезагружает схему модели и регистрирует ее с помощью cake. app_model, компонент или config / bootstrap могут быть подходящим местом для этого. Я не уверен, где Cake определил бы search_path в первый раз, но он почти наверняка был бы свойством объекта dataSource и мог бы быть переопределен там, как имя таблицы и т. Д. И затем перезагрузить схему Cake, чтобы зарегистрировать измененное дорожка. Необходимо убедиться, что Cake выгружает все значения по умолчанию, которые он мог выбрать, и загружать правильную схему на основе определенной в данный момент таблицы. (Похоже, это был единственный шаг, который вы пропустили.)

Если это не отвечает на ваш вопрос или если я неправильно понял, дайте мне знать. НТН. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...