cartodb/lib/carto/db/sql_interface.rb
2020-06-15 10:58:47 +08:00

69 lines
2.0 KiB
Ruby

module Carto
module Db
# Simple database interface that can be used through Sequel or ActiveRecord connections
# (e.g. as returned by User#in_database and Carto::User#in_database respectively)
# It provides two operations:
# * run to execute an SQL statement disregarding any results
# * fetch to obtain the resulting rows of a SQL SELECT
# the result is an array of hashes using symbol keys (with the name of the columns).
# The types of tuple values may vary between Sequel and ActiveRecord (ActiveRecord keeps them as text)
# If a block is passed to this method it receives each of the rows
class SqlInterface
class Error < RuntimeError; end
module SequelConnection
def run(sql)
@db_connection.run(sql)
nil
rescue Sequel::DatabaseError => e
raise Error.new(e.message)
end
def fetch(sql, &block)
if block
@db_connection.fetch(sql, &block)
nil
else
@db_connection.fetch(sql, &block).all
end
rescue Sequel::DatabaseError => e
raise Error.new(e.message)
end
end
module ActiveRecordConnection
def run(sql)
@db_connection.execute(sql)
nil
rescue ActiveRecord::StatementInvalid => e
raise Error.new(e.message)
end
def fetch(sql, &block)
rows = @db_connection.select_all(sql).map(&:symbolize_keys)
if block
rows.each &block
nil
else
rows
end
rescue ActiveRecord::StatementInvalid => e
raise Error.new(e.message)
end
end
def initialize(db_connection)
@db_connection = db_connection
case db_connection
when Sequel::Postgres::Database
extend SequelConnection
when ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
extend ActiveRecordConnection
else
raise "Invalid database connection"
end
end
end
end
end