diff options
26 files changed, 312 insertions, 82 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 92e0b47469..d7823855a3 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,5 +1,28 @@ ## Rails 4.0.0 (unreleased) ## +* Added the schema cache dump feature. + + `Schema cache dump` feature was implemetend. This feature can dump/load internal state of `SchemaCache` instance + because we want to boot rails more quickly when we have many models. + + Usage notes: + + 1) execute rake task. + RAILS_ENV=production bundle exec rake db:schema:cache:dump + => generate db/schema_cache.dump + + 2) add config.use_schema_cache_dump = true in config/production.rb. BTW, true is default. + + 3) boot rails. + RAILS_ENV=production bundle exec rails server + => use db/schema_cache.dump + + 4) If you remove clear dumped cache, execute rake task. + RAILS_ENV=production bundle exec rake db:schema:cache:clear + => remove db/schema_cache.dump + + *kennyj* + * Added support for partial indices to PostgreSQL adapter The `add_index` method now supports a `where` option that receives a diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 9657cb081d..53d49fef2e 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -73,7 +73,9 @@ module ActiveRecord # association def build_through_record(record) @through_records[record.object_id] ||= begin - through_record = through_association.build(construct_join_attributes(record)) + ensure_mutable + + through_record = through_association.build through_record.send("#{source_reflection.name}=", record) through_record end diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb index f95e5337c2..fd0e90aaf0 100644 --- a/activerecord/lib/active_record/associations/through_association.rb +++ b/activerecord/lib/active_record/associations/through_association.rb @@ -37,9 +37,7 @@ module ActiveRecord # situation it is more natural for the user to just create or modify their join records # directly as required. def construct_join_attributes(*records) - if source_reflection.macro != :belongs_to - raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection) - end + ensure_mutable join_attributes = { source_reflection.foreign_key => @@ -73,6 +71,12 @@ module ActiveRecord !owner[through_reflection.foreign_key].nil? end + def ensure_mutable + if source_reflection.macro != :belongs_to + raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection) + end + end + def ensure_not_nested if reflection.nested? raise HasManyThroughNestedAssociationsAreReadonly.new(owner, reflection) diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index 3e27e85f02..93c243e7b1 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -189,7 +189,7 @@ module ActiveRecord # nil nor empty? (the latter only applies to objects that respond to empty?, most notably Strings). def attribute_present?(attribute) value = read_attribute(attribute) - !value.nil? || (value.respond_to?(:empty?) && !value.empty?) + !value.nil? && !(value.respond_to?(:empty?) && value.empty?) end # Returns the column object for the named attribute. diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 594649189d..767c99de4c 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -86,6 +86,11 @@ module ActiveRecord end end + def schema_cache=(cache) + cache.connection = self + @schema_cache = cache + end + def expire @in_use = false end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index d2126a3e19..5b7fa029da 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -978,6 +978,27 @@ module ActiveRecord end_sql end + # Returns an array of schema names. + def schema_names + query(<<-SQL).flatten + SELECT nspname + FROM pg_namespace + WHERE nspname !~ '^pg_.*' + AND nspname NOT IN ('information_schema') + ORDER by nspname; + SQL + end + + # Creates a schema for the given schema name. + def create_schema schema_name + execute "CREATE SCHEMA #{schema_name}" + end + + # Drops the schema for the given schema name. + def drop_schema schema_name + execute "DROP SCHEMA #{schema_name} CASCADE" + end + # Sets the schema search path to a string of comma-separated schema names. # Names beginning with $ have to be quoted (e.g. $user => '$user'). # See: http://www.postgresql.org/docs/current/static/ddl-schemas.html diff --git a/activerecord/lib/active_record/connection_adapters/schema_cache.rb b/activerecord/lib/active_record/connection_adapters/schema_cache.rb index 962718da56..aad1f9a7ef 100644 --- a/activerecord/lib/active_record/connection_adapters/schema_cache.rb +++ b/activerecord/lib/active_record/connection_adapters/schema_cache.rb @@ -1,26 +1,17 @@ module ActiveRecord module ConnectionAdapters class SchemaCache - attr_reader :columns, :columns_hash, :primary_keys, :tables - attr_reader :connection + attr_reader :columns, :columns_hash, :primary_keys, :tables, :version + attr_accessor :connection def initialize(conn) @connection = conn - @tables = {} - @columns = Hash.new do |h, table_name| - h[table_name] = conn.columns(table_name) - end - - @columns_hash = Hash.new do |h, table_name| - h[table_name] = Hash[columns[table_name].map { |col| - [col.name, col] - }] - end - - @primary_keys = Hash.new do |h, table_name| - h[table_name] = table_exists?(table_name) ? conn.primary_key(table_name) : nil - end + @columns = {} + @columns_hash = {} + @primary_keys = {} + @tables = {} + prepare_default_proc end # A cached lookup for table existence. @@ -30,12 +21,22 @@ module ActiveRecord @tables[name] = connection.table_exists?(name) end + # Add internal cache for table with +table_name+. + def add(table_name) + if table_exists?(table_name) + @primary_keys[table_name] + @columns[table_name] + @columns_hash[table_name] + end + end + # Clears out internal caches def clear! @columns.clear @columns_hash.clear @primary_keys.clear @tables.clear + @version = nil end # Clear out internal caches for table with +table_name+. @@ -45,6 +46,37 @@ module ActiveRecord @primary_keys.delete table_name @tables.delete table_name end + + def marshal_dump + # if we get current version during initialization, it happens stack over flow. + @version = ActiveRecord::Migrator.current_version + [@version] + [:@columns, :@columns_hash, :@primary_keys, :@tables].map do |val| + self.instance_variable_get(val).inject({}) { |h, v| h[v[0]] = v[1]; h } + end + end + + def marshal_load(array) + @version, @columns, @columns_hash, @primary_keys, @tables = array + prepare_default_proc + end + + private + + def prepare_default_proc + @columns.default_proc = Proc.new do |h, table_name| + h[table_name] = connection.columns(table_name) + end + + @columns_hash.default_proc = Proc.new do |h, table_name| + h[table_name] = Hash[columns[table_name].map { |col| + [col.name, col] + }] + end + + @primary_keys.default_proc = Proc.new do |h, table_name| + h[table_name] = table_exists?(table_name) ? connection.primary_key(table_name) : nil + end + end end end end diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb index 058dd58efb..516c450f85 100644 --- a/activerecord/lib/active_record/railtie.rb +++ b/activerecord/lib/active_record/railtie.rb @@ -107,7 +107,7 @@ module ActiveRecord config.watchable_files.concat ["#{app.root}/db/schema.rb", "#{app.root}/db/structure.sql"] end - config.after_initialize do + config.after_initialize do |app| ActiveSupport.on_load(:active_record) do ActiveRecord::Base.instantiate_observers @@ -115,6 +115,21 @@ module ActiveRecord ActiveRecord::Base.instantiate_observers end end + + ActiveSupport.on_load(:active_record) do + if app.config.use_schema_cache_dump + filename = File.join(app.config.paths["db"].first, "schema_cache.dump") + if File.file?(filename) + cache = Marshal.load(open(filename, 'rb') { |f| f.read }) + if cache.version == ActiveRecord::Migrator.current_version + ActiveRecord::Base.connection.schema_cache = cache + else + warn "schema_cache.dump is expired. Current version is #{ActiveRecord::Migrator.current_version}, but cache version is #{cache.version}." + end + end + end + end + end end end diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index cf0092e0e3..f26989ae57 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -372,6 +372,25 @@ db_namespace = namespace :db do task :load_if_ruby => 'db:create' do db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :ruby end + + namespace :cache do + desc 'Create a db/schema_cache.dump file.' + task :dump => :environment do + con = ActiveRecord::Base.connection + filename = File.join(Rails.application.config.paths["db"].first, "schema_cache.dump") + + con.schema_cache.clear! + con.tables.each { |table| con.schema_cache.add(table) } + open(filename, 'wb') { |f| f.write(Marshal.dump(con.schema_cache)) } + end + + desc 'Clear a db/schema_cache.dump file.' + task :clear => :environment do + filename = File.join(Rails.application.config.paths["db"].first, "schema_cache.dump") + FileUtils.rm(filename) if File.exists?(filename) + end + end + end namespace :structure do diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb index 18c81d2b09..9208f53997 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb @@ -71,6 +71,45 @@ class SchemaTest < ActiveRecord::TestCase @connection.execute "DROP SCHEMA #{SCHEMA_NAME} CASCADE" end + def test_schema_names + assert_equal ["public", "test_schema", "test_schema2"], @connection.schema_names + end + + def test_create_schema + begin + @connection.create_schema "test_schema3" + assert @connection.schema_names.include? "test_schema3" + ensure + @connection.drop_schema "test_schema3" + end + end + + def test_raise_create_schema_with_existing_schema + begin + @connection.create_schema "test_schema3" + assert_raises(ActiveRecord::StatementInvalid) do + @connection.create_schema "test_schema3" + end + ensure + @connection.drop_schema "test_schema3" + end + end + + def test_drop_schema + begin + @connection.create_schema "test_schema3" + ensure + @connection.drop_schema "test_schema3" + end + assert !@connection.schema_names.include?("test_schema3") + end + + def test_raise_drop_schema_with_nonexisting_schema + assert_raises(ActiveRecord::StatementInvalid) do + @connection.drop_schema "test_schema3" + end + end + def test_schema_change_with_prepared_stmt altered = false @connection.exec_query "select * from developers where id = $1", 'sql', [[nil, 1]] @@ -183,13 +222,13 @@ class SchemaTest < ActiveRecord::TestCase end def test_raise_on_unquoted_schema_name - assert_raise(ActiveRecord::StatementInvalid) do + assert_raises(ActiveRecord::StatementInvalid) do with_schema_search_path '$user,public' end end def test_without_schema_search_path - assert_raise(ActiveRecord::StatementInvalid) { columns(TABLE_NAME) } + assert_raises(ActiveRecord::StatementInvalid) { columns(TABLE_NAME) } end def test_ignore_nil_schema_search_path diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index 9cc09194dc..e9b930204f 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -44,17 +44,33 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_associate_existing - posts(:thinking); people(:david) # Warm cache + post = posts(:thinking) + person = people(:david) assert_queries(1) do - posts(:thinking).people << people(:david) + post.people << person end assert_queries(1) do - assert posts(:thinking).people.include?(people(:david)) + assert post.people.include?(person) end - assert posts(:thinking).reload.people(true).include?(people(:david)) + assert post.reload.people(true).include?(person) + end + + def test_associate_existing_with_strict_mass_assignment_sanitizer + SecureReader.mass_assignment_sanitizer = :strict + + SecureReader.new + + post = posts(:thinking) + person = people(:david) + + assert_queries(1) do + post.secure_people << person + end + ensure + SecureReader.mass_assignment_sanitizer = :logger end def test_associate_existing_record_twice_should_add_to_target_twice @@ -688,6 +704,17 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase assert author.comments.include?(comment) end + def test_through_association_readonly_should_be_false + assert !people(:michael).posts.first.readonly? + assert !people(:michael).posts.all.first.readonly? + end + + def test_can_update_through_association + assert_nothing_raised do + people(:michael).posts.first.update_attributes!(:title => "Can write") + end + end + def test_has_many_through_polymorphic_with_primary_key_option assert_equal [categories(:general)], authors(:david).essay_categories diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index 23bdb09514..ef01476ae4 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -30,9 +30,12 @@ class AttributeMethodsTest < ActiveRecord::TestCase t = Topic.new t.title = "hello there!" t.written_on = Time.now + t.author_name = "" assert t.attribute_present?("title") assert t.attribute_present?("written_on") assert !t.attribute_present?("content") + assert !t.attribute_present?("author_name") + end def test_attribute_present_with_booleans diff --git a/activerecord/test/cases/connection_adapters/schema_cache_test.rb b/activerecord/test/cases/connection_adapters/schema_cache_test.rb index 42e39d534c..541e983758 100644 --- a/activerecord/test/cases/connection_adapters/schema_cache_test.rb +++ b/activerecord/test/cases/connection_adapters/schema_cache_test.rb @@ -39,6 +39,21 @@ module ActiveRecord assert_equal 0, @cache.tables.size assert_equal 0, @cache.primary_keys.size end + + def test_dump_and_load + @cache.columns['posts'] + @cache.columns_hash['posts'] + @cache.tables['posts'] + @cache.primary_keys['posts'] + + @cache = Marshal.load(Marshal.dump(@cache)) + + assert_equal 12, @cache.columns['posts'].size + assert_equal 12, @cache.columns_hash['posts'].size + assert @cache.tables['posts'] + assert_equal 'id', @cache.primary_keys['posts'] + end + end end end diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb index d2a0c6b40c..84bc901b5e 100644 --- a/activerecord/test/models/person.rb +++ b/activerecord/test/models/person.rb @@ -1,8 +1,10 @@ class Person < ActiveRecord::Base has_many :readers + has_many :secure_readers has_one :reader has_many :posts, :through => :readers + has_many :secure_posts, :through => :secure_readers has_many :posts_with_no_comments, :through => :readers, :source => :post, :include => :comments, :conditions => 'comments.id is null', :references => :comments diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb index 1cab78d8c7..0fc22ac6a3 100644 --- a/activerecord/test/models/post.rb +++ b/activerecord/test/models/post.rb @@ -115,8 +115,10 @@ class Post < ActiveRecord::Base has_many :named_categories, :through => :standard_categorizations has_many :readers + has_many :secure_readers has_many :readers_with_person, :include => :person, :class_name => "Reader" has_many :people, :through => :readers + has_many :secure_people, :through => :secure_readers has_many :single_people, :through => :readers has_many :people_with_callbacks, :source=>:person, :through => :readers, :before_add => lambda {|owner, reader| log(:added, :before, reader.first_name) }, diff --git a/activerecord/test/models/reader.rb b/activerecord/test/models/reader.rb index 0207a2bd92..59005ac604 100644 --- a/activerecord/test/models/reader.rb +++ b/activerecord/test/models/reader.rb @@ -3,3 +3,12 @@ class Reader < ActiveRecord::Base belongs_to :person, :inverse_of => :readers belongs_to :single_person, :class_name => 'Person', :foreign_key => :person_id, :inverse_of => :reader end + +class SecureReader < ActiveRecord::Base + self.table_name = "readers" + + belongs_to :secure_post, :class_name => "Post", :foreign_key => "post_id" + belongs_to :secure_person, :inverse_of => :secure_readers, :class_name => "Person", :foreign_key => "person_id" + + attr_accessible nil +end diff --git a/railties/guides/code/getting_started/config/database.yml b/railties/guides/code/getting_started/config/database.yml index 32a998ad72..51a4dd459d 100644 --- a/railties/guides/code/getting_started/config/database.yml +++ b/railties/guides/code/getting_started/config/database.yml @@ -6,9 +6,7 @@ development: adapter: sqlite3 database: db/development.sqlite3 - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 timeout: 5000 # Warning: The database defined as "test" will be erased and @@ -17,15 +15,11 @@ development: test: adapter: sqlite3 database: db/test.sqlite3 - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 timeout: 5000 production: adapter: sqlite3 database: db/production.sqlite3 - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 timeout: 5000 diff --git a/railties/guides/source/command_line.textile b/railties/guides/source/command_line.textile index 8ae8c61ae6..fe4a84dae9 100644 --- a/railties/guides/source/command_line.textile +++ b/railties/guides/source/command_line.textile @@ -521,9 +521,7 @@ development: adapter: postgresql encoding: unicode database: gitapp_development - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 username: gitapp password: ... diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile index e796f44606..2f465b37ed 100644 --- a/railties/guides/source/configuring.textile +++ b/railties/guides/source/configuring.textile @@ -652,19 +652,17 @@ The error occurred while evaluating nil.each h3. Database pooling -Active Record database connections are managed by +ActiveRecord::ConnectionAdapters::ConnectionPool+ which ensures that a connection pool synchronizes the amount of thread access to a limited number of database connections. This limit defaults to 1 and can be configured in +database.yml+. +Active Record database connections are managed by +ActiveRecord::ConnectionAdapters::ConnectionPool+ which ensures that a connection pool synchronizes the amount of thread access to a limited number of database connections. This limit defaults to 5 and can be configured in +database.yml+. <ruby> development: adapter: sqlite3 database: db/development.sqlite3 - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 timeout: 5000 </ruby> -Since the connection pooling is handled inside of Active Record by default, all application servers (Thin, Mongrel, Unicorn etc.) should behave the same. Initially, the database connection pool is empty and it will create additional connections as the demand for them increases, until it reaches the connection pool limit. +Since the connection pooling is handled inside of ActiveRecord by default, all application servers (Thin, mongrel, Unicorn etc.) should behave the same. Initially, the database connection pool is empty and it will create additional connections as the demand for them increases, until it reaches the connection pool limit. Any one request will check out a connection the first time it requires access to the database, after which it will check the connection back in, at the end of the request, meaning that the additional connection slot will be available again for the next request in the queue. diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile index d6f3c3e217..bed14ef6a8 100644 --- a/railties/guides/source/getting_started.textile +++ b/railties/guides/source/getting_started.textile @@ -329,9 +329,7 @@ environment: development: adapter: sqlite3 database: db/development.sqlite3 - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 timeout: 5000 </yaml> @@ -352,9 +350,7 @@ development: adapter: mysql2 encoding: utf8 database: blog_development - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 username: root password: socket: /tmp/mysql.sock @@ -374,9 +370,7 @@ development: adapter: postgresql encoding: unicode database: blog_development - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 username: blog password: </yaml> diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 1e424d9b4a..0f5fc2b7bc 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -11,7 +11,7 @@ module Rails :force_ssl, :helpers_paths, :logger, :log_tags, :preload_frameworks, :railties_order, :relative_url_root, :secret_token, :serve_static_assets, :ssl_options, :static_cache_control, :session_options, - :time_zone, :reload_classes_only_on_change + :time_zone, :reload_classes_only_on_change, :use_schema_cache_dump attr_writer :log_level attr_reader :encoding @@ -41,6 +41,7 @@ module Rails @file_watcher = ActiveSupport::FileUpdateChecker @exceptions_app = nil @autoflush_log = true + @use_schema_cache_dump = true @assets = ActiveSupport::OrderedOptions.new @assets.enabled = false diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml index 950016ad92..c3349912aa 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml @@ -12,9 +12,7 @@ development: adapter: mysql2 encoding: utf8 database: <%= app_name %>_development - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 username: root password: <% if mysql_socket -%> @@ -30,9 +28,7 @@ test: adapter: mysql2 encoding: utf8 database: <%= app_name %>_test - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 username: root password: <% if mysql_socket -%> @@ -45,9 +41,7 @@ production: adapter: mysql2 encoding: utf8 database: <%= app_name %>_production - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 username: root password: <% if mysql_socket -%> diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml index a8ed15c2dc..f08f86aac3 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml @@ -16,9 +16,7 @@ development: adapter: postgresql encoding: unicode database: <%= app_name %>_development - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 username: <%= app_name %> password: @@ -44,9 +42,7 @@ test: adapter: postgresql encoding: unicode database: <%= app_name %>_test - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 username: <%= app_name %> password: @@ -54,8 +50,6 @@ production: adapter: postgresql encoding: unicode database: <%= app_name %>_production - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 username: <%= app_name %> password: diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml index 32a998ad72..51a4dd459d 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml @@ -6,9 +6,7 @@ development: adapter: sqlite3 database: db/development.sqlite3 - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 timeout: 5000 # Warning: The database defined as "test" will be erased and @@ -17,15 +15,11 @@ development: test: adapter: sqlite3 database: db/test.sqlite3 - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 timeout: 5000 production: adapter: sqlite3 database: db/production.sqlite3 - # Maximum number of database connections available per process. Please - # increase this number in multithreaded applications. - pool: 1 + pool: 5 timeout: 5000 diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb index 8812685620..a0e88cd0f0 100644 --- a/railties/test/application/initializers/frameworks_test.rb +++ b/railties/test/application/initializers/frameworks_test.rb @@ -193,5 +193,31 @@ module ApplicationTests require "#{app_path}/config/environment" assert_nil defined?(ActiveRecord::Base) end + + test "use schema cache dump" do + Dir.chdir(app_path) do + `rails generate model post title:string` + `bundle exec rake db:migrate` + `bundle exec rake db:schema:cache:dump` + end + require "#{app_path}/config/environment" + ActiveRecord::Base.connection.drop_table("posts") # force drop posts table for test. + assert ActiveRecord::Base.connection.schema_cache.tables["posts"] + end + + test "expire schema cache dump" do + Dir.chdir(app_path) do + `rails generate model post title:string` + `bundle exec rake db:migrate` + `bundle exec rake db:schema:cache:dump` + + `bundle exec rake db:rollback` + end + silence_warnings { + require "#{app_path}/config/environment" + assert !ActiveRecord::Base.connection.schema_cache.tables["posts"] + } + end + end end diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index ff12b3e9fc..9515e40b6e 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -138,5 +138,24 @@ module ApplicationTests end assert File.exists?(File.join(app_path, 'db', 'my_structure.sql')) end + + def test_rake_dump_schema_cache + Dir.chdir(app_path) do + `rails generate model post title:string` + `rails generate model product name:string` + `bundle exec rake db:migrate` + `bundle exec rake db:schema:cache:dump` + end + assert File.exists?(File.join(app_path, 'db', 'schema_cache.dump')) + end + + def test_rake_clear_schema_cache + Dir.chdir(app_path) do + `bundle exec rake db:schema:cache:dump` + `bundle exec rake db:schema:cache:clear` + end + assert !File.exists?(File.join(app_path, 'db', 'schema_cache.dump')) + end + end end |