Esempio n. 1
0
 /**
  * Processes all column based build commands.
  * A build command is an additional instruction for the Query Writer. It is processed only when
  * a column gets created. The build command is often used to instruct the writer to write some
  * extra SQL to create indexes or constraints. Build commands are stored in meta data of the bean.
  * They are only for internal use, try to refrain from using them in your code directly.
  *
  * @param  string           $table    name of the table to process build commands for
  * @param  string           $property name of the property to process build commands for
  * @param  RedBean_OODBBean $bean     bean that contains the build commands
  *
  * @return void
  */
 private function processBuildCommands($table, $property, RedBean_OODBBean $bean)
 {
     if ($inx = $bean->getMeta('buildcommand.indexes')) {
         if (isset($inx[$property])) {
             $this->writer->addIndex($table, $inx[$property], $property);
         }
     }
 }
Esempio n. 2
0
 /**
  * Part of the store() functionality.
  * Handles all new additions after the bean has been saved.
  * Stores addition bean in own-list, extracts the id and
  * adds a foreign key. Also adds a constraint in case the type is
  * in the dependent list.
  * 
  * @param RedBean_OODBBean $bean         bean
  * @param array            $ownAdditions list of addition beans in own-list 
  */
 private function processAdditions($bean, $ownAdditions)
 {
     $myFieldLink = $bean->getMeta('type') . '_id';
     foreach ($ownAdditions as $addition) {
         if ($addition instanceof RedBean_OODBBean) {
             $addition->{$myFieldLink} = $bean->id;
             $addition->setMeta('cast.' . $myFieldLink, 'id');
             $this->store($addition);
             if (!$this->isFrozen) {
                 $this->writer->addIndex($addition->getMeta('type'), 'index_foreignkey_' . $bean->getMeta('type'), $myFieldLink);
                 $isDep = $this->isDependentOn($addition->getMeta('type'), $bean->getMeta('type'));
                 $this->writer->addFK($addition->getMeta('type'), $bean->getMeta('type'), $myFieldLink, 'id', $isDep);
             }
         } else {
             throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
         }
     }
 }
Esempio n. 3
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};
 }