Re: [Dbix-class] DBIx::Class::Relationship::CascadeActions::delete(): Not in database

2013-03-27 Thread David Cantrell
On Wed, Mar 27, 2013 at 06:02:27AM +1100, Peter Rabbitson wrote:

 From https://metacpan.org/module/DBIx::Class::Row#delete
 :: If you delete an object within a txn_do() (see txn_do in 
 :: DBIx::Class::Storage) and the transaction subsequently fails, the 
 :: result object will remain marked as not being in storage. If you know 
 :: for a fact that the object is still in storage (i.e. by inspecting 
 :: the cause of the transaction's failure), you can use 
 :: $obj-in_storage(1) to restore consistency between the object and the 
 :: database. This would allow a subsequent $obj-delete to work as 
 :: expected.

Eeuuww!

I would thunk that in_storage should be rolled back too.

-- 
David Cantrell | Cake Smuggler Extraordinaire

Computer Science is about lofty design goals and careful algorithmic
optimisation.  Sysadminning is about cleaning up the resulting mess.

___
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk


Re: [Dbix-class] DBIx::Class::Relationship::CascadeActions::delete(): Not in database

2013-03-27 Thread Peter Rabbitson
On Wed, Mar 27, 2013 at 12:30:03PM +, David Cantrell wrote:
 
 Eeuuww!
 
 I would thunk that in_storage should be rolled back too.
 

How would you implement that? (as in how would the perl logic actually 
look)

___
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk


Re: [Dbix-class] DBIx::Class::Relationship::CascadeActions::delete(): Not in database

2013-03-27 Thread David Cantrell
On Wed, Mar 27, 2013 at 11:49:53PM +1100, Peter Rabbitson wrote:
 On Wed, Mar 27, 2013 at 12:30:03PM +, David Cantrell wrote:
  Eeuuww!
  I would thunk that in_storage should be rolled back too.
 How would you implement that? (as in how would the perl logic actually 
 look)

in the code that flips that bit ...

if we're in a transaction
  store in the transaction (handwave handwave, i've not looked at the code)
a tuple of [ref to object we're updating, the old value of in_storage]
  update it
fi

and then in the transaction code ...

if the transaction gets rolled back
  go through that list of tuples, resetting in_storage on each object
fi

If you think that these half-arsed ideas seem plausible, then please
point me at the right places that I can shim them in!

-- 
David Cantrell | top google result for topless karaoke murders

 Nuke a disabled unborn gay baby whale for JESUS!

___
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk


Re: [Dbix-class] DBIx::Class::Relationship::CascadeActions::delete(): Not in database

2013-03-27 Thread Rob Kinyon
On Wed, Mar 27, 2013 at 6:54 AM, David Cantrell da...@cantrell.org.ukwrote:

 On Wed, Mar 27, 2013 at 11:49:53PM +1100, Peter Rabbitson wrote:
  On Wed, Mar 27, 2013 at 12:30:03PM +, David Cantrell wrote:
   Eeuuww!
   I would thunk that in_storage should be rolled back too.
  How would you implement that? (as in how would the perl logic actually
  look)

 in the code that flips that bit ...

 if we're in a transaction
   store in the transaction (handwave handwave, i've not looked at the code)
 a tuple of [ref to object we're updating, the old value of in_storage]
   update it
 fi

 and then in the transaction code ...

 if the transaction gets rolled back
   go through that list of tuples, resetting in_storage on each object
 fi

 If you think that these half-arsed ideas seem plausible, then please
 point me at the right places that I can shim them in!


Theoretically, this could work. In reality, this becomes a major source of
bugs. Especially in child classes.

The better solution is to have the bit flipped in the row object. Then,
::Row becomes responsible for storing these tuples and reversing them. Of
course, this means that all value changes have to be mediated through one
method, including for all children of ::Row. But, more workable than an
externalized list of tuples.

-- 
Thanks,
Rob Kinyon
___
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk

Re: [Dbix-class] DBIx::Class::Relationship::CascadeActions::delete(): Not in database

2013-03-27 Thread Peter Rabbitson
On Wed, Mar 27, 2013 at 01:54:00PM +, David Cantrell wrote:
 On Wed, Mar 27, 2013 at 11:49:53PM +1100, Peter Rabbitson wrote:
  On Wed, Mar 27, 2013 at 12:30:03PM +, David Cantrell wrote:
   Eeuuww!
   I would thunk that in_storage should be rolled back too.
  How would you implement that? (as in how would the perl logic actually 
  look)
 
 in the code that flips that bit ...
 
 if we're in a transaction
   store in the transaction (handwave handwave, i've not looked at the code)
 a tuple of [ref to object we're updating, the old value of in_storage]
   update it
 fi

What happens on:

my $result = $rs-new({...});

stuff happens

$schema-txn_do({
   more stuff happens 
   an insert happens incorporating $result, maybe directly maybe as part of a 
multicreate 
  $result-in_storage is now true
  exception happens !!!
});

Where would we have hooked the event that $result (which note is 
entirely external to the txn_do) got something done to it?

We could potentially have *every* $result object register a weakref to 
itself in its schema when its in_storage changes from 0 to 1, and have 
stuff being flipped back in case the objects are still alive but... gut 
feeling says I am missing something...

In any case - if it is all that there is to it - you are simply looking at
::Row::insert(), and at $self-result_source-schema-storage-txn_depth()
to figure out if you are in a txn or not...

Please handwave a bit more ;)

___
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk


Re: [Dbix-class] DBIx::Class::Relationship::CascadeActions::delete(): Not in database

2013-03-26 Thread Peter Rabbitson
On Mon, Mar 25, 2013 at 10:51:50PM -0700, Bill Moseley wrote:
 Here's a rather contrived example:
 
 
 my $artist = $schema-resultset( 'Artist' )-first;
 
 eval {
 my $guard = $schema-txn_scope_guard;
 $artist-delete;
 die 'rollback!';
 1;
 };
 
 #$artist-in_storage(1);
 $artist-delete;
 
 
 Produces:  DBIx::Class::Relationship::CascadeActions::delete(): Not in
 database
 
 I'm trying to remember if there's a way to handle code like this.I came
 across it writing tests (where I made some changes, and then rolled back to
 revert the changes).  I don't really see that there could be a general way
 to handle it, but thought I'd ask.
 
 Is forcing in_storage ok in this case?

From https://metacpan.org/module/DBIx::Class::Row#delete

:: If you delete an object within a txn_do() (see txn_do in 
:: DBIx::Class::Storage) and the transaction subsequently fails, the 
:: result object will remain marked as not being in storage. If you know 
:: for a fact that the object is still in storage (i.e. by inspecting 
:: the cause of the transaction's failure), you can use 
:: $obj-in_storage(1) to restore consistency between the object and the 
:: database. This would allow a subsequent $obj-delete to work as 
:: expected.

___
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk