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/// Marks this column as storing an enum type.
134///
135/// ## Example
136/// ```rust
137/// # let _ = r####"
138/// #[column(enum)]
139/// role: Role,
140///
141/// #[column(integer, enum)]
142/// status: Status,
143/// # "####;
144/// ```
145///
146/// The enum must derive `SQLiteEnum`, and that derive decides the storage:
147/// INTEGER when a variant has an explicit discriminant or the enum has an
148/// integer `#[repr]`, TEXT (variant names) otherwise. An explicit `integer` or
149/// `text` marker must agree with it, or the table fails to compile.
150pub const ENUM: ColumnMarker = ColumnMarker;
151
152//------------------------------------------------------------------------------
153// Default Value Parameters
154//------------------------------------------------------------------------------
155
156/// Specifies an application-side function that generates omitted insert values.
157///
158/// The function is called for each insert when no value is provided.
159///
160/// ## Example
161/// ```rust
162/// # let _ = r####"
163/// #[column(default_fn = Uuid::new_v4)]
164/// id: Uuid,
165/// # "####;
166/// ```
167///
168/// Unlike [`DEFAULT`], this does not add a database `DEFAULT` clause.
169pub const DEFAULT_FN: ColumnMarker = ColumnMarker;
170
171/// Specifies a database `DEFAULT` clause for new rows.
172///
173/// ## Example
174/// ```rust
175/// # let _ = r####"
176/// #[column(default = 0)]
177/// count: i32,
178///
179/// #[column(default = "guest")]
180/// role: String,
181///
182/// #[column(default = CURRENT_TIMESTAMP)]
183/// created_at: String,
184///
185/// #[column(default = strftime("%s", "now"))]
186/// created_at_unix: i64,
187/// # "####;
188/// ```
189///
190/// For application-generated values such as UUIDs, use [`DEFAULT_FN`] instead.
191///
192/// See: <https://sqlite.org/lang_createtable.html#the_default_clause>
193pub const DEFAULT: ColumnMarker = ColumnMarker;
194
195/// Marks this column as a generated column.
196///
197/// ## Examples
198/// ```rust
199/// # let _ = r####"
200/// #[column(generated(stored, "length(name)"))]
201/// stored_name_len: i32,
202///
203/// #[column(generated(virtual, "length(name)"))]
204/// virtual_name_len: i32,
205/// # "####;
206/// ```
207///
208/// See: <https://sqlite.org/gencol.html>
209pub const GENERATED: ColumnMarker = ColumnMarker;
210
211/// Adds a CHECK constraint for a column or table.
212///
213/// ## Examples
214/// ```rust
215/// # let _ = r####"
216/// #[column(check = "score >= 0")]
217/// score: i32,
218///
219/// #[SQLiteTable(check(name = "score_range", expr = "score >= 0 AND score <= 100"))]
220/// struct Scores {
221/// score: i32,
222/// }
223/// # "####;
224/// ```
225///
226/// See: <https://sqlite.org/lang_createtable.html#check_constraints>
227pub const CHECK: ColumnMarker = ColumnMarker;
228
229/// Establishes a foreign key reference to another table's column.
230///
231/// ## Example
232/// ```rust
233/// # let _ = r####"
234/// #[column(references = User::id)]
235/// user_id: i32,
236/// # "####;
237/// ```
238///
239/// With the `query` feature this also generates relation accessors: a
240/// forward one on this table, named after the column without its `_id` suffix
241/// (`user_id` gives `.user()`), and a reverse one on the referenced table
242/// (see [`RELATION`]).
243///
244/// See: <https://sqlite.org/foreignkeys.html>
245pub const REFERENCES: ColumnMarker = ColumnMarker;
246
247/// Sets the reverse relation accessor name on the referenced table.
248///
249/// By default, reverse relations are named from the source table
250/// (`posts` for a `Post` table). When multiple foreign keys target the
251/// same table — or the FK is self-referential — the name is disambiguated
252/// as `{forward}_{plural}` (e.g. `author_posts`). Use `relation` to pick
253/// an explicit reverse name instead.
254///
255/// The forward relation (on this table) is unchanged; only the reverse
256/// accessor on the referenced table is renamed.
257///
258/// ## Example
259/// ```rust
260/// # let _ = r####"
261/// // Users get `.authored()` instead of `.author_posts()`
262/// #[column(references = User::id, relation = "authored")]
263/// author_id: i32,
264///
265/// // Still auto-disambiguated: Users get `.editor_posts()`
266/// #[column(references = User::id)]
267/// editor_id: Option<i32>,
268/// # "####;
269/// ```
270///
271/// Requires a `references` attribute on the same column.
272pub const RELATION: ColumnMarker = ColumnMarker;
273
274/// Specifies the ON DELETE action for foreign key references.
275///
276/// ## Example
277/// ```rust
278/// # let _ = r####"
279/// #[column(references = User::id, on_delete = CASCADE)]
280/// user_id: i32,
281/// # "####;
282/// ```
283///
284/// ## Supported Actions
285/// - `CASCADE`: Delete rows that reference the deleted row
286/// - `SET_NULL`: Set the column to NULL when referenced row is deleted
287/// - `SET_DEFAULT`: Set the column to its default value
288/// - `RESTRICT`: Prevent deletion if referenced
289/// - `NO_ACTION`: Similar to RESTRICT (default)
290///
291/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
292pub const ON_DELETE: ColumnMarker = ColumnMarker;
293
294/// Specifies the ON UPDATE action for foreign key references.
295///
296/// ## Example
297/// ```rust
298/// # let _ = r####"
299/// #[column(references = User::id, on_update = CASCADE)]
300/// user_id: i32,
301/// # "####;
302/// ```
303///
304/// ## Supported Actions
305/// - `CASCADE`: Update referencing rows when referenced row is updated
306/// - `SET_NULL`: Set the column to NULL when referenced row is updated
307/// - `SET_DEFAULT`: Set the column to its default value
308/// - `RESTRICT`: Prevent update if referenced
309/// - `NO_ACTION`: Similar to RESTRICT (default)
310///
311/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
312pub const ON_UPDATE: ColumnMarker = ColumnMarker;
313
314//------------------------------------------------------------------------------
315// Referential Action Values
316//------------------------------------------------------------------------------
317
318/// Type alias for referential action markers (uses `ColumnMarker` for macro compatibility).
319pub type ReferentialAction = ColumnMarker;
320
321/// CASCADE action: Propagate the delete/update to referencing rows.
322///
323/// ## Example
324/// ```rust
325/// # let _ = r####"
326/// #[column(references = User::id, on_delete = CASCADE)]
327/// user_id: i32,
328/// # "####;
329/// ```
330///
331/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
332pub const CASCADE: ColumnMarker = ColumnMarker;
333
334/// SET NULL action: Set referencing columns to NULL.
335///
336/// ## Example
337/// ```rust
338/// # let _ = r####"
339/// #[column(references = User::id, on_delete = SET_NULL)]
340/// user_id: Option<i32>,
341/// # "####;
342/// ```
343///
344/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
345pub const SET_NULL: ColumnMarker = ColumnMarker;
346
347/// SET DEFAULT action: Set referencing columns to their default values.
348///
349/// ## Example
350/// ```rust
351/// # let _ = r####"
352/// #[column(references = User::id, on_delete = SET_DEFAULT, default = 0)]
353/// user_id: i32,
354/// # "####;
355/// ```
356///
357/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
358pub const SET_DEFAULT: ColumnMarker = ColumnMarker;
359
360/// RESTRICT action: Prevent delete/update if referenced.
361///
362/// ## Example
363/// ```rust
364/// # let _ = r####"
365/// #[column(references = User::id, on_delete = RESTRICT)]
366/// user_id: i32,
367/// # "####;
368/// ```
369///
370/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
371pub const RESTRICT: ColumnMarker = ColumnMarker;
372
373/// NO ACTION action: Similar to RESTRICT (default behavior).
374///
375/// ## Example
376/// ```rust
377/// # let _ = r####"
378/// #[column(references = User::id, on_delete = NO_ACTION)]
379/// user_id: i32,
380/// # "####;
381/// ```
382///
383/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
384pub const NO_ACTION: ColumnMarker = ColumnMarker;
385
386//------------------------------------------------------------------------------
387// Collation Markers
388//------------------------------------------------------------------------------
389
390/// Specifies a collation sequence for a text column.
391///
392/// ## Example
393/// ```rust
394/// # let _ = r####"
395/// #[column(COLLATE = NOCASE)]
396/// name: String,
397///
398/// // String form for custom registered collations:
399/// #[column(COLLATE = "my_collation")]
400/// label: String,
401/// # "####;
402/// ```
403///
404/// See: <https://sqlite.org/datatype3.html#collation>
405pub const COLLATE: ColumnMarker = ColumnMarker;
406
407/// BINARY collation: bytewise comparison of operands. The default for `BLOB`
408/// columns and any column without an explicit collation.
409pub const BINARY: ColumnMarker = ColumnMarker;
410
411/// NOCASE collation: ASCII case-insensitive comparison. Useful for text
412/// columns that need case-insensitive equality / sorting.
413pub const NOCASE: ColumnMarker = ColumnMarker;
414
415/// RTRIM collation: like `BINARY` but trailing spaces are ignored when
416/// comparing.
417pub const RTRIM: ColumnMarker = ColumnMarker;
418
419//------------------------------------------------------------------------------
420// Name Marker (shared by column and table attributes)
421//------------------------------------------------------------------------------
422
423/// Marker struct for the NAME attribute.
424#[derive(Debug, Clone, Copy)]
425pub struct NameMarker;
426
427/// Specifies a custom name in the database.
428///
429/// By default, table, view, and column names are automatically converted to `snake_case`
430/// from the Rust struct/field name. Use NAME to override this behavior.
431///
432/// ## Column Example
433/// ```rust
434/// # let _ = r####"
435/// // Field `createdAt` becomes `created_at` by default
436/// created_at: DateTime<Utc>,
437///
438/// // Override with custom name:
439/// #[column(name = "creation_timestamp")]
440/// created_at: DateTime<Utc>,
441/// # "####;
442/// ```
443///
444/// ## Table Example
445/// ```rust
446/// # let _ = r####"
447/// // Struct `UserAccount` becomes table `user_account` by default
448/// struct UserAccount { ... }
449///
450/// // Override with custom name:
451/// #[SQLiteTable(name = "user_accounts")]
452/// struct UserAccount { ... }
453/// # "####;
454/// ```
455///
456/// ## View Example
457/// ```rust
458/// # let _ = r####"
459/// #[SQLiteView(NAME = "active_users")]
460/// struct ActiveUsers { ... }
461/// # "####;
462/// ```
463pub const NAME: NameMarker = NameMarker;
464
465//------------------------------------------------------------------------------
466// View Attribute Markers
467//------------------------------------------------------------------------------
468
469/// Marker struct for view attributes.
470#[derive(Debug, Clone, Copy)]
471pub struct ViewMarker;
472
473/// Specifies a view definition SQL string or expression.
474///
475/// ## Examples
476/// ```rust
477/// # let _ = r####"
478/// #[SQLiteView(DEFINITION = "SELECT id, email FROM users")]
479/// struct UserEmails { id: i32, email: String }
480/// # "####;
481/// ```
482///
483/// ```rust
484/// # let _ = r####"
485/// #[SQLiteView(
486/// DEFINITION = {
487/// let builder = drizzle::sqlite::QueryBuilder::new::<Schema>();
488/// let Schema { user } = Schema::new();
489/// builder.select((user.id, user.email)).from(user)
490/// }
491/// )]
492/// struct UserEmails { id: i32, email: String }
493/// # "####;
494/// ```
495pub const DEFINITION: ViewMarker = ViewMarker;
496
497/// Marks the view as existing (skip creation).
498///
499/// ## Example
500/// ```rust
501/// # let _ = r####"
502/// #[SQLiteView(EXISTING)]
503/// struct ExistingView { ... }
504/// # "####;
505/// ```
506pub const EXISTING: ViewMarker = ViewMarker;
507
508//------------------------------------------------------------------------------
509// Table Attribute Markers
510//------------------------------------------------------------------------------
511
512/// Marker struct for table-level attributes.
513#[derive(Debug, Clone, Copy)]
514pub struct TableMarker;
515
516/// Adds a table-level composite foreign key constraint.
517///
518/// ## Example
519/// ```rust
520/// # let _ = r####"
521/// #[SQLiteTable(foreign_key(
522/// columns(tenant_id, user_id),
523/// references(Users, tenant_id, id),
524/// on_delete = "CASCADE"
525/// ))]
526/// struct Posts {
527/// tenant_id: i32,
528/// user_id: i32,
529/// }
530/// # "####;
531/// ```
532///
533/// See: <https://sqlite.org/foreignkeys.html#fk_composite>
534pub const FOREIGN_KEY: TableMarker = TableMarker;
535
536/// Enables STRICT mode for the table.
537///
538/// ## Example
539/// ```rust
540/// # let _ = r####"
541/// #[SQLiteTable(strict)]
542/// struct Users {
543/// #[column(primary)]
544/// id: i32,
545/// name: String,
546/// }
547/// # "####;
548/// ```
549///
550/// # `SQLite` Behavior
551/// - Enforces that values match declared column types exactly
552/// - `INTEGER` columns only accept integers
553/// - `TEXT` columns only accept text
554/// - `REAL` columns only accept floating-point numbers
555/// - `BLOB` columns only accept blobs
556/// - `ANY` type allows any value (only in STRICT tables)
557///
558/// See: <https://sqlite.org/stricttables.html>
559pub const STRICT: TableMarker = TableMarker;
560
561/// Enables WITHOUT ROWID optimization for the table.
562///
563/// ## Example
564/// ```rust
565/// # let _ = r####"
566/// #[SQLiteTable(without_rowid)]
567/// struct KeyValue {
568/// #[column(primary)]
569/// key: String,
570/// value: String,
571/// }
572/// # "####;
573/// ```
574///
575/// Requires an explicit PRIMARY KEY.
576///
577/// See: <https://sqlite.org/withoutrowid.html>
578pub const WITHOUT_ROWID: TableMarker = TableMarker;
579
580//------------------------------------------------------------------------------
581// Column Type Markers
582//------------------------------------------------------------------------------
583
584/// Marker struct for column type attributes.
585#[derive(Debug, Clone, Copy)]
586pub struct TypeMarker;
587
588/// Specifies an INTEGER column type.
589///
590/// ## Example
591/// ```rust
592/// # let _ = r####"
593/// #[column(integer, primary)]
594/// id: i32,
595/// # "####;
596/// ```
597///
598/// INTEGER columns store signed integers up to 8 bytes (64-bit).
599/// `SQLite` uses a variable-length encoding, so small values use less space.
600///
601/// See: <https://sqlite.org/datatype3.html#storage_classes_and_datatypes>
602pub const INTEGER: TypeMarker = TypeMarker;
603
604/// Specifies a TEXT column type.
605///
606/// ## Example
607/// ```rust
608/// # let _ = r####"
609/// #[column(text)]
610/// name: String,
611/// # "####;
612/// ```
613///
614/// TEXT columns store variable-length UTF-8 character strings with no size limit.
615///
616/// See: <https://sqlite.org/datatype3.html#storage_classes_and_datatypes>
617pub const TEXT: TypeMarker = TypeMarker;
618
619/// Specifies a BLOB column type.
620///
621/// ## Example
622/// ```rust
623/// # let _ = r####"
624/// #[column(blob)]
625/// data: Vec<u8>,
626/// # "####;
627/// ```
628///
629/// BLOB columns store binary data exactly as input.
630///
631/// See: <https://sqlite.org/datatype3.html#storage_classes_and_datatypes>
632pub const BLOB: TypeMarker = TypeMarker;
633
634/// Specifies a REAL column type.
635///
636/// ## Example
637/// ```rust
638/// # let _ = r####"
639/// #[column(real)]
640/// price: f64,
641/// # "####;
642/// ```
643///
644/// REAL columns store 8-byte IEEE floating point numbers.
645///
646/// See: <https://sqlite.org/datatype3.html#storage_classes_and_datatypes>
647pub const REAL: TypeMarker = TypeMarker;
648
649/// Specifies a NUMERIC column type.
650///
651/// ## Example
652/// ```rust
653/// # let _ = r####"
654/// #[column(numeric)]
655/// amount: f64,
656/// # "####;
657/// ```
658///
659/// NUMERIC columns store values as INTEGER, REAL, or TEXT depending on the value.
660///
661/// See: <https://sqlite.org/datatype3.html#type_affinity>
662pub const NUMERIC: TypeMarker = TypeMarker;
663
664/// Specifies an ANY column type (STRICT tables only).
665///
666/// ## Example
667/// ```rust
668/// # let _ = r####"
669/// #[SQLiteTable(strict)]
670/// struct Data {
671/// #[column(any)]
672/// value: serde_json::Value,
673/// }
674/// # "####;
675/// ```
676///
677/// ANY allows any type of data. Only valid in STRICT tables.
678///
679/// See: <https://sqlite.org/stricttables.html>
680pub const ANY: TypeMarker = TypeMarker;
681
682/// Specifies a BOOLEAN column (stored as INTEGER 0/1).
683///
684/// ## Example
685/// ```rust
686/// # let _ = r####"
687/// #[column(boolean)]
688/// active: bool,
689/// # "####;
690/// ```
691///
692/// `SQLite` has no native BOOLEAN. Values are stored as INTEGER (0 for false, 1 for true).
693///
694/// See: <https://sqlite.org/datatype3.html#boolean_datatype>
695pub const BOOLEAN: TypeMarker = TypeMarker;