Example #1
0
 protected function makeResrictionForAsscotion(array &$arrDataRow, $sFromTableName = null, array $arrFromKeys, $sToTableName = null, array $arrToKeys)
 {
     $aRestriction = new Restriction();
     foreach ($arrFromKeys as $nIdx => $sFromKey) {
         if ($sFromTableName) {
             $sFromKey = $sFromTableName . '.' . $sFromKey;
         }
         $aRestriction->expression(array(SQL::createRawColumn($sToTableName, $arrToKeys[$nIdx]), '=', SQL::transValue($arrDataRow[$sFromKey])), true, true);
     }
     return $aRestriction;
 }
Example #2
0
 public function setData($sColumnName, $value = null, $bValueExpr = false)
 {
     list($sTableName, $sColumnName) = SQL::splitColumn($sColumnName);
     $arrRawSet =& $this->rawClause(SQL::CLAUSE_SET);
     if (!isset($arrRawSet['subtree'][$sColumnName]) and !empty($arrRawSet['subtree'])) {
         $arrRawSet['subtree'][] = ',';
     }
     $arrRawSet['subtree'][$sColumnName] = array('expr_type' => 'assignment', 'pretree' => array(SQL::createRawColumn($sTableName, $sColumnName), '='));
     if ($bValueExpr) {
         $arrRawSet['subtree'][$sColumnName]['subtree'] =& SQL::parseSql($value, 'values', true);
     } else {
         $arrRawSet['subtree'][$sColumnName]['subtree'] = array(SQL::transValue($value));
     }
 }
Example #3
0
 public function execute(DB $aDB, Model $aModel)
 {
     $aPrototype = $aModel->prototype();
     $aDelete = new Delete($aPrototype->tableName());
     // 设置limit
     $aDelete->criteria()->setLimit(1);
     // delete 当前model
     foreach ($aPrototype->keys() as $sClmName) {
         if ($aModel->changed($sClmName)) {
             //主键发生修改
             throw new ORMException('org\\jecat\\framework\\mvc\\model\\db\\orm\\Updater : Key 有修改,无法进行Delete操作');
         } else {
             //用主键作为查询条件
             $aDelete->criteria()->where()->expression(array(SQL::createRawColumn(null, $sClmName), '=', SQL::transValue($aModel->data($sClmName))), true, true);
         }
     }
     $aDB->execute($aDelete);
     // 仅delete hasAndBelongsTo的桥表
     foreach ($aPrototype->associations() as $aAssociation) {
         $aAssociatedModel = $aModel->child($aAssociation->name());
         if (!$aAssociatedModel) {
             continue;
         }
         switch ($aAssociation->type()) {
             case Association::hasOne:
                 $this->setAssociatedModelData($aModel, $aAssociatedModel, $aAssociation->fromKeys(), $aAssociation->toKeys());
                 if (!$aAssociatedModel->delete()) {
                     return false;
                 }
                 break;
             case Association::belongsTo:
                 // nothing todo ...
                 break;
             case Association::hasMany:
                 $this->setAssociatedModelData($aModel, $aAssociatedModel, $aAssociation->fromKeys(), $aAssociation->toKeys());
                 if (!$aAssociatedModel->delete()) {
                     return false;
                 }
                 break;
             case Association::hasAndBelongsToMany:
                 // delete bridge table
                 foreach ($aAssociatedModel->childIterator() as $aOneChildModel) {
                     $this->deleteBridge($aDB, $aAssociation, $aModel, $aOneChildModel);
                 }
                 break;
         }
     }
     return true;
 }
Example #4
0
 /**
  *
  * @return string
  */
 public function toString(SqlCompiler $aSqlCompiler = null)
 {
     ksort($this->arrRawSql['subtree'][SQL::CLAUSE_INSERT]['subtree']);
     return parent::toString($aSqlCompiler);
 }
Example #5
0
 /**
  * 以sql表达式的形式,向select对像添加一个或多个返回字段。
  */
 public function addColumnsExpr($sExpression)
 {
     $arrSubTree =& SQL::parseSql($sExpression, 'select', true);
     if (!empty($arrSubTree)) {
         $arrRawColumns =& $this->rawClause(self::CLAUSE_SELECT);
         if ($arrRawColumns['subtree']) {
             $arrRawColumns['subtree'][] = ',';
         }
         $arrRawColumns['subtree'] = array_merge($arrRawColumns['subtree'], $arrSubTree);
     }
     return $this;
 }
