Download

Squareys Unreal-SQLite3 & UE4 4.21.2 Compile Errors

Hello, I am attempting to integrate SQLite into my project but I am running into so many problems.

First and foremost I am using this forked version of the old CISqlite3 plugin: GitHub - Squareys/unreal-sqlite3: Unreal SQLite3 Plugin with SQLite3 source included to avoid ThirdParty integration or precompile and I am compiling the code from the editor after creating a C++ Class from within the editor to generate the code files.

According to Square’s readme in the repo, for version 4.20.x, all we needed to do was drop in the plugin into our project folder and then enable it in the editor and allow it to build.

I don’t know what was changed between 20 and 21 but the process outline on the repo isn’t working for me. Here is what I did:

Download the repo, extract it the Plugins folder in the project. For sake of ease of installation for the first go around I am using CISQLite3 as the folder name. Open the editor, go to the plugins list and then enable the plugin. Restart the editor.

Everything up till this point is fine. Everything goes to **** after I create my DatabaseHandler class and include the sqlite plugin to it. First though, I don’t put anything in it, I just create it in the editor and then try to recompile in VS2017. That goes through fine. Once I try to include the plugin h file it all goes crazy wrong.

It will probably be easier to just post all of the errors I am getting and the related files. You can find the code for those files at the repo above.

The first two things I see are warnings (when I recompile at any time, not just after including the plugin header):

Now, if I just include …/…/…/Plugins/CISQLite3/Source/Public/SQLiteDatabase.h to my DatabaseHandler.cpp file and try to compile I get a generated file not found error:

When I try fully defining the file path in the include like so:


#include "F:/UE4/Projects/MiningTechDemo4/Plugins/CISQLite3/Intermediate/Build/Win64/UE4Editor/Inc/CISQLite3/SQLiteBlueprintNodes.generated.h"

Then I get this lovely array of compiler barf for the SQLiteBlueprintNodes.h file:

So I figured that this junk was due to other headers which also needed to have absolute links to the plugin’s intermediate folder. Each time I modify the header for one of the files that shows up, like SQLiteDatabaseStructs above, it barfs out the same errors for that file too. That is until I get to SQLiteDatabase.h. When I do the absolute path to its generated file I get a single error message:

For brevity, I will copy and paste the plugin code for the files mentioned above below; the full plugin code can be found at the GitHub repo linked to at the start of the post.

SQLiteBlueprintNodes.h:



#pragma once
#include "F:/UE4/Projects/MiningTechDemo4/Plugins/CISQLite3/Intermediate/Build/Win64/UE4Editor/Inc/CISQLite3/SQLiteBlueprintNodes.generated.h"


USTRUCT(BlueprintType)
struct CISQLITE3_API FSQLiteQueryLogicExpectedNode
{
    GENERATED_USTRUCT_BODY()

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Database Query")
    FString Query;

    FSQLiteQueryLogicExpectedNode(){}
    FSQLiteQueryLogicExpectedNode(FString LHSQuery, FString Append) : Query(LHSQuery)
    {
        Query += Append;
    }
};

USTRUCT(BlueprintType)
struct CISQLITE3_API FSQLiteQueryTermExpectedNode
{
    GENERATED_USTRUCT_BODY()

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Database Query")
    FString Query;

    FSQLiteQueryTermExpectedNode(){}
    FSQLiteQueryTermExpectedNode(FString LHSQuery, FString Append) : Query(LHSQuery)
    {
        Query += Append;
    }
};

USTRUCT(BlueprintType)
struct CISQLITE3_API FSQLiteQueryFinalizedQuery
{
    GENERATED_USTRUCT_BODY()

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Database Query")
    FString Query;

    FSQLiteQueryFinalizedQuery(){}
    FSQLiteQueryFinalizedQuery(FString Query) : Query(Query){}
};


SQLiteDatabaseStructs.h:


