sql_query_executor 0.0.1
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 +7 -0
- data/Gemfile +4 -0
- data/LICENSE +339 -0
- data/README.md +2 -0
- data/lib/sql_query_executor.rb +2 -0
- data/lib/sql_query_executor/base.rb +37 -0
- data/lib/sql_query_executor/operators/base.rb +46 -0
- data/lib/sql_query_executor/operators/between.rb +30 -0
- data/lib/sql_query_executor/operators/default.rb +26 -0
- data/lib/sql_query_executor/operators/in.rb +22 -0
- data/lib/sql_query_executor/operators/is.rb +29 -0
- data/lib/sql_query_executor/query/base.rb +106 -0
- data/lib/sql_query_executor/query/divider.rb +56 -0
- data/lib/sql_query_executor/query/executor.rb +17 -0
- data/lib/sql_query_executor/query/sub_query.rb +68 -0
- data/lib/sql_query_executor/version +3 -0
- data/spec/sql_query_executor/base_spec.rb +446 -0
- data/sql_query_executor.gemspec +31 -0
- metadata +105 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'sql_query_executor/operators/base'
|
2
|
+
|
3
|
+
module SqlQueryExecutor
|
4
|
+
module Operators
|
5
|
+
class Default < SqlQueryExecutor::Operators::Base
|
6
|
+
def initialize(query, collection)
|
7
|
+
super
|
8
|
+
convert_operator
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute!
|
12
|
+
@collection.select do |record|
|
13
|
+
value = record.send(@field.to_s)
|
14
|
+
|
15
|
+
value.send(@operator, @value) rescue false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def convert_operator
|
21
|
+
@operator = @operator == "=" ? "==" : @operator
|
22
|
+
@operator = @operator == "<>" ? "!=" : @operator
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'sql_query_executor/operators/base'
|
2
|
+
|
3
|
+
module SqlQueryExecutor
|
4
|
+
module Operators
|
5
|
+
class In < SqlQueryExecutor::Operators::Base
|
6
|
+
def execute!
|
7
|
+
@collection.select do |record|
|
8
|
+
value = record.send(@field)
|
9
|
+
|
10
|
+
@value.send('include?', value)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def get_value
|
16
|
+
value = super
|
17
|
+
|
18
|
+
value.gsub('$S$', '').split(',').map &:strip
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'sql_query_executor/operators/base'
|
2
|
+
|
3
|
+
module SqlQueryExecutor
|
4
|
+
module Operators
|
5
|
+
class Is < SqlQueryExecutor::Operators::Base
|
6
|
+
def initialize(query, collection)
|
7
|
+
super
|
8
|
+
convert_operator
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute!
|
12
|
+
@collection.select do |record|
|
13
|
+
value = record.send(@field)
|
14
|
+
|
15
|
+
value.send(@operator, nil)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def get_value
|
21
|
+
@array.include?('null') ? 'nil' : @array.last
|
22
|
+
end
|
23
|
+
|
24
|
+
def convert_operator
|
25
|
+
@operator = @array.include?('not') ? '!=' : '=='
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'sql_query_executor/query/executor'
|
2
|
+
|
3
|
+
module SqlQueryExecutor
|
4
|
+
module Query
|
5
|
+
class Base
|
6
|
+
attr_reader :query
|
7
|
+
|
8
|
+
CONVERT_METHODS = {"String" => ["get_query", ""], "Array" => ["interpolate_query", "query.flatten"], "Hash" => ["concatenate_hash", "query"]}
|
9
|
+
|
10
|
+
def initialize(query, collection)
|
11
|
+
query = clean_query_attribute(query)
|
12
|
+
array = CONVERT_METHODS[query.class.name]
|
13
|
+
|
14
|
+
@query = send(array.first, query)
|
15
|
+
@collection = collection
|
16
|
+
sanitize
|
17
|
+
end
|
18
|
+
|
19
|
+
def execute!
|
20
|
+
SqlQueryExecutor::Query::Executor.execute!(@query, @collection)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def clean_query_attribute(query)
|
25
|
+
return query unless query.is_a?(Array)
|
26
|
+
|
27
|
+
query = query.flatten
|
28
|
+
|
29
|
+
query.size == 1 ? query.first : query
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_query(query)
|
33
|
+
query
|
34
|
+
end
|
35
|
+
|
36
|
+
# Prepares query by replacing all ? by it's real values in #args
|
37
|
+
def interpolate_query(args)
|
38
|
+
args.flatten!
|
39
|
+
return args.first if args.size == 1 && args.first.is_a?(String)
|
40
|
+
|
41
|
+
query = args.first
|
42
|
+
param = args.delete_at(1)
|
43
|
+
|
44
|
+
param = convert_param(param)
|
45
|
+
|
46
|
+
args[0] = query.sub("?", param)
|
47
|
+
|
48
|
+
interpolate_query(args)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Removes all accents and other non default characters
|
52
|
+
def sanitize
|
53
|
+
cruft = /\'|\"|\(|\)/
|
54
|
+
|
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(cruft,"")
|
62
|
+
new_param = new_param.gsub(" ", "$S$")
|
63
|
+
|
64
|
+
new_query = new_query.gsub(param, new_param)
|
65
|
+
end
|
66
|
+
|
67
|
+
@query = new_query
|
68
|
+
|
69
|
+
remove_spaces
|
70
|
+
end
|
71
|
+
|
72
|
+
def remove_spaces
|
73
|
+
@query.gsub!(/\[.*?\]/) { |substr| substr.gsub(' ', '') }
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns converted #param based on its Class, so it can be used on the query
|
77
|
+
def convert_param(param)
|
78
|
+
case param.class.name
|
79
|
+
when "String"
|
80
|
+
param = "'#{param}'"
|
81
|
+
when "Date"
|
82
|
+
param = "'#{param.strftime("%Y-%m-%d")}'"
|
83
|
+
when "Time"
|
84
|
+
param = "'#{param.strftime("%Y-%m-%d %H:%M:%S %z")}'"
|
85
|
+
else
|
86
|
+
param = param.to_s
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def concatenate_hash(query)
|
91
|
+
return "" unless query.is_a?(Hash)
|
92
|
+
query_array = []
|
93
|
+
|
94
|
+
query.each do |key, value|
|
95
|
+
if value.is_a?(Array)
|
96
|
+
query_array << "#{key} in (#{value.join(',')})"
|
97
|
+
else
|
98
|
+
query_array << "#{key} = #{value}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
query_array.join(" and ")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,56 @@
|
|
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
|
@@ -0,0 +1,17 @@
|
|
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
|
@@ -0,0 +1,68 @@
|
|
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 SubQuery
|
9
|
+
OPERATORS = {
|
10
|
+
"between" => SqlQueryExecutor::Operators::Between,
|
11
|
+
"is" => SqlQueryExecutor::Operators::Is,
|
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
|
+
|
29
|
+
def initialize(query, collection)
|
30
|
+
@query = query
|
31
|
+
@collection = collection
|
32
|
+
@array = query.split(' ')
|
33
|
+
|
34
|
+
set_binding_operator
|
35
|
+
set_operator
|
36
|
+
end
|
37
|
+
|
38
|
+
def execute!(data)
|
39
|
+
return [] unless @operator
|
40
|
+
|
41
|
+
result = @operator.execute!
|
42
|
+
|
43
|
+
result = data.send(@binding_operator, result) if @binding_operator && (data && !data.empty?)
|
44
|
+
|
45
|
+
result
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
def set_operator
|
50
|
+
operator = OPERATORS[@query.split(' ')[1]]
|
51
|
+
|
52
|
+
@operator = operator ? operator.new(@query, @collection) : nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def set_binding_operator
|
56
|
+
@binding_operator = BINDING_OPERATORS[@array.first]
|
57
|
+
|
58
|
+
fix_query if @binding_operator
|
59
|
+
end
|
60
|
+
|
61
|
+
def fix_query
|
62
|
+
@array.delete_at(0)
|
63
|
+
|
64
|
+
@query = @array.join(' ')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,446 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'sql_query_executor'
|
4
|
+
|
5
|
+
describe SqlQueryExecutor, "Base" do
|
6
|
+
before do
|
7
|
+
@data = []
|
8
|
+
|
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
|
+
end
|
15
|
+
|
16
|
+
subject { SqlQueryExecutor::Base.new(@data) }
|
17
|
+
|
18
|
+
describe ".where" do
|
19
|
+
describe "=" do
|
20
|
+
context "when attribute is string" do
|
21
|
+
it "matches a record" do
|
22
|
+
record = subject.where("name = 'US'")
|
23
|
+
record.size.should == 1
|
24
|
+
record.first.id.should == 1
|
25
|
+
record.first.name.should == 'US'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "doesn't match any record" do
|
29
|
+
record = subject.where("name = 'Argentina'")
|
30
|
+
record.count.should == 0
|
31
|
+
record.should == []
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when attribute is integer" do
|
36
|
+
it "matches a record" do
|
37
|
+
record = subject.where("id = 1")
|
38
|
+
record.count.should == 1
|
39
|
+
record.first.id.should == 1
|
40
|
+
record.first.name.should == 'US'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "doesn't match any record" do
|
44
|
+
record = subject.where("id = 43")
|
45
|
+
record.count.should == 0
|
46
|
+
record.should == []
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "when attribute is datetime" do
|
51
|
+
it "matches a record" do
|
52
|
+
record = subject.where("founded_at = ?", Time.parse('1500-04-22 13:34:25'))
|
53
|
+
record.count.should == 1
|
54
|
+
record.first.id.should == 5
|
55
|
+
record.first.name.should == 'Brazil'
|
56
|
+
end
|
57
|
+
|
58
|
+
it "doesn't match any record" do
|
59
|
+
record = subject.where("id = ?", Time.parse('1500-09-07 13:34:25'))
|
60
|
+
record.count.should == 0
|
61
|
+
record.should == []
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe ">" do
|
67
|
+
context "when attribute is a string" do
|
68
|
+
it "matches a record" do
|
69
|
+
records = subject.where("name > 'T'")
|
70
|
+
records.count.should == 2
|
71
|
+
records.first.id.should == 1
|
72
|
+
|
73
|
+
records.map! do |record|
|
74
|
+
record.to_h
|
75
|
+
end
|
76
|
+
|
77
|
+
records.should == [@data[0], @data[3]]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "doesn't match any record" do
|
81
|
+
record = subject.where("name > 'Z'")
|
82
|
+
record.count.should == 0
|
83
|
+
record.should == []
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "when attribute is integer" do
|
88
|
+
it "matches a record" do
|
89
|
+
records = subject.where("id > 3")
|
90
|
+
records.count.should == 2
|
91
|
+
records.first.id.should == 4
|
92
|
+
|
93
|
+
records.map! do |record|
|
94
|
+
record.to_h
|
95
|
+
end
|
96
|
+
|
97
|
+
records.should == [@data[3], @data[4]]
|
98
|
+
end
|
99
|
+
|
100
|
+
it "doesn't match any record" do
|
101
|
+
record = subject.where("id > 5")
|
102
|
+
record.count.should == 0
|
103
|
+
record.should == []
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "when attribute is datetime" do
|
108
|
+
it "matches a record" do
|
109
|
+
record = subject.where("founded_at > ?", Time.parse('1500-04-20 13:34:25'))
|
110
|
+
record.count.should == 1
|
111
|
+
record.first.id.should == 5
|
112
|
+
record.first.name.should == 'Brazil'
|
113
|
+
end
|
114
|
+
|
115
|
+
it "doesn't match any record" do
|
116
|
+
record = subject.where("founded_at > ?", Time.parse('1500-04-23 13:34:25'))
|
117
|
+
record.count.should == 0
|
118
|
+
record.should == []
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe ">=" do
|
124
|
+
context "when attribute is a string" do
|
125
|
+
it "matches a record" do
|
126
|
+
records = subject.where("name >= 'U'")
|
127
|
+
records.count.should == 2
|
128
|
+
records.first.id.should == 1
|
129
|
+
|
130
|
+
records.map! do |record|
|
131
|
+
record.to_h
|
132
|
+
end
|
133
|
+
|
134
|
+
records.should == [@data[0], @data[3]]
|
135
|
+
end
|
136
|
+
|
137
|
+
it "doesn't match any record" do
|
138
|
+
record = subject.where("name >= 'Z'")
|
139
|
+
record.count.should == 0
|
140
|
+
record.should == []
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context "when attribute is integer" do
|
145
|
+
it "matches a record" do
|
146
|
+
records = subject.where("id >= 4")
|
147
|
+
records.count.should == 2
|
148
|
+
records.first.id.should == 4
|
149
|
+
|
150
|
+
records.map! do |record|
|
151
|
+
record.to_h
|
152
|
+
end
|
153
|
+
|
154
|
+
records.should == [@data[3], @data[4]]
|
155
|
+
end
|
156
|
+
|
157
|
+
it "doesn't match any record" do
|
158
|
+
record = subject.where("id >= 6")
|
159
|
+
record.count.should == 0
|
160
|
+
record.should == []
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context "when attribute is datetime" do
|
165
|
+
it "matches a record" do
|
166
|
+
record = subject.where("founded_at >= ?", Time.parse('1500-04-22 13:34:25'))
|
167
|
+
record.count.should == 1
|
168
|
+
record.first.id.should == 5
|
169
|
+
record.first.name.should == 'Brazil'
|
170
|
+
end
|
171
|
+
|
172
|
+
it "doesn't match any record" do
|
173
|
+
record = subject.where("founded_at >= ?", Time.parse('1500-04-23 13:34:25'))
|
174
|
+
record.count.should == 0
|
175
|
+
record.should == []
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe "<" do
|
181
|
+
context "when attribute is a string" do
|
182
|
+
it "matches a record" do
|
183
|
+
records = subject.where("name < 'C'")
|
184
|
+
records.count.should == 1
|
185
|
+
records.first.id.should == 5
|
186
|
+
|
187
|
+
records.map! do |record|
|
188
|
+
record.to_h
|
189
|
+
end
|
190
|
+
|
191
|
+
records.should == [@data[4]]
|
192
|
+
end
|
193
|
+
|
194
|
+
it "doesn't match any record" do
|
195
|
+
record = subject.where("name < 'B'")
|
196
|
+
record.count.should == 0
|
197
|
+
record.should == []
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context "when attribute is integer" do
|
202
|
+
it "matches a record" do
|
203
|
+
records = subject.where("id < 3")
|
204
|
+
records.count.should == 2
|
205
|
+
records.first.id.should == 1
|
206
|
+
|
207
|
+
records.map! do |record|
|
208
|
+
record.to_h
|
209
|
+
end
|
210
|
+
|
211
|
+
records.should == [@data[0], @data[1]]
|
212
|
+
end
|
213
|
+
|
214
|
+
it "doesn't match any record" do
|
215
|
+
record = subject.where("id < 1")
|
216
|
+
record.count.should == 0
|
217
|
+
record.should == []
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context "when attribute is datetime" do
|
222
|
+
it "matches a record" do
|
223
|
+
record = subject.where("founded_at < ?", Time.parse('1500-04-22 13:34:26'))
|
224
|
+
record.count.should == 1
|
225
|
+
record.first.id.should == 5
|
226
|
+
record.first.name.should == 'Brazil'
|
227
|
+
end
|
228
|
+
|
229
|
+
it "doesn't match any record" do
|
230
|
+
record = subject.where("founded_at < ?", Time.parse('1500-04-22 13:34:25'))
|
231
|
+
record.count.should == 0
|
232
|
+
record.should == []
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe "<=" do
|
238
|
+
context "when attribute is a string" do
|
239
|
+
it "matches a record" do
|
240
|
+
records = subject.where("name <= 'Brb'")
|
241
|
+
records.count.should == 1
|
242
|
+
records.first.id.should == 5
|
243
|
+
|
244
|
+
records.map! do |record|
|
245
|
+
record.to_h
|
246
|
+
end
|
247
|
+
|
248
|
+
records.should == [@data[4]]
|
249
|
+
end
|
250
|
+
|
251
|
+
it "doesn't match any record" do
|
252
|
+
record = subject.where("name <= 'A'")
|
253
|
+
record.count.should == 0
|
254
|
+
record.should == []
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context "when attribute is integer" do
|
259
|
+
it "matches a record" do
|
260
|
+
records = subject.where("id <= 2")
|
261
|
+
records.count.should == 2
|
262
|
+
records.first.id.should == 1
|
263
|
+
|
264
|
+
records.map! do |record|
|
265
|
+
record.to_h
|
266
|
+
end
|
267
|
+
|
268
|
+
records.should == [@data[0], @data[1]]
|
269
|
+
end
|
270
|
+
|
271
|
+
it "doesn't match any record" do
|
272
|
+
record = subject.where("id <= 0")
|
273
|
+
record.count.should == 0
|
274
|
+
record.should == []
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
context "when attribute is datetime" do
|
279
|
+
it "matches a record" do
|
280
|
+
record = subject.where("founded_at <= ?", Time.parse('1500-04-22 13:34:25'))
|
281
|
+
record.count.should == 1
|
282
|
+
record.first.id.should == 5
|
283
|
+
record.first.name.should == 'Brazil'
|
284
|
+
end
|
285
|
+
|
286
|
+
it "doesn't match any record" do
|
287
|
+
record = subject.where("founded_at <= ?", Time.parse('1500-04-22 13:34:24'))
|
288
|
+
record.count.should == 0
|
289
|
+
record.should == []
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
describe "between" do
|
295
|
+
context "when attribute is a string" do
|
296
|
+
it "matches a record" do
|
297
|
+
records = subject.where("name between 'A' and 'C'")
|
298
|
+
records.count.should == 1
|
299
|
+
records.first.id.should == 5
|
300
|
+
|
301
|
+
records.map! do |record|
|
302
|
+
record.to_h
|
303
|
+
end
|
304
|
+
|
305
|
+
records.should == [@data[4]]
|
306
|
+
end
|
307
|
+
|
308
|
+
it "doesn't match any record" do
|
309
|
+
record = subject.where("name between 'K' and 'M'")
|
310
|
+
record.count.should == 0
|
311
|
+
record.should == []
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
context "when attribute is integer" do
|
316
|
+
it "matches a record" do
|
317
|
+
records = subject.where("id between 1 and 2")
|
318
|
+
records.count.should == 2
|
319
|
+
records.first.id.should == 1
|
320
|
+
|
321
|
+
records.map! do |record|
|
322
|
+
record.to_h
|
323
|
+
end
|
324
|
+
|
325
|
+
records.should == [@data[0], @data[1]]
|
326
|
+
end
|
327
|
+
|
328
|
+
it "doesn't match any record" do
|
329
|
+
record = subject.where("id between 6 and 10")
|
330
|
+
record.count.should == 0
|
331
|
+
record.should == []
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
context "when attribute is datetime" do
|
336
|
+
it "matches a record" do
|
337
|
+
record = subject.where("founded_at between ? and ?", Time.parse('1500-04-22 13:34:24'), Time.parse('1500-04-22 13:34:26'))
|
338
|
+
record.count.should == 1
|
339
|
+
record.first.id.should == 5
|
340
|
+
record.first.name.should == 'Brazil'
|
341
|
+
end
|
342
|
+
|
343
|
+
it "doesn't match any record" do
|
344
|
+
record = subject.where("founded_at between ? and ?", Time.parse('1500-04-22 13:34:26'), Time.parse('1500-09-22 13:34:25'))
|
345
|
+
record.count.should == 0
|
346
|
+
record.should == []
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
describe "is" do
|
352
|
+
it "attribute is condition" do
|
353
|
+
records = subject.where("founded_at is null")
|
354
|
+
records.count.should == 4
|
355
|
+
records.first.id.should == 1
|
356
|
+
|
357
|
+
records.map! do |record|
|
358
|
+
record.to_h
|
359
|
+
end
|
360
|
+
|
361
|
+
records.should == [@data[0], @data[1], @data[2], @data[3]]
|
362
|
+
end
|
363
|
+
|
364
|
+
it "attribute is not condition" do
|
365
|
+
id = @data.last[:id]
|
366
|
+
records = subject.where("founded_at is not null")
|
367
|
+
records.count.should == 1
|
368
|
+
records.first.id.should == id
|
369
|
+
|
370
|
+
records.map! do |record|
|
371
|
+
record.to_h
|
372
|
+
end
|
373
|
+
|
374
|
+
records.should == [@data[id-1]]
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
describe "and" do
|
379
|
+
it "attribute and condition" do
|
380
|
+
records = subject.where("language = 'English' and monarch = 'The Crown of England'")
|
381
|
+
records.count.should == 2
|
382
|
+
records.first.id.should == 2
|
383
|
+
|
384
|
+
records.map! do |record|
|
385
|
+
record.to_h
|
386
|
+
end
|
387
|
+
|
388
|
+
records.should == [@data[1], @data[3]]
|
389
|
+
end
|
390
|
+
|
391
|
+
it "integer attribute and condition" do
|
392
|
+
records = subject.where("id = 2 and language = 'English'")
|
393
|
+
records.count.should == 1
|
394
|
+
records.first.id.should == 2
|
395
|
+
|
396
|
+
records.map! do |record|
|
397
|
+
record.to_h
|
398
|
+
end
|
399
|
+
|
400
|
+
records.should == [@data[1]]
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
describe "or" do
|
405
|
+
it "attribute or condition" do
|
406
|
+
records = subject.where("language = 'English' or language = 'Spanish'")
|
407
|
+
records.count.should == 4
|
408
|
+
records.first.id.should == 1
|
409
|
+
|
410
|
+
records.map! do |record|
|
411
|
+
record.to_h
|
412
|
+
end
|
413
|
+
|
414
|
+
records.should == [@data[0], @data[1], @data[2], @data[3]]
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
describe "in" do
|
419
|
+
it "attribute in condition" do
|
420
|
+
records = subject.where("language in ('English', 'Spanish')")
|
421
|
+
records.count.should == 4
|
422
|
+
records.first.id.should == 1
|
423
|
+
|
424
|
+
records.map! do |record|
|
425
|
+
record.to_h
|
426
|
+
end
|
427
|
+
|
428
|
+
records.should == [@data[0], @data[1], @data[2], @data[3]]
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
describe "not" do
|
433
|
+
xit "attribute not condition" do
|
434
|
+
records = subject.where("not language = 'English'")
|
435
|
+
records.count.should == 1
|
436
|
+
records.first.id.should == 5
|
437
|
+
|
438
|
+
records.map! do |record|
|
439
|
+
record.to_h
|
440
|
+
end
|
441
|
+
|
442
|
+
records.should == [@data[4]]
|
443
|
+
end
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|