Example #6
0
 /**
  * @return Select
  */
 public static function make($sSql, $factors = null)
 {
     $factors = func_get_args();
     $sSql = array_shift($factors);
     if (!($arrRawSqls = self::parseSql($sSql)) or empty($arrRawSqls[0])) {
         return;
     }
     if (isset($arrRawSqls[0]['command'])) {
         switch ($arrRawSqls[0]['command']) {
             case 'SELECT':
                 $aSql = new Select();
             case 'INSERT':
                 $aSql = new Insert();
             case 'UPDATE':
                 $aSql = new Update();
             case 'DELETE':
                 $aSql = new Delete();
                 break;
             default:
                 $aSql = new SQL();
                 break;
         }
     } else {
         $aSql = new SQL();
     }
     $aSql->setRawSql($arrRawSqls[0]);
     if ($factors) {
         $aSql->addFactors($factors);
     }
     return $aSql;
 }
Example #7
0
 /**
  * @wiki /MVC模式/数据库模型/数据表关联
  * ==Bean配置数组==
  * type string 指定关系类型
  * fromkeys array 起始表列名
  * tokeys array 目标表列名
  * frombridgekeys array 起始桥接表列名
  * tobridgekeys array 起始桥接表列名
  * bridge string 桥接表名
  * fromPrototype string 指定起源原型配置
  * on string 
  */
 public function buildBean(array &$arrConfig, $sNamespace = '*', \org\jecat\framework\bean\BeanFactory $aBeanFactory = null)
 {
     if (!$this->aDB) {
         $this->aDB = DB::singleton();
     }
     $arrConfigForToPrototype = $arrConfig;
     $arrConfigForToPrototype['class'] = 'prototype';
     $this->aToPrototype = BeanFactory::singleton()->createBean($arrConfigForToPrototype, $sNamespace);
     $this->aToPrototype->setassociatedBy($this);
     if (!empty($arrConfig['type'])) {
         $this->nType = $arrConfig['type'];
     }
     if (!empty($arrConfig['fromkeys'])) {
         $this->setFromKeys($arrConfig['fromkeys']);
     }
     if (!empty($arrConfig['tokeys'])) {
         $this->setToKeys($arrConfig['tokeys']);
     }
     if (!empty($arrConfig['tobridgekeys'])) {
         $this->setToBridgeKeys($arrConfig['tobridgekeys']);
     }
     if (!empty($arrConfig['frombridgekeys'])) {
         $this->setFromBridgeKeys($arrConfig['frombridgekeys']);
     }
     if (!empty($arrConfig['bridge'])) {
         $this->sBridgeTable = $arrConfig['bridge'];
     }
     if (!empty($arrConfig['fromPrototype'])) {
         $this->aFromPrototype = $arrConfig['fromPrototype'];
     }
     if (!empty($arrConfig['on'])) {
         if (is_array($arrConfig['on'])) {
             $arrOnFactors = $arrConfig['on'];
             $this->arrOnRawSql['expr_type'] = 'clause_on';
             $this->arrOnRawSql['subtree'] =& SQL::parseSql(array_shift($arrOnFactors), 'on', true);
             $aOnClause = new SQL($this->arrOnRawSql);
             $aOnClause->addFactors($arrOnFactors);
         } else {
             $this->arrOnRawSql['expr_type'] = 'clause_on';
             $this->arrOnRawSql['subtree'] =& SQL::parseSql($arrConfig['on'], 'on', true);
         }
     }
     if (!empty($arrConfig['join'])) {
         $this->sJoinType = strtoupper($arrConfig['join']);
     }
     $this->done();
     $this->arrBeanConfig = $arrConfig;
 }
