You've already forked OpenIntegrations
mirror of
https://github.com/Bayselonarrend/OpenIntegrations.git
synced 2026-06-20 09:19:27 +02:00
Fastfix
This commit is contained in:
Generated
+57
@@ -243,6 +243,20 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "7.0.0-rc2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4a1e35a65fe0538a60167f0ada6e195ad5d477f6ddae273943596d4a1a5730b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dateparser"
|
||||
version = "0.2.1"
|
||||
@@ -651,6 +665,16 @@ version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.26"
|
||||
@@ -870,10 +894,25 @@ dependencies = [
|
||||
"addin1c",
|
||||
"base64",
|
||||
"chrono",
|
||||
"dashmap",
|
||||
"dateparser",
|
||||
"mysql",
|
||||
"mysql_common",
|
||||
"serde_json",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -998,6 +1037,15 @@ dependencies = [
|
||||
"getrandom 0.2.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.1"
|
||||
@@ -1067,6 +1115,12 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.11.1"
|
||||
@@ -1360,6 +1414,9 @@ name = "uuid"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
|
||||
dependencies = [
|
||||
"getrandom 0.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
|
||||
@@ -20,4 +20,6 @@ serde_json = "1.0"
|
||||
base64 = "0.22.1"
|
||||
chrono = "0.4.40"
|
||||
mysql_common = "0.34.1"
|
||||
dateparser = "0.2.1"
|
||||
dateparser = "0.2.1"
|
||||
dashmap = "7.0.0-rc2"
|
||||
uuid = { version = "1.16.0", features = ["v4"] }
|
||||
@@ -1,13 +1,13 @@
|
||||
"MAIN ---"
|
||||
linux-vdso.so.1 (0x00007fffd6965000)
|
||||
libssl.so.3 => /lib64/libssl.so.3 (0x0000781f44600000)
|
||||
libcrypto.so.3 => /lib64/libcrypto.so.3 (0x0000781f43e00000)
|
||||
libm.so.6 => /lib64/libm.so.6 (0x0000781f43a00000)
|
||||
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000781f43600000)
|
||||
libc.so.6 => /lib64/libc.so.6 (0x0000781f43200000)
|
||||
libdl.so.2 => /lib64/libdl.so.2 (0x0000781f42e00000)
|
||||
/lib64/ld-linux-x86-64.so.2 (0x0000781f44c00000)
|
||||
libz.so.1 => /lib64/libz.so.1 (0x0000781f42a00000)
|
||||
linux-vdso.so.1 (0x00007ffe7cd0b000)
|
||||
libssl.so.3 => /lib64/libssl.so.3 (0x00007066f1a00000)
|
||||
libcrypto.so.3 => /lib64/libcrypto.so.3 (0x00007066f1200000)
|
||||
libm.so.6 => /lib64/libm.so.6 (0x00007066f0e00000)
|
||||
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007066f0a00000)
|
||||
libc.so.6 => /lib64/libc.so.6 (0x00007066f0600000)
|
||||
libdl.so.2 => /lib64/libdl.so.2 (0x00007066f0200000)
|
||||
/lib64/ld-linux-x86-64.so.2 (0x00007066f2000000)
|
||||
libz.so.1 => /lib64/libz.so.1 (0x00007066efe00000)
|
||||
GLIBC_2.2.5
|
||||
GLIBC_2.3
|
||||
GLIBC_2.3.4
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
use dashmap::DashMap;
|
||||
use serde_json::Value;
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub struct Datasets {
|
||||
data: Arc<DashMap<String, QueryData>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct QueryData {
|
||||
pub results: Vec<Value>,
|
||||
pub params: Vec<Value>,
|
||||
pub text: String,
|
||||
pub force_result: bool,
|
||||
}
|
||||
|
||||
impl Datasets {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
data: Arc::new(DashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_query(&self) -> String {
|
||||
let key = Uuid::new_v4().to_string();
|
||||
let query = QueryData::new();
|
||||
self.data.insert(key.clone(), query);
|
||||
key
|
||||
}
|
||||
|
||||
pub fn get_query(&self, key: &str) -> Option<QueryData> {
|
||||
self.data.get(key).map(|guard| guard.value().clone())
|
||||
}
|
||||
|
||||
pub fn set_results(&self, key: &str, values: Vec<Value>) {
|
||||
if let Some(mut entry) = self.data.get_mut(key) {
|
||||
entry.results = values;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_param(&self, key: &str, value: Value) {
|
||||
if let Some(mut entry) = self.data.get_mut(key) {
|
||||
entry.params.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_text(&self, key: &str, text: &str) {
|
||||
if let Some(mut entry) = self.data.get_mut(key) {
|
||||
entry.text = text.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_force_result(&self, key: &str, enabled: bool) {
|
||||
if let Some(mut entry) = self.data.get_mut(key) {
|
||||
entry.force_result = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self, key: &str) -> Option<usize> {
|
||||
self.data.get(key).map(|entry| entry.results.len())
|
||||
}
|
||||
|
||||
pub fn remove(&self, key: &str) {
|
||||
self.data.remove(key);
|
||||
}
|
||||
|
||||
pub fn get_row(&self, key: &str, index: usize) -> Option<String> {
|
||||
let entry = self.data.get(key)?;
|
||||
let value = entry.results.get(index)?;
|
||||
serde_json::to_string(value).ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl QueryData {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
results: Vec::new(),
|
||||
params: Vec::new(),
|
||||
text: String::new(),
|
||||
force_result: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +1,91 @@
|
||||
use serde_json::{Value, json};
|
||||
use crate::component::format_json_error;
|
||||
use crate::component::{format_json_error, AddIn};
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use mysql::prelude::Queryable;
|
||||
use std::collections::HashMap;
|
||||
use chrono::*;
|
||||
use mysql::PooledConn;
|
||||
use mysql_common::packets::Column;
|
||||
use dateparser::parse;
|
||||
|
||||
pub fn init_query(add_in: &mut AddIn, text: &str, force_result: bool) -> String {
|
||||
|
||||
let key = add_in.datasets.init_query();
|
||||
add_in.datasets.set_text(&key, text);
|
||||
add_in.datasets.set_force_result(&key, force_result);
|
||||
|
||||
key
|
||||
}
|
||||
|
||||
pub fn add_query_param(add_in: &mut AddIn, key: &str, param: String) -> String {
|
||||
|
||||
let value: Value = match serde_json::from_str(¶m) {
|
||||
Ok(param) => param,
|
||||
Err(e) => return format_json_error(&e.to_string()),
|
||||
};
|
||||
|
||||
add_in.datasets.add_param(key, value);
|
||||
json!({"result": true}).to_string()
|
||||
|
||||
}
|
||||
|
||||
pub fn execute_query(
|
||||
conn: &mut PooledConn,
|
||||
query: String,
|
||||
params_json: String,
|
||||
force_result: bool
|
||||
add_in: &mut AddIn,
|
||||
key: &str
|
||||
) -> String {
|
||||
|
||||
// Парсинг JSON параметров
|
||||
let mut parsed_params: Value = match serde_json::from_str(¶ms_json) {
|
||||
Ok(params) => params,
|
||||
Err(e) => return format_json_error(e)
|
||||
let mut conn = match add_in.get_connection(){
|
||||
Ok(conn) => conn,
|
||||
Err(e) => return format_json_error(e.to_string()),
|
||||
};
|
||||
|
||||
let params_array = match parsed_params.as_array_mut() {
|
||||
Some(array) => process_mysql_params(array),
|
||||
None => return format_json_error("Parameters must be a JSON array")
|
||||
let query = match add_in.datasets.get_query(key){
|
||||
Some(q) => q,
|
||||
None => return format_json_error(format!("No query found by key: {}", key).as_str()),
|
||||
};
|
||||
|
||||
// Определяем тип запроса
|
||||
if query.trim_start().to_uppercase().starts_with("SELECT") || force_result == true {
|
||||
let mut params = query.params;
|
||||
let text = query.text;
|
||||
let force_result = query.force_result;
|
||||
|
||||
let mut rows: Vec<mysql::Row> = match conn.exec(query, params_array){
|
||||
let params_array = process_mysql_params(&mut params);
|
||||
|
||||
let result = if text.trim_start().to_uppercase().starts_with("SELECT") || force_result == true {
|
||||
|
||||
let mut rows: Vec<mysql::Row> = match conn.exec(text, params_array){
|
||||
Ok(rows) => rows,
|
||||
Err(e) => return format_json_error(e)
|
||||
};
|
||||
|
||||
rows_to_json_array(&mut rows)
|
||||
match rows_to_json_array(&mut rows){
|
||||
Ok(json) => {
|
||||
add_in.datasets.set_results(&key, json);
|
||||
json!({"result": true, "data": true}).to_string()
|
||||
},
|
||||
Err(e) => return format_json_error(e)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
let exec_result = match params_array.len() == 0 {
|
||||
true => conn.query_drop(query),
|
||||
false => conn.exec_drop(query, params_array)
|
||||
true => conn.query_drop(text),
|
||||
false => conn.exec_drop(text, params_array)
|
||||
};
|
||||
|
||||
match exec_result{
|
||||
Ok(_) => json!({"result": true}).to_string(),
|
||||
Ok(_) => json!({"result": true, "data": false}).to_string(),
|
||||
Err(e) => format_json_error(e)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
match conn.as_mut().ping(){
|
||||
Ok(_) => add_in.connection = Some(conn),
|
||||
Err(_) => drop(conn)
|
||||
};
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn rows_to_json_array(rows: &mut Vec<mysql::Row>) -> String {
|
||||
fn rows_to_json_array(rows: &mut Vec<mysql::Row>) -> Result<Vec<Value>, String> {
|
||||
|
||||
let mut json_array = Vec::new();
|
||||
|
||||
@@ -72,12 +107,13 @@ fn rows_to_json_array(rows: &mut Vec<mysql::Row>) -> String {
|
||||
}
|
||||
match serde_json::to_value(json_obj){
|
||||
Ok(json) => json_array.push(json),
|
||||
Err(e) => return format_json_error(e)
|
||||
Err(e) => return Err(e.to_string())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
json!({ "result": true, "data": json_array }).to_string()
|
||||
Ok(json_array)
|
||||
|
||||
}
|
||||
|
||||
fn from_sql_to_json(value: mysql::Value, column: &Column) -> Value {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
mod methods;
|
||||
mod dataset;
|
||||
|
||||
use addin1c::{name, Variant};
|
||||
use crate::core::getset;
|
||||
use serde_json::json;
|
||||
use mysql::*;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::component::dataset::Datasets;
|
||||
// МЕТОДЫ КОМПОНЕНТЫ -------------------------------------------------------------------------------
|
||||
|
||||
// Синонимы
|
||||
@@ -13,7 +14,12 @@ pub const METHODS: &[&[u16]] = &[
|
||||
name!("Connect"),
|
||||
name!("Close"),
|
||||
name!("Execute"),
|
||||
name!("SetTLS")
|
||||
name!("SetTLS"),
|
||||
name!("GetQueryResultRow"),
|
||||
name!("GetQueryResultLength"),
|
||||
name!("RemoveQuery"),
|
||||
name!("InitQuery"),
|
||||
name!("AddQueryParam"),
|
||||
|
||||
];
|
||||
|
||||
@@ -22,8 +28,13 @@ pub fn get_params_amount(num: usize) -> usize {
|
||||
match num {
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 3,
|
||||
2 => 1,
|
||||
3 => 3,
|
||||
4 => 2,
|
||||
5 => 1,
|
||||
6 => 1,
|
||||
7 => 2,
|
||||
8 => 2,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
@@ -38,24 +49,9 @@ pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box<dyn
|
||||
1 => Box::new(obj.close_connection()),
|
||||
2 => {
|
||||
|
||||
let query = params[0].get_string().unwrap_or("".to_string());
|
||||
let params_json = params[1].get_string().unwrap_or("".to_string());
|
||||
let force_result = params[2].get_bool().unwrap_or(false);
|
||||
let key = params[0].get_string().unwrap_or("".to_string());
|
||||
Box::new(methods::execute_query(obj, &key))
|
||||
|
||||
match obj.get_connection(){
|
||||
Ok(mut conn) => {
|
||||
|
||||
let result = Box::new(methods::execute_query(&mut conn, query, params_json, force_result));
|
||||
|
||||
match conn.as_mut().ping(){
|
||||
Ok(_) => obj.connection = Some(conn),
|
||||
Err(_) => drop(conn)
|
||||
}
|
||||
|
||||
result
|
||||
},
|
||||
Err(e) => Box::new(e),
|
||||
}
|
||||
},
|
||||
3 => {
|
||||
|
||||
@@ -65,6 +61,41 @@ pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box<dyn
|
||||
|
||||
Box::new(obj.set_tls(use_tls, accept_invalid_certs, &ca_cert_path))
|
||||
|
||||
},
|
||||
4 => {
|
||||
let key = params[0].get_string().unwrap_or("".to_string());
|
||||
let index = params[1].get_i32().unwrap_or(0);
|
||||
|
||||
Box::new(obj.datasets.get_row(&key, index as usize).unwrap_or_else(|| "".to_string()))
|
||||
},
|
||||
5 => {
|
||||
let key = params[0].get_string().unwrap_or("".to_string());
|
||||
|
||||
match obj.datasets.len(&key){
|
||||
Some(len) => Box::new(len as i32),
|
||||
None => Box::new(json!(
|
||||
{"result": false, "error": format!("Dataset {} not found", key)}
|
||||
).to_string()),
|
||||
}
|
||||
},
|
||||
6 => {
|
||||
let key = params[0].get_string().unwrap_or("".to_string());
|
||||
obj.datasets.remove(&key);
|
||||
Box::new(json!({"result": true}).to_string())
|
||||
},
|
||||
7 => {
|
||||
|
||||
let text = params[0].get_string().unwrap_or("".to_string());
|
||||
let force = params[1].get_bool().unwrap_or(false);
|
||||
|
||||
Box::new(methods::init_query(obj, &text, force))
|
||||
},
|
||||
8 => {
|
||||
let key = params[0].get_string().unwrap_or("".to_string());
|
||||
let param = params[1].get_string().unwrap_or("".to_string());
|
||||
|
||||
Box::new(methods::add_query_param(obj, &key, param))
|
||||
|
||||
}
|
||||
_ => Box::new(false), // Неверный номер команды
|
||||
}
|
||||
@@ -88,6 +119,7 @@ pub struct AddIn {
|
||||
use_tls: bool,
|
||||
accept_invalid_certs: bool,
|
||||
ca_cert_path: String,
|
||||
datasets: Datasets,
|
||||
}
|
||||
|
||||
impl AddIn {
|
||||
@@ -100,6 +132,7 @@ impl AddIn {
|
||||
use_tls: false,
|
||||
accept_invalid_certs: false,
|
||||
ca_cert_path: String::new(),
|
||||
datasets: Datasets::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -144,11 +144,6 @@
|
||||
, Знач Соединение = ""
|
||||
, Знач Tls = "") Экспорт
|
||||
|
||||
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекстЗапроса, Истина);
|
||||
OPI_ПреобразованиеТипов.ПолучитьБулево(ФорсироватьРезультат);
|
||||
|
||||
Параметры_ = ОбработатьПараметры(Параметры);
|
||||
|
||||
Если ЭтоКоннектор(Соединение) Тогда
|
||||
ЗакрыватьСоединение = Ложь;
|
||||
Коннектор = Соединение;
|
||||
@@ -161,14 +156,16 @@
|
||||
Возврат Коннектор;
|
||||
КонецЕсли;
|
||||
|
||||
Результат = Коннектор.Execute(ТекстЗапроса, Параметры_, ФорсироватьРезультат);
|
||||
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекстЗапроса, Истина);
|
||||
OPI_ПреобразованиеТипов.ПолучитьБулево(ФорсироватьРезультат);
|
||||
|
||||
Параметры_ = ОбработатьПараметры(Параметры);
|
||||
Результат = OPI_ЗапросыSQL.ВыполнитьЗапросСОбработкой(Коннектор, ТекстЗапроса, ФорсироватьРезультат, Параметры_);
|
||||
|
||||
Если ЗакрыватьСоединение Тогда
|
||||
ЗакрытьСоединение(Коннектор);
|
||||
КонецЕсли;
|
||||
|
||||
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
|
||||
|
||||
Возврат Результат;
|
||||
|
||||
КонецФункции
|
||||
@@ -544,27 +541,28 @@
|
||||
Функция ОбработатьПараметры(Знач Параметры)
|
||||
|
||||
Если Не ЗначениеЗаполнено(Параметры) Тогда
|
||||
Возврат "[]";
|
||||
Возврат Новый Массив;
|
||||
КонецЕсли;
|
||||
|
||||
Параметры_ = Новый Массив;
|
||||
OPI_ПреобразованиеТипов.ПолучитьМассив(Параметры);
|
||||
|
||||
Для Н = 0 По Параметры.ВГраница() Цикл
|
||||
Счетчик = 0;
|
||||
Для Каждого Параметр Из Параметры Цикл
|
||||
|
||||
ТекущийПараметр = Параметры[Н];
|
||||
ТекущийПараметр = ОбработатьПараметр(Параметр);
|
||||
ТекущийПараметр = OPI_Инструменты.JSONСтрокой(ТекущийПараметр, , Ложь);
|
||||
|
||||
ТекущийПараметр = ОбработатьПараметр(ТекущийПараметр);
|
||||
Если СтрНачинаетсяС(ТекущийПараметр, "НЕ JSON") Тогда
|
||||
ВызватьИсключение СтрШаблон("Ошибка валидации JSON параметра. Индекс массив %1", Счетчик);
|
||||
Иначе
|
||||
Параметры_.Добавить(ТекущийПараметр);
|
||||
КонецЕсли;
|
||||
|
||||
Параметры[Н] = ТекущийПараметр;
|
||||
Счетчик = Счетчик + 1;
|
||||
|
||||
КонецЦикла;
|
||||
|
||||
Параметры_ = OPI_Инструменты.JSONСтрокой(Параметры, , Ложь);
|
||||
|
||||
Если СтрНачинаетсяС(Параметры_, "НЕ JSON") Тогда
|
||||
ВызватьИсключение "Ошибка валидации JSON массива параметров!";
|
||||
КонецЕсли;
|
||||
|
||||
Возврат Параметры_;
|
||||
|
||||
КонецФункции
|
||||
|
||||
Reference in New Issue
Block a user