1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2026-06-20 09:19:27 +02:00
Files
OpenIntegrations/src/en/OPI/src/CommonModules/OPI_SQLite/Module.bsl
T
Vitaly the Alpaca (bot) 4dc9a20cc4 Main build (Jenkins)
2025-02-27 13:01:50 +03:00

498 lines
14 KiB
Plaintext
Vendored

// 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
// Uncomment if OneScript is executed
// #Use "../../tools"
#Region Public
#Region CommonMethods
// Create Connection !NOCLI
// Creates a connection to the specified base
//
// Parameters:
// Base - String - Path to database. In memory, if not filled - db
//
// Returns:
// Arbitrary - Connector object or structure with error information
Function CreateConnection(Val Base = "") Export
If IsConnector(Base) Then
Return Base;
EndIf;
OPI_TypeConversion.GetLine(Base);
OPI_Tools.RestoreEscapeSequences(Base);
Connector = AttachAddInOnServer("OPI_SQLite");
Connector.Database = Base;
Result = Connector.Connect();
Result = OPI_Tools.JsonToStructure(Result, False);
Return ?(Result["result"], Connector, Result);
EndFunction
// Close connection !NOCLI
// Explicitly closes the passed connection
//
// Parameters:
// Connection - Arbitrary - AddIn object with open connection - db
//
// Returns:
// Structure Of KeyAndValue - Result of connection termination
Function CloseConnection(Val Connection) Export
If IsConnector(Connection) Then
Result = Connection.Close();
Result = OPI_Tools.JsonToStructure(Result, False);
Else
Result = New Structure("result,error", False, "It's not a connection");
EndIf;
Return Result;
EndFunction
// Is connector !NOCLI
// Checks that the value is an object of a SQLite AddIn
//
// Parameters:
// Value - Arbitrary - Value to check - value
//
// Returns:
// Boolean - Is connector
Function IsConnector(Val Value) Export
Return String(TypeOf(Value)) = "AddIn.OPI_SQLite.Main";
EndFunction
// Execute SQL query
// Executes an arbitrary SQL query
//
// Note
// Available parameter types: String, Number, Date, Boolean, BinaryData.^^
// Binary data can also be passed as a `{'blob':File path}` structure. Binary data (BLOB) values are returned^^
// as `{'blob':Base64 string}`
// Without specifying the `ForcifyResult` flag, result data is returned only for queries beginning with `SELECT` keyword^^
// For other queries, `result:true` or `false` with error text is returned
// When performing multiple requests within a single connection, it is better to connect extensions once using the `ConnectExtension` function
//
// Parameters:
// QueryText - String - Database query text - sql
// Parameters - Array Of Arbitrary - Array of positional parameters of the request - params
// ForceResult - Boolean - Includes an attempt to retrieve the result, even for nonSELECT queries - force
// Connection - String, Arbitrary - Existing connection or path to the base. In memory, if not filled - db
// Extensions - Map Of KeyAndValue - Extensions: Key > filepath or extension data, Value > entry point - exts
//
// Returns:
// Map Of KeyAndValue - Result of query execution
Function ExecuteSQLQuery(Val QueryText
, Val Parameters = ""
, Val ForceResult = False
, Val Connection = ""
, Val Extensions = Undefined) Export
OPI_TypeConversion.GetLine(QueryText, True);
OPI_TypeConversion.GetBoolean(ForceResult);
Parameters_ = ProcessParameters(Parameters);
Connector = CreateConnection(Connection);
If TypeOf(Connector) <> Type("AddIn.OPI_SQLite.Main") Then
Return Connector;
EndIf;
If ValueIsFilled(Extensions) Then
OPI_TypeConversion.GetKeyValueCollection(Extensions, "Incorrect collection of extensions!");
For Each Extension In Extensions Do
ExtensionConnection = ConnectExtension(Extension.Key, Extension.Value, Connector);
If Not ExtensionConnection["result"] Then
Return ExtensionConnection;
EndIf;
EndDo;
EndIf;
Result = Connector.Execute(QueryText, Parameters_, ForceResult);
Result = OPI_Tools.JsonToStructure(Result);
Return Result;
EndFunction
// Connect extension !NOCLI
// Connects the SQLite extension for the specified connection
//
// Note
// The extension is active only for the current connection. You must reconnect it each time a new connection is established
// Similar to using the `Extensions` parameter (`exts` in CLI) of the `ExecuteSQLQuery` function
//
// Parameters:
// Extension - String, BinaryData - Extension data or filepath - ext
// EntryPoint - String - Expansion entry point, if required - point
// Connection - String, Arbitrary - Existing connection or path to the base. In memory, if not filled - db
//
// Returns:
// Map Of KeyAndValue - Result of extension connecting
Function ConnectExtension(Val Extension, Val EntryPoint = "", Val Connection = "") Export
Extension_ = Extension;
OPI_TypeConversion.GetFileOnDisk(Extension_);
OPI_TypeConversion.GetLine(EntryPoint);
Temporary = Extension_["Temporary"];
FilePath = Extension_["Path"];
Connector = CreateConnection(Connection);
If TypeOf(Connector) <> Type("AddIn.OPI_SQLite.Main") Then
Return Connector;
EndIf;
Result = Connector.LoadExtension(FilePath, EntryPoint);
Result = OPI_Tools.JsonToStructure(Result);
If Temporary Then
Try
DeleteFiles(FilePath);
Except
Return Result;
EndTry;
EndIf;
Return Result;
EndFunction
#EndRegion
#Region ORM
// Get table information
// Gets information about the table
//
// Parameters:
// Table - String - Table name - table
// Connection - String, Arbitrary - Existing connection or database path - db
//
// Returns:
// Map Of KeyAndValue - Result of query execution
Function GetTableInformation(Val Table, Val Connection = "") Export
OPI_TypeConversion.GetLine(Table);
TextSQL = "PRAGMA table_info('%1')";
TextSQL = StrTemplate(TextSQL, Table);
Result = ExecuteSQLQuery(TextSQL, , True, Connection);
Return Result;
EndFunction
// Create table
// Creates an empty table in the database
//
// Parameters:
// Table - String - Table name - table
// ColoumnsStruct - Structure Of KeyAndValue - Column structure: Key > Name, Value > Data type - cols
// Connection - String, Arbitrary - Existing connection or database path - db
//
// Returns:
// Map Of KeyAndValue - Result of query execution
Function CreateTable(Val Table, Val ColoumnsStruct, Val Connection = "") Export
Result = OPI_SQLQueries.CreateTable(OPI_SQLite, Table, ColoumnsStruct, Connection);
Return Result;
EndFunction
// Add rows
// Adds new rows to the table
//
// Note
// Binary data can also be transferred as a structure `{'blob':File path}`
//
// Parameters:
// Table - String - Table name - table
// DataArray - Array of Structure - An array of string data structures: Key > field, Value > field value - rows
// Transaction - Boolean - True > adding records to transactions with rollback on error - trn
// Connection - String, Arbitrary - Existing connection or database path - db
//
// Returns:
// Map Of KeyAndValue - Result of query execution
Function AddRecords(Val Table, Val DataArray, Val Transaction = True, Val Connection = "") Export
Result = OPI_SQLQueries.AddRecords(OPI_SQLite, Table, DataArray, Transaction, Connection);
Return Result;
EndFunction
// Get records
// Gets records from the selected table
//
// Note
// Values of the Binary data type (BLOB) are returned as `{'blob':Base64 string}`
//
// Parameters:
// Table - String - Table name - table
// Fields - Array Of String - Fields for selection - fields
// Filters - Array of Structure - Filters array. See GetRecordsFilterStrucutre - filter
// Sort - Structure Of KeyAndValue - Sorting: Key > field name, Value > direction (ASC, DESC) - order
// Count - Number - Limiting the number of received strings - limit
// Connection - String, Arbitrary - Existing connection or database path - db
//
// Returns:
// Map Of KeyAndValue - Result of query execution
Function GetRecords(Val Table
, Val Fields = "*"
, Val Filters = ""
, Val Sort = ""
, Val Count = ""
, Val Connection = "") Export
Result = OPI_SQLQueries.GetRecords(OPI_SQLite, Table, Fields, Filters, Sort, Count, Connection);
Return Result;
EndFunction
// Update records
// Updates the value of records by selected criteria
//
// Parameters:
// Table - String - Table name - table
// ValueStructure - Structure Of KeyAndValue - Values structure: Key > field, Value > field value - values
// Filters - Array of Structure - Filters array. See GetRecordsFilterStrucutre - filter
// Connection - String, Arbitrary - Existing connection or database path - db
//
// Returns:
// Map Of KeyAndValue - Result of query execution
Function UpdateRecords(Val Table, Val ValueStructure, Val Filters = "", Val Connection = "") Export
Result = OPI_SQLQueries.UpdateRecords(OPI_SQLite, Table, ValueStructure, Filters, Connection);
Return Result;
EndFunction
// Delete records
// Deletes records from the table
//
// Parameters:
// Table - String - Table name - table
// Filters - Array of Structure - Filters array. See GetRecordsFilterStrucutre - filter
// Connection - String, Arbitrary - Existing connection or database path - db
//
// Returns:
// Map Of KeyAndValue - Result of query execution
Function DeleteRecords(Val Table, Val Filters = "", Val Connection = "") Export
Result = OPI_SQLQueries.DeleteRecords(OPI_SQLite, Table, Filters, Connection);
Return Result;
EndFunction
// Delete table
// Deletes a table from the database
//
// Parameters:
// Table - String - Table name - table
// Connection - String, Arbitrary - Existing connection or database path - db
//
// Returns:
// Map Of KeyAndValue - Result of query execution
Function DeleteTable(Val Table, Val Connection = "") Export
Result = OPI_SQLQueries.DeleteTable(OPI_SQLite, Table, Connection);
Return Result;
EndFunction
// Clear table
// Clears the database table
//
// Parameters:
// Table - String - Table name - table
// Connection - String, Arbitrary - Existing connection or database path - db
//
// Returns:
// Map Of KeyAndValue - Result of query execution
Function ClearTable(Val Table, Val Connection = "") Export
Result = OPI_SQLQueries.DeleteRecords(OPI_SQLite, Table, , Connection);
Return Result;
EndFunction
// Get records filter strucutre
// Gets the template structure for filtering records in ORM queries
//
// Note
// The use of the `raw` feature is necessary for compound constructions like `BEETWEEN`.^^
// For example: with `raw:false` the filter `type:BETWEEN` `value:10 AND 20` will be interpolated as `BETWEEN ?1 `^^
// where `?1 = "10 AND 20,"' which would cause an error.
// In such a case, you must use `raw:true` to set the condition directly in the query text
//
// Parameters:
// Clear - Boolean - True > structure with empty valuse, False > field descriptions at values - empty
//
// Returns:
// Structure Of KeyAndValue - Record filter element
Function GetRecordsFilterStrucutre(Val Clear = False) Export
Return OPI_SQLQueries.GetRecordsFilterStrucutre(Clear);
EndFunction
#EndRegion
#EndRegion
#Region Internal
Function ConnectorName() Export
Return "OPI_SQLite";
EndFunction
Function GetFeatures() Export
Features = New Map;
Features.Insert("ParameterNumeration", True);
Features.Insert("ParameterMarker" , "?");
Return Features;
EndFunction
#EndRegion
#Region Private
Function AttachAddInOnServer(Val AddInName, Val Class = "Main")
If OPI_Tools.IsOneScript() Then
TemplateName = OPI_Tools.AddInsFolderOS() + AddInName + ".zip";
Else
TemplateName = "CommonTemplate." + AddInName;
EndIf;
AttachAddIn(TemplateName, AddInName, AddInType.Native);
AddIn = New ("AddIn." + AddInName + "." + Class);
Return AddIn;
EndFunction
Function ProcessParameters(Val Parameters)
If Not ValueIsFilled(Parameters) Then
Return "[]";
EndIf;
OPI_TypeConversion.GetArray(Parameters);
For N = 0 To Parameters.UBound() Do
CurrentParameter = Parameters[N];
If TypeOf(CurrentParameter) = Type("BinaryData") Then
CurrentParameter = New Structure("blob", Base64String(CurrentParameter));
ElsIf OPI_Tools.CollectionFieldExists(CurrentParameter, "blob") Then
CurrentParameter = ProcessBlobStructure(CurrentParameter);
ElsIf TypeOf(CurrentParameter) = Type("Date") Then
CurrentParameter = Format(CurrentParameter, "DF='yyyy-MM-dd HH:MM:ss");
Else
If Not OPI_Tools.IsPrimitiveType(CurrentParameter) Then
OPI_TypeConversion.GetLine(CurrentParameter);
EndIf;
EndIf;
Parameters[N] = CurrentParameter;
EndDo;
Parameters_ = OPI_Tools.JSONString(Parameters, , False);
Return Parameters_;
EndFunction
Function ProcessBlobStructure(Val Value)
DataValue = Value["blob"];
DataFile = New File(String(DataValue));
If DataFile.Exists() Then
CurrentData = New BinaryData(String(DataValue));
Value = New Structure("blob", Base64String(CurrentData));
EndIf;
Return Value;
EndFunction
#EndRegion