json-arel 0.2

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/json_arel.rb +95 -0
  3. metadata +44 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9076d0b1c225fb523e2ebfa93ee57d12f982a16c
4
+ data.tar.gz: a656c6a47d815c91af6bb7e2d0476c6e47d0f69e
5
+ SHA512:
6
+ metadata.gz: d067b42c8b7959de4e2afdf28d97844e3d8b18cc479fac98157d1f54148a6c66469210bb54c1d14caaabd9fc743123811f40a82459cac90fff2f00345790a1bc
7
+ data.tar.gz: 3725926ae20e2b0da6416845f1a55067fd0d859945bb5c69ff40cff49340cea7a62da5d7577084afc3017570aab501582f0d46120138999b90b8e10a72d0c2d4
data/lib/json_arel.rb ADDED
@@ -0,0 +1,95 @@
1
+ require 'arel'
2
+
3
+ require 'active_record'
4
+
5
+ ActiveRecord::Base.establish_connection(
6
+ :adapter => 'postgresql',
7
+ :database => 'explorer_development'
8
+ )
9
+
10
+ module JSONArel
11
+ class Resolver
12
+
13
+ VALID_OPERATORS = %w[$eq $not_eq $gt $gteq $lt $lteq $in]
14
+
15
+ def initialize(tree)
16
+ @tree = tree
17
+ end
18
+
19
+ def resolve
20
+ resolve_node(@tree).to_sql
21
+ end
22
+
23
+ def resolve_node(node)
24
+
25
+ # (with) SELECT (fields) FROM (from) (join) WHERE (CONDITIONS) (GROUPBY) (LIMIT)
26
+ table = Arel::Table.new(node['from'])
27
+
28
+ # Does it contain a CTE?
29
+ ctes = (node['with'] || []).map do |cte|
30
+ Arel::Nodes::As.new(Arel::Table.new(cte['as'].to_sym), resolve_node(cte['select']))
31
+ end
32
+
33
+ # Resolve the SELECT fields
34
+ if node['fields'].class == String
35
+ # Is it a single string we're selecting?
36
+ node['fields'] = Arel.sql(node['fields'])
37
+ elsif node['fields'].class == Array
38
+ node['fields'] = node['fields'].map {|x| Arel.sql(x) }
39
+ elsif node['fields'].class == Hash
40
+ # Is it a hash?
41
+ node['fields'] = node['fields'].map do |k,v|
42
+ Arel.sql(k).as(v)
43
+ end
44
+ end
45
+
46
+ # Resolve WHERE
47
+ node['where'] = (node['where'] || {}).map do |key, val|
48
+ field, comparator, value = parse_where(key, val)
49
+ table[field.to_sym].send(comparator, val)
50
+ end
51
+
52
+ # Evaluate.
53
+ table = table.where(node['where']) if node['where'].length > 0
54
+ expr = table.project(node['fields'])
55
+
56
+ # TODO: support JOIN
57
+
58
+ # Resolve GROUP BY
59
+ node['group'] ||= []
60
+ if node['group'].class == String
61
+ node['group'] = [node['group']]
62
+ end
63
+ node['group'] = node['group'].map {|x| Arel.sql(x) }
64
+ expr = expr.group(node['group']) if node['group'].length > 0
65
+
66
+ # Evaluate CTEs
67
+ expr = expr.with(ctes) if ctes.length > 0
68
+
69
+ # Resolve LIMIT / OFFSET
70
+ expr.take(node['limit']) if node['limit']
71
+ expr.skip(node['offset']) if node['offset']
72
+
73
+ expr
74
+ end
75
+
76
+ def parse_where(field, val)
77
+ # TODO: Support OR
78
+ # Return func, params.
79
+ operator_index = field.index('$')
80
+ if operator_index
81
+ field, comparator = field[0..operator_index-1], field[operator_index..field.length]
82
+ if !VALID_OPERATORS.include? comparator
83
+ raise ResolverError, "#{comparator} is an invalid filter expression."
84
+ end
85
+ else
86
+ comparator = '$eq'
87
+ end
88
+ return field, comparator[1..-1], val
89
+ end
90
+
91
+ end
92
+
93
+ class ResolverError < StandardError
94
+ end
95
+ end
metadata ADDED
@@ -0,0 +1,44 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: json-arel
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.2'
5
+ platform: ruby
6
+ authors:
7
+ - Omar Bohsali
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-23 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email: omar.bohsali@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/json_arel.rb
20
+ homepage:
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubyforge_project:
40
+ rubygems_version: 2.2.2
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: Convert JSON into SQL queries.
44
+ test_files: []