Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/lintest/myrulib.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKandrashin Denis <mail@lintest.ru>2013-01-18 22:34:08 +0400
committerKandrashin Denis <mail@lintest.ru>2013-01-21 00:43:46 +0400
commit5a1614475a8c0cadff77faa50fbb74d126219d0c (patch)
tree02e98ab11ec2dc9675257db6bed400ff104490e9
parent03729be21c4baafd7909fb6f7da8864fb384b741 (diff)
Fix MacOS runtime error
-rw-r--r--Makefile.in8
-rwxr-xr-xconfigure1
-rw-r--r--configure.in4
-rw-r--r--desktop/info.plist16
-rw-r--r--desktop/myrulib.icnsbin0 -> 326063 bytes
-rw-r--r--myrulib.bkl9
-rwxr-xr-xprepare.sh5
-rw-r--r--sources/MyRuLib/controls/FbTreeView.cpp2
-rw-r--r--sources/WxSQLite3/wxsqlite3.cpp4297
-rwxr-xr-xubuntu.sh2
-rwxr-xr-xwindows.sh4
11 files changed, 4326 insertions, 22 deletions
diff --git a/Makefile.in b/Makefile.in
index fa3bc050..27f09a56 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -327,7 +327,6 @@ clean:
rm -f $(LIBPREFIX)mrl_faxpp$(LIBEXT)
rm -f $(LIBPREFIX)mrl_sqlite3$(LIBEXT)
rm -f $(LIBPREFIX)mrl_crengine$(LIBEXT)
- rm -f ./wxsqlite3.cpp
rm -f $(LIBPREFIX)mrl_wxsqlite3$(LIBEXT)
rm -f $(LIBPREFIX)mrl_wxbzip2$(LIBEXT)
rm -f zipscan$(EXEEXT)
@@ -374,9 +373,6 @@ distclean: clean
@COND_USE_READER_yes@ $(AR) $(AROPTIONS) $@ $(MRL_CRENGINE_OBJECTS)
@COND_USE_READER_yes@ $(RANLIB) $@
-wxsqlite3.cpp: $(srcdir)/3rdparty/wxsqlite3/src/wxsqlite3.cpp $(srcdir)/sources/WxSQLite3/wxsqlite3.patch
- patch -o ./wxsqlite3.cpp $(srcdir)/3rdparty/wxsqlite3/src/wxsqlite3.cpp $(srcdir)/sources/WxSQLite3/wxsqlite3.patch
-
$(LIBPREFIX)mrl_wxsqlite3$(LIBEXT): $(MRL_WXSQLITE3_OBJECTS)
rm -f $@
$(AR) $(AROPTIONS) $@ $(MRL_WXSQLITE3_OBJECTS)
@@ -652,8 +648,8 @@ mrl_crengine_wordfmt.o: $(srcdir)/3rdparty/crengine/src/wordfmt.cpp
mrl_crengine_xutils.o: $(srcdir)/3rdparty/crengine/src/xutils.cpp
$(CXXC) -c -o $@ $(MRL_CRENGINE_CXXFLAGS) $(srcdir)/3rdparty/crengine/src/xutils.cpp
-mrl_wxsqlite3_wxsqlite3.o: wxsqlite3.cpp
- $(CXXC) -c -o $@ $(MRL_WXSQLITE3_CXXFLAGS) wxsqlite3.cpp
+mrl_wxsqlite3_wxsqlite3.o: $(srcdir)/sources/WxSQLite3/wxsqlite3.cpp
+ $(CXXC) -c -o $@ $(MRL_WXSQLITE3_CXXFLAGS) $(srcdir)/sources/WxSQLite3/wxsqlite3.cpp
mrl_wxbzip2_bzipstream.o: $(srcdir)/3rdparty/wxbzipstream/bzipstream.cpp
$(CXXC) -c -o $@ $(MRL_WXBZIP2_CXXFLAGS) $(srcdir)/3rdparty/wxbzipstream/bzipstream.cpp
diff --git a/configure b/configure
index d49b4d97..2f3da2ae 100755
--- a/configure
+++ b/configure
@@ -4420,6 +4420,7 @@ rm -f core conftest.err conftest.$ac_objext \
rm -f conf.xmltest
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-expat" >&5
$as_echo_n "checking for --with-expat... " >&6; }
diff --git a/configure.in b/configure.in
index 28055fa0..79b91454 100644
--- a/configure.in
+++ b/configure.in
@@ -44,6 +44,10 @@ fi
AM_PATH_XML2(2.5.0, USE_LIBXML2="yes", USE_LIBXML2="no")
+dnl ---------------------------------------------------------------------------
+dnl Check compiler options
+dnl ---------------------------------------------------------------------------
+
AC_MSG_CHECKING([for --with-expat])
AC_ARG_WITH([expat], [AS_HELP_STRING([--with-expat], [Use Expat XML parser instead of Libxml2])], USE_EXPAT="$withval", USE_EXPAT="no")
AC_MSG_RESULT([$USE_EXPAT])
diff --git a/desktop/info.plist b/desktop/info.plist
new file mode 100644
index 00000000..87a13b52
--- /dev/null
+++ b/desktop/info.plist
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleExecutable</key>
+ <string>myrulib</string>
+ <key>CFBundleIdentifier</key>
+ <string>ru.lintest.MyRuLib</string>
+ <key>CFBundleName</key>
+ <string>MyRuLib</string>
+ <key>CFBundleIconFile</key>
+ <string>myrulib</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>ru</string>
+</dict>
+</plist> \ No newline at end of file
diff --git a/desktop/myrulib.icns b/desktop/myrulib.icns
new file mode 100644
index 00000000..2665aea2
--- /dev/null
+++ b/desktop/myrulib.icns
Binary files differ
diff --git a/myrulib.bkl b/myrulib.bkl
index da2c059c..c00ad18b 100644
--- a/myrulib.bkl
+++ b/myrulib.bkl
@@ -112,16 +112,9 @@
<sources>3rdparty/crengine/src/xutils.cpp</sources>
</lib>
- <action id="wxsqlite3.cpp">
- <depends-on-file>$(SRCDIR)/3rdparty/wxsqlite3/src/wxsqlite3.cpp</depends-on-file>
- <depends-on-file>$(SRCDIR)/sources/WxSQLite3/wxsqlite3.patch</depends-on-file>
- <command>patch -o $(BUILDDIR)/wxsqlite3.cpp $(SRCDIR)/3rdparty/wxsqlite3/src/wxsqlite3.cpp $(SRCDIR)/sources/WxSQLite3/wxsqlite3.patch</command>
- <clean-files>$(BUILDDIR)/wxsqlite3.cpp</clean-files>
- </action>
-
<lib id="mrl_wxsqlite3" template="wx-lib">
<define>NDEBUG</define>
- <sources>sources/wxsqlite3.cpp</sources>
+ <sources>sources/WxSQLite3/wxsqlite3.cpp</sources>
<include>$(SRCDIR)/3rdparty/wxsqlite3/include</include>
</lib>
diff --git a/prepare.sh b/prepare.sh
deleted file mode 100755
index f3483fef..00000000
--- a/prepare.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-# prepare.sh - process bakefile "myrulib.bkl" and patch it.
-
-bakefile -f autoconf myrulib.bkl
-sed -i 's|$(srcdir)/sources/wxsqlite3.cpp|wxsqlite3.cpp|g' Makefile.in
diff --git a/sources/MyRuLib/controls/FbTreeView.cpp b/sources/MyRuLib/controls/FbTreeView.cpp
index ee0474b2..5a88e9b4 100644
--- a/sources/MyRuLib/controls/FbTreeView.cpp
+++ b/sources/MyRuLib/controls/FbTreeView.cpp
@@ -1166,7 +1166,7 @@ void FbTreeViewCtrl::SetFocus()
void FbTreeViewCtrl::Refresh(bool erase, const wxRect* rect)
{
- m_main_win->Repaint();
+ if (m_main_win) m_main_win->Repaint();
if (m_header_win) m_header_win->Refresh (erase, rect);
}
diff --git a/sources/WxSQLite3/wxsqlite3.cpp b/sources/WxSQLite3/wxsqlite3.cpp
new file mode 100644
index 00000000..2be26eb0
--- /dev/null
+++ b/sources/WxSQLite3/wxsqlite3.cpp
@@ -0,0 +1,4297 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: wxsqlite3.cpp
+// Purpose: Implementation of wxSQLite3 classes
+// Author: Ulrich Telle
+// Modified by:
+// Created: 2005-07-06
+// Copyright: (c) Ulrich Telle
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+/// \file wxsqlite3.cpp Implementation of the wxSQLite3 class
+
+#if defined(__GNUG__) && !defined(__APPLE__)
+#pragma implementation "wxsqlite3.h"
+#endif
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/regex.h"
+
+#include "wx/wxsqlite3.h"
+#include "wx/wxsqlite3opt.h"
+
+// Error handling in wxSQLite3 library
+
+#if WXSQLITE_USE_EXCEPTIONS
+ #define WXSQLITE3_ERROR(code, message, result) throw wxSQLite3Exception(code, message);
+#else
+ void wxSQLite3_Error(int errorCode, const wxString& errorMsg)
+ {
+ if (errorCode == 9) return;
+ wxString m_errorMessage =
+ wxSQLite3Exception::ErrorCodeAsString(errorCode) + wxT("[") +
+ wxString::Format(wxT("%d"), errorCode) + wxT("]: ") +
+ wxGetTranslation(errorMsg);
+
+ wxLogError(m_errorMessage);
+ }
+ #define WXSQLITE3_ERROR(code, message, result) wxSQLite3_Error(code, message); return result;
+#endif // WXSQLITE_USE_EXCEPTIONS
+
+// Suppress some Visual C++ warnings regarding the default constructor
+// for a C struct used only in SQLite modules
+#ifdef __VISUALC__
+#pragma warning (disable:4510)
+#pragma warning (disable:4610)
+#endif
+
+#if WXSQLITE3_HAVE_CODEC
+#define SQLITE_HAS_CODEC 1
+#else
+#define SQLITE_HAS_CODEC 0
+#endif
+
+#include "sqlite3.h"
+
+// Dynamic loading of the SQLite library
+
+#if wxUSE_DYNAMIC_SQLITE3_LOAD
+
+#include "wx/dynlib.h"
+
+#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
+ typedef rtype (*p##fname) farg ; \
+ static p##fname s_##fname = NULL;
+#include "wx/wxsqlite3dyn.h"
+#undef DYNFUNC
+
+static wxDynamicLibrary s_dll;
+
+static void InitSQLite3DLL()
+{
+ if (s_dll.IsLoaded())
+ {
+ return;
+ }
+
+#ifdef __WIN32__
+ if (! s_dll.Load(wxT("sqlite3")))
+#else
+ if (! s_dll.Load(wxT("libsqlite3")))
+#endif
+ {
+ WXSQLITE3_ERROR(-1, wxT("error loading dynamic library"), );
+ }
+
+#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
+ s_##fname = (p##fname) s_dll.GetSymbol(wxT(#fname));\
+ if (! s_##fname)\
+ {\
+ s_dll.Unload();\
+ WXSQLITE3_ERROR(-1, wxT("error getting symbol <") wxT(#fname) wxT(">"), );\
+ }
+#include "wx/wxsqlite3dyn.h"
+#undef DYNFUNC
+
+};
+
+#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
+ rtype fname farg \
+ {\
+ InitSQLite3DLL();\
+ rcode s_##fname farguse;\
+ };
+#include "wx/wxsqlite3dyn.h"
+#undef DYNFUNC
+
+#endif // wxUSE_DYNAMIC_SQLITE3_LOAD
+
+// Error messages
+
+#if wxCHECK_VERSION(2,9,0)
+const char* wxERRMSG_NODB = wxTRANSLATE("No Database opened");
+const char* wxERRMSG_NOSTMT = wxTRANSLATE("Statement not accessible");
+const char* wxERRMSG_NOMEM = wxTRANSLATE("Out of memory");
+const char* wxERRMSG_DECODE = wxTRANSLATE("Cannot decode binary");
+const char* wxERRMSG_INVALID_INDEX = wxTRANSLATE("Invalid field index");
+const char* wxERRMSG_INVALID_NAME = wxTRANSLATE("Invalid field name");
+const char* wxERRMSG_INVALID_ROW = wxTRANSLATE("Invalid row index");
+const char* wxERRMSG_INVALID_QUERY = wxTRANSLATE("Invalid scalar query");
+const char* wxERRMSG_INVALID_BLOB = wxTRANSLATE("Invalid BLOB handle");
+
+const char* wxERRMSG_NORESULT = wxTRANSLATE("Null Results pointer");
+const char* wxERRMSG_BIND_STR = wxTRANSLATE("Error binding string param");
+const char* wxERRMSG_BIND_INT = wxTRANSLATE("Error binding int param");
+const char* wxERRMSG_BIND_INT64 = wxTRANSLATE("Error binding int64 param");
+const char* wxERRMSG_BIND_DBL = wxTRANSLATE("Error binding double param");
+const char* wxERRMSG_BIND_BLOB = wxTRANSLATE("Error binding blob param");
+const char* wxERRMSG_BIND_DATETIME = wxTRANSLATE("Error binding date/time param");
+const char* wxERRMSG_BIND_NULL = wxTRANSLATE("Error binding NULL param");
+const char* wxERRMSG_BIND_ZEROBLOB = wxTRANSLATE("Error binding zero blob param");
+const char* wxERRMSG_BIND_CLEAR = wxTRANSLATE("Error clearing bindings");
+const char* wxERRMSG_NOTOWNED = wxTRANSLATE("Transfer of statement ownership not possible");
+
+const char* wxERRMSG_NOMETADATA = wxTRANSLATE("Meta data support not available");
+const char* wxERRMSG_NOCODEC = wxTRANSLATE("Encryption support not available");
+const char* wxERRMSG_NOLOADEXT = wxTRANSLATE("Loadable extension support not available");
+const char* wxERRMSG_NOINCBLOB = wxTRANSLATE("Incremental BLOB support not available");
+const char* wxERRMSG_NOBLOBREBIND = wxTRANSLATE("Rebind BLOB support not available");
+const char* wxERRMSG_NOSAVEPOINT = wxTRANSLATE("Savepoint support not available");
+const char* wxERRMSG_NOBACKUP = wxTRANSLATE("Backup/restore support not available");
+const char* wxERRMSG_NOWAL = wxTRANSLATE("Write Ahead Log support not available");
+const char* wxERRMSG_NOCOLLECTIONS = wxTRANSLATE("Named collection support not available");
+
+const char* wxERRMSG_SHARED_CACHE = wxTRANSLATE("Setting SQLite shared cache mode failed");
+
+const char* wxERRMSG_INITIALIZE = wxTRANSLATE("Initialization of SQLite failed");
+const char* wxERRMSG_SHUTDOWN = wxTRANSLATE("Shutdown of SQLite failed");
+
+const char* wxERRMSG_SOURCEDB_BUSY = wxTRANSLATE("Source database is busy");
+const char* wxERRMSG_DBOPEN_FAILED = wxTRANSLATE("Database open failed");
+const char* wxERRMSG_DBASSIGN_FAILED = wxTRANSLATE("Database assignment failed");
+#else
+const wxChar* wxERRMSG_NODB = wxTRANSLATE("No Database opened");
+const wxChar* wxERRMSG_NOSTMT = wxTRANSLATE("Statement not accessible");
+const wxChar* wxERRMSG_NOMEM = wxTRANSLATE("Out of memory");
+const wxChar* wxERRMSG_DECODE = wxTRANSLATE("Cannot decode binary");
+const wxChar* wxERRMSG_INVALID_INDEX = wxTRANSLATE("Invalid field index");
+const wxChar* wxERRMSG_INVALID_NAME = wxTRANSLATE("Invalid field name");
+const wxChar* wxERRMSG_INVALID_ROW = wxTRANSLATE("Invalid row index");
+const wxChar* wxERRMSG_INVALID_QUERY = wxTRANSLATE("Invalid scalar query");
+const wxChar* wxERRMSG_INVALID_BLOB = wxTRANSLATE("Invalid BLOB handle");
+
+const wxChar* wxERRMSG_NORESULT = wxTRANSLATE("Null Results pointer");
+const wxChar* wxERRMSG_BIND_STR = wxTRANSLATE("Error binding string param");
+const wxChar* wxERRMSG_BIND_INT = wxTRANSLATE("Error binding int param");
+const wxChar* wxERRMSG_BIND_INT64 = wxTRANSLATE("Error binding int64 param");
+const wxChar* wxERRMSG_BIND_DBL = wxTRANSLATE("Error binding double param");
+const wxChar* wxERRMSG_BIND_BLOB = wxTRANSLATE("Error binding blob param");
+const wxChar* wxERRMSG_BIND_DATETIME = wxTRANSLATE("Error binding date/time param");
+const wxChar* wxERRMSG_BIND_NULL = wxTRANSLATE("Error binding NULL param");
+const wxChar* wxERRMSG_BIND_ZEROBLOB = wxTRANSLATE("Error binding zero blob param");
+const wxChar* wxERRMSG_BIND_CLEAR = wxTRANSLATE("Error clearing bindings");
+const wxChar* wxERRMSG_NOTOWNED = wxTRANSLATE("Transfer of statement ownership not possible");
+
+const wxChar* wxERRMSG_NOMETADATA = wxTRANSLATE("Meta data support not available");
+const wxChar* wxERRMSG_NOCODEC = wxTRANSLATE("Encryption support not available");
+const wxChar* wxERRMSG_NOLOADEXT = wxTRANSLATE("Loadable extension support not available");
+const wxChar* wxERRMSG_NOINCBLOB = wxTRANSLATE("Incremental BLOB support not available");
+const wxChar* wxERRMSG_NOBLOBREBIND = wxTRANSLATE("Rebind BLOB support not available");
+const wxChar* wxERRMSG_NOSAVEPOINT = wxTRANSLATE("Savepoint support not available");
+const wxChar* wxERRMSG_NOBACKUP = wxTRANSLATE("Backup/restore support not available");
+const wxChar* wxERRMSG_NOWAL = wxTRANSLATE("Write Ahead Log support not available");
+const wxChar* wxERRMSG_NOCOLLECTIONS = wxTRANSLATE("Named collection support not available");
+
+const wxChar* wxERRMSG_SHARED_CACHE = wxTRANSLATE("Setting SQLite shared cache mode failed");
+
+const wxChar* wxERRMSG_INITIALIZE = wxTRANSLATE("Initialization of SQLite failed");
+const wxChar* wxERRMSG_SHUTDOWN = wxTRANSLATE("Shutdown of SQLite failed");
+
+const wxChar* wxERRMSG_SOURCEDB_BUSY = wxTRANSLATE("Source database is busy");
+const wxChar* wxERRMSG_DBOPEN_FAILED = wxTRANSLATE("Database open failed");
+const wxChar* wxERRMSG_DBASSIGN_FAILED = wxTRANSLATE("Database assignment failed");
+#endif
+
+// ----------------------------------------------------------------------------
+// inline conversion from wxString to wxLongLong
+// ----------------------------------------------------------------------------
+
+inline wxLongLong ConvertStringToLongLong(const wxString& str, wxLongLong defValue /*=0*/)
+{
+ size_t n = str.Length();
+ size_t j = 0;
+ wxLongLong value = 0;
+ bool negative = false;
+
+ if (str[j] == '-')
+ {
+ negative = true;
+ j++;
+ }
+
+ while (j < n)
+ {
+ if (str[j] < '0' || str[j] > '9')
+ {
+ return defValue;
+ }
+ value *= 10;
+ value += (str[j] - '0');
+ j++;
+ }
+
+ return negative ? -value : value;
+}
+
+// ----------------------------------------------------------------------------
+// wxSQLite3Exception: class
+// ----------------------------------------------------------------------------
+
+wxSQLite3Exception::wxSQLite3Exception(int errorCode, const wxString& errorMsg)
+ : m_errorCode(errorCode)
+{
+ m_errorMessage = ErrorCodeAsString(errorCode) + wxT("[") +
+ wxString::Format(wxT("%d"), errorCode) + wxT("]: ") +
+ wxGetTranslation(errorMsg);
+}
+
+wxSQLite3Exception::wxSQLite3Exception(const wxSQLite3Exception& e)
+ : m_errorCode(e.m_errorCode), m_errorMessage(e.m_errorMessage)
+{
+}
+
+const wxString wxSQLite3Exception::ErrorCodeAsString(int errorCode)
+{
+ switch (errorCode)
+ {
+ case SQLITE_OK : return wxT("SQLITE_OK");
+ case SQLITE_ERROR : return wxT("SQLITE_ERROR");
+ case SQLITE_INTERNAL : return wxT("SQLITE_INTERNAL");
+ case SQLITE_PERM : return wxT("SQLITE_PERM");
+ case SQLITE_ABORT : return wxT("SQLITE_ABORT");
+ case SQLITE_BUSY : return wxT("SQLITE_BUSY");
+ case SQLITE_LOCKED : return wxT("SQLITE_LOCKED");
+ case SQLITE_NOMEM : return wxT("SQLITE_NOMEM");
+ case SQLITE_READONLY : return wxT("SQLITE_READONLY");
+ case SQLITE_INTERRUPT : return wxT("SQLITE_INTERRUPT");
+ case SQLITE_IOERR : return wxT("SQLITE_IOERR");
+ case SQLITE_CORRUPT : return wxT("SQLITE_CORRUPT");
+ case SQLITE_NOTFOUND : return wxT("SQLITE_NOTFOUND");
+ case SQLITE_FULL : return wxT("SQLITE_FULL");
+ case SQLITE_CANTOPEN : return wxT("SQLITE_CANTOPEN");
+ case SQLITE_PROTOCOL : return wxT("SQLITE_PROTOCOL");
+ case SQLITE_EMPTY : return wxT("SQLITE_EMPTY");
+ case SQLITE_SCHEMA : return wxT("SQLITE_SCHEMA");
+ case SQLITE_TOOBIG : return wxT("SQLITE_TOOBIG");
+ case SQLITE_CONSTRAINT : return wxT("SQLITE_CONSTRAINT");
+ case SQLITE_MISMATCH : return wxT("SQLITE_MISMATCH");
+ case SQLITE_MISUSE : return wxT("SQLITE_MISUSE");
+ case SQLITE_NOLFS : return wxT("SQLITE_NOLFS");
+ case SQLITE_AUTH : return wxT("SQLITE_AUTH");
+ case SQLITE_FORMAT : return wxT("SQLITE_FORMAT");
+ case SQLITE_RANGE : return wxT("SQLITE_RANGE");
+ case SQLITE_NOTADB : return wxT("SQLITE_NOTADB");
+ case SQLITE_ROW : return wxT("SQLITE_ROW");
+ case SQLITE_DONE : return wxT("SQLITE_DONE");
+ // Extended error codes
+ case SQLITE_IOERR_READ : return wxT("SQLITE_IOERR_READ");
+ case SQLITE_IOERR_SHORT_READ : return wxT("SQLITE_IOERR_SHORT_READ");
+ case SQLITE_IOERR_WRITE : return wxT("SQLITE_IOERR_WRITE");
+ case SQLITE_IOERR_FSYNC : return wxT("SQLITE_IOERR_FSYNC");
+ case SQLITE_IOERR_DIR_FSYNC : return wxT("SQLITE_IOERR_DIR_FSYNC");
+ case SQLITE_IOERR_TRUNCATE : return wxT("SQLITE_IOERR_TRUNCATE");
+ case SQLITE_IOERR_FSTAT : return wxT("SQLITE_IOERR_FSTAT");
+ case SQLITE_IOERR_UNLOCK : return wxT("SQLITE_IOERR_UNLOCK");
+ case SQLITE_IOERR_RDLOCK : return wxT("SQLITE_IOERR_RDLOCK");
+ case SQLITE_IOERR_DELETE : return wxT("SQLITE_IOERR_DELETE");
+#if SQLITE_VERSION_NUMBER >= 3004000
+ case SQLITE_IOERR_BLOCKED : return wxT("SQLITE_IOERR_BLOCKED");
+#endif
+#if SQLITE_VERSION_NUMBER >= 3005001
+ case SQLITE_IOERR_NOMEM : return wxT("SQLITE_IOERR_NOMEM");
+#endif
+#if SQLITE_VERSION_NUMBER >= 3006000
+ case SQLITE_IOERR_ACCESS : return wxT("SQLITE_IOERR_ACCESS");
+ case SQLITE_IOERR_CHECKRESERVEDLOCK : return wxT("SQLITE_IOERR_CHECKRESERVEDLOCK");
+#endif
+#if SQLITE_VERSION_NUMBER >= 3006002
+ case SQLITE_IOERR_LOCK : return wxT("SQLITE_IOERR_LOCK");
+#endif
+#if SQLITE_VERSION_NUMBER >= 3006007
+ case SQLITE_IOERR_CLOSE : return wxT("SQLITE_IOERR_CLOSE");
+ case SQLITE_IOERR_DIR_CLOSE : return wxT("SQLITE_IOERR_DIR_CLOSE");
+#endif
+#if SQLITE_VERSION_NUMBER >= 3007000
+ case SQLITE_IOERR_SHMOPEN : return wxT("SQLITE_IOERR_SHMOPEN");
+ case SQLITE_IOERR_SHMSIZE : return wxT("SQLITE_IOERR_SHMSIZE");
+ case SQLITE_IOERR_SHMLOCK : return wxT("SQLITE_IOERR_SHMLOCK");
+ case SQLITE_LOCKED_SHAREDCACHE : return wxT("SQLITE_LOCKED_SHAREDCACHE");
+ case SQLITE_BUSY_RECOVERY : return wxT("SQLITE_BUSY_RECOVERY");
+ case SQLITE_CANTOPEN_NOTEMPDIR : return wxT("SQLITE_CANTOPEN_NOTEMPDIR");
+#endif
+
+ case WXSQLITE_ERROR : return wxT("WXSQLITE_ERROR");
+ default : return wxT("UNKNOWN_ERROR");
+ }
+}
+
+wxSQLite3Exception::~wxSQLite3Exception()
+{
+}
+
+// ----------------------------------------------------------------------------
+// wxSQLite3StatementBuffer: class providing a statement buffer
+// for use with the SQLite3 vmprintf function
+// ----------------------------------------------------------------------------
+
+wxSQLite3StatementBuffer::wxSQLite3StatementBuffer()
+{
+ m_buffer = 0;
+}
+
+wxSQLite3StatementBuffer::~wxSQLite3StatementBuffer()
+{
+ Clear();
+}
+
+void wxSQLite3StatementBuffer::Clear()
+{
+ if (m_buffer)
+ {
+ sqlite3_free(m_buffer);
+ m_buffer = 0;
+ }
+
+}
+
+const char* wxSQLite3StatementBuffer::Format(const char* format, ...)
+{
+ Clear();
+ va_list va;
+ va_start(va, format);
+ m_buffer = sqlite3_vmprintf(format, va);
+ va_end(va);
+ return m_buffer;
+}
+
+const char* wxSQLite3StatementBuffer::FormatV(const char* format, va_list va)
+{
+ Clear();
+ m_buffer = sqlite3_vmprintf(format, va);
+ return m_buffer;
+}
+
+// ----------------------------------------------------------------------------
+// wxSQLite3ResultSet: class providing access to the result set of a query
+// ----------------------------------------------------------------------------
+
+wxSQLite3ResultSet::wxSQLite3ResultSet()
+{
+ m_db = 0;
+ m_stmt = 0;
+ m_eof = true;
+ m_first = true;
+ m_cols = 0;
+ m_ownStmt = false;
+}
+
+wxSQLite3ResultSet::wxSQLite3ResultSet(const wxSQLite3ResultSet& resultSet)
+{
+ m_db = resultSet.m_db;
+ m_stmt = resultSet.m_stmt;
+ // Only one object can own the statement
+ const_cast<wxSQLite3ResultSet&>(resultSet).m_stmt = 0;
+ m_eof = resultSet.m_eof;
+ m_first = resultSet.m_first;
+ m_cols = resultSet.m_cols;
+ m_ownStmt = resultSet.m_ownStmt;
+}
+
+wxSQLite3ResultSet::wxSQLite3ResultSet(void* db,
+ void* stmt,
+ bool eof,
+ bool first,
+ bool ownStmt /*=true*/)
+{
+ m_db = db;
+ m_stmt = stmt;
+ m_eof = eof;
+ m_first = first;
+ m_cols = sqlite3_column_count((sqlite3_stmt*) m_stmt);
+ m_ownStmt = ownStmt;
+}
+
+wxSQLite3ResultSet::~wxSQLite3ResultSet()
+{
+ try
+ {
+ Finalize();
+ }
+ catch (...)
+ {
+ }
+}
+
+wxSQLite3ResultSet& wxSQLite3ResultSet::operator=(const wxSQLite3ResultSet& resultSet)
+{
+ if (this != &resultSet)
+ {
+ try
+ {
+ Finalize();
+ }
+ catch (...)
+ {
+ }
+ m_db = resultSet.m_db;
+ m_stmt = resultSet.m_stmt;
+ // Only one object can own the statement
+ const_cast<wxSQLite3ResultSet&>(resultSet).m_stmt = 0;
+ m_eof = resultSet.m_eof;
+ m_first = resultSet.m_first;
+ m_cols = resultSet.m_cols;
+ m_ownStmt = resultSet.m_ownStmt;
+ }
+ return *this;
+}
+
+int wxSQLite3ResultSet::GetColumnCount()
+{
+ CheckStmt();
+ return m_cols;
+}
+
+wxString wxSQLite3ResultSet::GetAsString(int columnIndex)
+{
+ CheckStmt();
+
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, wxEmptyString);
+ }
+
+ const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
+ return wxString::FromUTF8(localValue);
+}
+
+wxString wxSQLite3ResultSet::GetAsString(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
+ return wxString::FromUTF8(localValue);
+}
+
+int wxSQLite3ResultSet::GetInt(int columnIndex, int nullValue /* = 0 */)
+{
+ if (GetColumnType(columnIndex) == SQLITE_NULL)
+ {
+ return nullValue;
+ }
+ else
+ {
+ return sqlite3_column_int((sqlite3_stmt*) m_stmt, columnIndex);
+ }
+}
+
+
+int wxSQLite3ResultSet::GetInt(const wxString& columnName, int nullValue /* = 0 */)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetInt(columnIndex, nullValue);
+}
+
+wxLongLong wxSQLite3ResultSet::GetInt64(int columnIndex, wxLongLong nullValue /* = 0 */)
+{
+ if (GetColumnType(columnIndex) == SQLITE_NULL)
+ {
+ return nullValue;
+ }
+ else
+ {
+ return wxLongLong(sqlite3_column_int64((sqlite3_stmt*) m_stmt, columnIndex));
+ }
+}
+
+wxLongLong wxSQLite3ResultSet::GetInt64(const wxString& columnName, wxLongLong nullValue /* = 0 */)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetInt64(columnIndex, nullValue);
+}
+
+double wxSQLite3ResultSet::GetDouble(int columnIndex, double nullValue /* = 0.0 */)
+{
+ if (GetColumnType(columnIndex) == SQLITE_NULL)
+ {
+ return nullValue;
+ }
+ else
+ {
+ return sqlite3_column_double((sqlite3_stmt*) m_stmt, columnIndex);
+ }
+}
+
+double wxSQLite3ResultSet::GetDouble(const wxString& columnName, double nullValue /* = 0.0 */)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetDouble(columnIndex, nullValue);
+}
+
+wxString wxSQLite3ResultSet::GetString(int columnIndex, const wxString& nullValue /* = wxEmptyString */)
+{
+ if (GetColumnType(columnIndex) == SQLITE_NULL)
+ {
+ return nullValue;
+ }
+ else
+ {
+ const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
+ return wxString::FromUTF8(localValue);
+ }
+}
+
+wxString wxSQLite3ResultSet::GetString(const wxString& columnName, const wxString& nullValue /* = wxEmptyString */)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetString(columnIndex, nullValue);
+}
+
+const unsigned char* wxSQLite3ResultSet::GetBlob(int columnIndex, int& len)
+{
+ CheckStmt();
+
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, NULL);
+ }
+
+ len = sqlite3_column_bytes((sqlite3_stmt*) m_stmt, columnIndex);
+ return (const unsigned char*) sqlite3_column_blob((sqlite3_stmt*) m_stmt, columnIndex);
+}
+
+const unsigned char* wxSQLite3ResultSet::GetBlob(const wxString& columnName, int& len)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetBlob(columnIndex, len);
+}
+
+wxMemoryBuffer& wxSQLite3ResultSet::GetBlob(int columnIndex, wxMemoryBuffer& buffer)
+{
+ CheckStmt();
+
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, buffer);
+ }
+
+ int len = sqlite3_column_bytes((sqlite3_stmt*) m_stmt, columnIndex);
+ const void* blob = sqlite3_column_blob((sqlite3_stmt*) m_stmt, columnIndex);
+ buffer.AppendData((void*) blob, (size_t) len);
+ return buffer;
+}
+
+wxMemoryBuffer& wxSQLite3ResultSet::GetBlob(const wxString& columnName, wxMemoryBuffer& buffer)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetBlob(columnIndex, buffer);
+}
+
+wxDateTime wxSQLite3ResultSet::GetDate(int columnIndex)
+{
+ if (GetColumnType(columnIndex) == SQLITE_NULL)
+ {
+ return wxInvalidDateTime;
+ }
+ else
+ {
+ wxDateTime date;
+ const wxChar* result = date.ParseDate(GetString(columnIndex));
+ if (result != NULL)
+ {
+ return date;
+ }
+ else
+ {
+ return wxInvalidDateTime;
+ }
+ }
+}
+
+wxDateTime wxSQLite3ResultSet::GetDate(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetDate(columnIndex);
+}
+
+
+wxDateTime wxSQLite3ResultSet::GetTime(int columnIndex)
+{
+ if (GetColumnType(columnIndex) == SQLITE_NULL)
+ {
+ return wxInvalidDateTime;
+ }
+ else
+ {
+ wxDateTime date;
+ const wxChar* result = date.ParseTime(GetString(columnIndex));
+ if (result != NULL)
+ {
+ return date;
+ }
+ else
+ {
+ return wxInvalidDateTime;
+ }
+ }
+}
+
+wxDateTime wxSQLite3ResultSet::GetTime(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetTime(columnIndex);
+}
+
+wxDateTime wxSQLite3ResultSet::GetDateTime(int columnIndex)
+{
+ if (GetColumnType(columnIndex) == SQLITE_NULL)
+ {
+ return wxInvalidDateTime;
+ }
+ else
+ {
+ wxDateTime date;
+ const wxChar* result = date.ParseDateTime(GetString(columnIndex));
+ if (result != NULL)
+ {
+ date.SetMillisecond(0);
+ return date;
+ }
+ else
+ {
+ return wxInvalidDateTime;
+ }
+ }
+}
+
+wxDateTime wxSQLite3ResultSet::GetDateTime(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetDateTime(columnIndex);
+}
+
+wxDateTime wxSQLite3ResultSet::GetTimestamp(int columnIndex)
+{
+ if (GetColumnType(columnIndex) == SQLITE_NULL)
+ {
+ return wxInvalidDateTime;
+ }
+ else
+ {
+ wxDateTime date;
+ const wxChar* result = date.ParseDateTime(GetString(columnIndex));
+ if (result != NULL)
+ {
+ return date;
+ }
+ else
+ {
+ return wxInvalidDateTime;
+ }
+ }
+}
+
+wxDateTime wxSQLite3ResultSet::GetTimestamp(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetTimestamp(columnIndex);
+}
+
+wxDateTime wxSQLite3ResultSet::GetNumericDateTime(int columnIndex)
+{
+ if (GetColumnType(columnIndex) == SQLITE_NULL)
+ {
+ return wxInvalidDateTime;
+ }
+ else
+ {
+ wxLongLong value = GetInt64(columnIndex);
+ return wxDateTime(value);
+ }
+}
+
+wxDateTime wxSQLite3ResultSet::GetNumericDateTime(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetNumericDateTime(columnIndex);
+}
+
+wxDateTime wxSQLite3ResultSet::GetJulianDayNumber(int columnIndex)
+{
+ if (GetColumnType(columnIndex) == SQLITE_NULL)
+ {
+ return wxInvalidDateTime;
+ }
+ else
+ {
+ double value = GetDouble(columnIndex);
+ return wxDateTime(value);
+ }
+}
+
+wxDateTime wxSQLite3ResultSet::GetJulianDayNumber(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetJulianDayNumber(columnIndex);
+}
+
+bool wxSQLite3ResultSet::GetBool(int columnIndex)
+{
+ return GetInt(columnIndex) != 0;
+}
+
+bool wxSQLite3ResultSet::GetBool(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetBool(columnIndex);
+}
+
+bool wxSQLite3ResultSet::IsNull(int columnIndex)
+{
+ return (GetColumnType(columnIndex) == SQLITE_NULL);
+}
+
+bool wxSQLite3ResultSet::IsNull(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return (GetColumnType(columnIndex) == SQLITE_NULL);
+}
+
+int wxSQLite3ResultSet::FindColumnIndex(const wxString& columnName)
+{
+ CheckStmt();
+
+ wxCharBuffer strColumnName = columnName.ToUTF8();
+ const char* localColumnName = strColumnName;
+
+ if (columnName.Len() > 0)
+ {
+ for (int columnIndex = 0; columnIndex < m_cols; columnIndex++)
+ {
+ const char* temp = sqlite3_column_name((sqlite3_stmt*) m_stmt, columnIndex);
+
+ if (strcmp(localColumnName, temp) == 0)
+ {
+ return columnIndex;
+ }
+ }
+ }
+
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, -1);
+}
+
+wxString wxSQLite3ResultSet::GetColumnName(int columnIndex)
+{
+ CheckStmt();
+
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, wxEmptyString);
+ }
+
+ const char* localValue = sqlite3_column_name((sqlite3_stmt*) m_stmt, columnIndex);
+ return wxString::FromUTF8(localValue);
+}
+
+wxString wxSQLite3ResultSet::GetDeclaredColumnType(int columnIndex)
+{
+ CheckStmt();
+
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, wxEmptyString);
+ }
+
+ const char* localValue = sqlite3_column_decltype((sqlite3_stmt*) m_stmt, columnIndex);
+ return wxString::FromUTF8(localValue);
+}
+
+int wxSQLite3ResultSet::GetColumnType(int columnIndex)
+{
+ CheckStmt();
+
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, -1);
+ }
+
+ return sqlite3_column_type((sqlite3_stmt*) m_stmt, columnIndex);
+}
+
+bool wxSQLite3ResultSet::Eof()
+{
+ CheckStmt();
+ return m_eof;
+}
+
+bool wxSQLite3ResultSet::NextRow()
+{
+ CheckStmt();
+
+ int rc;
+ if (m_first)
+ {
+ m_first = false;
+ rc = (m_eof) ? SQLITE_DONE : SQLITE_ROW;
+ }
+ else
+ {
+ rc = sqlite3_step((sqlite3_stmt*) m_stmt);
+ }
+
+ if (rc == SQLITE_DONE) // no more rows
+ {
+ m_eof = true;
+ return false;
+ }
+ else if (rc == SQLITE_ROW) // more rows
+ {
+ return true;
+ }
+ else
+ {
+ rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
+ m_stmt = 0;
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), false);
+ }
+}
+
+void wxSQLite3ResultSet::Finalize()
+{
+ if (m_stmt && m_ownStmt)
+ {
+ int rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
+ m_stmt = 0;
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+ }
+}
+
+wxString wxSQLite3ResultSet::GetSQL()
+{
+ wxString sqlString = wxEmptyString;
+#if SQLITE_VERSION_NUMBER >= 3005003
+ CheckStmt();
+ const char* sqlLocal = sqlite3_sql((sqlite3_stmt*) m_stmt);
+ if (sqlLocal != NULL) sqlString = wxString::FromUTF8(sqlLocal);
+#endif
+ return sqlString;
+}
+
+bool wxSQLite3ResultSet::IsOk()
+{
+ return (m_db != 0) && (m_stmt != 0);
+}
+
+void wxSQLite3ResultSet::CheckStmt()
+{
+ if (m_stmt == 0)
+ {
+ return;
+ }
+}
+
+wxString wxSQLite3ResultSet::GetDatabaseName(int columnIndex)
+{
+#if WXSQLITE3_HAVE_METADATA
+ CheckStmt();
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, wxEmptyString);
+ }
+
+ const char* localValue = sqlite3_column_database_name((sqlite3_stmt*) m_stmt, columnIndex);
+ if (localValue != NULL)
+ return wxString::FromUTF8(localValue);
+ else
+ return wxEmptyString;
+#else
+ wxUnusedVar(columnIndex);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOMETADATA, wxEmptyString);
+#endif
+}
+
+wxString wxSQLite3ResultSet::GetTableName(int columnIndex)
+{
+#if WXSQLITE3_HAVE_METADATA
+ CheckStmt();
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, wxEmptyString);
+ }
+
+ const char* localValue = sqlite3_column_table_name((sqlite3_stmt*) m_stmt, columnIndex);
+ if (localValue != NULL)
+ return wxString::FromUTF8(localValue);
+ else
+ return wxEmptyString;
+#else
+ wxUnusedVar(columnIndex);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOMETADATA, wxEmptyString);
+#endif
+}
+
+wxString wxSQLite3ResultSet::GetOriginName(int columnIndex)
+{
+#if WXSQLITE3_HAVE_METADATA
+ CheckStmt();
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, wxEmptyString);
+ }
+
+ const char* localValue = sqlite3_column_origin_name((sqlite3_stmt*) m_stmt, columnIndex);
+ if (localValue != NULL)
+ return wxString::FromUTF8(localValue);
+ else
+ return wxEmptyString;
+#else
+ wxUnusedVar(columnIndex);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOMETADATA, wxEmptyString);
+#endif
+}
+
+// ----------------------------------------------------------------------------
+// wxSQLite3Table: class holding the complete result set of a query
+// ----------------------------------------------------------------------------
+
+wxSQLite3Table::wxSQLite3Table()
+{
+ m_results = 0;
+ m_rows = 0;
+ m_cols = 0;
+ m_currentRow = 0;
+}
+
+wxSQLite3Table::wxSQLite3Table(const wxSQLite3Table& table)
+{
+ m_results = table.m_results;
+ // Only one object can own the results
+ const_cast<wxSQLite3Table&>(table).m_results = 0;
+ m_rows = table.m_rows;
+ m_cols = table.m_cols;
+ m_currentRow = table.m_currentRow;
+}
+
+wxSQLite3Table::wxSQLite3Table(char** results, int rows, int cols)
+{
+ m_results = results;
+ m_rows = rows;
+ m_cols = cols;
+ m_currentRow = 0;
+}
+
+wxSQLite3Table::~wxSQLite3Table()
+{
+ try
+ {
+ Finalize();
+ }
+ catch (...)
+ {
+ }
+}
+
+wxSQLite3Table& wxSQLite3Table::operator=(const wxSQLite3Table& table)
+{
+ if (this != &table)
+ {
+ try
+ {
+ Finalize();
+ }
+ catch (...)
+ {
+ }
+ m_results = table.m_results;
+ // Only one object can own the results
+ const_cast<wxSQLite3Table&>(table).m_results = 0;
+ m_rows = table.m_rows;
+ m_cols = table.m_cols;
+ m_currentRow = table.m_currentRow;
+ }
+ return *this;
+}
+
+void wxSQLite3Table::Finalize()
+{
+ if (m_results)
+ {
+ sqlite3_free_table(m_results);
+ m_results = 0;
+ }
+}
+
+int wxSQLite3Table::GetColumnCount()
+{
+ CheckResults();
+ return m_cols;
+}
+
+int wxSQLite3Table::GetRowCount()
+{
+ CheckResults();
+ return m_rows;
+}
+
+int wxSQLite3Table::FindColumnIndex(const wxString& columnName)
+{
+ CheckResults();
+
+ wxCharBuffer strColumnName = columnName.ToUTF8();
+ const char* localColumnName = strColumnName;
+
+ if (columnName.Len() > 0)
+ {
+ for (int columnIndex = 0; columnIndex < m_cols; columnIndex++)
+ {
+ if (strcmp(localColumnName, m_results[columnIndex]) == 0)
+ {
+ return columnIndex;
+ }
+ }
+ }
+
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_NAME, -1);
+}
+
+wxString wxSQLite3Table::GetAsString(int columnIndex)
+{
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, wxEmptyString);
+ }
+
+ int nIndex = (m_currentRow*m_cols) + m_cols + columnIndex;
+ const char* localValue = m_results[nIndex];
+ return wxString::FromUTF8(localValue);
+}
+
+wxString wxSQLite3Table::GetAsString(const wxString& columnName)
+{
+ int index = FindColumnIndex(columnName);
+ return GetAsString(index);
+}
+
+int wxSQLite3Table::GetInt(int columnIndex, int nullValue /* = 0 */)
+{
+ if (IsNull(columnIndex))
+ {
+ return nullValue;
+ }
+ else
+ {
+ long value = nullValue;
+ GetAsString(columnIndex).ToLong(&value);
+ return (int) value;
+ }
+}
+
+int wxSQLite3Table::GetInt(const wxString& columnName, int nullValue /* = 0 */)
+{
+ if (IsNull(columnName))
+ {
+ return nullValue;
+ }
+ else
+ {
+ long value = nullValue;
+ GetAsString(columnName).ToLong(&value);
+ return (int) value;
+ }
+}
+
+wxLongLong wxSQLite3Table::GetInt64(int columnIndex, wxLongLong nullValue /* = 0 */)
+{
+ if (IsNull(columnIndex))
+ {
+ return nullValue;
+ }
+ else
+ {
+ return ConvertStringToLongLong(GetAsString(columnIndex), nullValue);
+ }
+}
+
+wxLongLong wxSQLite3Table::GetInt64(const wxString& columnName, wxLongLong nullValue /* = 0 */)
+{
+ if (IsNull(columnName))
+ {
+ return nullValue;
+ }
+ else
+ {
+ return ConvertStringToLongLong(GetAsString(columnName), nullValue);
+ }
+}
+
+// Since SQLite uses internally a locale independent string representation
+// of double values, we need to provide our own conversion procedure using
+// always a point as the decimal separator.
+// The following code duplicates a SQLite utility function with minor modifications.
+
+static double wxSQLite3AtoF(const char *z)
+{
+ int sign = 1;
+ long double v1 = 0.0;
+ int nSignificant = 0;
+ while (isspace(*(unsigned char*)z))
+ {
+ ++z;
+ }
+ if (*z == '-')
+ {
+ sign = -1;
+ ++z;
+ }
+ else if (*z == '+')
+ {
+ ++z;
+ }
+ while (*z == '0')
+ {
+ ++z;
+ }
+ while (isdigit(*(unsigned char*)z))
+ {
+ v1 = v1*10.0 + (*z - '0');
+ ++z;
+ ++nSignificant;
+ }
+ if (*z == '.')
+ {
+ long double divisor = 1.0;
+ ++z;
+ if (nSignificant == 0)
+ {
+ while (*z == '0')
+ {
+ divisor *= 10.0;
+ ++z;
+ }
+ }
+ while (isdigit(*(unsigned char*)z))
+ {
+ if (nSignificant < 18)
+ {
+ v1 = v1*10.0 + (*z - '0');
+ divisor *= 10.0;
+ ++nSignificant;
+ }
+ ++z;
+ }
+ v1 /= divisor;
+ }
+ if (*z=='e' || *z=='E')
+ {
+ int esign = 1;
+ int eval = 0;
+ long double scale = 1.0;
+ ++z;
+ if (*z == '-')
+ {
+ esign = -1;
+ ++z;
+ }
+ else if (*z == '+')
+ {
+ ++z;
+ }
+ while (isdigit(*(unsigned char*)z))
+ {
+ eval = eval*10 + *z - '0';
+ ++z;
+ }
+ while (eval >= 64) { scale *= 1.0e+64; eval -= 64; }
+ while (eval >= 16) { scale *= 1.0e+16; eval -= 16; }
+ while (eval >= 4) { scale *= 1.0e+4; eval -= 4; }
+ while (eval >= 1) { scale *= 1.0e+1; eval -= 1; }
+ if (esign < 0)
+ {
+ v1 /= scale;
+ }
+ else
+ {
+ v1 *= scale;
+ }
+ }
+ return (double) ((sign < 0) ? -v1 : v1);
+}
+
+double wxSQLite3Table::GetDouble(int columnIndex, double nullValue /* = 0.0 */)
+{
+ if (IsNull(columnIndex))
+ {
+ return nullValue;
+ }
+ else
+ {
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, nullValue);
+ }
+ int nIndex = (m_currentRow*m_cols) + m_cols + columnIndex;
+ return wxSQLite3AtoF(m_results[nIndex]);
+ }
+}
+
+double wxSQLite3Table::GetDouble(const wxString& columnName, double nullValue /* = 0.0 */)
+{
+ int index = FindColumnIndex(columnName);
+ return GetDouble(index, nullValue);
+}
+
+wxString wxSQLite3Table::GetString(int columnIndex, const wxString& nullValue /* = wxEmptyString */)
+{
+ if (IsNull(columnIndex))
+ {
+ return nullValue;
+ }
+ else
+ {
+ return GetAsString(columnIndex);
+ }
+}
+
+wxString wxSQLite3Table::GetString(const wxString& columnName, const wxString& nullValue /* = wxEmptyString */)
+{
+ if (IsNull(columnName))
+ {
+ return nullValue;
+ }
+ else
+ {
+ return GetAsString(columnName);
+ }
+}
+
+wxDateTime wxSQLite3Table::GetDate(int columnIndex)
+{
+ wxDateTime date;
+ const wxChar* result = date.ParseDate(GetString(columnIndex));
+ if (result != NULL)
+ {
+ return date;
+ }
+ else
+ {
+ return wxInvalidDateTime;
+ }
+}
+
+wxDateTime wxSQLite3Table::GetDate(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetDate(columnIndex);
+}
+
+wxDateTime wxSQLite3Table::GetTime(int columnIndex)
+{
+ wxDateTime date;
+ const wxChar* result = date.ParseTime(GetString(columnIndex));
+ if (result != NULL)
+ {
+ return date;
+ }
+ else
+ {
+ return wxInvalidDateTime;
+ }
+}
+
+wxDateTime wxSQLite3Table::GetTime(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetTime(columnIndex);
+}
+
+wxDateTime wxSQLite3Table::GetDateTime(int columnIndex)
+{
+ wxDateTime date;
+ const wxChar* result = date.ParseDateTime(GetString(columnIndex));
+ if (result != NULL)
+ {
+ return date;
+ }
+ else
+ {
+ return wxInvalidDateTime;
+ }
+}
+
+wxDateTime wxSQLite3Table::GetDateTime(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetDateTime(columnIndex);
+}
+
+bool wxSQLite3Table::GetBool(int columnIndex)
+{
+ return GetInt(columnIndex) != 0;
+}
+
+bool wxSQLite3Table::GetBool(const wxString& columnName)
+{
+ int columnIndex = FindColumnIndex(columnName);
+ return GetBool(columnIndex);
+}
+
+bool wxSQLite3Table::IsNull(int columnIndex)
+{
+ CheckResults();
+
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, false);
+ }
+
+ int index = (m_currentRow*m_cols) + m_cols + columnIndex;
+ const char* localValue = m_results[index];
+ return (localValue == 0);
+}
+
+bool wxSQLite3Table::IsNull(const wxString& columnName)
+{
+ int index = FindColumnIndex(columnName);
+ return IsNull(index);
+}
+
+wxString wxSQLite3Table::GetColumnName(int columnIndex)
+{
+ CheckResults();
+
+ if (columnIndex < 0 || columnIndex > m_cols-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX, wxEmptyString);
+ }
+
+ const char* localValue = m_results[columnIndex];
+ return wxString::FromUTF8(localValue);
+}
+
+void wxSQLite3Table::SetRow(int row)
+{
+ CheckResults();
+
+ if (row < 0 || row > m_rows-1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_ROW, );
+ }
+
+ m_currentRow = row;
+}
+
+bool wxSQLite3Table::IsOk()
+{
+ return (m_results != 0);
+}
+
+void wxSQLite3Table::CheckResults()
+{
+ if (m_results == 0)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NORESULT, );
+ }
+}
+
+// ----------------------------------------------------------------------------
+// wxSQLite3Statement: class holding a prepared statement
+// ----------------------------------------------------------------------------
+
+wxSQLite3Statement::wxSQLite3Statement()
+{
+ m_db = 0;
+ m_stmt = 0;
+ m_hasOwnership = false;
+}
+
+wxSQLite3Statement::wxSQLite3Statement(const wxSQLite3Statement& statement)
+{
+ m_db = statement.m_db;
+ m_stmt = statement.m_stmt;
+ m_hasOwnership = statement.m_hasOwnership;
+ // Only one object can own prepared statement
+ const_cast<wxSQLite3Statement&>(statement).m_hasOwnership = false;
+}
+
+wxSQLite3Statement::wxSQLite3Statement(void* db, void* stmt)
+{
+ m_db = db;
+ m_stmt = stmt;
+ m_hasOwnership = true;
+}
+
+wxSQLite3Statement::~wxSQLite3Statement()
+{
+ try
+ {
+ Finalize();
+ }
+ catch (...)
+ {
+ }
+}
+
+wxSQLite3Statement& wxSQLite3Statement::operator=(const wxSQLite3Statement& statement)
+{
+ if (this != &statement)
+ {
+ try
+ {
+ Finalize();
+ }
+ catch (...)
+ {
+ }
+ m_db = statement.m_db;
+ m_stmt = statement.m_stmt;
+ m_hasOwnership = statement.m_hasOwnership;
+ // Only one object can own prepared statement
+ const_cast<wxSQLite3Statement&>(statement).m_hasOwnership = false;
+ }
+ return *this;
+}
+
+int wxSQLite3Statement::ExecuteUpdate()
+{
+ CheckDatabase();
+ CheckStmt();
+
+ const char* localError=0;
+
+ int rc = sqlite3_step((sqlite3_stmt*) m_stmt);
+
+ if (rc == SQLITE_DONE)
+ {
+ int rowsChanged = sqlite3_changes((sqlite3*) m_db);
+
+ rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
+
+ if (rc != SQLITE_OK)
+ {
+ localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), -1);
+ }
+
+ return rowsChanged;
+ }
+ else
+ {
+ rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
+ localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), -1);
+ }
+}
+
+wxSQLite3ResultSet wxSQLite3Statement::ExecuteQuery(bool transferStatementOwnership)
+{
+ CheckDatabase();
+ CheckStmt();
+ if (transferStatementOwnership)
+ {
+ if (m_hasOwnership)
+ {
+ m_hasOwnership = false;
+ }
+ else
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOTOWNED, wxSQLite3ResultSet());
+ }
+ }
+
+ int rc = sqlite3_step((sqlite3_stmt*) m_stmt);
+
+ if (rc == SQLITE_DONE) // no more rows
+ {
+ return wxSQLite3ResultSet(m_db, m_stmt, true/*eof*/, true/*first*/, transferStatementOwnership);
+ }
+ else if (rc == SQLITE_ROW) // one or more rows
+ {
+ return wxSQLite3ResultSet(m_db, m_stmt, false/*eof*/, true/*first*/, transferStatementOwnership);
+ }
+ else
+ {
+ rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), wxSQLite3ResultSet());
+ }
+}
+
+int wxSQLite3Statement::GetParamCount()
+{
+ CheckStmt();
+ return sqlite3_bind_parameter_count((sqlite3_stmt*) m_stmt);
+}
+
+int wxSQLite3Statement::GetParamIndex(const wxString& paramName)
+{
+ CheckStmt();
+
+ wxCharBuffer strParamName = paramName.ToUTF8();
+ const char* localParamName = strParamName;
+
+ return sqlite3_bind_parameter_index((sqlite3_stmt*) m_stmt, localParamName);
+}
+
+wxString wxSQLite3Statement::GetParamName(int paramIndex)
+{
+ CheckStmt();
+ const char* localParamName = sqlite3_bind_parameter_name((sqlite3_stmt*) m_stmt, paramIndex);
+ return wxString::FromUTF8(localParamName);
+}
+
+void wxSQLite3Statement::Bind(int paramIndex, const wxString& stringValue)
+{
+ CheckStmt();
+
+ wxCharBuffer strStringValue = stringValue.ToUTF8();
+ const char* localStringValue = strStringValue;
+
+ int rc = sqlite3_bind_text((sqlite3_stmt*) m_stmt, paramIndex, localStringValue, -1, SQLITE_TRANSIENT);
+
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_BIND_STR, );
+ }
+}
+
+void wxSQLite3Statement::Bind(int paramIndex, int intValue)
+{
+ CheckStmt();
+ int rc = sqlite3_bind_int((sqlite3_stmt*) m_stmt, paramIndex, intValue);
+
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_BIND_INT, );
+ }
+}
+
+void wxSQLite3Statement::Bind(int paramIndex, wxLongLong int64Value)
+{
+ CheckStmt();
+ int rc = sqlite3_bind_int64((sqlite3_stmt*) m_stmt, paramIndex, int64Value.GetValue());
+
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_BIND_INT64, );
+ }
+}
+
+void wxSQLite3Statement::Bind(int paramIndex, double doubleValue)
+{
+ CheckStmt();
+ int rc = sqlite3_bind_double((sqlite3_stmt*) m_stmt, paramIndex, doubleValue);
+
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_BIND_DBL, );
+ }
+}
+
+void wxSQLite3Statement::Bind(int paramIndex, const char* charValue)
+{
+ CheckStmt();
+ int rc = sqlite3_bind_text((sqlite3_stmt*) m_stmt, paramIndex, charValue, -1, SQLITE_TRANSIENT);
+
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_BIND_STR, );
+ }
+}
+
+void wxSQLite3Statement::Bind(int paramIndex, const unsigned char* blobValue, int blobLen)
+{
+ CheckStmt();
+ int rc = sqlite3_bind_blob((sqlite3_stmt*) m_stmt, paramIndex,
+ (const void*)blobValue, blobLen, SQLITE_TRANSIENT);
+
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_BIND_BLOB, );
+ }
+}
+
+void wxSQLite3Statement::Bind(int paramIndex, const wxMemoryBuffer& blobValue)
+{
+ CheckStmt();
+ int blobLen = (int) blobValue.GetDataLen();
+ int rc = sqlite3_bind_blob((sqlite3_stmt*) m_stmt, paramIndex,
+ (const void*)blobValue.GetData(), blobLen, SQLITE_TRANSIENT);
+
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_BIND_BLOB, );
+ }
+}
+
+void wxSQLite3Statement::BindDate(int paramIndex, const wxDateTime& date)
+{
+ if (date.IsValid())
+ {
+ Bind(paramIndex,date.FormatISODate());
+ }
+ else
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME, );
+ }
+}
+
+void wxSQLite3Statement::BindTime(int paramIndex, const wxDateTime& time)
+{
+ if (time.IsValid())
+ {
+ Bind(paramIndex,time.FormatISOTime());
+ }
+ else
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME, );
+ }
+}
+
+void wxSQLite3Statement::BindDateTime(int paramIndex, const wxDateTime& datetime)
+{
+ if (datetime.IsValid())
+ {
+ Bind(paramIndex,datetime.Format(wxT("%Y-%m-%d %H:%M:%S")));
+ }
+ else
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME, );
+ }
+}
+
+void wxSQLite3Statement::BindTimestamp(int paramIndex, const wxDateTime& timestamp)
+{
+ if (timestamp.IsValid())
+ {
+ Bind(paramIndex,timestamp.Format(wxT("%Y-%m-%d %H:%M:%S.%l")));
+ }
+ else
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME, );
+ }
+}
+
+void wxSQLite3Statement::BindNumericDateTime(int paramIndex, const wxDateTime& datetime)
+{
+ if (datetime.IsValid())
+ {
+ Bind(paramIndex, datetime.GetValue());
+ }
+ else
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME, );
+ }
+}
+
+void wxSQLite3Statement::BindJulianDayNumber(int paramIndex, const wxDateTime& datetime)
+{
+ if (datetime.IsValid())
+ {
+ Bind(paramIndex, datetime.GetJulianDayNumber());
+ }
+ else
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME, );
+ }
+}
+
+void wxSQLite3Statement::BindBool(int paramIndex, bool value)
+{
+ Bind(paramIndex, value ? 1 : 0);
+}
+
+void wxSQLite3Statement::BindNull(int paramIndex)
+{
+ CheckStmt();
+ int rc = sqlite3_bind_null((sqlite3_stmt*) m_stmt, paramIndex);
+
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_BIND_NULL, );
+ }
+}
+
+void wxSQLite3Statement::BindZeroBlob(int paramIndex, int blobSize)
+{
+#if SQLITE_VERSION_NUMBER >= 3004000
+ CheckStmt();
+ int rc = sqlite3_bind_zeroblob((sqlite3_stmt*) m_stmt, paramIndex, blobSize);
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_BIND_ZEROBLOB, );
+ }
+#else
+ wxUnusedVar(paramIndex);
+ wxUnusedVar(blobSize);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB, );
+#endif
+}
+
+void wxSQLite3Statement::ClearBindings()
+{
+ CheckStmt();
+#if 0 // missing in SQLite DLL
+ int rc = sqlite3_clear_bindings((sqlite3_stmt*) m_stmt);
+
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_BIND_CLEAR, );
+ }
+#else
+ for (int paramIndex = 1; paramIndex <= GetParamCount(); paramIndex++)
+ {
+ BindNull(paramIndex);
+ }
+#endif
+}
+
+wxString wxSQLite3Statement::GetSQL()
+{
+ wxString sqlString = wxEmptyString;
+#if SQLITE_VERSION_NUMBER >= 3005003
+ CheckStmt();
+ const char* sqlLocal = sqlite3_sql((sqlite3_stmt*) m_stmt);
+ if (sqlLocal != NULL) sqlString = wxString::FromUTF8(sqlLocal);
+#endif
+ return sqlString;
+}
+
+void wxSQLite3Statement::Reset()
+{
+ if (m_stmt)
+ {
+ int rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
+
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+ }
+}
+
+bool wxSQLite3Statement::IsReadOnly()
+{
+#if SQLITE_VERSION_NUMBER >= 3007004
+ CheckStmt();
+ return sqlite3_stmt_readonly((sqlite3_stmt*) m_stmt) != 0;
+#else
+ return false;
+#endif
+}
+
+void wxSQLite3Statement::Finalize()
+{
+ if (m_stmt && m_hasOwnership)
+ {
+ int rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
+ m_stmt = 0;
+ m_hasOwnership = false;
+
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+ }
+}
+
+bool wxSQLite3Statement::IsOk()
+{
+ return (m_db != 0) && (m_stmt != 0);
+}
+
+void wxSQLite3Statement::CheckDatabase()
+{
+ if (m_db == 0)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NODB, );
+ }
+}
+
+void wxSQLite3Statement::CheckStmt()
+{
+ if (m_stmt == 0)
+ {
+ return;
+ }
+}
+
+//
+
+wxSQLite3Blob::wxSQLite3Blob()
+{
+ m_db = NULL;
+ m_blob = NULL;
+ m_ok = false;
+ m_writable = false;
+}
+
+wxSQLite3Blob::wxSQLite3Blob(const wxSQLite3Blob& blob)
+{
+ m_db = blob.m_db;
+ m_blob = blob.m_blob;
+ m_ok = blob.m_ok;
+ m_writable = blob.m_writable;
+}
+
+wxSQLite3Blob& wxSQLite3Blob::operator=(const wxSQLite3Blob& blob)
+{
+ if (this != &blob)
+ {
+ try
+ {
+ Finalize();
+ }
+ catch (...)
+ {
+ }
+ m_db = blob.m_db;
+ m_blob = blob.m_blob;
+ m_ok = blob.m_ok;
+ m_writable = blob.m_writable;
+ // only one blob can own the blob handle
+ const_cast<wxSQLite3Blob&>(blob).m_ok = false;
+ }
+ return *this;
+}
+
+wxSQLite3Blob::wxSQLite3Blob(void* db, void* blobHandle, bool writable)
+{
+ m_db = db;
+ m_blob = blobHandle;
+ m_ok = true;
+ m_writable = writable;
+}
+
+wxSQLite3Blob::~wxSQLite3Blob()
+{
+ try
+ {
+ Finalize();
+ }
+ catch (...)
+ {
+ }
+}
+
+wxMemoryBuffer& wxSQLite3Blob::Read(wxMemoryBuffer& blobValue, int length, int offset)
+{
+#if SQLITE_VERSION_NUMBER >= 3004000
+ CheckBlob();
+ char* localBuffer = (char*) blobValue.GetAppendBuf((size_t) length);
+ int rc = sqlite3_blob_read((sqlite3_blob*) m_blob, localBuffer, length, offset);
+
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), blobValue);
+ }
+
+ blobValue.UngetAppendBuf((size_t) length);
+#else
+ wxUnusedVar(blobValue);
+ wxUnusedVar(length);
+ wxUnusedVar(offset);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB, blobValue);
+#endif
+ return blobValue;
+}
+
+void wxSQLite3Blob::Write(const wxMemoryBuffer& blobValue, int offset)
+{
+#if SQLITE_VERSION_NUMBER >= 3004000
+ CheckBlob();
+ if (m_writable)
+ {
+ int blobLen = (int) blobValue.GetDataLen();
+ int rc = sqlite3_blob_write((sqlite3_blob*) m_blob,
+ (const void*) blobValue.GetData(), blobLen, offset);
+
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+ }
+ else
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_BLOB, );
+ }
+#else
+ wxUnusedVar(blobValue);
+ wxUnusedVar(offset);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB, );
+#endif
+}
+
+bool wxSQLite3Blob::IsOk()
+{
+ return m_ok;
+}
+
+bool wxSQLite3Blob::IsReadOnly()
+{
+ return !m_writable;
+}
+
+int wxSQLite3Blob::GetSize()
+{
+#if SQLITE_VERSION_NUMBER >= 3004000
+ CheckBlob();
+ return sqlite3_blob_bytes((sqlite3_blob*) m_blob);
+#else
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB, 0);
+ return 0;
+#endif
+}
+
+void wxSQLite3Blob::Rebind(wxLongLong rowid)
+{
+#if SQLITE_VERSION_NUMBER >= 3007004
+ CheckBlob();
+ int rc = sqlite3_blob_reopen((sqlite3_blob*) m_blob, rowid.GetValue());
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+#else
+ wxUnusedVar(rowid);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOBLOBREBIND, );
+#endif
+}
+
+void wxSQLite3Blob::Finalize()
+{
+#if SQLITE_VERSION_NUMBER >= 3004000
+ if (m_ok)
+ {
+ int rc = sqlite3_blob_close((sqlite3_blob*) m_blob);
+ m_blob = NULL;
+ m_ok = false;
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+ }
+#else
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB, );
+#endif
+}
+
+void wxSQLite3Blob::CheckBlob()
+{
+ if (!m_ok)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_BLOB, );
+ }
+}
+
+// ----------------------------------------------------------------------------
+// wxSQLite3Database: class holding a SQLite3 database object
+// ----------------------------------------------------------------------------
+
+bool wxSQLite3Database::ms_sharedCacheEnabled = false;
+
+void
+wxSQLite3Database::SetSharedCache(bool enable)
+{
+ int flag = (enable) ? 1 : 0;
+ int rc = sqlite3_enable_shared_cache(flag);
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_SHARED_CACHE, );
+ }
+ ms_sharedCacheEnabled = enable;
+}
+
+#if WXSQLITE3_HAVE_CODEC
+bool wxSQLite3Database::ms_hasEncryptionSupport = true;
+#else
+bool wxSQLite3Database::ms_hasEncryptionSupport = false;
+#endif
+
+#if WXSQLITE3_HAVE_METADATA
+bool wxSQLite3Database::ms_hasMetaDataSupport = true;
+#else
+bool wxSQLite3Database::ms_hasMetaDataSupport = false;
+#endif
+
+#if WXSQLITE3_HAVE_LOAD_EXTENSION
+bool wxSQLite3Database::ms_hasLoadExtSupport = true;
+#else
+bool wxSQLite3Database::ms_hasLoadExtSupport = false;
+#endif
+
+#if WXSQLITE3_USE_NAMED_COLLECTIONS
+bool wxSQLite3Database::ms_hasNamedCollectionSupport = true;
+#else
+bool wxSQLite3Database::ms_hasNamedCollectionSupport = false;
+#endif
+
+#if SQLITE_VERSION_NUMBER >= 3004000
+bool wxSQLite3Database::ms_hasIncrementalBlobSupport = true;
+#else
+bool wxSQLite3Database::ms_hasIncrementalBlobSupport = false;
+#endif
+
+#if SQLITE_VERSION_NUMBER >= 3006008
+bool wxSQLite3Database::ms_hasSavepointSupport = true;
+#else
+bool wxSQLite3Database::ms_hasSavepointSupport = false;
+#endif
+
+#if SQLITE_VERSION_NUMBER >= 3006011
+bool wxSQLite3Database::ms_hasBackupSupport = true;
+#else
+bool wxSQLite3Database::ms_hasBackupSupport = false;
+#endif
+
+#if SQLITE_VERSION_NUMBER >= 3007000
+bool wxSQLite3Database::ms_hasWriteAheadLogSupport = true;
+#else
+bool wxSQLite3Database::ms_hasWriteAheadLogSupport = false;
+#endif
+
+bool
+wxSQLite3Database::HasEncryptionSupport()
+{
+ return ms_hasEncryptionSupport;
+}
+
+bool
+wxSQLite3Database::HasMetaDataSupport()
+{
+ return ms_hasMetaDataSupport;
+}
+
+bool
+wxSQLite3Database::HasLoadExtSupport()
+{
+ return ms_hasLoadExtSupport;
+}
+
+bool
+wxSQLite3Database::HasNamedCollectionSupport()
+{
+ return ms_hasNamedCollectionSupport;
+}
+
+bool
+wxSQLite3Database::HasIncrementalBlobSupport()
+{
+ return ms_hasIncrementalBlobSupport;
+}
+
+bool
+wxSQLite3Database::HasSavepointSupport()
+{
+ return ms_hasSavepointSupport;
+}
+
+bool
+wxSQLite3Database::HasBackupSupport()
+{
+ return ms_hasBackupSupport;
+}
+
+bool
+wxSQLite3Database::HasWriteAheadLogSupport()
+{
+ return ms_hasWriteAheadLogSupport;
+}
+
+wxSQLite3Database::wxSQLite3Database()
+{
+ m_db = 0;
+ m_busyTimeoutMs = 60000; // 60 seconds
+ m_isEncrypted = false;
+}
+
+wxSQLite3Database::wxSQLite3Database(const wxSQLite3Database& db)
+{
+ m_db = db.m_db;
+ m_busyTimeoutMs = 60000; // 60 seconds
+ m_isEncrypted = false;
+}
+
+wxSQLite3Database::~wxSQLite3Database()
+{
+ Close();
+}
+
+wxSQLite3Database& wxSQLite3Database::operator=(const wxSQLite3Database& db)
+{
+ if (this != &db)
+ {
+ if (m_db == 0)
+ {
+ m_db = db.m_db;
+ m_busyTimeoutMs = 60000; // 60 seconds
+ m_isEncrypted = db.m_isEncrypted;
+ }
+ else
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_DBASSIGN_FAILED, *this);
+ }
+ }
+ return *this;
+}
+
+void wxSQLite3Database::Open(const wxString& fileName, const wxString& key, int flags)
+{
+ wxCharBuffer strLocalKey = key.ToUTF8();
+ const char* localKey = strLocalKey;
+ wxMemoryBuffer binaryKey;
+ if (key.Length() > 0)
+ {
+ binaryKey.AppendData((void*) localKey, strlen(localKey));
+ }
+ Open(fileName, binaryKey, flags);
+}
+
+void wxSQLite3Database::Open(const wxString& fileName, const wxMemoryBuffer& key, int flags)
+{
+ wxCharBuffer strFileName = fileName.ToUTF8();
+ const char* localFileName = strFileName;
+
+ int rc = sqlite3_open_v2((const char*) localFileName, (sqlite3**) &m_db, flags, NULL);
+
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ Close();
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+
+ rc = sqlite3_extended_result_codes((sqlite3*) m_db, 1);
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ Close();
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+
+#if WXSQLITE3_HAVE_CODEC
+ if (key.GetDataLen() > 0)
+ {
+ rc = sqlite3_key((sqlite3*) m_db, key.GetData(), (int) key.GetDataLen());
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ Close();
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+ m_isEncrypted = true;
+ }
+#else
+ wxUnusedVar(key);
+#endif
+
+ SetBusyTimeout(m_busyTimeoutMs);
+}
+
+bool wxSQLite3Database::IsOpen() const
+{
+ return (m_db != NULL);
+}
+
+void wxSQLite3Database::Close()
+{
+ if (m_db)
+ {
+#if SQLITE_VERSION_NUMBER >= 3006000
+// Unfortunately the following code leads to a crash if the RTree module is used
+// therefore it is disabled for now
+#if 0
+ // Finalize all unfinalized prepared statements
+ sqlite3_stmt *pStmt;
+ while( (pStmt = sqlite3_next_stmt((sqlite3*) m_db, 0))!=0 )
+ {
+ sqlite3_finalize(pStmt);
+ }
+#endif
+#endif
+ sqlite3_close((sqlite3*) m_db);
+ m_db = 0;
+ m_isEncrypted = false;
+ }
+}
+
+void wxSQLite3Database::Backup(const wxString& targetFileName, const wxString& key, const wxString& sourceDatabaseName)
+{
+ wxCharBuffer strLocalKey = key.ToUTF8();
+ const char* localKey = strLocalKey;
+ wxMemoryBuffer binaryKey;
+ if (key.Length() > 0)
+ {
+ binaryKey.AppendData((void*) localKey, strlen(localKey));
+ }
+ Backup(targetFileName, binaryKey, sourceDatabaseName);
+}
+
+void wxSQLite3Database::Backup(const wxString& targetFileName, const wxMemoryBuffer& key, const wxString& sourceDatabaseName)
+{
+#if SQLITE_VERSION_NUMBER >= 3006011
+ CheckDatabase();
+
+ wxCharBuffer strFileName = targetFileName.ToUTF8();
+ const char* localTargetFileName = strFileName;
+ wxCharBuffer strDatabaseName = sourceDatabaseName.ToUTF8();
+ const char* localSourceDatabaseName = strDatabaseName;
+
+ sqlite3* pDest;
+ sqlite3_backup* pBackup;
+ int rc;
+ rc = sqlite3_open(localTargetFileName, &pDest);
+ if (rc != SQLITE_OK)
+ {
+ sqlite3_close(pDest);
+ WXSQLITE3_ERROR(rc, wxERRMSG_DBOPEN_FAILED, );
+ }
+#if WXSQLITE3_HAVE_CODEC
+ if (key.GetDataLen() > 0)
+ {
+ rc = sqlite3_key(pDest, key.GetData(), (int) key.GetDataLen());
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) pDest);
+ sqlite3_close(pDest);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+ }
+#else
+ wxUnusedVar(key);
+#endif
+
+ pBackup = sqlite3_backup_init(pDest, "main", (sqlite3*) m_db, localSourceDatabaseName);
+ if (pBackup == 0)
+ {
+ const char* localError = sqlite3_errmsg(pDest);
+ sqlite3_close(pDest);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+
+ do
+ {
+ rc = sqlite3_backup_step(pBackup, 10);
+#if 0
+ xProgress(sqlite3_backup_remaining(pBackup),
+ sqlite3_backup_pagecount(pBackup));
+#endif
+ if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED)
+ {
+ sqlite3_sleep(250);
+ }
+ }
+ while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED);
+
+ sqlite3_backup_finish(pBackup);
+ if (rc == SQLITE_DONE)
+ {
+ sqlite3_close(pDest);
+ }
+ else
+ {
+ const char* localError = sqlite3_errmsg(pDest);
+ sqlite3_close(pDest);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+#else
+ wxUnusedVar(targetFileName);
+ wxUnusedVar(sourceDatabaseName);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOBACKUP, );
+#endif
+}
+
+void wxSQLite3Database::Restore(const wxString& sourceFileName, const wxString& key, const wxString& targetDatabaseName)
+{
+ wxCharBuffer strLocalKey = key.ToUTF8();
+ const char* localKey = strLocalKey;
+ wxMemoryBuffer binaryKey;
+ if (key.Length() > 0)
+ {
+ binaryKey.AppendData((void*) localKey, strlen(localKey));
+ }
+ Restore(sourceFileName, binaryKey, targetDatabaseName);
+}
+
+void wxSQLite3Database::Restore(const wxString& sourceFileName, const wxMemoryBuffer& key, const wxString& targetDatabaseName)
+{
+#if SQLITE_VERSION_NUMBER >= 3006011
+ CheckDatabase();
+
+ wxCharBuffer strFileName = sourceFileName.ToUTF8();
+ const char* localSourceFileName = strFileName;
+ wxCharBuffer strDatabaseName = targetDatabaseName.ToUTF8();
+ const char* localTargetDatabaseName = strDatabaseName;
+
+ sqlite3* pSrc;
+ sqlite3_backup* pBackup;
+ int rc;
+ int nTimeout = 0;
+
+ rc = sqlite3_open(localSourceFileName, &pSrc);
+ if (rc != SQLITE_OK)
+ {
+ sqlite3_close(pSrc);
+ WXSQLITE3_ERROR(rc, wxERRMSG_DBOPEN_FAILED, );
+ }
+#if WXSQLITE3_HAVE_CODEC
+ if (key.GetDataLen() > 0)
+ {
+ rc = sqlite3_key(pSrc, key.GetData(), (int) key.GetDataLen());
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) pSrc);
+ sqlite3_close(pSrc);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+ }
+#else
+ wxUnusedVar(key);
+#endif
+
+ pBackup = sqlite3_backup_init((sqlite3*) m_db, localTargetDatabaseName, pSrc, "main");
+ if (pBackup == 0)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ sqlite3_close(pSrc);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+ while ((rc = sqlite3_backup_step(pBackup, 100)) == SQLITE_OK || rc == SQLITE_BUSY)
+ {
+ if (rc == SQLITE_BUSY)
+ {
+ if (nTimeout++ >= 3) break;
+ sqlite3_sleep(100);
+ }
+ }
+ sqlite3_backup_finish(pBackup);
+ if (rc == SQLITE_DONE)
+ {
+ sqlite3_close(pSrc);
+ }
+ else if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED)
+ {
+ sqlite3_close(pSrc);
+ WXSQLITE3_ERROR(rc, wxERRMSG_SOURCEDB_BUSY, );
+ }
+ else
+ {
+ const char* localError = sqlite3_errmsg(pSrc);
+ sqlite3_close(pSrc);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+#else
+ wxUnusedVar(sourceFileName);
+ wxUnusedVar(targetDatabaseName);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOBACKUP, );
+#endif
+}
+
+void wxSQLite3Database::Begin(wxSQLite3TransactionType transactionType)
+{
+ wxString sql;
+ switch (transactionType)
+ {
+ case WXSQLITE_TRANSACTION_DEFERRED:
+ sql << wxT("begin deferred transaction");
+ break;
+ case WXSQLITE_TRANSACTION_IMMEDIATE:
+ sql << wxT("begin immediate transaction");
+ break;
+ case WXSQLITE_TRANSACTION_EXCLUSIVE:
+ sql << wxT("begin exclusive transaction");
+ break;
+ default:
+ sql << wxT("begin transaction");
+ break;
+ }
+ ExecuteUpdate(sql);
+}
+
+void wxSQLite3Database::Commit()
+{
+ ExecuteUpdate("commit transaction");
+}
+
+void wxSQLite3Database::Rollback(const wxString& savepointName)
+{
+#if SQLITE_VERSION_NUMBER >= 3006008
+ if (savepointName.IsEmpty())
+ {
+#endif
+ ExecuteUpdate("rollback transaction");
+#if SQLITE_VERSION_NUMBER >= 3006008
+ }
+ else
+ {
+ ExecuteUpdate(wxString(wxT("rollback transaction to savepoint "))+savepointName);
+ }
+#endif
+}
+
+bool wxSQLite3Database::GetAutoCommit()
+{
+ CheckDatabase();
+ return sqlite3_get_autocommit((sqlite3*) m_db) != 0;
+}
+
+void wxSQLite3Database::Savepoint(const wxString& savepointName)
+{
+#if SQLITE_VERSION_NUMBER >= 3006008
+ ExecuteUpdate(wxString(wxT("savepoint "))+savepointName);
+#else
+ wxUnusedVar(savepointName);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOSAVEPOINT, );
+#endif
+}
+
+void wxSQLite3Database::ReleaseSavepoint(const wxString& savepointName)
+{
+#if SQLITE_VERSION_NUMBER >= 3006008
+ ExecuteUpdate(wxString(wxT("release savepoint "))+savepointName);
+#else
+ wxUnusedVar(savepointName);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOSAVEPOINT, );
+#endif
+}
+
+wxSQLite3Statement wxSQLite3Database::PrepareStatement(const wxString& sql)
+{
+ wxCharBuffer strSql = sql.ToUTF8();
+ const char* localSql = strSql;
+ return PrepareStatement(localSql);
+}
+
+wxSQLite3Statement wxSQLite3Database::PrepareStatement(const wxSQLite3StatementBuffer& sql)
+{
+ return PrepareStatement((const char*) sql);
+}
+
+wxSQLite3Statement wxSQLite3Database::PrepareStatement(const char* sql)
+{
+ CheckDatabase();
+ sqlite3_stmt* stmt = (sqlite3_stmt*) Prepare(sql);
+ return wxSQLite3Statement(m_db, stmt);
+}
+
+bool wxSQLite3Database::TableExists(const wxString& tableName, const wxString& databaseName)
+{
+ wxString sql;
+ if (databaseName.IsEmpty())
+ {
+ sql = wxT("select count(*) from sqlite_master where type='table' and name like ?");
+ }
+ else
+ {
+ sql = wxString(wxT("select count(*) from ")) + databaseName + wxString(wxT(".sqlite_master where type='table' and name like ?"));
+ }
+ wxSQLite3Statement stmt = PrepareStatement(sql);
+ stmt.Bind(1, tableName);
+ wxSQLite3ResultSet resultSet = stmt.ExecuteQuery();
+ long value = 0;
+ resultSet.GetAsString(0).ToLong(&value);
+ return (value > 0);
+}
+
+bool wxSQLite3Database::TableExists(const wxString& tableName, wxArrayString& databaseNames)
+{
+ wxArrayString databaseList;
+ GetDatabaseList(databaseList);
+
+ bool found = false;
+ size_t count = databaseList.GetCount();
+ if (count > 0)
+ {
+ size_t j;
+ for (j = 0; j < count; j++)
+ {
+ if (TableExists(tableName, databaseList.Item(j)))
+ {
+ found = true;
+ databaseNames.Add(databaseList.Item(j));
+ }
+ }
+ }
+ return found;
+}
+
+void wxSQLite3Database::GetDatabaseList(wxArrayString& databaseNames)
+{
+ databaseNames.Empty();
+ wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA database_list;");
+ while (resultSet.NextRow())
+ {
+ databaseNames.Add(resultSet.GetString(1));
+ }
+}
+
+void wxSQLite3Database::GetDatabaseList(wxArrayString& databaseNames, wxArrayString& databaseFiles)
+{
+ databaseNames.Empty();
+ databaseFiles.Empty();
+ wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA database_list;");
+ while (resultSet.NextRow())
+ {
+ databaseNames.Add(resultSet.GetString(1));
+ databaseFiles.Add(resultSet.GetString(2));
+ }
+}
+
+bool wxSQLite3Database::EnableForeignKeySupport(bool enable)
+{
+ if (enable)
+ {
+ ExecuteUpdate("PRAGMA foreign_keys=ON;");
+ }
+ else
+ {
+ ExecuteUpdate("PRAGMA foreign_keys=OFF;");
+ }
+ bool enabled = IsForeignKeySupportEnabled();
+ return (enable && enabled) || (!enable && !enabled);
+}
+
+bool wxSQLite3Database::IsForeignKeySupportEnabled()
+{
+ bool enabled = false;
+ wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA foreign_keys;");
+ if (resultSet.NextRow())
+ {
+ enabled = (resultSet.GetInt(0) == 1);
+ }
+ return enabled;
+}
+
+wxSQLite3JournalMode
+wxSQLite3Database::SetJournalMode(wxSQLite3JournalMode journalMode, const wxString& database)
+{
+ wxString mode = ConvertJournalMode(journalMode);
+ wxString query = wxT("PRAGMA ");
+ if (!database.IsEmpty())
+ {
+ query += database;
+ query += wxT(".");
+ }
+ query += wxT("journal_mode=");
+ query += mode;
+ query += wxT(";");
+ wxSQLite3ResultSet resultSet = ExecuteQuery(query);
+ if (resultSet.NextRow())
+ {
+ mode = resultSet.GetString(0);
+ }
+ return ConvertJournalMode(mode);
+}
+
+wxSQLite3JournalMode
+wxSQLite3Database::GetJournalMode(const wxString& database)
+{
+ wxString mode = wxT("DELETE");
+ wxString query = wxT("PRAGMA ");
+ if (!database.IsEmpty())
+ {
+ query += database;
+ query += wxT(".");
+ }
+ query += wxT("journal_mode;");
+ wxSQLite3ResultSet resultSet = ExecuteQuery(query);
+ if (resultSet.NextRow())
+ {
+ mode = resultSet.GetString(0);
+ }
+ return ConvertJournalMode(mode);
+}
+
+/* static */
+wxString wxSQLite3Database::ConvertJournalMode(wxSQLite3JournalMode mode)
+{
+ wxString journalMode;
+ if (mode == WXSQLITE_JOURNALMODE_DELETE) journalMode = wxT("DELETE");
+ else if (mode == WXSQLITE_JOURNALMODE_PERSIST) journalMode = wxT("PERSIST");
+ else if (mode == WXSQLITE_JOURNALMODE_OFF) journalMode = wxT("OFF");
+ else if (mode == WXSQLITE_JOURNALMODE_TRUNCATE) journalMode = wxT("TRUNCATE");
+ else if (mode == WXSQLITE_JOURNALMODE_MEMORY) journalMode = wxT("MEMORY");
+ else if (mode == WXSQLITE_JOURNALMODE_WAL) journalMode = wxT("WAL");
+ else journalMode = wxT("DELETE");
+ return journalMode;
+}
+
+/* static */
+wxSQLite3JournalMode wxSQLite3Database::ConvertJournalMode(const wxString& mode)
+{
+ wxSQLite3JournalMode journalMode;
+ if (mode.IsSameAs(wxT("DELETE"))) journalMode = WXSQLITE_JOURNALMODE_DELETE;
+ else if (mode.IsSameAs(wxT("PERSIST"))) journalMode = WXSQLITE_JOURNALMODE_PERSIST;
+ else if (mode.IsSameAs(wxT("OFF"))) journalMode = WXSQLITE_JOURNALMODE_OFF;
+ else if (mode.IsSameAs(wxT("TRUNCATE"))) journalMode = WXSQLITE_JOURNALMODE_TRUNCATE;
+ else if (mode.IsSameAs(wxT("MEMORY"))) journalMode = WXSQLITE_JOURNALMODE_MEMORY;
+ else if (mode.IsSameAs(wxT("WAL"))) journalMode = WXSQLITE_JOURNALMODE_WAL;
+ else journalMode = WXSQLITE_JOURNALMODE_DELETE;
+ return journalMode;
+}
+
+bool wxSQLite3Database::CheckSyntax(const wxString& sql)
+{
+ wxCharBuffer strSql = sql.ToUTF8();
+ const char* localSql = strSql;
+ return CheckSyntax(localSql);
+}
+
+bool wxSQLite3Database::CheckSyntax(const wxSQLite3StatementBuffer& sql)
+{
+ return CheckSyntax((const char*) sql);
+}
+
+bool wxSQLite3Database::CheckSyntax(const char* sql)
+{
+ return sqlite3_complete(sql) != 0;
+}
+
+int wxSQLite3Database::ExecuteUpdate(const wxString& sql)
+{
+ wxCharBuffer strSql = sql.ToUTF8();
+ const char* localSql = strSql;
+ return ExecuteUpdate(localSql);
+}
+
+int wxSQLite3Database::ExecuteUpdate(const wxSQLite3StatementBuffer& sql)
+{
+ return ExecuteUpdate((const char*) sql);
+}
+
+int wxSQLite3Database::ExecuteUpdate(const char* sql)
+{
+ CheckDatabase();
+
+ char* localError=0;
+
+ int rc = sqlite3_exec((sqlite3*) m_db, sql, 0, 0, &localError);
+
+ if (rc == SQLITE_OK)
+ {
+ return sqlite3_changes((sqlite3*) m_db);
+ }
+ else
+ {
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), 0);
+ }
+}
+
+wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const wxString& sql)
+{
+ wxCharBuffer strSql = sql.ToUTF8();
+ const char* localSql = strSql;
+ return ExecuteQuery(localSql);
+}
+
+wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const wxSQLite3StatementBuffer& sql)
+{
+ return ExecuteQuery((const char*) sql);
+}
+
+wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const char* sql)
+{
+ CheckDatabase();
+
+ sqlite3_stmt* stmt = (sqlite3_stmt*) Prepare(sql);
+
+ int rc = sqlite3_step(stmt);
+
+ if (rc == SQLITE_DONE) // no rows
+ {
+ return wxSQLite3ResultSet(m_db, stmt, true /* eof */);
+ }
+ else if (rc == SQLITE_ROW) // one or more rows
+ {
+ return wxSQLite3ResultSet(m_db, stmt, false /* eof */);
+ }
+ else
+ {
+ rc = sqlite3_finalize(stmt);
+ const char* localError= sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), wxSQLite3ResultSet());
+ }
+}
+
+int wxSQLite3Database::ExecuteScalar(const wxString& sql)
+{
+ wxCharBuffer strSql = sql.ToUTF8();
+ const char* localSql = strSql;
+ return ExecuteScalar(localSql);
+}
+
+int wxSQLite3Database::ExecuteScalar(const wxSQLite3StatementBuffer& sql)
+{
+ return ExecuteScalar((const char*) sql);
+}
+
+int wxSQLite3Database::ExecuteScalar(const char* sql)
+{
+ wxSQLite3ResultSet resultSet = ExecuteQuery(sql);
+
+ if (resultSet.Eof() || resultSet.GetColumnCount() < 1)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_INVALID_QUERY, 0);
+ }
+
+ long value = 0;
+ resultSet.GetAsString(0).ToLong(&value);
+ return (int) value;
+}
+
+wxSQLite3Table wxSQLite3Database::GetTable(const wxString& sql)
+{
+ wxCharBuffer strSql = sql.ToUTF8();
+ const char* localSql = strSql;
+ return GetTable(localSql);
+}
+
+wxSQLite3Table wxSQLite3Database::GetTable(const wxSQLite3StatementBuffer& sql)
+{
+ return GetTable((const char*) sql);
+}
+
+wxSQLite3Table wxSQLite3Database::GetTable(const char* sql)
+{
+ CheckDatabase();
+
+ char* localError=0;
+ char** results=0;
+ int rc;
+ int rows(0);
+ int cols(0);
+
+ rc = sqlite3_get_table((sqlite3*) m_db, sql, &results, &rows, &cols, &localError);
+
+ if (rc == SQLITE_OK)
+ {
+ return wxSQLite3Table(results, rows, cols);
+ }
+ else
+ {
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), wxSQLite3Table());
+ }
+}
+
+wxLongLong wxSQLite3Database::GetLastRowId()
+{
+ CheckDatabase();
+ return wxLongLong(sqlite3_last_insert_rowid((sqlite3*) m_db));
+}
+
+wxSQLite3Blob wxSQLite3Database::GetReadOnlyBlob(wxLongLong rowId,
+ const wxString& columnName,
+ const wxString& tableName,
+ const wxString& dbName)
+{
+ return GetBlob(rowId, columnName, tableName, dbName, false);
+}
+
+wxSQLite3Blob wxSQLite3Database::GetWritableBlob(wxLongLong rowId,
+ const wxString& columnName,
+ const wxString& tableName,
+ const wxString& dbName)
+{
+ return GetBlob(rowId, columnName, tableName, dbName, true);
+}
+
+wxSQLite3Blob wxSQLite3Database::GetBlob(wxLongLong rowId,
+ const wxString& columnName,
+ const wxString& tableName,
+ const wxString& dbName,
+ bool writable)
+{
+#if SQLITE_VERSION_NUMBER >= 3004000
+ wxCharBuffer strColumnName = columnName.ToUTF8();
+ const char* localColumnName = strColumnName;
+ wxCharBuffer strTableName = tableName.ToUTF8();
+ const char* localTableName = strTableName;
+ wxCharBuffer strDbName = dbName.ToUTF8();
+ const char* localDbName = (!dbName.IsEmpty()) ? (const char*) strDbName : (const char*) NULL;
+ int flags = (writable) ? 1 : 0;
+ sqlite3_blob* blobHandle;
+ CheckDatabase();
+ int rc = sqlite3_blob_open((sqlite3*) m_db, localDbName, localTableName, localColumnName, rowId.GetValue(), flags, &blobHandle);
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), wxSQLite3Blob());
+ }
+ return wxSQLite3Blob(m_db, (void*) blobHandle, writable);
+#else
+ wxUnusedVar(rowId);
+ wxUnusedVar(columnName);
+ wxUnusedVar(tableName);
+ wxUnusedVar(dbName);
+ wxUnusedVar(writable);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB, wxSQLite3Blob());
+ return NULL;
+#endif
+}
+
+void wxSQLite3Database::Interrupt()
+{
+ CheckDatabase();
+ sqlite3_interrupt((sqlite3*) m_db);
+}
+
+void wxSQLite3Database::SetBusyTimeout(int nMillisecs)
+{
+ CheckDatabase();
+ m_busyTimeoutMs = nMillisecs;
+ sqlite3_busy_timeout((sqlite3*) m_db, m_busyTimeoutMs);
+}
+
+wxString wxSQLite3Database::GetVersion()
+{
+ return wxString::FromUTF8(sqlite3_libversion());
+}
+
+wxString wxSQLite3Database::GetSourceId()
+{
+#if SQLITE_VERSION_NUMBER >= 3006018
+ return wxString::FromUTF8(sqlite3_sourceid());
+#else
+ return wxEmptyString;
+#endif
+}
+
+bool wxSQLite3Database::CompileOptionUsed(const wxString& optionName)
+{
+#if SQLITE_VERSION_NUMBER >= 3006023
+ wxCharBuffer strOption = optionName.ToUTF8();
+ const char* localOption = strOption;
+ return sqlite3_compileoption_used(localOption) == 1;
+#else
+ return false;
+#endif
+}
+
+wxString wxSQLite3Database::GetCompileOptionName(int optionIndex)
+{
+#if SQLITE_VERSION_NUMBER >= 3006023
+ const char* unknownOption = "";
+ const char* optionName = sqlite3_compileoption_get(optionIndex);
+ if (optionName == NULL)
+ {
+ optionName = unknownOption;
+ }
+ return wxString::FromUTF8(optionName);
+#else
+ return wxEmptyString;
+#endif
+}
+
+bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3ScalarFunction& function)
+{
+ CheckDatabase();
+ wxCharBuffer strFuncName = funcName.ToUTF8();
+ const char* localFuncName = strFuncName;
+ int rc = sqlite3_create_function((sqlite3*) m_db, localFuncName, argCount,
+ SQLITE_UTF8, &function,
+ (void (*)(sqlite3_context*,int,sqlite3_value**)) wxSQLite3FunctionContext::ExecScalarFunction, NULL, NULL);
+ return rc == SQLITE_OK;
+}
+
+bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3AggregateFunction& function)
+{
+ CheckDatabase();
+ wxCharBuffer strFuncName = funcName.ToUTF8();
+ const char* localFuncName = strFuncName;
+ int rc = sqlite3_create_function((sqlite3*) m_db, localFuncName, argCount,
+ SQLITE_UTF8, &function,
+ NULL,
+ (void (*)(sqlite3_context*,int,sqlite3_value**)) wxSQLite3FunctionContext::ExecAggregateStep,
+ (void (*)(sqlite3_context*)) wxSQLite3FunctionContext::ExecAggregateFinalize);
+ return rc == SQLITE_OK;
+}
+
+bool wxSQLite3Database::SetAuthorizer(wxSQLite3Authorizer& authorizer)
+{
+ CheckDatabase();
+ int rc = sqlite3_set_authorizer((sqlite3*) m_db, wxSQLite3FunctionContext::ExecAuthorizer, &authorizer);
+ return rc == SQLITE_OK;
+}
+
+void wxSQLite3Database::SetCommitHook(wxSQLite3Hook* commitHook)
+{
+ CheckDatabase();
+ if (commitHook)
+ {
+ sqlite3_commit_hook((sqlite3*) m_db, (int(*)(void*)) wxSQLite3FunctionContext::ExecCommitHook, commitHook);
+ }
+ else
+ {
+ sqlite3_commit_hook((sqlite3*) m_db, (int(*)(void*)) NULL, NULL);
+ }
+}
+
+void wxSQLite3Database::SetRollbackHook(wxSQLite3Hook* rollbackHook)
+{
+ CheckDatabase();
+ if (rollbackHook)
+ {
+ sqlite3_rollback_hook((sqlite3*) m_db, (void(*)(void*)) wxSQLite3FunctionContext::ExecRollbackHook, rollbackHook);
+ }
+ else
+ {
+ sqlite3_rollback_hook((sqlite3*) m_db, (void(*)(void*)) NULL, NULL);
+ }
+}
+
+void wxSQLite3Database::SetUpdateHook(wxSQLite3Hook* updateHook)
+{
+ CheckDatabase();
+ if (updateHook)
+ {
+ sqlite3_update_hook((sqlite3*) m_db, (void(*)(void*,int,const char*,const char*, wxsqlite_int64)) wxSQLite3FunctionContext::ExecUpdateHook, updateHook);
+ }
+ else
+ {
+ sqlite3_update_hook((sqlite3*) m_db, (void(*)(void*,int,const char*,const char*, wxsqlite_int64)) NULL, NULL);
+ }
+}
+
+void wxSQLite3Database::SetWriteAheadLogHook(wxSQLite3Hook* walHook)
+{
+#if SQLITE_VERSION_NUMBER >= 3007000
+ CheckDatabase();
+ if (walHook)
+ {
+ walHook->SetDatabase(this);
+ sqlite3_wal_hook((sqlite3*) m_db, (int(*)(void *,sqlite3*,const char*,int)) wxSQLite3FunctionContext::ExecWriteAheadLogHook, walHook);
+ }
+ else
+ {
+ sqlite3_wal_hook((sqlite3*) m_db, (int(*)(void *,sqlite3*,const char*,int)) NULL, NULL);
+ }
+#else
+ wxUnusedVar(walHook);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOWAL, );
+#endif
+}
+
+void wxSQLite3Database::WriteAheadLogCheckpoint(const wxString& database)
+{
+#if SQLITE_VERSION_NUMBER >= 3007000
+ CheckDatabase();
+ wxCharBuffer strDatabase = database.ToUTF8();
+ const char* localDatabase = strDatabase;
+ int rc = sqlite3_wal_checkpoint((sqlite3*) m_db, localDatabase);
+
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+#else
+ wxUnusedVar(database);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOWAL, );
+#endif
+}
+
+void wxSQLite3Database::AutoWriteAheadLogCheckpoint(int frameCount)
+{
+#if SQLITE_VERSION_NUMBER >= 3007000
+ CheckDatabase();
+ int rc = sqlite3_wal_autocheckpoint((sqlite3*) m_db, frameCount);
+
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+#else
+ wxUnusedVar(frameCount);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOWAL, );
+#endif
+}
+
+void wxSQLite3Database::SetCollation(const wxString& collationName, wxSQLite3Collation* collation)
+{
+ CheckDatabase();
+ wxCharBuffer strCollationName = collationName.ToUTF8();
+ const char* localCollationName = strCollationName;
+ int rc;
+ if (collation)
+ {
+ rc = sqlite3_create_collation((sqlite3*) m_db, localCollationName, SQLITE_UTF8, collation, (int(*)(void*,int,const void*,int,const void*)) wxSQLite3Database::ExecComparisonWithCollation);
+ }
+ else
+ {
+ rc = sqlite3_create_collation((sqlite3*) m_db, localCollationName, SQLITE_UTF8, NULL, (int(*)(void*,int,const void*,int,const void*)) NULL);
+ }
+}
+
+void wxSQLite3Database::SetCollationNeededCallback()
+{
+ CheckDatabase();
+ int rc = sqlite3_collation_needed((sqlite3*) m_db, this, (void(*)(void*,sqlite3*,int,const char*)) wxSQLite3Database::ExecCollationNeeded);
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+}
+
+void wxSQLite3Database::CheckDatabase()
+{
+ if (!m_db)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NODB, );
+ }
+}
+
+void* wxSQLite3Database::Prepare(const char* sql)
+{
+ CheckDatabase();
+
+ const char* tail=0;
+ sqlite3_stmt* stmt;
+
+ int rc = sqlite3_prepare_v2((sqlite3*) m_db, sql, -1, &stmt, &tail);
+
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), NULL);
+ }
+
+ return stmt;
+}
+
+/* static */
+int wxSQLite3Database::ExecComparisonWithCollation(void* collation,
+ int len1, const void* text1,
+ int len2, const void* text2)
+{
+ wxString locText1 = wxString::FromUTF8((const char*) text1, (size_t) len1);
+ wxString locText2 = wxString::FromUTF8((const char*) text2, (size_t) len2);
+ return ((wxSQLite3Collation*) collation)->Compare(locText1, locText2);
+}
+
+void wxSQLite3Database::ExecCollationNeeded(void* db, void*, int, const char* collationName)
+{
+ wxString locCollation = wxString::FromUTF8((const char*) collationName);
+ ((wxSQLite3Database*) db)->SetNeededCollation(locCollation);
+}
+
+void wxSQLite3Database::GetMetaData(const wxString& databaseName, const wxString& tableName, const wxString& columnName,
+ wxString* dataType, wxString* collation, bool* notNull, bool* primaryKey, bool* autoIncrement)
+{
+#if WXSQLITE3_HAVE_METADATA
+ wxCharBuffer strDatabaseName = databaseName.ToUTF8();
+ const char* localDatabaseName = strDatabaseName;
+ if (databaseName == wxEmptyString) localDatabaseName = NULL;
+ wxCharBuffer strTableName = tableName.ToUTF8();
+ const char* localTableName = strTableName;
+ wxCharBuffer strColumnName = columnName.ToUTF8();
+ const char* localColumnName = strColumnName;
+ const char* localDataType;
+ const char* localCollation;
+ int localNotNull;
+ int localPrimaryKey;
+ int localAutoIncrement;
+ int rc = sqlite3_table_column_metadata((sqlite3*) m_db, localDatabaseName, localTableName, localColumnName,
+ &localDataType, &localCollation, &localNotNull, &localPrimaryKey, &localAutoIncrement);
+
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+
+ if (dataType != NULL) *dataType = wxString::FromUTF8(localDataType);
+ if (collation != NULL) *collation = wxString::FromUTF8(localCollation);
+
+ if (notNull != NULL) *notNull = (localNotNull != 0);
+ if (primaryKey != NULL) *primaryKey = (localPrimaryKey != 0);
+ if (autoIncrement != NULL) *autoIncrement = (localAutoIncrement != 0);
+#else
+ wxUnusedVar(databaseName);
+ wxUnusedVar(tableName);
+ wxUnusedVar(columnName);
+ wxUnusedVar(dataType);
+ wxUnusedVar(collation);
+ wxUnusedVar(notNull);
+ wxUnusedVar(primaryKey);
+ wxUnusedVar(autoIncrement);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOMETADATA, );
+#endif
+}
+
+void wxSQLite3Database::LoadExtension(const wxString& fileName, const wxString& entryPoint)
+{
+#if WXSQLITE3_HAVE_LOAD_EXTENSION
+ wxCharBuffer strFileName = fileName.ToUTF8();
+ const char* localFileName = strFileName;
+ wxCharBuffer strEntryPoint = entryPoint.ToUTF8();
+ const char* localEntryPoint = strEntryPoint;
+
+ int rc = sqlite3_load_extension((sqlite3 *) m_db, localFileName, localEntryPoint, NULL);
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+#else
+ wxUnusedVar(fileName);
+ wxUnusedVar(entryPoint);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOLOADEXT, );
+#endif
+}
+
+void wxSQLite3Database::EnableLoadExtension(bool enable)
+{
+#if WXSQLITE3_HAVE_LOAD_EXTENSION
+ int onoff = (enable) ? 1 : 0;
+ int rc = sqlite3_enable_load_extension((sqlite3 *) m_db, onoff);
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+#else
+ wxUnusedVar(enable);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOLOADEXT, );
+#endif
+}
+
+void wxSQLite3Database::ReKey(const wxString& newKey)
+{
+#if WXSQLITE3_HAVE_CODEC
+ wxCharBuffer strLocalNewKey = newKey.ToUTF8();
+ const char* localNewKey = strLocalNewKey;
+ wxMemoryBuffer binaryNewKey;
+ if (newKey.Length() > 0)
+ {
+ binaryNewKey.AppendData((void*) localNewKey, strlen(localNewKey));
+ }
+ ReKey(binaryNewKey);
+#else
+ wxUnusedVar(newKey);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOCODEC, );
+#endif
+}
+
+void wxSQLite3Database::ReKey(const wxMemoryBuffer& newKey)
+{
+#if WXSQLITE3_HAVE_CODEC
+ int rc = sqlite3_rekey((sqlite3*) m_db, newKey.GetData(), (int) newKey.GetDataLen());
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), );
+ }
+#else
+ wxUnusedVar(newKey);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOCODEC, );
+#endif
+}
+
+int wxSQLite3Database::GetLimit(wxSQLite3LimitType id)
+{
+ int value = -1;
+#if SQLITE_VERSION_NUMBER >= 3005008
+ CheckDatabase();
+ if (id >= WXSQLITE_LIMIT_LENGTH && id <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
+ {
+ value = sqlite3_limit((sqlite3 *) m_db, id, -1);
+ }
+#else
+ wxUnusedVar(id);
+#endif
+ return value;
+}
+
+int wxSQLite3Database::SetLimit(wxSQLite3LimitType id, int newValue)
+{
+ int value = -1;
+#if SQLITE_VERSION_NUMBER >= 3005008
+ CheckDatabase();
+ if (id >= WXSQLITE_LIMIT_LENGTH && id <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
+ {
+ value = sqlite3_limit((sqlite3 *) m_db, id, newValue);
+ }
+#else
+ wxUnusedVar(id);
+ wxUnusedVar(newValue);
+#endif
+ return value;
+}
+
+static const wxChar* limitCodeString[] =
+{ wxT("SQLITE_LIMIT_LENGTH"), wxT("SQLITE_LIMIT_SQL_LENGTH"),
+ wxT("SQLITE_LIMIT_COLUMN"), wxT("SQLITE_LIMIT_EXPR_DEPTH"),
+ wxT("SQLITE_LIMIT_COMPOUND_SELECT"), wxT("SQLITE_LIMIT_VDBE_OP"),
+ wxT("SQLITE_LIMIT_FUNCTION_ARG"), wxT("SQLITE_LIMIT_ATTACHED"),
+ wxT("SQLITE_LIMIT_LIKE_PATTERN_LENGTH"), wxT("SQLITE_LIMIT_VARIABLE_NUMBER"),
+ wxT("SQLITE_LIMIT_TRIGGER_DEPTH")
+};
+
+
+/* static */
+wxString wxSQLite3Database::LimitTypeToString(wxSQLite3LimitType type)
+{
+ const wxChar* limitString = wxT("Unknown");
+ if (type >= WXSQLITE_LIMIT_LENGTH && type <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
+ {
+ limitString = limitCodeString[type];
+ }
+ return wxString(limitString);
+}
+
+/* static */
+void wxSQLite3Database::InitializeSQLite()
+{
+#if SQLITE_VERSION_NUMBER >= 3006000
+ int rc = sqlite3_initialize();
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_INITIALIZE, );
+ }
+#endif
+}
+
+/* static */
+void wxSQLite3Database::ShutdownSQLite()
+{
+#if SQLITE_VERSION_NUMBER >= 3006000
+ int rc = sqlite3_shutdown();
+ if (rc != SQLITE_OK)
+ {
+ WXSQLITE3_ERROR(rc, wxERRMSG_SHUTDOWN, );
+ }
+#endif
+}
+
+/* static */
+bool wxSQLite3Database::Randomness(int n, wxMemoryBuffer& random)
+{
+ bool ok = false;
+#if SQLITE_VERSION_NUMBER >= 3005008
+ if (n > 0)
+ {
+ void* buffer = random.GetWriteBuf(n);
+ sqlite3_randomness(n, buffer);
+ random.UngetWriteBuf(n);
+ ok = true;
+ }
+#else
+ wxUnusedVar(n);
+ wxUnusedVar(random);
+#endif
+ return ok;
+}
+
+// ----------------------------------------------------------------------------
+// wxSQLite3FunctionContext: class providing the function context
+// for user defined functions
+// ----------------------------------------------------------------------------
+
+int wxSQLite3FunctionContext::GetArgCount()
+{
+ return m_argc;
+}
+
+int wxSQLite3FunctionContext::GetArgType(int argIndex)
+{
+ if (argIndex >= 0 && argIndex < m_argc)
+ {
+ return sqlite3_value_type((sqlite3_value*) m_argv[argIndex]);
+ }
+ else
+ {
+ return SQLITE_NULL;
+ }
+}
+
+bool wxSQLite3FunctionContext::IsNull(int argIndex)
+{
+ if (argIndex >= 0 && argIndex < m_argc)
+ {
+ return sqlite3_value_type((sqlite3_value*) m_argv[argIndex]) == SQLITE_NULL;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+int wxSQLite3FunctionContext::GetInt(int argIndex, int nullValue)
+{
+ if (argIndex >= 0 && argIndex < m_argc)
+ {
+ if (!IsNull(argIndex))
+ {
+ return sqlite3_value_int((sqlite3_value*) m_argv[argIndex]);
+ }
+ else
+ {
+ return nullValue;
+ }
+ }
+ else
+ {
+ return nullValue;
+ }
+}
+
+wxLongLong wxSQLite3FunctionContext::GetInt64(int argIndex, wxLongLong nullValue)
+{
+ if (argIndex >= 0 && argIndex < m_argc)
+ {
+ if (!IsNull(argIndex))
+ {
+ return wxLongLong(sqlite3_value_int64((sqlite3_value*) m_argv[argIndex]));
+ }
+ else
+ {
+ return nullValue;
+ }
+ }
+ else
+ {
+ return nullValue;
+ }
+}
+
+double wxSQLite3FunctionContext::GetDouble(int argIndex, double nullValue)
+{
+ if (argIndex >= 0 && argIndex < m_argc)
+ {
+ if (!IsNull(argIndex))
+ {
+ return sqlite3_value_double((sqlite3_value*) m_argv[argIndex]);
+ }
+ else
+ {
+ return nullValue;
+ }
+ }
+ else
+ {
+ return nullValue;
+ }
+}
+
+wxString wxSQLite3FunctionContext::GetString(int argIndex, const wxString& nullValue)
+{
+ if (argIndex >= 0 && argIndex < m_argc)
+ {
+ if (!IsNull(argIndex))
+ {
+ const char* localValue = (const char*) sqlite3_value_text((sqlite3_value*) m_argv[argIndex]);
+ return wxString::FromUTF8(localValue);
+ }
+ else
+ {
+ return nullValue;
+ }
+ }
+ else
+ {
+ return nullValue;
+ }
+}
+
+wxMemoryBuffer& wxSQLite3FunctionContext::GetBlob(int argIndex, wxMemoryBuffer& buffer)
+{
+ if (argIndex >= 0 && argIndex < m_argc)
+ {
+ if (!IsNull(argIndex))
+ {
+ int len = sqlite3_value_bytes((sqlite3_value*) m_argv[argIndex]);
+ const void* blob = sqlite3_value_blob((sqlite3_value*) m_argv[argIndex]);
+ buffer.AppendData((void*) blob, (size_t) len);
+ }
+ }
+ return buffer;
+}
+
+void wxSQLite3FunctionContext::SetResult(int value)
+{
+ sqlite3_result_int((sqlite3_context*) m_ctx, value);
+}
+
+void wxSQLite3FunctionContext::SetResult(wxLongLong value)
+{
+ sqlite3_result_int64((sqlite3_context*) m_ctx, value.GetValue());
+}
+
+void wxSQLite3FunctionContext::SetResult(double value)
+{
+ sqlite3_result_double((sqlite3_context*) m_ctx, value);
+}
+
+void wxSQLite3FunctionContext::SetResult(const wxString& value)
+{
+ wxCharBuffer strValue = value.ToUTF8();
+ const char* localValue = strValue;
+ sqlite3_result_text((sqlite3_context*) m_ctx, localValue, -1, SQLITE_TRANSIENT);
+}
+
+void wxSQLite3FunctionContext::SetResult(unsigned char* value, int len)
+{
+ sqlite3_result_blob((sqlite3_context*) m_ctx, value, len, SQLITE_TRANSIENT);
+}
+
+void wxSQLite3FunctionContext::SetResult(const wxMemoryBuffer& buffer)
+{
+ sqlite3_result_blob((sqlite3_context*) m_ctx, buffer.GetData(), (int) buffer.GetDataLen(), SQLITE_TRANSIENT);
+}
+
+void wxSQLite3FunctionContext::SetResultNull()
+{
+ sqlite3_result_null((sqlite3_context*) m_ctx);
+}
+
+void wxSQLite3FunctionContext::SetResultZeroBlob(int blobSize)
+{
+#if SQLITE_VERSION_NUMBER >= 3004000
+ sqlite3_result_zeroblob((sqlite3_context*) m_ctx, blobSize);
+#endif
+}
+
+void wxSQLite3FunctionContext::SetResultArg(int argIndex)
+{
+ if (argIndex >= 0 && argIndex < m_argc) {
+ sqlite3_result_value((sqlite3_context*) m_ctx, (sqlite3_value*) m_argv[argIndex]);
+ } else {
+ sqlite3_result_null((sqlite3_context*) m_ctx);
+ }
+}
+
+void wxSQLite3FunctionContext::SetResultError(const wxString& errmsg)
+{
+ wxCharBuffer strErrmsg = errmsg.ToUTF8();
+ const char* localErrmsg = strErrmsg;
+ sqlite3_result_error((sqlite3_context*) m_ctx, localErrmsg, -1);
+}
+
+int wxSQLite3FunctionContext::GetAggregateCount()
+{
+ if (m_isAggregate)
+ {
+ return m_count;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void* wxSQLite3FunctionContext::GetAggregateStruct(int len)
+{
+ if (m_isAggregate)
+ {
+ return sqlite3_aggregate_context((sqlite3_context*) m_ctx, len);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+/* static */
+void wxSQLite3FunctionContext::ExecScalarFunction(void* ctx, int argc, void** argv)
+{
+ wxSQLite3FunctionContext context(ctx, false, argc, argv);
+ wxSQLite3ScalarFunction* func = (wxSQLite3ScalarFunction*) sqlite3_user_data((sqlite3_context*) ctx);
+ func->Execute(context);
+}
+
+/* static */
+void wxSQLite3FunctionContext::ExecAggregateStep(void* ctx, int argc, void** argv)
+{
+ wxSQLite3FunctionContext context(ctx, true, argc, argv);
+ wxSQLite3AggregateFunction* func = (wxSQLite3AggregateFunction*) sqlite3_user_data((sqlite3_context*) ctx);
+ func->m_count++;
+ context.m_count = func->m_count;
+ func->Aggregate(context);
+}
+
+/* static */
+void wxSQLite3FunctionContext::ExecAggregateFinalize(void* ctx)
+{
+ wxSQLite3FunctionContext context(ctx, true, 0, NULL);
+ wxSQLite3AggregateFunction* func = (wxSQLite3AggregateFunction*) sqlite3_user_data((sqlite3_context*) ctx);
+ context.m_count = func->m_count;
+ func->Finalize(context);
+}
+
+/* static */
+int wxSQLite3FunctionContext::ExecAuthorizer(void* func, int type,
+ const char* arg1, const char* arg2,
+ const char* arg3, const char* arg4)
+{
+ wxString locArg1 = wxString::FromUTF8(arg1);
+ wxString locArg2 = wxString::FromUTF8(arg2);
+ wxString locArg3 = wxString::FromUTF8(arg3);
+ wxString locArg4 = wxString::FromUTF8(arg4);
+ wxSQLite3Authorizer::wxAuthorizationCode localType = (wxSQLite3Authorizer::wxAuthorizationCode) type;
+ return (int) ((wxSQLite3Authorizer*) func)->Authorize(localType, locArg1, locArg2, locArg3, locArg3);
+}
+
+/* static */
+int wxSQLite3FunctionContext::ExecCommitHook(void* hook)
+{
+ return (int) ((wxSQLite3Hook*) hook)->CommitCallback();
+}
+
+/* static */
+void wxSQLite3FunctionContext::ExecRollbackHook(void* hook)
+{
+ ((wxSQLite3Hook*) hook)->RollbackCallback();
+}
+
+/* static */
+void wxSQLite3FunctionContext::ExecUpdateHook(void* hook, int type,
+ const char* database, const char* table,
+ wxsqlite_int64 rowid)
+{
+ wxString locDatabase = wxString::FromUTF8(database);
+ wxString locTable = wxString::FromUTF8(table);
+ wxSQLite3Hook::wxUpdateType locType = (wxSQLite3Hook::wxUpdateType) type;
+ wxLongLong locRowid = rowid;
+ ((wxSQLite3Hook*) hook)->UpdateCallback(locType, locDatabase, locTable, locRowid);
+}
+
+wxSQLite3FunctionContext::wxSQLite3FunctionContext(void* ctx, bool isAggregate, int argc, void** argv)
+: m_ctx(ctx), m_isAggregate(isAggregate), m_count(0), m_argc(argc), m_argv(argv)
+{
+}
+
+/* static */
+int wxSQLite3FunctionContext::ExecWriteAheadLogHook(void* hook, void* dbHandle,
+ const char* database, int numPages)
+{
+ wxString locDatabase = wxString::FromUTF8(database);
+ wxUnusedVar(dbHandle);
+ return (int) ((wxSQLite3Hook*) hook)->WriteAheadLogCallback(locDatabase, numPages);
+}
+
+static const wxChar* authCodeString[] =
+{ wxT("SQLITE_COPY"), wxT("SQLITE_CREATE_INDEX"), wxT("SQLITE_CREATE_TABLE"),
+ wxT("SQLITE_CREATE_TEMP_INDEX"), wxT("SQLITE_CREATE_TEMP_TABLE"), wxT("SQLITE_CREATE_TEMP_TRIGGER"),
+ wxT("SQLITE_CREATE_TEMP_VIEW"), wxT("SQLITE_CREATE_TRIGGER"), wxT("SQLITE_CREATE_VIEW"),
+ wxT("SQLITE_DELETE"), wxT("SQLITE_DROP_INDEX"), wxT("SQLITE_DROP_TABLE"),
+ wxT("SQLITE_DROP_TEMP_INDEX"), wxT("SQLITE_DROP_TEMP_TABLE"), wxT("SQLITE_DROP_TEMP_TRIGGER"),
+ wxT("SQLITE_DROP_TEMP_VIEW"), wxT("SQLITE_DROP_TRIGGER"), wxT("SQLITE_DROP_VIEW"),
+ wxT("SQLITE_INSERT"), wxT("SQLITE_PRAGMA"), wxT("SQLITE_READ"),
+ wxT("SQLITE_SELECT"), wxT("SQLITE_TRANSACTION"), wxT("SQLITE_UPDATE"),
+ wxT("SQLITE_ATTACH"), wxT("SQLITE_DETACH"), wxT("SQLITE_ALTER_TABLE"),
+ wxT("SQLITE_REINDEX"), wxT("SQLITE_ANALYZE"), wxT("SQLITE_CREATE_VTABLE"),
+ wxT("SQLITE_DROP_VTABLE"), wxT("SQLITE_FUNCTION"), wxT("SQLITE_SAVEPOINT")
+};
+
+
+/* static */
+wxString wxSQLite3Authorizer::AuthorizationCodeToString(wxSQLite3Authorizer::wxAuthorizationCode type)
+{
+ const wxChar* authString = wxT("Unknown");
+ if (type >= SQLITE_COPY && type <= SQLITE_MAX_CODE)
+ {
+ authString = authCodeString[type];
+ }
+ return wxString(authString);
+}
+
+// ----------------------------------------------------------------------------
+// wxSQLite3Transaction
+// ----------------------------------------------------------------------------
+
+wxSQLite3Transaction::wxSQLite3Transaction(wxSQLite3Database* db, wxSQLite3TransactionType transactionType)
+{
+ assert(db != NULL);
+ m_database = db;
+ try
+ {
+ m_database->Begin(transactionType);
+ }
+ catch (...)
+ {
+ m_database = NULL; // Flag that transaction is not active
+ }
+}
+
+wxSQLite3Transaction::~wxSQLite3Transaction()
+{
+ if (m_database != NULL)
+ {
+ m_database->Rollback();
+ }
+}
+
+void wxSQLite3Transaction::Commit()
+{
+ try
+ {
+ m_database->Commit();
+ }
+ catch (...)
+ {
+ m_database->Rollback();
+ }
+ m_database = NULL;
+}
+
+void wxSQLite3Transaction::Rollback()
+{
+ try
+ {
+ m_database->Rollback();
+ }
+ catch (...)
+ {
+ m_database->Rollback();
+ }
+ m_database = NULL;
+}
+
+// --- User defined function classes
+
+#if wxUSE_REGEX
+
+wxSQLite3RegExpOperator::wxSQLite3RegExpOperator(int flags) : m_flags(flags)
+{
+}
+
+wxSQLite3RegExpOperator::~wxSQLite3RegExpOperator()
+{
+}
+
+void wxSQLite3RegExpOperator::Execute(wxSQLite3FunctionContext& ctx)
+{
+ int argCount = ctx.GetArgCount();
+ if (argCount == 2)
+ {
+ wxString exprStr = ctx.GetString(0);
+ wxString textStr = ctx.GetString(1);
+ if (!m_exprStr.IsSameAs(exprStr))
+ {
+ m_exprStr = exprStr;
+ m_regEx.Compile(m_exprStr, m_flags);
+ }
+ if (m_regEx.IsValid())
+ {
+ int rc = (m_regEx.Matches(textStr)) ? 1 : 0;
+ ctx.SetResult(rc);
+ }
+ else
+ {
+ ctx.SetResultError(wxString(_("Regular expression invalid: '"))+exprStr+_T("'."));
+ }
+ }
+ else
+ {
+ ctx.SetResultError(wxString::Format(_("REGEXP called with wrong number of arguments: %d instead of 2."), argCount));
+ }
+}
+
+#endif
+
+// --- Support for named collections
+
+#if WXSQLITE3_USE_NAMED_COLLECTIONS
+
+// The following code is based on the SQLite test_intarray source code.
+
+#include <string.h>
+#include <assert.h>
+
+/// Definition of the sqlite3_intarray object (internal)
+struct sqlite3_intarray
+{
+ int n; // Number of elements in the array
+ sqlite3_int64* a; // Contents of the array
+ void (*xFree)(void*); // Function used to free a[]
+};
+
+// Objects used internally by the virtual table implementation
+typedef struct intarray_vtab intarray_vtab;
+typedef struct intarray_cursor intarray_cursor;
+
+/// Definition of intarray table object (internal)
+struct intarray_vtab
+{
+ sqlite3_vtab base; // Base class
+ sqlite3_intarray* pContent; // Content of the integer array
+};
+
+/// Definition of intarray cursor object (internal)
+struct intarray_cursor
+{
+ sqlite3_vtab_cursor base; // Base class
+ int i; // Current cursor position
+};
+
+// Free an sqlite3_intarray object.
+static void intarrayFree(sqlite3_intarray* p)
+{
+ if (p->a != NULL && p->xFree)
+ {
+ p->xFree(p->a);
+ }
+ sqlite3_free(p);
+}
+
+// Table destructor for the intarray module.
+static int intarrayDestroy(sqlite3_vtab* p)
+{
+ intarray_vtab* pVtab = (intarray_vtab*)p;
+ sqlite3_free(pVtab);
+ return 0;
+}
+
+// Table constructor for the intarray module.
+static int intarrayCreate(sqlite3* db, // Database where module is created
+ void* pAux, // clientdata for the module
+ int /*argc*/, // Number of arguments
+ const char* const* /*argv*/, // Value for all arguments
+ sqlite3_vtab** ppVtab, // Write the new virtual table object here
+ char** /*pzErr*/) // Put error message text here
+{
+ int rc = SQLITE_NOMEM;
+ intarray_vtab* pVtab = (intarray_vtab*) sqlite3_malloc(sizeof(intarray_vtab));
+
+ if (pVtab)
+ {
+ memset(pVtab, 0, sizeof(intarray_vtab));
+ pVtab->pContent = (sqlite3_intarray*)pAux;
+ rc = sqlite3_declare_vtab(db, "CREATE TABLE x(value INTEGER PRIMARY KEY)");
+ }
+ *ppVtab = (sqlite3_vtab*)pVtab;
+ return rc;
+}
+
+// Open a new cursor on the intarray table.
+static int intarrayOpen(sqlite3_vtab* /*pVTab*/, sqlite3_vtab_cursor** ppCursor)
+{
+ int rc = SQLITE_NOMEM;
+ intarray_cursor* pCur = (intarray_cursor*) sqlite3_malloc(sizeof(intarray_cursor));
+ if (pCur)
+ {
+ memset(pCur, 0, sizeof(intarray_cursor));
+ *ppCursor = (sqlite3_vtab_cursor *)pCur;
+ rc = SQLITE_OK;
+ }
+ return rc;
+}
+
+// Close a intarray table cursor.
+static int intarrayClose(sqlite3_vtab_cursor* cur)
+{
+ intarray_cursor* pCur = (intarray_cursor*)cur;
+ sqlite3_free(pCur);
+ return SQLITE_OK;
+}
+
+// Retrieve a column of data.
+static int intarrayColumn(sqlite3_vtab_cursor* cur, sqlite3_context* ctx, int /*i*/)
+{
+ intarray_cursor* pCur = (intarray_cursor*)cur;
+ intarray_vtab* pVtab = (intarray_vtab*)cur->pVtab;
+ if (pCur->i >= 0 && pCur->i < pVtab->pContent->n)
+ {
+ sqlite3_result_int64(ctx, pVtab->pContent->a[pCur->i]);
+ }
+ return SQLITE_OK;
+}
+
+// Retrieve the current rowid.
+static int intarrayRowid(sqlite3_vtab_cursor* cur, sqlite_int64* pRowid)
+{
+ intarray_cursor* pCur = (intarray_cursor*)cur;
+ *pRowid = pCur->i;
+ return SQLITE_OK;
+}
+
+static int intarrayEof(sqlite3_vtab_cursor* cur)
+{
+ intarray_cursor* pCur = (intarray_cursor*)cur;
+ intarray_vtab* pVtab = (intarray_vtab*)cur->pVtab;
+ return pCur->i >= pVtab->pContent->n;
+}
+
+// Advance the cursor to the next row.
+static int intarrayNext(sqlite3_vtab_cursor* cur)
+{
+ intarray_cursor* pCur = (intarray_cursor*)cur;
+ pCur->i++;
+ return SQLITE_OK;
+}
+
+// Reset a intarray table cursor.
+static int intarrayFilter(sqlite3_vtab_cursor* pVtabCursor,
+ int /*idxNum*/, const char* /*idxStr*/,
+ int /*argc*/, sqlite3_value** /*argv*/)
+{
+ intarray_cursor *pCur = (intarray_cursor *)pVtabCursor;
+ pCur->i = 0;
+ return SQLITE_OK;
+}
+
+// Analyse the WHERE condition.
+static int intarrayBestIndex(sqlite3_vtab* /*tab*/, sqlite3_index_info* /*pIdxInfo*/)
+{
+ return SQLITE_OK;
+}
+
+// Definition of a virtual table module for integer collections
+static sqlite3_module intarrayModule =
+{
+ 0, // iVersion
+ intarrayCreate, // xCreate - create a new virtual table
+ intarrayCreate, // xConnect - connect to an existing vtab
+ intarrayBestIndex, // xBestIndex - find the best query index
+ intarrayDestroy, // xDisconnect - disconnect a vtab
+ intarrayDestroy, // xDestroy - destroy a vtab
+ intarrayOpen, // xOpen - open a cursor
+ intarrayClose, // xClose - close a cursor
+ intarrayFilter, // xFilter - configure scan constraints
+ intarrayNext, // xNext - advance a cursor
+ intarrayEof, // xEof
+ intarrayColumn, // xColumn - read data
+ intarrayRowid, // xRowid - read data
+ 0, // xUpdate
+ 0, // xBegin
+ 0, // xSync
+ 0, // xCommit
+ 0, // xRollback
+ 0, // xFindMethod
+ 0, // xRename
+};
+
+/// Definition of the sqlite3_chararray object (internal)
+struct sqlite3_chararray
+{
+ int n; // Number of elements in the array
+ char** a; // Contents of the array
+ void (*xFree)(void*); // Function used to free a[]
+};
+
+// Objects used internally by the virtual table implementation
+typedef struct chararray_vtab chararray_vtab;
+typedef struct chararray_cursor chararray_cursor;
+
+/// Definition of chararray table object (internal)
+struct chararray_vtab
+{
+ sqlite3_vtab base; // Base class
+ sqlite3_chararray* pContent; // Content of the char array
+};
+
+/// Definition of chararray cursor object (internal)
+struct chararray_cursor
+{
+ sqlite3_vtab_cursor base; // Base class
+ int i; // Current cursor position
+};
+
+// Free an sqlite3_chararray object.
+static void chararrayFree(sqlite3_chararray* p)
+{
+ if (p->a != NULL && p->xFree)
+ {
+ int j;
+ for (j = 0; j < p->n; ++j)
+ {
+ p->xFree(p->a[j]);
+ }
+ p->xFree(p->a);
+ }
+ sqlite3_free(p);
+}
+
+// Table destructor for the chararray module.
+static int chararrayDestroy(sqlite3_vtab* p)
+{
+ chararray_vtab* pVtab = (chararray_vtab*)p;
+ sqlite3_free(pVtab);
+ return 0;
+}
+
+// Table constructor for the chararray module.
+static int chararrayCreate(sqlite3* db, // Database where module is created
+ void* pAux, // clientdata for the module
+ int /*argc*/, // Number of arguments
+ const char* const* /*argv*/, // Value for all arguments
+ sqlite3_vtab** ppVtab, // Write the new virtual table object here
+ char** /*pzErr*/) // Put error message text here
+{
+ int rc = SQLITE_NOMEM;
+ chararray_vtab* pVtab = (chararray_vtab*) sqlite3_malloc(sizeof(chararray_vtab));
+
+ if (pVtab)
+ {
+ memset(pVtab, 0, sizeof(chararray_vtab));
+ pVtab->pContent = (sqlite3_chararray*)pAux;
+ rc = sqlite3_declare_vtab(db, "CREATE TABLE x(value CHAR PRIMARY KEY)");
+ }
+ *ppVtab = (sqlite3_vtab*)pVtab;
+ return rc;
+}
+
+// Open a new cursor on the chararray table.
+static int chararrayOpen(sqlite3_vtab* /*pVTab*/, sqlite3_vtab_cursor** ppCursor)
+{
+ int rc = SQLITE_NOMEM;
+ chararray_cursor* pCur = (chararray_cursor*) sqlite3_malloc(sizeof(chararray_cursor));
+ if (pCur)
+ {
+ memset(pCur, 0, sizeof(chararray_cursor));
+ *ppCursor = (sqlite3_vtab_cursor *)pCur;
+ rc = SQLITE_OK;
+ }
+ return rc;
+}
+
+// Close a chararray table cursor.
+static int chararrayClose(sqlite3_vtab_cursor* cur)
+{
+ chararray_cursor* pCur = (chararray_cursor*)cur;
+ sqlite3_free(pCur);
+ return SQLITE_OK;
+}
+
+// Retrieve a column of data.
+static int chararrayColumn(sqlite3_vtab_cursor* cur, sqlite3_context* ctx, int /*i*/)
+{
+ chararray_cursor* pCur = (chararray_cursor*)cur;
+ chararray_vtab* pVtab = (chararray_vtab*)cur->pVtab;
+ if (pCur->i >= 0 && pCur->i < pVtab->pContent->n)
+ {
+ sqlite3_result_text(ctx, pVtab->pContent->a[pCur->i], -1, SQLITE_STATIC);
+ }
+ return SQLITE_OK;
+}
+
+// Retrieve the current rowid.
+static int chararrayRowid(sqlite3_vtab_cursor* cur, sqlite_int64* pRowid)
+{
+ chararray_cursor* pCur = (chararray_cursor*)cur;
+ *pRowid = pCur->i;
+ return SQLITE_OK;
+}
+
+static int chararrayEof(sqlite3_vtab_cursor* cur)
+{
+ chararray_cursor* pCur = (chararray_cursor*)cur;
+ chararray_vtab* pVtab = (chararray_vtab*)cur->pVtab;
+ return pCur->i >= pVtab->pContent->n;
+}
+
+// Advance the cursor to the next row.
+static int chararrayNext(sqlite3_vtab_cursor* cur)
+{
+ chararray_cursor* pCur = (chararray_cursor*)cur;
+ pCur->i++;
+ return SQLITE_OK;
+}
+
+// Reset a chararray table cursor.
+static int chararrayFilter(sqlite3_vtab_cursor* pVtabCursor,
+ int /*idxNum*/, const char* /*idxStr*/,
+ int /*argc*/, sqlite3_value** /*argv*/)
+{
+ chararray_cursor *pCur = (chararray_cursor *)pVtabCursor;
+ pCur->i = 0;
+ return SQLITE_OK;
+}
+
+// Analyse the WHERE condition.
+static int chararrayBestIndex(sqlite3_vtab* /*tab*/, sqlite3_index_info* /*pIdxInfo*/)
+{
+ return SQLITE_OK;
+}
+
+// Definition of a virtual table module for string collections
+static sqlite3_module chararrayModule =
+{
+ 0, // iVersion
+ chararrayCreate, // xCreate - create a new virtual table
+ chararrayCreate, // xConnect - connect to an existing vtab
+ chararrayBestIndex, // xBestIndex - find the best query index
+ chararrayDestroy, // xDisconnect - disconnect a vtab
+ chararrayDestroy, // xDestroy - destroy a vtab
+ chararrayOpen, // xOpen - open a cursor
+ chararrayClose, // xClose - close a cursor
+ chararrayFilter, // xFilter - configure scan constraints
+ chararrayNext, // xNext - advance a cursor
+ chararrayEof, // xEof
+ chararrayColumn, // xColumn - read data
+ chararrayRowid, // xRowid - read data
+ 0, // xUpdate
+ 0, // xBegin
+ 0, // xSync
+ 0, // xCommit
+ 0, // xRollback
+ 0, // xFindMethod
+ 0, // xRename
+};
+
+#endif // WXSQLITE3_USE_NAMED_COLLECTIONS
+
+wxSQLite3NamedCollection::wxSQLite3NamedCollection()
+{
+ m_name = wxEmptyString;
+ m_data = NULL;
+}
+
+wxSQLite3NamedCollection::wxSQLite3NamedCollection(const wxString& collectionName, void* collectionData)
+{
+ m_name = collectionName;
+ m_data = collectionData;
+}
+
+wxSQLite3NamedCollection::wxSQLite3NamedCollection(const wxSQLite3NamedCollection& collection)
+ : m_name(collection.m_name), m_data(collection.m_data)
+{
+}
+
+wxSQLite3NamedCollection&
+wxSQLite3NamedCollection::operator=(const wxSQLite3NamedCollection& collection)
+{
+ if (this != &collection)
+ {
+ m_name = collection.m_name;
+ m_data = collection.m_data;
+ }
+ return *this;
+}
+
+wxSQLite3NamedCollection::~wxSQLite3NamedCollection()
+{
+}
+
+wxSQLite3IntegerCollection::wxSQLite3IntegerCollection()
+ : wxSQLite3NamedCollection(wxEmptyString, NULL)
+{
+}
+
+wxSQLite3IntegerCollection::wxSQLite3IntegerCollection(const wxSQLite3IntegerCollection& collection)
+ : wxSQLite3NamedCollection(collection)
+{
+}
+
+wxSQLite3IntegerCollection&
+wxSQLite3IntegerCollection::operator=(const wxSQLite3IntegerCollection& collection)
+{
+ if (this != &collection)
+ {
+ wxSQLite3NamedCollection::operator=(collection);
+ }
+ return *this;
+}
+
+wxSQLite3IntegerCollection::wxSQLite3IntegerCollection(const wxString& collectionName, void* collectionData)
+ : wxSQLite3NamedCollection(collectionName, collectionData)
+{
+}
+
+wxSQLite3IntegerCollection::~wxSQLite3IntegerCollection()
+{
+}
+
+void
+wxSQLite3IntegerCollection::Bind(const wxArrayInt& integerCollection)
+{
+ size_t n = integerCollection.Count();
+ sqlite3_intarray* pIntArray = (sqlite3_intarray*) m_data;
+ if (m_data != NULL)
+ {
+ if (pIntArray->a != NULL && pIntArray->xFree)
+ {
+ pIntArray->xFree(pIntArray->a);
+ }
+ }
+ pIntArray->n = n;
+ if (n > 0)
+ {
+ pIntArray->a = (sqlite3_int64*) sqlite3_malloc(sizeof(sqlite3_int64)*n);
+ pIntArray->xFree = sqlite3_free;
+ }
+ else
+ {
+ pIntArray->a = NULL;
+ pIntArray->xFree = NULL;
+ }
+
+ size_t j;
+ for (j = 0; j < n; ++j)
+ {
+ pIntArray->a[j] = integerCollection[j];
+ }
+}
+
+void
+wxSQLite3IntegerCollection::Bind(int n, int* integerCollection)
+{
+ sqlite3_intarray* pIntArray = (sqlite3_intarray*) m_data;
+ if (m_data != NULL)
+ {
+ if (pIntArray->a != NULL && pIntArray->xFree)
+ {
+ pIntArray->xFree(pIntArray->a);
+ }
+ }
+ pIntArray->n = n;
+ if (n > 0)
+ {
+ pIntArray->a = (sqlite3_int64*) sqlite3_malloc(sizeof(sqlite3_int64)*n);
+ pIntArray->xFree = sqlite3_free;
+ }
+ else
+ {
+ pIntArray->a = NULL;
+ pIntArray->xFree = NULL;
+ }
+
+ int j;
+ for (j = 0; j < n; ++j)
+ {
+ pIntArray->a[j] = integerCollection[j];
+ }
+}
+
+wxSQLite3IntegerCollection
+wxSQLite3Database::CreateIntegerCollection(const wxString& collectionName)
+{
+#if WXSQLITE3_USE_NAMED_COLLECTIONS
+ int rc = SQLITE_OK;
+ wxCharBuffer strCollectionName = collectionName.ToUTF8();
+ const char* zName = strCollectionName;
+ sqlite3_intarray* p = (sqlite3_intarray*) sqlite3_malloc( sizeof(*p) );
+ if (p == 0)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOMEM, wxSQLite3IntegerCollection());
+ }
+ p->n = 0;
+ p->a= NULL;
+ p->xFree = NULL;
+ rc = sqlite3_create_module_v2((sqlite3*)m_db, zName, &intarrayModule, p, (void(*)(void*))intarrayFree);
+ if (rc == SQLITE_OK)
+ {
+ wxSQLite3StatementBuffer zBuffer;
+ const char* zSql = zBuffer.Format("CREATE VIRTUAL TABLE temp.%Q USING %Q", zName, zName);
+ rc = sqlite3_exec((sqlite3*)m_db, zSql, 0, 0, 0);
+ }
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), wxSQLite3IntegerCollection());
+ }
+ return wxSQLite3IntegerCollection(collectionName, p);
+#else
+ wxUnusedVar(collectionName);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOCOLLECTIONS, );
+#endif // WXSQLITE3_USE_NAMED_COLLECTIONS
+}
+
+wxSQLite3StringCollection::wxSQLite3StringCollection()
+ : wxSQLite3NamedCollection(wxEmptyString, NULL)
+{
+}
+
+wxSQLite3StringCollection::wxSQLite3StringCollection(const wxSQLite3StringCollection& collection)
+ : wxSQLite3NamedCollection(collection)
+{
+}
+
+wxSQLite3StringCollection&
+wxSQLite3StringCollection::operator=(const wxSQLite3StringCollection& collection)
+{
+ if (this != &collection)
+ {
+ wxSQLite3StringCollection::operator=(collection);
+ }
+ return *this;
+}
+
+wxSQLite3StringCollection::wxSQLite3StringCollection(const wxString& collectionName, void* collectionData)
+ : wxSQLite3NamedCollection(collectionName, collectionData)
+{
+}
+
+wxSQLite3StringCollection::~wxSQLite3StringCollection()
+{
+}
+
+void
+wxSQLite3StringCollection::Bind(const wxArrayString& stringCollection)
+{
+ size_t n = stringCollection.Count();
+ sqlite3_chararray* pCharArray = (sqlite3_chararray*) m_data;
+ if (m_data != NULL)
+ {
+ if (pCharArray->a != NULL && pCharArray->xFree)
+ {
+ pCharArray->xFree(pCharArray->a);
+ }
+ }
+ pCharArray->n = n;
+ if (n > 0)
+ {
+ pCharArray->a = (char**) sqlite3_malloc(sizeof(char*)*n);
+ pCharArray->xFree = sqlite3_free;
+ }
+ else
+ {
+ pCharArray->a = NULL;
+ pCharArray->xFree = NULL;
+ }
+
+ size_t j;
+ for (j = 0; j < n; ++j)
+ {
+ wxCharBuffer strValue = stringCollection[j].ToUTF8();
+ const char* zValue = strValue;
+ size_t k = strlen(zValue) + 1;
+ pCharArray->a[j] = (char*) sqlite3_malloc(sizeof(char)*k);
+ strcpy(pCharArray->a[j], zValue);
+ }
+}
+
+wxSQLite3StringCollection
+wxSQLite3Database::CreateStringCollection(const wxString& collectionName)
+{
+#if WXSQLITE3_USE_NAMED_COLLECTIONS
+ int rc = SQLITE_OK;
+ wxCharBuffer strCollectionName = collectionName.ToUTF8();
+ const char* zName = strCollectionName;
+ sqlite3_chararray* p = (sqlite3_chararray*) sqlite3_malloc( sizeof(*p) );
+ if (p == 0)
+ {
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOMEM, wxSQLite3StringCollection());
+ }
+ p->n = 0;
+ p->a= NULL;
+ p->xFree = NULL;
+ rc = sqlite3_create_module_v2((sqlite3*)m_db, zName, &chararrayModule, p, (void(*)(void*))chararrayFree);
+ if (rc == SQLITE_OK)
+ {
+ wxSQLite3StatementBuffer zBuffer;
+ const char* zSql = zBuffer.Format("CREATE VIRTUAL TABLE temp.%Q USING %Q", zName, zName);
+ rc = sqlite3_exec((sqlite3*)m_db, zSql, 0, 0, 0);
+ }
+ if (rc != SQLITE_OK)
+ {
+ const char* localError = sqlite3_errmsg((sqlite3*) m_db);
+ WXSQLITE3_ERROR(rc, wxString::FromUTF8(localError), wxSQLite3StringCollection());
+ }
+ return wxSQLite3StringCollection(collectionName, p);
+#else
+ wxUnusedVar(collectionName);
+ WXSQLITE3_ERROR(WXSQLITE_ERROR, wxERRMSG_NOCOLLECTIONS, wxSQLite3StringCollection());
+#endif // WXSQLITE3_USE_NAMED_COLLECTIONS
+}
+
diff --git a/ubuntu.sh b/ubuntu.sh
index ba76f335..c011435b 100755
--- a/ubuntu.sh
+++ b/ubuntu.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-LIST="quantal precise oneiric natty"
+LIST="raring quantal precise oneiric natty"
NUMBER=1
diff --git a/windows.sh b/windows.sh
index fee79b33..5456e5c2 100755
--- a/windows.sh
+++ b/windows.sh
@@ -6,7 +6,7 @@
##################################################################
WXW_VERSION="2.8.12" # Version wxWidgets
-FT2_VERSION="2.4.10" # Version FreeType2
+FT2_VERSION="2.4.11" # Version FreeType2
##################################################################
# Detect MyRuLib version
@@ -94,6 +94,7 @@ rm -rf build_msw
mkdir build_msw
cd build_msw
LDFLAGS="-static-libgcc -static-libstdc++" ../configure \
+ --with-expat \
--with-wx-prefix=$BUILD_DIR \
--host=i686-w64-mingw32 \
--with-locale
@@ -105,6 +106,7 @@ rm -rf build_cr3
mkdir build_cr3
cd build_cr3
LDFLAGS="-static-libgcc -static-libstdc++" ../configure \
+ --with-expat \
--host=i686-w64-mingw32 \
--with-wx-prefix=$BUILD_DIR \
--with-ft-prefix=$BUILD_DIR \