1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2025-03-25 21:39:21 +02:00

PG: Изменение обработки TIMESTAMP

This commit is contained in:
Anton Titovets 2025-02-15 22:52:56 +03:00
parent 84e96c61e7
commit 80e0daaebe
15 changed files with 6776 additions and 6687 deletions

View File

@ -15,9 +15,43 @@ sidebar_class_name: PostgreSQL
По умолчанию, все запросы SELECT возвращают массив выбранных данных, а остальные запросы - только `true` в поле `result` при успехе, либо `false` и текст ошибки в полях `result` и `error` соответственно. Для выполнения запросов, требующих возврата данных, но не являющихся запросами SELECT, в функции `ВыполнитьЗапросSQL()` есть параметр `ФорсироватьРезультат`
## Поля типа "BYTEA"
## Параметры запросов
Коннектор PostgreSQL поддерживает использование позиционных параметров. Все значения, передаваемые как при прямом выполнении запросов через функцию `ВыполнитьЗапросSQL()`, так и в ORM методах с установкой значений, вроде `ДобавитьЗаписи` и `ОбновитьЗаписи`, должный представлять из себя структуру вида `{'Тип данных': 'Значение'}`. Поддерживаются следующие типы данных:
| Тип | Поддержка | Синонимы | Допустимые типы 1С |
|-|-|-|-|
| BOOL | Реализовано, проверено | - | Булево |
| "char" | Реализовано, проверено | OLDCHAR | Число |
| SMALLINT | Реализовано, проверено | - | Число |
| SMALLSERIAL | Реализовано, проверено | - | Число |
| INT | Реализовано, проверено | - | Число |
| SERIAL | Реализовано, проверено | - | Число |
| BIGINT | Реализовано, проверено | - | Число |
| BIGSERIAL | Реализовано, проверено | - | Число |
| OID | Реализовано, проверено | - | Число |
| REAL | Реализовано, проверено | - | Число |
| DOUBLE PRECISION | Реализовано, проверено | DOUBLE_PRECISION | Число |
| VARCHAR | Реализовано, проверено | - | Строка |
| TEXT | Реализовано, проверено | - | Строка |
| CHAR | Реализовано, проверено | - | Строка |
| CITEXT | Реализовано, проверено | - | Строка |
| NAME | Реализовано, проверено | - | Строка |
| INET | Реализовано, проверено | - | Строка |
| UUID | Реализовано, проверено | - | Строка, УникальныйИдентификатор |
| TIMESTAMP | Реализовано, проверено | - | Дата, Строка (ISO 8601, RFC 3339) |
| TIMESTAMP WITH TIME ZONE | Реализовано, проверено | TIMESTAMP_WITH_TIME_ZONE | Дата (часовой пояс будет указан как UTC), Строка (RFC 3339) |
| DATE | Реализовано, проверено | - | Дата (с любым временем), Строка (ISO 8601, RFC 3339) |
| TIME | Реализовано, проверено | - | Дата (с любой датой), Строка (ISO 8601, RFC 3339) |
| BYTEA | Реализовано, проверено | - | ДвоичныеДанные, Путь к файлу, Base64 строка (все приводится к Base64 строке) |
| JSON | Реализовано, проверено | - | Массив, Структура, Соответствие |
| JSONB | Реализовано, проверено | - | Массив, Структура, Соответствие |
| LTREE | Реализовано, не проверено | - | Строка |
| LQUERY | Реализовано, не проверено | - | Строка |
| LTXTQUERY | Реализовано, не проверено | - | Строка |
| HSTORE | Реализовано, не проверено | - | Структура, Соответствие |
Данная библиотека умеет обрабатывать поля типа BYTEA (Двоичные данные)
## Совместимость

File diff suppressed because it is too large Load Diff

View File

