Declaring a Collection
Use@Collection() to mark a Dart class as a Cindel root collection. Pass a name: argument to set an explicit stored name, or omit it to let the generator derive the name from the class name.
- a schema constant (
UserSchema), - a typed collection accessor on the database instance (
db.users), - generated read, write, and query helpers for
User.
name parameter is the persisted collection name. Cindel stores it with the database and uses it for every open, migration, backup, and restore. Keep it stable once you have real user data — renaming the Dart class is safe, but changing the stored name changes the format your database expects.
@collection Shorthand
When you are happy with a derived name, use the lowercase @collection constant — it is equivalent to @Collection() with no arguments.
@Collection(name: ...) when you want the stored name to be explicit and stable.
Controlling Stored Names with @Name
Use @Name to decouple the stored name from the Dart identifier on either a class or a field.
Account, AccountSchema, db.accounts, and username. In storage the collection is named accounts and the field is named user_name. This lets you improve Dart naming freely while keeping the stored format stable for existing data.
Every Cindel collection class requires a
part directive pointing to the generated file — for example part 'user.g.dart';. Without it, code generation output will not be found and your project will not compile.IDs
Every root collection needs exactly one persisted id field nameddbId with type Id.
Auto-Increment IDs
UseautoIncrement when Cindel should assign the ID on first write.
put, the generated ID setter writes the allocated value back into the object:
Explicit IDs
Use an explicit ID when your app owns the value — for example imported data, deterministic fixtures, or records whose ID is assigned by a server.Persisted Field Types
Cindel persists every field whose type is in the supported set and that is not marked@ignore. Supported field shapes are:
List<List<int>> field will not be persisted. Use embedded objects for structured child values and a separate root collection for independently stored objects.
Ignoring Fields
Use@ignore (or @Ignore()) to exclude a field from persistence entirely. The field exists in Dart but Cindel will never read or write it.
Enums
Cindel persists enum fields when you annotate them with@Enumerated and choose a storage strategy.
Name-Based Storage
CindelEnumType.name stores the enum case name as a string. This is the easiest strategy to read and debug.
Ordinal-Based Storage
CindelEnumType.ordinal stores the enum case index (0, 1, 2 …). It is compact, but enum declaration order becomes part of the stored contract.
Value-Based Storage
CindelEnumType.value stores the value of a named instance field. Use this when your enum cases carry durable external codes.
Indexes
Indexes speed up queries and let you enforce uniqueness constraints. Cindel provides single-field indexes and class-level composite indexes.Single-Field Index
Place@Index (or the lowercase @index constant) directly on a field.
@Index options:
Index Types
Composite Index
Declare composite indexes at the class level using theindexes parameter of @Collection.
CompositeIndex takes a list of field names in the order they form the composite key. It supports the same unique, replace, and caseSensitive options as @Index.
Modeling Checklist
Before running code generation, verify each collection from your app’s point of view:1
Correct annotation
The class has
@Collection(name: ...) or @collection, and a part directive for the generated file.2
One persisted ID
There is exactly one
Id dbId field, set to autoIncrement or an explicit value as appropriate.3
Supported field types only
Every persisted field uses a supported type. Runtime-only fields are marked
@ignore.4
Stable stored names
@Collection(name: ...) and @Name(...) values are stable if real user data already exists.5
Enum strategies confirmed
Each
@Enumerated field uses a strategy whose contract (case names, ordinal positions, or value fields) is stable.6
Indexes match query patterns
Every field used in a sorted, range, or equality query has the appropriate index type.