2013-02-25 11:42:20 -05:00
|
|
|
class ActiveRecord::Base
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
# Execute SQL manually
|
|
|
|
def self.exec_sql(*args)
|
|
|
|
conn = ActiveRecord::Base.connection
|
|
|
|
sql = ActiveRecord::Base.send(:sanitize_sql_array, args)
|
|
|
|
conn.execute(sql)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.exec_sql_row_count(*args)
|
2013-02-25 11:42:20 -05:00
|
|
|
exec_sql(*args).cmd_tuples
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2013-10-30 15:45:13 -04:00
|
|
|
def self.sql_fragment(*sql_array)
|
|
|
|
ActiveRecord::Base.send(:sanitize_sql_array, sql_array)
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def exec_sql(*args)
|
|
|
|
ActiveRecord::Base.exec_sql(*args)
|
|
|
|
end
|
|
|
|
|
2013-02-11 15:47:28 -05:00
|
|
|
|
|
|
|
# Executes the given block +retries+ times (or forever, if explicitly given nil),
|
|
|
|
# catching and retrying SQL Deadlock errors.
|
|
|
|
#
|
|
|
|
# Thanks to: http://stackoverflow.com/a/7427186/165668
|
|
|
|
#
|
|
|
|
def self.retry_lock_error(retries=5, &block)
|
|
|
|
begin
|
|
|
|
yield
|
|
|
|
rescue ActiveRecord::StatementInvalid => e
|
2013-03-04 19:42:44 -05:00
|
|
|
if e.message =~ /deadlock detected/ && (retries.nil? || retries > 0)
|
2013-02-11 15:47:28 -05:00
|
|
|
retry_lock_error(retries ? retries - 1 : nil, &block)
|
|
|
|
else
|
|
|
|
raise e
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
# Support for psql. If we want to support multiple RDBMs in the future we can
|
|
|
|
# split this.
|
|
|
|
def exec_sql_row_count(*args)
|
|
|
|
exec_sql(*args).cmd_tuples
|
|
|
|
end
|
|
|
|
|
2013-02-25 11:42:20 -05:00
|
|
|
end
|