@ -4,8 +4,7 @@ use base64::{engine::general_purpose, Engine as _};
use crate::component::AddIn;
use std::collections::HashMap;
use std::net::IpAddr;
use std::time::{SystemTime, UNIX_EPOCH};
use chrono::{NaiveDate, NaiveTime, Utc};
use chrono::{NaiveDate, NaiveTime, Utc, FixedOffset};
use uuid::Uuid;
pub fn execute_query(
@ -148,14 +147,20 @@ fn process_object(object: &Map<String, Value>) -> Result<Box<dyn ToSql + Sync>,
Box::new(map) as Box<dyn ToSql + Sync>
})
.ok_or_else(|| "Invalid object for HSTORE".to_string()),
"TIMESTAMP" | "TIMESTAMP WITH TIME ZONE" | "TIMESTAMP_WITH_TIME_ZONE" => value
.as_i64()
.map(|v| {
let duration = UNIX_EPOCH + std::time::Duration::from_millis(v as u64 * 1000);
let system_time = SystemTime::from(duration);
Box::new(system_time) as Box<dyn ToSql + Sync>
})
.ok_or_else(|| "Invalid value for TIMESTAMP".to_string()),
"TIMESTAMP" => {
let value_str = value.as_str().ok_or("Invalid value for TIMESTAMP")?;
match parse_date(&value_str){
Ok(date) => Ok(Box::new(date) as Box<dyn ToSql + Sync>),
Err(_) => Err("Invalid value for TIMESTAMP".to_string()),
}
},
"TIMESTAMP WITH TIME ZONE" | "TIMESTAMP_WITH_TIME_ZONE" => {
let value_str = value.as_str().ok_or("Invalid value for TIMESTAMP")?;
match parse_date_tz(&value_str){
Ok(date) => Ok(Box::new(date) as Box<dyn ToSql + Sync>),
Err(_) => Err("Invalid value for TIMESTAMP".to_string()),
}
},
"INET" => value
.as_str()
.and_then(|s| s.parse::<IpAddr>().ok())
@ -184,7 +189,7 @@ fn process_object(object: &Map<String, Value>) -> Result<Box<dyn ToSql + Sync>,
}
},
"TIME" => {
let value_str = value.as_str().ok_or("Invalid value for DATE")?;
let value_str = value.as_str().ok_or("Invalid value for TIME")?;
match parse_date(&value_str){
Ok(date) => Ok(Box::new(date.time()) as Box<dyn ToSql + Sync>),
Err(_) => Err("Invalid value for TIME".to_string()),
@ -281,16 +286,11 @@ fn process_sql_value(column_name: &str, column_type: &str, row: &postgres::Row)
Value::Object(map)
})
.unwrap_or(Value::Null),
"TIMESTAMP" | "TIMESTAMP WITH TIME ZONE" | "TIMESTAMPTZ" => row.try_get::<_, Option<SystemTime>>(column_name)?
.map(|time| {
match time.duration_since(SystemTime::UNIX_EPOCH) {
Ok(d) => Value::Number(d.as_secs().into()), // Положительное значение для времени после UNIX_EPOCH
Err(_) => match SystemTime::UNIX_EPOCH.duration_since(time) {
Ok(d) => Value::Number((-(d.as_secs() as i64)).into()), // Отрицательное значение для даты до UNIX_EPOCH
Err(_) => Value::Null, // Это вообще не должно произойти
},
}
})
"TIMESTAMP" => row.try_get::<_, Option<chrono::NaiveDateTime>>(column_name)?
.map(|timestamp| Value::String(timestamp.to_string()))
.unwrap_or(Value::Null),
"TIMESTAMP WITH TIME ZONE" | "TIMESTAMPTZ" => row.try_get::<_, Option<chrono::DateTime<FixedOffset>>>(column_name)?
.map(|timestamp| Value::String(timestamp.to_string()))
.unwrap_or(Value::Null),
"INET" => row.try_get::<_, Option<IpAddr>>(column_name)?
.map(|ip| Value::String(ip.to_string()))
@ -343,6 +343,26 @@ fn parse_date(input: &str) -> Result<chrono::NaiveDateTime, String> {
if let Ok(naive_date) = chrono::NaiveDateTime::parse_from_str(input, "%Y-%m-%d") {
Ok(naive_date)
}else{
Err("Invalid ISO 8601 format".to_string())
Err("Invalid rfc3339 format".to_string())
}
}
fn parse_date_tz(input: &str) -> Result<chrono::DateTime<FixedOffset>, String> {
if let Ok(datetime) = chrono::DateTime::parse_from_rfc3339(input) {
return Ok(datetime);
}
// Если не получилось, попробуем спарсить только дату и время без часового пояса
if let Ok(naive_datetime) = chrono::NaiveDateTime::parse_from_str(input, "%Y-%m-%dT%H:%M:%S") {
return Ok(naive_datetime.and_utc().fixed_offset());
}
// Если не получилось, попробуем спарсить только дату
if let Ok(naive_date) = chrono::NaiveDateTime::parse_from_str(input, "%Y-%m-%d") {
Ok(naive_date.and_utc().fixed_offset())
}else{
Err("Invalid rfc3339 format".to_string())
}
}

Binary file not shown.

Binary file not shown.

View File

@ -101,7 +101,7 @@
КонецФункции
// Это коннектор !NOCLI
// Проверяет, что значение является объектом внешней компоненты SQLite
// Проверяет, что значение является объектом внешней компоненты PostgreSQL
//
// Параметры:
// Значение - Произвольный - Значение для проверки - value
@ -508,7 +508,7 @@
КонецФункции
Функция ОбработатьПараметр(ТекущийПараметр, Вложенный = Ложь)
Функция ОбработатьПараметр(ТекущийПараметр)
ТекущийТип = ТипЗнч(ТекущийПараметр);
@ -519,6 +519,10 @@
ИначеЕсли ТекущийТип = Тип("УникальныйИдентификатор") Тогда
ТекущийПараметр = Строка(ТекущийПараметр);
ИначеЕсли ТекущийТип = Тип("Дата") Тогда
ТекущийПараметр = OPI_Инструменты.ДатаRFC3339(ТекущийПараметр);
ИначеЕсли OPI_Инструменты.ПолеКоллекцииСуществует(ТекущийПараметр, "BYTEA") Тогда
@ -538,14 +542,13 @@
Продолжить;
КонецЕсли;
ТекущийПараметр[ЭлементПараметра.Ключ] = ОбработатьПараметр(ТекущееЗначение, Истина);
ТекущийПараметр[ЭлементПараметра.Ключ] = ОбработатьПараметр(ТекущееЗначение);
КонецЦикла;
Иначе
Если Не OPI_Инструменты.ЭтоПримитивныйТип(ТекущийПараметр)
И Не ТекущийТип = Тип("Дата") Тогда
Если Не OPI_Инструменты.ЭтоПримитивныйТип(ТекущийПараметр) Тогда
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекущийПараметр);
КонецЕсли;

View File

