+ self.manifest_text.scan(/ \d+:\d+:(\S+)/) do |name|
+ next if done[name]
+ done[name] = true
+ names << name.first.gsub('\040',' ') + "\n"
+ end
+ self.manifest_text.scan(/^\.\/(\S+)/m) do |stream_name|
+ next if done[stream_name]
+ done[stream_name] = true
+ names << stream_name.first.gsub('\040',' ') + "\n"
+ end
+ names
+ end
+
+ def default_empty_manifest
+ self.manifest_text ||= ''
+ end
+
+ def skip_uuid_existence_check
+ # Avoid checking the existence of current_version_uuid, as it's
+ # assigned on creation of a new 'current version' collection, so
+ # the collection's UUID only lives on memory when the validation check
+ # is performed.
+ ['current_version_uuid']
+ end
+
+ def manage_versioning
+ should_preserve_version = should_preserve_version? # Time sensitive, cache value
+ return(yield) unless (should_preserve_version || syncable_updates.any?)
+
+ # Put aside the changes because with_lock forces a record reload
+ changes = self.changes
+ snapshot = nil
+ with_lock do
+ # Copy the original state to save it as old version
+ if should_preserve_version
+ snapshot = self.dup
+ snapshot.uuid = nil # Reset UUID so it's created as a new record
+ snapshot.created_at = self.created_at
+ end
+
+ # Restore requested changes on the current version
+ changes.keys.each do |attr|
+ if attr == 'preserve_version' && changes[attr].last == false
+ next # Ignore false assignment, once true it'll be true until next version
+ end
+ self.attributes = {attr => changes[attr].last}
+ if attr == 'uuid'
+ # Also update the current version reference
+ self.attributes = {'current_version_uuid' => changes[attr].last}
+ end
+ end
+
+ if should_preserve_version
+ self.version += 1
+ self.preserve_version = false
+ end
+
+ yield
+
+ sync_past_versions if syncable_updates.any?
+ if snapshot
+ snapshot.attributes = self.syncable_updates
+ snapshot.manifest_text = snapshot.signed_manifest_text
+ snapshot.save