Paul M. Jones

Don't listen to the crowd, they say "jump."

Should Solar_Sql_Entity Support Oracle?

Solar is a simple object library and application repository for PHP5. It is currently in development. This post refers to the object-relation management tool, Solar_Sql_Entity, which follows closely the table data gateway pattern described by Martin Fowler.

Oracle only allows 30 characters for an object name (table, field, index, sequence). While that by itself may be OK, it seriously restricts the operation of Solar_Sql_Entity. (This class is the natural successor to DB_Table.)

One of the points of Solar_Sql_Entity is to make it possible to create a table that will work on *all* of the supported RDBMS backends. This means that it has to submit to a lowest common denominator in some ways.

For example, in PostgreSQL, your index names must be unique across all tables in the database. For example, if you have a "table1" and "table2", each with an "id" field, it's not enough to specify an index called "id" on table1 and annother index also named "id" on table2; PgSQL sees that as a conflict. You have to make the index names unique even though they refer to different tables.

Thus, to support PgSQL, the index names would have to be "table1_id" and "table2_id". This is why DB_Table and Solar_Sql_Entity prefix the table name automatically to your index name (i.e., to make sure there are no index name conflicts if the schema is created in PgSQL). As an additional identifier, the index name gets "_idx" suffixed to it.

You can see where this is going: because of the 30-char limit in Oracle, this means you're pretty limited in how long your table and field names can be when using Solar_Sql_Entity. Right now, Solar_Sql_Entity limits you to 15 characters for table names and 10 characters for field names, all to make sure we stay under 30 chars for Oracle. This is pretty short, almost too short to be universally useful.

If Solar_Sql_Entity were not to support Oracle, the next highest character limit is 64 (MySQL and MS-SQL). That effectively doubles the available length (~30 chars for table, ~25 chars for field), but at the cost of dropping Oracle support within Solar_Sql_Entity.

Frankly, I'm not sure Oracle is in the "target market" for Solar anyway; the point of Solar is to be provide a toolset to help build apps-for-distribution (although it's fine for in-place apps, too).

Anybody have any feelings about (or experiences with) this kind of issue, one way or another?


28 Feb 1991: Desert Storm Ceasefire

On this day in 1991, after 100 hours of land battle following roughly 5 weeks of air operations, the United States declared a ceasefire in its military campaign to drive Saddam Hussein's invading forces out of Kuwait. That was a good day, but looking back now it was the first major battle of World War IV, and the conclusion to that battle has been accomplished only recently with the sovreignty of a free Iraq. Let's hope it sticks.


Simplifying Automated Form Generation, Validation, and Output

First Praise, Then Critique

HTML_QuickForm is the standard class within PEAR for building forms programmatically. Here's an example:


$form =& new HTML_QuickForm();
$type = 'text';
$name = 'city';
$label = 'Your City:';
$form->addElement($type, $name, $label);

(All XHTML element types are supported, including some pseudo-types such as 'date' and 'time').

When you call $form->display(), the class builds all the HTML for the form and the elements you have added. That's just the start, though. If you have a POST variable called 'city', it will populate the form with that value for you. You can add validation methods to each element, and the class will check the values and print error messages inside the form if the values are not valid. You can apply special processing to the values before retrieving them as an array with $form->export().

It's quite a neat package, but I have some quibbles with its operation. These are not design flaws; indeed, its design seems quite internally consistent. For example, each element is represented internally as an object itself, with its own methods and properties (usually descended from a base element class). For example, to set the value of an individual element, you have to call its setValue() method -- but any submitted values (e.g., in POST) will override that value. There are ways around this, but none of them seem simple or straightforward.

More to the point, while I am not a strict model-view-controller devotee, I find that HTML_QuickForm not only pierces the veil between model and view (or controller and view, depending on your definition), it positively shreds that veil to pieces. Yes, it has renderers that allow you to parse through the internal objectified representatiion of the form elements, but they system seems overly complex.

