paulcarey-relaxdb 0.2.8 → 0.3.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,18 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+ require 'relaxdb'
3
+ require File.dirname(__FILE__) + '/../../spec/spec_models.rb'
4
+
5
+ RelaxDB.configure :host => "localhost", :port => 5984
6
+ RelaxDB.delete_db "relaxdb_spec" rescue :ok
7
+ RelaxDB.use_db "relaxdb_spec"
8
+
9
+ a1 = Atom.new.save!
10
+ a1_dup = a1.dup
11
+ a1.save!
12
+ begin
13
+ RelaxDB.bulk_save! a1_dup
14
+ puts "Atomic bulk_save _not_ supported"
15
+ rescue RelaxDB::UpdateConflict
16
+ puts "Atomic bulk_save supported"
17
+ end
18
+
@@ -3,65 +3,41 @@ module RelaxDB
3
3
  #
4
4
  # The AllDelegator allows clients to query CouchDB in a natural way
5
5
  # FooDoc.all - returns all docs in CouchDB of type FooDoc
6
- # FooDoc.all.sorted_by(:att1, :att2) - returns all docs in CouchDB of type FooDoc sorted by att1, then att2
7
- # FooDoc.all.sorted_by(:att1) { |q| q.key("bar") } - returns all docs of type FooDoc where att1 equals "bar"
8
- # FooDoc.all.destroy! - does what it says on the tin
9
6
  # FooDoc.all.size - issues a query to a reduce function that returns the total number of docs for that class
7
+ # FooDoc.all.destroy! - TODO - better description
10
8
  #
11
9
  class AllDelegator < Delegator
12
10
 
13
- def initialize(class_name)
11
+ def initialize(class_name, params)
14
12
  super([])
15
13
  @class_name = class_name
14
+ @params = params
16
15
  end
17
16
 
18
17
  def __getobj__
19
- view_path = "_view/#{@class_name}/all?reduce=false"
20
- map, reduce = ViewCreator.all(@class_name)
21
-
22
- RelaxDB.retrieve(view_path, @class_name, "all", map, reduce)
18
+ unless @objs
19
+ @objs = RelaxDB.view "#{@class_name}_all", @params
20
+ end
21
+ @objs
23
22
  end
24
23
 
25
- def sorted_by(*atts)
26
- view = SortedByView.new(@class_name, *atts)
27
-
28
- query = Query.new(@class_name, view.view_name)
29
- yield query if block_given?
30
-
31
- view.query(query)
24
+ def size
25
+ size = RelaxDB.view "#{@class_name}_all", :reduce => true
26
+ size || 0
32
27
  end
33
28
 
34
- # Note that this method leaves the corresponding DesignDoc for the associated class intact
29
+ # TODO: destroy in a bulk_save if feasible
35
30
  def destroy!
36
- each do |o|
31
+ __getobj__
32
+ @objs.each do |o|
37
33
  # A reload is required for deleting objects with a self referential references_many relationship
38
- # This makes all.destroy! very slow. Given that references_many is now deprecated and will
39
- # soon be removed, the required reload is no longer performed.
34
+ # This makes all.destroy! very slow. Change if needed
40
35
  # obj = RelaxDB.load(o._id)
41
36
  # obj.destroy!
42
37
 
43
38
  o.destroy!
44
39
  end
45
- end
46
-
47
- # This is pretty ugly - this pattern is now spread over three
48
- # places (sorted_by_view, relaxdb and here)
49
- # Consolidation needed
50
- def size
51
- view_path = "_view/#{@class_name}/all"
52
- map, reduce = ViewCreator.all(@class_name)
53
-
54
- begin
55
- resp = RelaxDB.db.get(view_path)
56
- rescue => e
57
- DesignDocument.get(@class_name).add_map_view("all", map).
58
- add_reduce_view("all", reduce).save
59
- resp = RelaxDB.db.get(view_path)
60
- end
61
-
62
- data = JSON.parse(resp.body)
63
- data["rows"][0] ? data["rows"][0]["value"] : 0
64
- end
40
+ end
65
41
 
66
42
  end
67
43
 
@@ -1,9 +1,11 @@
1
1
  module RelaxDB
2
2
 
3
3
  class DesignDocument
4
+
5
+ attr_reader :data
4
6
 
5
- def initialize(client_class, data)
6
- @client_class = client_class
7
+ def initialize(design_doc_name, data)
8
+ @design_doc_name = design_doc_name
7
9
  @data = data
8
10
  end
9
11
 
