diff options
author | fxqnlr <[email protected]> | 2022-11-03 21:34:04 +0100 |
---|---|---|
committer | fxqnlr <[email protected]> | 2022-11-03 21:34:04 +0100 |
commit | 96cc5257de09682df345e768dc2a91303f9b36c9 (patch) | |
tree | f505d14c581e2bef4cfe222bd1069661bedd22e0 /src/db.rs | |
parent | b125dfd03084fff47ab8e90d002c6699b762d998 (diff) | |
download | modlist-96cc5257de09682df345e768dc2a91303f9b36c9.tar modlist-96cc5257de09682df345e768dc2a91303f9b36c9.tar.gz modlist-96cc5257de09682df345e768dc2a91303f9b36c9.zip |
added update beginnings; init of tests
Diffstat (limited to 'src/db.rs')
-rw-r--r-- | src/db.rs | 183 |
1 files changed, 166 insertions, 17 deletions
@@ -1,36 +1,164 @@ | |||
1 | use std::io::ErrorKind; | 1 | use std::io::ErrorKind; |
2 | 2 | ||
3 | use crate::{Modloader, config::Cfg}; | 3 | use crate::{Modloader, config::Cfg, List, modrinth::Version, get_modloader}; |
4 | 4 | ||
5 | //TODO use prepared statements | 5 | //TODO use prepared statements |
6 | 6 | ||
7 | pub fn insert_mod(id: String, name: String, current_version: String, old_versions: Vec<String>, mod_loader: Modloader, desired_mc_version: String) -> Result<(), sqlite::Error> { | 7 | //MODS |
8 | pub fn insert_mod(config: Cfg, id: String, name: String, versions: Vec<String>) -> Result<(), sqlite::Error> { | ||
8 | 9 | ||
9 | let connection = sqlite::open("./data.db").unwrap(); | 10 | println!("Inserting into modlist"); |
10 | 11 | ||
11 | let loader = match mod_loader { | 12 | let data = format!("{}/data.db", config.data); |
12 | Modloader::Fabric => "fabric", | 13 | let connection = sqlite::open(data).unwrap(); |
13 | Modloader::Forge => "forge", | 14 | |
14 | }; | 15 | let sql = format!("INSERT INTO mods VALUES ('{}', '{}', '{}')", id, name, versions.join("|")); |
16 | |||
17 | connection.execute(sql) | ||
18 | } | ||
19 | |||
20 | pub fn insert_mod_in_list(config: Cfg, list: List, id: String, current_version: String, applicable_versions: Vec<Version>) -> Result<(), sqlite::Error> { | ||
21 | |||
22 | println!("Inserting into current list"); | ||
23 | |||
24 | let data = format!("{}/data.db", config.data); | ||
25 | let connection = sqlite::open(data).unwrap(); | ||
26 | |||
27 | let mut applicable_versions_vec = vec![]; | ||
28 | |||
29 | for ver in applicable_versions { | ||
30 | applicable_versions_vec.push(ver.id); | ||
31 | } | ||
32 | |||
33 | let sql = format!("INSERT INTO {} VALUES ('{}', '{}', '{}')", list.id, id, current_version, applicable_versions_vec.join("|")); | ||
34 | |||
35 | connection.execute(sql) | ||
36 | } | ||
37 | |||
38 | pub fn remove_mod_from_list(config: Cfg, list: List, mod_id: String) -> Result<(), sqlite::Error> { | ||
39 | let data = format!("{}/data.db", config.data); | ||
40 | let connection = sqlite::open(data).unwrap(); | ||
41 | |||
42 | let sql = format!("DELETE FROM {} WHERE mod_id = '{}'", list.id, mod_id); | ||
15 | 43 | ||
16 | let sql = format!("INSERT INTO mods VALUES ('{}', '{}', '{}', '{}', '{}', '{}')", id, name, current_version, old_versions.join("|"), loader, desired_mc_version); | 44 | dbg!(&sql); |
17 | 45 | ||
18 | connection.execute(sql) | 46 | connection.execute(sql) |
19 | } | 47 | } |
20 | 48 | ||
21 | //LIST | 49 | pub fn get_mods(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>> { |
22 | pub fn insert_list(config: Cfg, id: String, mc_version: String, mod_loader: Modloader) -> Result<(), sqlite::Error> { | 50 | |
23 | let data = format!("{}/data.db", config.data); | 51 | let data = format!("{}/data.db", config.data); |
24 | let connection = sqlite::open(data).unwrap(); | 52 | let connection = sqlite::open(data).unwrap(); |
53 | |||
54 | let sql = "SELECT id FROM mods"; | ||
25 | 55 | ||
26 | //Setup list in table | 56 | let mut mods: Vec<String> = Vec::new(); |
27 | let loader = match mod_loader { | 57 | //TODO catch sql errors better |
28 | Modloader::Fabric => "fabric", | 58 | connection.iterate(sql, |ids| { |
29 | Modloader::Forge => "forge", | 59 | if ids.is_empty() { return false; }; |
60 | for &(_column, value) in ids.iter() { | ||
61 | mods.push(String::from(value.unwrap())); | ||
62 | } | ||
63 | true | ||
64 | }).unwrap(); | ||
65 | match mods.is_empty() { | ||
66 | true => Err(Box::new(std::io::Error::new(ErrorKind::NotFound, "NO_MODS"))), | ||
67 | false => Ok(mods), | ||
68 | } | ||
69 | } | ||
70 | |||
71 | pub fn get_mods_from_list(config: Cfg, list: List) -> Result<Vec<String>, Box<dyn std::error::Error>> { | ||
72 | let data = format!("{}/data.db", config.data); | ||
73 | let connection = sqlite::open(data).unwrap(); | ||
74 | |||
75 | let sql = format!("SELECT mod_id FROM {}", list.id); | ||
76 | |||
77 | let mut mods: Vec<String> = Vec::new(); | ||
78 | //TODO catch sql errors better | ||
79 | connection.iterate(sql, |ids| { | ||
80 | if ids.is_empty() { return false; }; | ||
81 | for &(_column, value) in ids.iter() { | ||
82 | mods.push(String::from(value.unwrap())); | ||
83 | } | ||
84 | true | ||
85 | }).unwrap(); | ||
86 | match mods.is_empty() { | ||
87 | true => Err(Box::new(std::io::Error::new(ErrorKind::NotFound, "NO_MODS"))), | ||
88 | false => Ok(mods), | ||
89 | } | ||
90 | } | ||
91 | |||
92 | pub fn get_mod_id(config: Cfg, name: String) -> Result<String, Box<dyn std::error::Error>> { | ||
93 | let data = format!("{}/data.db", config.data); | ||
94 | let connection = sqlite::open(data).unwrap(); | ||
95 | |||
96 | let sql = format!("SELECT id FROM mods WHERE name = '{}'", name); | ||
97 | |||
98 | dbg!(&sql); | ||
99 | |||
100 | let mut modification = String::new(); | ||
101 | //TODO catch sql errors better | ||
102 | connection.iterate(sql, |id| { | ||
103 | if id.is_empty() { return false; }; | ||
104 | for &(_column, value) in id.iter() { | ||
105 | dbg!(&(_column, value)); | ||
106 | modification = String::from(value.unwrap()); | ||
107 | } | ||
108 | true | ||
109 | }).unwrap(); | ||
110 | |||
111 | dbg!(&modification); | ||
112 | |||
113 | if modification.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::NotFound, "MOD_NOT_IN_DATABASE"))) }; | ||
114 | |||
115 | Ok(modification) | ||
116 | } | ||
117 | |||
118 | #[derive(Debug, Clone)] | ||
119 | pub struct DBModlistVersions { | ||
120 | pub mod_id: String, | ||
121 | pub versions: String, | ||
122 | } | ||
123 | |||
124 | pub fn get_versions(config: Cfg, mods: Vec<String>) -> Result<Vec<DBModlistVersions>, Box<dyn std::error::Error>> { | ||
125 | let data = format!("{}/data.db", config.data); | ||
126 | let connection = sqlite::open(data).unwrap(); | ||
127 | |||
128 | let mut wherestr = String::from("WHERE"); | ||
129 | for (i, id) in mods.iter().enumerate() { | ||
130 | let mut or = " OR"; | ||
131 | if i == mods.len() - 1 { or = "" } | ||
132 | println!("Pushing {}({}) | OR: '{}'", id, i, or); | ||
133 | wherestr = format!("{} id = '{}'{}", wherestr, id, or); | ||
134 | } | ||
135 | |||
136 | let sql = format!("SELECT id, versions FROM mods {}", wherestr); | ||
137 | |||
138 | dbg!(&sql); | ||
139 | |||
140 | let mut versionmaps: Vec<DBModlistVersions> = Vec::new(); | ||
141 | //TODO catch sql errors better | ||
142 | let mut cursor = connection.prepare(sql).unwrap().into_cursor(); | ||
143 | |||
144 | while let Some(Ok(row)) = cursor.next() { | ||
145 | println!("{}: {}", row.get::<String, _>(0), row.get::<String, _>(1)); | ||
146 | versionmaps.push(DBModlistVersions { mod_id: row.get::<String, _>(0), versions: row.get::<String, _>(1) }) | ||
30 | }; | 147 | }; |
31 | 148 | ||
32 | let sql_list = format!("INSERT INTO lists VALUES ('{}', '{}', '{}')", id, mc_version, loader); | 149 | if versionmaps.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); }; |
33 | let sql_table = format!("CREATE TABLE '{}' ( 'mod_id' TEXT, 'current_version' TEXT, 'applicable_versions' BLOB, 'mod_loader' TEXT )", id); | 150 | |
151 | Ok(versionmaps) | ||
152 | } | ||
153 | |||
154 | |||
155 | //LIST | ||
156 | pub fn insert_list(config: Cfg, id: String, mc_version: String, mod_loader: Modloader) -> Result<(), sqlite::Error> { | ||
157 | let data = format!("{}/data.db", config.data); | ||
158 | let connection = sqlite::open(data).unwrap(); | ||
159 | |||
160 | let sql_list = format!("INSERT INTO lists VALUES ('{}', '{}', '{}')", id, mc_version, mod_loader.stringify()); | ||
161 | let sql_table = format!("CREATE TABLE '{}' ( 'mod_id' TEXT, 'current_version' TEXT, 'applicable_versions' BLOB)", id); | ||
34 | let sql = format!("{};{};", sql_list, sql_table); | 162 | let sql = format!("{};{};", sql_list, sql_table); |
35 | 163 | ||
36 | connection.execute(sql) | 164 | connection.execute(sql) |
@@ -68,6 +196,27 @@ pub fn get_lists(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>> | |||
68 | } | 196 | } |
69 | } | 197 | } |
70 | 198 | ||
199 | pub fn get_list(config: Cfg, id: String) -> Result<List, Box<dyn std::error::Error>> { | ||
200 | let data = format!("{}/data.db", config.data); | ||
201 | let connection = sqlite::open(data).unwrap(); | ||
202 | |||
203 | let sql = format!("SELECT mc_version, modloader FROM lists WHERE id = '{}'", id); | ||
204 | |||
205 | let mut list = vec![]; | ||
206 | //TODO catch sql errors better | ||
207 | connection.iterate(sql, |ids| { | ||
208 | if ids.is_empty() { return false; }; | ||
209 | for &(_column, value) in ids.iter() { | ||
210 | list.push(String::from(value.unwrap())); | ||
211 | } | ||
212 | true | ||
213 | }).unwrap(); | ||
214 | |||
215 | if list.len() != 2 { return Err(Box::new(std::io::Error::new(ErrorKind::InvalidData, "LIST_MISSING_DATA"))) }; | ||
216 | |||
217 | Ok(List { id, mc_version: String::from(&list[0]), modloader: get_modloader(String::from(&list[1]))? }) | ||
218 | } | ||
219 | |||
71 | //config | 220 | //config |
72 | pub fn change_list(config: Cfg, id: String) -> Result<(), sqlite::Error> { | 221 | pub fn change_list(config: Cfg, id: String) -> Result<(), sqlite::Error> { |
73 | let data = format!("{}/data.db", config.data); | 222 | let data = format!("{}/data.db", config.data); |
@@ -78,7 +227,7 @@ pub fn change_list(config: Cfg, id: String) -> Result<(), sqlite::Error> { | |||
78 | connection.execute(sql) | 227 | connection.execute(sql) |
79 | } | 228 | } |
80 | 229 | ||
81 | pub fn get_current_list(config: Cfg) -> Result<String, Box<dyn std::error::Error>> { | 230 | pub fn get_current_list_id(config: Cfg) -> Result<String, Box<dyn std::error::Error>> { |
82 | let data = format!("{}/data.db", config.data); | 231 | let data = format!("{}/data.db", config.data); |
83 | let connection = sqlite::open(data).unwrap(); | 232 | let connection = sqlite::open(data).unwrap(); |
84 | 233 | ||