|
@@ -10,6 +10,8 @@ use std::{
|
|
|
sync::LazyLock,
|
|
|
};
|
|
|
use std::{thread, time::Duration};
|
|
|
+use std::fs::File;
|
|
|
+use std::io::Write;
|
|
|
|
|
|
mod config;
|
|
|
mod fetch;
|
|
@@ -53,6 +55,10 @@ enum Commands {
|
|
|
/// Output file
|
|
|
#[arg(short, long)]
|
|
|
output: Option<PathBuf>,
|
|
|
+
|
|
|
+ /// SQL output
|
|
|
+ #[arg(short, long)]
|
|
|
+ sql: Option<PathBuf>,
|
|
|
},
|
|
|
/// Verse of the day
|
|
|
Verse {
|
|
@@ -291,7 +297,7 @@ fn main() -> Result<()> {
|
|
|
println!("I'm finished fetching!");
|
|
|
}
|
|
|
|
|
|
- Some(Commands::Extract { count, output }) => {
|
|
|
+ Some(Commands::Extract { count, output, sql }) => {
|
|
|
println!("Extract...");
|
|
|
let files = find_files(cli.work.to_str().unwrap(), cli.version.as_str());
|
|
|
let filepath = Path::new(&cli.work);
|
|
@@ -345,6 +351,114 @@ fn main() -> Result<()> {
|
|
|
println!("Saving output: {}", output.to_str().unwrap());
|
|
|
save_basic_json(output.to_str().unwrap(), &json_output)?;
|
|
|
}
|
|
|
+
|
|
|
+ if let Some(sql_file) = sql {
|
|
|
+ // SQL output
|
|
|
+ println!("Saving SQL: {}", sql_file.to_str().unwrap());
|
|
|
+ let mut file = File::create(sql_file)?;
|
|
|
+ writeln!(file, r#"CREATE TABLE "Books" (
|
|
|
+ "bid" INTEGER,
|
|
|
+ "book" TEXT NOT NULL UNIQUE,
|
|
|
+ PRIMARY KEY("bid" AUTOINCREMENT)
|
|
|
+);"#);
|
|
|
+ writeln!(file, r#"CREATE TABLE "Verses" (
|
|
|
+ "bid" INTEGER,
|
|
|
+ "chapter" INTEGER,
|
|
|
+ "verse" INTEGER,
|
|
|
+ "sequence" INTEGER,
|
|
|
+ "type" TEXT,
|
|
|
+ "text" TEXT,
|
|
|
+ PRIMARY KEY("bid","chapter","verse","sequence","verse"),
|
|
|
+ FOREIGN KEY("bid") REFERENCES "Books"("bid")
|
|
|
+);"#);
|
|
|
+ // Database tables are ready.
|
|
|
+ let mut book_id = HashMap::<String,usize>::new();
|
|
|
+
|
|
|
+ let base = "INSERT INTO Books(book) VALUES ";
|
|
|
+ let mut collection = Vec::<String>::new();
|
|
|
+
|
|
|
+ for (bidx,book) in (&json_output.books).into_iter().enumerate() {
|
|
|
+ collection.push(format!("(\"{}\")", book));
|
|
|
+ // Save index number
|
|
|
+ book_id.insert(book.clone(), bidx+1 );
|
|
|
+ // writeln!(file, "INSERT INTO Books(book) VALUES (\"{}\");", book);
|
|
|
+ }
|
|
|
+ writeln!(file, "BEGIN TRANSACTION;");
|
|
|
+ writeln!(file, "{} {};", base, collection.join(","));
|
|
|
+ writeln!(file, "COMMIT;");
|
|
|
+
|
|
|
+ for (book, info) in json_output.book {
|
|
|
+ // Find the index # we need.
|
|
|
+
|
|
|
+ let mut bid: usize = 0;
|
|
|
+ let mut bid_found = false;
|
|
|
+
|
|
|
+ if book_id.contains_key(&book) {
|
|
|
+ bid = *book_id.get(&book).unwrap();
|
|
|
+ bid_found = true;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ for (idx,b) in BOOK_NAMES.iter().enumerate() {
|
|
|
+ if book == *b {
|
|
|
+ bid = idx;
|
|
|
+ bid_found = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ */
|
|
|
+
|
|
|
+ if !bid_found {
|
|
|
+ panic!("I couldn't find index for {}!", book);
|
|
|
+ }
|
|
|
+
|
|
|
+ let base = "INSERT INTO Verses(bid, chapter, verse, sequence, type, text) VALUES ";
|
|
|
+ collection.clear();
|
|
|
+
|
|
|
+ for (cidx, ch) in info.chapters.iter().enumerate() {
|
|
|
+ // Chapter would be cidx + 1
|
|
|
+ writeln!(file, "BEGIN TRANSACTION;");
|
|
|
+ for (vidx, v) in ch.verses.iter().enumerate() {
|
|
|
+ // Verse would be vidx + 1
|
|
|
+
|
|
|
+ for (pidx, p) in v.iter().enumerate() {
|
|
|
+ let mut t = String::new();
|
|
|
+ let mut text = String::new();
|
|
|
+ match p {
|
|
|
+ config::BasicVerseJSON::Heading(txt) => {
|
|
|
+ t = String::from("H");
|
|
|
+ text = txt.clone();
|
|
|
+ }
|
|
|
+ config::BasicVerseJSON::Note(txt) => {
|
|
|
+ t = String::from("N");
|
|
|
+ text = txt.clone();
|
|
|
+ }
|
|
|
+ config::BasicVerseJSON::Verse{ text: txt, paragraph: p, quote: q, red: r} => {
|
|
|
+ t = String::from("V");
|
|
|
+ if *p {
|
|
|
+ t.push_str("P");
|
|
|
+ }
|
|
|
+ if *q {
|
|
|
+ t.push_str("Q");
|
|
|
+ }
|
|
|
+ if *r {
|
|
|
+ t.push_str("R");
|
|
|
+ }
|
|
|
+ text = txt.clone();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // Part would be pidx + 1
|
|
|
+ collection.push(format!("({},{},{},{},\"{}\",\"{}\")", bid, cidx+1, vidx+1, pidx+1, t, text));
|
|
|
+ }
|
|
|
+ // Output the insert statement
|
|
|
+ if !collection.is_empty() {
|
|
|
+ writeln!(file, "{} {};", base, collection.join(","));
|
|
|
+ collection.clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ writeln!(file, "COMMIT;");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
Some(Commands::Verse { fetch: _ }) => {
|