From ab37cc49eb7efdf7cc7e237df5ea31afb6fd9075 Mon Sep 17 00:00:00 2001 From: yy0931 <54441600+yy0931@users.noreply.github.com> Date: Mon, 10 Feb 2025 11:15:06 +0900 Subject: [PATCH] v1.0.202 --- .github/workflows/ci.yml | 10 +-- Cargo.lock | 75 ++++++++++------- Cargo.toml | 2 +- src/code_lens.rs | 171 ++++++++++++++++++++++++++++++++++++++- src/code_lens_test.rs | 105 +++++++++++++++++++++++- 5 files changed, 319 insertions(+), 44 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f3aacb..447ce7f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: rustup target add ${{ matrix.target }} cargo build --release --features sqlite --target ${{ matrix.target }} cp target/${{ matrix.target }}/release/sqlite3-editor.exe sqlite3-editor-${{ matrix.vsce_target }}.exe - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: artifact-${{ matrix.vsce_target }}.exe path: sqlite3-editor-${{ matrix.vsce_target }}.exe @@ -72,7 +72,7 @@ jobs: - name: Test run: target/${{ matrix.target }}/release/sqlite3-editor.exe version if: ${{ matrix.target == 'x86_64-win7-windows-msvc' }} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: artifact-${{ matrix.vsce_target }}.exe path: sqlite3-editor-${{ matrix.vsce_target }}.exe @@ -113,7 +113,7 @@ jobs: cross build --release --features sqlite --target ${{ matrix.target }} cp target/${{ matrix.target }}/release/sqlite3-editor sqlite3-editor-${{ matrix.vsce_target }} shell: bash - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: artifact-${{ matrix.vsce_target }} path: sqlite3-editor-${{ matrix.vsce_target }} @@ -140,7 +140,7 @@ jobs: cargo build --release --features sqlite --target ${{ matrix.target }} cp target/${{ matrix.target }}/release/sqlite3-editor sqlite3-editor-${{ matrix.vsce_target }} shell: bash - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: artifact-${{ matrix.vsce_target }} path: sqlite3-editor-${{ matrix.vsce_target }} @@ -155,7 +155,7 @@ jobs: - test runs-on: ubuntu-latest steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 - run: | for i in ./artifact-*/* do cp -r "$i" . diff --git a/Cargo.lock b/Cargo.lock index 86dc2f9..de11a62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,9 +117,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.2.10" +version = "1.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" +checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda" dependencies = [ "shlex", ] @@ -132,9 +132,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.26" +version = "4.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" +checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff" dependencies = [ "clap_builder", "clap_derive", @@ -142,9 +142,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.26" +version = "4.5.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" +checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" dependencies = [ "anstream", "anstyle", @@ -154,9 +154,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.24" +version = "4.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" +checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" dependencies = [ "heck", "proc-macro2", @@ -252,13 +252,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" dependencies = [ "cfg-if", "libc", "wasi", + "windows-targets", ] [[package]] @@ -319,7 +320,7 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libsqlite3-sys" version = "0.26.0" -source = "git+https://github.com/yy0931/rusqlite.git?branch=master#c43c713df81f19578258f9a7a7889474b903712a" +source = "git+https://github.com/yy0931/rusqlite.git?branch=master#d7da2970237a5c9eb8861f632b03a66f1be875dc" dependencies = [ "cc", "openssl-sys", @@ -365,9 +366,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "openssl-src" @@ -380,9 +381,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc" dependencies = [ "cc", "libc", @@ -481,7 +482,7 @@ dependencies = [ [[package]] name = "rusqlite" version = "0.29.0" -source = "git+https://github.com/yy0931/rusqlite.git?branch=master#c43c713df81f19578258f9a7a7889474b903712a" +source = "git+https://github.com/yy0931/rusqlite.git?branch=master#d7da2970237a5c9eb8861f632b03a66f1be875dc" dependencies = [ "bitflags", "fallible-iterator", @@ -504,9 +505,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.43" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags", "errno", @@ -517,9 +518,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "serde" @@ -552,9 +553,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.136" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336a0c23cf42a38d9eaa7cd22c7040d04e1228a19a933890805ffd00a16437d2" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" dependencies = [ "itoa", "memchr", @@ -576,7 +577,7 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "sqlite3-editor" -version = "1.0.201" +version = "1.0.202" dependencies = [ "base64", "clap", @@ -614,9 +615,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.96" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -625,9 +626,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.15.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" +checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91" dependencies = [ "cfg-if", "fastrand", @@ -691,9 +692,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" [[package]] name = "utf8parse" @@ -715,9 +716,12 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.13.3+wasi-0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] [[package]] name = "winapi-util" @@ -801,6 +805,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags", +] + [[package]] name = "zerocopy" version = "0.7.35" diff --git a/Cargo.toml b/Cargo.toml index 9bbe27b..1faa399 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sqlite3-editor" -version = "1.0.201" +version = "1.0.202" edition = "2021" [features] diff --git a/src/code_lens.rs b/src/code_lens.rs index 9246a6f..140ccfd 100644 --- a/src/code_lens.rs +++ b/src/code_lens.rs @@ -1,13 +1,16 @@ +use std::collections::HashMap; + +use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use sqlparser::keywords::Keyword; use sqlparser::tokenizer::{Token, Word}; -use crate::keywords::START_OF_STATEMENT_KEYWORDS_UNSUPPORTED_BY_SQLPARSER; +use crate::keywords::{KEYWORDS_UNSUPPORTED_BY_SQLPARSER, START_OF_STATEMENT_KEYWORDS_UNSUPPORTED_BY_SQLPARSER}; use crate::list_placeholders::{list_placeholders, Placeholder}; use crate::parse_cte::parse_cte; use crate::split_statements::{get_text_range, split_sqlite_statements}; use crate::sqlite3::escape_sql_identifier; -use crate::tokenize::ZeroIndexedLocation; +use crate::tokenize::{TokenWithRangeLocation, ZeroIndexedLocation}; /// Represents the kind of code lens. #[derive(ts_rs::TS, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] @@ -18,6 +21,13 @@ pub enum CodeLensKind { Other, } +#[derive(ts_rs::TS, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[ts(export)] +pub struct TableToBeFocused { + pub schema: Option, + pub table: String, +} + #[derive(ts_rs::TS, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[ts(export)] pub struct CodeLens { @@ -27,6 +37,7 @@ pub struct CodeLens { pub stmt_executed: String, pub cte_identifier: Option, pub placeholders: Vec, + pub table_to_be_focused: Option, } /// Returns a list of code lenses for the given SQL input. @@ -66,6 +77,7 @@ pub fn code_lens(sql: &str) -> Vec { start: entry.ident_start, end: entry.ident_end, cte_identifier: Some(cte_ident), + table_to_be_focused: None, // is None because cte_stmt is always a SELECT statement }) } cte_end = cte.body_start; @@ -73,11 +85,11 @@ pub fn code_lens(sql: &str) -> Vec { let mut kind: Option = None; let placeholders = list_placeholders(&stmt); - for token in stmt.real_tokens { + for token in &stmt.real_tokens { if token.start < cte_end { continue; } - if let Token::Word(w) = token.token { + if let Token::Word(w) = &token.token { match w { Word { keyword: Keyword::SELECT | Keyword::VALUES, @@ -136,9 +148,160 @@ pub fn code_lens(sql: &str) -> Vec { stmt_executed: stmt.real_text, cte_identifier: None, placeholders, + table_to_be_focused: get_table_to_be_focused(&stmt.real_tokens), }) } } code_lens } + +#[derive(Clone, Debug, PartialEq, Eq)] +enum PatternItem { + Keyword(Keyword), + WordAsSchema, + Period, + WordAsTable, +} + +static PATTERN_MAP: Lazy>>> = Lazy::new(|| { + fn k(k: Keyword) -> PatternItem { + PatternItem::Keyword(k) + } + + let mut map = HashMap::>>::new(); + + trait AddPattern { + fn add_pattern(&mut self, first_token: Keyword, pattern: &[PatternItem], follows_table_name: bool); + } + + impl AddPattern for HashMap>> { + fn add_pattern(&mut self, first_token: Keyword, pattern: &[PatternItem], follows_table_name: bool) { + if follows_table_name { + { + let mut vec = pattern.to_vec(); + vec.extend([PatternItem::WordAsSchema, PatternItem::Period, PatternItem::WordAsTable]); + self.entry(first_token).or_default().push(vec); + } + { + let mut vec = pattern.to_vec(); + vec.extend([PatternItem::WordAsTable]); + self.entry(first_token).or_default().push(vec); + } + } else { + self.entry(first_token).or_default().push(pattern.to_vec()); + } + } + } + + { + use Keyword::*; + map.add_pattern(CREATE, &[k(TRIGGER)], false); // CREATE TRIGGER ... INSERT INTO table1 ... should not show table1 + map.add_pattern(CREATE, &[k(TEMP), k(TRIGGER)], false); + map.add_pattern(CREATE, &[k(TEMPORARY), k(TRIGGER)], false); + map.add_pattern(CREATE, &[k(TABLE)], true); + map.add_pattern(CREATE, &[k(TABLE), k(IF), k(NOT), k(EXISTS)], true); + map.add_pattern(CREATE, &[k(VIEW)], true); + map.add_pattern(CREATE, &[k(VIEW), k(IF), k(NOT), k(EXISTS)], true); + map.add_pattern(CREATE, &[k(VIRTUAL), k(TABLE)], true); + map.add_pattern(CREATE, &[k(VIRTUAL), k(TABLE), k(IF), k(NOT), k(EXISTS)], true); + map.add_pattern(REPLACE, &[k(INTO)], true); + map.add_pattern(INSERT, &[k(INTO)], true); + map.add_pattern(INSERT, &[k(OR), k(ABORT), k(INTO)], true); + map.add_pattern(INSERT, &[k(OR), k(FAIL), k(INTO)], true); + map.add_pattern(INSERT, &[k(OR), k(IGNORE), k(INTO)], true); + map.add_pattern(INSERT, &[k(OR), k(REPLACE), k(INTO)], true); + map.add_pattern(INSERT, &[k(OR), k(ROLLBACK), k(INTO)], true); + map.add_pattern(UPDATE, &[], true); + map.add_pattern(UPDATE, &[k(OR), k(ABORT), k(INTO)], true); + map.add_pattern(UPDATE, &[k(OR), k(FAIL), k(INTO)], true); + map.add_pattern(UPDATE, &[k(OR), k(IGNORE), k(INTO)], true); + map.add_pattern(UPDATE, &[k(OR), k(REPLACE), k(INTO)], true); + map.add_pattern(UPDATE, &[k(OR), k(ROLLBACK), k(INTO)], true); + map.add_pattern(ALTER, &[k(TABLE)], true); + } + + map +}); + +fn match_pattern(tokens: &[&TokenWithRangeLocation], pattern: &[PatternItem]) -> Option> { + let mut schema: Option = None; + let mut table: Option = None; + + // Make sure we have enough tokens. + if pattern.len() > tokens.len() { + return None; + } + + for (j, pattern_item) in pattern.iter().enumerate() { + let token = &tokens[j].token; + match pattern_item { + PatternItem::Keyword(expected_keyword) => { + match token { + Token::Word(Word { + quote_style: None, + keyword, + .. + }) if keyword == expected_keyword => { /* continue */ } + _ => return None, + } + } + PatternItem::Period => { + if *token != Token::Period { + return None; + } + } + PatternItem::WordAsSchema | PatternItem::WordAsTable => match token { + Token::Word(Word { + keyword: Keyword::NoKeyword | Keyword::ENCODING, + value, + .. + }) if !KEYWORDS_UNSUPPORTED_BY_SQLPARSER.contains(&value.to_uppercase().as_str()) => { + if *pattern_item == PatternItem::WordAsSchema { + schema = Some(value.clone()); + } else { + table = Some(value.clone()); + } + } + _ => return None, + }, + } + } + + // Returns Some(None) if the pattern is CREATE TRIGGER. + // Returns Some(Some(...)) otherwise. + Some(table.map(|table| TableToBeFocused { schema, table })) +} + +pub fn get_table_to_be_focused(real_tokens: &[TokenWithRangeLocation]) -> Option { + // Filter out whitespace tokens. + let filtered: Vec<&TokenWithRangeLocation> = real_tokens + .iter() + .filter(|t| !matches!(t.token, Token::Whitespace(_))) + .collect(); + + for (i, token) in filtered.iter().enumerate() { + // We only start matching if a token is a Word with no quoting. + let Token::Word(Word { + quote_style: None, + keyword, + .. + }) = &token.token + else { + continue; + }; + + let Some(patterns) = PATTERN_MAP.get(keyword) else { + continue; + }; + + for pattern in patterns { + if i + pattern.len() < filtered.len() { + if let Some(result) = match_pattern(&filtered[i + 1..], pattern) { + return result; + } + } + } + } + None +} diff --git a/src/code_lens_test.rs b/src/code_lens_test.rs index 1688700..00ad9ab 100644 --- a/src/code_lens_test.rs +++ b/src/code_lens_test.rs @@ -1,6 +1,7 @@ use crate::{ - code_lens::{code_lens, CodeLens, CodeLensKind}, + code_lens::{code_lens, get_table_to_be_focused, CodeLens, CodeLensKind, TableToBeFocused}, list_placeholders::{Placeholder, PlaceholderRange}, + split_statements::split_sqlite_statements, tokenize::ZeroIndexedLocation, }; @@ -16,6 +17,7 @@ fn test_select() { stmt_executed: "SELECT 1;".to_owned(), cte_identifier: None, placeholders: vec![], + table_to_be_focused: None, }, CodeLens { kind: CodeLensKind::Select, @@ -24,6 +26,7 @@ fn test_select() { stmt_executed: "SELECT 2;".to_owned(), cte_identifier: None, placeholders: vec![], + table_to_be_focused: None, }, CodeLens { kind: CodeLensKind::Select, @@ -32,6 +35,7 @@ fn test_select() { stmt_executed: "VALUES(3);".to_owned(), cte_identifier: None, placeholders: vec![], + table_to_be_focused: None, }, ] ); @@ -49,6 +53,7 @@ fn test_with_clause() { stmt_executed: "WITH a AS (SELECT 1) SELECT * FROM `a`".to_owned(), cte_identifier: Some("`a`".to_owned()), placeholders: vec![], + table_to_be_focused: None, }, CodeLens { kind: CodeLensKind::Select, @@ -57,6 +62,7 @@ fn test_with_clause() { stmt_executed: "WITH a AS (SELECT 1) SELECT 2;".to_owned(), cte_identifier: None, placeholders: vec![], + table_to_be_focused: None, }, ] ); @@ -79,6 +85,7 @@ fn test_other() { stmt_executed: "DROP TABLE t;".to_owned(), cte_identifier: None, placeholders: vec![], + table_to_be_focused: None, }, CodeLens { kind: CodeLensKind::Other, @@ -87,6 +94,7 @@ fn test_other() { stmt_executed: "ATTACH 'db' as db".to_owned(), cte_identifier: None, placeholders: vec![], + table_to_be_focused: None, } ] ); @@ -103,6 +111,7 @@ fn test_begin_end() { stmt_executed: "BEGIN; SELECT 1; SELECT 2; END;".to_owned(), cte_identifier: None, placeholders: vec![], + table_to_be_focused: None, }] ); } @@ -118,6 +127,7 @@ fn test_pragma() { stmt_executed: "PRAGMA analysis_limit;".to_owned(), cte_identifier: None, placeholders: vec![], + table_to_be_focused: None, }] ); } @@ -133,6 +143,7 @@ fn test_vacuum() { stmt_executed: "VACUUM;".to_owned(), cte_identifier: None, placeholders: vec![], + table_to_be_focused: None, }] ); } @@ -149,6 +160,7 @@ fn test_with_update() { stmt_executed: "WITH x AS (SELECT 1) SELECT * FROM `x`".to_owned(), cte_identifier: Some("`x`".to_owned()), placeholders: vec![], + table_to_be_focused: None, }, CodeLens { kind: CodeLensKind::Other, @@ -157,6 +169,10 @@ fn test_with_update() { stmt_executed: "WITH x AS (SELECT 1) UPDATE t SET a = 1;".to_owned(), cte_identifier: None, placeholders: vec![], + table_to_be_focused: Some(TableToBeFocused { + schema: None, + table: "t".to_owned() + }), } ] ); @@ -188,7 +204,8 @@ fn test_placeholders() { }] } ], - },] + table_to_be_focused: None, + }] ); } @@ -218,6 +235,88 @@ fn test_placeholders_with_prefix() { }] } ], - },] + table_to_be_focused: None, + }] + ); +} + +#[test] +fn test_get_table_to_be_focused_create_table() { + assert_eq!( + get_table_to_be_focused(&split_sqlite_statements("CREATE TABLE table1").unwrap().0[0].real_tokens), + Some(TableToBeFocused { + schema: None, + table: "table1".to_owned(), + }) + ); +} + +#[test] +fn test_get_table_to_be_focused_insert_into() { + assert_eq!( + get_table_to_be_focused(&split_sqlite_statements("INSERT INTO table1").unwrap().0[0].real_tokens), + Some(TableToBeFocused { + schema: None, + table: "table1".to_owned(), + }) + ); +} + +#[test] +fn test_get_table_to_be_focused_insert_into_2() { + assert_eq!( + get_table_to_be_focused(&split_sqlite_statements("INSERT INTO \"table1\"").unwrap().0[0].real_tokens), + Some(TableToBeFocused { + schema: None, + table: "table1".to_owned(), + }) + ); +} + +#[test] +fn test_get_table_to_be_focused_insert_into_3() { + assert_eq!( + get_table_to_be_focused(&split_sqlite_statements("INSERT INTO \"table 1\"").unwrap().0[0].real_tokens), + Some(TableToBeFocused { + schema: None, + table: "table 1".to_owned(), + }) + ); +} + +#[test] +fn test_get_table_to_be_focused_insert_schema() { + assert_eq!( + get_table_to_be_focused(&split_sqlite_statements("INSERT INTO schema1.table1").unwrap().0[0].real_tokens), + Some(TableToBeFocused { + schema: Some("schema1".to_owned()), + table: "table1".to_owned(), + }) + ); +} + +#[test] +fn test_get_table_to_be_focused_create_table_schema() { + assert_eq!( + get_table_to_be_focused(&split_sqlite_statements("CREATE TABLE schema1.table1").unwrap().0[0].real_tokens), + Some(TableToBeFocused { + schema: Some("schema1".to_owned()), + table: "table1".to_owned(), + }) + ); +} + +#[test] +fn test_get_table_to_be_focused_create_trigger() { + assert_eq!( + get_table_to_be_focused( + &split_sqlite_statements( + "CREATE TRIGGER trigger_insert AFTER INSERT ON t INSERT INTO table1 VALUES (1); END" + ) + .unwrap() + .0[0] + .real_tokens + ), + None ); }