While I like HTML_QuickForm, and have written code (in DB_Table) that automatically generates forms from tables using it, I don't fully comprehend the methodologies underlying its operation. It seems to me there should be a simpler and more straightforward way of automating form generation, one that is both more comprehensible and more open to MVC separate while retaining the obvious strengths of validation and automated population of values.

Savant and Solar

Note: Savant3 and Solar are publicly available but are still in development. I present the remainder of this article as advance information on how they will interoperate, and while I am using the described methodologies on a continuing basis, the specifics may change in the future.

With the above points in mind, I developed a plugin for Savant2 that accepts an array of element definitions and generates forms from it (called Savant2_Plugin_form for obvious reasons). In Savant3, to be released, I have refined and extended that original idea to be a bit more full-featured (and I intend to backport it to Savant2, so don't worry about missing out). The Savant plugins cover the 'view' half of form generation. For the 'model' (or the 'controller' depending on how you think about these things) portion, I have implemented a complementary system in Solar_Form to collect and manage these element arrays.

The key here is that the form generation happens not in one location, as in HTML_QuickForm, but in two: Solar_Form defines the form elements, and Savant renders it. One benefit of this separation of duties is that neither class cares what the other class is. If you like, you can send a hand-built array of elements to Savant, and it will build the form just the same. Similarly, you can pass a Solar_Form element array to any template system, and if your template system knows how to deal with that array, it can render a form too. The point is that the information about the form is transmitted in a standard format as an array.

Therefore, the format of the element array is of paramount importance. Lucky for us, it is quite simple. For each element in the form, you have an array that looks like this:


$element = array(

    // the 'name' attribute for the XHTML form element
    'name'     => null,

    // the 'type' attribute
    'type'     => null,

    // a text label for the element
    'label'    => null,

    // the 'value' attribute of the element
    'value'    => null,

    // whether or not the element is required
    'require'  => false,

    // whether or not the element is disabled
    // (i.e., 'read-only')
    'disable'  => false,

    // any options related to the element values,
    // typically for select options, radios, or
    // checkbox values
    'options'  => array(),

    // additional attributes for the XHTML form element
    'attribs'  => array()
);

From our earlier example above, you would create an element under this system simply by specifying the array keys for it:


$element = array(
    'name' => 'city',
    'type' => 'text',
    'label' => 'Your City:',
    'value' => 'Memphis'
);

The Savant3 template system can take this array and render a form within a template script like this.


// assume that $element has been assigned as 'elem'
$this->form('start');
$this->form('auto', $this->elem);
$this->form('end');

Note the use of the 'auto' call, which automatically builds a single form element from an array; if you use the 'fullauto' call, it will build multiple elements from a sequential array of elements, in order.

The above discussion only describes the manual generation of form elements (the display is automated via Savant3). To get more of the functionality of HTML_QuickForm, we would need to use Solar_Form.

Solar_Form collects an array of elements together in a class property; you can add them one-by-one like this:


$form = Solar::object('Solar_Form');
$element = array(
    'type' => 'text',
    'label' => 'Your City:',
    'value' => 'Memphis'
);

// note that the 'name' key is optional when
// using setElement(); Solar_Form will use the
// first parameter as the 'name' value, overriding
// the 'name' key.  this has benefits when
// building arrays of elements.
$form->setElement('city', $element);

To populate the form elements with their related POST values, simply call the populate() method.


$form->populate();

You can then pass that form to Savant3 ...


$Savant3->form_elements = $form->elements;

... and render the form in a template script like so:


$this->form('start');
$this->form('fullauto', $this->form_elements);
$this->form('end');

Finally, you can add automated validation to the Solar_Form elements with the addValidate() method. Below, the $method relates to a standard Solar_Valid method; in addition to 'alpha', there are 'alphanumeric', 'numeric', 'isoDate', 'email', and other validation methods, as well as 'regex' (for user-defined regular expressions), 'custom' (for call_user_func callbacks), and 'multiple' (for arrays of validation routines).


$form = Solar::object('Solar_Form');

$element = array(
    'type' => 'text',
    'label' => 'Your City:',
    'value' => 'Memphis'
);

$form->setElement('city', $element);

$name = 'city';
$method = 'alpha';
$feedback = 'Please use only letters in the city name';
$form->addValidate($name, $method, $feedback);

Then you can call the validate() method, which will return true or false, and will automatically set the feedback messages for elements that failed validation.


if ($form->validate()) {
    $values = $form->values();
    // insert values into a table
}

$Savant3->form_elements = $form->elements;

Conclusion

While I shamelessly promote Solar and Savant throughout this entry, my main goal is to point out that MVC separation of form building, validation, automated population, and output display is possible with a unified format describing the form elements. It is not necessary to wrap all those functions into one class; indeed, separating the concerns seems vital to extended development cycles when differing framework systems must interoperate. Having it all in one class is great to start with, but after a while you find yourself coding to the class and trying to learn its intricacies, instead of using it for your own purposes.


Upgraded to WP 1.5

As you can see, the default theme is not really working for me. Have not figured out the problem yet, looks like a CSS thing.

Update: Had a mismatched anchor tag in an earlier post. Glad it was just me. :-)