Example #8
0
 private static function &makeResrictionForForeignKey($sFromTableName = null, $sToTableName = null, array &$arrFromKeys, array &$arrToKeys, array &$arrConditions = null)
 {
     $arrTokens = array('ON', '(');
     foreach ($arrFromKeys as $nIdx => $sFromKey) {
         if ($nIdx) {
             $arrTokens[] = 'AND';
         }
         $arrTokens[] = SQL::createRawColumn($sFromTableName, $sFromKey);
         $arrTokens[] = '=';
         $arrTokens[] = SQL::createRawColumn($sToTableName, $arrToKeys[$nIdx]);
     }
     if ($arrConditions) {
         $arrTokens[] = 'AND';
         $arrTokens[] = $arrConditions;
     }
     $arrTokens[] = ')';
     return $arrTokens;
 }
Example #9
0
 /**
  * @wiki /MVC模式/数据库模型/模型的基本操作(新建、保存、删除、加载)
  * ==模型的创建==
  * 模型的创建有两中方式,基于bean的创建以及基于原型(ProtoType)的直接创建,两中方式的创建原理其实都是基于原型的创建.
  * 
  * 
  * =Bean配置数组=
  * {|
  * !属性
  * !类型
  * !默认值
  * !可选
  * !说明
  * |-- --
  * |model-class
  * |string
  * |无
  * |可选
  * |用哪个类来实现模型对象
  * |-- --
  * |table
  * |string
  * |无
  * |可选
  * |对应的数据库表
  * |-- --
  * |name
  * |string
  * |无
  * |可选
  * |在原型关系中的名字,用来区分不同的原型
  * |-- --
  * |columns
  * |array
  * |无
  * |可选
  * |需要表中哪些列的数据
  * |-- --
  * |keys
  * |array
  * |无
  * |可选
  * |指定表中哪些列为主键,若指定了主键则使用这里的主键而忽略数据库主键,如果未指定则使用数据库指定的主键
  * |-- --
  * |alias
  * |string
  * |无
  * |可选
  * |别名
  * |-- --
  * |limit
  * |int
  * |无
  * |可选
  * |设置读取条目数目的上限,下限为0
  * |-- --
  * |limitLen
  * |int
  * |无
  * |可选
  * |设置读取条目数目的上限
  * |-- --
  * |limitFrom
  * |int
  * |无
  * |可选
  * |设置读取条目数目的下限
  * |-- --
  * |order
  * |array
  * |无
  * |可选
  * |指定依据某一列来排序,同时设置正序排列
  * |-- --
  * |orderAsc
  * |string
  * |无
  * |可选
  * |指定依据某一列正序排序
  * |-- --
  * |orderDesc
  * |string
  * |无
  * |可选
  * |指定依据某一列反序排序
  * |-- --
  * |orderRand
  * |bool
  * |无
  * |可选
  * |随机排列结果
  * |-- --
  * |where
  * |array
  * |无
  * |可选
  * |where条件(where的格式很有趣,是对Lisp风格的尝试)
  * |-- --
  * |hasOne
  * |array
  * |无
  * |可选
  * |配置hasone关系
  * |-- --
  * |belongsTo
  * |array
  * |无
  * |可选
  * |配置belongsTo关系
  * |-- --
  * |hasMany
  * |array
  * |无
  * |可选
  * |配置hasMany关系
  * |-- --
  * |hasAndBelongsToMany
  * |array
  * |无
  * |可选
  * |配置hasAndBelongsToMany关系
  * |}
  * [example title="/MVC模式/数据库模型/模型的基本操作(新建、保存、删除、加载)/新建(Bean)"]
  */
 public function buildBean(array &$arrConfig, $sNamespace = '*', \org\jecat\framework\bean\BeanFactory $aBeanFactory = null)
 {
     if (!empty($arrConfig['model-class'])) {
         $this->sModelClass = $arrConfig['model-class'];
     }
     // table
     if (!empty($arrConfig['table'])) {
         $this->setTableName($arrConfig['table']);
     } else {
         if (!empty($arrConfig['name'])) {
             $this->setTableName($arrConfig['name']);
         }
     }
     if (!empty($arrConfig['forceIndex'])) {
         $this->sForceIndex = $arrConfig['forceIndex'];
     }
     // name
     if (!empty($arrConfig['name'])) {
         $this->setName($arrConfig['name']);
     } else {
         if (!empty($arrConfig['table'])) {
             $this->setName($arrConfig['table']);
         }
     }
     // columns
     if (key_exists('columns', $arrConfig)) {
         call_user_func(array($this, 'addColumns'), $arrConfig['columns']);
     }
     // keys
     if (!empty($arrConfig['keys'])) {
         $this->setKeys($arrConfig['keys']);
     }
     // alias
     if (!empty($arrConfig['alias'])) {
         $this->addColumnAlias($arrConfig['alias']);
     }
     // limit ----------------
     if (!empty($arrConfig['limit'])) {
         $this->nLimitLen = $arrConfig['limit'];
     }
     // limitLen
     if (!empty($arrConfig['limitLen'])) {
         $this->nLimitLen = $arrConfig['limitLen'];
     }
     // limitFrom
     if (!empty($arrConfig['limitFrom'])) {
         $this->limitFrom = $arrConfig['limitFrom'];
     }
     if ($this->nLimitLen === -1) {
         $this->criteria()->clearLimit();
     } else {
         $this->criteria()->setLimit($this->nLimitLen, $this->limitFrom);
     }
     // order ----------------
     if (!empty($arrConfig['order'])) {
         foreach ((array) $arrConfig['order'] as $sColumn) {
             list($sTable, $sColumn) = SQL::splitColumn($sColumn);
             $this->criteria()->addOrderBy($sColumn, true, $sTable);
         }
     }
     // orderDesc
     if (!empty($arrConfig['orderDesc'])) {
         foreach ((array) $arrConfig['orderDesc'] as $sColumn) {
             list($sTable, $sColumn) = SQL::splitColumn($sColumn);
             $this->criteria()->addOrderBy($sColumn, true, $sTable);
         }
     }
     // orderAsc
     if (!empty($arrConfig['orderAsc'])) {
         foreach ((array) $arrConfig['orderAsc'] as $sColumn) {
             list($sTable, $sColumn) = SQL::splitColumn($sColumn);
             $this->criteria()->addOrderBy($sColumn, false, $sTable);
         }
     }
     // orderRand
     if (!empty($arrConfig['orderRand']) && ($arrConfig['orderRand'] = true)) {
         $this->criteria()->orders()->add(null, Order::rand);
     }
     // groupby
     if (!empty($arrConfig['groupby'])) {
         foreach ((array) $arrConfig['groupby'] as $sColumn) {
             $this->criteria()->addGroupBy($sColumn);
         }
     }
     // where
     if (!empty($arrConfig['where'])) {
         $arrRawWhere =& $this->criteria()->rawClause(SQL::CLAUSE_WHERE);
         if (is_array($arrConfig['where'])) {
             $arrOnFactors = $arrConfig['where'];
             $arrRawWhere['subtree'] =& SQL::parseSql(array_shift($arrOnFactors), 'where', true);
             if ($arrOnFactors) {
                 $this->criteria()->where()->addFactors($arrOnFactors);
             }
         } else {
             $arrRawWhere['subtree'] =& SQL::parseSql($arrConfig['where'], 'where', true);
         }
         // self::buildBeanRestriction($arrConfig['where'],$this->criteria()->where()->createRestriction()) ;
     }
     // associations
     $aBeanFactory = BeanFactory::singleton();
     foreach ($arrConfig as $sConfigKey => &$item) {
         if (strpos($sConfigKey, 'hasOne:') === 0) {
             $item['type'] = Association::hasOne;
             $item['name'] = substr($sConfigKey, 7);
         } else {
             if (strpos($sConfigKey, 'belongsTo:') === 0) {
                 $item['type'] = Association::belongsTo;
                 $item['name'] = substr($sConfigKey, 10);
             } else {
                 if (strpos($sConfigKey, 'hasMany:') === 0) {
                     $item['type'] = Association::hasMany;
                     $item['name'] = substr($sConfigKey, 8);
                 } else {
                     if (strpos($sConfigKey, 'hasAndBelongsToMany:') === 0) {
                         $item['type'] = Association::hasAndBelongsToMany;
                         $item['name'] = substr($sConfigKey, 20);
                     } else {
                         continue;
                     }
                 }
             }
         }
         if (empty($item['class'])) {
             $item['class'] = 'association';
         }
         $item['fromPrototype'] = $this;
         $aAssociation = $aBeanFactory->createBean($item, $sNamespace, $aBeanFactory);
         unset($item['fromPrototype']);
         $aAssociation->setDB($this->db());
         $this->arrAssociations[] = $aAssociation;
     }
     $this->done();
     $this->arrBeanConfig = $arrConfig;
 }
