Beispiel #1
0
 public function active(&$sToken, ParseState $aParseState)
 {
     $arrValuesToken = Insert::createRawInsertValues();
     // 追溯前面的 字段列表
     if (end($aParseState->arrTree) === ')') {
         $nDepth = 0;
         do {
             $token = array_pop($aParseState->arrTree);
             if (is_string($token)) {
                 if ($token === ')') {
                     $nDepth++;
                     continue;
                 } else {
                     if ($token === '(') {
                         $nDepth--;
                         continue;
                     }
                 }
             }
             if (!empty($token['expr_type']) and $token['expr_type'] === 'column') {
                 $arrValuesToken['pretree']['COLUMNS']['subtree'][$token['column']] = $token;
                 $arrValuesToken['columns'][] = $token['column'];
             } else {
                 $arrValuesToken['pretree']['COLUMNS']['subtree'][] = $token;
             }
         } while ($nDepth);
         $arrValuesToken['pretree']['COLUMNS']['subtree'] = array_reverse($arrValuesToken['pretree']['COLUMNS']['subtree'], true);
         if (!empty($arrValuesToken['columns'])) {
             $arrValuesToken['columns'] = array_reverse($arrValuesToken['columns'], false);
         }
     }
     $aParseState->arrTree[] =& $arrValuesToken;
     $this->switchToSubTree($aParseState, $arrValuesToken);
 }
Beispiel #2
0
 public function execute(DB $aDB, Model $aModel)
 {
     $aPrototype = $aModel->prototype();
     $aInsert = new Insert($aPrototype->tableName());
     // 从 belongs to model 中设置外键值
     foreach ($aPrototype->associations() as $aAssociation) {
         if ($aAssociation->isType(Association::belongsTo)) {
             if (!($aAssocModel = $aModel->child($aAssociation->name()))) {
                 continue;
             }
             if (!$aAssocModel->save()) {
                 return false;
             }
             $this->setAssocModelData($aAssocModel, $aModel, $aAssociation->toKeys(), $aAssociation->fromKeys());
         }
     }
     // -----------------------------------
     // insert 当前model
     $bTableLocked = false;
     $sTableName = $aPrototype->tableName();
     $e = null;
     try {
         // 检查/自动生成 主键值
         if ($arrKey = $aPrototype->keys()) {
             foreach ($arrKey as $sKeyName) {
                 if ($aModel->data($sKeyName) === null) {
                     $aClmRef = $aPrototype->columnReflecter($sKeyName);
                     if (!$aClmRef->isAutoIncrement()) {
                         // 锁表
                         if (!$bTableLocked) {
                             $aDB->execute("LOCK TABLES `{$sTableName}` WRITE ;");
                             $bTableLocked = true;
                         }
                         // 生成并设置主键值
                         $keyValue = AutoPrimaryGenerator::singleton()->generate($aClmRef, $sTableName, $aDB);
                         $aModel->setData($sKeyName, $keyValue);
                     }
                 }
             }
         }
         // 设置数据
         foreach ($aModel->dataNameIterator() as $sClmName) {
             $value = $aModel->data($sClmName);
             if ($value !== null) {
                 $aInsert->setData($sClmName, $value);
             }
         }
         // 执行 insert
         $aDB->execute($aInsert);
     } catch (\Exception $e) {
     }
     // 解锁后再抛出异常
     if ($bTableLocked) {
         $aDB->execute("UNLOCK TABLES ;");
     }
     if ($e) {
         throw $e;
     }
     // 自增形主键
     if ($sDevicePrimaryKey = $aPrototype->devicePrimaryKey() and $aModel->data($sDevicePrimaryKey) === null) {
         $aModel->setData($sDevicePrimaryKey, $aDB->lastInsertId(), false);
     }
     // -----------------------------------
     // insert 关联model
     foreach ($aPrototype->associations() as $aAssociation) {
         $aAssocModel = $aModel->child($aAssociation->name());
         if (!$aAssocModel) {
             continue;
         }
         switch ($aAssociation->type()) {
             case Association::hasOne:
                 $this->setAssocModelData($aModel, $aAssocModel, $aAssociation->fromKeys(), $aAssociation->toKeys());
                 if (!$aAssocModel->save()) {
                     return false;
                 }
                 break;
             case Association::belongsTo:
                 // nothing todo ...
                 break;
             case Association::hasMany:
                 $this->setAssocModelData($aModel, $aAssocModel, $aAssociation->fromKeys(), $aAssociation->toKeys());
                 if (!$aAssocModel->save()) {
                     return false;
                 }
                 break;
             case Association::hasAndBelongsToMany:
                 if (!$aAssocModel->save()) {
                     return false;
                 }
                 // -----------------------
                 // insert bridge table
                 foreach ($aAssocModel->childIterator() as $aOneChildModel) {
                     $this->buildBridge($aDB, $aAssociation, $aModel, $aOneChildModel);
                 }
                 break;
         }
     }
     return true;
 }