finox 0.1.0-aarch64-linux → 0.2.0-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -2,44 +2,49 @@
2
2
 
3
3
  A MySQL query parser for Ruby, powered by [sqlparser-rs](https://github.com/apache/datafusion-sqlparser-rs).
4
4
 
5
- Finox parses SQL with Rust and returns the AST as plain Ruby Hashes and Arrays.
5
+ Finox parses SQL with Rust and exposes tables, columns, fingerprints and the raw AST.
6
6
 
7
7
  ## Installation
8
8
 
9
- Add to your Gemfile:
10
-
11
9
  ```bash
12
10
  bundle add finox
13
11
  ```
14
12
 
15
- Or install directly:
13
+ Or without Bundler:
16
14
 
17
15
  ```bash
18
16
  gem install finox
19
17
  ```
20
18
 
21
- A Rust toolchain is required to build the native extension.
19
+ Precompiled native gems are available for Ruby 3.1–4.0 on the following
20
+ platforms, so installation there requires no Rust toolchain:
21
+
22
+ | OS | Platforms |
23
+ | ------- | ------------------------------------------------ |
24
+ | Linux | x86_64, aarch64 (glibc and musl variants) |
25
+ | macOS | x86_64, arm64 |
26
+ | Windows | x64-mingw-ucrt |
27
+
28
+ On any other platform the source gem is installed instead, and compiling it
29
+ requires a Rust toolchain.
22
30
 
23
31
  ## Usage
24
32
 
33
+ `Finox.parse` returns a `Finox::Result`:
34
+
25
35
  ```ruby
26
36
  require "finox"
27
37
 
28
- ast = Finox.parse("SELECT `name` FROM `users` WHERE id = 1")
29
- # => [{"Query" => {with: nil, body: {"Select" => {...}}, ...}}]
38
+ result = Finox.parse("SELECT `name` FROM `users` WHERE id = 1")
39
+ # => #<Finox::Result>
30
40
 
31
- ast.dig(0, "Query", :body, "Select", :projection)
32
- # => [{"UnnamedExpr" =>
33
- # {"Identifier" =>
34
- # {value: "name",
35
- # quote_style: "`",
36
- # span: {start: {line: 1, column: 8}, end: {line: 1, column: 14}}}}}]
41
+ result.tables # => ["users"]
42
+ result.columns # => ["name", "id"]
43
+ result.statement_types # => ["Query"]
44
+ result.normalize # => "SELECT `name` FROM `users` WHERE id = ?"
45
+ result.fingerprint # => "24e307ca0f02abfc"
37
46
  ```
38
47
 
39
- `Finox.parse` returns one Hash per statement, so `"SELECT 1; SELECT 2"` yields an array of two.
40
-
41
- Key convention (from serde's externally tagged enums): enum variant names are `String` keys (`"Query"`, `"Select"`, `"Identifier"`), struct fields are `Symbol` keys (`:body`, `:projection`, `:value`).
42
-
43
48
  Invalid SQL raises `Finox::ParseError`:
44
49
 
45
50
  ```ruby
@@ -47,6 +52,69 @@ Finox.parse("SELEKT 1")
47
52
  # => Finox::ParseError: sql parser error: Expected: an SQL statement, found: SELEKT at Line: 1, Column: 1
48
53
  ```
49
54
 
55
+ ### Table classification
56
+
57
+ `#select_tables`, `#dml_tables` and `#ddl_tables` classify the referenced
58
+ tables by how they are used: read, written by DML (`INSERT` / `UPDATE` /
59
+ `DELETE`) or targeted by DDL (`CREATE TABLE` / `ALTER TABLE` / `DROP TABLE` /
60
+ `TRUNCATE` etc.). A table appearing in multiple roles is listed in each.
61
+
62
+ ```ruby
63
+ result = Finox.parse("INSERT INTO logs SELECT message FROM events; DROP TABLE archives")
64
+
65
+ result.tables # => ["logs", "events", "archives"]
66
+ result.select_tables # => ["events"]
67
+ result.dml_tables # => ["logs"]
68
+ result.ddl_tables # => ["archives"]
69
+ ```
70
+
71
+ #### Known limitations
72
+
73
+ Extraction is syntactic, with no schema knowledge and only coarse scope
74
+ resolution:
75
+
76
+ - A CTE name shadows a same-named real table everywhere in the statement,
77
+ even inside the CTE's own definition.
78
+ - Multi-table `UPDATE` (`UPDATE t1 JOIN t2 ... SET t2.x = 1`) reports only
79
+ `t1` in `#dml_tables`.
80
+ - `#columns` does not resolve table aliases (`u.id` stays `u.id`).
81
+
82
+ ### Normalization and fingerprints
83
+
84
+ `#normalize` replaces literals with `?` placeholders and deparses from the
85
+ AST, so formatting and keyword case are normalized as well. `#fingerprint` is
86
+ a 64-bit hex hash (xxhash64) of the normalized SQL — stable across literal
87
+ and formatting differences, but not guaranteed to be stable across finox
88
+ versions, since the normalized form depends on the bundled sqlparser-rs.
89
+ Recompute stored fingerprints when upgrading finox.
90
+
91
+ ```ruby
92
+ Finox.parse("select * from users where id=1").normalize
93
+ # => "SELECT * FROM users WHERE id = ?"
94
+
95
+ Finox.parse("select * from users where id=1").fingerprint ==
96
+ Finox.parse("SELECT * FROM users WHERE id = 42").fingerprint
97
+ # => true
98
+ ```
99
+
100
+ ### Raw sqlparser-rs AST
101
+
102
+ For anything not covered above, `#statements` exposes sqlparser-rs's raw AST of each parsed statement as plain
103
+ Ruby Hashes and Arrays:
104
+
105
+ ```ruby
106
+ ast = Finox.parse("SELECT `name` FROM `users` WHERE id = 1").statements.first
107
+ # => {"Query" => {"with" => nil, "body" => {"Select" => {...}}, ...}}
108
+
109
+ ast.dig("Query", "body", "Select", "projection")
110
+ # => [{"UnnamedExpr" =>
111
+ # {"Identifier" =>
112
+ # {"value" => "name",
113
+ # "quote_style" => "`",
114
+ # "span" => {"start" => {"line" => 1, "column" => 8},
115
+ # "end" => {"line" => 1, "column" => 14}}}}}]
116
+ ```
117
+
50
118
  ## Development
51
119
 
52
120
  ```bash
@@ -58,3 +126,7 @@ bundle exec rake # compile + spec + rubocop
58
126
  ## License
59
127
 
60
128
  [MIT](LICENSE.txt)
129
+
130
+ Precompiled gems statically link Rust crates, including sqlparser-rs
131
+ (Apache-2.0). See [LICENSE-THIRD-PARTY.txt](LICENSE-THIRD-PARTY.txt) for
132
+ their licenses and attributions.
Binary file
Binary file
Binary file
Binary file
Binary file
data/lib/finox/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Finox
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: finox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - kyuuri1791
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-07-17 00:00:00.000000000 Z
11
+ date: 2026-07-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Parses MySQL queries with the Rust sqlparser crate (via magnus) and returns
14
14
  the AST as plain Ruby Hashes and Arrays.
@@ -17,9 +17,8 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
- - ".rspec"
21
- - ".rubocop.yml"
22
20
  - CHANGELOG.md
21
+ - LICENSE-THIRD-PARTY.txt
23
22
  - LICENSE.txt
24
23
  - README.md
25
24
  - Rakefile
@@ -28,6 +27,7 @@ files:
28
27
  - lib/finox/3.2/finox.so
29
28
  - lib/finox/3.3/finox.so
30
29
  - lib/finox/3.4/finox.so
30
+ - lib/finox/4.0/finox.so
31
31
  - lib/finox/version.rb
32
32
  homepage: https://github.com/kyuuri1791/finox
33
33
  licenses:
@@ -48,7 +48,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
48
48
  version: '3.1'
49
49
  - - "<"
50
50
  - !ruby/object:Gem::Version
51
- version: 3.5.dev
51
+ version: 4.1.dev
52
52
  required_rubygems_version: !ruby/object:Gem::Requirement
53
53
  requirements:
54
54
  - - ">="
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1,8 +0,0 @@
1
- AllCops:
2
- TargetRubyVersion: 3.1
3
-
4
- Style/StringLiterals:
5
- EnforcedStyle: double_quotes
6
-
7
- Style/StringLiteralsInInterpolation:
8
- EnforcedStyle: double_quotes