@@ -34,13 +36,13 @@ module RelaxDB
34
36
  self
35
37
  end
36
38
 
37
- def self.get(client_class)
39
+ def self.get(design_doc_name)
38
40
  begin
39
41
  database = RelaxDB.db
40
- resp = database.get("_design/#{client_class}")
41
- DesignDocument.new(client_class, JSON.parse(resp.body))
42
+ resp = database.get("_design/#{design_doc_name}")
43
+ DesignDocument.new(design_doc_name, JSON.parse(resp.body))
42
44
  rescue HTTP_404
43
- DesignDocument.new(client_class, {"_id" => "_design/#{client_class}"} )
45
+ DesignDocument.new(design_doc_name, {"_id" => "_design/#{design_doc_name}"} )
44
46
  end
45
47
  end
46
48
 
@@ -7,16 +7,28 @@ module RelaxDB
7
7
  # Used to store validation messages
8
8
  attr_accessor :errors
9
9
 
10
+ # A call issued to save_all will save this object and the
11
+ # contents of the save_list. This allows secondary object to
12
+ # be saved at the same time as this object.
13
+ attr_accessor :save_list
14
+
10
15
  # Attribute symbols added to this list won't be validated on save
11
16
  attr_accessor :validation_skip_list
12
17
 
13
- # Define properties and property methods
18
+ class_inheritable_accessor :properties, :reader => true
19
+ self.properties = []
20
+
21
+ class_inheritable_accessor :derived_prop_writers
22
+ self.derived_prop_writers = {}
23
+
24
+ class_inheritable_accessor :__view_by_list__
25
+ self.__view_by_list__ = []
14
26
 
27
+ class_inheritable_accessor :belongs_to_rels, :reder => true
28
+ self.belongs_to_rels = {}
29
+
15
30
  def self.property(prop, opts={})
16
- # Class instance varibles are not inherited, so the default properties must be explicitly listed
17
- # Perhaps a better solution exists. Revise. I think extlib contains a solution for this...
18
- @properties ||= [:_id, :_rev]
19
- @properties << prop
31
+ properties << prop
20
32
 
21
33
  define_method(prop) do
22
34
  instance_variable_get("@#{prop}".to_sym)
@@ -45,12 +57,10 @@ module RelaxDB
45
57
  if opts[:derived]
46
58
  add_derived_prop(prop, opts[:derived])
47
59
  end
48
- end
49
-
50
- def self.properties
51
- # Ensure that classes that don't define their own properties still function as CouchDB objects
52
- @properties ||= [:_id, :_rev]
53
- end
60
+ end
61
+
62
+ property :_id
63
+ property :_rev
54
64
 
55
65
  def self.create_validator(att, v)
56
66
  method_name = "validate_#{att}"
@@ -78,15 +88,10 @@ module RelaxDB
78
88
  # See derived_properties_spec.rb for usage
79
89
  def self.add_derived_prop(prop, deriver)
80
90
  source, writer = deriver[0], deriver[1]
81
- @derived_prop_writers ||= {}
82
- @derived_prop_writers[source] ||= {}
83
- @derived_prop_writers[source][prop] = writer
84
- end
85
-
86
- def self.derived_prop_writers
87
- @derived_prop_writers ||= {}
91
+ derived_prop_writers[source] ||= {}
92
+ derived_prop_writers[source][prop] = writer
88
93
  end
89
-
94
+
90
95
  #
91
96
  # The rationale for rescuing the send below is that the lambda for a derived
92
97
  # property shouldn't need to concern itself with checking the validity of
@@ -94,27 +99,19 @@ module RelaxDB
94
99
  # possibility of a writer raising an exception.
95
100
  #
96
101
  def write_derived_props(source)
97
- writers = self.class.derived_prop_writers[source]
102
+ writers = self.class.derived_prop_writers
103
+ writers = writers && writers[source]
98
104
  if writers
99
105
  writers.each do |prop, writer|
100
106
  current_val = send(prop)
101
107
  begin
102
108
  send("#{prop}=", writer.call(current_val, self))
103
109
  rescue => e
104
- RelaxDB.logger.warn "Deriving #{prop} from #{source} raised #{e}"
110
+ RelaxDB.logger.error "Deriving #{prop} from #{source} raised #{e}"
105
111
  end
106
112
  end
107
113
  end
108
114
  end
109
-
110
- def properties
111
- self.class.properties
112
- end
113
-
114
- # Specifying these properties here (after property method has been defined)
115
- # is kinda ugly. Consider a better solution.
116
- property :_id
117
- property :_rev
118
115
 
