summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data.dbbin24576 -> 24576 bytes
-rw-r--r--src/commands/download.rs4
-rw-r--r--src/commands/list.rs27
-rw-r--r--src/commands/modification.rs2
-rw-r--r--src/commands/setup.rs17
-rw-r--r--src/commands/update.rs13
-rw-r--r--src/db.rs406
-rw-r--r--src/lib.rs2
-rw-r--r--tests/db.rs248
-rw-r--r--tests/db_integration.rs115
10 files changed, 451 insertions, 383 deletions
diff --git a/data.db b/data.db
index 07e57ad..5308bbc 100644
--- a/data.db
+++ b/data.db
Binary files differ
diff --git a/src/commands/download.rs b/src/commands/download.rs
index 05c54cb..993294b 100644
--- a/src/commands/download.rs
+++ b/src/commands/download.rs
@@ -4,12 +4,12 @@ use reqwest::Client;
4 4
5use futures_util::StreamExt; 5use futures_util::StreamExt;
6 6
7use crate::{get_current_list, config::Cfg, db::get_dl_links}; 7use crate::{get_current_list, config::Cfg, db::userlist_get_all_downloads};
8 8
9pub async fn download(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { 9pub async fn download(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
10 let list = get_current_list(config.clone())?; 10 let list = get_current_list(config.clone())?;
11 11
12 let links = get_dl_links(config.clone(), list)?; 12 let links = userlist_get_all_downloads(config.clone(), list.id)?;
13 13
14 download_links(config, links).await?; 14 download_links(config, links).await?;
15 15
diff --git a/src/commands/list.rs b/src/commands/list.rs
index ffa5926..6c80e4e 100644
--- a/src/commands/list.rs
+++ b/src/commands/list.rs
@@ -1,8 +1,8 @@
1use std::io::{Error, ErrorKind}; 1use std::io::{Error, ErrorKind};
2 2
3use crate::{db::{lists_insert, remove_list, change_list, get_lists, get_current_list_id, get_list}, Modloader, config::Cfg, input::Input}; 3use crate::{db::{lists_insert, lists_remove, config_change_current_list, lists_get_all_ids, config_get_current_list, lists_get}, Modloader, config::Cfg, input::Input};
4 4
5#[derive(Clone)] 5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct List { 6pub struct List {
7 pub id: String, 7 pub id: String,
8 pub mc_version: String, 8 pub mc_version: String,
@@ -12,8 +12,8 @@ pub struct List {
12pub fn list(config: Cfg, args: Option<Vec<String>>) -> Result<(), Box<dyn std::error::Error>> { 12pub fn list(config: Cfg, args: Option<Vec<String>>) -> Result<(), Box<dyn std::error::Error>> {
13 13
14 if args.is_none() { 14 if args.is_none() {
15 let lists = get_lists(config.clone())?; 15 let lists = lists_get_all_ids(config.clone())?;
16 let current_list = get_current_list_id(config)?; 16 let current_list = config_get_current_list(config)?;
17 println!("Your lists:\n{}\n-----\nCurrently selected list: \"{}\"", lists.join(",\n"), current_list); 17 println!("Your lists:\n{}\n-----\nCurrently selected list: \"{}\"", lists.join(",\n"), current_list);
18 return Ok(()); 18 return Ok(());
19 } 19 }
@@ -37,8 +37,8 @@ pub fn list(config: Cfg, args: Option<Vec<String>>) -> Result<(), Box<dyn std::e
37} 37}
38 38
39pub fn get_current_list(config: Cfg) -> Result<List, Box<dyn std::error::Error>> { 39pub fn get_current_list(config: Cfg) -> Result<List, Box<dyn std::error::Error>> {
40 let id = get_current_list_id(config.clone())?; 40 let id = config_get_current_list(config.clone())?;
41 get_list(config, id) 41 lists_get(config, id)
42} 42}
43 43
44fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> { 44fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
@@ -52,10 +52,7 @@ 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 lists_insert(config, id, mc_version, mod_loader) { 55 lists_insert(config, id, mc_version, mod_loader)
56 Err(err) => { Err(Box::new(Error::new(ErrorKind::Other, "TBD"))) },
57 Ok(()) => Ok(()),
58 }
59 }, 56 },
60 5.. => Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_MANY_ARGUMENTS"))), 57 5.. => Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_MANY_ARGUMENTS"))),
61 _ => panic!("list arguments should never be zero or lower"), 58 _ => panic!("list arguments should never be zero or lower"),
@@ -63,13 +60,13 @@ fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>>
63} 60}
64 61
65fn change(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> { 62fn change(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
66 let lists = get_lists(config.clone())?; 63 let lists = lists_get_all_ids(config.clone())?;
67 match args.len() { 64 match args.len() {
68 1 => { 65 1 => {
69 let list = String::from(&args[0]); 66 let list = String::from(&args[0]);
70 if !lists.contains(&list) { return Err(Box::new(Error::new(ErrorKind::NotFound, "LIST_DOESNT_EXIST"))); }; 67 if !lists.contains(&list) { return Err(Box::new(Error::new(ErrorKind::NotFound, "LIST_DOESNT_EXIST"))); };
71 match change_list(config, list) { 68 match config_change_current_list(config, list) {
72 Err(err) => { Err(Box::new(Error::new(ErrorKind::Other, "TBD"))) }, 69 Err(..) => { Err(Box::new(Error::new(ErrorKind::Other, "72"))) },
73 Ok(()) => Ok(()), 70 Ok(()) => Ok(()),
74 } 71 }
75 }, 72 },
@@ -81,8 +78,8 @@ fn change(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Erro
81fn remove(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> { 78fn remove(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
82 match args.len() { 79 match args.len() {
83 1 => { 80 1 => {
84 match remove_list(config, String::from(&args[0])) { 81 match lists_remove(config, String::from(&args[0])) {
85 Err(err) => { Err(Box::new(Error::new(ErrorKind::Other, "TBD"))) }, 82 Err(..) => { Err(Box::new(Error::new(ErrorKind::Other, "85"))) },
86 Ok(()) => Ok(()), 83 Ok(()) => Ok(()),
87 } 84 }
88 }, 85 },
diff --git a/src/commands/modification.rs b/src/commands/modification.rs
index 7836735..595b677 100644
--- a/src/commands/modification.rs
+++ b/src/commands/modification.rs
@@ -22,7 +22,7 @@ pub async fn modification(config: Cfg, args: Option<Vec<String>>) -> Result<(),
22} 22}
23 23
24async fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> { 24async fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
25 25 //TODO! DO NOT PANIC IF MOD IS ALREADY IN MODS DB
26 if args.is_empty() { return Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_FEW_ARGUMENTS"))); }; 26 if args.is_empty() { return Err(Box::new(Error::new(ErrorKind::InvalidInput, "TOO_FEW_ARGUMENTS"))); };
27 27
28 let current_list = get_current_list(config.clone())?; 28 let current_list = get_current_list(config.clone())?;
diff --git a/src/commands/setup.rs b/src/commands/setup.rs
index 0940959..8c0fcfd 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, user_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, s_config_get_version, s_config_create_version, s_insert_column, lists_get_all_ids, lists_get, userlist_get_all_current_version_ids, s_userlist_update_download}, 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 user_dbversion(config.clone()) { 13 match s_config_get_version(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")))
@@ -29,26 +29,25 @@ fn create(config: Cfg, db_file: String) -> Result<(), Box<dyn std::error::Error>
29} 29}
30 30
31async fn to_02(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { 31async fn to_02(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
32 let lists = get_lists(config.clone())?; 32 let lists = lists_get_all_ids(config.clone())?;
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"), String::new())?; 36 s_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 = lists_get(config.clone(), String::from(&list))?;
39 39
40 let versions = get_current_versions(config.clone(), full_list.clone())?; 40 let versions = userlist_get_all_current_version_ids(config.clone(), full_list.clone().id)?;
41 41
42 let raw_versions = get_raw_versions(String::from(&config.apis.modrinth), versions).await; 42 let raw_versions = get_raw_versions(String::from(&config.apis.modrinth), versions).await;
43 43
44 for ver in raw_versions { 44 for ver in raw_versions {
45 println!("Adding link for {}", ver.project_id); 45 println!("Adding link for {}", ver.project_id);
46 let file = ver.files.into_iter().find(|f| f.primary).unwrap(); 46 let file = ver.files.into_iter().find(|f| f.primary).unwrap();
47 insert_dl_link(config.clone(), full_list.clone(), ver.project_id, file.url)?; 47 s_userlist_update_download(config.clone(), String::from(&full_list.id), ver.project_id, file.url)?;
48 } 48 }
49 }; 49 };
50 create_dbversion(config)?; 50 s_config_create_version(config)?;
51
52 51
53 Ok(()) 52 Ok(())
54} 53}
diff --git a/src/commands/update.rs b/src/commands/update.rs
index d278a78..e383eae 100644
--- a/src/commands/update.rs
+++ b/src/commands/update.rs
@@ -4,7 +4,7 @@ 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::{userlist_get_all_ids, 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, mods_get_versions, userlist_get_applicable_versions, userlist_change_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
@@ -12,7 +12,7 @@ pub async fn update(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
12 12
13 let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?; 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 = mods_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());
17 17
18 let mut projects = projects(String::from(&config.apis.modrinth), mods).await; 18 let mut projects = projects(String::from(&config.apis.modrinth), mods).await;
@@ -54,12 +54,15 @@ async fn specific_update(config: Cfg, list: List, project: Project) -> Result<Ve
54 } 54 }
55 55
56 let mut current: Vec<Version> = vec![]; 56 let mut current: Vec<Version> = vec![];
57 if versions.join("|") != get_list_version(config.clone(), list.clone(), String::from(&project.id))? { 57 if versions.join("|") != userlist_get_applicable_versions(config.clone(), String::from(&list.id), String::from(&project.id))? {
58 //get new versions 58 //get new versions
59 print!(" | getting new version"); 59 print!(" | getting new version");
60 let current_str = extract_current_version(applicable_versions.clone())?; 60 let current_str = extract_current_version(applicable_versions.clone())?;
61 current.push(applicable_versions.into_iter().find(|ver| ver.id == current_str).unwrap()); 61 let current_ver = applicable_versions.into_iter().find(|ver| ver.id == current_str).ok_or("")?;
62 change_list_versions(config, list, current_str, versions, project.id)?; 62 current.push(current_ver.clone());
63
64 let link = current_ver.files.into_iter().find(|f| f.primary).ok_or("")?.url;
65 userlist_change_versions(config, list.id, current_str, versions.join("|"), link, project.id)?;
63 } 66 }
64 67
65 if current.is_empty() { return Err(Box::new(Error::new(ErrorKind::NotFound, "NO_UPDATE_AVAILABLE"))) }; 68 if current.is_empty() { return Err(Box::new(Error::new(ErrorKind::NotFound, "NO_UPDATE_AVAILABLE"))) };
diff --git a/src/db.rs b/src/db.rs
index 86e697e..5d82271 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -2,9 +2,9 @@ use std::io::{Error, ErrorKind};
2 2
3use rusqlite::Connection; 3use rusqlite::Connection;
4 4
5use crate::{Modloader, config::Cfg, List}; 5use crate::{Modloader, config::Cfg, List, get_modloader};
6 6
7//MODS 7//mods
8pub fn mods_insert(config: Cfg, id: String, name: String, versions: Vec<String>) -> Result<(), Box<dyn std::error::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 mod {}({}) into database", name, id); 10 println!("Inserting mod {}({}) into database", name, id);
@@ -75,6 +75,43 @@ pub fn mods_remove(config: Cfg, id: String) -> Result<(), Box<dyn std::error::Er
75 Ok(()) 75 Ok(())
76} 76}
77 77
78#[derive(Debug, Clone, PartialEq, Eq)]
79pub struct DBModlistVersions {
80 pub mod_id: String,
81 pub versions: String,
82}
83
84pub fn mods_get_versions(config: Cfg, mods: Vec<String>) -> Result<Vec<DBModlistVersions>, Box<dyn std::error::Error>> {
85 let data = format!("{}/data.db", config.data);
86 let connection = Connection::open(data)?;
87
88 if mods.is_empty() { return Err(Box::new(Error::new(ErrorKind::Other, "MODS_NO_INPUT"))); }
89
90 let mut wherestr = String::from("WHERE");
91 for (i, id) in mods.iter().enumerate() {
92 let mut or = " OR";
93 if i == mods.len() - 1 { or = "" };
94 wherestr = format!("{} id = '{}'{}", wherestr, id, or);
95 }
96
97 let mut versionmaps: Vec<DBModlistVersions> = Vec::new();
98 let mut stmt = connection.prepare(dbg!(format!("SELECT id, versions FROM mods {}", wherestr).as_str()))?;
99 let id_iter = stmt.query_map([], |row| {
100 Ok(vec![row.get::<usize, String>(0)?, row.get::<usize, String>(1)?])
101 })?;
102
103 for ver in id_iter {
104 let version = ver?;
105 println!("Found versions {} for mod {}", version[1], version[0]);
106 versionmaps.push(DBModlistVersions { mod_id: String::from(&version[0]), versions: String::from(&version[1]) })
107 };
108
109 match versionmaps.is_empty() {
110 true => Err(Box::new(Error::new(ErrorKind::NotFound, "MODS_MODS_NOT_FOUND"))),
111 false => Ok(versionmaps),
112 }
113}
114
78//userlist 115//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>> { 116pub 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); 117 println!("Inserting {} into current list({})", mod_id, list_id);
@@ -119,69 +156,74 @@ pub fn userlist_remove(config: Cfg, list_id: String, mod_id: String) -> Result<(
119} 156}
120 157
121 158
122#[derive(Debug, Clone)] 159pub fn userlist_get_applicable_versions(config: Cfg, list_id: String, mod_id: String) -> Result<String, Box<dyn std::error::Error>> {
123pub struct DBModlistVersions {
124 pub mod_id: String,
125 pub versions: String,
126}
127
128pub fn get_versions(config: Cfg, mods: Vec<String>) -> Result<Vec<DBModlistVersions>, Box<dyn std::error::Error>> {
129 /*
130 let data = format!("{}/data.db", config.data); 160 let data = format!("{}/data.db", config.data);
131 let connection = sqlite::open(data).unwrap(); 161 let connection = Connection::open(data).unwrap();
132 162
133 let mut wherestr = String::from("WHERE"); 163 let mut version: String = String::new();
134 for (i, id) in mods.iter().enumerate() { 164 let mut stmt = connection.prepare(format!("SELECT applicable_versions FROM {} WHERE mod_id = ?", list_id).as_str())?;
135 let mut or = " OR"; 165 let ver_iter = stmt.query_map([mod_id], |row| {
136 if i == mods.len() - 1 { or = "" } 166 row.get::<usize, String>(0)
137 println!("Pushing {}({}) | OR: '{}'", id, i, or); 167 })?;
138 wherestr = format!("{} id = '{}'{}", wherestr, id, or);
139 }
140 168
141 let sql = format!("SELECT id, versions FROM mods {}", wherestr); 169 for ver in ver_iter {
170 println!("Found id {:?}", ver);
171 version = ver?;
172 };
142 173
143 dbg!(&sql); 174 match version.is_empty() {
175 true => Err(Box::new(Error::new(ErrorKind::NotFound, "MOD_NOT_FOUND"))),
176 false => Ok(version),
177 }
178}
144 179
145 let mut versionmaps: Vec<DBModlistVersions> = Vec::new(); 180pub fn userlist_get_all_current_version_ids(config: Cfg, list_id: String) -> Result<Vec<String>, Box<dyn std::error::Error>> {
146 //TODO catch sql errors better 181 let data = format!("{}/data.db", config.data);
147 let mut cursor = connection.prepare(sql).unwrap().into_cursor(); 182 let connection = Connection::open(data)?;
148 183
149 while let Some(Ok(row)) = cursor.next() { 184 let mut versions: Vec<String> = Vec::new();
150 println!("{}: {}", row.get::<String, _>(0), row.get::<String, _>(1)); 185 let mut stmt = connection.prepare(format!("SELECT current_version FROM {}", list_id).as_str())?;
151 versionmaps.push(DBModlistVersions { mod_id: row.get::<String, _>(0), versions: row.get::<String, _>(1) }) 186 let id_iter = stmt.query_map([], |row| {
187 row.get::<usize, String>(0)
188 })?;
189
190 for id in id_iter {
191 versions.push(id?);
152 }; 192 };
153 193
154 if versionmaps.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); }; 194 if versions.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); };
155 195
156 Ok(versionmaps) 196 Ok(versions)
157 */
158 Ok(vec![DBModlistVersions { mod_id: String::new(), versions: String::new() }])
159} 197}
160 198
161pub fn get_list_version(config: Cfg, list: List, mod_id: String) -> Result<String, Box<dyn std::error::Error>> { 199pub fn userlist_change_versions(config: Cfg, list_id: String, current_version: String, versions: String, link: String, mod_id: String) -> Result<(), Box<dyn std::error::Error>> {
162 /*
163 let data = format!("{}/data.db", config.data); 200 let data = format!("{}/data.db", config.data);
164 let connection = sqlite::open(data).unwrap(); 201 let connection = Connection::open(data)?;
165
166 let sql = format!("SELECT applicable_versions FROM {} WHERE mod_id = '{}'", list.id, mod_id);
167
168 //TODO catch sql errors better
169 let mut version: String = String::new();
170 connection.iterate(sql, |ver| {
171 if ver.is_empty() { return false; };
172 for &(_column, value) in ver.iter() {
173 version = String::from(value.unwrap());
174 }
175 true
176 }).unwrap();
177
178 if version.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); };
179 202
180 Ok(version) 203 connection.execute(format!("UPDATE {} SET current_version = ?1, applicable_versions = ?2, current_download = ?3 WHERE mod_id = ?4", list_id).as_str(), [current_version, versions, link, mod_id])?;
181 */ 204 Ok(())
182 Ok(String::new())
183} 205}
184 206
207pub fn userlist_get_all_downloads(config: Cfg, list_id: String) -> Result<Vec<String>, Box<dyn std::error::Error>> {
208 let data = format!("{}/data.db", config.data);
209 let connection = Connection::open(data).unwrap();
210
211 let mut links: Vec<String> = Vec::new();
212 let mut stmt = connection.prepare(format!("SELECT current_download FROM {}", list_id).as_str())?;
213 let link_iter = stmt.query_map([], |row| {
214 row.get::<usize, String>(0)
215 })?;
216
217 for link in link_iter {
218 let l = link?;
219 println!("Found link {}", String::from(&l));
220 links.push(l)
221 };
222
223 if links.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); };
224
225 Ok(links)
226}
185 227
186//lists 228//lists
187pub fn lists_insert(config: Cfg, id: String, mc_version: String, mod_loader: Modloader) -> Result<(), Box<dyn std::error::Error>> { 229pub fn lists_insert(config: Cfg, id: String, mc_version: String, mod_loader: Modloader) -> Result<(), Box<dyn std::error::Error>> {
@@ -196,222 +238,134 @@ pub fn lists_insert(config: Cfg, id: String, mc_version: String, mod_loader: Mod
196 Ok(()) 238 Ok(())
197} 239}
198 240
199pub fn remove_list(config: Cfg, id: String) -> Result<(), Box<dyn std::error::Error>> { 241pub fn lists_remove(config: Cfg, id: String) -> Result<(), Box<dyn std::error::Error>> {
200 /*
201 let data = format!("{}/data.db", config.data); 242 let data = format!("{}/data.db", config.data);
202 let connection = sqlite::open(data).unwrap(); 243 let connection = Connection::open(data)?;
203
204 let sql_list = format!("DELETE FROM lists WHERE id = '{}'", id);
205 let sql_table = format!("DROP TABLE '{}'", id);
206 let sql = format!("{};{};", sql_list, sql_table);
207 244
208 connection.execute(sql) 245 connection.execute("DELETE FROM lists WHERE id = ?", [&id])?;
209 */ 246 connection.execute(format!("DROP TABLE {}", id).as_str(), [])?;
210 Ok(()) 247 Ok(())
211} 248}
212 249
213pub fn get_lists(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>> { 250pub fn lists_get(config: Cfg, list_id: String) -> Result<List, Box<dyn std::error::Error>> {
214 /*
215 let data = format!("{}/data.db", config.data); 251 let data = format!("{}/data.db", config.data);
216 let connection = sqlite::open(data).unwrap(); 252 let connection = Connection::open(data).unwrap();
217
218 let sql = "SELECT id FROM lists";
219
220 let mut list: Vec<String> = Vec::new();
221 //TODO catch sql errors better
222 connection.iterate(sql, |ids| {
223 if ids.is_empty() { return false; };
224 for &(_column, value) in ids.iter() {
225 list.push(String::from(value.unwrap()));
226 }
227 true
228 }).unwrap();
229 match list.is_empty() {
230 true => Err(Box::new(std::io::Error::new(ErrorKind::NotFound, "NO_LISTS"))),
231 false => Ok(list),
232 }
233 */
234 Ok(vec![String::new()])
235}
236
237pub fn get_current_versions(config: Cfg, list: List) -> Result<Vec<String>, Box<std::io::Error>> {
238 /*
239 let data = format!("{}/data.db", config.data);
240 let connection = sqlite::open(data).unwrap();
241
242 let sql = format!("SELECT current_version FROM {}", list.id);
243 253
244 dbg!(&sql); 254 let mut list = List { id: String::new(), mc_version: String::new(), modloader: Modloader::Fabric };
255 let mut stmt = connection.prepare("SELECT mc_version, modloader FROM lists WHERE id = ?")?;
245 256
246 let mut versions: Vec<String> = Vec::new(); 257 let list_iter = stmt.query_map([&list_id], |row| {
247 //TODO catch sql errors better 258 Ok(vec![row.get::<usize, String>(0)?, row.get::<usize, String>(1)?])
248 let mut cursor = connection.prepare(sql).unwrap().into_cursor(); 259 })?;
249 260
250 while let Some(Ok(row)) = cursor.next() { 261 for l in list_iter {
251 versions.push(row.get::<String, _>(0)); 262 let li = l?;
263 list = List { id: String::from(&list_id), mc_version: String::from(&li[0]), modloader: get_modloader(String::from(&li[1]))? };
252 }; 264 };
253 265
254 if versions.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); }; 266 if list.id.is_empty() { return Err(Box::new(Error::new(ErrorKind::Other, "LIST_NOT_FOUND"))); }
255
256 Ok(versions)
257 */
258 Ok(vec![String::new()])
259}
260
261pub fn get_list(config: Cfg, id: String) -> Result<List, Box<dyn std::error::Error>> {
262 /*
263 let data = format!("{}/data.db", config.data);
264 let connection = sqlite::open(data).unwrap();
265
266 let sql = format!("SELECT mc_version, modloader FROM lists WHERE id = '{}'", id);
267 267
268 let mut list = vec![]; 268 Ok(list)
269 //TODO catch sql errors better
270 connection.iterate(sql, |ids| {
271 if ids.is_empty() { return false; };
272 for &(_column, value) in ids.iter() {
273 list.push(String::from(value.unwrap()));
274 }
275 true
276 }).unwrap();
277
278 if list.len() != 2 { return Err(Box::new(std::io::Error::new(ErrorKind::InvalidData, "LIST_MISSING_DATA"))) };
279
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 })
283} 269}
284 270
285pub fn change_list_versions(config: Cfg, list: List, current_version: String, versions: Vec<String>, mod_id: String) -> Result<(), Box<dyn std::error::Error>> { 271pub fn lists_get_all_ids(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>> {
286 /*
287 let data = format!("{}/data.db", config.data); 272 let data = format!("{}/data.db", config.data);
288 let connection = sqlite::open(data).unwrap(); 273 let connection = Connection::open(data).unwrap();
274
275 let mut list_ids: Vec<String> = Vec::new();
276 let mut stmt = connection.prepare("SELECT id FROM lists")?;
277 let id_iter = stmt.query_map([], |row| {
278 row.get::<usize, String>(0)
279 })?;
289 280
290 let sql = format!("UPDATE {} SET current_version = '{}', applicable_versions = '{}' WHERE mod_id = '{}'", list.id, current_version, versions.join("|"), mod_id); 281 for id in id_iter {
282 println!("Found id {:?}", id.as_ref().unwrap());
283 list_ids.push(id?)
284 };
291 285
292 connection.execute(sql) 286 match list_ids.is_empty() {
293 */ 287 true => Err(Box::new(std::io::Error::new(ErrorKind::NotFound, "NO_LISTS"))),
294 Ok(()) 288 false => Ok(list_ids),
289 }
295} 290}
296 291
297//DOWNLOAD 292//config
298 293pub fn config_change_current_list(config: Cfg, id: String) -> Result<(), Box<dyn std::error::Error>> {
299pub fn insert_dl_link(config: Cfg, list: List, mod_id: String, link: String) -> Result<(), Box<dyn std::error::Error>> {
300 /*
301 let data = format!("{}/data.db", config.data); 294 let data = format!("{}/data.db", config.data);
302 let connection = sqlite::open(data).unwrap(); 295 let connection = Connection::open(data)?;
303
304 let sql = format!("UPDATE {} SET current_download = '{}' WHERE mod_id = '{}'", list.id, link, mod_id);
305 296
306 connection.execute(sql) 297 connection.execute("UPDATE user_config SET value = ? WHERE id = 'current_list'", [id])?;
307 */
308 Ok(()) 298 Ok(())
309} 299}
310 300
311pub fn get_dl_links(config: Cfg, list: List) -> Result<Vec<String>, Box<std::io::Error>> { 301pub fn config_get_current_list(config: Cfg) -> Result<String, Box<dyn std::error::Error>> {
312 /*
313 let data = format!("{}/data.db", config.data); 302 let data = format!("{}/data.db", config.data);
314 let connection = sqlite::open(data).unwrap(); 303 let connection = Connection::open(data).unwrap();
315 304
316 let sql = format!("SELECT current_download FROM {}", list.id); 305 let mut list_id = String::new();
317 306 let mut stmt = connection.prepare("SELECT value FROM user_config WHERE id = 'current_list'")?;
318 dbg!(&sql); 307 let list_iter = stmt.query_map([], |row| {
319 308 row.get::<usize, String>(0)
320 let mut links: Vec<String> = Vec::new(); 309 })?;
321 //TODO catch sql errors better
322 let mut cursor = connection.prepare(sql).unwrap().into_cursor();
323 310
324 while let Some(Ok(row)) = cursor.next() { 311 for list in list_iter {
325 links.push(row.get::<String, _>(0)); 312 list_id = list?;
326 }; 313 };
327 314
328 if links.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); }; 315 if list_id.is_empty() { return Err(Box::new(Error::new(ErrorKind::Other, "NO_CURRENT_LIST"))); }
329 316
330 Ok(links) 317 Ok(list_id)
331 */
332 Ok(vec![String::new()])
333} 318}
334 319
335//config 320//SETUP(UPDATES)
336pub fn change_list(config: Cfg, id: String) -> Result<(), Box<dyn std::error::Error>> { 321pub fn s_userlist_update_download(config: Cfg, list_id: String, mod_id: String, link: String) -> Result<(), Box<dyn std::error::Error>> {
337 /*
338 let data = format!("{}/data.db", config.data); 322 let data = format!("{}/data.db", config.data);
339 let connection = sqlite::open(data).unwrap(); 323 let connection = Connection::open(data)?;
340
341 let sql = format!("UPDATE user_config SET value = '{}' WHERE id = 'current_list'", id);
342 324
343 connection.execute(sql) 325 connection.execute(format!("UPDATE {} SET current_download = ?1 WHERE mod_id = ?2", list_id).as_str(), [link, mod_id])?;
344 */
345 Ok(()) 326 Ok(())
346} 327}
347 328
348pub fn get_current_list_id(config: Cfg) -> Result<String, Box<dyn std::error::Error>> { 329pub fn s_config_create_version(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
349 /*
350 let data = format!("{}/data.db", config.data); 330 let data = format!("{}/data.db", config.data);
351 let connection = sqlite::open(data).unwrap(); 331 let connection = Connection::open(data)?;
352 332
353 let sql = "SELECT id FROM lists"; 333 connection.execute("INSERT INTO 'user_config' VALUES ( 'db_version', '0.2' )", ())?;
354 334 Ok(())
355 let mut list: String = String::new();
356 //TODO catch sql errors better
357 connection.iterate(sql, |ids| {
358 if ids.is_empty() { return false; };
359 for &(_column, value) in ids.iter() {
360 list = String::from(value.unwrap());
361 }
362 true
363 }).unwrap();
364 if list.is_empty() {
365 get_lists(config)?;
366 panic!("current list field should never be empty if there are other lists");
367 };
368 Ok(list)
369 */
370 Ok(String::new())
371} 335}
372 336
373pub fn update_dbversion(config: Cfg, ver: String) -> Result<(), Box<dyn std::error::Error>> { 337pub fn s_config_update_version(config: Cfg, ver: String) -> Result<(), Box<dyn std::error::Error>> {
374 /*
375 let data = format!("{}/data.db", config.data); 338 let data = format!("{}/data.db", config.data);
376 let connection = sqlite::open(data).unwrap(); 339 let connection = Connection::open(data)?;
377
378 let sql = format!("UPDATE user_config SET value = '{}' WHERE id = 'db_version'", ver);
379 340
380 connection.execute(sql) 341 connection.execute("UPDATE user_config SET value = ? WHERE id = 'db_version'", [ver])?;
381 */
382 Ok(()) 342 Ok(())
383} 343}
384 344
385pub fn create_dbversion(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { 345pub fn s_config_get_version(config: Cfg) -> Result<String, Box<dyn std::error::Error>> {
386 /*
387 let data = format!("{}/data.db", config.data); 346 let data = format!("{}/data.db", config.data);
388 let connection = sqlite::open(data).unwrap(); 347 let connection = Connection::open(data)?;
389 let sql = "INSERT INTO 'user_config' VALUES ( 'db_version', '0.2' );"; 348
390 connection.execute(sql) 349 let mut version: String = String::new();
391 */ 350 let mut stmt = connection.prepare("SELECT value FROM user_config WHERE id = 'db_version'")?;
392 Ok(()) 351 let ver_iter = stmt.query_map([], |row| {
352 row.get::<usize, String>(0)
353 })?;
354
355 for ver in ver_iter {
356 version = ver?;
357 };
358
359 if version.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_DBVERSION"))); };
360 Ok(version)
393} 361}
394 362
395pub fn user_dbversion(config: Cfg) -> Result<String, Box<dyn std::error::Error>> { 363pub fn s_insert_column(config: Cfg, table: String, column: String, c_type: String) -> Result<(), Box<dyn std::error::Error>> {
396 /*
397 let data = format!("{}/data.db", config.data); 364 let data = format!("{}/data.db", config.data);
398 let connection = sqlite::open(data).unwrap(); 365 let connection = Connection::open(data)?;
399 366
400 let sql = "SELECT db_version FROM user_config"; 367 connection.execute(format!("ALTER TABLE {} ADD '{}' {}", table, column, c_type).as_str(), ())?;
401 368 Ok(())
402 let mut ver: String = String::new();
403 //TODO catch sql errors better
404 connection.iterate(sql, |ids| {
405 if ids.is_empty() { return false; };
406 for &(_column, value) in ids.iter() {
407 ver = String::from(value.unwrap());
408 }
409 true
410 })?;
411 if ver.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_DBVERSION"))); };
412 Ok(ver)
413 */
414 Ok(String::from("0.2"))
415} 369}
416 370
417pub fn db_setup(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { 371pub fn db_setup(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
@@ -432,21 +386,3 @@ pub fn db_setup(config: Cfg) -> Result<(), Box<dyn std::error::Error>> {
432 Ok(()) 386 Ok(())
433} 387}
434 388
435pub fn insert_column(config: Cfg, table: String, column: String, c_type: String) -> Result<(), Box<dyn std::error::Error>> {
436 /*
437 let data = format!("{}/data.db", config.data);
438 let connection = sqlite::open(data).unwrap();
439
440 let ct = match c_type {
441 sqlite::Type::Null => "NULL",
442 sqlite::Type::Float => "FLOAT",
443 sqlite::Type::Binary => "BINARY",
444 sqlite::Type::String => "TEXT",
445 sqlite::Type::Integer => "INT",
446 };
447
448 let sql = format!("ALTER TABLE {} ADD '{}' {}", table, column, ct);
449 connection.execute(sql)
450 */
451 Ok(())
452}
diff --git a/src/lib.rs b/src/lib.rs
index e059293..1e7ebbf 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,7 +9,7 @@ use std::io::{Error, ErrorKind};
9pub use apis::*; 9pub use apis::*;
10pub use commands::*; 10pub use commands::*;
11 11
12#[derive(Debug, Clone)] 12#[derive(Debug, Clone, PartialEq, Eq)]
13pub enum Modloader { 13pub enum Modloader {
14 Fabric, 14 Fabric,
15 Forge 15 Forge
diff --git a/tests/db.rs b/tests/db.rs
new file mode 100644
index 0000000..16061d0
--- /dev/null
+++ b/tests/db.rs
@@ -0,0 +1,248 @@
1use std::{fs::{File, create_dir_all}, path::Path, sync::Once};
2
3use modlist::{config::{Cfg, Apis}, db::{mods_insert, db_setup, mods_get_all_ids, mods_get_id, mods_remove, userlist_insert, lists_insert, userlist_get_all_ids, userlist_remove, mods_get_versions, userlist_get_applicable_versions, lists_remove, lists_get, lists_get_all_ids, userlist_get_all_current_version_ids, userlist_change_versions, s_userlist_update_download, userlist_get_all_downloads, config_change_current_list, config_get_current_list, s_config_update_version, s_config_create_version, s_config_get_version}, Modloader, List};
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_mods_insert() {
25 let config = setup();
26
27 mods_insert(config.clone(), String::from("I"), String::from("INSERT_TEST"), vec![String::from("INSERT_VER1"), String::from("INSERT_VER2")]).unwrap();
28 let ids = mods_get_all_ids(config).unwrap();
29
30 assert!(ids.contains(&String::from("I")));
31}
32
33#[test]
34fn test_mods_get_all_ids() {
35 let config = setup();
36
37 mods_insert(config.clone(), String::from("GAI1"), String::from("GETALLIDS_TEST1"), vec![String::from("GAI1_VER1"), String::from("GAI1_VER2")]).unwrap();
38 mods_insert(config.clone(), String::from("GAI2"), String::from("GETALLIDS_TEST2"), vec![String::from("GAI2_VER1"), String::from("GAI2_VER2")]).unwrap();
39 let ids = mods_get_all_ids(config).unwrap();
40
41 assert!(ids.contains(&String::from("GAI1")));
42 assert!(ids.contains(&String::from("GAI2")));
43}
44
45#[test]
46fn test_mods_get_id() {
47 let config = setup();
48
49 mods_insert(config.clone(), String::from("GI"), String::from("GETID_TEST"), vec![String::from("GI_VER1"), String::from("GI_VER2")]).unwrap();
50}
51
52#[test]
53fn test_mods_remove() {
54 let config = setup();
55
56 mods_insert(config.clone(), String::from("R"), String::from("REMOVE_TEST"), vec![String::from("R_VER1"), String::from("R_VER2")]).unwrap();
57 let ids = mods_get_all_ids(config.clone()).unwrap();
58 assert!(ids.contains(&String::from("R")));
59 mods_remove(config.clone(), String::from("R")).unwrap();
60 assert!(mods_get_id(config, String::from("REMOVE_TEST")).is_err());
61}
62
63#[test]
64fn test_mods_get_versions() {
65 let config = setup();
66
67 mods_insert(config.clone(), String::from("M_GVs1"), String::from("M_GVs_TEST1"), vec![String::from("M_GVs1_VER1"), String::from("M_GVs1_VER2")]).unwrap();
68 mods_insert(config.clone(), String::from("M_GVs2"), String::from("M_GVs_TEST2"), vec![String::from("M_GVs2_VER1"), String::from("M_GVs2_VER2")]).unwrap();
69 let versions = mods_get_versions(config, vec![String::from("M_GVs1"), String::from("M_GVs2")]).unwrap();
70
71 assert!(versions.contains(&modlist::db::DBModlistVersions { mod_id: String::from("M_GVs1"), versions: String::from("M_GVs1_VER1|M_GVs1_VER2") }));
72 assert!(versions.contains(&modlist::db::DBModlistVersions { mod_id: String::from("M_GVs2"), versions: String::from("M_GVs2_VER1|M_GVs2_VER2") }));
73}
74
75//user_list
76#[test]
77fn test_userlist_insert() {
78 let config = setup();
79
80 lists_insert(config.clone(), String::from("UL_I_LIST"), String::from("UL_I_MC"), Modloader::Fabric).unwrap();
81 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();
82}
83
84#[test]
85fn test_userlist_get_all_ids() {
86 let config = setup();
87
88 lists_insert(config.clone(), String::from("UL_GAI_LIST"), String::from("UL_GAI_MC"), Modloader::Fabric).unwrap();
89 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();
90 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();
91 let ids = userlist_get_all_ids(config, String::from("UL_GAI_LIST")).unwrap();
92
93 assert!(ids.contains(&String::from("UL_GAI1")));
94 assert!(ids.contains(&String::from("UL_GAI2")));
95}
96
97#[test]
98fn test_userlist_remove() {
99 let config = setup();
100
101 lists_insert(config.clone(), String::from("UL_R_LIST"), String::from("UL_R_MC"), Modloader::Fabric).unwrap();
102 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();
103 let ids = userlist_get_all_ids(config.clone(), String::from("UL_R_LIST")).unwrap();
104 assert!(ids.contains(&String::from("UL_R")));
105 userlist_remove(config.clone(), String::from("UL_R_LIST"), String::from("UL_R")).unwrap();
106 assert!(userlist_get_all_ids(config, String::from("UL_R_LIST")).is_err())
107}
108
109#[test]
110fn test_userlist_get_applicable_versions() {
111 let config = setup();
112
113 lists_insert(config.clone(), String::from("UL_GAV_LIST"), String::from("UL_GAV_MC"), Modloader::Fabric).unwrap();
114 userlist_insert(config.clone(), String::from("UL_GAV_LIST"), String::from("UL_GAV"), String::from("UL_GAV_VER1"), vec![String::from("UL_GAV_VER1"), String::from("UL_GAV_VER2")], String::from("localhost:8080/dl/UL_GAV_VER1.test")).unwrap();
115 assert_eq!(userlist_get_applicable_versions(config, String::from("UL_GAV_LIST"), String::from("UL_GAV")).unwrap(), String::from("UL_GAV_VER1|UL_GAV_VER2"));
116}
117
118#[test]
119fn test_userlist_get_all_current_version_ids() {
120 let config = setup();
121
122 lists_insert(config.clone(), String::from("UL_GACVI_LIST"), String::from("UL_GACVI_MC"), Modloader::Fabric).unwrap();
123 userlist_insert(config.clone(), String::from("UL_GACVI_LIST"), String::from("UL_GACVI1"), String::from("UL_GACVI1_VER1"), vec![String::from("UL_GACVI2_VER1"), String::from("UL_GACVI1_VER2")], String::from("localhost:8080/dl/UL_GACVI1_VER1.test")).unwrap();
124 userlist_insert(config.clone(), String::from("UL_GACVI_LIST"), String::from("UL_GACVI2"), String::from("UL_GACVI2_VER1"), vec![String::from("UL_GACVI2_VER1"), String::from("UL_GACVI2_VER2")], String::from("localhost:8080/dl/UL_GACVI2_VER1.test")).unwrap();
125
126 let ids = userlist_get_all_current_version_ids(config, String::from("UL_GACVI_LIST")).unwrap();
127
128 assert!(ids.contains(&String::from("UL_GACVI1_VER1")));
129 assert!(ids.contains(&String::from("UL_GACVI2_VER1")));
130}
131
132#[test]
133fn test_userlist_change_versions() {
134 let config = setup();
135
136 lists_insert(config.clone(), String::from("UL_CV_LIST"), String::from("UL_CV_MC"), Modloader::Fabric).unwrap();
137 userlist_insert(config.clone(), String::from("UL_CV_LIST"), String::from("UL_CV"), String::from("UL_CV_VER1"), vec![String::from("UL_CV_VER1"), String::from("UL_CV_VER2")], String::from("localhost:8080/dl/UL_CV_VER1.test")).unwrap();
138 let versions = userlist_get_all_current_version_ids(config.clone(), String::from("UL_CV_LIST")).unwrap();
139 assert!(versions.contains(&String::from("UL_CV_VER1")));
140
141 userlist_change_versions(config.clone(), String::from("UL_CV_LIST"), String::from("UL_CV_VER3"), String::from("UL_CV_VER1|UL_CV_VER2|UL_CV_VER3"), String::from("localhost:8080/dl/UL_CV_VER3.test"), String::from("UL_CV")).unwrap();
142 let versions = userlist_get_all_current_version_ids(config, String::from("UL_CV_LIST")).unwrap();
143 assert!(!versions.contains(&String::from("UL_CV_VER1")));
144 assert!(versions.contains(&String::from("UL_CV_VER3")));
145}
146
147#[test]
148fn test_userlist_get_all_downloads() {
149 let config = setup();
150
151 lists_insert(config.clone(), String::from("UL_GAD_LIST"), String::from("UL_GAD_MC"), Modloader::Fabric).unwrap();
152 userlist_insert(config.clone(), String::from("UL_GAD_LIST"), String::from("UL_GAD1"), String::from("UL_GAD1_VER1"), vec![String::from("UL_GAD1_VER1"), String::from("UL_GAD1_VER1")], String::from("localhost:8080/dl/UL_GAD1_VER1.test")).unwrap();
153 userlist_insert(config.clone(), String::from("UL_GAD_LIST"), String::from("UL_GAD2"), String::from("UL_GAD2_VER1"), vec![String::from("UL_GAD2_VER1"), String::from("UL_GAD2_VER1")], String::from("localhost:8080/dl/UL_GAD2_VER1.test")).unwrap();
154 let links = userlist_get_all_downloads(config, String::from("UL_GAD_LIST")).unwrap();
155
156 assert!(links.contains(&String::from("localhost:8080/dl/UL_GAD1_VER1.test")));
157 assert!(links.contains(&String::from("localhost:8080/dl/UL_GAD2_VER1.test")));
158}
159
160
161//lists
162#[test]
163fn test_lists_insert() {
164 let config = setup();
165
166 lists_insert(config, String::from("L_I_LIST"), String::from("L_I_MC"), Modloader::Fabric).unwrap();
167}
168
169#[test]
170fn test_lists_remove() {
171 let config = setup();
172
173 lists_insert(config.clone(), String::from("L_R_LIST"), String::from("L_R_MC"), Modloader::Fabric).unwrap();
174 lists_remove(config, String::from("L_R_LIST")).unwrap();
175}
176
177#[test]
178fn test_lists_get() {
179 let config = setup();
180
181 lists_insert(config.clone(), String::from("L_G_LIST"), String::from("L_G_MC"), Modloader::Fabric).unwrap();
182
183 assert_eq!(lists_get(config, String::from("L_G_LIST")).unwrap(), List { id: String::from("L_G_LIST"), mc_version: String::from("L_G_MC"), modloader: Modloader::Fabric });
184}
185
186#[test]
187fn test_lists_get_all_ids() {
188 let config = setup();
189
190 lists_insert(config.clone(), String::from("L_GAI1_LIST"), String::from("L_GAI1_MC"), Modloader::Fabric).unwrap();
191 lists_insert(config.clone(), String::from("L_GAI2_LIST"), String::from("L_GAI2_MC"), Modloader::Fabric).unwrap();
192 let ids = lists_get_all_ids(config).unwrap();
193
194 assert!(ids.contains(&String::from("L_GAI1_LIST")));
195 assert!(ids.contains(&String::from("L_GAI2_LIST")));
196}
197
198//config
199#[test]
200fn test_config_change_current_list() {
201 let config = setup();
202
203 config_change_current_list(config, String::from("C_CCL_LIST")).unwrap();
204}
205
206#[test]
207fn test_config_get_current_list() {
208 let config = setup();
209
210 config_change_current_list(config.clone(), String::from("C_GCL_LIST")).unwrap();
211 assert_eq!(config_get_current_list(config).unwrap(), String::from("C_GCL_LIST"));
212}
213
214//setup
215#[test]
216fn test_s_userlist_update_download() {
217 let config = setup();
218
219 lists_insert(config.clone(), String::from("UL_UD_LIST"), String::from("UL_UD_MC"), Modloader::Fabric).unwrap();
220 userlist_insert(config.clone(), String::from("UL_UD_LIST"), String::from("UL_UD"), String::from("UL_UD_VER1"), vec![String::from("UL_UD_VER1"), String::from("UL_UD_VER1")], String::from("localhost:8080/dl/UL_UD_VER1.test")).unwrap();
221 s_userlist_update_download(config.clone(), String::from("UL_UD_LIST"), String::from("UL_UD"), String::from("localhost:8080/dl/UL_UD_VER1X.test")).unwrap();
222 let links = userlist_get_all_downloads(config, String::from("UL_UD_LIST")).unwrap();
223
224 assert!(links.contains(&String::from("localhost:8080/dl/UL_UD_VER1X.test")));
225 assert!(!links.contains(&String::from("localhost:8080/dl/UL_UD_VER1.test")));
226}
227
228#[test]
229fn test_s_config_create_version() {
230 let config = setup();
231
232 s_config_create_version(config).unwrap();
233}
234
235#[test]
236fn test_s_config_update_version() {
237 let config = setup();
238
239 s_config_update_version(config, String::from("S_C_UV")).unwrap();
240}
241
242#[test]
243fn test_s_config_get_version() {
244 let config = setup();
245
246 s_config_update_version(config.clone(), String::from("S_C_GV")).unwrap();
247 assert_eq!(s_config_get_version(config).unwrap(), String::from("S_C_GV"));
248}
diff --git a/tests/db_integration.rs b/tests/db_integration.rs
deleted file mode 100644
index 8c3d194..0000000
--- a/tests/db_integration.rs
+++ /dev/null
@@ -1,115 +0,0 @@
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}
97
98#[test]
99fn test_userlist_remove() {
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();
115}