diff --git a/README.md b/README.md index 1634182e..722a9982 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,9 @@ other databases, the database will be created as a new DB within the system. When you create a new database, all migrations will be run against that database, so it will be up to date when create returns. +You can configure the `schema_format` used to create a new database. The options are `:ruby` (the default) and `:sql`. For `:ruby` the 'db/schema.rb' file is used, and for `:sql` the 'db/structure.sql' is used. +When used within Rails the setting is assigned from the configured schema format set in 'application.rb' so there is no need to duplicate the configuration setting. + #### Notes on PostgreSQL PostgreSQL works slightly differently than other databases when creating a new DB. If you @@ -53,6 +56,8 @@ would not allow a full new database to be created. One can optionally use the full database creation instead if they want, though this is not recommended +The `:sql` schema format cannot be used when PostgreSQL schemas are used, since the `structure.sql` file sets the schema search path. + ### Switching Databases To switch databases using Apartment, use the following command: diff --git a/lib/apartment.rb b/lib/apartment.rb index 0e2ab7ba..9a6fcf6c 100644 --- a/lib/apartment.rb +++ b/lib/apartment.rb @@ -11,7 +11,7 @@ class << self extend Forwardable ACCESSOR_METHODS = [:use_schemas, :seed_after_create, :prepend_environment, :append_environment] - WRITER_METHODS = [:database_names, :database_schema_file, :excluded_models, :default_schema, :persistent_schemas, :connection_class] + WRITER_METHODS = [:database_names, :database_schema_file, :excluded_models, :default_schema, :persistent_schemas, :connection_class, :schema_format] attr_accessor(*ACCESSOR_METHODS) attr_writer(*WRITER_METHODS) @@ -45,10 +45,22 @@ def connection_class @connection_class || ActiveRecord::Base end + # Schema format :ruby or :sql + # as per http://guides.rubyonrails.org/configuring.html#configuring-rails-components + def schema_format + @schema_format || :ruby + end + def database_schema_file return @database_schema_file if defined?(@database_schema_file) - @database_schema_file = Rails.root.join('db', 'schema.rb') + if defined?(Rails) + @database_schema_file = if schema_format == :sql + Rails.root.join('db', 'structure.sql') + else + Rails.root.join('db', 'schema.rb') + end + end end # Reset all the config for Apartment diff --git a/lib/apartment/adapters/abstract_adapter.rb b/lib/apartment/adapters/abstract_adapter.rb index a99e0331..6e5f0f8f 100644 --- a/lib/apartment/adapters/abstract_adapter.rb +++ b/lib/apartment/adapters/abstract_adapter.rb @@ -147,9 +147,15 @@ def environmentify(database) # Import the database schema # def import_database_schema - ActiveRecord::Schema.verbose = false # do not log schema load output. + return if Apartment.database_schema_file.nil? - load_or_abort(Apartment.database_schema_file) if Apartment.database_schema_file + ActiveRecord::Schema.verbose = false # do not log schema load output. + if Apartment.schema_format == :sql + raise ApartmentError, "Using the :sql schema format is not supported when using Postgres schemas." if Apartment.use_postgres_schemas + execute_or_abort(Apartment.database_schema_file) + else + load_or_abort(Apartment.database_schema_file) + end end # Return a new config that is multi-tenanted @@ -170,6 +176,17 @@ def load_or_abort(file) end end + # Load a SQL file and execute it or abort if it doesn't exists + # + def execute_or_abort(file) + if File.exists?(file) + structure_sql = open(file, 'r').read + ActiveRecord::Base.connection.execute(structure_sql) + else + abort %{#{file} doesn't exist yet} + end + end + # Exceptions to rescue from on db operations # def rescuable_exceptions @@ -181,6 +198,7 @@ def rescuable_exceptions def rescue_from [] end + end end -end \ No newline at end of file +end diff --git a/lib/apartment/railtie.rb b/lib/apartment/railtie.rb index 12f5de33..a64d68e8 100644 --- a/lib/apartment/railtie.rb +++ b/lib/apartment/railtie.rb @@ -17,6 +17,7 @@ class Railtie < Rails::Railtie config.seed_after_create = false config.prepend_environment = false config.append_environment = false + config.schema_format = Rails.application.config.active_record.schema_format end ActiveRecord::Migrator.migrations_paths = Rails.application.paths['db/migrate'].to_a diff --git a/spec/unit/config_spec.rb b/spec/unit/config_spec.rb index 1270836e..a6cf18f5 100644 --- a/spec/unit/config_spec.rb +++ b/spec/unit/config_spec.rb @@ -28,6 +28,34 @@ Apartment.use_schemas.should be_false end + it "should set schema_format" do + Apartment.configure do |config| + config.schema_format = :sql + end + Apartment.schema_format.should eq(:sql) + end + + it "should set database_schema_file" do + Apartment.configure do |config| + config.database_schema_file = 'a_file' + end + Apartment.database_schema_file.should eq('a_file') + end + + it "should set database_schema_file for :ruby schema format" do + Apartment.configure do |config| + config.schema_format = :ruby + end + Apartment.database_schema_file.to_s.should match(/schema.rb/) + end + + it "should set database_schema_file for :sql schema format" do + Apartment.configure do |config| + config.schema_format = :sql + end + Apartment.database_schema_file.to_s.should match(/structure.sql/) + end + it "should set seed_after_create" do Apartment.configure do |config| config.excluded_models = []