sqlpp 1.1.1 → 1.2.0

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 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