sqlite_uuid/
lib.rs

1use sqlite_loadable::prelude::*;
2
3use sqlite_loadable::{api, define_scalar_function, Result};
4
5/// Create a TEXT UUIDv4
6///
7/// # Example
8///
9/// ```sql
10/// SELECT uuid(); -- v4
11/// ```
12pub fn uuid(context: *mut sqlite3_context, _values: &[*mut sqlite3_value]) -> Result<()> {
13    let val = uuid::Uuid::new_v4().to_string();
14    api::result_text(context, val)?;
15    Ok(())
16}
17
18/// Create a TEXT UUIDv7
19///
20/// # Example
21///
22/// ```sql
23/// SELECT uuid_v7(); -- v7
24/// ```
25pub fn uuid_v7(context: *mut sqlite3_context, _values: &[*mut sqlite3_value]) -> Result<()> {
26    let val = uuid::Uuid::now_v7().to_string();
27    api::result_text(context, val)?;
28    Ok(())
29}
30
31/// Create a blob UUIDv4
32///
33/// ## Example
34///
35/// ```sql
36/// SELECT uuid_blob(); -- 4
37/// ```
38pub fn uuid_blob(context: *mut sqlite3_context, _values: &[*mut sqlite3_value]) -> Result<()> {
39    let val = uuid::Uuid::new_v4();
40            api::result_blob(context, val.as_bytes());
41    Ok(())
42}
43
44/// Create a blob UUIDv7
45///
46/// ## Example
47///
48/// ```sql
49/// SELECT uuid_v7_blob(); -- v7
50/// ```
51pub fn uuid_v7_blob(context: *mut sqlite3_context, _values: &[*mut sqlite3_value]) -> Result<()> {
52    let val = uuid::Uuid::now_v7();
53    api::result_blob(context, val.as_bytes());
54    Ok(())
55}
56
57/// Convert a blob to a string representation of a UUID
58///
59/// It doesn't matter if it's a v4 or v7 UUID, it will be converted to a string
60///
61/// ## Example
62///
63/// ```sql
64/// SELECT uuid_from_blob(user_id) from users;
65/// ```
66pub fn uuid_from_blob(context: *mut sqlite3_context, values: &[*mut sqlite3_value]) -> Result<()> {
67    let v = api::value_blob(values.get(0).expect("Failed to get blob value"));
68    let uuid = uuid::Uuid::from_slice(v.as_ref()).expect("Invalid uuid blob");
69    api::result_text(context, uuid.to_string())?;
70    Ok(())
71}
72
73/// Convert a string representation of a UUID to blob
74///
75/// It doesn't matter if it's a v4 or v7 UUID, it will be converted to a string
76///
77/// ## Example
78///
79/// ```sql
80/// SELECT uuid_as_blob(user_id) from users;
81///
82/// --- or for inserting
83/// INSERT INTO events(event_id) VALUES (uuid_as_blob('018d9887-42cd-7115-b1ca-18227ac211b4'));
84/// ```
85pub fn uuid_as_blob(context: *mut sqlite3_context, values: &[*mut sqlite3_value]) -> Result<()> {
86    let v = api::value_text(values.get(0).expect("Failed to get text value"))?;
87    let uuid = uuid::Uuid::parse_str(v).expect("Invalid uuid string");
88    api::result_blob(context, uuid.as_bytes());
89    Ok(())
90}
91
92#[sqlite_entrypoint]
93pub fn sqlite3_sqliteuuid_init(db: *mut sqlite3) -> Result<()> {
94    define_scalar_function(db, "uuid", 0, uuid, FunctionFlags::UTF8)?;
95    define_scalar_function(db, "uuid_v7", 0, uuid_v7, FunctionFlags::UTF8)?;
96    define_scalar_function(db, "uuid_blob", 0, uuid_blob, FunctionFlags::UTF8)?;
97    define_scalar_function(db, "uuid_v7_blob", 0, uuid_v7_blob, FunctionFlags::UTF8)?;
98    define_scalar_function(
99        db,
100        "uuid_from_blob",
101        1,
102        uuid_from_blob,
103        FunctionFlags::UTF8 | FunctionFlags::DETERMINISTIC,
104    )?;
105    define_scalar_function(
106        db,
107        "uuid_as_blob",
108        1,
109        uuid_as_blob,
110        FunctionFlags::UTF8 | FunctionFlags::DETERMINISTIC,
111    )?;
112    Ok(())
113}
114
115#[cfg(test)]
116mod tests {}