Skip to content

Commit 906cf6b

Browse files
authored
Merge pull request #2 from sql-rb/rework
Rework into SQL::Builder with no external gem dependencies
2 parents 01d1006 + 6737653 commit 906cf6b

38 files changed

+495
-339
lines changed

.github/ISSUE_TEMPLATE/bug-report.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
name: "\U0001F41B Bug report"
3+
about: See CONTRIBUTING.md for more information
4+
title: ''
5+
labels: bug, help wanted
6+
assignees: ''
7+
8+
---
9+
10+
## Describe the bug
11+
12+
A clear and concise description of what the bug is.
13+
14+
## To Reproduce
15+
16+
Provide detailed steps to reproduce, **an executable script would be best**.
17+
18+
## Expected behavior
19+
20+
A clear and concise description of what you expected to happen.
21+
22+
## My environment
23+
24+
- Affects my production application: **YES/NO**
25+
- Ruby version: ...
26+
- OS: ...

.github/ISSUE_TEMPLATE/config.yml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
blank_issues_enabled: false
2+
contact_links:
3+
- name: Community Support
4+
url: https://discourse.dry-rb.org
5+
about: Please ask and answer questions here.

.github/SUPPORT.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## Support
2+
3+
If you need help with any of the dry-rb libraries, feel free to ask questions on our [discussion forum](https://discourse.dry-rb.org/). This is the best place to seek help. Make sure to search for a potential solution in past threads before posting your question. Thanks! :heart:

.github/workflows/ci.yml

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
name: ci
3+
on:
4+
push:
5+
paths:
6+
- ".github/workflows/ci.yml"
7+
- lib/**
8+
- "*.gemspec"
9+
- spec/**
10+
- Rakefile
11+
- Gemfile
12+
- Gemfile.devtools
13+
- ".rubocop.yml"
14+
- project.yml
15+
pull_request:
16+
branches:
17+
- master
18+
create:
19+
jobs:
20+
tests:
21+
runs-on: ubuntu-latest
22+
strategy:
23+
fail-fast: false
24+
matrix:
25+
ruby:
26+
- head
27+
- '2.7'
28+
- '2.6'
29+
- '2.5'
30+
- jruby
31+
include:
32+
- ruby: '2.7'
33+
coverage: 'true'
34+
env:
35+
COVERAGE: "${{matrix.coverage}}"
36+
COVERAGE_TOKEN: "${{secrets.CODACY_PROJECT_TOKEN}}"
37+
steps:
38+
- uses: actions/checkout@v1
39+
- name: Set up Ruby
40+
uses: ruby/setup-ruby@v1
41+
with:
42+
ruby-version: "${{matrix.ruby}}"
43+
- name: Install latest bundler
44+
run: |
45+
gem install bundler --no-document
46+
bundle config set without 'tools benchmarks docs'
47+
- name: Bundle install
48+
run: bundle install --jobs 4 --retry 3
49+
- name: Run all tests
50+
run: bundle exec rake

.rspec

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
--format documentation
21
--color
2+
--require spec_helper
3+
--order random
4+
--warnings

.rubocop.yml

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# this file is managed by dry-rb/devtools project
2+
3+
AllCops:
4+
TargetRubyVersion: 2.7
5+
NewCops: disable
6+
7+
Style/StringLiterals:
8+
Enabled: true
9+
EnforcedStyle: double_quotes
10+
11+
Style/AccessModifierDeclarations:
12+
Enabled: false
13+
14+
Style/BlockDelimiters:
15+
Enabled: false
16+
17+
Style/SymbolArray:
18+
Exclude:
19+
- "spec/**/*_spec.rb"
20+
21+
Style/ConditionalAssignment:
22+
Enabled: false
23+
24+
Style/ClassAndModuleChildren:
25+
Exclude:
26+
- "spec/**/*_spec.rb"
27+
28+
Style/ParallelAssignment:
29+
Enabled: false
30+
31+
Style/Alias:
32+
Enabled: true
33+
EnforcedStyle: prefer_alias_method
34+
35+
Style/LambdaCall:
36+
Enabled: false
37+
38+
Style/StabbyLambdaParentheses:
39+
Enabled: false
40+
41+
Style/FormatString:
42+
Enabled: false
43+
44+
Style/Documentation:
45+
Enabled: false
46+
47+
Style/AsciiComments:
48+
Enabled: false
49+
50+
Style/DateTime:
51+
Enabled: false
52+
53+
Style/IfUnlessModifier:
54+
Enabled: false
55+
56+
Style/EachWithObject:
57+
Enabled: false
58+
59+
Lint/SuppressedException:
60+
Exclude:
61+
- "spec/spec_helper.rb"
62+
63+
Lint/BooleanSymbol:
64+
Enabled: false
65+
66+
Layout/SpaceInLambdaLiteral:
67+
Enabled: false
68+
69+
Layout/MultilineMethodCallIndentation:
70+
Enabled: true
71+
EnforcedStyle: indented
72+
73+
Layout/FirstArrayElementIndentation:
74+
EnforcedStyle: consistent
75+
76+
Naming/VariableNumber:
77+
Enabled: false
78+
79+
Naming/PredicateName:
80+
Enabled: false
81+
82+
Naming/FileName:
83+
Exclude:
84+
- "lib/dry-*.rb"
85+
86+
Naming/MethodName:
87+
Enabled: false
88+
89+
Naming/MemoizedInstanceVariableName:
90+
Enabled: false
91+
92+
Layout/LineLength:
93+
Max: 100
94+
95+
Metrics/MethodLength:
96+
Enabled: false
97+
98+
Metrics/ClassLength:
99+
Enabled: false
100+
101+
Metrics/BlockLength:
102+
Enabled: false
103+
104+
Metrics/AbcSize:
105+
Max: 25
106+
107+
Metrics/CyclomaticComplexity:
108+
Enabled: true
109+
Max: 12

.travis.yml

-3
This file was deleted.

Gemfile

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1-
source 'https://rubygems.org'
1+
# frozen_string_literal: true
2+
3+
source "https://rubygems.org"
24

35
# Specify your gem's dependencies in sql.rb.gemspec
46
gemspec
57

8+
gem "rake"
9+
610
group :tools do
7-
gem 'byebug', platforms: :mri
11+
gem "byebug", platforms: :mri
12+
gem "rubocop", "~> 1.6"
13+
end
14+
15+
group :test do
16+
gem "rspec", "~> 3.10"
817
end

LICENSE.txt renamed to LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2015 Piotr Solnica
3+
Copyright (c) 2020 Piotr Solnica
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

+2-77
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,3 @@
1-
# SQL.rb (WIP/PoC)
1+
# sql-builder
22

3-
A set of tools to generate SQL using AST transformations.
4-
5-
The goal of this project is to provide a foundation for generating SQL that is
6-
reusable for other Ruby libraries that need to translate their SQL-representation
7-
into SQL strings.
8-
9-
The idea is that SQL.rb ships with its own AST and a couple of tools to help
10-
working with this AST.
11-
12-
In example ActiveRecord **could do this**:
13-
14-
``` ruby
15-
ar_ast = User.select(:id, :name).where(name: 'Jane').to_ast
16-
# s(:select,
17-
# s(:fields, :id, :name),
18-
# s(:from, 'users'),
19-
# s(:where,
20-
# s(:name, s(:eq, 'Jane'))
21-
# )
22-
# )
23-
24-
sql_ast = ActiveRecord::SQL.call(User, ar_ast)
25-
# s(:select,
26-
# s(:fields,
27-
# s(:id, 'id'), s(:id, 'name')
28-
# ),
29-
# s(:id, 'users'),
30-
# s(:where,
31-
# s(:eq, s(:id, 'name'), s(:string, 'Jane'))
32-
# )
33-
# )
34-
35-
SQL[sql_ast]
36-
# => SELECT "id", "name" FROM "users" WHERE "name" = 'Jane'
37-
```
38-
39-
This project is in a PoC state and is heavily based on the experience and actual
40-
code written initially for [ROM](https://github.com/rom-rb), specifically:
41-
42-
* [dkubb/sql](https://github.com/dkubb/sql) - ast-based pure sql generator/parser
43-
* [solnic/axiom-sql-generator](https://github.com/solnic/axiom-sql-generator) - which was an attempt to translate axiom ast into sql ast
44-
* a ton of ast-processing-related work done by [mbj](https://github.com/mbj) for unparser and mutant gems
45-
46-
## Installation
47-
48-
Add this line to your application's Gemfile:
49-
50-
```ruby
51-
gem 'sql.rb'
52-
```
53-
54-
And then execute:
55-
56-
$ bundle
57-
58-
Or install it yourself as:
59-
60-
$ gem install sql.rb
61-
62-
## Usage
63-
64-
TODO: Write usage instructions here
65-
66-
## Development
67-
68-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
69-
70-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
71-
72-
## Contributing
73-
74-
1. Fork it ( https://github.com/solnic/sql.rb/fork )
75-
2. Create your feature branch (`git checkout -b my-new-feature`)
76-
3. Commit your changes (`git commit -am 'Add some feature'`)
77-
4. Push to the branch (`git push origin my-new-feature`)
78-
5. Create a new Pull Request
3+
TODO

Rakefile

+6
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
1+
# frozen_string_literal: true
2+
13
require "bundler/gem_tasks"
4+
require "rspec/core/rake_task"
5+
6+
RSpec::Core::RakeTask.new(:spec)
27

8+
task default: :spec

lib/sql.rb

-16
This file was deleted.

lib/sql/builder.rb

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
require "sql/builder/dsl"
4+
5+
module SQL
6+
def self.build(*args, &block)
7+
Builder::DSL.new(*args, &block).()
8+
end
9+
end

lib/sql/builder/compiler.rb

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# frozen_string_literal: true
2+
3+
module SQL
4+
module Builder
5+
class Compiler
6+
attr_reader :nodes
7+
8+
def initialize
9+
@nodes = []
10+
end
11+
12+
def call(ast)
13+
ast.map { |node| visit(node) }
14+
freeze
15+
end
16+
17+
def to_s
18+
nodes.map(&:to_s).join("\n")
19+
end
20+
21+
def visit(node)
22+
visitor, *args = node
23+
__send__(:"visit_#{visitor}", args)
24+
self
25+
end
26+
27+
def visit_from(node)
28+
name, _ = node
29+
nodes << Nodes::From.new(name)
30+
self
31+
end
32+
33+
def visit_select(names)
34+
nodes << Nodes::Select.new(names)
35+
self
36+
end
37+
38+
def visit_where(ops)
39+
nodes << Nodes::Where.new(ops)
40+
self
41+
end
42+
end
43+
end
44+
end

0 commit comments

Comments
 (0)