On Tuesday, April 24, 2012 9:40:58 AM UTC-7, Rodrigo Rosenfeld Rosas wrote:
>
>  Em 24-04-2012 12:27, Jeremy Evans escreveu: 
>
> On Tuesday, April 24, 2012 6:55:29 AM UTC-7, Rodrigo Rosenfeld Rosas wrote:
>>
>> Moving on, the problem is that I'd like to have a set of records to be 
>> created for context, but only once or it would be too slow to run the spec.
>>
>
> Then just add the records before the spec and delete them after:
>
>   before(:all){# Add some records here}
>   after(:all){# Delete the records here}
>  
>
> This is not that easy. For example, if you write 
> FactoryGirl.create(:user), this might as well create a role or other 
> records in the database. It is hard to keep track of every record created 
> behind the scenes, so it would be a nightmare to maintain something like 
> this.
>

In general, if you don't care about concurrency (i.e. you run your specs in 
a single thread), it's safe to just do the following in the after block:
  
  [:table1, :table2, :table3, ...].each{|t| DB[t].delete}
 
Making sure to list every table that could be modified by the related 
specs.  I do this in apps where the tests don't use transactions (as they 
are testing an out-of-process webserver), and it's simple to maintain.

  
>
>> I'd like to be able to do something like this:
>>
>>  context "some sample records exists" do
>>   before(:all) do
>>     @sample_records_transaction = DB.transaction(savepoint: true)
>>     create_sample_records
>>   end
>>
>>    after(:all) { @sample_records_transaction.rollback! } # or even raise 
>> Rollback
>>
>>    # examples here
>> end
>>  
>>  Could you please add support for using transactions this way?
>>
>
> No.  Because of how the connection pool works, you need to use blocks for 
> transactions.
>
>
> Sorry, could you please elaborate on this? What do you mean?
>

You need to understand how Sequel's connection pool works.  Unlike some 
other database libraries, it doesn't leak connections and require manual 
cleanup later, it uses a block-based connection checkin/checkout.  By 
design, there is no method that allows you to checkout a connection without 
forcing a checkin later.  With transactions, you need to ensure that all 
database queries use the same connection (the one that started the 
transaction).  The way to do that is checking out a connection at the start 
of the transaction block, and checking in the connection at the end of the 
transaction block.  You cannot just checkout a connection to issue the 
BEGIN and then check the connection back in, as the connection code 
theoretically be used by other threads that should not be operating inside 
the transaction.

 You are free to implement such things yourself if you want.  In single 
> threaded mode, you could probably get something that works OK.
>  
>
> Sorry, but I couldn't understand what is the thread-safety role here.
>

I'm sure if you read the connection pool and transaction related code, you 
probably would.  You could then probably also figure out how to implement 
what you want yourself.

To hopefully be more clear: what you want is not implemented because it is 
a bad idea, not because it is difficult to implement.

Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sequel-talk/-/tcTgQHhpzc4J.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sequel-talk?hl=en.

Reply via email to