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
//! The per-dialect seam for the API token store.
//!
//! The store is one implementation. Everything that genuinely differs between
//! PostgreSQL, SQLite, and MySQL 8 -- the statement text, the placeholder
//! style, the spelling of "now", and the storage representation of a
//! timestamp -- lives behind this module, and nothing else in
//! [`crate::tokens`] mentions a driver by name.
//!
//! This mirrors [`crate::auth::session_store`]'s and [`crate::jobs`]'s seams
//! rather than sharing code with them. The three are twenty lines of
//! near-identical plumbing, and a generic seam parameterised over table name,
//! history table, and lock would couple subsystems that have no reason to
//! change together.
use ;
use ApiTokenError;
/// The SQLx database the store speaks. Chosen by the `db-*` features; the
/// mutual-exclusion check lives in [`crate::database`].
pub type TokenDb = crateDriver;
/// The connection pool the store runs over -- the application's own pool.
pub type TokenPool = cratePool;
/// How a timestamp is stored in this dialect.
///
/// PostgreSQL and MySQL have real timestamp types and SQLx binds
/// `DateTime<Utc>` straight into them. SQLite has no timestamp type: a value
/// bound as text would have to be compared as text, and text comparison of
/// timestamps is only correct while every writer agrees on the format down to
/// the digit. Epoch milliseconds are compared as integers, which is correct
/// no matter who wrote the row.
pub type StoredTime = ;
/// How a timestamp is stored in this dialect. See the PostgreSQL/MySQL
/// variant of this alias for why SQLite differs.
pub type StoredTime = i64;
/// Convert an instant into this dialect's storage representation.
pub
/// Convert an instant into this dialect's storage representation.
///
/// SQLite stores epoch milliseconds, so sub-millisecond precision is dropped.
/// A token expiry is a wall-clock deadline hours or months away; a
/// millisecond either side of it is not a distinction the store is asked to
/// keep.
pub
/// Read a timestamp back out of this dialect's storage representation.
///
/// # Errors
///
/// Never fails on this dialect; the signature matches SQLite's so the store
/// has one code path.
pub
/// Read a timestamp back out of this dialect's storage representation.
///
/// # Errors
///
/// Returns [`ApiTokenError::Expiry`] when the stored millisecond count is not
/// a time `chrono` can represent, which means the row was written by
/// something other than this store.
pub
pub use sql;
pub use sql;
pub use sql;