From b3f3789d075f204914b8891798f78ff5a6f21328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Tue, 20 Nov 2018 10:54:28 +0100 Subject: [PATCH] fixup! improve the docs --- docs/site/Database-migrations.md | 39 +++++++++++++++++++++++++++++--- examples/todo/data/db.json | 7 +++--- examples/todo/src/application.ts | 15 +++++++++++- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/docs/site/Database-migrations.md b/docs/site/Database-migrations.md index 802f59a1484d..97fbf6617480 100644 --- a/docs/site/Database-migrations.md +++ b/docs/site/Database-migrations.md @@ -35,6 +35,10 @@ is `migrateSchema`, which iterates over all registered repositories and asks them to migrate their schema. Repositories that do not support schema migrations are silently skipped. +In the future, we would like to provide finer-grained control of database schema +updates, learn more in the GitHub issue +[#487 Database Migration Management Framework](https://github.com/strongloop/loopback-next/issues/487) + ### Auto-update database at start To automatically update the database schema whenever the application is started, @@ -89,6 +93,35 @@ your database by running `node dist/src/migrate` and rebuild it from scratch by running `node dist/src/migrate --rebuild`. It is also possible to save this commands as `npm` scripts in your `package.json` file. -In the future, we would like to provide finer-grained control of database schema -updates, learn more in the GitHub issue -[#487 Database Migration Management Framework](https://github.com/strongloop/loopback-next/issues/487) +### Implement additional migration steps + +In some scenarios, the application may need to define additional schema +constraints or seed the databse with predefined model instances. This can be +achieved by overriding the `migrateSchema` method provided by the mixin. + +The example below shows how to do so in our Todo example application. + +{% include code-caption.html content="src/application.ts" %} + +```ts +export class TodoListApplication extends BootMixin( + ServiceMixin(RepositoryMixin(RestApplication)), +) { + // skipped: the constructor, etc. + + async migrateSchema(options?: SchemaMigrationOptions) { + // 1. Run migration scripts provided by connectors + await super.migrateSchema(options); + + // 2. Make further changes. When creating predefined model instances, + // handle the case when these instances already exist. + const todoRepo = await this.getRepository(TodoRepository); + const found = await todoRepo.findOne({where: {title: 'welcome'}}); + if (found) { + todoRepo.updateById(found.id, {isComplete: false}); + } else { + await todoRepo.create({title: 'welcome', isComplete: false}); + } + } +} +``` diff --git a/examples/todo/data/db.json b/examples/todo/data/db.json index c647c1b52827..2429e29e568d 100644 --- a/examples/todo/data/db.json +++ b/examples/todo/data/db.json @@ -1,13 +1,14 @@ { "ids": { - "Todo": 5 + "Todo": 6 }, "models": { "Todo": { "1": "{\"title\":\"Take over the galaxy\",\"desc\":\"MWAHAHAHAHAHAHAHAHAHAHAHAHAMWAHAHAHAHAHAHAHAHAHAHAHAHA\",\"id\":1}", "2": "{\"title\":\"destroy alderaan\",\"desc\":\"Make sure there are no survivors left!\",\"id\":2}", "3": "{\"title\":\"terrorize senate\",\"desc\":\"Tell them they're getting a budget cut.\",\"id\":3}", - "4": "{\"title\":\"crush rebel scum\",\"desc\":\"Every.Last.One.\",\"id\":4}" + "4": "{\"title\":\"crush rebel scum\",\"desc\":\"Every.Last.One.\",\"id\":4}", + "5": "{\"title\":\"welcome\",\"id\":5}" } } -} +} \ No newline at end of file diff --git a/examples/todo/src/application.ts b/examples/todo/src/application.ts index 8f2af45bd508..acfd9f8ddcb3 100644 --- a/examples/todo/src/application.ts +++ b/examples/todo/src/application.ts @@ -6,11 +6,12 @@ import {BootMixin} from '@loopback/boot'; import {ApplicationConfig} from '@loopback/core'; import {RestExplorerComponent} from '@loopback/rest-explorer'; -import {RepositoryMixin} from '@loopback/repository'; +import {RepositoryMixin, SchemaMigrationOptions} from '@loopback/repository'; import {RestApplication} from '@loopback/rest'; import {ServiceMixin} from '@loopback/service-proxy'; import * as path from 'path'; import {MySequence} from './sequence'; +import {TodoRepository} from './repositories'; export class TodoListApplication extends BootMixin( ServiceMixin(RepositoryMixin(RestApplication)), @@ -37,4 +38,16 @@ export class TodoListApplication extends BootMixin( }, }; } + + async migrateSchema(options?: SchemaMigrationOptions) { + await super.migrateSchema(options); + + const todoRepo = await this.getRepository(TodoRepository); + const found = await todoRepo.findOne({where: {title: 'welcome'}}); + if (found) { + todoRepo.updateById(found.id, {isComplete: false}); + } else { + await todoRepo.create({title: 'welcome', isComplete: false}); + } + } }