@ -17512,10 +17512,6 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "postgres";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
База = "testbase1";
@ -17523,6 +17519,10 @@
Удаление = OPI_PostgreSQL.УдалитьБазуДанных(База, СтрокаПодключения); // SKIP
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Удаление, "СоздатьБазуДанных (удаление)", "PostgreSQL"); // SKIP
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.СоздатьБазуДанных(База, СтрокаПодключения);
// END
@ -17559,10 +17559,6 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "testtable";
@ -17594,6 +17590,10 @@
СтруктураКолонок.Вставить("time_field" , "TIME");
СтруктураКолонок.Вставить("uuid_field" , "UUID");
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.СоздатьТаблицу(Таблица, СтруктураКолонок, СтрокаПодключения);
// END
@ -17625,14 +17625,14 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "testtable";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.ПолучитьИнформациюОТаблице(Таблица, СтрокаПодключения);
// END
@ -17656,10 +17656,6 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "testtable";
@ -17669,7 +17665,9 @@
OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Картинка); // Картинка - Тип: ДвоичныеДанные
СлучайнаяСтруктура = Новый Структура("key,value", "ItsKey", 10);
ТекущаяДата = OPI_Инструменты.ПолучитьТекущуюДату();
ТекущаяДатаЧП = OPI_Инструменты.ДатаRFC3339(ТекущаяДата, "+05:00");
СтруктураЗаписи = Новый Структура;
СтруктураЗаписи.Вставить("bool_field" , Новый Структура("BOOL" , Истина));
@ -17689,8 +17687,8 @@
СтруктураЗаписи.Вставить("char_field" , Новый Структура("CHAR" , "A"));
СтруктураЗаписи.Вставить("name_field" , Новый Структура("NAME" , "Vitaly"));
СтруктураЗаписи.Вставить("bytea_field" , Новый Структура("BYTEA" , Картинка));
СтруктураЗаписи.Вставить("ts_field" , Новый Структура("TIMESTAMP" , 1739207915));
СтруктураЗаписи.Вставить("tswtz_field" , Новый Структура("TIMESTAMP_WITH_TIME_ZONE", 1739207915)); // или TIMESTAMP WITH TIME ZONE
СтруктураЗаписи.Вставить("ts_field" , Новый Структура("TIMESTAMP" , ТекущаяДата));
СтруктураЗаписи.Вставить("tswtz_field" , Новый Структура("TIMESTAMP_WITH_TIME_ZONE", ТекущаяДатаЧП)); // или TIMESTAMP WITH TIME ZONE
СтруктураЗаписи.Вставить("ip_field" , Новый Структура("INET" , "127.0.0.1"));
СтруктураЗаписи.Вставить("json_field" , Новый Структура("JSON" , СлучайнаяСтруктура));
СтруктураЗаписи.Вставить("jsonb_field" , Новый Структура("JSONB" , СлучайнаяСтруктура));
@ -17700,6 +17698,10 @@
МассивЗаписей.Добавить(СтруктураЗаписи);
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.ДобавитьЗаписи(Таблица, МассивЗаписей, Истина, СтрокаПодключения);
// END
@ -17716,20 +17718,21 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
// Все записи без отборов
Таблица = "testtable";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.ПолучитьЗаписи(Таблица, , , , , СтрокаПодключения);
Если ЗначениеЗаполнено(Результат["data"]) Тогда // SKIP
Результат["data"][0]["bytea_field"]["BYTEA"] // SKIP
= Лев(Результат["data"][0]["bytea_field"]["BYTEA"], 10) + "..."; // SKIP
= Лев(Результат["data"][0]["bytea_field"]["BYTEA"], 10) + "..."; // SKIP
КонецЕсли; // SKIP
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьЗаписи", "PostgreSQL"); // SKIP
@ -17786,10 +17789,6 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "test_data";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "test_data";
@ -17812,6 +17811,10 @@
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Количество, "ОбновитьЗаписи (количество)", "PostgreSQL"); // SKIP
Количество = Количество["data"].Количество(); // SKIP
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQl.ОбновитьЗаписи(Таблица, СтруктураПолей, СтруктураФильтра, СтрокаПодключения);
// END
@ -17840,10 +17843,6 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "test_data";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "test_data";
@ -17868,6 +17867,11 @@
СтруктураФильтра.Вставить("raw" , Ложь);
Получение = OPI_PostgreSQL.ПолучитьЗаписи(Таблица, , Фильтры, , , СтрокаПодключения); // SKIP
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.УдалитьЗаписи(Таблица, Фильтры, СтрокаПодключения);
// END
@ -17896,14 +17900,14 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "testtable";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.УдалитьТаблицу(Таблица, СтрокаПодключения);
// END
@ -17929,14 +17933,14 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "postgres";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.УдалитьБазуДанных(База, СтрокаПодключения);
// END
@ -17985,14 +17989,14 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "testtable";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.ОчиститьТаблицу(Таблица, СтрокаПодключения);
// END
@ -18015,12 +18019,12 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Результат = OPI_PostgreSQL.ОтключитьВсеСоединенияБазыДанных(База, СтрокаПодключения);
// END

View File

@ -2155,9 +2155,9 @@
КонецФункции
Функция ПолучитьОбщийМодуль(Знач Имя)
Модуль = Вычислить(Имя);
Возврат Модуль;
КонецФункции

View File