119
116
  def initialize(hash={})
120
117
  unless hash["_id"]
@@ -122,6 +119,7 @@ module RelaxDB
122
119
  end
123
120
 
124
121
  @errors = Errors.new
122
+ @save_list = []
125
123
  @validation_skip_list = []
126
124
 
127
125
  # Set default properties if this object isn't being loaded from CouchDB
@@ -165,6 +163,7 @@ module RelaxDB
165
163
  s << ", #{relationship}_id: #{id}" if id
166
164
  end
167
165
  s << ", errors: #{errors.inspect}" unless errors.empty?
166
+ s << ", save_list: #{save_list.map { |o| o.inspect }.join ", " }" unless save_list.empty?
168
167
  s << ">"
169
168
  end
170
169
 
@@ -180,7 +179,7 @@ module RelaxDB
180
179
  prop_val = instance_variable_get("@#{prop}".to_sym)
181
180
  data["#{prop}"] = prop_val if prop_val
182
181
  end
183
- data["class"] = self.class.name
182
+ data["relaxdb_class"] = self.class.name
184
183
  data.to_json
185
184
  end
186
185
 
@@ -211,9 +210,9 @@ module RelaxDB
211
210
  end
212
211
 
213
212
  def pre_save
213
+ set_created_at if new_document?
214
214
  return false unless validates?
215
215
  return false unless before_save
216
- set_created_at if new_document?
217
216
  true
218
217
  end
219
218
 
@@ -221,6 +220,15 @@ module RelaxDB
221
220
  after_save
222
221
  end
223
222
 
223
+ # save_all and save_all! are untested
224
+ def save_all
225
+ RelaxDB.bulk_save self, *save_list
226
+ end
227
+
228
+ def save_all!
229
+ RelaxDB.bulk_save! self, *save_list
230
+ end
231
+
224
232
  def save!
225
233
  if save
226
234
  self
@@ -230,21 +238,7 @@ module RelaxDB
230
238
  raise ValidationFailure, self.errors.to_json
231
239
  end
232
240
  end
233
-
234
- def save_all
235
- RelaxDB.bulk_save(self, *all_children)
236
- end
237
-
238
- def save_all!
239
- RelaxDB.bulk_save!(self, *all_children)
240
- end
241
-
242
- def all_children
243
- ho = self.class.has_one_rels.map { |r| send(r) }
244
- hm = self.class.has_many_rels.inject([]) { |m,r| m += send(r).children }
245
- ho + hm
246
- end
247
-
241
+
248
242
  def update_conflict?
249
243
  @update_conflict
250
244
  end
@@ -269,6 +263,7 @@ module RelaxDB
269
263
 
270
264
  total_success
271
265
  end
266
+ alias_method :validate, :validates?
272
267
 
273
268
  def validate_att(att_name, att_val)
274
269
  begin
@@ -286,7 +281,8 @@ module RelaxDB
286
281
  RelaxDB.logger.warn "Validation_msg for #{att_name} with #{att_val} raised #{e}"
287
282
  @errors[att_name] = "validation_msg_exception:invalid:#{att_val}"
288
283
  end
289
- else
284
+ elsif @errors[att_name].nil?
285
+ # Only set a validation message if a validator hasn't already set one
290
286
  @errors[att_name] = "invalid:#{att_val}"
291
287
  end
292
288
  end
@@ -337,6 +333,12 @@ module RelaxDB
337
333
  @references_many_rels << relationship
338
334
 
339
335
  id_arr_sym = "@#{relationship}".to_sym
336
+
337
+ if RelaxDB.create_views?
338
+ target_class = opts[:class]
339
+ relationship_as_viewed_by_target = opts[:known_as].to_s
340
+ ViewCreator.references_many(self.name, relationship, target_class, relationship_as_viewed_by_target).save
341
+ end
340
342
 
341
343
  define_method(relationship) do
342
344
  instance_variable_set(id_arr_sym, []) unless instance_variable_defined? id_arr_sym
@@ -362,6 +364,12 @@ module RelaxDB
362
364
  @has_many_rels ||= []
363
365
  @has_many_rels << relationship
364
366
 
367
+ if RelaxDB.create_views?
368
+ target_class = opts[:class]
369
+ relationship_as_viewed_by_target = (opts[:known_as] || self.name.snake_case).to_s
370
+ ViewCreator.has_n(self.name, relationship, target_class, relationship_as_viewed_by_target).save
371
+ end
372
+
365
373
  define_method(relationship) do
