The database is used for storing majority of user entered data (except user uploaded files). Almost each database table has associated unit, that is responsible for reading/writing data from it.
Following is missing however:
- the unit isn't aware/responsible for the indexes added to associated table
- cross-table relations are not stored anywhere (even in database itself)
- adding new fields to database is not error-prone, because:
- developer needs to switch to DB application (Navicat, Sequel Pro, phpMyAdmin)
- developer needs to enter several values to configure new field (field name, field type, field value size, null/not null, default value)
- developer needs to go to "System Tools" section in Admin Console
- developer needs to type in unit name to see "Fields" array content
- developer needs to copy/paste relevant changed field declarations from there to the unit config in IDE
Solution
- describe database table columns in "
Fields
" array:- make "
db_type
" field option used to describe database type (e.g. "varchar(255)") required - add new optional "
db_extra
" field option of array type, where "auto_increment" and other db column options are defined
- make "
describe index structure in the new "
Indexes
" unit config option like so (the field specified in "IDField" of unit config is automatically assigned an "auto_increment" db extra and added as primary key):'Indexes' => array( 'IDX_INDEX_NAME' => array( 'columns' => array('DBColumn1', 'DBColumn2'), 'unique' => true, ), ),
- create the "in-portal db:sync" command, that will:
- create missing database tables
- change structure of existing tables to match one from unit config (but won't delete columns, because it takes time on large tables)
- integrate code, that creates multi-lingual columns (e.g. "l1_Name") into this command
- replace "Rebuild Multilingual Fields" action on "System Tools" page with "Rebuild Database Structure" action that would call above created command
if table column has association with another database table, then define it via new "foreign_key" field option (won't be used for now) like so:
'Fields' => array( 'ItemResourceId' => array( 'type' => 'int', ..., 'default' => null, 'foreign_key' => 'l:ResourceId' ), ),