migrate<T extends Model> static method

Future<void> migrate<T extends Model>({
  1. required T constructor(
    1. Map<String, dynamic>
    ),
  2. Map<String, String>? columnDefinitions,
})

Registers a model with schema and constructor.

Must be called before any CRUD operations.

  • constructor: (Map<String, dynamic>) → T
  • columnDefinitions: Custom columns (merged with defaults)

Example:

await SQLiteModel.migrate<User>(
  constructor: (json) => User.fromJson(json),
  columnDefinitions: {
    'name': 'TEXT NOT NULL',
    'email': 'TEXT UNIQUE NOT NULL',
  },
);

Implementation

static Future<void> migrate<T extends Model>({
  required T Function(Map<String, dynamic>) constructor,
  Map<String, String>? columnDefinitions,
}) async {
  _jsonConstructors[T] = constructor;

  if (columnDefinitions != null && columnDefinitions.isNotEmpty) {
    final tableName = _getTableName<T>();
    final allColumns = {..._columnDefinitions, ...columnDefinitions};

    final columnsDef = allColumns.entries
        .map((e) => '${e.key} ${e.value}')
        .join(', ');

    await _database.execute('''
      CREATE TABLE IF NOT EXISTS $tableName (
        $columnsDef
      )
    ''');

    // Performance indexes
    await _database.execute('''
      CREATE INDEX IF NOT EXISTS idx_${tableName}_uuid
      ON $tableName (uuid)
    ''');

    await _database.execute('''
      CREATE INDEX IF NOT EXISTS idx_${tableName}_created_at
      ON $tableName (created_at)
    ''');
  }
}