Skip to content

Commit

Permalink
v0.5.5
Browse files Browse the repository at this point in the history
Stop being so fancy with generics
  • Loading branch information
Colonial-Dev committed Oct 10, 2023
1 parent 4d3139f commit bd4b5b5
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 77 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ members = [
]

[workspace.package]
version = "0.5.4"
version = "0.5.5"
authors = ["Colonial"]
edition = "2021"
license = "MIT OR Apache-2.0"
Expand Down
8 changes: 1 addition & 7 deletions exemplar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,9 @@ keywords.workspace = true
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[features]
r2d2 = ["dep:r2d2", "dep:r2d2_sqlite"]

[dependencies]
exemplar_proc_macro = { version = "0.5.4" }
exemplar_proc_macro = { version = "0.5.5" }
rusqlite = "0.29.0"

r2d2 = { version = "0.8.10", optional = true }
r2d2_sqlite = {version = "0.22.0", optional = true }

[dev-dependencies]
anyhow = "1.0.75"
47 changes: 5 additions & 42 deletions exemplar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@ mod macros;

use std::ops::Deref;

use rusqlite::Connection;
use rusqlite::Result;
use rusqlite::Row;
use rusqlite::ToSql;
use rusqlite::Transaction;

use rusqlite::types::{
ToSqlOutput,
Expand Down Expand Up @@ -121,20 +119,18 @@ pub trait Model {
/// # Performance
/// This method uses [`prepare_cached`](rusqlite::Connection::prepare_cached) to create the insertion SQL statement,
/// so any calls after the first with the same connection and `self` type should be significantly faster.
fn insert<C>(&self, conn: &C) -> Result<()>
fn insert(&self, conn: &::rusqlite::Connection) -> Result<()>
where
Self: Sized,
C: Connector;

Self: Sized;

/// Attempt to insert `self` into the database behind the provided connection, using the provided [conflict resolution strategy](OnConflict).
///
/// # Performance
/// This method uses [`prepare_cached`](rusqlite::Connection::prepare_cached) to create the insertion SQL statement,
/// so any calls after the first with the same connection and `self` type should be significantly faster.
fn insert_or<C>(&self, conn: &C, strategy: OnConflict) -> Result<()>
fn insert_or(&self, conn: &::rusqlite::Connection, strategy: OnConflict) -> Result<()>
where
Self: Sized,
C: Connector;
Self: Sized;

/// Generate a slice of named [`Parameters`] from an instance of `self`.
///
Expand Down Expand Up @@ -163,39 +159,6 @@ pub trait Model {
Self: Sized;
}

/// Trait for abstracting over possible connection types.
///
/// This trait is implemented for [`Connection`] and [`Transaction`](rusqlite::Transaction)
pub trait Connector {
fn get(&self) -> &Connection;
}

impl Connector for Connection {
#[inline(always)]
fn get(&self) -> &Connection {
self
}
}

impl Connector for Transaction<'_> {
#[inline(always)]
fn get(&self) -> &Connection {
self
}
}

#[cfg(feature = "r2d2")]
use r2d2::PooledConnection;
#[cfg(feature = "r2d2")]
use r2d2_sqlite::SqliteConnectionManager as Sqlite;
#[cfg(feature = "r2d2")]
impl Connector for PooledConnection<Sqlite> {
#[inline(always)]
fn get(&self) -> &Connection {
self.deref()
}
}

/// Possible conflict resolution strategies when using [`Model::insert_or`].
///
/// The default setting (used by [`Model::insert`]) is [`Abort`](OnConflict::Abort).
Expand Down
50 changes: 23 additions & 27 deletions exemplar_proc_macro/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,26 +62,24 @@ pub fn inserts(derivee: &Derivee) -> (QuoteStream, QuoteStream) {

let insert = quote! {
#[inline]
fn insert<C>(&self, conn: &C) -> ::rusqlite::Result<()>
fn insert(&self, conn: &::rusqlite::Connection) -> ::rusqlite::Result<()>
where
Self: ::std::marker::Sized,
C: ::exemplar::Connector
Self: ::std::marker::Sized
{
self.insert_or(conn, ::exemplar::OnConflict::Abort)
}
};

let insert_or = quote! {
#[inline]
fn insert_or<C>(&self, conn: &C, strategy: ::exemplar::OnConflict) -> ::rusqlite::Result<()>
fn insert_or(&self, conn: &::rusqlite::Connection, strategy: ::exemplar::OnConflict) -> ::rusqlite::Result<()>
where
Self: ::std::marker::Sized,
C: ::exemplar::Connector
Self: ::std::marker::Sized
{
use ::exemplar::OnConflict::*;

let exec = |sql: &str| -> ::rusqlite::Result<()> {
let mut stmt = conn.get().prepare_cached(sql)?;
let mut stmt = conn.prepare_cached(sql)?;

let params = [
#((#col_names, #field_idents as &dyn ::rusqlite::ToSql)),*
Expand Down Expand Up @@ -195,8 +193,8 @@ pub fn check_test(derivee: &Derivee) -> QuoteStream {
return QuoteStream::new()
};

let module = derivee.name.to_string().to_lowercase();
let module = format_ident!("{}_exemplar_check", module);
let func = derivee.name.to_string().to_lowercase();
let func = format_ident!("{}_exemplar_check", func);

let table = &derivee.table;
let columns = derivee.col_names();
Expand All @@ -205,33 +203,31 @@ pub fn check_test(derivee: &Derivee) -> QuoteStream {
// Hack to prevent clippy::items_after_test_module from firing
#[cfg(not(not(test)))]
#[automatically_derived]
mod #module {
#[test]
fn #func() {
use ::rusqlite::Connection;

#[test]
fn schema_matches() {
let schema = include_str!(#path);
let schema = include_str!(#path);

let conn = Connection::open_in_memory()
.expect("In-memory DB connection should open successfully.");
let conn = Connection::open_in_memory()
.expect("In-memory DB connection should open successfully.");

conn.execute_batch(schema)
.expect("Failed to apply provided schema to check DB.");
conn.execute_batch(schema)
.expect("Failed to apply provided schema to check DB.");

let mut names = String::new();
let mut names = String::new();

conn.pragma(None, "table_info", #table, |row| {
let name = row.get::<_, String>("name")
.expect("Failed to get name for table row.");
conn.pragma(None, "table_info", #table, |row| {
let name = row.get::<_, String>("name")
.expect("Failed to get name for table row.");

names += &name;
names += "\n";
names += &name;
names += "\n";

Ok(())
}).expect("Failed to query table_info pragma.");
Ok(())
}).expect("Failed to query table_info pragma.");

#(assert!(names.contains(#columns)));*
}
#(assert!(names.contains(#columns)));*
}
}
}

0 comments on commit bd4b5b5

Please sign in to comment.