366
374
  create_or_get_proxy(HasManyProxy, relationship, opts)
367
375
  end
@@ -382,6 +390,12 @@ module RelaxDB
382
390
  @has_one_rels ||= []
383
391
  @has_one_rels << relationship
384
392
 
393
+ if RelaxDB.create_views?
394
+ target_class = relationship.to_s.camel_case
395
+ relationship_as_viewed_by_target = self.name.snake_case
396
+ ViewCreator.has_n(self.name, relationship, target_class, relationship_as_viewed_by_target).save
397
+ end
398
+
385
399
  define_method(relationship) do
386
400
  create_or_get_proxy(HasOneProxy, relationship).target
387
401
  end
@@ -398,8 +412,7 @@ module RelaxDB
398
412
  end
399
413
 
400
414
  def self.belongs_to(relationship, opts={})
401
- @belongs_to_rels ||= {}
402
- @belongs_to_rels[relationship] = opts
415
+ belongs_to_rels[relationship] = opts
403
416
 
404
417
  define_method(relationship) do
405
418
  create_or_get_proxy(BelongsToProxy, relationship).target
@@ -417,7 +430,6 @@ module RelaxDB
417
430
  id
418
431
  end
419
432
 
420
- # Allows belongs_to relationships to be used by the paginator
421
433
  define_method("#{relationship}_id") do
422
434
  instance_variable_get("@#{relationship}_id")
423
435
  end
@@ -432,16 +444,14 @@ module RelaxDB
432
444
  alias_method :references, :belongs_to
433
445
  end
434
446
 
435
- def self.belongs_to_rels
436
- @belongs_to_rels ||= {}
437
- end
447
+ self.belongs_to_rels = {}
438
448
 
439
449
  def self.all_relationships
440
450
  belongs_to_rels + has_one_rels + has_many_rels + references_many_rels
441
451
  end
442
452
 
443
- def self.all
444
- @all_delegator ||= AllDelegator.new(self.name)
453
+ def self.all params = {}
454
+ AllDelegator.new self.name, params
445
455
  end
446
456
 
447
457
  # destroy! nullifies all relationships with peers and children before deleting
@@ -482,7 +492,10 @@ module RelaxDB
482
492
  def before_save
483
493
  self.class.before_save_callbacks.each do |callback|
484
494
  resp = callback.is_a?(Proc) ? callback.call(self) : send(callback)
485
- return false unless resp
495
+ if resp == false
496
+ errors[:before_save] = :failed
497
+ return false
498
+ end
486
499
  end
487
500
  end
488
501
 
@@ -499,27 +512,80 @@ module RelaxDB
499
512
  callback.is_a?(Proc) ? callback.call(self) : send(callback)
500
513
  end
501
514
  end
502
-
503
- def self.paginate_by(page_params, *view_keys)
504
- paginate_params = PaginateParams.new
505
- yield paginate_params
506
- raise paginate_params.error_msg if paginate_params.invalid?
507
-
508
- paginator = Paginator.new(paginate_params, page_params)
509
-
510
- design_doc_name = self.name
511
- view = SortedByView.new(design_doc_name, *view_keys)
512
- query = Query.new(design_doc_name, view.view_name)
513
- query.merge(paginate_params)
515
+
516
+ #
517
+ # Creates the corresponding view and stores it in CouchDB
518
+ # Adds by_ and paginate_by_ methods to the class
519
+ #
520
+ def self.view_by *atts
521
+ opts = atts.last.is_a?(Hash) ? atts.pop : {}
522
+ __view_by_list__ << atts
514
523
 
515
- docs = view.query(query)
516
- docs.reverse! if paginate_params.order_inverted?
524
+ if RelaxDB.create_views?
525
+ ViewCreator.by_att_list([self.name], *atts).save
526
+ end
517
527
 
518
- paginator.add_next_and_prev(docs, design_doc_name, view.view_name, view_keys)
528
+ by_name = "by_#{atts.join "_and_"}"
529
+ meta_class.instance_eval do
530
+ define_method by_name do |*params|
531
+ view_name = "#{self.name}_#{by_name}"
532
+ if params.empty?
533
+ res = RelaxDB.view view_name, opts
534
+ elsif params[0].is_a? Hash
535
+ res = RelaxDB.view view_name, opts.merge(params[0])
536
+ else
537
+ res = RelaxDB.view(view_name, :key => params[0]).first
538
+ end
539
+ end
540
+ end
519
541
 
