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