1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2025-08-10 22:41:43 +02:00
This commit is contained in:
Anton Titovets
2024-12-12 16:04:12 +03:00
parent 66dc899907
commit e4806d002b
16 changed files with 750 additions and 3367 deletions

View File

@@ -1,3 +0,0 @@
[target.x86_64-unknown-linux-gnu]
linker = "zig cc"

File diff suppressed because it is too large Load Diff

View File

@@ -1,568 +0,0 @@
use mongodb::{options::{ClientOptions, FindOptions}, bson::{doc, Document}};
use mongodb::sync::{Client, Collection, Database};
use serde_json::{json, Value};
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() },
}
}
// Вспомогательная функция для формирования JSON ответа
fn make_response(ok: bool, data: &str) -> String {
// Попробуем распарсить строку как JSON
let parsed_data: Result<Value, _> = serde_json::from_str(data);
// Если удаётся распарсить, вставляем как объект, иначе — как строку
let response = match parsed_data {
Ok(json_data) => json!({
"ok": ok,
"data": json_data
}),
Err(_) => json!({
"ok": ok,
"data": data
}),
};
response.to_string()
}
// ОСНОВНЫЕ МЕТОДЫ -----------------------------------------------------------------------------
// РАБОТА С БАЗАМИ ДАННЫХ ----------------------------------------------------------------------
// Получение списка баз
pub fn list_databases(&self) -> String {
match self.client.list_database_names(None, None) {
Ok(databases) =>
Self::make_response(
true,
&format!("{:?}", databases)),
Err(err) =>
Self::make_response(
false,
&format!("Failed to list databases: {}", err)),
}
}
// Получение статистики базы данных
pub fn database_stats(&self, db_name: &str) -> String {
let db = self.client.database(db_name);
match db.run_command(doc! { "dbStats": 1 }, None) {
Ok(stats) =>
Self::make_response(
true,
&format!("{:?}", stats)),
Err(err) =>
Self::make_response(
false,
&format!("Failed to get database stats for '{}': {}", db_name, err)),
}
}
// Удаление базы
pub fn drop_database(&self, db_name: &str) -> String {
match self.client.database(db_name).drop(None) {
Ok(_) =>
Self::make_response(
true,
&format!("Database '{}' dropped successfully", db_name)),
Err(err) =>
Self::make_response(
false,
&format!("Failed to drop database '{}': {}", db_name, err)),
}
}
// Проверка существования базы
pub fn database_exists(&self, db_name: &str) -> bool {
// Получаем список всех баз данных
let db_list = match self.client.list_databases(None, None) {
Ok(databases) => databases,
Err(_) => return false, // Если ошибка при получении списка баз, возвращаем false
};
// Проверяем, есть ли указанная база данных в списке
db_list.iter().any(|db| db.name == db_name)
}
// РАБОТА С КОЛЛЕКЦИЯМИ ------------------------------------------------------------------------
// Получение списка коллекций
pub fn list_collections(&self, db_name: &str) -> String {
let db: Database = self.client.database(db_name);
match db.list_collection_names(None) {
Ok(collection_names) => {
// Преобразуем список коллекций в JSON
let collections_json = serde_json::to_string(&collection_names).unwrap();
Self::make_response(true, &collections_json)
}
Err(err) => Self::make_response(false, &format!("Failed to list collections: {}", err)),
}
}
// Создание коллекции в базе данных
pub fn create_collection(&self, db_name: &str, collection_name: &str) -> String {
let db = self.client.database(db_name);
match db.create_collection(collection_name, None) {
Ok(_) => Self::make_response(
true,
&format!("Collection '{}' created successfully in database '{}'", collection_name, db_name)),
Err(err) =>
Self::make_response(
false,
&format!("Failed to create collection '{}': {}", collection_name, err)),
}
}
// Удаление коллекции из базы данных
pub fn drop_collection(&self, db_name: &str, collection_name: &str) -> String {
let collection = self.client.database(db_name).collection::<Document>(collection_name);
match collection.drop(None) {
Ok(_) =>
Self::make_response(
true,
&format!("Collection '{}' dropped successfully from database '{}'", collection_name, db_name)),
Err(err) =>
Self::make_response(
false,
&format!("Failed to drop collection '{}': {}", collection_name, err)),
}
}
// Проверка, существует ли коллекция
pub fn collection_exists(&self, db_name: &str, collection_name: &str) -> String {
match self.client.database(db_name).list_collection_names(None) {
Ok(collections) => {
if collections.contains(&collection_name.to_string()) {
Self::make_response(
true,
&format!("Collection '{}' exists in database '{}'", collection_name, db_name))
} else {
Self::make_response(
false,
&format!("Collection '{}' does not exist in database '{}'", collection_name, db_name))
}
}
Err(err) =>
Self::make_response(
false,
&format!("Failed to list collections: {}", err)),
}
}
// РАБОТА С ДОКУМЕНТАМИ ------------------------------------------------------------------------
// ДОБАВЛЕНИЕ ДОКУМЕНТОВ -----------------------------------------------------------------------
// Метод для вставки одного документа
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 json_value: Value = match serde_json::from_str(data) {
Ok(value) => value,
Err(err) =>
return Self::make_response(
false,
&format!("Failed to parse JSON: {}", err)),
};
let bson_document = match bson::to_bson(&json_value) {
Ok(bson) => bson,
Err(err) =>
return Self::make_response(
false,
&format!("Failed to convert to BSON: {}", err)),
};
match collection.insert_one(bson_document.as_document().unwrap(), None) {
Ok(_) =>
Self::make_response(
true,
"Insert successful"),
Err(err) =>
Self::make_response(
false,
&format!("Insert failed: {}", err)),
}
}
// Метод для вставки нескольких документов
pub fn insert_many(&self, db_name: &str, collection_name: &str, data: &str) -> String {
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
let json_values: Vec<Value> = match serde_json::from_str(data) {
Ok(values) => values,
Err(err) =>
return Self::make_response(
false,
&format!("Failed to parse JSON array: {}", err)),
};
let bson_documents: Vec<Document> = match json_values
.into_iter()
.map(|value| bson::to_bson(&value))
.collect::<Result<Vec<_>, _>>()
{
Ok(bson_array) => bson_array
.into_iter()
.filter_map(|bson| bson.as_document().cloned())
.collect(),
Err(err) =>
return Self::make_response(
false,
&format!("Failed to convert JSON to BSON: {}", err)),
};
match collection.insert_many(bson_documents, None) {
Ok(result) =>
Self::make_response(
true,
&format!("Insert successful: {} documents inserted", result.inserted_ids.len())),
Err(err) =>
Self::make_response(
false,
&format!("Insert failed: {}", err)),
}
}
// ОБНОВЛЕНИЕ ДОКУМЕНТОВ -----------------------------------------------------------------------
// Обновление одного документа в коллекции
pub fn update_data(&self, db_name: &str, collection_name: &str, query: &str, update: &str) -> String {
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
// Парсим JSON в структуру Value
let bson_query: Value = match serde_json::from_str(query) {
Ok(value) => value,
Err(err) => return Self::make_response(false, &format!("Failed to parse query JSON: {}", err)),
};
let bson_update: Value = match serde_json::from_str(update) {
Ok(value) => value,
Err(err) => return Self::make_response(false, &format!("Failed to parse update JSON: {}", err)),
};
// Преобразуем в BSON документы
let bson_query_doc = bson::to_document(&bson_query).unwrap();
let bson_update_doc = bson::to_document(&bson_update).unwrap();
// Преобразуем в UpdateModifications
let update_modifications = doc! {
"$set": bson_update_doc
};
// Обновляем один документ
match collection.update_one(bson_query_doc, update_modifications, None) {
Ok(_) => Self::make_response(true, "Update successful"),
Err(err) => Self::make_response(false, &format!("Update failed: {}", err)),
}
}
// Обновление нескольких документов
pub fn update_many(&self, db_name: &str, collection_name: &str, query: &str, update: &str) -> String {
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
// Парсим JSON в структуру Value
let bson_query: Value = match serde_json::from_str(query) {
Ok(value) => value,
Err(err) => return Self::make_response(false, &format!("Failed to parse query JSON: {}", err)),
};
let bson_update: Value = match serde_json::from_str(update) {
Ok(value) => value,
Err(err) => return Self::make_response(false, &format!("Failed to parse update JSON: {}", err)),
};
// Преобразуем в BSON документы
let bson_query_doc = bson::to_document(&bson_query).unwrap();
let bson_update_doc = bson::to_document(&bson_update).unwrap();
// Преобразуем в UpdateModifications
let update_modifications = doc! {"$set": bson_update_doc};
// Обновляем все документы, которые соответствуют запросу
match collection.update_many(bson_query_doc, update_modifications, None) {
Ok(result) => Self::make_response(
true,
&format!("Update successful: {} documents updated", result.modified_count)
),
Err(err) => Self::make_response(false, &format!("Update failed: {}", err)),
}
}
// УДАЛЕНИЕ ДОКУМЕНТОВ -------------------------------------------------------------------------
// Удаление одного документа
pub fn delete_data(&self, db_name: &str, collection_name: &str, query: &str) -> String {
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
// Преобразуем строку JSON в объект
let query_value: Value = match serde_json::from_str(query) {
Ok(value) => value,
Err(err) => return Self::make_response(false, &format!("Failed to parse query JSON: {}", err)),
};
// Преобразуем объект JSON в BSON
let bson_query = match bson::to_bson(&query_value) {
Ok(bson) => bson,
Err(err) => return Self::make_response(false, &format!("Failed to convert query to BSON: {}", err)),
};
// Проверяем, что BSON является документом
match bson_query.as_document() {
Some(bson_query_doc) => {
// Удаляем один документ
match collection.delete_one(bson_query_doc.clone(), None) {
Ok(result) => {
if result.deleted_count > 0 {
Self::make_response(true, "Delete successful")
} else {
Self::make_response(false, "No documents matched the query")
}
}
Err(err) => Self::make_response(false, &format!("Delete failed: {}", err)),
}
}
None => Self::make_response(false, "Query is not a valid BSON document"),
}
}
// Удаление нескольких документов
pub fn delete_many(&self, db_name: &str, collection_name: &str, query: &str) -> String {
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
// Преобразуем строку JSON в объект
let query_value: Value = match serde_json::from_str(query) {
Ok(value) => value,
Err(err) => return Self::make_response(false, &format!("Failed to parse query JSON: {}", err)),
};
// Преобразуем объект JSON в BSON
let bson_query = match bson::to_bson(&query_value) {
Ok(bson) => bson,
Err(err) => return Self::make_response(false, &format!("Failed to convert query to BSON: {}", err)),
};
// Проверяем, что BSON является документом
match bson_query.as_document() {
Some(bson_query_doc) => {
// Удаляем несколько документов
match collection.delete_many(bson_query_doc.clone(), None) {
Ok(result) => Self::make_response(
true,
&format!("Delete successful: {} documents deleted", result.deleted_count),
),
Err(err) => Self::make_response(false, &format!("Delete failed: {}", err)),
}
}
None => Self::make_response(false, "Query is not a valid BSON document"),
}
}
// ПОИСК ДОКУМЕНТОВ ----------------------------------------------------------------------------
// Поиск одного документа
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)) => Self::make_response(true, &format!("{:?}", doc)),
Ok(None) => Self::make_response(false, "Document not found"),
Err(err) => Self::make_response(false, &format!("Find failed: {}", err)),
}
}
// Поиск нескольких документов с пагинацией
pub fn find_many(&self, db_name: &str, collection_name: &str, query: &str, page: i32, page_size: i32) -> String {
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
// Парсим JSON в структуру Value
let bson_query: Value = match serde_json::from_str(query) {
Ok(value) => value,
Err(err) => return Self::make_response(false, &format!("Failed to parse query JSON: {}", err)),
};
// Преобразуем JSON в BSON документ
let bson_query_doc = match bson::to_document(&bson_query) {
Ok(doc) => doc,
Err(err) => return Self::make_response(false, &format!("Failed to convert query to BSON: {}", err)),
};
// Создаем параметры запроса с пагинацией
let skip = page * page_size;
let find_options = FindOptions::builder()
.skip(skip as u64) // Пропустить количество документов
.limit(page_size as i64) // Ограничить количество документов
.build();
// Выполняем поиск
let cursor = match collection.find(bson_query_doc, find_options) {
Ok(cursor) => cursor,
Err(err) => return Self::make_response(false, &format!("Find failed: {}", err)),
};
// Собираем все документы из курсора в вектор
let mut results = Vec::new();
for result in cursor {
match result {
Ok(doc) => results.push(doc),
Err(err) => return Self::make_response(false, &format!("Error iterating documents: {}", err)),
}
}
// Преобразуем документы в JSON строку
let json_results = match serde_json::to_string(&results) {
Ok(json) => json,
Err(err) => return Self::make_response(false, &format!("Failed to convert documents to JSON: {}", err)),
};
Self::make_response(true, &json_results)
}
// Поиск всех документов с пагинацией
pub fn find_all(&self, db_name: &str, collection_name: &str, query: &str, page: i32, page_size: i32) -> String {
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
// Парсим JSON в структуру Value
let bson_query: Value = match serde_json::from_str(query) {
Ok(value) => value,
Err(err) => return Self::make_response(false, &format!("Failed to parse query JSON: {}", err)),
};
// Преобразуем JSON в BSON документ
let bson_query_doc = match bson::to_document(&bson_query) {
Ok(doc) => doc,
Err(err) => return Self::make_response(false, &format!("Failed to convert query to BSON: {}", err)),
};
// Создаем параметры запроса с пагинацией
let skip = page * page_size;
let find_options = FindOptions::builder()
.skip(skip as u64) // Пропустить количество документов
.limit(page_size as i64) // Ограничить количество документов
.build();
// Выполняем поиск
let cursor = match collection.find(bson_query_doc, find_options) {
Ok(cursor) => cursor,
Err(err) => return Self::make_response(false, &format!("Find failed: {}", err)),
};
// Собираем все документы из курсора в вектор
let mut results = Vec::new();
for result in cursor {
match result {
Ok(doc) => results.push(doc),
Err(err) => return Self::make_response(false, &format!("Error iterating documents: {}", err)),
}
}
// Преобразуем документы в JSON строку
let json_results = match serde_json::to_string(&results) {
Ok(json) => json,
Err(err) => return Self::make_response(false, &format!("Failed to convert documents to JSON: {}", err)),
};
Self::make_response(true, &json_results)
}
// Проверка существования документа
pub fn document_exists(&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(_)) => Self::make_response(true, "true"),
Ok(None) => Self::make_response(false, "false"),
Err(err) => Self::make_response(false, &format!("Check failed: {}", err)),
}
}
// Количество документов в коллекции
pub fn count_documents(&self, db_name: &str, collection_name: &str) -> String {
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
match collection.count_documents(None, None) {
Ok(count) => Self::make_response(true, &count.to_string()),
Err(err) => Self::make_response(false, &format!("Count failed: {}", err)),
}
}
// ДРУГОЕ --------------------------------------------------------------------------------------
// Произвольный запрос
pub fn run_custom_query(&self, db_name: &str, query: &str) -> String {
let db = self.client.database(db_name);
// Парсим строку запроса в BSON
let bson_query: Value = match serde_json::from_str(query) {
Ok(value) => value,
Err(err) => return Self::make_response(false, &format!("Failed to parse query JSON: {}", err)),
};
let bson_query_doc = match bson::to_document(&bson_query) {
Ok(doc) => doc,
Err(err) => return Self::make_response(false, &format!("Failed to convert query to BSON: {}", err)),
};
// Выполнение произвольного запроса
match db.run_command(bson_query_doc, None) {
Ok(result) => Self::make_response(true, &format!("{:?}", result)),
Err(err) => Self::make_response(false, &format!("Query execution failed: {}", err)),
}
}
// Агрегация
pub fn aggregate(&self, db_name: &str, collection_name: &str, pipeline: &str) -> String {
let collection: Collection<Document> = self.client.database(db_name).collection(collection_name);
// Парсим строку JSON в массив стадий агрегации
let bson_pipeline: Vec<Document> = match serde_json::from_str(pipeline) {
Ok(value) => value,
Err(err) => return Self::make_response(false, &format!("Failed to parse pipeline JSON: {}", err)),
};
// Выполняем агрегацию
let cursor = match collection.aggregate(bson_pipeline, None) {
Ok(cursor) => cursor,
Err(err) => return Self::make_response(false, &format!("Aggregation failed: {}", err)),
};
// Собираем результат в вектор
let mut result: Vec<Value> = Vec::new();
for document in cursor {
match document {
Ok(doc) => result.push(serde_json::to_value(doc).unwrap()),
Err(err) => return Self::make_response(false, &format!("Failed to read document: {}", err)),
}
}
// Возвращаем результат как строку
Self::make_response(true, &serde_json::to_string(&result).unwrap())
}
}

