Created
December 1, 2012 01:08
-
-
Save bobbytables/4179910 to your computer and use it in GitHub Desktop.
Temporary Table class for creating a join table
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TemporaryTable | |
attr_reader :name_prefix, :attributes | |
def initialize(name_prefix, attributes) | |
@name_prefix = name_prefix | |
@attributes = attributes | |
create_temp_table! | |
end | |
def table_name | |
@table_name ||= "#{name_prefix}_#{rand(1..9999)}" | |
end | |
def table | |
@table ||= begin | |
table_name = self.table_name | |
Class.new(ActiveRecord::Base) do | |
self.table_name = table_name | |
end | |
end | |
end | |
# Bulk insert relies on a multi-dimensional array that has the values in | |
# the order of the attributes passed in. | |
def bulk_insert(objects) | |
values = objects.each_with_object([]) do |object, collection| | |
if object.is_a? Array | |
line = object.map {|v| "'#{ActiveRecord::Base::sanitize(v)}'" }.join(", ") | |
else | |
line = "'#{ActiveRecord::Base::sanitize(object)}'" | |
end | |
collection << "(#{line})" | |
end | |
columns = attributes.keys.join(",") | |
conn.execute("INSERT INTO #{table_name} (#{columns}) VALUES #{values.join(", ")}") | |
end | |
def index(column) | |
conn.execute("ALTER TABLE #{table_name} ADD INDEX `#{column}` (`#{column}`)") | |
end | |
def drop! | |
return unless exists? | |
conn.execute("DROP TEMPORARY TABLE IF EXISTS #{table_name}") | |
@exists = false | |
end | |
def exists? | |
!!@exists | |
end | |
private | |
def create_temp_table! | |
return if exists? | |
schema = attributes.keys.each_with_object([]) do |key, columns| | |
columns << cast_attribute(key) | |
end | |
sql = "CREATE TEMPORARY TABLE #{table_name} (" | |
sql << schema.join(",\n") | |
sql << ")" | |
conn.execute(sql) | |
@exists = true | |
end | |
def cast_attribute(key) | |
case attributes[key] | |
when "integer" | |
"#{key} INTEGER(11) NOT NULL" | |
else | |
"#{key} VARCHAR(255)" | |
end | |
end | |
def conn | |
ActiveRecord::Base.connection | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment