mirror of
https://github.com/Bayselonarrend/OpenIntegrations.git
synced 2025-01-16 05:06:02 +02:00
Добавление проверок сеттеров и ВК для MongoDB
This commit is contained in:
parent
ff80f858e1
commit
0fd4806605
2552
src/addins/mongo/Cargo.lock
generated
Normal file
2552
src/addins/mongo/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
src/addins/mongo/Cargo.toml
Normal file
18
src/addins/mongo/Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "opi_mongodb"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[profile.release]
|
||||
lto = true # Enable Link Time Optimization
|
||||
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
|
||||
panic = "abort" # Abort on panic
|
||||
strip = true # Automatically strip symbols from the binary.
|
||||
|
||||
[dependencies]
|
||||
addin1c = "0.5.0"
|
||||
mongodb = { version = "2.0", features = ["sync"] }
|
||||
bson = "2.0"
|
83
src/addins/mongo/src/component/methods.rs
Normal file
83
src/addins/mongo/src/component/methods.rs
Normal file
@ -0,0 +1,83 @@
|
||||
use addin1c::{Variant};
|
||||
use crate::component::AddIn;
|
||||
use mongodb::{Client, Collection, options::ClientOptions, bson::{doc, Bson, Document}};
|
||||
use std::error::Error;
|
||||
|
||||
pub fn amount(obj: &AddIn, params: &mut [Variant]) -> i32 {
|
||||
|
||||
let result = params[0].get_i32().unwrap() + params[1].get_i32().unwrap();
|
||||
params[0].set_i32(999);
|
||||
|
||||
result
|
||||
|
||||
}
|
||||
|
||||
pub struct MongoClient {
|
||||
client: Client,
|
||||
}
|
||||
|
||||
impl MongoClient {
|
||||
// Конструктор для создания клиента
|
||||
pub fn new(uri: &str) -> MongoClient {
|
||||
|
||||
match ClientOptions::parse(uri) {
|
||||
Ok(client_options) => match Client::with_options(client_options) {
|
||||
Ok(client) => MongoClient { client },
|
||||
Err(_) => MongoClient { client: Client::with_options(ClientOptions::default()).unwrap() }, // Возвращаем дефолтный клиент в случае ошибки
|
||||
},
|
||||
Err(_) => MongoClient { client: Client::with_options(ClientOptions::default()).unwrap() }, // Возвращаем дефолтный клиент в случае ошибки
|
||||
}
|
||||
}
|
||||
|
||||
// Синхронный метод для вставки данных, возвращающий строку или ошибку
|
||||
pub fn insert_data(&self, db_name: &str, collection_name: &str, data: &str) -> String {
|
||||
|
||||
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
|
||||
let doc = doc! { "name": data };
|
||||
|
||||
match collection.insert_one(doc, None) {
|
||||
Ok(_) => "Insert successful".to_string(),
|
||||
Err(err) => format!("Insert failed: {}", err),
|
||||
}
|
||||
}
|
||||
|
||||
// Синхронный метод для поиска данных, возвращающий строку или ошибку
|
||||
pub fn find_data(&self, db_name: &str, collection_name: &str, query: &str) -> String {
|
||||
|
||||
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
|
||||
let filter = doc! { "name": query };
|
||||
|
||||
match collection.find_one(filter, None) {
|
||||
Ok(Some(doc)) => match doc.get_str("name") {
|
||||
Ok(name) => name.to_string(),
|
||||
Err(_) => "Error reading name from document".to_string(),
|
||||
},
|
||||
Ok(None) => "Document not found".to_string(),
|
||||
Err(err) => format!("Find failed: {}", err),
|
||||
}
|
||||
}
|
||||
|
||||
// Синхронный метод для подсчета документов, возвращающий количество или ошибку
|
||||
pub fn count_documents(&self, db_name: &str, collection_name: &str) -> i32 {
|
||||
|
||||
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
|
||||
|
||||
match collection.count_documents(None, None) {
|
||||
Ok(count) => count as i32,
|
||||
Err(_) => -1, // Возвращаем -1 в случае ошибки
|
||||
}
|
||||
}
|
||||
|
||||
// Синхронный метод для проверки наличия документа, возвращающий булевый результат
|
||||
pub fn document_exists(&self, db_name: &str, collection_name: &str, query: &str) -> bool {
|
||||
|
||||
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
|
||||
let filter = doc! { "name": query };
|
||||
|
||||
match collection.find_one(filter, None) {
|
||||
Ok(Some(_)) => true,
|
||||
Ok(None) => false,
|
||||
Err(_) => false, // Возвращаем false в случае ошибки
|
||||
}
|
||||
}
|
||||
}
|
111
src/addins/mongo/src/component/mod.rs
Normal file
111
src/addins/mongo/src/component/mod.rs
Normal file
@ -0,0 +1,111 @@
|
||||
mod methods;
|
||||
|
||||
use addin1c::{name, Variant};
|
||||
use crate::core::getset;
|
||||
|
||||
// МЕТОДЫ КОМПОНЕНТЫ -------------------------------------------------------------------------------
|
||||
|
||||
// Синонимы
|
||||
pub const METHODS: &[&[u16]] = &[
|
||||
name!("InsertData"), // 2
|
||||
name!("FindData"), // 3
|
||||
name!("CountDocuments"), // 4
|
||||
name!("DocumentExists"), // 5
|
||||
];
|
||||
|
||||
// Число параметров функций компоненты
|
||||
pub fn get_params_amount(num: usize) -> usize {
|
||||
match num {
|
||||
0 => 3,
|
||||
1 => 3,
|
||||
2 => 2,
|
||||
3 => 2,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
// Соответствие функций Rust функциям компоненты
|
||||
// Вызовы должны быть обернуты в Box::new
|
||||
pub fn cal_func(obj: &AddIn, num: usize, params: &mut [Variant]) -> Box<dyn crate::core::getset::ValueType> {
|
||||
|
||||
let address = &obj.address;
|
||||
let client = methods::MongoClient::new(address);
|
||||
|
||||
match num {
|
||||
0 => {
|
||||
|
||||
let db_name = params[0].get_string().unwrap_or(String::new());
|
||||
let collection_name= params[1].get_string().unwrap_or(String::new());
|
||||
let data = params[2].get_string().unwrap_or(String::new());
|
||||
|
||||
Box::new(client.insert_data(&db_name, &collection_name, &data))
|
||||
},
|
||||
|
||||
1 => {
|
||||
|
||||
let db_name = params[0].get_string().unwrap_or(String::new());
|
||||
let collection_name= params[1].get_string().unwrap_or(String::new());
|
||||
let query = params[2].get_string().unwrap_or(String::new());
|
||||
|
||||
Box::new(client.find_data(&db_name, &collection_name, &query))
|
||||
|
||||
},
|
||||
|
||||
2 => {
|
||||
|
||||
let db_name = params[0].get_string().unwrap_or(String::new());
|
||||
let collection_name= params[1].get_string().unwrap_or(String::new());
|
||||
|
||||
Box::new(client.count_documents(&db_name, &collection_name))
|
||||
|
||||
},
|
||||
|
||||
3 => {
|
||||
|
||||
let db_name = params[0].get_string().unwrap_or(String::new());
|
||||
let collection_name= params[1].get_string().unwrap_or(String::new());
|
||||
let query = params[2].get_string().unwrap_or(String::new());
|
||||
|
||||
Box::new(client.document_exists(&db_name, &collection_name, &query))
|
||||
|
||||
}
|
||||
_ => Box::new(false),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
// ПОЛЯ КОМПОНЕНТЫ ---------------------------------------------------------------------------------
|
||||
|
||||
// Синонимы
|
||||
pub const PROPS: &[&[u16]] = &[
|
||||
name!("address")
|
||||
];
|
||||
|
||||
// Имена и типы
|
||||
pub struct AddIn {
|
||||
address: String
|
||||
}
|
||||
|
||||
// Конструктор
|
||||
impl AddIn {
|
||||
|
||||
// Значения по умолчанию
|
||||
pub fn new() -> AddIn {
|
||||
AddIn {
|
||||
address: String::from("")
|
||||
}
|
||||
}
|
||||
|
||||
// Сюда просто нужно еще раз добавить имена полей
|
||||
pub fn get_field_ptr(&self, index: usize) -> *const dyn getset::ValueType {
|
||||
match index {
|
||||
0 => &self.address as &dyn getset::ValueType as *const _,
|
||||
_ => panic!("Index out of bounds"),
|
||||
}
|
||||
}
|
||||
pub fn get_field_ptr_mut(&mut self, index: usize) -> *mut dyn getset::ValueType { self.get_field_ptr(index) as *mut _ }
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
78
src/addins/mongo/src/core/getset.rs
Normal file
78
src/addins/mongo/src/core/getset.rs
Normal file
@ -0,0 +1,78 @@
|
||||
use addin1c::{Variant, Tm};
|
||||
|
||||
|
||||
pub trait ValueType {
|
||||
fn get_value(&self, val: &mut Variant) -> bool;
|
||||
fn set_value(&mut self, val: &Variant);
|
||||
}
|
||||
|
||||
// Реализация для i32
|
||||
impl ValueType for i32 {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
val.set_i32(*self);
|
||||
true
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_i32().unwrap_or(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Реализация для f64
|
||||
impl ValueType for f64 {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
val.set_f64(*self);
|
||||
true
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_f64().unwrap_or(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
// Реализация для bool
|
||||
impl ValueType for bool {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
val.set_bool(*self);
|
||||
true
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_bool().unwrap_or(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Реализация для tm
|
||||
impl ValueType for Tm {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
val.set_date(*self);
|
||||
true
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_date().unwrap_or(Tm::default());
|
||||
}
|
||||
}
|
||||
|
||||
// Реализация для String
|
||||
impl ValueType for String {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
let s: Vec<u16> = self.encode_utf16().collect();
|
||||
val.set_str1c(s.as_slice()).is_ok()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_string().unwrap_or("".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// Реализация для Vec<u8>
|
||||
impl ValueType for Vec<u8> {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
val.set_blob(self.as_slice()).is_ok()
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_blob().unwrap_or(&[]).to_vec()
|
||||
}
|
||||
}
|
59
src/addins/mongo/src/core/mod.rs
Normal file
59
src/addins/mongo/src/core/mod.rs
Normal file
@ -0,0 +1,59 @@
|
||||
pub mod getset;
|
||||
|
||||
use addin1c::{name, RawAddin, Variant};
|
||||
|
||||
use crate::component::METHODS;
|
||||
use crate::component::PROPS;
|
||||
use crate::component::get_params_amount;
|
||||
use crate::component::cal_func;
|
||||
use crate::component::AddIn;
|
||||
|
||||
|
||||
// Обработка удаления объекта
|
||||
impl Drop for AddIn {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
// Определение класса
|
||||
impl RawAddin for AddIn {
|
||||
|
||||
fn register_extension_as(&mut self) -> &'static [u16] {
|
||||
name!("Test")
|
||||
}
|
||||
fn get_n_props(&mut self) -> usize {
|
||||
PROPS.len()
|
||||
}
|
||||
fn find_prop(&mut self, name: &[u16]) -> Option<usize> {
|
||||
PROPS.iter().position(|&x| x == name)
|
||||
}
|
||||
fn get_prop_name(&mut self, num: usize, _alias: usize) -> Option<&'static [u16]> { PROPS.get(num).copied() }
|
||||
fn get_prop_val(&mut self, num: usize, val: &mut Variant) -> bool {let field: &dyn getset::ValueType = &self[num]; field.get_value(val) }
|
||||
fn set_prop_val(&mut self, num: usize, val: &Variant) -> bool {let field: &mut dyn getset::ValueType = &mut self[num]; field.set_value(val); true }
|
||||
fn is_prop_readable(&mut self, _num: usize) -> bool { true }
|
||||
fn is_prop_writable(&mut self, num: usize) -> bool { true }
|
||||
fn get_n_methods(&mut self) -> usize { METHODS.len() }
|
||||
fn find_method(&mut self, name: &[u16]) -> Option<usize> { METHODS.iter().position(|&x| x == name) }
|
||||
fn get_method_name(&mut self, num: usize, _alias: usize) -> Option<&'static [u16]> { METHODS.get(num).copied() }
|
||||
fn get_n_params(&mut self, num: usize) -> usize { get_params_amount(num) }
|
||||
fn get_param_def_value(&mut self, _method_num: usize, _param_num: usize, _value: Variant, ) -> bool { true }
|
||||
fn has_ret_val(&mut self, num: usize) -> bool { true }
|
||||
fn call_as_proc(&mut self, _num: usize, _params: &mut [Variant]) -> bool { false }
|
||||
fn call_as_func(&mut self, num: usize, params: &mut [Variant], ret_value: &mut Variant, ) -> bool { cal_func(self, num, params).get_value(ret_value) }
|
||||
|
||||
}
|
||||
|
||||
impl std::ops::Index<usize> for AddIn {
|
||||
type Output = dyn getset::ValueType;
|
||||
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
unsafe { &*self.get_field_ptr(index) }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::IndexMut<usize> for AddIn {
|
||||
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||
unsafe { &mut *self.get_field_ptr_mut(index) }
|
||||
}
|
||||
}
|
||||
|
||||
|
48
src/addins/mongo/src/lib.rs
Normal file
48
src/addins/mongo/src/lib.rs
Normal file
@ -0,0 +1,48 @@
|
||||
pub mod component;
|
||||
mod core;
|
||||
|
||||
|
||||
use std::{
|
||||
ffi::{c_int, c_long, c_void},
|
||||
sync::atomic::{AtomicI32, Ordering},
|
||||
};
|
||||
|
||||
use component::AddIn;
|
||||
use addin1c::{create_component, destroy_component, name, AttachType};
|
||||
|
||||
pub static mut PLATFORM_CAPABILITIES: AtomicI32 = AtomicI32::new(-1);
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn GetClassObject(name: *const u16, component: *mut *mut c_void) -> c_long {
|
||||
|
||||
let addin = AddIn::new();
|
||||
create_component(component, addin)
|
||||
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn DestroyObject(component: *mut *mut c_void) -> c_long {
|
||||
destroy_component(component)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn GetClassNames() -> *const u16 {
|
||||
// small strings for performance
|
||||
name!("Client").as_ptr()
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn SetPlatformCapabilities(capabilities: c_int) -> c_int {
|
||||
PLATFORM_CAPABILITIES.store(capabilities, Ordering::Relaxed);
|
||||
3
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn GetAttachType() -> AttachType {
|
||||
AttachType::Any
|
||||
}
|
4
src/addins/tmpl/Cargo.lock
generated
4
src/addins/tmpl/Cargo.lock
generated
@ -4,9 +4,9 @@ version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addin1c"
|
||||
version = "0.2.0"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58f985421a06951cfab1529e5bf26203b42fba9d792de9adc99486fbf3214dc3"
|
||||
checksum = "ef34e8b7ff4c43e87491a4cc30a4779a9f67c50db43378a36362c7a56246e05b"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
"utf16_lit",
|
||||
|
@ -13,4 +13,4 @@ panic = "abort" # Abort on panic
|
||||
strip = true # Automatically strip symbols from the binary.
|
||||
|
||||
[dependencies]
|
||||
addin1c = "0.2.0"
|
||||
addin1c = "0.5.0"
|
@ -1,20 +1,18 @@
|
||||
use addin1c::{Variant, ParamValue};
|
||||
use addin1c::{Variant};
|
||||
use crate::component::AddIn;
|
||||
|
||||
pub fn send_message(obj: &AddIn, params: &[Variant]) -> String {
|
||||
|
||||
let field1 = &obj.field1;
|
||||
|
||||
|
||||
if let ParamValue::Str(x) = ¶ms[0].get() {
|
||||
let pref = String::from_utf16(*x).unwrap();
|
||||
pref + field1
|
||||
} else {
|
||||
"Param error".to_string()
|
||||
}
|
||||
params[0].get_string().unwrap_or("".to_string()) + field1
|
||||
|
||||
}
|
||||
|
||||
pub fn amount(obj: &AddIn, params: &[Variant]) -> i32 {
|
||||
params[0].get_i32().unwrap() + params[1].get_i32().unwrap()
|
||||
pub fn amount(obj: &AddIn, params: &mut [Variant]) -> i32 {
|
||||
|
||||
let result = params[0].get_i32().unwrap() + params[1].get_i32().unwrap();
|
||||
params[0].set_i32(999);
|
||||
|
||||
result
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ mod methods;
|
||||
use addin1c::{name, Variant};
|
||||
use crate::core::getset;
|
||||
|
||||
|
||||
// МЕТОДЫ КОМПОНЕНТЫ -------------------------------------------------------------------------------
|
||||
|
||||
// Синонимы
|
||||
@ -27,7 +26,7 @@ pub fn cal_func(obj: &AddIn, num: usize, params: &mut [Variant]) -> Box<dyn crat
|
||||
|
||||
match num {
|
||||
0 => Box::new(methods::send_message(&obj, ¶ms)),
|
||||
1 => Box::new(methods::amount(&obj, ¶ms)),
|
||||
1 => Box::new(methods::amount(&obj, params)),
|
||||
_ => Box::new(false),
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
use addin1c::{Variant, ParamValue, Tm};
|
||||
use addin1c::{Variant, Tm};
|
||||
|
||||
// Реализация для i32
|
||||
|
||||
pub trait ValueType {
|
||||
fn get_value(&self, val: &mut Variant) -> bool;
|
||||
fn set_value(&mut self, val: &Variant);
|
||||
}
|
||||
|
||||
// Реализация для i32
|
||||
impl ValueType for i32 {
|
||||
fn get_value(&self, val: &mut Variant) -> bool {
|
||||
val.set_i32(*self);
|
||||
@ -14,7 +14,7 @@ impl ValueType for i32 {
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_i32().unwrap();
|
||||
*self = val.get_i32().unwrap_or(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ impl ValueType for f64 {
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_f64().unwrap();
|
||||
*self = val.get_f64().unwrap_or(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ impl ValueType for bool {
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_bool().unwrap();
|
||||
*self = val.get_bool().unwrap_or(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ impl ValueType for Tm {
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_date().unwrap();
|
||||
*self = val.get_date().unwrap_or(Tm::default());
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,6 +73,6 @@ impl ValueType for Vec<u8> {
|
||||
}
|
||||
|
||||
fn set_value(&mut self, val: &Variant) {
|
||||
*self = val.get_blob().unwrap().to_vec()
|
||||
*self = val.get_blob().unwrap_or(&[]).to_vec()
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
pub mod getset;
|
||||
|
||||
use addin1c::{name, ParamValue, RawAddin, Variant};
|
||||
use std::ops::{Index, IndexMut};
|
||||
use addin1c::{name, RawAddin, Variant};
|
||||
|
||||
use crate::component::METHODS;
|
||||
use crate::component::PROPS;
|
||||
|
Loading…
Reference in New Issue
Block a user