/** * @wiki /MVC模式/数据库模型/数据表原型 * ==原型的创建== * * 原型的创建方式有两种. * 1.通过原型的静态方法create直接创建ProtoType对象,这种方法会通过对传入的参数(数据表名,字段名,)来构造一个ProtoType,这个ProtoTpe对象是有血有肉的。 * 2.通过new Prototype创建一个ProtoType对象,这种方法则不会对构造出的ProtoType对象,这个ProtoType对象没有制定哪个数据表,相对于create的创建方法,这个ProtoType对象,如同一个躯壳。 */ public static function create($sTableName, $keys = self::youKnow, $columns = self::youKnow, $aDB = self::youKnow) { $aPrototype = new Prototype(); $aPrototype->setTableName($sTableName); $aPrototype->setName($sTableName); $aPrototype->arrColumns = $columns; $aPrototype->arrKeys = self::youKnow; $aPrototype->aDB = $aDB === self::youKnow ? DB::singleton() : $aDB; return $aPrototype; }
public static function rightColumn(Prototype $aPrototype) { return $aPrototype->getColumnByAlias('rgt') ?: 'rgt'; }
private static function joinTables(array &$arrSelectState, Prototype $aForPrototype) { // add columns for pass in prototype $arrColumns = array_merge($aForPrototype->columns(), $aForPrototype->keys()); foreach ($arrColumns as $sColumnName) { $arrSelectState['statement']->addColumn($sColumnName, null, $aForPrototype->sqlTableAlias()); } // join tables $sFromTableAlias = $aForPrototype->sqlTableAlias(); foreach ($aForPrototype->associationIterator() as $aAssoc) { $aPrototype = $aAssoc->toPrototype(); $sTableAlias = $aPrototype->sqlTableAlias(); // 一对一关联 if ($aAssoc->isType(Association::oneToOne)) { $arrSelectState['statement']->joinTableRaw($sFromTableAlias, $aPrototype->tableName(), $sTableAlias, $aAssoc->joinType(), self::makeResrictionForForeignKey($sFromTableAlias, $sTableAlias, $aAssoc->fromKeys(), $aAssoc->toKeys(), $aAssoc->joinOnRawSql())); // 递归 join self::joinTables($arrSelectState, $aPrototype); } else { $arrSelectState['multitermAssocs'][] = $aAssoc; // 三表关联 if ($aAssoc->isType(Association::triplet)) { $sBridgeTableAlias = $aAssoc->bridgeSqlTableAlias(); $sBridgeTable = $aAssoc->bridgeTableName(); // 从中间表连接到右表 $aPrototype->sharedStatementSelect()->joinTableRaw($sTableAlias, $sBridgeTable, $sBridgeTableAlias, $aAssoc->joinType(), self::makeResrictionForForeignKey($sTableAlias, $sBridgeTableAlias, $aAssoc->toKeys(), $aAssoc->fromBridgeKeys(), $aAssoc->joinOnRawSql())); } } } }
public static function buildRestriction(Prototype $aPrototype, $values = null, $keys = null) { if ($values === null) { return null; } $keys = $keys ? (array) $keys : $aPrototype->keys(); if ($values instanceof Restriction) { return $values; } else { $aRestriction = new Restriction(); $sSqlTableAlias = $aPrototype->sqlTableAlias(); $values = array_values((array) $values); foreach ($keys as $nIdx => $sKey) { list($sTable, $sColumn) = SQL::splitColumn($sKey); $aRestriction->expression(array(SQL::createRawColumn($sTable, $sColumn), '=', SQL::transValue($values[$nIdx])), true, true); } return $aRestriction; } }