List:MySQL++« Previous MessageNext Message »
From:Rick Gutleber Date:October 31 2008 5:17pm
Subject:Re: InsertPolicy and Transactions
View as plain text  
Warren Young wrote:
> Rick Gutleber wrote:
>> Does it really make sense for allow_transactions() to be part of the 
>> policy or should it be a bool option passed in to insertfrom( )?
>>
>> The reason I ask is because it seems silly to have to have two 
>> different InsertPolicy objects that differ only in whether 
>> transactions are allowed or not.
>
> There are patterns to allow the extra attribute without creating a 
> parallel class hierarchy.  I'd use traits:
>
>     template <class AccessController = Transaction>
>     class MyPolicy
>     {
>     public:   
>         typedef AccessController access_controller;
>     ...
>
> Then you could create a no-op NoTransactions class with the same 
> interface as Transaction, so that MyPolicy<NoTransactions> would be 
> MyPolicy without transactions.  This relieves from insertfrom() the 
> burden to care about transactions:
>
>     InsertPolicy::access_controller ac(&conn_);


Cool.  Templates are definitely still not instinctive for me... 
especially the idea of "faking" inheritance of an abstract interface.  
It feels like cheating from an OO point of view, although I definitely 
see the value.  In my pre-template days, I'd always used multiple 
inheritance with abstract classes that provided the interface.  For 
instance, if you have a collection that you want to be sortable, you 
inherit from the ISortable class and fill in the methods it uses.  
ISortable also included a couple of sort implementations you'd 
automatically get once you implemented a couple or three methods like 
::SortableCompare( ) and ::SortableSwap( ).


> A bool parameter to insertfrom() defaulting to true would make the 
> code more complex.   

At first, yes, but then I did this, putting the brains of the method in 
another private method:

template <class RowT, class InsertPolicy>
Query& insertfrom(const std::vector<RowT>& con, InsertPolicy& policy,
                  bool allow_transaction = true) {
    if ( allow_transaction ) {
        Transaction transaction(*conn_);

        if (_insertfrom(con, policy)) {
            transaction.commit();
        } else {
            transaction.rollback();
        }
    } else {
        _insertfrom(con, policy);
    }

    return *this;
}


But your way is a good idea.



> Based on the last code you posted, it looks like you'd have to add 4 
> or so new tests to decide whether to do the transaction stuff.  This 
> way, you avoid the additional tests.  This pays off in both 
> understandability and run-time efficiency (the former much more 
> important than the latter) because the compiler can optimize away 
> NoTransactions entirely.


The trait idea works very well in this context.


>
> This also localizes concerns better: whether to use transactions or 
> not *is* part of the insertion policy.


OK.  I didn't see it that way, but that's a reasonable view.


> And finally, it does offer some flexibility, at the low low cost of a 
> little extra template goo, which gets paid for out of other accounts: 
> efficiency, code simplicity, and proper localization of concerns.

Sounds good to me.

The real issues here aren't how to do something, but more what should be 
done at a more abstract level, and more to wrap my head around the 
philosophies behind MySQL++.  Also, it's nice to get some serious input 
and feedback from people better versed in the _current_ C++ scene.  I've 
been using the language very successfully on and off for about 15 years, 
but I realize that a lot of the new developments have changed the 
landscape considerably.  To wit, after spending a few hours catching up 
on the C++0x scene (how long until it's called "C++1x"?) I realized how 
radically they are changing, well really adding to, the language.  In 
particular, a piece written by Stroustrup made me understand that in 
effect, C++ is becoming a two-tier language (my characterization, not 
his).  The outer tier is C++ the way it's pretty much always been since 
1998, and the inner tier which allows people to make stuff like Boost 
more powerful and flexible, and not necessarily stuff you'd use on a 
daily basis (unless you are doing low-level tools like STL or Boost).



Thread
InsertPolicy and TransactionsRick Gutleber30 Oct
  • Re: InsertPolicy and TransactionsWarren Young31 Oct
    • Re: InsertPolicy and TransactionsRick Gutleber31 Oct
      • Re: InsertPolicy and TransactionsWarren Young31 Oct
        • Re: InsertPolicy and TransactionsRick Gutleber3 Nov