Browse Source

Merge pull request #1508 from rokups/feature/database

Database subsystem
JoshEngebretson 8 years ago
parent
commit
5d4e9e0319

+ 14 - 1
Source/Atomic/CMakeLists.txt

@@ -22,6 +22,12 @@ file (GLOB NAVIGATION_SOURCE Navigation/*.cpp Navigation/*.h)
 file (GLOB ENVIRONMENT_SOURCE Environment/*.cpp Environment/*.h)
 file (GLOB GRAPHICS_SOURCE Graphics/*.cpp Graphics/*.h)
 
+if (ATOMIC_DATABASE_SQLITE)
+    file (GLOB DATABASE_SOURCE Database/*.cpp Database/*.h Database/SQLite/*.cpp Database/SQLite/*.h)
+elseif (ATOMIC_DATABASE_ODBC)
+    file (GLOB DATABASE_SOURCE Database/*.cpp Database/*.h Database/ODBC/*.cpp Database/ODBC/*.h)
+endif ()
+
 if (WIN32)
     if (ATOMIC_D3D11) # DirectX 11
         file (GLOB GRAPHICS_IMPL_SOURCE Graphics/Direct3D11/*.cpp Graphics/Direct3D11/*.h)
@@ -46,7 +52,7 @@ set (SOURCE_FILES ${CONTAINER_SOURCE} ${CORE_SOURCE} ${ENGINE_SOURCE} ${INPUT_SO
                   ${ATOMIC2D_SOURCE} ${ENVIRONMENT_SOURCE}
                   ${SCENE_SOURCE} ${UI_SOURCE} ${SYSTEM_UI_SOURCE}
                   ${WEB_SOURCE} ${SCRIPT_SOURCE} ${METRICS_SOURCE}
-                  ${PLATFORM_SOURCE})
+                  ${PLATFORM_SOURCE} ${DATABASE_SOURCE})
 
 if (NOT WEB)
   set (SOURCE_FILES ${SOURCE_FILES} ${NETWORK_SOURCE} ${NAVIGATION_SOURCE})
@@ -197,6 +203,13 @@ if (NOT APPLE OR IOS OR WEB)
     target_compile_definitions (Atomic PUBLIC -DATOMIC_TBUI=1)
 endif ()
 
+if (ATOMIC_DATABASE_SQLITE)
+    target_link_libraries(Atomic sqlite)
+    target_compile_definitions(Atomic PUBLIC -DATOMIC_DATABASE=1 -DATOMIC_DATABASE_SQLITE=1)
+elseif (ATOMIC_DATABASE_ODBC)
+    target_link_libraries(Atomic nanodbc)
+    target_compile_definitions(Atomic PUBLIC -DATOMIC_DATABASE=1 -DATOMIC_DATABASE_ODBC=1)
+endif ()
 target_include_directories (Atomic PUBLIC
     ${ATOMIC_SOURCE_DIR}/Source
     ${ATOMIC_SOURCE_DIR}/Source/ThirdParty

+ 4 - 4
Source/Atomic/Database/Database.cpp

@@ -25,7 +25,7 @@
 #include "../Core/Profiler.h"
 #include "../Database/Database.h"
 
-namespace Urho3D
+namespace Atomic
 {
 
 Database::Database(Context* context_) :
@@ -40,7 +40,7 @@ Database::Database(Context* context_) :
 
 DBAPI Database::GetAPI()
 {
-#ifdef URHO3D_DATABASE_ODBC
+#ifdef ATOMIC_DATABASE_ODBC
     return DBAPI_ODBC;
 #else
     return DBAPI_SQLITE;
@@ -49,7 +49,7 @@ DBAPI Database::GetAPI()
 
 DbConnection* Database::Connect(const String& connectionString)
 {
-    URHO3D_PROFILE(DatabaseConnect);
+    ATOMIC_PROFILE(DatabaseConnect);
 
     SharedPtr<DbConnection> connection;
     if (IsPooling())
@@ -80,7 +80,7 @@ void Database::Disconnect(DbConnection* connection)
     if (!connection)
         return;
 
-    URHO3D_PROFILE(DatabaseDisconnect);
+    ATOMIC_PROFILE(DatabaseDisconnect);
 
     SharedPtr<DbConnection> dbConnection(connection);
     connections_.Remove(dbConnection);

+ 3 - 3
Source/Atomic/Database/Database.h

@@ -25,7 +25,7 @@
 #include "../Core/Object.h"
 #include "../Database/DbConnection.h"
 
-namespace Urho3D
+namespace Atomic
 {
 
 /// Supported database API.
@@ -38,9 +38,9 @@ enum DBAPI
 class DbConnection;
 
 /// %Database subsystem. Manage database connections.
-class URHO3D_API Database : public Object
+class ATOMIC_API Database : public Object
 {
-    URHO3D_OBJECT(Database, Object);
+    ATOMIC_OBJECT(Database, Object);
 
 public:
     /// Construct.

+ 10 - 10
Source/Atomic/Database/DatabaseEvents.h

@@ -25,20 +25,20 @@
 #include "../Core/Object.h"
 #include "../Database/DbConnection.h"
 
-namespace Urho3D
+namespace Atomic
 {
 
 /// %Database cursor. Event handler could set P_FILTER to true to filter out a row from resultset and P_ABORT to true to stop further cursor events.
-URHO3D_EVENT(E_DBCURSOR, DbCursor)
+ATOMIC_EVENT(E_DBCURSOR, DbCursor)
 {
-    URHO3D_PARAM(P_DBCONNECTION, DbConnection);    // DbConnection pointer
-    URHO3D_PARAM(P_RESULTIMPL, ResultImpl);        // Underlying result object pointer (cannot be used in scripting)
-    URHO3D_PARAM(P_SQL, SQL);                      // String
-    URHO3D_PARAM(P_NUMCOLS, NumCols);              // unsigned
-    URHO3D_PARAM(P_COLVALUES, ColValues);          // VariantVector
-    URHO3D_PARAM(P_COLHEADERS, ColHeaders);        // StringVector
-    URHO3D_PARAM(P_FILTER, Filter);                // bool [in]
-    URHO3D_PARAM(P_ABORT, Abort);                  // bool [in]
+    ATOMIC_PARAM(P_DBCONNECTION, DbConnection);    // DbConnection pointer
+    ATOMIC_PARAM(P_RESULTIMPL, ResultImpl);        // Underlying result object pointer (cannot be used in scripting)
+    ATOMIC_PARAM(P_SQL, SQL);                      // String
+    ATOMIC_PARAM(P_NUMCOLS, NumCols);              // unsigned
+    ATOMIC_PARAM(P_COLVALUES, ColValues);          // VariantVector
+    ATOMIC_PARAM(P_COLHEADERS, ColHeaders);        // StringVector
+    ATOMIC_PARAM(P_FILTER, Filter);                // bool [in]
+    ATOMIC_PARAM(P_ABORT, Abort);                  // bool [in]
 }
 
 }

+ 2 - 2
Source/Atomic/Database/DbConnection.h

@@ -22,9 +22,9 @@
 
 #pragma once
 
-#ifdef URHO3D_DATABASE_ODBC
+#ifdef ATOMIC_DATABASE_ODBC
 #include "ODBC/ODBCConnection.h"
-#elif defined(URHO3D_DATABASE_SQLITE)
+#elif defined(ATOMIC_DATABASE_SQLITE)
 #include "SQLite/SQLiteConnection.h"
 #else
 #error "Database subsystem not enabled"

+ 2 - 2
Source/Atomic/Database/DbResult.h

@@ -22,9 +22,9 @@
 
 #pragma once
 
-#ifdef URHO3D_DATABASE_ODBC
+#ifdef ATOMIC_DATABASE_ODBC
 #include "ODBC/ODBCResult.h"
-#elif defined(URHO3D_DATABASE_SQLITE)
+#elif defined(ATOMIC_DATABASE_SQLITE)
 #include "SQLite/SQLiteResult.h"
 #else
 #error "Database subsystem not enabled"

+ 2 - 2
Source/Atomic/Database/ODBC/ODBCConnection.cpp

@@ -33,7 +33,7 @@
 
 #include <sqlext.h>
 
-namespace Urho3D
+namespace Atomic
 {
 
 DbConnection::DbConnection(Context* context, const String& connectionString) :
@@ -158,7 +158,7 @@ DbResult DbConnection::Execute(const String& sql, bool useCursorEvent)
 void DbConnection::HandleRuntimeError(const char* message, const char* cause)
 {
     StringVector tokens = (String(cause) + "::").Split(':');      // Added "::" as sentinels against unexpected cause format
-    URHO3D_LOGERRORF("%s: nanodbc:%s:%s", message, tokens[1].CString(), tokens[2].CString());
+    ATOMIC_LOGERRORF("%s: nanodbc:%s:%s", message, tokens[1].CString(), tokens[2].CString());
 }
 
 }

+ 4 - 4
Source/Atomic/Database/ODBC/ODBCConnection.h

@@ -25,15 +25,15 @@
 #include "../../Core/Object.h"
 #include "../../Database/DbResult.h"
 
-#include <nanodbc/nanodbc.h>
+#include <nanodbc.h>
 
-namespace Urho3D
+namespace Atomic
 {
 
 /// %Database connection.
-class URHO3D_API DbConnection : public Object
+class ATOMIC_API DbConnection : public Object
 {
-    URHO3D_OBJECT(DbConnection, Object);
+    ATOMIC_OBJECT(DbConnection, Object);
 
 public:
     /// Construct.

+ 3 - 3
Source/Atomic/Database/ODBC/ODBCResult.h

@@ -24,13 +24,13 @@
 
 #include "../../Core/Variant.h"
 
-#include <nanodbc/nanodbc.h>
+#include <nanodbc.h>
 
-namespace Urho3D
+namespace Atomic
 {
 
 /// %Database query result.
-class URHO3D_API DbResult
+class ATOMIC_API DbResult
 {
     friend class DbConnection;
 

+ 11 - 7
Source/Atomic/Database/SQLite/SQLiteConnection.cpp

@@ -25,7 +25,7 @@
 #include "../../Database/DatabaseEvents.h"
 #include "../../IO/Log.h"
 
-namespace Urho3D
+namespace Atomic
 {
 
 DbConnection::DbConnection(Context* context, const String& connectionString) :
@@ -35,7 +35,7 @@ DbConnection::DbConnection(Context* context, const String& connectionString) :
 {
     if (sqlite3_open(connectionString.CString(), &connectionImpl_) != SQLITE_OK)
     {
-        URHO3D_LOGERRORF("Could not connect: %s", sqlite3_errmsg(connectionImpl_));
+        ATOMIC_LOGERRORF("Could not connect: %s", sqlite3_errmsg(connectionImpl_));
         sqlite3_close(connectionImpl_);
         connectionImpl_ = 0;
     }
@@ -47,7 +47,7 @@ DbConnection::~DbConnection()
     if (sqlite3_close(connectionImpl_) != SQLITE_OK)
     {
         // This should not happen after finalizing the connection, log error in Release but assert in Debug
-        URHO3D_LOGERRORF("Could not disconnect: %s", sqlite3_errmsg(connectionImpl_));
+        ATOMIC_LOGERRORF("Could not disconnect: %s", sqlite3_errmsg(connectionImpl_));
         assert(false);
     }
     connectionImpl_ = 0;
@@ -64,16 +64,20 @@ DbResult DbConnection::Execute(const String& sql, bool useCursorEvent)
     const char* zLeftover = 0;
     sqlite3_stmt* pStmt = 0;
     assert(connectionImpl_);
-    int rc = sqlite3_prepare_v2(connectionImpl_, sql.Trimmed().CString(), -1, &pStmt, &zLeftover);
+
+    // 2016-10-09: Prevent string corruption when trimmed is returned.
+    String trimmedSqlStr = sql.Trimmed();
+
+    int rc = sqlite3_prepare_v2(connectionImpl_, trimmedSqlStr.CString(), -1, &pStmt, &zLeftover);
     if (rc != SQLITE_OK)
     {
-        URHO3D_LOGERRORF("Could not execute: %s", sqlite3_errmsg(connectionImpl_));
+        ATOMIC_LOGERRORF("Could not execute: %s", sqlite3_errmsg(connectionImpl_));
         assert(!pStmt);
         return result;
     }
     if (*zLeftover)
     {
-        URHO3D_LOGERROR("Could not execute: only one SQL statement is allowed");
+        ATOMIC_LOGERROR("Could not execute: only one SQL statement is allowed");
         sqlite3_finalize(pStmt);
         return result;
     }
@@ -147,7 +151,7 @@ DbResult DbConnection::Execute(const String& sql, bool useCursorEvent)
             }
         }
         else if (rc != SQLITE_DONE)
-            URHO3D_LOGERRORF("Could not execute: %s", sqlite3_errmsg(connectionImpl_));
+            ATOMIC_LOGERRORF("Could not execute: %s", sqlite3_errmsg(connectionImpl_));
         if (rc != SQLITE_ROW)
         {
             sqlite3_finalize(pStmt);

+ 4 - 4
Source/Atomic/Database/SQLite/SQLiteConnection.h

@@ -25,15 +25,15 @@
 #include "../../Core/Object.h"
 #include "../../Database/DbResult.h"
 
-#include <SQLite/sqlite3.h>
+#include <sqlite3.h>
 
-namespace Urho3D
+namespace Atomic
 {
 
 /// %Database connection.
-class URHO3D_API DbConnection : public Object
+class ATOMIC_API DbConnection : public Object
 {
-    URHO3D_OBJECT(DbConnection, Object);
+    ATOMIC_OBJECT(DbConnection, Object);
 
 public:
     /// Construct.

+ 3 - 3
Source/Atomic/Database/SQLite/SQLiteResult.h

@@ -24,13 +24,13 @@
 
 #include "../../Core/Variant.h"
 
-#include <SQLite/sqlite3.h>
+#include <sqlite3.h>
 
-namespace Urho3D
+namespace Atomic
 {
 
 /// %Database query result.
-class URHO3D_API DbResult
+class ATOMIC_API DbResult
 {
     friend class DbConnection;
 

+ 2 - 2
Source/Atomic/IO/Log.cpp

@@ -228,10 +228,10 @@ void Log::WriteRaw(const String& message, bool error)
     if (logInstance->quiet_)
     {
         if (error)
-            __android_log_print(ANDROID_LOG_ERROR, "Urho3D", message.CString());
+            __android_log_print(ANDROID_LOG_ERROR, "Atomic", "%s", message.CString());
     }
     else
-        __android_log_print(error ? ANDROID_LOG_ERROR : ANDROID_LOG_INFO, "Urho3D", message.CString());
+        __android_log_print(error ? ANDROID_LOG_ERROR : ANDROID_LOG_INFO, "Atomic", "%s", message.CString());
 #elif defined(IOS)
     SDL_IOS_LogMessage(message.CString());
 #else

+ 2 - 0
Source/CMakeLists.txt

@@ -1,6 +1,8 @@
 option(ATOMIC_JAVASCRIPT "Build JS Bindings" ON)
 option(ATOMIC_DOTNET "Build .NET Bindings" ON)
 option(ATOMIC_EDITOR "Build Editor" ON)
+option(ATOMIC_DATABASE_SQLITE "Enable SQLite database subsystem" OFF)
+option(ATOMIC_DATABASE_ODBC "Enable ODBC database subsystem" OFF)
 
 add_subdirectory(ThirdParty)
 add_subdirectory(Atomic)

+ 7 - 1
Source/ThirdParty/CMakeLists.txt

@@ -67,12 +67,18 @@ if (NOT IOS AND NOT ANDROID AND NOT WEB)
     if (NOT LINUX)
         add_subdirectory(LibCpuId)
     endif()
-    #add_subdirectory(SQLite)
     add_subdirectory(Poco)
     add_subdirectory(nativefiledialog)
     add_subdirectory(libsquish)
 endif ()
 
+if (ATOMIC_DATABASE_SQLITE)
+    add_subdirectory(SQLite)
+endif ()
+if (ATOMIC_DATABASE_ODBC)
+    add_subdirectory(nanodbc)
+endif ()
+
 if (LINUX OR APPLE OR ATOMIC_OPENGL AND NOT IOS)
     add_subdirectory(GLEW)
 endif()

+ 24 - 18
Source/ThirdParty/SQLite/CMakeLists.txt

@@ -23,13 +23,6 @@
 # Define target name
 set (TARGET_NAME sqlite)
 
-# https://www.sqlite.org/compile.html
-add_definitions (-DSQLITE_USE_URI=1 -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_SOUNDEX)
-# Do not use pthread and dl libraries for Web platform
-if (WEB)
-    add_definitions (-DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION)
-endif ()
-
 # Define source files
 set (SOURCE_FILES src/sqlite3.c)
 
@@ -40,8 +33,25 @@ set (INCLUDE_DIRS src)
 # Setup target
 setup_library ()
 
+# ATOMIC BEGIN
+# Define preprocessor macros
+target_compile_definitions (${TARGET_NAME} PUBLIC -DSQLITE_USE_URI=1 -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_SOUNDEX)   # https://www.sqlite.org/compile.html
+if (WEB)
+    # Do not use pthread and dl libraries for Web platform
+    target_compile_definitions (${TARGET_NAME} PUBLIC -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION)
+elseif (MINGW)
+    # We only support MinGW with "_mingw.h" header file, note the leading underscore
+    target_compile_definitions (${TARGET_NAME} PRIVATE -D_HAVE__MINGW_H)
+endif ()
+foreach (VAR HAVE_STDINT_H HAVE_INTTYPES_H HAVE_MALLOC_H HAVE_MALLOC_USABLE_SIZE)
+    if (${VAR})
+        target_compile_definitions (${TARGET_NAME} PRIVATE -D${VAR})
+    endif ()
+endforeach ()
+# ATOMIC END
+
 # Setup additional SQLite CLI standalone target (this target can be transfered and executed on an embedded device, such as Raspberry Pi and Android)
-if (NOT IOS AND NOT WEB)
+if (NOT IOS AND NOT WEB AND NOT ANDROID)    # ATOMIC FIX
     # Define target name for SQLite shell
     set (TARGET_NAME isql)
 
@@ -50,16 +60,12 @@ if (NOT IOS AND NOT WEB)
 
     # Define dependency libs
     if (NOT WIN32)
-        set (LIBS dl)
-    endif ()
-    if (READLINE_FOUND)
-        add_definitions (-DHAVE_READLINE)
-        # FIXME: temporary quick fix
-        if (SYSROOT)
-            set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --sysroot=\"${SYSROOT}\"")
+        set (LIBS dl pthread)    # ATOMIC FIX
+        if (READLINE_FOUND)
+            add_definitions (-DHAVE_READLINE)
+            list (APPEND INCLUDE_DIRS ${READLINE_INCLUDE_DIRS})
+            list (APPEND LIBS ${READLINE_LIBRARIES})
         endif ()
-        list (APPEND INCLUDE_DIRS ${READLINE_INCLUDE_DIRS})
-        list (APPEND LIBS ${READLINE_LIBRARIES})
     endif ()
 
     # Setup target
@@ -69,5 +75,5 @@ endif ()
 # SQLite will not work correctly with the -ffast-math option of GCC
 # ATOMIC: Add check for empty CMAKE_C_FLAGS
 if (CMAKE_C_FLAGS)
-string (REPLACE -ffast-math "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
+    string (REPLACE -ffast-math "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
 endif()

File diff suppressed because it is too large
+ 857 - 52
Source/ThirdParty/SQLite/src/shell.c


File diff suppressed because it is too large
+ 367 - 132
Source/ThirdParty/SQLite/src/sqlite3.c


File diff suppressed because it is too large
+ 352 - 141
Source/ThirdParty/SQLite/src/sqlite3.h


+ 23 - 5
Source/ThirdParty/SQLite/src/sqlite3ext.h

@@ -15,12 +15,10 @@
 ** as extensions by SQLite should #include this file instead of 
 ** sqlite3.h.
 */
-#ifndef _SQLITE3EXT_H_
-#define _SQLITE3EXT_H_
+#ifndef SQLITE3EXT_H
+#define SQLITE3EXT_H
 #include "sqlite3.h"
 
-typedef struct sqlite3_api_routines sqlite3_api_routines;
-
 /*
 ** The following structure holds pointers to all of the SQLite API
 ** routines.
@@ -281,8 +279,23 @@ struct sqlite3_api_routines {
   int (*db_cacheflush)(sqlite3*);
   /* Version 3.12.0 and later */
   int (*system_errno)(sqlite3*);
+  /* Version 3.14.0 and later */
+  int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
+  char *(*expanded_sql)(sqlite3_stmt*);
+  /* Version 3.18.0 and later */
+  void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
 };
 
