Cindel’s migration system lets you advance your local database schema safely across app versions. You pass aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/mainser/cindel/llms.txt
Use this file to discover all available pages before exploring further.
CindelMigrationPlan to Cindel.open on every app start; Cindel reads the stored data version, skips steps that have already completed, and opens the final database handle with the target schemas only after every pending step succeeds. The same migration contract is supported across the SQLite native, MDBX, and SQLite Web/OPFS backends.
CindelMigrationPlan
CindelMigrationPlan describes the full upgrade path from any historical data version to the current targetVersion. Pass one instance to Cindel.open via the migrationPlan parameter on every cold start — Cindel is idempotent and simply skips steps whose toVersion is already recorded in the database.
Constructor Parameters
Final data version expected after all migration steps complete. Must be
non-negative. Cindel throws an
ArgumentError at construction time if a
negative value is supplied.Ordered list of migration steps. Each step is matched by its
fromVersion
value, so steps may be declared in any iterable order, but there must be
exactly one step for each version transition that exists between the stored
version and targetVersion.Version assumed for a database that already has a persisted schema but no
migration version marker — typically an app that was shipped before
CindelMigrationPlan was introduced. Setting this to the version your first
deployed schema represents prevents Cindel from re-running those steps for
existing users. Must be non-negative.When
true, Cindel compacts the storage backend after each step completes
successfully. Compaction reclaims space freed during data rewrites and is
recommended for steps that delete or replace large volumes of documents.Methods
run({directory, targetSchemas, backend})
public so the native and Web database facades can share one implementation, but application code should pass the plan to Cindel.open rather than calling run directly. Cindel opens a metadata database to determine the current version, then iterates through each pending step in order, invoking verifyBefore, migrate, registerTargetSchemas (if not already called), and verifyAfter for every step before persisting the new version number.
CindelMigrationStep
CindelMigrationStep represents a single version transition. Each step declares the schemas needed to read the current data (openSchemas) and optionally the schemas needed to write the migrated data (targetSchemas). It also carries up to three callbacks: an optional pre-check, the required migration body, and an optional post-check.
Constructor Parameters
Data version expected at the start of this step. Cindel uses this value to
look up the correct step when iterating through a plan — it must match the
version stored (or derived) in the database.
Data version persisted after this step succeeds. Must be strictly greater than
fromVersion. Cindel throws a StateError at plan-execution time if this
constraint is violated.Schemas used to open the database before rewriting data. These schemas must
describe the shape of data currently on disk so that
exportObjects and
exportDocuments can deserialize existing records correctly.Schemas that will be registered by
CindelMigrationContext.registerTargetSchemas.
When omitted, the step inherits the targetSchemas passed to Cindel.open,
which is the most common case. Supply an explicit value only when a step’s
intermediate target shape differs from the final app schema.Optional callback executed before
migrate. Use it to assert invariants on the
existing data — for example, checking that expected collections exist or that
document counts are within expected ranges. If this callback throws, the step
is aborted and the database version is not advanced.Main migration callback. It receives a
CindelMigrationContext and is
responsible for exporting old data, calling registerTargetSchemas, and
importing the rewritten data. If registerTargetSchemas has not been called
by the time migrate returns, Cindel calls it automatically before advancing
the version.Optional callback executed after
migrate and registerTargetSchemas have
both completed. Use it to confirm the resulting state — for example, reading
back a schema version or asserting that key documents were written.Callback Signature
All three callbacks share the same typedef:CindelMigrationContext
CindelMigrationContext is passed to every migration callback. It exposes the open database handle for the current step along with version information and the full set of data-transfer helpers needed to read old records and write new ones.
Properties
Open database handle for the running migration step. The handle is opened with
openSchemas so you can read existing documents through the old typed
collections. Do not close this handle manually — Cindel closes it after the
step completes.Source data version for this step; mirrors
CindelMigrationStep.fromVersion.Target data version for this step; mirrors
CindelMigrationStep.toVersion.Schemas that will be registered as the new target shape when
registerTargetSchemas is called. Read-only; set by the step or inherited
from Cindel.open.true once registerTargetSchemas has completed for this step. Cindel checks
this flag after migrate returns and calls registerTargetSchemas
automatically if it is still false.Methods
registerTargetSchemas() → Future<void>
importObjects or importDocuments calls write into the migrated
layout. This method is idempotent — calling it more than once is safe and
subsequent calls are no-ops. You must call it (or allow Cindel to call it
automatically) before importing data in the new format.
exportObjects<T>(schema, {batchSize}) → Future<List<T>>
schema in id order,
fetching batchSize ids at a time. Returns a flat List<T> containing every
non-null object found. Throws an ArgumentError if batchSize is less than or
equal to zero.
| Parameter | Type | Default | Description |
|---|---|---|---|
schema | CindelCollectionSchema<T> | — | Schema used to deserialize existing objects |
batchSize | int | 100 | Number of ids fetched per batch |
exportDocuments<T>(schema, {batchSize}) → Future<List<CindelDocument>>
exportObjects but returns raw CindelDocument maps (i.e. Map<String, Object?>) with the id field included. Useful when you want to inspect or transform document fields directly without working through the typed model.
| Parameter | Type | Default | Description |
|---|---|---|---|
schema | CindelCollectionSchema<T> | — | Schema used to deserialize existing objects |
batchSize | int | 100 | Number of ids fetched per batch |
importObjects<T>(schema, objects, {batchSize}) → Future<void>
schema in batches of batchSize, each batch executed inside a write transaction. Call registerTargetSchemas before calling this method so the target collection is registered in migrated mode. Throws an ArgumentError if batchSize is less than or equal to zero.
| Parameter | Type | Default | Description |
|---|---|---|---|
schema | CindelCollectionSchema<T> | — | Target schema to write into |
objects | Iterable<T> | — | Rewritten typed objects |
batchSize | int | 100 | Objects written per transaction |
importDocuments<T>(schema, documents, {batchSize}) → Future<void>
CindelDocument maps into schema by deserializing each map with schema.fromDocument, restoring the stored id when schema.setId is available, and delegating to importObjects in batches. Use this when your export step used exportDocuments or when you are building documents from external sources.
| Parameter | Type | Default | Description |
|---|---|---|---|
schema | CindelCollectionSchema<T> | — | Target schema to write into |
documents | Iterable<CindelDocument> | — | Raw map documents including the id field |
batchSize | int | 100 | Documents written per transaction |
Complete Migration Example
The following example is drawn from the README. It shows a full two-step plan with pre- and post-verification, advancing a database from version 1 to version 2 by rewritingOldUser records as the new User shape.