/** * 创建或更新主表记录时,保存关联的数据 * * @param array $row 要保存的关联数据 * @param mixed $pkv 主表的主键字段值 * * @return boolean */ function saveAssocData(&$row, $pkv) { if (!$this->init) { $this->init(); } $apkvs = array(); $entityRowset = array(); foreach ($row as $arow) { if (!is_array($arow)) { $apkvs[] = $arow; continue; } if (!isset($arow[$this->assocForeignKey])) { // 如果关联记录尚未保存到数据库,则创建一条新的关联记录 $newrowid = $this->assocTDG->create($arow); if ($newrowid == false) { return false; } $apkv = $newrowid; } else { $apkv = $arow[$this->assocForeignKey]; } $apkvs[] = $apkv; if ($this->joinTableIsEntity && isset($arow['#JOIN#'])) { $entityRowset[$apkv] =& $arow['#JOIN#']; } } // 首先取出现有的关联信息 $qpkv = $this->dbo->qstr($pkv); $sql = "SELECT {$this->qassocForeignKey} FROM {$this->qjoinTable} WHERE {$this->qforeignKey} = {$qpkv} "; $existsMiddle = (array) $this->dbo->getCol($sql); // 然后确定要添加的关联信息 $insertAssoc = array_diff($apkvs, $existsMiddle); $removeAssoc = array_diff($existsMiddle, $apkvs); if ($this->joinTableIsEntity) { $insertEntityRowset = array(); foreach ($insertAssoc as $assocId) { if (isset($entityRowset[$assocId])) { $row = $entityRowset[$assocId]; } else { $row = array(); } $row[$this->foreignKey] = $pkv; $row[$this->assocForeignKey] = $assocId; $insertEntityRowset[] = $row; } if ($this->joinTDG->createRowset($insertEntityRowset) === false) { return false; } } else { $sql = "INSERT INTO {$this->qjoinTable} ({$this->qforeignKey}, {$this->qassocForeignKey}) VALUES ({$qpkv}, "; foreach ($insertAssoc as $assocId) { if (!$this->dbo->execute($sql . $this->dbo->qstr($assocId) . ')')) { return false; } } } // 最后删除不再需要的关联信息 if ($this->joinTableIsEntity) { $conditions = array($this->foreignKey => $pkv); foreach ($removeAssoc as $assocId) { $conditions[$this->assocForeignKey] = $assocId; if ($this->joinTDG->removeByConditions($conditions) === false) { return false; } } } else { $sql = "DELETE FROM {$this->qjoinTable} WHERE {$this->qforeignKey} = {$qpkv} AND {$this->qassocForeignKey} = "; foreach ($removeAssoc as $assocId) { if (!$this->dbo->execute($sql . $this->dbo->qstr($assocId))) { return false; } } } if ($this->counterCache) { $sql = "UPDATE {$this->mainTDG->qtableName} SET {$this->counterCache} = (SELECT COUNT(*) FROM {$this->qjoinTable} WHERE {$this->qforeignKey} = {$qpkv}) WHERE {$this->mainTDG->qpk} = {$qpkv}"; $this->mainTDG->dbo->execute($sql); } return true; }