Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Use begin_transaction if connection responds to it (AR 4) #189

Merged
merged 1 commit into from

4 participants

@dchelimsky

Supports ActiveRecord-4.0.0.beta1

Fixes #188 and #187.
Based on the suggestion from @sjmadsen in #187.

I have not run the full test suite successfully (don't have everything set up), so let's see what travis says.

@dchelimsky

OK - we won't see what travis says because I don't think you have the PR bot set up :)

@bmabey I can tell you that this solves #188 for me, but I don't know what else it breaks. If anybody else has the time/inclination/setup to verify this works and doesn't break anything else, I'd be most appreciative.

@bmabey
Owner

Thanks @dchelimsky! The bot is set up and it has given this PR green. @sjmadsen, would you mind testing this PR on your Postgres setup?

@sjmadsen

@bmabey This PR solves #187 for me. Thanks @dchelimsky!

@dchelimsky

@sjmadsen all I did was implement your suggestion :) You're welcome!

@bmabey bmabey merged commit 0f6af3e into from
@bmabey
Owner

FYI, I've released v1.0.0.RC1 with this in it. I'll have some existing rails 3.0 users take it for a spin before releasing the final gem. Thanks again!

@dchelimsky dchelimsky deleted the branch
@dchelimsky dchelimsky restored the branch
@sigvei

This works great, except when switching strategies. I do this in spec_helper:

  config.before(:each) do
    DatabaseCleaner.strategy = case Capybara.current_driver
                               when :rack_test ; :transaction
                               else ; :truncation
                               end
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

All tests up to the selenium ones, which use truncation, succeed. But when the strategy is switched back to transaction for the remaining "normal" tests, I get the ActiveRecord::StatementInvalid: SQLite3::SQLException: cannot start a transaction within a transaction: begin transaction.

This is with v1.0.0.RC1, by the way.

@dchelimsky

@sigvei does the same spec_helper.rb work for you with database_cleaner 0.9.1?

@dchelimsky

@bmabey any word on @sigvei's issue?

@bmabey
Owner

Sorry, I haven't taken the time to look into @sigvei's issue yet. @sigvei, what version of AR are you using exactly?

@bmabey
Owner

@sigvei A base project with your setup on a bare rails project with the exact same dependencies would help me debug this. If you have the time please put one up on github so I can take a look.

Also, I've merged in some other changes dealing with new AR changes so please try the latest from git to see if they have resolved your issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 3, 2013
  1. @dchelimsky

    Use begin_transaction if connection responds to it

    dchelimsky authored
    Supports ActiveRecord-4.0.0.beta1