+/*
+** This is the function signature used for all extension entry points.  It
+** is also defined in the file "loadext.c".
+*/
+typedef int (*sqlite3_loadext_entry)(
+  sqlite3 *db,                       /* Handle to the database. */
+  char **pzErrMsg,                   /* Used to set error string on failure. */
+  const sqlite3_api_routines *pThunk /* Extension API function pointers. */
+);
+
 /*
 ** The following macros redefine the API routines so that they are
 ** redirected through the global sqlite3_api structure.
@@ -526,6 +539,11 @@ struct sqlite3_api_routines {
 #define sqlite3_db_cacheflush          sqlite3_api->db_cacheflush
 /* Version 3.12.0 and later */
 #define sqlite3_system_errno           sqlite3_api->system_errno
+/* Version 3.14.0 and later */
+#define sqlite3_trace_v2               sqlite3_api->trace_v2
+#define sqlite3_expanded_sql           sqlite3_api->expanded_sql
+/* Version 3.18.0 and later */
+#define sqlite3_set_last_insert_rowid  sqlite3_api->set_last_insert_rowid
 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
 
 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -543,4 +561,4 @@ struct sqlite3_api_routines {
 # define SQLITE_EXTENSION_INIT3     /*no-op*/
 #endif
 
-#endif /* _SQLITE3EXT_H_ */
+#endif /* SQLITE3EXT_H */

Some files were not shown because too many files changed in this diff