eql 0.0.1
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/LICENSE.txt +21 -0
- data/README.md +113 -0
- data/lib/eql/adapter_factory.rb +61 -0
- data/lib/eql/adapters/active_record.rb +66 -0
- data/lib/eql/adapters/base.rb +53 -0
- data/lib/eql/builder.rb +165 -0
- data/lib/eql/config.rb +30 -0
- data/lib/eql/proxy.rb +84 -0
- data/lib/eql/version.rb +4 -0
- data/lib/eql.rb +85 -0
- metadata +124 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2aec3fe36fce2efd0f4d5fd05f4ae6c8822c83a0
|
4
|
+
data.tar.gz: a00651310daeb5909ba5a4538ad7f3067764ed97
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 478099d1d7c7ca2f10d7e9df0a774350e7ee5e9ceda5fd8858f4351e8f44545c5713055571a06720299dfc9019f3b368828f22913cbb542ce1939cb1fbddc3eb
|
7
|
+
data.tar.gz: a95e2015c4e01699ae5b136e00e2065add263afa0cf1d92e0a5016fa830ad37dafc7680b50c382bc75967a311d9dd83deee7daf05f34ab5159adc8eb50767c3b
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Oleg Yashchuk
|
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
|
13
|
+
all 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
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# Eql
|
2
|
+
[](https://travis-ci.org/zoer/eql)
|
3
|
+
[](https://codeclimate.com/github/zoer/eql)
|
4
|
+
[](https://www.versioneye.com/ruby/eql)
|
5
|
+
[](http://inch-ci.org/github/zoer/eql)
|
6
|
+
[](http://badge.fury.io/rb/eql)
|
7
|
+
|
8
|
+
Eql provides an ability to create raw DB queries via ERB templates.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'eql'
|
16
|
+
```
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
### Simple usage
|
21
|
+
|
22
|
+
```erb
|
23
|
+
# queries/update.sql.erb
|
24
|
+
<% each do |item| %>
|
25
|
+
INSERT INTO items (category, name)
|
26
|
+
VALUES (<%= item.values_at(:category, :name).map { |i| quote(i) }.join(', ')) %>
|
27
|
+
ON CONFILICT (category, name) DO NOTHING
|
28
|
+
<% end %>
|
29
|
+
```
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
b = Eql.new('queries')
|
33
|
+
b.execute(update, [{category: 'cars', name: 'BMW'}, {category: 'cars', name: 'AUDI'}])
|
34
|
+
```
|
35
|
+
|
36
|
+
### Inline templates
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
b = Eql.template <<-ERB
|
40
|
+
SELECT products
|
41
|
+
FROM customer c
|
42
|
+
LEFT JOIN products p ON (c.id = p.customer_id)
|
43
|
+
WHERE c.id = <%= quote(id) %>
|
44
|
+
ERD
|
45
|
+
b.execute_params(id: 74)
|
46
|
+
```
|
47
|
+
|
48
|
+
### Usage with Rails
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
# config/initializers/eql.rb
|
52
|
+
|
53
|
+
Eql.configure do |config|
|
54
|
+
config.path = Rails.root.join('app/queries')
|
55
|
+
config.adapter = :active_record
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
```erb
|
60
|
+
# app/queries/fresh_items.sql.erb
|
61
|
+
SELECT *
|
62
|
+
FROM items
|
63
|
+
WHERE outdated IS DISTINCT FROM TRUE
|
64
|
+
LIMIT <%= limit %>
|
65
|
+
```
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
outdated = Eql.execute(:fresh_items, limit: 10)
|
69
|
+
```
|
70
|
+
|
71
|
+
### Create your own adapter
|
72
|
+
|
73
|
+
```
|
74
|
+
class BashAdapter < Eql::Adapters::Base
|
75
|
+
def self.match?(conn)
|
76
|
+
conn == :my_bash
|
77
|
+
end
|
78
|
+
|
79
|
+
def command
|
80
|
+
"bash << eof\n" \
|
81
|
+
"#{render}\n" \
|
82
|
+
"eof\n"
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def execute
|
87
|
+
`#{command}`
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
Eql.register_adapter(:my_bash, BashAdapter)
|
92
|
+
|
93
|
+
b = Eql.new(nil, :my_bash)
|
94
|
+
b.template <<-COMMAND
|
95
|
+
mkdir -p <%= folder %>
|
96
|
+
find . -name *.rb -not *_spec.rb -type f -exec mv {} <%= folder %> \;
|
97
|
+
ls folder/*
|
98
|
+
COMMAND
|
99
|
+
b.execute_params(folder: 'units')
|
100
|
+
``
|
101
|
+
|
102
|
+
### Adapters
|
103
|
+
Now implemented only `ActiveRecord` adapter. Please, fill free to contribute on
|
104
|
+
a new adapter.
|
105
|
+
|
106
|
+
## Contributing
|
107
|
+
|
108
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/zoer/eql.
|
109
|
+
|
110
|
+
|
111
|
+
## License
|
112
|
+
|
113
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Eql
|
2
|
+
#
|
3
|
+
# AdapterFactory class detects adapters and their helpers
|
4
|
+
#
|
5
|
+
class AdapterFactory
|
6
|
+
class << self
|
7
|
+
# @return [Symbol]
|
8
|
+
HELPERS_MODULE_NAME = :ContextHelpers
|
9
|
+
|
10
|
+
#
|
11
|
+
# Registered adapters
|
12
|
+
#
|
13
|
+
# @return [Hash{Symbol => Eql::Adapters::Base}]
|
14
|
+
#
|
15
|
+
def adapters
|
16
|
+
@adapters ||= {}
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Register a new adapter
|
21
|
+
#
|
22
|
+
# @param [Symbol] key adapter's key
|
23
|
+
# @param [Eql::Adapters::Base] klass adapter's class
|
24
|
+
#
|
25
|
+
def register_adapter(key, klass)
|
26
|
+
adapters[key] = klass
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Get adapter's helper modules
|
31
|
+
#
|
32
|
+
# @param [Eql::Adapters::Base] adapter
|
33
|
+
#
|
34
|
+
# @return [Array<Module>]
|
35
|
+
#
|
36
|
+
def adapter_helpers(adapter)
|
37
|
+
adapter.class.ancestors.each_with_object([]) do |klass, ret|
|
38
|
+
next unless klass.is_a?(Class)
|
39
|
+
next unless klass.const_defined?(HELPERS_MODULE_NAME)
|
40
|
+
ret.unshift klass.const_get(HELPERS_MODULE_NAME)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Detect adapter class
|
46
|
+
#
|
47
|
+
# @raise [RuntimeError] when can't find adapter's class
|
48
|
+
#
|
49
|
+
# @param [Object, nil] conn DB connection or a cursor
|
50
|
+
#
|
51
|
+
# @return [Eql::Adapters::Base]
|
52
|
+
#
|
53
|
+
def factory(conn)
|
54
|
+
return Eql.config.default_adapter unless conn
|
55
|
+
adapters.values.find { |a| a.match?(conn) if a.respond_to?(:match?) }.tap do |adapter|
|
56
|
+
raise "Unable to detect adapter for #{conn.inspect}" unless adapter
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Eql
|
2
|
+
module Adapters
|
3
|
+
#
|
4
|
+
# ActiveRecord class is a ActiveRecord::Base adapter
|
5
|
+
#
|
6
|
+
class ActiveRecord < Base
|
7
|
+
#
|
8
|
+
# ContextHelpers module contains template's helpers
|
9
|
+
#
|
10
|
+
module ContextHelpers
|
11
|
+
#
|
12
|
+
# Quote string
|
13
|
+
#
|
14
|
+
# @param [String] val string to quote
|
15
|
+
#
|
16
|
+
# @return [String] returns safety quoted string
|
17
|
+
#
|
18
|
+
def quote(val)
|
19
|
+
::ActiveRecord::Base.connection.quote(val)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# @see Eql::Adapters::Base#match?
|
25
|
+
#
|
26
|
+
def self.match?(conn)
|
27
|
+
defined?(::ActiveRecord::Base) &&
|
28
|
+
conn.is_a?(::ActiveRecord::ConnectionAdapters::AbstractAdapter)
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Get rendered SQL
|
33
|
+
#
|
34
|
+
# @return [Stirng]
|
35
|
+
#
|
36
|
+
def sql
|
37
|
+
builder.render
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# @see Eql::Adapters::Base#extension
|
42
|
+
#
|
43
|
+
def extension
|
44
|
+
'.{sql.erb,erb.sql}'
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# @see Eql::Adapters::Base#execute
|
49
|
+
#
|
50
|
+
def execute
|
51
|
+
conn.execute(sql).to_a
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Get DB connection to execute a query
|
56
|
+
#
|
57
|
+
# @return [ActiveRecord::ConnectionAdapters::AbstractAdapter]
|
58
|
+
#
|
59
|
+
def conn
|
60
|
+
builder.conn || ::ActiveRecord::Base.connection
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
Eql.register_adapter :active_record, Eql::Adapters::ActiveRecord
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Eql
|
2
|
+
#
|
3
|
+
# Adapters module contains DB adapters
|
4
|
+
#
|
5
|
+
module Adapters
|
6
|
+
#
|
7
|
+
# Base class contains basic adapter logic
|
8
|
+
#
|
9
|
+
class Base
|
10
|
+
module ContextHelpers
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [Eql::Builder]
|
14
|
+
attr_reader :builder
|
15
|
+
|
16
|
+
#
|
17
|
+
# Does adapter match connection?
|
18
|
+
#
|
19
|
+
# @param [Object] conn
|
20
|
+
#
|
21
|
+
# @return [Boolean]
|
22
|
+
#
|
23
|
+
def self.match?(conn)
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# @param [Eql::Builder] builder
|
29
|
+
#
|
30
|
+
def initialize(builder)
|
31
|
+
@builder = builder
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Execute adapter
|
36
|
+
#
|
37
|
+
# @return [Object] return exection results
|
38
|
+
#
|
39
|
+
def execute
|
40
|
+
raise NotImplementedError
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Get adapter's template extensions
|
45
|
+
#
|
46
|
+
# @return [String]
|
47
|
+
#
|
48
|
+
def extension
|
49
|
+
'.erb'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/eql/builder.rb
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
module Eql
|
2
|
+
#
|
3
|
+
# Builder class builds ERB templates and interact with adapters to run it.
|
4
|
+
#
|
5
|
+
class Builder
|
6
|
+
# @param [String] returns path to a root folder with templates
|
7
|
+
attr_reader :path
|
8
|
+
# @param [String] retruns DB connectionor a currsor
|
9
|
+
attr_reader :conn
|
10
|
+
|
11
|
+
#
|
12
|
+
# @param [String] path path to a root folder with templates
|
13
|
+
# @param [String] conn DB connection or a cursor
|
14
|
+
#
|
15
|
+
def initialize(path, conn)
|
16
|
+
@path = path
|
17
|
+
@conn = conn
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Load query's template and params
|
22
|
+
#
|
23
|
+
# @param [String] name template's name
|
24
|
+
# @param [Object] params query's params
|
25
|
+
#
|
26
|
+
def load(name = nil, params = nil)
|
27
|
+
load_template(name) if name
|
28
|
+
load_params(params) if params
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Load template with given name
|
33
|
+
#
|
34
|
+
# @param [String, Symbol] name template's name
|
35
|
+
#
|
36
|
+
def load_template(name)
|
37
|
+
@template_content = File.read(resolve_path(name))
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Load query's params
|
42
|
+
#
|
43
|
+
# @param [Object] params
|
44
|
+
#
|
45
|
+
def load_params(params)
|
46
|
+
@params = params
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Set content template
|
51
|
+
#
|
52
|
+
# @param [String] raw template's content
|
53
|
+
#
|
54
|
+
def template(raw)
|
55
|
+
@template_content = raw
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Proxy's adapter
|
60
|
+
#
|
61
|
+
# @retrn [Eql::Adapters::Base]
|
62
|
+
#
|
63
|
+
def adapter
|
64
|
+
@adapter ||= AdapterFactory.factory(conn).new(self)
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Template's content
|
69
|
+
#
|
70
|
+
# @return [String]
|
71
|
+
#
|
72
|
+
def template_content
|
73
|
+
@template_content.to_s
|
74
|
+
end
|
75
|
+
|
76
|
+
class H < Hash
|
77
|
+
def name
|
78
|
+
:h
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Render a template
|
84
|
+
#
|
85
|
+
# @return [String] returns rendered templated
|
86
|
+
#
|
87
|
+
def render
|
88
|
+
ERB.new(template_content).result(proxy_class.new(self, @params).get_binding)
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Proxy class for template
|
93
|
+
#
|
94
|
+
# @return [Eql::Proxy]
|
95
|
+
#
|
96
|
+
def proxy_class
|
97
|
+
Eql::Proxy.generate(adapter)
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# File template to find
|
102
|
+
#
|
103
|
+
# @param [String, Symbol] file template's name
|
104
|
+
#
|
105
|
+
# @return [String] returns file path pattern
|
106
|
+
#
|
107
|
+
def template_path(file)
|
108
|
+
File.join(@path.to_s, file.to_s) + adapter.extension
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Resolve file's path
|
113
|
+
#
|
114
|
+
# @raise [RuntimeError] when can't wind a file
|
115
|
+
#
|
116
|
+
# @param [String] file template's name
|
117
|
+
#
|
118
|
+
# @return [String] returns template's path
|
119
|
+
#
|
120
|
+
def resolve_path(file)
|
121
|
+
path = template_path(file)
|
122
|
+
Dir.glob(path).first.tap do |f|
|
123
|
+
raise "Unable to find query template with #{path.inspect} location" unless f
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def method_missing(name, *args, &block)
|
128
|
+
adapter.send(name, *args, &block)
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# Execute template query
|
133
|
+
#
|
134
|
+
# @param [String, Symbol] tmpl template's name
|
135
|
+
# @param [Object, nil] params o
|
136
|
+
#
|
137
|
+
# @return [Object] returns execution results
|
138
|
+
#
|
139
|
+
def execute(tmpl = nil, params = nil)
|
140
|
+
load(tmpl, params)
|
141
|
+
adapter.execute
|
142
|
+
end
|
143
|
+
|
144
|
+
#
|
145
|
+
# Execute params with a query
|
146
|
+
#
|
147
|
+
# @param [Object] params
|
148
|
+
#
|
149
|
+
# @return [Object] returns execution results
|
150
|
+
#
|
151
|
+
def execute_params(params = nil)
|
152
|
+
load_params(params)
|
153
|
+
adapter.execute
|
154
|
+
end
|
155
|
+
|
156
|
+
#
|
157
|
+
# Clone current builder
|
158
|
+
#
|
159
|
+
# @return [Eql::Builder]
|
160
|
+
#
|
161
|
+
def clone
|
162
|
+
self.class.new(path, conn)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
data/lib/eql/config.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Eql
|
2
|
+
#
|
3
|
+
# Config class holds rendering settings
|
4
|
+
#
|
5
|
+
class Config
|
6
|
+
# @param [String]
|
7
|
+
attr_accessor :path
|
8
|
+
# @param [Symbol]
|
9
|
+
attr_accessor :adapter
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@adapter = :active_record
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# @return [String] returns templates root folder
|
17
|
+
#
|
18
|
+
def path
|
19
|
+
@path ||= defined?(Rails) ? Rails.root : Dir.pwd
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# @return [Eql::Adapters::Base] returns default adapter
|
24
|
+
#
|
25
|
+
def default_adapter
|
26
|
+
return unless adapter
|
27
|
+
@default_adapter ||= AdapterFactory.adapters[adapter]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/eql/proxy.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
module Eql
|
2
|
+
#
|
3
|
+
# Proxy class proxies adapaters helpers and params to a template
|
4
|
+
#
|
5
|
+
class Proxy
|
6
|
+
#
|
7
|
+
# @param [Eql::Builder] builder
|
8
|
+
# @param [Object] params template's params to proxy
|
9
|
+
#
|
10
|
+
def initialize(builder, params = nil)
|
11
|
+
@builder = builder
|
12
|
+
@params = params
|
13
|
+
if @params.is_a?(Hash)
|
14
|
+
@params = params.keys.each_with_object({}) do |key, ret|
|
15
|
+
ret[key.respond_to?(:to_sym) ? key.to_sym : key] = params[key]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Render partial template
|
22
|
+
#
|
23
|
+
# @param [String] tmpl partial's name
|
24
|
+
# @param [Object] params template's params
|
25
|
+
#
|
26
|
+
# @return [String] returns rendered template
|
27
|
+
#
|
28
|
+
def render(tmpl, params = nil)
|
29
|
+
b = @builder.clone
|
30
|
+
b.load(tmpl, params)
|
31
|
+
b.render
|
32
|
+
end
|
33
|
+
|
34
|
+
def method_missing(name, *args, &block)
|
35
|
+
return @params[name] if @params.is_a?(Hash) && @params.key?(name)
|
36
|
+
@params.send(name, *args, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
def respond_to_missing?(name, *)
|
40
|
+
@params.is_a?(Hash) && @params.key?(name) ||
|
41
|
+
@params.respond_to?(name) ||
|
42
|
+
super
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Get proxy binding
|
47
|
+
#
|
48
|
+
# @return [Binding]
|
49
|
+
#
|
50
|
+
def get_binding
|
51
|
+
# binding.name # => :binding
|
52
|
+
# if we have variable with the 'name' name we need to make a closure
|
53
|
+
name = send(:name) if respond_to?(:name)
|
54
|
+
binding
|
55
|
+
end
|
56
|
+
|
57
|
+
class << self
|
58
|
+
#
|
59
|
+
# Cached generated proxy classes
|
60
|
+
#
|
61
|
+
# @return [Hash{Symbol => Eql::Proxy}]
|
62
|
+
#
|
63
|
+
def generated
|
64
|
+
@generated ||= {}
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Generate a proxy class for given adapter
|
69
|
+
#
|
70
|
+
# @param [Eql::Adapters::Base] adapter
|
71
|
+
#
|
72
|
+
# @return [Eql::Proxy] returns generated class
|
73
|
+
#
|
74
|
+
def generate(adapter)
|
75
|
+
generated[adapter.class] ||= begin
|
76
|
+
helpers = AdapterFactory.adapter_helpers(adapter)
|
77
|
+
Class.new(self) do
|
78
|
+
helpers.each { |h| include h }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/eql/version.rb
ADDED
data/lib/eql.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Eql module renders ERB query templates and runs them
|
5
|
+
#
|
6
|
+
module Eql
|
7
|
+
class << self
|
8
|
+
#
|
9
|
+
# Create new builder
|
10
|
+
#
|
11
|
+
# @param [String, nil] path template's root folder
|
12
|
+
# @param [Object, nil] conn DB connection or cursor
|
13
|
+
#
|
14
|
+
def new(path = nil, conn = nil)
|
15
|
+
Builder.new(path || config.path, conn)
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Load a builder with template and params
|
20
|
+
#
|
21
|
+
# @param [String, Symbol] tmpl template's name
|
22
|
+
# @param [Object, nil] params template's params
|
23
|
+
#
|
24
|
+
# @return [Eql::Builder]
|
25
|
+
#
|
26
|
+
def load(tmpl, params = nil)
|
27
|
+
new.tap { |b| b.load(tmpl, params) }
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Execute a builder with template and params
|
32
|
+
#
|
33
|
+
# @param [String, Symbol] tmpl template's name
|
34
|
+
# @param [Object, nil] params template's params
|
35
|
+
#
|
36
|
+
# @return [Object] returns excution results
|
37
|
+
#
|
38
|
+
def execute(tmpl, params = nil)
|
39
|
+
load(tmpl, params).execute
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Load a builder with template content
|
44
|
+
#
|
45
|
+
# @param [String] erb template's content
|
46
|
+
#
|
47
|
+
# @return [Eql::Builder]
|
48
|
+
#
|
49
|
+
def template(erb)
|
50
|
+
new.tap { |b| b.template(erb) }
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# @return [Eql::Config]
|
55
|
+
#
|
56
|
+
def config
|
57
|
+
@config ||= Config.new
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Setup
|
62
|
+
#
|
63
|
+
def configure
|
64
|
+
yield(config)
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# @see Eql::AdapterFactory#redister_adapter
|
69
|
+
#
|
70
|
+
def register_adapter(key, klass)
|
71
|
+
AdapterFactory.register_adapter(key, klass)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
%w[
|
77
|
+
version
|
78
|
+
config
|
79
|
+
proxy
|
80
|
+
builder
|
81
|
+
adapter_factory
|
82
|
+
adapters/base
|
83
|
+
adapters/active_record
|
84
|
+
].each { |f| require_relative "eql/#{f}" }
|
85
|
+
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eql
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Oleg Yashchuk
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: byebug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activerecord
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sqlite3
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Create a raw query to your DB via ERB templates
|
84
|
+
email:
|
85
|
+
- oazoer@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- LICENSE.txt
|
91
|
+
- README.md
|
92
|
+
- lib/eql.rb
|
93
|
+
- lib/eql/adapter_factory.rb
|
94
|
+
- lib/eql/adapters/active_record.rb
|
95
|
+
- lib/eql/adapters/base.rb
|
96
|
+
- lib/eql/builder.rb
|
97
|
+
- lib/eql/config.rb
|
98
|
+
- lib/eql/proxy.rb
|
99
|
+
- lib/eql/version.rb
|
100
|
+
homepage:
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 2.5.1
|
121
|
+
signing_key:
|
122
|
+
specification_version: 4
|
123
|
+
summary: Erb Query Language
|
124
|
+
test_files: []
|