lib/riak/search/result_document.rb in riak-client-2.2.0.pre1 vs lib/riak/search/result_document.rb in riak-client-2.2.0

- old
+ new

@@ -1,9 +1,11 @@ +require 'riak/errors/crdt_error' + module Riak::Search # A single document from a Riak Search 2 response. Materializes the document - # fields into {Riak::BucketType}, {Riak::Bucket}, and {Riak::RObject} + # fields into {Riak::BucketType}, {Riak::Bucket}, and {Riak::RObject} # instances on demand. class ResultDocument # @return [Riak::Client] attr_reader :client @@ -39,10 +41,59 @@ # @return [Numeric] the score of the match def score @score ||= Float(raw['score']) end + # Determining if the object is a CRDT or regular K-V object requires + # figuring out what data type the bucket type contains. If the bucket type + # has no data type, treat it as a regular K-V object. + # + # @return [Class] the class of the object referred to by the search result + def type_class + bucket_type.data_type_class || Riak::RObject + end + + # @return [Boolean] if the object is a CRDT + def crdt? + type_class != Riak::RObject + end + + # @raise [Riak::CrdtError::NotACrdt] if the result is not a CRDT + # @return [Riak::Crdt::Base] the materialized CRDT + def crdt + fail Riak::CrdtError::NotACrdt unless crdt? + + type_class.new bucket, key, bucket_type + end + + # If the result document describes a counter, return it. + # + # @return [Riak::Crdt::Counter] + # @raise [Riak::CrdtError::NotACrdt] if the result is not a CRDT + # @raise [Riak::CrdtError::UnexpectedDataType] if the CRDT is not a counter + def counter + return crdt if check_type_class Riak::Crdt::Counter + end + + # If the result document describes a map, return it. + # + # @return [Riak::Crdt::Map] + # @raise [Riak::CrdtError::NotACrdt] if the result is not a CRDT + # @raise [Riak::CrdtError::UnexpectedDataType] if the CRDT is not a map + def map + return crdt if check_type_class Riak::Crdt::Map + end + + # If the result document describes a set, return it. + # + # @return [Riak::Crdt::Set] + # @raise [Riak::CrdtError::NotACrdt] if the result is not a CRDT + # @raise [Riak::CrdtError::UnexpectedDataType] if the CRDT is not a set + def set + return crdt if check_type_class Riak::Crdt::Set + end + # Provides access to other parts of the result document without # materializing them. Useful when querying non-default fields. # # @return [String,Numeric] other search result document field def [](field_name) @@ -51,9 +102,28 @@ # Loads the {Riak::RObject} referred to by the result document. # # @return [Riak::RObject] def robject + if crdt? + fail Riak::SearchError::UnexpectedResultError. + new(Riak::RObject, type_class) + end + @robject ||= bucket.get key + end + + # Returns an appropriate object, be it CRDT or K-V. + def object + return crdt if crdt? + robject + end + + private + + def check_type_class(klass) + return true if type_class == klass + fail Riak::CrdtError::NotACrdt if type_class == Riak::RObject + fail Riak::CrdtError::UnexpectedDataType.new(klass, type_class) end end end