assembly_data/fdb/
sqlite.rs1use std::fmt::Write;
4
5use rusqlite::{types::ToSqlOutput, ToSql};
6pub use rusqlite::{Connection, Error, Result};
7
8use super::{
9 common::ValueType,
10 mem::{Database, Field},
11};
12
13impl<'a> ToSql for Field<'a> {
14 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
15 use rusqlite::types::Value;
16 let r = match *self {
17 Field::Nothing => Value::Null,
18 Field::Integer(i) => Value::Integer(i.into()),
19 Field::Float(f) => Value::Real(f.into()),
20 Field::Text(s) => Value::Text(s.decode().into_owned()),
21 Field::Boolean(b) => Value::Integer(if b { 1 } else { 0 }),
22 Field::BigInt(i) => Value::Integer(i),
23 Field::VarChar(b) => Value::Text(b.decode().into_owned()),
24 };
25 Ok(ToSqlOutput::Owned(r))
26 }
27}
28
29pub fn try_export_db(conn: &mut Connection, db: Database) -> rusqlite::Result<()> {
40 conn.execute("BEGIN", rusqlite::params![])?;
41
42 let tables = db.tables().unwrap();
43 for table in tables.iter() {
44 let table = table.unwrap();
45 let mut create_query = format!("CREATE TABLE IF NOT EXISTS \"{}\"\n(\n", table.name());
46 let mut insert_query = format!("INSERT INTO \"{}\" (", table.name());
47 let mut first = true;
48 for col in table.column_iter() {
49 if first {
50 first = false;
51 } else {
52 writeln!(create_query, ",").unwrap();
53 write!(insert_query, ", ").unwrap();
54 }
55 let typ = match col.value_type() {
56 ValueType::Nothing => "NULL",
57 ValueType::Integer => "INTEGER",
58 ValueType::Float => "REAL",
59 ValueType::Text => "TEXT",
60 ValueType::Boolean => "INTEGER",
61 ValueType::BigInt => "INTEGER",
62 ValueType::VarChar => "BLOB",
63 };
64 write!(create_query, " [{}] {}", col.name(), typ).unwrap();
65 write!(insert_query, "[{}]", col.name()).unwrap();
66 }
67 create_query.push_str(");");
68 insert_query.push_str(") VALUES (?1");
69 for i in 2..=table.column_count() {
70 write!(insert_query, ", ?{}", i).unwrap();
71 }
72 insert_query.push_str(");");
73 conn.execute(&create_query, rusqlite::params![])?;
74
75 let mut stmt = conn.prepare(&insert_query)?;
76 for row in table.row_iter() {
77 stmt.execute(row)?;
78 }
79 }
80
81 conn.execute("COMMIT", rusqlite::params![])?;
82 Ok(())
83}