module CouchPotato module View # Used to query views (and create them if they don't exist). Usually you won't have to use this class directly. Instead it is used internally by the CouchPotato::Database.view method. class ViewQuery def initialize(couchrest_database, design_document_name, view, list = nil, lib = nil, language = :javascript) @database = couchrest_database @design_document_name = design_document_name @view_name = view.keys[0] @map_function = view.values[0][:map] @reduce_function = view.values[0][:reduce] @lib = lib @language = language if list @list_function = list.values[0] @list_name = list.keys[0] end end def query_view!(parameters = {}) update_view unless view_has_been_updated? begin query_view parameters rescue RestClient::ResourceNotFound update_view retry end end # mainly useful for testing where you drop the database between tests. # only after clearing the cache design docs will be updated/re-created. def self.clear_cache __updated_views.clear end def self.__updated_views @updated_views ||= {} @updated_views end private def update_view design_doc = @database.get "_design/#{@design_document_name}" rescue nil original_views = design_doc && design_doc['views'].dup original_lists = design_doc && design_doc['lists'] && design_doc['lists'].dup view_updated unless design_doc.nil? design_doc ||= empty_design_document design_doc['views'][@view_name.to_s] = view_functions if @lib design_doc['views']['lib'] = (design_doc['views']['lib'] || {}).merge(@lib) end if @list_function design_doc['lists'] ||= {} design_doc['lists'][@list_name.to_s] = @list_function end @database.save_doc(design_doc) if original_views != design_doc['views'] || original_lists != design_doc['lists'] end def view_functions if @reduce_function {'map' => @map_function, 'reduce' => @reduce_function} else {'map' => @map_function} end end def empty_design_document {'views' => {}, 'lists' => {}, "_id" => "_design/#{@design_document_name}", "language" => @language.to_s} end def view_has_been_updated? updated_views[[@design_document_name, @view_name]] end def view_updated updated_views[[@design_document_name, @view_name]] = true end def updated_views self.class.__updated_views end def query_view(parameters) if @list_name CouchRest.get CouchRest.paramify_url(CouchPotato.full_url_to_database + "/_design/#{@design_document_name}/_list/#{@list_name}/#{@view_name}", parameters) else @database.view view_url, parameters end end def view_url "#{@design_document_name}/#{@view_name}" end end end end