WHAT THIS TALK is ▸ An introduction to qb's SchemaBuilder ▸ Co-locating your app's database structure in your app ▸ How to make changes to your database schema from CommandBox
WHAT ARE database migrations? ▸ Changes to your application's database schema ▸ Describes how to apply the change and how to rollback the change ▸ Ran up and down in order
WHY Database Migrations? ▸ Co-located inside your app's codebase ▸ Apply schema changes in order ▸ Able to bring up new instances / databases on demand
WHY CommandBox? ▸ No worries about exposing access to your database from the web ▸ Scriptable — can run as part of your deploy pipline ▸ Scaffold new migrations with a single command
CONVENTIONS ▸ Migrations are located inside resources/database/migrations ▸ Migration file names start with the timestamp they were created (2017_09_03_043150_create_users_table.cfc)
SCHEMABUILDER ▸ Is to database structure what QueryBuilder is to queries ▸ Fluent, expressive syntax for describing tables, columns, and constraints ▸ Bridges the many database idiosyncrasies in this area.
SCHEMABUILDER ▸ Not required to use for commandbox-migrations ▸ Also can be used outside of commandbox-migrations ▸ Comes bundled and configured for use because it makes life easier
component { function up( schema, query ) { // An pre-configured instance // of `SchemaBuilder` and `QueryBuilder` // are passed to each migration function } function down( schema, query ) { // feel free to ignore them // if they aren't your thing } }
COLUMNS table.string( "email" ); table.integer( "age", 3 ); ▸ Defines the column type, name, and attributes ▸ Can be used in create or alter method ▸ Columns are NOT NULL by default
COLUMN MODIFIERS table.integer( "age" ).nullable(); table.boolean( "is_active" ).default( false ); ▸ Can be called on any column ▸ default, nullable, unsigned, comment
DROP schema.drop( "user_logins" ); schema.dropIfExists( "user_profiles" ); ▸ Drop a table ▸ Doesn't disable any constraints first ▸ (But that's why migrations are ran in order)