rufus-doric 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +8 -0
- data/TODO.txt +7 -4
- data/lib/rufus/doric/model.rb +92 -36
- data/lib/rufus/doric/models.rb +1 -1
- data/lib/rufus/doric/version.rb +1 -1
- data/rufus-doric.gemspec +5 -2
- data/test/ut_14_model_default_id.rb +46 -0
- data/test/ut_15_model_view_by_and.rb +64 -0
- data/test/ut_16_model_custom_view.rb +70 -0
- metadata +6 -3
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
= rufus-doric CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-doric - 0.1.7 released 2010/04/16
|
6
|
+
|
7
|
+
- view_by 'tysec', "emit(doc.type + '__' + doc.security_level, null);"
|
8
|
+
- model : view_by [ :x, :y ] => view_by_x_and_y
|
9
|
+
- neutralize_id(i) now turns dots to underscores as well
|
10
|
+
- model : default _id generator (when no _id_field specified)
|
11
|
+
|
12
|
+
|
5
13
|
== rufus-doric - 0.1.6 released 2010/04/14
|
6
14
|
|
7
15
|
- property :sold, :default => false was not working. Fixed.
|
data/TODO.txt
CHANGED
@@ -3,12 +3,15 @@
|
|
3
3
|
[o] model : validation
|
4
4
|
[o] destroy/delete
|
5
5
|
[o] fix Amedeo's infinite loop (model.rb l438)
|
6
|
+
[o] all, by : limit and skip (pagination)
|
7
|
+
[o] pagination for everybody in Model (DRY)
|
8
|
+
[o] eventually : pagination for the text index
|
6
9
|
|
7
10
|
[x] lsof check (jig / patron)
|
8
11
|
|
9
|
-
[ ] all, by : limit and skip (pagination)
|
10
|
-
|
11
12
|
[ ] eventually : cache the text index
|
12
|
-
|
13
|
-
[ ]
|
13
|
+
|
14
|
+
[ ] view_by 'name' do
|
15
|
+
%{ emit(doc.nada) }
|
16
|
+
end
|
14
17
|
|
data/lib/rufus/doric/model.rb
CHANGED
@@ -103,16 +103,28 @@ module Doric
|
|
103
103
|
@_id_field
|
104
104
|
end
|
105
105
|
|
106
|
-
def self.view_by (key)
|
106
|
+
def self.view_by (key, func=nil)
|
107
107
|
|
108
|
-
|
109
|
-
@keys << key.to_s
|
108
|
+
if func
|
110
109
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
110
|
+
k = { key => func }
|
111
|
+
|
112
|
+
instance_eval %{
|
113
|
+
def by_#{key} (val, opts={})
|
114
|
+
by(#{k.inspect}, val, opts)
|
115
|
+
end
|
116
|
+
}
|
117
|
+
|
118
|
+
else
|
119
|
+
|
120
|
+
skey = key.is_a?(Array) ? key.join('_and_') : key
|
121
|
+
|
122
|
+
instance_eval %{
|
123
|
+
def by_#{skey} (val, opts={})
|
124
|
+
by(#{key.inspect}, val, opts)
|
125
|
+
end
|
126
|
+
}
|
127
|
+
end
|
116
128
|
end
|
117
129
|
|
118
130
|
def self.text_index (*keys)
|
@@ -164,15 +176,22 @@ module Doric
|
|
164
176
|
|
165
177
|
raise ActiveRecord::RecordInvalid.new(self) unless valid?
|
166
178
|
|
167
|
-
if @h['_id'].nil?
|
179
|
+
if @h['_id'].nil?
|
180
|
+
|
181
|
+
if self.class._id_field
|
182
|
+
|
183
|
+
@h['_id'] = if self.class._id_field.is_a?(String)
|
184
|
+
self.send(self.class._id_field)
|
185
|
+
else
|
186
|
+
self.instance_eval(&self.class._id_field)
|
187
|
+
end
|
168
188
|
|
169
|
-
i = if self.class._id_field.is_a?(String)
|
170
|
-
self.send(self.class._id_field)
|
171
189
|
else
|
172
|
-
|
190
|
+
|
191
|
+
@h['_id'] = generate_id
|
173
192
|
end
|
174
193
|
|
175
|
-
@h['_id'] = Rufus::Doric.neutralize_id(
|
194
|
+
@h['_id'] = Rufus::Doric.neutralize_id(@h['_id'])
|
176
195
|
end
|
177
196
|
|
178
197
|
raise ActiveRecord::RecordInvalid.new(self) if @h['_id'].nil?
|
@@ -402,6 +421,27 @@ module Doric
|
|
402
421
|
|
403
422
|
protected
|
404
423
|
|
424
|
+
# When there is no _id_field specified, this id generation routine
|
425
|
+
# is used.
|
426
|
+
#
|
427
|
+
def generate_id
|
428
|
+
|
429
|
+
s = [
|
430
|
+
$$, Thread.current.object_id, self.object_id, Time.now.to_f.to_s
|
431
|
+
].join('_')
|
432
|
+
|
433
|
+
"#{self.class.doric_type}__#{s}"
|
434
|
+
end
|
435
|
+
|
436
|
+
def self.func (body)
|
437
|
+
%{
|
438
|
+
function (doc) {
|
439
|
+
if (doc.doric_type != '#{@doric_type}') return;
|
440
|
+
#{body}
|
441
|
+
}
|
442
|
+
}
|
443
|
+
end
|
444
|
+
|
405
445
|
def self.put_design_doc (key=nil)
|
406
446
|
|
407
447
|
# the 'all' view
|
@@ -423,32 +463,42 @@ module Doric
|
|
423
463
|
# done on the client side
|
424
464
|
|
425
465
|
ddoc['views']['text_index'] = {
|
426
|
-
'map' => %{
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
if (word != '') emit(word, null);
|
436
|
-
});
|
437
|
-
}
|
438
|
-
}
|
466
|
+
'map' => func(%{
|
467
|
+
var keys = #{Rufus::Json.encode(@text_index)};
|
468
|
+
for (var key in doc) {
|
469
|
+
if (keys.indexOf(key) < 0) continue;
|
470
|
+
if (doc[key] == undefined) continue;
|
471
|
+
var words = doc[key].split(/[\s,;\.]/);
|
472
|
+
words.forEach(function (word) {
|
473
|
+
if (word != '') emit(word, null);
|
474
|
+
});
|
439
475
|
}
|
440
|
-
}
|
476
|
+
})
|
477
|
+
}
|
478
|
+
|
479
|
+
elsif key.is_a?(Hash)
|
480
|
+
|
481
|
+
ddoc['views']["by_#{key.keys.first}"] = {
|
482
|
+
'map' => func(key.values.first)
|
483
|
+
}
|
484
|
+
|
485
|
+
elsif key.is_a?(Array)
|
486
|
+
|
487
|
+
skey = key.join('_and_')
|
488
|
+
keys = key.collect { |k| "doc['#{k}']" }.join(', ')
|
489
|
+
|
490
|
+
ddoc['views']["by_#{skey}"] = {
|
491
|
+
'map' => func(%{
|
492
|
+
emit([#{keys}], null);
|
493
|
+
})
|
441
494
|
}
|
495
|
+
|
442
496
|
else
|
443
497
|
|
444
498
|
ddoc['views']["by_#{key}"] = {
|
445
|
-
'map' => %{
|
446
|
-
|
447
|
-
|
448
|
-
emit(doc['#{key}'], null);
|
449
|
-
}
|
450
|
-
}
|
451
|
-
}
|
499
|
+
'map' => func(%{
|
500
|
+
emit(doc['#{key}'], null);
|
501
|
+
})
|
452
502
|
}
|
453
503
|
end
|
454
504
|
|
@@ -488,7 +538,7 @@ module Doric
|
|
488
538
|
|
489
539
|
qs = [ 'include_docs=true' ]
|
490
540
|
|
491
|
-
if val.is_a?(Array)
|
541
|
+
if val.is_a?(Array) && ( ! key.is_a?(Array))
|
492
542
|
|
493
543
|
st, en = val
|
494
544
|
qs << "startkey=#{Rufus::Doric.escape(st)}" if st
|
@@ -500,7 +550,13 @@ module Doric
|
|
500
550
|
|
501
551
|
add_common_options(qs, opts)
|
502
552
|
|
503
|
-
|
553
|
+
skey = case key
|
554
|
+
when Array then key.join('_and_')
|
555
|
+
when Hash then key.keys.first
|
556
|
+
else key
|
557
|
+
end
|
558
|
+
|
559
|
+
path = "#{design_path}/_view/by_#{skey}?#{qs.join('&')}"
|
504
560
|
|
505
561
|
result = get_result(path, key)
|
506
562
|
|
data/lib/rufus/doric/models.rb
CHANGED
data/lib/rufus/doric/version.rb
CHANGED
data/rufus-doric.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rufus-doric}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.7"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["John Mettraux"]
|
12
|
-
s.date = %q{2010-04-
|
12
|
+
s.date = %q{2010-04-16}
|
13
13
|
s.description = %q{
|
14
14
|
something at the intersection of Rails3, CouchDB and rufus-jig
|
15
15
|
}
|
@@ -50,6 +50,9 @@ something at the intersection of Rails3, CouchDB and rufus-jig
|
|
50
50
|
"test/ut_11_model_view_range.rb",
|
51
51
|
"test/ut_12_model_default.rb",
|
52
52
|
"test/ut_13_one_doc_model_default.rb",
|
53
|
+
"test/ut_14_model_default_id.rb",
|
54
|
+
"test/ut_15_model_view_by_and.rb",
|
55
|
+
"test/ut_16_model_custom_view.rb",
|
53
56
|
"test/ut_1_model.rb",
|
54
57
|
"test/ut_2_model_view.rb",
|
55
58
|
"test/ut_3_model_lint.rb",
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# testing rufus-doric
|
4
|
+
#
|
5
|
+
# Thu Apr 15 15:31:51 JST 2010
|
6
|
+
#
|
7
|
+
|
8
|
+
require File.join(File.dirname(__FILE__), 'base')
|
9
|
+
|
10
|
+
require 'rufus/doric'
|
11
|
+
|
12
|
+
|
13
|
+
class Unknown < Rufus::Doric::Model
|
14
|
+
|
15
|
+
db :doric
|
16
|
+
doric_type :unknowns
|
17
|
+
|
18
|
+
#_id_field :serial
|
19
|
+
|
20
|
+
h_accessor :name
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
class UtModelDefaultTest < Test::Unit::TestCase
|
25
|
+
|
26
|
+
def setup
|
27
|
+
|
28
|
+
Rufus::Doric.db('doric').delete('.')
|
29
|
+
Rufus::Doric.db('doric').put('.')
|
30
|
+
|
31
|
+
Rufus::Doric.db('doric').http.cache.clear
|
32
|
+
# CouchDB feeds the same etags for views, even after a db has
|
33
|
+
# been deleted and put back, so have to do that 'forgetting'
|
34
|
+
end
|
35
|
+
|
36
|
+
#def teardown
|
37
|
+
#end
|
38
|
+
|
39
|
+
def test_default_id
|
40
|
+
|
41
|
+
Unknown.new(:name => 'nemo').save!
|
42
|
+
|
43
|
+
assert_equal 1, Unknown.all.size
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# testing rufus-doric
|
4
|
+
#
|
5
|
+
# Fri Apr 16 13:46:53 JST 2010
|
6
|
+
#
|
7
|
+
|
8
|
+
require File.join(File.dirname(__FILE__), 'base')
|
9
|
+
|
10
|
+
require 'rufus/doric'
|
11
|
+
|
12
|
+
|
13
|
+
class Squad < Rufus::Doric::Model
|
14
|
+
|
15
|
+
db :doric
|
16
|
+
doric_type :squads
|
17
|
+
|
18
|
+
h_accessor :type
|
19
|
+
h_accessor :ranking
|
20
|
+
|
21
|
+
view_by :ranking
|
22
|
+
view_by [ :type, :ranking ]
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
class UtModelViewByAndTest < Test::Unit::TestCase
|
27
|
+
|
28
|
+
def setup
|
29
|
+
|
30
|
+
Rufus::Doric.db('doric').delete('.')
|
31
|
+
Rufus::Doric.db('doric').put('.')
|
32
|
+
|
33
|
+
Rufus::Doric.db('doric').http.cache.clear
|
34
|
+
# CouchDB feeds the same etags for views, even after a db has
|
35
|
+
# been deleted and put back, so have to do that 'forgetting'
|
36
|
+
end
|
37
|
+
|
38
|
+
#def teardown
|
39
|
+
#end
|
40
|
+
|
41
|
+
def test_view_by_and
|
42
|
+
|
43
|
+
Squad.new(
|
44
|
+
'type' => 'rifle',
|
45
|
+
'ranking' => 'first'
|
46
|
+
).save!
|
47
|
+
Squad.new(
|
48
|
+
'type' => 'rifle',
|
49
|
+
'ranking' => 'first'
|
50
|
+
).save!
|
51
|
+
Squad.new(
|
52
|
+
'type' => 'artillery',
|
53
|
+
'ranking' => 'second'
|
54
|
+
).save!
|
55
|
+
Squad.new(
|
56
|
+
'type' => 'artillery',
|
57
|
+
'ranking' => 'first'
|
58
|
+
).save!
|
59
|
+
|
60
|
+
assert_equal 2, Squad.by_type_and_ranking([ 'rifle', 'first' ]).size
|
61
|
+
assert_equal 3, Squad.by_ranking('first').size
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# testing rufus-doric
|
4
|
+
#
|
5
|
+
# Fri Apr 16 15:19:46 JST 2010
|
6
|
+
#
|
7
|
+
|
8
|
+
require File.join(File.dirname(__FILE__), 'base')
|
9
|
+
|
10
|
+
require 'rufus/doric'
|
11
|
+
|
12
|
+
|
13
|
+
class Team < Rufus::Doric::Model
|
14
|
+
|
15
|
+
db :doric
|
16
|
+
doric_type :teams
|
17
|
+
|
18
|
+
h_accessor :type
|
19
|
+
h_accessor :security_level
|
20
|
+
h_accessor :headcount
|
21
|
+
|
22
|
+
view_by 'tysec', %{
|
23
|
+
emit(doc.type + '__' + doc.security_level, null);
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
class UtModelCustomViewTest < Test::Unit::TestCase
|
29
|
+
|
30
|
+
def setup
|
31
|
+
|
32
|
+
Rufus::Doric.db('doric').delete('.')
|
33
|
+
Rufus::Doric.db('doric').put('.')
|
34
|
+
|
35
|
+
Rufus::Doric.db('doric').http.cache.clear
|
36
|
+
# CouchDB feeds the same etags for views, even after a db has
|
37
|
+
# been deleted and put back, so have to do that 'forgetting'
|
38
|
+
end
|
39
|
+
|
40
|
+
#def teardown
|
41
|
+
#end
|
42
|
+
|
43
|
+
def test_view_by_and
|
44
|
+
|
45
|
+
Team.new(
|
46
|
+
'type' => 'rifle',
|
47
|
+
'security_level' => 'a'
|
48
|
+
).save!
|
49
|
+
Team.new(
|
50
|
+
'type' => 'rifle',
|
51
|
+
'security_level' => 'a'
|
52
|
+
).save!
|
53
|
+
Team.new(
|
54
|
+
'type' => 'rifle',
|
55
|
+
'security_level' => 'b'
|
56
|
+
).save!
|
57
|
+
Team.new(
|
58
|
+
'type' => 'artillery',
|
59
|
+
'security_level' => 'a'
|
60
|
+
).save!
|
61
|
+
Team.new(
|
62
|
+
'type' => 'artillery',
|
63
|
+
'security_level' => 'c'
|
64
|
+
).save!
|
65
|
+
|
66
|
+
assert_equal 2, Team.by_tysec('rifle__a').size
|
67
|
+
assert_equal 1, Team.by_tysec('rifle__b').size
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 7
|
9
|
+
version: 0.1.7
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- John Mettraux
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-16 00:00:00 +09:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -137,6 +137,9 @@ files:
|
|
137
137
|
- test/ut_11_model_view_range.rb
|
138
138
|
- test/ut_12_model_default.rb
|
139
139
|
- test/ut_13_one_doc_model_default.rb
|
140
|
+
- test/ut_14_model_default_id.rb
|
141
|
+
- test/ut_15_model_view_by_and.rb
|
142
|
+
- test/ut_16_model_custom_view.rb
|
140
143
|
- test/ut_1_model.rb
|
141
144
|
- test/ut_2_model_view.rb
|
142
145
|
- test/ut_3_model_lint.rb
|