From cd2d817c10cc90019e5d49ba9a93c7b446c01019 Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Sat, 8 Feb 2025 10:21:49 -0300 Subject: [PATCH 01/42] github.com/penberg/limbo was moved to github.com/tursodatabase/limbo Adjust all the references since they were broken --- CHANGELOG.md | 2 +- CONTRIBUTING.md | 2 +- bindings/python/pyproject.toml | 4 ++-- bindings/wasm/package.json | 2 +- core/benches/benchmark.rs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fee38e12c..847deec42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -303,7 +303,7 @@ - `ORDER BY` support for nullable sorting columns and qualified identifiers (Jussi Saurio) -- Fix `.schema` command crash in the CLI ([#212](https://github.com/penberg/limbo/issues/212) (Jussi Saurio) +- Fix `.schema` command crash in the CLI ([#212](https://github.com/tursodatabase/limbo/issues/212) (Jussi Saurio) ## 0.0.2 - 2024-07-24 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cad33a8db..ac4566c00 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -63,7 +63,7 @@ cargo bench --bench benchmark -- --profile-time=5 ## Finding things to work on -The issue tracker has issues tagged with [good first issue](https://github.com/penberg/limbo/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22), +The issue tracker has issues tagged with [good first issue](https://github.com/tursodatabase/limbo/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22), which are considered to be things to work on to get going. If you're interested in working on one of them, comment on the issue tracker, and we're happy to help you get going. ## Submitting your work diff --git a/bindings/python/pyproject.toml b/bindings/python/pyproject.toml index 3dd269b0e..4ed6066ce 100644 --- a/bindings/python/pyproject.toml +++ b/bindings/python/pyproject.toml @@ -40,8 +40,8 @@ dev = [ ] [project.urls] -Homepage = "https://github.com/penberg/limbo" -Source = "https://github.com/penberg/limbo" +Homepage = "https://github.com/tursodatabase/limbo" +Source = "https://github.com/tursodatabase/limbo" [tool.maturin] bindings = 'pyo3' diff --git a/bindings/wasm/package.json b/bindings/wasm/package.json index 2265a7799..d7c799bb9 100644 --- a/bindings/wasm/package.json +++ b/bindings/wasm/package.json @@ -7,7 +7,7 @@ "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/penberg/limbo" + "url": "https://github.com/tursodatabase/limbo" }, "type": "module", "main": "./node/dist/index.cjs", diff --git a/core/benches/benchmark.rs b/core/benches/benchmark.rs index 21b75424d..d2aef982b 100644 --- a/core/benches/benchmark.rs +++ b/core/benches/benchmark.rs @@ -12,7 +12,7 @@ fn rusqlite_open() -> rusqlite::Connection { } fn bench(criterion: &mut Criterion) { - // https://github.com/penberg/limbo/issues/174 + // https://github.com/tursodatabase/limbo/issues/174 // The rusqlite benchmark crashes on Mac M1 when using the flamegraph features let enable_rusqlite = std::env::var("DISABLE_RUSQLITE_BENCHMARK").is_err(); From 6308ce454413d226243a6c7fc79377c9e28c3b42 Mon Sep 17 00:00:00 2001 From: alpaylan Date: Sat, 8 Feb 2025 09:34:51 -0500 Subject: [PATCH 02/42] fix the shrinking file and poison errors --- simulator/main.rs | 10 +++++----- simulator/runner/execution.rs | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/simulator/main.rs b/simulator/main.rs index 82c39b809..b40934cfc 100644 --- a/simulator/main.rs +++ b/simulator/main.rs @@ -233,6 +233,11 @@ fn run_simulator( }) .collect::>(); + + // Write the shrunk plan to a file + let mut f = std::fs::File::create(&paths.shrunk_plan).unwrap(); + f.write_all(shrunk_plans[0].to_string().as_bytes()).unwrap(); + let last_execution = Arc::new(Mutex::new(*last_execution)); let shrunk = SandboxedResult::from( @@ -270,11 +275,6 @@ fn run_simulator( log::error!("shrinking failed, the error was not properly reproduced"); } } - - // Write the shrunk plan to a file - let shrunk_plan = std::fs::read(&paths.shrunk_plan).unwrap(); - let mut f = std::fs::File::create(&paths.shrunk_plan).unwrap(); - f.write_all(&shrunk_plan).unwrap(); } } } diff --git a/simulator/runner/execution.rs b/simulator/runner/execution.rs index 6544928a1..6342dff3a 100644 --- a/simulator/runner/execution.rs +++ b/simulator/runner/execution.rs @@ -62,6 +62,7 @@ pub(crate) fn execute_plans( ) -> ExecutionResult { let mut history = ExecutionHistory::new(); let now = std::time::Instant::now(); + env.clear_poison(); let mut env = env.lock().unwrap(); for _tick in 0..env.opts.ticks { // Pick the connection to interact with From 4362bc16a3876aed31e21056d31529e1fb7f6d8c Mon Sep 17 00:00:00 2001 From: alpaylan Date: Sat, 8 Feb 2025 09:37:08 -0500 Subject: [PATCH 03/42] fix formatting --- simulator/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/simulator/main.rs b/simulator/main.rs index b40934cfc..2eb463529 100644 --- a/simulator/main.rs +++ b/simulator/main.rs @@ -233,7 +233,6 @@ fn run_simulator( }) .collect::>(); - // Write the shrunk plan to a file let mut f = std::fs::File::create(&paths.shrunk_plan).unwrap(); f.write_all(shrunk_plans[0].to_string().as_bytes()).unwrap(); From 3ae3e650aed41823767fdbd1f3924f2fcc3063f4 Mon Sep 17 00:00:00 2001 From: alpaylan Date: Sat, 8 Feb 2025 10:59:11 -0500 Subject: [PATCH 04/42] fix watch mode bug deleting the last interaction of a property --- simulator/generation/plan.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/simulator/generation/plan.rs b/simulator/generation/plan.rs index d06cdfff3..b601a8975 100644 --- a/simulator/generation/plan.rs +++ b/simulator/generation/plan.rs @@ -57,8 +57,11 @@ impl InteractionPlan { i += 1; continue; } - - if interactions[i].contains(plan[j1][j2].to_string().as_str()) { + if plan[j1].len() == j2 { + i += 1; + j1 += 1; + j2 = 0; + } else if interactions[i].contains(plan[j1][j2].to_string().as_str()) { i += 1; if j2 + 1 < plan[j1].len() { j2 += 1; From e9046fef7818479f2c101ea6b1f2c5bde58d86ab Mon Sep 17 00:00:00 2001 From: wyhaya Date: Sun, 9 Feb 2025 00:01:07 +0800 Subject: [PATCH 05/42] cli: Improve pretty mode table --- Cargo.lock | 70 +++++++++++++++++++++++--------------- cli/Cargo.toml | 2 +- cli/app.rs | 91 ++++++++++++++++++-------------------------------- 3 files changed, 77 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 819311184..3d610591d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -399,29 +399,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" -[[package]] -name = "cli-table" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b53f9241f288a7b12c56565f04aaeaeeab6b8923d42d99255d4ca428b4d97f89" -dependencies = [ - "cli-table-derive", - "csv", - "termcolor", - "unicode-width", -] - -[[package]] -name = "cli-table-derive" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e83a93253aaae7c74eb7428ce4faa6e219ba94886908048888701819f82fb94" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "clipboard-win" version = "4.5.0" @@ -449,6 +426,17 @@ dependencies = [ "memchr", ] +[[package]] +name = "comfy-table" +version = "7.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a65ebfec4fb190b6f90e944a817d60499ee0744e582530e2c9900a22e591d9a" +dependencies = [ + "crossterm", + "unicode-segmentation", + "unicode-width 0.2.0", +] + [[package]] name = "comma" version = "1.0.0" @@ -595,6 +583,28 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags 2.8.0", + "crossterm_winapi", + "parking_lot", + "rustix", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -1564,7 +1574,7 @@ version = "0.0.14" dependencies = [ "anyhow", "clap", - "cli-table", + "comfy-table", "csv", "ctrlc", "dirs", @@ -1848,7 +1858,7 @@ dependencies = [ "terminal_size", "textwrap", "thiserror 1.0.69", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -2704,7 +2714,7 @@ dependencies = [ "radix_trie", "scopeguard", "unicode-segmentation", - "unicode-width", + "unicode-width 0.1.14", "utf8parse", "winapi", ] @@ -3033,7 +3043,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" dependencies = [ "unicode-linebreak", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -3201,6 +3211,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "unindent" version = "0.2.3" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 1886627e4..03857adb2 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -21,7 +21,7 @@ path = "main.rs" [dependencies] anyhow = "1.0.75" clap = { version = "4.5", features = ["derive"] } -cli-table = "0.4.7" +comfy-table = "7.1.4" dirs = "5.0.1" env_logger = "0.10.1" limbo_core = { path = "../core" } diff --git a/cli/app.rs b/cli/app.rs index 7fa7b70f0..45dd14896 100644 --- a/cli/app.rs +++ b/cli/app.rs @@ -2,8 +2,7 @@ use crate::{ import::{ImportFile, IMPORT_HELP}, opcodes_dictionary::OPCODE_DESCRIPTIONS, }; -use cli_table::format::{Border, HorizontalLine, Separator, VerticalLine}; -use cli_table::{Cell, Style, Table}; +use comfy_table::{Attribute, Cell, CellAlignment, ContentArrangement, Row, Table}; use limbo_core::{Database, LimboError, Statement, StepResult, Value}; use clap::{Parser, ValueEnum}; @@ -670,35 +669,42 @@ impl Limbo { println!("Query interrupted."); return Ok(()); } - let mut table_rows: Vec> = vec![]; + let mut table = Table::new(); + table + .set_content_arrangement(ContentArrangement::Dynamic) + .set_truncation_indicator("…") + .apply_modifier("││──├─┼┤│─┼├┤┬┴┌┐└┘"); if rows.num_columns() > 0 { - let columns = (0..rows.num_columns()) + let header = (0..rows.num_columns()) .map(|i| { - rows.get_column_name(i) - .map(|name| name.cell().bold(true)) - .unwrap_or_else(|| " ".cell()) + let name = rows.get_column_name(i).cloned().unwrap_or_default(); + Cell::new(name).add_attribute(Attribute::Bold) }) .collect::>(); - table_rows.push(columns); + table.set_header(header); } loop { match rows.step() { Ok(StepResult::Row) => { - let row = rows.row().unwrap(); - table_rows.push( - row.values - .iter() - .map(|value| match value.to_value() { - Value::Null => self.opts.null_value.clone().cell(), - Value::Integer(i) => i.to_string().cell(), - Value::Float(f) => f.to_string().cell(), - Value::Text(s) => s.cell(), - Value::Blob(b) => { - format!("{}", String::from_utf8_lossy(b)).cell() - } - }) - .collect(), - ); + let record = rows.row().unwrap(); + let mut row = Row::new(); + row.max_height(1); + for value in &record.values { + let (content, alignment) = match value.to_value() { + Value::Null => { + (self.opts.null_value.clone(), CellAlignment::Left) + } + Value::Integer(i) => (i.to_string(), CellAlignment::Right), + Value::Float(f) => (f.to_string(), CellAlignment::Right), + Value::Text(s) => (s.to_string(), CellAlignment::Left), + Value::Blob(b) => ( + String::from_utf8_lossy(b).to_string(), + CellAlignment::Left, + ), + }; + row.add_cell(Cell::new(content).set_alignment(alignment)); + } + table.add_row(row); } Ok(StepResult::IO) => { self.io.run_once()?; @@ -718,7 +724,10 @@ impl Limbo { } } } - self.print_table(table_rows); + + if table.header().is_some() { + let _ = self.write_fmt(format_args!("{}", table)); + } } }, Ok(None) => {} @@ -734,40 +743,6 @@ impl Limbo { Ok(()) } - fn print_table(&mut self, table_rows: Vec>) { - if table_rows.is_empty() { - return; - } - - let horizontal_line = HorizontalLine::new('┌', '┐', '┬', '─'); - let horizontal_line_mid = HorizontalLine::new('├', '┤', '┼', '─'); - let horizontal_line_bottom = HorizontalLine::new('└', '┘', '┴', '─'); - let vertical_line = VerticalLine::new('│'); - - let border = Border::builder() - .top(horizontal_line) - .bottom(horizontal_line_bottom) - .left(vertical_line.clone()) - .right(vertical_line.clone()) - .build(); - - let separator = Separator::builder() - .column(Some(vertical_line)) - .row(Some(horizontal_line_mid)) - .build(); - - if let Ok(table) = table_rows - .table() - .border(border) - .separator(separator) - .display() - { - let _ = self.write_fmt(format_args!("{}", table)); - } else { - let _ = self.writeln("Error displaying table."); - } - } - fn display_schema(&mut self, table: Option<&str>) -> anyhow::Result<()> { let sql = match table { Some(table_name) => format!( From 670dac59399ed17006c77ceb54ca5c391ab12f35 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sat, 8 Feb 2025 18:04:39 +0200 Subject: [PATCH 06/42] sqlite3-parser: box the where clause in Delete --- core/translate/delete.rs | 11 ++++++++--- vendored/sqlite3-parser/src/parser/ast/mod.rs | 2 +- vendored/sqlite3-parser/src/parser/parse.y | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/core/translate/delete.rs b/core/translate/delete.rs index ffad33d73..b5ce85fdc 100644 --- a/core/translate/delete.rs +++ b/core/translate/delete.rs @@ -13,7 +13,7 @@ pub fn translate_delete( query_mode: QueryMode, schema: &Schema, tbl_name: &QualifiedName, - where_clause: Option, + where_clause: Option>, limit: Option>, syms: &SymbolTable, ) -> Result { @@ -35,7 +35,7 @@ pub fn translate_delete( pub fn prepare_delete_plan( schema: &Schema, tbl_name: &QualifiedName, - where_clause: Option, + where_clause: Option>, limit: Option>, ) -> Result { let table = match schema.get_table(tbl_name.name.0.as_str()) { @@ -53,7 +53,12 @@ pub fn prepare_delete_plan( let mut where_predicates = vec![]; // Parse the WHERE clause - parse_where(where_clause, &table_references, None, &mut where_predicates)?; + parse_where( + where_clause.map(|e| *e), + &table_references, + None, + &mut where_predicates, + )?; // Parse the LIMIT/OFFSET clause let (resolved_limit, resolved_offset) = limit.map_or(Ok((None, None)), |l| parse_limit(*l))?; diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index f149322b3..077f2b6ac 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -168,7 +168,7 @@ pub enum Stmt { /// `INDEXED` indexed: Option, /// `WHERE` clause - where_clause: Option, + where_clause: Option>, /// `RETURNING` returning: Option>, /// `ORDER BY` diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index 226dca5a7..76c053964 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -761,13 +761,13 @@ limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). cmd ::= with(C) DELETE FROM xfullname(X) indexed_opt(I) where_opt_ret(W) orderby_opt(O) limit_opt(L). { let (where_clause, returning) = W; - self.ctx.stmt = Some(Stmt::Delete{ with: C, tbl_name: X, indexed: I, where_clause, returning, + self.ctx.stmt = Some(Stmt::Delete{ with: C, tbl_name: X, indexed: I, where_clause: where_clause.map(Box::new), returning, order_by: O, limit: L }); } %else cmd ::= with(C) DELETE FROM xfullname(X) indexed_opt(I) where_opt_ret(W). { let (where_clause, returning) = W; - self.ctx.stmt = Some(Stmt::Delete{ with: C, tbl_name: X, indexed: I, where_clause, returning, + self.ctx.stmt = Some(Stmt::Delete{ with: C, tbl_name: X, indexed: I, where_clause: where_clause.map(Box::new), returning, order_by: None, limit: None }); } %endif From 0dba39b025f82905fca2d3e504f999450d2b55e8 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sat, 8 Feb 2025 18:05:13 +0200 Subject: [PATCH 07/42] sqlite3-parser: box everything in Attach --- vendored/sqlite3-parser/src/parser/ast/mod.rs | 6 +++--- vendored/sqlite3-parser/src/parser/parse.y | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index 077f2b6ac..a60d2a592 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -78,11 +78,11 @@ pub enum Stmt { Attach { /// filename // TODO distinction between ATTACH and ATTACH DATABASE - expr: Expr, + expr: Box, /// schema name - db_name: Expr, + db_name: Box, /// password - key: Option, + key: Option>, }, /// `BEGIN`: tx type, tx name Begin(Option, Option), diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index 76c053964..0750af969 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -1276,7 +1276,7 @@ cmd ::= DROP TRIGGER ifexists(NOERR) fullname(X). { //////////////////////// ATTACH DATABASE file AS name ///////////////////////// %ifndef SQLITE_OMIT_ATTACH cmd ::= ATTACH database_kw_opt expr(F) AS expr(D) key_opt(K). { - self.ctx.stmt = Some(Stmt::Attach{ expr: F, db_name: D, key: K }); + self.ctx.stmt = Some(Stmt::Attach{ expr: Box::new(F), db_name: Box::new(D), key: K.map(Box::new) }); } cmd ::= DETACH database_kw_opt expr(D). { self.ctx.stmt = Some(Stmt::Detach(D)); From f341474fee3c76869fd49e8e6f43ebf7234c0e86 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sat, 8 Feb 2025 18:05:49 +0200 Subject: [PATCH 08/42] sqlite3-parser: box large members of CreateTrigger --- vendored/sqlite3-parser/src/parser/ast/mod.rs | 4 ++-- vendored/sqlite3-parser/src/parser/parse.y | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index a60d2a592..91f5633e3 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -125,13 +125,13 @@ pub enum Stmt { /// `BEFORE`/`AFTER`/`INSTEAD OF` time: Option, /// `DELETE`/`INSERT`/`UPDATE` - event: TriggerEvent, + event: Box, /// table name tbl_name: QualifiedName, /// `FOR EACH ROW` for_each_row: bool, /// `WHEN` - when_clause: Option, + when_clause: Option>, /// statements commands: Vec, }, diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index 0750af969..694bb4216 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -1167,8 +1167,8 @@ minus_num(A) ::= MINUS number(X). {A = Expr::unary(UnaryOperator::Negative, cmd ::= createkw temp(T) TRIGGER ifnotexists(NOERR) fullname(B) trigger_time(C) trigger_event(D) ON fullname(E) foreach_clause(X) when_clause(G) BEGIN trigger_cmd_list(S) END. { self.ctx.stmt = Some(Stmt::CreateTrigger{ - temporary: T, if_not_exists: NOERR, trigger_name: B, time: C, event: D, tbl_name: E, - for_each_row: X, when_clause: G, commands: S + temporary: T, if_not_exists: NOERR, trigger_name: B, time: C, event: Box::new(D), tbl_name: E, + for_each_row: X, when_clause: G.map(Box::new), commands: S }); } From ac7f9d67b7c62d41cb43491128dffa0b8bc04ef7 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sat, 8 Feb 2025 18:06:45 +0200 Subject: [PATCH 09/42] sqlite3-parser: box large members of Upsert --- vendored/sqlite3-parser/src/parser/ast/mod.rs | 4 ++-- vendored/sqlite3-parser/src/parser/parse.y | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index 91f5633e3..ffeafea07 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -1769,9 +1769,9 @@ pub enum TransactionType { #[derive(Clone, Debug, PartialEq, Eq)] pub struct Upsert { /// conflict targets - pub index: Option, + pub index: Option>, /// `DO` clause - pub do_clause: UpsertDo, + pub do_clause: Box, /// next upsert pub next: Option>, } diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index 694bb4216..af16eefa2 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -851,16 +851,16 @@ upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) { let index = UpsertIndex{ targets: T, where_clause: TW }; let do_clause = UpsertDo::Set{ sets: Z, where_clause: W }; let (next, returning) = N; - A = (Some(Upsert{ index: Some(index), do_clause, next: next.map(Box::new) }), returning);} + A = (Some(Upsert{ index: Some(Box::new(index)), do_clause: Box::new(do_clause), next: next.map(Box::new) }), returning);} upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) DO NOTHING upsert(N). { let index = UpsertIndex{ targets: T, where_clause: TW }; let (next, returning) = N; - A = (Some(Upsert{ index: Some(index), do_clause: UpsertDo::Nothing, next: next.map(Box::new) }), returning); } + A = (Some(Upsert{ index: Some(Box::new(index)), do_clause: Box::new(UpsertDo::Nothing), next: next.map(Box::new) }), returning); } upsert(A) ::= ON CONFLICT DO NOTHING returning(R). - { A = (Some(Upsert{ index: None, do_clause: UpsertDo::Nothing, next: None }), R); } + { A = (Some(Upsert{ index: None, do_clause: Box::new(UpsertDo::Nothing), next: None }), R); } upsert(A) ::= ON CONFLICT DO UPDATE SET setlist(Z) where_opt(W) returning(R). { let do_clause = UpsertDo::Set{ sets: Z, where_clause: W }; - A = (Some(Upsert{ index: None, do_clause, next: None }), R);} + A = (Some(Upsert{ index: None, do_clause: Box::new(do_clause), next: None }), R);} %type returning {Option>} returning(A) ::= RETURNING selcollist(X). {A = Some(X);} From 74262042040ffef407ffe516c11d967fde89ef32 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sat, 8 Feb 2025 18:07:38 +0200 Subject: [PATCH 10/42] sqlite3-parser: box Following and Preceding in FrameBound --- vendored/sqlite3-parser/src/parser/ast/mod.rs | 4 ++-- vendored/sqlite3-parser/src/parser/parse.y | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index ffeafea07..f8534e9a3 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -1872,9 +1872,9 @@ pub enum FrameBound { /// `CURRENT ROW` CurrentRow, /// `FOLLOWING` - Following(Expr), + Following(Box), /// `PRECEDING` - Preceding(Expr), + Preceding(Box), /// `UNBOUNDED FOLLOWING` UnboundedFollowing, /// `UNBOUNDED PRECEDING` diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index af16eefa2..0f17415e4 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -1454,9 +1454,9 @@ frame_bound_s(A) ::= UNBOUNDED PRECEDING. {A = FrameBound::UnboundedPreceding;} frame_bound_e(A) ::= frame_bound(X). {A = X;} frame_bound_e(A) ::= UNBOUNDED FOLLOWING. {A = FrameBound::UnboundedFollowing;} -frame_bound(A) ::= expr(X) PRECEDING. { A = FrameBound::Preceding(X); } +frame_bound(A) ::= expr(X) PRECEDING. { A = FrameBound::Preceding(Box::new(X)); } frame_bound(A) ::= CURRENT ROW. { A = FrameBound::CurrentRow; } -frame_bound(A) ::= expr(X) FOLLOWING. { A = FrameBound::Following(X); } +frame_bound(A) ::= expr(X) FOLLOWING. { A = FrameBound::Following(Box::new(X)); } %type frame_exclude_opt {Option} frame_exclude_opt(A) ::= . {A = None;} From 2a82091cb38be49a28ccb8c4fe57df2d464d3a73 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sat, 8 Feb 2025 18:08:31 +0200 Subject: [PATCH 11/42] sqlite3-parser: box the where clause in Update --- vendored/sqlite3-parser/src/parser/ast/mod.rs | 2 +- vendored/sqlite3-parser/src/parser/parse.y | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index f8534e9a3..b9e662683 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -256,7 +256,7 @@ pub enum Stmt { /// `FROM` from: Option, /// `WHERE` clause - where_clause: Option, + where_clause: Option>, /// `RETURNING` returning: Option>, /// `ORDER BY` diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index 0f17415e4..7fb578158 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -791,14 +791,14 @@ cmd ::= with(C) UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from where_opt_ret(W) orderby_opt(O) limit_opt(L). { let (where_clause, returning) = W; self.ctx.stmt = Some(Stmt::Update { with: C, or_conflict: R, tbl_name: X, indexed: I, sets: Y, from: F, - where_clause, returning, order_by: O, limit: L }); + where_clause: where_clause.map(Box::new), returning, order_by: O, limit: L }); } %else cmd ::= with(C) UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F) where_opt_ret(W). { let (where_clause, returning) = W; self.ctx.stmt = Some(Stmt::Update { with: C, or_conflict: R, tbl_name: X, indexed: I, sets: Y, from: F, - where_clause, returning, order_by: None, limit: None }); + where_clause: where_clause.map(Box::new), returning, order_by: None, limit: None }); } %endif From 781aa3b5d61d919d429e877957285abc2fc08565 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sat, 8 Feb 2025 18:08:54 +0200 Subject: [PATCH 12/42] sqlite3-parser: box the having clause in GroupBy --- core/translate/select.rs | 2 +- vendored/sqlite3-parser/src/parser/ast/mod.rs | 2 +- vendored/sqlite3-parser/src/parser/parse.y | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/translate/select.rs b/core/translate/select.rs index 2a055afd2..b5091af64 100644 --- a/core/translate/select.rs +++ b/core/translate/select.rs @@ -305,7 +305,7 @@ pub fn prepare_select_plan( exprs: group_by.exprs, having: if let Some(having) = group_by.having { let mut predicates = vec![]; - break_predicate_at_and_boundaries(having, &mut predicates); + break_predicate_at_and_boundaries(*having, &mut predicates); for expr in predicates.iter_mut() { bind_column_references( expr, diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index b9e662683..43f2c5dfb 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -1005,7 +1005,7 @@ pub struct GroupBy { /// expressions pub exprs: Vec, /// `HAVING` - pub having: Option, // HAVING clause on a non-aggregate query + pub having: Option>, // HAVING clause on a non-aggregate query } /// identifier or one of several keywords or `INDEXED` diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index 7fb578158..6402a6d5d 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -731,7 +731,7 @@ nulls(A) ::= . {A = None;} %type groupby_opt {Option} groupby_opt(A) ::= . {A = None;} -groupby_opt(A) ::= GROUP BY nexprlist(X) having_opt(Y). {A = Some(GroupBy{ exprs: X, having: Y });} +groupby_opt(A) ::= GROUP BY nexprlist(X) having_opt(Y). {A = Some(GroupBy{ exprs: X, having: Y.map(Box::new) });} %type having_opt {Option} having_opt(A) ::= . {A = None;} From 4faadd86b0af548d3d176181f7dac516ea45acde Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sat, 8 Feb 2025 18:09:58 +0200 Subject: [PATCH 13/42] sqlite3-parser: box the InsertBody --- .../sqlite3-parser/src/parser/ast/check.rs | 20 +++++++++---------- vendored/sqlite3-parser/src/parser/ast/mod.rs | 2 +- vendored/sqlite3-parser/src/parser/parse.y | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/vendored/sqlite3-parser/src/parser/ast/check.rs b/vendored/sqlite3-parser/src/parser/ast/check.rs index e1e0eecd3..ca1e8cb55 100644 --- a/vendored/sqlite3-parser/src/parser/ast/check.rs +++ b/vendored/sqlite3-parser/src/parser/ast/check.rs @@ -160,19 +160,19 @@ impl Stmt { } => Err(custom_err!("ORDER BY without LIMIT on DELETE")), Self::Insert { columns: Some(columns), - body: InsertBody::Select(select, ..), + body, .. - } => match select.body.select.column_count() { - ColumnCount::Fixed(n) if n != columns.len() => { - Err(custom_err!("{} values for {} columns", n, columns.len())) + } => match &**body { + InsertBody::Select(select, ..) => match select.body.select.column_count() { + ColumnCount::Fixed(n) if n != columns.len() => { + Err(custom_err!("{} values for {} columns", n, columns.len())) + } + _ => Ok(()), + }, + InsertBody::DefaultValues => { + Err(custom_err!("0 values for {} columns", columns.len())) } - _ => Ok(()), }, - Self::Insert { - columns: Some(columns), - body: InsertBody::DefaultValues, - .. - } => Err(custom_err!("0 values for {} columns", columns.len())), Self::Update { order_by: Some(_), limit: None, diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index 43f2c5dfb..8cf4f805d 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -217,7 +217,7 @@ pub enum Stmt { /// `COLUMNS` columns: Option, /// `VALUES` or `SELECT` - body: InsertBody, + body: Box, /// `RETURNING` returning: Option>, }, diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index 6402a6d5d..bb3c80e91 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -828,13 +828,13 @@ cmd ::= with(W) insert_cmd(R) INTO xfullname(X) idlist_opt(F) select(S) let (upsert, returning) = U; let body = InsertBody::Select(Box::new(S), upsert); self.ctx.stmt = Some(Stmt::Insert{ with: W, or_conflict: R, tbl_name: X, columns: F, - body, returning }); + body: Box::new(body), returning }); } cmd ::= with(W) insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES returning(Y). { let body = InsertBody::DefaultValues; self.ctx.stmt = Some(Stmt::Insert{ with: W, or_conflict: R, tbl_name: X, columns: F, - body, returning: Y }); + body: Box::new(body), returning: Y }); } %type upsert {(Option, Option>)} From 69d72da837d0668e93f671a6692f63546c97c064 Mon Sep 17 00:00:00 2001 From: alpaylan Date: Sat, 8 Feb 2025 12:53:25 -0500 Subject: [PATCH 14/42] fix the diff computing algorithm --- simulator/generation/plan.rs | 48 ++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/simulator/generation/plan.rs b/simulator/generation/plan.rs index b601a8975..ce24e0693 100644 --- a/simulator/generation/plan.rs +++ b/simulator/generation/plan.rs @@ -47,9 +47,9 @@ impl InteractionPlan { .map(|i| i.interactions()) .collect::>(); - let (mut i, mut j1, mut j2) = (0, 0, 0); + let (mut i, mut j) = (0, 0); - while i < interactions.len() && j1 < plan.len() { + while i < interactions.len() && j < plan.len() { if interactions[i].starts_with("-- begin") || interactions[i].starts_with("-- end") || interactions[i].is_empty() @@ -57,32 +57,32 @@ impl InteractionPlan { i += 1; continue; } - if plan[j1].len() == j2 { - i += 1; - j1 += 1; - j2 = 0; - } else if interactions[i].contains(plan[j1][j2].to_string().as_str()) { - i += 1; - if j2 + 1 < plan[j1].len() { - j2 += 1; - } else { - j1 += 1; - j2 = 0; - } - } else { - plan[j1].remove(j2); - if plan[j1].is_empty() { - plan.remove(j1); - j2 = 0; + // interactions[i] is the i'th line in the human readable plan + // plan[j][k] is the k'th interaction in the j'th property + let mut k = 0; + + while k < plan[j].len() { + + if i >= interactions.len() { + let _ = plan.split_off(j + 1); + let _ = plan[j].split_off(k); + break; + } + + if interactions[i].contains(plan[j][k].to_string().as_str()) { + i += 1; + k += 1; + } else { + plan[j].remove(k); } } - } - if j1 < plan.len() { - if j2 < plan[j1].len() { - let _ = plan[j1].split_off(j2); + + if plan[j].is_empty() { + plan.remove(j); + } else { + j += 1; } - let _ = plan.split_off(j1); } plan From 7ddbcf07afe49821b1235be2f40e1a294d62fd54 Mon Sep 17 00:00:00 2001 From: alpaylan Date: Sat, 8 Feb 2025 15:41:57 -0500 Subject: [PATCH 15/42] fix formatting --- simulator/generation/plan.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/simulator/generation/plan.rs b/simulator/generation/plan.rs index ce24e0693..cf41c1060 100644 --- a/simulator/generation/plan.rs +++ b/simulator/generation/plan.rs @@ -63,7 +63,6 @@ impl InteractionPlan { let mut k = 0; while k < plan[j].len() { - if i >= interactions.len() { let _ = plan.split_off(j + 1); let _ = plan[j].split_off(k); From be5ea350bba83bb9122fc7223cced0885a2b8380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20L=C3=B3pez?= Date: Sun, 9 Feb 2025 01:10:35 +0100 Subject: [PATCH 16/42] bindings: select io_uring feature from limbo_core explicitly as it will be made non-default --- bindings/go/Cargo.toml | 4 ++-- bindings/java/Cargo.toml | 2 +- bindings/python/Cargo.toml | 2 +- bindings/rust/Cargo.toml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bindings/go/Cargo.toml b/bindings/go/Cargo.toml index b73902c5f..e268d0a27 100644 --- a/bindings/go/Cargo.toml +++ b/bindings/go/Cargo.toml @@ -17,7 +17,7 @@ io_uring = ["limbo_core/io_uring"] [dependencies] -limbo_core = { path = "../../core/" } +limbo_core = { path = "../../core" } [target.'cfg(target_os = "linux")'.dependencies] -limbo_core = { path = "../../core/", features = ["io_uring"] } +limbo_core = { path = "../../core", features = ["io_uring"] } diff --git a/bindings/java/Cargo.toml b/bindings/java/Cargo.toml index 9b78b1597..fd38d1e65 100644 --- a/bindings/java/Cargo.toml +++ b/bindings/java/Cargo.toml @@ -12,6 +12,6 @@ crate-type = ["cdylib"] path = "rs_src/lib.rs" [dependencies] -limbo_core = { path = "../../core" } +limbo_core = { path = "../../core", features = ["io_uring"] } jni = "0.21.1" thiserror = "2.0.9" diff --git a/bindings/python/Cargo.toml b/bindings/python/Cargo.toml index 6157fa579..43639f94c 100644 --- a/bindings/python/Cargo.toml +++ b/bindings/python/Cargo.toml @@ -16,7 +16,7 @@ extension-module = ["pyo3/extension-module"] [dependencies] anyhow = "1.0" -limbo_core = { path = "../../core" } +limbo_core = { path = "../../core", features = ["io_uring"] } pyo3 = { version = "0.22.4", features = ["anyhow"] } [build-dependencies] diff --git a/bindings/rust/Cargo.toml b/bindings/rust/Cargo.toml index bdf101c56..a5c3a3829 100644 --- a/bindings/rust/Cargo.toml +++ b/bindings/rust/Cargo.toml @@ -9,7 +9,7 @@ license.workspace = true repository.workspace = true [dependencies] -limbo_core = { path = "../../core" } +limbo_core = { path = "../../core", features = ["io_uring"] } thiserror = "2.0.9" [dev-dependencies] From 62dea0b12b275ac74faa032b1e2966d2dd74dbb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20L=C3=B3pez?= Date: Sun, 9 Feb 2025 01:11:00 +0100 Subject: [PATCH 17/42] cli: select io_uring feature by default --- cli/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 1886627e4..7464b36a5 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -31,4 +31,5 @@ csv = "1.3.1" miette = { version = "7.4.0", features = ["fancy"] } [features] +default = ["io_uring"] io_uring = ["limbo_core/io_uring"] From c07c08aa988f8c85e616a15f23b9b36867905e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20L=C3=B3pez?= Date: Sun, 9 Feb 2025 01:12:27 +0100 Subject: [PATCH 18/42] core: make io_uring feature non-default. All crates that depend on core select it by default. This enables us to build CLI without io_uring, which before this commit would still have used io_uring in core. --- core/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/Cargo.toml b/core/Cargo.toml index 687f4ff19..d13591aee 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -14,7 +14,7 @@ name = "limbo_core" path = "lib.rs" [features] -default = ["fs", "json", "uuid", "io_uring", "time"] +default = ["fs", "json", "uuid", "time"] fs = [] json = [ "dep:jsonb", From 83b158fb3a2bcb2ab2663dfb1d838a69fbcc0eaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20L=C3=B3pez?= Date: Sun, 9 Feb 2025 01:13:12 +0100 Subject: [PATCH 19/42] core: silence some unused warnings when building without default features --- core/ext/mod.rs | 1 + core/io/mod.rs | 3 +++ core/io/unix.rs | 1 + core/storage/database.rs | 4 +++- core/translate/expr.rs | 1 + 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/core/ext/mod.rs b/core/ext/mod.rs index 67fd78491..b6fb67fbb 100644 --- a/core/ext/mod.rs +++ b/core/ext/mod.rs @@ -153,6 +153,7 @@ impl Database { } pub fn register_builtins(&self) -> Result<(), String> { + #[allow(unused_variables)] let ext_api = self.build_limbo_ext(); #[cfg(feature = "uuid")] if unsafe { !limbo_uuid::register_extension_static(&ext_api).is_ok() } { diff --git a/core/io/mod.rs b/core/io/mod.rs index f88a5d554..50b4551bf 100644 --- a/core/io/mod.rs +++ b/core/io/mod.rs @@ -166,14 +166,17 @@ impl Buffer { cfg_block! { #[cfg(all(target_os = "linux", feature = "io_uring"))] { mod io_uring; + #[cfg(feature = "fs")] pub use io_uring::UringIO; mod unix; + #[cfg(feature = "fs")] pub use unix::UnixIO; pub use io_uring::UringIO as PlatformIO; } #[cfg(any(all(target_os = "linux",not(feature = "io_uring")), target_os = "macos"))] { mod unix; + #[cfg(feature = "fs")] pub use unix::UnixIO; pub use unix::UnixIO as PlatformIO; } diff --git a/core/io/unix.rs b/core/io/unix.rs index effd94bf5..d06b71770 100644 --- a/core/io/unix.rs +++ b/core/io/unix.rs @@ -22,6 +22,7 @@ pub struct UnixIO { } impl UnixIO { + #[cfg(feature = "fs")] pub fn new() -> Result { debug!("Using IO backend 'syscall'"); Ok(Self { diff --git a/core/storage/database.rs b/core/storage/database.rs index e59519f38..7e30c9215 100644 --- a/core/storage/database.rs +++ b/core/storage/database.rs @@ -1,4 +1,6 @@ -use crate::{error::LimboError, io::Completion, Buffer, Result}; +#[cfg(feature = "fs")] +use crate::error::LimboError; +use crate::{io::Completion, Buffer, Result}; use std::{cell::RefCell, rc::Rc}; /// DatabaseStorage is an interface a database file that consists of pages. diff --git a/core/translate/expr.rs b/core/translate/expr.rs index 8ddb580df..36acfa935 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -159,6 +159,7 @@ macro_rules! expect_arguments_min { }}; } +#[allow(unused_macros)] macro_rules! expect_arguments_even { ( $args:expr, From 79e2fba42467372aabf8b52501781cbe7a899a6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=A0=EC=9A=B0?= Date: Sun, 9 Feb 2025 17:17:47 +0900 Subject: [PATCH 20/42] Implement minor methods/features in JDBC4Connection.java --- .../tursodatabase/jdbc4/JDBC4Connection.java | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java index d5b73e627..34287f0f9 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java @@ -10,6 +10,8 @@ import org.github.tursodatabase.core.LimboConnection; public class JDBC4Connection extends LimboConnection { + private Map> typeMap = new HashMap<>(); + public JDBC4Connection(String url, String filePath) throws SQLException { super(url, filePath); } @@ -45,17 +47,8 @@ public class JDBC4Connection extends LimboConnection { } @Override - @SkipNullableCheck - public CallableStatement prepareCall(String sql) throws SQLException { - // TODO - return null; - } - - @Override - @SkipNullableCheck public String nativeSQL(String sql) throws SQLException { - // TODO - return ""; + return sql; } @Override @@ -108,13 +101,10 @@ public class JDBC4Connection extends LimboConnection { } @Override - public void setCatalog(String catalog) throws SQLException { - // TODO - } + public void setCatalog(String catalog) throws SQLException {} @Override public String getCatalog() throws SQLException { - // TODO return ""; } @@ -149,33 +139,30 @@ public class JDBC4Connection extends LimboConnection { return null; } - @Override - @SkipNullableCheck - public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) - throws SQLException { - // TODO - return null; - } - @Override public Map> getTypeMap() throws SQLException { - // TODO - return new HashMap<>(); + return this.typeMap; } @Override public void setTypeMap(Map> map) throws SQLException { - // TODO - } - - @Override - public void setHoldability(int holdability) throws SQLException { - // TODO + synchronized (this) { + this.typeMap = map; + } } @Override public int getHoldability() throws SQLException { - return 0; + checkOpen(); + return ResultSet.CLOSE_CURSORS_AT_COMMIT; + } + + @Override + public void setHoldability(int holdability) throws SQLException { + checkOpen(); + if (holdability != ResultSet.CLOSE_CURSORS_AT_COMMIT) { + throw new SQLException("Limbo only supports CLOSE_CURSORS_AT_COMMIT"); + } } @Override @@ -212,12 +199,25 @@ public class JDBC4Connection extends LimboConnection { } @Override - @SkipNullableCheck + public CallableStatement prepareCall(String sql) throws SQLException { + return prepareCall( + sql, + ResultSet.TYPE_FORWARD_ONLY, + ResultSet.CONCUR_READ_ONLY, + ResultSet.CLOSE_CURSORS_AT_COMMIT); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) + throws SQLException { + return prepareCall(sql, resultSetType, resultSetConcurrency, ResultSet.CLOSE_CURSORS_AT_COMMIT); + } + + @Override public CallableStatement prepareCall( String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - // TODO - return null; + throw new SQLException("Limbo does not support stored procedures"); } @Override From 1f3ddaeec6d749938005a298e7cf2a640787dbfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=A0=EC=9A=B0?= Date: Sun, 9 Feb 2025 17:24:35 +0900 Subject: [PATCH 21/42] Implement prepareStatement --- .../tursodatabase/jdbc4/JDBC4Connection.java | 56 +++++++++---------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java index 34287f0f9..598404b06 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java @@ -41,11 +41,6 @@ public class JDBC4Connection extends LimboConnection { return new JDBC4Statement(this); } - @Override - public PreparedStatement prepareStatement(String sql) throws SQLException { - return new JDBC4PreparedStatement(this, sql); - } - @Override public String nativeSQL(String sql) throws SQLException { return sql; @@ -131,14 +126,6 @@ public class JDBC4Connection extends LimboConnection { // TODO } - @Override - @SkipNullableCheck - public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) - throws SQLException { - // TODO - return null; - } - @Override public Map> getTypeMap() throws SQLException { return this.typeMap; @@ -189,15 +176,6 @@ public class JDBC4Connection extends LimboConnection { // TODO } - @Override - @SkipNullableCheck - public PreparedStatement prepareStatement( - String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) - throws SQLException { - // TODO - return null; - } - @Override public CallableStatement prepareCall(String sql) throws SQLException { return prepareCall( @@ -221,24 +199,40 @@ public class JDBC4Connection extends LimboConnection { } @Override - @SkipNullableCheck + public PreparedStatement prepareStatement(String sql) throws SQLException { + return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) + throws SQLException { + return prepareStatement(sql, resultSetType, resultSetConcurrency, ResultSet.CLOSE_CURSORS_AT_COMMIT); + } + + @Override + public PreparedStatement prepareStatement( + String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) + throws SQLException { + checkOpen(); + checkCursor(resultSetType, resultSetConcurrency, resultSetHoldability); + return new JDBC4PreparedStatement(this, sql); + } + + @Override public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { - // TODO - return null; + return prepareStatement(sql); } @Override - @SkipNullableCheck public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { - // TODO - return null; + // TODO: maybe we can enhance this functionality by using columnIndexes + return prepareStatement(sql); } @Override - @SkipNullableCheck public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { - // TODO - return null; + // TODO: maybe we can enhance this functionality by using columnNames + return prepareStatement(sql); } @Override From 4e067b2997db25bb6781ab6779bc8f7ca6bb5fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=A0=EC=9A=B0?= Date: Sun, 9 Feb 2025 17:24:52 +0900 Subject: [PATCH 22/42] Throw exceptions on unsupported methods --- .../tursodatabase/jdbc4/JDBC4Connection.java | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java index 598404b06..61df095ff 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java @@ -236,31 +236,24 @@ public class JDBC4Connection extends LimboConnection { } @Override - @SkipNullableCheck public Clob createClob() throws SQLException { - // TODO - return null; + throw new SQLFeatureNotSupportedException("createClob not supported"); } @Override - @SkipNullableCheck public Blob createBlob() throws SQLException { - // TODO - return null; + throw new SQLFeatureNotSupportedException("createBlob not supported"); } @Override - @SkipNullableCheck public NClob createNClob() throws SQLException { - // TODO - return null; + throw new SQLFeatureNotSupportedException("createNClob not supported"); } @Override @SkipNullableCheck public SQLXML createSQLXML() throws SQLException { - // TODO - return null; + throw new SQLFeatureNotSupportedException("createSQLXML not supported"); } @Override From 968ae74810623ed82a84f76098fe4ab27c6947d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=A0=EC=9A=B0?= Date: Sun, 9 Feb 2025 17:28:32 +0900 Subject: [PATCH 23/42] Implement isValid --- .../tursodatabase/jdbc4/JDBC4Connection.java | 18 ++++++++++++------ .../jdbc4/JDBC4ConnectionTest.java | 11 +++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java index 61df095ff..b6e2dcfe7 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java @@ -205,14 +205,15 @@ public class JDBC4Connection extends LimboConnection { @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) - throws SQLException { - return prepareStatement(sql, resultSetType, resultSetConcurrency, ResultSet.CLOSE_CURSORS_AT_COMMIT); + throws SQLException { + return prepareStatement( + sql, resultSetType, resultSetConcurrency, ResultSet.CLOSE_CURSORS_AT_COMMIT); } @Override public PreparedStatement prepareStatement( - String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) - throws SQLException { + String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) + throws SQLException { checkOpen(); checkCursor(resultSetType, resultSetConcurrency, resultSetHoldability); return new JDBC4PreparedStatement(this, sql); @@ -258,8 +259,13 @@ public class JDBC4Connection extends LimboConnection { @Override public boolean isValid(int timeout) throws SQLException { - // TODO - return false; + if (isClosed()) { + return false; + } + + try (Statement statement = createStatement()) { + return statement.execute("select 1;"); + } } @Override diff --git a/bindings/java/src/test/java/org/github/tursodatabase/jdbc4/JDBC4ConnectionTest.java b/bindings/java/src/test/java/org/github/tursodatabase/jdbc4/JDBC4ConnectionTest.java index 1bc4fb526..6302bc899 100644 --- a/bindings/java/src/test/java/org/github/tursodatabase/jdbc4/JDBC4ConnectionTest.java +++ b/bindings/java/src/test/java/org/github/tursodatabase/jdbc4/JDBC4ConnectionTest.java @@ -84,4 +84,15 @@ class JDBC4ConnectionTest { connection.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, -1)); } + + @Test + void isValid_should_return_true_on_open_connection() throws SQLException { + assertTrue(connection.isValid(10)); + } + + @Test + void isValid_should_return_false_on_closed_connection() throws SQLException { + connection.close(); + assertFalse(connection.isValid(10)); + } } From ed9cf63c51c195daa88ba19966f0e2b46436b075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=A0=EC=9A=B0?= Date: Sun, 9 Feb 2025 17:37:19 +0900 Subject: [PATCH 24/42] Implement abort --- .../org/github/tursodatabase/jdbc4/JDBC4Connection.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java index b6e2dcfe7..8026827a6 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Connection.java @@ -319,7 +319,11 @@ public class JDBC4Connection extends LimboConnection { @Override public void abort(Executor executor) throws SQLException { - // TODO + if (isClosed()) { + return; + } + + close(); } @Override From d1789d1d6eab176078defb1db6fc482594ee695d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=A0=EC=9A=B0?= Date: Sun, 9 Feb 2025 17:49:16 +0900 Subject: [PATCH 25/42] Implement executeUpdate --- .../jdbc4/JDBC4PreparedStatement.java | 7 ++++- .../tursodatabase/jdbc4/JDBC4Statement.java | 26 +++++++++---------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4PreparedStatement.java b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4PreparedStatement.java index f109cb647..024fe3c3c 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4PreparedStatement.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4PreparedStatement.java @@ -24,6 +24,7 @@ import java.sql.Timestamp; import java.util.Calendar; import org.github.tursodatabase.annotations.SkipNullableCheck; import org.github.tursodatabase.core.LimboConnection; +import org.github.tursodatabase.core.LimboResultSet; public class JDBC4PreparedStatement extends JDBC4Statement implements PreparedStatement { @@ -46,7 +47,11 @@ public class JDBC4PreparedStatement extends JDBC4Statement implements PreparedSt @Override public int executeUpdate() throws SQLException { - // TODO + requireNonNull(this.statement); + final LimboResultSet resultSet = statement.getResultSet(); + resultSet.consumeAll(); + + // TODO: return updated count return 0; } diff --git a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Statement.java b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Statement.java index 729134a44..1bc0b6f63 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Statement.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/jdbc4/JDBC4Statement.java @@ -253,10 +253,8 @@ public class JDBC4Statement implements Statement { } @Override - @SkipNullableCheck - public Connection getConnection() throws SQLException { - // TODO - return null; + public Connection getConnection() { + return connection; } @Override @@ -274,32 +272,32 @@ public class JDBC4Statement implements Statement { @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { - // TODO - return 0; + // TODO: enhance + return executeUpdate(sql); } @Override public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { - // TODO - return 0; + // TODO: enhance + return executeUpdate(sql); } @Override public int executeUpdate(String sql, String[] columnNames) throws SQLException { - // TODO - return 0; + // TODO: enhance + return executeUpdate(sql); } @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { - // TODO - return false; + // TODO: enhance + return execute(sql); } @Override public boolean execute(String sql, int[] columnIndexes) throws SQLException { - // TODO - return false; + // TODO: enhance + return execute(sql); } @Override From d51c1dc5b1e3b4997e7e5a871cccf2c00561ad3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=A0=EC=9A=B0?= Date: Sun, 9 Feb 2025 18:40:42 +0900 Subject: [PATCH 26/42] Remove AbstractDB and move those methods into LimboDB --- .../github/tursodatabase/core/AbstractDB.java | 75 ------------------- .../tursodatabase/core/LimboConnection.java | 6 +- .../github/tursodatabase/core/LimboDB.java | 46 ++++++++---- .../tursodatabase/core/LimboDBTest.java | 20 ++++- 4 files changed, 49 insertions(+), 98 deletions(-) delete mode 100644 bindings/java/src/main/java/org/github/tursodatabase/core/AbstractDB.java diff --git a/bindings/java/src/main/java/org/github/tursodatabase/core/AbstractDB.java b/bindings/java/src/main/java/org/github/tursodatabase/core/AbstractDB.java deleted file mode 100644 index 4906acd9c..000000000 --- a/bindings/java/src/main/java/org/github/tursodatabase/core/AbstractDB.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.github.tursodatabase.core; - -import java.sql.SQLException; -import java.sql.SQLFeatureNotSupportedException; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Interface to Limbo. It provides some helper functions used by other parts of the driver. The goal - * of the helper functions here are not only to provide functionality, but to handle contractual - * differences between the JDBC specification and the Limbo API. - */ -public abstract class AbstractDB { - protected final String url; - protected final String filePath; - private final AtomicBoolean closed = new AtomicBoolean(true); - - public AbstractDB(String url, String filePath) { - this.url = url; - this.filePath = filePath; - } - - public boolean isClosed() { - return closed.get(); - } - - /** Aborts any pending operation and returns at its earliest opportunity. */ - public abstract void interrupt() throws SQLException; - - /** - * Creates an SQLite interface to a database for the given connection. - * - * @param openFlags Flags for opening the database. - * @throws SQLException if a database access error occurs. - */ - public final synchronized void open(int openFlags) throws SQLException { - open0(filePath, openFlags); - } - - protected abstract void open0(String fileName, int openFlags) throws SQLException; - - /** - * Closes a database connection and finalizes any remaining statements before the closing - * operation. - * - * @throws SQLException if a database access error occurs. - */ - public final synchronized void close() throws SQLException { - // TODO: add implementation - throw new SQLFeatureNotSupportedException(); - } - - /** - * Connects to a database. - * - * @return Pointer to the connection. - */ - public abstract long connect() throws SQLException; - - /** - * Creates an SQLite interface to a database with the provided open flags. - * - * @param fileName The database to open. - * @param openFlags Flags for opening the database. - * @return pointer to database instance - * @throws SQLException if a database access error occurs. - */ - protected abstract long openUtf8(byte[] fileName, int openFlags) throws SQLException; - - /** - * Closes the SQLite interface to a database. - * - * @throws SQLException if a database access error occurs. - */ - protected abstract void close0() throws SQLException; -} diff --git a/bindings/java/src/main/java/org/github/tursodatabase/core/LimboConnection.java b/bindings/java/src/main/java/org/github/tursodatabase/core/LimboConnection.java index 639a2be56..3267e69e6 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/core/LimboConnection.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/core/LimboConnection.java @@ -15,7 +15,7 @@ public abstract class LimboConnection implements Connection { private static final Logger logger = LoggerFactory.getLogger(LimboConnection.class); private final long connectionPtr; - private final AbstractDB database; + private final LimboDB database; private boolean closed; public LimboConnection(String url, String filePath) throws SQLException { @@ -33,7 +33,7 @@ public abstract class LimboConnection implements Connection { this.connectionPtr = this.database.connect(); } - private static AbstractDB open(String url, String filePath, Properties properties) + private static LimboDB open(String url, String filePath, Properties properties) throws SQLException { return LimboDBFactory.open(url, filePath, properties); } @@ -58,7 +58,7 @@ public abstract class LimboConnection implements Connection { return closed; } - public AbstractDB getDatabase() { + public LimboDB getDatabase() { return database; } diff --git a/bindings/java/src/main/java/org/github/tursodatabase/core/LimboDB.java b/bindings/java/src/main/java/org/github/tursodatabase/core/LimboDB.java index e1d619239..64b005d35 100644 --- a/bindings/java/src/main/java/org/github/tursodatabase/core/LimboDB.java +++ b/bindings/java/src/main/java/org/github/tursodatabase/core/LimboDB.java @@ -7,7 +7,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.sql.SQLException; -import java.util.concurrent.locks.ReentrantLock; import org.github.tursodatabase.LimboErrorCode; import org.github.tursodatabase.annotations.NativeInvocation; import org.github.tursodatabase.annotations.VisibleForTesting; @@ -16,14 +15,15 @@ import org.github.tursodatabase.utils.Logger; import org.github.tursodatabase.utils.LoggerFactory; /** This class provides a thin JNI layer over the SQLite3 C API. */ -public final class LimboDB extends AbstractDB { +public final class LimboDB implements AutoCloseable { private static final Logger logger = LoggerFactory.getLogger(LimboDB.class); // Pointer to database instance private long dbPointer; private boolean isOpen; + private final String url; + private final String filePath; private static boolean isLoaded; - private ReentrantLock dbLock = new ReentrantLock(); static { if ("The Android Project".equals(System.getProperty("java.vm.vendor"))) { @@ -176,23 +176,26 @@ public final class LimboDB extends AbstractDB { // TODO: receive config as argument private LimboDB(String url, String filePath) { - super(url, filePath); + this.url = url; + this.filePath = filePath; } // TODO: add support for JNI - @Override - protected native long openUtf8(byte[] file, int openFlags) throws SQLException; - - // TODO: add support for JNI - @Override - protected native void close0() throws SQLException; - - // TODO: add support for JNI - @Override public native void interrupt(); - @Override - protected void open0(String filePath, int openFlags) throws SQLException { + public boolean isClosed() { + return !this.isOpen; + } + + public boolean isOpen() { + return this.isOpen; + } + + public void open(int openFlags) throws SQLException { + open0(filePath, openFlags); + } + + private void open0(String filePath, int openFlags) throws SQLException { if (isOpen) { throw LimboExceptionUtils.buildLimboException( LimboErrorCode.LIMBO_ETC.code, "Already opened"); @@ -209,13 +212,24 @@ public final class LimboDB extends AbstractDB { isOpen = true; } - @Override + private native long openUtf8(byte[] file, int openFlags) throws SQLException; + public long connect() throws SQLException { return connect0(dbPointer); } private native long connect0(long databasePtr) throws SQLException; + @Override + public void close() throws Exception { + if (!isOpen) return; + + close0(dbPointer); + isOpen = false; + } + + private native void close0(long databasePtr) throws SQLException; + @VisibleForTesting native void throwJavaException(int errorCode) throws SQLException; diff --git a/bindings/java/src/test/java/org/github/tursodatabase/core/LimboDBTest.java b/bindings/java/src/test/java/org/github/tursodatabase/core/LimboDBTest.java index ca75ac4c7..e2fcc8204 100644 --- a/bindings/java/src/test/java/org/github/tursodatabase/core/LimboDBTest.java +++ b/bindings/java/src/test/java/org/github/tursodatabase/core/LimboDBTest.java @@ -2,6 +2,7 @@ package org.github.tursodatabase.core; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertFalse; import java.sql.SQLException; import org.github.tursodatabase.LimboErrorCode; @@ -13,16 +14,27 @@ public class LimboDBTest { @Test void db_should_open_normally() throws Exception { - String dbPath = TestUtils.createTempFile(); LimboDB.load(); + String dbPath = TestUtils.createTempFile(); LimboDB db = LimboDB.create("jdbc:sqlite" + dbPath, dbPath); db.open(0); } @Test - void should_throw_exception_when_opened_twice() throws Exception { - String dbPath = TestUtils.createTempFile(); + void db_should_close_normally() throws Exception { LimboDB.load(); + String dbPath = TestUtils.createTempFile(); + LimboDB db = LimboDB.create("jdbc:sqlite" + dbPath, dbPath); + db.open(0); + db.close(); + + assertFalse(db.isOpen()); + } + + @Test + void should_throw_exception_when_opened_twice() throws Exception { + LimboDB.load(); + String dbPath = TestUtils.createTempFile(); LimboDB db = LimboDB.create("jdbc:sqlite:" + dbPath, dbPath); db.open(0); @@ -31,8 +43,8 @@ public class LimboDBTest { @Test void throwJavaException_should_throw_appropriate_java_exception() throws Exception { - String dbPath = TestUtils.createTempFile(); LimboDB.load(); + String dbPath = TestUtils.createTempFile(); LimboDB db = LimboDB.create("jdbc:sqlite:" + dbPath, dbPath); final int limboExceptionCode = LimboErrorCode.LIMBO_ETC.code; From e0b0a667bbfc77ce0f389d374954524f2728e91e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=A0=EC=9A=B0?= Date: Sun, 9 Feb 2025 18:40:50 +0900 Subject: [PATCH 27/42] Implement close --- bindings/java/rs_src/limbo_db.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/bindings/java/rs_src/limbo_db.rs b/bindings/java/rs_src/limbo_db.rs index 16cb3d66b..5f0dfb84c 100644 --- a/bindings/java/rs_src/limbo_db.rs +++ b/bindings/java/rs_src/limbo_db.rs @@ -21,7 +21,6 @@ impl LimboDB { Box::into_raw(Box::new(self)) as jlong } - #[allow(dead_code)] pub fn drop(ptr: jlong) { let _boxed = unsafe { Box::from_raw(ptr as *mut LimboDB) }; } @@ -97,6 +96,15 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_connect0<'loca conn.to_ptr() } +#[no_mangle] +pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_close0<'local>( + _env: JNIEnv<'local>, + _obj: JObject<'local>, + db_pointer: jlong +) { + LimboDB::drop(db_pointer); +} + #[no_mangle] pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_throwJavaException<'local>( mut env: JNIEnv<'local>, From d177f6195bfdeb1e7bf0c43cce6b68fbd3a60f0d Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sun, 9 Feb 2025 12:34:53 +0200 Subject: [PATCH 28/42] sqlite3-parser: box big members of createindex --- vendored/sqlite3-parser/src/parser/ast/mod.rs | 4 ++-- vendored/sqlite3-parser/src/parser/parse.y | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index 8cf4f805d..780af728f 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -95,13 +95,13 @@ pub enum Stmt { /// `IF NOT EXISTS` if_not_exists: bool, /// index name - idx_name: QualifiedName, + idx_name: Box, /// table name tbl_name: Name, /// indexed columns or expressions columns: Vec, /// partial index - where_clause: Option, + where_clause: Option>, }, /// `CREATE TABLE` CreateTable { diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index bb3c80e91..38fb47fda 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -1077,8 +1077,8 @@ paren_exprlist(A) ::= LP exprlist(X) RP. {A = X;} // cmd ::= createkw uniqueflag(U) INDEX ifnotexists(NE) fullname(X) ON nm(Y) LP sortlist(Z) RP where_opt(W). { - self.ctx.stmt = Some(Stmt::CreateIndex { unique: U, if_not_exists: NE, idx_name: X, - tbl_name: Y, columns: Z, where_clause: W }); + self.ctx.stmt = Some(Stmt::CreateIndex { unique: U, if_not_exists: NE, idx_name: Box::new(X), + tbl_name: Y, columns: Z, where_clause: W.map(Box::new) }); } %type uniqueflag {bool} From 358fda2ec74c6ae1b33dff8b14519b8101f99909 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sun, 9 Feb 2025 12:42:53 +0200 Subject: [PATCH 29/42] sqlite3-parser: box the create table body --- core/ext/mod.rs | 2 +- core/schema.rs | 2 +- core/translate/mod.rs | 2 +- vendored/sqlite3-parser/src/parser/ast/mod.rs | 2 +- vendored/sqlite3-parser/src/parser/parse.y | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/ext/mod.rs b/core/ext/mod.rs index 67fd78491..344b8f4a4 100644 --- a/core/ext/mod.rs +++ b/core/ext/mod.rs @@ -127,7 +127,7 @@ impl Database { let Stmt::CreateTable { body, .. } = stmt else { return ResultCode::Error; }; - let Ok(columns) = columns_from_create_table_body(body) else { + let Ok(columns) = columns_from_create_table_body(*body) else { return ResultCode::Error; }; let vtab_module = self.vtab_modules.get(name).unwrap().clone(); diff --git a/core/schema.rs b/core/schema.rs index f4a6aee2b..aa38cd191 100644 --- a/core/schema.rs +++ b/core/schema.rs @@ -150,7 +150,7 @@ impl BTreeTable { let cmd = parser.next()?; match cmd { Some(Cmd::Stmt(Stmt::CreateTable { tbl_name, body, .. })) => { - create_table(tbl_name, body, root_page) + create_table(tbl_name, *body, root_page) } _ => todo!("Expected CREATE TABLE statement"), } diff --git a/core/translate/mod.rs b/core/translate/mod.rs index 79791866b..d9c3f7421 100644 --- a/core/translate/mod.rs +++ b/core/translate/mod.rs @@ -67,7 +67,7 @@ pub fn translate( bail_parse_error!("TEMPORARY table not supported yet"); } - translate_create_table(query_mode, tbl_name, body, if_not_exists, schema)? + translate_create_table(query_mode, tbl_name, *body, if_not_exists, schema)? } ast::Stmt::CreateTrigger { .. } => bail_parse_error!("CREATE TRIGGER not supported yet"), ast::Stmt::CreateView { .. } => bail_parse_error!("CREATE VIEW not supported yet"), diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index 780af728f..049084bd5 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -112,7 +112,7 @@ pub enum Stmt { /// table name tbl_name: QualifiedName, /// table body - body: CreateTableBody, + body: Box, }, /// `CREATE TRIGGER` CreateTrigger { diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index 38fb47fda..511c83c3b 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -109,7 +109,7 @@ cmd ::= ROLLBACK trans_opt(Y) TO savepoint_opt nm(X). { ///////////////////// The CREATE TABLE statement //////////////////////////// // cmd ::= createkw temp(T) TABLE ifnotexists(E) fullname(Y) create_table_args(X). { - self.ctx.stmt = Some(Stmt::CreateTable{ temporary: T, if_not_exists: E, tbl_name: Y, body: X }); + self.ctx.stmt = Some(Stmt::CreateTable{ temporary: T, if_not_exists: E, tbl_name: Y, body: Box::new(X) }); } createkw(A) ::= CREATE(A). From 575b48474065e8c2720de5ccfec2889f73b105b0 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sun, 9 Feb 2025 12:50:00 +0200 Subject: [PATCH 30/42] sqlite3-parser: separate boxed CreateTrigger struct --- vendored/sqlite3-parser/src/parser/ast/fmt.rs | 23 ++++--- vendored/sqlite3-parser/src/parser/ast/mod.rs | 67 +++++++------------ vendored/sqlite3-parser/src/parser/parse.y | 8 +-- 3 files changed, 39 insertions(+), 59 deletions(-) diff --git a/vendored/sqlite3-parser/src/parser/ast/fmt.rs b/vendored/sqlite3-parser/src/parser/ast/fmt.rs index 34a7fa3f0..10e7c1ad9 100644 --- a/vendored/sqlite3-parser/src/parser/ast/fmt.rs +++ b/vendored/sqlite3-parser/src/parser/ast/fmt.rs @@ -211,17 +211,18 @@ impl ToTokens for Stmt { tbl_name.to_tokens(s)?; body.to_tokens(s) } - Self::CreateTrigger { - temporary, - if_not_exists, - trigger_name, - time, - event, - tbl_name, - for_each_row, - when_clause, - commands, - } => { + Self::CreateTrigger(trigger) => { + let CreateTrigger { + temporary, + if_not_exists, + trigger_name, + time, + event, + tbl_name, + for_each_row, + when_clause, + commands, + } = &**trigger; s.append(TK_CREATE, None)?; if *temporary { s.append(TK_TEMP, None)?; diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index 049084bd5..814aacdb1 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -115,26 +115,7 @@ pub enum Stmt { body: Box, }, /// `CREATE TRIGGER` - CreateTrigger { - /// `TEMPORARY` - temporary: bool, - /// `IF NOT EXISTS` - if_not_exists: bool, - /// trigger name - trigger_name: QualifiedName, - /// `BEFORE`/`AFTER`/`INSTEAD OF` - time: Option, - /// `DELETE`/`INSERT`/`UPDATE` - event: Box, - /// table name - tbl_name: QualifiedName, - /// `FOR EACH ROW` - for_each_row: bool, - /// `WHEN` - when_clause: Option>, - /// statements - commands: Vec, - }, + CreateTrigger(Box), /// `CREATE VIEW` CreateView { /// `TEMPORARY` @@ -242,30 +223,28 @@ pub enum Stmt { /// `SELECT` Select(Box), /// `UPDATE` + Update(Box), + /// `VACUUM`: database name, into expr + Vacuum(Option, Option), +} + /// `CREATE TRIGGER #[derive(Clone, Debug, PartialEq, Eq)] pub struct CreateTrigger { @@ -245,6 +250,30 @@ pub struct CreateTrigger { /// statements pub commands: Vec, } + +/// `UPDATE` clause +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Update { + /// CTE + pub with: Option, + /// `OR` + pub or_conflict: Option, + /// table name + pub tbl_name: QualifiedName, + /// `INDEXED` + pub indexed: Option, + /// `SET` assignments + pub sets: Vec, + /// `FROM` + pub from: Option, + /// `WHERE` clause + pub where_clause: Option>, + /// `RETURNING` + pub returning: Option>, + /// `ORDER BY` + pub order_by: Option>, + /// `LIMIT` + pub limit: Option>, } /// SQL expression diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index b24c9b708..2e298aa9e 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -790,15 +790,15 @@ where_opt_ret(A) ::= WHERE expr(X) RETURNING selcollist(Y). cmd ::= with(C) UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F) where_opt_ret(W) orderby_opt(O) limit_opt(L). { let (where_clause, returning) = W; - self.ctx.stmt = Some(Stmt::Update { with: C, or_conflict: R, tbl_name: X, indexed: I, sets: Y, from: F, - where_clause: where_clause.map(Box::new), returning, order_by: O, limit: L }); + self.ctx.stmt = Some(Stmt::Update(Box::new(Update{ with: C, or_conflict: R, tbl_name: X, indexed: I, sets: Y, from: F, + where_clause: where_clause.map(Box::new), returning, order_by: O, limit: L }))); } %else cmd ::= with(C) UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F) where_opt_ret(W). { let (where_clause, returning) = W; - self.ctx.stmt = Some(Stmt::Update { with: C, or_conflict: R, tbl_name: X, indexed: I, sets: Y, from: F, - where_clause: where_clause.map(Box::new), returning, order_by: None, limit: None }); + self.ctx.stmt = Some(Stmt::Update(Box::new(Update{ with: C, or_conflict: R, tbl_name: X, indexed: I, sets: Y, from: F, + where_clause: where_clause.map(Box::new), returning, order_by: None, limit: None }))); } %endif From f75aca67bb00124008b1081be5e6ae0ad18031e9 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sun, 9 Feb 2025 12:52:30 +0200 Subject: [PATCH 32/42] sqlite3-parser: separate boxed TriggerCmd struct variants --- vendored/sqlite3-parser/src/parser/ast/fmt.rs | 41 +++++----- vendored/sqlite3-parser/src/parser/ast/mod.rs | 76 +++++++++++-------- vendored/sqlite3-parser/src/parser/parse.y | 6 +- 3 files changed, 67 insertions(+), 56 deletions(-) diff --git a/vendored/sqlite3-parser/src/parser/ast/fmt.rs b/vendored/sqlite3-parser/src/parser/ast/fmt.rs index 2d44f5255..313177a39 100644 --- a/vendored/sqlite3-parser/src/parser/ast/fmt.rs +++ b/vendored/sqlite3-parser/src/parser/ast/fmt.rs @@ -1651,13 +1651,14 @@ impl ToTokens for TriggerEvent { impl ToTokens for TriggerCmd { fn to_tokens(&self, s: &mut S) -> Result<(), S::Error> { match self { - Self::Update { - or_conflict, - tbl_name, - sets, - from, - where_clause, - } => { + Self::Update(update) => { + let TriggerCmdUpdate { + or_conflict, + tbl_name, + sets, + from, + where_clause, + } = &**update; s.append(TK_UPDATE, None)?; if let Some(or_conflict) = or_conflict { s.append(TK_OR, None)?; @@ -1676,14 +1677,15 @@ impl ToTokens for TriggerCmd { } Ok(()) } - Self::Insert { - or_conflict, - tbl_name, - col_names, - select, - upsert, - returning, - } => { + Self::Insert(insert) => { + let TriggerCmdInsert { + or_conflict, + tbl_name, + col_names, + select, + upsert, + returning, + } = &**insert; if let Some(ResolveType::Replace) = or_conflict { s.append(TK_REPLACE, None)?; } else { @@ -1710,14 +1712,11 @@ impl ToTokens for TriggerCmd { } Ok(()) } - Self::Delete { - tbl_name, - where_clause, - } => { + Self::Delete(delete) => { s.append(TK_DELETE, None)?; s.append(TK_FROM, None)?; - tbl_name.to_tokens(s)?; - if let Some(where_clause) = where_clause { + delete.tbl_name.to_tokens(s)?; + if let Some(where_clause) = &delete.where_clause { s.append(TK_WHERE, None)?; where_clause.to_tokens(s)?; } diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index 3c729ea70..6b0ac88df 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -1640,44 +1640,56 @@ pub enum TriggerEvent { #[derive(Clone, Debug, PartialEq, Eq)] pub enum TriggerCmd { /// `UPDATE` - Update { - /// `OR` - or_conflict: Option, - /// table name - tbl_name: Name, - /// `SET` assignments - sets: Vec, - /// `FROM` - from: Option, - /// `WHERE` clause - where_clause: Option, - }, + Update(Box), /// `INSERT` - Insert { - /// `OR` - or_conflict: Option, - /// table name - tbl_name: Name, - /// `COLUMNS` - col_names: Option, - /// `SELECT` or `VALUES` - select: Box), } +/// `UPDATE` trigger command +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct TriggerCmdUpdate { + /// `OR` + pub or_conflict: Option, + /// table name + pub tbl_name: Name, + /// `SET` assignments + pub sets: Vec, + /// `FROM` + pub from: Option, + /// `WHERE` clause + pub where_clause: Option, +} + +/// `INSERT` trigger command +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct TriggerCmdInsert { + /// `OR` + pub or_conflict: Option, + /// table name + pub tbl_name: Name, + /// `COLUMNS` + pub col_names: Option, + /// `SELECT` or `VALUES` + pub select: Box, }, /// `CREATE VIRTUAL TABLE` - CreateVirtualTable { - /// `IF NOT EXISTS` - if_not_exists: bool, - /// table name - tbl_name: QualifiedName, - /// module - module_name: Name, - /// args - args: Option>, // TODO smol str - }, + CreateVirtualTable(Box), /// `DELETE` Delete(Box), /// `DETACH DATABASE`: db name @@ -197,7 +188,17 @@ pub enum Stmt { /// `UPDATE` Update(Box), /// `VACUUM`: database name, into expr - Vacuum(Option, Option), +/// `CREATE VIRTUAL TABLE` +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct CreateVirtualTable { + /// `IF NOT EXISTS` + pub if_not_exists: bool, + /// table name + pub tbl_name: QualifiedName, + /// module name + pub module_name: Name, + /// args + pub args: Option>, // TODO smol str } /// `CREATE TRIGGER diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index 16c8b9f00..6ff139835 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -1329,15 +1329,15 @@ kwcolumn_opt ::= COLUMNKW. cmd ::= create_vtab(X). {self.ctx.stmt = Some(X);} cmd ::= create_vtab(X) LP vtabarglist RP. { let mut stmt = X; - if let Stmt::CreateVirtualTable{ ref mut args, .. } = stmt { - *args = self.ctx.module_args(); + if let Stmt::CreateVirtualTable(ref mut create_virtual_table) = stmt { + create_virtual_table.args = self.ctx.module_args(); } self.ctx.stmt = Some(stmt); } %type create_vtab {Stmt} create_vtab(A) ::= createkw VIRTUAL TABLE ifnotexists(E) fullname(X) USING nm(Z). { - A = Stmt::CreateVirtualTable{ if_not_exists: E, tbl_name: X, module_name: Z, args: None }; + A = Stmt::CreateVirtualTable(Box::new(CreateVirtualTable{ if_not_exists: E, tbl_name: X, module_name: Z, args: None })); } vtabarglist ::= vtabarg. vtabarglist ::= vtabarglist COMMA vtabarg. From a8685c80862f994f20965f825864474076b56898 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sun, 9 Feb 2025 14:11:57 +0200 Subject: [PATCH 40/42] sqlite3-parser: box the Expr in Vacuum --- vendored/sqlite3-parser/src/parser/ast/mod.rs | 3 +++ vendored/sqlite3-parser/src/parser/parse.y | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index f942d1090..3ea9d5992 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -188,6 +188,9 @@ pub enum Stmt { /// `UPDATE` Update(Box), /// `VACUUM`: database name, into expr + Vacuum(Option, Option>), +} + /// `CREATE VIRTUAL TABLE` #[derive(Clone, Debug, PartialEq, Eq)] pub struct CreateVirtualTable { diff --git a/vendored/sqlite3-parser/src/parser/parse.y b/vendored/sqlite3-parser/src/parser/parse.y index 6ff139835..aeb6c689f 100644 --- a/vendored/sqlite3-parser/src/parser/parse.y +++ b/vendored/sqlite3-parser/src/parser/parse.y @@ -1130,8 +1130,8 @@ cmd ::= DROP INDEX ifexists(E) fullname(X). {self.ctx.stmt = Some(Stmt::DropIn // %if !SQLITE_OMIT_VACUUM && !SQLITE_OMIT_ATTACH %type vinto {Option} -cmd ::= VACUUM vinto(Y). {self.ctx.stmt = Some(Stmt::Vacuum(None, Y));} -cmd ::= VACUUM nm(X) vinto(Y). {self.ctx.stmt = Some(Stmt::Vacuum(Some(X), Y));} +cmd ::= VACUUM vinto(Y). {self.ctx.stmt = Some(Stmt::Vacuum(None, Y.map(Box::new)));} +cmd ::= VACUUM nm(X) vinto(Y). {self.ctx.stmt = Some(Stmt::Vacuum(Some(X), Y.map(Box::new)));} vinto(A) ::= INTO expr(X). {A = Some(X);} vinto(A) ::= . {A = None;} %endif From a99d9a8988cc44fc57202dbf74bfd63aa217ebe1 Mon Sep 17 00:00:00 2001 From: meteorgan Date: Sun, 9 Feb 2025 21:05:06 +0800 Subject: [PATCH 41/42] chore: remove unused dependencies --- Cargo.lock | 53 ------------------------------------ core/Cargo.toml | 3 -- extensions/core/Cargo.toml | 1 - extensions/regexp/Cargo.toml | 1 - extensions/series/Cargo.toml | 1 - tests/Cargo.toml | 3 -- 6 files changed, 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3d610591d..a57d30b7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -480,8 +480,6 @@ version = "0.0.14" dependencies = [ "anyhow", "assert_cmd", - "clap", - "dirs", "env_logger 0.10.2", "limbo_core", "log", @@ -489,7 +487,6 @@ dependencies = [ "rand_chacha 0.9.0", "rexpect", "rusqlite", - "rustyline", "tempfile", ] @@ -721,12 +718,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" -[[package]] -name = "downcast" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" - [[package]] name = "either" version = "1.13.0" @@ -901,12 +892,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fragile" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" - [[package]] name = "fsevent-sys" version = "4.1.0" @@ -1617,7 +1602,6 @@ name = "limbo_core" version = "0.0.14" dependencies = [ "built", - "bumpalo", "cfg_block", "chrono", "criterion", @@ -1642,7 +1626,6 @@ dependencies = [ "log", "miette", "mimalloc", - "mockall", "parking_lot", "pest", "pest_derive", @@ -1657,7 +1640,6 @@ dependencies = [ "rusqlite", "rustix", "serde", - "sieve-cache", "sqlite3-parser", "strum", "tempfile", @@ -1683,7 +1665,6 @@ name = "limbo_ext" version = "0.0.14" dependencies = [ "limbo_macros", - "log", ] [[package]] @@ -1717,7 +1698,6 @@ name = "limbo_regexp" version = "0.0.14" dependencies = [ "limbo_ext", - "log", "mimalloc", "regex", ] @@ -1727,7 +1707,6 @@ name = "limbo_series" version = "0.0.14" dependencies = [ "limbo_ext", - "log", "mimalloc", "quickcheck", "quickcheck_macros", @@ -1908,32 +1887,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "mockall" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" -dependencies = [ - "cfg-if", - "downcast", - "fragile", - "mockall_derive", - "predicates", - "predicates-tree", -] - -[[package]] -name = "mockall_derive" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn 2.0.96", -] - [[package]] name = "nibble_vec" version = "0.1.0" @@ -2796,12 +2749,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "sieve-cache" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51bf3a9dccf2c079bf1465d449a485c85b36443caf765f2f127bfec28b180f75" - [[package]] name = "signal-hook-registry" version = "1.4.2" diff --git a/core/Cargo.toml b/core/Cargo.toml index d13591aee..933654d78 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -47,7 +47,6 @@ fallible-iterator = "0.3.0" hex = "0.4.3" libc = "0.2.155" log = "0.4.20" -sieve-cache = "0.1.4" sqlite3-parser = { path = "../vendored/sqlite3-parser" } thiserror = "1.0.61" getrandom = { version = "0.2.15", features = ["js"] } @@ -61,7 +60,6 @@ serde = { version = "1.0", features = ["derive"] } pest = { version = "2.0", optional = true } pest_derive = { version = "2.0", optional = true } rand = "0.8.5" -bumpalo = { version = "3.16.0", features = ["collections", "boxed"] } limbo_macros = { path = "../macros" } limbo_uuid = { path = "../extensions/uuid", optional = true, features = ["static"] } limbo_regexp = { path = "../extensions/regexp", optional = true, features = ["static"] } @@ -88,7 +86,6 @@ criterion = { version = "0.5", features = [ "async", "async_futures", ] } -mockall = "0.13.0" rstest = "0.18.2" rusqlite = "0.29.0" tempfile = "3.8.0" diff --git a/extensions/core/Cargo.toml b/extensions/core/Cargo.toml index 3194bcadb..7dc60b498 100644 --- a/extensions/core/Cargo.toml +++ b/extensions/core/Cargo.toml @@ -12,5 +12,4 @@ default = [] static = [] [dependencies] -log = "0.4.20" limbo_macros = { path = "../../macros" } diff --git a/extensions/regexp/Cargo.toml b/extensions/regexp/Cargo.toml index c8288e601..9702db5f1 100644 --- a/extensions/regexp/Cargo.toml +++ b/extensions/regexp/Cargo.toml @@ -17,7 +17,6 @@ crate-type = ["cdylib", "lib"] [dependencies] limbo_ext = { path = "../core", features = ["static"] } regex = "1.11.1" -log = "0.4.20" [target.'cfg(not(target_family = "wasm"))'.dependencies] mimalloc = { version = "*", default-features = false } diff --git a/extensions/series/Cargo.toml b/extensions/series/Cargo.toml index 823e95472..33f45cff2 100644 --- a/extensions/series/Cargo.toml +++ b/extensions/series/Cargo.toml @@ -15,7 +15,6 @@ crate-type = ["cdylib", "lib"] [dependencies] limbo_ext = { path = "../core", features = ["static"] } -log = "0.4.20" [target.'cfg(not(target_family = "wasm"))'.dependencies] mimalloc = { version = "*", default-features = false } diff --git a/tests/Cargo.toml b/tests/Cargo.toml index f3e67d73a..a17c58910 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -16,11 +16,8 @@ path = "integration/mod.rs" [dependencies] anyhow = "1.0.75" -clap = { version = "4.5", features = ["derive"] } -dirs = "5.0.1" env_logger = "0.10.1" limbo_core = { path = "../core" } -rustyline = "12.0.0" rusqlite = { version = "0.29", features = ["bundled"] } tempfile = "3.0.7" log = "0.4.22" From 2fa3a1e6ae968d28d7d2348f0d13e8b18ec128dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=84=A0=EC=9A=B0?= Date: Sun, 9 Feb 2025 22:46:48 +0900 Subject: [PATCH 42/42] Apply lint --- bindings/java/rs_src/limbo_db.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/java/rs_src/limbo_db.rs b/bindings/java/rs_src/limbo_db.rs index 5f0dfb84c..65f6dafc0 100644 --- a/bindings/java/rs_src/limbo_db.rs +++ b/bindings/java/rs_src/limbo_db.rs @@ -100,7 +100,7 @@ pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_connect0<'loca pub extern "system" fn Java_org_github_tursodatabase_core_LimboDB_close0<'local>( _env: JNIEnv<'local>, _obj: JObject<'local>, - db_pointer: jlong + db_pointer: jlong, ) { LimboDB::drop(db_pointer); }