activerecord-alt-mongo-adapter 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.
@@ -0,0 +1,585 @@
1
+ require 'rubygems'
2
+ require 'active_record'
3
+ require 'active_mongo/collection'
4
+ require 'mongo' # for test
5
+
6
+ # global setup ###############################################################
7
+
8
+ Mongo::Connection.new.drop_database('scott')
9
+ ActiveRecord::Base.establish_connection(:adapter => 'mongo', :database => 'scott')
10
+
11
+ # spec ########################################################################
12
+
13
+ describe ActiveMongo do
14
+ before do
15
+ Emp.setup
16
+ Dept.setup
17
+ end
18
+
19
+ it 'EMP: find(:all)' do
20
+ emps = Emp.find(:all).sort_by {|i| i.empno }
21
+ emps.length.should == Emp::DATA.length
22
+
23
+ emps.each_with_index do |emp, i|
24
+ emp.should == Emp::DATA[i]
25
+ end
26
+ end
27
+
28
+ it 'EMP: find multi cond' do
29
+ emps = Emp.find(:all, :conditions => ['job = ? and deptno > ?', 'MANAGER', 10], :order => 'empno')
30
+ expected = Emp::DATA.select {|i| i['job'] == 'MANAGER' and i['deptno'] > 10 }
31
+ emps.length.should == expected.length
32
+ emps.map {|i| i['empno'] }.should == expected.map {|i| i['empno'] }
33
+ end
34
+
35
+ it 'DEPT: find(:all)' do
36
+ depts = Dept.find(:all).sort_by {|i| i.deptno }
37
+ depts.length.should == Dept::DATA.length
38
+
39
+ depts.each_with_index do |dept, i|
40
+ dept.should == Dept::DATA[i]
41
+ end
42
+ end
43
+
44
+ it 'EMP: count' do
45
+ Emp.count.should == Emp::DATA.length
46
+ end
47
+
48
+ it 'DATA: count' do
49
+ Dept.count.should == Dept::DATA.length
50
+ end
51
+
52
+ it 'EMP: count with cond' do
53
+ Emp.count(:conditions => ['job = ?', 'MANAGER']).should == Emp::DATA.select {|i| i['job'] == 'MANAGER' }.length
54
+ end
55
+
56
+ it 'DATA: count with cond' do
57
+ Dept.count(:conditions => ['deptno >= ?', 30]).should == Dept::DATA.select {|i| i['deptno'] >= 30 }.length
58
+ end
59
+
60
+ it 'EMP: order asc' do
61
+ emps = Emp.find(:all, :conditions => {:job => 'MANAGER'}, :order => 'sal')
62
+ expected = Emp::DATA.select {|i| i['job'] == 'MANAGER' }.sort_by {|i| i['sal'] }
63
+ emps.map {|i| i['empno'] }.should == expected.map {|i| i['empno'] }
64
+
65
+ emps = Emp.find(:all, :conditions => {:job => 'SALESMAN'}, :order => 'sal asc')
66
+ expected = Emp::DATA.select {|i| i['job'] == 'SALESMAN' }.sort_by {|i| i['sal'] }
67
+ emps.map {|i| i['empno'] }.should == expected.map {|i| i['empno'] }
68
+ end
69
+
70
+ it 'DATA: order desc' do
71
+ depts = Dept.find(:all, :order => 'deptno desc')
72
+ expected = Dept::DATA.sort_by {|i| i['deptno'] }.reverse
73
+ depts.map {|i| i['deptno'] }.should == expected.map {|i| i['deptno'] }
74
+ end
75
+
76
+ it 'EMP: find limit' do
77
+ emps = Emp.find(:all, :limit => 5)
78
+ emps.length.should == 5
79
+ end
80
+
81
+ it 'DEPT: find limit' do
82
+ depts = Dept.find(:all, :limit => 3)
83
+ depts.length.should == 3
84
+ end
85
+
86
+ it 'EMP: find limit sort' do
87
+ emps = Emp.find(:all, :conditions => {:job => 'MANAGER'}, :limit => 2, :order => 'empno desc')
88
+ expected = Emp::DATA.select {|i| i['job'] == 'MANAGER' }.sort_by {|i| i['empno'] }.reverse.slice(0, 2)
89
+ emps.map {|i| i['empno'] }.should == expected.map {|i| i['empno'] }
90
+ end
91
+
92
+ it 'DEPT: count limit' do
93
+ Dept.count(:limit => 2).should == 2
94
+ end
95
+
96
+ it 'EMP: save' do
97
+ emp = Emp.find(:first, :conditions => ["empno = 7782"])
98
+ emp.should_not be_nil
99
+
100
+ emp.job = 'ANALYST'
101
+ emp.age = 48
102
+ emp.save.should be_true
103
+
104
+ emps = Emp.find(:all, :conditions => ["age = 48"])
105
+ emps.length.should == 1
106
+ emps[0].should_not be_nil
107
+ emps[0].empno.should == 7782
108
+ emps[0]['job'].should == 'ANALYST'
109
+ emps[0].age.should == 48
110
+ end
111
+
112
+ it 'DATA: update all' do
113
+ Dept.update_all('age = 20', ['deptno >= ?', 20])
114
+
115
+ Dept.find(:all).each do |dept|
116
+ if dept.deptno >= 20
117
+ dept.age.should == 20
118
+ end
119
+ end
120
+ end
121
+
122
+ it 'EMP: destroy' do
123
+ emp = Emp.find(:first, :conditions => ['empno = 7566'])
124
+ emp.destroy
125
+
126
+ emps = Emp.find(:all, :order => 'empno')
127
+ expected = Emp::DATA.select {|i| i['empno'] != 7566 }
128
+ emps.length.should == expected.length
129
+
130
+ emps.each_with_index do |emp, i|
131
+ emp.should == expected[i]
132
+ emp.empno.should_not == 7566
133
+ end
134
+ end
135
+
136
+ it 'EMP: destroy all' do
137
+ Emp.destroy_all(['job = ?', 'SALESMAN'])
138
+
139
+ emps = Emp.find(:all, :order => 'empno')
140
+ expected = Emp::DATA.select {|i| i['job'] != 'SALESMAN' }
141
+ emps.length.should == expected.length
142
+
143
+ emps.each_with_index do |emp, i|
144
+ emp.should == expected[i]
145
+ emp.job.should_not == 'SALESMAN'
146
+ end
147
+ end
148
+
149
+ it 'DEPT: delete all' do
150
+ Dept.delete_all(['deptno > 20'])
151
+
152
+ depts = Dept.find(:all, :order => 'deptno')
153
+ expected = Dept::DATA.select {|i| not i['deptno'] > 20 }
154
+ depts.length.should == expected.length
155
+
156
+ depts.each_with_index do |dept, i|
157
+ dept.should == expected[i]
158
+ dept.deptno.should_not > 20
159
+ end
160
+ end
161
+
162
+ it 'EMP: new' do
163
+ emp1 = Emp.new
164
+ emp1.empno = 1
165
+ emp1.foo = 'bar'
166
+ emp1.zoo = 'baz'
167
+ emp1.save.should be_true
168
+
169
+ emp2 = Emp.new
170
+ emp2.empno = 2
171
+ emp2.hoge = 'fuga'
172
+ emp2.hogera = 'hogehoge'
173
+ emp2.save!
174
+
175
+ emps = Emp.find(:all, :order => 'empno')
176
+ emps.length.should == Emp::DATA.length + 2
177
+
178
+ emps.each_with_index do |emp, i|
179
+ case emp.empno
180
+ when 1
181
+ emp = emp.attributes
182
+ emp.delete('id').should_not be_nil
183
+ emp.delete('_id').should_not be_nil
184
+ emp.should == { 'empno' => 1, 'foo' => 'bar', 'zoo' => 'baz' }
185
+ when 2
186
+ emp = emp.attributes
187
+ emp.delete('id').should_not be_nil
188
+ emp.delete('_id').should_not be_nil
189
+ emp.should == { 'empno' => 2, 'hoge' => 'fuga', 'hogera' => 'hogehoge' }
190
+ else
191
+ emp.should == Emp::DATA[i - 2]
192
+ end
193
+ end
194
+ end
195
+
196
+ it 'DEPT: create' do
197
+ Dept.create(
198
+ :deptno => 1,
199
+ :foo => 'bar',
200
+ :zoo => 'baz'
201
+ ).should be_true
202
+
203
+ Dept.create!(
204
+ :deptno => 2,
205
+ :hoge => 'fuga',
206
+ :hogera => 'hogehoge'
207
+ )
208
+
209
+ depts = Dept.find(:all, :order => 'deptno')
210
+ depts.length.should == Dept::DATA.length + 2
211
+
212
+ depts.each_with_index do |dept, i|
213
+ case dept.deptno
214
+ when 1
215
+ dept = dept.attributes
216
+ dept.delete('id').should_not be_nil
217
+ dept.delete('_id').should_not be_nil
218
+ dept.should == { 'deptno' => 1, 'foo' => 'bar', 'zoo' => 'baz' }
219
+ when 2
220
+ dept = dept.attributes
221
+ dept.delete('id').should_not be_nil
222
+ dept.delete('_id').should_not be_nil
223
+ dept.should == { 'deptno' => 2, 'hoge' => 'fuga', 'hogera' => 'hogehoge' }
224
+ else
225
+ dept.should == Dept::DATA[i - 2]
226
+ end
227
+ end
228
+ end
229
+
230
+ it 'EMP: not' do
231
+ emps = Emp.find(:all, :conditions => ['not empno = 7566'], :order => 'empno')
232
+ expected = Emp::DATA.select {|i| i['empno'] != 7566 }
233
+ emps.length.should == expected.length
234
+
235
+ emps.each_with_index do |emp, i|
236
+ emp.should == expected[i]
237
+ emp.empno.should_not == 7566
238
+ end
239
+ end
240
+
241
+ it 'EMP: not ne' do
242
+ emps = Emp.find(:all, :conditions => ['not empno <> 7566'], :order => 'empno')
243
+ expected = Emp::DATA.select {|i| i['empno'] == 7566 }
244
+ emps.length.should == expected.length
245
+
246
+ emps.each_with_index do |emp, i|
247
+ emp.should == expected[i]
248
+ emp.empno.should == 7566
249
+ end
250
+ end
251
+
252
+ it 'EMP: regexp' do
253
+ emps = Emp.find(:all, :conditions => ['job regexp ?', 'LE'], :order => 'empno')
254
+ expected = Emp::DATA.select {|i| i['job'] =~ /LE/ }
255
+ emps.length.should == expected.length
256
+
257
+ emps.each_with_index do |emp, i|
258
+ emp.should == expected[i]
259
+ end
260
+ end
261
+
262
+ it 'EMP: not regexp' do
263
+ emps = Emp.find(:all, :conditions => ['not job regexp ?', 'LE'], :order => 'empno')
264
+ expected = Emp::DATA.select {|i| i['job'] !~ /LE/ }
265
+ emps.length.should == expected.length
266
+
267
+ emps.each_with_index do |emp, i|
268
+ emp.should == expected[i]
269
+ end
270
+ end
271
+
272
+ it 'EMP: find limit offset' do
273
+ emps = Emp.find(:all, :limit => 3, :offset => 5, :order => 'empno')
274
+ expected = Emp::DATA.slice(5..7)
275
+ emps.length.should == expected.length
276
+
277
+ emps.each_with_index do |emp, i|
278
+ emp.should == expected[i]
279
+ end
280
+ end
281
+
282
+ it 'DEPT: find conds' do
283
+ depts = Dept.find(:all, :conditions => ['deptno >= ? and deptno < ?', 20, 40], :order => 'deptno')
284
+ expected = Dept::DATA.select {|i| i['deptno'] >= 20 and i['deptno'] < 40 }
285
+ depts.length.should == expected.length
286
+
287
+ depts.each_with_index do |dept, i|
288
+ dept.should == expected[i]
289
+ end
290
+ end
291
+
292
+ it 'DEPT: find between' do
293
+ depts = Dept.find(:all, :conditions => ['deptno between ? and ?', 20, 40], :order => 'deptno')
294
+ expected = Dept::DATA.select {|i| 20 <= i['deptno'] and i['deptno'] <= 40 }
295
+ depts.length.should == expected.length
296
+
297
+ depts.each_with_index do |dept, i|
298
+ dept.should == expected[i]
299
+ end
300
+ end
301
+
302
+ it 'EMP: find distinct' do
303
+ emps = Emp.find(:all, :select => 'distinct job').sort_by {|i| i['job'] }
304
+ expected = Emp::DATA.map {|i| i['job'] }.sort.uniq
305
+ emps.length.should == expected.length
306
+
307
+ emps.each_with_index do |emp, i|
308
+ emp.job.should == expected[i]
309
+ end
310
+ end
311
+
312
+ it 'EMP: collection' do
313
+ actual = {}
314
+ coll = Emp.collection
315
+
316
+ m =<<-EOS
317
+ function() {
318
+ emit(this.job, 1);
319
+ }
320
+ EOS
321
+
322
+ r =<<-EOS
323
+ function(k, vals) {
324
+ var sum = 0;
325
+
326
+ for(var i in vals) {
327
+ sum += vals[i];
328
+ }
329
+
330
+ return sum;
331
+ }
332
+ EOS
333
+
334
+ coll.map_reduce(m, r).find.each do |i|
335
+ actual[i['_id']] = i['value'].to_i
336
+ end
337
+
338
+ actual.should == {
339
+ 'ANALYST' => 2,
340
+ 'CLERK' => 4,
341
+ 'MANAGER' => 3,
342
+ 'PRESIDENT' => 1,
343
+ 'SALESMAN' => 4
344
+ }
345
+ end
346
+
347
+ it 'EMP: collection with block' do
348
+ actual = {}
349
+
350
+ Emp.collection do |coll|
351
+ m =<<-EOS
352
+ function() {
353
+ emit(this.job, 1);
354
+ }
355
+ EOS
356
+
357
+ r =<<-EOS
358
+ function(k, vals) {
359
+ var sum = 0;
360
+
361
+ for(var i in vals) {
362
+ sum += vals[i];
363
+ }
364
+
365
+ return sum;
366
+ }
367
+ EOS
368
+
369
+ coll.map_reduce(m, r).find.each do |i|
370
+ actual[i['_id']] = i['value'].to_i
371
+ end
372
+ end
373
+
374
+ actual.should == {
375
+ 'ANALYST' => 2,
376
+ 'CLERK' => 4,
377
+ 'MANAGER' => 3,
378
+ 'PRESIDENT' => 1,
379
+ 'SALESMAN' => 4
380
+ }
381
+ end
382
+
383
+ it 'EMP: in' do
384
+ # String
385
+ emps = Emp.find(:all, :conditions => ['job in (?)', ['SALESMAN', 'MANAGER']], :order => 'empno')
386
+ expected = Emp::DATA.select {|i| ['SALESMAN', 'MANAGER'].include?(i['job']) }
387
+ emps.length.should == expected.length
388
+
389
+ emps.each_with_index do |emp, i|
390
+ emp.should == expected[i]
391
+ end
392
+
393
+ # Hash
394
+ emps = Emp.find(:all, :conditions => {:job => ['SALESMAN', 'MANAGER']}, :order => 'empno')
395
+ expected = Emp::DATA.select {|i| ['SALESMAN', 'MANAGER'].include?(i['job']) }
396
+ emps.length.should == expected.length
397
+
398
+ emps.each_with_index do |emp, i|
399
+ emp.should == expected[i]
400
+ end
401
+ end
402
+
403
+ it 'EMP: not in' do
404
+ emps = Emp.find(:all, :conditions => ['job not in (?)', ['SALESMAN', 'MANAGER']], :order => 'empno')
405
+ expected = Emp::DATA.select {|i| not ['SALESMAN', 'MANAGER'].include?(i['job']) }
406
+ emps.length.should == expected.length
407
+
408
+ emps.each_with_index do |emp, i|
409
+ emp.should == expected[i]
410
+ end
411
+ end
412
+
413
+ it 'EMP: mod' do
414
+ emps = Emp.find(:all, :conditions => ['empno mod (?)', [2, 0]], :order => 'empno')
415
+ expected = Emp::DATA.select {|i| (i['empno'] % 2) == 0 }
416
+ emps.length.should == expected.length
417
+
418
+ emps.each_with_index do |emp, i|
419
+ emp.should == expected[i]
420
+ end
421
+ end
422
+
423
+ it 'EMP: not mod' do
424
+ emps = Emp.find(:all, :conditions => ['not empno mod (?)', [2, 0]], :order => 'empno')
425
+ expected = Emp::DATA.select {|i| (i['empno'] % 2) != 0 }
426
+ emps.length.should == expected.length
427
+
428
+ emps.each_with_index do |emp, i|
429
+ emp.should == expected[i]
430
+ end
431
+ end
432
+
433
+ it 'DEPT: exists true' do
434
+ Dept.create(
435
+ :deptno => 1,
436
+ :foo => 'bar',
437
+ :zoo => 'baz'
438
+ ).should be_true
439
+
440
+ Dept.create!(
441
+ :deptno => 2,
442
+ :hoge => 'fuga',
443
+ :hogera => 'hogehoge'
444
+ )
445
+
446
+ depts = Dept.find(:all, :conditions => ['foo exists ?', true])
447
+ depts.length.should == 1
448
+ depts[0].deptno.should == 1
449
+ end
450
+
451
+ it 'DEPT: exists false' do
452
+ Dept.create(
453
+ :deptno => 1,
454
+ :foo => 'bar',
455
+ :zoo => 'baz'
456
+ ).should be_true
457
+
458
+ Dept.create!(
459
+ :deptno => 2,
460
+ :hoge => 'fuga',
461
+ :hogera => 'hogehoge'
462
+ )
463
+
464
+ depts = Dept.find(:all, :conditions => ['foo exists ?', false], :order => 'deptno')
465
+ depts.length.should == Dept::DATA.length + 1
466
+ depts.map {|i| i['deptno'] }.should == [2] + Dept::DATA.map {|i| i['deptno'] }
467
+ end
468
+
469
+ it 'DEPT: not exists' do
470
+ Dept.create(
471
+ :deptno => 1,
472
+ :foo => 'bar',
473
+ :zoo => 'baz'
474
+ ).should be_true
475
+
476
+ Dept.create!(
477
+ :deptno => 2,
478
+ :hoge => 'fuga',
479
+ :hogera => 'hogehoge'
480
+ )
481
+
482
+ depts = Dept.find(:all, :conditions => ['not foo exists ?', true], :order => 'deptno')
483
+ depts.length.should == Dept::DATA.length + 1
484
+ depts.map {|i| i['deptno'] }.should == [2] + Dept::DATA.map {|i| i['deptno'] }
485
+ end
486
+
487
+ it 'examples' do
488
+ emp = Emp.find(:first,
489
+ :conditions => ["job = ? and sal >= ?", "MANAGER", 2800],
490
+ :order => 'sal desc', :limit => 3, :offset => 1)
491
+
492
+ p emp.id #=> 4bb795e8f15d3d0324000006
493
+ emp.age = 30
494
+ emp.save
495
+
496
+ emp_list = Emp.find(:all, :conditions => {:empno => [7654, 7698, 7782]})
497
+
498
+ emp_list.each do |i|
499
+ i.destroy if i.sal < 2000
500
+ end
501
+
502
+ new_emp = Emp.new
503
+ new_emp.empno = 8000
504
+ new_emp.ename = 'YAMADA'
505
+ new_emp.age = 27
506
+ new_emp.save!
507
+ end
508
+
509
+ after do
510
+ Emp.teardown
511
+ Dept.teardown
512
+ end
513
+ end
514
+
515
+ # model #######################################################################
516
+
517
+ class Emp < ActiveRecord::Base
518
+ include ActiveMongo::Collection
519
+
520
+ NAMES = %w(empno ename job mgr hiredate sal comm deptno)
521
+
522
+ DATA = [
523
+ [7369, 'SMITH' , 'CLERK' , 7902, '17-DEC-1980', 800.0, nil, 20],
524
+ [7499, 'ALLEN' , 'SALESMAN' , 7698, '20-FEB-1981', 1600.0, 300.0, 30],
525
+ [7521, 'WARD' , 'SALESMAN' , 7698, '22-FEB-1981', 1250.0, 500.0, 30],
526
+ [7566, 'JONES' , 'MANAGER' , 7839, '2-APR-1981' , 2975.0, nil, 20],
527
+ [7654, 'MARTIN' , 'SALESMAN' , 7698, '28-SEP-1981', 1250.1, 1400.0, 30],
528
+ [7698, 'BLAKE' , 'MANAGER' , 7839, '1-MAY-1981' , 2850.0, nil, 30],
529
+ [7782, 'CLARK' , 'MANAGER' , 7839, '9-JUN-1981' , 2450.0, nil, 10],
530
+ [7788, 'SCOTT' , 'ANALYST' , 7566, '09-DEC-1982', 3000.0, nil, 20],
531
+ [7839, 'KING' , 'PRESIDENT' , nil, '17-NOV-1981', 5000.0, nil, 10],
532
+ [7844, 'TURNER' , 'SALESMAN' , 7698, '8-SEP-1981' , 1500.0, 0.0, 30],
533
+ [7876, 'ADAMS' , 'CLERK' , 7788, '12-JAN-1983', 1100.0, nil, 20],
534
+ [7900, 'JAMES' , 'CLERK' , 7698, '3-DEC-1981' , 950.0, nil, 30],
535
+ [7902, 'FORD' , 'ANALYST' , 7566, '3-DEC-1981' , 3000.0, nil, 20],
536
+ [7934, 'MILLER' , 'CLERK' , 7782, '23-JAN-1982', 1300.0, nil, 10],
537
+ ].map {|i| Hash[*NAMES.zip(i).flatten] }
538
+
539
+ def self.setup
540
+ db = connection.raw_connection
541
+ coll = db.collection(table_name)
542
+ DATA.each {|doc| coll.insert(doc) }
543
+ end
544
+
545
+ def self.teardown
546
+ db = connection.raw_connection
547
+ db.drop_collection(table_name)
548
+ end
549
+
550
+ def ==(obj)
551
+ NAMES.all? do |name|
552
+ self.send(name) == obj[name] and self[name] == obj[name]
553
+ end
554
+ end
555
+ end
556
+
557
+ class Dept < ActiveRecord::Base
558
+ include ActiveMongo::Collection
559
+
560
+ NAMES = %w(deptno dname loc)
561
+
562
+ DATA = [
563
+ [10, 'ACCOUNTING', 'NEW YORK'],
564
+ [20, 'RESEARCH' , 'DALLAS' ],
565
+ [30, 'SALES' , 'CHICAGO' ],
566
+ [40, 'OPERATIONS', 'BOSTON' ],
567
+ ].map {|i| Hash[*NAMES.zip(i).flatten] }
568
+
569
+ def self.setup
570
+ db = connection.raw_connection
571
+ coll = db.collection(table_name)
572
+ DATA.each {|doc| coll.insert(doc) }
573
+ end
574
+
575
+ def self.teardown
576
+ db = connection.raw_connection
577
+ db.drop_collection(table_name)
578
+ end
579
+
580
+ def ==(obj)
581
+ NAMES.all? do |name|
582
+ self.send(name) == obj[name] and self[name] == obj[name]
583
+ end
584
+ end
585
+ end