Browse Source

Initial commit

master
Colin Reeder 1 year ago
commit
774dd22702
6 changed files with 97 additions and 0 deletions
  1. +3
    -0
      .gitignore
  2. +12
    -0
      Cargo.toml
  3. +5
    -0
      examples/parse.rs
  4. +14
    -0
      macros/Cargo.toml
  5. +48
    -0
      macros/src/lib.rs
  6. +15
    -0
      src/lib.rs

+ 3
- 0
.gitignore View File

@@ -0,0 +1,3 @@
/target
**/*.rs.bk
Cargo.lock

+ 12
- 0
Cargo.toml View File

@@ -0,0 +1,12 @@
[workspace]
members = ["macros"]

[package]
name = "prequel"
version = "0.1.0"
authors = ["Colin Reeder <colin@vpzom.click>"]
edition = "2018"

[dependencies]
prequel-macros = { path = "./macros" }
proc-macro-hack = "0.5.8"

+ 5
- 0
examples/parse.rs View File

@@ -0,0 +1,5 @@
use prequel::postgres as sql;

fn main() {
let query = sql!("SELECT column FROM table");
}

+ 14
- 0
macros/Cargo.toml View File

@@ -0,0 +1,14 @@
[package]
name = "prequel-macros"
version = "0.1.0"
authors = ["Colin Reeder <colin@vpzom.click>"]
edition = "2018"

[lib]
proc-macro = true

[dependencies]
sqlparser = "0.4.0"
syn = "0.15.39"
quote = "0.6.13"
proc-macro-hack = "0.5.8"

+ 48
- 0
macros/src/lib.rs View File

@@ -0,0 +1,48 @@
#![recursion_limit="128"]

extern crate proc_macro;

fn base(tokens: proc_macro::TokenStream, dialect: &sqlparser::dialect::Dialect) -> proc_macro::TokenStream {
let literal = syn::parse_macro_input!(tokens as syn::LitStr);
let query_str = literal.value();
let query = sqlparser::parser::Parser::parse_sql(dialect, query_str.clone()).expect("Failed to parse SQL");

if query.len() != 1 {
panic!("Expected exactly one SQL statement");
}

match query.into_iter().next().unwrap() {
sqlparser::ast::Statement::Query(query) => {
(quote::quote! {
{
struct __PrequelResponse<B: ::prequel::Backend>(B::OutputRow);
impl<B: ::prequel::Backend> __PrequelResponse<B> {}

struct __PrequelQuery<B: ::prequel::Backend> {
query: &'static str,
_d: ::std::marker::PhantomData<B>,
}

impl<B: ::prequel::Backend> ::prequel::SelectQuery for __PrequelQuery<B> {
type Response = __PrequelResponse<B>;
fn query_text(&self) -> &'static str {
&self.query
}
}

__PrequelQuery {
query: #query_str,
_d: ::std::marker::PhantomData,
}
}
}).into()
},
_ => panic!("Unsupported query type"),
}
}

#[proc_macro_hack::proc_macro_hack]
pub fn postgres(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
const DIALECT: sqlparser::dialect::PostgreSqlDialect = sqlparser::dialect::PostgreSqlDialect {};
base(tokens, &DIALECT)
}

+ 15
- 0
src/lib.rs View File

@@ -0,0 +1,15 @@
#[proc_macro_hack::proc_macro_hack]
pub use prequel_macros::postgres;

pub trait BackendOutputRow {
fn get<T>(index: usize) -> T;
}

pub trait Backend {
type OutputRow: BackendOutputRow;
}

pub trait SelectQuery {
type Response;
fn query_text(&self) -> &'static str;
}

Loading…
Cancel
Save