Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
154 lines (131 sloc) 5.31 KB
class Event < ActiveRecord::Base
validates_presence_of :event_type, :bot_instance_id, :provider
validates_inclusion_of :provider, in: %w(slack kik facebook telegram)
belongs_to :user, foreign_key: 'bot_user_id', class_name: 'BotUser'
belongs_to :bot_instance
validates_with EventAttributesValidator
validates_with EventTypeValidator
validates_with BotUserIdValidator
store_accessor :event_attributes, :mid, :seq
def self.rollup!
Event.connection.execute(<<-SQL
CREATE OR REPLACE FUNCTION custom_append_to_rolledup_events_queue_on_update()
RETURNS TRIGGER LANGUAGE plpgsql
AS $body$
DECLARE
__bot_instance_id int;
__bot_user_id int;
__created_at timestamp;
BEGIN
CASE TG_OP
WHEN 'UPDATE' THEN
SELECT events.bot_instance_id, events.bot_user_id, events.created_at INTO __bot_instance_id, __bot_user_id, __created_at FROM events WHERE events.id = NEW.event_id LIMIT 1;
IF NOT FOUND THEN
RETURN NULL;
END IF;
INSERT INTO rolledup_event_queue(bot_instance_id, bot_user_id, dashboard_id, diff, created_at)
VALUES (__bot_instance_id, __bot_user_id, NEW.dashboard_id, +1, date_trunc('hour', __created_at));
END CASE;
RETURN NULL;
END;
$body$;
CREATE OR REPLACE FUNCTION append_to_rolledup_events_queue_on_update()
RETURNS TRIGGER LANGUAGE plpgsql
AS $body$
DECLARE
__bot_id int;
__dashboard_id int;
BEGIN
CASE TG_OP
WHEN 'UPDATE' THEN
SELECT bot_instances.bot_id INTO __bot_id FROM bot_instances WHERE bot_instances.id = NEW.bot_instance_id LIMIT 1;
IF NOT FOUND THEN
RETURN NULL;
END IF;
IF NEW.event_type = 'message' AND NEW.is_from_bot = 't' THEN
SELECT dashboards.id FROM dashboards INTO __dashboard_id WHERE dashboards.dashboard_type = 'messages-from-bot' AND dashboards.bot_id = __bot_id LIMIT 1;
IF NOT FOUND THEN
RETURN NULL;
END IF;
ELSIF NEW.event_type = 'message' AND NEW.is_for_bot = 't' THEN
SELECT dashboards.id FROM dashboards INTO __dashboard_id WHERE dashboards.dashboard_type = 'messages-to-bot' AND dashboards.bot_id = __bot_id LIMIT 1;
IF NOT FOUND THEN
RETURN NULL;
END IF;
ELSE
SELECT dashboards.id FROM dashboards INTO __dashboard_id WHERE dashboards.event_type = NEW.event_type AND dashboards.bot_id = __bot_id LIMIT 1;
IF NOT FOUND THEN
RETURN NULL;
END IF;
END IF;
INSERT INTO rolledup_event_queue(bot_instance_id, bot_user_id, dashboard_id, diff, created_at)
VALUES (NEW.bot_instance_id, NEW.bot_user_id, __dashboard_id, +1, date_trunc('hour', NEW.created_at));
IF random() < 0.0001 THEN /* 1/10,000 probability */
PERFORM flush_rolledup_event_queue();
END IF;
END CASE;
RETURN NULL;
END;
$body$;
DROP TRIGGER IF EXISTS event_update ON events;
CREATE TRIGGER event_update after
UPDATE
ON events FOR each row
EXECUTE PROCEDURE append_to_rolledup_events_queue_on_update();
DROP TRIGGER IF EXISTS custom_event_update ON dashboard_events;
CREATE TRIGGER custom_event_update after
UPDATE
ON dashboard_events FOR each row
EXECUTE PROCEDURE custom_append_to_rolledup_events_queue_on_update();
SQL
)
months = ["2016-04-01", "2016-05-01", "2016-06-01", "2016-07-01", "2016-08-01", "2016-09-01", "2016-10-01"]
require 'benchmark'
months.each do |month|
puts "Starting month: #{month}"
puts Benchmark.measure {
date = Date.parse(month)
Event.where("events.created_at" => date.beginning_of_month..date.end_of_month).update_all(updated_at: Time.now)
RolledupEventQueue.connection.execute("SELECT flush_rolledup_event_queue();")
}
end
start = Date.parse("2016-11-01")
end_time = Date.parse("2016-11-20")
Event.where("events.created_at" => start.beginning_of_day..end_time.end_of_day).update_all(updated_at: Time.now)
RolledupEventQueue.connection.execute("SELECT flush_rolledup_event_queue();")
Date.parse("2016-11-21").upto(Date.parse("2016-12-10")) do |date|
puts "Starting day: #{date}"
puts Benchmark.measure {
Event.where("events.created_at" => date.beginning_of_day..date.end_of_day).update_all(updated_at: Time.now)
RolledupEventQueue.connection.execute("SELECT flush_rolledup_event_queue();")
}
end
Event.connection.execute("DROP TRIGGER IF EXISTS event_update ON events;")
Event.connection.execute("DROP FUNCTION IF EXISTS append_to_rolledup_events_queue_on_update() CASCADE;")
puts Benchmark.measure {
DashboardEvent.update_all(updated_at: Time.now)
RolledupEventQueue.connection.execute("SELECT flush_rolledup_event_queue();")
}
Event.connection.execute("DROP TRIGGER IF EXISTS custom_event_update ON events;")
Event.connection.execute("DROP FUNCTION IF EXISTS custom_append_to_rolledup_events_queue_on_update() CASCADE;")
end
def in_words
if self.event_type == 'message'
"Said '#{self.text}'"
else
case self.event_type
when 'messaging_postbacks'
payload = self.event_attributes['payload']
begin
payload = JSON.parse(payload)
rescue JSON::ParserError
return "Clicked Button: #{payload}"
end
"Clicked Button with user defined payload"
end
end
end
def created_at_string
self.created_at.to_s('%Y-%m-%d %H:%M:%S.%N')
end
end