DB_Table and Text_Wiki Release Candidates

For more information, please visit the related PEAR pages:

DB_Table

Text_Wiki

If I don't get any new (critical) bug reports for the next week or so, I can release them as "stable" and check them off my to-do list. While Text_Wiki could still use some add-ons (more renderers, more parsing rulesets) the core is complete. These two projects are each 18-24 months old at this point, so it's nice to be able to say "done!" to them.

Now all I have to do is finish the respective documentation. With any luck, the addition of YaWiki to the PEAR website will aid in that (then I can keep everything related to those two projects in one place; i.e., at PEAR).


Solar: Version 0.0.3 dev released

You can download, view the API docs, and join the mailing list from the official site (solarphp.com).

The change notes are:

* Converted all __hive() calls to __solar() instead.

* Added email and initial description to Solar_Cell_Bugs columns, removed reference to Solar_Cell_Talk (should be handled by the application object, not the bugs entity)

* Converted all 'dt' (date-time) abbreviations to 'ts' (timestamp) for consistency with Solar_Sql_Entity column type naming

* Multiple changes to Solar_Sql_Entity array keys ('ent' ==> 'tbl', 'seqname' ==> 'sequence', 'valid' ==> 'validate', 'message' ==> 'feedback'

* Added Solar_Form class (aggregates element-building instructions and validation)

* Added "None.php" drivers for Solar_User_Auth and Solar_User_Role (to facilitate having no backend for those services)

----

There were some internal changes to the Solar_Cell classes for Bugs and Talk (the bug and comment table entities, respectively). The biggest addition is the Solar_Form class, which is kind of like HTML_QuickForm, except it's not. ;-)

I really do have to start on at least some outline documentation; YaWiki will be perfect for it when I find the time between my MBA projects and my day job.


Write For Persons, Not Groups

Ryan King links to this great essay.

Anyway, I babbled at Nat along these lines for a while, predicting that, while I was sure that anyone he talked to in a corporation would tell him, "free groupware, yes, awesome!", there was really no reason to even bother releasing something like that as open source, because there was going to be absolutely no buy-in from the "itch-scratching" crowd. With a product like that, there was going to be no teenager in his basement hacking on it just because it was cool, or because it doing so made his life easier. Maybe IBM would throw some bucks at a developer or two to help out with it, because it might be cheaper to pay someone to write software than to just buy it off the shelf. But with a groupware product, nobody would ever work on it unless they were getting paid to, because it's just fundamentally not interesting to individuals.

And there you have it in a nutshell. No **organization** ever wrote or used a program. **Individuals** write and use programs. If you want people to love your software, it has to appeal to individuals.

As a corollary, if your program sucks for individuals, it will suck for the organization. This goes along with the complex adaptive systems and emergent behavior issues I rant about from time to time.

Good idea for a project at the end of the article, too: server-less calendar sharing. Cool.


Solar: We Have A Logo!

Courtesy of Ben Carter, graphic design wunderkind, we have a a logo now. You can view it at solarphp.com.

Carter did the original work in PhotoShop, but because I am a freak I re-created it, vectorized, in Macromedia Fireworks. Any flaws you may discover are mine.


Solar 0.0.2 released

It used to be called Hive; now it's Solar, the "Simple Object Library and Application Repository" for PHP5. This is only a development release. You can pick up the PEAR tarball here:

http://solarphp.com/Solar-0.0.2.tgz

No real documentation yet, but you can read the auto-generated API reference here:

http://solarphp.com/api/

Next set of tasks is to get the Solar_Cell_Bugs component working properly, and I can write up a quick app to do bug tracking. Also need a mailing list, and need to set up YaWiki installation for real documentation (although Solar will have a wiki component of its own, and at that point it can be self-hosted / autonomous / internally-dependent / eat its own dog food / whatever).

Revision control is going through Subversion now instead of CVS, provided by the kind folks at TextDrive, who are the web hosts for solarphp.com as well. For $12/month, it's a sweet deal; my thanks to Ryan King for pointing them out.


Battlestar Galactica

When I heard lat year that Sci-Fi channel was re-making Battlestar Galactica, my reaction was "eh." The original was a lot of fun for a 10-year old, but seeing re-runs of it, as an adult, were not very exciting.

Flipping through TV channels a few weeks ago, I happened upon an over-the-air broadcast on NBC of last year's 3-hours pilot episode. At first, I didn't recognize it; all I saw was a space panorama and some really good camera work, zooming in from a distance onto a far battle scene. It was an amazing shot, communicating the vast distances of space and the dynamic of the dogfight at the same time. Although I had stumbled across it by accident and the story was already half over, I was hooked immediately.

This new Battlestar Galactica is a very, very smart piece of work in too many ways to detail in one sitting. I cannot begin to describe how exceptionally well-done this series is: the characters are well developed and have distinct and conflicting personalities and motivations, the effects are amazing, the physics is really quite decent, the backstory is believable, and the bad guys have religion (really!).

Above all, the plotlines are not stupid; the writers assume you can figure things out yourself, and then hint you along so you can keep up. They don't use technical jargon and pseudo-science as deus ex machina (*cough*startrek*cough*). There are some great surprises, little touches that you would not have guessed but are funny and realistic and enjoyable.

Not to wax too enthusiastic (although I am very enthusiastic about this series now) but the effects are spectacular. The attention to detail is superb. To take one element, look at the Viper combat spacecraft. When a Viper is shooting out of a launch tube, you can see its counterweight-driver racing backwards beneath the track; while maneuvering, you see the attitude jets firing; and the maneuvering itself is three-dimensional -- it looks very like space combat should, with a full sphere of action, not just a plane, and arcs of fire, not just straight lines.

The camera work, even though a lot of it is CGI, is both believable and engrossing; you just cant take your eyes off it. The interior shots are shaky, as if it were a documentary. There are lots of little homages to other science fiction films in the set work; in particular, the interior design of the President's ship reminds me a great deal of the Pan-Am LEO shuttle from 2001. The first time I saw the blonde Cylon agent, all I could think of was Maria from Metropolis.

A friend of mine snagged the entire first season and passed it over to me last night. I have now lost all productivity as I watch "just one more epsiode". I watched two last night, and three this morning, ignoring homework, domestic duties, and programming. Get your hands on it as soon as you can, and then set aside a weekend to watch it (or five sequential evenings). It's just that good.