Class: ProjectUnification::SpecialHandlers::DocumentHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/project_unification/special_handlers.rb

Overview

Handler for Document with fingerprint-based deduplication. Mirrors ImageHandler — see its comment for the Phase 1 / Phase 2 design.

Constant Summary collapse

SENTINEL_PREFIX =
'UNIFICATION TO PROJECT'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_project_id:, target_project_id:, options: {}) ⇒ DocumentHandler

Returns a new instance of DocumentHandler.



405
406
407
408
# File 'lib/project_unification/special_handlers.rb', line 405

def initialize(source_project_id:, target_project_id:, options: {})
  @source_project_id = source_project_id
  @target_project_id = target_project_id
end

Instance Attribute Details

#source_project_idObject (readonly)

Returns the value of attribute source_project_id.



403
404
405
# File 'lib/project_unification/special_handlers.rb', line 403

def source_project_id
  @source_project_id
end

#target_project_idObject (readonly)

Returns the value of attribute target_project_id.



403
404
405
# File 'lib/project_unification/special_handlers.rb', line 403

def target_project_id
  @target_project_id
end

Instance Method Details

#duplicate_pairsObject (private)

Returns [[source_document, target_id], ...] for documents whose fingerprint matches one in the target project. Excludes .prj/.cpg files since fingerprint uniqueness is not enforced for those.



454
455
456
457
458
459
460
461
462
# File 'lib/project_unification/special_handlers.rb', line 454

def duplicate_pairs
  target_by_fingerprint = non_shapefile_documents(target_project_id)
                            .pluck(:document_file_fingerprint, :id)
                            .to_h

  non_shapefile_documents(source_project_id)
    .where(document_file_fingerprint: target_by_fingerprint.keys)
    .map { |doc| [doc, target_by_fingerprint[doc.document_file_fingerprint]] }
end

#migrateObject



410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# File 'lib/project_unification/special_handlers.rb', line 410

def migrate
  result = {
    track: :special,
    model: 'Document',
    migrated: 0,
    duplicates_found: [],
    errors: [],
    merge_registry: []
  }

  duplicate_pairs.each do |source_document, target_id|
    original_fingerprint = source_document.document_file_fingerprint
    source_document.update_columns(
      document_file_fingerprint: "#{SENTINEL_PREFIX} #{target_project_id} #{source_document.id}"
    )
    result[:duplicates_found] << {
      source_id: source_document.id,
      target_id: target_id,
      fingerprint: original_fingerprint
    }
    result[:merge_registry] << {
      model: 'Document',
      renamed_id: source_document.id,
      target_id: target_id
    }
  end

  result[:migrated] = Document.where(project_id: source_project_id)
                              .update_all(project_id: target_project_id)
  result
rescue => e
  {
    track: :special,
    model: 'Document',
    migrated: 0,
    errors: [{ error: e.message, backtrace: e.backtrace.first(3) }]
  }
end

#non_shapefile_documents(project_id) ⇒ Object (private)



464
465
466
467
468
# File 'lib/project_unification/special_handlers.rb', line 464

def non_shapefile_documents(project_id)
  Document.where(project_id: project_id)
          .where.not(document_file_fingerprint: nil)
          .where.not("document_file_file_name ILIKE '%.prj' OR document_file_file_name ILIKE '%.cpg'")
end