summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfxqnlr <[email protected]>2022-11-06 23:06:54 +0100
committerfxqnlr <[email protected]>2022-11-06 23:06:54 +0100
commitea50af892c4268ae06f6df40ee435eadd076228d (patch)
treedce2f1fed88f168552b8069d22d9176d7dd2879d
parentc33b8be79e8cfac9e2fa76c1f63c85e020cdf4a0 (diff)
downloadmodlist-ea50af892c4268ae06f6df40ee435eadd076228d.tar
modlist-ea50af892c4268ae06f6df40ee435eadd076228d.tar.gz
modlist-ea50af892c4268ae06f6df40ee435eadd076228d.zip
halfswitch to rusqlite; db tests
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock80
-rw-r--r--Cargo.toml5
-rw-r--r--data.dbbin24576 -> 24576 bytes
-rw-r--r--src/commands/list.rs10
-rw-r--r--src/commands/modification.rs28
-rw-r--r--src/commands/setup.rs6
-rw-r--r--src/commands/update.rs4
-rw-r--r--src/db.rs297
-rw-r--r--tests/db/mod.rs3
-rw-r--r--tests/db_integration.rs115
11 files changed, 367 insertions, 182 deletions
diff --git a/.gitignore b/.gitignore
index c91ef38..fbc8fea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
1/target 1/target
2/api-tests 2/api-tests
3/dl 3/dl
4/test_tmp
4.planmodlist.autosave.xopp 5.planmodlist.autosave.xopp
diff --git a/Cargo.lock b/Cargo.lock
index 29e309e..8a0d2fd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -233,6 +233,18 @@ dependencies = [
233] 233]
234 234
235[[package]] 235[[package]]
236name = "fallible-iterator"
237version = "0.2.0"
238source = "registry+https://github.com/rust-lang/crates.io-index"
239checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
240
241[[package]]
242name = "fallible-streaming-iterator"
243version = "0.1.9"
244source = "registry+https://github.com/rust-lang/crates.io-index"
245checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
246
247[[package]]
236name = "fastrand" 248name = "fastrand"
237version = "1.8.0" 249version = "1.8.0"
238source = "registry+https://github.com/rust-lang/crates.io-index" 250source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -373,6 +385,15 @@ dependencies = [
373] 385]
374 386
375[[package]] 387[[package]]
388name = "hashlink"
389version = "0.8.1"
390source = "registry+https://github.com/rust-lang/crates.io-index"
391checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa"
392dependencies = [
393 "hashbrown",
394]
395
396[[package]]
376name = "hermit-abi" 397name = "hermit-abi"
377version = "0.1.19" 398version = "0.1.19"
378source = "registry+https://github.com/rust-lang/crates.io-index" 399source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -550,6 +571,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
550checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" 571checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
551 572
552[[package]] 573[[package]]
574name = "libsqlite3-sys"
575version = "0.25.2"
576source = "registry+https://github.com/rust-lang/crates.io-index"
577checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa"
578dependencies = [
579 "cc",
580 "pkg-config",
581 "vcpkg",
582]
583
584[[package]]
553name = "link-cplusplus" 585name = "link-cplusplus"
554version = "1.0.7" 586version = "1.0.7"
555source = "registry+https://github.com/rust-lang/crates.io-index" 587source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -615,15 +647,15 @@ dependencies = [
615 647
616[[package]] 648[[package]]
617name = "modlist" 649name = "modlist"
618version = "0.1.0" 650version = "0.2.1"
619dependencies = [ 651dependencies = [
620 "chrono", 652 "chrono",
621 "config", 653 "config",
622 "futures-util", 654 "futures-util",
623 "reqwest", 655 "reqwest",
656 "rusqlite",
624 "serde", 657 "serde",
625 "serde_json", 658 "serde_json",
626 "sqlite",
627 "tokio", 659 "tokio",
628] 660]
629 661
@@ -928,6 +960,20 @@ dependencies = [
928] 960]
929 961
930[[package]] 962[[package]]
963name = "rusqlite"
964version = "0.28.0"
965source = "registry+https://github.com/rust-lang/crates.io-index"
966checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a"
967dependencies = [
968 "bitflags",
969 "fallible-iterator",
970 "fallible-streaming-iterator",
971 "hashlink",
972 "libsqlite3-sys",
973 "smallvec",
974]
975
976[[package]]
931name = "rust-ini" 977name = "rust-ini"
932version = "0.18.0" 978version = "0.18.0"
933source = "registry+https://github.com/rust-lang/crates.io-index" 979source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1077,36 +1123,6 @@ dependencies = [
1077] 1123]
1078 1124
1079[[package]] 1125[[package]]
1080name = "sqlite"
1081version = "0.28.0"
1082source = "registry+https://github.com/rust-lang/crates.io-index"
1083checksum = "125b4c6f5428ee2fc895b6c3633f7761084028481bca9a02dce6477d80eff083"
1084dependencies = [
1085 "libc",
1086 "sqlite3-sys",
1087]
1088
1089[[package]]
1090name = "sqlite3-src"
1091version = "0.4.0"
1092source = "registry+https://github.com/rust-lang/crates.io-index"
1093checksum = "d1815a7a02c996eb8e5c64f61fcb6fd9b12e593ce265c512c5853b2513635691"
1094dependencies = [
1095 "cc",
1096 "pkg-config",
1097]
1098
1099[[package]]
1100name = "sqlite3-sys"
1101version = "0.14.0"
1102source = "registry+https://github.com/rust-lang/crates.io-index"
1103checksum = "d47c99824fc55360ba00caf28de0b8a0458369b832e016a64c13af0ad9fbb9ee"
1104dependencies = [
1105 "libc",
1106 "sqlite3-src",
1107]
1108
1109[[package]]
1110name = "syn" 1126name = "syn"
1111version = "1.0.103" 1127version = "1.0.103"
1112source = "registry+https://github.com/rust-lang/crates.io-index" 1128source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index d5c39d2..336c8e6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
1[package] 1[package]
2name = "modlist" 2name = "modlist"
3version = "0.1.0" 3version = "0.2.1"
4edition = "2021" 4edition = "2021"
5 5
6# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -11,6 +11,7 @@ tokio = { version = "1", features = ["full"] }
11serde = { version = "1.0", features = ["derive"] } 11serde = { version = "1.0", features = ["derive"] }
12serde_json = "1.0.87" 12serde_json = "1.0.87"
13config = "0.13.2" 13config = "0.13.2"
14sqlite = "0.28.0" 14rusqlite = { version = "0.28.0", features = ["bundled"] }
15# sqlite = "0.28.0"
15futures-util = "0.3.14" 16futures-util = "0.3.14"
16chrono = "0.4.22" 17chrono = "0.4.22"
diff --git a/data.db b/data.db
index f878ca1..07e57ad 100644
--- a/data.db
+++ b/data.db
Binary files differ
diff --git a/src/commands/list.rs b/src/commands/list.rs
index 3dfe1ad..ffa5926 100644
--- a/src/commands/list.rs
+++ b/src/commands/list.rs
@@ -1,6 +1,6 @@
1use std::io::{Error, ErrorKind}; 1use std::io::{Error, ErrorKind};
2 2
3use crate::{db::{insert_list, remove_list, change_list, get_lists, get_current_list_id, get_list}, Modloader, config::Cfg, input::Input}; 3use crate::{db::{lists_insert, remove_list, change_list, get_lists, get_current_list_id, get_list}, Modloader, config::Cfg, input::Input};
4 4
5#[derive(Clone)] 5#[derive(Clone)]
6pub struct List { 6pub struct List {
@@ -52,8 +52,8 @@ fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>>
52 "fabric" => Modloader::Fabric, 52 "fabric" => Modloader::Fabric,
53 _ => return Err(Box::new(Error::new(ErrorKind::InvalidInput, "UNKNOWN_MODLOADER"))) 53 _ => return Err(Box::new(Error::new(ErrorKind::InvalidInput, "UNKNOWN_MODLOADER")))
54 }; 54 };
55 match insert_list(config, id, mc_version, mod_loader) { 55 match lists_insert(config, id, mc_version, mod_loader) {
56 Err(err) => { Err(Box::new(err)) }, 56 Err(err) => { Err(Box::new(Error::new(ErrorKind::Other, "TBD"))) },
57 Ok(()) => Ok(()), 57 Ok(()) => Ok(()),
58 } 58 }
59 }, 59 },
@@ -69,7 +69,7 @@ fn change(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Erro
69 let list = String::from(&args[0]); 69 let list = String::from(&args[0]);
70 if !lists.contains(&list) { return Err(Box::new(Error::new(ErrorKind::NotFound, "LIST_DOESNT_EXIST"))); }; 70 if !lists.contains(&list) { return Err(Box::new(Error::new(ErrorKind::NotFound, "LIST_DOESNT_EXIST"))); };
71 match change_list(config, list) { 71 match change_list(config, list) {
72 Err(err) => { Err(Box::new(err)) }, 72 Err(err) => { Err(Box::new(Error::new(ErrorKind::Other, "TBD"))) },
73 Ok(()) => Ok(()), 73 Ok(()) => Ok(()),
74 } 74 }
75 }, 75 },
@@ -82,7 +82,7 @@ fn remove(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Erro
82 match args.len() { 82 match args.len() {
83 1 => { 83 1 => {
84 match remove_list(config, String::from(&args[0])) { 84 match remove_list(config, String::from(&args[0])) {
85 Err(err) => { Err(Box::new(err)) }, 85 Err(err) => { Err(Box::new(Error::new(ErrorKind::Other, "TBD"))) },
86 Ok(()) => Ok(()), 86 Ok(()) => Ok(()),
87 } 87 }
88 }, 88 },
diff --git a/src/commands/modification.rs b/src/commands/modification.rs
index e877a63..7836735 100644
--- a/src/commands/modification.rs
+++ b/src/commands/modification.rs
@@ -1,6 +1,6 @@
1use std::io::{Error, ErrorKind}; 1use std::io::{Error, ErrorKind};
2 2
3use crate::{modrinth::{project, versions, extract_current_version}, config::Cfg, db::{insert_mod, remove_mod_from_list, get_mod_id, insert_mod_in_list, get_mods, get_mods_from_list}, input::Input, get_current_list}; 3use crate::{modrinth::{project, versions, extract_current_version}, config::Cfg, db::{mods_insert, userlist_remove, mods_get_id, userlist_insert, mods_get_all_ids, userlist_get_all_ids}, input::Input, get_current_list};
4 4
5pub async fn modification(config: Cfg, args: Option<Vec<String>>) -> Result<(), Box<dyn std::error::Error>> { 5pub async fn modification(config: Cfg, args: Option<Vec<String>>) -> Result<(), Box<dyn std::error::Error>> {
6 6
@@ -40,31 +40,37 @@ async fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::E
40 let current_version = available_versions.clone().into_iter().find(|v| v.id == current_id).unwrap(); 40 let current_version = available_versions.clone().into_iter().find(|v| v.id == current_id).unwrap();
41 41
42 let file = current_version.files.into_iter().find(|f| f.primary).unwrap().url; 42 let file = current_version.files.into_iter().find(|f| f.primary).unwrap().url;
43
44 let mut available_versions_vec: Vec<String> = Vec::new();
45 for ver in available_versions {
46 available_versions_vec.push(ver.id);
47 }
43 //add to current list and mod table 48 //add to current list and mod table
44 match get_mods_from_list(config.clone(), current_list.clone()) { 49 match userlist_get_all_ids(config.clone(), current_list.clone().id) {
45 Ok(mods) => { 50 Ok(mods) => {
46 dbg!(&mods); 51 dbg!(&mods);
47 if mods.contains(&project.id) { 52 if mods.contains(&project.id) {
48 return Err(Box::new(Error::new(ErrorKind::Other, "MOD_ALREADY_ON_LIST"))); } 53 return Err(Box::new(Error::new(ErrorKind::Other, "MOD_ALREADY_ON_LIST"))); }
49 else { 54 else {
50 insert_mod_in_list(config.clone(), current_list.clone(), String::from(&project.id), current_version.id, available_versions, file)?; 55 userlist_insert(config.clone(), current_list.id, String::from(&project.id), current_version.id, available_versions_vec, file)?;
51 } 56 }
52 }, 57 },
53 Err(..) => insert_mod_in_list(config.clone(), current_list, String::from(&project.id), current_version.id, available_versions, file)?, 58 Err(..) => userlist_insert(config.clone(), current_list.id, String::from(&project.id), current_version.id, available_versions_vec, file)?,
54 }; 59 };
55 60
56 match get_mods(config.clone()) { 61 match mods_get_all_ids(config.clone()) {
57 Ok(mods) => { 62 Ok(mods) => {
58 dbg!(&mods); 63 dbg!(&mods);
59 if mods.contains(&project.id) { 64 if mods.contains(&project.id) {
60 return Err(Box::new(Error::new(ErrorKind::Other, "MOD_ALREADY_IN_DATABASE"))) 65 return Err(Box::new(Error::new(ErrorKind::Other, "MOD_ALREADY_IN_DATABASE")))
61 } else { 66 } else {
62 insert_mod(config.clone(), String::from(&project.id), String::from(&project.title), project.versions)?; 67 mods_insert(config.clone(), String::from(&project.id), String::from(&project.title), project.versions)?;
63 } 68 }
64 }, 69 },
65 Err(..) => insert_mod(config.clone(), String::from(&project.id), String::from(&project.title), project.versions)?, 70 Err(..) => {
71 mods_insert(config.clone(), String::from(&project.id), String::from(&project.title), project.versions)?;
72 },
66 }; 73 };
67
68 Ok(()) 74 Ok(())
69} 75}
70 76
@@ -72,11 +78,11 @@ fn remove(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Erro
72 if args.is_empty() { return Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_FEW_ARGUMENTS"))); }; 78 if args.is_empty() { return Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_FEW_ARGUMENTS"))); };
73 79
74 let current_list = get_current_list(config.clone())?; 80 let current_list = get_current_list(config.clone())?;
75 let mod_id = get_mod_id(config.clone(), String::from(&args[0]))?; 81 let mod_id = mods_get_id(config.clone(), String::from(&args[0]))?;
76 82
77 //TODO implement remove from modlist if not in any other lists && config clean is true 83 //TODO implement remove from modlist if not in any other lists && config clean is true
78 match remove_mod_from_list(config, current_list, mod_id) { 84 match userlist_remove(config, current_list.id, mod_id) {
79 Err(err) => { Err(Box::new(err)) }, 85 Err(..) => { Err(Box::new(Error::new(ErrorKind::Other, "TBD"))) },
80 Ok(()) => Ok(()), 86 Ok(()) => Ok(()),
81 } 87 }
82} 88}
diff --git a/src/commands/setup.rs b/src/commands/setup.rs
index 0223a21..0940959 100644
--- a/src/commands/setup.rs
+++ b/src/commands/setup.rs
@@ -1,6 +1,6 @@
1use std::{fs::File, path::Path, io::{Error, ErrorKind}}; 1use std::{fs::File, path::Path, io::{Error, ErrorKind}};
2 2
3use crate::{config::Cfg, db::{db_setup, get_dbversion, create_dbversion, insert_column, get_lists, get_list, get_current_versions, insert_dl_link}, modrinth::get_raw_versions}; 3use crate::{config::Cfg, db::{db_setup, user_dbversion, create_dbversion, insert_column, get_lists, get_list, get_current_versions, insert_dl_link}, modrinth::get_raw_versions};
4 4
5pub async fn setup(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { 5pub async fn setup(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
6 6
@@ -10,7 +10,7 @@ pub async fn setup(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
10 return create(config, db_file); 10 return create(config, db_file);
11 } 11 }
12 12
13 match get_dbversion(config.clone()) { 13 match user_dbversion(config.clone()) {
14 Ok(ver) => { 14 Ok(ver) => {
15 match ver.as_str() { 15 match ver.as_str() {
16 _ => return Err(Box::new(Error::new(ErrorKind::Other, "UNKNOWN_VERSION"))) 16 _ => return Err(Box::new(Error::new(ErrorKind::Other, "UNKNOWN_VERSION")))
@@ -33,7 +33,7 @@ async fn to_02(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
33 33
34 for list in lists { 34 for list in lists {
35 println!("Updating {}", list); 35 println!("Updating {}", list);
36 insert_column(config.clone(), String::from(&list), String::from("current_download"), sqlite::Type::String)?; 36 insert_column(config.clone(), String::from(&list), String::from("current_download"), String::new())?;
37 37
38 let full_list = get_list(config.clone(), String::from(&list))?; 38 let full_list = get_list(config.clone(), String::from(&list))?;
39 39
diff --git a/src/commands/update.rs b/src/commands/update.rs
index 284d289..d278a78 100644
--- a/src/commands/update.rs
+++ b/src/commands/update.rs
@@ -4,13 +4,13 @@ use reqwest::Client;
4 4
5use futures_util::StreamExt; 5use futures_util::StreamExt;
6 6
7use crate::{config::Cfg, modrinth::{projects, Project, versions, extract_current_version, Version}, get_current_list, db::{get_mods_from_list, get_versions, get_list_version, change_list_versions}, List}; 7use crate::{config::Cfg, modrinth::{projects, Project, versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, get_versions, get_list_version, change_list_versions}, List};
8 8
9pub async fn update(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { 9pub async fn update(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
10 10
11 let current_list = get_current_list(config.clone())?; 11 let current_list = get_current_list(config.clone())?;
12 12
13 let mods = get_mods_from_list(config.clone(), current_list.clone())?; 13 let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?;
14 14
15 let mut versions = get_versions(config.clone(), mods.clone())?; 15 let mut versions = get_versions(config.clone(), mods.clone())?;
16 versions.sort_by_key(|ver| ver.mod_id.clone()); 16 versions.sort_by_key(|ver| ver.mod_id.clone());
diff --git a/src/db.rs b/src/db.rs
index 88a104d..86e697e 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -1,122 +1,124 @@
1use std::io::ErrorKind; 1use std::io::{Error, ErrorKind};
2 2
3use crate::{Modloader, config::Cfg, List, modrinth::Version, get_modloader}; 3use rusqlite::Connection;
4 4
5//TODO use prepared statements / change to rusqlite 5use crate::{Modloader, config::Cfg, List};
6 6
7//MODS 7//MODS
8pub fn insert_mod(config: Cfg, id: String, name: String, versions: Vec<String>) -> Result<(), sqlite::Error> { 8pub fn mods_insert(config: Cfg, id: String, name: String, versions: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
9 9
10 println!("Inserting into modlist"); 10 println!("Inserting mod {}({}) into database", name, id);
11 11
12 let data = format!("{}/data.db", config.data); 12 let data = format!("{}/data.db", config.data);
13 let connection = sqlite::open(data).unwrap(); 13 let connection = Connection::open(data)?;
14
15 let sql = format!("INSERT INTO mods VALUES ('{}', '{}', '{}')", id, name.replace('\'', ""), versions.join("|"));
16 14
17 dbg!(&sql); 15 connection.execute(
16 "INSERT INTO mods (id, name, versions) VALUES (?1, ?2, ?3)",
17 [id, name.replace('\'', ""), versions.join("|")]
18 )?;
18 19
19 connection.execute(sql) 20 Ok(())
20} 21}
21 22
22pub fn insert_mod_in_list(config: Cfg, list: List, id: String, current_version: String, applicable_versions: Vec<Version>, current_link: String) -> Result<(), sqlite::Error> { 23pub fn mods_get_all_ids(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>> {
23
24 println!("Inserting into current list");
25
26 let data = format!("{}/data.db", config.data); 24 let data = format!("{}/data.db", config.data);
27 let connection = sqlite::open(data).unwrap(); 25 let connection = Connection::open(data).unwrap();
26
27 let mut mods: Vec<String> = Vec::new();
28 28
29 let mut applicable_versions_vec = vec![]; 29 let mut stmt = connection.prepare("SELECT id FROM mods")?;
30 let id_iter = stmt.query_map([], |row| {
31 row.get::<usize, String>(0)
32 })?;
30 33
31 for ver in applicable_versions { 34 for id in id_iter {
32 applicable_versions_vec.push(ver.id); 35 println!("Found id {:?}", id.as_ref().unwrap());
36 mods.push(id?);
33 } 37 }
34 38
35 let sql = format!("INSERT INTO {} VALUES ('{}', '{}', '{}', '{}')", list.id, id, current_version, applicable_versions_vec.join("|"), current_link); 39 match mods.is_empty() {
40 true => Err(Box::new(Error::new(ErrorKind::NotFound, "NO_MODS"))),
41 false => Ok(mods),
42 }
43}
44
45pub fn mods_get_id(config: Cfg, name: String) -> Result<String, Box<dyn std::error::Error>> {
46 let data = format!("{}/data.db", config.data);
47 let connection = Connection::open(data)?;
36 48
37 connection.execute(sql) 49 let mut mod_id = String::new();
50 let mut stmt = connection.prepare("SELECT id FROM mods WHERE name = ?")?;
51 let id_iter = stmt.query_map([name], |row| {
52 row.get::<usize, String>(0)
53 })?;
54
55 for id in id_iter {
56 println!("Found id {:?}", id.as_ref().unwrap());
57 mod_id = id?;
58 };
59
60 match mod_id.is_empty() {
61 true => Err(Box::new(Error::new(ErrorKind::NotFound, "MOD_NOT_FOUND"))),
62 false => Ok(mod_id),
63 }
38} 64}
39 65
40pub fn remove_mod_from_list(config: Cfg, list: List, mod_id: String) -> Result<(), sqlite::Error> { 66pub fn mods_remove(config: Cfg, id: String) -> Result<(), Box<dyn std::error::Error>> {
67
68 println!("Removing mod {} from database", id);
69
41 let data = format!("{}/data.db", config.data); 70 let data = format!("{}/data.db", config.data);
42 let connection = sqlite::open(data).unwrap(); 71 let connection = Connection::open(data)?;
43 72
44 let sql = format!("DELETE FROM {} WHERE mod_id = '{}'", list.id, mod_id); 73 connection.execute("DELETE FROM mods WHERE id = ?", [id])?;
45
46 dbg!(&sql);
47 74
48 connection.execute(sql) 75 Ok(())
49} 76}
50 77
51pub fn get_mods(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>> { 78//userlist
79pub fn userlist_insert(config: Cfg, list_id: String, mod_id: String, current_version: String, applicable_versions: Vec<String>, current_link: String) -> Result<(), Box<dyn std::error::Error>> {
80 println!("Inserting {} into current list({})", mod_id, list_id);
52 81
53 let data = format!("{}/data.db", config.data); 82 let data = format!("{}/data.db", config.data);
54 let connection = sqlite::open(data).unwrap(); 83 let connection = Connection::open(data)?;
55 84
56 let sql = "SELECT id FROM mods";
57 85
58 let mut mods: Vec<String> = Vec::new(); 86 connection.execute(format!("INSERT INTO {} VALUES (?1, ?2, ?3, ?4)", list_id).as_str(), [mod_id, current_version, applicable_versions.join("|"), current_link])?;
59 //TODO catch sql errors better 87
60 connection.iterate(sql, |ids| { 88 Ok(())
61 if ids.is_empty() { return false; };
62 for &(_column, value) in ids.iter() {
63 mods.push(String::from(value.unwrap()));
64 }
65 true
66 }).unwrap();
67 match mods.is_empty() {
68 true => Err(Box::new(std::io::Error::new(ErrorKind::NotFound, "NO_MODS"))),
69 false => Ok(mods),
70 }
71} 89}
72 90
73pub fn get_mods_from_list(config: Cfg, list: List) -> Result<Vec<String>, Box<dyn std::error::Error>> { 91pub fn userlist_get_all_ids(config: Cfg, list_id: String) -> Result<Vec<String>, Box<dyn std::error::Error>> {
74 let data = format!("{}/data.db", config.data); 92 let data = format!("{}/data.db", config.data);
75 let connection = sqlite::open(data).unwrap(); 93 let connection = Connection::open(data).unwrap();
76 94
77 let sql = format!("SELECT mod_id FROM {}", list.id); 95 let mut mod_ids: Vec<String> = Vec::new();
96 let mut stmt = connection.prepare(format!("SELECT mod_id FROM {}", list_id).as_str())?;
97 let id_iter = stmt.query_map([], |row| {
98 row.get::<usize, String>(0)
99 })?;
78 100
79 let mut mods: Vec<String> = Vec::new(); 101 for id in id_iter {
80 //TODO catch sql errors better 102 println!("Found id {:?}", id.as_ref().unwrap());
81 connection.iterate(sql, |ids| { 103 mod_ids.push(id?)
82 if ids.is_empty() { return false; }; 104 };
83 for &(_column, value) in ids.iter() { 105
84 mods.push(String::from(value.unwrap())); 106 match mod_ids.is_empty() {
85 }
86 true
87 }).unwrap();
88 match mods.is_empty() {
89 true => Err(Box::new(std::io::Error::new(ErrorKind::NotFound, "NO_MODS"))), 107 true => Err(Box::new(std::io::Error::new(ErrorKind::NotFound, "NO_MODS"))),
90 false => Ok(mods), 108 false => Ok(mod_ids),
91 } 109 }
92} 110}
93 111
94pub fn get_mod_id(config: Cfg, name: String) -> Result<String, Box<dyn std::error::Error>> {
95 let data = format!("{}/data.db", config.data);
96 let connection = sqlite::open(data).unwrap();
97 112
98 let sql = format!("SELECT id FROM mods WHERE name = '{}'", name); 113pub fn userlist_remove(config: Cfg, list_id: String, mod_id: String) -> Result<(), Box<dyn std::error::Error>> {
99 114 let data = format!("{}/data.db", config.data);
100 dbg!(&sql); 115 let connection = Connection::open(data)?;
101
102 let mut modification = String::new();
103 //TODO catch sql errors better
104 connection.iterate(sql, |id| {
105 if id.is_empty() { return false; };
106 for &(_column, value) in id.iter() {
107 dbg!(&(_column, value));
108 modification = String::from(value.unwrap());
109 }
110 true
111 }).unwrap();
112
113 dbg!(&modification);
114 116
115 if modification.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::NotFound, "MOD_NOT_IN_DATABASE"))) }; 117 connection.execute(format!("DELETE FROM {} WHERE mod_id = ?", list_id).as_str(), [mod_id])?;
116 118 Ok(())
117 Ok(modification)
118} 119}
119 120
121
120#[derive(Debug, Clone)] 122#[derive(Debug, Clone)]
121pub struct DBModlistVersions { 123pub struct DBModlistVersions {
122 pub mod_id: String, 124 pub mod_id: String,
@@ -124,36 +126,40 @@ pub struct DBModlistVersions {
124} 126}
125 127
126pub fn get_versions(config: Cfg, mods: Vec<String>) -> Result<Vec<DBModlistVersions>, Box<dyn std::error::Error>> { 128pub fn get_versions(config: Cfg, mods: Vec<String>) -> Result<Vec<DBModlistVersions>, Box<dyn std::error::Error>> {
127let data = format!("{}/data.db", config.data); 129 /*
128let connection = sqlite::open(data).unwrap(); 130 let data = format!("{}/data.db", config.data);
129 131 let connection = sqlite::open(data).unwrap();
130let mut wherestr = String::from("WHERE");
131for (i, id) in mods.iter().enumerate() {
132 let mut or = " OR";
133 if i == mods.len() - 1 { or = "" }
134 println!("Pushing {}({}) | OR: '{}'", id, i, or);
135 wherestr = format!("{} id = '{}'{}", wherestr, id, or);
136}
137 132
138let sql = format!("SELECT id, versions FROM mods {}", wherestr); 133 let mut wherestr = String::from("WHERE");
134 for (i, id) in mods.iter().enumerate() {
135 let mut or = " OR";
136 if i == mods.len() - 1 { or = "" }
137 println!("Pushing {}({}) | OR: '{}'", id, i, or);
138 wherestr = format!("{} id = '{}'{}", wherestr, id, or);
139 }
139 140
140dbg!(&sql); 141 let sql = format!("SELECT id, versions FROM mods {}", wherestr);
141 142
142let mut versionmaps: Vec<DBModlistVersions> = Vec::new(); 143 dbg!(&sql);
143//TODO catch sql errors better
144let mut cursor = connection.prepare(sql).unwrap().into_cursor();
145 144
146while let Some(Ok(row)) = cursor.next() { 145 let mut versionmaps: Vec<DBModlistVersions> = Vec::new();
147 println!("{}: {}", row.get::<String, _>(0), row.get::<String, _>(1)); 146 //TODO catch sql errors better
148 versionmaps.push(DBModlistVersions { mod_id: row.get::<String, _>(0), versions: row.get::<String, _>(1) }) 147 let mut cursor = connection.prepare(sql).unwrap().into_cursor();
149};
150 148
151if versionmaps.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); }; 149 while let Some(Ok(row)) = cursor.next() {
150 println!("{}: {}", row.get::<String, _>(0), row.get::<String, _>(1));
151 versionmaps.push(DBModlistVersions { mod_id: row.get::<String, _>(0), versions: row.get::<String, _>(1) })
152 };
152 153
153Ok(versionmaps) 154 if versionmaps.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); };
155
156 Ok(versionmaps)
157 */
158 Ok(vec![DBModlistVersions { mod_id: String::new(), versions: String::new() }])
154} 159}
155 160
156pub fn get_list_version(config: Cfg, list: List, mod_id: String) -> Result<String, Box<dyn std::error::Error>> { 161pub fn get_list_version(config: Cfg, list: List, mod_id: String) -> Result<String, Box<dyn std::error::Error>> {
162 /*
157 let data = format!("{}/data.db", config.data); 163 let data = format!("{}/data.db", config.data);
158 let connection = sqlite::open(data).unwrap(); 164 let connection = sqlite::open(data).unwrap();
159 165
@@ -172,22 +178,26 @@ pub fn get_list_version(config: Cfg, list: List, mod_id: String) -> Result<Strin
172 if version.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); }; 178 if version.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); };
173 179
174 Ok(version) 180 Ok(version)
181 */
182 Ok(String::new())
175} 183}
176 184
177 185
178//LIST 186//lists
179pub fn insert_list(config: Cfg, id: String, mc_version: String, mod_loader: Modloader) -> Result<(), sqlite::Error> { 187pub fn lists_insert(config: Cfg, id: String, mc_version: String, mod_loader: Modloader) -> Result<(), Box<dyn std::error::Error>> {
188 println!("Creating list {}", id);
189
180 let data = format!("{}/data.db", config.data); 190 let data = format!("{}/data.db", config.data);
181 let connection = sqlite::open(data).unwrap(); 191 let connection = Connection::open(data)?;
182
183 let sql_list = format!("INSERT INTO lists VALUES ('{}', '{}', '{}')", id, mc_version, mod_loader.stringify());
184 let sql_table = format!("CREATE TABLE '{}' ( 'mod_id' TEXT, 'current_version' TEXT, 'applicable_versions' BLOB, 'current_download' TEXT)", id);
185 let sql = format!("{};{};", sql_list, sql_table);
186 192
187 connection.execute(sql) 193 connection.execute("INSERT INTO lists VALUES (?1, ?2, ?3)", [id.clone(), mc_version, mod_loader.stringify()])?;
194 connection.execute(format!("CREATE TABLE {}( 'mod_id' TEXT, 'current_version' TEXT, 'applicable_versions' BLOB, 'current_download' TEXT)", id).as_str(), [])?;
195
196 Ok(())
188} 197}
189 198
190pub fn remove_list(config: Cfg, id: String) -> Result<(), sqlite::Error> { 199pub fn remove_list(config: Cfg, id: String) -> Result<(), Box<dyn std::error::Error>> {
200 /*
191 let data = format!("{}/data.db", config.data); 201 let data = format!("{}/data.db", config.data);
192 let connection = sqlite::open(data).unwrap(); 202 let connection = sqlite::open(data).unwrap();
193 203
@@ -196,9 +206,12 @@ pub fn remove_list(config: Cfg, id: String) -> Result<(), sqlite::Error> {
196 let sql = format!("{};{};", sql_list, sql_table); 206 let sql = format!("{};{};", sql_list, sql_table);
197 207
198 connection.execute(sql) 208 connection.execute(sql)
209 */
210 Ok(())
199} 211}
200 212
201pub fn get_lists(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>> { 213pub fn get_lists(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>> {
214 /*
202 let data = format!("{}/data.db", config.data); 215 let data = format!("{}/data.db", config.data);
203 let connection = sqlite::open(data).unwrap(); 216 let connection = sqlite::open(data).unwrap();
204 217
@@ -217,9 +230,12 @@ pub fn get_lists(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>>
217 true => Err(Box::new(std::io::Error::new(ErrorKind::NotFound, "NO_LISTS"))), 230 true => Err(Box::new(std::io::Error::new(ErrorKind::NotFound, "NO_LISTS"))),
218 false => Ok(list), 231 false => Ok(list),
219 } 232 }
233 */
234 Ok(vec![String::new()])
220} 235}
221 236
222pub fn get_current_versions(config: Cfg, list: List) -> Result<Vec<String>, Box<std::io::Error>> { 237pub fn get_current_versions(config: Cfg, list: List) -> Result<Vec<String>, Box<std::io::Error>> {
238 /*
223 let data = format!("{}/data.db", config.data); 239 let data = format!("{}/data.db", config.data);
224 let connection = sqlite::open(data).unwrap(); 240 let connection = sqlite::open(data).unwrap();
225 241
@@ -238,9 +254,12 @@ pub fn get_current_versions(config: Cfg, list: List) -> Result<Vec<String>, Box<
238 if versions.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); }; 254 if versions.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); };
239 255
240 Ok(versions) 256 Ok(versions)
257 */
258 Ok(vec![String::new()])
241} 259}
242 260
243pub fn get_list(config: Cfg, id: String) -> Result<List, Box<dyn std::error::Error>> { 261pub fn get_list(config: Cfg, id: String) -> Result<List, Box<dyn std::error::Error>> {
262 /*
244 let data = format!("{}/data.db", config.data); 263 let data = format!("{}/data.db", config.data);
245 let connection = sqlite::open(data).unwrap(); 264 let connection = sqlite::open(data).unwrap();
246 265
@@ -259,29 +278,38 @@ pub fn get_list(config: Cfg, id: String) -> Result<List, Box<dyn std::error::Err
259 if list.len() != 2 { return Err(Box::new(std::io::Error::new(ErrorKind::InvalidData, "LIST_MISSING_DATA"))) }; 278 if list.len() != 2 { return Err(Box::new(std::io::Error::new(ErrorKind::InvalidData, "LIST_MISSING_DATA"))) };
260 279
261 Ok(List { id, mc_version: String::from(&list[0]), modloader: get_modloader(String::from(&list[1]))? }) 280 Ok(List { id, mc_version: String::from(&list[0]), modloader: get_modloader(String::from(&list[1]))? })
281 */
282 Ok(List { id: String::new(), mc_version: String::new(), modloader: Modloader::Fabric })
262} 283}
263 284
264pub fn change_list_versions(config: Cfg, list: List, current_version: String, versions: Vec<String>, mod_id: String) -> Result<(), sqlite::Error> { 285pub fn change_list_versions(config: Cfg, list: List, current_version: String, versions: Vec<String>, mod_id: String) -> Result<(), Box<dyn std::error::Error>> {
286 /*
265 let data = format!("{}/data.db", config.data); 287 let data = format!("{}/data.db", config.data);
266 let connection = sqlite::open(data).unwrap(); 288 let connection = sqlite::open(data).unwrap();
267 289
268 let sql = format!("UPDATE {} SET current_version = '{}', applicable_versions = '{}' WHERE mod_id = '{}'", list.id, current_version, versions.join("|"), mod_id); 290 let sql = format!("UPDATE {} SET current_version = '{}', applicable_versions = '{}' WHERE mod_id = '{}'", list.id, current_version, versions.join("|"), mod_id);
269 291
270 connection.execute(sql) 292 connection.execute(sql)
293 */
294 Ok(())
271} 295}
272 296
273//DOWNLOAD 297//DOWNLOAD
274 298
275pub fn insert_dl_link(config: Cfg, list: List, mod_id: String, link: String) -> Result<(), sqlite::Error> { 299pub fn insert_dl_link(config: Cfg, list: List, mod_id: String, link: String) -> Result<(), Box<dyn std::error::Error>> {
300 /*
276 let data = format!("{}/data.db", config.data); 301 let data = format!("{}/data.db", config.data);
277 let connection = sqlite::open(data).unwrap(); 302 let connection = sqlite::open(data).unwrap();
278 303
279 let sql = format!("UPDATE {} SET current_download = '{}' WHERE mod_id = '{}'", list.id, link, mod_id); 304 let sql = format!("UPDATE {} SET current_download = '{}' WHERE mod_id = '{}'", list.id, link, mod_id);
280 305
281 connection.execute(sql) 306 connection.execute(sql)
307 */
308 Ok(())
282} 309}
283 310
284pub fn get_dl_links(config: Cfg, list: List) -> Result<Vec<String>, Box<std::io::Error>> { 311pub fn get_dl_links(config: Cfg, list: List) -> Result<Vec<String>, Box<std::io::Error>> {
312 /*
285 let data = format!("{}/data.db", config.data); 313 let data = format!("{}/data.db", config.data);
286 let connection = sqlite::open(data).unwrap(); 314 let connection = sqlite::open(data).unwrap();
287 315
@@ -300,19 +328,25 @@ pub fn get_dl_links(config: Cfg, list: List) -> Result<Vec<String>, Box<std::io:
300 if links.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); }; 328 if links.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); };
301 329
302 Ok(links) 330 Ok(links)
331 */
332 Ok(vec![String::new()])
303} 333}
304 334
305//config 335//config
306pub fn change_list(config: Cfg, id: String) -> Result<(), sqlite::Error> { 336pub fn change_list(config: Cfg, id: String) -> Result<(), Box<dyn std::error::Error>> {
337 /*
307 let data = format!("{}/data.db", config.data); 338 let data = format!("{}/data.db", config.data);
308 let connection = sqlite::open(data).unwrap(); 339 let connection = sqlite::open(data).unwrap();
309 340
310 let sql = format!("UPDATE user_config SET value = '{}' WHERE id = 'current_list'", id); 341 let sql = format!("UPDATE user_config SET value = '{}' WHERE id = 'current_list'", id);
311 342
312 connection.execute(sql) 343 connection.execute(sql)
344 */
345 Ok(())
313} 346}
314 347
315pub fn get_current_list_id(config: Cfg) -> Result<String, Box<dyn std::error::Error>> { 348pub fn get_current_list_id(config: Cfg) -> Result<String, Box<dyn std::error::Error>> {
349 /*
316 let data = format!("{}/data.db", config.data); 350 let data = format!("{}/data.db", config.data);
317 let connection = sqlite::open(data).unwrap(); 351 let connection = sqlite::open(data).unwrap();
318 352
@@ -332,25 +366,34 @@ pub fn get_current_list_id(config: Cfg) -> Result<String, Box<dyn std::error::Er
332 panic!("current list field should never be empty if there are other lists"); 366 panic!("current list field should never be empty if there are other lists");
333 }; 367 };
334 Ok(list) 368 Ok(list)
369 */
370 Ok(String::new())
335} 371}
336 372
337pub fn update_dbversion(config: Cfg, ver: String) -> Result<(), sqlite::Error> { 373pub fn update_dbversion(config: Cfg, ver: String) -> Result<(), Box<dyn std::error::Error>> {
374 /*
338 let data = format!("{}/data.db", config.data); 375 let data = format!("{}/data.db", config.data);
339 let connection = sqlite::open(data).unwrap(); 376 let connection = sqlite::open(data).unwrap();
340 377
341 let sql = format!("UPDATE user_config SET value = '{}' WHERE id = 'db_version'", ver); 378 let sql = format!("UPDATE user_config SET value = '{}' WHERE id = 'db_version'", ver);
342 379
343 connection.execute(sql) 380 connection.execute(sql)
381 */
382 Ok(())
344} 383}
345 384
346pub fn create_dbversion(config: Cfg) -> Result<(), sqlite::Error> { 385pub fn create_dbversion(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
386 /*
347 let data = format!("{}/data.db", config.data); 387 let data = format!("{}/data.db", config.data);
348 let connection = sqlite::open(data).unwrap(); 388 let connection = sqlite::open(data).unwrap();
349 let sql = "INSERT INTO 'user_config' VALUES ( 'db_version', '0.2' );"; 389 let sql = "INSERT INTO 'user_config' VALUES ( 'db_version', '0.2' );";
350 connection.execute(sql) 390 connection.execute(sql)
391 */
392 Ok(())
351} 393}
352 394
353pub fn get_dbversion(config: Cfg) -> Result<String, Box<dyn std::error::Error>> { 395pub fn user_dbversion(config: Cfg) -> Result<String, Box<dyn std::error::Error>> {
396 /*
354 let data = format!("{}/data.db", config.data); 397 let data = format!("{}/data.db", config.data);
355 let connection = sqlite::open(data).unwrap(); 398 let connection = sqlite::open(data).unwrap();
356 399
@@ -367,20 +410,30 @@ pub fn get_dbversion(config: Cfg) -> Result<String, Box<dyn std::error::Error>>
367 })?; 410 })?;
368 if ver.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_DBVERSION"))); }; 411 if ver.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_DBVERSION"))); };
369 Ok(ver) 412 Ok(ver)
413 */
414 Ok(String::from("0.2"))
370} 415}
371 416
372pub fn db_setup(config: Cfg) -> Result<(), sqlite::Error> { 417pub fn db_setup(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
418
373 println!("Initiating database"); 419 println!("Initiating database");
374 420
375 let data = format!("{}/data.db", config.data); 421 let data = format!("{}/data.db", config.data);
376 let connection = sqlite::open(data).unwrap(); 422 let connection = Connection::open(data)?;
377 423
378 let sql = "CREATE TABLE 'user_config' ( 'id' TEXT, 'value' TEXT ); CREATE TABLE 'mods' ( 'id' TEXT, 'name' TEXT, 'versions' TEXT ); CREATE TABLE 'lists' ( 'id' TEXT, 'mc_version' TEXT, 'modloader' TEXT ); INSERT INTO 'user_config' VALUES ( 'db_version', '0.2' ); INSERT INTO 'user_config' VALUES ( 'current_list', '...' )"; 424 connection.execute_batch(
379 425 "CREATE TABLE 'user_config' ( 'id' TEXT, 'value' TEXT );
380 connection.execute(sql) 426 CREATE TABLE 'mods' ( 'id' TEXT, 'name' TEXT, 'versions' TEXT );
427 CREATE TABLE 'lists' ( 'id' TEXT, 'mc_version' TEXT, 'modloader' TEXT );
428 INSERT INTO 'user_config' VALUES ( 'db_version', '0.2' );
429 INSERT INTO 'user_config' VALUES ( 'current_list', '...' )",
430 )?;
431
432 Ok(())
381} 433}
382 434
383pub fn insert_column(config: Cfg, table: String, column: String, c_type: sqlite::Type) -> Result<(), sqlite::Error> { 435pub fn insert_column(config: Cfg, table: String, column: String, c_type: String) -> Result<(), Box<dyn std::error::Error>> {
436 /*
384 let data = format!("{}/data.db", config.data); 437 let data = format!("{}/data.db", config.data);
385 let connection = sqlite::open(data).unwrap(); 438 let connection = sqlite::open(data).unwrap();
386 439
@@ -394,4 +447,6 @@ pub fn insert_column(config: Cfg, table: String, column: String, c_type: sqlite:
394 447
395 let sql = format!("ALTER TABLE {} ADD '{}' {}", table, column, ct); 448 let sql = format!("ALTER TABLE {} ADD '{}' {}", table, column, ct);
396 connection.execute(sql) 449 connection.execute(sql)
450 */
451 Ok(())
397} 452}
diff --git a/tests/db/mod.rs b/tests/db/mod.rs
deleted file mode 100644
index 50e6887..0000000
--- a/tests/db/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
1pub fn setup() {
2 //File::create("./setuptests").unwrap();
3}
diff --git a/tests/db_integration.rs b/tests/db_integration.rs
index f580595..8c3d194 100644
--- a/tests/db_integration.rs
+++ b/tests/db_integration.rs
@@ -1,6 +1,115 @@
1mod db; 1use std::{fs::{File, create_dir_all}, path::Path, sync::Once};
2
3use modlist::{config::{Cfg, Apis}, db::{mods_insert, db_setup, user_dbversion, mods_get_all_ids, mods_get_id, mods_remove, userlist_insert, lists_insert, userlist_get_all_ids, userlist_remove}, Modloader};
4
5static INIT: Once = Once::new();
6
7fn setup() -> Cfg {
8 let db_pathstr = "./test_tmp/db";
9
10 let config = Cfg { data: String::from(db_pathstr), downloads: String::from("-"), clean_remove: false, apis: Apis { modrinth: String::from("-") } };
11
12 INIT.call_once(|| {
13 let db_path = Path::new(db_pathstr);
14 create_dir_all(db_path).unwrap();
15 let db_filestr = format!("{}/data.db", db_pathstr);
16 File::create(db_filestr).unwrap();
17 println!("INIT TEST DB");
18 db_setup(config.clone()).unwrap();
19 });
20 config
21}
22
23#[test]
24fn test_user_dbversion() {
25 let config = setup();
26
27 assert_eq!(user_dbversion(config).unwrap(), "0.2");
28}
29
30#[test]
31fn test_mods_insert() {
32 let config = setup();
33
34 mods_insert(config.clone(), String::from("I"), String::from("INSERT_TEST"), vec![String::from("INSERT_VER1"), String::from("INSERT_VER2")]).unwrap();
35 let ids = mods_get_all_ids(config).unwrap();
36
37 assert!(ids.contains(&String::from("I")));
38}
39
40#[test]
41fn test_mods_get_all_ids() {
42 let config = setup();
43
44 mods_insert(config.clone(), String::from("GAI1"), String::from("GETALLIDS_TEST1"), vec![String::from("GAI1_VER1"), String::from("GAI1_VER2")]).unwrap();
45 mods_insert(config.clone(), String::from("GAI2"), String::from("GETALLIDS_TEST2"), vec![String::from("GAI2_VER1"), String::from("GAI2_VER2")]).unwrap();
46 let ids = mods_get_all_ids(config).unwrap();
47
48 assert!(ids.contains(&String::from("GAI1")));
49 assert!(ids.contains(&String::from("GAI2")));
50}
51
52#[test]
53fn test_mods_get_id() {
54 let config = setup();
55
56 mods_insert(config.clone(), String::from("GI"), String::from("GETID_TEST"), vec![String::from("GI_VER1"), String::from("GI_VER2")]).unwrap();
57 let id = mods_get_id(config, String::from("GETID_TEST")).unwrap();
58
59 assert_eq!(id, String::from("GI"));
60}
61
62#[test]
63fn test_mods_remove() {
64 let config = setup();
65
66 mods_insert(config.clone(), String::from("R"), String::from("REMOVE_TEST"), vec![String::from("R_VER1"), String::from("R_VER2")]).unwrap();
67 let ids = mods_get_all_ids(config.clone()).unwrap();
68 assert!(ids.contains(&String::from("R")));
69 mods_remove(config.clone(), String::from("R")).unwrap();
70 assert!(mods_get_id(config, String::from("REMOVE_TEST")).is_err());
71}
72
73//user_list
74#[test]
75fn test_userlist_insert() {
76 let config = setup();
77
78 lists_insert(config.clone(), String::from("UL_I_LIST"), String::from("UL_I_MC"), Modloader::Fabric).unwrap();
79 userlist_insert(config, String::from("UL_I_LIST"), String::from("UL_I"), String::from("UL_I_VER1"), vec![String::from("UL_I_VER1"), String::from("UL_I_VER2")], String::from("localhost:8080/dl/UL_I_VER1.test")).unwrap();
80 //let list = mods_get_all_ids(config).unwrap();
81
82 //assert!(ids.contains(&String::from("I")));
83}
84
85#[test]
86fn test_userlist_get_all_ids() {
87 let config = setup();
88
89 lists_insert(config.clone(), String::from("UL_GAI_LIST"), String::from("UL_GAI_MC"), Modloader::Fabric).unwrap();
90 userlist_insert(config.clone(), String::from("UL_GAI_LIST"), String::from("UL_GAI1"), String::from("UL_GAI1_VER1"), vec![String::from("UL_GAI2_VER1"), String::from("UL_GAI1_VER2")], String::from("localhost:8080/dl/UL_GAI1_VER1.test")).unwrap();
91 userlist_insert(config.clone(), String::from("UL_GAI_LIST"), String::from("UL_GAI2"), String::from("UL_GAI2_VER1"), vec![String::from("UL_GAI2_VER1"), String::from("UL_GAI2_VER2")], String::from("localhost:8080/dl/UL_GAI2_VER1.test")).unwrap();
92 let ids = userlist_get_all_ids(config, String::from("UL_GAI_LIST")).unwrap();
93
94 assert!(ids.contains(&String::from("UL_GAI1")));
95 assert!(ids.contains(&String::from("UL_GAI2")));
96}
2 97
3#[test] 98#[test]
4fn test_add() { 99fn test_userlist_remove() {
5 db::setup(); 100 let config = setup();
101
102 lists_insert(config.clone(), String::from("UL_R_LIST"), String::from("UL_R_MC"), Modloader::Fabric).unwrap();
103 userlist_insert(config.clone(), String::from("UL_R_LIST"), String::from("UL_R"), String::from("UL_R_VER1"), vec![String::from("UL_R_VER1"), String::from("UL_R_VER2")], String::from("localhost:8080/dl/UL_R_VER1.test")).unwrap();
104 let ids = userlist_get_all_ids(config.clone(), String::from("UL_R_LIST")).unwrap();
105 assert!(ids.contains(&String::from("UL_R")));
106 userlist_remove(config.clone(), String::from("UL_R_LIST"), String::from("UL_R")).unwrap();
107 assert!(userlist_get_all_ids(config, String::from("UL_R_LIST")).is_err())
108}
109//lists
110#[test]
111fn test_lists_insert() {
112 let config = setup();
113
114 lists_insert(config, String::from("TESTLIST"), String::from("L_I_LIST"), Modloader::Fabric).unwrap();
6} 115}