Skip to content

Commit

Permalink
Switch from compiler plugin to proc-macro
Browse files Browse the repository at this point in the history
  • Loading branch information
antoyo committed Dec 11, 2017
1 parent 0b30dec commit 7b7b97f
Show file tree
Hide file tree
Showing 106 changed files with 5,208 additions and 4,136 deletions.
49 changes: 27 additions & 22 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
[package]
name = "tql"
version = "0.0.1"
authors = ["Antoni Boucher <[email protected]>"]
description = "ORM as a compiler plugin (runtime library)"
homepage = "http://tql.tuxfamily.org/"
repository = "http://git.tuxfamily.org/tql/tql.git"
license = "GPL-3.0"

[lib]
categories = ["database"]
name = "tql"
doc = true
version = "0.1.0"

[dependencies]
chrono = "0.2"
postgres = { version = "0.10.2", features = ["chrono"] }

[dependencies.postgres]
optional = true
version = "^0.15.1"

[dev-dependencies]
chrono = "0.2"
compiletest_rs = "0.0.11"
handlebars-iron = "0.9.1"
iron = "0.2.6"
persistent = "0.0.8"
postgres = { version = "0.10.2", features = ["chrono"] }
r2d2 = "0.6.1"
r2d2_postgres = "0.9.3"
rustc-serialize = "0.3.16"
tql_macros = "0.0.1"
urlencoded = "0.2.0"
chrono = "^0.4.0"
handlebars-iron = "^0.26.0"
iron = "^0.6.0"
lazy_static = "^1.0.0"
persistent = "^0.4.0"
r2d2 = "^0.8.1"
r2d2_postgres = "^0.14.0"
serde = "^1.0.24"
serde_derive = "^1.0.24"
urlencoded = "^0.6.0"

[dev-dependencies.postgres]
features = ["with-chrono"]
version = "^0.15.1"

[dev-dependencies.tql_macros]
path = "./tql_macros"

[features]
default = ["unstable"]
unstable = ["tql_macros/unstable"]
4 changes: 2 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ SELECT * FROM Table1 WHERE field1 REGEXP BINARY '\^[a-d]'
|
[source, rust]
----
Table1.filter(field1.match(r"\^[a-d]"))
Table1.filter(field1.regex(r"\^[a-d]"))
----

|
Expand All @@ -319,7 +319,7 @@ SELECT * FROM Table1 WHERE field1 REGEXP '\^[a-d]'
|
[source, rust]
----
Table1.filter(field1.imatch(r"\^[a-d]"))
Table1.filter(field1.iregex(r"\^[a-d]"))
----

