Skip to main content

drizzle_sqlite/
attrs.rs

1//! Attribute markers for `SQLiteTable` derive macro.
2//!
3//! These const markers are used within `#[column(...)]` and `#[SQLiteTable(...)]`
4//! attributes. Import them from the prelude to get IDE hover documentation.
5//!
6//! # Example
7//! ```rust
8//! # let _ = r####"
9//! # use drizzle::sqlite::prelude::*;
10//!
11//! #[SQLiteTable(
12//!     name = "users",
13//!     strict,
14//!     unique(columns(email, tenant_id)),
15//!     check(name = "users_score_check", expr = "score >= 0")
16//! )]
17//! struct User {
18//!     #[column(primary, autoincrement)]
19//!     id: i32,
20//!     #[column(unique)]
21//!     email: String,
22//!     tenant_id: i32,
23//!     score: i32,
24//!     metadata: String,
25//! }
26//! # "####;
27//! ```
28
29/// Marker struct for column constraint attributes.
30#[derive(Debug, Clone, Copy)]
31pub struct ColumnMarker;
32
33//------------------------------------------------------------------------------
34// Primary Key Constraints
35//------------------------------------------------------------------------------
36
37/// Marks this column as the PRIMARY KEY.
38///
39/// ## Example
40/// ```rust
41/// # let _ = r####"
42/// #[column(primary)]
43/// id: i32,
44/// # "####;
45/// ```
46///
47/// See: <https://sqlite.org/lang_createtable.html#primkeyconst>
48pub const PRIMARY: ColumnMarker = ColumnMarker;
49
50/// Alias for [`PRIMARY`].
51pub const PRIMARY_KEY: ColumnMarker = ColumnMarker;
52
53/// Enables AUTOINCREMENT for INTEGER PRIMARY KEY columns.
54///
55/// ## Example
56/// ```rust
57/// # let _ = r####"
58/// #[column(primary, autoincrement)]
59/// id: i32,
60/// # "####;
61/// ```
62///
63/// See: <https://sqlite.org/autoinc.html>
64pub const AUTOINCREMENT: ColumnMarker = ColumnMarker;
65
66//------------------------------------------------------------------------------
67// Index Attributes
68//------------------------------------------------------------------------------
69
70/// Marker struct for index attributes.
71#[derive(Debug, Clone, Copy)]
72pub struct IndexMarker;
73
74/// Specifies a partial-index predicate as raw SQLite SQL.
75///
76/// Use database column names in the predicate. Rust field or column renames do
77/// not rewrite this string.
78///
79/// ## Example
80/// ```rust
81/// # let _ = r####"
82/// #[SQLiteIndex(where = "deleted_at IS NULL")]
83/// struct ActiveUsersEmailIdx(Users::email);
84/// # "####;
85/// ```
86///
87/// See: <https://sqlite.org/partialindex.html>
88pub const WHERE: IndexMarker = IndexMarker;
89
90//------------------------------------------------------------------------------
91// Uniqueness Constraints
92//------------------------------------------------------------------------------
93
94/// Adds a UNIQUE constraint to a column, table, or index.
95///
96/// ## Examples
97/// ```rust
98/// # let _ = r####"
99/// #[column(unique)]
100/// email: String,
101///
102/// #[SQLiteTable(unique(columns(email, tenant_id)))]
103/// struct Users {
104///     email: String,
105///     tenant_id: i32,
106/// }
107///
108/// #[SQLiteIndex(unique)]
109/// struct UsersEmailIdx(Users::email);
110/// # "####;
111/// ```
112///
113/// See: <https://sqlite.org/lang_createtable.html#unique_constraints>
114pub const UNIQUE: ColumnMarker = ColumnMarker;
115
116//------------------------------------------------------------------------------
117// Serialization Modes
118//------------------------------------------------------------------------------
119
120/// Enables JSON serialization with TEXT storage.
121///
122/// ## Example
123/// ```rust
124/// # let _ = r####"
125/// #[column(json)]
126/// metadata: UserMetadata,
127/// # "####;
128/// ```
129///
130/// Requires the `serde` feature. The field type must implement `Serialize` and `Deserialize`.
131pub const JSON: ColumnMarker = ColumnMarker;
132
133/// Enables JSON serialization with BLOB storage.
134///
135/// ## Example
136/// ```rust
137/// # let _ = r####"
138/// #[column(jsonb)]
139/// config: AppConfig,
140/// # "####;
141/// ```
142///
143/// Requires the `serde` feature. The field type must implement `Serialize` and `Deserialize`.
144pub const JSONB: ColumnMarker = ColumnMarker;
145
146/// Marks this column as storing an enum type.
147///
148/// ## Example
149/// ```rust
150/// # let _ = r####"
151/// #[column(enum)]
152/// role: Role,
153///
154/// #[column(integer, enum)]
155/// status: Status,
156/// # "####;
157/// ```
158///
159/// The enum must derive `SQLiteEnum`.
160pub const ENUM: ColumnMarker = ColumnMarker;
161
162//------------------------------------------------------------------------------
163// Default Value Parameters
164//------------------------------------------------------------------------------
165
166/// Specifies a function to generate default values at runtime.
167///
168/// The function is called for each insert when no value is provided.
169///
170/// ## Example
171/// ```rust
172/// # let _ = r####"
173/// #[column(default_fn = Uuid::new_v4)]
174/// id: Uuid,
175/// # "####;
176/// ```
177///
178/// ## Difference from DEFAULT
179/// - `default_fn`: Calls the function at runtime for each insert (e.g., UUID generation)
180/// - `default`: Uses a fixed compile-time value
181pub const DEFAULT_FN: ColumnMarker = ColumnMarker;
182
183/// Specifies a fixed default value for new rows.
184///
185/// ## Example
186/// ```rust
187/// # let _ = r####"
188/// #[column(default = 0)]
189/// count: i32,
190///
191/// #[column(default = "guest")]
192/// role: String,
193/// # "####;
194/// ```
195///
196/// For runtime-generated values (UUIDs, timestamps), use [`DEFAULT_FN`] instead.
197pub const DEFAULT: ColumnMarker = ColumnMarker;
198
199/// Specifies a raw SQL default expression for new rows.
200///
201/// ## Example
202/// ```rust
203/// # let _ = r####"
204/// #[column(default_sql = "CURRENT_TIMESTAMP")]
205/// created_at: String,
206/// # "####;
207/// ```
208///
209/// See: <https://sqlite.org/lang_createtable.html#the_default_clause>
210pub const DEFAULT_SQL: ColumnMarker = ColumnMarker;
211
212/// Marks this column as a generated column.
213///
214/// ## Examples
215/// ```rust
216/// # let _ = r####"
217/// #[column(generated(stored, "length(name)"))]
218/// stored_name_len: i32,
219///
220/// #[column(generated(virtual, "length(name)"))]
221/// virtual_name_len: i32,
222/// # "####;
223/// ```
224///
225/// See: <https://sqlite.org/gencol.html>
226pub const GENERATED: ColumnMarker = ColumnMarker;
227
228/// Adds a CHECK constraint for a column or table.
229///
230/// ## Examples
231/// ```rust
232/// # let _ = r####"
233/// #[column(check = "score >= 0")]
234/// score: i32,
235///
236/// #[SQLiteTable(check(name = "score_range", expr = "score >= 0 AND score <= 100"))]
237/// struct Scores {
238///     score: i32,
239/// }
240/// # "####;
241/// ```
242///
243/// See: <https://sqlite.org/lang_createtable.html#check_constraints>
244pub const CHECK: ColumnMarker = ColumnMarker;
245
246/// Establishes a foreign key reference to another table's column.
247///
248/// ## Example
249/// ```rust
250/// # let _ = r####"
251/// #[column(references = User::id)]
252/// user_id: i32,
253/// # "####;
254/// ```
255///
256/// See: <https://sqlite.org/foreignkeys.html>
257pub const REFERENCES: ColumnMarker = ColumnMarker;
258
259/// Sets the reverse relation accessor name on the referenced table.
260///
261/// By default, reverse relations are named from the source table
262/// (`posts` for a `Post` table). When multiple foreign keys target the
263/// same table — or the FK is self-referential — the name is disambiguated
264/// as `{forward}_{plural}` (e.g. `author_posts`). Use `relation` to pick
265/// an explicit reverse name instead.
266///
267/// The forward relation (on this table) is unchanged; only the reverse
268/// accessor on the referenced table is renamed.
269///
270/// ## Example
271/// ```rust
272/// # let _ = r####"
273/// // Users get `.authored()` instead of `.author_posts()`
274/// #[column(references = User::id, relation = "authored")]
275/// author_id: i32,
276///
277/// // Still auto-disambiguated: Users get `.editor_posts()`
278/// #[column(references = User::id)]
279/// editor_id: Option<i32>,
280/// # "####;
281/// ```
282///
283/// Requires a `references` attribute on the same column.
284pub const RELATION: ColumnMarker = ColumnMarker;
285
286/// Specifies the ON DELETE action for foreign key references.
287///
288/// ## Example
289/// ```rust
290/// # let _ = r####"
291/// #[column(references = User::id, on_delete = CASCADE)]
292/// user_id: i32,
293/// # "####;
294/// ```
295///
296/// ## Supported Actions
297/// - `CASCADE`: Delete rows that reference the deleted row
298/// - `SET_NULL`: Set the column to NULL when referenced row is deleted
299/// - `SET_DEFAULT`: Set the column to its default value
300/// - `RESTRICT`: Prevent deletion if referenced
301/// - `NO_ACTION`: Similar to RESTRICT (default)
302///
303/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
304pub const ON_DELETE: ColumnMarker = ColumnMarker;
305
306/// Specifies the ON UPDATE action for foreign key references.
307///
308/// ## Example
309/// ```rust
310/// # let _ = r####"
311/// #[column(references = User::id, on_update = CASCADE)]
312/// user_id: i32,
313/// # "####;
314/// ```
315///
316/// ## Supported Actions
317/// - `CASCADE`: Update referencing rows when referenced row is updated
318/// - `SET_NULL`: Set the column to NULL when referenced row is updated
319/// - `SET_DEFAULT`: Set the column to its default value
320/// - `RESTRICT`: Prevent update if referenced
321/// - `NO_ACTION`: Similar to RESTRICT (default)
322///
323/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
324pub const ON_UPDATE: ColumnMarker = ColumnMarker;
325
326//------------------------------------------------------------------------------
327// Referential Action Values
328//------------------------------------------------------------------------------
329
330/// Type alias for referential action markers (uses `ColumnMarker` for macro compatibility).
331pub type ReferentialAction = ColumnMarker;
332
333/// CASCADE action: Propagate the delete/update to referencing rows.
334///
335/// ## Example
336/// ```rust
337/// # let _ = r####"
338/// #[column(references = User::id, on_delete = CASCADE)]
339/// user_id: i32,
340/// # "####;
341/// ```
342///
343/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
344pub const CASCADE: ColumnMarker = ColumnMarker;
345
346/// SET NULL action: Set referencing columns to NULL.
347///
348/// ## Example
349/// ```rust
350/// # let _ = r####"
351/// #[column(references = User::id, on_delete = SET_NULL)]
352/// user_id: Option<i32>,
353/// # "####;
354/// ```
355///
356/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
357pub const SET_NULL: ColumnMarker = ColumnMarker;
358
359/// SET DEFAULT action: Set referencing columns to their default values.
360///
361/// ## Example
362/// ```rust
363/// # let _ = r####"
364/// #[column(references = User::id, on_delete = SET_DEFAULT, default = 0)]
365/// user_id: i32,
366/// # "####;
367/// ```
368///
369/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
370pub const SET_DEFAULT: ColumnMarker = ColumnMarker;
371
372/// RESTRICT action: Prevent delete/update if referenced.
373///
374/// ## Example
375/// ```rust
376/// # let _ = r####"
377/// #[column(references = User::id, on_delete = RESTRICT)]
378/// user_id: i32,
379/// # "####;
380/// ```
381///
382/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
383pub const RESTRICT: ColumnMarker = ColumnMarker;
384
385/// NO ACTION action: Similar to RESTRICT (default behavior).
386///
387/// ## Example
388/// ```rust
389/// # let _ = r####"
390/// #[column(references = User::id, on_delete = NO_ACTION)]
391/// user_id: i32,
392/// # "####;
393/// ```
394///
395/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
396pub const NO_ACTION: ColumnMarker = ColumnMarker;
397
398//------------------------------------------------------------------------------
399// Collation Markers
400//------------------------------------------------------------------------------
401
402/// Specifies a collation sequence for a text column.
403///
404/// ## Example
405/// ```rust
406/// # let _ = r####"
407/// #[column(COLLATE = NOCASE)]
408/// name: String,
409///
410/// // String form for custom registered collations:
411/// #[column(COLLATE = "my_collation")]
412/// label: String,
413/// # "####;
414/// ```
415///
416/// See: <https://sqlite.org/datatype3.html#collation>
417pub const COLLATE: ColumnMarker = ColumnMarker;
418
419/// BINARY collation: bytewise comparison of operands. The default for `BLOB`
420/// columns and any column without an explicit collation.
421pub const BINARY: ColumnMarker = ColumnMarker;
422
423/// NOCASE collation: ASCII case-insensitive comparison. Useful for text
424/// columns that need case-insensitive equality / sorting.
425pub const NOCASE: ColumnMarker = ColumnMarker;
426
427/// RTRIM collation: like `BINARY` but trailing spaces are ignored when
428/// comparing.
429pub const RTRIM: ColumnMarker = ColumnMarker;
430
431//------------------------------------------------------------------------------
432// Name Marker (shared by column and table attributes)
433//------------------------------------------------------------------------------
434
435/// Marker struct for the NAME attribute.
436#[derive(Debug, Clone, Copy)]
437pub struct NameMarker;
438
439/// Specifies a custom name in the database.
440///
441/// By default, table, view, and column names are automatically converted to `snake_case`
442/// from the Rust struct/field name. Use NAME to override this behavior.
443///
444/// ## Column Example
445/// ```rust
446/// # let _ = r####"
447/// // Field `createdAt` becomes `created_at` by default
448/// created_at: DateTime<Utc>,
449///
450/// // Override with custom name:
451/// #[column(name = "creation_timestamp")]
452/// created_at: DateTime<Utc>,
453/// # "####;
454/// ```
455///
456/// ## Table Example
457/// ```rust
458/// # let _ = r####"
459/// // Struct `UserAccount` becomes table `user_account` by default
460/// struct UserAccount { ... }
461///
462/// // Override with custom name:
463/// #[SQLiteTable(name = "user_accounts")]
464/// struct UserAccount { ... }
465/// # "####;
466/// ```
467///
468/// ## View Example
469/// ```rust
470/// # let _ = r####"
471/// #[SQLiteView(NAME = "active_users")]
472/// struct ActiveUsers { ... }
473/// # "####;
474/// ```
475pub const NAME: NameMarker = NameMarker;
476
477//------------------------------------------------------------------------------
478// View Attribute Markers
479//------------------------------------------------------------------------------
480
481/// Marker struct for view attributes.
482#[derive(Debug, Clone, Copy)]
483pub struct ViewMarker;
484
485/// Specifies a view definition SQL string or expression.
486///
487/// ## Examples
488/// ```rust
489/// # let _ = r####"
490/// #[SQLiteView(DEFINITION = "SELECT id, email FROM users")]
491/// struct UserEmails { id: i32, email: String }
492/// # "####;
493/// ```
494///
495/// ```rust
496/// # let _ = r####"
497/// #[SQLiteView(
498///     DEFINITION = {
499///         let builder = drizzle::sqlite::QueryBuilder::new::<Schema>();
500///         let Schema { user } = Schema::new();
501///         builder.select((user.id, user.email)).from(user)
502///     }
503/// )]
504/// struct UserEmails { id: i32, email: String }
505/// # "####;
506/// ```
507pub const DEFINITION: ViewMarker = ViewMarker;
508
509/// Marks the view as existing (skip creation).
510///
511/// ## Example
512/// ```rust
513/// # let _ = r####"
514/// #[SQLiteView(EXISTING)]
515/// struct ExistingView { ... }
516/// # "####;
517/// ```
518pub const EXISTING: ViewMarker = ViewMarker;
519
520//------------------------------------------------------------------------------
521// Table Attribute Markers
522//------------------------------------------------------------------------------
523
524/// Marker struct for table-level attributes.
525#[derive(Debug, Clone, Copy)]
526pub struct TableMarker;
527
528/// Adds a table-level composite foreign key constraint.
529///
530/// ## Example
531/// ```rust
532/// # let _ = r####"
533/// #[SQLiteTable(foreign_key(
534///     columns(tenant_id, user_id),
535///     references(Users, tenant_id, id),
536///     on_delete = "CASCADE"
537/// ))]
538/// struct Posts {
539///     tenant_id: i32,
540///     user_id: i32,
541/// }
542/// # "####;
543/// ```
544///
545/// See: <https://sqlite.org/foreignkeys.html#fk_composite>
546pub const FOREIGN_KEY: TableMarker = TableMarker;
547
548/// Enables STRICT mode for the table.
549///
550/// ## Example
551/// ```rust
552/// # let _ = r####"
553/// #[SQLiteTable(strict)]
554/// struct Users {
555///     #[column(primary)]
556///     id: i32,
557///     name: String,
558/// }
559/// # "####;
560/// ```
561///
562/// # `SQLite` Behavior
563/// - Enforces that values match declared column types exactly
564/// - `INTEGER` columns only accept integers
565/// - `TEXT` columns only accept text
566/// - `REAL` columns only accept floating-point numbers
567/// - `BLOB` columns only accept blobs
568/// - `ANY` type allows any value (only in STRICT tables)
569///
570/// See: <https://sqlite.org/stricttables.html>
571pub const STRICT: TableMarker = TableMarker;
572
573/// Enables WITHOUT ROWID optimization for the table.
574///
575/// ## Example
576/// ```rust
577/// # let _ = r####"
578/// #[SQLiteTable(without_rowid)]
579/// struct KeyValue {
580///     #[column(primary)]
581///     key: String,
582///     value: String,
583/// }
584/// # "####;
585/// ```
586///
587/// Requires an explicit PRIMARY KEY.
588///
589/// See: <https://sqlite.org/withoutrowid.html>
590pub const WITHOUT_ROWID: TableMarker = TableMarker;
591
592//------------------------------------------------------------------------------
593// Column Type Markers
594//------------------------------------------------------------------------------
595
596/// Marker struct for column type attributes.
597#[derive(Debug, Clone, Copy)]
598pub struct TypeMarker;
599
600/// Specifies an INTEGER column type.
601///
602/// ## Example
603/// ```rust
604/// # let _ = r####"
605/// #[column(integer, primary)]
606/// id: i32,
607/// # "####;
608/// ```
609///
610/// INTEGER columns store signed integers up to 8 bytes (64-bit).
611/// `SQLite` uses a variable-length encoding, so small values use less space.
612///
613/// See: <https://sqlite.org/datatype3.html#storage_classes_and_datatypes>
614pub const INTEGER: TypeMarker = TypeMarker;
615
616/// Specifies a TEXT column type.
617///
618/// ## Example
619/// ```rust
620/// # let _ = r####"
621/// #[column(text)]
622/// name: String,
623/// # "####;
624/// ```
625///
626/// TEXT columns store variable-length UTF-8 character strings with no size limit.
627///
628/// See: <https://sqlite.org/datatype3.html#storage_classes_and_datatypes>
629pub const TEXT: TypeMarker = TypeMarker;
630
631/// Specifies a BLOB column type.
632///
633/// ## Example
634/// ```rust
635/// # let _ = r####"
636/// #[column(blob)]
637/// data: Vec<u8>,
638/// # "####;
639/// ```
640///
641/// BLOB columns store binary data exactly as input.
642///
643/// See: <https://sqlite.org/datatype3.html#storage_classes_and_datatypes>
644pub const BLOB: TypeMarker = TypeMarker;
645
646/// Specifies a REAL column type.
647///
648/// ## Example
649/// ```rust
650/// # let _ = r####"
651/// #[column(real)]
652/// price: f64,
653/// # "####;
654/// ```
655///
656/// REAL columns store 8-byte IEEE floating point numbers.
657///
658/// See: <https://sqlite.org/datatype3.html#storage_classes_and_datatypes>
659pub const REAL: TypeMarker = TypeMarker;
660
661/// Specifies a NUMERIC column type.
662///
663/// ## Example
664/// ```rust
665/// # let _ = r####"
666/// #[column(numeric)]
667/// amount: f64,
668/// # "####;
669/// ```
670///
671/// NUMERIC columns store values as INTEGER, REAL, or TEXT depending on the value.
672///
673/// See: <https://sqlite.org/datatype3.html#type_affinity>
674pub const NUMERIC: TypeMarker = TypeMarker;
675
676/// Specifies an ANY column type (STRICT tables only).
677///
678/// ## Example
679/// ```rust
680/// # let _ = r####"
681/// #[SQLiteTable(strict)]
682/// struct Data {
683///     #[column(any)]
684///     value: serde_json::Value,
685/// }
686/// # "####;
687/// ```
688///
689/// ANY allows any type of data. Only valid in STRICT tables.
690///
691/// See: <https://sqlite.org/stricttables.html>
692pub const ANY: TypeMarker = TypeMarker;
693
694/// Specifies a BOOLEAN column (stored as INTEGER 0/1).
695///
696/// ## Example
697/// ```rust
698/// # let _ = r####"
699/// #[column(boolean)]
700/// active: bool,
701/// # "####;
702/// ```
703///
704/// `SQLite` has no native BOOLEAN. Values are stored as INTEGER (0 for false, 1 for true).
705///
706/// See: <https://sqlite.org/datatype3.html#boolean_datatype>
707pub const BOOLEAN: TypeMarker = TypeMarker;