├── .gitignore ├── Build └── Windows │ └── Application.ico ├── Config ├── DefaultEditor.ini └── DefaultEngine.ini ├── Content ├── Blueprints │ ├── BP_MyActor.uasset │ └── BP_UnrealChair.uasset ├── DatabaseTestLevel.umap ├── Databases │ └── TestDatabase.db └── Maps │ └── TestLevel.umap ├── Docs ├── CreateTableExample.png └── CreateTableExample2.png ├── LICENSE ├── Plugins └── SQLite3UE4Plugin │ ├── Resources │ └── Icon128.png │ ├── SQLite3UE4Plugin.uplugin │ ├── Source │ └── SQLite3UE4Plugin │ │ ├── Classes │ │ ├── SQLiteBlueprintFunctionLibrary.h │ │ ├── SQLiteBlueprintNodes.h │ │ └── SQLiteDatabase.h │ │ ├── Private │ │ ├── SQLite3UE4Plugin.cpp │ │ ├── SQLite3UE4PluginPrivatePCH.h │ │ ├── SQLiteBlueprintFunctionLibrary.cpp │ │ └── SQLiteDatabase.cpp │ │ └── SQLite3UE4Plugin.Build.cs │ └── ThirdParty │ └── SQLite3 │ ├── Include │ └── sqlite3.h │ └── Lib │ ├── SQLite3.x64.lib │ └── SQLite3.x86.lib ├── README.md ├── SQLite.uproject └── Source ├── SQLite.Target.cs ├── SQLite ├── MyActor.cpp ├── MyActor.h ├── Resources │ └── Windows │ │ └── SQLite.rc ├── SQLite.Build.cs ├── SQLite.cpp ├── SQLite.h ├── SQLiteGameMode.cpp └── SQLiteGameMode.h └── SQLiteEditor.Target.cs /.gitignore: -------------------------------------------------------------------------------- 1 | Binaries/ 2 | Saved/Backup/ 3 | Saved/Autosaves/ 4 | Saved/AutoScreenshot.png 5 | *.suo 6 | *.sdf 7 | Intermediate/ 8 | Saved/Logs/ 9 | Saved/ 10 | *.opensdf 11 | SQLite.sln 12 | temppi/ 13 | Build/ 14 | -------------------------------------------------------------------------------- /Build/Windows/Application.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jusas/SQLite3UE4/5ac19d608278f7643ea2d04a7fa8d9c2debb379d/Build/Windows/Application.ico -------------------------------------------------------------------------------- /Config/DefaultEditor.ini: -------------------------------------------------------------------------------- 1 | [EditoronlyBP] 2 | bAllowClassAndBlueprintPinMatching=true 3 | bReplaceBlueprintWithClass=true 4 | bDontLoadBlueprintOutsideEditor=true 5 | bBlueprintIsNotBlueprintType=true 6 | -------------------------------------------------------------------------------- /Config/DefaultEngine.ini: -------------------------------------------------------------------------------- 1 | [URL] 2 | [/Script/Engine.UserInterfaceSettings] 3 | UIScaleCurve=(EditorCurveData=(Keys=((Time=480,Value=0.444),(Time=720,Value=0.666),(Time=1080,Value=1.0),(Time=8640,Value=8.0))),ExternalCurve=None) 4 | UIScaleCurve=(EditorCurveData=(Keys=((Time=480.000000,Value=0.444000),(Time=720.000000,Value=0.666000),(Time=1080.000000,Value=1.000000),(Time=8640.000000,Value=8.000000))),ExternalCurve=None) 5 | 6 | [/Script/Engine.RendererSettings] 7 | r.MobileHDR=True 8 | r.AllowOcclusionQueries=True 9 | r.MinScreenRadiusForLights=0.030000 10 | r.MinScreenRadiusForDepthPrepass=0.030000 11 | r.PrecomputedVisibilityWarning=False 12 | r.TextureStreaming=True 13 | Compat.UseDXT5NormalMaps=False 14 | r.AllowStaticLighting=True 15 | r.NormalMapsForStaticLighting=False 16 | r.GBuffer=True 17 | r.GenerateMeshDistanceFields=False 18 | r.Shadow.DistanceFieldPenumbraSize=0.050000 19 | r.TessellationAdaptivePixelsPerTriangle=48.000000 20 | r.SeparateTranslucency=True 21 | r.CustomDepth=1 22 | r.DefaultFeature.Bloom=True 23 | r.DefaultFeature.AmbientOcclusion=True 24 | r.DefaultFeature.AmbientOcclusionStaticFraction=True 25 | r.DefaultFeature.AutoExposure=True 26 | r.DefaultFeature.MotionBlur=True 27 | r.DefaultFeature.LensFlare=True 28 | r.DefaultFeature.AntiAliasing=2 29 | r.EarlyZPass=3 30 | r.EarlyZPassMovable=False 31 | r.DBuffer=False 32 | r.ClearSceneMethod=1 33 | r.MSAA.CompositingSampleCount=4 34 | r.WireframeCullThreshold=5.000000 35 | UIScaleRule=ShortestSide 36 | UIScaleCurve=(EditorCurveData=(Keys=),ExternalCurve=None) 37 | 38 | [/Script/HardwareTargeting.HardwareTargetingSettings] 39 | TargetedHardwareClass=Desktop 40 | AppliedTargetedHardwareClass=Desktop 41 | DefaultGraphicsPerformance=Maximum 42 | AppliedDefaultGraphicsPerformance=Maximum 43 | 44 | 45 | -------------------------------------------------------------------------------- /Content/Blueprints/BP_MyActor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jusas/SQLite3UE4/5ac19d608278f7643ea2d04a7fa8d9c2debb379d/Content/Blueprints/BP_MyActor.uasset -------------------------------------------------------------------------------- /Content/Blueprints/BP_UnrealChair.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jusas/SQLite3UE4/5ac19d608278f7643ea2d04a7fa8d9c2debb379d/Content/Blueprints/BP_UnrealChair.uasset -------------------------------------------------------------------------------- /Content/DatabaseTestLevel.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jusas/SQLite3UE4/5ac19d608278f7643ea2d04a7fa8d9c2debb379d/Content/DatabaseTestLevel.umap -------------------------------------------------------------------------------- /Content/Databases/TestDatabase.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jusas/SQLite3UE4/5ac19d608278f7643ea2d04a7fa8d9c2debb379d/Content/Databases/TestDatabase.db -------------------------------------------------------------------------------- /Content/Maps/TestLevel.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jusas/SQLite3UE4/5ac19d608278f7643ea2d04a7fa8d9c2debb379d/Content/Maps/TestLevel.umap -------------------------------------------------------------------------------- /Docs/CreateTableExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jusas/SQLite3UE4/5ac19d608278f7643ea2d04a7fa8d9c2debb379d/Docs/CreateTableExample.png -------------------------------------------------------------------------------- /Docs/CreateTableExample2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jusas/SQLite3UE4/5ac19d608278f7643ea2d04a7fa8d9c2debb379d/Docs/CreateTableExample2.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jussi Saarivirta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Plugins/SQLite3UE4Plugin/Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jusas/SQLite3UE4/5ac19d608278f7643ea2d04a7fa8d9c2debb379d/Plugins/SQLite3UE4Plugin/Resources/Icon128.png -------------------------------------------------------------------------------- /Plugins/SQLite3UE4Plugin/SQLite3UE4Plugin.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion" : 3, 3 | "FriendlyName" : "SQLite3 Plugin", 4 | "Version" : 1, 5 | "VersionName": "1.0", 6 | "EngineVersion" : 1579795, 7 | "Description" : "Exposing SQLite3 functionality to UE4", 8 | "Category" : "Database", 9 | "CreatedBy" : "Jussi Saarivirta", 10 | "CreatedByURL" : "http://jusas.net", 11 | "CanContainContent" : "false", 12 | "Modules" : 13 | [ 14 | { 15 | "Name" : "SQLite3UE4Plugin", 16 | "Type" : "Runtime", 17 | "LoadingPhase" : "PreDefault" 18 | 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /Plugins/SQLite3UE4Plugin/Source/SQLite3UE4Plugin/Classes/SQLiteBlueprintFunctionLibrary.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include "SQLiteDatabase.h" 4 | #include "SQLiteBlueprintNodes.h" 5 | #include "Kismet/BlueprintFunctionLibrary.h" 6 | #include "SQLiteBlueprintFunctionLibrary.generated.h" 7 | 8 | 9 | /** 10 | * Blueprint function library, convenience stuff. 11 | */ 12 | UCLASS() 13 | class USQLiteBlueprintFunctionLibrary : public UBlueprintFunctionLibrary 14 | { 15 | GENERATED_UCLASS_BODY() 16 | 17 | public: 18 | 19 | UFUNCTION(BlueprintPure, meta = (DefaultToSelf = "WorldContextObject", HidePin = "WorldContextObject"), Category = "SQLite") 20 | static UObject* NewObjectFromBlueprint(UObject* WorldContextObject, TSubclassOf UC); 21 | 22 | /** 23 | * Simple casts for blueprint use. 24 | */ 25 | 26 | UFUNCTION(BlueprintCallable, Category = "SQLite|Value Conversion") 27 | static int32 CastToInt(FString SQLiteResultValue); 28 | 29 | //UFUNCTION(BlueprintCallable, Category = "SQLite|Value Conversion") 30 | //static int64 CastToInt64(FString SQLiteResultValue); 31 | 32 | UFUNCTION(BlueprintCallable, Category = "SQLite|Value Conversion") 33 | static bool CastToBoolean(FString SQLiteResultValue); 34 | 35 | UFUNCTION(BlueprintCallable, Category = "SQLite|Value Conversion") 36 | static float CastToFloat(FString SQLiteResultValue); 37 | 38 | //UFUNCTION(BlueprintCallable, Category = "SQLite|Value Conversion") 39 | //static double CastToDouble(FString SQLiteResultValue); 40 | 41 | /** 42 | * Blueprint nodes for building queries. 43 | */ 44 | 45 | /** Start a new query block. */ 46 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Query Start", CompactNodeTitle = "("), Category = "SQLite|Query") 47 | static FSQLiteQueryTermExpectedNode QueryStart(FSQLiteQueryTermExpectedNode LogicOperationOrNone); 48 | 49 | /** 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. */ 50 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Query End", CompactNodeTitle = ")"), Category = "SQLite|Query") 51 | static FSQLiteQueryLogicExpectedNode QueryEnd(const FSQLiteQueryLogicExpectedNode& LastQueryTerm); 52 | 53 | /** A query term. Basically creating a "Key Value" comparison. */ 54 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Query Term"), Category = "SQLite|Query") 55 | static FSQLiteQueryLogicExpectedNode QueryTerm(const FSQLiteQueryTermExpectedNode& LogicOperation, FString Field, FString Operator, FString Value); 56 | 57 | /** AND logic node, combining two terms. */ 58 | UFUNCTION(BlueprintPure, meta = (DisplayName = "AND", CompactNodeTitle = "AND"), Category = "SQLite|Query|Logic") 59 | static FSQLiteQueryTermExpectedNode QueryLogicAnd(const FSQLiteQueryLogicExpectedNode& LHS); 60 | 61 | /** OR logic node, combining two terms. */ 62 | UFUNCTION(BlueprintPure, meta = (DisplayName = "OR", CompactNodeTitle = "OR"), Category = "SQLite|Query|Logic") 63 | static FSQLiteQueryTermExpectedNode QueryLogicOr(const FSQLiteQueryLogicExpectedNode& LHS); 64 | 65 | /** Finalizes the query. This node's output can be linked to a Get Data node's query source pin. */ 66 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Finalize Query"), Category = "SQLite|Query") 67 | static FSQLiteQueryFinalizedQuery QueryFinal(const FSQLiteQueryLogicExpectedNode& QueryEndNode); 68 | 69 | UFUNCTION(BlueprintPure, meta = (DisplayName = "INTEGER (SQLite)"), Category = "SQLite|Query|DataTypes") 70 | static FString SQLiteINTEGER( FString FieldName, const bool PK, const bool AI, 71 | FString &ForPrimaryKey, const bool Unique, FString &FieldNameOutput); 72 | 73 | UFUNCTION(BlueprintPure, meta = (DisplayName = "TEXT (SQLite)"), Category = "SQLite|Query|DataTypes") 74 | static FString SQLiteTEXT(const FString FieldName, const bool PK, 75 | FString &ForPrimaryKey, const bool Unique, FString &FieldNameOutput); 76 | 77 | UFUNCTION(BlueprintPure, meta = (DisplayName = "REAL (SQLite)"), Category = "SQLite|Query|DataTypes") 78 | static FString SQLiteREAL(const FString FieldName, const bool PK, 79 | FString &ForPrimaryKey, const bool Uniqu, FString &FieldNameOutpute); 80 | 81 | UFUNCTION(BlueprintPure, meta = (DisplayName = "NUMERIC (SQLite)"), Category = "SQLite|Query|DataTypes") 82 | static FString SQLiteNUMERIC(const FString FieldName, const bool PK, 83 | FString &ForPrimaryKey, const bool Unique, FString &FieldNameOutput); 84 | 85 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Primary Key (SQLite)"), Category = "SQLite|Query|DataTypes") 86 | static FString SQLitePrimaryKey(const TArray Fields); 87 | 88 | UFUNCTION(BlueprintPure, meta = (DisplayName = "Index (SQLite)"), Category = "SQLite|Query|DataTypes") 89 | static FString SQLiteIndex(const TArray Fields, FString idxName, bool Unique); 90 | 91 | 92 | 93 | }; 94 | -------------------------------------------------------------------------------- /Plugins/SQLite3UE4Plugin/Source/SQLite3UE4Plugin/Classes/SQLiteBlueprintNodes.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include "SQLiteBlueprintNodes.generated.h" 4 | 5 | 6 | USTRUCT(BlueprintType) 7 | struct SQLITE3UE4PLUGIN_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 SQLITE3UE4PLUGIN_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 SQLITE3UE4PLUGIN_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 | -------------------------------------------------------------------------------- /Plugins/SQLite3UE4Plugin/Source/SQLite3UE4Plugin/Classes/SQLiteDatabase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "SQLiteBlueprintNodes.h" 3 | #include "SQLiteDatabase.generated.h" 4 | 5 | USTRUCT(BlueprintType) 6 | struct SQLITE3UE4PLUGIN_API FSQLiteDatabaseReference 7 | { 8 | GENERATED_USTRUCT_BODY() 9 | 10 | /** The database name (not the filename) */ 11 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Database Reference") 12 | FString DatabaseName; 13 | 14 | /** The database tables we want to get data from */ 15 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Database Reference") 16 | TArray Tables; 17 | }; 18 | 19 | USTRUCT(BlueprintType) 20 | struct SQLITE3UE4PLUGIN_API FSQLiteKeyValuePair 21 | { 22 | GENERATED_USTRUCT_BODY() 23 | 24 | /** The database table field name */ 25 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Key Value Pair") 26 | FString Key; 27 | 28 | /** The value of the field */ 29 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Key Value Pair") 30 | FString Value; 31 | }; 32 | 33 | USTRUCT(BlueprintType) 34 | struct SQLITE3UE4PLUGIN_API FSQLiteQueryResultRow 35 | { 36 | GENERATED_USTRUCT_BODY() 37 | 38 | /** A list of field name, field value pairs */ 39 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Query Result") 40 | TArray Fields; 41 | }; 42 | 43 | USTRUCT(BlueprintType) 44 | struct SQLITE3UE4PLUGIN_API FSQLiteQueryResult 45 | { 46 | GENERATED_USTRUCT_BODY() 47 | 48 | /** The resulting rows from the query */ 49 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Query Result") 50 | TArray ResultRows; 51 | 52 | /** Was the query successful or not */ 53 | UPROPERTY(BlueprintReadOnly, Category = "SQLite Query Result") 54 | bool Success; 55 | 56 | /** If the query was unsuccessful a human readable error message will be populated here */ 57 | UPROPERTY(BlueprintReadOnly, Category = "SQLite Query Result") 58 | FString ErrorMessage; 59 | 60 | }; 61 | 62 | 63 | 64 | // A few things for internal use here. 65 | namespace SQLiteResultValueTypes 66 | { 67 | enum SQLiteResultValType 68 | { 69 | Integer, 70 | Float, 71 | Text, 72 | UnsupportedValueType 73 | }; 74 | } 75 | 76 | // Result field, used as an intermediary when collecting results from 77 | // an SQLITE3 query. 78 | struct SQLiteResultField 79 | { 80 | FString StringValue; 81 | double DoubleValue; 82 | int64 IntValue; 83 | 84 | FString Name; 85 | SQLiteResultValueTypes::SQLiteResultValType Type; 86 | 87 | FString ToString() 88 | { 89 | if (Type == SQLiteResultValueTypes::Text) 90 | return StringValue; 91 | else if (Type == SQLiteResultValueTypes::Integer) 92 | return FString::Printf(TEXT("%i"), IntValue); 93 | else if (Type == SQLiteResultValueTypes::Float) 94 | return FString::Printf(TEXT("%f"), DoubleValue); 95 | 96 | return StringValue; 97 | } 98 | }; 99 | 100 | // Represents a single row in the result. 101 | struct SQLiteResultValue 102 | { 103 | TArray Fields; 104 | }; 105 | 106 | // The internal result object. 107 | struct SQLiteQueryResult 108 | { 109 | bool Success; 110 | FString ErrorMessage; 111 | TArray Results; 112 | }; 113 | 114 | 115 | 116 | /** 117 | * SQLite main database class. 118 | */ 119 | UCLASS() 120 | class SQLITE3UE4PLUGIN_API USQLiteDatabase : public UObject 121 | { 122 | GENERATED_UCLASS_BODY() 123 | 124 | public: 125 | 126 | /** Add a database to the list of databases. It will be checked that it's valid (will try to open it) */ 127 | UFUNCTION(BlueprintCallable, Category = "SQLite") 128 | static bool RegisterDatabase(FString Name, FString Filename, bool RelativeToGameContentDirectory); 129 | 130 | /** Checks if the database is registered, ie. that it can be found in Databases. */ 131 | UFUNCTION(BlueprintCallable, Category = "SQLite") 132 | static bool IsDatabaseRegistered(FString DatabaseName); 133 | 134 | /** Get data from the database using a select statement straight into an UObject, ie. populates its properties. */ 135 | UFUNCTION(BlueprintCallable, Category = "SQLite", meta = (DisplayName = "Get Data Into Object (manual query)")) 136 | static bool GetDataIntoObject(const FString& DatabaseName, const FString& Query, UObject* ObjectToPopulate); 137 | 138 | /** Blueprint: Gets data from the database using a select statement straight into an UObject, ie. populates its properties. 139 | * Note: Does not create a new object. ObjectToPopulate is the reference to the object you want to populate. */ 140 | UFUNCTION(BlueprintCallable, Category = "SQLite", meta = (DisplayName = "Get Data Into Object")) 141 | static bool GetDataIntoObjectBP(const FSQLiteDatabaseReference& DataSource, TArray Fields, FSQLiteQueryFinalizedQuery Query, UObject* ObjectToPopulate); 142 | 143 | /** Get data from the database using a select statement and return the rows. */ 144 | UFUNCTION(BlueprintCallable, Category = "SQLite", meta = (DisplayName = "Get Data From Table(s) (manual query)")) 145 | static FSQLiteQueryResult GetData(const FString& DatabaseName, const FString& Query); 146 | 147 | /** Blueprint: Get data from the database. Returns the resulting rows. */ 148 | UFUNCTION(BlueprintCallable, Category = "SQLite", meta = (DisplayName = "Get Data From Table(s)")) 149 | static FSQLiteQueryResult GetDataBP(const FSQLiteDatabaseReference& DataSource, TArray Fields, FSQLiteQueryFinalizedQuery Query, int32 MaxResults = -1, int32 ResultOffset = 0); 150 | 151 | /** Create table in the database. */ 152 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Create Table")) 153 | static bool CreateTable(const FString DatabaseName, const FString TableName, 154 | const TArray Fields, const FString PK, FString &TableNameOutput); 155 | 156 | /** Create indexes for table */ 157 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Create Indexes")) 158 | static bool CreateIndexes(const FString DatabaseName, const FString TableName, const TArray Indexes); 159 | 160 | /** Create index for table */ 161 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Create Index")) 162 | static bool CreateIndex(const FString DatabaseName, const FString TableName, const FString Index); 163 | 164 | /** Drop index*/ 165 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Drop Index")) 166 | static bool DropIndex(const FString DatabaseName, const FString IndexName); 167 | 168 | /** Drop index*/ 169 | UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Drop Table")) 170 | static bool DropTable(const FString DatabaseName, const FString TableName); 171 | 172 | private: 173 | /** Checks database validity (if the file exists and/or if it can be opened). */ 174 | static bool IsValidDatabase(FString DatabaseFilename, bool TestByOpening); 175 | /** Tries to open a database. */ 176 | static bool CanOpenDatabase(FString DatabaseFilename); 177 | /** Collects all properties from an UObject and maps them by the property name. */ 178 | static TMap CollectProperties(UObject* SourceObject); 179 | /** Constructs an SQL query from the blueprint fed data. */ 180 | static FString ConstructQuery(TArray Tables, TArray Fields, FSQLiteQueryFinalizedQuery QueryObject, int32 MaxResults = -1, int32 ResultOffset = 0); 181 | /** Runs a query and returns fetched rows. */ 182 | static SQLiteQueryResult RunQueryAndGetResults(FString DatabaseName, FString Query); 183 | /** Assigns a result row's fields' values to an UObject, ie. assigns them to the properties that have the same name. */ 184 | static void AssignResultsToObjectProperties(const SQLiteResultValue& ResultValue, UObject* ObjectToPopulate); 185 | static void PrepareStatement(const FString* DatabaseName, const FString* Query, sqlite3** Db, int32** SqlReturnCode, 186 | sqlite3_stmt** PreparedStatement); 187 | static bool ExecSql(const FString DatabaseName, const FString Query); 188 | 189 | private: 190 | /** A list of the databases for convenience, easier to refer to them by name rather than a long filename. */ 191 | static TMap Databases; 192 | 193 | }; 194 | -------------------------------------------------------------------------------- /Plugins/SQLite3UE4Plugin/Source/SQLite3UE4Plugin/Private/SQLite3UE4Plugin.cpp: -------------------------------------------------------------------------------- 1 | #include "SQLite3UE4PluginPrivatePCH.h" 2 | 3 | DEFINE_LOG_CATEGORY(LogDatabase) 4 | 5 | IMPLEMENT_MODULE(FDefaultGameModuleImpl, SQLite3UE4Plugin) 6 | -------------------------------------------------------------------------------- /Plugins/SQLite3UE4Plugin/Source/SQLite3UE4Plugin/Private/SQLite3UE4PluginPrivatePCH.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreUObject.h" 4 | #include "sqlite3.h" 5 | #include "SQLiteDatabase.h" 6 | #include "SQLiteBlueprintFunctionLibrary.h" 7 | #include "SQLiteBlueprintNodes.h" 8 | 9 | 10 | DECLARE_LOG_CATEGORY_EXTERN(LogDatabase, All, All); -------------------------------------------------------------------------------- /Plugins/SQLite3UE4Plugin/Source/SQLite3UE4Plugin/Private/SQLiteBlueprintFunctionLibrary.cpp: -------------------------------------------------------------------------------- 1 | #include "SQLite3UE4PluginPrivatePCH.h" 2 | #include "Engine.h" 3 | #include "CString.h" 4 | 5 | static USQLiteDatabase* DatabasePtr = NewObject(); 6 | 7 | //-------------------------------------------------------------------------------------------------------------- 8 | 9 | USQLiteBlueprintFunctionLibrary::USQLiteBlueprintFunctionLibrary(const FObjectInitializer& ObjectInitializer) 10 | : Super(ObjectInitializer) 11 | { 12 | 13 | } 14 | 15 | //-------------------------------------------------------------------------------------------------------------- 16 | 17 | UObject* USQLiteBlueprintFunctionLibrary::NewObjectFromBlueprint(UObject* WorldContextObject, TSubclassOf UC) 18 | { 19 | UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject); 20 | UObject* tempObject = StaticConstructObject(UC); 21 | 22 | return tempObject; 23 | } 24 | 25 | //-------------------------------------------------------------------------------------------------------------- 26 | 27 | int32 USQLiteBlueprintFunctionLibrary::CastToInt(FString SQLiteResultValue) 28 | { 29 | return FCString::Atoi(*SQLiteResultValue); 30 | } 31 | 32 | //-------------------------------------------------------------------------------------------------------------- 33 | 34 | //int64 USQLiteBlueprintFunctionLibrary::CastToInt64(FString SQLiteResultValue) 35 | //{ 36 | // return FCString::Atoi64(*SQLiteResultValue); 37 | //} 38 | 39 | //-------------------------------------------------------------------------------------------------------------- 40 | 41 | bool USQLiteBlueprintFunctionLibrary::CastToBoolean(FString SQLiteResultValue) 42 | { 43 | return FCString::Atoi(*SQLiteResultValue) > 0; 44 | } 45 | 46 | //-------------------------------------------------------------------------------------------------------------- 47 | 48 | float USQLiteBlueprintFunctionLibrary::CastToFloat(FString SQLiteResultValue) 49 | { 50 | return FCString::Atof(*SQLiteResultValue); 51 | } 52 | 53 | //-------------------------------------------------------------------------------------------------------------- 54 | 55 | //double USQLiteBlueprintFunctionLibrary::CastToDouble(FString SQLiteResultValue) 56 | //{ 57 | // return FCString::Atod(*SQLiteResultValue); 58 | //} 59 | 60 | //-------------------------------------------------------------------------------------------------------------- 61 | 62 | FSQLiteQueryTermExpectedNode USQLiteBlueprintFunctionLibrary::QueryStart(FSQLiteQueryTermExpectedNode LogicOperationOrNone) 63 | { 64 | return FSQLiteQueryTermExpectedNode(LogicOperationOrNone.Query, TEXT("(")); 65 | } 66 | 67 | //-------------------------------------------------------------------------------------------------------------- 68 | 69 | FSQLiteQueryLogicExpectedNode USQLiteBlueprintFunctionLibrary::QueryEnd(const FSQLiteQueryLogicExpectedNode& LastQueryTerm) 70 | { 71 | return FSQLiteQueryLogicExpectedNode(LastQueryTerm.Query, TEXT(")")); 72 | } 73 | 74 | //-------------------------------------------------------------------------------------------------------------- 75 | 76 | FSQLiteQueryLogicExpectedNode USQLiteBlueprintFunctionLibrary::QueryTerm(const FSQLiteQueryTermExpectedNode& LogicOperation, FString Field, FString Operator, FString Value) 77 | { 78 | return FSQLiteQueryLogicExpectedNode(LogicOperation.Query, FString::Printf(TEXT("%s %s \"%s\""), *Field, *Operator, *Value)); 79 | } 80 | 81 | //-------------------------------------------------------------------------------------------------------------- 82 | 83 | FSQLiteQueryTermExpectedNode USQLiteBlueprintFunctionLibrary::QueryLogicAnd(const FSQLiteQueryLogicExpectedNode& LHS) 84 | { 85 | return FSQLiteQueryTermExpectedNode(LHS.Query, TEXT(" AND ")); 86 | } 87 | 88 | //-------------------------------------------------------------------------------------------------------------- 89 | 90 | FSQLiteQueryTermExpectedNode USQLiteBlueprintFunctionLibrary::QueryLogicOr(const FSQLiteQueryLogicExpectedNode& LHS) 91 | { 92 | return FSQLiteQueryTermExpectedNode(LHS.Query, TEXT(" OR ")); 93 | } 94 | //-------------------------------------------------------------------------------------------------------------- 95 | 96 | FSQLiteQueryFinalizedQuery USQLiteBlueprintFunctionLibrary::QueryFinal(const FSQLiteQueryLogicExpectedNode& QueryEndNode) 97 | { 98 | return FSQLiteQueryFinalizedQuery(QueryEndNode.Query); 99 | } 100 | 101 | FString USQLiteBlueprintFunctionLibrary::SQLiteINTEGER(const FString FieldName, const bool PK, const bool AI, 102 | FString &ForPrimaryKey, const bool Unique, FString &FieldNameOutput) 103 | { 104 | 105 | FieldNameOutput = FieldName; 106 | 107 | FString outStr = FieldName + " INTEGER "; 108 | if (PK && AI) { 109 | outStr += " PRIMARY KEY AUTOINCREMENT "; 110 | } 111 | else if (AI) { 112 | outStr += " PRIMARY KEY AUTOINCREMENT "; 113 | } 114 | else if (PK) { 115 | ForPrimaryKey = FieldName; 116 | } 117 | 118 | if (Unique) { 119 | outStr += " UNIQUE "; 120 | } 121 | 122 | return outStr; 123 | } 124 | 125 | FString USQLiteBlueprintFunctionLibrary::SQLiteTEXT(const FString FieldName, const bool PK, 126 | FString &ForPrimaryKey, const bool Unique, FString &FieldNameOutput) 127 | { 128 | FieldNameOutput = FieldName; 129 | 130 | if (PK) { 131 | ForPrimaryKey = FieldName; 132 | } 133 | FString outStr = FieldName + " TEXT "; 134 | if (Unique) { 135 | outStr += " UNIQUE "; 136 | } 137 | 138 | return outStr; 139 | } 140 | 141 | FString USQLiteBlueprintFunctionLibrary::SQLiteREAL(const FString FieldName, const bool PK, 142 | FString &ForPrimaryKey, const bool Unique, FString &FieldNameOutput) 143 | { 144 | 145 | FieldNameOutput = FieldName; 146 | 147 | if (PK) { 148 | ForPrimaryKey = FieldName; 149 | } 150 | 151 | FString outStr = FieldName + " REAL "; 152 | if (Unique) { 153 | outStr += " UNIQUE "; 154 | } 155 | 156 | return outStr; 157 | 158 | } 159 | 160 | FString USQLiteBlueprintFunctionLibrary::SQLiteNUMERIC(const FString FieldName, const bool PK, 161 | FString &ForPrimaryKey, const bool Unique, FString &FieldNameOutput) 162 | { 163 | 164 | FieldNameOutput = FieldName; 165 | 166 | if (PK) { 167 | ForPrimaryKey = FieldName; 168 | } 169 | 170 | FString outStr = FieldName + " NUMERIC "; 171 | if (Unique) { 172 | outStr += " UNIQUE "; 173 | } 174 | 175 | return outStr; 176 | 177 | } 178 | 179 | FString USQLiteBlueprintFunctionLibrary::SQLitePrimaryKey(const TArray Fields) 180 | { 181 | 182 | FString i = ""; 183 | for (const FString& field : Fields) { 184 | if (field.Len()>1) { 185 | i += field + ", "; 186 | } 187 | } 188 | 189 | FString o = ""; 190 | 191 | if (i.Len() > 1) { 192 | o = " PRIMARY KEY( "; 193 | o += i; 194 | o = o.Left(o.Len() - 2); 195 | o += ")"; 196 | } 197 | 198 | 199 | return o; 200 | } 201 | 202 | FString USQLiteBlueprintFunctionLibrary::SQLiteIndex(const TArray Fields, FString idxName, bool Unique) { 203 | FString o = "CREATE "; 204 | 205 | if (Unique) { 206 | o += "UNIQUE "; 207 | } 208 | 209 | o += "INDEX " + idxName+" ON $$$TABLE_NAME$$$ ("; 210 | 211 | for (const FString fld : Fields) { 212 | o += fld + ", "; 213 | } 214 | 215 | o = o.Left(o.Len() - 2); 216 | o += ");"; 217 | 218 | return o; 219 | 220 | } -------------------------------------------------------------------------------- /Plugins/SQLite3UE4Plugin/Source/SQLite3UE4Plugin/Private/SQLiteDatabase.cpp: -------------------------------------------------------------------------------- 1 | #include "SQLite3UE4PluginPrivatePCH.h" 2 | #include "../Classes/SQLiteDatabase.h" 3 | 4 | #define LOGSQLITE(verbosity, text) UE_LOG(LogDatabase, verbosity, TEXT("SQLite: %s"), text) 5 | 6 | TMap USQLiteDatabase::Databases; 7 | 8 | //-------------------------------------------------------------------------------------------------------------- 9 | 10 | USQLiteDatabase::USQLiteDatabase(const FObjectInitializer& ObjectInitializer) 11 | : Super(ObjectInitializer) 12 | { 13 | } 14 | 15 | //-------------------------------------------------------------------------------------------------------------- 16 | 17 | bool USQLiteDatabase::RegisterDatabase(FString Name, FString Filename, bool RelativeToGameContentDirectory) 18 | { 19 | FString actualFilename = Filename; 20 | 21 | if (RelativeToGameContentDirectory) 22 | { 23 | actualFilename = FPaths::GameDir() + Filename; 24 | } 25 | 26 | if (IsDatabaseRegistered(Name)) 27 | { 28 | FString message = "Database '" + actualFilename + "' is already registered, skipping."; 29 | LOGSQLITE(Warning, *message); 30 | return true; 31 | } 32 | 33 | if (!IsValidDatabase(actualFilename, true)) 34 | { 35 | FString message = "Unable to add database '" + actualFilename + "', it is not valid (problems opening it)!"; 36 | LOGSQLITE(Error, *message); 37 | return false; 38 | } 39 | 40 | Databases.Add(Name, actualFilename); 41 | 42 | FString successMessage = "Registered SQLite database '" + actualFilename + "' successfully."; 43 | LOGSQLITE(Verbose, *successMessage); 44 | return true; 45 | 46 | } 47 | 48 | //-------------------------------------------------------------------------------------------------------------- 49 | 50 | bool USQLiteDatabase::GetDataIntoObject(const FString& DatabaseName, const FString& Query, UObject* ObjectToPopulate) 51 | { 52 | ////////////////////////////////////////////////////////////////////////// 53 | // Check input validness. 54 | ////////////////////////////////////////////////////////////////////////// 55 | 56 | if (ObjectToPopulate == NULL) 57 | { 58 | LOGSQLITE(Error, TEXT("ObjectToPopulate needs to be set to get any results!")); 59 | return false; 60 | } 61 | 62 | ////////////////////////////////////////////////////////////////////////// 63 | // Validate the database 64 | ////////////////////////////////////////////////////////////////////////// 65 | 66 | if (!IsDatabaseRegistered(DatabaseName) || 67 | !IsValidDatabase(Databases[DatabaseName], false)) 68 | { 69 | LOGSQLITE(Error, *FString::Printf(TEXT("Unable to get data into object, invalid database '%s'"), *DatabaseName)); 70 | return false; 71 | } 72 | 73 | if (!CanOpenDatabase(Databases[DatabaseName])) 74 | { 75 | LOGSQLITE(Error, *FString::Printf(TEXT("Unable to open database '%s'"), *DatabaseName)); 76 | return false; 77 | } 78 | 79 | ////////////////////////////////////////////////////////////////////////// 80 | // Get the results 81 | ////////////////////////////////////////////////////////////////////////// 82 | 83 | SQLiteQueryResult queryResult = RunQueryAndGetResults(DatabaseName, Query); 84 | 85 | if (queryResult.Success && queryResult.Results.Num() > 0) 86 | { 87 | AssignResultsToObjectProperties(queryResult.Results[0], ObjectToPopulate); 88 | return true; 89 | } 90 | else if (!queryResult.Success) 91 | { 92 | LOGSQLITE(Error, *FString::Printf(TEXT("Query resulted in an error: '%s'"), *queryResult.ErrorMessage)); 93 | return false; 94 | } 95 | else if (queryResult.Results.Num() == 0) 96 | { 97 | LOGSQLITE(Error, TEXT("Query returned zero rows, no data to assign to object properties.")); 98 | return false; 99 | } 100 | 101 | return false; 102 | } 103 | 104 | //-------------------------------------------------------------------------------------------------------------- 105 | 106 | bool USQLiteDatabase::GetDataIntoObjectBP(const FSQLiteDatabaseReference& DataSource, TArray Fields, 107 | FSQLiteQueryFinalizedQuery Query, UObject* ObjectToPopulate) 108 | { 109 | ////////////////////////////////////////////////////////////////////////// 110 | // Check input validness. 111 | ////////////////////////////////////////////////////////////////////////// 112 | 113 | if (ObjectToPopulate == NULL) 114 | { 115 | LOGSQLITE(Error, TEXT("ObjectToPopulate needs to be set to get any results!")); 116 | return false; 117 | } 118 | 119 | if (DataSource.Tables.Num() == 0) 120 | { 121 | LOGSQLITE(Error, TEXT("The query needs the table name!")); 122 | return false; 123 | } 124 | 125 | if (Fields.Num() == 0) 126 | { 127 | LOGSQLITE(Error, TEXT("The query needs fields! You may use * to get all fields.")); 128 | return false; 129 | } 130 | 131 | ////////////////////////////////////////////////////////////////////////// 132 | // Validate the database 133 | ////////////////////////////////////////////////////////////////////////// 134 | 135 | if (!IsDatabaseRegistered(DataSource.DatabaseName) || 136 | !IsValidDatabase(Databases[DataSource.DatabaseName], true)) 137 | { 138 | LOGSQLITE(Error, TEXT("Unable to get data to object, database validation failed!")); 139 | return false; 140 | } 141 | 142 | 143 | ////////////////////////////////////////////////////////////////////////// 144 | // Get the results 145 | ////////////////////////////////////////////////////////////////////////// 146 | 147 | FString constructedQuery = ConstructQuery(DataSource.Tables, Fields, Query, 1, 0); 148 | 149 | SQLiteQueryResult queryResult = RunQueryAndGetResults(DataSource.DatabaseName, constructedQuery); 150 | 151 | if (queryResult.Success && queryResult.Results.Num() > 0) 152 | { 153 | AssignResultsToObjectProperties(queryResult.Results[0], ObjectToPopulate); 154 | return true; 155 | } 156 | else if (!queryResult.Success) 157 | { 158 | LOGSQLITE(Error, *FString::Printf(TEXT("Query resulted in an error: '%s'"), *queryResult.ErrorMessage)); 159 | return false; 160 | } 161 | else if (queryResult.Results.Num() == 0) 162 | { 163 | LOGSQLITE(Error, TEXT("Query returned zero rows, no data to assign to object properties.")); 164 | return false; 165 | } 166 | 167 | return false; 168 | 169 | } 170 | 171 | //-------------------------------------------------------------------------------------------------------------- 172 | 173 | TMap USQLiteDatabase::CollectProperties(UObject* SourceObject) 174 | { 175 | 176 | UClass* SourceObjectClass = SourceObject->GetClass(); 177 | TMap Props; 178 | for (TFieldIterator PropIt(SourceObjectClass, EFieldIteratorFlags::SuperClassFlags::IncludeSuper); 179 | PropIt; ++PropIt) 180 | { 181 | Props.Add(*PropIt->GetNameCPP(), *PropIt); 182 | } 183 | 184 | return Props; 185 | } 186 | 187 | //-------------------------------------------------------------------------------------------------------------- 188 | 189 | bool USQLiteDatabase::IsDatabaseRegistered(FString DatabaseName) 190 | { 191 | return Databases.Contains(DatabaseName); 192 | } 193 | 194 | //-------------------------------------------------------------------------------------------------------------- 195 | 196 | bool USQLiteDatabase::CanOpenDatabase(FString DatabaseFilename) 197 | { 198 | sqlite3* db; 199 | if (sqlite3_open(TCHAR_TO_ANSI(*DatabaseFilename), &db) == SQLITE_OK) 200 | { 201 | sqlite3_close(db); 202 | return true; 203 | } 204 | return false; 205 | } 206 | 207 | //-------------------------------------------------------------------------------------------------------------- 208 | 209 | bool USQLiteDatabase::IsValidDatabase(FString DatabaseFilename, bool TestByOpening) 210 | { 211 | if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*DatabaseFilename)) 212 | { 213 | if (TestByOpening) 214 | { 215 | return CanOpenDatabase(DatabaseFilename); 216 | } 217 | else 218 | { 219 | return true; 220 | } 221 | } 222 | 223 | return false; 224 | } 225 | 226 | //-------------------------------------------------------------------------------------------------------------- 227 | 228 | FSQLiteQueryResult USQLiteDatabase::GetData(const FString& DatabaseName, const FString& Query) 229 | { 230 | FSQLiteQueryResult result; 231 | 232 | ////////////////////////////////////////////////////////////////////////// 233 | // Validate the database 234 | ////////////////////////////////////////////////////////////////////////// 235 | 236 | if (!IsDatabaseRegistered(DatabaseName) || 237 | !IsValidDatabase(Databases[DatabaseName], true)) 238 | { 239 | LOGSQLITE(Error, TEXT("Unable to get data to object, database validation failed!")); 240 | result.Success = false; 241 | result.ErrorMessage = TEXT("Database validation failed"); 242 | return result; 243 | } 244 | 245 | ////////////////////////////////////////////////////////////////////////// 246 | // Get the results 247 | ////////////////////////////////////////////////////////////////////////// 248 | 249 | SQLiteQueryResult queryResult = RunQueryAndGetResults(DatabaseName, Query); 250 | result.Success = queryResult.Success; 251 | result.ErrorMessage = queryResult.ErrorMessage; 252 | 253 | for (auto row : queryResult.Results) 254 | { 255 | FSQLiteQueryResultRow outRow; 256 | for (auto field : row.Fields) 257 | { 258 | FSQLiteKeyValuePair outField; 259 | outField.Key = field.Name; 260 | outField.Value = field.ToString(); 261 | 262 | outRow.Fields.Add(outField); 263 | } 264 | result.ResultRows.Add(outRow); 265 | } 266 | 267 | return result; 268 | 269 | } 270 | 271 | //-------------------------------------------------------------------------------------------------------------- 272 | 273 | FSQLiteQueryResult USQLiteDatabase::GetDataBP(const FSQLiteDatabaseReference& DataSource, 274 | TArray Fields, FSQLiteQueryFinalizedQuery Query, int32 MaxResults, int32 ResultOffset) 275 | { 276 | 277 | FSQLiteQueryResult result; 278 | 279 | ////////////////////////////////////////////////////////////////////////// 280 | // Check input validness. 281 | ////////////////////////////////////////////////////////////////////////// 282 | 283 | if (DataSource.Tables.Num() == 0) 284 | { 285 | LOGSQLITE(Error, TEXT("The query needs at least one table name!")); 286 | result.Success = false; 287 | result.ErrorMessage = TEXT("No table given"); 288 | return result; 289 | } 290 | 291 | if (Fields.Num() == 0) 292 | { 293 | LOGSQLITE(Error, TEXT("The query needs fields! You can use * to get all fields.")); 294 | result.Success = false; 295 | result.ErrorMessage = TEXT("No fields given"); 296 | return result; 297 | } 298 | 299 | FString constructedQuery = ConstructQuery(DataSource.Tables, Fields, Query, MaxResults, ResultOffset); 300 | 301 | return GetData(DataSource.DatabaseName, constructedQuery); 302 | 303 | } 304 | 305 | //-------------------------------------------------------------------------------------------------------------- 306 | 307 | FString USQLiteDatabase::ConstructQuery(TArray Tables, TArray Fields, 308 | FSQLiteQueryFinalizedQuery QueryObject, int32 MaxResults, int32 ResultOffset) 309 | { 310 | FString fieldString; 311 | for (int32 i = 0; i < Fields.Num(); i++) 312 | { 313 | fieldString.Append(Fields[i] + (i < Fields.Num() - 1 ? "," : "")); 314 | } 315 | 316 | FString tableList = FString::Join(Tables, TEXT(",")); 317 | TArray allQueryParams; 318 | 319 | allQueryParams.Add(FString::Printf(TEXT("SELECT %s FROM %s"), *fieldString, *tableList)); 320 | 321 | if (QueryObject.Query.Len() > 0) 322 | { 323 | allQueryParams.Add(FString::Printf(TEXT("WHERE %s"), *QueryObject.Query)); 324 | } 325 | 326 | if (MaxResults >= 0) 327 | { 328 | allQueryParams.Add(FString::Printf(TEXT("LIMIT %i"), MaxResults)); 329 | } 330 | 331 | if (ResultOffset > 0) 332 | { 333 | allQueryParams.Add(FString::Printf(TEXT("OFFSET %i"), ResultOffset)); 334 | } 335 | 336 | FString finalQuery = FString::Join(allQueryParams, TEXT(" ")); 337 | return finalQuery; 338 | 339 | } 340 | 341 | //-------------------------------------------------------------------------------------------------------------- 342 | 343 | void USQLiteDatabase::PrepareStatement(const FString* DatabaseName, const FString* Query, sqlite3** Db, int32** SqlReturnCode, 344 | sqlite3_stmt** PreparedStatement) { 345 | 346 | ANSICHAR* dbNameAsUtf8 = TCHAR_TO_UTF8(*Databases[**DatabaseName]); 347 | 348 | int32 i = sqlite3_open(dbNameAsUtf8, Db); 349 | 350 | **SqlReturnCode = i; 351 | 352 | ANSICHAR* queryAsUtf8 = TCHAR_TO_UTF8(**Query); 353 | 354 | **SqlReturnCode = sqlite3_prepare_v2(*Db, queryAsUtf8, -1, PreparedStatement, NULL); 355 | } 356 | 357 | //-------------------------------------------------------------------------------------------------------------- 358 | 359 | bool USQLiteDatabase::CreateTable(const FString DatabaseName, const FString TableName, 360 | const TArray Fields, const FString PK, FString &TableNameOutput) 361 | { 362 | 363 | TableNameOutput = TableName; 364 | 365 | FString query = ""; 366 | query += "CREATE TABLE IF NOT EXISTS "; 367 | query += TableName; 368 | query += "("; 369 | 370 | bool singlePrimaryKeyExists = false; 371 | 372 | for (const FString& field : Fields) 373 | { 374 | if (field.Len() > 2) { 375 | 376 | if (field.Contains("PRIMARY KEY")) { 377 | singlePrimaryKeyExists = true; 378 | } 379 | 380 | query += field + ", "; 381 | 382 | } 383 | 384 | } 385 | 386 | if (singlePrimaryKeyExists) { 387 | query = query.Left(query.Len() - 2); 388 | 389 | query += ");"; 390 | } 391 | else { 392 | if (PK.Len() > 2) { 393 | query += " " + PK + " "; 394 | } 395 | else { 396 | query = query.Left(query.Len() - 2); 397 | } 398 | 399 | query += ");"; 400 | } 401 | 402 | return ExecSql(DatabaseName, query); 403 | 404 | } 405 | 406 | //-------------------------------------------------------------------------------------------------------------- 407 | 408 | bool USQLiteDatabase::DropTable(const FString DatabaseName, const FString TableName) 409 | { 410 | bool idxCrSts = true; 411 | 412 | 413 | FString query = "DROP TABLE " + TableName; 414 | 415 | //LOGSQLITE(Warning, *query); 416 | 417 | idxCrSts = ExecSql(DatabaseName, query); 418 | 419 | return idxCrSts; 420 | 421 | } 422 | 423 | //-------------------------------------------------------------------------------------------------------------- 424 | 425 | bool USQLiteDatabase::ExecSql(const FString DatabaseName, const FString Query) { 426 | //LOGSQLITE(Warning, *query); 427 | 428 | bool execStatus = false; 429 | 430 | char *zErrMsg = 0; 431 | sqlite3 *db; 432 | 433 | ANSICHAR* dbNameAsUtf8 = TCHAR_TO_UTF8(*Databases[DatabaseName]); 434 | int32 i = sqlite3_open(dbNameAsUtf8, &db); 435 | 436 | if (i == SQLITE_OK){ 437 | 438 | int32 k = sqlite3_exec(db, TCHAR_TO_UTF8(*Query), NULL, 0, &zErrMsg); 439 | 440 | if (i == SQLITE_OK){ 441 | execStatus = true; 442 | } 443 | else { 444 | LOGSQLITE(Warning, TEXT("CreateTable - Query Exec Failed..")); 445 | } 446 | 447 | 448 | } 449 | else { 450 | LOGSQLITE(Warning, TEXT("CreateTable - DB Open failed..")); 451 | } 452 | 453 | sqlite3_close(db); 454 | 455 | return execStatus; 456 | } 457 | 458 | //-------------------------------------------------------------------------------------------------------------- 459 | 460 | bool USQLiteDatabase::CreateIndexes(const FString DatabaseName, const FString TableName, const TArray Indexes) 461 | { 462 | bool idxCrSts = true; 463 | 464 | for (const FString& idx : Indexes) 465 | { 466 | if (idx.Len() > 2) { 467 | FString query = idx.Replace(TEXT("$$$TABLE_NAME$$$"), *TableName); 468 | 469 | //LOGSQLITE(Warning, *query); 470 | 471 | idxCrSts = ExecSql(DatabaseName, query); 472 | if (!idxCrSts) { 473 | //LOGSQLITE(Warning, TEXT("ExecSql break")); 474 | break; 475 | } 476 | } 477 | 478 | } 479 | 480 | return idxCrSts; 481 | 482 | } 483 | 484 | //-------------------------------------------------------------------------------------------------------------- 485 | 486 | bool USQLiteDatabase::CreateIndex(const FString DatabaseName, const FString TableName, const FString Index) 487 | { 488 | bool idxCrSts = true; 489 | 490 | 491 | FString query = Index.Replace(TEXT("$$$TABLE_NAME$$$"), *TableName); 492 | 493 | //LOGSQLITE(Warning, *query); 494 | 495 | idxCrSts = ExecSql(DatabaseName, query); 496 | 497 | return idxCrSts; 498 | 499 | } 500 | 501 | //-------------------------------------------------------------------------------------------------------------- 502 | 503 | bool USQLiteDatabase::DropIndex(const FString DatabaseName, const FString IndexName) 504 | { 505 | bool idxCrSts = true; 506 | 507 | 508 | FString query = "DROP INDEX " + IndexName; 509 | 510 | //LOGSQLITE(Warning, *query); 511 | 512 | idxCrSts = ExecSql(DatabaseName, query); 513 | 514 | return idxCrSts; 515 | 516 | } 517 | 518 | //-------------------------------------------------------------------------------------------------------------- 519 | 520 | SQLiteQueryResult USQLiteDatabase::RunQueryAndGetResults(FString DatabaseName, FString Query) 521 | { 522 | SQLiteQueryResult result; 523 | 524 | sqlite3* db; 525 | int32 sqlReturnCode = 0; 526 | int32* sqlReturnCode1 = &sqlReturnCode; 527 | sqlite3_stmt* preparedStatement; 528 | 529 | PrepareStatement(&DatabaseName, &Query, &db, &sqlReturnCode1, &preparedStatement); 530 | sqlReturnCode = *sqlReturnCode1; 531 | 532 | if (sqlReturnCode != SQLITE_OK) 533 | { 534 | const char* errorMessage = sqlite3_errmsg(db); 535 | FString error = "SQL error: " + FString(UTF8_TO_TCHAR(errorMessage)); 536 | LOGSQLITE(Error, *error); 537 | LOGSQLITE(Error, *FString::Printf(TEXT("The attempted query was: %s"), *Query)); 538 | result.ErrorMessage = error; 539 | result.Success = false; 540 | sqlite3_finalize(preparedStatement); 541 | sqlite3_close(db); 542 | return result; 543 | } 544 | 545 | ////////////////////////////////////////////////////////////////////////// 546 | // Get and assign the data 547 | ////////////////////////////////////////////////////////////////////////// 548 | 549 | TArray resultRows; 550 | 551 | for (sqlReturnCode = sqlite3_step(preparedStatement); 552 | sqlReturnCode != SQLITE_DONE && sqlReturnCode == SQLITE_ROW; 553 | sqlReturnCode = sqlite3_step(preparedStatement)) 554 | { 555 | SQLiteResultValue row; 556 | 557 | LOGSQLITE(Verbose, TEXT("Query returned a result row.")); 558 | int32 resultColumnCount = sqlite3_column_count(preparedStatement); 559 | for (int32 c = 0; c < resultColumnCount; c++) 560 | { 561 | int32 columnType = sqlite3_column_type(preparedStatement, c); 562 | const char* columnName = sqlite3_column_name(preparedStatement, c); 563 | FString columnNameStr = UTF8_TO_TCHAR(columnName); 564 | SQLiteResultField val; 565 | val.Name = columnNameStr; 566 | switch (columnType) 567 | { 568 | case SQLITE_INTEGER: 569 | val.Type = SQLiteResultValueTypes::Integer; 570 | val.IntValue = sqlite3_column_int64(preparedStatement, c); 571 | break; 572 | case SQLITE_TEXT: 573 | val.Type = SQLiteResultValueTypes::Text; 574 | val.StringValue = UTF8_TO_TCHAR(sqlite3_column_text(preparedStatement, c)); 575 | break; 576 | case SQLITE_FLOAT: 577 | val.Type = SQLiteResultValueTypes::Float; 578 | val.DoubleValue = sqlite3_column_double(preparedStatement, c); 579 | break; 580 | case SQLITE_NULL: 581 | default: 582 | val.Type = SQLiteResultValueTypes::UnsupportedValueType; 583 | } 584 | 585 | if (val.Type != SQLiteResultValueTypes::UnsupportedValueType) 586 | { 587 | row.Fields.Add(val); 588 | } 589 | } 590 | 591 | resultRows.Add(row); 592 | } 593 | 594 | ////////////////////////////////////////////////////////////////////////// 595 | // Release the statement and close the connection 596 | ////////////////////////////////////////////////////////////////////////// 597 | 598 | sqlite3_finalize(preparedStatement); 599 | sqlite3_close(db); 600 | 601 | result.Results = resultRows; 602 | result.Success = true; 603 | return result; 604 | 605 | } 606 | 607 | //-------------------------------------------------------------------------------------------------------------- 608 | 609 | void USQLiteDatabase::AssignResultsToObjectProperties(const SQLiteResultValue& ResultValue, UObject* ObjectToPopulate) 610 | { 611 | auto propertyMap = CollectProperties(ObjectToPopulate); 612 | for (SQLiteResultField field : ResultValue.Fields) 613 | { 614 | if (propertyMap.Contains(field.Name)) 615 | { 616 | UProperty* targetProperty = propertyMap[field.Name]; 617 | 618 | if (field.Type == SQLiteResultValueTypes::Integer) 619 | { 620 | UInt64Property* int64prop = NULL; 621 | UIntProperty* int32prop = NULL; 622 | UInt16Property* int16prop = NULL; 623 | UInt8Property* int8prop = NULL; 624 | UBoolProperty* boolProp = NULL; 625 | 626 | if ((int64prop = Cast(targetProperty)) != NULL) 627 | { 628 | int64prop->SetPropertyValue_InContainer(ObjectToPopulate, field.IntValue); 629 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%d'"), *field.Name, field.IntValue)); 630 | } 631 | else if ((int32prop = Cast(targetProperty)) != NULL) 632 | { 633 | int32prop->SetPropertyValue_InContainer(ObjectToPopulate, (int32)field.IntValue); 634 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%d'"), *field.Name, field.IntValue)); 635 | } 636 | else if ((int16prop = Cast(targetProperty)) != NULL) 637 | { 638 | int16prop->SetPropertyValue_InContainer(ObjectToPopulate, (int16)field.IntValue); 639 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%d'"), *field.Name, field.IntValue)); 640 | } 641 | else if ((int8prop = Cast(targetProperty)) != NULL) 642 | { 643 | int8prop->SetPropertyValue_InContainer(ObjectToPopulate, (int8)field.IntValue); 644 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%d'"), *field.Name, field.IntValue)); 645 | } 646 | else if ((boolProp = Cast(targetProperty)) != NULL) 647 | { 648 | boolProp->SetPropertyValue_InContainer(ObjectToPopulate, field.IntValue > 0); 649 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%d'"), *field.Name, field.IntValue)); 650 | } 651 | } 652 | 653 | else if (field.Type == SQLiteResultValueTypes::Float) 654 | { 655 | UDoubleProperty* doubleProp = NULL; 656 | UFloatProperty* floatProp = NULL; 657 | if ((doubleProp = Cast(targetProperty)) != NULL) 658 | { 659 | doubleProp->SetPropertyValue_InContainer(ObjectToPopulate, field.DoubleValue); 660 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%f'"), *field.Name, field.DoubleValue)); 661 | } 662 | else if ((floatProp = Cast(targetProperty)) != NULL) 663 | { 664 | floatProp->SetPropertyValue_InContainer(ObjectToPopulate, (float)field.DoubleValue); 665 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%f'"), *field.Name, field.DoubleValue)); 666 | } 667 | } 668 | 669 | else if (field.Type == SQLiteResultValueTypes::Text) 670 | { 671 | UStrProperty* strProp = NULL; 672 | if ((strProp = Cast(targetProperty)) != NULL) 673 | { 674 | strProp->SetPropertyValue_InContainer(ObjectToPopulate, field.StringValue); 675 | LOGSQLITE(Verbose, *FString::Printf(TEXT("Property '%s' was set to '%s'"), *field.Name, *field.StringValue.Mid(0, 64))); 676 | } 677 | } 678 | 679 | } 680 | } 681 | } 682 | 683 | //-------------------------------------------------------------------------------------------------------------- 684 | -------------------------------------------------------------------------------- /Plugins/SQLite3UE4Plugin/Source/SQLite3UE4Plugin/SQLite3UE4Plugin.Build.cs: -------------------------------------------------------------------------------- 1 | using UnrealBuildTool; 2 | using System.IO; 3 | 4 | public class SQLite3UE4Plugin : ModuleRules 5 | { 6 | public SQLite3UE4Plugin(TargetInfo Target) 7 | { 8 | string ModulePath = Path.GetDirectoryName( RulesCompiler.GetModuleFilename( this.GetType().Name ) ); 9 | string PlatformString = (Target.Platform == UnrealTargetPlatform.Win64) ? "x64" : "x86"; 10 | string ThirdPartyPath = Path.GetFullPath( Path.Combine( ModulePath, "../../ThirdParty/" ) ); 11 | string LibrariesPath = Path.Combine(ThirdPartyPath, "SQLite3", "Lib"); 12 | string IncludesPath = Path.Combine(ThirdPartyPath, "SQLite3", "Include"); 13 | string LibraryName = Path.Combine(LibrariesPath, "SQLite3." + PlatformString + ".lib"); 14 | 15 | PrivateIncludePaths.AddRange(new string[] { "SQLite3UE4Plugin/Private" }); 16 | PublicIncludePaths.AddRange(new string[] { "SQLite3UE4Plugin/Public" }); 17 | PublicAdditionalLibraries.Add(LibraryName); 18 | PublicIncludePaths.Add(IncludesPath); 19 | 20 | PublicDependencyModuleNames.AddRange(new string[] { "Engine", "Core", "CoreUObject" }); 21 | } 22 | } -------------------------------------------------------------------------------- /Plugins/SQLite3UE4Plugin/ThirdParty/SQLite3/Lib/SQLite3.x64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jusas/SQLite3UE4/5ac19d608278f7643ea2d04a7fa8d9c2debb379d/Plugins/SQLite3UE4Plugin/ThirdParty/SQLite3/Lib/SQLite3.x64.lib -------------------------------------------------------------------------------- /Plugins/SQLite3UE4Plugin/ThirdParty/SQLite3/Lib/SQLite3.x86.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jusas/SQLite3UE4/5ac19d608278f7643ea2d04a7fa8d9c2debb379d/Plugins/SQLite3UE4Plugin/ThirdParty/SQLite3/Lib/SQLite3.x86.lib -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Note: DEPRECATED! # 2 | This repository is no longer maintained but fear not, the work has been continued in other forks and repositories. 3 | 4 | You'll want to check these out: 5 | 6 | | Repo | Description | 7 | | :------------- |:-------------| 8 | | https://github.com/KhArtNJava/SQLite3UE4 | KhArtNJava fork | 9 | | https://github.com/cindustries/unreal-sqlite3 | CIndustries repo, combining this repo with KhArtNJava fork and providing full multiplatform support | 10 | 11 | Also, don't miss this resource: https://github.com/cindustries/unreal-directory 12 | 13 | # SQLite3UE4 14 | SQLite3 Database Plugin for Unreal Engine 4 15 | 16 | 17 | ## What is it? 18 | A plugin for UE4 that provides code and blueprint functionality that enables you to use SQLite3 databases in your projects. 19 | 20 | Currently only supports reading data from databases. Updates and inserts will come next. 21 | By using reflection it is possible to get data directly into member properties of C++ classes and blueprints, provided that the database field names match the UObject property names and that they have compatible data types. By using a normal query you can get data from tables into an array of string key -> value pairs. 22 | Both C++ and blueprints are supported. For convenience, queries can be constructed from nodes in blueprints (easier to plug in variables into queries) or entered directly as a string. From C++ you're expected to use the string version of the methods. 23 | 24 | 25 | ## Currently supported platforms 26 | 27 | The current version was built with Unreal Engine version 4.8. 28 | 29 | Win32 and Win64 platforms are currently supported and tested. Mac and Linux should work as well but requires compiling the sqlite3 binaries and editing the build script so that the compiler can find the correct libraries to link to. Contributions on this would be much appreciated. 30 | 31 | 32 | ## How to install 33 | 34 | For the convenience of testing and providing a sample of its usage, the plugin is inside a sample project in the repository (/Plugins/SQLite3UE4). Download the repository and just copy that folder into your own project's Plugins folder and you should be set. 35 | 36 | 37 | ## How does it work? 38 | 39 | The plugin is pretty straightforward. 40 | The steps to get your data are: 41 | 42 | * Register a database to the plugin 43 | * Construct a query from blueprint nodes or by supplying the SQL query string 44 | * Plug in the query to a Get Data method and you're done 45 | 46 | It's really simple. 47 | 48 | 49 | ## Sample usage 50 | 51 | ### Blueprints 52 | 53 | Here's a screenshot of a query setup with blueprints. 54 | 55 | ![alt text](http://i.imgur.com/5BtGuzH.png "Blueprint query sample") 56 | 57 | With the database table looking like this: 58 | 59 | ![alt text](http://i.imgur.com/TLteHL2.png "Blueprint query sample") 60 | 61 | Create table, Create index, Drop index, Drop table sample: 62 | ![alt text](https://github.com/KhArtNJava/SQLite3UE4/blob/master/Docs/CreateTableExample2.png?raw=true "Blueprint Create table, Create index, Drop index, Drop table sample") 63 | 64 | 65 | ### C++ 66 | 67 | And here's a simple sample in C++: 68 | 69 | Header: 70 | ```c++ 71 | UCLASS() 72 | class SQLITE_API AMyActor : public AActor 73 | { 74 | GENERATED_BODY() 75 | 76 | 77 | public: 78 | 79 | UFUNCTION(BlueprintCallable, Category = "My Actor") 80 | bool GetMyStats(); 81 | 82 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") 83 | FString Name; 84 | 85 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") 86 | int32 Age; 87 | 88 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") 89 | FString Gender; 90 | 91 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") 92 | float Height; 93 | 94 | 95 | }; 96 | 97 | ``` 98 | 99 | CPP: 100 | 101 | ```c++ 102 | #include "MyActor.h" 103 | #include "SQLiteDatabase.h" 104 | 105 | bool AMyActor::GetMyStats() 106 | { 107 | FString dbName = TEXT("TestDatabase"); 108 | FString actorName = TEXT("Bruce Willis"); 109 | 110 | if (!USQLiteDatabase::IsDatabaseRegistered(dbName)) 111 | { 112 | USQLiteDatabase::RegisterDatabase(dbName, "Databases/TestDatabase.db", true); 113 | } 114 | 115 | bool didPopulate = USQLiteDatabase::GetDataIntoObject(dbName, FString::Printf(TEXT("SELECT Name, Age, Gender, Height FROM Actors WHERE Name = \"%s\""), *actorName), this); 116 | 117 | return didPopulate; 118 | } 119 | ``` 120 | 121 | -------------------------------------------------------------------------------- /SQLite.uproject: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "EngineAssociation": "4.8", 4 | "Category": "", 5 | "Description": "", 6 | "Modules": [ 7 | { 8 | "Name": "SQLite", 9 | "Type": "Runtime", 10 | "LoadingPhase": "Default" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /Source/SQLite.Target.cs: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class SQLiteTarget : TargetRules 7 | { 8 | public SQLiteTarget(TargetInfo Target) 9 | { 10 | Type = TargetType.Game; 11 | } 12 | 13 | // 14 | // TargetRules interface. 15 | // 16 | 17 | public override void SetupBinaries( 18 | TargetInfo Target, 19 | ref List OutBuildBinaryConfigurations, 20 | ref List OutExtraModuleNames 21 | ) 22 | { 23 | OutExtraModuleNames.AddRange( new string[] { "SQLite" } ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Source/SQLite/MyActor.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #include "SQLite.h" 4 | #include "MyActor.h" 5 | #include "SQLiteDatabase.h" 6 | 7 | 8 | 9 | 10 | bool AMyActor::GetMyStats() 11 | { 12 | FString dbName = TEXT("TestDatabase"); 13 | if (!USQLiteDatabase::IsDatabaseRegistered(dbName)) 14 | { 15 | USQLiteDatabase::RegisterDatabase(dbName, "Databases/TestDatabase.db", true); 16 | } 17 | 18 | bool didPopulate = USQLiteDatabase::GetDataIntoObject(dbName, FString::Printf(TEXT("SELECT * FROM Actors WHERE Name = \"%s\""), *Name), this); 19 | 20 | return didPopulate; 21 | } 22 | -------------------------------------------------------------------------------- /Source/SQLite/MyActor.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "GameFramework/Actor.h" 6 | #include "MyActor.generated.h" 7 | 8 | /** 9 | * 10 | */ 11 | UCLASS() 12 | class SQLITE_API AMyActor : public AActor 13 | { 14 | GENERATED_BODY() 15 | 16 | 17 | public: 18 | 19 | UFUNCTION(BlueprintCallable, Category = "My Actor") 20 | bool GetMyStats(); 21 | 22 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") 23 | FString Name; 24 | 25 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") 26 | int32 Age; 27 | 28 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") 29 | FString Gender; 30 | 31 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") 32 | float Height; 33 | 34 | 35 | }; 36 | -------------------------------------------------------------------------------- /Source/SQLite/Resources/Windows/SQLite.rc: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2014 Epic Games, Inc. All Rights Reserved. 2 | 3 | #define APSTUDIO_READONLY_SYMBOLS 4 | ///////////////////////////////////////////////////////////////////////////// 5 | // 6 | // Generated from the TEXTINCLUDE 2 resource. 7 | // 8 | #include 9 | #include "Runtime/Launch/Resources/Version.h" 10 | 11 | ///////////////////////////////////////////////////////////////////////////// 12 | #undef APSTUDIO_READONLY_SYMBOLS 13 | 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | ///////////////////////////////////////////////////////////////////////////// 25 | // 26 | // Version 27 | // 28 | 29 | VS_VERSION_INFO VERSIONINFO 30 | FILEVERSION ENGINE_MAJOR_VERSION,ENGINE_MINOR_VERSION,ENGINE_PATCH_VERSION,0 31 | PRODUCTVERSION ENGINE_MAJOR_VERSION,ENGINE_MINOR_VERSION,ENGINE_PATCH_VERSION,0 32 | FILEFLAGSMASK 0x17L 33 | #ifdef _DEBUG 34 | FILEFLAGS 0x1L 35 | #else 36 | FILEFLAGS 0x0L 37 | #endif 38 | FILEOS 0x4L 39 | FILETYPE 0x2L 40 | FILESUBTYPE 0x0L 41 | BEGIN 42 | BLOCK "StringFileInfo" 43 | BEGIN 44 | BLOCK "040904b0" 45 | BEGIN 46 | VALUE "CompanyName", EPIC_COMPANY_NAME 47 | VALUE "LegalCopyright", EPIC_COPYRIGHT_STRING 48 | VALUE "ProductName", EPIC_PRODUCT_NAME 49 | VALUE "ProductVersion", ENGINE_VERSION_STRING 50 | VALUE "FileDescription", "SQLite" 51 | VALUE "InternalName", "SQLite" 52 | VALUE "OriginalFilename", "SQLite.exe" 53 | END 54 | END 55 | BLOCK "VarFileInfo" 56 | BEGIN 57 | VALUE "Translation", 0x409, 1200 58 | END 59 | END 60 | 61 | ///////////////////////////////////////////////////////////////////////////// 62 | // 63 | // Icon 64 | // 65 | 66 | // Icon with lowest ID value placed first to ensure application icon 67 | // remains consistent on all systems. 68 | IDICON_UE4Game ICON "../../../../Build/Windows/Application.ico" 69 | 70 | #endif // English (U.S.) resources 71 | ///////////////////////////////////////////////////////////////////////////// 72 | 73 | 74 | 75 | //#ifndef APSTUDIO_INVOKED 76 | ///////////////////////////////////////////////////////////////////////////// 77 | // 78 | // Generated from the TEXTINCLUDE 3 resource. 79 | // 80 | 81 | 82 | ///////////////////////////////////////////////////////////////////////////// 83 | //#endif // not APSTUDIO_INVOKED 84 | -------------------------------------------------------------------------------- /Source/SQLite/SQLite.Build.cs: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class SQLite : ModuleRules 6 | { 7 | public SQLite(TargetInfo Target) 8 | { 9 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); 10 | PublicDependencyModuleNames.AddRange(new string[] { "SQLite3UE4Plugin" }); 11 | 12 | PrivateDependencyModuleNames.AddRange(new string[] { }); 13 | PublicIncludePaths.AddRange(new string[] { "SQLite3UE4Plugin/Classes" }); 14 | 15 | // Uncomment if you are using Slate UI 16 | // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); 17 | 18 | // Uncomment if you are using online features 19 | // PrivateDependencyModuleNames.Add("OnlineSubsystem"); 20 | // if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64)) 21 | // { 22 | // if (UEBuildConfiguration.bCompileSteamOSS == true) 23 | // { 24 | // DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam"); 25 | // } 26 | // } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/SQLite/SQLite.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #include "SQLite.h" 4 | 5 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, SQLite, "SQLite" ); 6 | -------------------------------------------------------------------------------- /Source/SQLite/SQLite.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "Engine.h" 6 | 7 | -------------------------------------------------------------------------------- /Source/SQLite/SQLiteGameMode.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #include "SQLite.h" 4 | #include "SQLiteGameMode.h" 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Source/SQLite/SQLiteGameMode.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "GameFramework/GameMode.h" 6 | #include "SQLiteGameMode.generated.h" 7 | 8 | /** 9 | * 10 | */ 11 | UCLASS() 12 | class SQLITE_API ASQLiteGameMode : public AGameMode 13 | { 14 | GENERATED_BODY() 15 | 16 | 17 | 18 | 19 | }; 20 | -------------------------------------------------------------------------------- /Source/SQLiteEditor.Target.cs: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class SQLiteEditorTarget : TargetRules 7 | { 8 | public SQLiteEditorTarget(TargetInfo Target) 9 | { 10 | Type = TargetType.Editor; 11 | } 12 | 13 | // 14 | // TargetRules interface. 15 | // 16 | 17 | public override void SetupBinaries( 18 | TargetInfo Target, 19 | ref List OutBuildBinaryConfigurations, 20 | ref List OutExtraModuleNames 21 | ) 22 | { 23 | OutExtraModuleNames.AddRange( new string[] { "SQLite" } ); 24 | } 25 | } 26 | --------------------------------------------------------------------------------