private function _prepareSaveStatement()
{
$stmt = new EntityStatement($this->db(), get_class($this));
/* @var $iterator EntityPropertiesIterator */
$iterator = $this->getIterator();
$pk = $iterator->getPrimaryKey();
if (empty($pk)) {
throw new ModelException("Primary key has not been defined with @Id tag for " . get_class($this));
}
$stmtPk = [];
$stmtFields = [];
$stmtUpdate = [];
$args = [];
$pkArgs = [];
$onDuplicateArgs = [];
/* @var $field Field */
foreach ($iterator->fields() as $field) {
$stmtFields[] = "{$field->getColumnName()} = {$field->type->wh()}";
$args[] = $field;
if (isset($field->id)) {
//Field takes a part in primary key
$stmtPk[] = "{$field->getColumnName()} = {$field->type->wh()}";
$pkArgs[] = $field;
} else {
$stmtUpdate[] = "{$field->getColumnName()} = {$field->type->wh()}";
$onDuplicateArgs[] = $field;
}
}
$stmtFields = implode(", ", $stmtFields);
$table = static::table();
if ($this->_hasUniqueIndex()) {
$stmt->setInsertStatement(static::db()->Prepare("INSERT INTO {$table} SET {$stmtFields} "), $args);
} else {
$stmt->setInsertStatement(static::db()->Prepare("INSERT INTO {$table} SET {$stmtFields}" . (empty($stmtUpdate) ? '' : " ON DUPLICATE KEY UPDATE " . implode(", ", $stmtUpdate))), array_merge($args, $onDuplicateArgs));
}
if (!empty($stmtPk)) {
$stmtPk = implode(" AND ", $stmtPk);
$stmt->setUpdateStatement(static::db()->Prepare("UPDATE {$table} SET {$stmtFields} WHERE {$stmtPk} LIMIT 1"), array_merge($args, $pkArgs));
$stmt->setDeleteStatement(static::db()->Prepare("DELETE FROM {$table} WHERE {$stmtPk} LIMIT 1"), $pkArgs);
}
return $stmt;
}