/** * Molds 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. * * @param RedBean_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 moldTable(RedBean_OODBBean $bean, $property, $value) { $table = $bean->getMeta('type'); $columns = $this->writer->getColumns($table); if (!in_array($bean->getMeta('type'), $this->chillList)) { 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); } } else { $this->writer->addColumn($table, $property, $typeno); $bean->setMeta('buildreport.flags.addcolumn', TRUE); $this->processBuildCommands($table, $property, $bean); } } }
/** * Stores a cleaned bean; i.e. only scalar values. This is the core of the store() * method. When all lists and embedded beans (parent objects) have been processed and * removed from the original bean the bean is passed to this method to be stored * in the database. * * @param RedBean_OODBBean $bean the clean bean */ private function storeBean(RedBean_OODBBean $bean) { if (!$this->isFrozen) { $this->check($bean); } //what table does it want $table = $bean->getMeta('type'); if ($bean->getMeta('tainted')) { //Does table exist? If not, create if (!$this->isFrozen && !$this->tableExists($this->writer->esc($table, true))) { $this->writer->createTable($table); $bean->setMeta('buildreport.flags.created', true); } if (!$this->isFrozen) { $columns = $this->writer->getColumns($table); } //does the table fit? $insertvalues = array(); $insertcolumns = array(); $updatevalues = array(); foreach ($bean as $p => $v) { $origV = $v; if ($p !== 'id') { if (!$this->isFrozen) { //Not in the chill list? if (!in_array($bean->getMeta('type'), $this->chillList)) { //Does the user want to specify the type? if ($bean->getMeta("cast.{$p}", -1) !== -1) { $cast = $bean->getMeta("cast.{$p}"); $typeno = $this->getTypeFromCast($cast); } else { $cast = false; //What kind of property are we dealing with? $typeno = $this->writer->scanType($v, true); } //Is this property represented in the table? if (isset($columns[$this->writer->esc($p, true)])) { //rescan $v = $origV; if (!$cast) { $typeno = $this->writer->scanType($v, false); } //yes it is, does it still fit? $sqlt = $this->writer->code($columns[$this->writer->esc($p, true)]); if ($typeno > $sqlt) { //no, we have to widen the database column type $this->writer->widenColumn($table, $p, $typeno); $bean->setMeta('buildreport.flags.widen', true); } } else { //no it is not $this->writer->addColumn($table, $p, $typeno); $bean->setMeta('buildreport.flags.addcolumn', true); //@todo: move build commands here... more practical $this->processBuildCommands($table, $p, $bean); } } } //Okay, now we are sure that the property value will fit $insertvalues[] = $v; $insertcolumns[] = $p; $updatevalues[] = array('property' => $p, 'value' => $v); } } if (!$this->isFrozen && ($uniques = $bean->getMeta('buildcommand.unique'))) { foreach ($uniques as $unique) { $this->writer->addUniqueIndex($table, $unique); } } $rs = $this->writer->updateRecord($table, $updatevalues, $bean->id); $bean->id = $rs; $bean->setMeta('tainted', false); } }