Ticket #2292: pg_seq.2363.diff
| File pg_seq.2363.diff, 13.0 kB (added by Rick, 4 years ago) |
|---|
-
activerecord/test/fixtures_test.rb
old new 5 5 require 'fixtures/task' 6 6 require 'fixtures/reply' 7 7 8 # Dummy model used to test fixtures loaded from a model 9 module TestModule 10 class Task < ActiveRecord::Base 11 end 12 end 13 8 14 class FixturesTest < Test::Unit::TestCase 9 15 self.use_instantiated_fixtures = true 10 16 self.use_transactional_fixtures = false 11 17 12 fixtures :topics, :developers, :accounts, :tasks 18 fixtures :topics, :developers, :accounts, :tasks, TestModule::Task 13 19 14 20 FIXTURES = %w( accounts companies customers 15 21 developers developers_projects entrants -
activerecord/test/adapter_test.rb
old new 35 35 ensure 36 36 @connection.remove_index :accounts, :firm_id rescue nil 37 37 end 38 39 # test resetting sequences in odd tables in postgreSQL 40 if ActiveRecord::Base.connection.respond_to?(:reset_sequences) 41 require 'fixtures/movie' 42 require 'fixtures/subscriber' 43 def test_reset_empty_table_with_custom_pk 44 Movie.destroy_all 45 Movie.connection.reset_sequences 'movies' 46 assert_equal 1, Movie.create(:name => 'fight club').id 47 end 48 49 def test_reset_table_with_non_integer_pk 50 Subscriber.destroy_all 51 Subscriber.connection.reset_sequences 'sequences' 52 assert Subscriber.new(:id => 'bob drake', :name => 'robert drake').save 53 end 54 end 38 55 end -
activerecord/test/inheritance_test.rb
old new 11 11 if ActiveRecord::ConnectionAdapters.const_defined? :SQLServerAdapter and ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::SQLServerAdapter) 12 12 Company.connection.execute "SET IDENTITY_INSERT companies ON" 13 13 end 14 Company.connection.insert "INSERT INTO companies (id, type, name) VALUES(100, 'bad_class!', 'Not happening')" 14 Company.connection.insert "INSERT INTO companies (id, type, name) VALUES(100, 'bad_class!', 'Not happening')", nil, 'id', 100 15 15 #We then need to turn it back Off before continuing. 16 16 if ActiveRecord::ConnectionAdapters.const_defined? :SQLServerAdapter and ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::SQLServerAdapter) 17 17 Company.connection.execute "SET IDENTITY_INSERT companies OFF" -
activerecord/test/fixtures/db_definitions/postgresql.sql
old new 6 6 ); 7 7 SELECT setval('accounts_id_seq', 100); 8 8 9 CREATE SEQUENCE companies_nonstd_seq START 101; 10 9 11 CREATE TABLE companies ( 10 id serial,12 id integer DEFAULT nextval('companies_nonstd_seq'), 11 13 "type" character varying(50), 12 14 "ruby_type" character varying(50), 13 15 firm_id integer, … … 16 18 rating integer default 1, 17 19 PRIMARY KEY (id) 18 20 ); 19 SELECT setval('companies_id_seq', 100);20 21 21 22 CREATE TABLE developers_projects ( 22 23 developer_id integer NOT NULL, -
activerecord/test/pk_test.rb
old new 32 32 subscriber.id = "jdoe" 33 33 assert_equal("jdoe", subscriber.id) 34 34 subscriber.name = "John Doe" 35 assert_nothing_raised{ subscriber.save }35 assert_nothing_raised{ subscriber.save! } 36 36 37 37 subscriberReloaded = Subscriber.find("jdoe") 38 38 assert_equal("John Doe", subscriberReloaded.name) -
activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
old new 104 104 def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc: 105 105 execute(sql, name) 106 106 table = sql.split(" ", 4)[2] 107 return id_value || last_insert_id(table, pk)107 return id_value || last_insert_id(table, sequence_name) 108 108 end 109 109 110 110 def query(sql, name = nil) #:nodoc: … … 200 200 def schema_search_path #:nodoc: 201 201 @schema_search_path ||= query('SHOW search_path')[0][0] 202 202 end 203 203 204 def default_sequence_format(table_name, pk) 205 "#{table_name}_#{pk}_seq" 206 end 207 208 # Start PostgreSQL fixtures at id 1. Skip tables without models 209 # and models with nonstandard primary keys. 210 def reset_sequences(*table_names) 211 table_names.each do |table| 212 table_name = table.to_s.split('.') 213 if table_name[1] 214 schema = table_name[0] 215 relname = table_name[1] 216 else 217 schema = 'public' 218 relname = table_name[0] 219 end 220 seq_sql = <<-end_seq 221 SELECT attname, CASE WHEN substr(pg_get_expr(adbin, attrelid), 1, 7) = 'nextval' THEN 222 substr(split_part((pg_get_expr(adbin, attrelid)), '''::', 1), 10) ELSE NULL END 223 FROM pg_attrdef, pg_namespace, pg_class, pg_attribute, pg_constraint 224 WHERE pg_namespace.nspname = '#{schema}' AND 225 pg_class.relnamespace = pg_namespace.oid AND 226 pg_class.relname = '#{relname}' AND 227 pg_attribute.attrelid = pg_class.oid AND 228 pg_attribute.attnum = pg_constraint.conkey[1] AND 229 pg_constraint.conrelid = pg_class.oid AND 230 pg_constraint.contype = 'p' AND 231 pg_attrdef.adrelid = pg_class.oid AND 232 pg_attrdef.adnum = pg_attribute.attnum 233 end_seq 234 seq = execute(seq_sql, 'Retrieve sequence name') 235 execute( 236 "SELECT setval('#{seq[0][1]}', (SELECT COALESCE(MAX(#{seq[0][0]})+1, 1) FROM #{schema}.#{relname}), false)", 237 'Setting Sequence' 238 ) unless seq[0].nil? || seq[0][1].nil? 239 end 240 end 241 204 242 def add_column(table_name, column_name, type, options = {}) 205 243 native_type = native_database_types[type] 206 244 sql_commands = ["ALTER TABLE #{table_name} ADD #{column_name} #{type_to_sql(type, options[:limit])}"] … … 240 278 private 241 279 BYTEA_COLUMN_TYPE_OID = 17 242 280 243 def last_insert_id(table, column = "id") 244 sequence_name = "#{table}_#{column || 'id'}_seq" 281 def last_insert_id(table, sequence_name) 245 282 @connection.exec("SELECT currval('#{sequence_name}')")[0][0].to_i 246 283 end 247 284 -
activerecord/lib/active_record/connection_adapters/oci_adapter.rb
old new 263 263 def adapter_name() 264 264 'OCI' 265 265 end 266 266 267 def default_sequence_format(table_name, pk) 268 "#{table_name}_seq" 269 end 270 267 271 private 268 272 # Oracle column names by default are case-insensitive, but treated as upcase; 269 273 # for neatness, we'll downcase within Rails. EXCEPT that folks CAN quote -
activerecord/lib/active_record/fixtures.rb
old new 220 220 self.all_loaded_fixtures = {} 221 221 222 222 def self.create_fixtures(fixtures_directory, *table_names) 223 class_mapping = table_names.last.is_a?(Hash) ? table_names.pop : {} 223 224 connection = block_given? ? yield : ActiveRecord::Base.connection 224 225 old_logger_level = ActiveRecord::Base.logger.level 225 226 … … 237 238 fixtures.reverse.each { |fixture| fixture.delete_existing_fixtures } 238 239 fixtures.each { |fixture| fixture.insert_fixtures } 239 240 end 240 241 reset_sequences(connection, table_names) if connection.is_a?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)242 241 242 if connection.respond_to?(:reset_sequences) 243 connection.reset_sequences(*(table_names.flatten.collect { |t| t.respond_to?(:table_name) ? t.table_name : t })) 244 end 245 243 246 return fixtures.size > 1 ? fixtures : fixtures.first 244 247 ensure 245 248 ActiveRecord::Base.logger.level = old_logger_level 246 249 end 247 250 end 248 251 249 # Start PostgreSQL fixtures at id 1. Skip tables without models250 # and models with nonstandard primary keys.251 def self.reset_sequences(connection, table_names)252 table_names.flatten.each do |table|253 if table_class = table.to_s.classify.constantize rescue nil254 pk = table_class.columns_hash[table_class.primary_key]255 if pk and pk.type == :integer256 connection.execute(257 "SELECT setval('#{table}_#{pk.name}_seq', (SELECT COALESCE(0, MAX(#{pk.name}))+1 FROM #{table}), false)",258 'Setting Sequence'259 )260 end261 end262 end263 end264 265 252 attr_reader :table_name 266 253 267 254 def initialize(connection, table_name, fixture_path, file_filter = DEFAULT_FILTER_RE) … … 404 391 class_inheritable_accessor :use_transactional_fixtures 405 392 class_inheritable_accessor :use_instantiated_fixtures # true, false, or :no_instances 406 393 class_inheritable_accessor :pre_loaded_fixtures 394 class_inheritable_accessor :fixture_class_mapping 407 395 408 396 self.fixture_table_names = [] 397 self.fixture_class_mapping = {} 409 398 self.use_transactional_fixtures = false 410 399 self.use_instantiated_fixtures = true 411 400 self.pre_loaded_fixtures = false … … 414 403 415 404 def self.fixtures(*table_names) 416 405 table_names = table_names.flatten 417 self.fixture_table_names |= table_names 406 table_names.each do |table| 407 next unless table.respond_to?(:table_name) 408 fixture_class_mapping[table.table_name.to_sym] = table 409 end 410 self.fixture_table_names |= table_names.collect { |t| t.respond_to?(:table_name) ? t.table_name.to_sym : t } 418 411 require_fixture_classes(table_names) 419 setup_fixture_accessors (table_names)412 setup_fixture_accessors 420 413 end 421 414 422 415 def self.require_fixture_classes(table_names=nil) 423 416 (table_names || fixture_table_names).each do |table_name| 417 next if table_name.respond_to?(:table_name) # skip if it's an AR model instead of a table name string 424 418 begin 425 419 require Inflector.singularize(table_name.to_s) 426 420 rescue LoadError … … 519 513 private 520 514 def load_fixtures 521 515 @loaded_fixtures = {} 522 fixtures = Fixtures.create_fixtures(fixture_path, fixture_table_names )516 fixtures = Fixtures.create_fixtures(fixture_path, fixture_table_names, fixture_class_mapping) 523 517 unless fixtures.nil? 524 518 if fixtures.instance_of?(Fixtures) 525 519 @loaded_fixtures[fixtures.table_name] = fixtures -
activerecord/lib/active_record/base.rb
old new 566 566 "type" 567 567 end 568 568 569 # Defines the sequence_name (for Oracle ) -- can be overridden in subclasses.569 # Defines the sequence_name (for Oracle and PostgreSQL) -- can be overridden in subclasses. 570 570 def sequence_name 571 "#{table_name}_seq" 571 connection.respond_to?(:default_sequence_format) ? 572 connection.default_sequence_format(table_name, primary_key) : 573 nil 572 574 end 573 575 574 576 # Sets the table name to use to the given value, or (if the value … … 616 618 617 619 # Sets the name of the sequence to use when generating ids to the given 618 620 # value, or (if the value is nil or false) to the value returned by the 619 # given block. Currently useful only when using Oracle , which requires620 # explicit sequences.621 # given block. Currently useful only when using Oracle and PostgreSQL, 622 # which require explicit sequences. 621 623 # 622 624 # Setting the sequence name when using other dbs will have no effect. 623 # If a sequence name is not explicitly set when using Oracle, it will 624 # default to the commonly used pattern of: #{table_name}_seq 625 # If a sequence name is not explicitly set, it will default to the 626 # commonly used pattern of: #{table_name}_seq for Oracle and #{table_name}_#{pk}_seq 627 # for PostgreSQL. 625 628 # 626 629 # Example: 627 630 #