Esempio n. 1
0
 /**
  * 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);
         }
     }
 }
Esempio n. 2
0
 /**
  * Stores a bean in the database. This function takes a
  * RedBean_OODBBean Bean Object $bean and stores it
  * in the database. If the database schema is not compatible
  * with this bean and RedBean runs in fluid mode the schema
  * will be altered to store the bean correctly.
  * If the database schema is not compatible with this bean and
  * RedBean runs in frozen mode it will throw an exception.
  * This function returns the primary key ID of the inserted
  * bean.
  * @throws RedBean_Exception_Security $exception
  * @param RedBean_OODBBean $bean
  * @return integer $newid
  */
 public function store(RedBean_OODBBean $bean)
 {
     $this->signal("update", $bean);
     $this->check($bean);
     //what table does it want
     $table = $bean->getMeta("type");
     $idfield = $this->writer->getIDField($table);
     //does this table exist?
     $tables = $this->writer->getTables();
     //If not, create
     if (!$this->isFrozen && !in_array($table, $tables)) {
         $this->writer->createTable($table);
     }
     $columns = $this->writer->getColumns($table);
     //does the table fit?
     $insertvalues = array();
     $insertcolumns = array();
     $updatevalues = array();
     foreach ($bean as $p => $v) {
         if ($p != $idfield) {
             if (!$this->isFrozen) {
                 //What kind of property are we dealing with?
                 $typeno = $this->writer->scanType($v);
                 //Is this property represented in the table?
                 if (isset($columns[$p])) {
                     //yes it is, does it still fit?
                     $sqlt = $this->writer->code($columns[$p]);
                     if ($typeno > $sqlt) {
                         //no, we have to widen the database column type
                         $this->writer->widenColumn($table, $p, $typeno);
                     }
                 } else {
                     //no it is not
                     $this->writer->addColumn($table, $p, $typeno);
                 }
             }
             //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);
         }
     }
     if ($bean->{$idfield}) {
         if (count($updatevalues) > 0) {
             $this->writer->updateRecord($table, $updatevalues, $bean->{$idfield});
         }
         return (int) $bean->{$idfield};
     } else {
         $id = $this->writer->insertRecord($table, $insertcolumns, array($insertvalues));
         $bean->{$idfield} = $id;
         return (int) $id;
     }
 }
Esempio n. 3
0
 /**
  * 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->safeTable($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);
                             $v = $this->writer->getValue();
                         }
                         //Is this property represented in the table?
                         if (isset($columns[$this->writer->safeColumn($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->safeColumn($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);
     }
 }
Esempio n. 4
0
 /**
  * Stores a bean in the database. This function takes a
  * RedBean_OODBBean Bean Object $bean and stores it
  * in the database. If the database schema is not compatible
  * with this bean and RedBean runs in fluid mode the schema
  * will be altered to store the bean correctly.
  * If the database schema is not compatible with this bean and
  * RedBean runs in frozen mode it will throw an exception.
  * This function returns the primary key ID of the inserted
  * bean.
  * @throws RedBean_Exception_Security $exception
  * @param RedBean_OODBBean $bean
  * @return integer $newid
  */
 public function store(RedBean_OODBBean $bean)
 {
     $this->signal("update", $bean);
     $this->check($bean);
     $table = $bean->getMeta("type");
     $idfield = $this->writer->getIDField($table);
     if (!$this->isFrozen && !$this->tableExists($table)) {
         $this->writer->createTable($table);
     }
     if (!$this->isFrozen) {
         $columns = $this->writer->getColumns($table);
     }
     $insertvalues = array();
     $insertcolumns = array();
     $updatevalues = array();
     foreach ($bean as $p => $v) {
         if ($p != $idfield) {
             if (!$this->isFrozen) {
                 $typeno = $this->writer->scanType($v);
                 if (isset($columns[$p])) {
                     $sqlt = $this->writer->code($columns[$p]);
                     if ($typeno > $sqlt) {
                         $this->writer->widenColumn($table, $p, $typeno);
                     }
                 } else {
                     $this->writer->addColumn($table, $p, $typeno);
                 }
             }
             $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);
         }
     }
     if ($bean->{$idfield}) {
         if (count($updatevalues) > 0) {
             $this->writer->updateRecord($table, $updatevalues, $bean->{$idfield});
         }
         $bean->setMeta("tainted", false);
         $this->signal("after_update", $bean);
         return (int) $bean->{$idfield};
     } else {
         $id = $this->writer->insertRecord($table, $insertcolumns, array($insertvalues));
         $bean->{$idfield} = $id;
         $bean->setMeta("tainted", false);
         $this->signal("after_update", $bean);
         return (int) $id;
     }
 }
