Skip Menu |

This queue is for tickets about the Class-DBI-DATA-Schema CPAN distribution.

Report information
The Basics
Id: 82814
Status: open
Priority: 0/
Queue: Class-DBI-DATA-Schema

People
Owner: Nobody in particular
Requestors: wftk [...] vivtek.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: (no value)



After some flabbergasted investigation, I finally figured out what the problem is that prevents the test from passing. Your scheme of translating only those statements that SQLFairy understands, and passing through the rest unchanged, is a great one - except it looks as though about 2005 or 2006, SQLFairy started *parsing* INSERT commands without *handling* them. The result is that it returns a BEGIN TRANSACTION and COMMIT TRANSACTION wrapped around a blank statement for the SQLite insert, and your pass-through code therefore doesn't emit an INSERT, and the test for having the right number of rows in the table thus fails. The cheap fix is to use REPLACE INTO in the test, which isn't picked up by the SQLFairy parser but has the same effect in the test, and allows a pass. A better fix would be to avoid sending INSERT to SQLFairy in the first place, which is sadly less elegant than your solution but has the advantage of working when schemas include INSERT to load the tables. The reason CPANtesters list passing tests, by the way, is that the tests don't run on machines where SQLite isn't installed. Apparently about half of the testing machines don't have SQLite installed in the test environment unless you specify it as a dependency (which clearly wouldn't be the right thing to do). Incidentally, I learned a lot from reading your code. It's really cleverly written. This module is a prerequisite for Email::Storage, which is how I came across it. I'd appreciate it if you could update - or I can if you don't want to bother. I want to use Email::Storage, possibly eventually in a product even. (Although at the speed I work, we'll all have brain interfaces to the cloud by then and email will be long obsolete.)
Subject: More information and patch
RT-Send-CC: modules [...] perl.org
A little more information about this long-standing bug (RT ticket #82814). First, the change in behavior in SQL::Translator probably happened about 2008 and involved wrapping transaction commit statements around the return value. The problem was that if SQL::Translator's SQLite output module didn't find any actionable statements, it would still return begin transaction/commit statements, so your groovy fall-back code that would just use the INSERT didn't get a chance to work - it made it appear that SQL::Translator had translated them. I didn't like the idea of cluttering your code with an explicit INSERT detector, so I've submitted a patch to the SQLite output module (with the agreement of the SQL::Translator maintainers) and hopefully that will be cleared up next time they post a new version to CPAN. Once that was working, though, it revealed another problem with the tests - your scheme of letting the error for reinvocation of the setup fall through to the caller doesn't work any more. I added a flag (already_called) and an explicit check for the flag, which also allows us to return a better error message. Once the SQL::Translator patch is in the CPAN distro, this patch will allow Class::DBI::DATA::Schema to install cleanly again. I've attached a patch to this bug report; alternatively, I've also set up a version update to 1.01 on Github at https://github.com/Vivtek/Class-DBI-DATA-Schema if you don't want to mess with it (in other words, I'm offering to take over co-maintainer status, which shouldn't make much difference, since honestly very little should ever need much maintenance in this module.)
Subject: Class-DBI-patch.txt
*** Class-DBI-DATA-Schema-1.00/lib/Class/DBI/DATA/Schema.pm 2005-09-03 22:19:23.000000000 +0200 --- Class-DBI-DATA-Schema/lib/Class/DBI/DATA/Schema.pm 2013-03-16 20:39:41.744198600 +0100 *************** *** 120,134 **** --- 120,139 ---- chomp(my $sql = <$h>); return grep /\S/, split /;/, $translating ? $transform->($sql) : $sql; }; my %cache; + + my $already_run = 0; no strict 'refs'; *{"$caller\::run_data_sql"} = sub { my $class = shift; + die "Data SQL already run" if $already_run; no strict 'refs'; $cache{$class} ||= [ $get_statements->(*{"$class\::DATA"}{IO}) ]; $class->db_Main->do($_) foreach @{ $cache{$class} }; + $already_run = 1; return 1; }
Subject: Argh - disregard that last patch
That patch won't work, as it's just checking whether Class::DBI::Data::Schema has *ever* been imported. That was stupid. Back to the ol' drawing board. I shall keep you posted.
Subject: A patch that actually works as intended
Obviously, the flag needs to be kept *per class*, just like the SQL statements. Sorry about that. The patch attached not only passes tests, it also works when used with *other* modules - much better! On Sat Mar 16 16:31:09 2013, Michael wrote: Show quoted text
> That patch won't work, as it's just checking whether > Class::DBI::Data::Schema has *ever* been imported. That was stupid. > > Back to the ol' drawing board. I shall keep you posted.
Subject: Class-DBI-patch.txt
*** Class-DBI-DATA-Schema-1.00/lib/Class/DBI/DATA/Schema.pm 2005-09-03 22:19:23.000000000 +0200 --- Class-DBI-DATA-Schema/lib/Class/DBI/DATA/Schema.pm 2013-03-16 21:34:46.556223000 +0100 *************** *** 122,134 **** --- 122,137 ---- }; my %cache; + my %already_run; no strict 'refs'; *{"$caller\::run_data_sql"} = sub { my $class = shift; + die "Data SQL already run" if $already_run{$class}; no strict 'refs'; $cache{$class} ||= [ $get_statements->(*{"$class\::DATA"}{IO}) ]; $class->db_Main->do($_) foreach @{ $cache{$class} }; + $already_run{$class} = 1; return 1; }