Автоматизировать создание таблицы базы данных в рамках CakePHP - PullRequest
3 голосов
/ 31 октября 2009

Я пытаюсь написать веб-приложение с CakePHP, и, как и большинство веб-приложений, я хотел бы создать установщик, который определяет, была ли база данных инициализирована, и, если нет, выполняет процесс установки.

Этот процесс будет полностью автоматизирован (предполагается, что сама база данных уже существует, и что ей предоставлен полный административный доступ через анонимную учетную запись без пароля ... это для среды песочницы, поэтому не стоит беспокоиться о безопасности), поэтому он должен иметь возможность определять (независимо от запроса!), были ли таблицы базы данных созданы и инициализированы, а если нет, выполнить эту инициализацию прозрачно, а затем по-прежнему обслуживать исходный запрос пользователя.

Я подумал о создании своего рода контроллера Bootstrap, через который маршрутизируются все запросы, и запускается один SQL-запрос, чтобы определить, существуют ли таблицы базы данных, но это казалось громоздким (а контроллеру требуется соответствующая модель, которая не требует быть здесь). Другая возможность состояла в том, чтобы переопределить AppModel и поместить в него тот же тест, но я не был уверен, как это сделать, так как нет никакой документации в этом направлении.

Заранее спасибо!

tl; dr version : Что такое эквивалент CakePHP (или как можно записать эквивалент для CakePHP) метода "init ()" сервлета J2EE?

Ответы [ 4 ]

3 голосов
/ 31 октября 2009

Ознакомьтесь с классом AppError - может быть, существует ошибка отсутствующей таблицы базы данных, которую вы можете переопределить и запустить оттуда свой SQL-файл создания таблицы базы данных?

2 голосов
/ 31 октября 2009

Нечто подобное может сделать то, что вы ищете, но для каждой модели требуется дополнительный запрос.

<?php
class AppModel extends Model {
    var $create_query = false;

    function __construct($id = false, $table = null, $ds = null) {
        parent::__construct($id, $table, $ds);

        if (!empty($this->create_query)) {
            $this->query($this->create_query);
        }
    }
}
?>

Тогда вам просто нужно добавить var $create_query = 'CREATE TABLE IF NOT EXISTS ...; `в ваши модели. Документация MySQL CREATE TABLE содержит дополнительную информацию, ЕСЛИ НЕ СУЩЕСТВУЕТ.

Однако , я не уверен, что он не пытается вызвать query () слишком рано. Или перед проверкой, чтобы увидеть, существует ли уже таблица, которая будет иметь . В противном случае CakePHP выдаст ошибку вместо создания вашей таблицы. По этому вопросу не так много документации, и вам лучше всего получить дополнительную информацию, чтобы непосредственно взглянуть на cake / libs / model / model.php.

Обновление: приведенный выше код не будет работать так, как написано.

После более глубокого изучения класса Model конструкция Model :: __ вызывает Model :: setSource (). Model :: setSource () проверяет, существует ли таблица, и выдает ошибку, если ее нет. Чтобы использовать этот метод, вам нужно переопределить и вставить запрос. Приведенный ниже код может отличаться в зависимости от используемой версии CakePHP.

<?php
function setSource($tableName) {
    // From Model::setSource().  I believe this is needed to make query() work.
    $this->setDataSource($this->useDbConfig);

    // Create our table if we have a create query
    if (!empty($this->create_query)) {
        $this->query($this->create_query);
    }

    // Now call the parent
    parent::setSource($tableName);
}
?>
2 голосов
/ 31 октября 2009

Вы действительно хотите сделать каждый запрос проверки, что база данных существует? Это кажется ужасно расточительным.

При первой проверке будет настроена база данных, а затем для каждого следующего миллиона запросов она будет проверяться снова, хотя база данных, конечно, к этому времени уже настроена!

Лучше всего потребовать, чтобы тот, кто устанавливает ваше приложение, выполнил некоторые настройки. Вы должны предоставить отдельный скрипт, который не запускается при каждом запросе, но запускается вручную человеком во время установки.


Ваш комментарий о лучшем способе сделать это с CakePHP, вы смотрели на поддержку Cake для миграции схем базы данных?

http://book.cakephp.org/view/734/Schema-management-and-migrations

1 голос
/ 01 ноября 2009

Я думал о том, чтобы сделать это в определенный момент времени, и придумал хороший способ сделать это.

Прежде всего, примечание: я считаю, что вашему приложению необходим доступ на запись к app / config / database.php, чтобы вы могли написать правильную информацию. У меня есть обходной путь, но позвольте мне объяснить метод, с помощью которого работает установщик.

PHP-скрипты могут переписывать себя (или удалять себя) на лету. Поскольку скрипт загружается в память, а затем выполняется байт-код, он не зависит от файла после его работы. Таким образом, теоретически у вас может быть что-то, что переопределяет класс AppError для запуска определенного контроллера (скажем, вашего SetupWizardController) со всеми обычными загруженными вещами CakePHP. После того, как вы пройдете весь мастер, запишите файл database.php / настройте все остальное, перезапишите файлы AppError и AppController (я вижу, что вам нужен AppController для работы по-другому, если приложение в некоторых случаях не было установлено) с те, которые хранятся где-то как в app / vendors / myapp. Сценарий завершил выполнение, и теперь ваши проверки не будут выполняться при последующих запусках.

Это позволит избавиться от проблемы, возникшей у Билла Карвина, использовать AppError и создать установщик.

Другой способ сделать это - включить идею среды в ваше приложение. Допустим, вы храните свои среды в app / config / environment.php. Этому файлу будет предоставлен доступ для записи (и этот доступ будет удален в конце установки), или он может быть перезаписан. В любом случае, он существует, когда кто-то пытается развернуть ваше приложение, и database.php автоматически импортирует базы данных из файла environment.php. Затем конструктор класса database.php перезапишет свою базу данных $ default с базой данных, указанной в environment.php. $ Default в database.php будет ссылаться на источник данных NoDB, который вы можете проверить в AppController (я думаю, вы сможете создать фиктивную модель и проверить ее источник данных), а затем нажать требуемый установщик. Очевидно, что и после этого вы перезапишете AppController.

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