Skip to content

Commit

Permalink
Merge pull request #2 from Cosmian/master
Browse files Browse the repository at this point in the history
be able to use a parse a string containing sql queries
  • Loading branch information
manute authored Apr 19, 2022
2 parents 27c1e2d + 9fe511a commit 77d69ab
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 54 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rawsql"
version = "0.1.0"
version = "0.1.1"
authors = ["Manuel Alonso <[email protected]>"]
license = "MIT"
description = "A rust library for reusing SQL"
Expand All @@ -16,4 +16,4 @@ path = "src/lib.rs"
doctest = false

[dev-dependencies]
postgres = "0.10"
postgres = "0.19.2"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ You can integrate rawsql into your project through the [releases on crates.io](h
```toml
# Cargo.toml
[dependencies]
rawsql = "0.1.0"
rawsql = "0.1.1"
```

## Overview
Expand Down Expand Up @@ -51,7 +51,7 @@ fn main() {
let queries = Loader::get_queries_from("examples/postgre.sql").unwrap().queries;

//Insert query
let qìnsert = queries.get("insert-person").unwrap();
let qinsert = queries.get("insert-person").unwrap();

println!("{}", qinsert);

Expand Down
18 changes: 9 additions & 9 deletions examples/posgtre.rs → examples/postgre.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
extern crate rawsql;
extern crate postgres;
extern crate rawsql;

use postgres::{Client, NoTls};
use rawsql::Loader;
use postgres::{Connection, SslMode};

struct Person {
id: i32,
name: String,
data: Option<Vec<u8>>,
}


fn main() {
let conn = Connection::connect("postgres://postgres:local@localhost", &SslMode::None).unwrap();
let mut conn = Client::connect("postgres://postgres:local@localhost", NoTls).unwrap();

let queries = Loader::get_queries_from("examples/postgre.sql").unwrap().queries;
let queries = Loader::get_queries_from("examples/postgre.sql").unwrap();

// Drop table
conn.execute(queries.get("drop-table-person").unwrap(), &[]).unwrap();
conn.execute(queries.get("drop-table-person").unwrap(), &[])
.unwrap();

// Create table
conn.execute(queries.get("create-table-person").unwrap(), &[]).unwrap();
conn.execute(queries.get("create-table-person").unwrap(), &[])
.unwrap();

let me = Person {
id: 0,
Expand All @@ -33,8 +34,7 @@ fn main() {
.unwrap();

// Select
let stmt = conn.prepare(queries.get("select-all").unwrap()).unwrap();
for row in stmt.query(&[]).unwrap() {
for row in conn.query(queries.get("select-all").unwrap(), &[]).unwrap() {
let person = Person {
id: row.get(0),
name: row.get(1),
Expand Down
94 changes: 53 additions & 41 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
//! fn main() {
//! let conn = Connection::connect("postgres://postgres:local@localhost", &SslMode::None).unwrap();
//!
//! let queries = Loader::get_queries_from("examples/postgre.sql").unwrap().queries;
//! let queries = Loader::read_queries_from("examples/postgre.sql").unwrap().queries;
//!
//! //Drop table
//! conn.execute(queries.get("drop-table-person").unwrap(), &[]).unwrap();
Expand Down Expand Up @@ -68,13 +68,15 @@
//! }
//!
//! ```
#![doc(html_root_url="https://manute.github.io/rawsql")]
#![doc(html_root_url = "https://manute.github.io/rawsql")]
#![warn(missing_docs)]

use std::io::{Read, Result};
use std::fs::File;
use std::collections::HashMap;

use std::{
collections::HashMap,
fs::File,
io::{Read, Result},
ops::Deref,
};

struct Parser {
name: String,
Expand All @@ -90,21 +92,22 @@ impl Parser {
}

fn tag_name(&mut self, line: &str) {
let tag = line.replace("--", "")
.replace("name", "")
.replace(":", "")
.trim_left()
.to_string();
self.name = tag.to_string();
let tag = line
.replace("--", "")
.replace("name", "")
.replace(':', "")
.trim_start()
.to_string();
self.name = tag;
self.query = "".to_string();
}

fn build_query(&mut self, line: &str) {
let q = line.trim_left();
let q = line.trim_start();
if self.query.is_empty() {
self.query = q.to_string();
} else {
self.query = self.query.to_string() + " " + &q;
self.query = self.query.to_string() + " " + q
}
}

Expand All @@ -113,7 +116,7 @@ impl Parser {
}

fn is_finishing_query(&mut self, line: &str) -> bool {
!self.query.is_empty() && line.ends_with(";")
!self.query.is_empty() && line.ends_with(';')
}

fn is_tagged_name(&mut self, line: &str) -> bool {
Expand All @@ -122,21 +125,24 @@ impl Parser {
}

/// All queries info
pub struct Loader {
/// Queries as key(name) and value(query)
pub queries: HashMap<String, String>,
}
/// Queries as key(name) and value(query)
pub struct Loader(pub HashMap<String, String>);

impl Loader {
///Given a path of file retrieve all the queries.
pub fn get_queries_from(path: &str) -> Result<Loader> {
impl Deref for Loader {
type Target = HashMap<String, String>;

let data_file = try!(read_file(path));
fn deref(&self) -> &Self::Target {
&self.0
}
}

impl Loader {
///Given a string content retrieve all the queries.
pub fn get_queries_from(content: &str) -> Result<Loader> {
let mut parser = Parser::init();
let mut queries: HashMap<String, String> = HashMap::new();

for line in data_file.lines() {
for line in content.lines() {
if line.is_empty() {
continue;
}
Expand All @@ -152,68 +158,74 @@ impl Loader {
parser = Parser::init()
}
}
Ok(Loader { queries: queries })
Ok(Loader(queries))
}

///Given a path of file retrieve all the queries.
pub fn read_queries_from(path: &str) -> Result<Loader> {
let data_file = read_file(path)?;
Loader::get_queries_from(&data_file)
}
}

/// Read file data into string from path
fn read_file(path: &str) -> Result<String> {
let mut file = try!(File::open(&path));
let mut file = File::open(&path)?;
let mut data_file = String::new();
try!(file.read_to_string(&mut data_file));
file.read_to_string(&mut data_file)?;
Ok(data_file)
}



#[cfg(test)]
mod tests {
use super::*;

#[test]
#[should_panic]
fn it_when_file_not_exists() {
let loaded = Loader::get_queries_from("examples/non_exist.sql");
let loaded = Loader::read_queries_from("examples/non_exist.sql");
match loaded {
Ok(r) => r,
Err(why) => panic!(why),
Err(why) => panic!("{}", why),
};
}

#[test]
fn it_should_parse_queries() {
let loaded = Loader::get_queries_from("examples/example.sql");
let loaded = Loader::read_queries_from("examples/example.sql");

let res = match loaded {
Ok(r) => r,
Err(why) => panic!(why),
Err(why) => panic!("{}", why),
};

let q_simple = match res.queries.get("simple") {
let q_simple = match res.get("simple") {
Some(r) => r,
None => panic!("no result on get query"),
};

assert_eq!(q_simple, "SELECT * FROM table1 u where u.name = ?;");

let q_2_lines = match res.queries.get("two-lines") {
let q_2_lines = match res.get("two-lines") {
Some(r) => r,
None => panic!("no result on get query"),
};

assert_eq!(q_2_lines, "Insert INTO table2 SELECT * FROM table1;");

let q_complex = match res.queries.get("complex") {
let q_complex = match res.get("complex") {
Some(r) => r,
None => panic!("no result on get query"),
};

assert_eq!(q_complex,
"SELECT * FROM Customers c INNER JOIN CustomerAccounts ca ON ca.CustomerID = \
c.CustomerID AND c.State = ? INNER JOIN Accounts a ON ca.AccountID = \
a.AccountID AND a.Status = ?;");
assert_eq!(
q_complex,
"SELECT * FROM Customers c INNER JOIN CustomerAccounts ca ON ca.CustomerID = \
c.CustomerID AND c.State = ? INNER JOIN Accounts a ON ca.AccountID = a.AccountID AND \
a.Status = ?;"
);

let q_psql = match res.queries.get("psql-insert") {
let q_psql = match res.get("psql-insert") {
Some(r) => r,
None => panic!("no result on get query"),
};
Expand Down

0 comments on commit 77d69ab

Please sign in to comment.