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

Доработка SQLite

This commit is contained in:
Anton Titovets 2024-12-29 17:51:59 +03:00
parent 21d4e61e67
commit 7b99ec57f9
22 changed files with 7288 additions and 6632 deletions

File diff suppressed because it is too large Load Diff

View File

@ -117,9 +117,7 @@ dependencies = [
"addin1c", "addin1c",
"base64", "base64",
"rusqlite", "rusqlite",
"serde",
"serde_json", "serde_json",
"serde_rusqlite",
] ]
[[package]] [[package]]
@ -198,16 +196,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_rusqlite"
version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b741cc5ef185cd96157e762c3bba743c4e94c8dc6af0edb053c48d2b3c27e691"
dependencies = [
"rusqlite",
"serde",
]
[[package]] [[package]]
name = "shlex" name = "shlex"
version = "1.3.0" version = "1.3.0"

View File

@ -16,6 +16,4 @@ strip = true # Automatically strip symbols from the binary.
addin1c = "0.5.0" addin1c = "0.5.0"
rusqlite = { version = "0.32.1", features = ["bundled"]} rusqlite = { version = "0.32.1", features = ["bundled"]}
serde_json = "1.0" serde_json = "1.0"
serde_rusqlite = "0.36.0" base64 = "0.22.1"
base64 = "0.22.1"
serde = "1.0.217"

View File

