{"id":30536513,"url":"https://github.com/kholdrex/code_to_query","last_synced_at":"2026-01-20T16:59:49.457Z","repository":{"id":309839151,"uuid":"1037634955","full_name":"kholdrex/code_to_query","owner":"kholdrex","description":"Ask for data in plain English; get validated, parameterized SQL with guardrails.","archived":false,"fork":false,"pushed_at":"2025-08-13T23:43:03.000Z","size":83,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-28T17:36:57.959Z","etag":null,"topics":["ai-to-sql","database-security","natural-language-processing","rails","ruby-gem"],"latest_commit_sha":null,"homepage":"https://codetoquery.com","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kholdrex.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-13T22:08:00.000Z","updated_at":"2025-08-17T02:04:09.000Z","dependencies_parsed_at":"2025-08-14T05:37:30.809Z","dependency_job_id":null,"html_url":"https://github.com/kholdrex/code_to_query","commit_stats":null,"previous_names":["kholdrex/code_to_query"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/kholdrex/code_to_query","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kholdrex%2Fcode_to_query","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kholdrex%2Fcode_to_query/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kholdrex%2Fcode_to_query/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kholdrex%2Fcode_to_query/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kholdrex","download_url":"https://codeload.github.com/kholdrex/code_to_query/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kholdrex%2Fcode_to_query/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278792907,"owners_count":26046874,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-to-sql","database-security","natural-language-processing","rails","ruby-gem"],"created_at":"2025-08-27T16:21:34.124Z","updated_at":"2025-10-08T17:07:32.878Z","avatar_url":"https://github.com/kholdrex.png","language":"Ruby","readme":"# CodeToQuery\n\nA 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.\n\n## What it does\n\nInstead 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.\n\n## Key features\n\n- **Multiple AI providers**: Works with OpenAI or local models\n- **Built-in safety**: SQL linting, table allowlists, EXPLAIN plan checks\n- **Schema awareness**: Understands your models, associations, and scopes\n- **Policy enforcement**: Automatically injects tenant filters and access rules\n- **Performance monitoring**: Optional query analysis and optimization\n\n## Getting started\n\nAdd to your Gemfile:\n\n```ruby\ngem 'code_to_query'\n```\n\nRun `bundle install` and create a config file:\n\n```ruby\n# config/initializers/code_to_query.rb\nCodeToQuery.configure do |config|\n  config.openai_api_key = ENV['OPENAI_API_KEY']\n  config.openai_model = 'gpt-4.1-mini'\n  \n  # Security settings\n  config.enable_explain_gate = true\n  config.allow_seq_scans = false\n  config.max_query_cost = 10000\n  config.require_limit_by_default = true\nend\n```\n\nGenerate your schema context:\n\n```bash\nrails code_to_query:bootstrap\n```\n\n## Basic usage\n\n```ruby\n# Ask a question\nquery = CodeToQuery.ask(\n  prompt: \"Top 10 invoices by amount in July\",\n  allow_tables: %w[invoices vendors],\n  current_user: current_user\n)\n\n# Check if it's safe to run\nif query.safe?\n  results = query.run\n  puts \"Found #{results.rows.length} results\"\nend\n\n# Or get the SQL for review\nputs query.sql\nputs query.params\n```\n\n## Configuration options\n\n### Database settings\n```ruby\nconfig.adapter = :postgres           # :postgres, :mysql, :sqlite\nconfig.readonly_role = :reporting    # Database role for queries\nconfig.default_limit = 100           # Default row limit\nconfig.max_limit = 10000             # Max allowed limit\n```\n\n### Security settings\n```ruby\nconfig.enable_explain_gate = true    # Block expensive queries\nconfig.allow_seq_scans = false       # Prevent table scans\nconfig.max_query_cost = 10000        # Cost threshold\nconfig.max_joins = 3                 # Join limit\n```\n\n### OpenAI settings\n```ruby\nconfig.openai_api_key = ENV['OPENAI_API_KEY']\nconfig.openai_model = 'gpt-4'\nconfig.stub_llm = false              # Set true for testing\n```\n\n## Rake tasks\n\n```bash\nrails code_to_query:bootstrap    # Generate full context pack\nrails code_to_query:schema       # Extract schema info\nrails code_to_query:scan_app     # Scan models and associations\nrails code_to_query:verify       # Check context pack integrity\n```\n\n## Security features\n\n- **SQL injection prevention**: All queries are parameterized\n- **Access control**: Table allowlists and row-level policies\n- **Performance limits**: EXPLAIN plan analysis and cost thresholds\n- **Readonly execution**: Uses dedicated readonly database connections\n\n## Advanced usage\n\n### Custom policies\n```ruby\nconfig.policy_adapter = -\u003e(user) do\n  return {} unless user\n  \n  {\n    company_id: user.company_id,\n    user_id: user.admin? ? nil : user.id\n  }\nend\n```\n\n### Custom schema\n```ruby\nschema = {\n  tables: [\n    {\n      name: \"users\",\n      columns: [\n        { name: \"id\", sql_type: \"integer\" },\n        { name: \"email\", sql_type: \"varchar\" }\n      ]\n    }\n  ]\n}\n\nquery = CodeToQuery.ask(\n  prompt: \"Recent users\",\n  schema: schema,\n  allow_tables: [\"users\"]\n)\n```\n\n## Error handling\n\n```ruby\nbegin\n  query = CodeToQuery.ask(prompt: \"Complex query\")\n  results = query.run if query.safe?\nrescue CodeToQuery::ExecutionError =\u003e e\n  Rails.logger.error \"Query failed: #{e.message}\"\nrescue CodeToQuery::ConnectionError =\u003e e\n  Rails.logger.error \"Database issue: #{e.message}\"\nend\n```\n\n## Contributing\n\n1. Fork the repo\n2. Create a feature branch\n3. Make your changes\n4. Add tests\n5. Submit a pull request\n\n## License\n\nMIT License - see LICENSE file for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkholdrex%2Fcode_to_query","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkholdrex%2Fcode_to_query","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkholdrex%2Fcode_to_query/lists"}