lib/active_fedora/base.rb in active-fedora-4.1.0 vs lib/active_fedora/base.rb in active-fedora-4.2.0

- old
+ new

@@ -1,7 +1,8 @@ SOLR_DOCUMENT_ID = "id" unless (defined?(SOLR_DOCUMENT_ID) && !SOLR_DOCUMENT_ID.nil?) ENABLE_SOLR_UPDATES = true unless defined?(ENABLE_SOLR_UPDATES) +require "digest" module ActiveFedora # This class ties together many of the lower-level modules, and # implements something akin to an ActiveRecord-alike interface to @@ -130,14 +131,23 @@ end end fedora_connection[idx].connection end - #If you want to use sharding override this method with your strategy + # This is where your sharding strategy is implemented -- it's how we figure out which shard an object will be (or was) written to. + # Given a pid, it decides which shard that pid will be written to (and thus retrieved from). + # For a given pid, as long as your shard configuration remains the same it will always return the same value. + # If you're not using sharding, this will always return 0, meaning use the first/only Fedora Repository in your configuration. + # Default strategy runs a modulo of the md5 of the pid against the number of shards. + # If you want to use a different sharding strategy, override this method. Make sure that it will always return the same value for a given pid and shard configuration. #@return [Integer] the index of the shard this object is stored in def self.shard_index(pid) - 0 + if ActiveFedora.config.sharded? + Digest::MD5.hexdigest(pid).hex % ActiveFedora.config.credentials.length + else + 0 + end end def self.datastream_class_for_name(dsid) ds_specs[dsid] ? ds_specs[dsid][:type] : ActiveFedora::Datastream @@ -147,18 +157,45 @@ obj = self.new(args) obj.save obj end + def clone + new_object = self.class.create + clone_into(new_object) + end + # Clone the datastreams from this object into the provided object, while preserving the pid of the provided object + # @param [Base] new_object clone into this object + def clone_into(new_object) + rels = Nokogiri::XML( rels_ext.content) + rels.xpath("//rdf:Description/@rdf:about").first.value = new_object.internal_uri + new_object.rels_ext.content = rels.to_xml + new_object.rels_ext.dirty = false + + datastreams.each do |k, v| + next if k == 'RELS-EXT' + new_object.datastreams[k].content = v.content + end + new_object if new_object.save + end + ### if you are doing sharding, override this method to do something other than use a sequence # @return [String] the unique pid for a new object def self.assign_pid(obj) - args = {} - args[:namespace] = obj.namespace if obj.namespace - raise RuntimeError, "When using shards, you must override #{self}.assign_pid()" if ActiveFedora.config.sharded? - d = REXML::Document.new(connection_for_pid('0').next_pid(args)) - d.elements['//pid'].text + args = {} + args[:namespace] = obj.namespace if obj.namespace + # TODO: This juggling of Fedora credentials & establishing connections should be handled by + # an establish_fedora_connection method,possibly wrap it all into a fedora_connection method - MZ 06-05-2012 + if ActiveFedora.config.sharded? + credentials = ActiveFedora.config.credentials[0] + else + credentials = ActiveFedora.config.credentials + end + fedora_connection[0] ||= ActiveFedora::RubydoraConnection.new(credentials) + d = REXML::Document.new( fedora_connection[0].connection.next_pid(args)) + pid =d.elements['//pid'].text + pid end def inner_object # :nodoc @inner_object end