Skip to content

Commit

Permalink
quaint: fix compilation errors in sqlite.rs and error.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
aqrln committed Aug 14, 2023
1 parent 930214f commit 2fb2c7b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 107 deletions.
23 changes: 11 additions & 12 deletions quaint/src/connector/sqlite.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod conversion;
mod error;

pub use rusqlite::{params_from_iter, version as sqlite_version};
pub use libsql::{params_from_iter, version as sqlite_version};

use super::IsolationLevel;
use crate::{
Expand All @@ -18,12 +18,13 @@ pub(crate) const DEFAULT_SQLITE_SCHEMA_NAME: &str = "main";

/// The underlying sqlite driver. Only available with the `expose-drivers` Cargo feature.
#[cfg(feature = "expose-drivers")]
pub use rusqlite;
pub use libsql;

/// A connector interface for the SQLite database
#[cfg_attr(feature = "docs", doc(cfg(feature = "sqlite")))]
pub struct Sqlite {
pub(crate) client: Mutex<rusqlite::Connection>,
db: libsql::Database,
pub(crate) client: Mutex<libsql::Connection>,
}

/// Wraps a connection url and exposes the parsing logic used by Quaint,
Expand Down Expand Up @@ -133,15 +134,16 @@ impl TryFrom<&str> for Sqlite {
let params = SqliteParams::try_from(path)?;
let file_path = params.file_path;

let conn = rusqlite::Connection::open(file_path.as_str())?;
let db = libsql::Database::open(file_path);
let conn = db.connect()?;

if let Some(timeout) = params.socket_timeout {
conn.busy_timeout(timeout)?;
};

let client = Mutex::new(conn);

Ok(Sqlite { client })
Ok(Sqlite { db, client })
}
}

