Skip to main content

valence_backend_sql/
document.rs

1//! Table layout: `(id TEXT PRIMARY KEY, body JSON)`.
2
3use serde_json::{Map, Value};
4
5/// Primary key column name in SQL document tables.
6pub const ID_COLUMN: &str = "id";
7pub const BODY_COLUMN: &str = "body";
8
9/// Edge junction table shared by SQL backends.
10pub const EDGES_TABLE: &str = "valence_edges";
11
12/// DDL for a Valence schemaless table.
13pub fn ensure_table_ddl(table: &str) -> String {
14    format!(
15        "CREATE TABLE IF NOT EXISTS {table} (\
16         {ID_COLUMN} TEXT PRIMARY KEY NOT NULL, \
17         {BODY_COLUMN} TEXT NOT NULL DEFAULT '{{}}')"
18    )
19}
20
21/// DDL for the shared edge junction table.
22pub fn ensure_edges_table_ddl() -> String {
23    format!(
24        "CREATE TABLE IF NOT EXISTS {EDGES_TABLE} (\
25         from_table TEXT NOT NULL, \
26         from_id TEXT NOT NULL, \
27         edge_type TEXT NOT NULL, \
28         to_table TEXT NOT NULL, \
29         to_id TEXT NOT NULL, \
30         PRIMARY KEY (from_table, from_id, edge_type, to_table, to_id))"
31    )
32}
33
34/// Ensure a table exists (caller runs DDL via sqlx).
35pub fn ensure_table(table: &str) -> String {
36    ensure_table_ddl(table)
37}
38
39/// Build a JSON row object from stored body + id.
40pub fn row_from_body(table: &str, id: &str, body: Value) -> Value {
41    let mut obj = match body {
42        Value::Object(map) => map,
43        _ => Map::new(),
44    };
45    obj.insert(
46        "id".into(),
47        Value::Object(Map::from_iter([
48            ("table".into(), Value::String(table.to_string())),
49            ("id".into(), Value::String(id.to_string())),
50        ])),
51    );
52    Value::Object(obj)
53}
54
55/// Merge content fields into body map for insert/update.
56pub fn upsert_body_fields(content: Value) -> Map<String, Value> {
57    match content {
58        Value::Object(map) => map,
59        _ => Map::new(),
60    }
61}