PrepareInsertSQL($table, $row); // Выполняю запрос $count = $this->Execute($sql, $params); // Если результат - false или добавлена не одна запись if (($count === false) || ($count < 1) || ($count > 1)) // - то и общий результат - false return false; // Задаю переменную для последнего id $lastId = match ($this->Config->Driver) { DBDriver::MSSQL => $this->Query('SELECT SCOPE_IDENTITY() AS last_inserted_id;')['last_inserted_id'], DBDriver::MySQL, DBDriver::SQLite => $this->DataBaseHandle->lastInsertId(), DBDriver::PostgreSQL, DBDriver::OracleDB => $this->DataBaseHandle->lastInsertId('sequence_name') }; // Если id не получен if ($lastId === false) // - то вывожу просто true $lastId = true; // Если id не генерировался if ($lastId === null) // - то вывожу -1 $lastId = $primaryKeyValue !== "NULL" ? $primaryKeyValue : true; // Вывожу последний id return $lastId; } /** * Вставляет несколько строк в базу данных. * * @param string $table Имя таблицы. * @param IDBItem ...$sources Модели или классы, реализующие интерфейс IDBItem, для вставки. * * @return false|array Возвращает массив id созданных записей и false, если ошибка. */ public function InsertMany (string $table, IDBItem ...$sources): false | array { // Инициализирую транзакцию $this->InitTransaction(); // Подготавливаю массив последних id $result = []; try { // Для каждого источника foreach ($sources as $source) // - вставляю строку $result[] = $this->Insert($table, $source); // Если вставка успешна, то подтверждаю транзакцию $this->Commit(); } catch (Exception) { // - если ошибка, то откатываю транзакцию $this->RollBack(); // - и вывожу ошибку return false; } // Вывожу результат return $result; } /** * Подготавливает запрос для вставки строки в базу данных. * * @param string $table Имя таблицы. * @param IDBItem $row Элемент. * * @return Tuple Возвращает [запрос, параметры запроса, значение первичного ключа]. */ private function PrepareInsertSQL (string $table, IDBItem $row): Tuple { // Подготавливаю массив параметров $params = []; // Получаю массив свойств $properties = self::GetProperties($row, DBOperation::Insert); /** * Для каждого свойства... * * @var DBItemProperty $property Свойство. */ foreach ($properties as $property) { // - пропускаю игнорируемые поля if ($property->IsIgnored) continue; // - получаю значение имени поля $fieldName = $property->Column->Name; // - преобразую тип $value = call_user_func($property->ConvertToDB, $property->Value); // - добавляю в массив $params[$fieldName] = $value; } // Получаю ключи параметров $keys = array_keys($params); // Создаю результирующий массив имён ключей параметров $keys_params = []; // Создаю результирующий массив значений параметров $keys_values = []; // Для каждого ключа параметра foreach ($keys as $key) { // - получаю его имя $keyReal = $key[0] == ":" ? substr($key, 1) : $key; // - добавляю в результирующий массив ключей $keys_params[] = "$this->DBSignOpen$keyReal$this->DBSignClose"; // - добавляю в результирующий массив значений $keys_values[] = ":$keyReal"; } // Ключи sql запроса $sql_keys = implode(', ', $keys_params); // Значения sql запроса $sql_values = implode(', ', $keys_values); // Подготавливаю имя таблицы $table = $this->PrepareTableName($table); // Создаю запрос $sql = "INSERT INTO $table ($sql_keys) VALUES ($sql_values);"; /** * Получаю первичный ключ таблицы. * * @var false|DBItemProperty $key Первичный ключ таблицы. */ $key = $properties->GetRow( selectCondition: fn (DBItemProperty $property): bool => $property->Column->IsPrimaryKey ); // Передаю первичный ключ в переменную $pKey = $key === false ? 'NULL' : $key->Value ?? "NULL"; // Возвращаю результат return new Tuple($sql, $params, $pKey); } }