View File

@@ -1,226 +0,0 @@
mod methods;
use addin1c::{name, Variant};
use crate::core::getset;
// МЕТОДЫ КОМПОНЕНТЫ -------------------------------------------------------------------------------
// Синонимы
pub const METHODS: &[&[u16]] = &[
name!("ListDatabases"), // 0
name!("DatabaseStats"), // 1
name!("DropDatabase"), // 2
name!("DatabaseExists"), // 3
name!("ListCollections"), // 4
name!("CreateCollection"), // 5
name!("DropCollection"), // 6
name!("CollectionExists"), // 7
name!("InsertData"), // 8
name!("InsertMany"), // 9
name!("UpdateData"), // 10
name!("UpdateMany"), // 11
name!("DeleteData"), // 12
name!("DeleteMany"), // 13
name!("FindData"), // 14
name!("FindMany"), // 15
name!("FindAll"), // 16
name!("DocumentExists"), // 17
name!("CountDocuments"), // 18
name!("RunCustomQuery"), // 19
name!("Aggregate"), // 20
];
// Число параметров функций компоненты
pub fn get_params_amount(num: usize) -> usize {
match num {
0 => 0, // list_databases (нет параметров)
1 => 1, // database_stats
2 => 1, // drop_database
3 => 1, // database_exists
4 => 1, // list_collections
5 => 2, // create_collection
6 => 2, // drop_collection
7 => 2, // collection_exists
8 => 3, // insert_data
9 => 3, // insert_many
10 => 4, // update_data
11 => 4, // update_many
12 => 3, // delete_data
13 => 3, // delete_many
14 => 3, // find_data
15 => 5, // find_many
16 => 5, // find_all
17 => 3, // document_exists
18 => 2, // count_documents
19 => 2, // run_custom_query
20 => 3, // aggregate
_ => 0, // по умолчанию 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 => { // list_databases
Box::new(client.list_databases())
},
1 => { // database_stats
let db_name = params[0].get_string().unwrap_or(String::new());
Box::new(client.database_stats(&db_name))
},
2 => { // drop_database
let db_name = params[0].get_string().unwrap_or(String::new());
Box::new(client.drop_database(&db_name))
},
3 => { // database_exists
let db_name = params[0].get_string().unwrap_or(String::new());
Box::new(client.database_exists(&db_name))
},
4 => { // list_collections
let db_name = params[0].get_string().unwrap_or(String::new());
Box::new(client.list_collections(&db_name))
},
5 => { // create_collection
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.create_collection(&db_name, &collection_name))
},
6 => { // drop_collection
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.drop_collection(&db_name, &collection_name))
},
7 => { // collection_exists
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.collection_exists(&db_name, &collection_name))
},
8 => { // insert_data
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))
},
9 => { // insert_many
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_many(&db_name, &collection_name, &data))
},
10 => { // update_data
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());
let update = params[3].get_string().unwrap_or(String::new());
Box::new(client.update_data(&db_name, &collection_name, &query, &update))
},
11 => { // update_many
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());
let update = params[3].get_string().unwrap_or(String::new());
Box::new(client.update_many(&db_name, &collection_name, &query, &update))
},
12 => { // delete_data
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.delete_data(&db_name, &collection_name, &query))
},
13 => { // delete_many
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.delete_many(&db_name, &collection_name, &query))
},
14 => { // find_data
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))
},
15 => { // find_many
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());
let page = params[3].get_i32().unwrap_or(0);
let page_size = params[4].get_i32().unwrap_or(0) as i32;
Box::new(client.find_many(&db_name, &collection_name, &query, page, page_size))
},
16 => { // find_all
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());
let page = params[3].get_i32().unwrap_or(0);
let page_size = params[4].get_i32().unwrap_or(0);
Box::new(client.find_all(&db_name, &collection_name, &query, page, page_size))
},
17 => { // document_exists
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))
},
18 => { // count_documents
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))
},
19 => { // run_custom_query
let db_name = params[0].get_string().unwrap_or(String::new());
let query = params[1].get_string().unwrap_or(String::new());
Box::new(client.run_custom_query(&db_name, &query))
},
20 => { // aggregate
let db_name = params[0].get_string().unwrap_or(String::new());
let collection_name = params[1].get_string().unwrap_or(String::new());
let pipeline = params[2].get_string().unwrap_or(String::new());
Box::new(client.aggregate(&db_name, &collection_name, &pipeline))
},
_ => {
Box::new(false)
}
}
}
// -------------------------------------------------------------------------------------------------
// ПОЛЯ КОМПОНЕНТЫ ---------------------------------------------------------------------------------
// Синонимы
pub const PROPS: &[&[u16]] = &[
name!("ConnectionString")
];
// Имена и типы
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 _ }
}
// -------------------------------------------------------------------------------------------------

