Pragmatism in the real world

ADOdb Data Dictionary

CMS Made Simple (CMSMS) uses ADOdb for database abstraction. This is a good thing from my point of view as we use ADOdb at work so I don’t have any paradigm shifts to worry about. When writing my modules for CMSMS I discovered ADOdb’s data dictionary system. This allows you to create and edit tables in a cross-database manner. For instance:

		
$db = $this->cms->db; /* @var $db ADOConnection */
$dict = NewDataDictionary($db);  /* @var $dict ADODB_DataDict */
	
$table_options = array('mysql' => 'TYPE=MyISAM');

// create categories table
$fields = "
    category_id I KEY,
    category_name C(255),
    category_order I";

$sql_array = $dict->CreateTableSQL($this->categories_table_name, 
               $fields, $table_options);
$dict->ExecuteSQLArray($sql_array);
$db->CreateSequence($this->categories_table_name . '_seq');

This code creates a simple table for storing categories in any supported database. CMSMS uses it so that a module can create it’s own tables in Install() and then remove them again in Uninstall(). There is also a function Upgrade() which I’d never used before (having got my DB tables right first time!)

Whilst developing the Calendar module, I had a need to alter the database table structure that held an event. A feature request came in asking for “from” and “to” dates for each event rather than just a single date.”Aha!” thought I; a chance to play with some more data dictionary functions. (Actually, I wondered if I could just require users to dump their data as it’s only a 0.2 release, then I relented!)

Having decided to manipulate the table, I worked out that I needed to add a new timestamp field called event_date_end and rename my event_date field to event_date_start. I wandered over to the ADOdb Data Dictionary manual to find out what I could do. As with the main documentation, it’s very well written and easy to understand (with examples!). I quickly discovered RenameColumnSQL() and AddColumnSQL() were what I wanted.

Thus the Upgrade code is:

function Upgrade($oldversion, $newversion)
{
  // 0.3 introduces new event_date_start and event_date_end
  $db = $this->cms->db; /* @var $db ADOConnection */
  $dict = NewDataDictionary($db); /* @var $dict ADODB_DataDict */

  if(version_compare($oldversion, 0.3, "< "))
  {
    // this is version 0.2 or 0.1
    $sqlarray = $dict->RenameColumnSQL($this->events_table_name,
                  "event_date", "event_date_start", 
                  "event_date_start T");
    $dict->ExecuteSQLArray($sqlarray);
    $sqlarray = $dict->AddColumnSQL($this->events_table_name, 
                  "event_date_end T");
    $dict->ExecuteSQLArray($sqlarray);			

    // ensure that the new field has valid data in it.
    $sql = "UPDATE {$this->events_table_name} 
            SET event_date_end = event_date_start";
    $db->Execute($sql);
  }		
}

How easy is that?