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.



358
359
360
361
# File 'lib/project_unification/special_handlers.rb', line 358

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.



356
357
358
# File 'lib/project_unification/special_handlers.rb', line 356

def source_project_id
  @source_project_id
end

#target_project_idObject (readonly)

Returns the value of attribute target_project_id.



356
357
358
# File 'lib/project_unification/special_handlers.rb', line 356

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.



407
408
409
410
411
412
413
414
415
# File 'lib/project_unification/special_handlers.rb', line 407

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



363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/project_unification/special_handlers.rb', line 363

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)



417
418
419
420
421
# File 'lib/project_unification/special_handlers.rb', line 417

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