Skip to content

Commit bf0e5d0

Browse files
committed
Move LibSqlConnection from spin-sqlite to spin-sqlite-libsql
Signed-off-by: Caleb Schoepp <[email protected]>
1 parent 6f010fa commit bf0e5d0

File tree

4 files changed

+66
-60
lines changed

4 files changed

+66
-60
lines changed

Cargo.lock

Lines changed: 6 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/sqlite-libsql/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ async-trait = "0.1.68"
1111
# libsqlite3-sys as used by spin-sqlite-inproc.
1212
libsql = { version = "0.3.2", features = ["remote"], default-features = false }
1313
rusqlite = { version = "0.29.0", features = ["bundled"] }
14+
spin-factor-sqlite = { path = "../factor-sqlite" }
1415
spin-world = { path = "../world" }
1516
sqlparser = "0.34"
1617
tokio = { version = "1", features = ["full"] }

crates/sqlite-libsql/src/lib.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,63 @@
1+
use anyhow::Context;
2+
use async_trait::async_trait;
3+
use spin_factor_sqlite::Connection;
4+
use spin_world::v2::sqlite as v2;
15
use spin_world::v2::sqlite::{self, RowResult};
6+
use tokio::sync::OnceCell;
27
use tracing::{instrument, Level};
38

9+
/// A wrapper around a libSQL connection that implements the [`Connection`] trait.
10+
pub struct LibSqlConnection {
11+
url: String,
12+
token: String,
13+
// Since the libSQL client can only be created asynchronously, we wait until
14+
// we're in the `Connection` implementation to create. Since we only want to do
15+
// this once, we use a `OnceCell` to store it.
16+
inner: OnceCell<LibsqlClient>,
17+
}
18+
19+
impl LibSqlConnection {
20+
pub fn new(url: String, token: String) -> Self {
21+
Self {
22+
url,
23+
token,
24+
inner: OnceCell::new(),
25+
}
26+
}
27+
28+
pub async fn get_client(&self) -> Result<&LibsqlClient, v2::Error> {
29+
self.inner
30+
.get_or_try_init(|| async {
31+
LibsqlClient::create(self.url.clone(), self.token.clone())
32+
.await
33+
.context("failed to create SQLite client")
34+
})
35+
.await
36+
.map_err(|_| v2::Error::InvalidConnection)
37+
}
38+
}
39+
40+
#[async_trait]
41+
impl Connection for LibSqlConnection {
42+
async fn query(
43+
&self,
44+
query: &str,
45+
parameters: Vec<v2::Value>,
46+
) -> Result<v2::QueryResult, v2::Error> {
47+
let client = self.get_client().await?;
48+
client.query(query, parameters).await
49+
}
50+
51+
async fn execute_batch(&self, statements: &str) -> anyhow::Result<()> {
52+
let client = self.get_client().await?;
53+
client.execute_batch(statements).await
54+
}
55+
56+
fn summary(&self) -> Option<String> {
57+
Some(format!("libSQL at {}", self.url))
58+
}
59+
}
60+
461
#[derive(Clone)]
562
pub struct LibsqlClient {
663
inner: libsql::Connection,

crates/sqlite/src/lib.rs

Lines changed: 2 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,14 @@ use std::{
55
sync::Arc,
66
};
77

8-
use async_trait::async_trait;
98
use serde::Deserialize;
10-
use spin_factor_sqlite::{Connection, ConnectionCreator, DefaultLabelResolver};
9+
use spin_factor_sqlite::{ConnectionCreator, DefaultLabelResolver};
1110
use spin_factors::{
1211
anyhow::{self, Context as _},
1312
runtime_config::toml::GetTomlValue,
1413
};
1514
use spin_sqlite_inproc::InProcDatabaseLocation;
16-
use spin_world::v2::sqlite as v2;
17-
use tokio::sync::OnceCell;
15+
use spin_sqlite_libsql::LibSqlConnection;
1816

1917
/// Spin's default resolution of runtime configuration for SQLite databases.
2018
///
@@ -121,58 +119,6 @@ impl DefaultLabelResolver for RuntimeConfigResolver {
121119

122120
const DEFAULT_SQLITE_DB_FILENAME: &str = "sqlite_db.db";
123121

124-
/// A wrapper around a libSQL connection that implements the [`Connection`] trait.
125-
struct LibSqlConnection {
126-
url: String,
127-
token: String,
128-
// Since the libSQL client can only be created asynchronously, we wait until
129-
// we're in the `Connection` implementation to create. Since we only want to do
130-
// this once, we use a `OnceCell` to store it.
131-
inner: OnceCell<spin_sqlite_libsql::LibsqlClient>,
132-
}
133-
134-
impl LibSqlConnection {
135-
fn new(url: String, token: String) -> Self {
136-
Self {
137-
url,
138-
token,
139-
inner: OnceCell::new(),
140-
}
141-
}
142-
143-
async fn get_client(&self) -> Result<&spin_sqlite_libsql::LibsqlClient, v2::Error> {
144-
self.inner
145-
.get_or_try_init(|| async {
146-
spin_sqlite_libsql::LibsqlClient::create(self.url.clone(), self.token.clone())
147-
.await
148-
.context("failed to create SQLite client")
149-
})
150-
.await
151-
.map_err(|_| v2::Error::InvalidConnection)
152-
}
153-
}
154-
155-
#[async_trait]
156-
impl Connection for LibSqlConnection {
157-
async fn query(
158-
&self,
159-
query: &str,
160-
parameters: Vec<v2::Value>,
161-
) -> Result<v2::QueryResult, v2::Error> {
162-
let client = self.get_client().await?;
163-
client.query(query, parameters).await
164-
}
165-
166-
async fn execute_batch(&self, statements: &str) -> anyhow::Result<()> {
167-
let client = self.get_client().await?;
168-
client.execute_batch(statements).await
169-
}
170-
171-
fn summary(&self) -> Option<String> {
172-
Some(format!("libSQL at {}", self.url))
173-
}
174-
}
175-
176122
/// Configuration for a local SQLite database.
177123
#[derive(Clone, Debug, Deserialize)]
178124
#[serde(deny_unknown_fields)]

0 commit comments

Comments
 (0)