diff --git a/ci/os/internal/Modules/МетодыПримеровКода.os b/ci/os/internal/Modules/МетодыПримеровКода.os index cf4625be5d..88a0d1c45a 100644 --- a/ci/os/internal/Modules/МетодыПримеровКода.os +++ b/ci/os/internal/Modules/МетодыПримеровКода.os @@ -243,6 +243,7 @@ СоответствиеЗамен = Новый Соответствие; СоответствиеЗамен.Вставить("MDB_CString", "mongodb://bayselonarrend:***@127.0.0.1:27017"); + СоответствиеЗамен.Вставить("PG_Connection", "postgresql://bayselonarrend:***@127.0.0.1:5432/"); Для Каждого Признак Из СоответствиеПризнаковСекретов Цикл diff --git a/src/addins/postgres/OPI_PostgreSQL.zip b/src/addins/postgres/OPI_PostgreSQL.zip index 13766143c9..c625e49d57 100644 Binary files a/src/addins/postgres/OPI_PostgreSQL.zip and b/src/addins/postgres/OPI_PostgreSQL.zip differ diff --git a/src/addins/postgres/src/component/methods.rs b/src/addins/postgres/src/component/methods.rs index 8f1cc8f540..077a27438b 100644 --- a/src/addins/postgres/src/component/methods.rs +++ b/src/addins/postgres/src/component/methods.rs @@ -39,7 +39,7 @@ pub fn execute_query( Err(e) => format_json_error(&e.to_string()), } } else { - match client.execute(&query, ¶ms_unboxed) { + match client.execute(&query, ¶ms_unboxed.as_slice()) { Ok(_) => json!({"result": true}).to_string(), Err(e) => format_json_error(&e.to_string()), } @@ -86,7 +86,7 @@ fn process_object(object: &Map) -> Result, .as_bool() .map(|v| Box::new(v) as Box) .ok_or_else(|| "Invalid value for BOOL".to_string()), - "\"CHAR\"" => value + "\"CHAR\"" | "OLDCHAR" => value .as_i64() .and_then(|v| i8::try_from(v).ok()) .map(|v| Box::new(v) as Box) @@ -115,7 +115,7 @@ fn process_object(object: &Map) -> Result, .map(|v| v as f32) // Преобразование f64 в f32 .map(|v| Box::new(v) as Box) .ok_or_else(|| "Invalid value for REAL".to_string()), - "DOUBLE PRECISION" => value + "DOUBLE PRECISION" | "DOUBLE_PRECISION" => value .as_f64() .map(|v| Box::new(v) as Box) .ok_or_else(|| "Invalid value for DOUBLE PRECISION".to_string()), @@ -204,9 +204,16 @@ fn rows_to_json(rows: Vec) -> String { "varchar" | "text" | "char" | "citext" | "name" | "unknown" => row.get::<_, Option>(column_name) .map(Value::String) .unwrap_or(Value::Null), - "bytea" => row.get::<_, Option>>(column_name) - .map(|v| Value::String(general_purpose::STANDARD.encode(v))) - .unwrap_or(Value::Null), + "bytea" => { + + let base64_string = row.get::<_, Option>>(column_name) + .map(|v| general_purpose::STANDARD.encode(v)) + .unwrap_or("Unable to make Base64 string".to_string()); + + let mut blob_object = serde_json::Map::new(); + blob_object.insert("BYTEA".to_string(), Value::String(base64_string)); // Оборачиваем в объект + Value::Object(blob_object) + }, "hstore" => row.get::<_, Option>>>(column_name) .map(|hstore| { let mut map = Map::new(); diff --git a/src/addins/postgres/src/component/mod.rs b/src/addins/postgres/src/component/mod.rs index 918f87dd89..7dbaff0c54 100644 --- a/src/addins/postgres/src/component/mod.rs +++ b/src/addins/postgres/src/component/mod.rs @@ -52,7 +52,7 @@ pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box Тип("AddIn.OPI_PostgreSQL.Main") Тогда + Возврат Коннектор; + КонецЕсли; + + Результат = Коннектор.Execute(ТекстЗапроса, Параметры_, ФорсироватьРезультат); + Результат = OPI_Инструменты.JsonВСтруктуру(Результат); + + Возврат Результат; + +КонецФункции + +// Сформировать строку подключения +// Формирует строку подключения из переданных данных +// +// Параметры: +// Адрес - Строка - IP адрес или доменное имя сервера - addr +// База - Строка - Имя базы данных для подключения - db +// Логин - Строка - Логин пользователя postgres - login +// Пароль - Строка - Пароль пользователя postgres - pass +// Порт - Строка - Порт подключения - port +// +// Возвращаемое значение: +// Строка - Строка подключения к базе PostgreSQL +Функция СформироватьСтрокуПодключения(Знач Адрес, Знач База, Знач Логин, Знач Пароль = "", Знач Порт = "5432") Экспорт + + OPI_ПреобразованиеТипов.ПолучитьСтроку(Адрес); + OPI_ПреобразованиеТипов.ПолучитьСтроку(Логин); + OPI_ПреобразованиеТипов.ПолучитьСтроку(База); + OPI_ПреобразованиеТипов.ПолучитьСтроку(Порт); + OPI_ПреобразованиеТипов.ПолучитьСтроку(Пароль); + + Порт = ?(ЗначениеЗаполнено(Порт), ":" + Порт, Порт); + Пароль = ?(ЗначениеЗаполнено(Пароль), ":" + Пароль, Пароль); + + ШаблонСтроки = "postgresql://%1%2@%3%4/%5"; + СтрокаПодключения = СтрШаблон(ШаблонСтроки, Логин, Пароль, Адрес, Порт, База); + + Возврат СтрокаПодключения; + +КонецФункции + +#КонецОбласти + +#Область ORM + +// Создать базу данных +// Создает базу данных с указанным именем +// +// Параметры: +// База - Строка - Имя базы - base +// Соединение - Строка, Произвольный - Соединение или строка подключения - dbc +// +// Возвращаемое значение: +// Структура Из КлючИЗначение, Строка - Результат выполнения запроса +Функция СоздатьБазуДанных(Знач База, Знач Соединение = "") Экспорт + + Результат = OPI_ЗапросыSQL.СоздатьБазу(OPI_PostgreSQL, База, Соединение); + Возврат Результат; + +КонецФункции + +// Удалить базу данных +// Удаляет базу данных +// +// Параметры: +// База - Строка - Имя базы - base +// Соединение - Строка, Произвольный - Соединение или строка подключения - dbc +// +// Возвращаемое значение: +// Структура Из КлючИЗначение, Строка - Результат выполнения запроса +Функция УдалитьБазуДанных(Знач База, Знач Соединение = "") Экспорт + + Результат = OPI_ЗапросыSQL.УдалитьБазу(OPI_PostgreSQL, База, Соединение); + Возврат Результат; + +КонецФункции + +// Создать таблицу +// Создает пустую таблицу в базе +// +// Параметры: +// Таблица - Строка - Имя таблицы - table +// СтруктураКолонок - Структура Из КлючИЗначение - Структура колонок: Ключ > имя, Значение > Тип данных - cols +// Соединение - Строка, Произвольный - Соединение или строка подключения - dbc +// +// Возвращаемое значение: +// Структура Из КлючИЗначение, Строка - Результат выполнения запроса +Функция СоздатьТаблицу(Знач Таблица, Знач СтруктураКолонок, Знач Соединение = "") Экспорт + + Результат = OPI_ЗапросыSQL.СоздатьТаблицу(OPI_PostgreSQL, Таблица, СтруктураКолонок, Соединение); + Возврат Результат; + +КонецФункции + +// Добавить записи +// Добавляет записи в таблицу +// +// Примечание: +// Двоичные данные могут также быть переданы как структура `{'blob':Путь к файлу}` +// +// Параметры: +// Таблица - Строка - Имя таблицы - table +// МассивДанных - Массив Из Структура - Массив структур данных строк: Ключ > поле, Значение > значение поля - rows +// Транзакция - Булево - Истина > добавление записей в транзакции с откатом при ошибке - trn +// Соединение - Строка, Произвольный - Соединение или строка подключения - dbc +// +// Возвращаемое значение: +// Структура Из КлючИЗначение, Строка - Результат выполнения запроса +Функция ДобавитьЗаписи(Знач Таблица, Знач МассивДанных, Знач Транзакция = Истина, Знач Соединение = "") Экспорт + + Результат = OPI_ЗапросыSQL.ДобавитьЗаписи(OPI_PostgreSQL, Таблица, МассивДанных, Транзакция, Соединение); + Возврат Результат; + +КонецФункции + +// Получить записи +// Получает записи из выбранной таблицы +// +// Примечание: +// Значения типа Двоичные данные (BLOB) возвращаются в виде `{'blob':Base64 строка}` +// +// Параметры: +// Таблица - Строка - Имя таблицы - table +// Поля - Массив Из Строка - Поля для выборки - fields +// Фильтры - Массив Из Структура - Массив фильтров. См. ПолучитьСтруктуруФильтраЗаписей - filter +// Сортировка - Структура Из КлючИЗначение - Сортировка: Ключ > поле, Значение > направление (ASC, DESC) - order +// Количество - Число - Ограничение количества получаемых строк - limit +// Соединение - Строка, Произвольный - Соединение или строка подключения - dbc +// +// Возвращаемое значение: +// Структура Из КлючИЗначение, Строка - Результат выполнения запроса +Функция ПолучитьЗаписи(Знач Таблица + , Знач Поля = "*" + , Знач Фильтры = "" + , Знач Сортировка = "" + , Знач Количество = "" + , Знач Соединение = "") Экспорт + + Результат = OPI_ЗапросыSQL.ПолучитьЗаписи(OPI_PostgreSQL, Таблица, Поля, Фильтры, Сортировка, Количество, Соединение); + Возврат Результат; + +КонецФункции + +// Обновить записи +// Обновляет значение записей по выбранным критериям +// +// Параметры: +// Таблица - Строка - Имя таблицы - table +// СтруктураЗначений - Структура Из КлючИЗначение - Структура значений: Ключ > поле, Значение > значение поля - values +// Фильтры - Массив Из Структура - Массив фильтров. См. ПолучитьСтруктуруФильтраЗаписей - filter +// Соединение - Строка, Произвольный - Соединение или строка подключения - dbc +// +// Возвращаемое значение: +// Структура Из КлючИЗначение, Строка - Результат выполнения запроса +Функция ОбновитьЗаписи(Знач Таблица, Знач СтруктураЗначений, Знач Фильтры = "", Знач Соединение = "") Экспорт + + Результат = OPI_ЗапросыSQL.ОбновитьЗаписи(OPI_PostgreSQL, Таблица, СтруктураЗначений, Фильтры, Соединение); + Возврат Результат; + +КонецФункции + +// Удалить записи +// Удаляет записи из таблицы +// +// Параметры: +// Таблица - Строка - Имя таблицы - table +// Фильтры - Массив Из Структура - Массив фильтров. См. ПолучитьСтруктуруФильтраЗаписей - filter +// Соединение - Строка, Произвольный - Соединение или строка подключения - dbc +// +// Возвращаемое значение: +// Структура Из КлючИЗначение, Строка - Результат выполнения запроса +Функция УдалитьЗаписи(Знач Таблица, Знач Фильтры = "", Знач Соединение = "") Экспорт + + Результат = OPI_ЗапросыSQL.УдалитьЗаписи(OPI_PostgreSQL, Таблица, Фильтры, Соединение); + Возврат Результат; + +КонецФункции + +// Удалить таблицу +// Удаляет таблицу из базы +// +// Параметры: +// Таблица - Строка - Имя таблицы - table +// Соединение - Строка, Произвольный - Соединение или строка подключения - dbc +// +// Возвращаемое значение: +// Структура Из КлючИЗначение, Строка - Результат выполнения запроса +Функция УдалитьТаблицу(Знач Таблица, Знач Соединение = "") Экспорт + + Результат = OPI_ЗапросыSQL.УдалитьТаблицу(OPI_PostgreSQL, Таблица, Соединение); + Возврат Результат; + +КонецФункции + +// Очистить таблицу +// Очищает таблицу базы +// +// Параметры: +// Таблица - Строка - Имя таблицы - table +// Соединение - Строка, Произвольный - Соединение или строка подключения - dbc +// +// Возвращаемое значение: +// Структура Из КлючИЗначение, Строка - Результат выполнения запроса +Функция ОчиститьТаблицу(Знач Таблица, Знач Соединение = "") Экспорт + + Результат = OPI_ЗапросыSQL.УдалитьЗаписи(OPI_PostgreSQL, Таблица, , Соединение); + Возврат Результат; + +КонецФункции + +// Получить структуру фильтра записей +// Получает структуру шаблон для фильтрации записей в запросах ORM +// +// Примечание: +// Использование признака `raw` необходимо для составных конструкций, вроде `BEETWEEN`.^^ +// Например: при `raw:false` фильтр `type:BETWEEN` `value:10 AND 20` будет интерпритирован как `BETWEEN ?1 `^^ +// где `?1 = "10 AND 20"`, что приведет к ошибке.^^ +// В таком случае необходимо использовать `raw:true` для установки условия напрямую в текст запроса +// +// Параметры: +// Пустая - Булево - Истина > структура с пустыми значениями, Ложь > в значениях будут описания полей - empty +// +// Возвращаемое значение: +// Структура Из КлючИЗначение - Элемент фильтра записей +Функция ПолучитьСтруктуруФильтраЗаписей(Знач Пустая = Ложь) Экспорт + + Возврат OPI_ЗапросыSQL.ПолучитьСтруктуруФильтраЗаписей(Пустая); + +КонецФункции + +#КонецОбласти + +#КонецОбласти + +#Область СлужебныйПрограммныйИнтерфейс + +Функция ИмяКоннектора() Экспорт + Возврат "OPI_PostgreSQL"; +КонецФункции + +Функция ПолучитьОсобенности() Экспорт + + Особенности = Новый Структура; + Особенности.Вставить("НумерацияПараметров", Истина); + Особенности.Вставить("МаркерПараметров" , "$"); + + Возврат Особенности; + +КонецФункции + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +Функция ПодключитьКомпонентуНаСервере(Знач ИмяКомпоненты, Знач Класс = "Main") + + Если OPI_Инструменты.ЭтоOneScript() Тогда + ИмяМакета = OPI_Инструменты.КаталогКомпонентOS() + ИмяКомпоненты + ".zip"; + Иначе + ИмяМакета = "ОбщийМакет." + ИмяКомпоненты; + КонецЕсли; + + ПодключитьВнешнююКомпоненту(ИмяМакета, ИмяКомпоненты, ТипВнешнейКомпоненты.Native); + + Компонента = Новый ("AddIn." + ИмяКомпоненты + "." + Класс); + Возврат Компонента; + +КонецФункции + +Функция ОбработатьПараметры(Знач Параметры) + + Если Не ЗначениеЗаполнено(Параметры) Тогда + Возврат "[]"; + КонецЕсли; + + OPI_ПреобразованиеТипов.ПолучитьМассив(Параметры); + + Для Н = 0 По Параметры.ВГраница() Цикл + + ТекущийПараметр = Параметры[Н]; + + Если ТипЗнч(ТекущийПараметр) = Тип("ДвоичныеДанные") Тогда + + ТекущийПараметр = Новый Структура("BYTEA", Base64Строка(ТекущийПараметр)); + + ИначеЕсли OPI_Инструменты.ПолеКоллекцииСуществует(ТекущийПараметр, "BYTEA") Тогда + + ТекущийПараметр = ОбработатьСтруктуруBlob(ТекущийПараметр); + + ИначеЕсли ТипЗнч(ТекущийПараметр) = Тип("Дата") Тогда + + ТекущийПараметр = Формат(ТекущийПараметр, "ДФ='yyyy-MM-dd HH:MM:ss'"); + + ИначеЕсли ТипЗнч(ТекущийПараметр) = Тип("Структура") Или ТипЗнч(ТекущийПараметр) = Тип("Соответствие") Тогда + + Продолжить; + + Иначе + + Если Не OPI_Инструменты.ЭтоПримитивныйТип(ТекущийПараметр) Тогда + OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекущийПараметр); + КонецЕсли; + + КонецЕсли; + + Параметры[Н] = ТекущийПараметр; + + КонецЦикла; + + Параметры_ = OPI_Инструменты.JSONСтрокой(Параметры, , Ложь); + + Возврат Параметры_; + +КонецФункции + +Функция ОбработатьСтруктуруBlob(Знач Значение) + + ЗначениеДанных = Значение["BYTEA"]; + + Если ТипЗнч(ЗначениеДанных) = Тип("ДвоичныеДанные") Тогда + Значение = Новый Структура("BYTEA", Base64Строка(ЗначениеДанных)); + Иначе + + ФайлДанных = Новый Файл(Строка(ЗначениеДанных)); + + Если ФайлДанных.Существует() Тогда + + ТекущиеДанные = Новый ДвоичныеДанные(Строка(ЗначениеДанных)); + Значение = Новый Структура("BYTEA", Base64Строка(ТекущиеДанные)); + + КонецЕсли; + + КонецЕсли; + + Возврат Значение; + +КонецФункции + +#КонецОбласти diff --git a/src/ru/OPI/src/CommonModules/OPI_PostgreSQL/OPI_PostgreSQL.mdo b/src/ru/OPI/src/CommonModules/OPI_PostgreSQL/OPI_PostgreSQL.mdo new file mode 100644 index 0000000000..4c98f01b6a --- /dev/null +++ b/src/ru/OPI/src/CommonModules/OPI_PostgreSQL/OPI_PostgreSQL.mdo @@ -0,0 +1,11 @@ + + + OPI_PostgreSQL + + ru + Postgre SQL (ОПИ) + + true + true + true + diff --git a/src/ru/OPI/src/CommonModules/OPI_SQLite/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_SQLite/Module.bsl index 7d5871a158..9d47c8e98f 100644 --- a/src/ru/OPI/src/CommonModules/OPI_SQLite/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_SQLite/Module.bsl @@ -1,4 +1,4 @@ -// OneScript: ./OInt/core/Modules/OPI_SQLite.os +// OneScript: ./OInt/core/Modules/OPI_SQLite.os // Lib: SQLite // CLI: sqlite @@ -342,6 +342,16 @@ Возврат "OPI_SQLite"; КонецФункции +Функция ПолучитьОсобенности() Экспорт + + Особенности = Новый Структура; + Особенности.Вставить("НумерацияПараметров", Истина); + Особенности.Вставить("МаркерПараметров" , "?"); + + Возврат Особенности; + +КонецФункции + #КонецОбласти #Область СлужебныеПроцедурыИФункции diff --git a/src/ru/OPI/src/CommonModules/OPI_ЗапросыSQL/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_ЗапросыSQL/Module.bsl index ea3562449e..641b5a2187 100644 --- a/src/ru/OPI/src/CommonModules/OPI_ЗапросыSQL/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_ЗапросыSQL/Module.bsl @@ -1,4 +1,4 @@ -// OneScript: ./OInt/tools/Modules/OPI_ЗапросыSQL.os +// OneScript: ./OInt/tools/Modules/OPI_ЗапросыSQL.os // MIT License @@ -44,6 +44,32 @@ #Область СлужебныйПрограммныйИнтерфейс +Функция СоздатьБазу(Знач Модуль, Знач База, Знач Соединение = "") Экспорт + + Схема = ПустаяСхемаSQL("CREATEDATABASE"); + + УстановитьИмяБазы(Схема, База); + + Запрос = СформироватьТекстSQL(Схема); + Результат = Модуль.ВыполнитьЗапросSQL(Запрос, , , Соединение); + + Возврат Результат; + +КонецФункции + +Функция УдалитьБазу(Знач Модуль, Знач База, Знач Соединение = "") Экспорт + + Схема = ПустаяСхемаSQL("DROPDATABASE"); + + УстановитьИмяБазы(Схема, База); + + Запрос = СформироватьТекстSQL(Схема); + Результат = Модуль.ВыполнитьЗапросSQL(Запрос, , , Соединение); + + Возврат Результат; + +КонецФункции + Функция СоздатьТаблицу(Знач Модуль, Знач Таблица, Знач СтруктураКолонок, Знач Соединение = "") Экспорт ТекстОшибки = "Структура колонок не является валидной структурой ключ-значение"; @@ -207,7 +233,7 @@ #Область Схемы -Функция ПустаяСхемаSQL(Знач Действие) +Функция ПустаяСхемаSQL(Знач Действие, Знач Особенности = Неопределено) OPI_ПреобразованиеТипов.ПолучитьСтроку(Действие); @@ -219,7 +245,7 @@ ИначеЕсли Действие = "INSERT" Тогда - Схема = ПустаяСхемаInsert(); + Схема = ПустаяСхемаInsert(Особенности); ИначеЕсли Действие = "UPDATE" Тогда @@ -240,6 +266,15 @@ ИначеЕсли Действие = "TRUNCATE" Тогда Схема = ПустаяСхемаTruncate(); + + ИначеЕсли Действие = "CREATEDATABASE" Тогда + + Схема = ПустаяСхемаCreateDatabase(); + + ИначеЕсли Действие = "DROPDATABASE" Тогда + + Схема = ПустаяСхемаDropDatabase(); + Иначе Схема = Новый Структура; @@ -265,12 +300,17 @@ КонецФункции -Функция ПустаяСхемаInsert() +Функция ПустаяСхемаInsert(Знач Особенности) Схема = Новый Структура("type", "INSERT"); + + НумерацияПараметров = ?(ЗначениеЗаполнено(Особенности), Особенности["НумерацияПараметров"], Ложь); + МаркерПараметров = ?(ЗначениеЗаполнено(Особенности), Особенности["МаркерПараметров"] , "?"); Схема.Вставить("table", ""); Схема.Вставить("set" , Новый Массив); + Схема.Вставить("nump" , НумерацияПараметров); + Схема.Вставить("markp", МаркерПараметров); Возврат Схема; @@ -332,6 +372,26 @@ КонецФункции +Функция ПустаяСхемаCreateDatabase(); + + Схема = Новый Структура("type", "CREATEDATABASE"); + + Схема.Вставить("database" , ""); + + Возврат Схема; + +КонецФункции + +Функция ПустаяСхемаDropDatabase(); + + Схема = Новый Структура("type", "DROPDATABASE"); + + Схема.Вставить("database" , ""); + + Возврат Схема; + +КонецФункции + #КонецОбласти #Область Процессоры @@ -376,7 +436,14 @@ ИначеЕсли ТипСхемы = "TRUNCATE" Тогда ТекстЗапроса = СформироватьТекстTruncate(Схема); - + + ИначеЕсли ТипСхемы = "CREATEDATABASE" Тогда + + ТекстЗапроса = СформироватьТекстCreateDatabase(Схема); + + ИначеЕсли ТипСхемы = "DROPDATABASE" Тогда + + ТекстЗапроса = СформироватьТекстDropDatabase(Схема); Иначе ТекстЗапроса = ""; @@ -412,15 +479,25 @@ ПроверитьОбязательныеПоляСхемы(Схема, "table,set"); - Таблица = Схема["table"]; - Поля = Схема["set"]; + Таблица = Схема["table"]; + Поля = Схема["set"]; + Нумерация = Схема["nump"]; + Маркер = Схема["markp"]; ШаблонSQL = "INSERT INTO %1 (%2) VALUES (%3)"; Параметры = Новый Массив; - - Для Н = 1 По Поля.Количество() Цикл - Параметры.Добавить("?" + OPI_Инструменты.ЧислоВСтроку(Н)); + + Для Н = 1 По Поля.Количество() Цикл + + ТекущийМаркер = Маркер; + + Если Нумерация Тогда + ТекущийМаркер = ТекущийМаркер + OPI_Инструменты.ЧислоВСтроку(Н); + КонецЕсли; + + Параметры.Добавить(ТекущийМаркер); + КонецЦикла; ТекстSQL = СтрШаблон(ШаблонSQL @@ -530,6 +607,34 @@ КонецФункции +Функция СформироватьТекстCreateDatabase(Знач Схема) + + ПроверитьОбязательныеПоляСхемы(Схема, "database"); + + База = Схема["database"]; + + ШаблонSQL = "CREATE DATABASE %1"; + + ТекстSQL = СтрШаблон(ШаблонSQL, База); + + Возврат ТекстSQL; + +КонецФункции + +Функция СформироватьТекстDropDatabase(Знач Схема) + + ПроверитьОбязательныеПоляСхемы(Схема, "database"); + + База = Схема["database"]; + + ШаблонSQL = "DROP DATABASE %1"; + + ТекстSQL = СтрШаблон(ШаблонSQL, База); + + Возврат ТекстSQL; + +КонецФункции + #КонецОбласти #Область Вспомогательные @@ -634,7 +739,9 @@ МассивПолей = Новый Массив; МассивЗначений = Новый Массив; - Схема = ПустаяСхемаSQL("INSERT"); + Особенности = Модуль.ПолучитьОсобенности(); + + Схема = ПустаяСхемаSQL("INSERT", Особенности); УстановитьИмяТаблицы(Схема, Таблица); РазделитьКоллекциюДанных(Запись, МассивПолей, МассивЗначений); @@ -751,9 +858,10 @@ OPI_ПреобразованиеТипов.ПолучитьСтроку(База); OPI_Инструменты.ВернутьУправляющиеПоследовательности(База); - Коннектор = ПодключитьКомпонентуНаСервере("OPI_SQLite"); + ИмяПоля = ПолучитьИмяОсновногоПоля(Коннектор); + Коннектор = ПодключитьКомпонентуНаСервере(Коннектор); - Коннектор.Database = База; + Коннектор[ИмяПоля] = База; Результат = Коннектор.Connect(); Результат = OPI_Инструменты.JsonВСтруктуру(Результат, Ложь); @@ -784,6 +892,16 @@ КонецФункции +Функция ПолучитьИмяОсновногоПоля(Знач Коннектор) + + Если Коннектор = "OPI_SQLite" Тогда + Возврат "Database"; + Иначе + Возврат "ConnectionString"; + КонецЕсли; + +КонецФункции + Процедура РазделитьКоллекциюДанных(Знач Запись, МассивПолей, МассивЗначений) ТекстОшибки = "Некорректный набор данных для обновления"; @@ -930,6 +1048,14 @@ КонецПроцедуры +Процедура УстановитьИмяБазы(Схема, Знач Имя) + + OPI_ПреобразованиеТипов.ПолучитьСтроку(Имя); + + Схема.Вставить("database", Имя); + +КонецПроцедуры + Процедура УстановитьЛимит(Схема, Знач Количество) OPI_ПреобразованиеТипов.ПолучитьЧисло(Количество); diff --git a/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl index c679dba0fd..044165f25d 100644 --- a/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl @@ -53,6 +53,7 @@ Разделы.Вставить("VK" , 5); Разделы.Вставить("Viber" , 5); Разделы.Вставить("Twitter" , 4); + Разделы.Вставить("PostgreSQL" , 5); Разделы.Вставить("SQLite" , 5); Разделы.Вставить("YandexDisk" , 5); Разделы.Вставить("GoogleWorkspace", 2); @@ -86,6 +87,7 @@ Разделы.Вставить("VK" , СтандартныеЗависимости); Разделы.Вставить("Viber" , СтандартныеЗависимости); Разделы.Вставить("Twitter" , СтандартныеЗависимости); + Разделы.Вставить("PostgreSQL" , СтандартныеЗависимости); Разделы.Вставить("SQLite" , СтандартныеЗависимости); Разделы.Вставить("YandexDisk" , СтандартныеЗависимости); Разделы.Вставить("GoogleWorkspace", СтандартныеЗависимости); @@ -133,6 +135,7 @@ S3_ = "S3"; TCP = "TCP"; SQLite = "SQLite"; + Postgres = "PostgreSQL"; ТаблицаТестов = Новый ТаблицаЗначений; ТаблицаТестов.Колонки.Добавить("Метод"); @@ -270,6 +273,7 @@ НовыйТест(ТаблицаТестов, "TC_Клиент" , "TCP Клиент" , TCP); НовыйТест(ТаблицаТестов, "SQLL_ОсновныеМетоды" , "Основные методы" , SQLite); НовыйТест(ТаблицаТестов, "SQLL_ORM" , "ORM" , SQLite); + НовыйТест(ТаблицаТестов, "Postgres_ORM" , "ORM" , Postgres); Возврат ТаблицаТестов; @@ -2386,15 +2390,7 @@ КонецЕсли; ТекущаяОпция = ОформитьОпцию(Опция.Значение, Опция.Ключ); - - Если Библиотека = "bitrix24" - И Опция.Ключ = "url" Тогда - - ТекущаяОпция = ?(СтрНайти(ТекущаяОпция, "rest") > 0 - , "https://b24-ar17wx.bitrix24.by/rest/1/***" - , ТекущаяОпция); - - КонецЕсли; + ОбработатьОсобенныеСекретыОпций(Библиотека, Опция.Ключ, ТекущаяОпция); МассивОпций.Добавить(ТекущаяОпция); @@ -2427,4 +2423,26 @@ КонецПроцедуры +Процедура ОбработатьОсобенныеСекретыОпций(Знач Библиотека, Знач Опция, Значение) + + Если Библиотека = "bitrix24" + И Опция = "url" Тогда + + Значение = ?(СтрНайти(Значение, "rest") > 0 + , "https://b24-ar17wx.bitrix24.by/rest/1/***" + , Значение); + + Возврат; + + КонецЕсли; + + Если Библиотека = "postgres" + И Опция = "conn" Тогда + + Значение = "postgresql://bayselonarrend:***@127.0.0.1:5432/"; + + КонецЕсли; + +КонецПроцедуры + #КонецОбласти diff --git a/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl index 5a08fb2d0f..d9f5fb81c7 100644 --- a/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl @@ -1,4 +1,4 @@ -// OneScript: ./OInt/tests/Modules/internal/OPI_Тесты.os +// OneScript: ./OInt/tests/Modules/internal/OPI_Тесты.os // MIT License @@ -2311,6 +2311,24 @@ #КонецОбласти +#Область PostgreSQL + +Процедура Postgres_ORM() Экспорт + + ПараметрыТеста = Новый Структура; + OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("PG_IP", ПараметрыТеста); + OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("PG_Password", ПараметрыТеста); + OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("Picture", ПараметрыТеста); + + PostgreSQL_СоздатьБазуДанных(ПараметрыТеста); + PostgreSQL_СоздатьТаблицу(ПараметрыТеста); + PostgreSQL_ДобавитьЗаписи(ПараметрыТеста); + PostgreSQL_УдалитьБазуДанных(ПараметрыТеста); + +КонецПроцедуры + +#КонецОбласти + #КонецОбласти #КонецОбласти @@ -17274,6 +17292,129 @@ #КонецОбласти +#Область PostgreSQL + +Процедура PostgreSQL_СоздатьБазуДанных(ПараметрыФункции) + + Адрес = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + База = "postgres"; + + СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль); + + База = "testbase1"; + + OPI_PostgreSQL.УдалитьБазуДанных(База, СтрокаПодключения); // SKIP + + Результат = OPI_PostgreSQL.СоздатьБазуДанных(База, СтрокаПодключения); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "СоздатьБазуДанных", "PostgreSQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + +КонецПроцедуры + +Процедура PostgreSQL_УдалитьБазуДанных(ПараметрыФункции) + + Адрес = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + База = "postgres"; + + СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль); + + База = "testbase1"; + + Результат = OPI_PostgreSQL.УдалитьБазуДанных(База, СтрокаПодключения); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьБазуДанных", "PostgreSQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + +КонецПроцедуры + +Процедура PostgreSQL_СоздатьТаблицу(ПараметрыФункции) + + Адрес = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + База = "testbase1"; + + СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль); + + Таблица = "testtable"; + + СтруктураКолонок = Новый Структура; + СтруктураКолонок.Вставить("bool_field", "BOOL"); + СтруктураКолонок.Вставить("char_field", """char"""); + СтруктураКолонок.Вставить("smallint_field", "SMALLINT"); + СтруктураКолонок.Вставить("int_field", "INT"); + СтруктураКолонок.Вставить("oid_field", "OID"); + СтруктураКолонок.Вставить("bigint_field", "BIGINT"); + СтруктураКолонок.Вставить("real_field", "REAL"); + СтруктураКолонок.Вставить("dp_field", "DOUBLE PRECISION"); + СтруктураКолонок.Вставить("text_field", "TEXT"); + СтруктураКолонок.Вставить("bytea_field", "BYTEA"); + СтруктураКолонок.Вставить("ts_field", "TIMESTAMP"); + СтруктураКолонок.Вставить("ip_field", "INET"); + + Результат = OPI_PostgreSQL.СоздатьТаблицу(Таблица, СтруктураКолонок, СтрокаПодключения); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "СоздатьТаблицу", "PostgreSQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + +КонецПроцедуры + +Процедура PostgreSQL_ДобавитьЗаписи(ПараметрыФункции) + + Адрес = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + База = "testbase1"; + + СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль); + + Таблица = "testtable"; + + Картинка = ПараметрыФункции["Picture"]; + OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Картинка); // Картинка - Тип: ДвоичныеДанные + + Char = Новый Соответствие; + Char.Вставить("""char""", 1); + + DP = Новый Соответствие; + DP.Вставить("DOUBLE PRECISION", 1.0000000000000002); + + СтруктураЗаписи = Новый Структура; + СтруктураЗаписи.Вставить("bool_field" , Новый Структура("BOOL", Истина)); + СтруктураЗаписи.Вставить("char_field" , Char); + СтруктураЗаписи.Вставить("smallint_field", Новый Структура("SMALLINT", 5)); + СтруктураЗаписи.Вставить("int_field" , Новый Структура("INT", 100)); + СтруктураЗаписи.Вставить("oid_field" , Новый Структура("OID", 24576)); + СтруктураЗаписи.Вставить("bigint_field" , Новый Структура("BIGINT", 9999999)); + СтруктураЗаписи.Вставить("real_field" , Новый Структура("REAL", 15.2)); + СтруктураЗаписи.Вставить("dp_field" , DP); + СтруктураЗаписи.Вставить("text_field" , Новый Структура("TEXT", "Some text")); + СтруктураЗаписи.Вставить("bytea_field" , Новый Структура("BYTEA", Картинка)); + СтруктураЗаписи.Вставить("ts_field" , Новый Структура("TIMESTAMP", 1739207915)); + СтруктураЗаписи.Вставить("ip_field" , Новый Структура("INET", "127.0.0.1")); + + Результат = OPI_PostgreSQL.ДобавитьЗаписи(Таблица, СтруктураЗаписи, Ложь, СтрокаПодключения); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ДобавитьЗаписи", "PostgreSQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + +КонецПроцедуры + +#КонецОбласти + #КонецОбласти #КонецОбласти diff --git a/src/ru/OPI/src/CommonTemplates/OPI_PostgreSQL/Template.addin b/src/ru/OPI/src/CommonTemplates/OPI_PostgreSQL/Template.addin index 13766143c9..c625e49d57 100644 Binary files a/src/ru/OPI/src/CommonTemplates/OPI_PostgreSQL/Template.addin and b/src/ru/OPI/src/CommonTemplates/OPI_PostgreSQL/Template.addin differ diff --git a/src/ru/OPI/src/Configuration/Configuration.mdo b/src/ru/OPI/src/Configuration/Configuration.mdo index 23b3fbfae6..14954d4555 100644 --- a/src/ru/OPI/src/Configuration/Configuration.mdo +++ b/src/ru/OPI/src/Configuration/Configuration.mdo @@ -53,6 +53,7 @@ CommonModule.OPI_Neocities CommonModule.OPI_Notion CommonModule.OPI_Ozon + CommonModule.OPI_PostgreSQL CommonModule.OPI_Slack CommonModule.OPI_SQLite CommonModule.OPI_S3