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.”
[4] http://www.postgresql.org/