520
- docs
542
+ paginate_by_name = "paginate_by_#{atts.join "_and_"}"
543
+ meta_class.instance_eval do
544
+ define_method paginate_by_name do |params|
545
+ view_name = "#{self.name}_#{by_name}"
546
+ params[:attributes] = atts
547
+ params = opts.merge params
548
+ RelaxDB.paginate_view view_name, params
549
+ end
550
+ end
551
+ end
552
+
553
+ # Create a view allowing all instances of a particular class to be retreived
554
+ def self.create_all_by_class_view
555
+ if RelaxDB.create_views?
556
+ view = ViewCreator.all
557
+ view.save unless view.exists?
558
+ end
559
+ end
560
+
561
+ def self.inherited subclass
562
+ chain = subclass.up_chain
563
+ while k = chain.pop
564
+ k.create_views chain
565
+ end
566
+ end
567
+
568
+ def self.up_chain
569
+ k = self
570
+ kls = [k]
571
+ kls << k while ((k = k.superclass) != RelaxDB::Document)
572
+ kls
573
+ end
574
+
575
+ def self.create_views chain
576
+ # Capture the inheritance hierarchy of this class
577
+ @hierarchy ||= [self]
578
+ @hierarchy += chain
579
+ @hierarchy.uniq!
580
+
581
+ if RelaxDB.create_views?
582
+ ViewCreator.all(@hierarchy).save
583
+ __view_by_list__.each do |atts|
584
+ ViewCreator.by_att_list(@hierarchy, *atts).save
585
+ end
586
+ end
521
587
  end
522
-
588
+
523
589
  end
524
590
 
525
591
  end
@@ -77,11 +77,8 @@ module RelaxDB
77
77
  end
78
78
 
79
79
  def load_children
80
- view_path = "_view/#{@client.class}/#{@relationship}?key=\"#{@client._id}\""
81
- design_doc = @client.class
82
- view_name = @relationship
83
- map_function = ViewCreator.has_n(@target_class, @relationship_as_viewed_by_target)
84
- @children = RelaxDB.retrieve(view_path, design_doc, view_name, map_function)
80
+ view_name = "#{@client.class}_#{@relationship}"
81
+ @children = RelaxDB.view(view_name, :key => @client._id)
85
82
  end
86
83
 
87
84
  def children=(children)
@@ -94,6 +91,10 @@ module RelaxDB
94
91
  def inspect
95
92
  @children.inspect
96
93
  end
94
+
95
+ # Play nice with Merb partials - [ obj ].flatten invokes
96
+ # obj.to_ary if it responds to to_ary
97
+ alias_method :to_ary, :to_a
97
98
 
98
99
  end
99
100
 
@@ -33,11 +33,8 @@ module RelaxDB
33
33
  end
34
34
 
35
35
  def load_target
36
- design_doc = @client.class
37
- view_name = @relationship
38
- view_path = "_view/#{design_doc}/#{view_name}?key=\"#{@client._id}\""
39
- map_function = ViewCreator.has_n(@target_class, @relationship_as_viewed_by_target)
40
- RelaxDB.retrieve(view_path, design_doc, view_name, map_function).first
36
+ view_name = "#{@client.class}_#{@relationship}"
37
+ RelaxDB.view(view_name, :key => @client._id).first
41
38
  end
42
39
 
43
40
  end
@@ -17,11 +17,11 @@ module RelaxDB
17
17
  end
18
18
  end
19
19
 
20
- def initialize
20
+ def initialize(params)
21
+ params.each { |k, v| send(k, v) }
22
+
21
23
  # If a client hasn't explicitly set descending, set it to the CouchDB default
22
24
  @descending = false if @descending.nil?
23
- # CouchDB defaults reduce to true when a reduce func is present
24
- @reduce = false
25
25
  end
26
26
 
27
27
  def update(params)
@@ -44,7 +44,6 @@ module RelaxDB
44
44
 
45
45
  def invalid?
46
46
  # Simply because allowing either to be omitted increases the complexity of the paginator
47
- # This constraint may be removed in future, but don't hold your breath
48
47
  @startkey_set && @endkey_set ? nil : "Both startkey and endkey must be set"
49
48
  end
50
49
  alias error_msg invalid?
@@ -13,21 +13,17 @@ module RelaxDB
13
13
  @paginate_params.update(page_params)
14
14
  end
15
15
 
