Permalink
Browse files

remove knowledge of SQL from the column definition object

  • Loading branch information...
1 parent a03ab8c commit 69ef76a6f8b1fbfdee81e753d6e50c3c0396d47c @tenderlove tenderlove committed Mar 16, 2013
@@ -20,29 +20,9 @@ def string_to_binary(value)
value
end
- def sql_type
- base.type_to_sql(type.to_sym, limit, precision, scale)
- end
-
def primary_key?
type.to_sym == :primary_key
end
-
- def to_sql
- column_sql = "#{base.quote_column_name(name)} #{sql_type}"
- column_options = {}
- column_options[:null] = null unless null.nil?
- column_options[:default] = default unless default.nil?
- column_options[:column] = self
- add_column_options!(column_sql, column_options) unless primary_key?
- column_sql
- end
-
- private
-
- def add_column_options!(sql, options)
- base.add_column_options!(sql, options)
- end
end
# Represents the schema of an SQL table in an abstract way. This class
@@ -287,7 +267,8 @@ def references(*args)
# concatenated together. This string can then be prepended and appended to
# to generate the final SQL to create the table.
def to_sql
- columns.map { |c| c.to_sql } * ', '
+ viz = @base.schema_creation
+ columns.map { |c| viz.accept c }.join ', '
end
private
@@ -100,6 +100,47 @@ def initialize(connection, logger = nil, pool = nil) #:nodoc:
@visitor = nil
end
+ class SchemaCreation
+ def initialize(conn)
+ @conn = conn
+ @cache = {}
+ end
+
+ def accept(o)
+ m = @cache[o.class] ||= "visit_#{o.class.name.split('::').last}"
+ send m, o
+ end
+
+ private
+
+ def visit_ColumnDefinition(o)
+ sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale)
+ column_sql = "#{quote_column_name(o.name)} #{sql_type}"
+ column_options = {}
+ column_options[:null] = o.null unless o.null.nil?
+ column_options[:default] = o.default unless o.default.nil?
+ column_options[:column] = o
+ add_column_options!(column_sql, column_options) unless o.primary_key?
+ column_sql
+ end
+
+ def quote_column_name(name)
+ @conn.quote_column_name name
+ end
+
+ def type_to_sql(type, limit, precision, scale)
+ @conn.type_to_sql type.to_sym, limit, precision, scale
+ end
+
+ def add_column_options!(column_sql, column_options)
+ @conn.add_column_options! column_sql, column_options
+ end
+ end
+
+ def schema_creation
+ SchemaCreation.new self
+ end
+
def lease
synchronize do
unless in_use
@@ -8,6 +8,7 @@ def setup
def @adapter.native_database_types
{:string => "varchar"}
end
+ @viz = @adapter.schema_creation
end
def test_can_set_coder
@@ -37,23 +38,23 @@ def test_should_not_include_default_clause_when_default_is_null
column_def = ColumnDefinition.new(
@adapter, column.name, "string",
column.limit, column.precision, column.scale, column.default, column.null)
- assert_equal "title varchar(20)", column_def.to_sql
+ assert_equal "title varchar(20)", @viz.accept(column_def)
end
def test_should_include_default_clause_when_default_is_present
column = Column.new("title", "Hello", "varchar(20)")
column_def = ColumnDefinition.new(
@adapter, column.name, "string",
column.limit, column.precision, column.scale, column.default, column.null)
- assert_equal %Q{title varchar(20) DEFAULT 'Hello'}, column_def.to_sql
+ assert_equal %Q{title varchar(20) DEFAULT 'Hello'}, @viz.accept(column_def)
end
def test_should_specify_not_null_if_null_option_is_false
column = Column.new("title", "Hello", "varchar(20)", false)
column_def = ColumnDefinition.new(
@adapter, column.name, "string",
column.limit, column.precision, column.scale, column.default, column.null)
- assert_equal %Q{title varchar(20) DEFAULT 'Hello' NOT NULL}, column_def.to_sql
+ assert_equal %Q{title varchar(20) DEFAULT 'Hello' NOT NULL}, @viz.accept(column_def)
end
if current_adapter?(:MysqlAdapter)

0 comments on commit 69ef76a

Please sign in to comment.