You've already forked OpenIntegrations
mirror of
https://github.com/Bayselonarrend/OpenIntegrations.git
synced 2025-08-10 22:41:43 +02:00
Доработки PG
This commit is contained in:
Binary file not shown.
@@ -86,11 +86,6 @@ fn process_object(object: &Map<String, Value>) -> Result<Box<dyn ToSql + Sync>,
|
||||
.as_bool()
|
||||
.map(|v| Box::new(v) as Box<dyn ToSql + Sync>)
|
||||
.ok_or_else(|| "Invalid value for BOOL".to_string()),
|
||||
"\"CHAR\"" | "OLDCHAR" => value
|
||||
.as_i64()
|
||||
.and_then(|v| i8::try_from(v).ok())
|
||||
.map(|v| Box::new(v) as Box<dyn ToSql + Sync>)
|
||||
.ok_or_else(|| "Invalid value for \"char\"".to_string()),
|
||||
"SMALLINT" | "SMALLSERIAL" => value
|
||||
.as_i64()
|
||||
.and_then(|v| i16::try_from(v).ok())
|
||||
@@ -123,6 +118,11 @@ fn process_object(object: &Map<String, Value>) -> Result<Box<dyn ToSql + Sync>,
|
||||
.as_str()
|
||||
.map(|v| Box::new(v.to_string()) as Box<dyn ToSql + Sync>)
|
||||
.ok_or_else(|| format!("Invalid value for {}", key)),
|
||||
"\"CHAR\"" | "OLDCHAR" => value
|
||||
.as_i64()
|
||||
.and_then(|v| i8::try_from(v).ok())
|
||||
.map(|v| Box::new(v) as Box<dyn ToSql + Sync>)
|
||||
.ok_or_else(|| "Invalid value for \"char\"".to_string()),
|
||||
"BYTEA" => value
|
||||
.as_str()
|
||||
.map(|blob_str| {
|
||||
@@ -160,12 +160,18 @@ fn process_object(object: &Map<String, Value>) -> Result<Box<dyn ToSql + Sync>,
|
||||
.map(|ip| Box::new(ip) as Box<dyn ToSql + Sync>)
|
||||
.ok_or_else(|| "Invalid value for INET".to_string()),
|
||||
"JSON" | "JSONB" => {
|
||||
// Если значение уже является объектом или массивом, передаем его как есть
|
||||
if value.is_object() || value.is_array() {
|
||||
Ok(Box::new(value.to_string()) as Box<dyn ToSql + Sync>)
|
||||
Ok(Box::new(value.clone()) as Box<dyn ToSql + Sync>)
|
||||
} else if value.is_string() {
|
||||
Ok(Box::new(value.as_str().unwrap().to_string()) as Box<dyn ToSql + Sync>)
|
||||
|
||||
let json_str = value.as_str().ok_or("Expected a string value for JSON/JSONB")?;
|
||||
match serde_json::from_str::<Value>(json_str) {
|
||||
Ok(parsed_value) => Ok(Box::new(parsed_value) as Box<dyn ToSql + Sync>),
|
||||
Err(e) => Err(format!("Invalid JSON string: {}", e)),
|
||||
}
|
||||
} else {
|
||||
Err("Invalid value for JSON/JSONB: must be an object, array, or string".to_string())
|
||||
Err("Invalid value for JSON/JSONB: must be an object, array, or valid JSON string".to_string())
|
||||
}
|
||||
}
|
||||
_ => Err(format!("Unsupported type: {}", key)),
|
||||
@@ -182,39 +188,45 @@ fn rows_to_json(rows: Vec<postgres::Row>) -> String {
|
||||
let column_name = column.name();
|
||||
let column_type = column.type_().name();
|
||||
|
||||
let value = match column_type.to_lowercase().as_str() {
|
||||
"bool" => row.get::<_, Option<bool>>(column_name).map(Value::Bool).unwrap_or(Value::Null),
|
||||
"int2" | "smallint" | "smallserial" => row.get::<_, Option<i16>>(column_name)
|
||||
let value = match column_type.to_uppercase().as_str() {
|
||||
"BOOL" => row.get::<_, Option<bool>>(column_name)
|
||||
.map(Value::Bool)
|
||||
.unwrap_or(Value::Null),
|
||||
"INT2" | "SMALLINT" | "SMALLSERIAL" => row.get::<_, Option<i16>>(column_name)
|
||||
.map(|v| Value::Number(v.into()))
|
||||
.unwrap_or(Value::Null),
|
||||
"int4" | "int" | "serial" => row.get::<_, Option<i32>>(column_name)
|
||||
"INT4" | "INT" | "SERIAL" => row.get::<_, Option<i32>>(column_name)
|
||||
.map(|v| Value::Number(v.into()))
|
||||
.unwrap_or(Value::Null),
|
||||
"oid" => row.get::<_, Option<u32>>(column_name)
|
||||
"OID" => row.get::<_, Option<u32>>(column_name)
|
||||
.map(|v| Value::Number(v.into()))
|
||||
.unwrap_or(Value::Null),
|
||||
"int8" | "bigint" | "bigserial" => row.get::<_, Option<i64>>(column_name)
|
||||
"INT8" | "BIGINT" | "BIGSERIAL" => row.get::<_, Option<i64>>(column_name)
|
||||
.map(|v| Value::Number(v.into()))
|
||||
.unwrap_or(Value::Null),
|
||||
"float4" | "real" => row.get::<_, Option<f32>>(column_name)
|
||||
"FLOAT4" | "REAL" => row.get::<_, Option<f32>>(column_name)
|
||||
.map(|v| match v {
|
||||
v if v.is_nan() => Value::String("NaN".to_string()),
|
||||
v if v.is_infinite() => Value::String("Infinity".to_string()),
|
||||
_ => serde_json::Number::from_f64(v as f64).map(Value::Number).unwrap_or(Value::Null),
|
||||
})
|
||||
.unwrap_or(Value::Null),
|
||||
"float8" | "double precision" => row.get::<_, Option<f64>>(column_name)
|
||||
"FLOAT8" | "DOUBLE PRECISION" => row.get::<_, Option<f64>>(column_name)
|
||||
.map(|v| match v {
|
||||
v if v.is_nan() => Value::String("NaN".to_string()),
|
||||
v if v.is_infinite() => Value::String("Infinity".to_string()),
|
||||
_ => serde_json::Number::from_f64(v).map(Value::Number).unwrap_or(Value::Null),
|
||||
})
|
||||
.unwrap_or(Value::Null),
|
||||
"varchar" | "text" | "char" | "citext" | "name" | "unknown" => row.get::<_, Option<String>>(column_name)
|
||||
"\"CHAR\"" => {
|
||||
row.get::<_, Option<i8>>(column_name)
|
||||
.map(|v| Value::Number(v.into()))
|
||||
.unwrap_or(Value::Null)
|
||||
},
|
||||
"VARCHAR" | "TEXT" | "CHAR" | "CITEXT" | "NAME" | "LTREE" | "LQUERY" | "LTXTQUERY" | "UNKNOWN" => row.get::<_, Option<String>>(column_name)
|
||||
.map(Value::String)
|
||||
.unwrap_or(Value::Null),
|
||||
"bytea" => {
|
||||
|
||||
"BYTEA" => {
|
||||
let base64_string = row.get::<_, Option<Vec<u8>>>(column_name)
|
||||
.map(|v| general_purpose::STANDARD.encode(v))
|
||||
.unwrap_or("Unable to make Base64 string".to_string());
|
||||
@@ -223,7 +235,7 @@ fn rows_to_json(rows: Vec<postgres::Row>) -> String {
|
||||
blob_object.insert("BYTEA".to_string(), Value::String(base64_string)); // Оборачиваем в объект
|
||||
Value::Object(blob_object)
|
||||
},
|
||||
"hstore" => row.get::<_, Option<HashMap<String, Option<String>>>>(column_name)
|
||||
"HSTORE" => row.get::<_, Option<HashMap<String, Option<String>>>>(column_name)
|
||||
.map(|hstore| {
|
||||
let mut map = Map::new();
|
||||
for (k, v) in hstore {
|
||||
@@ -232,7 +244,7 @@ fn rows_to_json(rows: Vec<postgres::Row>) -> String {
|
||||
Value::Object(map)
|
||||
})
|
||||
.unwrap_or(Value::Null),
|
||||
"timestamp" | "timestamptz" => row.get::<_, Option<SystemTime>>(column_name)
|
||||
"TIMESTAMP" | "TIMESTAMP WITH TIME ZONE" | "TIMESTAMPTZ" => row.get::<_, Option<SystemTime>>(column_name)
|
||||
.map(|time| {
|
||||
match time.duration_since(SystemTime::UNIX_EPOCH) {
|
||||
Ok(d) => Value::Number(d.as_secs().into()), // Положительное значение для времени после UNIX_EPOCH
|
||||
@@ -241,18 +253,16 @@ fn rows_to_json(rows: Vec<postgres::Row>) -> String {
|
||||
Err(_) => Value::Null, // Это вообще не должно произойти
|
||||
},
|
||||
}
|
||||
|
||||
})
|
||||
.unwrap_or(Value::Null),
|
||||
"inet" => row.get::<_, Option<IpAddr>>(column_name)
|
||||
"INET" => row.get::<_, Option<IpAddr>>(column_name)
|
||||
.map(|ip| Value::String(ip.to_string()))
|
||||
.unwrap_or(Value::Null),
|
||||
"json" | "jsonb" => {
|
||||
row.get::<_, Option<String>>(column_name)
|
||||
.and_then(|s| serde_json::from_str(&s).ok())
|
||||
"JSON" | "JSONB" => {
|
||||
row.get::<_, Option<Value>>(column_name)
|
||||
.unwrap_or(Value::Null)
|
||||
},
|
||||
_ => Value::Null,
|
||||
current_type => Value::String(format!("Unsupported type: {}", current_type)),
|
||||
};
|
||||
|
||||
row_map.insert(column_name.to_string(), value);
|
||||
|
BIN
src/en/OInt/addins/OPI_PostgreSQL.zip
vendored
BIN
src/en/OInt/addins/OPI_PostgreSQL.zip
vendored
Binary file not shown.
Binary file not shown.
BIN
src/ru/OInt/addins/OPI_PostgreSQL.zip
vendored
BIN
src/ru/OInt/addins/OPI_PostgreSQL.zip
vendored
Binary file not shown.
122
src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl
vendored
122
src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl
vendored
@@ -2324,7 +2324,8 @@
|
||||
PostgreSQL_СоздатьТаблицу(ПараметрыТеста);
|
||||
PostgreSQL_ПолучитьИнформациюОТаблице(ПараметрыТеста);
|
||||
PostgreSQL_ДобавитьЗаписи(ПараметрыТеста);
|
||||
PostgreSQL_УдалитьБазуДанных(ПараметрыТеста);
|
||||
PostgreSQL_ПолучитьЗаписи(ПараметрыТеста);
|
||||
//PostgreSQL_УдалитьБазуДанных(ПараметрыТеста);
|
||||
|
||||
КонецПроцедуры
|
||||
|
||||
@@ -17306,8 +17307,9 @@
|
||||
|
||||
База = "testbase1";
|
||||
|
||||
OPI_PostgreSQL.УдалитьБазуДанных(База, СтрокаПодключения); // SKIP
|
||||
|
||||
Удаление = OPI_PostgreSQL.УдалитьБазуДанных(База, СтрокаПодключения); // SKIP
|
||||
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Удаление, "СоздатьБазуДанных (удаление)", "PostgreSQL"); // SKIP
|
||||
|
||||
Результат = OPI_PostgreSQL.СоздатьБазуДанных(База, СтрокаПодключения);
|
||||
|
||||
// END
|
||||
@@ -17349,18 +17351,27 @@
|
||||
Таблица = "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");
|
||||
СтруктураКолонок.Вставить("bool_field" , "BOOL");
|
||||
СтруктураКолонок.Вставить("oldchar_field" , """char""");
|
||||
СтруктураКолонок.Вставить("smallint_field" , "SMALLINT");
|
||||
СтруктураКолонок.Вставить("smallserial_field", "SMALLSERIAL");
|
||||
СтруктураКолонок.Вставить("int_field" , "INT");
|
||||
СтруктураКолонок.Вставить("serial_field" , "SERIAL");
|
||||
СтруктураКолонок.Вставить("oid_field" , "OID");
|
||||
СтруктураКолонок.Вставить("bigint_field" , "BIGINT");
|
||||
СтруктураКолонок.Вставить("bigserial_field" , "BIGSERIAL");
|
||||
СтруктураКолонок.Вставить("real_field" , "REAL");
|
||||
СтруктураКолонок.Вставить("dp_field" , "DOUBLE PRECISION");
|
||||
СтруктураКолонок.Вставить("text_field" , "TEXT");
|
||||
СтруктураКолонок.Вставить("varchar_field" , "VARCHAR");
|
||||
СтруктураКолонок.Вставить("char_field" , "CHAR(1)");
|
||||
СтруктураКолонок.Вставить("name_field" , "NAME");
|
||||
СтруктураКолонок.Вставить("bytea_field" , "BYTEA");
|
||||
СтруктураКолонок.Вставить("ts_field" , "TIMESTAMP");
|
||||
СтруктураКолонок.Вставить("tswtz_field" , "TIMESTAMP WITH TIME ZONE");
|
||||
СтруктураКолонок.Вставить("ip_field" , "INET");
|
||||
СтруктураКолонок.Вставить("json_field" , "JSON");
|
||||
СтруктураКолонок.Вставить("jsonb_field" , "JSONB");
|
||||
|
||||
Результат = OPI_PostgreSQL.СоздатьТаблицу(Таблица, СтруктураКолонок, СтрокаПодключения);
|
||||
|
||||
@@ -17404,21 +17415,32 @@
|
||||
|
||||
Картинка = ПараметрыФункции["Picture"];
|
||||
OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Картинка); // Картинка - Тип: ДвоичныеДанные
|
||||
|
||||
СлучайнаяСтруктура = Новый Структура("key,value", "ItsKey", 10);
|
||||
|
||||
СтруктураЗаписи = Новый Структура;
|
||||
СтруктураЗаписи.Вставить("bool_field" , Новый Структура("BOOL" , Истина));
|
||||
СтруктураЗаписи.Вставить("char_field" , Новый Структура("OLDCHAR" , 1));
|
||||
СтруктураЗаписи.Вставить("smallint_field", Новый Структура("SMALLINT" , 5));
|
||||
СтруктураЗаписи.Вставить("int_field" , Новый Структура("INT" , 100));
|
||||
СтруктураЗаписи.Вставить("oid_field" , Новый Структура("OID" , 24576));
|
||||
СтруктураЗаписи.Вставить("bigint_field" , Новый Структура("BIGINT" , 9999999));
|
||||
СтруктураЗаписи.Вставить("real_field" , Новый Структура("REAL" , 15.2));
|
||||
СтруктураЗаписи.Вставить("dp_field" , Новый Структура("DOUBLE_PRECISION", 1.0000000000000002));
|
||||
СтруктураЗаписи.Вставить("text_field" , Новый Структура("TEXT" , "Some text"));
|
||||
СтруктураЗаписи.Вставить("bytea_field" , Новый Структура("BYTEA" , Картинка));
|
||||
СтруктураЗаписи.Вставить("ts_field" , Новый Структура("TIMESTAMP" , 1739207915));
|
||||
СтруктураЗаписи.Вставить("ip_field" , Новый Структура("INET" , "127.0.0.1"));
|
||||
|
||||
СтруктураЗаписи.Вставить("bool_field" , Новый Структура("BOOL" , Истина));
|
||||
СтруктураЗаписи.Вставить("oldchar_field" , Новый Структура("OLDCHAR" , 1)); // или "char"
|
||||
СтруктураЗаписи.Вставить("smallint_field" , Новый Структура("SMALLINT" , 5));
|
||||
СтруктураЗаписи.Вставить("smallserial_field", Новый Структура("SMALLSERIAL" , 6));
|
||||
СтруктураЗаписи.Вставить("int_field" , Новый Структура("INT" , 100));
|
||||
СтруктураЗаписи.Вставить("serial_field" , Новый Структура("SERIAL" , 100));
|
||||
СтруктураЗаписи.Вставить("oid_field" , Новый Структура("OID" , 24576));
|
||||
СтруктураЗаписи.Вставить("bigint_field" , Новый Структура("BIGINT" , 9999999));
|
||||
СтруктураЗаписи.Вставить("bigserial_field" , Новый Структура("BIGSERIAL" , 9999999));
|
||||
СтруктураЗаписи.Вставить("real_field" , Новый Структура("REAL" , 15.2));
|
||||
СтруктураЗаписи.Вставить("dp_field" , Новый Структура("DOUBLE_PRECISION" , 1.0000000000000002)); // или DOUBLE PRECISION
|
||||
СтруктураЗаписи.Вставить("text_field" , Новый Структура("TEXT" , "Some text"));
|
||||
СтруктураЗаписи.Вставить("varchar_field" , Новый Структура("VARCHAR" , "Some varchar"));
|
||||
СтруктураЗаписи.Вставить("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
|
||||
СтруктураЗаписи.Вставить("ip_field" , Новый Структура("INET" , "127.0.0.1"));
|
||||
СтруктураЗаписи.Вставить("json_field" , Новый Структура("JSON" , СлучайнаяСтруктура));
|
||||
СтруктураЗаписи.Вставить("jsonb_field" , Новый Структура("JSONB" , СлучайнаяСтруктура));
|
||||
|
||||
Результат = OPI_PostgreSQL.ДобавитьЗаписи(Таблица, СтруктураЗаписи, Ложь, СтрокаПодключения);
|
||||
|
||||
// END
|
||||
@@ -17428,6 +17450,50 @@
|
||||
|
||||
КонецПроцедуры
|
||||
|
||||
Процедура PostgreSQL_ПолучитьЗаписи(ПараметрыФункции)
|
||||
|
||||
Адрес = ПараметрыФункции["PG_IP"];
|
||||
Логин = "bayselonarrend";
|
||||
Пароль = ПараметрыФункции["PG_Password"];
|
||||
База = "testbase1";
|
||||
|
||||
СтрокаПодключения = OPI_PostgreSQL.СформироватьСтрокуПодключения(Адрес, База, Логин, Пароль);
|
||||
|
||||
Таблица = "testtable";
|
||||
|
||||
Поля = Новый Массив;
|
||||
Поля.Добавить("bool_field");
|
||||
Поля.Добавить("oldchar_field");
|
||||
Поля.Добавить("smallint_field");
|
||||
Поля.Добавить("smallserial_field");
|
||||
Поля.Добавить("int_field");
|
||||
Поля.Добавить("serial_field");
|
||||
Поля.Добавить("oid_field");
|
||||
Поля.Добавить("bigint_field");
|
||||
Поля.Добавить("bigserial_field");
|
||||
Поля.Добавить("real_field");
|
||||
Поля.Добавить("dp_field");
|
||||
Поля.Добавить("text_field");
|
||||
Поля.Добавить("varchar_field");
|
||||
Поля.Добавить("char_field");
|
||||
Поля.Добавить("name_field");
|
||||
Поля.Добавить("bytea_field");
|
||||
Поля.Добавить("ts_field");
|
||||
Поля.Добавить("tswtz_field");
|
||||
Поля.Добавить("ip_field");
|
||||
Поля.Добавить("json_field");
|
||||
Поля.Добавить("jsonb_field");
|
||||
|
||||
Результат = OPI_PostgreSQL.ПолучитьЗаписи(Таблица, Поля, , , , СтрокаПодключения);
|
||||
|
||||
// END
|
||||
|
||||
Результат["data"][0]["bytea_field"]["BYTEA"] = Лев(Результат["data"][0]["bytea_field"]["BYTEA"], 10) + "...";
|
||||
|
||||
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ДобавитьЗаписи", "PostgreSQL");
|
||||
OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат);
|
||||
|
||||
КонецПроцедуры
|
||||
#КонецОбласти
|
||||
|
||||
#КонецОбласти
|
||||
|
Binary file not shown.
Reference in New Issue
Block a user