Class: ContainerManagementMigration
- Inherits:
-
Object
- Object
- ContainerManagementMigration
- Defined in:
- backend/app/lib/container_management_migration.rb
Defined Under Namespace
Classes: MigrationMapper
Constant Summary
- MIGRATION_MODELS =
For performance reasons, we’re going to feed the ASpace -> Container Management mapper something that behaves like a JSONModel but isn’t fully realized.
We don’t want to have to pull every field of every record back just to update their instances.
So, this implements just enough of our JSONModels to keep the mapper happy.
{}
- MAX_RECORDS_PER_TRANSACTION =
10
Class Method Summary (collapse)
Instance Method Summary (collapse)
Class Method Details
+ (Boolean) already_run?
7 8 9 10 11 |
# File 'backend/app/lib/container_management_migration.rb', line 7 def self.already_run? DB.open do |db| return !db[:system_event].where( :title => "CONTAINER_MANAGEMENT_UPGRADE_COMPLETED" ).empty? end end |
Instance Method Details
- (Object) ContainerMigrationModel(model_type)
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'backend/app/lib/container_management_migration.rb', line 23 def ContainerMigrationModel(model_type) MIGRATION_MODELS[model_type] ||= Class.new(JSONModel::JSONModel(model_type)) do include JSONModel def initialize(record) @acting_as = record.class @fields = {} load_relevant_fields(record) end def is_a?(clz) @acting_as.my_jsonmodel == clz end def [](key) @fields.fetch(key.to_s) end def create_containers(top_containers_in_this_tree) # If our incoming instance records already have their subcontainers created, we won't create them again. instances_with_subcontainers = self['instance_ids'].zip(self['instances']).map {|instance_id, instance| if instance['sub_container'] instance_id end }.compact MigrationMapper.new(self, false, top_containers_in_this_tree).call self['instance_ids'].zip(self['instances']).map {|instance_id, instance| # Create a new subcontainer that links everything up if instance['sub_container'] # This subcontainer was added by the mapping process. Create it. if !instances_with_subcontainers.include?(instance_id) SubContainer.create_from_json(JSONModel(:sub_container).from_hash(instance['sub_container']), :instance_id => instance_id) end # Extract the top container we linked to and return it if we haven't seen it before top_container_id = JSONModel(:top_container).id_for(instance['sub_container']['top_container']['ref']) if !top_containers_in_this_tree.has_key?(top_container_id) TopContainer[top_container_id] else nil end end }.compact end private def load_relevant_fields(record) @fields['uri'] = record.uri # Set the fields that are used by the mapper to walk the tree. if record.is_a?(ArchivalObject) if record.parent_id @fields['parent'] = {'ref' => ArchivalObject.uri_for(:archival_object, record.parent_id)} end if record.root_record_id @fields['resource'] = {'ref' => Resource.uri_for(:resource, record.root_record_id)} end end # Find the existing instances and their IDs and load them in as well. instance_join_column = record.class.association_reflection(:instance)[:key] @fields['instances'] = [] @fields['instance_ids'] = [] Instance.filter(instance_join_column => record.id).each do |instance| @fields['instances'] << Instance.to_jsonmodel(instance).to_hash(:trusted) @fields['instance_ids'] << instance.id end end end end |
- (Object) run
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'backend/app/lib/container_management_migration.rb', line 140 def run # just in case.... if self.class.already_run? Log.info("*" * 100 ) Log.info("*\t\t How did you get here? The container management conversion process has already run, or at least there's log of it in the system_event table.") Log.info("*" * 100 ) return end DB.open do |db| db[:system_event].insert(:title => "CONTAINER_MANAGEMENT_UPGRADE_STARTED", :time => Time.now) end records_migrated = 0 Repository.all.each do |repo| RequestContext.open(:repo_id => repo.id, :is_high_priority => false, :current_username => "admin") do # Migrate accession records Accession.filter(:repo_id => repo.id).each do |accession| Log.info("Working on Accession #{accession.id} (records migrated: #{records_migrated})") records_migrated += 1 ContainerMigrationModel(:accession).new(accession).create_containers({}) end # Then resources and containers Resource.filter(:repo_id => repo.id).each do |resource| top_containers_in_this_tree = {} records_migrated += 1 ContainerMigrationModel(:resource).new(resource).create_containers(top_containers_in_this_tree).each do |top_container| top_containers_in_this_tree[top_container.id] = top_container end ao_roots = resource.tree['children'] ao_roots.each do |ao_root| work_queue = [ao_root] while !work_queue.empty? nodes_for_transaction = [] while !work_queue.empty? nodes_for_transaction << work_queue.shift break if nodes_for_transaction.length == MAX_RECORDS_PER_TRANSACTION end Log.info("Running #{nodes_for_transaction.length} for the next transaction") DB.open do nodes_for_transaction.each do |node| work_queue.concat(node['children']) record = ArchivalObject[node['id']] Log.info("Working on ArchivalObject #{record.id} (records migrated: #{records_migrated})") migration_record = ContainerMigrationModel(:archival_object).new(record) migration_record.create_containers(top_containers_in_this_tree).each do |top_container| top_containers_in_this_tree[top_container.id] = top_container end records_migrated += 1 end end end end end end end DB.open do |db| db[:system_event].insert(:title => "CONTAINER_MANAGEMENT_UPGRADE_COMPLETED", :time => Time.now) end end |