16
- def total_doc_count(design_doc, view_name)
17
- result = RelaxDB.view(design_doc, view_name) do |q|
18
- q.reduce(true)
19
- q.startkey(@orig_paginate_params.startkey).endkey(@orig_paginate_params.endkey).descending(@orig_paginate_params.descending)
20
- end
21
-
22
- total_docs = RelaxDB.reduce_result(result)
16
+ def total_doc_count(view_name)
17
+ RelaxDB.view view_name, :startkey => @orig_paginate_params.startkey, :endkey => @orig_paginate_params.endkey,
18
+ :descending => @orig_paginate_params.descending, :reduce => true
23
19
  end
24
20
 
25
- def add_next_and_prev(docs, design_doc, view_name, view_keys)
21
+ def add_next_and_prev(docs, view_name, view_keys)
26
22
  unless docs.empty?
27
23
  no_docs = docs.size
28
24
  offset = docs.offset
29
- orig_offset = orig_offset(design_doc, view_name)
30
- total_doc_count = total_doc_count(design_doc, view_name)
25
+ orig_offset = orig_offset(view_name)
26
+ total_doc_count = total_doc_count(view_name)
31
27
 
32
28
  next_exists = !@paginate_params.order_inverted? ? (offset - orig_offset + no_docs < total_doc_count) : true
33
29
  next_params = create_next(docs.last, view_keys) if next_exists
@@ -62,15 +58,15 @@ module RelaxDB
62
58
  prev_params = { :startkey => prev_key, :startkey_docid => prev_key_docid, :descending => !@orig_paginate_params.descending }
63
59
  end
64
60
 
65
- def orig_offset(design_doc, view_name)
66
- query = Query.new(design_doc, view_name)
61
+ def orig_offset(view_name)
67
62
  if @paginate_params.order_inverted?
68
- query.startkey(@orig_paginate_params.endkey).descending(!@orig_paginate_params.descending)
63
+ params = {:startkey => @orig_paginate_params.endkey, :descending => !@orig_paginate_params.descending}
69
64
  else
70
- query.startkey(@orig_paginate_params.startkey).descending(@orig_paginate_params.descending)
65
+ params = {:startkey => @orig_paginate_params.startkey, :descending => @orig_paginate_params.descending}
71
66
  end
72
- query.reduce(false).limit(1)
73
- RelaxDB.retrieve(query.view_path).offset
67
+ params[:limit] = 1
68
+
69
+ RelaxDB.view(view_name, params).offset
74
70
  end
75
71
 
76
72
  end
data/lib/relaxdb/query.rb CHANGED
@@ -3,17 +3,7 @@ module RelaxDB
3
3
  # A Query is used to build the query string made against a view
4
4
  # All parameter values are first JSON encoded and then URL encoded
5
5
  # Nil values are set to the empty string
6
- # All parameter calls return self so calls may be chained => q.startkey("foo").endkey("bar").limit(2)
7
6
 
8
- #
9
- # The query object is currently inconsistent with the RelaxDB object idiom. Consider
10
- # paul = User.new(:name => "paul").save; Event.new(:host=>paul).save
11
- # but an event query requires
12
- # Event.all.sorted_by(:host_id) { |q| q.key(paul._id) }
13
- # rather than
14
- # Event.all.sorted_by(:host) { |q| q.key(paul) }
15
- # I feel that both forms should be supported
16
- #
17
7
  class Query
18
8
 
19
9
  # keys is not included in the standard param as it is significantly different from the others
@@ -32,9 +22,13 @@ module RelaxDB
32
22
  end
33
23
  end
34
24
 
35
- def initialize(design_doc, view_name)
36
- @design_doc = design_doc
25
+ def initialize(view_name, params = {})
26
+ # CouchDB defaults reduce to true when a reduce func is present
27
+ # but returning the map view is typically more useful
28
+ reduce(false)
29
+
37
30
  @view_name = view_name
31
+ params.each { |k, v| send(k, v) }
38
32
  end
39
33
 
40
34
  def keys(keys=nil)
@@ -46,8 +40,18 @@ module RelaxDB
46
40
  end
47
41
  end
48
42
 
43
+ # If set to true RelaxDB.view will return unprocessed data
44
+ def raw(val = nil)
45
+ if val.nil?
46
+ @raw
47
+ else
48
+ @raw = val
49
+ self
50
+ end
51
+ end
52
+
49
53
  def view_path
50
- uri = "_view/#{@design_doc}/#{@view_name}"
54
+ uri = "_design/#{RelaxDB.dd}/_view/#{@view_name}"
51
55
 
52
56
  query = ""
53
57
  @@params.each do |param|