drizzle-sqlite 0.4.0

A type-safe SQL query builder for Rust
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
//! Names accepted inside `#[SQLiteTable(...)]`, `#[column(...)]`,
//! `#[SQLiteView(...)]` and `#[SQLiteIndex(...)]`.
//!
//! The macros read these attributes by name, case-insensitively
//! (`primary` and `PRIMARY` are the same). The constants here exist so your
//! editor can show their documentation on hover; the macros point each
//! attribute at its constant, so import them through the prelude.
//!
//! # Examples
//!
//! ```rust
//! # mod drizzle {
//! #     pub mod core { pub use drizzle_core::*; }
//! #     pub mod error { pub use drizzle_core::error::*; }
//! #     pub mod types { pub use drizzle_types::*; }
//! #     pub mod migrations { pub use drizzle_migrations::*; }
//! #     pub use drizzle_types::Dialect;
//! #     pub use drizzle_types as ddl;
//! #     pub mod sqlite {
//! #         pub use drizzle_sqlite::{*, attrs::*};
//! #         #[cfg(feature = "rusqlite")]
//! #         pub mod rusqlite { pub use ::rusqlite::{Error, Result, Row, types}; }
//! #         #[cfg(feature = "libsql")]
//! #         pub mod libsql { pub use ::libsql::{Row, Value}; }
//! #         #[cfg(feature = "turso")]
//! #         pub mod turso { pub use ::turso::{Error, IntoValue, Result, Row, Value}; }
//! #         pub mod prelude {
//! #             pub use drizzle_macros::{SQLiteTable, SQLiteSchema};
//! #             pub use drizzle_sqlite::{*, attrs::*};
//! #             pub use drizzle_core::*;
//! #         }
//! #     }
//! # }
//! use drizzle::sqlite::prelude::*;
//!
//! #[SQLiteTable(
//!     name = "users",
//!     strict,
//!     unique(columns(email, tenant_id)),
//!     check(name = "users_score_check", expr = "score >= 0")
//! )]
//! struct User {
//!     #[column(primary, autoincrement)]
//!     id: i32,
//!     #[column(unique, collate = NOCASE)]
//!     email: String,
//!     tenant_id: i32,
//!     #[column(default = 0)]
//!     score: i32,
//! }
//!
//! #[SQLiteTable(name = "posts")]
//! struct Post {
//!     #[column(primary)]
//!     id: i32,
//!     #[column(references = User::id, on_delete = CASCADE)]
//!     author_id: i32,
//!     title: String,
//! }
//! ```
//!
//! The per-attribute examples below are fragments of such a definition.

/// The type of the column constraint and option constants.
#[derive(Debug, Clone, Copy)]
pub struct ColumnMarker;

//------------------------------------------------------------------------------
// Primary Key Constraints
//------------------------------------------------------------------------------

/// Marks this column as the PRIMARY KEY.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(primary)]
/// id: i32,
/// # "####;
/// ```
///
/// See: <https://sqlite.org/lang_createtable.html#primkeyconst>
pub const PRIMARY: ColumnMarker = ColumnMarker;

/// Alias for [`PRIMARY`].
pub const PRIMARY_KEY: ColumnMarker = ColumnMarker;

/// Adds `AUTOINCREMENT` to an `INTEGER PRIMARY KEY` column, so rowids of
/// deleted rows are never reused.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(primary, autoincrement)]
/// id: i32,
/// # "####;
/// ```
///
/// See: <https://sqlite.org/autoinc.html>
pub const AUTOINCREMENT: ColumnMarker = ColumnMarker;

//------------------------------------------------------------------------------
// Index Attributes
//------------------------------------------------------------------------------

/// The type of the index option constants.
#[derive(Debug, Clone, Copy)]
pub struct IndexMarker;

/// Makes an index partial: only rows matching the SQL predicate are indexed.
///
/// The predicate is raw SQL. Write database column names; renaming a Rust
/// field does not rewrite it.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[SQLiteIndex(where = "deleted_at IS NULL")]
/// struct ActiveUsersEmailIdx(Users::email);
/// # "####;
/// ```
///
/// See: <https://sqlite.org/partialindex.html>
pub const WHERE: IndexMarker = IndexMarker;

//------------------------------------------------------------------------------
// Uniqueness Constraints
//------------------------------------------------------------------------------

