code_to_query 0.1.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +22 -0
- data/LICENSE.txt +23 -0
- data/README.md +167 -0
- data/lib/code_to_query/compiler.rb +674 -0
- data/lib/code_to_query/configuration.rb +92 -0
- data/lib/code_to_query/context/builder.rb +1087 -0
- data/lib/code_to_query/context/pack.rb +36 -0
- data/lib/code_to_query/errors.rb +5 -0
- data/lib/code_to_query/guardrails/explain_gate.rb +229 -0
- data/lib/code_to_query/guardrails/sql_linter.rb +335 -0
- data/lib/code_to_query/llm_client.rb +46 -0
- data/lib/code_to_query/performance/cache.rb +250 -0
- data/lib/code_to_query/performance/optimizer.rb +396 -0
- data/lib/code_to_query/planner.rb +289 -0
- data/lib/code_to_query/policies/pundit_adapter.rb +71 -0
- data/lib/code_to_query/providers/base.rb +173 -0
- data/lib/code_to_query/providers/local.rb +84 -0
- data/lib/code_to_query/providers/openai.rb +581 -0
- data/lib/code_to_query/query.rb +385 -0
- data/lib/code_to_query/railtie.rb +16 -0
- data/lib/code_to_query/runner.rb +188 -0
- data/lib/code_to_query/validator.rb +203 -0
- data/lib/code_to_query/version.rb +6 -0
- data/lib/code_to_query.rb +90 -0
- data/tasks/code_to_query.rake +326 -0
- metadata +225 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 46846303df2e09d6bcfcd98759381a486f760cc280c5d9a8f171fad62e7b1009
|
4
|
+
data.tar.gz: cebec7881b707d8f135b1c97e56ae8678b7fdbd84cb824ec121e9ad869e26138
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 21e4c488f347e132ef62f09db92989b2b7015d4eeb69e3eb6ae55b44429bed6b8988734ee14e6d5db7cb18aa008c2b1cf29d17cc1b7d0cbab90a437a983b566f
|
7
|
+
data.tar.gz: a52f6f1ddea3f4e6f80ffdecba78d1eeb781d9d3f15cf3f6e998287a3a3fe1755f8d4d8102b6b33e7b9614a243dd585b9531e25512e65cb26a6024d46a70a6d7
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
This file tracks the major changes in each release.
|
4
|
+
|
5
|
+
## [0.1.0] - 2025-08-14
|
6
|
+
|
7
|
+
### Added
|
8
|
+
- Support for OpenAI and local AI providers
|
9
|
+
- SQL safety checks with table allowlists and EXPLAIN analysis
|
10
|
+
- Automatic policy enforcement for row-level security
|
11
|
+
- Query performance monitoring and caching
|
12
|
+
- CI setup for multiple Ruby and Rails versions
|
13
|
+
- Basic gem structure and setup
|
14
|
+
- Core Query class with SQL generation and safety checks
|
15
|
+
- Simple query validation using dry-schema
|
16
|
+
- Local query planning and compilation
|
17
|
+
- MIT license and initial docs
|
18
|
+
|
19
|
+
### Changed
|
20
|
+
- Simplified the SQL linter to work better with different database adapters
|
21
|
+
- Improved the query compiler with better Arel integration
|
22
|
+
- Cleaner error messages and logging
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Alex Kholodniak
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
23
|
+
|
data/README.md
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
# CodeToQuery
|
2
|
+
|
3
|
+
A gem that converts natural language questions into SQL queries for Rails apps. It's built for teams who need to give non-developers access to data without compromising security or performance.
|
4
|
+
|
5
|
+
## What it does
|
6
|
+
|
7
|
+
Instead of writing SQL, your team can ask questions like "Show me top customers by revenue this month" and get back safe, parameterized queries that respect your database policies and security rules.
|
8
|
+
|
9
|
+
## Key features
|
10
|
+
|
11
|
+
- **Multiple AI providers**: Works with OpenAI or local models
|
12
|
+
- **Built-in safety**: SQL linting, table allowlists, EXPLAIN plan checks
|
13
|
+
- **Schema awareness**: Understands your models, associations, and scopes
|
14
|
+
- **Policy enforcement**: Automatically injects tenant filters and access rules
|
15
|
+
- **Performance monitoring**: Optional query analysis and optimization
|
16
|
+
|
17
|
+
## Getting started
|
18
|
+
|
19
|
+
Add to your Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'code_to_query'
|
23
|
+
```
|
24
|
+
|
25
|
+
Run `bundle install` and create a config file:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
# config/initializers/code_to_query.rb
|
29
|
+
CodeToQuery.configure do |config|
|
30
|
+
config.openai_api_key = ENV['OPENAI_API_KEY']
|
31
|
+
config.openai_model = 'gpt-4.1-mini'
|
32
|
+
|
33
|
+
# Security settings
|
34
|
+
config.enable_explain_gate = true
|
35
|
+
config.allow_seq_scans = false
|
36
|
+
config.max_query_cost = 10000
|
37
|
+
config.require_limit_by_default = true
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
Generate your schema context:
|
42
|
+
|
43
|
+
```bash
|
44
|
+
rails code_to_query:bootstrap
|
45
|
+
```
|
46
|
+
|
47
|
+
## Basic usage
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
# Ask a question
|
51
|
+
query = CodeToQuery.ask(
|
52
|
+
prompt: "Top 10 invoices by amount in July",
|
53
|
+
allow_tables: %w[invoices vendors],
|
54
|
+
current_user: current_user
|
55
|
+
)
|
56
|
+
|
57
|
+
# Check if it's safe to run
|
58
|
+
if query.safe?
|
59
|
+
results = query.run
|
60
|
+
puts "Found #{results.rows.length} results"
|
61
|
+
end
|
62
|
+
|
63
|
+
# Or get the SQL for review
|
64
|
+
puts query.sql
|
65
|
+
puts query.params
|
66
|
+
```
|
67
|
+
|
68
|
+
## Configuration options
|
69
|
+
|
70
|
+
### Database settings
|
71
|
+
```ruby
|
72
|
+
config.adapter = :postgres # :postgres, :mysql, :sqlite
|
73
|
+
config.readonly_role = :reporting # Database role for queries
|
74
|
+
config.default_limit = 100 # Default row limit
|
75
|
+
config.max_limit = 10000 # Max allowed limit
|
76
|
+
```
|
77
|
+
|
78
|
+
### Security settings
|
79
|
+
```ruby
|
80
|
+
config.enable_explain_gate = true # Block expensive queries
|
81
|
+
config.allow_seq_scans = false # Prevent table scans
|
82
|
+
config.max_query_cost = 10000 # Cost threshold
|
83
|
+
config.max_joins = 3 # Join limit
|
84
|
+
```
|
85
|
+
|
86
|
+
### OpenAI settings
|
87
|
+
```ruby
|
88
|
+
config.openai_api_key = ENV['OPENAI_API_KEY']
|
89
|
+
config.openai_model = 'gpt-4'
|
90
|
+
config.stub_llm = false # Set true for testing
|
91
|
+
```
|
92
|
+
|
93
|
+
## Rake tasks
|
94
|
+
|
95
|
+
```bash
|
96
|
+
rails code_to_query:bootstrap # Generate full context pack
|
97
|
+
rails code_to_query:schema # Extract schema info
|
98
|
+
rails code_to_query:scan_app # Scan models and associations
|
99
|
+
rails code_to_query:verify # Check context pack integrity
|
100
|
+
```
|
101
|
+
|
102
|
+
## Security features
|
103
|
+
|
104
|
+
- **SQL injection prevention**: All queries are parameterized
|
105
|
+
- **Access control**: Table allowlists and row-level policies
|
106
|
+
- **Performance limits**: EXPLAIN plan analysis and cost thresholds
|
107
|
+
- **Readonly execution**: Uses dedicated readonly database connections
|
108
|
+
|
109
|
+
## Advanced usage
|
110
|
+
|
111
|
+
### Custom policies
|
112
|
+
```ruby
|
113
|
+
config.policy_adapter = ->(user) do
|
114
|
+
return {} unless user
|
115
|
+
|
116
|
+
{
|
117
|
+
company_id: user.company_id,
|
118
|
+
user_id: user.admin? ? nil : user.id
|
119
|
+
}
|
120
|
+
end
|
121
|
+
```
|
122
|
+
|
123
|
+
### Custom schema
|
124
|
+
```ruby
|
125
|
+
schema = {
|
126
|
+
tables: [
|
127
|
+
{
|
128
|
+
name: "users",
|
129
|
+
columns: [
|
130
|
+
{ name: "id", sql_type: "integer" },
|
131
|
+
{ name: "email", sql_type: "varchar" }
|
132
|
+
]
|
133
|
+
}
|
134
|
+
]
|
135
|
+
}
|
136
|
+
|
137
|
+
query = CodeToQuery.ask(
|
138
|
+
prompt: "Recent users",
|
139
|
+
schema: schema,
|
140
|
+
allow_tables: ["users"]
|
141
|
+
)
|
142
|
+
```
|
143
|
+
|
144
|
+
## Error handling
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
begin
|
148
|
+
query = CodeToQuery.ask(prompt: "Complex query")
|
149
|
+
results = query.run if query.safe?
|
150
|
+
rescue CodeToQuery::ExecutionError => e
|
151
|
+
Rails.logger.error "Query failed: #{e.message}"
|
152
|
+
rescue CodeToQuery::ConnectionError => e
|
153
|
+
Rails.logger.error "Database issue: #{e.message}"
|
154
|
+
end
|
155
|
+
```
|
156
|
+
|
157
|
+
## Contributing
|
158
|
+
|
159
|
+
1. Fork the repo
|
160
|
+
2. Create a feature branch
|
161
|
+
3. Make your changes
|
162
|
+
4. Add tests
|
163
|
+
5. Submit a pull request
|
164
|
+
|
165
|
+
## License
|
166
|
+
|
167
|
+
MIT License - see LICENSE file for details.
|