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