370
src/addins/tcp/Cargo.lock generated Normal file
View File

@@ -0,0 +1,370 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "addin1c"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef34e8b7ff4c43e87491a4cc30a4779a9f67c50db43378a36362c7a56246e05b"
dependencies = [
"smallvec",
"utf16_lit",
]
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "cc"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "errno"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "libc"
version = "0.2.168"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d"
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "log"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "native-tls"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
dependencies = [
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
name = "once_cell"
version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "openssl"
version = "0.10.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5"
dependencies = [
"bitflags",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "openssl-probe"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
version = "0.9.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "opi_tcp"
version = "0.1.0"
dependencies = [
"addin1c",
"native-tls",
]
[[package]]
name = "pkg-config"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "proc-macro2"
version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustix"
version = "0.38.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "schannel"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
dependencies = [
"windows-sys",
]
[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "syn"
version = "2.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tempfile"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
dependencies = [
"cfg-if",
"fastrand",
"once_cell",
"rustix",
"windows-sys",
]
[[package]]
name = "unicode-ident"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "utf16_lit"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14706d2a800ee8ff38c1d3edb873cd616971ea59eb7c0d046bb44ef59b06a1ae"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"

View File

@@ -1,10 +1,8 @@
[package]
name = "opi_mongodb"
name = "opi_tcp"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
@@ -13,17 +11,7 @@ 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.
opt-level = "z"
[dependencies]
addin1c = "0.5.0"
bson = "2.0"
serde_json = "1.0.133"
[dependencies.mongodb]
version = "=2.8.2"
default-features = false
features = ["sync"]
native-tls = "0.2.12"

View File

@@ -0,0 +1,64 @@
use std::io::{Read, Write};
use std::net::TcpStream;
use native_tls::TlsStream;
use std::time::Duration;
pub enum Connection {
Tcp(TcpStream),
Tls(TlsStream<TcpStream>),
}
impl Connection {
pub fn write(&mut self, data: &[u8]) -> std::io::Result<usize> {
match self {
Connection::Tcp(stream) => stream.write(data),
Connection::Tls(stream) => stream.write(data),
}
}
pub fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
match self {
Connection::Tcp(stream) => stream.read(buffer),
Connection::Tls(stream) => stream.read(buffer),
}
}
}
/// Отправляет данные
pub fn send(connection: &mut Connection, data: Vec<u8>) -> bool {
match connection.write(&data) {
Ok(_) => true,
Err(_) => false, // Ошибка при отправке данных
}
}
/// Считывает данные
pub fn receive(connection: &mut Connection, buffer_size: i32, timeout_ms: i32) -> Vec<u8> {
let mut result = Vec::new();
let mut buffer = vec![0u8; buffer_size as usize];
match connection {
Connection::Tcp(stream) => {
stream.set_read_timeout(Some(Duration::from_millis(timeout_ms as u64))).ok();
}
Connection::Tls(stream) => {
stream.get_ref().set_read_timeout(Some(Duration::from_millis(timeout_ms as u64))).ok();
}
}
loop {
match connection.read(&mut buffer) {
Ok(0) => break, // Конец данных (EOF)
Ok(size) => result.extend_from_slice(&buffer[..size]),
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break, // Нет данных
Err(e) => break, // Любая другая ошибка
}
}
result
}
/// Закрывает соединение
pub fn disconnect(add_in: &mut crate::component::AddIn) {
add_in.connection = None;
}

View File

@@ -0,0 +1,132 @@
mod methods;
use addin1c::{name, Variant};
use crate::core::getset;
use methods::Connection;
use std::net::TcpStream;
use native_tls::{TlsConnector};
use crate::component::methods::disconnect;
// МЕТОДЫ КОМПОНЕНТЫ -------------------------------------------------------------------------------
// Синонимы
pub const METHODS: &[&[u16]] = &[
name!("Connect"), // 0
name!("Disconnect"), // 1
name!("Read"), // 2
name!("Write"), // 3
];
// Число параметров функций компоненты
pub fn get_params_amount(num: usize) -> usize {
match num {
0 => 0,
1 => 0,
2 => 2,
3 => 1,
_ => 0,
}
}
// Соответствие функций Rust функциям компоненты
// Вызовы должны быть обернуты в Box::new
pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box<dyn getset::ValueType> {
match num {
0 => Box::new(obj.connect()),
1 => {
disconnect(obj);
Box::new(true) // Возвращаем true для обозначения успешного выполнения
},
2 => {
let size = params[0].get_i32().unwrap_or(0);
let timeout = params[1].get_i32().unwrap_or(0);
if let Some(ref mut connection) = obj.connection {
Box::new(methods::receive(connection, size, timeout))
} else {
Box::new(Vec::<u8>::new()) // Если соединения нет, возвращаем пустой массив
}
},
3 => {
let empty_array: [u8; 0] = [];
let data = params[0].get_blob().unwrap_or(&empty_array);
if let Some(ref mut connection) = obj.connection {
Box::new(methods::send(connection, data.to_vec()))
} else {
Box::new(false) // Если соединения нет, возвращаем false
}
},
_ => Box::new(false), // Неверный номер команды
}
}
// -------------------------------------------------------------------------------------------------
// ПОЛЯ КОМПОНЕНТЫ ---------------------------------------------------------------------------------
// Синонимы
pub const PROPS: &[&[u16]] = &[
name!("Address"),
name!("SSL")
];
pub struct AddIn {
pub address: String,
pub use_ssl: bool,
connection: Option<Connection>,
}
impl AddIn {
/// Создает новый объект
pub fn new() -> Self {
AddIn {
address: String::new(),
use_ssl: false,
connection: None,
}
}
/// Подключается к серверу
pub fn connect(&mut self) -> bool {
if self.address.is_empty() {
return false; // Ошибка: пустой адрес
}
if self.use_ssl {
let connector = match TlsConnector::new() {
Ok(conn) => conn,
Err(_) => return false, // Ошибка при создании TLS-коннектора
};
let stream = match TcpStream::connect(&self.address) {
Ok(s) => s,
Err(_) => return false, // Ошибка при подключении
};
match connector.connect(&self.address, stream) {
Ok(tls_stream) => {
self.connection = Some(Connection::Tls(tls_stream));
true
}
Err(_) => false, // Ошибка при установлении TLS
}
} else {
match TcpStream::connect(&self.address) {
Ok(tcp_stream) => {
self.connection = Some(Connection::Tcp(tcp_stream));
true
}
Err(_) => false, // Ошибка при подключении
}
}
}
pub fn get_field_ptr(&self, index: usize) -> *const dyn getset::ValueType {
match index {
0 => &self.address as &dyn getset::ValueType as *const _,
1 => &self.use_ssl 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 _ }
}
// -------------------------------------------------------------------------------------------------

View File

@@ -31,7 +31,7 @@ pub unsafe extern "C" fn DestroyObject(component: *mut *mut c_void) -> c_long {
#[no_mangle]
pub extern "C" fn GetClassNames() -> *const u16 {
// small strings for performance
name!("Main").as_ptr()
name!("Client").as_ptr()
}
#[allow(non_snake_case)]

View File

@@ -31,7 +31,7 @@ pub unsafe extern "C" fn DestroyObject(component: *mut *mut c_void) -> c_long {
#[no_mangle]
pub extern "C" fn GetClassNames() -> *const u16 {
// small strings for performance
name!("Client").as_ptr()
name!("Main").as_ptr()
}
#[allow(non_snake_case)]

View File

@@ -47,7 +47,7 @@
#Область УправлениеБазамиДанных
// Получить список баз
// Получает список баз
// Получает список баз данных
//
// Примечание:
// Метод в документации MongoDB: [listDatabases](@mongodb.com/docs/manual/reference/command/listDatabases/)
@@ -68,6 +68,110 @@
КонецФункции
// Получить статистику базы
// Получает информацию о базе данных
//
// Примечание:
// Метод в документации MongoDB: [dbStats](@mongodb.com/docs/manual/reference/command/dbStats/)
//
// Параметры:
// СтрокаПодключения - Строка - Строка подключения к серверу MongoDB - connect
// БазаДанных - Строка - Имя базы данных - db
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - сериализованный JSON ответа от сервера MongoDB
Функция ПолучитьСтатистикуБазы(Знач СтрокаПодключения, Знач БазаДанных) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(БазаДанных);
Клиент = КлиентMongoDB(СтрокаПодключения);
Ответ = Клиент.DatabaseStats(БазаДанных);
Ответ = OPI_Инструменты.JsonВСтруктуру(Ответ, Ложь);
Возврат Ответ;
КонецФункции
// База данных существует
// Проверяет существование базы данных по имени
//
// Параметры:
// СтрокаПодключения - Строка - Строка подключения к серверу MongoDB - connect
// БазаДанных - Строка - Имя базы данных - db
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - сериализованный JSON ответа от сервера MongoDB
Функция БазаДанныхСуществует(Знач СтрокаПодключения, Знач БазаДанных) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(БазаДанных);
Клиент = КлиентMongoDB(СтрокаПодключения);
Ответ = Клиент.DatabaseExists(БазаДанных);
Ответ = OPI_Инструменты.JsonВСтруктуру(Ответ, Ложь);
Возврат Ответ;
КонецФункции
// Удалить базу
// Удаляет базу данных
//
// Примечание:
// Метод в документации MongoDB: [db.dropDatabase](@mongodb.com/docs/manual/reference/method/db.dropDatabase/)
//
// Параметры:
// СтрокаПодключения - Строка - Строка подключения к серверу MongoDB - connect
// БазаДанных - Строка - Имя базы данных - db
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - сериализованный JSON ответа от сервера MongoDB
Функция УдалитьБазу(Знач СтрокаПодключения, Знач БазаДанных) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(БазаДанных);
Клиент = КлиентMongoDB(СтрокаПодключения);
Ответ = Клиент.DropDatabase(БазаДанных);
Ответ = OPI_Инструменты.JsonВСтруктуру(Ответ, Ложь);
Возврат Ответ;
КонецФункции
#КонецОбласти
#Область УправлениеКоллекциями
// Создать коллекцию
// Создает пустую коллекцию в выбранной базе
//
// Примечание:
// Если база с именем, указанным в параметре БазаДанных, отсутствует, то она будет создана
// Метод в документации MongoDB: [db.createCollection](@mongodb.com/docs/manual/reference/method/db.createCollection/)
//
// Параметры:
// СтрокаПодключения - Строка - Строка подключения к серверу MongoDB - connect
// БазаДанных - Строка - Имя базы данных - db
// Наименование - Строка - Имя коллекции - cl
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - сериализованный JSON ответа от сервера MongoDB
Функция СоздатьКоллекцию(Знач СтрокаПодключения, Знач БазаДанных, Знач Наименование) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(БазаДанных);
OPI_ПреобразованиеТипов.ПолучитьСтроку(Наименование);
Клиент = КлиентMongoDB(СтрокаПодключения);
Ответ = Клиент.CreateCollection(БазаДанных, Наименование);
Ответ = OPI_Инструменты.JsonВСтруктуру(Ответ, Ложь);
Возврат Ответ;
КонецФункции
#КонецОбласти
#КонецОбласти
@@ -78,7 +182,8 @@
OPI_ПреобразованиеТипов.ПолучитьСтроку(СтрокаПодключения);
Клиент = OPI_Инструменты.ПолучитьКомпоненту("MongoDB");
Клиент = OPI_Инструменты.ПолучитьКомпоненту("MongoDB");
Клиент.ConnectionString = СтрокаПодключения;
Возврат Клиент;

View File

@@ -262,6 +262,7 @@
НовыйТест(ТаблицаТестов, "AWS_РаботаСБакетами" , "Работа с бакетами" , S3_);
НовыйТест(ТаблицаТестов, "AWS_РаботаСОбъектами" , "Работа с объектами" , S3_);
НовыйТест(ТаблицаТестов, "Mongo_УправлениеБазамиДанных" , "Управление базами данных" , Монго);
НовыйТест(ТаблицаТестов, "Mongo_УправлениеКоллекциями" , "Управление коллекциями" , Монго);
Возврат ТаблицаТестов;

View File

@@ -2178,9 +2178,27 @@
ПараметрыТеста = Новый Структура;
OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("MDB_CString", ПараметрыТеста);
СтрокаПодключения = ПараметрыТеста["MDB_CString"];
БазаДанных = "testbase";
Наименование = "testcollection";
MongoDB_ПолучитьСписокБаз(ПараметрыТеста);
OPI_MongoDB.СоздатьКоллекцию(СтрокаПодключения, БазаДанных, Наименование);
MongoDB_ПолучитьСписокБаз(ПараметрыТеста);
MongoDB_ПолучитьСтатистикуБазы(ПараметрыТеста);
MongoDB_БазаДанныхСуществует(ПараметрыТеста);
MongoDB_УдалитьБазу(ПараметрыТеста);
КонецПроцедуры
Процедура Mongo_УправлениеКоллекциями() Экспорт
ПараметрыТеста = Новый Структура;
OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("MDB_CString", ПараметрыТеста);
MongoDB_СоздатьКоллекцию(ПараметрыТеста);
КонецПроцедуры
#КонецОбласти
@@ -15677,6 +15695,59 @@
КонецПроцедуры
Процедура MongoDB_ПолучитьСтатистикуБазы(ПараметрыФункции)
СтрокаПодключения = ПараметрыФункции["MDB_CString"];
БазаДанных = "testbase";
Результат = OPI_MongoDB.ПолучитьСтатистикуБазы(СтрокаПодключения, БазаДанных);
// END
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьСтатистикуБазы", "MongoDB");
КонецПроцедуры
Процедура MongoDB_БазаДанныхСуществует(ПараметрыФункции)
СтрокаПодключения = ПараметрыФункции["MDB_CString"];
БазаДанных = "testbase";
Результат = OPI_MongoDB.БазаДанныхСуществует(СтрокаПодключения, БазаДанных);
// END
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "БазаДанныхСуществует", "MongoDB");
КонецПроцедуры
Процедура MongoDB_УдалитьБазу(ПараметрыФункции)
СтрокаПодключения = ПараметрыФункции["MDB_CString"];
БазаДанных = "testbase";
Результат = OPI_MongoDB.УдалитьБазу(СтрокаПодключения, БазаДанных);
// END
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьБазу", "MongoDB");
КонецПроцедуры
Процедура MongoDB_СоздатьКоллекцию(ПараметрыФункции)
СтрокаПодключения = ПараметрыФункции["MDB_CString"];
БазаДанных = "testbase";
Наименование = "testcollection";
Результат = OPI_MongoDB.СоздатьКоллекцию(СтрокаПодключения, БазаДанных, Наименование);
// END
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "СоздатьКоллекцию", "MongoDB");
КонецПроцедуры
#КонецОбласти
#КонецОбласти