diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/compliance_control_set_copier.rb | 97 |
1 files changed, 33 insertions, 64 deletions
diff --git a/lib/compliance_control_set_copier.rb b/lib/compliance_control_set_copier.rb index b015735c2..0a688c964 100644 --- a/lib/compliance_control_set_copier.rb +++ b/lib/compliance_control_set_copier.rb @@ -1,7 +1,3 @@ -# We use a class instead of a singleton object because we will use -# a cache to avoid copying instancs of ComplianceControl twice as they -# might be reachable from CCSet **and** its descendent CCBlock. -# More generally spoken, we copy a DAG, not a tree. class ComplianceControlSetCopier # Naming Convention: As we are in a domain with quite long names we @@ -14,13 +10,12 @@ class ComplianceControlSetCopier @cc_set_id = cc_set_id @referential_id = referential_id check_organisation_coherence! - copy_dag + copy_set end private - # Workers # ------- def check_organisation_coherence! @@ -28,62 +23,48 @@ class ComplianceControlSetCopier raise ArgumentError, "Incoherent organisation of referential" end - def copy_dag - # Assure cck_set's existance, just in case cc_set is _empty_. + # Copy Set: + def copy_set + # Force lazy creation of cck_set, just in case cc_set is _empty_. cck_set - make_cck_blocks + # Copy all ccs -> ccks make_ccks_from_ccs + # Copy all cc_blocks -> cck_blocks + make_cck_blocks end - def make_all_cck_block_children cc_block, cck_block - cc_block - .compliance_controls - .each{ |compliance_control| make_compliance_check(compliance_control, cck_block.id) } - end + # Copy Blocks: def make_cck_block cc_block - cck_block = - cck_set.compliance_check_blocks.create( - name: name_with_refid(cc_block.name)) - - make_all_cck_block_children cc_block, cck_block + cck_set.compliance_check_blocks.create( + name: name_with_refid(cc_block.name)).tap do | cck_block | + relink_checks_to_block cc_block, cck_block + end end def make_cck_blocks cc_set.compliance_control_blocks.each(&method(:make_cck_block)) end + def relink_checks_to_block cc_block, cck_block + cc_block + .compliance_controls + .each do | compliance_control | + control_id_to_check[compliance_control.id] + .update(compliance_check_block_id: cck_block.id) + end + end + # Copy Checks: def make_ccks_from_ccs cc_set.compliance_controls.each(&method(:make_compliance_check)) end - - def make_compliance_check(compliance_control, cck_block_id = nil) - already_there = get_from_cache compliance_control.id - # We do not want to impose traversal order of the DAG, that would - # make the code more resistant to change... - # So we check if we need to update the compliance_check_block_id - # of a control found in the cache. - # N.B. By traversing the indirect descendents from a set first, - # or IOW, traversing the control_blocks before the controls, - # this check could go away and we could return from the - # method in case of a cache hit. - if already_there - # Purely defensive: - if already_there.compliance_check_block_id.nil? && cck_block_id - already_there.update compliance_check_block_id: cck_block_id - end - return + def make_compliance_check(compliance_control) + cck_set.compliance_checks.create( + criticity: compliance_control.criticity, + name: name_with_refid(compliance_control.name), + code: compliance_control.code, + origin_code: compliance_control.origin_code + ).tap do | compliance_check | + control_id_to_check.update compliance_control.id => compliance_check end - make_compliance_check!(compliance_control, cck_block_id) - end - def make_compliance_check!(compliance_control, cck_block_id) - add_to_cache( - compliance_control.id, - cck_set.compliance_checks.create( - criticity: compliance_control.criticity, - name: name_with_refid(compliance_control.name), - code: compliance_control.code, - origin_code: compliance_control.origin_code, - compliance_check_block_id: cck_block_id - )) end def name_with_refid name @@ -104,23 +85,11 @@ class ComplianceControlSetCopier status: 'new' ) end + def control_id_to_check + # Map: compliance_control_id -> compliance_check + @__control_id_to_check__ ||= Hash.new + end def referential @__referential__ ||= Referential.find(referential_id) end - - # Copy Cache - # ---------- - def add_to_cache key, obj - # Right now we map key -> obj, in case memory consumption becomes too important - # we can map key -> obj.id and fetch the object from the database in get_from_cache - # (time vs. space tradeoff) - copy_cache.merge!(key => obj) - end - def get_from_cache key - copy_cache[key].tap do | ele | - end - end - def copy_cache - @__copy_cache__ ||= Hash.new - end end |
