Example #1
0
 /**
  *
  * @param RedBean_OODBBean $parent
  * @return array $childObjects
  */
 public function children(RedBean_OODBBean $parent)
 {
     $idfield = $this->writer->getIDField($parent->getMeta("type"));
     try {
         $ids = $this->adapter->getCol("SELECT `" . $idfield . "` FROM\n\t\t\t`" . $parent->getMeta("type") . "`\n\t\t\tWHERE `" . $this->property . "` = " . intval($parent->{$idfield}) . "\n\t\t");
     } catch (RedBean_Exception_SQL $e) {
         return array();
     }
     return $this->oodb->batch($parent->getMeta("type"), $ids);
 }
Example #2
0
 /**
  * Returns all the nodes that have been attached to the specified
  * parent node.
  * @param RedBean_OODBBean $parent
  * @return array $childObjects
  */
 public function children(RedBean_OODBBean $parent)
 {
     $idfield = $this->writer->getIDField($parent->getMeta("type"));
     try {
         $ids = $this->writer->selectByCrit($idfield, $parent->getMeta("type"), $this->property, intval($parent->{$idfield}));
     } catch (RedBean_Exception_SQL $e) {
         return array();
     }
     return $this->oodb->batch($parent->getMeta("type"), $ids);
 }
Example #3
0
 /**
  * Given two beans this function returns TRUE if they are associated using a
  * many-to-many association, FALSE otherwise.
  *
  * @throws RedBean_Exception_SQL
  *
  * @param RedBean_OODBBean $bean1 bean
  * @param RedBean_OODBBean $bean2 bean
  *
  * @return bool $related whether they are associated N-M
  */
 public function areRelated(RedBean_OODBBean $bean1, RedBean_OODBBean $bean2)
 {
     if (!$bean1->getID() || !$bean2->getID()) {
         return false;
     }
     $table = $this->getTable(array($bean1->getMeta("type"), $bean2->getMeta("type")));
     $idfield1 = $this->writer->getIDField($bean1->getMeta("type"));
     $idfield2 = $this->writer->getIDField($bean2->getMeta("type"));
     $type = $bean1->getMeta("type");
     if ($type == $bean2->getMeta("type")) {
         $type .= "2";
         $cross = 1;
     } else {
         $cross = 0;
     }
     $property1 = $type . "_id";
     $property2 = $bean2->getMeta("type") . "_id";
     $value1 = (int) $bean1->{$idfield1};
     $value2 = (int) $bean2->{$idfield2};
     try {
         $rows = $this->writer->selectRecord($table, array($property1 => array($value1), $property2 => array($value2)), null);
         if ($cross) {
             $rows2 = $this->writer->selectRecord($table, array($property2 => array($value1), $property1 => array($value2)), null);
             $rows = array_merge($rows, $rows2);
         }
     } catch (RedBean_Exception_SQL $e) {
         if (!$this->writer->sqlStateIn($e->getSQLState(), array(RedBean_QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN, RedBean_QueryWriter::C_SQLSTATE_NO_SUCH_TABLE))) {
             throw $e;
         }
         return false;
     }
     return count($rows) > 0;
 }
 /**
  *
  * @param RedBean_OODBBean $parent
  * @return array $childObjects
  */
 public function children(RedBean_OODBBean $parent)
 {
     $idfield = $this->writer->getIDField($parent->getMeta("type"));
     try {
         /*
         $ids = $this->adapter->getCol("SELECT `".$idfield."` FROM
         	`".$parent->getMeta("type")."`
         	WHERE `".$this->property."` = ".intval( $parent->$idfield )."
         ");
         */
         /*
         		$ids = $this->adapter->getCol($this->writer->buildSimpleQuery(
         			"select",array($idfield),$parent->getMeta("type"),
         			array("name"=>$this->property,
         				  "value"=>intval($parent->$idfield),
         				  "operator"=>"=","structure"=>"")
         		));
         */
         $ids = $this->writer->selectByCrit($idfield, $parent->getMeta("type"), $this->property, intval($parent->{$idfield}));
     } catch (RedBean_Exception_SQL $e) {
         return array();
     }
     return $this->oodb->batch($parent->getMeta("type"), $ids);
 }
 /**
  * Returns all the beans associated with $bean.
  * This method will return an array containing all the beans that have
  * been associated once with the associate() function and are still
  * associated with the bean specified. The type parameter indicates the
  * type of beans you are looking for. You can also pass some extra SQL and
  * values for that SQL to filter your results after fetching the
  * related beans.
  *
  * Don't try to make use of subqueries, a subquery using IN() seems to
  * be slower than two queries!
  *
  * Since 3.2, you can now also pass an array of beans instead just one
  * bean as the first parameter.
  *
  * @param RedBean_OODBBean|array $bean      the bean you have
  * @param string                 $type      the type of beans you want
  * @param string                 $sql       SQL snippet for extra filtering
  * @param array                  $bindings  values to be inserted in SQL slots
  * @param boolean                $glue      whether the SQL should be prefixed with WHERE
  *
  * @return array
  */
 public function relatedSimple($bean, $type, $sql = '', $bindings = array())
 {
     $sql = $this->writer->glueSQLCondition($sql);
     $rows = $this->relatedRows($bean, $type, FALSE, $sql, $bindings);
     $links = array();
     foreach ($rows as $key => $row) {
         if (!isset($links[$row['id']])) {
             $links[$row['id']] = array();
         }
         $links[$row['id']][] = $row['linked_by'];
         unset($rows[$key]['linked_by']);
     }
     $beans = $this->oodb->convertToBeans($type, $rows);
     foreach ($beans as $bean) {
         $bean->setMeta('sys.belongs-to', $links[$bean->id]);
     }
     return $beans;
 }
