compound-key views work
This commit is contained in:
parent
5e0cb81ad7
commit
f408dfceb6
3 changed files with 70 additions and 15 deletions
|
@ -15,6 +15,7 @@
|
||||||
require "rubygems"
|
require "rubygems"
|
||||||
require 'json'
|
require 'json'
|
||||||
require 'rest_client'
|
require 'rest_client'
|
||||||
|
require 'extlib'
|
||||||
|
|
||||||
$:.unshift File.dirname(__FILE__) unless
|
$:.unshift File.dirname(__FILE__) unless
|
||||||
$:.include?(File.dirname(__FILE__)) ||
|
$:.include?(File.dirname(__FILE__)) ||
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
require 'rubygems'
|
|
||||||
gem 'extlib'
|
|
||||||
require 'extlib'
|
|
||||||
|
|
||||||
module CouchRest
|
module CouchRest
|
||||||
module Model
|
module Model
|
||||||
class << self
|
class << self
|
||||||
|
@ -148,19 +144,47 @@ module CouchRest
|
||||||
@@design_doc['views'][method_name] = {
|
@@design_doc['views'][method_name] = {
|
||||||
'map' => map_function
|
'map' => map_function
|
||||||
}
|
}
|
||||||
|
|
||||||
@@design_doc_fresh = false
|
@@design_doc_fresh = false
|
||||||
|
|
||||||
self.meta_class.instance_eval do
|
self.meta_class.instance_eval do
|
||||||
define_method method_name do
|
define_method method_name do |args|
|
||||||
|
args ||= {}
|
||||||
unless @@design_doc_fresh
|
unless @@design_doc_fresh
|
||||||
refresh_design_doc
|
refresh_design_doc
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
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
|
def design_doc_id
|
||||||
"_design/#{self.to_s}"
|
"_design/#{self.to_s}"
|
||||||
end
|
end
|
||||||
|
@ -173,11 +197,13 @@ module CouchRest
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def refresh_design_doc
|
def refresh_design_doc
|
||||||
saved = database.get(design_doc_id) rescue nil
|
saved = database.get(design_doc_id) rescue nil
|
||||||
if saved
|
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
|
else
|
||||||
database.save(@@design_doc)
|
database.save(@@design_doc)
|
||||||
end
|
end
|
||||||
|
@ -190,7 +216,7 @@ module CouchRest
|
||||||
def self.included(model)
|
def self.included(model)
|
||||||
model.class_eval <<-EOS, __FILE__, __LINE__
|
model.class_eval <<-EOS, __FILE__, __LINE__
|
||||||
include Extlib::Hook
|
include Extlib::Hook
|
||||||
register_instance_hooks :save #, :create, :update, :destroy
|
register_instance_hooks :save, :create, :update #, :destroy
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
end # module Callbacks
|
end # module Callbacks
|
||||||
|
|
|
@ -22,6 +22,7 @@ class Article
|
||||||
key_writer :date
|
key_writer :date
|
||||||
|
|
||||||
view_by :date
|
view_by :date
|
||||||
|
view_by :user_id, :date
|
||||||
end
|
end
|
||||||
|
|
||||||
describe CouchRest::Model do
|
describe CouchRest::Model do
|
||||||
|
@ -189,7 +190,8 @@ describe CouchRest::Model do
|
||||||
describe "a model with simple views" do
|
describe "a model with simple views" do
|
||||||
before(:all) do
|
before(:all) do
|
||||||
written_at = Time.now - 24 * 3600 * 7
|
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 = Article.new(:title => title)
|
||||||
a.date = written_at
|
a.date = written_at
|
||||||
a.save
|
a.save
|
||||||
|
@ -198,17 +200,43 @@ describe CouchRest::Model do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should create the design doc" do
|
it "should create the design doc" do
|
||||||
Article.by_date
|
Article.by_date rescue nil
|
||||||
doc = Article.database.get("_design/Article")
|
doc = Article.database.get("_design/Article")
|
||||||
doc['views']['by_date'].should_not be_nil
|
doc['views']['by_date'].should_not be_nil
|
||||||
end
|
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 = Article.by_date :raw => true
|
||||||
# view.should == 'x'
|
view['rows'].length.should == 4
|
||||||
# view['rows'].should == 4
|
|
||||||
end
|
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
|
||||||
end
|
end
|
Loading…
Add table
Reference in a new issue