mirror of
https://gitlab.com/hashborgir/d2tools.git
synced 2025-10-13 16:34:23 -05:00
Begin Refactor
This commit is contained in:
323
vendor/gabordemooij/redbean/RedBeanPHP/Repository/Fluid.php
vendored
Normal file
323
vendor/gabordemooij/redbean/RedBeanPHP/Repository/Fluid.php
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
|
||||
namespace RedBeanPHP\Repository;
|
||||
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
use RedBeanPHP\QueryWriter as QueryWriter;
|
||||
use RedBeanPHP\RedException as RedException;
|
||||
use RedBeanPHP\BeanHelper as BeanHelper;
|
||||
use RedBeanPHP\RedException\SQL as SQLException;
|
||||
use RedBeanPHP\Repository as Repository;
|
||||
|
||||
/**
|
||||
* Fluid Repository.
|
||||
* OODB manages two repositories, a fluid one that
|
||||
* adjust the database schema on-the-fly to accomodate for
|
||||
* new bean types (tables) and new properties (columns) and
|
||||
* a frozen one for use in a production environment. OODB
|
||||
* allows you to swap the repository instances using the freeze()
|
||||
* method.
|
||||
*
|
||||
* @file RedBeanPHP/Repository/Fluid.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class Fluid extends Repository
|
||||
{
|
||||
/**
|
||||
* Figures out the desired type given the cast string ID.
|
||||
* Given a cast ID, this method will return the associated
|
||||
* type (INT(10) or VARCHAR for instance). The returned type
|
||||
* can be processed by the Query Writer to build the specified
|
||||
* column for you in the database. The Cast ID is actually just
|
||||
* a superset of the QueryWriter types. In addition to default
|
||||
* Query Writer column types you can pass the following 'cast types':
|
||||
* 'id' and 'string'. These will map to Query Writer specific
|
||||
* column types (probably INT and VARCHAR).
|
||||
*
|
||||
* @param string $cast cast identifier
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
private function getTypeFromCast( $cast )
|
||||
{
|
||||
if ( $cast == 'string' ) {
|
||||
$typeno = $this->writer->scanType( 'STRING' );
|
||||
} elseif ( $cast == 'id' ) {
|
||||
$typeno = $this->writer->getTypeForID();
|
||||
} elseif ( isset( $this->writer->sqltype_typeno[$cast] ) ) {
|
||||
$typeno = $this->writer->sqltype_typeno[$cast];
|
||||
} else {
|
||||
throw new RedException( 'Invalid Cast' );
|
||||
}
|
||||
|
||||
return $typeno;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orders the Query Writer to create a table if it does not exist already and
|
||||
* adds a note in the build report about the creation.
|
||||
*
|
||||
* @param OODBBean $bean bean to update report of
|
||||
* @param string $table table to check and create if not exists
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function createTableIfNotExists( OODBBean $bean, $table )
|
||||
{
|
||||
//Does table exist? If not, create
|
||||
if ( !$this->tableExists( $this->writer->esc( $table, TRUE ) ) ) {
|
||||
$this->writer->createTable( $table );
|
||||
$bean->setMeta( 'buildreport.flags.created', TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, &$columns = NULL )
|
||||
{
|
||||
$doFKStuff = FALSE;
|
||||
$table = $bean->getMeta( 'type' );
|
||||
if ($columns === NULL) {
|
||||
$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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Note that this method raises a custom exception if the bean
|
||||
* is not an instance of OODBBean. Therefore it does not use
|
||||
* a type hint. This allows the user to take action in case
|
||||
* invalid objects are passed in the list.
|
||||
*
|
||||
* @param OODBBean $bean bean to process
|
||||
* @param array $ownAdditions list of addition beans in own-list
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processAdditions( $bean, $ownAdditions )
|
||||
{
|
||||
$beanType = $bean->getMeta( 'type' );
|
||||
|
||||
foreach ( $ownAdditions as $addition ) {
|
||||
if ( $addition instanceof OODBBean ) {
|
||||
|
||||
$myFieldLink = $beanType . '_id';
|
||||
$alias = $bean->getMeta( 'sys.alias.' . $addition->getMeta( 'type' ) );
|
||||
if ( $alias ) $myFieldLink = $alias . '_id';
|
||||
|
||||
$addition->$myFieldLink = $bean->id;
|
||||
$addition->setMeta( 'cast.' . $myFieldLink, 'id' );
|
||||
|
||||
if ($alias) {
|
||||
$addition->setMeta( "sys.typeof.{$alias}", $beanType );
|
||||
} else {
|
||||
$addition->setMeta( "sys.typeof.{$beanType}", $beanType );
|
||||
}
|
||||
|
||||
$this->store( $addition );
|
||||
} else {
|
||||
throw new RedException( 'Array may only contain OODBBeans' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 OODBBean $bean the clean bean
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function storeBean( OODBBean $bean )
|
||||
{
|
||||
if ( $bean->getMeta( 'changed' ) ) {
|
||||
$this->check( $bean );
|
||||
$table = $bean->getMeta( 'type' );
|
||||
$this->createTableIfNotExists( $bean, $table );
|
||||
|
||||
$updateValues = array();
|
||||
|
||||
$partial = ( $this->partialBeans === TRUE || ( is_array( $this->partialBeans ) && in_array( $table, $this->partialBeans ) ) );
|
||||
if ( $partial ) {
|
||||
$mask = $bean->getMeta( 'changelist' );
|
||||
$bean->setMeta( 'changelist', array() );
|
||||
}
|
||||
|
||||
$columnCache = NULL;
|
||||
foreach ( $bean as $property => $value ) {
|
||||
if ( $partial && !in_array( $property, $mask ) ) continue;
|
||||
if ( $property !== 'id' ) {
|
||||
$this->modifySchema( $bean, $property, $value, $columnCache );
|
||||
}
|
||||
if ( $property !== 'id' ) {
|
||||
$updateValues[] = array( 'property' => $property, 'value' => $value );
|
||||
}
|
||||
}
|
||||
|
||||
$bean->id = $this->writer->updateRecord( $table, $updateValues, $bean->id );
|
||||
$bean->setMeta( 'changed', FALSE );
|
||||
}
|
||||
$bean->setMeta( 'tainted', FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception handler.
|
||||
* Fluid and Frozen mode have different ways of handling
|
||||
* exceptions. Fluid mode (using the fluid repository) ignores
|
||||
* exceptions caused by the following:
|
||||
*
|
||||
* - missing tables
|
||||
* - missing column
|
||||
*
|
||||
* In these situations, the repository will behave as if
|
||||
* no beans could be found. This is because in fluid mode
|
||||
* it might happen to query a table or column that has not been
|
||||
* created yet. In frozen mode, this is not supposed to happen
|
||||
* and the corresponding exceptions will be thrown.
|
||||
*
|
||||
* @param \Exception $exception exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function handleException( \Exception $exception )
|
||||
{
|
||||
if ( !$this->writer->sqlStateIn( $exception->getSQLState(),
|
||||
array(
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_TABLE,
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN ),
|
||||
$exception->getDriverDetails() )
|
||||
) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a bean from the object database.
|
||||
* It searches for a OODBBean Bean Object in the
|
||||
* database. It does not matter how this bean has been stored.
|
||||
* RedBean uses the primary key ID $id and the string $type
|
||||
* to find the bean. The $type specifies what kind of bean you
|
||||
* are looking for; this is the same type as used with the
|
||||
* dispense() function. If RedBean finds the bean it will return
|
||||
* the OODB Bean object; if it cannot find the bean
|
||||
* RedBean will return a new bean of type $type and with
|
||||
* primary key ID 0. In the latter case it acts basically the
|
||||
* same as dispense().
|
||||
*
|
||||
* Important note:
|
||||
* If the bean cannot be found in the database a new bean of
|
||||
* the specified type will be generated and returned.
|
||||
*
|
||||
* @param string $type type of bean you want to load
|
||||
* @param integer $id ID of the bean you want to load
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
public function load( $type, $id )
|
||||
{
|
||||
$rows = array();
|
||||
$bean = $this->dispense( $type );
|
||||
if ( isset( $this->stash[$this->nesting][$id] ) ) {
|
||||
$row = $this->stash[$this->nesting][$id];
|
||||
} else {
|
||||
try {
|
||||
$rows = $this->writer->queryRecord( $type, array( 'id' => array( $id ) ) );
|
||||
} catch ( SQLException $exception ) {
|
||||
if (
|
||||
$this->writer->sqlStateIn(
|
||||
$exception->getSQLState(),
|
||||
array(
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN,
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_TABLE
|
||||
),
|
||||
$exception->getDriverDetails()
|
||||
)
|
||||
) {
|
||||
$rows = array();
|
||||
} else {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
if ( !count( $rows ) ) {
|
||||
return $bean;
|
||||
}
|
||||
$row = array_pop( $rows );
|
||||
}
|
||||
$bean->importRow( $row );
|
||||
$this->nesting++;
|
||||
$this->oodb->signal( 'open', $bean );
|
||||
$this->nesting--;
|
||||
|
||||
return $bean->setMeta( 'tainted', FALSE );
|
||||
}
|
||||
}
|
176
vendor/gabordemooij/redbean/RedBeanPHP/Repository/Frozen.php
vendored
Normal file
176
vendor/gabordemooij/redbean/RedBeanPHP/Repository/Frozen.php
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace RedBeanPHP\Repository;
|
||||
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
use RedBeanPHP\QueryWriter as QueryWriter;
|
||||
use RedBeanPHP\RedException as RedException;
|
||||
use RedBeanPHP\BeanHelper as BeanHelper;
|
||||
use RedBeanPHP\RedException\SQL as SQLException;
|
||||
use RedBeanPHP\Repository as Repository;
|
||||
|
||||
/**
|
||||
* Frozen Repository.
|
||||
* OODB manages two repositories, a fluid one that
|
||||
* adjust the database schema on-the-fly to accomodate for
|
||||
* new bean types (tables) and new properties (columns) and
|
||||
* a frozen one for use in a production environment. OODB
|
||||
* allows you to swap the repository instances using the freeze()
|
||||
* method.
|
||||
*
|
||||
* @file RedBeanPHP/Repository/Frozen.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class Frozen extends Repository
|
||||
{
|
||||
/**
|
||||
* Exception handler.
|
||||
* Fluid and Frozen mode have different ways of handling
|
||||
* exceptions. Fluid mode (using the fluid repository) ignores
|
||||
* exceptions caused by the following:
|
||||
*
|
||||
* - missing tables
|
||||
* - missing column
|
||||
*
|
||||
* In these situations, the repository will behave as if
|
||||
* no beans could be found. This is because in fluid mode
|
||||
* it might happen to query a table or column that has not been
|
||||
* created yet. In frozen mode, this is not supposed to happen
|
||||
* and the corresponding exceptions will be thrown.
|
||||
*
|
||||
* @param \Exception $exception exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function handleException( \Exception $exception )
|
||||
{
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 OODBBean $bean the clean bean
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function storeBean( OODBBean $bean )
|
||||
{
|
||||
if ( $bean->getMeta( 'changed' ) ) {
|
||||
|
||||
list( $properties, $table ) = $bean->getPropertiesAndType();
|
||||
$id = $properties['id'];
|
||||
unset($properties['id']);
|
||||
$updateValues = array();
|
||||
$k1 = 'property';
|
||||
$k2 = 'value';
|
||||
|
||||
$partial = ( $this->partialBeans === TRUE || ( is_array( $this->partialBeans ) && in_array( $table, $this->partialBeans ) ) );
|
||||
if ( $partial ) {
|
||||
$mask = $bean->getMeta( 'changelist' );
|
||||
$bean->setMeta( 'changelist', array() );
|
||||
}
|
||||
|
||||
foreach( $properties as $key => $value ) {
|
||||
if ( $partial && !in_array( $key, $mask ) ) continue;
|
||||
$updateValues[] = array( $k1 => $key, $k2 => $value );
|
||||
}
|
||||
$bean->id = $this->writer->updateRecord( $table, $updateValues, $id );
|
||||
$bean->setMeta( 'changed', FALSE );
|
||||
}
|
||||
$bean->setMeta( 'tainted', FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Note that this method raises a custom exception if the bean
|
||||
* is not an instance of OODBBean. Therefore it does not use
|
||||
* a type hint. This allows the user to take action in case
|
||||
* invalid objects are passed in the list.
|
||||
*
|
||||
* @param OODBBean $bean bean to process
|
||||
* @param array $ownAdditions list of addition beans in own-list
|
||||
*
|
||||
* @return void
|
||||
* @throws RedException
|
||||
*/
|
||||
protected function processAdditions( $bean, $ownAdditions )
|
||||
{
|
||||
$beanType = $bean->getMeta( 'type' );
|
||||
|
||||
$cachedIndex = array();
|
||||
foreach ( $ownAdditions as $addition ) {
|
||||
if ( $addition instanceof OODBBean ) {
|
||||
|
||||
$myFieldLink = $beanType . '_id';
|
||||
$alias = $bean->getMeta( 'sys.alias.' . $addition->getMeta( 'type' ) );
|
||||
if ( $alias ) $myFieldLink = $alias . '_id';
|
||||
|
||||
$addition->$myFieldLink = $bean->id;
|
||||
$addition->setMeta( 'cast.' . $myFieldLink, 'id' );
|
||||
$this->store( $addition );
|
||||
|
||||
} else {
|
||||
throw new RedException( 'Array may only contain OODBBeans' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a bean from the object database.
|
||||
* It searches for a OODBBean Bean Object in the
|
||||
* database. It does not matter how this bean has been stored.
|
||||
* RedBean uses the primary key ID $id and the string $type
|
||||
* to find the bean. The $type specifies what kind of bean you
|
||||
* are looking for; this is the same type as used with the
|
||||
* dispense() function. If RedBean finds the bean it will return
|
||||
* the OODB Bean object; if it cannot find the bean
|
||||
* RedBean will return a new bean of type $type and with
|
||||
* primary key ID 0. In the latter case it acts basically the
|
||||
* same as dispense().
|
||||
*
|
||||
* Important note:
|
||||
* If the bean cannot be found in the database a new bean of
|
||||
* the specified type will be generated and returned.
|
||||
*
|
||||
* @param string $type type of bean you want to load
|
||||
* @param integer $id ID of the bean you want to load
|
||||
*
|
||||
* @return OODBBean
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function load( $type, $id )
|
||||
{
|
||||
$rows = array();
|
||||
$bean = $this->dispense( $type );
|
||||
if ( isset( $this->stash[$this->nesting][$id] ) ) {
|
||||
$row = $this->stash[$this->nesting][$id];
|
||||
} else {
|
||||
$rows = $this->writer->queryRecord( $type, array( 'id' => array( $id ) ) );
|
||||
if ( !count( $rows ) ) {
|
||||
return $bean;
|
||||
}
|
||||
$row = array_pop( $rows );
|
||||
}
|
||||
$bean->importRow( $row );
|
||||
$this->nesting++;
|
||||
$this->oodb->signal( 'open', $bean );
|
||||
$this->nesting--;
|
||||
|
||||
return $bean->setMeta( 'tainted', FALSE );
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user