/// Adds a UNIQUE constraint to a column, table, or index.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(unique)]
/// email: String,
///
/// #[SQLiteTable(unique(columns(email, tenant_id)))]
/// struct Users {
///     email: String,
///     tenant_id: i32,
/// }
///
/// #[SQLiteIndex(unique)]
/// struct UsersEmailIdx(Users::email);
/// # "####;
/// ```
///
/// See: <https://sqlite.org/lang_createtable.html#unique_constraints>
pub const UNIQUE: ColumnMarker = ColumnMarker;

//------------------------------------------------------------------------------
// Serialization Modes
//------------------------------------------------------------------------------

/// Stores the field as JSON text, serialized with serde.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(json)]
/// metadata: UserMetadata,
/// # "####;
/// ```
///
/// Requires the `serde` feature. The field type must implement `Serialize`
/// and `Deserialize`. Values are bound through `json(?)`.
pub const JSON: ColumnMarker = ColumnMarker;

/// Stores a `#[derive(SQLiteEnum)]` enum.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(enum)]
/// role: Role,
///
/// #[column(integer, enum)]
/// status: Status,
/// # "####;
/// ```
///
/// The enum must derive `SQLiteEnum`, and that derive decides the storage:
/// INTEGER when a variant has an explicit discriminant or the enum has an
/// integer `#[repr]`, TEXT (variant names) otherwise. An explicit `integer` or
/// `text` marker must agree with it, or the table fails to compile.
pub const ENUM: ColumnMarker = ColumnMarker;

//------------------------------------------------------------------------------
// Default Value Parameters
//------------------------------------------------------------------------------

/// Generates a value in Rust for each insert that leaves the column unset.
///
/// The function takes no arguments and returns the field type.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(default_fn = Uuid::new_v4)]
/// id: Uuid,
/// # "####;
/// ```
///
/// Unlike [`DEFAULT`], this does not add a database `DEFAULT` clause.
pub const DEFAULT_FN: ColumnMarker = ColumnMarker;

/// Adds a `DEFAULT` clause to the column.
///
/// Takes a literal, `CURRENT_TIME`, `CURRENT_DATE`, `CURRENT_TIMESTAMP`, or
/// an SQL function call. Expressions other than literals and the `CURRENT_*`
/// keywords are wrapped in parentheses, as SQLite requires.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(default = 0)]
/// count: i32,
///
/// #[column(default = "guest")]
/// role: String,
///
/// #[column(default = CURRENT_TIMESTAMP)]
/// created_at: String,
///
/// #[column(default = strftime("%s", "now"))]
/// created_at_unix: i64,
/// # "####;
/// ```
///
/// For application-generated values such as UUIDs, use [`DEFAULT_FN`] instead.
///
/// See: <https://sqlite.org/lang_createtable.html#the_default_clause>
pub const DEFAULT: ColumnMarker = ColumnMarker;

/// Makes the column a generated column: `stored` (computed on write) or
/// `virtual` (computed on read), from a raw SQL expression.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(generated(stored, "length(name)"))]
/// stored_name_len: i32,
///
/// #[column(generated(virtual, "length(name)"))]
/// virtual_name_len: i32,
/// # "####;
/// ```
///
/// See: <https://sqlite.org/gencol.html>
pub const GENERATED: ColumnMarker = ColumnMarker;

/// Adds a CHECK constraint to a column (`check = "..."`) or a table
/// (`check(name = "...", expr = "...")`). The expression is raw SQL.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(check = "score >= 0")]
/// score: i32,
///
/// #[SQLiteTable(check(name = "score_range", expr = "score >= 0 AND score <= 100"))]
/// struct Scores {
///     score: i32,
/// }
/// # "####;
/// ```
///
/// See: <https://sqlite.org/lang_createtable.html#check_constraints>
pub const CHECK: ColumnMarker = ColumnMarker;

/// Adds a foreign key that references a column of another table.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(references = User::id)]
/// user_id: i32,
/// # "####;
/// ```
///
/// With the `query` feature this also generates relation accessors: a
/// forward one on this table, named after the column without its `_id` suffix
/// (`user_id` gives `.user()`), and a reverse one on the referenced table
/// (see [`RELATION`]).
///
/// See: <https://sqlite.org/foreignkeys.html>
pub const REFERENCES: ColumnMarker = ColumnMarker;

