b_b 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +9 -0
- data/.hound.yml +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +13 -0
- data/.ruby-style.yml +243 -0
- data/.travis.yml +14 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +212 -0
- data/Rakefile +6 -0
- data/b_b.gemspec +33 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/b_b/builder.rb +81 -0
- data/lib/b_b/component.rb +81 -0
- data/lib/b_b/converter/formula.rb +87 -0
- data/lib/b_b/converter/order.rb +30 -0
- data/lib/b_b/converter/table.rb +49 -0
- data/lib/b_b/converter/value.rb +99 -0
- data/lib/b_b/converter.rb +8 -0
- data/lib/b_b/evaluator/formula.rb +81 -0
- data/lib/b_b/evaluator/table.rb +42 -0
- data/lib/b_b/evaluator/value.rb +72 -0
- data/lib/b_b/evaluator.rb +7 -0
- data/lib/b_b/exception.rb +13 -0
- data/lib/b_b/factory.rb +67 -0
- data/lib/b_b/factory_decorator/extractable.rb +75 -0
- data/lib/b_b/factory_decorator/from.rb +25 -0
- data/lib/b_b/factory_decorator/joinable.rb +15 -0
- data/lib/b_b/factory_decorator/limit.rb +19 -0
- data/lib/b_b/factory_decorator/order.rb +21 -0
- data/lib/b_b/factory_decorator/selectable.rb +15 -0
- data/lib/b_b/factory_decorator.rb +10 -0
- data/lib/b_b/relation.rb +49 -0
- data/lib/b_b/version.rb +3 -0
- data/lib/b_b.rb +58 -0
- metadata +221 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0eb5f13d8db2d94fb62a2e75a51a34a305ab580d
|
4
|
+
data.tar.gz: 24fa3ef4a9ac0bf7b459c6d0797adaa532737800
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e540f2d694a216c2d7315047649c0f2e1a3983c7d7ee681e51f1f4e0ca389781671049b2b7697a8e34776602c53387ec55c3052c1e3e42944bcf86bae62ba627
|
7
|
+
data.tar.gz: cf30f527a0000c84c66121adc488515980febd2e3dfc0b8a8d9d638d3eda0b92636ec56585a2822e0fcfc5afeb4a025497f8d60e2b93b744b99df99d3ffc6655
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.gitignore
ADDED
data/.hound.yml
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.ruby-style.yml
ADDED
@@ -0,0 +1,243 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- "vendor/**/*"
|
4
|
+
- "db/schema.rb"
|
5
|
+
UseCache: false
|
6
|
+
Style/CollectionMethods:
|
7
|
+
Description: Preferred collection methods.
|
8
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#map-find-select-reduce-size
|
9
|
+
Enabled: true
|
10
|
+
PreferredMethods:
|
11
|
+
collect: map
|
12
|
+
collect!: map!
|
13
|
+
find: detect
|
14
|
+
find_all: select
|
15
|
+
reduce: inject
|
16
|
+
Style/DotPosition:
|
17
|
+
Description: Checks the position of the dot in multi-line method calls.
|
18
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains
|
19
|
+
Enabled: true
|
20
|
+
EnforcedStyle: trailing
|
21
|
+
SupportedStyles:
|
22
|
+
- leading
|
23
|
+
- trailing
|
24
|
+
Style/FileName:
|
25
|
+
Description: Use snake_case for source file names.
|
26
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-files
|
27
|
+
Enabled: false
|
28
|
+
Exclude: []
|
29
|
+
Style/GuardClause:
|
30
|
+
Description: Check for conditionals that can be replaced with guard clauses
|
31
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals
|
32
|
+
Enabled: false
|
33
|
+
MinBodyLength: 1
|
34
|
+
Style/IfUnlessModifier:
|
35
|
+
Description: Favor modifier if/unless usage when you have a single-line body.
|
36
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier
|
37
|
+
Enabled: false
|
38
|
+
MaxLineLength: 80
|
39
|
+
Style/OptionHash:
|
40
|
+
Description: Don't use option hashes when you can use keyword arguments.
|
41
|
+
Enabled: false
|
42
|
+
Style/PercentLiteralDelimiters:
|
43
|
+
Description: Use `%`-literal delimiters consistently
|
44
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-literal-braces
|
45
|
+
Enabled: false
|
46
|
+
PreferredDelimiters:
|
47
|
+
"%": "()"
|
48
|
+
"%i": "()"
|
49
|
+
"%q": "()"
|
50
|
+
"%Q": "()"
|
51
|
+
"%r": "{}"
|
52
|
+
"%s": "()"
|
53
|
+
"%w": "()"
|
54
|
+
"%W": "()"
|
55
|
+
"%x": "()"
|
56
|
+
Style/PredicateName:
|
57
|
+
Description: Check the names of predicate methods.
|
58
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark
|
59
|
+
Enabled: true
|
60
|
+
NamePrefix:
|
61
|
+
- is_
|
62
|
+
- has_
|
63
|
+
- have_
|
64
|
+
NamePrefixBlacklist:
|
65
|
+
- is_
|
66
|
+
Exclude:
|
67
|
+
- spec/**/*
|
68
|
+
Style/RaiseArgs:
|
69
|
+
Description: Checks the arguments passed to raise/fail.
|
70
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#exception-class-messages
|
71
|
+
Enabled: false
|
72
|
+
EnforcedStyle: exploded
|
73
|
+
SupportedStyles:
|
74
|
+
- compact
|
75
|
+
- exploded
|
76
|
+
Style/SignalException:
|
77
|
+
Description: Checks for proper usage of fail and raise.
|
78
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
|
79
|
+
Enabled: false
|
80
|
+
EnforcedStyle: semantic
|
81
|
+
SupportedStyles:
|
82
|
+
- only_raise
|
83
|
+
- only_fail
|
84
|
+
- semantic
|
85
|
+
Style/SingleLineBlockParams:
|
86
|
+
Description: Enforces the names of some block params.
|
87
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#reduce-blocks
|
88
|
+
Enabled: false
|
89
|
+
Methods:
|
90
|
+
- reduce:
|
91
|
+
- a
|
92
|
+
- e
|
93
|
+
- inject:
|
94
|
+
- a
|
95
|
+
- e
|
96
|
+
Style/SingleLineMethods:
|
97
|
+
Description: Avoid single-line methods.
|
98
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-single-line-methods
|
99
|
+
Enabled: false
|
100
|
+
AllowIfMethodIsEmpty: true
|
101
|
+
Style/StringLiterals:
|
102
|
+
Description: Checks if uses of quotes match the configured preference.
|
103
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-string-literals
|
104
|
+
Enabled: true
|
105
|
+
EnforcedStyle: double_quotes
|
106
|
+
SupportedStyles:
|
107
|
+
- single_quotes
|
108
|
+
- double_quotes
|
109
|
+
Style/StringLiteralsInInterpolation:
|
110
|
+
Description: Checks if uses of quotes inside expressions in interpolated strings
|
111
|
+
match the configured preference.
|
112
|
+
Enabled: true
|
113
|
+
EnforcedStyle: single_quotes
|
114
|
+
SupportedStyles:
|
115
|
+
- single_quotes
|
116
|
+
- double_quotes
|
117
|
+
Style/TrailingCommaInArguments:
|
118
|
+
Description: 'Checks for trailing comma in argument lists.'
|
119
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
|
120
|
+
Enabled: false
|
121
|
+
EnforcedStyleForMultiline: no_comma
|
122
|
+
SupportedStyles:
|
123
|
+
- comma
|
124
|
+
- consistent_comma
|
125
|
+
- no_comma
|
126
|
+
Style/TrailingCommaInLiteral:
|
127
|
+
Description: 'Checks for trailing comma in array and hash literals.'
|
128
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
|
129
|
+
Enabled: false
|
130
|
+
EnforcedStyleForMultiline: no_comma
|
131
|
+
SupportedStyles:
|
132
|
+
- comma
|
133
|
+
- consistent_comma
|
134
|
+
- no_comma
|
135
|
+
Metrics/AbcSize:
|
136
|
+
Description: A calculated magnitude based on number of assignments, branches, and
|
137
|
+
conditions.
|
138
|
+
Enabled: false
|
139
|
+
Max: 15
|
140
|
+
Metrics/ClassLength:
|
141
|
+
Description: Avoid classes longer than 100 lines of code.
|
142
|
+
Enabled: false
|
143
|
+
CountComments: false
|
144
|
+
Max: 100
|
145
|
+
Metrics/ModuleLength:
|
146
|
+
CountComments: false
|
147
|
+
Max: 100
|
148
|
+
Description: Avoid modules longer than 100 lines of code.
|
149
|
+
Enabled: false
|
150
|
+
Metrics/CyclomaticComplexity:
|
151
|
+
Description: A complexity metric that is strongly correlated to the number of test
|
152
|
+
cases needed to validate a method.
|
153
|
+
Enabled: false
|
154
|
+
Max: 6
|
155
|
+
Metrics/MethodLength:
|
156
|
+
Description: Avoid methods longer than 10 lines of code.
|
157
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods
|
158
|
+
Enabled: false
|
159
|
+
CountComments: false
|
160
|
+
Max: 10
|
161
|
+
Metrics/ParameterLists:
|
162
|
+
Description: Avoid parameter lists longer than three or four parameters.
|
163
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#too-many-params
|
164
|
+
Enabled: false
|
165
|
+
Max: 5
|
166
|
+
CountKeywordArgs: true
|
167
|
+
Metrics/PerceivedComplexity:
|
168
|
+
Description: A complexity metric geared towards measuring complexity for a human
|
169
|
+
reader.
|
170
|
+
Enabled: false
|
171
|
+
Max: 7
|
172
|
+
Lint/AssignmentInCondition:
|
173
|
+
Description: Don't use assignment in conditions.
|
174
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition
|
175
|
+
Enabled: false
|
176
|
+
AllowSafeAssignment: true
|
177
|
+
Style/InlineComment:
|
178
|
+
Description: Avoid inline comments.
|
179
|
+
Enabled: false
|
180
|
+
Style/AccessorMethodName:
|
181
|
+
Description: Check the naming of accessor methods for get_/set_.
|
182
|
+
Enabled: false
|
183
|
+
Style/Alias:
|
184
|
+
Description: Use alias_method instead of alias.
|
185
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#alias-method
|
186
|
+
Enabled: false
|
187
|
+
Style/Documentation:
|
188
|
+
Description: Document classes and non-namespace modules.
|
189
|
+
Enabled: false
|
190
|
+
Style/DoubleNegation:
|
191
|
+
Description: Checks for uses of double negation (!!).
|
192
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-bang-bang
|
193
|
+
Enabled: false
|
194
|
+
Style/EachWithObject:
|
195
|
+
Description: Prefer `each_with_object` over `inject` or `reduce`.
|
196
|
+
Enabled: false
|
197
|
+
Style/EmptyLiteral:
|
198
|
+
Description: Prefer literals to Array.new/Hash.new/String.new.
|
199
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#literal-array-hash
|
200
|
+
Enabled: false
|
201
|
+
Style/ModuleFunction:
|
202
|
+
Description: Checks for usage of `extend self` in modules.
|
203
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#module-function
|
204
|
+
Enabled: false
|
205
|
+
Style/OneLineConditional:
|
206
|
+
Description: Favor the ternary operator(?:) over if/then/else/end constructs.
|
207
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#ternary-operator
|
208
|
+
Enabled: false
|
209
|
+
Style/PerlBackrefs:
|
210
|
+
Description: Avoid Perl-style regex back references.
|
211
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers
|
212
|
+
Enabled: false
|
213
|
+
Style/Send:
|
214
|
+
Description: Prefer `Object#__send__` or `Object#public_send` to `send`, as `send`
|
215
|
+
may overlap with existing methods.
|
216
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#prefer-public-send
|
217
|
+
Enabled: false
|
218
|
+
Style/SpecialGlobalVars:
|
219
|
+
Description: Avoid Perl-style global variables.
|
220
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms
|
221
|
+
Enabled: false
|
222
|
+
Style/VariableInterpolation:
|
223
|
+
Description: Don't interpolate global, instance and class variables directly in
|
224
|
+
strings.
|
225
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#curlies-interpolate
|
226
|
+
Enabled: false
|
227
|
+
Style/WhenThen:
|
228
|
+
Description: Use when x then ... for one-line cases.
|
229
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#one-line-cases
|
230
|
+
Enabled: false
|
231
|
+
Lint/EachWithObjectArgument:
|
232
|
+
Description: Check for immutable argument given to each_with_object.
|
233
|
+
Enabled: true
|
234
|
+
Lint/HandleExceptions:
|
235
|
+
Description: Don't suppress exception.
|
236
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions
|
237
|
+
Enabled: false
|
238
|
+
Lint/LiteralInCondition:
|
239
|
+
Description: Checks of literals used in conditions.
|
240
|
+
Enabled: false
|
241
|
+
Lint/LiteralInInterpolation:
|
242
|
+
Description: Checks for literals used in interpolation.
|
243
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Yoshiyuki Hirano
|
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,212 @@
|
|
1
|
+
# BB
|
2
|
+
|
3
|
+
(b_b) is SQL Query Builder for [Google BigQuery](https://cloud.google.com/bigquery)
|
4
|
+
|
5
|
+
[![Build Status](https://travis-ci.org/yhirano55/b_b.svg?branch=master)](https://travis-ci.org/yhirano55/b_b) [![Coverage Status](https://coveralls.io/repos/github/yhirano55/b_b/badge.svg?branch=master)](https://coveralls.io/github/yhirano55/b_b?branch=master) [![codebeat badge](https://codebeat.co/badges/5e694b1a-93b1-4fda-ad6e-3dc0d5afe76b)](https://codebeat.co/projects/github-com-yhirano55-b_b)
|
6
|
+
|
7
|
+
## Install
|
8
|
+
|
9
|
+
Add the following line to Gemfile:
|
10
|
+
|
11
|
+
gem 'b_b'
|
12
|
+
|
13
|
+
and run `bundle` from your shell.
|
14
|
+
|
15
|
+
To install the gem manually from your shell, run:
|
16
|
+
|
17
|
+
gem install b_b
|
18
|
+
|
19
|
+
## Basic usage
|
20
|
+
|
21
|
+
(b_b) can build only **SQL SELECT Statement**.
|
22
|
+
|
23
|
+
```rb
|
24
|
+
BB.select("word", "corpus", "COUNT(word)").
|
25
|
+
from("publicdata:samples.shakespeare").
|
26
|
+
where(word_cont: "th").
|
27
|
+
group(:word, :corpus).
|
28
|
+
to_sql
|
29
|
+
|
30
|
+
# => "SELECT word, corpus, COUNT(word) FROM publicdata:samples.shakespeare WHERE (word CONTAINS 'th') GROUP BY word, corpus"
|
31
|
+
```
|
32
|
+
|
33
|
+
Query Reference of BigQuery's query syntax and functions is [here](https://cloud.google.com/bigquery/query-reference?hl=en).
|
34
|
+
|
35
|
+
## Examples
|
36
|
+
|
37
|
+
### SELECT clause
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
BB.select(:id, :name, :state).to_sql
|
41
|
+
# => "SELECT id, name, state"
|
42
|
+
|
43
|
+
BB.select("id", "name", "COUNT(*)").to_sql
|
44
|
+
# => "SELECT id, name, COUNT(*)"
|
45
|
+
```
|
46
|
+
|
47
|
+
### FROM clause
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
BB.from("publicdata:samples.shakespeare").to_sql
|
51
|
+
# => "SELECT * FROM publicdata:samples.shakespeare"
|
52
|
+
|
53
|
+
BB.from("[applogs.events_20120501]", "[applogs.events_20120502]", "[applogs.events_20120503]").to_sql
|
54
|
+
# => "SELECT * FROM [applogs.events_20120501], [applogs.events_20120502], [applogs.events_20120503]"
|
55
|
+
|
56
|
+
BB.from("applogs.events_", on: Date.new(2012, 5, 1)).to_sql
|
57
|
+
# => "SELECT * FROM applogs.events_20120501"
|
58
|
+
|
59
|
+
BB.from("mydata.people", from: Date.new(2014, 3, 25), to: Date.new(2014, 3, 27)).to_sql
|
60
|
+
# => "SELECT * FROM TABLE_DATE_RANGE(mydata.people, TIMESTAMP('2014-03-25'), TIMESTAMP('2014-03-27'))"
|
61
|
+
|
62
|
+
BB.from(BB.from("publicdata:samples.shakespeare"), as: shakespeare).to_sql
|
63
|
+
# => "SELECT * FROM (SELECT * FROM publicdata:samples.shakespeare) AS shakespeare"
|
64
|
+
```
|
65
|
+
|
66
|
+
### JOIN clause
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
BB.from(:customers, as: :t1).inner_join(:orders, as: :t2).on("t1.customer_id = t2.customer_id").to_sql
|
70
|
+
# => "SELECT * FROM customers AS t1 INNER JOIN orders AS t2 ON t1.customer_id = t2.customer_id"
|
71
|
+
|
72
|
+
BB.from(:customers, as: :t1).join_each(BB.select(:id, :name).from(:orders), as: :t2).on("t1.customer_id = t2.customer_id").to_sql
|
73
|
+
# => "SELECT * FROM customers AS t1 JOIN EACH (SELECT id, name FROM orders) AS t2 ON t1.customer_id = t2.customer_id"
|
74
|
+
```
|
75
|
+
|
76
|
+
### WHERE clause
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
BB.where(id: 1..10, name: "donald", flag: false).to_sql
|
80
|
+
# => "WHERE (id BETWEEN 1 AND 10 AND name = 'donald' AND flag IS false)"
|
81
|
+
|
82
|
+
BB.where("id = ? OR name CONTAINS ?", 123, "john").to_sql
|
83
|
+
# => "WHERE (id = 123 OR name CONTAINS 'john')"
|
84
|
+
|
85
|
+
BB.where("id = :id AND name <> :name", id: 123, name: "trump").to_sql
|
86
|
+
# => "WHERE (id = 123 AND name <> 'trump')"
|
87
|
+
|
88
|
+
BB.where(id_gteq: 123, name_not_cont: "melania").to_sql
|
89
|
+
# => "WHERE (id >= 123 AND NOT name CONTAINS 'melania')"
|
90
|
+
|
91
|
+
BB.where(id: 123).or.where(id: 456).to_sql
|
92
|
+
# => "WHERE (id = 123) OR (id = 456)"
|
93
|
+
|
94
|
+
BB.not.where(id: 123).or.not.where(id: 456).to_sql
|
95
|
+
# => "WHERE (id <> 123) OR (id <> 456)"
|
96
|
+
|
97
|
+
BB.where(id: 123, name: "trump", reduce: :or).to_sql
|
98
|
+
# => "WHERE (id = 123 OR name = 'trump')"
|
99
|
+
```
|
100
|
+
|
101
|
+
### OMIT RECORD IF clause
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
BB.omit_record_if("COUNT(payload.pages.page_name) <= ?", 80).to_sql
|
105
|
+
# => "OMIT RECORD IF (COUNT(payload.pages.page_name) <= 80)"
|
106
|
+
```
|
107
|
+
|
108
|
+
### GROUP BY clause
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
BB.group(:age, :gender).to_sql
|
112
|
+
# => "GROUP BY age, gender"
|
113
|
+
|
114
|
+
BB.group("ROLLUP(year, is_male)").to_sql
|
115
|
+
# => "GROUP BY ROLLUP(year, is_male)"
|
116
|
+
|
117
|
+
BB.group_each(:age, :gender).to_sql
|
118
|
+
# => "GROUP EACH BY age, gender"
|
119
|
+
```
|
120
|
+
|
121
|
+
### HAVING clause
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
BB.having(first_cont: "a", ngram_count_lt: 10000).to_sql
|
125
|
+
# => "HAVING (first CONTAINS 'a' AND ngram_count < 10000)"
|
126
|
+
|
127
|
+
BB.having("first CONTAINS ? AND negram_count < ?", "a", 10000).to_sql
|
128
|
+
# => "HAVING (first CONTAINS 'a' AND ngram_count < 10000)"
|
129
|
+
|
130
|
+
BB.having("first CONTAINS :first AND negram_count < :negram_count", first: "a", negram_count: 10000).to_sql
|
131
|
+
# => "HAVING (first CONTAINS 'a' AND ngram_count < 10000)"
|
132
|
+
|
133
|
+
BB.having(first: "a").or.not.having(first: "b").to_sql
|
134
|
+
=> "HAVING (first = 'a') OR (first <> 'b')"
|
135
|
+
```
|
136
|
+
|
137
|
+
### ORDER BY clause
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
BB.order(:age, :gender).to_sql
|
141
|
+
# => "ORDER BY age, gender"
|
142
|
+
|
143
|
+
BB.order(age: :desc, gender: :asc).to_sql
|
144
|
+
# => "ORDER BY age DESC, gender ASC"
|
145
|
+
```
|
146
|
+
|
147
|
+
### LIMIT clause
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
BB.limit(1000).to_sql
|
151
|
+
# => "LIMIT 1000"
|
152
|
+
|
153
|
+
BB.limit(1000).offset(500).to_sql
|
154
|
+
# => "LIMIT 1000 OFFSET 500"
|
155
|
+
```
|
156
|
+
|
157
|
+
## Support
|
158
|
+
|
159
|
+
### JOINS
|
160
|
+
|
161
|
+
Support methods:
|
162
|
+
|
163
|
+
- cross_join
|
164
|
+
- full_outer_join_each
|
165
|
+
- inner_join
|
166
|
+
- inner_join_each
|
167
|
+
- join
|
168
|
+
- join_each
|
169
|
+
- left_join
|
170
|
+
- left_join_each
|
171
|
+
- left_outer_join
|
172
|
+
- left_outer_join_each
|
173
|
+
- right_join
|
174
|
+
- right_join_each
|
175
|
+
- right_outer_join
|
176
|
+
- right_outer_join_each
|
177
|
+
|
178
|
+
### Suffix of hash keys
|
179
|
+
|
180
|
+
For `omit_record_if`, `where`, `having`:
|
181
|
+
|
182
|
+
| suffix | means | alias | opposite | example |
|
183
|
+
|:------:|:------|:------|:---------|:--------|
|
184
|
+
| cont | contains | `contains`, `like` | `not_cont`, `not_contains`, `not_like` | `BB.where(name_cont: "banana")` |
|
185
|
+
| eq | equals | `eql`, `equals` | `not_eq`, `not_eql`, `not_equals` | `BB.where(id_not_eq: 123)` |
|
186
|
+
| gt | greater than | *undefined* | `not_gt` | `BB.where(id_not_gt: 123)` |
|
187
|
+
| gteq | greater than or equals to | *undefined* | `not_gteq` | `BB.where(id_not_gteq: 123)` |
|
188
|
+
| lt | less than | *undefined* | `not_lt` | `BB.where(id_not_lt: 123)` |
|
189
|
+
| lteq | less than or equals to | *undefined* | `not_lteq` | `BB.where(id_not_lteq: 123)` |
|
190
|
+
|
191
|
+
## Contributing
|
192
|
+
|
193
|
+
Here's a quick guide:
|
194
|
+
|
195
|
+
1. Fork the repo.
|
196
|
+
2. Create a thoughtfully-named branch for your changes (`git checkout -b my-new-feature`).
|
197
|
+
3. Install the development dependencies by running `bundle install`.
|
198
|
+
4. Begin by running the tests.
|
199
|
+
|
200
|
+
$ bundle exec rspec
|
201
|
+
|
202
|
+
5. Implement something.
|
203
|
+
6. Add tests for your changes.
|
204
|
+
7. Make the tests pass.
|
205
|
+
8. Commit your changes (`git commit -am 'Add feature/Fix bug/improve something'`)
|
206
|
+
9. Push the branch up to your fork on GitHub
|
207
|
+
(`git push origin my-new-feature`) and from GitHub submit a pull request to
|
208
|
+
b_b's `master` branch.
|
209
|
+
|
210
|
+
## License
|
211
|
+
|
212
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/b_b.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "b_b/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "b_b"
|
7
|
+
spec.version = BB::VERSION
|
8
|
+
spec.authors = ["Yoshiyuki Hirano"]
|
9
|
+
spec.email = ["yhirano@me.com"]
|
10
|
+
|
11
|
+
spec.required_ruby_version = ">= 2.0.0"
|
12
|
+
|
13
|
+
spec.summary = "SQL Query Builder in Ruby for Google BigQuery"
|
14
|
+
spec.description = "SQL Query Builder in Ruby for Google BigQuery"
|
15
|
+
spec.homepage = "https://github.com/yhirano55/BB"
|
16
|
+
spec.license = "MIT"
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
26
|
+
spec.add_development_dependency "activesupport", "~> 4.2.0"
|
27
|
+
spec.add_development_dependency "factory_girl", "~> 4.0"
|
28
|
+
spec.add_development_dependency "faker", "~> 1.6.0"
|
29
|
+
spec.add_development_dependency "pry", "~> 0.10.0"
|
30
|
+
spec.add_development_dependency "rubocop", "~> 0.40.0"
|
31
|
+
spec.add_development_dependency "simplecov", "~> 0.11.0"
|
32
|
+
spec.add_development_dependency "coveralls", "~> 0.8.0"
|
33
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "b_b"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|