Example #10
0
 public function execute(DB $aDB, Model $aModel)
 {
     $aPrototype = $aModel->prototype();
     $aUpdate = $aPrototype->sharedStatementUpdate();
     // 从 belongs to model 中设置外键值
     foreach ($aPrototype->associations() as $aAssociation) {
         if ($aAssociation->isType(Association::belongsTo)) {
             if (!($aAssociatedModel = $aModel->child($aAssociation->name()))) {
                 continue;
             }
             if (!$aAssociatedModel->save()) {
                 return false;
             }
             $this->setAssociatedModelData($aAssociatedModel, $aModel, $aAssociation->toKeys(), $aAssociation->fromKeys());
         }
     }
     // 产生一个criteria并设置给$aUpdate
     //$aCriteria = StatementFactory::singleton()->createCriteria() ;
     //$aUpdate->setCriteria($aCriteria);
     // 处理主键
     $aUpdate->where()->clear();
     foreach ($aPrototype->keys() as $sKey) {
         //主键发生修改
         if ($aModel->changed($sKey)) {
             throw new ORMException('org\\jecat\\framework\\mvc\\model\\db\\orm\\Updater : Key 有修改,无法进行Update操作');
         } else {
             $aUpdate->where()->expression(array(SQL::createRawColumn(null, $sKey), '=', SQL::transValue($aModel->data($sKey))), true, true);
         }
     }
     $aUpdate->clearData();
     $bFlagChanged = false;
     //当前表是否有修改
     foreach ($aPrototype->columns() as $sClmName) {
         //只update发生修改的项
         if ($aModel->changed($sClmName)) {
             $aUpdate->setData($sClmName, $aModel->data($sClmName), false);
             $bFlagChanged = true;
         }
     }
     //只有当有修改的时候才发生更新
     if ($bFlagChanged) {
         $aDB->execute($aUpdate);
     }
     // update关联model
     foreach ($aPrototype->associations() as $aAssociation) {
         $aAssociatedModel = $aModel->child($aAssociation->name());
         if (!$aAssociatedModel) {
             continue;
         }
         switch ($aAssociation->type()) {
             case Association::hasOne:
                 $this->setAssociatedModelData($aModel, $aAssociatedModel, $aAssociation->fromKeys(), $aAssociation->toKeys());
                 if (!$aAssociatedModel->save()) {
                     return false;
                 }
                 break;
             case Association::belongsTo:
                 // nothing todo ...
                 break;
             case Association::hasMany:
                 $this->setAssociatedModelData($aModel, $aAssociatedModel, $aAssociation->fromKeys(), $aAssociation->toKeys());
                 if (!$aAssociatedModel->save()) {
                     return false;
                 }
                 break;
             case Association::hasAndBelongsToMany:
                 if (!$aAssociatedModel->save()) {
                     return false;
                 }
                 // update bridge table
                 foreach ($aAssociatedModel->childIterator() as $aOneChildModel) {
                     $this->buildBridge($aDB, $aAssociation, $aModel, $aOneChildModel);
                 }
                 break;
         }
     }
     return true;
 }
Example #11
0
 private function makeSql($inputSql, $factors = null, SqlCompiler $aSqlCompiler = null)
 {
     if (is_string($inputSql)) {
         $aSql = SQL::make($inputSql, $factors);
     } else {
         if ($inputSql instanceof SQL) {
             $aSql = $inputSql;
             if ($factors) {
                 $aSql->addFactors($factors);
             }
         } else {
             throw new ExecuteException($this, null, 0, "DB::query() 输入的参数 \$sql 类型无效。");
         }
     }
     if ($aSql) {
         return $aSql->toString($aSqlCompiler);
     } else {
         return $inputSql;
     }
 }
Example #12
0
 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;
     }
 }