deli 0.5.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.
- data/Rakefile +77 -0
- data/lib/deli.rb +18 -0
- data/lib/deli/adapters.rb +9 -0
- data/lib/deli/adapters/active_record.rb +251 -0
- data/lib/deli/adapters/cassandra.rb +52 -0
- data/lib/deli/adapters/mongoid.rb +180 -0
- data/lib/deli/adapters/neo4j.rb +54 -0
- data/lib/deli/adapters/simple.rb +39 -0
- data/lib/deli/configuration.rb +47 -0
- data/lib/deli/controller.rb +75 -0
- data/lib/deli/helper.rb +61 -0
- data/lib/deli/model.rb +13 -0
- data/lib/deli/pagination.rb +117 -0
- data/lib/deli/param.rb +189 -0
- data/lib/deli/query.rb +133 -0
- data/lib/deli/railtie.rb +14 -0
- data/spec/active_record_spec.rb +358 -0
- data/spec/cassandra_spec.rb +40 -0
- data/spec/mongoid_spec.rb +40 -0
- data/spec/neo4j_spec.rb +40 -0
- data/spec/param_spec.rb +318 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/support/database.rb +69 -0
- data/spec/support/models.rb +27 -0
- metadata +77 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Deli::Adapters::Cassandra do
|
4
|
+
before do
|
5
|
+
Deli.configuration.default_adapter = :cassandra
|
6
|
+
@url = "http://site.com/search?title=Ruby+-'Hello+World'&created_at=t..2011-02-01&sort=created_at,title-&page=12&limit=20"
|
7
|
+
@params = {
|
8
|
+
:title => "Ruby+-'Hello+World'",
|
9
|
+
:created_at => "t..2011-02-01",
|
10
|
+
:sort => "created_at,title-",
|
11
|
+
:page => "12",
|
12
|
+
:limit => "20"
|
13
|
+
}.stringify_keys
|
14
|
+
|
15
|
+
@params.each do |k, v|
|
16
|
+
@params[k] = v.gsub("+", " ")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "definitions" do
|
21
|
+
before do
|
22
|
+
@controller = ::Deli::Controller.new(:user) do
|
23
|
+
match :title, :type => :string
|
24
|
+
match :created_at, :type => :datetime
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should render query" do
|
29
|
+
query = {
|
30
|
+
"page" => 12,
|
31
|
+
"sort" => [[:created_at, :asc], [:title, :desc]],
|
32
|
+
"limit" => 20,
|
33
|
+
"title" => {"$regex" => /(?i-mx:Ruby)|(?i-mx:(?!Hello World))/},
|
34
|
+
"created_at" => {"$lte" => Time.zone.parse("2011-02-01")}
|
35
|
+
}
|
36
|
+
|
37
|
+
@controller.render(@params).should == query
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Deli::Adapters::Mongoid do
|
4
|
+
before do
|
5
|
+
Deli.configuration.default_adapter = :mongoid
|
6
|
+
@url = "http://site.com/search?title=Ruby+-'Hello+World'&created_at=t..2011-02-01&sort=created_at,title-&page=12&limit=20"
|
7
|
+
@params = {
|
8
|
+
:title => "Ruby+-'Hello+World'",
|
9
|
+
:created_at => "t..2011-02-01",
|
10
|
+
:sort => "created_at,title-",
|
11
|
+
:page => "12",
|
12
|
+
:limit => "20"
|
13
|
+
}.stringify_keys
|
14
|
+
|
15
|
+
@params.each do |k, v|
|
16
|
+
@params[k] = v.gsub("+", " ")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "definitions" do
|
21
|
+
before do
|
22
|
+
@controller = ::Deli::Controller.new(:user) do
|
23
|
+
match :title, :type => :string
|
24
|
+
match :created_at, :type => :datetime
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should render query" do
|
29
|
+
query = {
|
30
|
+
"page" => 12,
|
31
|
+
"sort" => [[:created_at, :asc], [:title, :desc]],
|
32
|
+
"limit" => 20,
|
33
|
+
"title" => {"$regex" => /(?i-mx:Ruby)|(?i-mx:(?!Hello World))/},
|
34
|
+
"created_at" => {"$lte" => Time.zone.parse("2011-02-01")}
|
35
|
+
}
|
36
|
+
|
37
|
+
@controller.render(@params).should == query
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/spec/neo4j_spec.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Deli::Adapters::Neo4j do
|
4
|
+
before do
|
5
|
+
Deli.configuration.default_adapter = :neo4j
|
6
|
+
@url = "http://site.com/search?title=Ruby+-'Hello+World'&created_at=t..2011-02-01&sort=created_at,title-&page=12&limit=20"
|
7
|
+
@params = {
|
8
|
+
:title => "Ruby+-'Hello+World'",
|
9
|
+
:created_at => "t..2011-02-01",
|
10
|
+
:sort => "created_at,title-",
|
11
|
+
:page => "12",
|
12
|
+
:limit => "20"
|
13
|
+
}.stringify_keys
|
14
|
+
|
15
|
+
@params.each do |k, v|
|
16
|
+
@params[k] = v.gsub("+", " ")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "definitions" do
|
21
|
+
before do
|
22
|
+
@controller = ::Deli::Controller.new(:user) do
|
23
|
+
match :title, :type => :string
|
24
|
+
match :created_at, :type => :datetime
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should render query" do
|
29
|
+
query = {
|
30
|
+
"page" => 12,
|
31
|
+
"sort" => [[:created_at, :asc], [:title, :desc]],
|
32
|
+
"limit" => 20,
|
33
|
+
"title" => {"$regex" => /(?i-mx:Ruby)|(?i-mx:(?!Hello World))/},
|
34
|
+
"created_at" => {"$lte" => Time.zone.parse("2011-02-01")}
|
35
|
+
}
|
36
|
+
|
37
|
+
@controller.render(@params).should == query
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/spec/param_spec.rb
ADDED
@@ -0,0 +1,318 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# ruby test/param_test.rb -n "/param:time/"
|
4
|
+
describe Deli::Param do
|
5
|
+
context "param:string" do
|
6
|
+
before do
|
7
|
+
::Deli::Param.send :include, ::Deli::Param::String
|
8
|
+
@param = ::Deli::Param.new(:title)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should parse a simple string" do
|
12
|
+
@param.parse("Hello World").should == [
|
13
|
+
[
|
14
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "Hello World"}
|
15
|
+
]
|
16
|
+
]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should split + into individual tokens" do
|
20
|
+
@param.parse("Hello+World").should == [
|
21
|
+
[
|
22
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "Hello"},
|
23
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "World"}
|
24
|
+
]
|
25
|
+
]
|
26
|
+
end
|
27
|
+
|
28
|
+
context "query for exact matches" do
|
29
|
+
it "should split single quotes ' into tokens" do
|
30
|
+
@param.parse("'Hello World'").should == [
|
31
|
+
[
|
32
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "Hello World"}
|
33
|
+
]
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should query for exact matches: split single quotes ' into tokens, even with + signs" do
|
38
|
+
@param.parse("'Hello+World'").should == [
|
39
|
+
[
|
40
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "Hello World"}
|
41
|
+
]
|
42
|
+
]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "query negations" do
|
47
|
+
it "should parse a simple string" do
|
48
|
+
@param.parse("-Hello+-World").should == [
|
49
|
+
[
|
50
|
+
{:namespace => nil, :key => "title", :operators => ["!~"], :value => "Hello"},
|
51
|
+
{:namespace => nil, :key => "title", :operators => ["!~"], :value => "World"}
|
52
|
+
]
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should not negate hyphenated phrases" do
|
57
|
+
@param.parse("Hello-World").should == [
|
58
|
+
[
|
59
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "Hello-World"}
|
60
|
+
]
|
61
|
+
]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "query OR" do
|
66
|
+
it "should parse a simple string with +OR+" do
|
67
|
+
@param.parse("Hello+OR+World").should == [
|
68
|
+
[{:namespace => nil, :key => "title", :operators => ["=~"], :value => "Hello"}],
|
69
|
+
[{:namespace => nil, :key => "title", :operators => ["=~"], :value => "World"}]
|
70
|
+
]
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should parse a complex string" do
|
74
|
+
@param.parse("Hello+World+OR+Query").should == [
|
75
|
+
[
|
76
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "Hello"},
|
77
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "World"}
|
78
|
+
],
|
79
|
+
[
|
80
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "Query"}
|
81
|
+
]
|
82
|
+
]
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should with single quotes" do
|
86
|
+
@param.parse("Hello+World+OR+'ruby+on+rails'").should == [
|
87
|
+
[
|
88
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "Hello"},
|
89
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "World"}
|
90
|
+
],
|
91
|
+
[
|
92
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "ruby on rails"}
|
93
|
+
]
|
94
|
+
]
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should with multiple on each side" do
|
98
|
+
@param.parse("Hello+World+OR+Ruby+JavaScript").should == [
|
99
|
+
[
|
100
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "Hello"},
|
101
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "World"}
|
102
|
+
],
|
103
|
+
[
|
104
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "Ruby"},
|
105
|
+
{:namespace => nil, :key => "title", :operators => ["=~"], :value => "JavaScript"}
|
106
|
+
]
|
107
|
+
]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "query start and end" do
|
112
|
+
it "should parse start match" do
|
113
|
+
@param.parse("^phone").should == [
|
114
|
+
[{:namespace => nil, :key => "title", :operators => ["=~", "^"], :value => "phone"}]
|
115
|
+
]
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should parse end match" do
|
119
|
+
@param.parse("phone$").should == [
|
120
|
+
[{:namespace => nil, :key => "title", :operators => ["=~", "$"], :value => "phone"}]
|
121
|
+
]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "handle special characters" do
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "param:number" do
|
131
|
+
before do
|
132
|
+
::Deli::Param.send :include, ::Deli::Param::Number
|
133
|
+
@param = ::Deli::Param.new(:login_count)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should parse single digit numbers" do
|
137
|
+
@param.parse("8").should == [
|
138
|
+
[{:namespace => nil, :key => "login_count", :operators => ["="], :value => 8}]
|
139
|
+
]
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should parse multiple digit numbers" do
|
143
|
+
@param.parse("1_920").should == [
|
144
|
+
[{:namespace => nil, :key => "login_count", :operators => ["="], :value => 1920}]
|
145
|
+
]
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should parse negative single digit numbers" do
|
149
|
+
@param.parse("-4").should == [
|
150
|
+
[{:namespace => nil, :key => "login_count", :operators => ["="], :value => -4}]
|
151
|
+
]
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
it "should parse negative multiple digit numbers" do
|
156
|
+
@param.parse("-470").should == [
|
157
|
+
[{:namespace => nil, :key => "login_count", :operators => ["="], :value => -470}]
|
158
|
+
]
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should parse range" do
|
162
|
+
@param.parse("3..21").should == [
|
163
|
+
[
|
164
|
+
{:namespace => nil, :key => "login_count", :operators => [">="], :value => 3},
|
165
|
+
{:namespace => nil, :key => "login_count", :operators => ["<="], :value => 21}
|
166
|
+
]
|
167
|
+
]
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should parse range with no end" do
|
171
|
+
@param.parse("3..n").should == [
|
172
|
+
[
|
173
|
+
{:namespace => nil, :key => "login_count", :operators => [">="], :value => 3}
|
174
|
+
]
|
175
|
+
]
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should parse range with no start" do
|
179
|
+
@param.parse("n..21").should == [
|
180
|
+
[
|
181
|
+
{:namespace => nil, :key => "login_count", :operators => ["<="], :value => 21}
|
182
|
+
]
|
183
|
+
]
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should parse multiple numbers with OR" do
|
187
|
+
@param.parse("10,1000").should == [
|
188
|
+
[{:namespace => nil, :key => "login_count", :operators => ["="], :value => 10}],
|
189
|
+
[{:namespace => nil, :key => "login_count", :operators => ["="], :value => 1000}]
|
190
|
+
]
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should parse multiple ranges with OR" do
|
194
|
+
@param.parse("1..10,100..1000").should == [
|
195
|
+
[
|
196
|
+
{:namespace => nil, :key => "login_count", :operators => [">="], :value => 1},
|
197
|
+
{:namespace => nil, :key => "login_count", :operators => ["<="], :value => 10}
|
198
|
+
],
|
199
|
+
[
|
200
|
+
{:namespace => nil, :key => "login_count", :operators => [">="], :value => 100},
|
201
|
+
{:namespace => nil, :key => "login_count", :operators => ["<="], :value => 1000}
|
202
|
+
]
|
203
|
+
]
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should parse multiple numbers with OR, along with a range" do
|
207
|
+
@param.parse("1,10,100..1000").should == [
|
208
|
+
[
|
209
|
+
{:namespace => nil, :key => "login_count", :operators => ["="], :value => 1}
|
210
|
+
],
|
211
|
+
[
|
212
|
+
{:namespace => nil, :key => "login_count", :operators => ["="], :value => 10}
|
213
|
+
],
|
214
|
+
[
|
215
|
+
{:namespace => nil, :key => "login_count", :operators => [">="], :value => 100},
|
216
|
+
{:namespace => nil, :key => "login_count", :operators => ["<="], :value => 1000}
|
217
|
+
]
|
218
|
+
]
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context "param:time" do
|
223
|
+
before do
|
224
|
+
::Deli::Param.send :include, ::Deli::Param::Time
|
225
|
+
@param = ::Deli::Param.new(:created_at)
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should parse single date" do
|
229
|
+
time = Time.zone.parse("2011-02-01") # feb 1, 2011
|
230
|
+
@param.parse("2011-02-01").should == [
|
231
|
+
[
|
232
|
+
{:namespace => nil, :key => "created_at", :operators => ["="], :value => time}
|
233
|
+
]
|
234
|
+
]
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should parse date range" do
|
238
|
+
starts_on = Time.zone.parse("2011-02-01")
|
239
|
+
ends_on = Time.zone.parse("2011-03-01")
|
240
|
+
@param.parse("2011-02-01..2011-03-01").should == [
|
241
|
+
[
|
242
|
+
{:namespace => nil, :key => "created_at", :operators => [">="], :value => starts_on},
|
243
|
+
{:namespace => nil, :key => "created_at", :operators => ["<="], :value => ends_on}
|
244
|
+
]
|
245
|
+
]
|
246
|
+
end
|
247
|
+
|
248
|
+
it "should parse date range with no end" do
|
249
|
+
starts_on = Time.zone.parse("2011-02-01")
|
250
|
+
@param.parse("2011-02-01..t").should == [
|
251
|
+
[
|
252
|
+
{:namespace => nil, :key => "created_at", :operators => [">="], :value => starts_on}
|
253
|
+
]
|
254
|
+
]
|
255
|
+
end
|
256
|
+
|
257
|
+
it "should parse date range with no start" do
|
258
|
+
ends_on = Time.zone.parse("2011-03-01")
|
259
|
+
@param.parse("t..2011-03-01").should == [
|
260
|
+
[
|
261
|
+
{:namespace => nil, :key => "created_at", :operators => ["<="], :value => ends_on}
|
262
|
+
]
|
263
|
+
]
|
264
|
+
end
|
265
|
+
|
266
|
+
it "should parse single time" do
|
267
|
+
time = Time.zone.parse("2011-12-25@2am") # christmas morning
|
268
|
+
@param.parse("2011-12-25@2am").should == [
|
269
|
+
[
|
270
|
+
{:namespace => nil, :key => "created_at", :operators => ["="], :value => time}
|
271
|
+
]
|
272
|
+
]
|
273
|
+
end
|
274
|
+
|
275
|
+
it "should parse single complex time" do
|
276
|
+
time = Time.zone.parse("2011-12-25@2:15:27am")
|
277
|
+
@param.parse("2011-12-25@2:15:27am").should == [
|
278
|
+
[
|
279
|
+
{:namespace => nil, :key => "created_at", :operators => ["="], :value => time}
|
280
|
+
]
|
281
|
+
]
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
# DATE
|
286
|
+
|
287
|
+
context "param:sort" do
|
288
|
+
before do
|
289
|
+
::Deli::Param.send :include, ::Deli::Param::Order
|
290
|
+
@param = ::Deli::Param.new(:sort)
|
291
|
+
end
|
292
|
+
|
293
|
+
it "should parse single sort param (defaults to ASC)" do
|
294
|
+
@param.parse("created_at").should == [
|
295
|
+
{:namespace => nil, :key => "created_at", :operators => ["+"]}
|
296
|
+
]
|
297
|
+
end
|
298
|
+
|
299
|
+
it "should parse single sort param DESC" do
|
300
|
+
@param.parse("created_at-").should == [
|
301
|
+
{:namespace => nil, :key => "created_at", :operators => ["-"]}
|
302
|
+
]
|
303
|
+
end
|
304
|
+
|
305
|
+
it "should parse single sort param ASC" do
|
306
|
+
@param.parse("created_at+").should == [
|
307
|
+
{:namespace => nil, :key => "created_at", :operators => ["+"]}
|
308
|
+
]
|
309
|
+
end
|
310
|
+
|
311
|
+
it "should parse mutiple sort params" do
|
312
|
+
@param.parse("created_at,name+").should == [
|
313
|
+
{:namespace => nil, :key => "created_at", :operators => ["+"]},
|
314
|
+
{:namespace => nil, :key => "name", :operators => ["+"]}
|
315
|
+
]
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
|
3
|
+
this = File.expand_path(File.dirname(__FILE__))
|
4
|
+
require File.expand_path(File.join(this, '/../lib/deli'))
|
5
|
+
|
6
|
+
require 'active_support/test_case'
|
7
|
+
require 'active_record'
|
8
|
+
require 'mongoid'
|
9
|
+
require 'rspec'
|
10
|
+
require 'faker'
|
11
|
+
require 'factory_girl'
|
12
|
+
require 'logger'
|
13
|
+
|
14
|
+
#ActiveRecord::Base.logger = Logger.new(STDOUT)
|
15
|
+
|
16
|
+
require File.join(this, "support/database")
|
17
|
+
require File.join(this, "support/models")
|
18
|
+
|
19
|
+
ActiveRecord::Base.send :extend, ::Deli::Pagination
|
20
|
+
|
21
|
+
Time.zone = "Central Time (US & Canada)"
|
22
|
+
|
23
|
+
ActiveRecord::Base.connection.class.class_eval do
|
24
|
+
IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /SHOW FIELDS/]
|
25
|
+
|
26
|
+
def execute_with_query_record(sql, name = nil, &block)
|
27
|
+
$queries_executed ||= []
|
28
|
+
$queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
|
29
|
+
execute_without_query_record(sql, name, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
alias_method_chain :execute, :query_record
|
33
|
+
end
|