libsql_orm/
compat.rs

1//! Compatibility layer for handling different database backends
2//!
3//! This module provides type aliases and compatibility functions
4//! for working with both libsql and WASM-only environments.
5
6#[cfg(all(feature = "libsql", target_arch = "wasm32"))]
7pub use libsql::{Value as LibsqlValue, Row as LibsqlRow, Error as LibsqlError};
8#[cfg(all(feature = "libsql", target_arch = "wasm32"))]
9pub use libsql::wasm::{Rows as LibsqlRows};
10
11#[cfg(all(feature = "libsql", not(target_arch = "wasm32")))]
12pub use libsql::{Value as LibsqlValue, Row as LibsqlRow, Rows as LibsqlRows, Error as LibsqlError};
13
14#[cfg(not(feature = "libsql"))]
15#[derive(Debug, Clone, PartialEq)]
16pub enum LibsqlValue {
17    Null,
18    Integer(i64),
19    Real(f64),
20    Text(String),
21    Blob(Vec<u8>),
22}
23
24#[cfg(not(feature = "libsql"))]
25pub struct LibsqlRow {
26    data: std::collections::HashMap<String, LibsqlValue>,
27}
28
29#[cfg(not(feature = "libsql"))]
30impl LibsqlRow {
31    pub fn new() -> Self {
32        Self {
33            data: std::collections::HashMap::new(),
34        }
35    }
36
37    pub fn get(&self, index: usize) -> Result<&LibsqlValue, crate::error::Error> {
38        // For WASM implementation, we'll use a simple index-based access
39        // This is a stub - in a real implementation you'd map indices to column names
40        Err(crate::error::Error::Generic("Column access by index not supported in WASM mode".to_string()))
41    }
42
43    pub fn get_value(&self, index: usize) -> Option<LibsqlValue> {
44        // Stub implementation
45        Some(LibsqlValue::Null)
46    }
47
48    pub fn column_count(&self) -> usize {
49        // Stub implementation
50        0
51    }
52
53    pub fn column_name(&self, _index: usize) -> Option<&str> {
54        // Stub implementation
55        None
56    }
57}
58
59#[cfg(not(feature = "libsql"))]
60pub struct LibsqlRows {
61    rows: Vec<LibsqlRow>,
62    index: std::cell::Cell<usize>,
63}
64
65#[cfg(not(feature = "libsql"))]
66impl LibsqlRows {
67    pub fn new(rows: Vec<LibsqlRow>) -> Self {
68        Self {
69            rows,
70            index: std::cell::Cell::new(0),
71        }
72    }
73
74    pub async fn next(&self) -> Result<Option<&LibsqlRow>, crate::error::Error> {
75        let current_index = self.index.get();
76        if current_index < self.rows.len() {
77            self.index.set(current_index + 1);
78            Ok(self.rows.get(current_index))
79        } else {
80            Ok(None)
81        }
82    }
83}
84
85#[cfg(not(feature = "libsql"))]
86pub type LibsqlError = crate::error::Error;
87
88/// Create a null value compatible with both backends
89pub fn null_value() -> LibsqlValue {
90    #[cfg(feature = "libsql")]
91    return libsql::Value::Null;
92
93    #[cfg(not(feature = "libsql"))]
94    return LibsqlValue::Null;
95}
96
97/// Create a text value compatible with both backends
98pub fn text_value(s: String) -> LibsqlValue {
99    #[cfg(feature = "libsql")]
100    return libsql::Value::Text(s);
101
102    #[cfg(not(feature = "libsql"))]
103    return LibsqlValue::Text(s);
104}
105
106/// Create an integer value compatible with both backends
107pub fn integer_value(i: i64) -> LibsqlValue {
108    #[cfg(feature = "libsql")]
109    return libsql::Value::Integer(i);
110
111    #[cfg(not(feature = "libsql"))]
112    return LibsqlValue::Integer(i);
113}
114
115/// Create a real/float value compatible with both backends
116pub fn real_value(f: f64) -> LibsqlValue {
117    #[cfg(feature = "libsql")]
118    return libsql::Value::Real(f);
119
120    #[cfg(not(feature = "libsql"))]
121    return LibsqlValue::Real(f);
122}
123
124/// Create a blob value compatible with both backends
125pub fn blob_value(b: Vec<u8>) -> LibsqlValue {
126    #[cfg(feature = "libsql")]
127    return libsql::Value::Blob(b);
128
129    #[cfg(not(feature = "libsql"))]
130    return LibsqlValue::Blob(b);
131}