diff options
Diffstat (limited to 'activerecord')
7 files changed, 108 insertions, 101 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 84fc4c03f9..6480aeb171 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -318,21 +318,13 @@ module ActiveRecord @base = base end - #Handles non supported datatypes - e.g. XML - def method_missing(symbol, *args) - if symbol.to_s == 'xml' - xml_column_fallback(args) - else - super - end - end + def xml(*args) + raise NotImplementedError unless %w{ + sqlite mysql mysql2 + }.include? @base.adapter_name.downcase - def xml_column_fallback(*args) - case @base.adapter_name.downcase - when 'sqlite', 'mysql' - options = args.extract_options! - column(args[0], :text, options) - end + options = args.extract_options! + column(args[0], :text, options) end # Appends a primary key definition to the table definition. diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index ce6782aac7..4e770c37da 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -151,10 +151,10 @@ module ActiveRecord # # See also TableDefinition#column for details on how to create columns. def create_table(table_name, options = {}) - table_definition = TableDefinition.new(self) - table_definition.primary_key(options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false + td = table_definition + td.primary_key(options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false - yield table_definition if block_given? + yield td if block_given? if options[:force] && table_exists?(table_name) drop_table(table_name, options) @@ -162,7 +162,7 @@ module ActiveRecord create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE " create_sql << "#{quote_table_name(table_name)} (" - create_sql << table_definition.to_sql + create_sql << td.to_sql create_sql << ") #{options[:options]}" execute create_sql end @@ -534,6 +534,11 @@ module ActiveRecord def options_include_default?(options) options.include?(:default) && !(options[:null] == false && options[:default].nil?) end + + private + def table_definition + TableDefinition.new(self) + end end end end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 0a2bacdb84..194842a9a0 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -1,20 +1,19 @@ require 'active_record/connection_adapters/abstract_adapter' require 'active_support/core_ext/kernel/requires' require 'active_support/core_ext/object/blank' +require 'pg' module ActiveRecord class Base # Establishes a connection to the database that's used by all Active Record objects def self.postgresql_connection(config) # :nodoc: - require 'pg' - config = config.symbolize_keys host = config[:host] port = config[:port] || 5432 username = config[:username].to_s if config[:username] password = config[:password].to_s if config[:password] - if config.has_key?(:database) + if config.key?(:database) database = config[:database] else raise ArgumentError, "No database specified. Missing argument: database." @@ -27,12 +26,6 @@ module ActiveRecord end module ConnectionAdapters - class TableDefinition - def xml(*args) - options = args.extract_options! - column(args[0], 'xml', options) - end - end # PostgreSQL-specific extensions to column definitions in a table. class PostgreSQLColumn < Column #:nodoc: # Instantiates a new PostgreSQL column definition in a table. @@ -170,9 +163,7 @@ module ActiveRecord end end end - end - module ConnectionAdapters # The PostgreSQL adapter works both with the native C (http://ruby.scripting.ca/postgres/) and the pure # Ruby (available both as gem and from http://rubyforge.org/frs/?group_id=234&release_id=1944) drivers. # @@ -192,10 +183,17 @@ module ActiveRecord # * <tt>:allow_concurrency</tt> - If true, use async query methods so Ruby threads don't deadlock; # otherwise, use blocking query methods. class PostgreSQLAdapter < AbstractAdapter - ADAPTER_NAME = 'PostgreSQL'.freeze + class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition + def xml(*args) + options = args.extract_options! + column(args[0], 'xml', options) + end + end + + ADAPTER_NAME = 'PostgreSQL' NATIVE_DATABASE_TYPES = { - :primary_key => "serial primary key".freeze, + :primary_key => "serial primary key", :string => { :name => "character varying", :limit => 255 }, :text => { :name => "text" }, :integer => { :name => "integer" }, @@ -317,19 +315,22 @@ module ActiveRecord def quote(value, column = nil) #:nodoc: return super unless column - if value.kind_of?(String) && column.type == :binary - "'#{escape_bytea(value)}'" - elsif value.kind_of?(String) && column.sql_type == 'xml' - "xml '#{quote_string(value)}'" - elsif value.kind_of?(Numeric) && column.sql_type == 'money' + case value + when Numeric + return super unless column.sql_type == 'money' # Not truly string input, so doesn't require (or allow) escape string syntax. "'#{value}'" - elsif value.kind_of?(String) && column.sql_type =~ /^bit/ - case value - when /^[01]*$/ - "B'#{value}'" # Bit-string notation - when /^[0-9A-F]*$/i - "X'#{value}'" # Hexadecimal notation + when String + case column.sql_type + when 'bytea' then "'#{escape_bytea(value)}'" + when 'xml' then "xml '#{quote_string(value)}'" + when /^bit/ + case value + when /^[01]*$/ then "B'#{value}'" # Bit-string notation + when /^[0-9A-F]*$/i then "X'#{value}'" # Hexadecimal notation + end + else + super end else super @@ -1024,6 +1025,10 @@ module ActiveRecord [match_data[1], (rest.length > 0 ? rest : nil)] end end + + def table_definition + TableDefinition.new(self) + end end end end diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index e5e92f2b1c..5ca1923d89 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -1,4 +1,5 @@ require 'active_record/connection_adapters/sqlite_adapter' +require 'sqlite3' module ActiveRecord class Base @@ -20,16 +21,12 @@ module ActiveRecord raise ArgumentError, 'adapter name should be "sqlite3"' end - unless self.class.const_defined?(:SQLite3) - require_library_or_gem(config[:adapter]) - end - db = SQLite3::Database.new( config[:database], :results_as_hash => true ) - db.busy_timeout(config[:timeout]) unless config[:timeout].nil? + db.busy_timeout(config[:timeout]) if config[:timeout] ConnectionAdapters::SQLite3Adapter.new(db, logger, config) end diff --git a/activerecord/test/cases/dynamic_finder_match_test.rb b/activerecord/test/cases/dynamic_finder_match_test.rb index 64bf6cb508..e576870317 100644 --- a/activerecord/test/cases/dynamic_finder_match_test.rb +++ b/activerecord/test/cases/dynamic_finder_match_test.rb @@ -2,18 +2,67 @@ require "cases/helper" module ActiveRecord class DynamicFinderMatchTest < ActiveRecord::TestCase + def test_find_or_create_by + match = DynamicFinderMatch.match("find_or_create_by_age_and_sex_and_location") + assert_not_nil match + assert !match.finder? + assert match.instantiator? + assert_equal :first, match.finder + assert_equal :create, match.instantiator + assert_equal %w(age sex location), match.attribute_names + end + + def test_find_or_initialize_by + match = DynamicFinderMatch.match("find_or_initialize_by_age_and_sex_and_location") + assert_not_nil match + assert !match.finder? + assert match.instantiator? + assert_equal :first, match.finder + assert_equal :new, match.instantiator + assert_equal %w(age sex location), match.attribute_names + end + + def test_find_no_match + assert_nil DynamicFinderMatch.match("not_a_finder") + end + + def find_by_bang + match = DynamicFinderMatch.match("find_by_age_and_sex_and_location!") + assert_not_nil match + assert match.finder? + assert match.bang? + assert_equal :first, match.finder + assert_equal %w(age sex location), match.attribute_names + end + def test_find_by + match = DynamicFinderMatch.match("find_by_age_and_sex_and_location") + assert_not_nil match + assert match.finder? + assert_equal :first, match.finder + assert_equal %w(age sex location), match.attribute_names + end + + def test_find_by_with_symbol m = DynamicFinderMatch.match(:find_by_foo) assert_equal :first, m.finder assert_equal %w{ foo }, m.attribute_names end - def test_find_all_by + def test_find_all_by_with_symbol m = DynamicFinderMatch.match(:find_all_by_foo) assert_equal :all, m.finder assert_equal %w{ foo }, m.attribute_names end + def test_find_all_by + match = DynamicFinderMatch.match("find_all_by_age_and_sex_and_location") + assert_not_nil match + assert match.finder? + assert_equal :all, match.finder + assert_equal %w(age sex location), match.attribute_names + end + def test_find_last_by m = DynamicFinderMatch.match(:find_last_by_foo) assert_equal :last, m.finder diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 4f3e43d77d..26b5096255 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -11,57 +11,6 @@ require 'models/project' require 'models/developer' require 'models/customer' -class DynamicFinderMatchTest < ActiveRecord::TestCase - def test_find_no_match - assert_nil ActiveRecord::DynamicFinderMatch.match("not_a_finder") - end - - def test_find_by - match = ActiveRecord::DynamicFinderMatch.match("find_by_age_and_sex_and_location") - assert_not_nil match - assert match.finder? - assert_equal :first, match.finder - assert_equal %w(age sex location), match.attribute_names - end - - def find_by_bang - match = ActiveRecord::DynamicFinderMatch.match("find_by_age_and_sex_and_location!") - assert_not_nil match - assert match.finder? - assert match.bang? - assert_equal :first, match.finder - assert_equal %w(age sex location), match.attribute_names - end - - def test_find_all_by - match = ActiveRecord::DynamicFinderMatch.match("find_all_by_age_and_sex_and_location") - assert_not_nil match - assert match.finder? - assert_equal :all, match.finder - assert_equal %w(age sex location), match.attribute_names - end - - def test_find_or_initialize_by - match = ActiveRecord::DynamicFinderMatch.match("find_or_initialize_by_age_and_sex_and_location") - assert_not_nil match - assert !match.finder? - assert match.instantiator? - assert_equal :first, match.finder - assert_equal :new, match.instantiator - assert_equal %w(age sex location), match.attribute_names - end - - def test_find_or_create_by - match = ActiveRecord::DynamicFinderMatch.match("find_or_create_by_age_and_sex_and_location") - assert_not_nil match - assert !match.finder? - assert match.instantiator? - assert_equal :first, match.finder - assert_equal :create, match.instantiator - assert_equal %w(age sex location), match.attribute_names - end -end - class FinderTest < ActiveRecord::TestCase fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers, :categories, :categorizations diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 5242d78033..6e8ee95613 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -1588,13 +1588,23 @@ if ActiveRecord::Base.connection.supports_migrations? end end - if current_adapter?(:PostgreSQLAdapter) + if current_adapter?(:PostgreSQLAdapter) || current_adapter?(:SQLiteAdapter) || current_adapter?(:MysqlAdapter) || current_adapter?(:Mysql2Adapter) def test_xml_creates_xml_column + type = current_adapter?(:PostgreSQLAdapter) ? 'xml' : :text + with_new_table do |t| - t.expects(:column).with(:data, 'xml', {}) + t.expects(:column).with(:data, type, {}) t.xml :data end end + else + def test_xml_creates_xml_column + with_new_table do |t| + assert_raises(NotImplementedError) do + t.xml :data + end + end + end end protected |