From 99f69ecfdbb2591a0fa6917c6bb4bf7ae4fcda5f Mon Sep 17 00:00:00 2001 From: Anton Titovets Date: Thu, 3 Apr 2025 21:45:52 +0300 Subject: [PATCH] =?UTF-8?q?MYSQL:=20=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B8=20=D0=B8=20=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/addins/mysql/Cargo.lock | 1 + src/addins/mysql/Cargo.toml | 3 +- src/addins/mysql/dependencies.log | 18 +- src/addins/mysql/src/component/methods.rs | 40 +- src/addins/sqlite/dependencies.log | 12 +- src/addins/sqlite/src/component/mod.rs | 8 +- .../src/CommonModules/OPI_Тесты/Module.bsl | 399 +++++++++++++++++- .../src/CommonModules/OPI_ТестыCLI/Module.bsl | 186 ++++++++ 8 files changed, 631 insertions(+), 36 deletions(-) diff --git a/src/addins/mysql/Cargo.lock b/src/addins/mysql/Cargo.lock index e42ab0d094..1b3c9c4fcc 100644 --- a/src/addins/mysql/Cargo.lock +++ b/src/addins/mysql/Cargo.lock @@ -853,6 +853,7 @@ dependencies = [ "base64", "chrono", "mysql", + "mysql_common", "serde_json", ] diff --git a/src/addins/mysql/Cargo.toml b/src/addins/mysql/Cargo.toml index 3d34f6850b..c631aaaf2d 100644 --- a/src/addins/mysql/Cargo.toml +++ b/src/addins/mysql/Cargo.toml @@ -18,4 +18,5 @@ addin1c = "0.5.0" mysql = { version = "26.0.0", features = ["time", "chrono", "native-tls"] } serde_json = "1.0" base64 = "0.22.1" -chrono = "0.4.40" \ No newline at end of file +chrono = "0.4.40" +mysql_common = "0.34.1" \ No newline at end of file diff --git a/src/addins/mysql/dependencies.log b/src/addins/mysql/dependencies.log index e183ef3f78..4dd2ef67fc 100644 --- a/src/addins/mysql/dependencies.log +++ b/src/addins/mysql/dependencies.log @@ -1,13 +1,13 @@ "MAIN ---" - linux-vdso.so.1 (0x00007ffeac7c5000) - libssl.so.3 => /lib64/libssl.so.3 (0x00007f9e7b4ff000) - libcrypto.so.3 => /lib64/libcrypto.so.3 (0x00007f9e7adea000) - libm.so.6 => /lib64/libm.so.6 (0x00007f9e7aa68000) - libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f9e7a848000) - libc.so.6 => /lib64/libc.so.6 (0x00007f9e7a471000) - libdl.so.2 => /lib64/libdl.so.2 (0x00007f9e7a26d000) - /lib64/ld-linux-x86-64.so.2 (0x00007f9e7ba15000) - libz.so.1 => /lib64/libz.so.1 (0x00007f9e7a055000) + linux-vdso.so.1 (0x00007fffc755a000) + libssl.so.3 => /lib64/libssl.so.3 (0x00007fb2cf7d6000) + libcrypto.so.3 => /lib64/libcrypto.so.3 (0x00007fb2cf0c1000) + libm.so.6 => /lib64/libm.so.6 (0x00007fb2ced3f000) + libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fb2ceb1f000) + libc.so.6 => /lib64/libc.so.6 (0x00007fb2ce748000) + libdl.so.2 => /lib64/libdl.so.2 (0x00007fb2ce544000) + /lib64/ld-linux-x86-64.so.2 (0x00007fb2cfcec000) + libz.so.1 => /lib64/libz.so.1 (0x00007fb2ce32c000) GLIBC_2.2.5 GLIBC_2.3 GLIBC_2.3.4 diff --git a/src/addins/mysql/src/component/methods.rs b/src/addins/mysql/src/component/methods.rs index 07434c0956..01923ce0ab 100644 --- a/src/addins/mysql/src/component/methods.rs +++ b/src/addins/mysql/src/component/methods.rs @@ -4,7 +4,7 @@ use base64::{engine::general_purpose, Engine as _}; use mysql::prelude::Queryable; use std::collections::HashMap; use chrono::*; -use mysql::consts::ColumnType; +use mysql_common::packets::Column; pub fn execute_query( client: &mut component::AddIn, @@ -70,8 +70,7 @@ fn rows_to_json_array(rows: &mut Vec) -> String { let value: Value = match row.get::, usize>(i) { Some(mysql_value) => match mysql_value { Some(value) => { - let column_type = column.column_type(); - from_sql_to_json(value, &column_type) + from_sql_to_json(value, &column) }, None => Value::Null }, @@ -89,14 +88,14 @@ fn rows_to_json_array(rows: &mut Vec) -> String { json!({ "result": true, "data": json_array }).to_string() } -fn from_sql_to_json(value: mysql::Value, column_type: &ColumnType) -> Value { +fn from_sql_to_json(value: mysql::Value, column: &Column) -> Value { match value { mysql::Value::NULL => Value::Null, mysql::Value::Int(i) => Value::Number(i.into()), mysql::Value::Double(d) => serde_json::Number::from_f64(d).map(Value::Number).unwrap_or(Value::Null), mysql::Value::Float(f) => serde_json::Number::from_f64(f as f64).map(Value::Number).unwrap_or(Value::Null), mysql::Value::UInt(i) => serde_json::Number::from_f64(i as f64).map(Value::Number).unwrap_or(Value::Null), - mysql::Value::Bytes(b) => process_bytes(b, column_type), + mysql::Value::Bytes(b) => process_bytes(b, column), mysql::Value::Date(year, month, day, hour, minute, second, micros) => { // Создаем дату и время let date = NaiveDate::from_ymd_opt(year as i32, month as u32, day as u32) @@ -123,12 +122,12 @@ fn from_sql_to_json(value: mysql::Value, column_type: &ColumnType) -> Value { } } -fn process_bytes(bytes: Vec, column_type: &ColumnType) -> Value { +fn process_bytes(bytes: Vec, column: &Column) -> Value { - if is_text_type(column_type) { + if is_text_type(column) { match String::from_utf8(bytes.clone()) { Ok(text) => Value::String(text), - Err(_) => encode_to_base64(bytes), + Err(e) => Value::String(e.to_string()), } } else { encode_to_base64(bytes) @@ -142,14 +141,25 @@ fn encode_to_base64(bytes: Vec) -> Value { Value::Object(blob_object) } -fn is_text_type(column_type: &ColumnType) -> bool { +fn is_text_type(column: &Column) -> bool { + use mysql::consts::ColumnType; // или mysql_async::consts::ColumnType - if column_type.is_character_type() && column_type != &ColumnType::MYSQL_TYPE_BLOB { - true - } else if column_type.is_enum_or_set_type() { - true - } else { - false + let column_type = column.column_type(); + + match column.column_type() { + // Обычные строковые типы + ColumnType::MYSQL_TYPE_STRING + | ColumnType::MYSQL_TYPE_VAR_STRING + | ColumnType::MYSQL_TYPE_VARCHAR => true, + + // BLOB — только если charset не binary (63) + ColumnType::MYSQL_TYPE_BLOB => column.character_set() != 63, + + // ENUM/SET — текстовые + _ if column_type.is_enum_or_set_type() => true, + + // Остальные (включая TINYBLOB/MEDIUMBLOB/LONGBLOB) — не текстовые + _ => false, } } diff --git a/src/addins/sqlite/dependencies.log b/src/addins/sqlite/dependencies.log index 4ade8cbf8b..f705731b4c 100644 --- a/src/addins/sqlite/dependencies.log +++ b/src/addins/sqlite/dependencies.log @@ -1,10 +1,10 @@ "MAIN ---" - linux-vdso.so.1 (0x00007ffe4a1fc000) - libm.so.6 => /lib64/libm.so.6 (0x00007fcb64aeb000) - libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fcb648cb000) - libc.so.6 => /lib64/libc.so.6 (0x00007fcb644f4000) - libdl.so.2 => /lib64/libdl.so.2 (0x00007fcb642f0000) - /lib64/ld-linux-x86-64.so.2 (0x00007fcb64e6d000) + linux-vdso.so.1 (0x00007ffc9fb72000) + libm.so.6 => /lib64/libm.so.6 (0x00007f4f57c7f000) + libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f4f57a5f000) + libc.so.6 => /lib64/libc.so.6 (0x00007f4f57688000) + libdl.so.2 => /lib64/libdl.so.2 (0x00007f4f57484000) + /lib64/ld-linux-x86-64.so.2 (0x00007f4f58001000) GLIBC_2.2.5 GLIBC_2.3 GLIBC_2.3.4 diff --git a/src/addins/sqlite/src/component/mod.rs b/src/addins/sqlite/src/component/mod.rs index b7e0727b4f..7345640708 100644 --- a/src/addins/sqlite/src/component/mod.rs +++ b/src/addins/sqlite/src/component/mod.rs @@ -2,7 +2,7 @@ mod methods; use addin1c::{name, Variant}; use crate::core::getset; -use rusqlite::{Connection}; +use rusqlite::{Connection, OpenFlags}; use serde_json::json; // МЕТОДЫ КОМПОНЕНТЫ ------------------------------------------------------------------------------- @@ -82,7 +82,11 @@ impl AddIn { let conn_result = if self.connection_string.is_empty() { Connection::open_in_memory() } else { - Connection::open(&self.connection_string) + let flags = OpenFlags::SQLITE_OPEN_READ_WRITE + | OpenFlags::SQLITE_OPEN_CREATE + | OpenFlags::SQLITE_OPEN_URI + | OpenFlags::SQLITE_OPEN_NO_MUTEX; + Connection::open_with_flags(&self.connection_string, flags) }; match conn_result { diff --git a/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl index 8b1056851f..7d39b34cd9 100644 --- a/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl @@ -2414,6 +2414,13 @@ MySQL_СоздатьБазуДанных(ПараметрыТеста); MySQL_СоздатьТаблицу(ПараметрыТеста); MySQL_ДобавитьЗаписи(ПараметрыТеста); + MySQL_ПолучитьЗаписи(ПараметрыТеста); + MySQL_ОбновитьЗаписи(ПараметрыТеста); + MySQL_УдалитьЗаписи(ПараметрыТеста); + MySQL_ОчиститьТаблицу(ПараметрыТеста); + MySQL_УдалитьТаблицу(ПараметрыТеста); + MySQL_УдалитьБазуДанных(ПараметрыТеста); + MySQL_ПолучитьСтруктуруФильтраЗаписей(ПараметрыТеста); КонецПроцедуры @@ -18086,12 +18093,11 @@ Результат = OPI_PostgreSQL.ПолучитьЗаписи(Таблица, , , , , СтрокаПодключения); Если ЗначениеЗаполнено(Результат["data"]) Тогда // SKIP - Результат["data"][0]["bytea_field"]["BYTEA"] // SKIP - = Лев(Результат["data"][0]["bytea_field"]["BYTEA"], 10) + "..."; // SKIP + Результат["data"][0]["bytea_field"]["BYTEA"] = Лев(Результат["data"][0]["bytea_field"]["BYTEA"], 10) + "..."; // SKIP КонецЕсли; // SKIP OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьЗаписи", "PostgreSQL"); // SKIP - OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); // SKIP + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); // SKIP // Отборы, выбранные поля, количество и сортировка @@ -18701,6 +18707,7 @@ OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ВыполнитьЗапросSQL", "MySQL"); // SKIP OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); // SKIP OPI_ПолучениеДанныхТестов.Проверка_Равенство(Base64Значение(Blob).Размер(), Картинка.Размер()); // SKIP + OPI_MySQL.ВыполнитьЗапросSQL("create table TEST_DATA (id INT,first_name VARCHAR(50),last_name VARCHAR(50),email VARCHAR(50),gender VARCHAR(50),ip_address VARCHAR(20));", , , Соединение); // SKIP // SQL запрос из файла @@ -18916,6 +18923,392 @@ КонецПроцедуры +Процедура MySQL_ПолучитьЗаписи(ПараметрыФункции) + + Адрес = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + База = "testbase1"; + + СтрокаПодключения = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль); + + // Все записи без отборов + + Таблица = "testtable"; + + // При использовании строки подключения инициализируется новое соединение, + // которое будет закрыто после выполнения функции. + // В случае выполнения нескольких операций желательно использовать одно соединение, + // заранее созданное функцией ОткрытьСоединение() + Результат = OPI_MySQL.ПолучитьЗаписи(Таблица, , , , , СтрокаПодключения); + + Если ЗначениеЗаполнено(Результат["data"]) Тогда // SKIP + Результат["data"][0]["mediumblob_field"]["BYTES"] = Лев(Результат["data"][0]["mediumblob_field"]["BYTES"], 10) + "..."; // SKIP + КонецЕсли; // SKIP + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьЗаписи", "MySQL"); // SKIP + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); // SKIP + + // Отборы, выбранные поля, количество и сортировка + + СтрокаПодключения = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, "test_data", Логин, Пароль); + + Таблица = "test_data"; + + Поля = Новый Массив; + Поля.Добавить("first_name"); + Поля.Добавить("last_name"); + Поля.Добавить("email"); + + Фильтры = Новый Массив; + + СтруктураФильтра1 = Новый Структура; + + СтруктураФильтра1.Вставить("field", "gender"); + СтруктураФильтра1.Вставить("type" , "="); + СтруктураФильтра1.Вставить("value", "Male"); + СтруктураФильтра1.Вставить("union", "AND"); + СтруктураФильтра1.Вставить("raw" , Ложь); + + СтруктураФильтра2 = Новый Структура; + + СтруктураФильтра2.Вставить("field", "id"); + СтруктураФильтра2.Вставить("type" , "BETWEEN"); + СтруктураФильтра2.Вставить("value", "20 AND 50"); + СтруктураФильтра2.Вставить("raw" , Истина); + + Фильтры.Добавить(СтруктураФильтра1); + Фильтры.Добавить(СтруктураФильтра2); + + Сортировка = Новый Структура("ip_address", "DESC"); + Количество = 5; + + Результат = OPI_MySQL.ПолучитьЗаписи(Таблица, Поля, Фильтры, Сортировка, Количество, СтрокаПодключения); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьЗаписи (отборы)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + OPI_ПолучениеДанныхТестов.Проверка_Массив(Результат["data"], 5); + + Адрес = "api.athenaeum.digital"; + Порт = "3307"; + + СтрокаПодключенияTLS = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль, Порт); + НастройкиTLS = OPI_MySQL.ПолучитьНастройкиTls(Ложь); + + Таблица = "testtable"; + + Результат = OPI_MySQL.ПолучитьЗаписи(Таблица, , , , , СтрокаПодключенияTLS, НастройкиTLS); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьЗаписи (TLS)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + OPI_ПолучениеДанныхТестов.Проверка_Массив(Результат["data"]); + +КонецПроцедуры + +Процедура MySQL_ОбновитьЗаписи(ПараметрыФункции) + + Адрес = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + База = "test_data"; + + СтрокаПодключения = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль); + + Таблица = "test_data"; + + СтруктураПолей = Новый Структура; + СтруктураПолей.Вставить("ip_address", Новый Структура("VARCHAR", "127.0.0.1")); + + Фильтры = Новый Массив; + + СтруктураФильтра = Новый Структура; + + СтруктураФильтра.Вставить("field", "gender"); + СтруктураФильтра.Вставить("type" , "="); + СтруктураФильтра.Вставить("value", Новый Структура("VARCHAR", "Male")); + СтруктураФильтра.Вставить("raw" , Ложь); + + Фильтры.Добавить(СтруктураФильтра); + + Количество = OPI_MySQL.ПолучитьЗаписи(Таблица, , Фильтры, , , СтрокаПодключения); // SKIP + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Количество, "ОбновитьЗаписи (количество)", "MySQL"); // SKIP + Количество = Количество["data"].Количество(); // SKIP + + // При использовании строки подключения инициализируется новое соединение, + // которое будет закрыто после выполнения функции. + // В случае выполнения нескольких операций желательно использовать одно соединение, + // заранее созданное функцией ОткрытьСоединение() + Результат = OPI_MySQL.ОбновитьЗаписи(Таблица, СтруктураПолей, СтруктураФильтра, СтрокаПодключения); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ОбновитьЗаписи", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + + Проверка = OPI_MySQL.ПолучитьЗаписи(Таблица, "['ip_address']", Фильтры, , , СтрокаПодключения); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Проверка, "ОбновитьЗаписи (проверка)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Проверка); + OPI_ПолучениеДанныхТестов.Проверка_Массив(Проверка["data"], Количество); + + Для Н = 0 По Проверка["data"].ВГраница() Цикл + OPI_ПолучениеДанныхТестов.Проверка_SQLiteЗначенияПолей(Проверка["data"][Н], СтруктураПолей); + КонецЦикла; + + Адрес = "api.athenaeum.digital"; + Порт = "3307"; + + СтруктураПолей = Новый Структура; + СтруктураПолей.Вставить("varchar_field", Новый Структура("VARCHAR", "Another varchar")); + + СтрокаПодключенияTLS = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, "testbase1", Логин, Пароль, Порт); + НастройкиTLS = OPI_MySQL.ПолучитьНастройкиTls(Ложь); + + Результат = OPI_MySQL.ОбновитьЗаписи("testtable", СтруктураПолей, , СтрокаПодключенияTLS, НастройкиTLS); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ОбновитьЗаписи (TLS)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + +КонецПроцедуры + +Процедура MySQL_УдалитьЗаписи(ПараметрыФункции) + + Адрес = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + База = "test_data"; + + СтрокаПодключения = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль); + + Таблица = "test_data"; + + Фильтры = Новый Массив; + + СтруктураФильтра = Новый Структура; + + СтруктураФильтра.Вставить("field", "gender"); + СтруктураФильтра.Вставить("type" , "="); + СтруктураФильтра.Вставить("value", Новый Структура("VARCHAR", "Male")); + СтруктураФильтра.Вставить("raw" , Ложь); + СтруктураФильтра.Вставить("union", "AND"); + + Фильтры.Добавить(СтруктураФильтра); + + СтруктураФильтра = Новый Структура; + + СтруктураФильтра.Вставить("field", "ip_address"); + СтруктураФильтра.Вставить("type" , "="); + СтруктураФильтра.Вставить("value", Новый Структура("VARCHAR", "127.0.0.1")); + СтруктураФильтра.Вставить("raw" , Ложь); + + Получение = OPI_MySQL.ПолучитьЗаписи(Таблица, , Фильтры, , , СтрокаПодключения); // SKIP + + // При использовании строки подключения инициализируется новое соединение, + // которое будет закрыто после выполнения функции. + // В случае выполнения нескольких операций желательно использовать одно соединение, + // заранее созданное функцией ОткрытьСоединение() + Результат = OPI_MySQL.УдалитьЗаписи(Таблица, Фильтры, СтрокаПодключения); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Получение, "УдалитьЗаписи (получение)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + + Количество = Получение["data"].Количество(); + Остаток = 100 - Количество; + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьЗаписи", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + + Результат = OPI_MySQL.ПолучитьЗаписи(Таблица, , , , , СтрокаПодключения); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьЗаписи (проверка)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + OPI_ПолучениеДанныхТестов.Проверка_Массив(Результат["data"], Остаток); + + Адрес = "api.athenaeum.digital"; + Порт = "3307"; + + СтрокаПодключенияTLS = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, "testbase1", Логин, Пароль, Порт); + НастройкиTLS = OPI_MySQL.ПолучитьНастройкиTls(Ложь); + + Результат = OPI_MySQL.УдалитьЗаписи("testtable", , СтрокаПодключенияTLS, НастройкиTLS); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьЗаписи (TLS)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + +КонецПроцедуры + +Процедура MySQL_УдалитьТаблицу(ПараметрыФункции) + + Адрес = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + База = "testbase1"; + + СтрокаПодключения = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль); + + Таблица = "testtable"; + + // При использовании строки подключения инициализируется новое соединение, + // которое будет закрыто после выполнения функции. + // В случае выполнения нескольких операций желательно использовать одно соединение, + // заранее созданное функцией ОткрытьСоединение() + Результат = OPI_MySQL.УдалитьТаблицу(Таблица, СтрокаПодключения); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьТаблицу", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + + Адрес = "api.athenaeum.digital"; + Порт = "3307"; + + СтрокаПодключенияTLS = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль, Порт); + НастройкиTLS = OPI_MySQL.ПолучитьНастройкиTls(Ложь); + + Результат = OPI_MySQL.УдалитьТаблицу(Таблица, СтрокаПодключенияTLS, НастройкиTLS); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьТаблицу (TLS)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + + База = "test_data"; + Таблица = "test_data"; + + СтрокаПодключения = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль); + Результат = OPI_MySQL.УдалитьТаблицу(Таблица, СтрокаПодключения); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьТаблицу (тест)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + +КонецПроцедуры + +Процедура MySQL_УдалитьБазуДанных(ПараметрыФункции) + + Адрес = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + База = ""; + + СтрокаПодключения = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль); + + База = "testbase1"; + + // При использовании строки подключения инициализируется новое соединение, + // которое будет закрыто после выполнения функции. + // В случае выполнения нескольких операций желательно использовать одно соединение, + // заранее созданное функцией ОткрытьСоединение() + Результат = OPI_MySQL.УдалитьБазуДанных(База, СтрокаПодключения); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьБазуДанных", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + + База = "testbase2"; + + Подключение = OPI_MySQL.ОткрытьСоединение(СтрокаПодключения); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Подключение, "УдалитьБазуДанных (открытие)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_Компонента(Подключение, "AddIn.OPI_MySQL.Main"); + + Результат = OPI_MySQL.УдалитьБазуДанных(База, Подключение); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьБазуДанных (подключение)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + + Результат = OPI_MySQL.УдалитьБазуДанных(База, Подключение); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьБазуДанных (ошибка)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатЛожь(Результат); + + Закрытие = OPI_MySQL.ЗакрытьСоединение(Подключение); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Закрытие, "УдалитьБазуДанных (закрытие)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Закрытие); + + Результат = OPI_MySQL.УдалитьБазуДанных(База, Подключение); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьБазуДанных (ошибка подключения)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатЛожь(Результат); + + Адрес = "api.athenaeum.digital"; + Порт = "3307"; + + СтрокаПодключенияTLS = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, "", Логин, Пароль, Порт); + НастройкиTLS = OPI_MySQL.ПолучитьНастройкиTls(Ложь); + База = "testbase1"; + + Результат = OPI_MySQL.УдалитьБазуДанных(База, СтрокаПодключенияTLS, НастройкиTLS); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьБазуДанных (TLS)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + +КонецПроцедуры + +Процедура MySQL_ОчиститьТаблицу(ПараметрыФункции) + + Адрес = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + База = "testbase1"; + + СтрокаПодключения = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль); + + Таблица = "testtable"; + + // При использовании строки подключения инициализируется новое соединение, + // которое будет закрыто после выполнения функции. + // В случае выполнения нескольких операций желательно использовать одно соединение, + // заранее созданное функцией ОткрытьСоединение() + Результат = OPI_MySQL.ОчиститьТаблицу(Таблица, СтрокаПодключения); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ОчиститьТаблицу", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + + Адрес = "api.athenaeum.digital"; + Порт = "3307"; + + СтрокаПодключенияTLS = OPI_MySQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль, Порт); + НастройкиTLS = OPI_MySQL.ПолучитьНастройкиTls(Ложь); + + Результат = OPI_MySQL.ОчиститьТаблицу(Таблица, СтрокаПодключенияTLS, НастройкиTLS); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ОчиститьТаблицу (TLS)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + + Результат = OPI_MySQL.ПолучитьЗаписи(Таблица, , , , , СтрокаПодключения); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ОчиститьТаблицу (проверка)", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + OPI_ПолучениеДанныхТестов.Проверка_Массив(Результат["data"], 0); + +КонецПроцедуры + +Процедура MySQL_ПолучитьСтруктуруФильтраЗаписей(ПараметрыФункции) + + Результат = OPI_MySQL.ПолучитьСтруктуруФильтраЗаписей(); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьСтруктуруФильтраЗаписей", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_Структура(Результат); + + Результат = OPI_MySQL.ПолучитьСтруктуруФильтраЗаписей(Истина); + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьСтруктуруФильтраЗаписей (пустая)", "MySQL"); + + Для Каждого Элемент Из Результат Цикл + + OPI_ПолучениеДанныхТестов.Проверка_Пусто(Элемент.Значение); + + КонецЦикла; + +КонецПроцедуры + #КонецОбласти #Область GreenAPI diff --git a/src/ru/OPI/src/CommonModules/OPI_ТестыCLI/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_ТестыCLI/Module.bsl index 5fc05f75c7..29bac65c1f 100644 --- a/src/ru/OPI/src/CommonModules/OPI_ТестыCLI/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_ТестыCLI/Module.bsl @@ -2347,6 +2347,23 @@ #КонецОбласти +#Область MySQL + +Процедура CLI_MYS_ОсновныеМетоды() Экспорт + + ПараметрыТеста = Новый Структура; + OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("PG_IP" , ПараметрыТеста); + OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("PG_Password", ПараметрыТеста); + OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("Picture" , ПараметрыТеста); + OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("SQL2" , ПараметрыТеста); + + CLI_MySQL_СформироватьСтрокуПодключения(ПараметрыТеста); + CLI_MySQL_ВыполнитьЗапросSQL(ПараметрыТеста); + +КонецПроцедуры + +#КонецОбласти + #Область GreenAPI Процедура CLI_GAPI_Аккаунт() Экспорт @@ -20459,6 +20476,175 @@ #КонецОбласти +#Область MySQL + +Процедура CLI_MySQL_СформироватьСтрокуПодключения(ПараметрыФункции) + + Адрес = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + База = ""; + + Опции = Новый Структура; + Опции.Вставить("addr" , Адрес); + Опции.Вставить("db" , База); + Опции.Вставить("login", Логин); + Опции.Вставить("pass" , Пароль); + + Результат = OPI_ПолучениеДанныхТестов.ВыполнитьТестCLI("mysql", "СформироватьСтрокуПодключения", Опции); + Результат = ПолучитьСтрокуИзДвоичныхДанных(Результат); + + Результат = СтрЗаменить(Результат, Пароль, "***"); + Результат = СтрЗаменить(Результат, Адрес , "127.0.0.1"); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "СформироватьСтрокуПодключения", "MySQL"); + OPI_ПолучениеДанныхТестов.Проверка_Строка(Результат); + +КонецПроцедуры + +Процедура CLI_MySQL_ВыполнитьЗапросSQL(ПараметрыФункции) + + Картинка = ПараметрыФункции["Picture"]; + ИВФ = ПолучитьИмяВременногоФайла(); + OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Картинка); + Картинка.Записать(ИВФ); + + Адрес = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + База = "test_data"; + + Опции = Новый Структура; + Опции.Вставить("addr" , Адрес); + Опции.Вставить("db" , База); + Опции.Вставить("login", Логин); + Опции.Вставить("pass" , Пароль); + + СтрокаПодключения = OPI_ПолучениеДанныхТестов.ВыполнитьТестCLI("mysql", "СформироватьСтрокуПодключения", Опции, Ложь); + СтрокаПодключения = ПолучитьСтрокуИзДвоичныхДанных(СтрокаПодключения); + + Опции = Новый Структура(); + Опции.Вставить("dbc" , СтрокаПодключения); + + Опции.Вставить("table", "users"); + OPI_ПолучениеДанныхТестов.ВыполнитьТестCLI("mysql", "УдалитьТаблицу", Опции, Ложь); + + Опции.Вставить("table", "test_data"); + OPI_ПолучениеДанныхТестов.ВыполнитьТестCLI("mysql", "УдалитьТаблицу", Опции, Ложь); + + Опции.Вставить("table", "test_table"); + OPI_ПолучениеДанныхТестов.ВыполнитьТестCLI("mysql", "УдалитьТаблицу", Опции, Ложь); + + // CREATE + + ТекстЗапроса = " + |CREATE TABLE test_table ( + |id SERIAL PRIMARY KEY, + |name NAME, + |age INT, + |salary REAL, + |is_active BOOL, + |created_at DATE, + |data BYTEA + |);"; + + Опции = Новый Структура; + Опции.Вставить("sql" , СтрЗаменить(ТекстЗапроса, Символы.ПС, " ")); + Опции.Вставить("dbc" , СтрокаПодключения); + + Результат = OPI_ПолучениеДанныхТестов.ВыполнитьТестCLI("mysql", "ВыполнитьЗапросSQL", Опции, Ложь); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛогCLI(Результат, "ВыполнитьЗапросSQL (Create)", "MySQL"); // SKIP + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); // SKIP + + // INSERT с параметрами + + ТекстЗапроса = " + |INSERT INTO test_table (name, age, salary, is_active, created_at, data) + |VALUES ($1, $2, $3, $4, $5, $6);"; + + МассивПараметров = Новый Массив; + МассивПараметров.Добавить(Новый Структура("NAME" , "Vitaly")); + МассивПараметров.Добавить(Новый Структура("INT" , 25)); + МассивПараметров.Добавить(Новый Структура("REAL" , 1000.12)); + МассивПараметров.Добавить(Новый Структура("BOOL" , Истина)); + МассивПараметров.Добавить(Новый Структура("DATE" , OPI_Инструменты.ПолучитьТекущуюДату())); + МассивПараметров.Добавить(Новый Структура("BYTEA", ИВФ)); + + Опции = Новый Структура; + Опции.Вставить("sql" , СтрЗаменить(ТекстЗапроса, Символы.ПС, " ")); + Опции.Вставить("params", МассивПараметров); + Опции.Вставить("dbc" , СтрокаПодключения); + + Результат = OPI_ПолучениеДанныхТестов.ВыполнитьТестCLI("mysql", "ВыполнитьЗапросSQL", Опции, Ложь); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛогCLI(Результат, "ВыполнитьЗапросSQL (Insert)", "MySQL"); // SKIP + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); // SKIP + + // SELECT (Результат этого запроса приведен в следующем блоке) + + ТекстЗапроса = "SELECT id, name, age, salary, is_active, created_at, data FROM test_table;"; + + Опции = Новый Структура; + Опции.Вставить("sql" , СтрЗаменить(ТекстЗапроса, Символы.ПС, " ")); + Опции.Вставить("dbc" , СтрокаПодключения); + + Результат = OPI_ПолучениеДанныхТестов.ВыполнитьТестCLI("mysql", "ВыполнитьЗапросSQL", Опции, Ложь); + + Blob = Результат["data"][0]["data"]["BYTES"]; // SKIP + + Результат["data"][0]["data"]["BYTES"] = "Base64"; // SKIP + OPI_ПолучениеДанныхТестов.ЗаписатьЛогCLI(Результат, "ВыполнитьЗапросSQL", "MySQL"); // SKIP + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); // SKIP + OPI_ПолучениеДанныхТестов.Проверка_Равенство(Base64Значение(Blob).Размер(), Картинка.Размер()); // SKIP + + // DO + Транзакция + + ТекстЗапроса = "DO $$ + |BEGIN + | CREATE TABLE users ( + | id SMALLSERIAL, + | name TEXT NOT NULL, + | age INT NOT NULL + | ); + | INSERT INTO users (name, age) VALUES ('Alice', 30); + | INSERT INTO users (name, age) VALUES ('Bob', 25); + | INSERT INTO users (name, age) VALUES ('Charlie', 35); + | COMMIT; + |END $$ LANGUAGE plpgsql;"; + + Опции = Новый Структура; + Опции.Вставить("sql" , СтрЗаменить(ТекстЗапроса, Символы.ПС, " ")); + Опции.Вставить("dbc" , СтрокаПодключения); + + Результат = OPI_ПолучениеДанныхТестов.ВыполнитьТестCLI("mysql", "ВыполнитьЗапросSQL", Опции, Ложь); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛогCLI(Результат, "ВыполнитьЗапросSQL (Transaction)", "MySQL"); // SKIP + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); // SKIP + + // SQL запрос из файла + + ФайлSQL = ПараметрыФункции["SQL2"]; // Двоичные данные, URL или путь к файлу + + Опции = Новый Структура; + Опции.Вставить("sql" , ФайлSQL); + Опции.Вставить("dbc" , СтрокаПодключения); + + Результат = OPI_ПолучениеДанныхТестов.ВыполнитьТестCLI("mysql", "ВыполнитьЗапросSQL", Опции); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛогCLI(Результат, "ВыполнитьЗапросSQL (файл)", "MySQL"); // SKIP + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); // SKIP + + Попытка + УдалитьФайлы(ИВФ); + Исключение + OPI_ПолучениеДанныхТестов.ЗаписатьЛогCLI(ОписаниеОшибки(), "Ошибка удаления файла картинки", "MySQL"); + КонецПопытки; + +КонецПроцедуры + +#КонецОбласти + #Область GreenAPI Процедура CLI_GreenAPI_СформироватьПараметрыДоступа(ПараметрыФункции)