#pragma once
#include "F:/UE4/Projects/MiningTechDemo4/Plugins/CISQLite3/Intermediate/Build/Win64/UE4Editor/Inc/CISQLite3/SQLiteDatabaseStructs.generated.h"

USTRUCT(BlueprintType)
struct CISQLITE3_API FSQLiteIndex
{
    GENERATED_USTRUCT_BODY()

        /** String with piece if SQL script*/
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Index")
        FString ResultStr = "";

    /** Index name*/
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Index")
        FString IndexName = "";

};

USTRUCT(BlueprintType)
struct CISQLITE3_API FSQLitePrimaryKey
{
    GENERATED_USTRUCT_BODY()

        /** String with piece if SQL script*/
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Primary Key")
        FString ResultStr = "";
};

USTRUCT(BlueprintType)
struct CISQLITE3_API FSQLiteTableField
{
    GENERATED_USTRUCT_BODY()

        /** String with piece if SQL script*/
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table Field")
        FString ResultStr = "";

    /** Field name*/
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table Field")
        FString FieldName = "";

    /** Field type*/
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table Field")
        FString FieldType = "";

    /** Field value*/
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table Field")
        FString FieldValue = "";

};

USTRUCT(BlueprintType)
struct CISQLITE3_API FSQLiteTableRowSimulator
{
    GENERATED_USTRUCT_BODY()

        /** Index name*/
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Index")
        TArray<FSQLiteTableField> rowsOfFields;

};

USTRUCT(BlueprintType)
struct CISQLITE3_API FSQLiteTable
{
    GENERATED_USTRUCT_BODY()

        /** Database name*/
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table")
        FString DatabaseName = "";

    /** Table name*/
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table")
        FString TableName = "";

    /** Array with Fields*/
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table")
        TArray<FSQLiteTableField> Fields;

    /** Primary Key */
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table")
        FSQLitePrimaryKey PK;

    /** Created Key */
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Table")
        bool Created = false;

};


SQLiteDatabase.h:


#pragma once
#include "sqlite3.h"
#include "SQLiteBlueprintNodes.h"
#include "SQLiteDatabaseStructs.h"
#include "F:/UE4/Projects/MiningTechDemo4/Plugins/CISQLite3/Intermediate/Build/Win64/UE4Editor/Inc/CISQLite3/SQLiteDatabase.generated.h"

USTRUCT(BlueprintType)
struct CISQLITE3_API FSQLiteDatabaseReference
{
    GENERATED_USTRUCT_BODY()

        /** The database name (not the filename) */
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Database Reference")
        FString DatabaseName;

    /** The database tables we want to get data from */
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Database Reference")
        TArray<FString> Tables;
};

USTRUCT(BlueprintType)
struct CISQLITE3_API FSQLiteKeyValuePair
{
    GENERATED_USTRUCT_BODY()

        /** The database table field name */
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Key Value Pair")
        FString Key;

    /** The value of the field */
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Key Value Pair")
        FString Value;
};

USTRUCT(BlueprintType)
struct CISQLITE3_API FSQLiteQueryResultRow
{
    GENERATED_USTRUCT_BODY()

        /** A list of field name, field value pairs */
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Query Result")
        TArray<FSQLiteKeyValuePair> Fields;
};

USTRUCT(BlueprintType)
struct CISQLITE3_API FSQLiteQueryResult
{
    GENERATED_USTRUCT_BODY()

        /** The resulting rows from the query */
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SQLite Query Result")
        TArray<FSQLiteQueryResultRow> ResultRows;

    /** Was the query successful or not */
    UPROPERTY(BlueprintReadOnly, Category = "SQLite Query Result")
        bool Success;

    /** If the query was unsuccessful a human readable error message will be populated here */
    UPROPERTY(BlueprintReadOnly, Category = "SQLite Query Result")
        FString ErrorMessage;

};



