good chemistry is complicated,
and a little bit messy -LW
DBI vs DBIx::Recordset vs princepawn vs chromaticby princepawn (Parson)
|on Mar 08, 2001 at 00:32 UTC||Need Help??|
About a week after I published this, I noticed an email from the email@example.com mailing list in which a short piece of a criticism of my article by chromatic appeared. In my eyes, the criticism is weak, but in the email, the acting editor of Perl.com write supportively of it. The aggravations for me in this are:
Now as I write this, I am starting to think: "Tim Bunce and Alligator Descartes could say the same thing about me. I didn't tell them I was writing an article concerning DBI. And next thing you know, there it is in from 100,00 eyes for all to see." There is one difference. I did try to reach Tim and Alligator but caught pure hell trying to subscribe to the DBI mailing lists. I felt like I was interviewing for a position with the FBI or something.
So anyway, I am now writing, as open letter what I planned to write to chromatic in email and CC to the acting editor of perl.com. I hope to hear what everyone thinks about whether DBI is really a sensible tool for application development, not scripts.
And let's not forget we have several options besides Recordset for application database use from Perl:
Let's take the criticisms one-by-one. The first criticism is of the following code:
Chromatic is saying that by predefining the order the formdata, we can eliminate the monstrous "my @data = (...)" code completely and simply change
where @formdata_column_ordering is an array indicating the order in which to choose fields from %formdata so that they match the columns indicated. And my response to Chromatic is to say that he is 100% correct he could do this. In fact, he could simplify generation of the insert sql by a couple of simple joins:
After this the "$sql = ..." code becomes much smaller too:
And so we see that Chromatic is 100% correct, you can make use of the Perl language to come up with more succinct ways to use DBI. Now let's take this statement from my paper to compare the DBI and DBIx::Recordset APIs for application-level useability:
As we can see, to make up for the fact that DBI does not directly support commission of hashes to database, I have had to do the following:
This is in contrast the DBIx::Recordset example:
Now of course, the other valid criticism is that you can write even more subroutines to allow yourself to handle steps 1-5 in one step, but by the time you have done so, you have basically re-written DBIx::Recordset! Again referring to the intro:
What I mean here is suppose that had I not created subroutines to deal with placeholder and column-name generation, but instead done something like this:
Then I would have been mixing the generic application-level functionality of SQL generation with the specifics of the data about to be inserted. In the intro I continue:
This would be the case if I developed large bodies of code with my make_placeholder() and make_column_name() routines but did not make them available for widespread use. Finally I state:
And this is exactly what the paper showed as an example. Regarding your accusation:
Neither option you present is the case. This code example was lifted directly from a now-defunct dot-com that I consulted at. My goal was to show the type of kludgery that results when people who don't have the time, education, or interest to develop viable high-level APIs for their Perl programs make use of what is available and what is available (in this case DBI and it's manpages and book) provides the wrong level of abstraction for the task at hand.
The second criticism is of the final DBI example. Chromatic says:
How would the final example be improved by placeholders? Speed of execution? Reduction of code lines? Since the blurb did not clarify this, I assume you mean that execution speed would improve. I won't argue that the final DBI example could be made faster with fewer lines of code. But I would argue that the final DBI could be made as functional as the DBIx::Recordset example in as many lines of code. The intent of the final example was to contrast DBIx::Recordset use with DBI use in a high-level database task and show what automatic features of Recordset had to be manually coded when directly using DBI.