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)); } }
/** * 以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; }
/** * @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; }
/** * @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; }