From 0fd658ab5037adf3b1180f787fec5eeee8e3efcf Mon Sep 17 00:00:00 2001 From: Dan Kubb Date: Thu, 4 Feb 2010 06:00:20 +0100 Subject: [PATCH] Ensure Text can be auto-migrated when :index and :unique_index are true [#1103 state:resolved] --- lib/dm-core/migrations.rb | 35 ++++++++++++++++++++++++++++--- lib/dm-core/property_set.rb | 5 +++++ spec/public/property/text_spec.rb | 22 +++++++++++++++++++ spec/spec_helper.rb | 2 +- 4 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 spec/public/property/text_spec.rb diff --git a/lib/dm-core/migrations.rb b/lib/dm-core/migrations.rb index 76f8f3ac..a7ae1a67 100644 --- a/lib/dm-core/migrations.rb +++ b/lib/dm-core/migrations.rb @@ -208,7 +208,7 @@ def drop_table_statement(model) def create_index_statements(model) name = self.name table_name = model.storage_name(name) - model.properties(name).indexes.map do |index_name, fields| + indexes(model).map do |index_name, fields| <<-SQL.compress_lines CREATE INDEX #{quote_name("index_#{table_name}_#{index_name}")} ON #{quote_name(table_name)} (#{fields.map { |field| quote_name(field) }.join(', ')}) @@ -220,7 +220,7 @@ def create_index_statements(model) def create_unique_index_statements(model) name = self.name table_name = model.storage_name(name) - model.properties(name).unique_indexes.map do |index_name, fields| + unique_indexes(model).map do |index_name, fields| <<-SQL.compress_lines CREATE UNIQUE INDEX #{quote_name("unique_#{table_name}_#{index_name}")} ON #{quote_name(table_name)} (#{fields.map { |field| quote_name(field) }.join(', ')}) @@ -283,6 +283,16 @@ def property_schema_statement(connection, schema) statement << ' NOT NULL' unless schema[:allow_nil] statement end + + # @api private + def indexes(model) + model.properties(name).indexes + end + + # @api private + def unique_indexes(model) + model.properties(name).unique_indexes + end end # module SQL include SQL @@ -547,6 +557,26 @@ def integer_display_size(range) def integer_statement_sign(range) ' UNSIGNED' unless range.first < 0 end + + # @api private + def indexes(model) + filter_indexes(model, super) + end + + # @api private + def unique_indexes(model) + filter_indexes(model, super) + end + + # Filter out any indexes with an unindexable column in MySQL + # + # @api private + def filter_indexes(model, indexes) + field_map = model.properties(name).field_map + indexes.select do |index_name, fields| + fields.all? { |field| field_map[field].type != Types::Text } + end + end end # module SQL include SQL @@ -1275,7 +1305,6 @@ def type_map end # module SqlserverAdapter - module Repository # Determine whether a particular named storage exists in this repository # diff --git a/lib/dm-core/property_set.rb b/lib/dm-core/property_set.rb index fdd6fd5a..9c494291 100644 --- a/lib/dm-core/property_set.rb +++ b/lib/dm-core/property_set.rb @@ -147,6 +147,11 @@ def in_context(properties) properties_in_context.flatten.uniq end + # @api private + def field_map + map { |property| [ property.field, property ] }.to_hash + end + private # @api semipublic diff --git a/spec/public/property/text_spec.rb b/spec/public/property/text_spec.rb new file mode 100644 index 00000000..520a341e --- /dev/null +++ b/spec/public/property/text_spec.rb @@ -0,0 +1,22 @@ +require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) + +describe DataMapper::Property, 'Text type' do + describe 'migration with an index' do + supported_by :all do + before do + @model = DataMapper::Model.new do + storage_names[:default] = 'anonymous' + + property :id, DataMapper::Types::Serial + property :body, DataMapper::Types::Text, :index => true + end + end + + it 'should allow a migration' do + lambda { + @model.auto_migrate! + }.should_not raise_error(DataObjects::SyntaxError) + end + end + end if defined?(DataObjects::SyntaxError) +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ba5243a4..21db756b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -133,7 +133,7 @@ def remove_ivars(object, instance_variables = object.instance_variables) constant_name = parts.pop.to_sym base = parts.empty? ? Object : Object.full_const_get(parts.join('::')) - if base.const_defined?(constant_name) + if constant_name.to_s[0] != ?# && base.const_defined?(constant_name) base.send(:remove_const, constant_name) end