/** * Modifies the table to fit the bean data. * Given a property and a value and the bean, this method will * adjust the table structure to fit the requirements of the property and value. * This may include adding a new column or widening an existing column to hold a larger * or different kind of value. This method employs the writer to adjust the table * structure in the database. Schema updates are recorded in meta properties of the bean. * * This method will also apply indexes, unique constraints and foreign keys. * * @param OODBBean $bean bean to get cast data from and store meta in * @param string $property property to store * @param mixed $value value to store * * @return void */ private function modifySchema(OODBBean $bean, $property, $value) { $doFKStuff = FALSE; $table = $bean->getMeta('type'); $columns = $this->writer->getColumns($table); $columnNoQ = $this->writer->esc($property, TRUE); if (!$this->oodb->isChilled($bean->getMeta('type'))) { if ($bean->getMeta("cast.{$property}", -1) !== -1) { //check for explicitly specified types $cast = $bean->getMeta("cast.{$property}"); $typeno = $this->getTypeFromCast($cast); } else { $cast = FALSE; $typeno = $this->writer->scanType($value, TRUE); } if (isset($columns[$this->writer->esc($property, TRUE)])) { //Is this property represented in the table ? if (!$cast) { //rescan without taking into account special types >80 $typeno = $this->writer->scanType($value, FALSE); } $sqlt = $this->writer->code($columns[$this->writer->esc($property, TRUE)]); if ($typeno > $sqlt) { //no, we have to widen the database column type $this->writer->widenColumn($table, $property, $typeno); $bean->setMeta('buildreport.flags.widen', TRUE); $doFKStuff = TRUE; } } else { $this->writer->addColumn($table, $property, $typeno); $bean->setMeta('buildreport.flags.addcolumn', TRUE); $doFKStuff = TRUE; } if ($doFKStuff) { if (strrpos($columnNoQ, '_id') === strlen($columnNoQ) - 3) { $destinationColumnNoQ = substr($columnNoQ, 0, strlen($columnNoQ) - 3); $indexName = "index_foreignkey_{$table}_{$destinationColumnNoQ}"; $this->writer->addIndex($table, $indexName, $columnNoQ); $typeof = $bean->getMeta("sys.typeof.{$destinationColumnNoQ}", $destinationColumnNoQ); $isLink = $bean->getMeta('sys.buildcommand.unique', FALSE); //Make FK CASCADING if part of exclusive list (dependson=typeof) or if link bean $isDep = $bean->moveMeta('sys.buildcommand.fkdependson') === $typeof || is_array($isLink); $result = $this->writer->addFK($table, $typeof, $columnNoQ, 'id', $isDep); //If this is a link bean and all unique columns have been added already, then apply unique constraint if (is_array($isLink) && !count(array_diff($isLink, array_keys($this->writer->getColumns($table))))) { $this->writer->addUniqueConstraint($table, $bean->moveMeta('sys.buildcommand.unique')); $bean->setMeta("sys.typeof.{$destinationColumnNoQ}", NULL); } } } } }