use njord::condition::Condition;
use njord::keys::AutoIncrementPrimaryKey;
use njord::sqlite;
use njord::{column::Column, condition::Value};
use njord_derive::sql;
use std::collections::HashMap;
use std::path::Path;
use crate::{User, UserWithSubQuery};
#[test]
fn open_db() {
let db_relative_path = "./db/open.db";
let db_path = Path::new(&db_relative_path);
let result = sqlite::open(db_path);
assert!(result.is_ok());
}
#[test]
fn insert_row() {
let db_relative_path = "./db/insert.db";
let db_path = Path::new(&db_relative_path);
let mut conn = sqlite::open(db_path);
let table_row: User = User {
id: AutoIncrementPrimaryKey::default(),
username: "mjovanc".to_string(),
email: "mjovanc@icloud.com".to_string(),
address: "Some Random Address 1".to_string(),
};
match conn {
Ok(ref mut c) => {
let result = sqlite::insert(c, vec![table_row]);
assert!(result.is_ok());
}
Err(e) => {
panic!("Failed to INSERT: {:?}", e);
}
}
}
#[test]
fn update() {
let db_relative_path = "./db/insert.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
let columns = vec!["username".to_string()];
let condition = Condition::Eq(
"username".to_string(),
Value::Literal("mjovanc".to_string()),
);
let table_row: User = User {
id: AutoIncrementPrimaryKey::<usize>::new(Some(0)),
username: "mjovanc".to_string(),
email: "mjovanc@icloud.com".to_string(),
address: "Some Random Address 1".to_string(),
};
let mut order = HashMap::new();
order.insert(vec!["id".to_string()], "DESC".to_string());
match conn {
Ok(ref c) => {
let result = sqlite::update(table_row)
.set(columns)
.where_clause(condition)
.order_by(order)
.limit(4)
.offset(0)
.build(c);
println!("{:?}", result);
assert!(result.is_ok());
}
Err(e) => {
panic!("Failed to UPDATE: {:?}", e);
}
}
}
#[test]
fn delete() {
let db_relative_path = "./db/insert.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
let condition = Condition::Eq(
"address".to_string(),
Value::Literal("Some Random Address 1".to_string()),
);
let mut order = HashMap::new();
order.insert(vec!["id".to_string()], "DESC".to_string());
match conn {
Ok(ref c) => {
let result = sqlite::delete()
.from(User::default())
.where_clause(condition)
.order_by(order)
.limit(20)
.offset(0)
.build(c);
println!("{:?}", result);
assert!(result.is_ok());
}
Err(e) => {
panic!("Failed to DELETE: {:?}", e);
}
}
}
#[test]
fn select() {
let db_relative_path = "./db/select.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
let columns = vec![
Column::Text("id".to_string()),
Column::Text("username".to_string()),
Column::Text("email".to_string()),
Column::Text("address".to_string()),
];
let condition = Condition::Eq(
"username".to_string(),
Value::Literal("mjovanc".to_string()),
);
match conn {
Ok(ref c) => {
let result = sqlite::select(columns)
.from(User::default())
.where_clause(condition)
.build(c);
match result {
Ok(r) => assert_eq!(r.len(), 2),
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
#[test]
fn select_distinct() {
let db_relative_path = "./db/select.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
let columns = vec![
Column::Text("id".to_string()),
Column::Text("username".to_string()),
Column::Text("email".to_string()),
Column::Text("address".to_string()),
];
let condition = Condition::Eq(
"username".to_string(),
Value::Literal("mjovanc".to_string()),
);
match conn {
Ok(ref c) => {
let result = sqlite::select(columns)
.from(User::default())
.where_clause(condition)
.distinct()
.build(c);
match result {
Ok(r) => {
assert_eq!(r.len(), 2);
}
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
#[test]
fn select_group_by() {
let db_relative_path = "./db/select.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
let columns = vec![
Column::Text("id".to_string()),
Column::Text("username".to_string()),
Column::Text("email".to_string()),
Column::Text("address".to_string()),
];
let condition = Condition::Eq(
"username".to_string(),
Value::Literal("mjovanc".to_string()),
);
let group_by = vec!["username".to_string(), "email".to_string()];
match conn {
Ok(ref c) => {
let result = sqlite::select(columns)
.from(User::default())
.where_clause(condition)
.group_by(group_by)
.build(c);
match result {
Ok(r) => assert_eq!(r.len(), 1),
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
#[test]
fn select_order_by() {
let db_relative_path = "./db/select.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
let columns = vec![
Column::Text("id".to_string()),
Column::Text("username".to_string()),
Column::Text("email".to_string()),
Column::Text("address".to_string()),
];
let condition = Condition::Eq(
"username".to_string(),
Value::Literal("mjovanc".to_string()),
);
let group_by = vec!["username".to_string(), "email".to_string()];
let mut order_by = HashMap::new();
order_by.insert(vec!["email".to_string()], "ASC".to_string());
match conn {
Ok(ref c) => {
let result = sqlite::select(columns)
.from(User::default())
.where_clause(condition)
.order_by(order_by)
.group_by(group_by)
.build(c);
match result {
Ok(r) => assert_eq!(r.len(), 1),
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
#[test]
fn select_limit_offset() {
let db_relative_path = "./db/select.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
let columns = vec![
Column::Text("id".to_string()),
Column::Text("username".to_string()),
Column::Text("email".to_string()),
Column::Text("address".to_string()),
];
let condition = Condition::Eq(
"username".to_string(),
Value::Literal("mjovanc".to_string()),
);
let group_by = vec!["username".to_string(), "email".to_string()];
let mut order_by = HashMap::new();
order_by.insert(vec!["id".to_string()], "DESC".to_string());
match conn {
Ok(ref c) => {
let result = sqlite::select(columns)
.from(User::default())
.where_clause(condition)
.order_by(order_by)
.group_by(group_by)
.limit(1)
.offset(0)
.build(c);
match result {
Ok(r) => assert_eq!(r.len(), 1),
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
Err(error) => panic!("Failed to SELECT: {:?}", error),
};
}
#[test]
fn select_having() {
let db_relative_path = "./db/select.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
let columns = vec![
Column::Text("id".to_string()),
Column::Text("username".to_string()),
Column::Text("email".to_string()),
Column::Text("address".to_string()),
];
let condition = Condition::Eq(
"username".to_string(),
Value::Literal("mjovanc".to_string()),
);
let group_by = vec!["username".to_string(), "email".to_string()];
let mut order_by = HashMap::new();
order_by.insert(vec!["email".to_string()], "DESC".to_string());
let having_condition = Condition::Gt("id".to_string(), Value::Literal("1".to_string()));
match conn {
Ok(ref c) => {
let result = sqlite::select(columns)
.from(User::default())
.where_clause(condition)
.order_by(order_by)
.group_by(group_by)
.having(having_condition)
.build(c);
match result {
Ok(r) => assert_eq!(r.len(), 1),
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
Err(e) => panic!("Failed to SELECT: {:?}", e),
}
}
#[test]
fn select_except() {
let db_relative_path = "./db/select.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
let columns = vec![
Column::Text("id".to_string()),
Column::Text("username".to_string()),
Column::Text("email".to_string()),
Column::Text("address".to_string()),
];
let condition1 = Condition::Eq(
"username".to_string(),
Value::Literal("mjovanc".to_string()),
);
let condition2 = Condition::Eq(
"username".to_string(),
Value::Literal("otheruser".to_string()),
);
let condition3 = Condition::Eq(
"username".to_string(),
Value::Literal("anotheruser".to_string()),
);
match conn {
Ok(ref c) => {
let query1 = sqlite::select(columns.clone())
.from(User::default())
.where_clause(condition1);
let query2 = sqlite::select(columns.clone())
.from(User::default())
.where_clause(condition2);
let query3 = sqlite::select(columns.clone())
.from(User::default())
.where_clause(condition3);
let result = query1.except(query2).except(query3).build(c);
match result {
Ok(r) => {
assert_eq!(r.len(), 2, "Expected 2 results after EXCEPT clauses.");
}
Err(e) => panic!("Failed to SELECT with EXCEPT: {:?}", e),
};
}
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
#[test]
fn select_union() {
let db_relative_path = "./db/select.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
let columns = vec![
Column::Text("id".to_string()),
Column::Text("username".to_string()),
Column::Text("email".to_string()),
Column::Text("address".to_string()),
];
let condition1 = Condition::Eq("id".to_string(), Value::Literal(42.to_string()));
let condition2 = Condition::Eq("id".to_string(), Value::Literal(43.to_string()));
match conn {
Ok(ref c) => {
let query1 = sqlite::select(columns.clone())
.from(User::default())
.where_clause(condition1);
let query2 = sqlite::select(columns.clone())
.from(User::default())
.where_clause(condition2);
let result = query1.union(query2).build(c);
match result {
Ok(r) => {
assert_eq!(r.len(), 2, "Expected 2 results from the UNION query.");
assert_eq!(
r[0].id,
AutoIncrementPrimaryKey::new(Some(42)),
"First user should be mjovanc."
);
assert_eq!(
r[1].id,
AutoIncrementPrimaryKey::new(Some(43)),
"Second user should be otheruser."
);
}
Err(e) => panic!("Failed to SELECT with UNION: {:?}", e),
};
}
Err(e) => panic!("Failed to SELECT: {:?}", e),
}
}
#[test]
fn select_sub_queries() {
let db_relative_path = "./db/select.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
match conn {
Ok(c) => {
let sub_query = sqlite::select(vec![Column::Text("username".to_string())])
.from(UserWithSubQuery::default());
let columns = vec![
Column::Text("id".to_string()),
Column::Text("username".to_string()),
Column::Text("email".to_string()),
Column::Text("address".to_string()),
Column::SubQuery(Box::new(sub_query), "additional_address".to_string()),
];
let result = sqlite::select(columns)
.from(UserWithSubQuery::default())
.build(&c);
match result {
Ok(r) => {
assert_eq!(r.len(), 2);
assert_eq!(r[0].additional_address, "mjovanc");
}
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
#[test]
fn select_in() {
let db_relative_path = "./db/select.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
let columns = vec![
Column::Text("id".to_string()),
Column::Text("username".to_string()),
Column::Text("email".to_string()),
Column::Text("address".to_string()),
];
let condition = Condition::And(
Box::new(Condition::In(
"username".to_string(),
vec![
Value::Literal("mjovanc".to_string()),
Value::Literal("otheruser".to_string()),
],
)),
Box::new(Condition::NotIn(
"username".to_string(),
vec![Value::Literal("chasewillden".to_string())],
)),
);
match conn {
Ok(ref c) => {
let result = sqlite::select(columns)
.from(User::default())
.where_clause(condition)
.build(c);
match result {
Ok(r) => assert_eq!(r.len(), 2),
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
#[test]
fn sql_bang() {
let user_id = 1;
let query = sql! {
SELECT *
FROM user
WHERE id = {user_id}
};
assert_eq!(query.to_string(), "SELECT * FROM user WHERE id = '1'");
let complex_query = sql! {
SELECT a.company, COUNT(i.id) AS total_impressions, COUNT(DISTINCT i.ip_address) AS unique_impressions
FROM impressions i
INNER JOIN cached_content c ON c.content_hash = i.content_hash
INNER JOIN ads a ON a.id = c.ad_id
GROUP BY a.company;
};
assert_eq!(
complex_query.to_string(),
"SELECT a.company, COUNT (i.id) AS total_impressions, COUNT (DISTINCT i.ip_address) AS unique_impressions \
FROM impressions i \
INNER JOIN cached_content c ON c.content_hash = i.content_hash \
INNER JOIN ads a ON a.id = c.ad_id \
GROUP BY a.company;"
);
}
#[test]
fn raw_execute() {
let db_relative_path = "./db/select.db";
let db_path = Path::new(&db_relative_path);
let conn = sqlite::open(db_path);
let username = "mjovanc";
let query = sql! {
SELECT *
FROM users
WHERE username = {username}
};
match conn {
Ok(ref c) => {
let result = sqlite::select::raw_execute::<User>(&query, c);
match result {
Ok(r) => assert_eq!(r.len(), 2),
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}
Err(e) => panic!("Failed to SELECT: {:?}", e),
};
}