sqlpp 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1107aeb0686b607cae85119da28fb50ce493d9d2
4
- data.tar.gz: 590fdc355e514201a0b8d7e0cb3aee3e1a42afc6
3
+ metadata.gz: e96af138b105ce5c23190556cfe34c20e7d275da
4
+ data.tar.gz: 33dc95f6c3d0222cd82b3c2c373c5462c698506f
5
5
  SHA512:
6
- metadata.gz: 6b9e6569b08495e7157a1e0293b92fa589c9edc5905c77a45a9a4081f1d3d2270239091a6a4cb1f269da78592c4e7ba86dc066933435c894a8a67083c1ff777e
7
- data.tar.gz: aa73a36f3a87f2102019345a1c1ecb99cdbefc011fbd7aa0684474f057c123e9026e546abb38706b1a4a6644e414c1779f446187b1f4fd34ada010006c9f28c4
6
+ metadata.gz: 8ead60811f2f761ae6da39c124a50dcc3d2cef1eeca80c38a3213fc5d44537ee97276d538996c609b703dd954ceb1bff366bf060e51159505341d51dcbfac707
7
+ data.tar.gz: c1eb147f0e416a3f04911f208c23e825cf83530b3d83f392a5dac9382e7cba3d2a868c42c77021a2908ff57f04327152f97861c3de72b482842a6ba507dff3c5
data/lib/sqlpp/ast.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module SQLPP
2
2
  module AST
3
- class Select < Struct.new(:projections, :froms, :wheres, :groups, :orders)
3
+ class Select < Struct.new(:projections, :froms, :wheres, :groups, :orders, :distinct, :limit, :offset)
4
4
  end
5
5
 
6
6
  class Expr < Struct.new(:left, :op, :right)
@@ -26,5 +26,11 @@ module SQLPP
26
26
 
27
27
  class SortKey < Struct.new(:key, :options)
28
28
  end
29
+
30
+ class Limit < Struct.new(:expr)
31
+ end
32
+
33
+ class Offset < Struct.new(:expr)
34
+ end
29
35
  end
30
36
  end
@@ -23,6 +23,7 @@ module SQLPP
23
23
  end
24
24
 
25
25
  output << (select = "#{_indent}SELECT ")
26
+ output << "DISTINCT " if node.distinct
26
27
  link = ","
27
28
  link << ((@projections == :wrap) ? "\n#{" " * select.length}" : " ")
28
29
  output << node.projections.map { |c| format(c) }.join(link)
@@ -54,6 +55,19 @@ module SQLPP
54
55
  output << "\n"
55
56
  end
56
57
 
58
+ if node.limit || node.offset
59
+ output << _indent
60
+
61
+ if node.limit
62
+ output << format(node.limit)
63
+ output << " " if node.offset
64
+ end
65
+
66
+ output << format(node.offset) if node.offset
67
+
68
+ output << "\n"
69
+ end
70
+
57
71
  @indent -= 2
58
72
  @indent = nil if @indent < 0
59
73
 
@@ -156,6 +170,14 @@ module SQLPP
156
170
  output
157
171
  end
158
172
 
173
+ def _format_Limit(node)
174
+ "LIMIT #{format(node.expr)}"
175
+ end
176
+
177
+ def _format_Offset(node)
178
+ "OFFSET #{format(node.expr)}"
179
+ end
180
+
159
181
  def _format_String(string)
160
182
  string
161
183
  end
data/lib/sqlpp/parser.rb CHANGED
@@ -1,11 +1,16 @@
1
1
  require 'sqlpp/ast'
2
2
 
3
- # select := 'SELECT'
3
+ # select := 'SELECT' optional_distinct
4
4
  # optional_projections
5
5
  # optional_froms
6
6
  # optional_wheres
7
7
  # optional_groups
8
8
  # optional_orders
9
+ # optional_limit
10
+ # optional_offset
11
+ #
12
+ # optional_distinct := ''
13
+ # | 'DISTINCT'
9
14
  #
10
15
  # optional_projections := ''
11
16
  # | list
@@ -22,6 +27,12 @@ require 'sqlpp/ast'
22
27
  # optional_orders := ''
23
28
  # | 'ORDER' 'BY' sort_keys
24
29
  #
30
+ # optional_limit := ''
31
+ # | 'LIMIT' expr4
32
+ #
33
+ # optional_offset := ''
34
+ # | 'OFFSET' expr4
35
+ #
25
36
  # sort_keys := sort_key
26
37
  # | sort_key ',' sort_keys
27
38
  #
@@ -67,7 +78,7 @@ require 'sqlpp/ast'
67
78
  #
68
79
  # op2 := '+' | '-' | '*' | '/'
69
80
  #
70
- # unary := '+' | '-' | 'NOT'
81
+ # unary := '+' | '-' | 'NOT' | 'DISTINCT'
71
82
  #
72
83
  # expr4 := lit
73
84
  # | id
@@ -133,6 +144,10 @@ module SQLPP
133
144
  select = AST::Select.new
134
145
 
135
146
  _eat :space
147
+ if _eat(:key, :distinct)
148
+ select.distinct = true
149
+ _eat :space
150
+ end
136
151
 
137
152
  if !_peek(:key, /^(from|where)$/) && !_peek(:eof)
138
153
  list = []
@@ -212,6 +227,22 @@ module SQLPP
212
227
  select.orders = list
213
228
  end
214
229
 