|
Expand Down
82 changes: 43 additions & 39 deletions examples/chat.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
/*
* Copyright (C) 2015 Boucher, Antoni <[email protected]>
* Copyright (c) 2017 Boucher, Antoni <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#![feature(plugin)]
#![plugin(tql_macros)]
#![feature(proc_macro)]

extern crate chrono;
extern crate handlebars_iron as hbs;
Expand All @@ -25,15 +28,19 @@ extern crate persistent;
extern crate postgres;
extern crate r2d2;
extern crate r2d2_postgres;
extern crate rustc_serialize;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate tql;
#[macro_use]
extern crate tql_macros;
extern crate urlencoded;

use std::collections::BTreeMap;

use chrono::datetime::DateTime;
use chrono::offset::utc::UTC;
use hbs::{HandlebarsEngine, Template};
use chrono::DateTime;
use chrono::offset::Utc;
use hbs::{DirectorySource, HandlebarsEngine, Template};
use iron::{Iron, IronResult, Plugin, status};
use iron::middleware::Chain;
use iron::method::Method;
Expand All @@ -42,11 +49,10 @@ use iron::modifiers::Redirect;
use iron::request::Request;
use iron::response::Response;
use iron::typemap::Key;
use postgres::SslMode;
use r2d2::Pool;
use r2d2_postgres::PostgresConnectionManager;
use rustc_serialize::json::{Json, ToJson};
use r2d2_postgres::{PostgresConnectionManager, TlsMode};
use tql::PrimaryKey;
use tql_macros::sql;
use urlencoded::UrlEncodedBody;

struct AppDb;
Expand All @@ -56,21 +62,14 @@ impl Key for AppDb {
}

// A Message is a table containing a username, a text and an added date.
#[SqlTable]
#[derive(Serialize, SqlTable)]
struct Message {
#[serde(skip)]
id: PrimaryKey,
username: String,
message: String,
date_added: DateTime<UTC>,
}

impl ToJson for Message {
fn to_json(&self) -> Json {
let mut map = BTreeMap::new();
map.insert("username".to_owned(), self.username.to_json());
map.insert("message".to_owned(), self.message.to_json());
map.to_json()
}
#[serde(skip)]
date_added: DateTime<Utc>,
}

fn chat(req: &mut Request) -> IronResult<Response> {
Expand All @@ -88,9 +87,9 @@ fn chat(req: &mut Request) -> IronResult<Response> {

// Insert a new message.
let _ = sql!(Message.insert(
username = username,
message = message,
date_added = UTC::now()
username = &username,
message = &message,
date_added = Utc::now()
));
}
}
Expand All @@ -101,7 +100,7 @@ fn chat(req: &mut Request) -> IronResult<Response> {
// Get the last 10 messages by date.
let messages: Vec<Message> = sql!(Message.sort(-date_added)[..10]);

data.insert("messages".to_owned(), messages.to_json());
data.insert("messages".to_owned(), messages);

resp.set_mut(Template::new("chat", data))
.set_mut(status::Ok);
Expand All @@ -121,13 +120,18 @@ fn main() {

let mut chain = Chain::new(chat);
chain.link(persistent::Read::<AppDb>::both(pool));
chain.link_after(HandlebarsEngine::new("./examples/templates/", ".hbs"));
let mut handlebars = HandlebarsEngine::new();
handlebars.add(Box::new(DirectorySource::new("./examples/templates/", ".hbs")));
// TODO: maybe load?
if let Err(error) = handlebars.reload() {
panic!("{}", error);
}
chain.link_after(handlebars);
println!("Running on http://localhost:3000");
Iron::new(chain).http("localhost:3000").unwrap();
}

fn get_connection_pool() -> Pool<PostgresConnectionManager> {
let manager = r2d2_postgres::PostgresConnectionManager::new("postgres://test:test@localhost/database", SslMode::None).unwrap();
let config = r2d2::Config::builder().pool_size(1).build();
r2d2::Pool::new(config, manager).unwrap()
let manager = r2d2_postgres::PostgresConnectionManager::new("postgres://test:test@localhost/database", TlsMode::None).unwrap();
r2d2::Pool::new(manager).unwrap()
}
1 change: 1 addition & 0 deletions examples/todo-stable/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
13 changes: 13 additions & 0 deletions examples/todo-stable/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
authors = ["Antoni Boucher <[email protected]>"]
name = "todo-stable"
version = "0.1.0"

[dependencies]
chrono = "^0.4.0"
tql = { path = "../..", default-features = false }
tql_macros = { path = "../../tql_macros" }

[dependencies.postgres]
features = ["with-chrono"]
version = "^0.15.1"
155 changes: 155 additions & 0 deletions examples/todo-stable/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* Copyright (c) 2017 Boucher, Antoni <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

extern crate chrono;
extern crate postgres;
#[macro_use]
extern crate tql;
#[macro_use]
extern crate tql_macros;

use std::env;

use chrono::DateTime;
use chrono::offset::Utc;
use postgres::{Connection, TlsMode};
use tql::PrimaryKey;

// A TodoItem is a table containing a text, an added date and a done boolean.
#[derive(SqlTable)]
struct TodoItem {
id: PrimaryKey,
text: String,
date_added: DateTime<Utc>,
done: bool,
}

fn add_todo_item(connection: Connection, text: String) {
// Insert the new item.
let result = sql!(TodoItem.insert(text = &text, date_added = Utc::now(), done = false));
if let Err(err) = result {
println!("Failed to add the item ({})", err);
}
else {
println!("Item added");
}
}

fn delete_todo_item(connection: Connection, id: i32) {
// Delete the item.
let result = sql!(TodoItem.get(id).delete());
if let Err(err) = result {
println!("Failed to delete the item ({})", err);
}
else {
println!("Item deleted");
}
}

fn do_todo_item(connection: Connection, id: i32) {
// Update the item to make it done.
let result = sql!(TodoItem.get(id).update(done = true));
if let Err(err) = result {
println!("Failed to do the item ({})", err);
}
else {
println!("Item done");
}
}

fn get_id(args: &mut env::Args) -> Option<i32> {
if let Some(arg) = args.next() {
if let Ok(id) = arg.parse() {
return Some(id);
}
else {
println!("Please provide a valid id");
}
}
else {
println!("Missing argument: id");
}
None
}

fn list_todo_items(connection: Connection, show_done: bool) {
let items =
if show_done {
// Show the last 10 todo items.
sql!(TodoItem.sort(-date_added)[..10])
}
else {
// Show the last 10 todo items that are not done.
sql!(TodoItem.filter(done == false).sort(-date_added)[..10])
};

for item in items {
let done_text =
if item.done {
"(✓)"
}
else {
""
};
println!("{}. {} {}", item.id, item.text, done_text);
}
}

fn main() {
let connection = get_connection();

// Create the table.
let _ = sql!(TodoItem.create());

let mut args = env::args();
args.next();

let command = args.next().unwrap_or("list".to_owned());
match command.as_ref() {
"add" => {
if let Some(item_text) = args.next() {
add_todo_item(connection, item_text);
}
else {
println!("Missing argument: task");
}
},
"delete" => {
if let Some(id) = get_id(&mut args) {
delete_todo_item(connection, id);
}
},
"do" => {
if let Some(id) = get_id(&mut args) {
do_todo_item(connection, id);
}
},
"list" => {
let show_done = args.next() == Some("--show-done".to_owned());
list_todo_items(connection, show_done);
},
command => println!("Unknown command {}", command),
}
}

fn get_connection() -> Connection {
Connection::connect("postgres://test:test@localhost/database", TlsMode::None).unwrap()
}
Loading

0 comments on commit 7b7b97f

Please sign in to comment.