logical_query_parser 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,62 @@
1
+ grammar LogicalQuery
2
+ rule exp
3
+ any:(cond / exp_paren / literal_seq / literal) <ExpNode>
4
+ end
5
+
6
+ rule exp_paren
7
+ lparen sp* exp sp* rparen <ExpParenNode>
8
+ end
9
+
10
+ rule cond
11
+ lexp:(exp_paren / literal) sp+ logic:(land / lor) sp+ rexp:exp <CondNode>
12
+ end
13
+
14
+ rule literal_seq
15
+ lliteral:literal sp+ rliteral:(literal_seq / literal) <LiteralSeqNode>
16
+ end
17
+
18
+ rule literal
19
+ negative:negative* word <LiteralNode>
20
+ end
21
+
22
+ rule word
23
+ (quoted_word / unquoted_word) <WordNode>
24
+ end
25
+
26
+ rule quoted_word
27
+ '"' ('\"' / !'"' .)* '"'
28
+ end
29
+
30
+ rule unquoted_word
31
+ atom+
32
+ end
33
+
34
+ rule land
35
+ ('AND' / 'and') <AndNode>
36
+ end
37
+
38
+ rule lor
39
+ ('OR' / 'or') <OrNode>
40
+ end
41
+
42
+ rule lparen
43
+ '(' <LParenNode>
44
+ end
45
+
46
+ rule rparen
47
+ ')' <RParenNode>
48
+ end
49
+
50
+ rule negative
51
+ ('-' / '-' / '-') <NegativeNode>
52
+ end
53
+
54
+ rule sp
55
+ ' ' / ' '
56
+ end
57
+
58
+ rule atom
59
+ !(lparen / rparen / negative / sp) .
60
+ end
61
+ end
62
+
@@ -0,0 +1,73 @@
1
+ module LogicalQuery
2
+ module ExpNode
3
+ def to_sql(opts = {}, sql = '')
4
+ any.to_sql(opts, sql)
5
+ end
6
+ end
7
+
8
+ module ExpParenNode
9
+ def to_sql(opts, sql = '')
10
+ lparen.to_sql(opts, sql)
11
+ exp.to_sql(opts, sql)
12
+ rparen.to_sql(opts, sql)
13
+ end
14
+ end
15
+
16
+ module CondNode
17
+ def to_sql(opts, sql = '')
18
+ lexp.to_sql(opts, sql)
19
+ logic.to_sql(opts, sql)
20
+ rexp.to_sql(opts, sql)
21
+ end
22
+ end
23
+
24
+ module LParenNode
25
+ def to_sql(opts, sql = '')
26
+ sql << '('
27
+ end
28
+ end
29
+
30
+ module RParenNode
31
+ def to_sql(opts, sql = '')
32
+ sql << ')'
33
+ end
34
+ end
35
+
36
+ module AndNode
37
+ def to_sql(opts, sql = '')
38
+ sql << ' AND '
39
+ end
40
+ end
41
+
42
+ module OrNode
43
+ def to_sql(opts, sql = '')
44
+ sql << ' OR '
45
+ end
46
+ end
47
+
48
+ module LiteralSeqNode
49
+ def to_sql(opts, sql = '')
50
+ lliteral.to_sql(opts, sql)
51
+ sql << ' AND '
52
+ rliteral.to_sql(opts, sql)
53
+ end
54
+ end
55
+
56
+ module LiteralNode
57
+ def to_sql(opts, sql = '')
58
+ operator, logic = negative.elements.size > 0 ? [:does_not_match, :and] : [:matches, :or]
59
+ unquoted = LogicalQuery.unquote(word.text_value)
60
+
61
+ arel_table = opts[:model].arel_table
62
+ relations = opts[:columns].map { |c| arel_table[c].send(operator, "%#{unquoted}%") }.reduce(logic)
63
+ sql << relations.to_sql
64
+ end
65
+ end
66
+
67
+ class << self
68
+ def unquote(str)
69
+ str = str[1..-2].to_s.gsub(/\\(.)/, '\1') if str[0] == '"' && str[-1] == '"'
70
+ str
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,34 @@
1
+ module LogicalQuery
2
+ module ExpNode
3
+ end
4
+
5
+ module ExpParenNode
6
+ end
7
+
8
+ module CondNode
9
+ end
10
+
11
+ module LiteralSeqNode
12
+ end
13
+
14
+ module LiteralNode
15
+ end
16
+
17
+ module WordNode
18
+ end
19
+
20
+ module AndNode
21
+ end
22
+
23
+ module OrNode
24
+ end
25
+
26
+ module LParenNode
27
+ end
28
+
29
+ module RParenNode
30
+ end
31
+
32
+ module NegativeNode
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module LogicalQuery
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,18 @@
1
+ require 'treetop'
2
+ require 'logical_query'
3
+ require 'logical_query_parser/version'
4
+ require 'logical_query_parser/nodes/base'
5
+ require 'logical_query_parser/nodes/active_record' if defined? ActiveRecord::Base
6
+
7
+ class LogicalQueryParser < Treetop::Runtime::CompiledParser
8
+ class << self
9
+ def walk_tree(node, &block)
10
+ yield node
11
+ unless node.elements.nil?
12
+ node.elements.each do |element|
13
+ walk_tree(element, &block)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'logical_query_parser/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "logical_query_parser"
8
+ spec.version = LogicalQuery::VERSION
9
+ spec.authors = ["Yoshikazu Kaneta"]
10
+ spec.email = ["kaneta@sitebridge.co.jp"]
11
+
12
+ spec.summary = %q{A parser for a logical query string.}
13
+ spec.description = %q{A parser to generate a tree structure from a logical query string using treetop.}
14
+ spec.homepage = "https://github.com/kanety/logical_query_parser"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "treetop", "~> 1.6.8"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.12"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ spec.add_development_dependency "simplecov", "~> 0.12.0"
28
+ spec.add_development_dependency "activerecord", ">= 4.2"
29
+ spec.add_development_dependency "sqlite3"
30
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logical_query_parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Yoshikazu Kaneta
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-10-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: treetop
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.6.8
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.6.8
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.12'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.12.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.12.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: activerecord
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '4.2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '4.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: sqlite3
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: A parser to generate a tree structure from a logical query string using
112
+ treetop.
113
+ email:
114
+ - kaneta@sitebridge.co.jp
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - ".rspec"
121
+ - ".travis.yml"
122
+ - CODE_OF_CONDUCT.md
123
+ - Gemfile
124
+ - LICENSE.txt
125
+ - README.md
126
+ - Rakefile
127
+ - bin/console
128
+ - bin/setup
129
+ - lib/logical_query.rb
130
+ - lib/logical_query.treetop
131
+ - lib/logical_query_parser.rb
132
+ - lib/logical_query_parser/nodes/active_record.rb
133
+ - lib/logical_query_parser/nodes/base.rb
134
+ - lib/logical_query_parser/version.rb
135
+ - logical_query_parser.gemspec
136
+ homepage: https://github.com/kanety/logical_query_parser
137
+ licenses:
138
+ - MIT
139
+ metadata: {}
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ requirements: []
155
+ rubyforge_project:
156
+ rubygems_version: 2.5.1
157
+ signing_key:
158
+ specification_version: 4
159
+ summary: A parser for a logical query string.
160
+ test_files: []