summaryrefslogtreecommitdiff
path: root/src
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 /src
parentc33b8be79e8cfac9e2fa76c1f63c85e020cdf4a0 (diff)
downloadmodlist-ea50af892c4268ae06f6df40ee435eadd076228d.tar
modlist-ea50af892c4268ae06f6df40ee435eadd076228d.tar.gz
modlist-ea50af892c4268ae06f6df40ee435eadd076228d.zip
halfswitch to rusqlite; db tests
Diffstat (limited to 'src')
-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
5 files changed, 203 insertions, 142 deletions
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}