This page is out of date. Refresh to see the latest.
View
16 lib/database_cleaner/active_record/transaction.rb
@@ -14,14 +14,22 @@ def start
connection_class.__send__(:increment_open_transactions)
end
end
- connection_class.connection.begin_db_transaction
+ if connection_class.connection.respond_to?(:begin_transaction)
+ connection_class.connection.begin_transaction
+ else
+ connection_class.connection.begin_db_transaction
+ end
end
def clean
return unless connection_class.connection.open_transactions > 0
- connection_class.connection.rollback_db_transaction
+ if connection_class.connection.respond_to?(:rollback_transaction)
+ connection_class.connection.rollback_transaction
+ else
+ connection_class.connection.rollback_db_transaction
+ end
# The below is for handling after_commit hooks.. see https://github.com/bmabey/database_cleaner/issues/99
if connection_class.connection.respond_to?(:rollback_transaction_records)
@@ -36,10 +44,10 @@ def clean
end
end
end
-
+
def connection_maintains_transaction_count?
ActiveRecord::VERSION::MAJOR < 4
end
-
+
end
end
View
92 spec/database_cleaner/active_record/transaction_spec.rb
@@ -8,31 +8,36 @@ module ActiveRecord
describe Transaction do
let (:connection) { mock("connection") }
before(:each) do
- ::ActiveRecord::Base.stub!(:connection).and_return(connection)
+ ::ActiveRecord::Base.stub(:connection).and_return(connection)
end
describe "#start" do
- it "should increment open transactions if possible" do
- connection.stub!(:respond_to?).with(:increment_open_transactions).and_return(true)
- connection.stub!(:begin_db_transaction)
-
- connection.should_receive(:increment_open_transactions)
- Transaction.new.start
- end
-
- it "should tell ActiveRecord to increment connection if its not possible to increment current connection" do
- connection.stub!(:respond_to?).with(:increment_open_transactions).and_return(false)
- connection.stub!(:begin_db_transaction)
-
- ::ActiveRecord::Base.should_receive(:increment_open_transactions)
- Transaction.new.start
- end
-
- it "should start a transaction" do
- connection.stub!(:increment_open_transactions)
-
- connection.should_receive(:begin_db_transaction)
- Transaction.new.start
+ [:begin_transaction, :begin_db_transaction].each do |begin_transaction_method|
+ context "using #{begin_transaction_method}" do
+ before do
+ connection.stub(begin_transaction_method)
+ connection.stub(:respond_to?).with(:begin_transaction).and_return(:begin_transaction == begin_transaction_method)
+ end
+
+ it "should increment open transactions if possible" do
+ connection.stub(:respond_to?).with(:increment_open_transactions).and_return(true)
+ connection.should_receive(:increment_open_transactions)
+ Transaction.new.start
+ end
+
+ it "should tell ActiveRecord to increment connection if its not possible to increment current connection" do
+ connection.stub(:respond_to?).with(:increment_open_transactions).and_return(false)
+ ::ActiveRecord::Base.should_receive(:increment_open_transactions)
+ Transaction.new.start
+ end
+
+ it "should start a transaction" do
+ connection.stub(:respond_to?).with(:increment_open_transactions).and_return(true)
+ connection.stub(:increment_open_transactions)
+ connection.should_receive(begin_transaction_method)
+ Transaction.new.start
+ end
+ end
end
end
@@ -41,7 +46,7 @@ module ActiveRecord
it "should start a transaction" do
connection.should_receive(:open_transactions).and_return(1)
- connection.stub!(:decrement_open_transactions)
+ connection.stub(:decrement_open_transactions)
connection.should_receive(:rollback_db_transaction)
Transaction.new.clean
@@ -50,9 +55,10 @@ module ActiveRecord
it "should decrement open transactions if possible" do
connection.should_receive(:open_transactions).and_return(1)
- connection.stub!(:respond_to?).with(:decrement_open_transactions).and_return(true)
- connection.stub!(:respond_to?).with(:rollback_transaction_records).and_return(false)
- connection.stub!(:rollback_db_transaction)
+ connection.stub(:respond_to?).with(:decrement_open_transactions).and_return(true)
+ connection.stub(:respond_to?).with(:rollback_transaction_records).and_return(false)
+ connection.stub(:respond_to?).with(:rollback_transaction).and_return(false)
+ connection.stub(:rollback_db_transaction)
connection.should_receive(:decrement_open_transactions)
Transaction.new.clean
@@ -66,30 +72,30 @@ module ActiveRecord
it "should decrement connection via ActiveRecord::Base if connection won't" do
connection.should_receive(:open_transactions).and_return(1)
- connection.stub!(:respond_to?).with(:decrement_open_transactions).and_return(false)
- connection.stub!(:respond_to?).with(:rollback_transaction_records).and_return(false)
- connection.stub!(:rollback_db_transaction)
+ connection.stub(:respond_to?).with(:decrement_open_transactions).and_return(false)
+ connection.stub(:respond_to?).with(:rollback_transaction_records).and_return(false)
+ connection.stub(:respond_to?).with(:rollback_transaction).and_return(false)
+ connection.stub(:rollback_db_transaction)
::ActiveRecord::Base.should_receive(:decrement_open_transactions)
Transaction.new.clean
end
end
-
- context "automatic accounting of transaction count" do
+
+ context "automatic accounting of transaction count (AR 4)" do
+ before {stub_const("ActiveRecord::VERSION::MAJOR", 4) }
it "should start a transaction" do
- stub_const("ActiveRecord::VERSION::MAJOR", 4)
- connection.stub!(:rollback_db_transaction)
+ connection.stub(:rollback_db_transaction)
connection.should_receive(:open_transactions).and_return(1)
connection.should_not_receive(:decrement_open_transactions)
- connection.should_receive(:rollback_db_transaction)
+ connection.should_receive(:rollback_transaction)
Transaction.new.clean
end
it "should decrement open transactions if possible" do
- stub_const("ActiveRecord::VERSION::MAJOR", 4)
- connection.stub!(:rollback_db_transaction)
+ connection.stub(:rollback_transaction)
connection.should_receive(:open_transactions).and_return(1)
connection.should_not_receive(:decrement_open_transactions)
@@ -97,24 +103,23 @@ module ActiveRecord
end
it "should not try to decrement or rollback if open_transactions is 0 for whatever reason" do
- stub_const("ActiveRecord::VERSION::MAJOR", 4)
connection.should_receive(:open_transactions).and_return(0)
Transaction.new.clean
end
it "should decrement connection via ActiveRecord::Base if connection won't" do
- stub_const("ActiveRecord::VERSION::MAJOR", 4)
connection.should_receive(:open_transactions).and_return(1)
- connection.stub!(:respond_to?).with(:rollback_transaction_records).and_return(false)
- connection.stub!(:rollback_db_transaction)
+ connection.stub(:respond_to?).with(:rollback_transaction_records).and_return(false)
+ connection.stub(:respond_to?).with(:rollback_transaction).and_return(true)
+ connection.stub(:rollback_transaction)
::ActiveRecord::Base.should_not_receive(:decrement_open_transactions)
Transaction.new.clean
end
end
end
-
+
describe "#connection_maintains_transaction_count?" do
it "should return true if the major active record version is < 4" do
stub_const("ActiveRecord::VERSION::MAJOR", 3)
@@ -125,10 +130,7 @@ module ActiveRecord
Transaction.new.connection_maintains_transaction_count?.should be_false
end
end
-
- end
-
-
+ end
end
end
Something went wrong with that request. Please try again.