// A few things for internal use here.
namespace SQLiteResultValueTypes
{
    enum SQLiteResultValType
    {
        Integer,
        Float,
        Text,
        UnsupportedValueType
    };
}

// Result field, used as an intermediary when collecting results from
// an SQLITE3 query.
struct SQLiteResultField
{
    FString StringValue;
    double DoubleValue;
    int64 IntValue;

    FString Name;
    SQLiteResultValueTypes::SQLiteResultValType Type;

    FString ToString()
    {
        if (Type == SQLiteResultValueTypes::Text)
            return StringValue;
        else if (Type == SQLiteResultValueTypes::Integer)
            return FString::Printf(TEXT("%i"), IntValue);
        else if (Type == SQLiteResultValueTypes::Float)
            return FString::Printf(TEXT("%f"), DoubleValue);

        return StringValue;
    }
};

// Represents a single row in the result.
struct SQLiteResultValue
{
    TArray<SQLiteResultField> Fields;
};

// The internal result object.
struct SQLiteQueryResult
{
    bool Success;
    FString ErrorMessage;
    TArray<SQLiteResultValue> Results;
};



/**
* SQLite main database class.
*/
UCLASS()
class CISQLITE3_API USQLiteDatabase : public UObject
{
    GENERATED_UCLASS_BODY()

public:
    /** Create a sqlite database file if it doesn't exist already. Does nothing if already exists.
    *   Returns false if the file couldn't be created */
    UFUNCTION(BlueprintCallable, Category = "SQLite")
        static bool CreateDatabase(const FString& Filename, bool RelativeToGameContentDirectory);

    /** Checks if the database is registered, ie. that it can be found in Databases. */

    /** Add a database to the list of databases. It will be checked that it's valid (will try to open it) */
    UFUNCTION(BlueprintCallable, Category = "SQLite")
        static bool RegisterDatabase(const FString& Name, const FString& Filename, bool RelativeToGameContentDirectory, bool KeepOpen=false);

    /** Remove a database from the list of databases. Closes the database in case KeepOpen flag was set during @ref RegisterDatabase */
    UFUNCTION(BlueprintCallable, Category = "SQLite")
        static void UnregisterDatabase(const FString& Name);

    /** Checks if the database is registered, ie. that it can be found in Databases. */
    UFUNCTION(BlueprintCallable, Category = "SQLite")
        static bool IsDatabaseRegistered(const FString& DatabaseName);

    /** Get data from the database using a select statement straight into an UObject, ie. populates its properties. */
    UFUNCTION(BlueprintCallable, Category = "SQLite", meta = (DisplayName = "Get Data Into Object (manual query)"))
        static bool GetDataIntoObject(const FString& DatabaseName, const FString& Query, UObject* ObjectToPopulate);

    /** Blueprint: Gets data from the database using a select statement straight into an UObject, ie. populates its properties.
    *   Note: Does not create a new object. ObjectToPopulate is the reference to the object you want to populate. */
    UFUNCTION(BlueprintCallable, Category = "SQLite", meta = (DisplayName = "Get Data Into Object"))
        static bool GetDataIntoObjectBP(const FSQLiteDatabaseReference& DataSource, TArray<FString> Fields, FSQLiteQueryFinalizedQuery Query, UObject* ObjectToPopulate);

    /** Get data from the database using a select statement and return the rows. */
    UFUNCTION(BlueprintCallable, Category = "SQLite", meta = (DisplayName = "Get Data From Table(s) (manual query)"))
        static FSQLiteQueryResult GetData(const FString& DatabaseName, const FString& Query);

    /** Blueprint: Get data from the database. Returns the resulting rows. */
    UFUNCTION(BlueprintCallable, Category = "SQLite", meta = (DisplayName = "Get Data From Table(s)"))
        static FSQLiteQueryResult GetDataBP(const FSQLiteDatabaseReference& DataSource, TArray<FString> Fields, FSQLiteQueryFinalizedQuery Query, int32 MaxResults = -1, int32 ResultOffset = 0);

