diff options
-rw-r--r-- | data.db | bin | 36864 -> 24576 bytes | |||
-rw-r--r-- | src/apis/modrinth.rs | 10 | ||||
-rw-r--r-- | src/commands/download.rs | 46 | ||||
-rw-r--r-- | src/commands/mod.rs | 4 | ||||
-rw-r--r-- | src/commands/modification.rs | 11 | ||||
-rw-r--r-- | src/commands/setup.rs | 54 | ||||
-rw-r--r-- | src/commands/update.rs | 2 | ||||
-rw-r--r-- | src/db.rs | 171 | ||||
-rw-r--r-- | src/input.rs | 22 |
9 files changed, 281 insertions, 39 deletions
Binary files differ | |||
diff --git a/src/apis/modrinth.rs b/src/apis/modrinth.rs index c71b47f..abb8eec 100644 --- a/src/apis/modrinth.rs +++ b/src/apis/modrinth.rs | |||
@@ -156,6 +156,16 @@ pub async fn versions(api: String, id: String, list: List) -> Vec<Version> { | |||
156 | serde_json::from_slice(&data.await.unwrap()).unwrap() | 156 | serde_json::from_slice(&data.await.unwrap()).unwrap() |
157 | } | 157 | } |
158 | 158 | ||
159 | pub async fn get_raw_versions(api: String, versions: Vec<String>) -> Vec<Version> { | ||
160 | println!("Getting versions"); | ||
161 | |||
162 | let url = format!(r#"versions?ids=["{}"]"#, versions.join(r#"",""#)); | ||
163 | |||
164 | let data = get(api, url).await; | ||
165 | |||
166 | serde_json::from_slice(&data.unwrap()).unwrap() | ||
167 | } | ||
168 | |||
159 | pub fn extract_current_version(versions: Vec<Version>) -> Result<String, Box<dyn std::error::Error>> { | 169 | pub fn extract_current_version(versions: Vec<Version>) -> Result<String, Box<dyn std::error::Error>> { |
160 | match versions.len() { | 170 | match versions.len() { |
161 | 0 => Err(Box::new(Error::new(ErrorKind::NotFound, "NO_VERSIONS_AVAILABLE"))), | 171 | 0 => Err(Box::new(Error::new(ErrorKind::NotFound, "NO_VERSIONS_AVAILABLE"))), |
diff --git a/src/commands/download.rs b/src/commands/download.rs new file mode 100644 index 0000000..05c54cb --- /dev/null +++ b/src/commands/download.rs | |||
@@ -0,0 +1,46 @@ | |||
1 | use std::{io::Write, fs::File}; | ||
2 | |||
3 | use reqwest::Client; | ||
4 | |||
5 | use futures_util::StreamExt; | ||
6 | |||
7 | use crate::{get_current_list, config::Cfg, db::get_dl_links}; | ||
8 | |||
9 | pub async fn download(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { | ||
10 | let list = get_current_list(config.clone())?; | ||
11 | |||
12 | let links = get_dl_links(config.clone(), list)?; | ||
13 | |||
14 | download_links(config, links).await?; | ||
15 | |||
16 | Ok(()) | ||
17 | } | ||
18 | |||
19 | async fn download_links(config: Cfg, links: Vec<String>) -> Result<String, Box<dyn std::error::Error>> { | ||
20 | |||
21 | let dl_path = String::from(&config.downloads); | ||
22 | |||
23 | for link in links { | ||
24 | let filename = link.split('/').last().unwrap(); | ||
25 | let dl_path_file = format!("{}/{}", config.downloads, filename); | ||
26 | println!("Downloading {}", link); | ||
27 | |||
28 | let res = Client::new() | ||
29 | .get(String::from(&link)) | ||
30 | .send() | ||
31 | .await | ||
32 | .or(Err(format!("Failed to GET from '{}'", &link)))?; | ||
33 | |||
34 | // download chunks | ||
35 | let mut file = File::create(String::from(&dl_path_file)).or(Err(format!("Failed to create file '{}'", dl_path_file)))?; | ||
36 | let mut stream = res.bytes_stream(); | ||
37 | |||
38 | while let Some(item) = stream.next().await { | ||
39 | let chunk = item.or(Err("Error while downloading file"))?; | ||
40 | file.write_all(&chunk) | ||
41 | .or(Err("Error while writing to file"))?; | ||
42 | } | ||
43 | } | ||
44 | |||
45 | Ok(dl_path) | ||
46 | } | ||
diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 5d008fd..20badcb 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs | |||
@@ -1,7 +1,11 @@ | |||
1 | pub mod modification; | 1 | pub mod modification; |
2 | pub mod list; | 2 | pub mod list; |
3 | pub mod update; | 3 | pub mod update; |
4 | pub mod setup; | ||
5 | pub mod download; | ||
4 | 6 | ||
5 | pub use modification::*; | 7 | pub use modification::*; |
6 | pub use list::*; | 8 | pub use list::*; |
7 | pub use update::*; | 9 | pub use update::*; |
10 | pub use setup::*; | ||
11 | pub use download::*; | ||
diff --git a/src/commands/modification.rs b/src/commands/modification.rs index b90c82c..e877a63 100644 --- a/src/commands/modification.rs +++ b/src/commands/modification.rs | |||
@@ -34,9 +34,12 @@ async fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::E | |||
34 | if project.versions.is_empty() { panic!("This should never happen"); }; | 34 | if project.versions.is_empty() { panic!("This should never happen"); }; |
35 | 35 | ||
36 | let available_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), current_list.clone()).await; | 36 | let available_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), current_list.clone()).await; |
37 | |||
38 | let current_version = extract_current_version(available_versions.clone())?; | ||
39 | 37 | ||
38 | let current_id = extract_current_version(available_versions.clone())?; | ||
39 | |||
40 | let current_version = available_versions.clone().into_iter().find(|v| v.id == current_id).unwrap(); | ||
41 | |||
42 | let file = current_version.files.into_iter().find(|f| f.primary).unwrap().url; | ||
40 | //add to current list and mod table | 43 | //add to current list and mod table |
41 | match get_mods_from_list(config.clone(), current_list.clone()) { | 44 | match get_mods_from_list(config.clone(), current_list.clone()) { |
42 | Ok(mods) => { | 45 | Ok(mods) => { |
@@ -44,10 +47,10 @@ async fn add(config: Cfg, args: Vec<String>) -> Result<(), Box<dyn std::error::E | |||
44 | if mods.contains(&project.id) { | 47 | if mods.contains(&project.id) { |
45 | return Err(Box::new(Error::new(ErrorKind::Other, "MOD_ALREADY_ON_LIST"))); } | 48 | return Err(Box::new(Error::new(ErrorKind::Other, "MOD_ALREADY_ON_LIST"))); } |
46 | else { | 49 | else { |
47 | insert_mod_in_list(config.clone(), current_list.clone(), String::from(&project.id), current_version, available_versions)?; | 50 | insert_mod_in_list(config.clone(), current_list.clone(), String::from(&project.id), current_version.id, available_versions, file)?; |
48 | } | 51 | } |
49 | }, | 52 | }, |
50 | Err(..) => insert_mod_in_list(config.clone(), current_list, String::from(&project.id), current_version, available_versions)?, | 53 | Err(..) => insert_mod_in_list(config.clone(), current_list, String::from(&project.id), current_version.id, available_versions, file)?, |
51 | }; | 54 | }; |
52 | 55 | ||
53 | match get_mods(config.clone()) { | 56 | match get_mods(config.clone()) { |
diff --git a/src/commands/setup.rs b/src/commands/setup.rs new file mode 100644 index 0000000..0223a21 --- /dev/null +++ b/src/commands/setup.rs | |||
@@ -0,0 +1,54 @@ | |||
1 | use std::{fs::File, path::Path, io::{Error, ErrorKind}}; | ||
2 | |||
3 | use 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}; | ||
4 | |||
5 | pub async fn setup(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { | ||
6 | |||
7 | let db_file = format!("{}/data.db", String::from(&config.data)); | ||
8 | |||
9 | if !Path::new(&db_file).exists() { | ||
10 | return create(config, db_file); | ||
11 | } | ||
12 | |||
13 | match get_dbversion(config.clone()) { | ||
14 | Ok(ver) => { | ||
15 | match ver.as_str() { | ||
16 | _ => return Err(Box::new(Error::new(ErrorKind::Other, "UNKNOWN_VERSION"))) | ||
17 | } | ||
18 | }, | ||
19 | Err(..) => to_02(config).await? | ||
20 | }; | ||
21 | |||
22 | Ok(()) | ||
23 | } | ||
24 | |||
25 | fn create(config: Cfg, db_file: String) -> Result<(), Box<dyn std::error::Error>> { | ||
26 | File::create(db_file)?; | ||
27 | db_setup(config)?; | ||
28 | Ok(()) | ||
29 | } | ||
30 | |||
31 | async fn to_02(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { | ||
32 | let lists = get_lists(config.clone())?; | ||
33 | |||
34 | for list in lists { | ||
35 | println!("Updating {}", list); | ||
36 | insert_column(config.clone(), String::from(&list), String::from("current_download"), sqlite::Type::String)?; | ||
37 | |||
38 | let full_list = get_list(config.clone(), String::from(&list))?; | ||
39 | |||
40 | let versions = get_current_versions(config.clone(), full_list.clone())?; | ||
41 | |||
42 | let raw_versions = get_raw_versions(String::from(&config.apis.modrinth), versions).await; | ||
43 | |||
44 | for ver in raw_versions { | ||
45 | println!("Adding link for {}", ver.project_id); | ||
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)?; | ||
48 | } | ||
49 | }; | ||
50 | create_dbversion(config)?; | ||
51 | |||
52 | |||
53 | Ok(()) | ||
54 | } | ||
diff --git a/src/commands/update.rs b/src/commands/update.rs index 6275bce..284d289 100644 --- a/src/commands/update.rs +++ b/src/commands/update.rs | |||
@@ -37,7 +37,7 @@ pub async fn update(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { | |||
37 | }; | 37 | }; |
38 | //println!("{:?}", updatestack); | 38 | //println!("{:?}", updatestack); |
39 | 39 | ||
40 | //download_updates(config, updatestack).await?; | 40 | download_updates(config, updatestack).await?; |
41 | 41 | ||
42 | Ok(()) | 42 | Ok(()) |
43 | } | 43 | } |
@@ -12,12 +12,14 @@ pub fn insert_mod(config: Cfg, id: String, name: String, versions: Vec<String>) | |||
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 = sqlite::open(data).unwrap(); |
14 | 14 | ||
15 | let sql = format!("INSERT INTO mods VALUES ('{}', '{}', '{}')", id, name, versions.join("|")); | 15 | let sql = format!("INSERT INTO mods VALUES ('{}', '{}', '{}')", id, name.replace('\'', ""), versions.join("|")); |
16 | |||
17 | dbg!(&sql); | ||
16 | 18 | ||
17 | connection.execute(sql) | 19 | connection.execute(sql) |
18 | } | 20 | } |
19 | 21 | ||
20 | pub fn insert_mod_in_list(config: Cfg, list: List, id: String, current_version: String, applicable_versions: Vec<Version>) -> Result<(), sqlite::Error> { | 22 | pub fn insert_mod_in_list(config: Cfg, list: List, id: String, current_version: String, applicable_versions: Vec<Version>, current_link: String) -> Result<(), sqlite::Error> { |
21 | 23 | ||
22 | println!("Inserting into current list"); | 24 | println!("Inserting into current list"); |
23 | 25 | ||
@@ -30,8 +32,8 @@ pub fn insert_mod_in_list(config: Cfg, list: List, id: String, current_version: | |||
30 | applicable_versions_vec.push(ver.id); | 32 | applicable_versions_vec.push(ver.id); |
31 | } | 33 | } |
32 | 34 | ||
33 | let sql = format!("INSERT INTO {} VALUES ('{}', '{}', '{}')", list.id, id, current_version, applicable_versions_vec.join("|")); | 35 | let sql = format!("INSERT INTO {} VALUES ('{}', '{}', '{}', '{}')", list.id, id, current_version, applicable_versions_vec.join("|"), current_link); |
34 | 36 | ||
35 | connection.execute(sql) | 37 | connection.execute(sql) |
36 | } | 38 | } |
37 | 39 | ||
@@ -122,33 +124,33 @@ pub struct DBModlistVersions { | |||
122 | } | 124 | } |
123 | 125 | ||
124 | pub fn get_versions(config: Cfg, mods: Vec<String>) -> Result<Vec<DBModlistVersions>, Box<dyn std::error::Error>> { | 126 | 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); | 127 | let data = format!("{}/data.db", config.data); |
126 | let connection = sqlite::open(data).unwrap(); | 128 | let connection = sqlite::open(data).unwrap(); |
127 | 129 | ||
128 | let mut wherestr = String::from("WHERE"); | 130 | let mut wherestr = String::from("WHERE"); |
129 | for (i, id) in mods.iter().enumerate() { | 131 | for (i, id) in mods.iter().enumerate() { |
130 | let mut or = " OR"; | 132 | let mut or = " OR"; |
131 | if i == mods.len() - 1 { or = "" } | 133 | if i == mods.len() - 1 { or = "" } |
132 | println!("Pushing {}({}) | OR: '{}'", id, i, or); | 134 | println!("Pushing {}({}) | OR: '{}'", id, i, or); |
133 | wherestr = format!("{} id = '{}'{}", wherestr, id, or); | 135 | wherestr = format!("{} id = '{}'{}", wherestr, id, or); |
134 | } | 136 | } |
135 | 137 | ||
136 | let sql = format!("SELECT id, versions FROM mods {}", wherestr); | 138 | let sql = format!("SELECT id, versions FROM mods {}", wherestr); |
137 | |||
138 | dbg!(&sql); | ||
139 | 139 | ||
140 | let mut versionmaps: Vec<DBModlistVersions> = Vec::new(); | 140 | dbg!(&sql); |
141 | //TODO catch sql errors better | ||
142 | let mut cursor = connection.prepare(sql).unwrap().into_cursor(); | ||
143 | 141 | ||
144 | while let Some(Ok(row)) = cursor.next() { | 142 | let mut versionmaps: Vec<DBModlistVersions> = Vec::new(); |
145 | println!("{}: {}", row.get::<String, _>(0), row.get::<String, _>(1)); | 143 | //TODO catch sql errors better |
146 | versionmaps.push(DBModlistVersions { mod_id: row.get::<String, _>(0), versions: row.get::<String, _>(1) }) | 144 | let mut cursor = connection.prepare(sql).unwrap().into_cursor(); |
147 | }; | ||
148 | 145 | ||
149 | if versionmaps.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); }; | 146 | while let Some(Ok(row)) = cursor.next() { |
147 | println!("{}: {}", row.get::<String, _>(0), row.get::<String, _>(1)); | ||
148 | versionmaps.push(DBModlistVersions { mod_id: row.get::<String, _>(0), versions: row.get::<String, _>(1) }) | ||
149 | }; | ||
150 | 150 | ||
151 | Ok(versionmaps) | 151 | if versionmaps.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); }; |
152 | |||
153 | Ok(versionmaps) | ||
152 | } | 154 | } |
153 | 155 | ||
154 | pub fn get_list_version(config: Cfg, list: List, mod_id: String) -> Result<String, Box<dyn std::error::Error>> { | 156 | pub fn get_list_version(config: Cfg, list: List, mod_id: String) -> Result<String, Box<dyn std::error::Error>> { |
@@ -179,7 +181,7 @@ pub fn insert_list(config: Cfg, id: String, mc_version: String, mod_loader: Modl | |||
179 | let connection = sqlite::open(data).unwrap(); | 181 | let connection = sqlite::open(data).unwrap(); |
180 | 182 | ||
181 | let sql_list = format!("INSERT INTO lists VALUES ('{}', '{}', '{}')", id, mc_version, mod_loader.stringify()); | 183 | let sql_list = format!("INSERT INTO lists VALUES ('{}', '{}', '{}')", id, mc_version, mod_loader.stringify()); |
182 | let sql_table = format!("CREATE TABLE '{}' ( 'mod_id' TEXT, 'current_version' TEXT, 'applicable_versions' BLOB)", id); | 184 | let sql_table = format!("CREATE TABLE '{}' ( 'mod_id' TEXT, 'current_version' TEXT, 'applicable_versions' BLOB, 'current_download' TEXT)", id); |
183 | let sql = format!("{};{};", sql_list, sql_table); | 185 | let sql = format!("{};{};", sql_list, sql_table); |
184 | 186 | ||
185 | connection.execute(sql) | 187 | connection.execute(sql) |
@@ -217,6 +219,27 @@ pub fn get_lists(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>> | |||
217 | } | 219 | } |
218 | } | 220 | } |
219 | 221 | ||
222 | pub fn get_current_versions(config: Cfg, list: List) -> Result<Vec<String>, Box<std::io::Error>> { | ||
223 | let data = format!("{}/data.db", config.data); | ||
224 | let connection = sqlite::open(data).unwrap(); | ||
225 | |||
226 | let sql = format!("SELECT current_version FROM {}", list.id); | ||
227 | |||
228 | dbg!(&sql); | ||
229 | |||
230 | let mut versions: Vec<String> = Vec::new(); | ||
231 | //TODO catch sql errors better | ||
232 | let mut cursor = connection.prepare(sql).unwrap().into_cursor(); | ||
233 | |||
234 | while let Some(Ok(row)) = cursor.next() { | ||
235 | versions.push(row.get::<String, _>(0)); | ||
236 | }; | ||
237 | |||
238 | if versions.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); }; | ||
239 | |||
240 | Ok(versions) | ||
241 | } | ||
242 | |||
220 | pub fn get_list(config: Cfg, id: String) -> Result<List, Box<dyn std::error::Error>> { | 243 | pub fn get_list(config: Cfg, id: String) -> Result<List, Box<dyn std::error::Error>> { |
221 | let data = format!("{}/data.db", config.data); | 244 | let data = format!("{}/data.db", config.data); |
222 | let connection = sqlite::open(data).unwrap(); | 245 | let connection = sqlite::open(data).unwrap(); |
@@ -247,6 +270,38 @@ pub fn change_list_versions(config: Cfg, list: List, current_version: String, ve | |||
247 | connection.execute(sql) | 270 | connection.execute(sql) |
248 | } | 271 | } |
249 | 272 | ||
273 | //DOWNLOAD | ||
274 | |||
275 | pub fn insert_dl_link(config: Cfg, list: List, mod_id: String, link: String) -> Result<(), sqlite::Error> { | ||
276 | let data = format!("{}/data.db", config.data); | ||
277 | let connection = sqlite::open(data).unwrap(); | ||
278 | |||
279 | let sql = format!("UPDATE {} SET current_download = '{}' WHERE mod_id = '{}'", list.id, link, mod_id); | ||
280 | |||
281 | connection.execute(sql) | ||
282 | } | ||
283 | |||
284 | pub fn get_dl_links(config: Cfg, list: List) -> Result<Vec<String>, Box<std::io::Error>> { | ||
285 | let data = format!("{}/data.db", config.data); | ||
286 | let connection = sqlite::open(data).unwrap(); | ||
287 | |||
288 | let sql = format!("SELECT current_download FROM {}", list.id); | ||
289 | |||
290 | dbg!(&sql); | ||
291 | |||
292 | let mut links: Vec<String> = Vec::new(); | ||
293 | //TODO catch sql errors better | ||
294 | let mut cursor = connection.prepare(sql).unwrap().into_cursor(); | ||
295 | |||
296 | while let Some(Ok(row)) = cursor.next() { | ||
297 | links.push(row.get::<String, _>(0)); | ||
298 | }; | ||
299 | |||
300 | if links.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_MODS_ON_LIST"))); }; | ||
301 | |||
302 | Ok(links) | ||
303 | } | ||
304 | |||
250 | //config | 305 | //config |
251 | pub fn change_list(config: Cfg, id: String) -> Result<(), sqlite::Error> { | 306 | pub fn change_list(config: Cfg, id: String) -> Result<(), sqlite::Error> { |
252 | let data = format!("{}/data.db", config.data); | 307 | let data = format!("{}/data.db", config.data); |
@@ -278,3 +333,65 @@ pub fn get_current_list_id(config: Cfg) -> Result<String, Box<dyn std::error::Er | |||
278 | }; | 333 | }; |
279 | Ok(list) | 334 | Ok(list) |
280 | } | 335 | } |
336 | |||
337 | pub fn update_dbversion(config: Cfg, ver: String) -> Result<(), sqlite::Error> { | ||
338 | let data = format!("{}/data.db", config.data); | ||
339 | let connection = sqlite::open(data).unwrap(); | ||
340 | |||
341 | let sql = format!("UPDATE user_config SET value = '{}' WHERE id = 'db_version'", ver); | ||
342 | |||
343 | connection.execute(sql) | ||
344 | } | ||
345 | |||
346 | pub fn create_dbversion(config: Cfg) -> Result<(), sqlite::Error> { | ||
347 | let data = format!("{}/data.db", config.data); | ||
348 | let connection = sqlite::open(data).unwrap(); | ||
349 | let sql = "INSERT INTO 'user_config' VALUES ( 'db_version', '0.2' );"; | ||
350 | connection.execute(sql) | ||
351 | } | ||
352 | |||
353 | pub fn get_dbversion(config: Cfg) -> Result<String, Box<dyn std::error::Error>> { | ||
354 | let data = format!("{}/data.db", config.data); | ||
355 | let connection = sqlite::open(data).unwrap(); | ||
356 | |||
357 | let sql = "SELECT db_version FROM user_config"; | ||
358 | |||
359 | let mut ver: String = String::new(); | ||
360 | //TODO catch sql errors better | ||
361 | connection.iterate(sql, |ids| { | ||
362 | if ids.is_empty() { return false; }; | ||
363 | for &(_column, value) in ids.iter() { | ||
364 | ver = String::from(value.unwrap()); | ||
365 | } | ||
366 | true | ||
367 | })?; | ||
368 | if ver.is_empty() { return Err(Box::new(std::io::Error::new(ErrorKind::Other, "NO_DBVERSION"))); }; | ||
369 | Ok(ver) | ||
370 | } | ||
371 | |||
372 | pub fn db_setup(config: Cfg) -> Result<(), sqlite::Error> { | ||
373 | println!("Initiating database"); | ||
374 | |||
375 | let data = format!("{}/data.db", config.data); | ||
376 | let connection = sqlite::open(data).unwrap(); | ||
377 | |||
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', '...' )"; | ||
379 | |||
380 | connection.execute(sql) | ||
381 | } | ||
382 | |||
383 | pub fn insert_column(config: Cfg, table: String, column: String, c_type: sqlite::Type) -> Result<(), sqlite::Error> { | ||
384 | let data = format!("{}/data.db", config.data); | ||
385 | let connection = sqlite::open(data).unwrap(); | ||
386 | |||
387 | let ct = match c_type { | ||
388 | sqlite::Type::Null => "NULL", | ||
389 | sqlite::Type::Float => "FLOAT", | ||
390 | sqlite::Type::Binary => "BINARY", | ||
391 | sqlite::Type::String => "TEXT", | ||
392 | sqlite::Type::Integer => "INT", | ||
393 | }; | ||
394 | |||
395 | let sql = format!("ALTER TABLE {} ADD '{}' {}", table, column, ct); | ||
396 | connection.execute(sql) | ||
397 | } | ||
diff --git a/src/input.rs b/src/input.rs index e0c9ae9..c7e82d9 100644 --- a/src/input.rs +++ b/src/input.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use std::io::{stdin, Error, ErrorKind}; | 1 | use std::{io::{Error, ErrorKind}, env}; |
2 | use crate::{config::Cfg, list, modification, update}; | 2 | use crate::{config::Cfg, list, modification, update, setup, download}; |
3 | 3 | ||
4 | #[derive(Debug, PartialEq, Eq)] | 4 | #[derive(Debug, PartialEq, Eq)] |
5 | pub struct Input { | 5 | pub struct Input { |
@@ -32,12 +32,14 @@ impl Input { | |||
32 | } | 32 | } |
33 | 33 | ||
34 | pub async fn get_input(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { | 34 | pub async fn get_input(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { |
35 | let mut user_input = String::new(); | 35 | let mut args: Vec<String> = env::args().collect(); |
36 | stdin() | 36 | dbg!(&args); |
37 | .read_line(&mut user_input) | 37 | args.reverse(); |
38 | .expect("ERROR"); | 38 | args.pop(); |
39 | args.reverse(); | ||
40 | dbg!(&args); | ||
39 | 41 | ||
40 | let input = Input::from(user_input.trim().to_string())?; | 42 | let input = Input::from(args.join(" "))?; |
41 | 43 | ||
42 | match input.command.as_str() { | 44 | match input.command.as_str() { |
43 | "mod" => { | 45 | "mod" => { |
@@ -49,6 +51,12 @@ pub async fn get_input(config: Cfg) -> Result<(), Box<dyn std::error::Error>> { | |||
49 | "update" => { | 51 | "update" => { |
50 | update(config).await | 52 | update(config).await |
51 | }, | 53 | }, |
54 | "setup" => { | ||
55 | setup(config).await | ||
56 | }, | ||
57 | "download" => { | ||
58 | download(config).await | ||
59 | }, | ||
52 | _ => Err(Box::new(Error::new(ErrorKind::InvalidInput, "UNKNOWN_COMMAND"))), | 60 | _ => Err(Box::new(Error::new(ErrorKind::InvalidInput, "UNKNOWN_COMMAND"))), |
53 | } | 61 | } |
54 | } | 62 | } |