compound-key views work

This commit is contained in:
Chris Anderson 2008-09-29 17:27:41 -07:00
parent 5e0cb81ad7
commit f408dfceb6
3 changed files with 70 additions and 15 deletions

View file

@ -15,6 +15,7 @@
require "rubygems"
require 'json'
require 'rest_client'
require 'extlib'
$:.unshift File.dirname(__FILE__) unless
$:.include?(File.dirname(__FILE__)) ||

View file

@ -1,7 +1,3 @@
require 'rubygems'
gem 'extlib'
require 'extlib'
module CouchRest
module Model
class << self
@ -148,19 +144,47 @@ module CouchRest
@@design_doc['views'][method_name] = {
'map' => map_function
}
@@design_doc_fresh = false
self.meta_class.instance_eval do
define_method method_name do
define_method method_name do |args|
args ||= {}
unless @@design_doc_fresh
refresh_design_doc
end
@@design_doc
raw = args.delete(:raw)
view_name = "#{type}/#{method_name}"
if raw
fetch_view(view_name)
else
view = fetch_view(view_name)
# TODO this can be optimized once the include-docs patch is applied
view['rows'].collect{|r|new(database.get(r['id']))}
end
end
end
end
private
def fetch_view view_name
retryable = true
begin
database.view(view_name)
# the design doc could have been deleted by a rouge process
rescue RestClient::ResourceNotFound => e
if retryable
refresh_design_doc
retryable = false
retry
else
raise e
end
end
end
def design_doc_id
"_design/#{self.to_s}"
end
@ -173,11 +197,13 @@ module CouchRest
}
end
def refresh_design_doc
saved = database.get(design_doc_id) rescue nil
if saved
# merge the new views in and save if it needs to be saved
@@design_doc['views'].each do |name, view|
saved['views'][name] = view
end
database.save(saved)
else
database.save(@@design_doc)
end
@ -190,7 +216,7 @@ module CouchRest
def self.included(model)
model.class_eval <<-EOS, __FILE__, __LINE__
include Extlib::Hook
register_instance_hooks :save #, :create, :update, :destroy
register_instance_hooks :save, :create, :update #, :destroy
EOS
end
end # module Callbacks

View file

@ -22,6 +22,7 @@ class Article
key_writer :date
view_by :date
view_by :user_id, :date
end
describe CouchRest::Model do
@ -189,7 +190,8 @@ describe CouchRest::Model do
describe "a model with simple views" do
before(:all) do
written_at = Time.now - 24 * 3600 * 7
["this and that", "also interesting", "more fun", "some junk"].each do |title|
@titles = ["this and that", "also interesting", "more fun", "some junk"]
@titles.each do |title|
a = Article.new(:title => title)
a.date = written_at
a.save
@ -198,17 +200,43 @@ describe CouchRest::Model do
end
it "should create the design doc" do
Article.by_date
Article.by_date rescue nil
doc = Article.database.get("_design/Article")
doc['views']['by_date'].should_not be_nil
end
it "should return the matching view result" do
it "should return the matching raw view result" do
view = Article.by_date :raw => true
# view.should == 'x'
# view['rows'].should == 4
view['rows'].length.should == 4
end
it "should return the matching object" do
articles = Article.by_date
articles.collect{|a|a.title}.should == @titles
end
end
describe "a model with a compound key view" do
before(:all) do
written_at = Time.now - 24 * 3600 * 7
@titles = ["uniq one", "even more interesting", "less fun", "not junk"]
@user_ids = ["quentin", "aaron"]
@titles.each_with_index do |title,i|
u = i % 2
a = Article.new(:title => title, :user_id => @user_ids[u])
a.date = written_at
a.save
written_at += 24 * 3600
end
end
it "should create the design doc" do
Article.by_user_id_and_date rescue nil
doc = Article.database.get("_design/Article")
doc['views']['by_date'].should_not be_nil
end
it "should sort correctly" do
articles = Article.by_user_id_and_date
# articles.should == 'x'
end
end
end