rufus-doric 0.1.6 → 0.1.7

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/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
- [ ] eventually : pagination for the text index
13
- [ ] pagination for everybody in Model (DRY)
13
+
14
+ [ ] view_by 'name' do
15
+ %{ emit(doc.nada) }
16
+ end
14
17
 
@@ -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
- @keys ||= []
109
- @keys << key.to_s
108
+ if func
110
109
 
111
- instance_eval %{
112
- def by_#{key} (val, opts={})
113
- by('#{key}', val, opts)
114
- end
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? && self.class._id_field
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
- self.instance_eval &self.class._id_field
190
+
191
+ @h['_id'] = generate_id
173
192
  end
174
193
 
175
- @h['_id'] = Rufus::Doric.neutralize_id(i)
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
- function(doc) {
428
- if (doc.doric_type == '#{@doric_type}') {
429
- var keys = #{Rufus::Json.encode(@text_index)};
430
- for (var key in doc) {
431
- if (keys.indexOf(key) < 0) continue;
432
- if (doc[key] == undefined) continue;
433
- var words = doc[key].split(/[\s,;\.]/);
434
- words.forEach(function (word) {
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
- function(doc) {
447
- if (doc.doric_type == '#{@doric_type}') {
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
- path = "#{design_path}/_view/by_#{key}?#{qs.join('&')}"
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
 
@@ -33,7 +33,7 @@ module Doric
33
33
 
34
34
  def self.neutralize_id (s)
35
35
 
36
- s.to_s.strip.gsub(/[\s\/:;\*\\\+\?]/, '_')
36
+ s.to_s.strip.gsub(/[\.\s\/:;\*\\\+\?]/, '_')
37
37
  end
38
38
 
39
39
  def self.escape (o)
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Rufus
3
3
  module Doric
4
- VERSION = '0.1.6'
4
+ VERSION = '0.1.7'
5
5
  end
6
6
  end
7
7
 
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.6"
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-14}
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
- - 6
9
- version: 0.1.6
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-14 00:00:00 +09:00
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