diff --git a/Cargo.lock b/Cargo.lock index 048ca63..fd314cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -528,6 +528,7 @@ dependencies = [ "rayon", "regex-lite", "ron", + "rusqlite", "serde", "serde_json", "simd-json", @@ -678,6 +679,18 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" version = "2.0.1" @@ -841,6 +854,15 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.2", +] + [[package]] name = "heck" version = "0.4.1" @@ -1028,6 +1050,16 @@ version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.11" @@ -1310,6 +1342,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + [[package]] name = "postgres" version = "0.19.7" @@ -1317,7 +1355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7915b33ed60abc46040cbcaa25ffa1c7ec240668e0477c4f3070786f5916d451" dependencies = [ "bytes", - "fallible-iterator", + "fallible-iterator 0.2.0", "futures-util", "log", "tokio", @@ -1333,7 +1371,7 @@ dependencies = [ "base64 0.21.5", "byteorder", "bytes", - "fallible-iterator", + "fallible-iterator 0.2.0", "hmac", "md-5", "memchr", @@ -1349,7 +1387,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" dependencies = [ "bytes", - "fallible-iterator", + "fallible-iterator 0.2.0", "postgres-protocol", ] @@ -1520,6 +1558,20 @@ dependencies = [ "serde", ] +[[package]] +name = "rusqlite" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78046161564f5e7cd9008aff3b2990b3850dc8e0349119b98e8f251e099f24d" +dependencies = [ + "bitflags 2.4.1", + "fallible-iterator 0.3.0", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -1890,7 +1942,7 @@ dependencies = [ "async-trait", "byteorder", "bytes", - "fallible-iterator", + "fallible-iterator 0.2.0", "futures-channel", "futures-util", "log", @@ -2043,6 +2095,12 @@ dependencies = [ "ryu", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index 27af9c0..90f0190 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ tui-textarea = { version = "0.4", optional = true } ellipse = "0.2.0" ark-ff = "0.4.2" memmap2 = "0.9.0" +rusqlite = "0.30.0" [target.'cfg(all(target_arch = "x86_64", target_feature = "avx"))'.dependencies] simd-json = "0.13" diff --git a/shell.nix b/shell.nix index c6332a1..f9a3fbf 100644 --- a/shell.nix +++ b/shell.nix @@ -3,7 +3,7 @@ pkgs.mkShell { buildInputs = [ pkgs.cargo pkgs.rust-analyzer pkgs.rustc pkgs.rustfmt pkgs.clippy - pkgs.libiconv + pkgs.libiconv pkgs.sqlite pkgs.sqlite-interactive pkgs.git-cliff ]; diff --git a/src/exporters/convert.rs b/src/exporters/convert.rs new file mode 100644 index 0000000..b609128 --- /dev/null +++ b/src/exporters/convert.rs @@ -0,0 +1,68 @@ +use crate::{ + compiler::ConstraintSet, + pretty::{Base, Pretty}, + utils::purify, +}; +use anyhow::*; +use itertools::Itertools; +use rusqlite::Connection; + +pub(crate) fn to_sqlite(cs: &ConstraintSet, exclude: &[String], filename: &str) -> Result<()> { + let db = Connection::open(filename)?; + + for module in cs.columns.modules() { + if exclude.contains(&module) { + continue; + } + println!("Exporting {}", &module); + let column_names = cs + .columns + .iter_module(&module) + .map(|c| cs.handle(&c.0)) + .collect::>(); + let sql_column_headers = column_names + .iter() + .map(|h| format!("{}_ TEXT NOT NULL", h.name)) + .join(", "); + let sql_column_names = column_names + .iter() + .map(|h| format!("{}_ ", h.name)) + .join(", "); + db.execute(&format!("DROP TABLE IF EXISTS {}_", purify(&module)), ())?; + db.execute( + &format!("CREATE TABLE {}_ ({})", purify(&module), sql_column_headers), + (), + )?; + let max_i = cs.iter_len(&module); + if max_i == 0 { + continue; + } + + for i in 0..max_i { + let vals = cs + .columns + .iter_module(&module) + .map(|col| { + format!( + "\"{}\"", + cs.columns + .get(&col.0, i.try_into().unwrap(), false) + .unwrap_or_default() + .pretty_with_base(Base::Hex) + ) + }) + .join(", "); + db.execute( + &format!( + "INSERT INTO {}_ ({}) VALUES ({})", + purify(&module), + &sql_column_names, + &vals + ), + (), + )?; + } + } + + Ok(()) +} diff --git a/src/exporters/mod.rs b/src/exporters/mod.rs index 106596c..7eaf307 100755 --- a/src/exporters/mod.rs +++ b/src/exporters/mod.rs @@ -4,6 +4,7 @@ use log::*; pub mod besu; #[cfg(feature = "conflater")] pub mod conflater; +pub mod convert; pub(crate) mod debugger; #[cfg(feature = "exporters")] pub mod latex; diff --git a/src/main.rs b/src/main.rs index e6f43a7..06e6b0e 100755 --- a/src/main.rs +++ b/src/main.rs @@ -130,6 +130,29 @@ enum Commands { constraints_filename: Option, }, /// Given a set of constraints and a trace file, fill the computed columns + Convert { + #[arg( + short = 'T', + long = "trace", + required = true, + help = "the trace to convert" + )] + tracefile: String, + + #[arg( + long = "exclude", + help = "do not export these modules", + value_delimiter = ',' + )] + exclude: Option>, + + #[arg(short = 'o', long = "out", help = "where to write the computed trace")] + outfile: Option, + + #[arg(short='f', long="format", value_parser=["sorts", "nhood"], value_delimiter=',', global=true)] + auto_constraints: Vec, + }, + /// Given a set of constraints and a trace file, fill the computed columns Compute { #[arg( short = 'T', @@ -662,6 +685,28 @@ fn main() -> Result<()> { constraints_filename, )?; } + Commands::Convert { + tracefile, + outfile, + auto_constraints, + exclude, + } => { + // if auto_constraints { + // builder.auto_constraints(AutoConstraint::all()); + // } + + let mut cs = builder.into_constraint_set()?; + compute::compute_trace(&tracefile, &mut cs, false) + .with_context(|| format!("while computing from `{}`", tracefile))?; + exporters::convert::to_sqlite( + &cs, + &exclude.unwrap_or_default(), + outfile + .as_ref() + .map(String::as_str) + .unwrap_or("trace.sqlite"), + )?; + } Commands::Compute { tracefile, outfile,