lib/vvz_updater/vvz_updater/event_date_updater.rb
require 'upsert'
require 'upsert/active_record_upsert'
require 'pg_hstore'
module VVZUpdater
class EventDateUpdater
def initialize(term)
# @source = source.to_s
@term = term
@connection = ActiveRecord::Base.connection
end
def run!(events)
@event_index = get_event_index()
dates = get_dates(events)
puts "create room index"
@room_index = get_room_index(dates)
# puts "setup date grouper"
# grouper = DateGrouper.new(dates, existing_dates(events))
# puts "delete"
# delete(grouper.removed_db_dates)
# puts "create"
# create(grouper.new_dates)
# puts "update"
# update(grouper.existing_date_pairs)
puts "delete all dates"
delete_existing()
puts "create"
create(dates)
# upsert(dates)
end
def self.run!(term, events)
new(term).run!(events)
end
def get_dates(events)
events.flat_map do |event|
dates = event.fetch(:dates)
dates.each {|date| date[:event_id] = @event_index.fetch(event.fetch(:id)) }
dates
end
end
def delete_existing()
EventDate.where(term: @term).delete_all
end
# def existing_dates(events)
# # event_ids = events.map {|event| event.fetch(:id)}
# # EventDate.where(event_id: event_ids).select([:id, :uuid])
# uuids = events.flat_map {|event| event.fetch(:dates)}.map {|date| date.fetch(:id)}
# EventDate.where(uuid: uuids).select([:id, :uuid])
# end
def create(dates)
puts "prepare create"
hashes = dates.map {|date| attributes(date) }
puts "actually create"
mass_insert(hashes)
end
def upsert(dates)
Upsert.batch(@connection, :event_dates) do |upsert|
dates.each do |date|
attributes = attributes(date)
upsert.row({uuid: attributes[:uuid]}, attributes)
end
end
end
def mass_insert(hashes)
keys = hashes.first.keys.map(&:to_s)
inserts = hashes.map do |data|
items = data.values.map do |x|
!x.nil? ? "'#{x}'" : "NULL"
end.join(", ")
"(#{items})"
end
sql = "INSERT INTO event_dates (#{keys.join(", ")}) VALUES #{inserts.join(", ")}"
@connection.execute(sql)
end
# def delete(db_dates)
# # binding.pry
# # EventDate.destroy(db_dates) unless
# # db_dates.delete_all
# raise
# end
# def update(pairs)
# zipped = pairs.map do |pair|
# [pair.db_node.id, attributes_hash(pair.node)]
# end
# ids, hashes = zipped.transpose
# EventDate.update(ids, hashes)
# end
def attributes(date)
start_time = Time.zone.parse("#{date.fetch(:start_time)} #{date.fetch(:start_date)}").utc.to_s(:db)
end_time = Time.zone.parse("#{date.fetch(:end_time)} #{date.fetch(:end_date)}").utc.to_s(:db)
room_id = date.fetch(:room) ? date.fetch(:room).fetch(:id) : nil
{
uuid: date.fetch(:id),
start_time: start_time,
end_time: end_time,
# api_last_modified: date.fetch(:last_modified),
room_id: room_id && @room_index[room_id],
created_at: Time.now.to_s,
updated_at: Time.now.to_s,
relation: date.fetch(:relation),
event_id: date.fetch(:event_id),
term: @term
}
end
def get_room_index(dates)
create_rooms(dates)
room_index = {}
db_rooms = Room.select([:id, :uuid])
db_rooms.each {|room| room_index[room.uuid] = room.id if room.uuid }
room_index
end
def create_rooms(dates)
rooms = dates.map {|date| date.fetch(:room) }.compact
db_rooms = Room.select([:id, :uuid])
grouper = RoomGrouper.new(rooms, db_rooms)
rooms = grouper.new_nodes
Upsert.batch(@connection, :rooms) do |upsert|
rooms.each do |room|
attributes = room_attributes(room)
upsert.row({uuid: attributes[:uuid]}, attributes)
end
end
end
def room_attributes(room)
{
uuid: room.fetch(:id),
name: room.fetch(:name),
created_at: Time.now.to_s,
updated_at: Time.now.to_s
}
end
def get_event_index()
db_events = Event.where(term: @term).select([:id, :external_id])
db_events.reduce({}) do |index, event|
index[event.external_id] = event.id
index
end
end
end
end
require_relative "event_date_updater/value_set"
require_relative "event_date_updater/date_grouper"
require_relative "event_date_updater/room_grouper"