/// Names the accessor that loads this table's rows from the referenced table
/// (the reverse relation).
///
/// By default it is the plural of this struct's name (`posts` for a `Post`
/// table), or the singular when this column alone is unique, which loads an
/// `Option` (`profile` for a `Profile` table). A column named for a role
/// rather than the table it references starts the name with the role:
/// `author_id` gives `users.author_posts()`, while `user_id` gives
/// `users.posts()`. The name depends on this column alone, so `relation` is needed
/// only to choose another one.
///
/// The forward relation (on this table) is unchanged; only the reverse
/// accessor on the referenced table is renamed.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// // Users get `.authored()` instead of `.author_posts()`
/// #[column(references = User::id, relation = "authored")]
/// author_id: i32,
/// # "####;
/// ```
///
/// Requires a `references` attribute on the same column.
pub const RELATION: ColumnMarker = ColumnMarker;

/// Names the many-to-many accessor the referenced table gets through this
/// link table.
///
/// A table is a link table when it has exactly two foreign keys and its rows
/// are that pair: the pair is the primary key or a `UNIQUE` constraint, or
/// the table has no other column besides a single-column primary key, and
/// neither key is unique on its own. Each referenced table then gets an
/// accessor to the other one, named after the other column: `post_id` and
/// `tag_id` in `PostTags` give `posts.tags()` and `tags.posts()`. A link whose
/// name adds to what it links appends it, so `PostLikes` gives
/// `users.posts_via_likes()` and never clashes with another link.
///
/// `many_to_many` chooses another name, and makes any table with two foreign keys a
/// link table.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// // users.liked_posts() instead of users.posts_via_likes()
/// #[column(references = User::id, many_to_many = "liked_posts")]
/// user_id: i32,
/// # "####;
/// ```
///
/// Requires a `references` attribute on the same column.
pub const MANY_TO_MANY: ColumnMarker = ColumnMarker;

/// Sets the `ON DELETE` action of a foreign key.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(references = User::id, on_delete = CASCADE)]
/// user_id: i32,
/// # "####;
/// ```
///
/// ## Supported Actions
/// - `CASCADE`: Delete rows that reference the deleted row
/// - `SET_NULL`: Set the column to NULL when referenced row is deleted
/// - `SET_DEFAULT`: Set the column to its default value
/// - `RESTRICT`: Prevent deletion if referenced
/// - `NO_ACTION`: Like `RESTRICT`, but checked at the end of the statement
///   (the default)
///
/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
pub const ON_DELETE: ColumnMarker = ColumnMarker;

/// Sets the `ON UPDATE` action of a foreign key.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(references = User::id, on_update = CASCADE)]
/// user_id: i32,
/// # "####;
/// ```
///
/// ## Supported Actions
/// - `CASCADE`: Update referencing rows when referenced row is updated
/// - `SET_NULL`: Set the column to NULL when referenced row is updated
/// - `SET_DEFAULT`: Set the column to its default value
/// - `RESTRICT`: Prevent update if referenced
/// - `NO_ACTION`: Like `RESTRICT`, but checked at the end of the statement
///   (the default)
///
/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
pub const ON_UPDATE: ColumnMarker = ColumnMarker;

//------------------------------------------------------------------------------
// Referential Action Values
//------------------------------------------------------------------------------

/// The type of the referential action constants ([`CASCADE`], [`SET_NULL`], ...).
pub type ReferentialAction = ColumnMarker;

/// `CASCADE`: delete or update the referencing rows too.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(references = User::id, on_delete = CASCADE)]
/// user_id: i32,
/// # "####;
/// ```
///
/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
pub const CASCADE: ColumnMarker = ColumnMarker;

/// `SET NULL`: set the referencing columns to NULL.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(references = User::id, on_delete = SET_NULL)]
/// user_id: Option<i32>,
/// # "####;
/// ```
///
/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
pub const SET_NULL: ColumnMarker = ColumnMarker;

/// `SET DEFAULT`: set the referencing columns to their defaults.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(references = User::id, on_delete = SET_DEFAULT, default = 0)]
/// user_id: i32,
/// # "####;
/// ```
///
/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
pub const SET_DEFAULT: ColumnMarker = ColumnMarker;