    /** Create table in the database. */
    UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Create Table"))
        static FSQLiteTable CreateTable(const FString& DatabaseName, const FString& TableName,
        const TArray<FSQLiteTableField> Fields, const FSQLitePrimaryKey PK);

    /** Create indexes for table */
    UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Create Indexes"))
        static bool CreateIndexes(const FString& DatabaseName, const FString& TableName, const TArray<FSQLiteIndex> Indexes);

    /** Create index for table */
    UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Create Index"))
        static bool CreateIndex(const FString& DatabaseName, const FString& TableName, const FSQLiteIndex Index);

    /** Drop index*/
    UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Drop Index"))
        static bool DropIndex(const FString& DatabaseName, const FString& IndexName);

    /** Drop Table*/
    UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Drop Table"))
        static bool DropTable(const FString& DatabaseName, const FString& TableName);

    /** Truncate Table*/
    UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Truncate Table"))
        static bool TruncateTable(const FString& DatabaseName, const FString& TableName);

    /** Is table exists?*/
    UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Is table exists?"))
        static bool IsTableExists(const FString& DatabaseName, const FString& TableName);

    /** Insert rows into table */
    UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Insert Rows Into Table"))
        static void InsertRowsIntoTable(const FString& DatabaseName, const FString& TableName, TArray<FSQLiteTableRowSimulator> rowsOfFields);

    /** Compact database*/
    UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Compact database"))
        static bool Vacuum(const FString& DatabaseName);

    /** Execute SQL (can be used for insert statement)*/
    UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Execute SQL"))
        static bool ExecSql(const FString& DatabaseName, const FString& Query);

    /** Checks database validity (if the file exists and/or if it can be opened). */
    UFUNCTION(BlueprintCallable, Category = "SQLite|Query", meta = (DisplayName = "Is Valid Database"))
        static bool IsValidDatabase(const FString& DatabaseFilename, bool TestByOpening);

    /** Runs a query and returns fetched rows. */
        static TUniquePtr<SQLiteQueryResult> RunQueryAndGetResults(const FString& DatabaseName, const FString& Query);
private:
    /** Tries to open a database. */
    static bool CanOpenDatabase(const FString& DatabaseFilename);
    /** Collects all properties from an UObject and maps them by the property name. */
    static TMap<FString, UProperty*> CollectProperties(UObject* SourceObject);
    /** Constructs an SQL query from the blueprint fed data. */
    static FString ConstructQuery(TArray<FString> Tables, TArray<FString> Fields, FSQLiteQueryFinalizedQuery QueryObject, int32 MaxResults = -1, int32 ResultOffset = 0);
    /** Assigns a result row's fields' values to an UObject, ie. assigns them to the properties that have the same name. */
    static void AssignResultsToObjectProperties(const SQLiteResultValue& ResultValue, UObject* ObjectToPopulate);
    /** @brief Prepare given statement, returns whether to keep the database open */
    static bool PrepareStatement(const FString& DatabaseName, const FString& Query, sqlite3** Db, int32** SqlReturnCode,
        sqlite3_stmt** PreparedStatement);


private:
    /** A list of the databases for convenience, easier to refer to them by name rather than a long filename. */
    static TMap<FString, FString> Databases;

    static TMap<FString, sqlite3*> SQLite3Databases;

};


I have tried a dozen different things and tried starting fresh projects three times. It always ends up at this point not being able to compile. Any help will be appreciated by both me and the wall next to my computer.

Okay, I have resolved this problem but not by fixing anything. I created a new project and added the amalgamation straight into the code. It works perfectly fine after adding bEnableUndefinedIdentifierWarnings = false; to the build file.

Still, I think it would be beneficial for someone to get that plugin working.

I will be starting a live stream in a bit in case anyone is interested in how to include SQLite into your project.