Skip to content

Instantly share code, notes, and snippets.

@bobbytables
Created December 1, 2012 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bobbytables/4179910 to your computer and use it in GitHub Desktop.
Save bobbytables/4179910 to your computer and use it in GitHub Desktop.
Temporary Table class for creating a join table
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