/// `RESTRICT`: reject the delete or update while rows reference it.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(references = User::id, on_delete = RESTRICT)]
/// user_id: i32,
/// # "####;
/// ```
///
/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
pub const RESTRICT: ColumnMarker = ColumnMarker;

/// `NO ACTION`: like `RESTRICT`, but checked at the end of the statement.
/// The default.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(references = User::id, on_delete = NO_ACTION)]
/// user_id: i32,
/// # "####;
/// ```
///
/// See: <https://sqlite.org/foreignkeys.html#fk_actions>
pub const NO_ACTION: ColumnMarker = ColumnMarker;

//------------------------------------------------------------------------------
// Collation Markers
//------------------------------------------------------------------------------

/// Sets the collation of a text column.
///
/// Takes `BINARY`, `NOCASE`, `RTRIM`, or the name of a collation the
/// application registers, as a string.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(COLLATE = NOCASE)]
/// name: String,
///
/// // String form for custom registered collations:
/// #[column(COLLATE = "my_collation")]
/// label: String,
/// # "####;
/// ```
///
/// See: <https://sqlite.org/datatype3.html#collation>
pub const COLLATE: ColumnMarker = ColumnMarker;

/// BINARY collation: bytewise comparison of operands. The default for `BLOB`
/// columns and any column without an explicit collation.
pub const BINARY: ColumnMarker = ColumnMarker;

/// NOCASE collation: compares ASCII letters case-insensitively.
pub const NOCASE: ColumnMarker = ColumnMarker;

/// RTRIM collation: like `BINARY` but trailing spaces are ignored when
/// comparing.
pub const RTRIM: ColumnMarker = ColumnMarker;

//------------------------------------------------------------------------------
// Name Marker (shared by column and table attributes)
//------------------------------------------------------------------------------

/// The type of the [`NAME`] constant.
#[derive(Debug, Clone, Copy)]
pub struct NameMarker;

/// Sets the name used in the database.
///
/// By default, table, view and column names are the `snake_case` form of the
/// Rust struct or field name. `name` overrides that.
///
/// ## Column Example
/// ```rust
/// # let _ = r####"
/// // Column `created_at` by default; stored as `creation_timestamp` here.
/// #[column(name = "creation_timestamp")]
/// created_at: DateTime<Utc>,
/// # "####;
/// ```
///
/// ## Table Example
/// ```rust
/// # let _ = r####"
/// // Struct `UserAccount` becomes table `user_account` by default
/// struct UserAccount { ... }
///
/// // Override with custom name:
/// #[SQLiteTable(name = "user_accounts")]
/// struct UserAccount { ... }
/// # "####;
/// ```
///
/// ## View Example
/// ```rust
/// # let _ = r####"
/// #[SQLiteView(NAME = "active_users")]
/// struct ActiveUsers { ... }
/// # "####;
/// ```
pub const NAME: NameMarker = NameMarker;

//------------------------------------------------------------------------------
// View Attribute Markers
//------------------------------------------------------------------------------

/// The type of the view option constants.
#[derive(Debug, Clone, Copy)]
pub struct ViewMarker;

/// The view's query: an SQL string, or a block that returns a query
/// builder.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[SQLiteView(DEFINITION = "SELECT id, email FROM users")]
/// struct UserEmails { id: i32, email: String }
/// # "####;
/// ```
///
/// ```rust
/// # let _ = r####"
/// #[SQLiteView(
///     DEFINITION = {
///         let builder = drizzle::sqlite::QueryBuilder::new::<Schema>();
///         let Schema { user } = Schema::new();
///         builder.select((user.id, user.email)).from(user)
///     }
/// )]
/// struct UserEmails { id: i32, email: String }
/// # "####;
/// ```
pub const DEFINITION: ViewMarker = ViewMarker;

/// Marks the view as already existing, so migrations do not create it.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[SQLiteView(EXISTING)]
/// struct ExistingView { ... }
/// # "####;
/// ```
pub const EXISTING: ViewMarker = ViewMarker;

//------------------------------------------------------------------------------
// Table Attribute Markers
//------------------------------------------------------------------------------

/// The type of the table option constants.
#[derive(Debug, Clone, Copy)]
pub struct TableMarker;