Example #6
0
 /**
  * Loads a batch of beans all at once.
  * This function first inspects the cache; if every element in the batch
  * is available in the cache, the function will return the collected beans
  * from the cache. If one or more beans cannot be found, the function will
  * ask oodb for the beans and update the cache.	
  * @param string $type
  * @param integer $ids
  * @return array $beans 
  */
 public function batch($type, $ids)
 {
     $idfield = $this->writer->getIDField($type);
     $collect = array();
     foreach ($ids as $id) {
         $bean = $this->fetchFromCacheByTypeID($type, $id);
         if ($bean) {
             $collect[$id] = $bean;
         }
     }
     if (count($collect) == count($ids)) {
         return $collect;
     } else {
         $beans = $this->oodb->batch($type, $ids);
         foreach ($beans as $bean) {
             $this->putInCache($bean);
         }
         return $beans;
     }
 }
Example #7
0
 /**
  * Performs the actual optimization. In this case the optimizer looks
  * at the size of the column and the size of the value. If the value size is
  * smaller than the column size it tries to convert the column to a smaller
  * size. Next, it counts if there is any different between the smaller column
  * and the original column. If no differences are found the original column
  * gets replaced.
  * Like the other optimizers, this optimizer returns TRUE if it thinks
  * further optimizations can happen, FALSE otherwise.
  *
  * @return boolean $yesNo advance to next optimizer
  */
 public function optimize()
 {
     //get the type of the current value
     $type = $this->writer->scanType($this->value);
     //get all the fields in the table
     $fields = $this->writer->getColumns($this->table);
     //If the column for some reason does not occur in fields, return
     if (!in_array($this->column, array_keys($fields))) {
         return false;
     }
     //get the type we got in the field of the table
     $typeInField = $this->writer->code($fields[$this->column]);
     //Is the type too wide?
     if ($type < $typeInField) {
         try {
             @$this->adapter->exec("alter table " . $this->writer->safeTable($this->table) . " drop __test");
         } catch (Exception $e) {
         }
         //Try to re-fit the entire column; by testing it.
         $type = $this->writer->typeno_sqltype[$type];
         //Add a test column.
         @$this->adapter->exec("alter table " . $this->writer->safeTable($this->table) . " add __test " . $type);
         //Copy the values and see if there are differences.
         @$this->adapter->exec("update " . $this->writer->safeTable($this->table) . " set __test=" . $this->writer->safeColumn($this->column) . "");
         $rows = $this->adapter->get("select " . $this->writer->safeColumn($this->column) . " as a, __test as b from " . $this->writer->safeTable($this->table));
         $diff = 0;
         foreach ($rows as $row) {
             $diff += $row["a"] != $row["b"];
         }
         if (!$diff) {
             //No differences; shrink column.
             @$this->adapter->exec("alter table " . $this->writer->safeTable($this->table) . " change " . $this->writer->safeColumn($this->column) . " " . $this->writer->safeColumn($this->column) . " " . $type);
         }
         //Throw away test column; we don't need it anymore!
         @$this->adapter->exec("alter table " . $this->writer->safeTable($this->table) . " drop __test");
     }
     return false;
 }
 /**
  * Removes all relations for a bean
  * @param RedBean_OODBBean $bean
  * @param string $type
  */
 public function clearRelations(RedBean_OODBBean $bean, $type)
 {
     $this->oodb->store($bean);
     $table = $this->getTable(array($bean->getMeta("type"), $type));
     $idfield = $this->writer->getIDField($bean->getMeta("type"));
     if ($type == $bean->getMeta("type")) {
         $property2 = $type . "2_id";
         $cross = 1;
     } else {
         $cross = 0;
     }
     $property = $bean->getMeta("type") . "_id";
     try {
         $this->writer->deleteByCrit($table, array($property => $bean->{$idfield}));
         if ($cross) {
             $this->writer->deleteByCrit($table, array($property2 => $bean->{$idfield}));
         }
     } catch (RedBean_Exception_SQL $e) {
         if ($e->getSQLState() != "42S02" && $e->getSQLState() != "42S22") {
             throw $e;
         }
     }
 }
