nql 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,109 +1,109 @@
1
- module NQL
2
- grammar Syntax
3
-
4
- rule expression
5
- boolean / primary
6
- end
7
-
8
- rule boolean
9
- left:primary space coordinator:coordinator space right:expression {
10
- def to_ransack
11
- group = {g: [{m: coordinator.to_ransack}]}
12
-
13
- [left, right].each do |side|
14
- if side.is_node?(:boolean)
15
- group[:g][0].merge! side.to_ransack
16
- else
17
- group[:g][0][:c] ||= []
18
- group[:g][0][:c] << side.to_ransack
19
- end
20
- end
21
-
22
- group
23
- end
24
-
25
- def is_node?(node_type)
26
- node_type.to_sym == :boolean
27
- end
28
- }
29
- end
30
-
31
- rule primary
32
- (space comparison space / '(' space expression space ')') {
33
- def to_ransack
34
- detect_node.to_ransack
35
- end
36
-
37
- def detect_node
38
- self.send %w(comparison expression).detect { |m| self.respond_to? m }
39
- end
40
-
41
- def is_node?(node_type)
42
- detect_node.is_node?(node_type)
43
- end
44
- }
45
- end
46
-
47
- rule coordinator
48
- ('|' / '&') {
49
- def to_ransack
50
- coordinators = {'|' => 'or', '&' => 'and'}
51
- coordinators[text_value]
52
- end
53
- }
54
- end
55
-
56
- rule comparison
57
- variable:alphanumeric space comparator:comparator space value:text {
58
- def to_ransack
59
- hash = {a: {'0' => {name: self.variable.text_value.gsub('.', '_')}}, p: self.comparator.to_ransack, v: {'0' => {value: self.value.text_value}}}
60
- hash = {c: [hash]} if !parent || !parent.parent || text_value == parent.parent.text_value
61
- hash
62
- end
63
-
64
- def is_node?(node_type)
65
- node_type.to_sym == :comparison
66
- end
67
- }
68
- end
69
-
70
- rule comparator
71
- ('=' / '!=' / '>' / '>=' / '<' / '<=' / ':')+ {
72
- def to_ransack
73
- comparators = {
74
- '=' => 'eq',
75
- '!=' => 'not_eq',
76
- '>' => 'gt',
77
- '>=' => 'gteq',
78
- '<' => 'lt',
79
- '<=' => 'lteq',
80
- ':' => 'cont'
81
- }
82
- comparators[text_value]
83
- end
84
- }
85
- end
86
-
87
- rule text
88
- (alphanumeric / utf8 / symbol)+
89
- (space (alphanumeric / utf8 / symbol)+)*
90
- end
91
-
92
- rule alphanumeric
93
- [a-zA-Z0-9_.]+
94
- end
95
-
96
- rule space
97
- ' '*
98
- end
99
-
100
- rule symbol
101
- [><=+-\/\\@#$%!?:]
102
- end
103
-
104
- rule utf8
105
- [\u00c1\u00c0\u00c9\u00c8\u00cd\u00cc\u00d3\u00d2\u00da\u00d9\u00dc\u00d1\u00c7\u00e1\u00e0\u00e9\u00e8\u00ed\u00ec\u00f3\u00f2\u00fa\u00f9\u00fc\u00f1\u00e7]
106
- end
107
-
108
- end
1
+ module NQL
2
+ grammar Syntax
3
+
4
+ rule expression
5
+ boolean / primary
6
+ end
7
+
8
+ rule boolean
9
+ left:primary space coordinator:coordinator space right:expression {
10
+ def to_ransack
11
+ group = {g: [{m: coordinator.to_ransack}]}
12
+
13
+ [left, right].each do |side|
14
+ if side.is_node?(:boolean)
15
+ group[:g][0].merge! side.to_ransack
16
+ else
17
+ group[:g][0][:c] ||= []
18
+ group[:g][0][:c] << side.to_ransack
19
+ end
20
+ end
21
+
22
+ group
23
+ end
24
+
25
+ def is_node?(node_type)
26
+ node_type.to_sym == :boolean
27
+ end
28
+ }
29
+ end
30
+
31
+ rule primary
32
+ (space comparison space / '(' space expression space ')') {
33
+ def to_ransack
34
+ detect_node.to_ransack
35
+ end
36
+
37
+ def detect_node
38
+ self.send %w(comparison expression).detect { |m| self.respond_to? m }
39
+ end
40
+
41
+ def is_node?(node_type)
42
+ detect_node.is_node?(node_type)
43
+ end
44
+ }
45
+ end
46
+
47
+ rule coordinator
48
+ ('|' / '&') {
49
+ def to_ransack
50
+ coordinators = {'|' => 'or', '&' => 'and'}
51
+ coordinators[text_value]
52
+ end
53
+ }
54
+ end
55
+
56
+ rule comparison
57
+ variable:alphanumeric space comparator:comparator space value:text {
58
+ def to_ransack
59
+ hash = {a: {'0' => {name: self.variable.text_value.gsub('.', '_')}}, p: self.comparator.to_ransack, v: {'0' => {value: self.value.text_value}}}
60
+ hash = {c: [hash]} if !parent || !parent.parent || text_value == parent.parent.text_value
61
+ hash
62
+ end
63
+
64
+ def is_node?(node_type)
65
+ node_type.to_sym == :comparison
66
+ end
67
+ }
68
+ end
69
+
70
+ rule comparator
71
+ ('=' / '!=' / '>' / '>=' / '<' / '<=' / ':')+ {
72
+ def to_ransack
73
+ comparators = {
74
+ '=' => 'eq',
75
+ '!=' => 'not_eq',
76
+ '>' => 'gt',
77
+ '>=' => 'gteq',
78
+ '<' => 'lt',
79
+ '<=' => 'lteq',
80
+ ':' => 'cont'
81
+ }
82
+ comparators[text_value]
83
+ end
84
+ }
85
+ end
86
+
87
+ rule text
88
+ (alphanumeric / utf8 / symbol)+
89
+ (space (alphanumeric / utf8 / symbol)+)*
90
+ end
91
+
92
+ rule alphanumeric
93
+ [a-zA-Z0-9_.]+
94
+ end
95
+
96
+ rule space
97
+ ' '*
98
+ end
99
+
100
+ rule symbol
101
+ [><=+-\/\\@#$%!?:]
102
+ end
103
+
104
+ rule utf8
105
+ [\u00c0\u00c1\u00c2\u00c3\u00c4\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d9\u00da\u00db\u00dc\u00e0\u00e1\u00e2\u00e3\u00e4\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f9\u00fa\u00fb\u00fc]
106
+ end
107
+
108
+ end
109
109
  end
@@ -1,7 +1,7 @@
1
- module NQL
2
- class InvalidExpressionError < StandardError
3
- def initialize(message)
4
- super
5
- end
6
- end
1
+ module NQL
2
+ class InvalidExpressionError < StandardError
3
+ def initialize(message)
4
+ super
5
+ end
6
+ end
7
7
  end
@@ -1,3 +1,3 @@
1
- module NQL
2
- VERSION = '0.0.3'
3
- end
1
+ module NQL
2
+ VERSION = '0.0.4'
3
+ end
@@ -1,25 +1,25 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/nql/version', __FILE__)
3
-
4
- Gem::Specification.new do |s|
5
- s.name = 'nql'
6
- s.version = NQL::VERSION
7
- s.authors = ['Gabriel Naiman']
8
- s.email = ['gabynaiman@gmail.com']
9
- s.description = 'Natural Query Language built on top of ActiveRecord and Ransack'
10
- s.summary = 'Natural Query Language built on top of ActiveRecord and Ransack'
11
- s.homepage = 'https://github.com/gabynaiman/nql'
12
-
13
- s.files = `git ls-files`.split($\)
14
- s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
- s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
- s.require_paths = ["lib"]
17
-
18
- s.add_dependency 'treetop'
19
- s.add_dependency 'activerecord', '>= 3.2.0'
20
- s.add_dependency 'activesupport', '>= 3.2.0'
21
- s.add_dependency 'ransack'
22
-
23
- s.add_development_dependency 'sqlite3'
24
- s.add_development_dependency 'rspec'
25
- end
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/nql/version', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'nql'
6
+ s.version = NQL::VERSION
7
+ s.authors = ['Gabriel Naiman']
8
+ s.email = ['gabynaiman@gmail.com']
9
+ s.description = 'Natural Query Language built on top of ActiveRecord and Ransack'
10
+ s.summary = 'Natural Query Language built on top of ActiveRecord and Ransack'
11
+ s.homepage = 'https://github.com/gabynaiman/nql'
12
+
13
+ s.files = `git ls-files`.split($\)
14
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
+ s.require_paths = ["lib"]
17
+
18
+ s.add_dependency 'treetop'
19
+ s.add_dependency 'activerecord', '>= 3.2.0'
20
+ s.add_dependency 'activesupport', '>= 3.2.0'
21
+ s.add_dependency 'ransack'
22
+
23
+ s.add_development_dependency 'sqlite3'
24
+ s.add_development_dependency 'rspec'
25
+ end
@@ -1,147 +1,147 @@
1
- require 'spec_helper'
2
-
3
- describe NQL::SyntaxParser, '-> Comparison' do
4
-
5
- let(:parser) { NQL::SyntaxParser.new }
6
-
7
- context 'Structure and comparators' do
8
-
9
- it 'Equals' do
10
- tree = parser.parse('var = value')
11
-
12
- tree.comparison.variable.text_value.should eq 'var'
13
- tree.comparison.comparator.text_value.should eq '='
14
- tree.comparison.value.text_value.should eq 'value'
15
- end
16
-
17
- it 'Not equals' do
18
- tree = parser.parse('var != value')
19
-
20
- tree.comparison.variable.text_value.should eq 'var'
21
- tree.comparison.comparator.text_value.should eq '!='
22
- tree.comparison.value.text_value.should eq 'value'
23
- end
24
-
25
- it 'Greater than' do
26
- tree = parser.parse('var > value')
27
-
28
- tree.comparison.variable.text_value.should eq 'var'
29
- tree.comparison.comparator.text_value.should eq '>'
30
- tree.comparison.value.text_value.should eq 'value'
31
- end
32
-
33
- it 'Greater or equals than' do
34
- tree = parser.parse('var >= value')
35
-
36
- tree.comparison.variable.text_value.should eq 'var'
37
- tree.comparison.comparator.text_value.should eq '>='
38
- tree.comparison.value.text_value.should eq 'value'
39
- end
40
-
41
- it 'Less than' do
42
- tree = parser.parse('var < value')
43
-
44
- tree.comparison.variable.text_value.should eq 'var'
45
- tree.comparison.comparator.text_value.should eq '<'
46
- tree.comparison.value.text_value.should eq 'value'
47
- end
48
-
49
- it 'Less or equals than' do
50
- tree = parser.parse('var <= value')
51
-
52
- tree.comparison.variable.text_value.should eq 'var'
53
- tree.comparison.comparator.text_value.should eq '<='
54
- tree.comparison.value.text_value.should eq 'value'
55
- end
56
-
57
- it 'Contains' do
58
- tree = parser.parse('var : value')
59
-
60
- tree.comparison.variable.text_value.should eq 'var'
61
- tree.comparison.comparator.text_value.should eq ':'
62
- tree.comparison.value.text_value.should eq 'value'
63
- end
64
-
65
- end
66
-
67
- context 'Space separators' do
68
-
69
- it 'Without spaces' do
70
- tree = parser.parse('var=value')
71
-
72
- tree.comparison.variable.text_value.should eq 'var'
73
- tree.comparison.comparator.text_value.should eq '='
74
- tree.comparison.value.text_value.should eq 'value'
75
- end
76
-
77
- it 'With many spaces' do
78
- tree = parser.parse('var = value')
79
-
80
- tree.comparison.variable.text_value.should eq 'var'
81
- tree.comparison.comparator.text_value.should eq '='
82
- tree.comparison.value.text_value.should eq 'value'
83
- end
84
-
85
- end
86
-
87
- context 'Variable names' do
88
-
89
- it 'With numbers' do
90
- tree = parser.parse('var1 = value')
91
- tree.comparison.variable.text_value.should eq 'var1'
92
- end
93
-
94
- it 'With uppercase' do
95
- tree = parser.parse('varName = value')
96
- tree.comparison.variable.text_value.should eq 'varName'
97
- end
98
-
99
- it 'With underscore' do
100
- tree = parser.parse('var_name = value')
101
- tree.comparison.variable.text_value.should eq 'var_name'
102
- end
103
-
104
- it 'With dot' do
105
- tree = parser.parse('var.name = value')
106
- tree.comparison.variable.text_value.should eq 'var.name'
107
- end
108
-
109
- end
110
-
111
- context 'Values' do
112
-
113
- it 'With numbers' do
114
- tree = parser.parse('var = value1')
115
- tree.comparison.value.text_value.should eq 'value1'
116
- end
117
-
118
- it 'With uppercase' do
119
- tree = parser.parse('var = valueDummy')
120
- tree.comparison.value.text_value.should eq 'valueDummy'
121
- end
122
-
123
- it 'With dot' do
124
- tree = parser.parse('var = value.dummy')
125
- tree.comparison.value.text_value.should eq 'value.dummy'
126
- end
127
-
128
-
129
- it 'With utf8 chars and symbols' do
130
- utf8_symbols = "\u00c1\u00c0\u00c9\u00c8\u00cd\u00cc\u00d3\u00d2\u00da\u00d9\u00dc\u00d1\u00c7\u00e1\u00e0\u00e9\u00e8\u00ed\u00ec\u00f3\u00f2\u00fa\u00f9\u00fc\u00f1\u00e7"
131
- tree = parser.parse("var = .#+-#{utf8_symbols}")
132
- tree.comparison.value.text_value.should eq ".#+-#{utf8_symbols}"
133
- end
134
-
135
- it 'With spaces' do
136
- tree = parser.parse('var = value 123')
137
- tree.comparison.value.text_value.should eq 'value 123'
138
- end
139
-
140
- it 'With comparators, symbols and spaces' do
141
- tree = parser.parse('var = value1 > value2 ! value3')
142
- tree.comparison.value.text_value.should eq 'value1 > value2 ! value3'
143
- end
144
-
145
- end
146
-
147
- end
1
+ require 'spec_helper'
2
+
3
+ describe NQL::SyntaxParser, '-> Comparison' do
4
+
5
+ let(:parser) { NQL::SyntaxParser.new }
6
+
7
+ context 'Structure and comparators' do
8
+
9
+ it 'Equals' do
10
+ tree = parser.parse('var = value')
11
+
12
+ tree.comparison.variable.text_value.should eq 'var'
13
+ tree.comparison.comparator.text_value.should eq '='
14
+ tree.comparison.value.text_value.should eq 'value'
15
+ end
16
+
17
+ it 'Not equals' do
18
+ tree = parser.parse('var != value')
19
+
20
+ tree.comparison.variable.text_value.should eq 'var'
21
+ tree.comparison.comparator.text_value.should eq '!='
22
+ tree.comparison.value.text_value.should eq 'value'
23
+ end
24
+
25
+ it 'Greater than' do
26
+ tree = parser.parse('var > value')
27
+
28
+ tree.comparison.variable.text_value.should eq 'var'
29
+ tree.comparison.comparator.text_value.should eq '>'
30
+ tree.comparison.value.text_value.should eq 'value'
31
+ end
32
+
33
+ it 'Greater or equals than' do
34
+ tree = parser.parse('var >= value')
35
+
36
+ tree.comparison.variable.text_value.should eq 'var'
37
+ tree.comparison.comparator.text_value.should eq '>='
38
+ tree.comparison.value.text_value.should eq 'value'
39
+ end
40
+
41
+ it 'Less than' do
42
+ tree = parser.parse('var < value')
43
+
44
+ tree.comparison.variable.text_value.should eq 'var'
45
+ tree.comparison.comparator.text_value.should eq '<'
46
+ tree.comparison.value.text_value.should eq 'value'
47
+ end
48
+
49
+ it 'Less or equals than' do
50
+ tree = parser.parse('var <= value')
51
+
52
+ tree.comparison.variable.text_value.should eq 'var'
53
+ tree.comparison.comparator.text_value.should eq '<='
54
+ tree.comparison.value.text_value.should eq 'value'
55
+ end
56
+
57
+ it 'Contains' do
58
+ tree = parser.parse('var : value')
59
+
60
+ tree.comparison.variable.text_value.should eq 'var'
61
+ tree.comparison.comparator.text_value.should eq ':'
62
+ tree.comparison.value.text_value.should eq 'value'
63
+ end
64
+
65
+ end
66
+
67
+ context 'Space separators' do
68
+
69
+ it 'Without spaces' do
70
+ tree = parser.parse('var=value')
71
+
72
+ tree.comparison.variable.text_value.should eq 'var'
73
+ tree.comparison.comparator.text_value.should eq '='
74
+ tree.comparison.value.text_value.should eq 'value'
75
+ end
76
+
77
+ it 'With many spaces' do
78
+ tree = parser.parse('var = value')
79
+
80
+ tree.comparison.variable.text_value.should eq 'var'
81
+ tree.comparison.comparator.text_value.should eq '='
82
+ tree.comparison.value.text_value.should eq 'value'
83
+ end
84
+
85
+ end
86
+
87
+ context 'Variable names' do
88
+
89
+ it 'With numbers' do
90
+ tree = parser.parse('var1 = value')
91
+ tree.comparison.variable.text_value.should eq 'var1'
92
+ end
93
+
94
+ it 'With uppercase' do
95
+ tree = parser.parse('varName = value')
96
+ tree.comparison.variable.text_value.should eq 'varName'
97
+ end
98
+
99
+ it 'With underscore' do
100
+ tree = parser.parse('var_name = value')
101
+ tree.comparison.variable.text_value.should eq 'var_name'
102
+ end
103
+
104
+ it 'With dot' do
105
+ tree = parser.parse('var.name = value')
106
+ tree.comparison.variable.text_value.should eq 'var.name'
107
+ end
108
+
109
+ end
110
+
111
+ context 'Values' do
112
+
113
+ it 'With numbers' do
114
+ tree = parser.parse('var = value1')
115
+ tree.comparison.value.text_value.should eq 'value1'
116
+ end
117
+
118
+ it 'With uppercase' do
119
+ tree = parser.parse('var = valueDummy')
120
+ tree.comparison.value.text_value.should eq 'valueDummy'
121
+ end
122
+
123
+ it 'With dot' do
124
+ tree = parser.parse('var = value.dummy')
125
+ tree.comparison.value.text_value.should eq 'value.dummy'
126
+ end
127
+
128
+
129
+ it 'With utf8 chars and symbols' do
130
+ utf8_symbols = "\u00c0\u00c1\u00c2\u00c3\u00c4\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d9\u00da\u00db\u00dc\u00e0\u00e1\u00e2\u00e3\u00e4\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f9\u00fa\u00fb\u00fc"
131
+ tree = parser.parse("var = .#+-#{utf8_symbols}")
132
+ tree.comparison.value.text_value.should eq ".#+-#{utf8_symbols}"
133
+ end
134
+
135
+ it 'With spaces' do
136
+ tree = parser.parse('var = value 123')
137
+ tree.comparison.value.text_value.should eq 'value 123'
138
+ end
139
+
140
+ it 'With comparators, symbols and spaces' do
141
+ tree = parser.parse('var = value1 > value2 ! value3')
142
+ tree.comparison.value.text_value.should eq 'value1 > value2 ! value3'
143
+ end
144
+
145
+ end
146
+
147
+ end