* * * * *
Stone knives and bear skins, Part II
I briefly mentioned “Project Leaflet [1]” before, with respect to separating
logic, language and layout [2] of an application (in this case, a PHP web
application), possibly with the use of an IDE (Integrated Development
Environment).
But the problem goes deeper—what if you need alternative versions of the
language? Or logic?
In C, this is handled by conditional compilation:
> #ifdef MSDOS
> fp = fopen("C:\\temp\\foobar","wb");
> #elif defined(VMS)
> fp = fopen("SYS$USERS:[TEMP.FOOBAR]","wb");
> #elif defined(UNIX)
> fp = fopen("/tmp/foobar","w");
> #else
> fp = fopen("foobar","wb");
> #endif
> if (fp == NULL)
> {
> #if defined(UNIX)
> fprintf(stderr,"could not open /tmp/foobar\n");
> return(ENOENT);
> #elif defined(MSDOS)
> fprintf(stderr,"could not open C:\\TEMP\\FOOBAR\n");
> return(ENOTFOUND);
> #elif defined(VMS)
> fprintf(stderr,"cold not open SYS:USERS:[TEMP.FOOBAR]\n");
> return(ENOFILE);
> #else
> fprintf(stderr,"could not open foobar\n");
> return(EXIT_FAILURE);
> #endif
> }
>
As you can see, this method leaves a lot to be desired, but still, it's much
better than what you get with PHP.
One of the design requirements for “Project Leaflet” is that it can use
either MySQL [3] or PostgreSQL [4]. I've already gone through the code and
abstracted out the database calls on the (okay, laughably incorrect)
assumption that the SQL (Structured Query Language) statements themselves
won't require changing.
Ha ha.
Now granted, for the most part, the SQL statments are simple enough that
either MysQL or PostgreSQL can run them without problem. But there are a few
rough spots, like:
> $query = "SELECT "
> . " *, "
> . " DATE_FORMAT(sent, '%b. %e, %Y at %l:%i%p') as datesent "
> . "FROM pl_emails WHERE id=$id";
>
PostgreSQL doesn't understand DATE_FORMAT(); no, it wants TO_CHAR(). To make
things even more amusing, the format string is completely different:
> $query = "SELECT "
> . " *, "
> . " TO_CHAR(sent, 'Mon DD YYYY at HH12:MMam') as datesent "
> . "FROM pl_emails WHERE id=$id";
>
So right now I'm looking at two codebases, separated by a common language
[5]. Sure, there are any number of methods to merge the two into a common
codebase:
> //---------------
> // Variant 1
> //---------------
>
> // would this even work, as it requires
> // the use if $id ...
>
> $query = $db_view_query['all_by_date'];
>
> //-----------
> // Variant 2
> //-----------
>
> if ($db === "MySQL")
> {
> $query = "SELECT "
> . " *, "
> . " DATE_FORMAT(sent, '%b. %e, %Y at %l:%i%p') as datesent "
> . "FROM pl_emails WHERE id=$id";
> }
> elsif ($db === "PostgreSQL")
> {
> $query = "SELECT "
> . " *, "
> . " TO_CHAR(sent, 'Mon DD YYYY at HH12:MMam') as datesent "
> . "FROM pl_emails WHERE id=$id";
> }
> else
> {
> // -------------------------------------
> // love the way the language separation
> // was done ...
> // -------------------------------------
>
> die ($lang['a_horrible_death']);
>
> //----------------
> // Variant 3
> //----------------
>
> $query = "SELECT "
> . " *, "
> . $dbdatefunct . "(send,'$dbdateformat') as datasent "
> . "FROM pl_emails WHERE id=$id";
>
>
Each solution being worse than the previous one. At least C has the decisions
being done at compile time; I'm stuck with runtime decisions, or with very
gross self-modifying code (variant #3—yes, that's what that is, self-
modifying code).
As it stands right now, I have two branches of the code, a MySQL version and
a PostgreSQL version, and I'm wavering between keeping them separate or
merging the two, and the “keep them separate” faction is winning. That's
because I'm currently using git [6], which makes branching a no-brainer (no,
truly—switching between branches is trivial and takes no time at all; yes,
it's a bit clunky trying to keep a central repository using git, but the
branching is worth the clunkiness). And git's merging capabilities means that
propagating fixes between the branches is easy as well (for fixes that apply
across all branches, obviously). git comes very close to the fine-grained
revision control [7] I talked about.
So, not only do I want find-grained revision control, but a way to say “these
changes I'm making apply to all the branches, and these changes only to this
branch over here.”
[1]
gopher://gopher.conman.org/0Phlog:2008/02/05.1
[2]
gopher://gopher.conman.org/0Phlog:2008/02/10.1
[3]
http://www.mysql.com/
[4]
http://www.postgresql.org/
[5]
http://www.quotationspage.com/quote/897.html
[6]
http://git.or.cz/
[7]
gopher://gopher.conman.org/0Phlog:2007/09/08.1
Email author at
[email protected]