Пример #1
0
 /**
  * 插入一条新记录,返回新记录的主键值
  *
  * create() 操作会引发 _beforeCreate()、_beforeCreateDb() 和 _afterCreateDb() 事件。
  *
  * @param array $row
  * @param boolean $saveLinks
  *
  * @return mixed
  */
 function create(&$row, $saveLinks = true)
 {
     if (!$this->_beforeCreate($row)) {
         return false;
     }
     // 自动设置日期字段
     $this->_setCreatedTimeFields($row);
     // 处理主键
     $mpk = strtoupper($this->primaryKey);
     $insertId = null;
     $unsetpk = true;
     if (isset($this->meta[$mpk]['autoIncrement']) && $this->meta[$mpk]['autoIncrement']) {
         if (isset($row[$this->primaryKey])) {
             if (empty($row[$this->primaryKey])) {
                 // 如果主键字段是自增,而提供的记录数据虽然包含主键字段,
                 // 但却是空值,则删除这个空值
                 unset($row[$this->primaryKey]);
             } else {
                 $unsetpk = false;
             }
         }
     } else {
         // 如果主键字段不是自增字段,并且没有提供主键字段值时,则获取一个新的主键字段值
         if (!isset($row[$this->primaryKey]) || empty($row[$this->primaryKey])) {
             $insertId = $this->newInsertId();
             $row[$this->primaryKey] = $insertId;
         } else {
             // 使用开发者提交的主键字段值
             $insertId = $row[$this->primaryKey];
             $unsetpk = false;
         }
     }
     // 自动验证数据
     if ($this->autoValidating && !is_null($this->verifier)) {
         if (!$this->checkRowData($row)) {
             FLEA::loadClass('FLEA_Exception_ValidationFailed');
             __THROW(new FLEA_Exception_ValidationFailed($this->getLastValidation(), $row));
             return false;
         }
     }
     // 调用 _beforeCreateDb() 事件
     $this->dbo->startTrans();
     if (!$this->_beforeCreateDb($row)) {
         if ($unsetpk) {
             unset($row[$this->primaryKey]);
         }
         $this->dbo->completeTrans(false);
         return false;
     }
     // 生成 SQL 语句
     list($holders, $values) = $this->dbo->getPlaceholder($row, $this->fields);
     $holders = implode(',', $holders);
     $fields = $this->dbo->qfields(array_keys($values));
     $sql = "INSERT INTO {$this->qtableName} ({$fields}) VALUES ({$holders})";
     // 插入数据
     if (!$this->dbo->Execute($sql, $values, true)) {
         if ($unsetpk) {
             unset($row[$this->primaryKey]);
         }
         $this->dbo->completeTrans(false);
         return false;
     }
     // 如果提交的数据中没有主键字段值,则尝试获取新插入记录的主键值
     if (is_null($insertId)) {
         $insertId = $this->dbo->insertId();
         if (!$insertId) {
             if ($unsetpk) {
                 unset($row[$this->primaryKey]);
             }
             $this->dbo->completeTrans(false);
             FLEA::loadClass('FLEA_Db_Exception_InvalidInsertID');
             return __THROW(new FLEA_Db_Exception_InvalidInsertID());
         }
     }
     // 处理关联数据表
     if ($this->autoLink && $saveLinks) {
         foreach (array_keys($this->links) as $linkKey) {
             $link =& $this->links[$linkKey];
             /* @var $link FLEA_Db_TableLink */
             if (!$link->enabled || !$link->linkCreate || !isset($row[$link->mappingName]) || !is_array($row[$link->mappingName])) {
                 // 跳过没有关联数据的关联和不需要处理的关联
                 continue;
             }
             if (!$link->saveAssocData($row[$link->mappingName], $insertId)) {
                 if ($unsetpk) {
                     unset($row[$this->primaryKey]);
                 }
                 $this->dbo->completeTrans(false);
                 return false;
             }
         }
     }
     $row[$this->primaryKey] = $insertId;
     $this->_updateCounterCache($row);
     // 提交事务
     $this->dbo->CompleteTrans();
     $this->_afterCreateDb($row);
     if ($unsetpk) {
         unset($row[$this->primaryKey]);
     }
     return $insertId;
 }