/** * Refreshes the metadata table for a given table. This means that missing * columns and keys are created so that the schema matches the schema of * the current table structure. * * @param string $tablename The name of the table for which the metadata is being * stored. */ function refreshMetadataTable($tablename = null) { if (!isset($tablename)) { $tablename = $this->tablename; } if (Dataface_MetadataTool::isMetadataTable($tablename)) { return false; } $app =& Dataface_Application::getInstance(); $table =& Dataface_Table::loadTable($tablename); $md_tablename = $tablename . '__metadata'; if (!Dataface_Table::tableExists($md_tablename, false)) { if ($this->createMetadataTable($tablename)) { return true; } } $cols =& $this->getColumns($tablename, false); // First we have to go through all of the key fields of the subject table // and make sure that they appear in the metadata table. $updatePrimaryKey = false; foreach ($table->keys() as $field) { if (!isset($cols[$field['Field']])) { $updatePrimaryKey = true; $default = @$field['Default'] ? " DEFAULT {$field['Default']}" : ''; $sql = "alter table `{$md_tablename}` add column `{$field['Field']}` {$field['Type']}{$default}"; $res = xf_db_query($sql, $app->db()); if (!$res) { trigger_error(xf_db_error($app->db()), E_USER_ERROR); } } } $table_keys =& $table->keys(); //Next we have to go through all of the key fields in the metadata table ane make sure that they // appear in the subject table primary keys. foreach ($this->getKeyColumns($tablename, false) as $field) { if (!isset($table_keys[$field['Field']])) { $updatePrimaryKey = true; $sql = "alter table `{$md_tablename}` drop column `{$field['Field']}`"; $res = xf_db_query($sql, $app->db()); if (!$res) { trigger_error(xf_db_error($app->db()), E_USER_ERROR); } } } // If the primary key needed to be updated, we will update it now. if ($updatePrimaryKey) { // The primary key needs to be updated $sql = "drop primary key"; @xf_db_query($sql, $app->db()); $sql = "alter table `{$md_tablename}` add primary key (`" . implode('`,`', array_keys($table->keys())) . "`)"; $res = xf_db_query($sql, $app->db()); if (!$res) { trigger_error(xf_db_error($app->db()), E_USER_ERROR); } } // Now we need to make sure that all of the prescribed meta fields are // in the metadata field. $fielddefs = $this->loadMetadataFieldDefs($tablename); $cols = $this->getColumns($tablename, false); foreach ($fielddefs as $field) { if (!isset($cols[$field['Field']])) { $default = @$field['Default'] ? " DEFAULT {$field['Default']}" : ''; $sql = "alter table `{$md_tablename}` add column `{$field['Field']}` {$field['Type']}{$default}"; $res = xf_db_query($sql, $app->db()); if (!$res) { trigger_error(xf_db_error($app->db()), E_USER_ERROR); } } } return true; }
/** * Returns an array of names of columns in the metadata table for this * table. The metadata table contains metadata such as state and * translation state for the corresponding records of this table. * Fields of this table that are considered to be metadata must begin * with two underscores to signify that they are metadata. * * If no metadata table yet exists, it will be created. * @returns array List of column names. */ function getMetadataColumns() { if (!isset($this->metadataColumns)) { $metatablename = $this->tablename . '__metadata'; $sql = "SHOW COLUMNS FROM `{$metatablename}`"; $res = mysql_query($sql, $this->db); if (!$res || mysql_num_rows($res) == 0) { Dataface_MetadataTool::refreshMetadataTable($this->tablename); $res = mysql_query($sql, $this->db); } if (!$res) { trigger_error(mysql_error($this->db), E_USER_ERROR); } if (mysql_num_rows($res) == 0) { trigger_error("No metadata table set up for table '{$this->tablename}'", E_USER_ERROR); } $this->metadataColumns = array(); while ($row = mysql_fetch_assoc($res)) { if (substr($row['Field'], 0, 2) == '__') { $this->metadataColumns[] = $row['Field']; } } } return $this->metadataColumns; }
/** * Updates the metadata tables to make sure that they are current. * Meta data tables are tables created by dataface to enrich the database. * For example, if workflow is enabled via the enable_workflow flag in the * conf.ini file, then dataface will maintain a workflow table to correspond * to each table in the database. This method will make sure that the * workflow table is consistent with base table. */ function refreshSchemas($tablename) { if (@$this->_conf['metadata_enabled']) { $metadataTool = new Dataface_MetadataTool(); $metadataTool->updateWorkflowTable($tablename); } }
function test_refreshMetadataTable() { $app =& Dataface_Application::getInstance(); $sql = "create table `md_test3` (\n\t\t\t\tfname varchar(32) NOT NULL,\n\t\t\t\tlname varchar(32) NOT NULL,\n\t\t\t\tage int(11) default 10,\n\t\t\t\tprimary key (`fname`,`lname`))"; $res = xf_db_query($sql, $app->db()); if (!$res) { trigger_error(xf_db_error($app->db()), E_USER_ERROR); } $mt = new Dataface_MetadataTool('md_test3'); $this->assertTrue($mt->refreshMetadataTable()); $this->assertEquals(1, xf_db_num_rows(xf_db_query("show tables like 'md_test3__metadata'", $app->db()))); $cols = $mt->getColumns(null, false); $this->assertEquals(array('fname', 'lname', '__translation_state', '__published_state'), array_keys($cols)); $mt->fieldDefs['__test_col'] = array('Type' => 'varchar(32)', 'Default' => 'Null', 'Field' => '__test_col'); $this->assertTrue($mt->refreshMetadataTable()); $cols = $mt->getColumns(null, false); $this->assertEquals(array('fname', 'lname', '__translation_state', '__published_state', '__test_col'), array_keys($cols)); }
function test_metadata_from() { $app =& Dataface_Application::getInstance(); $original_value = @$app->_conf['metadata_enabled']; $app->_conf['metadata_enabled'] = 1; import('Dataface/MetadataTool.php'); $mt = new Dataface_MetadataTool('Profiles'); $mt->createMetadataTable(); $builder = new Dataface_QueryBuilder('Profiles'); echo $from = $builder->_from(); $sql = "select * {$from} where id='10'"; //$res = xf_db_query($sql, $app->db()); //if ( !$res ) trigger_error(xf_db_error($app->db()), E_USER_ERROR); }