diff options
| author | Robert | 2017-06-06 10:41:17 +0200 |
|---|---|---|
| committer | Robert | 2017-06-06 11:32:23 +0200 |
| commit | 12290bbdabb8f53c4dddb1a647296a426b88709e (patch) | |
| tree | bbc5728f9322c4d331e9410785376b73735d1a58 | |
| parent | 29fbffa1928fc08b5e2392afdd98cc1e2094f023 (diff) | |
| download | chouette-core-12290bbdabb8f53c4dddb1a647296a426b88709e.tar.bz2 | |
Refs: #3604; added tests for cloning with data ⇒ ✓
| -rw-r--r-- | app/models/referential.rb | 4 | ||||
| -rw-r--r-- | app/models/referential_cloning.rb | 3 | ||||
| -rw-r--r-- | app/workers/referential_cloning_worker.rb | 2 | ||||
| -rw-r--r-- | lib/af83/stored_procedures.rb | 4 | ||||
| -rw-r--r-- | lib/sql/message.sql | 8 | ||||
| -rw-r--r-- | spec/lib/af83/stored_procedures/clone_schema_spec.rb | 68 | ||||
| -rw-r--r-- | spec/support/pg_catalog.rb | 5 | ||||
| -rw-r--r-- | spec/workers/referential_cloning_worker_spec.rb | 23 |
8 files changed, 76 insertions, 41 deletions
diff --git a/app/models/referential.rb b/app/models/referential.rb index 83d507320..824320c27 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -127,7 +127,7 @@ class Referential < ActiveRecord::Base end def self.new_from(from, organisation:) - Referential.new({ + Referential.new( name: I18n.t("activerecord.copy", :name => from.name), slug: "#{from.slug}_clone", prefix: from.prefix, @@ -139,7 +139,7 @@ class Referential < ActiveRecord::Base workbench: from.workbench, created_from: from, metadatas: from.metadatas.map { |m| ReferentialMetadata.new_from(m) } - }) + ) end def self.available_srids diff --git a/app/models/referential_cloning.rb b/app/models/referential_cloning.rb index 2f34093e2..9006b2ac5 100644 --- a/app/models/referential_cloning.rb +++ b/app/models/referential_cloning.rb @@ -6,7 +6,8 @@ class ReferentialCloning < ActiveRecord::Base private def perform_clone - ReferentialCloningWorker.perform_async(self.id) + # ReferentialCloningWorker.perform_async(id) + ReferentialCloningWorker.new.perform(id) end aasm column: :status do diff --git a/app/workers/referential_cloning_worker.rb b/app/workers/referential_cloning_worker.rb index c74566966..2a524dbcd 100644 --- a/app/workers/referential_cloning_worker.rb +++ b/app/workers/referential_cloning_worker.rb @@ -16,7 +16,7 @@ class ReferentialCloningWorker def clone_schema ref_cloning, source_schema, target_schema ref_cloning.run! - StoredProcedures.invoke_stored_procedure(:clone_schema, source_schema, target_schema, true) + StoredProcedures.invoke_stored_procedure(:clone_schema, source_schema, target_schema) ref_cloning.successful! rescue Exception => e diff --git a/lib/af83/stored_procedures.rb b/lib/af83/stored_procedures.rb index 698f3861d..b13941a32 100644 --- a/lib/af83/stored_procedures.rb +++ b/lib/af83/stored_procedures.rb @@ -30,9 +30,9 @@ module StoredProcedures extend self when String "'#{param}'" when TrueClass - "TRUE" + "'t'" when FalseClass - "FALSE" + "'f'" else param end diff --git a/lib/sql/message.sql b/lib/sql/message.sql new file mode 100644 index 000000000..94d7a3496 --- /dev/null +++ b/lib/sql/message.sql @@ -0,0 +1,8 @@ +CREATE OR REPLACE FUNCTION message( content text) RETURNS void AS +$BODY$ + BEGIN + INSERT INTO xxx VALUES (nextval('xxx_id_seq'), 'message from stored procedure: ' || content, current_timestamp); + RAISE EXCEPTION 'Oh no'; + RETURN; + END; +$BODY$ LANGUAGE plpgsql VOLATILE COST 100; diff --git a/spec/lib/af83/stored_procedures/clone_schema_spec.rb b/spec/lib/af83/stored_procedures/clone_schema_spec.rb index c387ddc7d..c0502f1ad 100644 --- a/spec/lib/af83/stored_procedures/clone_schema_spec.rb +++ b/spec/lib/af83/stored_procedures/clone_schema_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' include Support::PGCatalog + RSpec.describe StoredProcedures do let( :source_schema ){ "source_schema" } let( :target_schema ){ "target_schema" } @@ -72,10 +73,10 @@ RSpec.describe StoredProcedures do end end - context "after cloning" do - before do - described_class.invoke_stored_procedure(:clone_schema, source_schema, target_schema, false) - end + shared_examples_for "after cloning schema" do + + let( :expected_target_parent_count ){ include_recs ? 1 : 0 } + let( :expected_target_child_count ){ include_recs ? 1 : 0 } it "target schema does exist" do expect( get_schema_oid(target_schema) ).not_to be_nil @@ -142,26 +143,55 @@ RSpec.describe StoredProcedures do "constraint_def" => "FOREIGN KEY (parents_id) REFERENCES target_schema.parents(id)"}]) end + it "the data has been copied or not" do + source_pt_count = count_records(source_schema, parent_table) + source_ch_count = count_records(source_schema, child_table) + target_pt_count = count_records(target_schema, parent_table) + target_ch_count = count_records(target_schema, child_table) + + expect( source_pt_count ).to eq( 1 ) + expect( source_ch_count ).to eq( 1 ) + expect( target_pt_count ).to eq( expected_target_parent_count ) + expect( target_ch_count ).to eq( expected_target_child_count ) + end + end + + context "after cloning" do + before do + described_class.invoke_stored_procedure(:clone_schema, source_schema, target_schema, include_recs) + end + + context "without including records" do + let( :include_recs ){ false } + it_behaves_like 'after cloning schema' + end + + context "with including records" do + let( :include_recs ){ true } + it_behaves_like 'after cloning schema' + end + end end def create_schema_with_tables - execute("CREATE SCHEMA IF NOT EXISTS #{source_schema}") execute <<-EOSQL - DROP SCHEMA IF EXISTS #{source_schema} CASCADE; - CREATE SCHEMA #{source_schema}; - - CREATE TABLE #{source_schema}.#{parent_table} ( - id bigserial PRIMARY KEY - ); - CREATE TABLE #{source_schema}.#{child_table} ( - id bigserial PRIMARY KEY, - #{parent_table}_id bigint - ); - ALTER TABLE #{source_schema}.#{child_table} - ADD CONSTRAINT #{child_table}_#{parent_table} - FOREIGN KEY( #{parent_table}_id ) REFERENCES #{source_schema}.#{parent_table}(id); - EOSQL + DROP SCHEMA IF EXISTS #{source_schema} CASCADE; + CREATE SCHEMA #{source_schema}; + + CREATE TABLE #{source_schema}.#{parent_table} ( + id bigserial PRIMARY KEY + ); + CREATE TABLE #{source_schema}.#{child_table} ( + id bigserial PRIMARY KEY, + #{parent_table}_id bigint + ); + ALTER TABLE #{source_schema}.#{child_table} + ADD CONSTRAINT #{child_table}_#{parent_table} + FOREIGN KEY( #{parent_table}_id ) REFERENCES #{source_schema}.#{parent_table}(id); + INSERT INTO #{source_schema}.#{parent_table} VALUES (100); + INSERT INTO #{source_schema}.#{child_table} VALUES (1, 100); + EOSQL end diff --git a/spec/support/pg_catalog.rb b/spec/support/pg_catalog.rb index bb61adba5..7f86ee582 100644 --- a/spec/support/pg_catalog.rb +++ b/spec/support/pg_catalog.rb @@ -3,6 +3,11 @@ module Support # TODO: Check what of the follwowing can be done with ActiveRecord. E.g. # @connection.foreign_keys(table)... + def count_records(schema_name, table_name) + result = execute("SELECT COUNT(*) AS count FROM #{schema_name}.#{table_name}") + return result.to_a.first["count"].to_i + end + def get_columns(schema_name, table_name) execute("SELECT * from information_schema.columns WHERE table_name = '#{table_name}' AND table_schema = '#{schema_name}'") end diff --git a/spec/workers/referential_cloning_worker_spec.rb b/spec/workers/referential_cloning_worker_spec.rb index 85d771742..c531e02a9 100644 --- a/spec/workers/referential_cloning_worker_spec.rb +++ b/spec/workers/referential_cloning_worker_spec.rb @@ -9,10 +9,14 @@ RSpec.describe ReferentialCloningWorker do let( :worker ){ described_class.new } + def make_referential(schema_name) + return OpenStruct.new( slug: schema_name ) + end let( :source_schema ){ "source_schema" } - let( :target_schema ){ "#{source_schema}_tmp" } - let( :referential_cloning ){ OpenStruct.new(source_referential: OpenStruct.new(slug: source_schema)) } + let( :target_schema ){ "target_schema" } + let( :referential_cloning ){ OpenStruct.new(source_referential: make_referential(source_schema), + target_referential: make_referential(target_schema)) } before do expect( ReferentialCloning ).to receive(:find).with(id).and_return(referential_cloning) @@ -20,26 +24,13 @@ RSpec.describe ReferentialCloningWorker do .to receive(:invoke_stored_procedure) .with(:clone_schema, source_schema, target_schema, true) - expect( worker ).to receive(:execute_sql).with( "DROP SCHEMA #{source_schema} CASCADE;" ) - expect( referential_cloning ).to receive(:run!) end it "invokes the correct stored procedure, updates the database and the AASM" do - expect( worker ).to receive(:execute_sql).with( "ALTER SCHEMA #{target_schema} RENAME TO #{source_schema};" ) expect( referential_cloning ).to receive(:successful!) worker.perform(id) end - - it "handles failure correctly" do - expect( worker ) - .to receive(:execute_sql) - .with( "ALTER SCHEMA #{target_schema} RENAME TO #{source_schema};" ) - .and_raise(RuntimeError) - - expect( referential_cloning ).to receive(:failed!) - worker.perform(id) - end end - + end |
