PostgreSQL extension for generating Xata-style xata_id unique identifiers (rec_<20_chars>) using Rust and pgrx.
1use pgrx::prelude::*;
2
3::pgrx::pg_module_magic!(name, version);
4
5fn generate_xata_id() -> String {
6 format!("rec_{}", xid::new())
7}
8
9#[pg_extern]
10fn xata_id() -> String {
11 generate_xata_id()
12}
13
14#[cfg(any(test, feature = "pg_test"))]
15#[pg_schema]
16mod tests {
17 use pgrx::prelude::*;
18
19 #[pg_test]
20 fn test_xata_id_length_and_prefix() {
21 let id = crate::generate_xata_id();
22 assert_eq!(id.len(), 24, "ID length should be 24");
23 assert!(id.starts_with("rec_"), "ID should start with 'rec_'");
24 }
25
26 #[pg_test]
27 fn test_xata_id_valid_characters() {
28 let id = crate::generate_xata_id();
29 let random_part = &id[4..];
30 for c in random_part.chars() {
31 assert!(
32 c.is_ascii_lowercase() || c.is_ascii_digit(),
33 "Invalid character in random part: {}",
34 c
35 );
36 }
37 }
38
39 #[pg_test]
40 fn test_xata_id_uniqueness() {
41 let id1 = crate::generate_xata_id();
42 let id2 = crate::generate_xata_id();
43 assert_ne!(id1, id2, "IDs should be unique");
44 }
45
46 #[pg_test]
47 fn test_xata_id_multiple() {
48 for _ in 0..100 {
49 let id = crate::generate_xata_id();
50 assert_eq!(id.len(), 24, "ID length should be 24");
51 assert!(id.starts_with("rec_"), "ID should start with 'rec_'");
52 for c in id[4..].chars() {
53 assert!(
54 c.is_ascii_lowercase() || c.is_ascii_digit(),
55 "Invalid character: {}",
56 c
57 );
58 }
59 }
60 }
61}
62
63#[cfg(test)]
64pub mod pg_test {
65 pub fn setup(_options: Vec<&str>) {
66 // No initialization needed
67 }
68
69 pub fn postgresql_conf_options() -> Vec<&'static str> {
70 vec![]
71 }
72}