Example #9
0
 /**
  * Performs the actual optimization. In this case the optimizer first
  * scans the value. If the value if of type 'datetime' and the column
  * is not it tries to make the column datetime. If the column is 'datetime'
  * and the value 'datetime' it blocks further optimization. If the value
  * is NOT 'datetime' then it immediately returns true, thus allowing further
  * optimization.
  *
  * @return boolean $yesNo advance to next optimizer
  */
 public function optimize()
 {
     if (!$this->matchesDateTime($this->value)) {
         return true;
     }
     //get the type of the current value
     $type = $this->writer->scanType($this->value);
     //get all the fields in the table
     $fields = $this->writer->getColumns($this->table);
     //If the column for some reason does not occur in fields, return
     //print_r($fields);
     if (!in_array($this->column, array_keys($fields))) {
         return false;
     }
     //get the type we got in the field of the table
     $typeInField = $this->writer->code($fields[$this->column]);
     //Is column already datetime?
     if ($typeInField != "datetime") {
         if ($this->matchesDateTime($this->value)) {
             //Ok, value is datetime, can we convert the column to support this?
             $cnt = (int) $this->adapter->getCell("select count(*) as n from " . $this->writer->safeTable($this->table) . " where\n\t\t\t\t\t\t  {$this->column} regexp '[0-9]{4}-[0-1][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]'\n\t\t\t\t\t\t  OR {$this->column} IS NULL");
             $total = (int) $this->adapter->getCell("SELECT count(*) FROM " . $this->writer->safeTable($this->table));
             //Is it safe to convert: ie are all values compatible?
             if ($total === $cnt) {
                 //yes
                 $this->adapter->exec("ALTER TABLE " . $this->writer->safeTable($this->table) . " change " . $this->writer->safeColumn($this->column) . " " . $this->writer->safeColumn($this->column) . " datetime ");
             }
             //No further optimization required.
             return false;
         }
         //Further optimization could be useful.
         return true;
     } else {
         //yes column is datetime, if value is stop further optimizing
         return false;
     }
 }
Example #10
0
 /**
  * Removes all relations for a bean
  * @param RedBean_OODBBean $bean
  * @param <type> $type
  */
 public function clearRelations(RedBean_OODBBean $bean, $type)
 {
     $this->oodb->store($bean);
     $table = $this->getTable(array($bean->getMeta("type"), $type));
     $idfield = $this->writer->getIDField($bean->getMeta("type"));
     if ($type == $bean->getMeta("type")) {
         $property2 = $type . "2_id";
         $cross = 1;
     } else {
         $cross = 0;
     }
     $property = $bean->getMeta("type") . "_id";
     $sql = "DELETE FROM `{$table}`\n\t\tWHERE " . $this->adapter->escape($property) . " = " . $this->adapter->escape($bean->{$idfield});
     if ($cross) {
         $sql .= " OR  " . $this->adapter->escape($property2) . " = " . $this->adapter->escape($bean->{$idfield});
     }
     try {
         $this->adapter->exec($sql);
     } catch (RedBean_Exception_SQL $e) {
         if ($e->getSQLState() != "42S02" && $e->getSQLState() != "42S22") {
             throw $e;
         }
     }
 }