Expand All @@ -152,17 +154,14 @@ impl Sqlite {

/// Open a new SQLite database in memory.
pub fn new_in_memory() -> crate::Result<Sqlite> {
let client = rusqlite::Connection::open_in_memory()?;

Ok(Sqlite {
client: Mutex::new(client),
})
// TODO(libsql): Connection::open_in_memory
Self::new(":memory:")
}

/// The underlying rusqlite::Connection. Only available with the `expose-drivers` Cargo
/// feature. This is a lower level API when you need to get into database specific features.
#[cfg(feature = "expose-drivers")]
pub fn connection(&self) -> &Mutex<rusqlite::Connection> {
pub fn connection(&self) -> &Mutex<libsql::Connection> {
&self.client
}
}
Expand Down Expand Up @@ -230,7 +229,7 @@ impl Queryable for Sqlite {
}

async fn version(&self) -> crate::Result<Option<String>> {
Ok(Some(rusqlite::version().into()))
Ok(Some(libsql::version().into()))
}

fn is_healthy(&self) -> bool {
Expand Down
5 changes: 1 addition & 4 deletions quaint/src/connector/sqlite/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ use crate::{
error::{Error, ErrorKind},
};

use rusqlite::{
types::{Null, ToSql, ToSqlOutput, ValueRef},
Column, Error as RusqlError, Row as SqliteRow, Rows as SqliteRows,
};
use libsql::{Column, Error as RusqlError, Null, Row as SqliteRow, Rows as SqliteRows, ToSql, ToSqlOutput, ValueRef};

#[cfg(feature = "chrono")]
use chrono::TimeZone;
Expand Down
125 changes: 34 additions & 91 deletions quaint/src/connector/sqlite/error.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
use crate::error::*;
use rusqlite::ffi;
use rusqlite::types::FromSqlError;
use libsql::ffi;
// use libsql::types::FromSqlError;

impl From<rusqlite::Error> for Error {
fn from(e: rusqlite::Error) -> Error {
impl From<libsql::Error> for Error {
fn from(e: libsql::Error) -> Error {
match e {
rusqlite::Error::ToSqlConversionFailure(error) => match error.downcast::<Error>() {
Ok(error) => *error,
Err(error) => {
let mut builder = Error::builder(ErrorKind::QueryError(error));
// libsql::Error::ToSqlConversionFailure(error) => match error.downcast::<Error>() {
// Ok(error) => *error,
// Err(error) => {
// let mut builder = Error::builder(ErrorKind::QueryError(error));

builder.set_original_message("Could not interpret parameters in an SQLite query.");
// builder.set_original_message("Could not interpret parameters in an SQLite query.");

builder.build()
}
},
rusqlite::Error::InvalidQuery => {
// builder.build()
// }
// },

libsql::Error::InvalidQuery => {
let mut builder = Error::builder(ErrorKind::QueryError(e.into()));

builder.set_original_message(
Expand All @@ -24,22 +25,17 @@ impl From<rusqlite::Error> for Error {

builder.build()
}
rusqlite::Error::ExecuteReturnedResults => {

libsql::Error::ExecuteReturnedResults => {
let mut builder = Error::builder(ErrorKind::QueryError(e.into()));
builder.set_original_message("Execute returned results, which is not allowed in SQLite.");

builder.build()
}

rusqlite::Error::QueryReturnedNoRows => Error::builder(ErrorKind::NotFound).build(),
libsql::Error::QueryReturnedNoRows => Error::builder(ErrorKind::NotFound).build(),

rusqlite::Error::SqliteFailure(
ffi::Error {
code: ffi::ErrorCode::ConstraintViolation,
extended_code: 2067,
},
Some(description),
) => {
libsql::Error::LibError(2067, description) => {
let constraint = description
.split(": ")
.nth(1)
Expand All @@ -57,13 +53,7 @@ impl From<rusqlite::Error> for Error {
builder.build()
}

rusqlite::Error::SqliteFailure(
ffi::Error {
code: ffi::ErrorCode::ConstraintViolation,
extended_code: 1555,
},
Some(description),
) => {
libsql::Error::LibError(1555, description) => {
let constraint = description
.split(": ")
.nth(1)
Expand All @@ -81,13 +71,7 @@ impl From<rusqlite::Error> for Error {
builder.build()
}

rusqlite::Error::SqliteFailure(
ffi::Error {
code: ffi::ErrorCode::ConstraintViolation,
extended_code: 1299,
},
Some(description),
) => {
libsql::Error::LibError(1299, description) => {
let constraint = description
.split(": ")
.nth(1)
Expand All @@ -105,13 +89,7 @@ impl From<rusqlite::Error> for Error {
builder.build()
}

rusqlite::Error::SqliteFailure(
ffi::Error {
code: ffi::ErrorCode::ConstraintViolation,
extended_code: 787,
},
Some(description),
) => {
libsql::Error::LibError(787, description) => {
let mut builder = Error::builder(ErrorKind::ForeignKeyConstraintViolation {
constraint: DatabaseConstraint::ForeignKey,
});
Expand All @@ -122,13 +100,7 @@ impl From<rusqlite::Error> for Error {
builder.build()
}

rusqlite::Error::SqliteFailure(
ffi::Error {
code: ffi::ErrorCode::ConstraintViolation,
extended_code: 1811,
},
Some(description),
) => {
libsql::Error::LibError(1811, description) => {
let mut builder = Error::builder(ErrorKind::ForeignKeyConstraintViolation {
constraint: DatabaseConstraint::ForeignKey,
});
Expand All @@ -139,13 +111,9 @@ impl From<rusqlite::Error> for Error {
builder.build()
}

rusqlite::Error::SqliteFailure(
ffi::Error {
code: ffi::ErrorCode::DatabaseBusy,
extended_code,
},
description,
) => {
// TODO(libsql): exposing both primary and extended_code and representing primary codes
// as a Rust enum for easy matching.
libsql::Error::LibError(extended_code, description) if extended_code & 0xff == ffi::SQLITE_BUSY => {
let mut builder = Error::builder(ErrorKind::SocketTimeout);
builder.set_original_code(format!("{extended_code}"));

Expand All @@ -156,8 +124,8 @@ impl From<rusqlite::Error> for Error {
builder.build()
}

rusqlite::Error::SqliteFailure(ffi::Error { extended_code, .. }, ref description) => match description {
Some(d) if d.starts_with("no such table") => {
libsql::Error::LibError(extended_code, description) => match description {
d if d.starts_with("no such table") => {
let table = d.split(": ").last().into();
let kind = ErrorKind::TableDoesNotExist { table };

Expand All @@ -167,7 +135,7 @@ impl From<rusqlite::Error> for Error {

builder.build()
}
Some(d) if d.contains("has no column named") => {
d if d.contains("has no column named") => {
let column = d.split(" has no column named ").last().into();
let kind = ErrorKind::ColumnNotFound { column };

Expand All @@ -177,7 +145,7 @@ impl From<rusqlite::Error> for Error {

builder.build()
}
Some(d) if d.starts_with("no such column: ") => {
d if d.starts_with("no such column: ") => {
let column = d.split("no such column: ").last().into();
let kind = ErrorKind::ColumnNotFound { column };

Expand All @@ -200,38 +168,13 @@ impl From<rusqlite::Error> for Error {
}
},

rusqlite::Error::SqlInputError {
error: ffi::Error { extended_code, .. },
ref msg,
..
} => match msg {
d if d.starts_with("no such column: ") => {
let column = d.split("no such column: ").last().into();
let kind = ErrorKind::ColumnNotFound { column };

let mut builder = Error::builder(kind);
builder.set_original_code(extended_code.to_string());
builder.set_original_message(d);

builder.build()
}
_ => {
let description = msg.clone();
let mut builder = Error::builder(ErrorKind::QueryError(e.into()));
builder.set_original_code(extended_code.to_string());
builder.set_original_message(description);

builder.build()
}
},

e => Error::builder(ErrorKind::QueryError(e.into())).build(),
}
}
}

impl From<FromSqlError> for Error {
fn from(e: FromSqlError) -> Error {
Error::builder(ErrorKind::ColumnReadFailure(e.into())).build()
}
}
// impl From<FromSqlError> for Error {
// fn from(e: FromSqlError) -> Error {
// Error::builder(ErrorKind::ColumnReadFailure(e.into())).build()
// }
// }

0 comments on commit 2fb2c7b

Please sign in to comment.