/// Adds a table-level foreign key, for keys over several columns.
///
/// `on_delete` and `on_update` take the action as a string here.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[SQLiteTable(foreign_key(
///     columns(tenant_id, user_id),
///     references(Users, tenant_id, id),
///     on_delete = "CASCADE"
/// ))]
/// struct Posts {
///     tenant_id: i32,
///     user_id: i32,
/// }
/// # "####;
/// ```
///
/// See: <https://sqlite.org/foreignkeys.html#fk_composite>
pub const FOREIGN_KEY: TableMarker = TableMarker;

/// Makes the table `STRICT`, so SQLite rejects values that do not match
/// the declared column types.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[SQLiteTable(strict)]
/// struct Users {
///     #[column(primary)]
///     id: i32,
///     name: String,
/// }
/// # "####;
/// ```
///
/// A STRICT table still converts values losslessly where it can (the text
/// `'1'` into an `INTEGER` column), and only `ANY` columns accept any value.
///
/// See: <https://sqlite.org/stricttables.html>
pub const STRICT: TableMarker = TableMarker;

/// Makes the table `WITHOUT ROWID`, stored as a clustered index on its
/// primary key.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[SQLiteTable(without_rowid)]
/// struct KeyValue {
///     #[column(primary)]
///     key: String,
///     value: String,
/// }
/// # "####;
/// ```
///
/// Requires an explicit PRIMARY KEY.
///
/// See: <https://sqlite.org/withoutrowid.html>
pub const WITHOUT_ROWID: TableMarker = TableMarker;

//------------------------------------------------------------------------------
// Column Type Markers
//------------------------------------------------------------------------------

/// The type of the column type constants.
#[derive(Debug, Clone, Copy)]
pub struct TypeMarker;

/// Sets the column type to `INTEGER`.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(integer, primary)]
/// id: i32,
/// # "####;
/// ```
///
/// INTEGER columns store signed integers up to 8 bytes (64-bit).
/// `SQLite` uses a variable-length encoding, so small values use less space.
///
/// See: <https://sqlite.org/datatype3.html#storage_classes_and_datatypes>
pub const INTEGER: TypeMarker = TypeMarker;

/// Sets the column type to `TEXT`.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(text)]
/// name: String,
/// # "####;
/// ```
///
/// TEXT columns store strings in the database encoding (UTF-8 by default).
///
/// See: <https://sqlite.org/datatype3.html#storage_classes_and_datatypes>
pub const TEXT: TypeMarker = TypeMarker;

/// Sets the column type to `BLOB`.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(blob)]
/// data: Vec<u8>,
/// # "####;
/// ```
///
/// BLOB columns store bytes exactly as given.
///
/// See: <https://sqlite.org/datatype3.html#storage_classes_and_datatypes>
pub const BLOB: TypeMarker = TypeMarker;

/// Sets the column type to `REAL`.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(real)]
/// price: f64,
/// # "####;
/// ```
///
/// REAL columns store 8-byte IEEE 754 floating-point numbers.
///
/// See: <https://sqlite.org/datatype3.html#storage_classes_and_datatypes>
pub const REAL: TypeMarker = TypeMarker;

/// Sets the column type to `NUMERIC`.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(numeric)]
/// amount: f64,
/// # "####;
/// ```
///
/// A NUMERIC column converts text that looks like a number into INTEGER or
/// REAL, and stores other values as given.
///
/// See: <https://sqlite.org/datatype3.html#type_affinity>
pub const NUMERIC: TypeMarker = TypeMarker;

/// Sets the column type to `ANY` (STRICT tables only).
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[SQLiteTable(strict)]
/// struct Data {
///     #[column(any)]
///     value: serde_json::Value,
/// }
/// # "####;
/// ```
///
/// An ANY column stores any value without conversion.
///
/// See: <https://sqlite.org/stricttables.html>
pub const ANY: TypeMarker = TypeMarker;

/// Stores a `bool` as `INTEGER` 0 or 1.
///
/// # Examples
/// ```rust
/// # let _ = r####"
/// #[column(boolean)]
/// active: bool,
/// # "####;
/// ```
///
/// `SQLite` has no native BOOLEAN. Values are stored as INTEGER (0 for false, 1 for true).
///
/// See: <https://sqlite.org/datatype3.html#boolean_datatype>
pub const BOOLEAN: TypeMarker = TypeMarker;