surrealdb_sql/record_id/
key.rs1use std::ops::Bound;
2
3use common::fmt::{EscapeObjectKey, EscapeRidKey, Fmt, QuoteStr};
4use surrealdb_strand::Strand;
5use surrealdb_types::{RecordIdKey as PublicRecordIdKey, SqlFormat, ToSql, write_sql};
6
7use crate::literal::ObjectEntry;
8use crate::{CoverStmts, Expr, RecordIdKeyRangeLit};
9
10#[derive(Clone, Debug, Eq, PartialEq, Hash)]
11#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
12pub enum RecordIdKeyGen {
13 Rand,
14 Ulid,
15 Uuid,
16}
17
18#[derive(Clone, Debug, PartialEq, Eq)]
19#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
20pub enum RecordIdKeyLit {
21 Number(i64),
22 String(Strand),
23 Uuid(uuid::Uuid),
24 Array(Vec<Expr>),
25 Object(Vec<ObjectEntry>),
26 Generate(RecordIdKeyGen),
27 Range(Box<RecordIdKeyRangeLit>),
28}
29
30impl RecordIdKeyLit {
31 pub fn from_record_id_key(key: PublicRecordIdKey) -> Self {
32 match key {
33 PublicRecordIdKey::Number(x) => RecordIdKeyLit::Number(x),
34 PublicRecordIdKey::String(x) => RecordIdKeyLit::String(x.into()),
35 PublicRecordIdKey::Uuid(x) => RecordIdKeyLit::Uuid(x.into_inner()),
36 PublicRecordIdKey::Array(x) => {
37 RecordIdKeyLit::Array(x.into_iter().map(Expr::from_public_value).collect())
38 }
39 PublicRecordIdKey::Object(x) => RecordIdKeyLit::Object(
40 x.into_iter()
41 .map(|(k, v)| ObjectEntry {
42 key: k.into(),
43 value: Expr::from_public_value(v),
44 })
45 .collect(),
46 ),
47 PublicRecordIdKey::Range(x) => {
48 let range = x.into_inner();
49 RecordIdKeyLit::Range(Box::new(RecordIdKeyRangeLit {
50 start: match range.0 {
51 Bound::Included(x) => Bound::Included(Self::from_record_id_key(x)),
52 Bound::Excluded(x) => Bound::Excluded(Self::from_record_id_key(x)),
53 Bound::Unbounded => Bound::Unbounded,
54 },
55 end: match range.1 {
56 Bound::Included(x) => Bound::Included(Self::from_record_id_key(x)),
57 Bound::Excluded(x) => Bound::Excluded(Self::from_record_id_key(x)),
58 Bound::Unbounded => Bound::Unbounded,
59 },
60 }))
61 }
62 }
63 }
64}
65
66impl ToSql for RecordIdKeyLit {
67 fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
68 match self {
69 Self::Number(v) => write_sql!(f, fmt, "{v}"),
70 Self::String(v) => EscapeRidKey(v).fmt_sql(f, fmt),
71 Self::Uuid(v) => write_sql!(f, fmt, "u{}", QuoteStr(&v.to_string())),
72 Self::Array(v) => {
73 f.push('[');
74 if !v.is_empty() {
75 let fmt = fmt.increment();
76 write_sql!(f, fmt, "{}", Fmt::pretty_comma_separated(v.iter().map(CoverStmts)));
77 }
78 f.push(']');
79 }
80 Self::Object(v) => {
81 if fmt.is_pretty() {
82 f.push('{');
83 } else {
84 f.push_str("{ ");
85 }
86 if !v.is_empty() {
87 let fmt = fmt.increment();
88 write_sql!(
89 f,
90 fmt,
91 "{}",
92 Fmt::pretty_comma_separated(v.iter().map(|args| Fmt::new(
93 args,
94 |entry, f, fmt| write_sql!(
95 f,
96 fmt,
97 "{}: {}",
98 EscapeObjectKey(&entry.key),
99 CoverStmts(&entry.value)
100 )
101 )),)
102 );
103 }
104 if fmt.is_pretty() {
105 f.push('}');
106 } else {
107 f.push_str(" }");
108 }
109 }
110 Self::Generate(v) => match v {
111 RecordIdKeyGen::Rand => f.push_str("rand()"),
112 RecordIdKeyGen::Ulid => f.push_str("ulid()"),
113 RecordIdKeyGen::Uuid => f.push_str("uuid()"),
114 },
115 Self::Range(v) => v.fmt_sql(f, fmt),
116 }
117 }
118}