Example #11
0
 /**
  * Nukes the entire database.
  */
 public static function nuke()
 {
     if (!self::$redbean->isFrozen()) {
         self::$writer->wipeAll();
     }
 }
 /**
  * Nukes the entire database.
  * This will remove all schema structures from the database.
  * Only works in fluid mode. Be careful with this method.
  *
  * @warning dangerous method, will remove all tables, columns etc.
  *
  * @return void
  */
 public function nuke()
 {
     if (!$this->redbean->isFrozen()) {
         $this->writer->wipeAll();
     }
 }
Example #13
0
 /**
  * Executes SQL function but corrects for SQL states.
  * @param closure $func
  * @param mixed $default
  * @param string $sql
  * @param array $values
  * @return mixed $results
  */
 private static function secureExec($func, $sql, $values, $default = NULL)
 {
     if (!self::$redbean->isFrozen()) {
         try {
             $rs = R::$adapter->{$func}($sql, $values);
         } catch (RedBean_Exception_SQL $e) {
             //die($e);
             if (self::$writer->sqlStateIn($e->getSQLState(), array(RedBean_QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN, RedBean_QueryWriter::C_SQLSTATE_NO_SUCH_TABLE))) {
                 return $default;
             } else {
                 throw $e;
             }
         }
         return $rs;
     } else {
         return R::$adapter->{$func}($sql, $values);
     }
 }
 /**
  * Set prefix in query writer
  *
  * @param string $prefix
  */
 public function prefix($prefix)
 {
     $this->writer->setPrefix($prefix);
 }
Example #15
0
 /**
  * Creates a view with name $viewID based on $refType bean type
  * and then left-joining the specified types in $types in the given
  * order.
  *
  * @param  string $viewID  desired name of the view
  * @param  string $refType first bean type to be used as base
  * @param  array  $types   array with types to be left-joined in view
  *
  * @return boolean $success whether we created a new view (false if already exists)
  */
 public function createView($viewID, $refType, $types)
 {
     if ($this->oodb->isFrozen()) {
         return false;
     }
     $history = array();
     $tables = array_flip($this->writer->getTables());
     $refTable = $refType;
     //$this->writer->safeTable($refType, true);
     $currentTable = $refTable;
     $history[$refType] = $refType;
     foreach ($types as $t) {
         if (!isset($history[$t])) {
             $history[$t] = $t;
             $connection = array($t, $currentTable);
             sort($connection);
             $connection = implode("_", $connection);
             $connectionTable = $this->writer->safeTable($connection, true);
             if (isset($tables[$connectionTable])) {
                 //this connection exists
                 $srcPoint = $this->writer->safeTable($connection) . "." . $this->writer->safeColumn($currentTable . "_id");
                 //i.e. partic_project.project_id
                 $dstPoint = $this->writer->safeTable($currentTable) . "." . $this->writer->safeColumn($this->writer->getIDField($currentTable));
                 //i.e. project.id
                 $joins[$connection] = array($srcPoint, $dstPoint);
                 //now join the type
                 $srcPoint = $this->writer->safeTable($connection) . "." . $this->writer->safeColumn($t . "_id");
                 $dstPoint = $this->writer->safeTable($t) . "." . $this->writer->safeColumn($this->writer->getIDField($t));
                 $joins[$t] = array($srcPoint, $dstPoint);
             } else {
                 //this connection does not exist
                 $srcPoint = $this->writer->safeTable($t) . "." . $this->writer->safeColumn($currentTable . "_id");
                 $dstPoint = $this->writer->safeTable($currentTable) . "." . $this->writer->safeColumn($this->writer->getIDField($currentTable));
                 $joins[$t] = array($srcPoint, $dstPoint);
             }
         }
         //now set the new refTable
         $currentTable = $t;
     }
     try {
         $rs = (bool) $this->writer->createView($refType, $joins, $viewID);
     } catch (Exception $e) {
         throw new RedBean_Exception_SQL('Could not create view, types does not seem related (yet)..');
     }
     return $rs;
 }