@ -1053,6 +1053,15 @@
КонецФункции
Функция ДатаRFC3339(Знач Дата, Знач Смещение = "Z") Экспорт
OPI_ПреобразованиеТипов.ПолучитьДату(Дата);
OPI_ПреобразованиеТипов.ПолучитьСтроку(Смещение);
Возврат XMLСтрока(Дата) + Смещение;
КонецФункции
Функция ПреобразоватьДанныеСПолучениемРазмера(Данные, Знач МинимальныйРазмерДляПотока = 0) Экспорт
Размер = 0;

View File

@ -101,7 +101,7 @@
КонецФункции
// Это коннектор !NOCLI
// Проверяет, что значение является объектом внешней компоненты SQLite
// Проверяет, что значение является объектом внешней компоненты PostgreSQL
//
// Параметры:
// Значение - Произвольный - Значение для проверки - value
@ -508,7 +508,7 @@
КонецФункции
Функция ОбработатьПараметр(ТекущийПараметр, Вложенный = Ложь)
Функция ОбработатьПараметр(ТекущийПараметр)
ТекущийТип = ТипЗнч(ТекущийПараметр);
@ -519,6 +519,10 @@
ИначеЕсли ТекущийТип = Тип("УникальныйИдентификатор") Тогда
ТекущийПараметр = Строка(ТекущийПараметр);
ИначеЕсли ТекущийТип = Тип("Дата") Тогда
ТекущийПараметр = OPI_Инструменты.ДатаRFC3339(ТекущийПараметр);
ИначеЕсли OPI_Инструменты.ПолеКоллекцииСуществует(ТекущийПараметр, "BYTEA") Тогда
@ -538,14 +542,13 @@
Продолжить;
КонецЕсли;
ТекущийПараметр[ЭлементПараметра.Ключ] = ОбработатьПараметр(ТекущееЗначение, Истина);
ТекущийПараметр[ЭлементПараметра.Ключ] = ОбработатьПараметр(ТекущееЗначение);
КонецЦикла;
Иначе
Если Не OPI_Инструменты.ЭтоПримитивныйТип(ТекущийПараметр)
И Не ТекущийТип = Тип("Дата") Тогда
Если Не OPI_Инструменты.ЭтоПримитивныйТип(ТекущийПараметр) Тогда
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекущийПараметр);
КонецЕсли;

View File

@ -1053,6 +1053,15 @@
КонецФункции
Функция ДатаRFC3339(Знач Дата, Знач Смещение = "Z") Экспорт
OPI_ПреобразованиеТипов.ПолучитьДату(Дата);
OPI_ПреобразованиеТипов.ПолучитьСтроку(Смещение);
Возврат XMLСтрока(Дата) + Смещение;
КонецФункции
Функция ПреобразоватьДанныеСПолучениемРазмера(Данные, Знач МинимальныйРазмерДляПотока = 0) Экспорт
Размер = 0;

View File

