dawarich/app/services/geojson/importer.rb

64 lines
1.5 KiB
Ruby
Raw Normal View History

2024-09-02 16:33:54 -04:00
# frozen_string_literal: true
2025-04-23 17:36:16 -04:00
class Geojson::Importer
include Imports::Broadcaster
2025-08-22 14:13:10 -04:00
include Imports::FileLoader
include PointValidation
BATCH_SIZE = 1000
2025-08-22 13:10:40 -04:00
attr_reader :import, :user_id, :file_path
2024-09-02 16:33:54 -04:00
2025-08-22 13:10:40 -04:00
def initialize(import, user_id, file_path = nil)
2024-09-02 16:33:54 -04:00
@import = import
@user_id = user_id
2025-08-22 13:10:40 -04:00
@file_path = file_path
2024-09-02 16:33:54 -04:00
end
def call
2025-08-22 13:10:40 -04:00
json = load_json_data
2025-04-23 17:27:55 -04:00
data = Geojson::Params.new(json).call
2024-09-02 16:33:54 -04:00
points_data = data.map do |point|
next if point[:lonlat].nil?
point.merge(
user_id: user_id,
import_id: import.id,
created_at: Time.current,
updated_at: Time.current
)
end
2024-09-02 16:33:54 -04:00
points_data.compact.each_slice(BATCH_SIZE).with_index do |batch, batch_index|
bulk_insert_points(batch)
broadcast_import_progress(import, (batch_index + 1) * BATCH_SIZE)
end
2024-09-02 16:33:54 -04:00
end
private
def bulk_insert_points(batch)
unique_batch = batch.uniq { |record| [record[:lonlat], record[:timestamp], record[:user_id]] }
# rubocop:disable Rails/SkipsModelValidations
Point.upsert_all(
unique_batch,
unique_by: %i[lonlat timestamp user_id],
returning: false,
on_duplicate: :skip
)
# rubocop:enable Rails/SkipsModelValidations
rescue StandardError => e
create_notification("Failed to process GeoJSON batch: #{e.message}")
end
def create_notification(message)
Notification.create!(
user_id: user_id,
title: 'GeoJSON Import Error',
content: message,
kind: :error
)
end
2024-09-02 16:33:54 -04:00
end