1use std::time::Duration;
8
9use serde::{Deserialize, Serialize};
10
11use crate::rows::{Parameter, Rows};
12
13pub const STORAGE_CONTEXT_VERSION: u16 = 1;
15
16#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
23pub struct StorageContext {
24 version: u16,
25 payload: serde_json::Value,
26}
27
28impl StorageContext {
29 pub fn new(
31 version: u16,
32 payload: serde_json::Value,
33 ) -> Result<Self, crate::error::DactylError> {
34 let context = Self { version, payload };
35 context.validate()?;
36 Ok(context)
37 }
38
39 pub fn version(&self) -> u16 {
40 self.version
41 }
42
43 pub fn payload(&self) -> &serde_json::Value {
45 &self.payload
46 }
47
48 pub(crate) fn validate(&self) -> Result<(), crate::error::DactylError> {
49 if self.version == 0 {
50 return Err(crate::error::DactylError::adapter_with_code(
51 crate::error::AdapterErrorKind::Protocol,
52 "invalid_context",
53 "storage context version must be non-zero",
54 ));
55 }
56 if !self.payload.is_object() {
57 return Err(crate::error::DactylError::adapter_with_code(
58 crate::error::AdapterErrorKind::Protocol,
59 "invalid_context",
60 "storage context payload must be a JSON object",
61 ));
62 }
63 Ok(())
64 }
65}
66
67#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
69#[serde(rename_all = "snake_case")]
70pub enum AccessMode {
71 #[default]
72 ReadWrite,
73 ReadOnly,
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
79#[serde(rename_all = "snake_case")]
80pub enum OperationKind {
81 Read,
82 Write,
83 Schema,
84}
85
86#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
88pub struct Operation {
89 pub(crate) kind: OperationKind,
90 pub(crate) sql: String,
91 #[serde(default)]
92 pub(crate) params: Vec<Parameter>,
93}
94
95impl Operation {
96 pub fn read(sql: impl Into<String>, params: impl Into<Vec<Parameter>>) -> Self {
97 Self {
98 kind: OperationKind::Read,
99 sql: sql.into(),
100 params: params.into(),
101 }
102 }
103
104 pub fn write(sql: impl Into<String>, params: impl Into<Vec<Parameter>>) -> Self {
105 Self {
106 kind: OperationKind::Write,
107 sql: sql.into(),
108 params: params.into(),
109 }
110 }
111
112 pub fn schema(sql: impl Into<String>, params: impl Into<Vec<Parameter>>) -> Self {
113 Self {
114 kind: OperationKind::Schema,
115 sql: sql.into(),
116 params: params.into(),
117 }
118 }
119
120 pub fn kind(&self) -> OperationKind {
121 self.kind
122 }
123
124 pub fn sql(&self) -> &str {
125 &self.sql
126 }
127
128 pub fn params(&self) -> &[Parameter] {
129 &self.params
130 }
131}
132
133#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
135#[serde(untagged)]
136pub enum GeneratedKey {
137 Integer(i64),
138 Text(String),
139}
140
141#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
143pub struct WriteResult {
144 pub affected_rows: u64,
145 #[serde(default)]
146 pub generated_keys: Vec<GeneratedKey>,
147}
148
149impl WriteResult {
150 pub fn generated_key(&self) -> Option<&GeneratedKey> {
151 self.generated_keys.first()
152 }
153}
154
155#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
157pub enum OperationResult {
158 Rows(Rows),
159 Write(WriteResult),
160}
161
162#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
164pub struct AtomicResult {
165 pub results: Vec<OperationResult>,
166}
167
168#[derive(Debug, Clone, Copy, PartialEq, Eq)]
170pub struct OpenOptions {
171 pub access_mode: AccessMode,
172 pub lock_timeout: Duration,
173}
174
175impl Default for OpenOptions {
176 fn default() -> Self {
177 Self {
178 access_mode: AccessMode::ReadWrite,
179 lock_timeout: Duration::from_millis(250),
180 }
181 }
182}