@ -17512,10 +17512,6 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "postgres";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
База = "testbase1";
@ -17523,6 +17519,10 @@
Удаление = OPI_PostgreSQL.УдалитьБазуДанных(База, СтрокаПодключения); // SKIP
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Удаление, "СоздатьБазуДанных (удаление)", "PostgreSQL"); // SKIP
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.СоздатьБазуДанных(База, СтрокаПодключения);
// END
@ -17559,10 +17559,6 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "testtable";
@ -17594,6 +17590,10 @@
СтруктураКолонок.Вставить("time_field" , "TIME");
СтруктураКолонок.Вставить("uuid_field" , "UUID");
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.СоздатьТаблицу(Таблица, СтруктураКолонок, СтрокаПодключения);
// END
@ -17625,14 +17625,14 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "testtable";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.ПолучитьИнформациюОТаблице(Таблица, СтрокаПодключения);
// END
@ -17656,10 +17656,6 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "testtable";
@ -17669,7 +17665,9 @@
OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Картинка); // Картинка - Тип: ДвоичныеДанные
СлучайнаяСтруктура = Новый Структура("key,value", "ItsKey", 10);
ТекущаяДата = OPI_Инструменты.ПолучитьТекущуюДату();
ТекущаяДатаЧП = OPI_Инструменты.ДатаRFC3339(ТекущаяДата, "+05:00");
СтруктураЗаписи = Новый Структура;
СтруктураЗаписи.Вставить("bool_field" , Новый Структура("BOOL" , Истина));
@ -17689,8 +17687,8 @@
СтруктураЗаписи.Вставить("char_field" , Новый Структура("CHAR" , "A"));
СтруктураЗаписи.Вставить("name_field" , Новый Структура("NAME" , "Vitaly"));
СтруктураЗаписи.Вставить("bytea_field" , Новый Структура("BYTEA" , Картинка));
СтруктураЗаписи.Вставить("ts_field" , Новый Структура("TIMESTAMP" , 1739207915));
СтруктураЗаписи.Вставить("tswtz_field" , Новый Структура("TIMESTAMP_WITH_TIME_ZONE", 1739207915)); // или TIMESTAMP WITH TIME ZONE
СтруктураЗаписи.Вставить("ts_field" , Новый Структура("TIMESTAMP" , ТекущаяДата));
СтруктураЗаписи.Вставить("tswtz_field" , Новый Структура("TIMESTAMP_WITH_TIME_ZONE", ТекущаяДатаЧП)); // или TIMESTAMP WITH TIME ZONE
СтруктураЗаписи.Вставить("ip_field" , Новый Структура("INET" , "127.0.0.1"));
СтруктураЗаписи.Вставить("json_field" , Новый Структура("JSON" , СлучайнаяСтруктура));
СтруктураЗаписи.Вставить("jsonb_field" , Новый Структура("JSONB" , СлучайнаяСтруктура));
@ -17700,6 +17698,10 @@
МассивЗаписей.Добавить(СтруктураЗаписи);
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.ДобавитьЗаписи(Таблица, МассивЗаписей, Истина, СтрокаПодключения);
// END
@ -17716,20 +17718,21 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
// Все записи без отборов
Таблица = "testtable";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.ПолучитьЗаписи(Таблица, , , , , СтрокаПодключения);
Если ЗначениеЗаполнено(Результат["data"]) Тогда // SKIP
Результат["data"][0]["bytea_field"]["BYTEA"] // SKIP
= Лев(Результат["data"][0]["bytea_field"]["BYTEA"], 10) + "..."; // SKIP
= Лев(Результат["data"][0]["bytea_field"]["BYTEA"], 10) + "..."; // SKIP
КонецЕсли; // SKIP
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьЗаписи", "PostgreSQL"); // SKIP
@ -17786,10 +17789,6 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "test_data";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "test_data";
@ -17812,6 +17811,10 @@
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Количество, "ОбновитьЗаписи (количество)", "PostgreSQL"); // SKIP
Количество = Количество["data"].Количество(); // SKIP
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQl.ОбновитьЗаписи(Таблица, СтруктураПолей, СтруктураФильтра, СтрокаПодключения);
// END
@ -17840,10 +17843,6 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "test_data";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "test_data";
@ -17868,6 +17867,11 @@
СтруктураФильтра.Вставить("raw" , Ложь);
Получение = OPI_PostgreSQL.ПолучитьЗаписи(Таблица, , Фильтры, , , СтрокаПодключения); // SKIP
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.УдалитьЗаписи(Таблица, Фильтры, СтрокаПодключения);
// END
@ -17896,14 +17900,14 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "testtable";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.УдалитьТаблицу(Таблица, СтрокаПодключения);
// END
@ -17929,14 +17933,14 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "postgres";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.УдалитьБазуДанных(База, СтрокаПодключения);
// END
@ -17985,14 +17989,14 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Таблица = "testtable";
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
Результат = OPI_PostgreSQL.ОчиститьТаблицу(Таблица, СтрокаПодключения);
// END
@ -18015,12 +18019,12 @@
Пароль = ПараметрыФункции["PG_Password"];
База = "testbase1";
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
// При использовании строки подключения инициализируется новое соединение,
// которое будет закрыто после выполнения функции.
// В случае выполнения нескольких операций желательно использовать одно соединение,
// заранее созданное функцией ОткрытьСоединение()
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
Результат = OPI_PostgreSQL.ОтключитьВсеСоединенияБазыДанных(База, СтрокаПодключения);
// END