Database
The process for recording changes to the Elentra Platform database schema, is relatively simple thanks to the Elentra CLI utility.
In this example, we will be adding a new
uuid
column to the elentra_auth.user_data
table.Using Terminal change to your Elentra project directory in the docker container, and run the base CLI utility
cd /var/www/vhosts/elentra-1x-me
php elentra
You should see something like:
php elentra
The following commands are available in Elentra CLI 1.0:
migrate Allows you to manage database migrations.
model Create blank models based on database information.
help The Elentra CLI help menu.
Now lets see which actions are available to the migrate command:
php elentra migrate
The following actions are available in the migrate command:
--create Create a new database migration file.
--pending See a list of the pending database migrations in your installation.
--up-s Run all pending migrations against your database. Provide optional filename to output SQL instead of run it.
--down-s Rollback the last successful up migration. Provide optional filename to output SQL instead of run it.
--audit Verifies that all present migrations have been run successfully.
--help The migrate help menu.
To create a new migration use the
--create
action:php elentra migrate --create
Provide the Elentra ME Jira Issue number for this change: ME1234
Successfully created new migration file:
/Users/simpson/Sites/elentra-1x-me/www-root/core/library/Migrate/2020_04_17_233339_ME1234.php
Open up the newly generated
www-root/core/library/Migrate/2020_04_17_233339_ME1234.php
file and record your changes for upgrading to the up()
method, and your changes for reverting to the down()
method. Elentra also provides an extremely useful audit()
method that allows you to programmatically check to see if this change exists in your Elentra database or not.<?php
class Migrate_2020_04_17_225348_ME1234 extends Entrada_Cli_Migrate {
/**
* Required: SQL / PHP that performs the upgrade migration.
*/
public function up() {
$this->record();
?>
ALTER TABLE `<?php echo AUTH_DATABASE; ?>`.`user_data` ADD COLUMN `uuid` varchar(36) DEFAULT NULL;
<?php
$this->stop();
return $this->run();
}
/**
* Required: SQL / PHP that performs the downgrade migration.
*/
public function down() {
$this->record();
?>
ALTER TABLE `<?php echo AUTH_DATABASE; ?>`.`user_data` DROP `uuid`;
<?php
$this->stop();
return $this->run();
}
/**
* Optional: PHP that verifies whether or not the changes outlined
* in "up" are present in the active database.
*
* Return Values: -1 (not run) | 0 (changes not present or complete) | 1 (present)
*
* @return int
*/
public function audit() {
$migration = new Models_Migration();
if ($migration->columnExists(AUTH_DATABASE, "user_data", "uuid")) {
return 1;
}
return 0;
}
}
You can now commit this file to version control, and everyone can apply your changes.
If you would simply like to see if there are pending migrations you can use
--pending
:php elentra migrate --pending
The following 2 up migrations need to be run:
> 2015_04_17_225348_ME1234
> 2015_04_17_233339_ME1235
To apply the changes to your database simply use
--up
:php elentra migrate --up
The following 2 up migrations need to be run:
> 2020_04_17_225348_ME1234
> 2020_04_17_233339_ME1235
These SQL changes will be automatically applied to the database.
Would you like to proceed? [Y/n]:
A model is a PHP class that represents a table in the database. It provides getter and setter methods for attributes that correspond to the columns in the table. A model class also provides the create, read, update and delete (CRUD) methods required to interact with the database. Elentra ME read methods follow the naming convention
fetchRowBy<attributes>
or fetchAllBy<attributes>
to fetch a single row or a collection of results, respectively. <attributes>
is replaced by the names of the columns that are used in the query.Elentra ME has a base model that all other models can inherit from. This base model provides private fetchRow and fetchAll methods that child classes can call from their public fetch* methods. This helps to abstract the basic mechanics of performing a fetch and provides a simplified interface for creating queries.
Below is an example of how to use the model base class. The base class itself is commented with a detailed explanation of how to use the fetch methods it contains.
class Models_Example extends Models_Base {
/**
* N.B.: Put the exact names of the columns as these are accessed literally
* in the base class's fetching code (e.g. fromArray()).
*/
protected $example_id;
protected $title;
protected $active;
protected $database_name = DATABASE_NAME;
protected $table_name = "example";
protected $primary_key = "example_id"; // Name of primary key column in the database. The "closest thing to a standard" is to name primary key columns table_name_singular_id, e.g. "events.event_id".
protected $default_sort_column = "title";
public function __construct($arr = NULL) {
parent::__construct($arr);
}
/**
* Get the primary key.
*
* @return The primary key of the record represented by this model.
*/
public function getID() {
return $this->example_id;
}
/**
* @param int $active
*/
public function setActive($active) {
$this->active = $active;
}
/**
* @return int
*/
public function getActive() {
return $this->active;
}
/**
* @param string $title
*/
public function setTitle($title) {
$this->title = $title;
}
/**
* @return string
*/
public function getTitle() {
return $this->title;
}
public static function fetchRowByID($example_id, $active = 1) {
$self = new self();
$constraints = array(
array(
"key" => "example_id",
"method" => "=",
"value" => $example_id,
"mode" => "AND"
),
array(
"key" => "active",
"method" => "=",
"value" => $active,
"mode" => "AND"
)
);