Rust SQLite-WASM extension for UUIDv4 (Random) & UUIDv7 (Time-ordered) generation.
Powered by the uuid crate and built for sqlite-wasm-rs.
The crate is no_std and compiles to wasm32-unknown-unknown.
uuid(): Returns a new random Version 4 UUID as a 36-character string.uuid_str(X): Parses X (blob or text) and returns a canonical 36-char string.uuid_blob(X): Converts X to a 16-byte blob, or generates a new one if no X.uuid7(): Returns a new Version 7 UUID as a 36-character string.uuid7_blob(): Returns a new Version 7 UUID as a 16-byte BLOB. If called with 1 argument, converts the input UUID (TEXT or BLOB format) to a 16-byte BLOB.
For instance, you can now set the DEFAULT value of a TEXT column to uuid() and of a BLOB column to uuid_blob() to have UUIDs automatically generated upon insertion.
CREATE TABLE so_many_uuids (
id_text TEXT PRIMARY KEY DEFAULT (uuid()),
id_blob BLOB PRIMARY KEY DEFAULT (uuid_blob()),
idv7_text TEXT DEFAULT (uuid7()),
idv7_blob BLOB DEFAULT (uuid7_blob())
);Add the dependency to your Cargo.toml:
[dependencies]
sqlite-wasm-uuid-rs = "0.1"Then, depending on which library you are using to interface with SQLite-WASM, register the extension and use the functions as shown below. Please be mindful that the following examples are not executed as part of the CI tests because the different libraries have different sqlite dependencies which would conflict with each other. Instead, complete working examples are provided in the test-rusqlite and test-diesel directories.
use rusqlite::Connection;
// Register the extension (unsafe because it affects global SQLite state)
unsafe {
sqlite_wasm_uuid_rs::register().expect("failed to register");
}
let conn = Connection::open_in_memory().unwrap();
// Generate a random UUIDv4 string
let uuid_str: String = conn.query_row("SELECT uuid()", [], |r| r.get(0)).unwrap();
// Generate a random UUIDv4 blob
let uuid_blob: Vec<u8> = conn.query_row("SELECT uuid_blob()", [], |r| r.get(0)).unwrap();See test-rusqlite for a complete CI-tested example.
Do note that if you are using diesel you can avoid using this extension altogether by simply using declare_sql_function to map the Rust functions you need. Nevertheless, if you want to use the extension, here's how to do it:
// Register the extension
unsafe {
sqlite_wasm_uuid_rs::register().expect("failed to register");
}
// Use raw SQL or `sql_query`
diesel::sql_query("SELECT uuid()").execute(&mut conn)?;
// Or use the functions in your schema definitions (requires custom SQL types)
// See test-diesel for the full boilerplate setup.See test-diesel for a complete CI-tested example.
Here instead for completeness is how you could implement the UUID functions yourself in Diesel without using this extension:
#[declare_sql_function]
extern "SQL" {
/// Generates a UUID v4
fn uuidv4() -> Binary;
/// Generates a UUID v7
fn uuidv7() -> Binary;
}
/// Returns a UUID v4 as a byte vector
fn uuidv4_impl() -> Vec<u8> {
Uuid::new_v4().as_bytes().to_vec()
}
/// Returns a UUID v7 as a byte vector, using the UTC timestamp.
fn uuidv7_impl() -> Vec<u8> {
let utc_now = chrono::Utc::now();
let seconds = utc_now.timestamp() as u64;
let subsec_nanos = utc_now.timestamp_subsec_nanos();
let counter = 0;
let usable_counter_bits = 12;
let timestamp =
uuid::Timestamp::from_unix_time(seconds, subsec_nanos, counter, usable_counter_bits);
Uuid::new_v7(timestamp).as_bytes().to_vec()
}
fn establish_connection() -> SqliteConnection {
let connection =
SqliteConnection::establish(":memory:").expect("Error connecting to in-memory SQLite");
uuidv4_utils::register_impl(&connection, uuidv4_impl).expect("Failed to register uuidv4");
uuidv7_utils::register_impl(&connection, uuidv7_impl).expect("Failed to register uuidv7");
connection
}To run the tests (including the usage examples which are mirrored in the test suite), use wasm-pack:
# Run tests in Headless Firefox
wasm-pack test --firefox --headless
# Or in Headless Chrome
wasm-pack test --chrome --headlessNote: Standard
cargo testdoes not work for this crate as it targetswasm32-unknown-unknownand requires a browser environment provided bywasm-pack.