use std::{fs, fs::File, path, str::FromStr, sync::Arc};
use log::LevelFilter;
use rust_kits::Executor;
use sqlx::{
sqlite::{SqliteConnectOptions, SqlitePoolOptions},
ConnectOptions, Pool, Sqlite,
};
pub struct KitsDb {}
impl KitsDb {
pub fn uuid() -> String {
xid::new().to_string()
}
pub async fn new_with_name(db_name: &str, sql_file: &str) -> Result<Arc<Pool<Sqlite>>, sqlx::Error> {
let mut p = path::PathBuf::from(format!("temp/data/{}", db_name));
let mut init_table = false;
if !p.exists() {
p = Executor::path();
log::info!("exe path: {}", p.to_str().expect(""));
p = p.join("data");
if !p.exists() {
fs::create_dir_all(p.as_path()).expect("");
}
p = p.join(db_name);
if !p.exists() {
File::create(p.as_path()).expect("");
init_table = true;
}
}
let str = format!("sqlite:{}", p.to_str().expect(""));
let options = SqlitePoolOptions::new().max_connections(30);
let mut con_options = SqliteConnectOptions::from_str(&str)?;
con_options = con_options.log_statements(LevelFilter::Debug);
con_options = con_options.log_slow_statements(LevelFilter::Warn, std::time::Duration::from_secs(1));
let pool = options.connect_with(con_options).await?;
let pool = Arc::new(pool);
if init_table {
let sql = {
match fs::read_to_string(sql_file) {
Err(err) => {
log::error!("{}", err);
String::new()
}
Ok(data) => data,
}
};
sqlx::query(&sql).execute(pool.as_ref()).await?;
}
Ok(pool)
}
}
#[cfg(test)]
mod tests {
use chrono::{Datelike, Local, NaiveDateTime, TimeZone, Utc};
use crate::dao::{KitsDb, Times};
#[test]
fn test_day() {
let d = Times::day_of_year();
assert_eq!(d, Local::now().ordinal() as i32);
}
#[test]
fn test_ts() {
{
let u = Utc::now();
let l = u.with_timezone(&Local);
assert_eq!(u.timestamp_millis(), l.timestamp_millis());
let ts = u.timestamp_millis();
let u = Utc.timestamp_millis_opt(ts).unwrap();
let l = Local.timestamp_millis_opt(ts).unwrap();
let ustr = u.to_string();
let lstr = l.to_string();
assert_ne!(ustr, lstr);
}
{
let f = "%Y-%m-%d %H:%M:%S%.3f";
let u = Utc::now();
let l = u.with_timezone(&Local);
let c = u.with_timezone(&Times::china_offset());
let c_str = c.format(f).to_string();
let naive = NaiveDateTime::parse_from_str(&c_str, f).unwrap();
let c2 = Times::naive_to_china_date(naive);
let c2_str = c2.format(f).to_string();
assert_eq!(c2_str, c_str);
assert_eq!(c.timestamp_millis(), c2.timestamp_millis());
assert_eq!(c.timestamp_millis(), u.timestamp_millis());
assert_eq!(c.timestamp_millis(), l.timestamp_millis());
}
}
#[test]
fn test_id() {
let id = KitsDb::uuid();
assert_eq!(20, id.len());
}
}