sql_query_executor 0.0.1 → 0.1.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 +4 -4
- data/lib/sql_query_executor/operators/base.rb +44 -18
- data/lib/sql_query_executor/operators/between.rb +3 -3
- data/lib/sql_query_executor/operators/default.rb +1 -1
- data/lib/sql_query_executor/operators/in.rb +3 -3
- data/lib/sql_query_executor/operators/is.rb +1 -1
- data/lib/sql_query_executor/query/base.rb +29 -16
- data/lib/sql_query_executor/query/sentence.rb +70 -0
- data/lib/sql_query_executor/query/sub_query.rb +101 -42
- data/lib/sql_query_executor/{version → version.rb} +1 -1
- data/spec/sql_query_executor/base_spec.rb +43 -5
- data/sql_query_executor.gemspec +4 -4
- metadata +6 -6
- data/lib/sql_query_executor/query/divider.rb +0 -56
- data/lib/sql_query_executor/query/executor.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d35ed6525f34f2fa2b89077179627bb398e60569
|
4
|
+
data.tar.gz: d7f5b1378fe6932180ed501143f8282620b36ee1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17f7149a30b187f41262d8dfe826cf3a100400764aea984b5783cb440f9874b356038574ee5a16e9dd0e7f87d24c40e2085dad37ead3fe0f23db9f23fe8971b5
|
7
|
+
data.tar.gz: 407df8d2c2a114b9979b17f7249bfcf9698a04b317087a59b3199e9cda64bcb2fa58e74657069c76190954bc80b6cba1cc2f97a2e6e8f9e23047629724358ece
|
@@ -2,7 +2,7 @@ module SqlQueryExecutor
|
|
2
2
|
module Operators
|
3
3
|
class Base
|
4
4
|
def initialize(query, collection)
|
5
|
-
@query = query
|
5
|
+
@query = sanitize_query(query)
|
6
6
|
@collection = collection
|
7
7
|
@array = query.split(' ')
|
8
8
|
@operator = @query.split(' ')[1]
|
@@ -16,31 +16,57 @@ module SqlQueryExecutor
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def get_value
|
19
|
-
value = @array.last.gsub(
|
19
|
+
value = @array.last.gsub(::SqlQueryExecutor::Query::Base::STRING_SPACE, ' ')
|
20
20
|
|
21
21
|
convert_value(value)
|
22
22
|
end
|
23
23
|
|
24
24
|
def convert_value(value)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
if (value.to_i.to_s == value.to_s)
|
34
|
-
return value.to_i
|
35
|
-
elsif array.size == 3
|
36
|
-
return array.first.to_i > 1000 ? Date.new(array[0].to_i, array[1].to_i, array[2].to_i) : value
|
37
|
-
elsif array.size == 7
|
38
|
-
array[6] = array[6] == '+0000' ? '+00:00' : array[6].gsub('00', ':00')
|
39
|
-
return array.first.to_i > 1000 ? Time.new(*array) : value
|
40
|
-
end
|
25
|
+
value.gsub!(/[\(\)\'\"]/, "")
|
26
|
+
return value.to_i if is_a_number?(value)
|
27
|
+
|
28
|
+
methods = {3 => "convert_date", 7 => "convert_time"}
|
29
|
+
|
30
|
+
array = split(value)
|
31
|
+
|
32
|
+
value = (send(methods[array.size], array) || value) if methods.keys.include?(array.size)
|
41
33
|
|
42
34
|
value
|
43
35
|
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def sanitize_query(query)
|
39
|
+
params = query.scan(/(\(.*?\))/).flatten.compact
|
40
|
+
|
41
|
+
params.each { |param| query.gsub!(param, param.gsub(" ", "")) }
|
42
|
+
|
43
|
+
query
|
44
|
+
end
|
45
|
+
|
46
|
+
def is_a_number?(value)
|
47
|
+
value.to_s == value.to_i.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
def split(value)
|
51
|
+
return [] unless value.size >= 10
|
52
|
+
|
53
|
+
array = value.split(/[ :]/)
|
54
|
+
array[0] = array.first.split('-')
|
55
|
+
array.flatten
|
56
|
+
end
|
57
|
+
|
58
|
+
def convert_date(args)
|
59
|
+
return if args.first.to_i < 1000
|
60
|
+
|
61
|
+
Date.new(args[0].to_i, args[1].to_i, args[2].to_i)
|
62
|
+
end
|
63
|
+
|
64
|
+
def convert_time(args)
|
65
|
+
return if args.first.to_i < 1000
|
66
|
+
args[6] = args[6].gsub('00', ':00').gsub("+:", "+")
|
67
|
+
|
68
|
+
Time.new(*args)
|
69
|
+
end
|
44
70
|
end
|
45
71
|
end
|
46
72
|
end
|
@@ -3,7 +3,7 @@ require 'sql_query_executor/operators/base'
|
|
3
3
|
module SqlQueryExecutor
|
4
4
|
module Operators
|
5
5
|
class Between < SqlQueryExecutor::Operators::Base
|
6
|
-
def execute!
|
6
|
+
def execute!(result)
|
7
7
|
@collection.select do |record|
|
8
8
|
value = convert_value(record.send(@field).to_s)
|
9
9
|
|
@@ -22,8 +22,8 @@ module SqlQueryExecutor
|
|
22
22
|
def get_value
|
23
23
|
value = []
|
24
24
|
|
25
|
-
value << convert_value(@array[2].gsub(
|
26
|
-
value << convert_value(@array[4].gsub(
|
25
|
+
value << convert_value(@array[2].gsub(SqlQueryExecutor::Query::Base::STRING_SPACE, ' '))
|
26
|
+
value << convert_value(@array[4].gsub(SqlQueryExecutor::Query::Base::STRING_SPACE, ' '))
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -3,8 +3,8 @@ require 'sql_query_executor/operators/base'
|
|
3
3
|
module SqlQueryExecutor
|
4
4
|
module Operators
|
5
5
|
class In < SqlQueryExecutor::Operators::Base
|
6
|
-
def execute!
|
7
|
-
@collection.select do |record|
|
6
|
+
def execute!(result)
|
7
|
+
result = @collection.select do |record|
|
8
8
|
value = record.send(@field)
|
9
9
|
|
10
10
|
@value.send('include?', value)
|
@@ -15,7 +15,7 @@ module SqlQueryExecutor
|
|
15
15
|
def get_value
|
16
16
|
value = super
|
17
17
|
|
18
|
-
value.gsub(
|
18
|
+
value.gsub(SqlQueryExecutor::Query::Base::STRING_SPACE, '').split(',').map &:strip
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -1,23 +1,23 @@
|
|
1
|
-
require 'sql_query_executor/query/executor'
|
2
|
-
|
3
1
|
module SqlQueryExecutor
|
4
2
|
module Query
|
5
3
|
class Base
|
6
4
|
attr_reader :query
|
7
5
|
|
8
6
|
CONVERT_METHODS = {"String" => ["get_query", ""], "Array" => ["interpolate_query", "query.flatten"], "Hash" => ["concatenate_hash", "query"]}
|
7
|
+
STRING_SPACE = "$SS$"
|
8
|
+
QUERY_SPACE = "$QS$"
|
9
|
+
TEMP_SPACE = "$TS$"
|
9
10
|
|
10
11
|
def initialize(query, collection)
|
11
12
|
query = clean_query_attribute(query)
|
12
13
|
array = CONVERT_METHODS[query.class.name]
|
13
14
|
|
14
|
-
|
15
|
-
@
|
16
|
-
sanitize
|
15
|
+
query = sanitize(send(array.first, query))
|
16
|
+
@query = SqlQueryExecutor::Query::SubQuery.new query, collection
|
17
17
|
end
|
18
18
|
|
19
19
|
def execute!
|
20
|
-
|
20
|
+
@query.execute!
|
21
21
|
end
|
22
22
|
|
23
23
|
private
|
@@ -43,34 +43,45 @@ module SqlQueryExecutor
|
|
43
43
|
|
44
44
|
param = convert_param(param)
|
45
45
|
|
46
|
-
args[0] = query.sub("?", param)
|
46
|
+
args[0] = query.sub("?", param.is_a?(Numeric) ? param : "#{param}")
|
47
47
|
|
48
48
|
interpolate_query(args)
|
49
49
|
end
|
50
50
|
|
51
51
|
# Removes all accents and other non default characters
|
52
|
-
def sanitize
|
52
|
+
def sanitize(query)
|
53
53
|
cruft = /\'|\"|\(|\)/
|
54
54
|
|
55
|
-
new_query =
|
56
|
-
params = new_query.scan(/(["|'].*?["|'])
|
55
|
+
new_query = query ? query.dup : query
|
56
|
+
params = new_query.scan(/(["|'].*?["|'])/).flatten.compact
|
57
|
+
|
58
|
+
params.each do |param|
|
59
|
+
new_param = param.dup
|
60
|
+
|
61
|
+
new_param = new_param.gsub(" ", STRING_SPACE)
|
62
|
+
|
63
|
+
new_query = new_query.gsub(param, new_param)
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
params = new_query.scan(/(\(.*?\))/).flatten.compact
|
57
68
|
|
58
69
|
params.each do |param|
|
59
70
|
new_param = param.dup
|
60
71
|
|
61
|
-
new_param = new_param.gsub(
|
62
|
-
new_param = new_param.gsub(" ", "$S$")
|
72
|
+
new_param = new_param.gsub(" ", QUERY_SPACE)
|
63
73
|
|
64
74
|
new_query = new_query.gsub(param, new_param)
|
65
75
|
end
|
66
76
|
|
67
|
-
|
77
|
+
query = new_query.gsub(" and ", "#{TEMP_SPACE}and#{QUERY_SPACE}").gsub(" or ", "#{TEMP_SPACE}or#{QUERY_SPACE}").gsub(" ", QUERY_SPACE).gsub(TEMP_SPACE, " ")
|
68
78
|
|
69
|
-
remove_spaces
|
79
|
+
remove_spaces(query)
|
70
80
|
end
|
71
81
|
|
72
|
-
def remove_spaces
|
73
|
-
|
82
|
+
def remove_spaces(query)
|
83
|
+
query.gsub!(/\[.*?\]/) { |substr| substr.gsub(' ', '') }
|
84
|
+
query
|
74
85
|
end
|
75
86
|
|
76
87
|
# Returns converted #param based on its Class, so it can be used on the query
|
@@ -93,8 +104,10 @@ module SqlQueryExecutor
|
|
93
104
|
|
94
105
|
query.each do |key, value|
|
95
106
|
if value.is_a?(Array)
|
107
|
+
value = value.first.is_a?(Numeric) ? value : value.map{ |v| "'#{v}'" }
|
96
108
|
query_array << "#{key} in (#{value.join(',')})"
|
97
109
|
else
|
110
|
+
value = value.is_a?(Numeric) ? value : "'#{value}'"
|
98
111
|
query_array << "#{key} = #{value}"
|
99
112
|
end
|
100
113
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'sql_query_executor/operators/default'
|
2
|
+
require 'sql_query_executor/operators/between'
|
3
|
+
require 'sql_query_executor/operators/is'
|
4
|
+
require 'sql_query_executor/operators/in'
|
5
|
+
|
6
|
+
module SqlQueryExecutor
|
7
|
+
module Query
|
8
|
+
class Sentence
|
9
|
+
attr_reader :query, :binding_operator, :operator
|
10
|
+
|
11
|
+
OPERATORS = {
|
12
|
+
"between" => SqlQueryExecutor::Operators::Between,
|
13
|
+
"is" => SqlQueryExecutor::Operators::Is,
|
14
|
+
"in" => SqlQueryExecutor::Operators::In,
|
15
|
+
"=" => SqlQueryExecutor::Operators::Default,
|
16
|
+
">" => SqlQueryExecutor::Operators::Default,
|
17
|
+
"<" => SqlQueryExecutor::Operators::Default,
|
18
|
+
">=" => SqlQueryExecutor::Operators::Default,
|
19
|
+
"<=" => SqlQueryExecutor::Operators::Default,
|
20
|
+
"<>" => SqlQueryExecutor::Operators::Default,
|
21
|
+
"!=" => SqlQueryExecutor::Operators::Default,
|
22
|
+
"not" => SqlQueryExecutor::Operators::Default,
|
23
|
+
"exists" => SqlQueryExecutor::Operators::Default,#Exists
|
24
|
+
}
|
25
|
+
|
26
|
+
BINDING_OPERATORS = {
|
27
|
+
"and" => "&",
|
28
|
+
"or" => "+"
|
29
|
+
}
|
30
|
+
|
31
|
+
def initialize(query, collection)
|
32
|
+
@query = query
|
33
|
+
@collection = collection
|
34
|
+
@array = query.split(' ')
|
35
|
+
|
36
|
+
set_binding_operator
|
37
|
+
set_operator
|
38
|
+
end
|
39
|
+
|
40
|
+
def execute!(data)
|
41
|
+
return [] unless @operator
|
42
|
+
|
43
|
+
result = @operator.execute!(data)
|
44
|
+
|
45
|
+
result = data.send(@binding_operator, result) if @binding_operator && (data && !data.empty?)
|
46
|
+
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def set_operator
|
52
|
+
operator = OPERATORS[@query.split(' ')[1]]
|
53
|
+
|
54
|
+
@operator = operator ? operator.new(@query, @collection) : nil
|
55
|
+
end
|
56
|
+
|
57
|
+
def set_binding_operator
|
58
|
+
@binding_operator = BINDING_OPERATORS[@array.first]
|
59
|
+
|
60
|
+
fix_query if @binding_operator
|
61
|
+
end
|
62
|
+
|
63
|
+
def fix_query
|
64
|
+
@array.delete_at(0)
|
65
|
+
|
66
|
+
@query = @array.join(' ')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -1,67 +1,126 @@
|
|
1
|
-
require 'sql_query_executor/operators/default'
|
2
|
-
require 'sql_query_executor/operators/between'
|
3
|
-
require 'sql_query_executor/operators/is'
|
4
|
-
require 'sql_query_executor/operators/in'
|
5
|
-
|
6
1
|
module SqlQueryExecutor
|
7
2
|
module Query
|
8
3
|
class SubQuery
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
"in" => SqlQueryExecutor::Operators::In,
|
13
|
-
"=" => SqlQueryExecutor::Operators::Default,
|
14
|
-
">" => SqlQueryExecutor::Operators::Default,
|
15
|
-
"<" => SqlQueryExecutor::Operators::Default,
|
16
|
-
">=" => SqlQueryExecutor::Operators::Default,
|
17
|
-
"<=" => SqlQueryExecutor::Operators::Default,
|
18
|
-
"<>" => SqlQueryExecutor::Operators::Default,
|
19
|
-
"!=" => SqlQueryExecutor::Operators::Default,
|
20
|
-
"not" => SqlQueryExecutor::Operators::Default,
|
21
|
-
"exists" => SqlQueryExecutor::Operators::Default,#Exists
|
22
|
-
}
|
23
|
-
|
24
|
-
BINDING_OPERATORS = {
|
25
|
-
"and" => "&",
|
26
|
-
"or" => "+"
|
27
|
-
}
|
28
|
-
|
4
|
+
BINDING_OPERATORS = { "or" => "+", "and" => "&" }
|
5
|
+
attr_reader :query, :children, :kind
|
6
|
+
ADD_CHILDREN_METHODS = { sentence: :add_sentence_children, sub_query: :add_sub_query_children }
|
29
7
|
def initialize(query, collection)
|
30
|
-
@query = query
|
31
8
|
@collection = collection
|
32
|
-
@
|
33
|
-
|
9
|
+
@query = query
|
10
|
+
@children = []
|
34
11
|
set_binding_operator
|
35
|
-
|
12
|
+
set_kind
|
13
|
+
set_children
|
36
14
|
end
|
37
15
|
|
38
|
-
def execute!(data)
|
39
|
-
return [] unless @
|
16
|
+
def execute!(data=[])
|
17
|
+
return [] unless @children
|
18
|
+
|
19
|
+
result = []
|
40
20
|
|
41
|
-
|
21
|
+
@children.each do |child|
|
22
|
+
result = child.execute!(result)
|
23
|
+
end
|
42
24
|
|
43
25
|
result = data.send(@binding_operator, result) if @binding_operator && (data && !data.empty?)
|
44
26
|
|
45
|
-
result
|
27
|
+
result.sort_by(&:id)
|
46
28
|
end
|
47
29
|
|
48
30
|
private
|
49
|
-
def
|
50
|
-
|
31
|
+
def set_binding_operator
|
32
|
+
@binding_operator = nil
|
33
|
+
operator = @query.split(Base::QUERY_SPACE).first
|
51
34
|
|
52
|
-
|
35
|
+
if ["and", "or"].include?(operator)
|
36
|
+
@binding_operator = BINDING_OPERATORS[operator]
|
37
|
+
@query = @query.gsub("#{operator}$QS$", "")
|
38
|
+
end
|
53
39
|
end
|
54
40
|
|
55
|
-
def
|
56
|
-
@
|
41
|
+
def set_kind
|
42
|
+
@kind = is_single_query? ? :sentence : :sub_query
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_children
|
46
|
+
send(ADD_CHILDREN_METHODS[@kind])
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_sentence_children
|
50
|
+
@children << SqlQueryExecutor::Query::Sentence.new(@query.gsub(Base::QUERY_SPACE, " "), @collection)
|
51
|
+
end
|
52
|
+
|
53
|
+
def add_sub_query_children
|
54
|
+
array = @query.split(" ")
|
55
|
+
queries = []
|
56
|
+
|
57
|
+
array.each do |query|
|
58
|
+
sanitized_query = replace_parentheses(query)
|
59
|
+
params = sanitized_query.scan(/\$op1\$(\S+)\$cp1\$/).flatten.compact
|
60
|
+
|
61
|
+
params.each do |param|
|
62
|
+
string = param.gsub("$QS$and$QS$", " and$QS$").gsub("$QS$or$QS$", " or$QS$")
|
63
|
+
query = sanitized_query.gsub(param, string)
|
64
|
+
end
|
57
65
|
|
58
|
-
|
66
|
+
query = query.gsub("\$op1\$", "").gsub("\$cp1\$", "").gsub(/\$\Sp\d\$/, "")
|
67
|
+
|
68
|
+
@children << SqlQueryExecutor::Query::SubQuery.new(query, @collection)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def is_single_query?
|
73
|
+
array = @query.gsub(Base::QUERY_SPACE, ' ').split(' ')
|
74
|
+
|
75
|
+
array.size <= 5
|
76
|
+
end
|
77
|
+
|
78
|
+
def build_sub_query(query)
|
79
|
+
array = query.split(" ")
|
80
|
+
|
81
|
+
offset = is_binding_operator?(array.first) ? 1 : 0
|
82
|
+
operator = array[1+offset]
|
83
|
+
|
84
|
+
result = case operator
|
85
|
+
when "between"
|
86
|
+
array[0..4+offset]
|
87
|
+
when "is"
|
88
|
+
size = array[2+offset] == "not" ? 3 : 2
|
89
|
+
array[0..size+offset]
|
90
|
+
when "not"
|
91
|
+
array[0..3+offset]
|
92
|
+
else
|
93
|
+
array[0..2+offset]
|
94
|
+
end
|
95
|
+
|
96
|
+
result.join(' ')
|
97
|
+
end
|
98
|
+
|
99
|
+
def is_binding_operator?(operator)
|
100
|
+
BINDING_OPERATORS.include?(operator)
|
59
101
|
end
|
60
102
|
|
61
|
-
def
|
62
|
-
|
103
|
+
def replace_parentheses(query)
|
104
|
+
count = 1
|
105
|
+
string = ""
|
106
|
+
|
107
|
+
query.each_char do |c|
|
108
|
+
char = c
|
109
|
+
|
110
|
+
if c == "("
|
111
|
+
char = "$op#{count}$"
|
112
|
+
count += 1
|
113
|
+
end
|
114
|
+
|
115
|
+
if c == ")"
|
116
|
+
count -= 1
|
117
|
+
char = "$cp#{count}$"
|
118
|
+
end
|
119
|
+
|
120
|
+
string << char
|
121
|
+
end
|
63
122
|
|
64
|
-
|
123
|
+
string
|
65
124
|
end
|
66
125
|
end
|
67
126
|
end
|
@@ -6,11 +6,11 @@ describe SqlQueryExecutor, "Base" do
|
|
6
6
|
before do
|
7
7
|
@data = []
|
8
8
|
|
9
|
-
@data << {:
|
10
|
-
@data << {:
|
11
|
-
@data << {:
|
12
|
-
@data << {:
|
13
|
-
@data << {:
|
9
|
+
@data << {id: 1, name: "US", language: 'English'}
|
10
|
+
@data << {id: 2, name: "Canada", language: 'English', monarch: "The Crown of England"}
|
11
|
+
@data << {id: 3, name: "Mexico", language: 'Spanish'}
|
12
|
+
@data << {id: 4, name: "UK", language: 'English', monarch: "The Crown of England"}
|
13
|
+
@data << {id: 5, name: "Brazil", founded_at: Time.parse('1500-04-22 13:34:25')}
|
14
14
|
end
|
15
15
|
|
16
16
|
subject { SqlQueryExecutor::Base.new(@data) }
|
@@ -413,6 +413,32 @@ describe SqlQueryExecutor, "Base" do
|
|
413
413
|
|
414
414
|
records.should == [@data[0], @data[1], @data[2], @data[3]]
|
415
415
|
end
|
416
|
+
|
417
|
+
context "nested queries" do
|
418
|
+
it "respects priority" do
|
419
|
+
records = subject.where("(language = 'English' and name = 'US') or (language is null)")
|
420
|
+
records.count.should == 2
|
421
|
+
records.first.id.should == 1
|
422
|
+
|
423
|
+
records.map! do |record|
|
424
|
+
record.to_h
|
425
|
+
end
|
426
|
+
|
427
|
+
records.should == [@data[0], @data[4]]
|
428
|
+
end
|
429
|
+
|
430
|
+
it "respects priority" do
|
431
|
+
records = subject.where("(language is null) or (language = 'English' and name = 'US')")
|
432
|
+
records.count.should == 2
|
433
|
+
records.first.id.should == 1
|
434
|
+
|
435
|
+
records.map! do |record|
|
436
|
+
record.to_h
|
437
|
+
end
|
438
|
+
|
439
|
+
records.should == [@data[0], @data[4]]
|
440
|
+
end
|
441
|
+
end
|
416
442
|
end
|
417
443
|
|
418
444
|
describe "in" do
|
@@ -427,6 +453,18 @@ describe SqlQueryExecutor, "Base" do
|
|
427
453
|
|
428
454
|
records.should == [@data[0], @data[1], @data[2], @data[3]]
|
429
455
|
end
|
456
|
+
|
457
|
+
xit "attribute not in condition" do
|
458
|
+
records = subject.where("language not in ('English', 'Spanish')")
|
459
|
+
records.count.should == 1
|
460
|
+
records.first.id.should == 5
|
461
|
+
|
462
|
+
records.map! do |record|
|
463
|
+
record.to_h
|
464
|
+
end
|
465
|
+
|
466
|
+
records.should == [@data[4]]
|
467
|
+
end
|
430
468
|
end
|
431
469
|
|
432
470
|
describe "not" do
|
data/sql_query_executor.gemspec
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
require File.expand_path('../lib/sql_query_executor/version.rb', __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.authors = ["Caio Torres"]
|
6
6
|
gem.email = ["efreesen@gmail.com"]
|
7
|
-
gem.description = %q{Gem to run SQL like queries on array of hashes}
|
8
|
-
gem.summary = %q{With SqlQueryExecutor you can run SQL like queries on any array of hashes}
|
7
|
+
gem.description = %q{Gem to run SQL like queries on array of hashes or similar objects}
|
8
|
+
gem.summary = %q{With SqlQueryExecutor you can run SQL like queries on any array of hashes or similar objects}
|
9
9
|
gem.homepage = "http://github.com/efreesen/sql_query_executor"
|
10
10
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
12
12
|
gem.test_files = gem.files.grep(%r{^(spec)/})
|
13
13
|
gem.name = "sql_query_executor"
|
14
14
|
gem.require_paths = ["lib"]
|
15
|
-
gem.version =
|
15
|
+
gem.version = SqlQueryExecutor::VERSION
|
16
16
|
gem.license = "GPLv2"
|
17
17
|
gem.files = [
|
18
18
|
"LICENSE",
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sql_query_executor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Caio Torres
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-02-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -52,7 +52,7 @@ dependencies:
|
|
52
52
|
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
description: Gem to run SQL like queries on array of hashes
|
55
|
+
description: Gem to run SQL like queries on array of hashes or similar objects
|
56
56
|
email:
|
57
57
|
- efreesen@gmail.com
|
58
58
|
executables: []
|
@@ -69,10 +69,9 @@ files:
|
|
69
69
|
- lib/sql_query_executor/operators/in.rb
|
70
70
|
- lib/sql_query_executor/operators/is.rb
|
71
71
|
- lib/sql_query_executor/query/base.rb
|
72
|
-
- lib/sql_query_executor/query/
|
73
|
-
- lib/sql_query_executor/query/executor.rb
|
72
|
+
- lib/sql_query_executor/query/sentence.rb
|
74
73
|
- lib/sql_query_executor/query/sub_query.rb
|
75
|
-
- lib/sql_query_executor/version
|
74
|
+
- lib/sql_query_executor/version.rb
|
76
75
|
- lib/sql_query_executor.rb
|
77
76
|
- Gemfile
|
78
77
|
- spec/sql_query_executor/base_spec.rb
|
@@ -100,6 +99,7 @@ rubygems_version: 2.0.14
|
|
100
99
|
signing_key:
|
101
100
|
specification_version: 4
|
102
101
|
summary: With SqlQueryExecutor you can run SQL like queries on any array of hashes
|
102
|
+
or similar objects
|
103
103
|
test_files:
|
104
104
|
- Gemfile
|
105
105
|
- spec/sql_query_executor/base_spec.rb
|
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'sql_query_executor/query/sub_query'
|
2
|
-
|
3
|
-
module SqlQueryExecutor
|
4
|
-
module Query
|
5
|
-
class Divider
|
6
|
-
BINDING_OPERATORS = ['and', 'or']
|
7
|
-
|
8
|
-
class << self
|
9
|
-
def divide(query, collection)
|
10
|
-
@query = query
|
11
|
-
divide_query(collection)
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
# Splits the first sub query from the rest of the query and returns it.
|
16
|
-
def divide_query(collection)
|
17
|
-
array = @query.split(" ")
|
18
|
-
operator = array[1].downcase
|
19
|
-
|
20
|
-
sub_query = get_sub_array(operator, array)
|
21
|
-
remaining_query = @query.gsub(sub_query, '').strip
|
22
|
-
|
23
|
-
sub_query = SqlQueryExecutor::Query::SubQuery.new(sub_query, collection)
|
24
|
-
|
25
|
-
return sub_query, remaining_query == '' ? nil : remaining_query
|
26
|
-
end
|
27
|
-
|
28
|
-
def get_sub_array(operator, array)
|
29
|
-
result = case operator
|
30
|
-
when "between"
|
31
|
-
array[0..4]
|
32
|
-
when "is"
|
33
|
-
size = array[2] == "not" ? 3 : 2
|
34
|
-
array[0..size]
|
35
|
-
when "not"
|
36
|
-
array[0..3]
|
37
|
-
else
|
38
|
-
array[0..2]
|
39
|
-
end
|
40
|
-
|
41
|
-
result = fix_array(array, result)
|
42
|
-
|
43
|
-
result.join(' ')
|
44
|
-
end
|
45
|
-
|
46
|
-
def fix_array(array, result)
|
47
|
-
if BINDING_OPERATORS.include?(result.first)
|
48
|
-
array[0..result.size]
|
49
|
-
else
|
50
|
-
result
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'sql_query_executor/query/divider'
|
2
|
-
|
3
|
-
module SqlQueryExecutor
|
4
|
-
module Query
|
5
|
-
class Executor
|
6
|
-
class << self
|
7
|
-
def execute!(query, collection, data=[])
|
8
|
-
sub_query, remaining_query = SqlQueryExecutor::Query::Divider.divide(query, collection)
|
9
|
-
|
10
|
-
result = sub_query.execute!(data)
|
11
|
-
|
12
|
-
remaining_query.nil? ? result.sort_by{ |r| r.id } : execute!(remaining_query, collection, result)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|