Esempio n. 5
0
 /**
  * Stores a bean in the database. This function takes a
  * RedBean_OODBBean Bean Object $bean and stores it
  * in the database. If the database schema is not compatible
  * with this bean and RedBean runs in fluid mode the schema
  * will be altered to store the bean correctly.
  * If the database schema is not compatible with this bean and
  * RedBean runs in frozen mode it will throw an exception.
  * This function returns the primary key ID of the inserted
  * bean.
  *
  * @throws RedBean_Exception_Security $exception
  * @param RedBean_OODBBean $bean bean to store
  *
  * @return integer $newid
  */
 public function store(RedBean_OODBBean $bean)
 {
     $processLists = false;
     foreach ($bean as $k => $v) {
         if (is_array($v) || is_object($v)) {
             $processLists = true;
             break;
         }
     }
     if (!$processLists && !$bean->getMeta('tainted')) {
         return $bean->getID();
     }
     $this->signal("update", $bean);
     if ($processLists) {
         //Define groups
         $sharedAdditions = $sharedTrashcan = $sharedresidue = $sharedItems = array();
         $ownAdditions = $ownTrashcan = $ownresidue = array();
         $tmpCollectionStore = array();
         $embeddedBeans = array();
         foreach ($bean as $p => $v) {
             if ($v instanceof RedBean_OODBBean) {
                 $embtype = $v->getMeta('type');
                 $idfield = $this->writer->getIDField($embtype);
                 if (!$v->{$idfield} || $v->getMeta('tainted')) {
                     $this->store($v);
                 }
                 $beanID = $v->{$idfield};
                 $linkField = $p . '_id';
                 $bean->{$linkField} = $beanID;
                 $bean->setMeta('cast.' . $linkField, 'id');
                 $embeddedBeans[$linkField] = $v;
                 $tmpCollectionStore[$p] = $bean->{$p};
                 $bean->removeProperty($p);
             }
             if (is_array($v)) {
                 $originals = $bean->getMeta('sys.shadow.' . $p);
                 if (!$originals) {
                     $originals = array();
                 }
                 if (strpos($p, 'own') === 0) {
                     list($ownAdditions, $ownTrashcan, $ownresidue) = $this->processGroups($originals, $v, $ownAdditions, $ownTrashcan, $ownresidue);
                     $bean->removeProperty($p);
                 } elseif (strpos($p, 'shared') === 0) {
                     list($sharedAdditions, $sharedTrashcan, $sharedresidue) = $this->processGroups($originals, $v, $sharedAdditions, $sharedTrashcan, $sharedresidue);
                     $bean->removeProperty($p);
                 } else {
                 }
             }
         }
     }
     if (!$this->isFrozen) {
         $this->check($bean);
     }
     //what table does it want
     $table = $bean->getMeta("type");
     $idfield = $this->writer->getIDField($table);
     if ($bean->getMeta('tainted')) {
         //Does table exist? If not, create
         if (!$this->isFrozen && !$this->tableExists($table)) {
             $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) {
             if ($p != $idfield) {
                 if (!$this->isFrozen) {
                     //Does the user want to specify the type?
                     if ($bean->getMeta("cast.{$p}", -1) !== -1) {
                         $cast = $bean->getMeta("cast.{$p}");
                         if ($cast == "string") {
                             $typeno = $this->writer->scanType("STRING");
                         } elseif ($cast == "id") {
                             $typeno = $this->writer->getTypeForID();
                         } else {
                             throw new RedBean_Exception("Invalid Cast");
                         }
                     } else {
                         //What kind of property are we dealing with?
                         $typeno = $this->writer->scanType($v);
                     }
                     //Is this property represented in the table?
                     if (isset($columns[$p])) {
                         //yes it is, does it still fit?
                         $sqlt = $this->writer->code($columns[$p]);
                         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->{$idfield});
         $bean->{$idfield} = $rs;
         $bean->setMeta("tainted", false);
     }
     if ($processLists) {
         foreach ($embeddedBeans as $linkField => $embeddedBean) {
             if (!$this->isFrozen) {
                 $this->writer->addIndex($bean->getMeta('type'), 'index_foreignkey_' . $embeddedBean->getMeta('type'), $linkField);
                 $this->writer->addFK($bean->getMeta('type'), $embeddedBean->getMeta('type'), $linkField, $this->writer->getIDField($embeddedBean->getMeta('type')));
             }
         }
         $myFieldLink = $bean->getMeta('type') . '_id';
         //Handle related beans
         foreach ($ownTrashcan as $trash) {
             if ($trash instanceof RedBean_OODBBean) {
                 $trash->{$myFieldLink} = null;
                 $this->store($trash);
             } else {
                 throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
             }
         }
         foreach ($ownAdditions as $addition) {
             if ($addition instanceof RedBean_OODBBean) {
                 $addition->{$myFieldLink} = $bean->{$idfield};
                 $addition->setMeta('cast.' . $myFieldLink, 'id');
                 $this->store($addition);
                 if (!$this->isFrozen) {
                     $this->writer->addIndex($addition->getMeta('type'), 'index_foreignkey_' . $bean->getMeta('type'), $myFieldLink);
                     $this->writer->addFK($addition->getMeta('type'), $bean->getMeta('type'), $myFieldLink, $idfield);
                 }
             } else {
                 throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
             }
         }
         foreach ($ownresidue as $residue) {
             if ($residue instanceof RedBean_OODBBean) {
                 if ($residue->getMeta('tainted')) {
                     $this->store($residue);
                 }
             } else {
                 throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
             }
         }
         foreach ($sharedTrashcan as $trash) {
             if ($trash instanceof RedBean_OODBBean) {
                 $this->assocManager->unassociate($trash, $bean);
             } else {
                 throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
             }
         }
         foreach ($sharedAdditions as $addition) {
             if ($addition instanceof RedBean_OODBBean) {
                 $this->assocManager->associate($addition, $bean);
             } else {
                 throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
             }
         }
         foreach ($sharedresidue as $residue) {
             if ($residue instanceof RedBean_OODBBean) {
                 $this->store($residue);
             } else {
                 throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
             }
         }
     }
     $this->signal("after_update", $bean);
     return (int) $bean->{$idfield};
 }