├── .gitignore ├── CISQLite3.uplugin ├── LICENSE ├── README.md ├── Resources └── Icon128.png └── Source └── CISQLite3 ├── CISQLite3.Build.cs ├── Private ├── CISQLite3.cpp ├── CISQLite3PrivatePCH.h ├── SQLiteBlueprintFunctionLibrary.cpp ├── SQLiteDatabase.cpp └── sqlite3.c └── Public ├── CISQLite3.h ├── SQLiteBlueprintFunctionLibrary.h ├── SQLiteBlueprintNodes.h ├── SQLiteDatabase.h ├── SQLiteDatabaseStructs.h ├── sqlite3.h └── sqlite3ext.h /.gitignore: -------------------------------------------------------------------------------- 1 | Intermediate/ 2 | Binaries/ 3 | 4 | *.swp 5 | -------------------------------------------------------------------------------- /CISQLite3.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1, 4 | "VersionName": "1.0", 5 | "FriendlyName": "SQLite3 Plugin", 6 | "Description": "SQLite3 plugin with Blueprint nodes and C++ functions (based on github.com/KhArtNJava/SQLite3UE4)", 7 | "Category": "Database", 8 | "CreatedBy": "conflict.industries", 9 | "CreatedByURL": "http://conflict.industries/", 10 | "DocsURL": "http://conflict.industries/sqlite3/", 11 | "MarketplaceURL": "", 12 | "SupportURL": "http://conflict.industries/support", 13 | "EnabledByDefault": false, 14 | "CanContainContent": false, 15 | "IsBetaVersion": true, 16 | "Installed": false, 17 | "Modules": [ 18 | { 19 | "Name": "CISQLite3", 20 | "Type": "Runtime", 21 | "LoadingPhase": "Default" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | All files starting with "sqlite3" have the following license: 3 | ------------------------------------------------------------- 4 | 5 | The author disclaims copyright to this source code. In place of a legal notice, here is a blessing: 6 | 7 | May you do good and not evil. 8 | 9 | May you find forgiveness for yourself and forgive others. 10 | 11 | May you share freely, never taking more than you give. 12 | 13 | 14 | 15 | CISQLite3 / SQLite3UE4 (all other files) 16 | ---------------------------------------- 17 | 18 | The MIT License (MIT) 19 | 20 | Copyright (c) 2015,2016 Jussi Saarivirta & KhArtNJava (SQLite3UE4) 21 | Copyright (c) 2016 conflict.industries 22 | Copyright (c) 2019 Jonathan Hale (Vhite Rabbit GbR) 23 | Copyright (c) 2019 Rehub GmbH 24 | 25 | Permission is hereby granted, free of charge, to any person obtaining a copy 26 | of this software and associated documentation files (the "Software"), to deal 27 | in the Software without restriction, including without limitation the rights 28 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 29 | copies of the Software, and to permit persons to whom the Software is 30 | furnished to do so, subject to the following conditions: 31 | 32 | The above copyright notice and this permission notice shall be included in all 33 | copies or substantial portions of the Software. 34 | 35 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 37 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 38 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 39 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 40 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 41 | SOFTWARE. 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple SQLite3 Source integration for Unreal Engine 4 2 | 3 | Based on [SQLite3UE4 Plugin by Jussi Saarivirta & KhArtNJava](https://github.com/KhArtNJava/SQLite3UE4/) but with compiling SQLite3 as part of the module code, this opens up compiling it (hopefully) on all platforms without any extra process. 4 | 5 | Please report any problems to the [issues tracker](https://github.com/cindustries/unreal-sqlite3/issues) on this GitHub, or join us at [#unrealengine on irc.freenode.net](https://webchat.freenode.net/?channels=#unrealengine)), you can msg me under **Getty**. 6 | 7 | # Difference to SQLite3UE4 8 | 9 | SQLite3UE4 integrates sqlite3 as a ThirdParty module, which leads to a chain of complexity and also requires people to build the sqlite3 library before using it. On CISQLite3, we integrated the sqlite3 code directly into the module, and so it gets linked like the rest of the module on compile. 10 | 11 | # Works On 12 | 13 | Compiled and basic functionality: 14 | 15 | OS | Tested 16 | ---|------- 17 | Windows x64 | ✓ 18 | Android | ✓ 19 | 20 | UE4 Version | Tested 21 | ---|------- 22 | 4.22.x | ✓ 23 | 4.21.x | ✓ 24 | 4.20.x | ✓ 25 | 4.19.x | ✓ 26 | 27 | # Installation 28 | 29 | Copy this plugin (like Download as ZIP) into the folder **Plugins/CISQLite3** on your project and a start of the project should compile the plugin automatically, if the project is C++. If you don't have a C++ project, then you can just make one for the sole purpose of compiling this plugin. Alternative you can install it as Engine Plugin in the Engine Plugins directory (like **Epic Games/4.22/Engine/Plugins/Runtime/CISQLite3**). 30 | 31 | # Usage 32 | 33 | (More usages to come....) 34 | 35 | ## C++ 36 | 37 | And here's a simple sample in C++: 38 | 39 | Header: 40 | ```c++ 41 | UCLASS() 42 | class SQLITE_API AMyActor : public AActor 43 | { 44 | 45 | GENERATED_BODY() 46 | 47 | public: 48 | 49 | UFUNCTION(BlueprintCallable, Category = "My Actor") 50 | bool GetMyStats(); 51 | 52 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") 53 | FString Name; 54 | 55 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") 56 | int32 Age; 57 | 58 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") 59 | FString Gender; 60 | 61 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") 62 | float Height; 63 | 64 | }; 65 | 66 | ``` 67 | 68 | CPP: 69 | 70 | ```c++ 71 | #include "MyActor.h" 72 | #include "SQLiteDatabase.h" 73 | 74 | bool AMyActor::GetMyStats() 75 | { 76 | 77 | FString dbName = TEXT("TestDatabase"); 78 | FString actorName = TEXT("Bruce Willis"); 79 | 80 | if (!USQLiteDatabase::IsDatabaseRegistered(dbName)) 81 | { 82 | USQLiteDatabase::RegisterDatabase(dbName, "Databases/TestDatabase.db", true); 83 | } 84 | 85 | bool didPopulate = USQLiteDatabase::GetDataIntoObject(dbName, FString::Printf(TEXT("SELECT Name, Age, Gender, Height FROM Actors WHERE Name = \"%s\""), *actorName), this); 86 | 87 | return didPopulate; 88 | 89 | } 90 | ``` 91 | 92 | # License & Copyright 93 | 94 | ## CISQLite3 95 | 96 | The MIT License (MIT) 97 | 98 | Copyright (c) 2015 Jussi Saarivirta & KhArtNJava (SQLite3UE4) 99 | 100 | Copyright (c) 2016 conflict.industries 101 | 102 | Copyright (c) 2019 Jonathan Hale (Vhite Rabbit GbR) 103 | Copyright (c) 2019 Rehub GmbH 104 | 105 | ## SQLite3 106 | 107 | The author disclaims copyright to this source code. In place of a legal notice, here is a blessing: 108 | 109 | May you do good and not evil. 110 | 111 | May you find forgiveness for yourself and forgive others. 112 | 113 | May you share freely, never taking more than you give. 114 | -------------------------------------------------------------------------------- /Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Squareys/unreal-sqlite3/c1af8a172daa1841bef6eaa7e599189a199259a9/Resources/Icon128.png -------------------------------------------------------------------------------- /Source/CISQLite3/CISQLite3.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Jussi Saarivirta 2016 conflict.industries MIT License (MIT) 2 | 3 | using UnrealBuildTool; 4 | using System.IO; 5 | 6 | public class CISQLite3 : ModuleRules 7 | { 8 | public CISQLite3(ReadOnlyTargetRules Target) : base(Target) 9 | { 10 | 11 | PublicIncludePaths.AddRange(new string[] { Path.Combine(ModuleDirectory, "Public") }); 12 | PrivateIncludePaths.AddRange(new string[] { Path.Combine(ModuleDirectory, "Private") }); 13 | 14 | PrivatePCHHeaderFile = "Private/CISQLite3PrivatePCH.h"; 15 | 16 | PublicDependencyModuleNames.AddRange( 17 | new string[] { 18 | "Engine", 19 | "Core", 20 | "CoreUObject" 21 | } 22 | ); 23 | 24 | PrivateDefinitions.Add("SQLITE_ENABLE_DESERIALIZE=1"); 25 | 26 | PrivateDependencyModuleNames.AddRange( 27 | new string[] {} 28 | ); 29 | 30 | DynamicallyLoadedModuleNames.AddRange( 31 | new string[] {} 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Source/CISQLite3/Private/CISQLite3.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 conflict.industries MIT License (MIT) 2 | 3 | #include "CISQLite3PrivatePCH.h" 4 | 5 | DEFINE_LOG_CATEGORY(LogDatabase) 6 | 7 | #define LOCTEXT_NAMESPACE "FCISQLite3" 8 | 9 | void FCISQLite3::StartupModule() {} 10 | void FCISQLite3::ShutdownModule() {} 11 | 12 | #undef LOCTEXT_NAMESPACE 13 | 14 | IMPLEMENT_MODULE(FCISQLite3, CISQLite3) 15 | 16 | -------------------------------------------------------------------------------- /Source/CISQLite3/Private/CISQLite3PrivatePCH.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 conflict.industries MIT License (MIT) 2 | 3 | #pragma once 4 | 5 | #include "CISQLite3.h" 6 | #include "CoreUObject.h" 7 | #include "SQLiteDatabase.h" 8 | #include "SQLiteBlueprintFunctionLibrary.h" 9 | #include "SQLiteBlueprintNodes.h" 10 | 11 | DECLARE_LOG_CATEGORY_EXTERN(LogDatabase, Log, All); -------------------------------------------------------------------------------- /Source/CISQLite3/Private/SQLiteBlueprintFunctionLibrary.cpp: -------------------------------------------------------------------------------- 1 | #include "CISQLite3PrivatePCH.h" 2 | #include "Engine.h" 3 | #include "CString.h" 4 | 5 | #include "SQLiteBlueprintFunctionLibrary.h" 6 | 7 | 8 | 9 | 10 | int32 USQLiteBlueprintFunctionLibrary::CastToInt(FString SQLiteResultValue) 11 | { 12 | return FCString::Atoi(*SQLiteResultValue); 13 | } 14 | 15 | 16 | bool USQLiteBlueprintFunctionLibrary::CastToBoolean(FString SQLiteResultValue) 17 | { 18 | return FCString::Atoi(*SQLiteResultValue) > 0; 19 | } 20 | 21 | //-------------------------------------------------------------------------------------------------------------- 22 | 23 | float USQLiteBlueprintFunctionLibrary::CastToFloat(FString SQLiteResultValue) 24 | { 25 | return FCString::Atof(*SQLiteResultValue); 26 | } 27 | 28 | //-------------------------------------------------------------------------------------------------------------- 29 | 30 | FSQLiteQueryTermExpectedNode USQLiteBlueprintFunctionLibrary::QueryStart(FSQLiteQueryTermExpectedNode LogicOperationOrNone) 31 | { 32 | return FSQLiteQueryTermExpectedNode(LogicOperationOrNone.Query, TEXT("(")); 33 | } 34 | 35 | //-------------------------------------------------------------------------------------------------------------- 36 | 37 | FSQLiteQueryLogicExpectedNode USQLiteBlueprintFunctionLibrary::QueryEnd(const FSQLiteQueryLogicExpectedNode& LastQueryTerm) 38 | { 39 | return FSQLiteQueryLogicExpectedNode(LastQueryTerm.Query, TEXT(")")); 40 | } 41 | 42 | //-------------------------------------------------------------------------------------------------------------- 43 | 44 | FSQLiteQueryLogicExpectedNode USQLiteBlueprintFunctionLibrary::QueryTerm(const FSQLiteQueryTermExpectedNode& LogicOperation, FString Field, FString Operator, FString Value) 45 | { 46 | return FSQLiteQueryLogicExpectedNode(LogicOperation.Query, FString::Printf(TEXT("%s %s \"%s\""), *Field, *Operator, *Value)); 47 | } 48 | 49 | //-------------------------------------------------------------------------------------------------------------- 50 | 51 | FSQLiteQueryTermExpectedNode USQLiteBlueprintFunctionLibrary::QueryLogicAnd(const FSQLiteQueryLogicExpectedNode& LHS) 52 | { 53 | return FSQLiteQueryTermExpectedNode(LHS.Query, TEXT(" AND ")); 54 | } 55 | 56 | //-------------------------------------------------------------------------------------------------------------- 57 | 58 | FSQLiteQueryTermExpectedNode USQLiteBlueprintFunctionLibrary::QueryLogicOr(const FSQLiteQueryLogicExpectedNode& LHS) 59 | { 60 | return FSQLiteQueryTermExpectedNode(LHS.Query, TEXT(" OR ")); 61 | } 62 | //-------------------------------------------------------------------------------------------------------------- 63 | 64 | FSQLiteQueryFinalizedQuery USQLiteBlueprintFunctionLibrary::QueryFinal(const FSQLiteQueryLogicExpectedNode& QueryEndNode) 65 | { 66 | return FSQLiteQueryFinalizedQuery(QueryEndNode.Query); 67 | } 68 | 69 | FSQLiteTableField USQLiteBlueprintFunctionLibrary::SQLiteINTEGER(const FString FieldName, const bool PK, const bool AI, 70 | const bool Unique) 71 | { 72 | 73 | FSQLiteTableField f; 74 | f.FieldType = "INTEGER"; 75 | 76 | f.FieldName = FieldName; 77 | 78 | FString outStr = FieldName + " INTEGER "; 79 | if (PK && AI) { 80 | outStr += " PRIMARY KEY AUTOINCREMENT "; 81 | } 82 | else if (AI) { 83 | outStr += " PRIMARY KEY AUTOINCREMENT "; 84 | } 85 | 86 | if (Unique) { 87 | outStr += " UNIQUE "; 88 | } 89 | 90 | f.ResultStr = outStr; 91 | 92 | return f; 93 | } 94 | 95 | FSQLiteTableField USQLiteBlueprintFunctionLibrary::SQLiteTEXT(const FString FieldName, const bool PK, 96 | const bool Unique) 97 | { 98 | FSQLiteTableField f; 99 | f.FieldType = "TEXT"; 100 | 101 | f.FieldName = FieldName; 102 | 103 | FString outStr = FieldName + " TEXT "; 104 | if (Unique) { 105 | outStr += " UNIQUE "; 106 | } 107 | 108 | f.ResultStr = outStr; 109 | 110 | return f; 111 | } 112 | 113 | FSQLiteTableField USQLiteBlueprintFunctionLibrary::SQLiteREAL(const FString FieldName, const bool PK, 114 | const bool Unique) 115 | { 116 | FSQLiteTableField f; 117 | f.FieldType = "REAL"; 118 | 119 | f.FieldName = FieldName; 120 | 121 | FString outStr = FieldName + " REAL "; 122 | if (Unique) { 123 | outStr += " UNIQUE "; 124 | } 125 | f.ResultStr = outStr; 126 | 127 | return f; 128 | 129 | } 130 | 131 | FSQLiteTableField USQLiteBlueprintFunctionLibrary::SQLiteNUMERIC(const FString FieldName, const bool PK, 132 | const bool Unique) 133 | { 134 | FSQLiteTableField f; 135 | f.FieldType = "NUMERIC"; 136 | 137 | f.FieldName = FieldName; 138 | 139 | FString outStr = FieldName + " NUMERIC "; 140 | if (Unique) { 141 | outStr += " UNIQUE "; 142 | } 143 | 144 | f.ResultStr = outStr; 145 | 146 | return f; 147 | 148 | } 149 | 150 | FSQLitePrimaryKey USQLiteBlueprintFunctionLibrary::SQLitePrimaryKey(const TArray Fields) 151 | { 152 | FSQLitePrimaryKey result; 153 | result.ResultStr = ""; 154 | 155 | FString i = ""; 156 | for (const FSQLiteTableField& field : Fields) { 157 | if (field.FieldName.Len() > 1) { 158 | i += field.FieldName + ", "; 159 | } 160 | } 161 | 162 | FString o = ""; 163 | 164 | if (i.Len() > 1) { 165 | o = " PRIMARY KEY( "; 166 | o += i; 167 | o = o.Left(o.Len() - 2); 168 | o += ")"; 169 | } 170 | 171 | result.ResultStr = o; 172 | return result; 173 | } 174 | 175 | FSQLiteIndex USQLiteBlueprintFunctionLibrary::SQLiteIndexFunction(const TArray Fields, FString idxName, bool Unique) { 176 | 177 | FSQLiteIndex i; 178 | i.IndexName = idxName; 179 | 180 | FString o = "CREATE "; 181 | 182 | if (Unique) { 183 | o += "UNIQUE "; 184 | } 185 | 186 | o += "INDEX " + idxName + " ON $$$TABLE_NAME$$$ ("; 187 | 188 | for (const FSQLiteTableField fld : Fields) { 189 | o += fld.FieldName + ", "; 190 | } 191 | 192 | o = o.Left(o.Len() - 2); 193 | o += ");"; 194 | 195 | i.ResultStr = o; 196 | 197 | return i; 198 | 199 | } 200 | -------------------------------------------------------------------------------- /Source/CISQLite3/Private/SQLiteDatabase.cpp: -------------------------------------------------------------------------------- 1 | #include "CISQLite3PrivatePCH.h" 2 | #include "SQLiteDatabase.h" 3 | 4 | #define LOGSQLITE(verbosity, text) UE_LOG(LogDatabase, verbosity, TEXT("SQLite: %s"), text) 5 | 6 | TMap USQLiteDatabase::Databases; 7 | TMap USQLiteDatabase::SQLite3Databases; 8 | 9 | //-------------------------------------------------------------------------------------------------------------- 10 | 11 | USQLiteDatabase::USQLiteDatabase(const FObjectInitializer& ObjectInitializer) 12 | : Super(ObjectInitializer) 13 | { 14 | } 15 | 16 | //-------------------------------------------------------------------------------------------------------------- 17 | 18 | bool USQLiteDatabase::CreateDatabase(const FString& Filename, bool RelativeToProjectContentDirectory) 19 | { 20 | const FString actualFilename = RelativeToProjectContentDirectory ? FPaths::ProjectContentDir() + Filename : Filename; 21 | 22 | sqlite3* db; 23 | int res = sqlite3_open(TCHAR_TO_ANSI(*actualFilename), &db); 24 | if (res == SQLITE_OK) 25 | { 26 | sqlite3_close(db); 27 | return true; 28 | } 29 | else { 30 | LOGSQLITE(Error, *FString::Printf(TEXT("Could not create database, error code: %d"), res)); 31 | } 32 | 33 | return false; 34 | } 35 | 36 | //-------------------------------------------------------------------------------------------------------------- 37 | 38 | bool USQLiteDatabase::RegisterDatabase(const FString& Name, const FString& Filename, bool RelativeToProjectContentDirectory, bool KeepOpen) 39 | { 40 | const FString actualFilename = RelativeToProjectContentDirectory ? FPaths::ProjectContentDir() + Filename : Filename; 41 | 42 | if (!IsValidDatabase(actualFilename, true)) 43 | { 44 | FString message = "Unable to add database '" + actualFilename + "', it is not valid (problems opening it)!"; 45 | LOGSQLITE(Error, *message); 46 | return false; 47 | } 48 | 49 | if (!IsDatabaseRegistered(Name)) 50 | { 51 | Databases.Add(Name, actualFilename); 52 | FString successMessage = "Registered SQLite database '" + actualFilename + "' successfully."; 53 | LOGSQLITE(Verbose, *successMessage); 54 | } 55 | else { 56 | FString message = "Database '" + actualFilename + "' is already registered, skipping."; 57 | LOGSQLITE(Warning, *message); 58 | } 59 | 60 | if (KeepOpen) { 61 | sqlite3* db; 62 | if (sqlite3_open(TCHAR_TO_ANSI(*actualFilename), &db) == SQLITE_OK) 63 | { 64 | SQLite3Databases.Add(Name, db); 65 | } 66 | } 67 | 68 | return true; 69 | 70 | } 71 | 72 | //-------------------------------------------------------------------------------------------------------------- 73 | 74 | void USQLiteDatabase::UnregisterDatabase(const FString& Name) { 75 | /* Remove in case KeepOpen flag was set to true */ 76 | if (SQLite3Databases.Contains(Name)) { 77 | sqlite3_close(SQLite3Databases[Name]); 78 | SQLite3Databases.Remove(Name); 79 | } 80 | Databases.Remove(Name); 81 | } 82 | 83 | //-------------------------------------------------------------------------------------------------------------- 84 | TArray USQLiteDatabase::Dump(const FString& DatabaseName) { 85 | sqlite3* Db; 86 | const bool keepOpen = SQLite3Databases.Contains(DatabaseName); 87 | if (keepOpen) { 88 | Db = SQLite3Databases[DatabaseName]; 89 | } else { 90 | const FString* databaseName = Databases.Find(DatabaseName); 91 | if (!databaseName) { 92 | LOGSQLITE(Error, TEXT("DB not registered.")); 93 | return {}; 94 | } 95 | 96 | const int err = sqlite3_open(TCHAR_TO_ANSI(**databaseName), &Db); 97 | if (err != SQLITE_OK) { 98 | const char* msg = sqlite3_errmsg(Db); 99 | if(msg) { 100 | UE_LOG(LogDatabase, Error, TEXT("Error ocurred during serialization, code: '%s' (%i), message: '%s'"), sqlite3_errstr(err), err, sqlite3_errmsg(Db)); 101 | } else { 102 | UE_LOG(LogDatabase, Error, TEXT("Error ocurred during serialization, code: %s"), sqlite3_errstr(err)); 103 | } 104 | return {}; 105 | } 106 | } 107 | 108 | int64 size; 109 | uint8* ptr = sqlite3_serialize(Db, "main", &size, 0); 110 | const int err = sqlite3_errcode(Db); 111 | if (err != SQLITE_OK) { 112 | const char* msg = sqlite3_errmsg(Db); 113 | if(msg) { 114 | UE_LOG(LogDatabase, Error, TEXT("Error ocurred during serialization, code: '%s' (%i), message: '%s'"), sqlite3_errstr(err), err, sqlite3_errmsg(Db)); 115 | } else { 116 | UE_LOG(LogDatabase, Error, TEXT("Error ocurred during serialization, code: %s"), sqlite3_errstr(err)); 117 | } 118 | return {}; 119 | } 120 | return TArray(ptr, size); 121 | } 122 | 123 | bool USQLiteDatabase::Restore(const FString& DatabaseName, const TArray& data) { 124 | sqlite3* Db; 125 | const bool keepOpen = SQLite3Databases.Contains(DatabaseName); 126 | if (keepOpen) { 127 | Db = SQLite3Databases[DatabaseName]; 128 | } else { 129 | const FString* databaseName = Databases.Find(DatabaseName); 130 | if (!databaseName) { 131 | LOGSQLITE(Error, TEXT("DB not registered.")); 132 | return false; 133 | } 134 | 135 | sqlite3_open(TCHAR_TO_ANSI(**databaseName), &Db); 136 | } 137 | 138 | const int err = sqlite3_deserialize(Db, "main", 139 | const_cast(data.GetData()), data.Num(), data.Num(), SQLITE_DESERIALIZE_READONLY); 140 | if (err != SQLITE_OK) { 141 | const char* msg = sqlite3_errmsg(Db); 142 | if(msg) { 143 | UE_LOG(LogDatabase, Error, TEXT("Error ocurred during serialization, code: '%s' (%i), message: '%s'"), sqlite3_errstr(err), err, sqlite3_errmsg(Db)); 144 | } else { 145 | UE_LOG(LogDatabase, Error, TEXT("Error ocurred during serialization, code: %s"), sqlite3_errstr(err)); 146 | } 147 | return false; 148 | } 149 | return true; 150 | } 151 | //-------------------------------------------------------------------------------------------------------------- 152 | 153 | bool USQLiteDatabase::GetDataIntoObject(const FString& DatabaseName, const FString& Query, UObject* ObjectToPopulate) 154 | { 155 | ////////////////////////////////////////////////////////////////////////// 156 | // Check input validness. 157 | ////////////////////////////////////////////////////////////////////////// 158 | 159 | if (ObjectToPopulate == NULL) 160 | { 161 | LOGSQLITE(Error, TEXT("ObjectToPopulate needs to be set to get any results!")); 162 | return false; 163 | } 164 | 165 | ////////////////////////////////////////////////////////////////////////// 166 | // Validate the database 167 | ////////////////////////////////////////////////////////////////////////// 168 | 169 | if (!IsDatabaseRegistered(DatabaseName) || 170 | !IsValidDatabase(Databases[DatabaseName], false)) 171 | { 172 | LOGSQLITE(Error, *FString::Printf(TEXT("Unable to get data into object, invalid database '%s'"), *DatabaseName)); 173 | return false; 174 | } 175 | 176 | if (!CanOpenDatabase(Databases[DatabaseName])) 177 | { 178 | LOGSQLITE(Error, *FString::Printf(TEXT("Unable to open database '%s'"), *DatabaseName)); 179 | return false; 180 | } 181 | 182 | ////////////////////////////////////////////////////////////////////////// 183 | // Get the results 184 | ////////////////////////////////////////////////////////////////////////// 185 | 186 | TUniquePtr queryResult = RunQueryAndGetResults(DatabaseName, Query); 187 | 188 | if (queryResult->Success && queryResult->Results.Num() > 0) 189 | { 190 | AssignResultsToObjectProperties(queryResult->Results[0], ObjectToPopulate); 191 | return true; 192 | } 193 | else if (!queryResult->Success) 194 | { 195 | LOGSQLITE(Error, *FString::Printf(TEXT("Query resulted in an error: '%s'"), *queryResult->ErrorMessage)); 196 | return false; 197 | } 198 | else if (queryResult->Results.Num() == 0) 199 | { 200 | LOGSQLITE(Error, TEXT("Query returned zero rows, no data to assign to object properties.")); 201 | return false; 202 | } 203 | 204 | return false; 205 | } 206 | 207 | //-------------------------------------------------------------------------------------------------------------- 208 | 209 | bool USQLiteDatabase::GetDataIntoObjectBP(const FSQLiteDatabaseReference& DataSource, TArray Fields, 210 | FSQLiteQueryFinalizedQuery Query, UObject* ObjectToPopulate) 211 | { 212 | ////////////////////////////////////////////////////////////////////////// 213 | // Check input validness. 214 | ////////////////////////////////////////////////////////////////////////// 215 | 216 | if (ObjectToPopulate == NULL) 217 | { 218 | LOGSQLITE(Error, TEXT("ObjectToPopulate needs to be set to get any results!")); 219 | return false; 220 | } 221 | 222 | if (DataSource.Tables.Num() == 0) 223 | { 224 | LOGSQLITE(Error, TEXT("The query needs the table name!")); 225 | return false; 226 | } 227 | 228 | if (Fields.Num() == 0) 229 | { 230 | LOGSQLITE(Error, TEXT("The query needs fields! You may use * to get all fields.")); 231 | return false; 232 | } 233 | 234 | ////////////////////////////////////////////////////////////////////////// 235 | // Validate the database 236 | ////////////////////////////////////////////////////////////////////////// 237 | 238 | if (!IsDatabaseRegistered(DataSource.DatabaseName) || 239 | !IsValidDatabase(Databases[DataSource.DatabaseName], true)) 240 | { 241 | LOGSQLITE(Error, TEXT("Unable to get data to object, database validation failed!")); 242 | return false; 243 | } 244 | 245 | 246 | ////////////////////////////////////////////////////////////////////////// 247 | // Get the results 248 | ////////////////////////////////////////////////////////////////////////// 249 | 250 | FString constructedQuery = ConstructQuery(DataSource.Tables, Fields, Query, 1, 0); 251 | 252 | TUniquePtr queryResult = RunQueryAndGetResults(DataSource.DatabaseName, constructedQuery); 253 | 254 | if (queryResult->Success && queryResult->Results.Num() > 0) 255 | { 256 | AssignResultsToObjectProperties(queryResult->Results[0], ObjectToPopulate); 257 | return true; 258 | } 259 | else if (!queryResult->Success) 260 | { 261 | LOGSQLITE(Error, *FString::Printf(TEXT("Query resulted in an error: '%s'"), *queryResult->ErrorMessage)); 262 | return false; 263 | } 264 | else if (queryResult->Results.Num() == 0) 265 | { 266 | LOGSQLITE(Error, TEXT("Query returned zero rows, no data to assign to object properties.")); 267 | return false; 268 | } 269 | 270 | return false; 271 | 272 | } 273 | 274 | //-------------------------------------------------------------------------------------------------------------- 275 | 276 | TMap USQLiteDatabase::CollectProperties(UObject* SourceObject) 277 | { 278 | 279 | UClass* SourceObjectClass = SourceObject->GetClass(); 280 | TMap Props; 281 | for (TFieldIterator PropIt(SourceObjectClass, EFieldIteratorFlags::SuperClassFlags::IncludeSuper); 282 | PropIt; ++PropIt) 283 | { 284 | Props.Add(*PropIt->GetNameCPP(), *PropIt); 285 | } 286 | 287 | return Props; 288 | } 289 | 290 | //-------------------------------------------------------------------------------------------------------------- 291 | 292 | bool USQLiteDatabase::IsDatabaseRegistered(const FString& DatabaseName) 293 | { 294 | return Databases.Contains(DatabaseName); 295 | } 296 | 297 | //-------------------------------------------------------------------------------------------------------------- 298 | 299 | bool USQLiteDatabase::CanOpenDatabase(const FString& DatabaseFilename) 300 | { 301 | sqlite3* db; 302 | if (sqlite3_open(TCHAR_TO_ANSI(*DatabaseFilename), &db) == SQLITE_OK) 303 | { 304 | sqlite3_close(db); 305 | return true; 306 | } 307 | return false; 308 | } 309 | 310 | //-------------------------------------------------------------------------------------------------------------- 311 | 312 | bool USQLiteDatabase::IsValidDatabase(const FString& DatabaseFilename, bool TestByOpening) 313 | { 314 | if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*DatabaseFilename)) 315 | { 316 | if (TestByOpening) 317 | { 318 | return CanOpenDatabase(DatabaseFilename); 319 | } 320 | else 321 | { 322 | return true; 323 | } 324 | } 325 | 326 | return false; 327 | } 328 | 329 | //-------------------------------------------------------------------------------------------------------------- 330 | 331 | FSQLiteQueryResult USQLiteDatabase::GetData(const FString& DatabaseName, const FString& Query) 332 | { 333 | FSQLiteQueryResult result; 334 | 335 | ////////////////////////////////////////////////////////////////////////// 336 | // Validate the database 337 | ////////////////////////////////////////////////////////////////////////// 338 | 339 | if (!IsDatabaseRegistered(DatabaseName) || 340 | !IsValidDatabase(Databases[DatabaseName], true)) 341 | { 342 | LOGSQLITE(Error, TEXT("Unable to get data to object, database validation failed!")); 343 | result.Success = false; 344 | result.ErrorMessage = TEXT("Database validation failed"); 345 | return result; 346 | } 347 | 348 | ////////////////////////////////////////////////////////////////////////// 349 | // Get the results 350 | ////////////////////////////////////////////////////////////////////////// 351 | 352 | TUniquePtr queryResult = RunQueryAndGetResults(DatabaseName, Query); 353 | result.Success = queryResult->Success; 354 | result.ErrorMessage = queryResult->ErrorMessage; 355 | 356 | for (auto row : queryResult->Results) 357 | { 358 | FSQLiteQueryResultRow outRow; 359 | for (auto field : row.Fields) 360 | { 361 | FSQLiteKeyValuePair outField; 362 | outField.Key = field.Name; 363 | outField.Value = field.ToString(); 364 | 365 | outRow.Fields.Add(outField); 366 | } 367 | result.ResultRows.Add(outRow); 368 | } 369 | 370 | return result; 371 | 372 | } 373 | 374 | //-------------------------------------------------------------------------------------------------------------- 375 | 376 | FSQLiteQueryResult USQLiteDatabase::GetDataBP(const FSQLiteDatabaseReference& DataSource, 377 | TArray Fields, FSQLiteQueryFinalizedQuery Query, int32 MaxResults, int32 ResultOffset) 378 | { 379 | 380 | FSQLiteQueryResult result; 381 | 382 | ////////////////////////////////////////////////////////////////////////// 383 | // Check input validness. 384 | ////////////////////////////////////////////////////////////////////////// 385 | 386 | if (DataSource.Tables.Num() == 0) 387 | { 388 | LOGSQLITE(Error, TEXT("The query needs at least one table name!")); 389 | result.Success = false; 390 | result.ErrorMessage = TEXT("No table given"); 391 | return result; 392 | } 393 | 394 | if (Fields.Num() == 0) 395 | { 396 | LOGSQLITE(Error, TEXT("The query needs fields! You can use * to get all fields.")); 397 | result.Success = false; 398 | result.ErrorMessage = TEXT("No fields given"); 399 | return result; 400 | } 401 | 402 | FString constructedQuery = ConstructQuery(DataSource.Tables, Fields, Query, MaxResults, ResultOffset); 403 | 404 | return GetData(DataSource.DatabaseName, constructedQuery); 405 | 406 | } 407 | 408 | //-------------------------------------------------------------------------------------------------------------- 409 | 410 | FString USQLiteDatabase::ConstructQuery(TArray Tables, TArray Fields, 411 | FSQLiteQueryFinalizedQuery QueryObject, int32 MaxResults, int32 ResultOffset) 412 | { 413 | FString fieldString; 414 | for (int32 i = 0; i < Fields.Num(); i++) 415 | { 416 | fieldString.Append(Fields[i] + (i < Fields.Num() - 1 ? "," : "")); 417 | } 418 | 419 | FString tableList = FString::Join(Tables, TEXT(",")); 420 | TArray allQueryParams; 421 | 422 | allQueryParams.Add(FString::Printf(TEXT("SELECT %s FROM %s"), *fieldString, *tableList)); 423 | 424 | if (QueryObject.Query.Len() > 0) 425 | { 426 | allQueryParams.Add(FString::Printf(TEXT("WHERE %s"), *QueryObject.Query)); 427 | } 428 | 429 | if (MaxResults >= 0) 430 | { 431 | allQueryParams.Add(FString::Printf(TEXT("LIMIT %i"), MaxResults)); 432 | } 433 | 434 | if (ResultOffset > 0) 435 | { 436 | allQueryParams.Add(FString::Printf(TEXT("OFFSET %i"), ResultOffset)); 437 | } 438 | 439 | FString finalQuery = FString::Join(allQueryParams, TEXT(" ")); 440 | return finalQuery; 441 | 442 | } 443 | 444 | //-------------------------------------------------------------------------------------------------------------- 445 | 446 | bool USQLiteDatabase::PrepareStatement(const FString& DatabaseName, const FString& Query, sqlite3** Db, int32** SqlReturnCode, 447 | sqlite3_stmt** PreparedStatement) { 448 | 449 | const FString* databaseName = Databases.Find(DatabaseName); 450 | if (!databaseName) { 451 | LOGSQLITE(Error, TEXT("DB not registered.")); 452 | return false; 453 | } 454 | 455 | const bool keepOpen = SQLite3Databases.Contains(DatabaseName); 456 | if (keepOpen) { 457 | *Db = SQLite3Databases[DatabaseName]; 458 | } else { 459 | sqlite3_open(TCHAR_TO_ANSI(**databaseName), Db); 460 | } 461 | 462 | **SqlReturnCode = sqlite3_prepare_v2(*Db, TCHAR_TO_UTF8(*Query), -1, PreparedStatement, NULL); 463 | return keepOpen; 464 | } 465 | 466 | //-------------------------------------------------------------------------------------------------------------- 467 | 468 | FSQLiteTable USQLiteDatabase::CreateTable(const FString& DatabaseName, const FString& TableName, 469 | const TArray Fields, const FSQLitePrimaryKey PK) 470 | { 471 | FSQLiteTable t; 472 | t.DatabaseName = DatabaseName; 473 | t.TableName = TableName; 474 | t.Fields = Fields; 475 | t.PK = PK; 476 | 477 | FString query = ""; 478 | query += "CREATE TABLE IF NOT EXISTS "; 479 | query += TableName; 480 | query += "("; 481 | 482 | bool singlePrimaryKeyExists = false; 483 | 484 | for (const FSQLiteTableField& field : Fields) 485 | { 486 | if (field.ResultStr.Len() > 2) { 487 | 488 | if (field.ResultStr.Contains("PRIMARY KEY")) { 489 | singlePrimaryKeyExists = true; 490 | } 491 | 492 | query += field.ResultStr + ", "; 493 | 494 | } 495 | 496 | } 497 | 498 | if (singlePrimaryKeyExists) { 499 | query = query.Left(query.Len() - 2); 500 | 501 | query += ");"; 502 | } 503 | else { 504 | if (PK.ResultStr.Len() > 2) { 505 | query += " " + PK.ResultStr + " "; 506 | } 507 | else { 508 | query = query.Left(query.Len() - 2); 509 | } 510 | 511 | query += ");"; 512 | } 513 | 514 | //LOGSQLITE(Warning, *query); 515 | 516 | t.Created = ExecSql(DatabaseName, query); 517 | 518 | return t; 519 | 520 | } 521 | 522 | //-------------------------------------------------------------------------------------------------------------- 523 | 524 | bool USQLiteDatabase::DropTable(const FString& DatabaseName, const FString& TableName) 525 | { 526 | return ExecSql(DatabaseName, "DROP TABLE " + TableName); 527 | } 528 | 529 | //-------------------------------------------------------------------------------------------------------------- 530 | 531 | bool USQLiteDatabase::TruncateTable(const FString& DatabaseName, const FString& TableName) 532 | { 533 | return ExecSql(DatabaseName, "DELETE FROM " + TableName + ";"); 534 | } 535 | 536 | //-------------------------------------------------------------------------------------------------------------- 537 | 538 | bool USQLiteDatabase::Vacuum(const FString& DatabaseName) 539 | { 540 | return ExecSql(DatabaseName, "VACUUM; "); 541 | } 542 | 543 | //-------------------------------------------------------------------------------------------------------------- 544 | 545 | bool USQLiteDatabase::ExecSql(const FString& DatabaseName, const FString& Query) { 546 | LOGSQLITE(Verbose, *Query); 547 | 548 | sqlite3 *db = nullptr; 549 | const FString* databaseName = Databases.Find(DatabaseName); 550 | if (!databaseName) { 551 | LOGSQLITE(Error, TEXT("DB not registered.")); 552 | return false; 553 | } 554 | 555 | const bool keepOpen = SQLite3Databases.Contains(DatabaseName); 556 | if (keepOpen) { 557 | db = SQLite3Databases[DatabaseName]; 558 | } 559 | else { 560 | if (sqlite3_open(TCHAR_TO_ANSI(**databaseName), &db) != SQLITE_OK) { 561 | LOGSQLITE(Error, TEXT("DB open failed.")); 562 | return false; 563 | } 564 | } 565 | 566 | bool success = false; 567 | char *zErrMsg = nullptr; 568 | if (sqlite3_exec(db, TCHAR_TO_UTF8(*Query), NULL, 0, &zErrMsg) == SQLITE_OK) { 569 | success = true; 570 | } else { 571 | UE_LOG(LogDatabase, Error, TEXT("SQLite: Query Exec Failed: %s"), UTF8_TO_TCHAR(zErrMsg)); 572 | sqlite3_free(zErrMsg); 573 | } 574 | 575 | if (!keepOpen) sqlite3_close(db); 576 | 577 | return success; 578 | } 579 | 580 | //-------------------------------------------------------------------------------------------------------------- 581 | 582 | bool USQLiteDatabase::CreateIndexes(const FString& DatabaseName, const FString& TableName, const TArray Indexes) 583 | { 584 | bool idxCrSts = true; 585 | 586 | for (const FSQLiteIndex& idx : Indexes) 587 | { 588 | if (idx.ResultStr.Len() > 2) { 589 | FString query = idx.ResultStr.Replace(TEXT("$$$TABLE_NAME$$$"), *TableName); 590 | 591 | //LOGSQLITE(Warning, *query); 592 | 593 | idxCrSts = ExecSql(DatabaseName, query); 594 | if (!idxCrSts) { 595 | //LOGSQLITE(Warning, TEXT("ExecSql break")); 596 | break; 597 | } 598 | } 599 | 600 | } 601 | 602 | return idxCrSts; 603 | 604 | } 605 | 606 | //-------------------------------------------------------------------------------------------------------------- 607 | 608 | bool USQLiteDatabase::CreateIndex(const FString& DatabaseName, const FString& TableName, const FSQLiteIndex Index) 609 | { 610 | return ExecSql(DatabaseName, Index.ResultStr.Replace(TEXT("$$$TABLE_NAME$$$"), *TableName)); 611 | } 612 | 613 | //-------------------------------------------------------------------------------------------------------------- 614 | 615 | bool USQLiteDatabase::DropIndex(const FString& DatabaseName, const FString& IndexName) 616 | { 617 | return ExecSql(DatabaseName, "DROP INDEX " + IndexName); 618 | } 619 | 620 | //-------------------------------------------------------------------------------------------------------------- 621 | 622 | bool USQLiteDatabase::IsTableExists(const FString& DatabaseName, const FString& TableName) 623 | { 624 | 625 | sqlite3* db; 626 | int32 sqlReturnCode = 0; 627 | int32* sqlReturnCode1 = &sqlReturnCode; 628 | sqlite3_stmt* preparedStatement; 629 | 630 | FString Query = "SELECT * FROM sqlite_master WHERE type='table' AND name='" + TableName + "';"; 631 | 632 | const bool keepOpen = PrepareStatement(DatabaseName, Query, &db, &sqlReturnCode1, &preparedStatement); 633 | sqlReturnCode = *sqlReturnCode1; 634 | 635 | if (sqlReturnCode != SQLITE_OK) 636 | { 637 | const char* errorMessage = sqlite3_errmsg(db); 638 | FString error = "SQL error: " + FString(UTF8_TO_TCHAR(errorMessage)); 639 | LOGSQLITE(Error, *error); 640 | LOGSQLITE(Error, *FString::Printf(TEXT("The attempted query was: %s"), *Query)); 641 | sqlite3_finalize(preparedStatement); 642 | if (!keepOpen) sqlite3_close(db); 643 | } 644 | 645 | bool tableExists = false; 646 | 647 | for (sqlReturnCode = sqlite3_step(preparedStatement); 648 | sqlReturnCode != SQLITE_DONE && sqlReturnCode == SQLITE_ROW; 649 | sqlReturnCode = sqlite3_step(preparedStatement)) 650 | { 651 | tableExists = true; 652 | break; 653 | } 654 | 655 | ////////////////////////////////////////////////////////////////////////// 656 | // Release the statement and close the connection 657 | ////////////////////////////////////////////////////////////////////////// 658 | 659 | sqlite3_finalize(preparedStatement); 660 | if (!keepOpen) sqlite3_close(db); 661 | 662 | return tableExists; 663 | 664 | } 665 | 666 | void USQLiteDatabase::InsertRowsIntoTable(const FString& DatabaseName, const FString& TableName, TArray rowsOfFields){ 667 | for (FSQLiteTableRowSimulator row : rowsOfFields) { 668 | FString query = "INSERT INTO " + TableName + " ("; 669 | for (FSQLiteTableField field : row.rowsOfFields) { 670 | query += field.FieldName + ", "; 671 | } 672 | 673 | query = query.Left(query.Len() - 2); 674 | 675 | query = query + ") VALUES ("; 676 | for (FSQLiteTableField field : row.rowsOfFields) { 677 | if (field.FieldType.Equals(TEXT("TEXT"))) { 678 | query = query + "'" + field.FieldValue + "', "; 679 | } 680 | else { 681 | query = query + field.FieldValue + ", "; 682 | } 683 | } 684 | 685 | query = query.Left(query.Len() - 2); 686 | query = query + ");"; 687 | 688 | //LOGSQLITE(Warning, *query); 689 | 690 | ExecSql(DatabaseName, query); 691 | 692 | } 693 | } 694 | 695 | //-------------------------------------------------------------------------------------------------------------- 696 | 697 | TUniquePtr USQLiteDatabase::RunQueryAndGetResults(const FString& DatabaseName, const FString& Query) 698 | { 699 | LOGSQLITE(Verbose, *Query); 700 | const FString* databaseName = Databases.Find(DatabaseName); 701 | if (!databaseName) { 702 | LOGSQLITE(Error, TEXT("DB not registered.")); 703 | return nullptr; 704 | } 705 | 706 | SQLiteQueryResult result; 707 | 708 | sqlite3* db; 709 | int32 sqlReturnCode = 0; 710 | int32* sqlReturnCode1 = &sqlReturnCode; 711 | sqlite3_stmt* preparedStatement; 712 | 713 | const bool keepOpen = PrepareStatement(DatabaseName, Query, &db, &sqlReturnCode1, &preparedStatement); 714 | sqlReturnCode = *sqlReturnCode1; 715 | 716 | if (sqlReturnCode != SQLITE_OK) 717 | { 718 | const char* errorMessage = sqlite3_errmsg(db); 719 | FString error = "SQL error: " + FString(UTF8_TO_TCHAR(errorMessage)); 720 | LOGSQLITE(Error, *error); 721 | LOGSQLITE(Error, *FString::Printf(TEXT("The attempted query was: %s"), *Query)); 722 | result.ErrorMessage = error; 723 | result.Success = false; 724 | sqlite3_finalize(preparedStatement); 725 | if (!keepOpen) sqlite3_close(db); 726 | return MakeUnique(MoveTemp(result)); 727 | } 728 | 729 | ////////////////////////////////////////////////////////////////////////// 730 | // Get and assign the data 731 | ////////////////////////////////////////////////////////////////////////// 732 | 733 | TArray resultRows; 734 | 735 | for (sqlReturnCode = sqlite3_step(preparedStatement); 736 | sqlReturnCode != SQLITE_DONE && sqlReturnCode == SQLITE_ROW; 737 | sqlReturnCode = sqlite3_step(preparedStatement)) 738 | { 739 | SQLiteResultValue row; 740 | 741 | LOGSQLITE(Verbose, TEXT("Query returned a result row.")); 742 | int32 resultColumnCount = sqlite3_column_count(preparedStatement); 743 | for (int32 c = 0; c < resultColumnCount; c++) 744 | { 745 | int32 columnType = sqlite3_column_type(preparedStatement, c); 746 | const char* columnName = sqlite3_column_name(preparedStatement, c); 747 | FString columnNameStr = UTF8_TO_TCHAR(columnName); 748 | SQLiteResultField val; 749 | val.Name = columnNameStr; 750 | switch (columnType) 751 | { 752 | case SQLITE_INTEGER: 753 | val.Type = SQLiteResultValueTypes::Integer; 754 | val.IntValue = sqlite3_column_int64(preparedStatement, c); 755 | break; 756 | case SQLITE_TEXT: 757 | val.Type = SQLiteResultValueTypes::Text; 758 | val.StringValue = UTF8_TO_TCHAR(sqlite3_column_text(preparedStatement, c)); 759 | break; 760 | case SQLITE_FLOAT: 761 | val.Type = SQLiteResultValueTypes::Float; 762 | val.DoubleValue = sqlite3_column_double(preparedStatement, c); 763 | break; 764 | case SQLITE_NULL: 765 | default: 766 | val.Type = SQLiteResultValueTypes::UnsupportedValueType; 767 | } 768 | 769 | if (val.Type != SQLiteResultValueTypes::UnsupportedValueType) 770 | { 771 | row.Fields.Add(val); 772 | } 773 | } 774 | 775 | resultRows.Add(row); 776 | } 777 | 778 | ////////////////////////////////////////////////////////////////////////// 779 | // Release the statement and close the connection 780 | ////////////////////////////////////////////////////////////////////////// 781 | 782 | sqlite3_finalize(preparedStatement); 783 | if (!keepOpen) sqlite3_close(db); 784 | 785 | result.Results = resultRows; 786 | result.Success = true; 787 | return MakeUnique(MoveTemp(result)); 788 | 789 | } 790 | 791 | //-------------------------------------------------------------------------------------------------------------- 792 | 793 | void USQLiteDatabase::AssignResultsToObjectProperties(const SQLiteResultValue& ResultValue, UObject* ObjectToPopulate) 794 | { 795 | auto propertyMap = CollectProperties(ObjectToPopulate); 796 | for (SQLiteResultField field : ResultValue.Fields) 797 | { 798 | if (propertyMap.Contains(field.Name)) 799 | { 800 | UProperty* targetProperty = propertyMap[field.Name]; 801 | 802 | if (field.Type == SQLiteResultValueTypes::Integer) 803 | { 804 | UInt64Property* int64prop = NULL; 805 | UIntProperty* int32prop = NULL; 806 | UInt16Property* int16prop = NULL; 807 | UInt8Property* int8prop = NULL; 808 | UBoolProperty* boolProp = NULL; 809 | 810 | if ((int64prop = Cast(targetProperty)) != NULL) 811 | { 812 | int64prop->SetPropertyValue_InContainer(ObjectToPopulate, field.IntValue); 813 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%d'"), *field.Name, field.IntValue)); 814 | } 815 | else if ((int32prop = Cast(targetProperty)) != NULL) 816 | { 817 | int32prop->SetPropertyValue_InContainer(ObjectToPopulate, (int32)field.IntValue); 818 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%d'"), *field.Name, field.IntValue)); 819 | } 820 | else if ((int16prop = Cast(targetProperty)) != NULL) 821 | { 822 | int16prop->SetPropertyValue_InContainer(ObjectToPopulate, (int16)field.IntValue); 823 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%d'"), *field.Name, field.IntValue)); 824 | } 825 | else if ((int8prop = Cast(targetProperty)) != NULL) 826 | { 827 | int8prop->SetPropertyValue_InContainer(ObjectToPopulate, (int8)field.IntValue); 828 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%d'"), *field.Name, field.IntValue)); 829 | } 830 | else if ((boolProp = Cast(targetProperty)) != NULL) 831 | { 832 | boolProp->SetPropertyValue_InContainer(ObjectToPopulate, field.IntValue > 0); 833 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%d'"), *field.Name, field.IntValue)); 834 | } 835 | } 836 | 837 | else if (field.Type == SQLiteResultValueTypes::Float) 838 | { 839 | UDoubleProperty* doubleProp = NULL; 840 | UFloatProperty* floatProp = NULL; 841 | if ((doubleProp = Cast(targetProperty)) != NULL) 842 | { 843 | doubleProp->SetPropertyValue_InContainer(ObjectToPopulate, field.DoubleValue); 844 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%f'"), *field.Name, field.DoubleValue)); 845 | } 846 | else if ((floatProp = Cast(targetProperty)) != NULL) 847 | { 848 | floatProp->SetPropertyValue_InContainer(ObjectToPopulate, (float)field.DoubleValue); 849 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%f'"), *field.Name, field.DoubleValue)); 850 | } 851 | } 852 | 853 | else if (field.Type == SQLiteResultValueTypes::Text) 854 | { 855 | UStrProperty* strProp = NULL; 856 | if ((strProp = Cast(targetProperty)) != NULL) 857 | { 858 | strProp->SetPropertyValue_InContainer(ObjectToPopulate, field.StringValue); 859 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%s'"), *field.Name, *field.StringValue.Mid(0, 64))); 860 | } 861 | } 862 | 863 | } 864 | } 865 | } 866 | 867 | //-------------------------------------------------------------------------------------------------------------- 868 | -------------------------------------------------------------------------------- /Source/CISQLite3/Public/CISQLite3.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Jussi Saarivirta 2016 conflict.industries MIT License (MIT) 2 | 3 | #pragma once 4 | 5 | #include "ModuleManager.h" 6 | 7 | class FCISQLite3 : public IModuleInterface 8 | { 9 | public: 10 | 11 | /** IModuleInterface implementation */ 12 | virtual void StartupModule() override; 13 | virtual void ShutdownModule() override; 14 | }; 15 | -------------------------------------------------------------------------------- /Source/CISQLite3/Public/SQLiteBlueprintFunctionLibrary.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "SQLiteDatabase.h" 3 | #include "SQLiteBlueprintNodes.h" 4 | #include "Kismet/BlueprintFunctionLibrary.h" 5 | #include "SQLiteBlueprintFunctionLibrary.generated.h" 6 | 7 | /** 8 | * Blueprint function library, convenience stuff. 9 | */ 10 | UCLASS() 11 | class CISQLITE3_API USQLiteBlueprintFunctionLibrary : public UBlueprintFunctionLibrary 12 | { 13 | GENERATED_BODY() 14 | 15 | public: 16 | 17 | 18 | UFUNCTION(BlueprintCallable, Category = "SQLite|Value Conversion") 19 | static int32 CastToInt(FString SQLiteResultValue); 20 | 21 | UFUNCTION(BlueprintCallable, Category = "SQLite|Value Conversion") 22 | static bool CastToBoolean(FString SQLiteResultValue); 23 | 24 | UFUNCTION(BlueprintCallable, Category = "SQLite|Value Conversion") 25 | static float CastToFloat(FString SQLiteResultValue); 26 | /** 27 | * Blueprint nodes for building queries. 28 | */ 29 | 30 | /** Start a new query block. */ 31 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Query Start", CompactNodeTitle = "("), Category = "SQLite|Query") 32 | static FSQLiteQueryTermExpectedNode QueryStart(FSQLiteQueryTermExpectedNode LogicOperationOrNone); 33 | 34 | /** End a query block. NOTE: To link this query to a Get Data node's query pin, link a Finalize Query node to the end of the query chain and link that to the pin. */ 35 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Query End", CompactNodeTitle = ")"), Category = "SQLite|Query") 36 | static FSQLiteQueryLogicExpectedNode QueryEnd(const FSQLiteQueryLogicExpectedNode& LastQueryTerm); 37 | 38 | /** A query term. Basically creating a "Key Value" comparison. */ 39 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Query Term"), Category = "SQLite|Query") 40 | static FSQLiteQueryLogicExpectedNode QueryTerm(const FSQLiteQueryTermExpectedNode& LogicOperation, FString Field, FString Operator, FString Value); 41 | 42 | /** AND logic node, combining two terms. */ 43 | UFUNCTION(BlueprintPure, meta = (DisplayName = "AND", CompactNodeTitle = "AND"), Category = "SQLite|Query|Logic") 44 | static FSQLiteQueryTermExpectedNode QueryLogicAnd(const FSQLiteQueryLogicExpectedNode& LHS); 45 | 46 | /** OR logic node, combining two terms. */ 47 | UFUNCTION(BlueprintPure, meta = (DisplayName = "OR", CompactNodeTitle = "OR"), Category = "SQLite|Query|Logic") 48 | static FSQLiteQueryTermExpectedNode QueryLogicOr(const FSQLiteQueryLogicExpectedNode& LHS); 49 | 50 | /** Finalizes the query. This node's output can be linked to a Get Data node's query source pin. */ 51 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Finalize Query"), Category = "SQLite|Query") 52 | static FSQLiteQueryFinalizedQuery QueryFinal(const FSQLiteQueryLogicExpectedNode& QueryEndNode); 53 | 54 | UFUNCTION(BlueprintPure, meta = (DisplayName = "INTEGER (SQLite)"), Category = "SQLite|Query|DataTypes") 55 | static FSQLiteTableField SQLiteINTEGER(FString FieldName, const bool PK, const bool AI, const bool Unique); 56 | 57 | UFUNCTION(BlueprintPure, meta = (DisplayName = "TEXT (SQLite)"), Category = "SQLite|Query|DataTypes") 58 | static FSQLiteTableField SQLiteTEXT(const FString FieldName, const bool PK, const bool Unique); 59 | 60 | UFUNCTION(BlueprintPure, meta = (DisplayName = "REAL (SQLite)"), Category = "SQLite|Query|DataTypes") 61 | static FSQLiteTableField SQLiteREAL(const FString FieldName, const bool PK, const bool Unique); 62 | 63 | UFUNCTION(BlueprintPure, meta = (DisplayName = "NUMERIC (SQLite)"), Category = "SQLite|Query|DataTypes") 64 | static FSQLiteTableField SQLiteNUMERIC(const FString FieldName, const bool PK, const bool Unique); 65 | 66 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Primary Key (SQLite)"), Category = "SQLite|Query|DataTypes") 67 | static FSQLitePrimaryKey SQLitePrimaryKey(const TArray Fields); 68 | 69 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Index (SQLite)"), Category = "SQLite|Query|DataTypes") 70 | static FSQLiteIndex SQLiteIndexFunction(const TArray Fields, FString idxName, bool Unique); 71 | 72 | 73 | 74 | }; 75 | -------------------------------------------------------------------------------- /Source/CISQLite3/Public/SQLiteBlueprintNodes.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include "SQLiteBlueprintNodes.generated.h" 4 | 5 | 6 | USTRUCT(BlueprintType) 7 | struct CISQLITE3_API FSQLiteQueryLogicExpectedNode 8 | { 9 | GENERATED_USTRUCT_BODY() 10 | 11 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Database Query") 12 | FString Query; 13 | 14 | FSQLiteQueryLogicExpectedNode(){} 15 | FSQLiteQueryLogicExpectedNode(FString LHSQuery, FString Append) : Query(LHSQuery) 16 | { 17 | Query += Append; 18 | } 19 | }; 20 | 21 | USTRUCT(BlueprintType) 22 | struct CISQLITE3_API FSQLiteQueryTermExpectedNode 23 | { 24 | GENERATED_USTRUCT_BODY() 25 | 26 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Database Query") 27 | FString Query; 28 | 29 | FSQLiteQueryTermExpectedNode(){} 30 | FSQLiteQueryTermExpectedNode(FString LHSQuery, FString Append) : Query(LHSQuery) 31 | { 32 | Query += Append; 33 | } 34 | }; 35 | 36 | USTRUCT(BlueprintType) 37 | struct CISQLITE3_API FSQLiteQueryFinalizedQuery 38 | { 39 | GENERATED_USTRUCT_BODY() 40 | 41 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Database Query") 42 | FString Query; 43 | 44 | FSQLiteQueryFinalizedQuery(){} 45 | FSQLiteQueryFinalizedQuery(FString Query) : Query(Query){} 46 | }; 47 | -------------------------------------------------------------------------------- /Source/CISQLite3/Public/SQLiteDatabase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "sqlite3.h" 3 | #include "SQLiteBlueprintNodes.h" 4 | #include "SQLiteDatabaseStructs.h" 5 | #include "SQLiteDatabase.generated.h" 6 | 7 | USTRUCT(BlueprintType) 8 | struct CISQLITE3_API FSQLiteDatabaseReference 9 | { 10 | GENERATED_USTRUCT_BODY() 11 | 12 | /** The database name (not the filename) */ 13 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Database Reference") 14 | FString DatabaseName; 15 | 16 | /** The database tables we want to get data from */ 17 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Database Reference") 18 | TArray Tables; 19 | }; 20 | 21 | USTRUCT(BlueprintType) 22 | struct CISQLITE3_API FSQLiteKeyValuePair 23 | { 24 | GENERATED_USTRUCT_BODY() 25 | 26 | /** The database table field name */ 27 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Key Value Pair") 28 | FString Key; 29 | 30 | /** The value of the field */ 31 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Key Value Pair") 32 | FString Value; 33 | }; 34 | 35 | USTRUCT(BlueprintType) 36 | struct CISQLITE3_API FSQLiteQueryResultRow 37 | { 38 | GENERATED_USTRUCT_BODY() 39 | 40 | /** A list of field name, field value pairs */ 41 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Query Result") 42 | TArray Fields; 43 | }; 44 | 45 | USTRUCT(BlueprintType) 46 | struct CISQLITE3_API FSQLiteQueryResult 47 | { 48 | GENERATED_USTRUCT_BODY() 49 | 50 | /** The resulting rows from the query */ 51 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Query Result") 52 | TArray ResultRows; 53 | 54 | /** Was the query successful or not */ 55 | UPROPERTY(BlueprintReadOnly, Category = "SQLite Query Result") 56 | bool Success; 57 | 58 | /** If the query was unsuccessful a human readable error message will be populated here */ 59 | UPROPERTY(BlueprintReadOnly, Category = "SQLite Query Result") 60 | FString ErrorMessage; 61 | 62 | }; 63 | 64 | 65 | 66 | // A few things for internal use here. 67 | namespace SQLiteResultValueTypes 68 | { 69 | enum SQLiteResultValType 70 | { 71 | Integer, 72 | Float, 73 | Text, 74 | UnsupportedValueType 75 | }; 76 | } 77 | 78 | // Result field, used as an intermediary when collecting results from 79 | // an SQLITE3 query. 80 | struct SQLiteResultField 81 | { 82 | FString StringValue; 83 | double DoubleValue; 84 | int64 IntValue; 85 | 86 | FString Name; 87 | SQLiteResultValueTypes::SQLiteResultValType Type; 88 | 89 | FString ToString() 90 | { 91 | if (Type == SQLiteResultValueTypes::Text) 92 | return StringValue; 93 | else if (Type == SQLiteResultValueTypes::Integer) 94 | return FString::Printf(TEXT("%i"), IntValue); 95 | else if (Type == SQLiteResultValueTypes::Float) 96 | return FString::Printf(TEXT("%f"), DoubleValue); 97 | 98 | return StringValue; 99 | } 100 | }; 101 | 102 | // Represents a single row in the result. 103 | struct SQLiteResultValue 104 | { 105 | TArray Fields; 106 | }; 107 | 108 | // The internal result object. 109 | struct SQLiteQueryResult 110 | { 111 | bool Success; 112 | FString ErrorMessage; 113 | TArray Results; 114 | }; 115 | 116 | 117 | 118 | /** 119 | * SQLite main database class. 120 | */ 121 | UCLASS() 122 | class CISQLITE3_API USQLiteDatabase : public UObject 123 | { 124 | GENERATED_UCLASS_BODY() 125 | 126 | public: 127 | /** Create a sqlite database file if it doesn't exist already. Does nothing if already exists. 128 | * Returns false if the file couldn't be created */ 129 | UFUNCTION(BlueprintCallable, Category = "SQLite") 130 | static bool CreateDatabase(const FString& Filename, bool RelativeToGameContentDirectory); 131 | 132 | /** Checks if the database is registered, ie. that it can be found in Databases. */ 133 | 134 | /** Add a database to the list of databases. It will be checked that it's valid (will try to open it) */ 135 | UFUNCTION(BlueprintCallable, Category = "SQLite") 136 | static bool RegisterDatabase(const FString& Name, const FString& Filename, bool RelativeToGameContentDirectory, bool KeepOpen=false); 137 | 138 | /** Remove a database from the list of databases. Closes the database in case KeepOpen flag was set during @ref RegisterDatabase */ 139 | UFUNCTION(BlueprintCallable, Category = "SQLite") 140 | static void UnregisterDatabase(const FString& Name); 141 | 142 | /** Checks if the database is registered, ie. that it can be found in Databases. */ 143 | UFUNCTION(BlueprintCallable, Category = "SQLite") 144 | static bool IsDatabaseRegistered(const FString& DatabaseName); 145 | 146 | /** Get data from the database using a select statement straight into an UObject, ie. populates its properties. */ 147 | UFUNCTION(BlueprintCallable, Category = "SQLite", meta = (DisplayName = "Get Data Into Object (manual query)")) 148 | static bool GetDataIntoObject(const FString& DatabaseName, const FString& Query, UObject* ObjectToPopulate); 149 | 150 | /** Blueprint: Gets data from the database using a select statement straight into an UObject, ie. populates its properties. 151 | * Note: Does not create a new object. ObjectToPopulate is the reference to the object you want to populate. */ 152 | UFUNCTION(BlueprintCallable, Category = "SQLite", meta = (DisplayName = "Get Data Into Object")) 153 | static bool GetDataIntoObjectBP(const FSQLiteDatabaseReference& DataSource, TArray Fields, FSQLiteQueryFinalizedQuery Query, UObject* ObjectToPopulate); 154 | 155 | /** Get data from the database using a select statement and return the rows. */ 156 | UFUNCTION(BlueprintCallable, Category = "SQLite", meta = (DisplayName = "Get Data From Table(s) (manual query)")) 157 | static FSQLiteQueryResult GetData(const FString& DatabaseName, const FString& Query); 158 | 159 | /** Blueprint: Get data from the database. Returns the resulting rows. */ 160 | UFUNCTION(BlueprintCallable, Category = "SQLite", meta = (DisplayName = "Get Data From Table(s)")) 161 | static FSQLiteQueryResult GetDataBP(const FSQLiteDatabaseReference& DataSource, TArray Fields, FSQLiteQueryFinalizedQuery Query, int32 MaxResults = -1, int32 ResultOffset = 0); 162 | 163 | /** Create table in the database. */ 164 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Create Table")) 165 | static FSQLiteTable CreateTable(const FString& DatabaseName, const FString& TableName, 166 | const TArray Fields, const FSQLitePrimaryKey PK); 167 | 168 | /** Create indexes for table */ 169 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Create Indexes")) 170 | static bool CreateIndexes(const FString& DatabaseName, const FString& TableName, const TArray Indexes); 171 | 172 | /** Create index for table */ 173 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Create Index")) 174 | static bool CreateIndex(const FString& DatabaseName, const FString& TableName, const FSQLiteIndex Index); 175 | 176 | /** Drop index*/ 177 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Drop Index")) 178 | static bool DropIndex(const FString& DatabaseName, const FString& IndexName); 179 | 180 | /** Drop Table*/ 181 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Drop Table")) 182 | static bool DropTable(const FString& DatabaseName, const FString& TableName); 183 | 184 | /** Truncate Table*/ 185 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Truncate Table")) 186 | static bool TruncateTable(const FString& DatabaseName, const FString& TableName); 187 | 188 | /** Is table exists?*/ 189 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Is table exists?")) 190 | static bool IsTableExists(const FString& DatabaseName, const FString& TableName); 191 | 192 | /** Insert rows into table */ 193 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Insert Rows Into Table")) 194 | static void InsertRowsIntoTable(const FString& DatabaseName, const FString& TableName, TArray rowsOfFields); 195 | 196 | /** Compact database*/ 197 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Compact database")) 198 | static bool Vacuum(const FString& DatabaseName); 199 | 200 | /** Execute SQL (can be used for insert statement)*/ 201 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Execute SQL")) 202 | static bool ExecSql(const FString& DatabaseName, const FString& Query); 203 | 204 | /** Checks database validity (if the file exists and/or if it can be opened). */ 205 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Is Valid Database")) 206 | static bool IsValidDatabase(const FString& DatabaseFilename, bool TestByOpening); 207 | 208 | static TArray Dump(const FString& DatabaseFilename); 209 | static bool Restore(const FString& DatabaseFilename, const TArray& data); 210 | 211 | /** Runs a query and returns fetched rows. */ 212 | static TUniquePtr RunQueryAndGetResults(const FString& DatabaseName, const FString& Query); 213 | private: 214 | /** Tries to open a database. */ 215 | static bool CanOpenDatabase(const FString& DatabaseFilename); 216 | /** Collects all properties from an UObject and maps them by the property name. */ 217 | static TMap CollectProperties(UObject* SourceObject); 218 | /** Constructs an SQL query from the blueprint fed data. */ 219 | static FString ConstructQuery(TArray Tables, TArray Fields, FSQLiteQueryFinalizedQuery QueryObject, int32 MaxResults = -1, int32 ResultOffset = 0); 220 | /** Assigns a result row's fields' values to an UObject, ie. assigns them to the properties that have the same name. */ 221 | static void AssignResultsToObjectProperties(const SQLiteResultValue& ResultValue, UObject* ObjectToPopulate); 222 | /** @brief Prepare given statement, returns whether to keep the database open */ 223 | static bool PrepareStatement(const FString& DatabaseName, const FString& Query, sqlite3** Db, int32** SqlReturnCode, 224 | sqlite3_stmt** PreparedStatement); 225 | 226 | 227 | private: 228 | /** A list of the databases for convenience, easier to refer to them by name rather than a long filename. */ 229 | static TMap Databases; 230 | 231 | static TMap SQLite3Databases; 232 | 233 | }; 234 | -------------------------------------------------------------------------------- /Source/CISQLite3/Public/SQLiteDatabaseStructs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "SQLiteDatabaseStructs.generated.h" 3 | 4 | USTRUCT(BlueprintType) 5 | struct CISQLITE3_API FSQLiteIndex 6 | { 7 | GENERATED_USTRUCT_BODY() 8 | 9 | /** String with piece if SQL script*/ 10 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Index") 11 | FString ResultStr = ""; 12 | 13 | /** Index name*/ 14 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Index") 15 | FString IndexName = ""; 16 | 17 | }; 18 | 19 | USTRUCT(BlueprintType) 20 | struct CISQLITE3_API FSQLitePrimaryKey 21 | { 22 | GENERATED_USTRUCT_BODY() 23 | 24 | /** String with piece if SQL script*/ 25 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Primary Key") 26 | FString ResultStr = ""; 27 | }; 28 | 29 | USTRUCT(BlueprintType) 30 | struct CISQLITE3_API FSQLiteTableField 31 | { 32 | GENERATED_USTRUCT_BODY() 33 | 34 | /** String with piece if SQL script*/ 35 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table Field") 36 | FString ResultStr = ""; 37 | 38 | /** Field name*/ 39 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table Field") 40 | FString FieldName = ""; 41 | 42 | /** Field type*/ 43 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table Field") 44 | FString FieldType = ""; 45 | 46 | /** Field value*/ 47 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table Field") 48 | FString FieldValue = ""; 49 | 50 | }; 51 | 52 | USTRUCT(BlueprintType) 53 | struct CISQLITE3_API FSQLiteTableRowSimulator 54 | { 55 | GENERATED_USTRUCT_BODY() 56 | 57 | /** Index name*/ 58 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Index") 59 | TArray rowsOfFields; 60 | 61 | }; 62 | 63 | USTRUCT(BlueprintType) 64 | struct CISQLITE3_API FSQLiteTable 65 | { 66 | GENERATED_USTRUCT_BODY() 67 | 68 | /** Database name*/ 69 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table") 70 | FString DatabaseName = ""; 71 | 72 | /** Table name*/ 73 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table") 74 | FString TableName = ""; 75 | 76 | /** Array with Fields*/ 77 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table") 78 | TArray Fields; 79 | 80 | /** Primary Key */ 81 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table") 82 | FSQLitePrimaryKey PK; 83 | 84 | /** Created Key */ 85 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table") 86 | bool Created = false; 87 | 88 | }; 89 | -------------------------------------------------------------------------------- /Source/CISQLite3/Public/sqlite3ext.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 2006 June 7 3 | ** 4 | ** The author disclaims copyright to this source code. In place of 5 | ** a legal notice, here is a blessing: 6 | ** 7 | ** May you do good and not evil. 8 | ** May you find forgiveness for yourself and forgive others. 9 | ** May you share freely, never taking more than you give. 10 | ** 11 | ************************************************************************* 12 | ** This header file defines the SQLite interface for use by 13 | ** shared libraries that want to be imported as extensions into 14 | ** an SQLite instance. Shared libraries that intend to be loaded 15 | ** as extensions by SQLite should #include this file instead of 16 | ** sqlite3.h. 17 | */ 18 | #ifndef SQLITE3EXT_H 19 | #define SQLITE3EXT_H 20 | #include "sqlite3.h" 21 | 22 | /* 23 | ** The following structure holds pointers to all of the SQLite API 24 | ** routines. 25 | ** 26 | ** WARNING: In order to maintain backwards compatibility, add new 27 | ** interfaces to the end of this structure only. If you insert new 28 | ** interfaces in the middle of this structure, then older different 29 | ** versions of SQLite will not be able to load each other's shared 30 | ** libraries! 31 | */ 32 | struct sqlite3_api_routines { 33 | void * (*aggregate_context)(sqlite3_context*,int nBytes); 34 | int (*aggregate_count)(sqlite3_context*); 35 | int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); 36 | int (*bind_double)(sqlite3_stmt*,int,double); 37 | int (*bind_int)(sqlite3_stmt*,int,int); 38 | int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); 39 | int (*bind_null)(sqlite3_stmt*,int); 40 | int (*bind_parameter_count)(sqlite3_stmt*); 41 | int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); 42 | const char * (*bind_parameter_name)(sqlite3_stmt*,int); 43 | int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); 44 | int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); 45 | int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); 46 | int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); 47 | int (*busy_timeout)(sqlite3*,int ms); 48 | int (*changes)(sqlite3*); 49 | int (*close)(sqlite3*); 50 | int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*, 51 | int eTextRep,const char*)); 52 | int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*, 53 | int eTextRep,const void*)); 54 | const void * (*column_blob)(sqlite3_stmt*,int iCol); 55 | int (*column_bytes)(sqlite3_stmt*,int iCol); 56 | int (*column_bytes16)(sqlite3_stmt*,int iCol); 57 | int (*column_count)(sqlite3_stmt*pStmt); 58 | const char * (*column_database_name)(sqlite3_stmt*,int); 59 | const void * (*column_database_name16)(sqlite3_stmt*,int); 60 | const char * (*column_decltype)(sqlite3_stmt*,int i); 61 | const void * (*column_decltype16)(sqlite3_stmt*,int); 62 | double (*column_double)(sqlite3_stmt*,int iCol); 63 | int (*column_int)(sqlite3_stmt*,int iCol); 64 | sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); 65 | const char * (*column_name)(sqlite3_stmt*,int); 66 | const void * (*column_name16)(sqlite3_stmt*,int); 67 | const char * (*column_origin_name)(sqlite3_stmt*,int); 68 | const void * (*column_origin_name16)(sqlite3_stmt*,int); 69 | const char * (*column_table_name)(sqlite3_stmt*,int); 70 | const void * (*column_table_name16)(sqlite3_stmt*,int); 71 | const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); 72 | const void * (*column_text16)(sqlite3_stmt*,int iCol); 73 | int (*column_type)(sqlite3_stmt*,int iCol); 74 | sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); 75 | void * (*commit_hook)(sqlite3*,int(*)(void*),void*); 76 | int (*complete)(const char*sql); 77 | int (*complete16)(const void*sql); 78 | int (*create_collation)(sqlite3*,const char*,int,void*, 79 | int(*)(void*,int,const void*,int,const void*)); 80 | int (*create_collation16)(sqlite3*,const void*,int,void*, 81 | int(*)(void*,int,const void*,int,const void*)); 82 | int (*create_function)(sqlite3*,const char*,int,int,void*, 83 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 84 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 85 | void (*xFinal)(sqlite3_context*)); 86 | int (*create_function16)(sqlite3*,const void*,int,int,void*, 87 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 88 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 89 | void (*xFinal)(sqlite3_context*)); 90 | int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); 91 | int (*data_count)(sqlite3_stmt*pStmt); 92 | sqlite3 * (*db_handle)(sqlite3_stmt*); 93 | int (*declare_vtab)(sqlite3*,const char*); 94 | int (*enable_shared_cache)(int); 95 | int (*errcode)(sqlite3*db); 96 | const char * (*errmsg)(sqlite3*); 97 | const void * (*errmsg16)(sqlite3*); 98 | int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); 99 | int (*expired)(sqlite3_stmt*); 100 | int (*finalize)(sqlite3_stmt*pStmt); 101 | void (*free)(void*); 102 | void (*free_table)(char**result); 103 | int (*get_autocommit)(sqlite3*); 104 | void * (*get_auxdata)(sqlite3_context*,int); 105 | int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); 106 | int (*global_recover)(void); 107 | void (*interruptx)(sqlite3*); 108 | sqlite_int64 (*last_insert_rowid)(sqlite3*); 109 | const char * (*libversion)(void); 110 | int (*libversion_number)(void); 111 | void *(*malloc)(int); 112 | char * (*mprintf)(const char*,...); 113 | int (*open)(const char*,sqlite3**); 114 | int (*open16)(const void*,sqlite3**); 115 | int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); 116 | int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); 117 | void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); 118 | void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); 119 | void *(*realloc)(void*,int); 120 | int (*reset)(sqlite3_stmt*pStmt); 121 | void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); 122 | void (*result_double)(sqlite3_context*,double); 123 | void (*result_error)(sqlite3_context*,const char*,int); 124 | void (*result_error16)(sqlite3_context*,const void*,int); 125 | void (*result_int)(sqlite3_context*,int); 126 | void (*result_int64)(sqlite3_context*,sqlite_int64); 127 | void (*result_null)(sqlite3_context*); 128 | void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); 129 | void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); 130 | void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); 131 | void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); 132 | void (*result_value)(sqlite3_context*,sqlite3_value*); 133 | void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); 134 | int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, 135 | const char*,const char*),void*); 136 | void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); 137 | char * (*xsnprintf)(int,char*,const char*,...); 138 | int (*step)(sqlite3_stmt*); 139 | int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, 140 | char const**,char const**,int*,int*,int*); 141 | void (*thread_cleanup)(void); 142 | int (*total_changes)(sqlite3*); 143 | void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); 144 | int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); 145 | void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*, 146 | sqlite_int64),void*); 147 | void * (*user_data)(sqlite3_context*); 148 | const void * (*value_blob)(sqlite3_value*); 149 | int (*value_bytes)(sqlite3_value*); 150 | int (*value_bytes16)(sqlite3_value*); 151 | double (*value_double)(sqlite3_value*); 152 | int (*value_int)(sqlite3_value*); 153 | sqlite_int64 (*value_int64)(sqlite3_value*); 154 | int (*value_numeric_type)(sqlite3_value*); 155 | const unsigned char * (*value_text)(sqlite3_value*); 156 | const void * (*value_text16)(sqlite3_value*); 157 | const void * (*value_text16be)(sqlite3_value*); 158 | const void * (*value_text16le)(sqlite3_value*); 159 | int (*value_type)(sqlite3_value*); 160 | char *(*vmprintf)(const char*,va_list); 161 | /* Added ??? */ 162 | int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); 163 | /* Added by 3.3.13 */ 164 | int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); 165 | int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); 166 | int (*clear_bindings)(sqlite3_stmt*); 167 | /* Added by 3.4.1 */ 168 | int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*, 169 | void (*xDestroy)(void *)); 170 | /* Added by 3.5.0 */ 171 | int (*bind_zeroblob)(sqlite3_stmt*,int,int); 172 | int (*blob_bytes)(sqlite3_blob*); 173 | int (*blob_close)(sqlite3_blob*); 174 | int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64, 175 | int,sqlite3_blob**); 176 | int (*blob_read)(sqlite3_blob*,void*,int,int); 177 | int (*blob_write)(sqlite3_blob*,const void*,int,int); 178 | int (*create_collation_v2)(sqlite3*,const char*,int,void*, 179 | int(*)(void*,int,const void*,int,const void*), 180 | void(*)(void*)); 181 | int (*file_control)(sqlite3*,const char*,int,void*); 182 | sqlite3_int64 (*memory_highwater)(int); 183 | sqlite3_int64 (*memory_used)(void); 184 | sqlite3_mutex *(*mutex_alloc)(int); 185 | void (*mutex_enter)(sqlite3_mutex*); 186 | void (*mutex_free)(sqlite3_mutex*); 187 | void (*mutex_leave)(sqlite3_mutex*); 188 | int (*mutex_try)(sqlite3_mutex*); 189 | int (*open_v2)(const char*,sqlite3**,int,const char*); 190 | int (*release_memory)(int); 191 | void (*result_error_nomem)(sqlite3_context*); 192 | void (*result_error_toobig)(sqlite3_context*); 193 | int (*sleep)(int); 194 | void (*soft_heap_limit)(int); 195 | sqlite3_vfs *(*vfs_find)(const char*); 196 | int (*vfs_register)(sqlite3_vfs*,int); 197 | int (*vfs_unregister)(sqlite3_vfs*); 198 | int (*xthreadsafe)(void); 199 | void (*result_zeroblob)(sqlite3_context*,int); 200 | void (*result_error_code)(sqlite3_context*,int); 201 | int (*test_control)(int, ...); 202 | void (*randomness)(int,void*); 203 | sqlite3 *(*context_db_handle)(sqlite3_context*); 204 | int (*extended_result_codes)(sqlite3*,int); 205 | int (*limit)(sqlite3*,int,int); 206 | sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); 207 | const char *(*sql)(sqlite3_stmt*); 208 | int (*status)(int,int*,int*,int); 209 | int (*backup_finish)(sqlite3_backup*); 210 | sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); 211 | int (*backup_pagecount)(sqlite3_backup*); 212 | int (*backup_remaining)(sqlite3_backup*); 213 | int (*backup_step)(sqlite3_backup*,int); 214 | const char *(*compileoption_get)(int); 215 | int (*compileoption_used)(const char*); 216 | int (*create_function_v2)(sqlite3*,const char*,int,int,void*, 217 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 218 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 219 | void (*xFinal)(sqlite3_context*), 220 | void(*xDestroy)(void*)); 221 | int (*db_config)(sqlite3*,int,...); 222 | sqlite3_mutex *(*db_mutex)(sqlite3*); 223 | int (*db_status)(sqlite3*,int,int*,int*,int); 224 | int (*extended_errcode)(sqlite3*); 225 | void (*log)(int,const char*,...); 226 | sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); 227 | const char *(*sourceid)(void); 228 | int (*stmt_status)(sqlite3_stmt*,int,int); 229 | int (*strnicmp)(const char*,const char*,int); 230 | int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); 231 | int (*wal_autocheckpoint)(sqlite3*,int); 232 | int (*wal_checkpoint)(sqlite3*,const char*); 233 | void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); 234 | int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); 235 | int (*vtab_config)(sqlite3*,int op,...); 236 | int (*vtab_on_conflict)(sqlite3*); 237 | /* Version 3.7.16 and later */ 238 | int (*close_v2)(sqlite3*); 239 | const char *(*db_filename)(sqlite3*,const char*); 240 | int (*db_readonly)(sqlite3*,const char*); 241 | int (*db_release_memory)(sqlite3*); 242 | const char *(*errstr)(int); 243 | int (*stmt_busy)(sqlite3_stmt*); 244 | int (*stmt_readonly)(sqlite3_stmt*); 245 | int (*stricmp)(const char*,const char*); 246 | int (*uri_boolean)(const char*,const char*,int); 247 | sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64); 248 | const char *(*uri_parameter)(const char*,const char*); 249 | char *(*xvsnprintf)(int,char*,const char*,va_list); 250 | int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); 251 | /* Version 3.8.7 and later */ 252 | int (*auto_extension)(void(*)(void)); 253 | int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, 254 | void(*)(void*)); 255 | int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, 256 | void(*)(void*),unsigned char); 257 | int (*cancel_auto_extension)(void(*)(void)); 258 | int (*load_extension)(sqlite3*,const char*,const char*,char**); 259 | void *(*malloc64)(sqlite3_uint64); 260 | sqlite3_uint64 (*msize)(void*); 261 | void *(*realloc64)(void*,sqlite3_uint64); 262 | void (*reset_auto_extension)(void); 263 | void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64, 264 | void(*)(void*)); 265 | void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64, 266 | void(*)(void*), unsigned char); 267 | int (*strglob)(const char*,const char*); 268 | /* Version 3.8.11 and later */ 269 | sqlite3_value *(*value_dup)(const sqlite3_value*); 270 | void (*value_free)(sqlite3_value*); 271 | int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64); 272 | int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64); 273 | /* Version 3.9.0 and later */ 274 | unsigned int (*value_subtype)(sqlite3_value*); 275 | void (*result_subtype)(sqlite3_context*,unsigned int); 276 | /* Version 3.10.0 and later */ 277 | int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int); 278 | int (*strlike)(const char*,const char*,unsigned int); 279 | int (*db_cacheflush)(sqlite3*); 280 | /* Version 3.12.0 and later */ 281 | int (*system_errno)(sqlite3*); 282 | /* Version 3.14.0 and later */ 283 | int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*); 284 | char *(*expanded_sql)(sqlite3_stmt*); 285 | /* Version 3.18.0 and later */ 286 | void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64); 287 | /* Version 3.20.0 and later */ 288 | int (*prepare_v3)(sqlite3*,const char*,int,unsigned int, 289 | sqlite3_stmt**,const char**); 290 | int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int, 291 | sqlite3_stmt**,const void**); 292 | int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*)); 293 | void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*)); 294 | void *(*value_pointer)(sqlite3_value*,const char*); 295 | int (*vtab_nochange)(sqlite3_context*); 296 | int (*value_nochange)(sqlite3_value*); 297 | const char *(*vtab_collation)(sqlite3_index_info*,int); 298 | }; 299 | 300 | /* 301 | ** This is the function signature used for all extension entry points. It 302 | ** is also defined in the file "loadext.c". 303 | */ 304 | typedef int (*sqlite3_loadext_entry)( 305 | sqlite3 *db, /* Handle to the database. */ 306 | char **pzErrMsg, /* Used to set error string on failure. */ 307 | const sqlite3_api_routines *pThunk /* Extension API function pointers. */ 308 | ); 309 | 310 | /* 311 | ** The following macros redefine the API routines so that they are 312 | ** redirected through the global sqlite3_api structure. 313 | ** 314 | ** This header file is also used by the loadext.c source file 315 | ** (part of the main SQLite library - not an extension) so that 316 | ** it can get access to the sqlite3_api_routines structure 317 | ** definition. But the main library does not want to redefine 318 | ** the API. So the redefinition macros are only valid if the 319 | ** SQLITE_CORE macros is undefined. 320 | */ 321 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) 322 | #define sqlite3_aggregate_context sqlite3_api->aggregate_context 323 | #ifndef SQLITE_OMIT_DEPRECATED 324 | #define sqlite3_aggregate_count sqlite3_api->aggregate_count 325 | #endif 326 | #define sqlite3_bind_blob sqlite3_api->bind_blob 327 | #define sqlite3_bind_double sqlite3_api->bind_double 328 | #define sqlite3_bind_int sqlite3_api->bind_int 329 | #define sqlite3_bind_int64 sqlite3_api->bind_int64 330 | #define sqlite3_bind_null sqlite3_api->bind_null 331 | #define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count 332 | #define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index 333 | #define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name 334 | #define sqlite3_bind_text sqlite3_api->bind_text 335 | #define sqlite3_bind_text16 sqlite3_api->bind_text16 336 | #define sqlite3_bind_value sqlite3_api->bind_value 337 | #define sqlite3_busy_handler sqlite3_api->busy_handler 338 | #define sqlite3_busy_timeout sqlite3_api->busy_timeout 339 | #define sqlite3_changes sqlite3_api->changes 340 | #define sqlite3_close sqlite3_api->close 341 | #define sqlite3_collation_needed sqlite3_api->collation_needed 342 | #define sqlite3_collation_needed16 sqlite3_api->collation_needed16 343 | #define sqlite3_column_blob sqlite3_api->column_blob 344 | #define sqlite3_column_bytes sqlite3_api->column_bytes 345 | #define sqlite3_column_bytes16 sqlite3_api->column_bytes16 346 | #define sqlite3_column_count sqlite3_api->column_count 347 | #define sqlite3_column_database_name sqlite3_api->column_database_name 348 | #define sqlite3_column_database_name16 sqlite3_api->column_database_name16 349 | #define sqlite3_column_decltype sqlite3_api->column_decltype 350 | #define sqlite3_column_decltype16 sqlite3_api->column_decltype16 351 | #define sqlite3_column_double sqlite3_api->column_double 352 | #define sqlite3_column_int sqlite3_api->column_int 353 | #define sqlite3_column_int64 sqlite3_api->column_int64 354 | #define sqlite3_column_name sqlite3_api->column_name 355 | #define sqlite3_column_name16 sqlite3_api->column_name16 356 | #define sqlite3_column_origin_name sqlite3_api->column_origin_name 357 | #define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 358 | #define sqlite3_column_table_name sqlite3_api->column_table_name 359 | #define sqlite3_column_table_name16 sqlite3_api->column_table_name16 360 | #define sqlite3_column_text sqlite3_api->column_text 361 | #define sqlite3_column_text16 sqlite3_api->column_text16 362 | #define sqlite3_column_type sqlite3_api->column_type 363 | #define sqlite3_column_value sqlite3_api->column_value 364 | #define sqlite3_commit_hook sqlite3_api->commit_hook 365 | #define sqlite3_complete sqlite3_api->complete 366 | #define sqlite3_complete16 sqlite3_api->complete16 367 | #define sqlite3_create_collation sqlite3_api->create_collation 368 | #define sqlite3_create_collation16 sqlite3_api->create_collation16 369 | #define sqlite3_create_function sqlite3_api->create_function 370 | #define sqlite3_create_function16 sqlite3_api->create_function16 371 | #define sqlite3_create_module sqlite3_api->create_module 372 | #define sqlite3_create_module_v2 sqlite3_api->create_module_v2 373 | #define sqlite3_data_count sqlite3_api->data_count 374 | #define sqlite3_db_handle sqlite3_api->db_handle 375 | #define sqlite3_declare_vtab sqlite3_api->declare_vtab 376 | #define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache 377 | #define sqlite3_errcode sqlite3_api->errcode 378 | #define sqlite3_errmsg sqlite3_api->errmsg 379 | #define sqlite3_errmsg16 sqlite3_api->errmsg16 380 | #define sqlite3_exec sqlite3_api->exec 381 | #ifndef SQLITE_OMIT_DEPRECATED 382 | #define sqlite3_expired sqlite3_api->expired 383 | #endif 384 | #define sqlite3_finalize sqlite3_api->finalize 385 | #define sqlite3_free sqlite3_api->free 386 | #define sqlite3_free_table sqlite3_api->free_table 387 | #define sqlite3_get_autocommit sqlite3_api->get_autocommit 388 | #define sqlite3_get_auxdata sqlite3_api->get_auxdata 389 | #define sqlite3_get_table sqlite3_api->get_table 390 | #ifndef SQLITE_OMIT_DEPRECATED 391 | #define sqlite3_global_recover sqlite3_api->global_recover 392 | #endif 393 | #define sqlite3_interrupt sqlite3_api->interruptx 394 | #define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid 395 | #define sqlite3_libversion sqlite3_api->libversion 396 | #define sqlite3_libversion_number sqlite3_api->libversion_number 397 | #define sqlite3_malloc sqlite3_api->malloc 398 | #define sqlite3_mprintf sqlite3_api->mprintf 399 | #define sqlite3_open sqlite3_api->open 400 | #define sqlite3_open16 sqlite3_api->open16 401 | #define sqlite3_prepare sqlite3_api->prepare 402 | #define sqlite3_prepare16 sqlite3_api->prepare16 403 | #define sqlite3_prepare_v2 sqlite3_api->prepare_v2 404 | #define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 405 | #define sqlite3_profile sqlite3_api->profile 406 | #define sqlite3_progress_handler sqlite3_api->progress_handler 407 | #define sqlite3_realloc sqlite3_api->realloc 408 | #define sqlite3_reset sqlite3_api->reset 409 | #define sqlite3_result_blob sqlite3_api->result_blob 410 | #define sqlite3_result_double sqlite3_api->result_double 411 | #define sqlite3_result_error sqlite3_api->result_error 412 | #define sqlite3_result_error16 sqlite3_api->result_error16 413 | #define sqlite3_result_int sqlite3_api->result_int 414 | #define sqlite3_result_int64 sqlite3_api->result_int64 415 | #define sqlite3_result_null sqlite3_api->result_null 416 | #define sqlite3_result_text sqlite3_api->result_text 417 | #define sqlite3_result_text16 sqlite3_api->result_text16 418 | #define sqlite3_result_text16be sqlite3_api->result_text16be 419 | #define sqlite3_result_text16le sqlite3_api->result_text16le 420 | #define sqlite3_result_value sqlite3_api->result_value 421 | #define sqlite3_rollback_hook sqlite3_api->rollback_hook 422 | #define sqlite3_set_authorizer sqlite3_api->set_authorizer 423 | #define sqlite3_set_auxdata sqlite3_api->set_auxdata 424 | #define sqlite3_snprintf sqlite3_api->xsnprintf 425 | #define sqlite3_step sqlite3_api->step 426 | #define sqlite3_table_column_metadata sqlite3_api->table_column_metadata 427 | #define sqlite3_thread_cleanup sqlite3_api->thread_cleanup 428 | #define sqlite3_total_changes sqlite3_api->total_changes 429 | #define sqlite3_trace sqlite3_api->trace 430 | #ifndef SQLITE_OMIT_DEPRECATED 431 | #define sqlite3_transfer_bindings sqlite3_api->transfer_bindings 432 | #endif 433 | #define sqlite3_update_hook sqlite3_api->update_hook 434 | #define sqlite3_user_data sqlite3_api->user_data 435 | #define sqlite3_value_blob sqlite3_api->value_blob 436 | #define sqlite3_value_bytes sqlite3_api->value_bytes 437 | #define sqlite3_value_bytes16 sqlite3_api->value_bytes16 438 | #define sqlite3_value_double sqlite3_api->value_double 439 | #define sqlite3_value_int sqlite3_api->value_int 440 | #define sqlite3_value_int64 sqlite3_api->value_int64 441 | #define sqlite3_value_numeric_type sqlite3_api->value_numeric_type 442 | #define sqlite3_value_text sqlite3_api->value_text 443 | #define sqlite3_value_text16 sqlite3_api->value_text16 444 | #define sqlite3_value_text16be sqlite3_api->value_text16be 445 | #define sqlite3_value_text16le sqlite3_api->value_text16le 446 | #define sqlite3_value_type sqlite3_api->value_type 447 | #define sqlite3_vmprintf sqlite3_api->vmprintf 448 | #define sqlite3_vsnprintf sqlite3_api->xvsnprintf 449 | #define sqlite3_overload_function sqlite3_api->overload_function 450 | #define sqlite3_prepare_v2 sqlite3_api->prepare_v2 451 | #define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 452 | #define sqlite3_clear_bindings sqlite3_api->clear_bindings 453 | #define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob 454 | #define sqlite3_blob_bytes sqlite3_api->blob_bytes 455 | #define sqlite3_blob_close sqlite3_api->blob_close 456 | #define sqlite3_blob_open sqlite3_api->blob_open 457 | #define sqlite3_blob_read sqlite3_api->blob_read 458 | #define sqlite3_blob_write sqlite3_api->blob_write 459 | #define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2 460 | #define sqlite3_file_control sqlite3_api->file_control 461 | #define sqlite3_memory_highwater sqlite3_api->memory_highwater 462 | #define sqlite3_memory_used sqlite3_api->memory_used 463 | #define sqlite3_mutex_alloc sqlite3_api->mutex_alloc 464 | #define sqlite3_mutex_enter sqlite3_api->mutex_enter 465 | #define sqlite3_mutex_free sqlite3_api->mutex_free 466 | #define sqlite3_mutex_leave sqlite3_api->mutex_leave 467 | #define sqlite3_mutex_try sqlite3_api->mutex_try 468 | #define sqlite3_open_v2 sqlite3_api->open_v2 469 | #define sqlite3_release_memory sqlite3_api->release_memory 470 | #define sqlite3_result_error_nomem sqlite3_api->result_error_nomem 471 | #define sqlite3_result_error_toobig sqlite3_api->result_error_toobig 472 | #define sqlite3_sleep sqlite3_api->sleep 473 | #define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit 474 | #define sqlite3_vfs_find sqlite3_api->vfs_find 475 | #define sqlite3_vfs_register sqlite3_api->vfs_register 476 | #define sqlite3_vfs_unregister sqlite3_api->vfs_unregister 477 | #define sqlite3_threadsafe sqlite3_api->xthreadsafe 478 | #define sqlite3_result_zeroblob sqlite3_api->result_zeroblob 479 | #define sqlite3_result_error_code sqlite3_api->result_error_code 480 | #define sqlite3_test_control sqlite3_api->test_control 481 | #define sqlite3_randomness sqlite3_api->randomness 482 | #define sqlite3_context_db_handle sqlite3_api->context_db_handle 483 | #define sqlite3_extended_result_codes sqlite3_api->extended_result_codes 484 | #define sqlite3_limit sqlite3_api->limit 485 | #define sqlite3_next_stmt sqlite3_api->next_stmt 486 | #define sqlite3_sql sqlite3_api->sql 487 | #define sqlite3_status sqlite3_api->status 488 | #define sqlite3_backup_finish sqlite3_api->backup_finish 489 | #define sqlite3_backup_init sqlite3_api->backup_init 490 | #define sqlite3_backup_pagecount sqlite3_api->backup_pagecount 491 | #define sqlite3_backup_remaining sqlite3_api->backup_remaining 492 | #define sqlite3_backup_step sqlite3_api->backup_step 493 | #define sqlite3_compileoption_get sqlite3_api->compileoption_get 494 | #define sqlite3_compileoption_used sqlite3_api->compileoption_used 495 | #define sqlite3_create_function_v2 sqlite3_api->create_function_v2 496 | #define sqlite3_db_config sqlite3_api->db_config 497 | #define sqlite3_db_mutex sqlite3_api->db_mutex 498 | #define sqlite3_db_status sqlite3_api->db_status 499 | #define sqlite3_extended_errcode sqlite3_api->extended_errcode 500 | #define sqlite3_log sqlite3_api->log 501 | #define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64 502 | #define sqlite3_sourceid sqlite3_api->sourceid 503 | #define sqlite3_stmt_status sqlite3_api->stmt_status 504 | #define sqlite3_strnicmp sqlite3_api->strnicmp 505 | #define sqlite3_unlock_notify sqlite3_api->unlock_notify 506 | #define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint 507 | #define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint 508 | #define sqlite3_wal_hook sqlite3_api->wal_hook 509 | #define sqlite3_blob_reopen sqlite3_api->blob_reopen 510 | #define sqlite3_vtab_config sqlite3_api->vtab_config 511 | #define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict 512 | /* Version 3.7.16 and later */ 513 | #define sqlite3_close_v2 sqlite3_api->close_v2 514 | #define sqlite3_db_filename sqlite3_api->db_filename 515 | #define sqlite3_db_readonly sqlite3_api->db_readonly 516 | #define sqlite3_db_release_memory sqlite3_api->db_release_memory 517 | #define sqlite3_errstr sqlite3_api->errstr 518 | #define sqlite3_stmt_busy sqlite3_api->stmt_busy 519 | #define sqlite3_stmt_readonly sqlite3_api->stmt_readonly 520 | #define sqlite3_stricmp sqlite3_api->stricmp 521 | #define sqlite3_uri_boolean sqlite3_api->uri_boolean 522 | #define sqlite3_uri_int64 sqlite3_api->uri_int64 523 | #define sqlite3_uri_parameter sqlite3_api->uri_parameter 524 | #define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf 525 | #define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 526 | /* Version 3.8.7 and later */ 527 | #define sqlite3_auto_extension sqlite3_api->auto_extension 528 | #define sqlite3_bind_blob64 sqlite3_api->bind_blob64 529 | #define sqlite3_bind_text64 sqlite3_api->bind_text64 530 | #define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension 531 | #define sqlite3_load_extension sqlite3_api->load_extension 532 | #define sqlite3_malloc64 sqlite3_api->malloc64 533 | #define sqlite3_msize sqlite3_api->msize 534 | #define sqlite3_realloc64 sqlite3_api->realloc64 535 | #define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension 536 | #define sqlite3_result_blob64 sqlite3_api->result_blob64 537 | #define sqlite3_result_text64 sqlite3_api->result_text64 538 | #define sqlite3_strglob sqlite3_api->strglob 539 | /* Version 3.8.11 and later */ 540 | #define sqlite3_value_dup sqlite3_api->value_dup 541 | #define sqlite3_value_free sqlite3_api->value_free 542 | #define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64 543 | #define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64 544 | /* Version 3.9.0 and later */ 545 | #define sqlite3_value_subtype sqlite3_api->value_subtype 546 | #define sqlite3_result_subtype sqlite3_api->result_subtype 547 | /* Version 3.10.0 and later */ 548 | #define sqlite3_status64 sqlite3_api->status64 549 | #define sqlite3_strlike sqlite3_api->strlike 550 | #define sqlite3_db_cacheflush sqlite3_api->db_cacheflush 551 | /* Version 3.12.0 and later */ 552 | #define sqlite3_system_errno sqlite3_api->system_errno 553 | /* Version 3.14.0 and later */ 554 | #define sqlite3_trace_v2 sqlite3_api->trace_v2 555 | #define sqlite3_expanded_sql sqlite3_api->expanded_sql 556 | /* Version 3.18.0 and later */ 557 | #define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid 558 | /* Version 3.20.0 and later */ 559 | #define sqlite3_prepare_v3 sqlite3_api->prepare_v3 560 | #define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3 561 | #define sqlite3_bind_pointer sqlite3_api->bind_pointer 562 | #define sqlite3_result_pointer sqlite3_api->result_pointer 563 | #define sqlite3_value_pointer sqlite3_api->value_pointer 564 | /* Version 3.22.0 and later */ 565 | #define sqlite3_vtab_nochange sqlite3_api->vtab_nochange 566 | #define sqlite3_value_nochange sqlite3_api->value_nochange 567 | #define sqlite3_vtab_collation sqlite3_api->vtab_collation 568 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ 569 | 570 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) 571 | /* This case when the file really is being compiled as a loadable 572 | ** extension */ 573 | # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; 574 | # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; 575 | # define SQLITE_EXTENSION_INIT3 \ 576 | extern const sqlite3_api_routines *sqlite3_api; 577 | #else 578 | /* This case when the file is being statically linked into the 579 | ** application */ 580 | # define SQLITE_EXTENSION_INIT1 /*no-op*/ 581 | # define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ 582 | # define SQLITE_EXTENSION_INIT3 /*no-op*/ 583 | #endif 584 | 585 | #endif /* SQLITE3EXT_H */ 586 | --------------------------------------------------------------------------------