@ -1,7 +1,6 @@
use rusqlite::{types::ValueRef}; use rusqlite::{types::ValueRef, types::Value as SqlValue, params_from_iter, ParamsFromIter};
use serde_json::{Value, json, Map}; use serde_json::{Value, json, Map};
use crate::component; use crate::component;
use serde_rusqlite::{to_params};
use base64::{engine::general_purpose, Engine as _}; use base64::{engine::general_purpose, Engine as _};
@ -10,6 +9,7 @@ pub fn execute_query(
client: &mut component::AddIn, client: &mut component::AddIn,
query: String, query: String,
params_json: String, params_json: String,
force_result: bool
) -> String { ) -> String {
let conn = match client.get_connection() { let conn = match client.get_connection() {
@ -35,15 +35,10 @@ pub fn execute_query(
} }
}; };
process_blobs(params_array); let convert = process_blobs(params_array);
let convert = match to_params(params_array){
Ok(params) => params,
Err(e) => {return format!(r#"{{"result": false, "error": "{}"}}"#, e.to_string())}
};
// Определяем тип запроса // Определяем тип запроса
if query.trim_start().to_uppercase().starts_with("SELECT") { if query.trim_start().to_uppercase().starts_with("SELECT") || force_result == true {
// Выполняем SELECT // Выполняем SELECT
match conn.prepare(&query) { match conn.prepare(&query) {
Ok(mut query_result) => { Ok(mut query_result) => {
@ -93,10 +88,17 @@ fn rows_to_json_array(rows: &mut rusqlite::Rows, cols: &Vec<String>) -> String {
for i in 0..cols.len() { for i in 0..cols.len() {
let val = row.get_ref_unwrap(i); let val = match row.get_ref(i) {
let jval = from_sql_to_json(val); Ok(v) => v,
Err(e) => {
current.insert("error".to_string(), Value::String(e.to_string()));
continue;
}
};
current.insert(cols[i].to_string(), jval); let json_val = from_sql_to_json(val);
current.insert(cols[i].to_string(), json_val);
}; };
json_array.push(current); json_array.push(current);
@ -131,38 +133,37 @@ fn from_sql_to_json(value: ValueRef) -> Value {
} }
} }
fn process_blobs(json_array: &mut Vec<Value>) { fn process_blobs(json_array: &mut Vec<Value>) -> ParamsFromIter<Vec<SqlValue>> {
let mut result = Vec::new();
for item in json_array.iter_mut() { for item in json_array.iter_mut() {
match item {
if let Value::Object(obj) = item { Value::Null => { result.push(SqlValue::Null); },
Value::Bool(b) => { result.push(SqlValue::from(*b)); }
// Проверяем, есть ли ключ "blob" Value::String(s) => { result.push(SqlValue::from(s.clone())); }
if let Some(Value::String(blob_str)) = obj.get("blob") { Value::Number(num) => {
match general_purpose::STANDARD.decode(blob_str) { if let Some(int_val) = num.as_i64() {
Ok(decoded_blob) => { result.push(SqlValue::from(int_val));
let current_blob = decoded_blob } else if let Some(float_val) = num.as_f64() {
.into_iter() result.push(SqlValue::from(float_val));
.map(|b| { } else {
if u64::from(b) > i64::MAX as u64 { result.push(SqlValue::from(0));
Value::Number(serde_json::Number::from(i64::MAX))
} else {
Value::Number(serde_json::Number::from(b as i64))
}
})
.collect::<Vec<Value>>();
*item = Value::Array(current_blob);
}
Err(e) => {
// Обработка ошибок декодирования
*item = Value::String(format!("blob_error: {}", e));
}
} }
} }
} else if let Value::Array(array) = item { Value::Object(obj) => {
// Рекурсивно обрабатываем вложенные массивы
process_blobs(array); if let Some(Value::String(blob_str)) = obj.get("blob") {
match general_purpose::STANDARD.decode(blob_str) {
Ok(decoded_blob) => result.push(SqlValue::Blob(decoded_blob)),
Err(_) => result.push(SqlValue::Blob([].to_vec()))
}
} else { result.push(SqlValue::Blob([].to_vec())) }
}
_ => { result.push(SqlValue::Null) }
} }
} }
params_from_iter(result)
} }

View File

@ -9,7 +9,7 @@ use rusqlite::{Connection};
// Синонимы // Синонимы
pub const METHODS: &[&[u16]] = &[ pub const METHODS: &[&[u16]] = &[
name!("Connect"), name!("Connect"),
name!("Execute"), // 0 name!("Execute"),
]; ];
@ -36,8 +36,9 @@ pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box<dyn
let query = params[0].get_string().unwrap_or("".to_string()); let query = params[0].get_string().unwrap_or("".to_string());
let params_json = params[1].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);
Box::new(methods::execute_query(obj, query, params_json)) Box::new(methods::execute_query(obj, query, params_json, force_result))
}, },
_ => Box::new(false), // Неверный номер команды _ => Box::new(false), // Неверный номер команды
} }

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,223 @@
// OneScript: ./OInt/core/Modules/OPI_SQLite.os
// Lib: SQLite
// CLI: sqlite
// MIT License
// Copyright (c) 2023 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
// BSLLS:Typo-off
// BSLLS:LatinAndCyrillicSymbolInWord-off
// BSLLS:IncorrectLineBreak-off
// BSLLS:NumberOfOptionalParams-off
// BSLLS:UsingServiceTag-off
// BSLLS:LineLength-off
//@skip-check module-structure-top-region
//@skip-check module-structure-method-in-regions
//@skip-check wrong-string-literal-content
//@skip-check method-too-many-params
//@skip-check constructor-function-return-section
// Раскомментировать, если выполняется OneScript
#Использовать "../../tools"
#Область ПрограммныйИнтерфейс
#Область ОсновныеМетоды
// Создать подключение !NOCLI
// Создает подключение к указанной базе
//
// Параметры:
// База - Строка - Путь к базе. In memory, если не заполнено - db
//
// Возвращаемое значение:
// Произвольный - объект коннектора или структура с информацией об ошибке
Функция СоздатьПодключение(Знач База = "") Экспорт
Если Строка(ТипЗнч(База)) = "AddIn.OPI_SQLite.Main" Тогда
Возврат База;
КонецЕсли;
OPI_ПреобразованиеТипов.ПолучитьСтроку(База);
Коннектор = ПодключитьКомпонентуНаСервере("OPI_SQLite");
Коннектор.Database = База;
Результат = Коннектор.Connect();
Результат = OPI_Инструменты.JsonВСтруктуру(Результат, Ложь);
Возврат ?(Результат["result"], Коннектор, Результат);
КонецФункции
// Выполнить запрос SQL
// Выполняет произвольный SQL запрос
//
// Примечание:
// Доступные типы параметров: Cтрока, Число, Дата, Булево, ДвоичныеДанные
// Без указания флага `ФорсироватьРезультат`, чтение результата осуществляется только для запросов, начинающихся с `SELECT`^^
// Для остальных запросов возвращается result:true или false с текстом ошибки
//
// Параметры:
// ТекстЗапроса - Строка - Текст запроса к базе - sql
// Параметры - Массив Из Произвольный - Массив позиционных параметров запроса - params
// ФорсироватьРезультат - Булево - Включает попытку получения результата, даже для не SELECT запросов - force
// Соединение - Строка - Существующее соединение или путь к базе. In memory, если не заполнено - db
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - Результат выполнения запроса
Функция ВыполнитьЗапросSQL(Знач ТекстЗапроса, Знач Параметры = "", Знач ФорсироватьРезультат = Ложь,
Знач Соединение = "") Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекстЗапроса);
Параметры_ = ОбработатьПараметры(Параметры);
Коннектор = СоздатьПодключение(Соединение);
Если ТипЗнч(Коннектор) <> Тип("AddIn.OPI_SQLite.Main") Тогда
Возврат Коннектор;
КонецЕсли;
Результат = Коннектор.Execute(ТекстЗапроса, Параметры_, ФорсироватьРезультат);
Результат = OPI_Инструменты.JsonВСтруктуру(Результат, Ложь);
Возврат Результат;
КонецФункции
#КонецОбласти
#Область ORM
// Создать таблицу
// Создает пустую таблицу в базе
//
// Параметры:
// Таблица - Строка - Имя таблицы - table
// СтруктураКолонок - Структура Из КлючИЗначение - Структура колонок: Ключ > имя, Значение > Тип данных - cols
// НеВыполнять - Булево - Истина > Не выполняет запрос, а возвращает текст SQL - noex
// Соединение - Строка - Существующее соединение или путь к базе - db
//
// Возвращаемое значение:
// Структура Из КлючИЗначение, Строка - Результат выполнения запроса или его текст
Функция СоздатьТаблицу(Знач Таблица, Знач СтруктураКолонок, Знач НеВыполнять = Ложь, Знач Соединение = "") Экспорт
OPI_ПреобразованиеТипов.ПолучитьБулево(НеВыполнять);
ТекстОшибки = "Структура колонок не является валидной структурой ключ-значение";
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(СтруктураКолонок, ТекстОшибки);
Схема = OPI_ЗапросыSQL.ПустаяСхемаSQL("CREATE");
OPI_ЗапросыSQL.УстановитьИмяТаблицы(Схема, Таблица);
Для Каждого Колонка Из СтруктураКолонок Цикл
OPI_ЗапросыSQL.ДобавитьКолонку(Схема, Колонка.Ключ, Колонка.Значение);
КонецЦикла;
Запрос = OPI_ЗапросыSQL.СформироватьТекстSQL(Схема);
Если НеВыполнять Тогда
Результат = Запрос;
Иначе
Результат = ВыполнитьЗапросSQL(Запрос, , , Соединение);
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ПодключитьКомпонентуНаСервере(Знач ИмяКомпоненты, Знач Класс = "Main")
Если OPI_Инструменты.ЭтоOneScript() Тогда
ИмяМакета = OPI_Инструменты.КаталогКомпонентOS() + ИмяКомпоненты + ".zip";
Иначе
ИмяМакета = "ОбщийМакет." + ИмяКомпоненты;
КонецЕсли;
ПодключитьВнешнююКомпоненту(ИмяМакета, ИмяКомпоненты, ТипВнешнейКомпоненты.Native);
Компонента = Новый ("AddIn." + ИмяКомпоненты + "." + Класс);
Возврат Компонента;
КонецФункции
Функция ОбработатьПараметры(Знач Параметры)
Если ЗначениеЗаполнено(Параметры) Тогда
OPI_ПреобразованиеТипов.ПолучитьМассив(Параметры);
Для Н = 0 По Параметры.ВГраница() Цикл
ТекущийПараметр = Параметры[Н];
Если ТипЗнч(ТекущийПараметр) = Тип("ДвоичныеДанные") Тогда
ТекущийПараметр = Новый Структура("blob", Base64Строка(ТекущийПараметр));
ИначеЕсли OPI_Инструменты.ПолеКоллекцииСуществует(ТекущийПараметр, "blob") Тогда
ЗначениеДанных = ТекущийПараметр["blob"];
ФайлДанных = Новый Файл(Строка(ЗначениеДанных));
Если ФайлДанных.Существует() Тогда
ТекущиеДанные = Новый ДвоичныеДанные(Строка(ЗначениеДанных));
ТекущийПараметр = Новый Структура("blob", Base64Строка(ТекущиеДанные));
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийПараметр) = Тип("Дата") Тогда
ТекущийПараметр = Формат(ТекущийПараметр, "ДФ='yyyy-MM-dd HH:MM:ss'");
ИначеЕсли Не OPI_Инструменты.ЭтоПримитивныйТип(ТекущийПараметр) Тогда
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекущийПараметр);
КонецЕсли;
Параметры[Н] = ТекущийПараметр;
КонецЦикла;
Параметры_ = OPI_Инструменты.JSONСтрокой(Параметры, , Ложь);
Иначе
Параметры_ = "[]";
КонецЕсли;
Возврат Параметры_;
КонецФункции
#КонецОбласти

View File

@ -202,12 +202,12 @@
КонецФункции КонецФункции
// Обработать данные Telegram Mini App // Обработать данные Telegram Mini App !NOCLI
// Обрабатывает данные Telegram Mini App и опредеяет их достоверность // Обрабатывает данные Telegram Mini App и опредеяет их достоверность
// //
// Параметры: // Параметры:
// СтрокаДанных - Строка - querry из Telegram.WebApp.initData // СтрокаДанных - Строка - query из Telegram.WebApp.initData - datastring
// Токен - Строка - Токен бота // Токен - Строка - Токен бота - token
// //
// Возвращаемое значение: // Возвращаемое значение:
// Соответствие из Строка - Соответствие данных с результатом проверки в поле passed // Соответствие из Строка - Соответствие данных с результатом проверки в поле passed

View File

@ -12,6 +12,7 @@
<module name="OPI_Ozon" file="core/Modules/OPI_Ozon.os"/> <module name="OPI_Ozon" file="core/Modules/OPI_Ozon.os"/>
<module name="OPI_S3" file="core/Modules/OPI_S3.os"/> <module name="OPI_S3" file="core/Modules/OPI_S3.os"/>
<module name="OPI_Slack" file="core/Modules/OPI_Slack.os"/> <module name="OPI_Slack" file="core/Modules/OPI_Slack.os"/>
<module name="OPI_SQLite" file="core/Modules/OPI_SQLite.os"/>
<module name="OPI_TCP" file="core/Modules/OPI_TCP.os"/> <module name="OPI_TCP" file="core/Modules/OPI_TCP.os"/>
<module name="OPI_Telegram" file="core/Modules/OPI_Telegram.os"/> <module name="OPI_Telegram" file="core/Modules/OPI_Telegram.os"/>
<module name="OPI_Twitter" file="core/Modules/OPI_Twitter.os"/> <module name="OPI_Twitter" file="core/Modules/OPI_Twitter.os"/>

View File

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

View File

@ -1146,6 +1146,14 @@
КонецФункции КонецФункции
Функция ЭтоПримитивныйТип(Знач Значение) Экспорт
Возврат ТипЗнч(Значение) = Тип("Строка")
Или ТипЗнч(Значение) = Тип("Число")
Или ТипЗнч(Значение) = Тип("Булево")
КонецФункции
#КонецОбласти #КонецОбласти
#КонецОбласти #КонецОбласти

View File

@ -41,92 +41,183 @@
// Раскомментировать, если выполняется OneScript // Раскомментировать, если выполняется OneScript
// #Использовать "../../tools" // #Использовать "../../tools"
#Область ПрограммныйИнтерфейс #Область ПрограммныйИнтерфейс
#Область ОсновныеМетоды
// Создать подключение !NOCLI
// Создает подключение к указанной базе
//
// Параметры:
// База - Строка - Путь к базе. In memory, если не заполнено - db
//
// Возвращаемое значение:
// Произвольный - Объект коннектора или структура с информацией об ошибке
Функция СоздатьПодключение(Знач База = "") Экспорт Функция СоздатьПодключение(Знач База = "") Экспорт
Если Строка(ТипЗнч(База)) = "AddIn.OPI_SQLite.Main" Тогда Если Строка(ТипЗнч(База)) = "AddIn.OPI_SQLite.Main" Тогда
Возврат База; Возврат База;
КонецЕсли; КонецЕсли;
OPI_ПреобразованиеТипов.ПолучитьСтроку(База); OPI_ПреобразованиеТипов.ПолучитьСтроку(База);
Коннектор = ПодключитьКомпонентуНаСервере("OPI_SQLite"); Коннектор = ПодключитьКомпонентуНаСервере("OPI_SQLite");
Коннектор.Database = База; Коннектор.Database = База;
Результат = Коннектор.Connect(); Результат = Коннектор.Connect();
Результат = OPI_Инструменты.JsonВСтруктуру(Результат, Ложь); Результат = OPI_Инструменты.JsonВСтруктуру(Результат, Ложь);
Возврат ?(Результат["result"], Коннектор, Результат); Возврат ?(Результат["result"], Коннектор, Результат);
КонецФункции КонецФункции
Функция ВыполнитьЗапрос(Знач ТекстЗапроса, Знач Параметры = "", Знач Соединение = "") Экспорт // Выполнить запрос SQL
// Выполняет произвольный SQL запрос
//
// Примечание:
// Доступные типы параметров: Cтрока, Число, Дата, Булево, ДвоичныеДанные
// Без указания флага `ФорсироватьРезультат`, чтение результата осуществляется только для запросов, начинающихся с `SELECT`^^
// Для остальных запросов возвращается result:true или false с текстом ошибки
//
// Параметры:
// ТекстЗапроса - Строка - Текст запроса к базе - sql
// Параметры - Массив Из Произвольный - Массив позиционных параметров запроса - params
// ФорсироватьРезультат - Булево - Включает попытку получения результата, даже для не SELECT запросов - force
// Соединение - Строка - Существующее соединение или путь к базе. In memory, если не заполнено - db
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - Результат выполнения запроса
Функция ВыполнитьЗапросSQL(Знач ТекстЗапроса, Знач Параметры = "", Знач ФорсироватьРезультат = Ложь,
Знач Соединение = "") Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекстЗапроса); OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекстЗапроса);
Параметры_ = ОбработатьПараметры(Параметры); Параметры_ = ОбработатьПараметры(Параметры);
Коннектор = СоздатьПодключение(Соединение); Коннектор = СоздатьПодключение(Соединение);
Если ТипЗнч(Коннектор) <> Тип("AddIn.OPI_SQLite.Main") Тогда Если ТипЗнч(Коннектор) <> Тип("AddIn.OPI_SQLite.Main") Тогда
Возврат Коннектор; Возврат Коннектор;
КонецЕсли; КонецЕсли;
Результат = Коннектор.Execute(ТекстЗапроса, Параметры_); Результат = Коннектор.Execute(ТекстЗапроса, Параметры_, ФорсироватьРезультат);
Результат = OPI_Инструменты.JsonВСтруктуру(Результат, Ложь);
Возврат Результат; Возврат Результат;
КонецФункции КонецФункции
#КонецОбласти #КонецОбласти
#Область ORM
// Создать таблицу
// Создает пустую таблицу в базе
//
// Параметры:
// Таблица - Строка - Имя таблицы - table
// СтруктураКолонок - Структура Из КлючИЗначение - Структура колонок: Ключ > имя, Значение > Тип данных - cols
// НеВыполнять - Булево - Истина > Не выполняет запрос, а возвращает текст SQL - noex
// Соединение - Строка - Существующее соединение или путь к базе - db
//
// Возвращаемое значение:
// Структура Из КлючИЗначение, Строка - Результат выполнения запроса или его текст
Функция СоздатьТаблицу(Знач Таблица, Знач СтруктураКолонок, Знач НеВыполнять = Ложь, Знач Соединение = "") Экспорт
OPI_ПреобразованиеТипов.ПолучитьБулево(НеВыполнять);
ТекстОшибки = "Структура колонок не является валидной структурой ключ-значение";
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(СтруктураКолонок, ТекстОшибки);
Схема = OPI_ЗапросыSQL.ПустаяСхемаSQL("CREATE");
OPI_ЗапросыSQL.УстановитьИмяТаблицы(Схема, Таблица);
Для Каждого Колонка Из СтруктураКолонок Цикл
OPI_ЗапросыSQL.ДобавитьКолонку(Схема, Колонка.Ключ, Колонка.Значение);
КонецЦикла;
Запрос = OPI_ЗапросыSQL.СформироватьТекстSQL(Схема);
Если НеВыполнять Тогда
Результат = Запрос;
Иначе
Результат = ВыполнитьЗапросSQL(Запрос, , , Соединение);
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции #Область СлужебныеПроцедурыИФункции
Функция ПодключитьКомпонентуНаСервере(Знач ИмяКомпоненты, Знач Класс = "Main") Функция ПодключитьКомпонентуНаСервере(Знач ИмяКомпоненты, Знач Класс = "Main")
Если OPI_Инструменты.ЭтоOneScript() Тогда Если OPI_Инструменты.ЭтоOneScript() Тогда
ИмяМакета = OPI_Инструменты.КаталогКомпонентOS() + ИмяКомпоненты + ".zip"; ИмяМакета = OPI_Инструменты.КаталогКомпонентOS() + ИмяКомпоненты + ".zip";
Иначе Иначе
ИмяМакета = "ОбщийМакет." + ИмяКомпоненты; ИмяМакета = "ОбщийМакет." + ИмяКомпоненты;
КонецЕсли; КонецЕсли;
ПодключитьВнешнююКомпоненту(ИмяМакета, ИмяКомпоненты, ТипВнешнейКомпоненты.Native); ПодключитьВнешнююКомпоненту(ИмяМакета, ИмяКомпоненты, ТипВнешнейКомпоненты.Native);
Компонента = Новый("AddIn." + ИмяКомпоненты + "." + Класс); Компонента = Новый ("AddIn." + ИмяКомпоненты + "." + Класс);
Возврат Компонента; Возврат Компонента;
КонецФункции КонецФункции
Функция ОбработатьПараметры(Знач Параметры) Функция ОбработатьПараметры(Знач Параметры)
Если ЗначениеЗаполнено(Параметры) Тогда Если ЗначениеЗаполнено(Параметры) Тогда
OPI_ПреобразованиеТипов.ПолучитьМассив(Параметры); OPI_ПреобразованиеТипов.ПолучитьМассив(Параметры);
Для Н = 0 По Параметры.ВГраница() Цикл Для Н = 0 По Параметры.ВГраница() Цикл
ТекущийПараметр = Параметры[Н]; ТекущийПараметр = Параметры[Н];
Если Не OPI_Инструменты.ЭтоПримитивныйТип(ТекущийПараметр) Тогда Если ТипЗнч(ТекущийПараметр) = Тип("ДвоичныеДанные") Тогда
ТекущийПараметр = Новый Структура("blob", Base64Строка(ТекущийПараметр));
ИначеЕсли OPI_Инструменты.ПолеКоллекцииСуществует(ТекущийПараметр, "blob") Тогда
ЗначениеДанных = ТекущийПараметр["blob"];
ФайлДанных = Новый Файл(Строка(ЗначениеДанных));
Если ФайлДанных.Существует() Тогда
ТекущиеДанные = Новый ДвоичныеДанные(Строка(ЗначениеДанных));
ТекущийПараметр = Новый Структура("blob", Base64Строка(ТекущиеДанные));
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийПараметр) = Тип("Дата") Тогда
ТекущийПараметр = Формат(ТекущийПараметр, "ДФ='yyyy-MM-dd HH:MM:ss'");
ИначеЕсли Не OPI_Инструменты.ЭтоПримитивныйТип(ТекущийПараметр) Тогда
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекущийПараметр); OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекущийПараметр);
КонецЕсли; КонецЕсли;
Параметры[Н] = ТекущийПараметр; Параметры[Н] = ТекущийПараметр;
КонецЦикла; КонецЦикла;
Параметры_ = OPI_Инструменты.JSONСтрокой(Параметры, , Ложь); Параметры_ = OPI_Инструменты.JSONСтрокой(Параметры, , Ложь);
Иначе Иначе
Параметры_ = "[]"; Параметры_ = "[]";
КонецЕсли; КонецЕсли;
Возврат Параметры_; Возврат Параметры_;
КонецФункции КонецФункции
#КонецОбласти #КонецОбласти

View File

@ -202,12 +202,12 @@
КонецФункции КонецФункции
// Обработать данные Telegram Mini App // Обработать данные Telegram Mini App !NOCLI
// Обрабатывает данные Telegram Mini App и опредеяет их достоверность // Обрабатывает данные Telegram Mini App и опредеяет их достоверность
// //
// Параметры: // Параметры:
// СтрокаДанных - Строка - querry из Telegram.WebApp.initData // СтрокаДанных - Строка - query из Telegram.WebApp.initData - datastring
// Токен - Строка - Токен бота // Токен - Строка - Токен бота - token
// //
// Возвращаемое значение: // Возвращаемое значение:
// Соответствие из Строка - Соответствие данных с результатом проверки в поле passed // Соответствие из Строка - Соответствие данных с результатом проверки в поле passed

View File

@ -0,0 +1,266 @@
// MIT License
// Copyright (c) 2023 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
// BSLLS:Typo-off
// BSLLS:LatinAndCyrillicSymbolInWord-off
// BSLLS:IncorrectLineBreak-off
// BSLLS:NumberOfOptionalParams-off
// BSLLS:UsingServiceTag-off
// BSLLS:LineLength-off
//@skip-check module-structure-top-region
//@skip-check module-structure-method-in-regions
//@skip-check wrong-string-literal-content
//@skip-check method-too-many-params
//@skip-check constructor-function-return-section
// Раскомментировать, если выполняется OneScript
// #Использовать "../../tools"
#Область СлужебныйПрограммныйИнтерфейс
Функция ПустаяСхемаSQL(Знач Действие) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(Действие);
Действие = вРег(Действие);
Если Действие = "SELECT" Тогда
Схема = ПустаяСхемаSelect();
ИначеЕсли Действие = "INSERT" Тогда
Схема = ПустаяСхемаInsert();
ИначеЕсли Действие = "UPDATE" Тогда
Схема = ПустаяСхемаUpdate();
ИначеЕсли Действие = "DELETE" Тогда
Схема = ПустаяСхемаDelete();
ИначеЕсли Действие = "CREATE" Тогда
Схема = ПустаяСхемаCreate();
Иначе
Схема = Новый Структура;
КонецЕсли;
Возврат Схема;
КонецФункции
Функция СформироватьТекстSQL(Знач Схема) Экспорт
ТекстОшибки = "Переданное значение не является валидной схемой SQL запроса";
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(Схема, ТекстОшибки);
ТипСхемы = "";
Если Не OPI_Инструменты.ПолеКоллекцииСуществует(Схема, "type", ТипСхемы) Тогда
ВызватьИсключение ТекстОшибки;
КонецЕсли;
ТипСхемы = вРег(ТипСхемы);
Если ТипСхемы = "SELECT" Тогда
ТекстЗапроса = СформироватьТекстSelect(Схема);
ИначеЕсли ТипСхемы = "INSERT" Тогда
ТекстЗапроса = СформироватьТекстInsert(Схема);
ИначеЕсли ТипСхемы = "UPDATE" Тогда
ТекстЗапроса = СформироватьТекстUpdate(Схема);
ИначеЕсли ТипСхемы = "DELETE" Тогда
ТекстЗапроса = СформироватьТекстDelete(Схема);
ИначеЕсли ТипСхемы = "CREATE" Тогда
ТекстЗапроса = СформироватьТекстCreate(Схема);
Иначе
ТекстЗапроса = "";
КонецЕсли;
Возврат ТекстЗапроса;
КонецФункции
Процедура ДобавитьКолонку(Схема, Знач Имя, Знач Тип) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(Имя);
OPI_ПреобразованиеТипов.ПолучитьСтроку(Тип);
Если Не Схема["type"] = "CREATE" Тогда
Возврат;
КонецЕсли;
Схема["columns"].Добавить(Новый Структура(Имя, Тип));
КонецПроцедуры
Процедура УстановитьИмяТаблицы(Схема, Знач Имя) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(Имя);
Схема.Вставить("table", Имя);
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
#Область Схемы
Функция ПустаяСхемаSelect()
Схема = Новый Структура("type", "SELECT");
Схема.Вставить("table" , "");
Схема.Вставить("filter" , Новый Массив);
Схема.Вставить("order_by", Новый Массив);
Схема.Вставить("limit" , Новый Массив);
Схема.Вставить("fileds" , Новый Массив);
Возврат Схема;
КонецФункции
Функция ПустаяСхемаInsert()
Схема = Новый Структура("type", "INSERT");
Схема.Вставить("table", "");
Схема.Вставить("set" , Новый Массив);
Возврат Схема;
КонецФункции
Функция ПустаяСхемаUpdate()
Схема = Новый Структура("type", "UPDATE");
Схема.Вставить("table" , "");
Схема.Вставить("set" , Новый Массив);
Схема.Вставить("filter", Новый Массив);
Возврат Схема;
КонецФункции
Функция ПустаяСхемаDelete()
Схема = Новый Структура("type", "DELETE");
Схема.Вставить("table" , "");
Схема.Вставить("filter", Новый Массив);
Возврат Схема;
КонецФункции
Функция ПустаяСхемаCreate()
Схема = Новый Структура("type", "CREATE");
Схема.Вставить("table" , "");
Схема.Вставить("columns", Новый Массив);
Возврат Схема;
КонецФункции
#КонецОбласти
#Область Процессоры
Функция СформироватьТекстSelect(Знач Схема)
КонецФункции
Функция СформироватьТекстInsert(Знач Схема)
КонецФункции
Функция СформироватьТекстUpdate(Знач Схема)
КонецФункции
Функция СформироватьТекстDelete(Знач Схема)
КонецФункции
Функция СформироватьТекстCreate(Знач Схема)
ПроверитьОбязательныеПоляСхемы(Схема, "table,columns");
Таблица = Схема["table"];
Колонки = Схема["columns"];
ШаблонSQL = "CREATE TABLE %1 (
| %2
| )";
ШаблонКолонки = "%1 %2";
МассивОписанийКолонок = Новый Массив;
Для Каждого Колонка Из Колонки Цикл
МассивОписанийКолонок.Добавить(СтрШаблон(ШаблонКолонки, Колонка.Ключ, Колонка.Значение));
КонецЦикла;
ОписанияКолонок = СтрСоединить(МассивОписанийКолонок, "," + Символы.ПС);
ТекстSQL = СтрШаблон(ШаблонSQL, )
КонецФункции
#КонецОбласти
Процедура ПроверитьОбязательныеПоляСхемы(Схема, Знач Поля)
МассивОбязательныхПолей = СтрСоединить(Поля, ",");
МассивОтсутствующих = OPI_Инструменты.НайтиОтсутствующиеПоляКоллекции(МассивОбязательныхПолей);
Если ЗначениеЗаполнено(МассивОтсутствующих) Тогда
ВызватьИсключение "Отсутствуют необходимые поля схемы: " + СтрСоединить(МассивОтсутствующих, ", ");
КонецЕсли;
КонецПроцедуры
#КонецОбласти

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="715648f2-d9af-4b70-bbba-21d3173cec43">
<name>OPI_ЗапросыSQL</name>
<synonym>
<key>ru</key>
<value>SQL</value>
</synonym>
<server>true</server>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
</mdclass:CommonModule>

View File

@ -1,4 +1,4 @@
// OneScript: ./OInt/tools/Modules/internal/Modules/OPI_Криптография.os // OneScript: ./OInt/tools/Modules/internal/Modules/OPI_Криптография.os
// MIT License // MIT License

View File

@ -1,4 +1,4 @@
// OneScript: ./OInt/tools/Modules/OPI_ПолучениеДанныхТестов.os // OneScript: ./OInt/tools/Modules/OPI_ПолучениеДанныхТестов.os
// MIT License // MIT License

View File

@ -1,4 +1,4 @@
// OneScript: ./OInt/tools/Modules/OPI_ПреобразованиеТипов.os // OneScript: ./OInt/tools/Modules/OPI_ПреобразованиеТипов.os
// MIT License // MIT License

View File

@ -68,6 +68,7 @@
<commonModules>CommonModule.OPI_YandexID</commonModules> <commonModules>CommonModule.OPI_YandexID</commonModules>
<commonModules>CommonModule.OPI_YandexMarket</commonModules> <commonModules>CommonModule.OPI_YandexMarket</commonModules>
<commonModules>CommonModule.OPI_YandexMetrika</commonModules> <commonModules>CommonModule.OPI_YandexMetrika</commonModules>
<commonModules>CommonModule.OPI_ЗапросыSQL</commonModules>
<commonModules>CommonModule.OPI_Тесты</commonModules> <commonModules>CommonModule.OPI_Тесты</commonModules>
<commonModules>CommonModule.OPI_ТестыCLI</commonModules> <commonModules>CommonModule.OPI_ТестыCLI</commonModules>
<commonModules>CommonModule.OPI_ПолучениеДанныхТестов</commonModules> <commonModules>CommonModule.OPI_ПолучениеДанныхТестов</commonModules>