├── .flutter-plugins ├── .gitignore ├── .metadata ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── example └── example.dart ├── lib ├── sqflite_migration.dart └── src │ ├── migration_config.dart │ ├── migrator.dart │ └── open_database_with_migration.dart ├── pubspec.lock ├── pubspec.yaml ├── res └── values │ └── strings_en.arb └── test └── src ├── migrator_test.dart └── open_database_with_migration_test.dart /.flutter-plugins: -------------------------------------------------------------------------------- 1 | sqflite=/usr/local/var/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.1.1/ 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | ios/.generated/ 9 | ios/Flutter/Generated.xcconfig 10 | ios/Runner/GeneratedPluginRegistrant.* 11 | 12 | android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java 13 | android/local.properties 14 | 15 | *.iml 16 | .idea/ 17 | 18 | coverage/ -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 5391447fae6209bb21a89e6a5a6583cac1af9b4b 8 | channel: stable 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - linux 3 | sudo: false 4 | addons: 5 | apt: 6 | sources: 7 | - ubuntu-toolchain-r-test 8 | packages: 9 | - libstdc++6 10 | - fonts-droid-fallback 11 | before_script: 12 | - git clone https://github.com/flutter/flutter.git -b master --depth 1 13 | - ./flutter/bin/flutter doctor 14 | script: 15 | - ./flutter/bin/flutter test --coverage --coverage-path=lcov.info 16 | after_success: 17 | - bash <(curl -s https://codecov.io/bash) 18 | cache: 19 | directories: 20 | - $HOME/.pub-cache 21 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log for sqflite_migration 2 | A library to enable sqlite db migrations, using sqflite plugin. 3 | 4 | ## [v0.3.0](http://github.com/flutterings/sqflite_migration/compare/v0.2.0...v0.3.0) - 2021-04-14 5 | 6 | ### Feats 7 | * Support null-safety. 8 | [36a4011](https://github.com/flutterings/sqflite_migration/commit/36a4011fdd0def1469c28bb154f3edb0d0b93319) 9 | 10 | ### Bugs 11 | * Fixed async/await bug in executeInitialization function. 12 | [0fb80ae](https://github.com/flutterings/sqflite_migration/commit/0fb80aee26564d3df92e4950b3976d94f8db3abc) 13 | 14 | ### Docs 15 | * Fix example code in documentation. 16 | [3a36bdf](https://github.com/flutterings/sqflite_migration/commit/3a36bdf3227df1894e17a5ff15917a9a96d1aa34) 17 | [3a36bdf](https://github.com/flutterings/sqflite_migration/commit/3a36bdf3227df1894e17a5ff15917a9a96d1aa34) 18 | 19 | ## [v0.2.0](http://github.com/flutterings/sqflite_migration/compare/v0.1.1...v0.2.0) - 2020-09-04 20 | 21 | ### Bugs 22 | * Based on open_database_with_migration.dart new version of database every time will be equal migrations.length + 1. Situation when we'll perform migration to the version lesser than migrations.length + 1 looks impossible, because of the way we determine the current version. In this case assertion should check it in the manner suggested by the current PR. [ad24d00](https://github.com/flutterings/sqflite_migration/commit/ad24d00874189fbf8c73ef4a8b60cceb9f3d1748) 23 | 24 | ## [v0.1.2](http://github.com/flutterings/sqflite_migration/compare/v0.1.1...v0.1.2) - 2019-08-23 25 | 26 | ### Test 27 | * remove deprecated failing tests [dfc249c](https://github.com/flutterings/sqflite_migration/commit/dfc249c48ec5d350561762444dd104778c35a564) 28 | 29 | ## [v0.1.1](http://github.com/flutterings/sqflite_migration/compare/v0.1.0...v0.1.1) - 2019-08-23 30 | 31 | ### Chore 32 | * replace deprecated fonts-droid dependency in travis, with fonts-droid-fallback [091605a](https://github.com/flutterings/sqflite_migration/commit/091605a5089d8f3614074cdbb00aacd6258d7c91) 33 | 34 | ### Bugs 35 | * allow empty scripts array closes #2 [5d22773](https://github.com/flutterings/sqflite_migration/commit/5d2277350eddfab27e58a042421752c8e80f373a) 36 | 37 | ## [v0.1.0](http://github.com/flutterings/sqflite_migration/compare/v0.0.2...v0.1.0) - 2019-03-19 38 | 39 | ### Chore 40 | * fix formatting issue [9038c91](https://github.com/flutterings/sqflite_migration/commit/9038c916ff224ac413972b67a32de2b7ba91a8a6) 41 | 42 | ### Docs 43 | * add example [6ce670a](https://github.com/flutterings/sqflite_migration/commit/6ce670a2da4ccc642d76e83dd2b1cee279ca097b) 44 | 45 | ## [v0.0.2](http://github.com/flutterings/sqflite_migration/compare/v0.0.1...v0.0.2) - 2019-03-04 46 | 47 | ### Chore 48 | * fix formatting issue [8155d98](https://github.com/flutterings/sqflite_migration/commit/8155d98093e6e02a339f9a432f4799fd98047db8) 49 | 50 | ### Fixes 51 | * Use dart:async imports to make the library backward compatible. [6b4194e](https://github.com/flutterings/sqflite_migration/commit/6b4194ec734585cdc07dd99ca296b9e3a75bb0b7) 52 | 53 | ### Docs 54 | * enhance package description. [e6804ba](https://github.com/flutterings/sqflite_migration/commit/e6804ba14c014414ae919531d7f92c1c09d1d68c) 55 | 56 | 57 | This CHANGELOG.md was generated with [**Changelog for Dart**](https://pub.dartlang.org/packages/changelog) 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | egal advice. Learn more about repository licenses. 2 | 3 | MIT License 4 | 5 | Copyright (c) 2019 flutterings 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/flutterings/sqflite_migration.svg?branch=master)](https://travis-ci.org/flutterings/sqflite_migration) 2 | [![codecov](https://codecov.io/gh/flutterings/sqflite_migration/branch/master/graph/badge.svg)](https://codecov.io/gh/flutterings/sqflite_migration) 3 | 4 | # Migrate your mobile sqlite database 5 | 6 | Library to manage sqlite db migrations using [sqflite](https://pub.dartlang.org/packages/sqflite) plugin. 7 | 8 | ## Getting Started 9 | 10 | ```dart 11 | import 'package:path/path.dart'; 12 | import 'package:sqflite/sqflite.dart'; 13 | import 'package:sqflite_migration/sqflite_migration.dart'; 14 | 15 | final initialScript = [ 16 | ''' 17 | create table _todo_list ( 18 | id integer primary key autoincrement, 19 | alias text not null 20 | ) 21 | ''', 22 | ''' 23 | create table _task ( 24 | id integer primary key autoincrement, 25 | description text, 26 | todo_list_id integer not null, 27 | CONSTRAINT fk_todo_lists 28 | FOREIGN KEY (todo_list_id) 29 | REFERENCES _todo_list(id) 30 | ); 31 | ''' 32 | ]; 33 | 34 | final migrations = [ 35 | ''' 36 | alter table _task add column done integer default 0; 37 | ''' 38 | ]; 39 | 40 | final config = MigrationConfig(initializationScript: initialScript, migrationScripts: migrations); 41 | 42 | Future open() async { 43 | final databasesPath = await getDatabasesPath(); 44 | final path = join(databasesPath, 'test.db'); 45 | 46 | return await openDatabaseWithMigration(path, config); 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /example/example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:path/path.dart'; 4 | import 'package:sqflite/sqflite.dart'; 5 | import 'package:sqflite_migration/sqflite_migration.dart'; 6 | 7 | final initialScript = [ 8 | ''' 9 | create table _todo_list ( 10 | id integer primary key autoincrement, 11 | alias text not null 12 | ) 13 | ''', 14 | ''' 15 | create table _task ( 16 | id integer primary key autoincrement, 17 | description text, 18 | todo_list_id integer not null, 19 | CONSTRAINT fk_todo_lists 20 | FOREIGN KEY (todo_list_id) 21 | REFERENCES _todo_list(id) 22 | ); 23 | ''' 24 | ]; 25 | 26 | final migrations = [ 27 | ''' 28 | alter table _task add column done integer default 0; 29 | ''' 30 | ]; 31 | 32 | final config = MigrationConfig( 33 | initializationScript: initialScript, migrationScripts: migrations); 34 | 35 | class DatabaseRepository { 36 | static Database? _database; 37 | String? path; 38 | 39 | Future get database async { 40 | if (_database != null) { 41 | return _database!; 42 | } 43 | 44 | _database = await _open(); 45 | return _database!; 46 | } 47 | 48 | Future _open() async { 49 | final databasesPath = await (getDatabasesPath() as FutureOr); 50 | final path = join(databasesPath, 'test.db'); 51 | 52 | return await openDatabaseWithMigration(path, config); 53 | } 54 | 55 | Future findById(int id) async { 56 | final db = await (database as FutureOr); 57 | List maps = await db.query('_task', 58 | columns: ['id', 'description'], where: 'id = ?', whereArgs: [id]); 59 | if (maps.length > 0) { 60 | return maps.first; 61 | } 62 | return null; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lib/sqflite_migration.dart: -------------------------------------------------------------------------------- 1 | library sqflite_migration; 2 | 3 | export 'package:sqflite_migration/src/migration_config.dart'; 4 | export 'package:sqflite_migration/src/open_database_with_migration.dart'; 5 | -------------------------------------------------------------------------------- /lib/src/migration_config.dart: -------------------------------------------------------------------------------- 1 | /// 2 | /// Contains the needed configuration to run the migration on a sqlite database. 3 | /// 4 | /// [initializationScript] (required) should create the initial db state in a 5 | /// form of sql script. Every item in the list must contain a single sqlite 6 | /// statement. Must not be empty. 7 | /// 8 | /// [migrationScripts] (required) should contain migrations towards the newest 9 | /// db state. Every item in the list must contain a single sqlite statement. 10 | /// Must not be empty. 11 | /// 12 | class MigrationConfig { 13 | final List initializationScript; 14 | final List migrationScripts; 15 | 16 | MigrationConfig({required this.initializationScript, required this.migrationScripts}); 17 | } 18 | -------------------------------------------------------------------------------- /lib/src/migrator.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:sqflite/sqflite.dart'; 4 | import 'package:sqflite_migration/src/migration_config.dart'; 5 | 6 | /// 7 | /// An internal class which contains methods to execute the initial and 8 | /// migration scripts. 9 | /// 10 | /// [config] (required) the migration configuration to execute. 11 | /// 12 | class Migrator { 13 | final MigrationConfig config; 14 | 15 | Migrator(this.config); 16 | 17 | Future executeInitialization(DatabaseExecutor db, int version) async { 18 | for (String script in config.initializationScript) { 19 | await db.execute(script); 20 | } 21 | 22 | for (String script in config.migrationScripts) { 23 | await db.execute(script); 24 | } 25 | } 26 | 27 | Future executeMigration( 28 | DatabaseExecutor db, int oldVersion, int newVersion) async { 29 | assert(oldVersion < newVersion, 30 | 'The newVersion($newVersion) should always be greater than the oldVersion($oldVersion).'); 31 | assert(config.migrationScripts.length == newVersion - 1, 32 | 'New version ($newVersion) requires exact ${newVersion - config.migrationScripts.length} migrations.'); 33 | 34 | for (var i = oldVersion - 1; i < newVersion - 1; i++) { 35 | await db.execute(config.migrationScripts[i]); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/src/open_database_with_migration.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:sqflite/sqflite.dart'; 4 | import 'package:sqflite_migration/src/migration_config.dart'; 5 | import 'package:sqflite_migration/src/migrator.dart'; 6 | 7 | /// 8 | /// Open the database at a given path, while running the provided migration 9 | /// scripts. 10 | /// 11 | /// [path] (required) specifies the path to the database file. 12 | /// [config] (required) specifies the migration configuration. 13 | /// [openDatabase] (optional) do not override this. It is used for testing 14 | /// purposes. 15 | /// 16 | Future openDatabaseWithMigration(String path, MigrationConfig config, 17 | {openDatabase = openDatabase}) async { 18 | final migrator = Migrator(config); 19 | return await openDatabase(path, 20 | version: config.migrationScripts.length + 1, 21 | onCreate: migrator.executeInitialization, 22 | onUpgrade: migrator.executeMigration); 23 | } 24 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _fe_analyzer_shared: 5 | dependency: transitive 6 | description: 7 | name: _fe_analyzer_shared 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "17.0.0" 11 | analyzer: 12 | dependency: transitive 13 | description: 14 | name: analyzer 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "1.1.0" 18 | args: 19 | dependency: transitive 20 | description: 21 | name: args 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.0.0" 25 | async: 26 | dependency: transitive 27 | description: 28 | name: async 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "2.5.0" 32 | boolean_selector: 33 | dependency: transitive 34 | description: 35 | name: boolean_selector 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "2.1.0" 39 | build: 40 | dependency: transitive 41 | description: 42 | name: build 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.6.3" 46 | built_collection: 47 | dependency: transitive 48 | description: 49 | name: built_collection 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "5.0.0" 53 | built_value: 54 | dependency: transitive 55 | description: 56 | name: built_value 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "8.0.0" 60 | characters: 61 | dependency: transitive 62 | description: 63 | name: characters 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "1.1.0" 67 | charcode: 68 | dependency: transitive 69 | description: 70 | name: charcode 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "1.2.0" 74 | cli_util: 75 | dependency: transitive 76 | description: 77 | name: cli_util 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "0.3.0" 81 | clock: 82 | dependency: transitive 83 | description: 84 | name: clock 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "1.1.0" 88 | code_builder: 89 | dependency: transitive 90 | description: 91 | name: code_builder 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "3.6.0" 95 | collection: 96 | dependency: transitive 97 | description: 98 | name: collection 99 | url: "https://pub.dartlang.org" 100 | source: hosted 101 | version: "1.15.0" 102 | convert: 103 | dependency: transitive 104 | description: 105 | name: convert 106 | url: "https://pub.dartlang.org" 107 | source: hosted 108 | version: "3.0.0" 109 | crypto: 110 | dependency: transitive 111 | description: 112 | name: crypto 113 | url: "https://pub.dartlang.org" 114 | source: hosted 115 | version: "3.0.0" 116 | dart_style: 117 | dependency: transitive 118 | description: 119 | name: dart_style 120 | url: "https://pub.dartlang.org" 121 | source: hosted 122 | version: "1.3.14" 123 | fake_async: 124 | dependency: transitive 125 | description: 126 | name: fake_async 127 | url: "https://pub.dartlang.org" 128 | source: hosted 129 | version: "1.2.0" 130 | file: 131 | dependency: transitive 132 | description: 133 | name: file 134 | url: "https://pub.dartlang.org" 135 | source: hosted 136 | version: "6.1.0" 137 | fixnum: 138 | dependency: transitive 139 | description: 140 | name: fixnum 141 | url: "https://pub.dartlang.org" 142 | source: hosted 143 | version: "1.0.0" 144 | flutter: 145 | dependency: "direct main" 146 | description: flutter 147 | source: sdk 148 | version: "0.0.0" 149 | flutter_test: 150 | dependency: "direct dev" 151 | description: flutter 152 | source: sdk 153 | version: "0.0.0" 154 | glob: 155 | dependency: transitive 156 | description: 157 | name: glob 158 | url: "https://pub.dartlang.org" 159 | source: hosted 160 | version: "2.0.0" 161 | logging: 162 | dependency: transitive 163 | description: 164 | name: logging 165 | url: "https://pub.dartlang.org" 166 | source: hosted 167 | version: "1.0.0" 168 | matcher: 169 | dependency: "direct dev" 170 | description: 171 | name: matcher 172 | url: "https://pub.dartlang.org" 173 | source: hosted 174 | version: "0.12.10" 175 | meta: 176 | dependency: transitive 177 | description: 178 | name: meta 179 | url: "https://pub.dartlang.org" 180 | source: hosted 181 | version: "1.3.0" 182 | mockito: 183 | dependency: "direct dev" 184 | description: 185 | name: mockito 186 | url: "https://pub.dartlang.org" 187 | source: hosted 188 | version: "5.0.0" 189 | package_config: 190 | dependency: transitive 191 | description: 192 | name: package_config 193 | url: "https://pub.dartlang.org" 194 | source: hosted 195 | version: "2.0.0" 196 | path: 197 | dependency: transitive 198 | description: 199 | name: path 200 | url: "https://pub.dartlang.org" 201 | source: hosted 202 | version: "1.8.0" 203 | pedantic: 204 | dependency: transitive 205 | description: 206 | name: pedantic 207 | url: "https://pub.dartlang.org" 208 | source: hosted 209 | version: "1.11.0" 210 | pub_semver: 211 | dependency: transitive 212 | description: 213 | name: pub_semver 214 | url: "https://pub.dartlang.org" 215 | source: hosted 216 | version: "2.0.0" 217 | sky_engine: 218 | dependency: transitive 219 | description: flutter 220 | source: sdk 221 | version: "0.0.99" 222 | source_gen: 223 | dependency: transitive 224 | description: 225 | name: source_gen 226 | url: "https://pub.dartlang.org" 227 | source: hosted 228 | version: "0.9.10+3" 229 | source_span: 230 | dependency: transitive 231 | description: 232 | name: source_span 233 | url: "https://pub.dartlang.org" 234 | source: hosted 235 | version: "1.8.0" 236 | sqflite: 237 | dependency: "direct main" 238 | description: 239 | name: sqflite 240 | url: "https://pub.dartlang.org" 241 | source: hosted 242 | version: "2.0.0+2" 243 | sqflite_common: 244 | dependency: transitive 245 | description: 246 | name: sqflite_common 247 | url: "https://pub.dartlang.org" 248 | source: hosted 249 | version: "2.0.0+1" 250 | stack_trace: 251 | dependency: transitive 252 | description: 253 | name: stack_trace 254 | url: "https://pub.dartlang.org" 255 | source: hosted 256 | version: "1.10.0" 257 | stream_channel: 258 | dependency: transitive 259 | description: 260 | name: stream_channel 261 | url: "https://pub.dartlang.org" 262 | source: hosted 263 | version: "2.1.0" 264 | string_scanner: 265 | dependency: transitive 266 | description: 267 | name: string_scanner 268 | url: "https://pub.dartlang.org" 269 | source: hosted 270 | version: "1.1.0" 271 | synchronized: 272 | dependency: transitive 273 | description: 274 | name: synchronized 275 | url: "https://pub.dartlang.org" 276 | source: hosted 277 | version: "3.0.0" 278 | term_glyph: 279 | dependency: transitive 280 | description: 281 | name: term_glyph 282 | url: "https://pub.dartlang.org" 283 | source: hosted 284 | version: "1.2.0" 285 | test_api: 286 | dependency: transitive 287 | description: 288 | name: test_api 289 | url: "https://pub.dartlang.org" 290 | source: hosted 291 | version: "0.2.19" 292 | typed_data: 293 | dependency: transitive 294 | description: 295 | name: typed_data 296 | url: "https://pub.dartlang.org" 297 | source: hosted 298 | version: "1.3.0" 299 | vector_math: 300 | dependency: transitive 301 | description: 302 | name: vector_math 303 | url: "https://pub.dartlang.org" 304 | source: hosted 305 | version: "2.1.0" 306 | watcher: 307 | dependency: transitive 308 | description: 309 | name: watcher 310 | url: "https://pub.dartlang.org" 311 | source: hosted 312 | version: "1.0.0" 313 | yaml: 314 | dependency: transitive 315 | description: 316 | name: yaml 317 | url: "https://pub.dartlang.org" 318 | source: hosted 319 | version: "3.1.0" 320 | sdks: 321 | dart: ">=2.12.0 <3.0.0" 322 | flutter: ">=1.24.0-10" 323 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: sqflite_migration 2 | description: A library to enable sqlite db migrations, using sqflite plugin. 3 | version: 0.3.0 4 | homepage: https://github.com/flutterings/sqflite_migration 5 | 6 | environment: 7 | sdk: '>=2.12.0 <3.0.0' 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | sqflite: ^2.0.0 13 | 14 | dev_dependencies: 15 | flutter_test: 16 | sdk: flutter 17 | mockito: ^5.0.0 18 | matcher: ^0.12.10 19 | 20 | flutter: 21 | -------------------------------------------------------------------------------- /res/values/strings_en.arb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutterings/sqflite_migration/4bc00a82a731b0fb412a7d1627ed964051745767/res/values/strings_en.arb -------------------------------------------------------------------------------- /test/src/migrator_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:matcher/matcher.dart'; 3 | import 'package:mockito/mockito.dart'; 4 | import 'package:sqflite/sqflite.dart'; 5 | 6 | import 'package:sqflite_migration/sqflite_migration.dart'; 7 | import 'package:sqflite_migration/src/migrator.dart'; 8 | 9 | class MockDatabase extends Mock implements DatabaseExecutor { 10 | @override 11 | Future execute(String sql, [List? arguments]) async { 12 | return super.noSuchMethod(Invocation.method(#execute, [sql])); 13 | } 14 | } 15 | 16 | void main() { 17 | test('should not run any executions on an empty initializationScript list', 18 | () async { 19 | var db = MockDatabase(); 20 | 21 | var config = MigrationConfig( 22 | initializationScript: [], 23 | migrationScripts: [], 24 | ); 25 | 26 | await Migrator(config).executeInitialization(db, 1); 27 | 28 | verifyZeroInteractions(db); 29 | }); 30 | 31 | test('should run executions on an initializationScript list of 1', () async { 32 | var db = MockDatabase(); 33 | 34 | var config = MigrationConfig( 35 | initializationScript: ['script line 1'], 36 | migrationScripts: [], 37 | ); 38 | 39 | await Migrator(config).executeInitialization(db, 1); 40 | 41 | verify(db.execute('script line 1')); 42 | }); 43 | 44 | test('should run all executions on an initializationScript list', () async { 45 | var db = MockDatabase(); 46 | 47 | var config = MigrationConfig( 48 | initializationScript: ['script line 1', 'script line 2'], 49 | migrationScripts: [], 50 | ); 51 | 52 | await Migrator(config).executeInitialization(db, 1); 53 | 54 | verify(db.execute('script line 1')); 55 | verify(db.execute('script line 2')); 56 | }); 57 | 58 | test('should run any migrations when initializing', () async { 59 | var db = MockDatabase(); 60 | 61 | var config = MigrationConfig( 62 | initializationScript: ['init script line 1', 'init script line 2'], 63 | migrationScripts: ['migration script line 1', 'migration script line 2'], 64 | ); 65 | 66 | await Migrator(config) 67 | .executeInitialization(db, config.migrationScripts.length + 1); 68 | 69 | verify(db.execute('init script line 1')); 70 | verify(db.execute('init script line 2')); 71 | 72 | verify(db.execute('migration script line 1')); 73 | verify(db.execute('migration script line 2')); 74 | }); 75 | 76 | test('should throw error if the new version is not greater than the old', 77 | () async { 78 | var db = MockDatabase(); 79 | var config = MigrationConfig( 80 | initializationScript: [], 81 | migrationScripts: [], 82 | ); 83 | 84 | expect( 85 | () async => await Migrator(config).executeMigration(db, 1, 1), 86 | throwsA(TypeMatcher().having( 87 | (e) => e.message, 88 | 'message', 89 | equals( 90 | 'The newVersion(1) should always be greater than the oldVersion(1).')))); 91 | }); 92 | 93 | test( 94 | 'should throw error if the new version is greater than the migration scripts', 95 | () async { 96 | var db = MockDatabase(); 97 | var config = MigrationConfig( 98 | initializationScript: ['init script line 1', 'init script line 2'], 99 | migrationScripts: [], 100 | ); 101 | 102 | expect( 103 | () async => await Migrator(config).executeMigration(db, 1, 2), 104 | throwsA(TypeMatcher().having( 105 | (e) => e.message, 106 | 'message', 107 | equals('New version (2) requires exact 2 migrations.')))); 108 | }); 109 | 110 | test( 111 | 'should throw error if the new version is greater than the migration scripts', 112 | () async { 113 | var db = MockDatabase(); 114 | var config = MigrationConfig( 115 | initializationScript: [], 116 | migrationScripts: [], 117 | ); 118 | 119 | expect( 120 | () async => await Migrator(config).executeMigration(db, 1, 2), 121 | throwsA(TypeMatcher().having( 122 | (e) => e.message, 123 | 'message', 124 | equals('New version (2) requires exact 2 migrations.')))); 125 | }); 126 | 127 | test('should not execute migrations older than the oldVersion', () async { 128 | var db = MockDatabase(); 129 | var config = MigrationConfig( 130 | initializationScript: [], 131 | migrationScripts: [ 132 | 'migration line 1', 133 | 'migration line 2', 134 | 'migration line 3', 135 | ], 136 | ); 137 | 138 | await Migrator(config) 139 | .executeMigration(db, 2, config.migrationScripts.length + 1); 140 | 141 | verify(db.execute('migration line 2')); 142 | verify(db.execute('migration line 3')); 143 | }); 144 | } 145 | -------------------------------------------------------------------------------- /test/src/open_database_with_migration_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:sqflite/sqflite.dart'; 3 | 4 | import 'package:sqflite_migration/sqflite_migration.dart'; 5 | 6 | void main() { 7 | test('should pass the path to sqflite', () async { 8 | final config = MigrationConfig( 9 | initializationScript: [], 10 | migrationScripts: [], 11 | ); 12 | 13 | final log = []; 14 | 15 | await openDatabaseWithMigration('path', config, 16 | openDatabase: ( 17 | path, { 18 | int? version, 19 | OnDatabaseCreateFn? onCreate, 20 | OnDatabaseVersionChangeFn? onUpgrade, 21 | }) => 22 | log.add(path)); 23 | 24 | expect(log, ['path']); 25 | }); 26 | 27 | test( 28 | 'should determine the version according to the number of migration scripts', 29 | () async { 30 | final config = MigrationConfig( 31 | initializationScript: [], 32 | migrationScripts: ['script 1', 'script 2'], 33 | ); 34 | 35 | final log = []; 36 | 37 | await openDatabaseWithMigration('path', config, 38 | openDatabase: ( 39 | path, { 40 | int? version, 41 | OnDatabaseCreateFn? onCreate, 42 | OnDatabaseVersionChangeFn? onUpgrade, 43 | }) => 44 | log.add(version)); 45 | 46 | expect(log, [3]); 47 | }); 48 | } 49 | --------------------------------------------------------------------------------