230
+ if _eat(:key, :limit)
231
+ _eat :space
232
+ atom = _parse_atom
233
+ _eat :space
234
+
235
+ select.limit = AST::Limit.new(atom)
236
+ end
237
+
238
+ if _eat(:key, :offset)
239
+ _eat :space
240
+ atom = _parse_atom
241
+ _eat :space
242
+
243
+ select.offset = AST::Offset.new(atom)
244
+ end
245
+
215
246
  select
216
247
  end
217
248
 
@@ -346,7 +377,7 @@ module SQLPP
346
377
  def _parse_expr3
347
378
  _eat :space
348
379
 
349
- if (op = (_eat(:punct, /[-+]/) || _eat(:key, :not)))
380
+ if (op = (_eat(:punct, /[-+]/) || _eat(:key, /^(not|distinct)$/)))
350
381
  _eat :space
351
382
  AST::Unary.new(op.text, _parse_expr3)
352
383
 
@@ -18,6 +18,7 @@ module SQLPP
18
18
  case
19
19
  cross
20
20
  desc
21
+ distinct
21
22
  else
22
23
  end
23
24
  first
@@ -33,9 +34,11 @@ module SQLPP
33
34
  last
34
35
  left
35
36
  like
37
+ limit
36
38
  not
37
39
  null
38
40
  nulls
41
+ offset
39
42
  on
40
43
  or
41
44
  order
data/lib/sqlpp/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module SQLPP
2
2
  module Version
3
3
  MAJOR = 1
4
- MINOR = 1
5
- TINY = 1
4
+ MINOR = 2
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join(".")
8
8
  end
@@ -42,6 +42,49 @@ FROM foo
42
42
  SQL
43
43
  end
44
44
 
45
+ def test_format_select_distinct
46
+ ast = _parser("select distinct a, b, c, d from foo").parse
47
+ assert_equal <<-SQL, _format(ast)
48
+ SELECT DISTINCT a, b, c, d
49
+ FROM foo
50
+ SQL
51
+ end
52
+
53
+ def test_format_count_distinct
54
+ ast = _parser("select count(distinct id) from foo").parse
55
+ assert_equal <<-SQL, _format(ast)
56
+ SELECT count(DISTINCT id)
57
+ FROM foo
58
+ SQL
59
+ end
60
+
61
+ def test_format_limit
62
+ ast = _parser("select * from foo limit 5").parse
63
+ assert_equal <<-SQL, _format(ast)
64
+ SELECT *
65
+ FROM foo
66
+ LIMIT 5
67
+ SQL
68
+ end
69
+
70
+ def test_format_offset
71
+ ast = _parser("select * from foo offset 5").parse
72
+ assert_equal <<-SQL, _format(ast)
73
+ SELECT *
74
+ FROM foo
75
+ OFFSET 5
76
+ SQL
77
+ end
78
+
79
+ def test_format_limit_and_offset
80
+ ast = _parser("select * from foo limit 10 offset 5").parse
81
+ assert_equal <<-SQL, _format(ast)
82
+ SELECT *
83
+ FROM foo
84
+ LIMIT 10 OFFSET 5
85
+ SQL
86
+ end
87
+
45
88
  def _parser(string)
46
89
  SQLPP::Parser.new(string)
47
90
  end
data/test/parser_test.rb CHANGED
@@ -179,6 +179,19 @@ class ParserTest < Minitest::Test
179
179
  end
180
180
  end
181
181
 
182
+ def test_it_should_parse_distinct_expression
183
+ expr = _parser("count(distinct id)").parse_expression
184
+ assert_instance_of SQLPP::AST::Atom, expr
185
+ assert_equal :func, expr.type
186
+ assert_equal 1, expr.right.count
187
+
188
+ assert_instance_of SQLPP::AST::Unary, expr.right[0]
189
+ assert_equal :distinct, expr.right[0].op
190
+ assert_instance_of SQLPP::AST::Atom, expr.right[0].expr
191
+ assert_equal :attr, expr.right[0].expr.type
192
+ assert_equal "id", expr.right[0].expr.left
193
+ end
194
+
182
195
  def test_from_should_recognize_single_attr
183
196
  from = _parser("x").parse_from
184
197
  assert_instance_of SQLPP::AST::Atom, from
@@ -269,11 +282,33 @@ class ParserTest < Minitest::Test
269
282
  assert_equal [:desc, "nulls last"], s.orders[1].options
270
283
  end
271
284
 
285
+ def test_accepts_select_distinct
286
+ s = _parser("select distinct * from x").parse_select
287
+ assert_instance_of SQLPP::AST::Select, s
288
+ assert_equal s.distinct, true
289
+ end
290
+
272
291
  def test_parse_should_recognize_select
273
292
  s = _parser("select * from x").parse
274
293
  assert_instance_of SQLPP::AST::Select, s
275
294
  end
276
295
 
296
+ def test_accepts_select_with_limit
297
+ s = _parser("select * from x limit 5").parse_select
298
+ assert_instance_of SQLPP::AST::Limit, s.limit
299
+ assert_instance_of SQLPP::AST::Atom, s.limit.expr
300
+ assert_equal :lit, s.limit.expr.type
301
+ assert_equal "5", s.limit.expr.left
302
+ end
303
+
304
+ def test_accepts_select_with_offset
305
+ s = _parser("select * from x offset 5").parse_select
306
+ assert_instance_of SQLPP::AST::Offset, s.offset
307
+ assert_instance_of SQLPP::AST::Atom, s.offset.expr
308
+ assert_equal :lit, s.offset.expr.type
309
+ assert_equal "5", s.offset.expr.left
310
+ end
311
+
277
312
  def _parser(string)
278
313
  SQLPP::Parser.new(string)
279
314
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sqlpp
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamis Buck
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-20 00:00:00.000000000 Z
11
+ date: 2016-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake