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