1
///////////////////////////////////////////////////////////////////////////////
3
// Purpose: Implementation of wxSQLite3 classes
4
// Author: Ulrich Telle
7
// Copyright: (c) Ulrich Telle
8
// Licence: wxWindows licence
9
///////////////////////////////////////////////////////////////////////////////
11
/// \file wxsqlite3.cpp Implementation of the wxSQLite3 class
13
#if defined(__GNUG__) && !defined(__APPLE__)
14
#pragma implementation "wxsqlite3.h"
18
#include <wx/wxprec.h>
28
#include "wx/wxsqlite3.h"
29
#include "wx/wxsqlite3opt.h"
31
// Suppress some Visual C++ warnings regarding the default constructor
32
// for a C struct used only in SQLite modules
34
#pragma warning (disable:4510)
35
#pragma warning (disable:4610)
40
// Dynamic loading of the SQLite library
42
#if wxUSE_DYNAMIC_SQLITE3_LOAD
44
#include "wx/dynlib.h"
46
#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
47
typedef rtype (*p##fname) farg ; \
48
static p##fname s_##fname = NULL;
49
#include "wx/wxsqlite3dyn.h"
52
static wxDynamicLibrary s_dll;
54
static void InitSQLite3DLL()
62
if (! s_dll.Load(wxT("sqlite3")))
64
if (! s_dll.Load(wxT("libsqlite3")))
67
throw wxSQLite3Exception(-1, wxT("error loading dynamic library"));
70
#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
71
s_##fname = (p##fname) s_dll.GetSymbol(wxT(#fname));\
75
throw wxSQLite3Exception(-1, wxT("error getting symbol <") wxT(#fname) wxT(">"));\
77
#include "wx/wxsqlite3dyn.h"
82
#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
86
rcode s_##fname farguse;\
88
#include "wx/wxsqlite3dyn.h"
91
#endif // wxUSE_DYNAMIC_SQLITE3_LOAD
95
const wxChar* wxERRMSG_NODB = wxTRANSLATE("No Database opened");
96
const wxChar* wxERRMSG_NOSTMT = wxTRANSLATE("Statement not accessible");
97
const wxChar* wxERRMSG_NOMEM = wxTRANSLATE("Out of memory");
98
const wxChar* wxERRMSG_DECODE = wxTRANSLATE("Cannot decode binary");
99
const wxChar* wxERRMSG_INVALID_INDEX = wxTRANSLATE("Invalid field index");
100
const wxChar* wxERRMSG_INVALID_NAME = wxTRANSLATE("Invalid field name");
101
const wxChar* wxERRMSG_INVALID_ROW = wxTRANSLATE("Invalid row index");
102
const wxChar* wxERRMSG_INVALID_QUERY = wxTRANSLATE("Invalid scalar query");
103
const wxChar* wxERRMSG_INVALID_BLOB = wxTRANSLATE("Invalid BLOB handle");
105
const wxChar* wxERRMSG_NORESULT = wxTRANSLATE("Null Results pointer");
106
const wxChar* wxERRMSG_BIND_STR = wxTRANSLATE("Error binding string param");
107
const wxChar* wxERRMSG_BIND_INT = wxTRANSLATE("Error binding int param");
108
const wxChar* wxERRMSG_BIND_INT64 = wxTRANSLATE("Error binding int64 param");
109
const wxChar* wxERRMSG_BIND_DBL = wxTRANSLATE("Error binding double param");
110
const wxChar* wxERRMSG_BIND_BLOB = wxTRANSLATE("Error binding blob param");
111
const wxChar* wxERRMSG_BIND_DATETIME = wxTRANSLATE("Error binding date/time param");
112
const wxChar* wxERRMSG_BIND_NULL = wxTRANSLATE("Error binding NULL param");
113
const wxChar* wxERRMSG_BIND_ZEROBLOB = wxTRANSLATE("Error binding zero blob param");
114
const wxChar* wxERRMSG_BIND_CLEAR = wxTRANSLATE("Error clearing bindings");
116
const wxChar* wxERRMSG_NOMETADATA = wxTRANSLATE("Meta data support not available");
117
const wxChar* wxERRMSG_NOCODEC = wxTRANSLATE("Encryption support not available");
118
const wxChar* wxERRMSG_NOLOADEXT = wxTRANSLATE("Loadable extension support not available");
119
const wxChar* wxERRMSG_NOINCBLOB = wxTRANSLATE("Incremental BLOB support not available");
120
const wxChar* wxERRMSG_NOSAVEPOINT = wxTRANSLATE("Savepoint support not available");
122
const wxChar* wxERRMSG_SHARED_CACHE = wxTRANSLATE("Setting SQLite shared cache mode failed");
124
const wxChar* wxERRMSG_INITIALIZE = wxTRANSLATE("Initialization of SQLite failed");
125
const wxChar* wxERRMSG_SHUTDOWN = wxTRANSLATE("Shutdown of SQLite failed");
127
// ----------------------------------------------------------------------------
128
// inline conversion from UTF8 strings to wxStringe
129
// ----------------------------------------------------------------------------
131
inline wxString UTF8toWxString(const char* localValue)
134
return wxString(localValue, wxConvUTF8);
136
return wxString(wxConvUTF8.cMB2WC(localValue), *wxConvCurrent);
140
// ----------------------------------------------------------------------------
141
// inline conversion from wxString to wxLongLong
142
// ----------------------------------------------------------------------------
144
inline wxLongLong ConvertStringToLongLong(const wxString& str, wxLongLong defValue /*=0*/)
146
size_t n = str.Length();
148
wxLongLong value = 0;
149
bool negative = false;
159
if (str[j] < '0' || str[j] > '9')
164
value += (str[j] - '0');
168
return negative ? -value : value;
171
// ----------------------------------------------------------------------------
172
// wxSQLite3Exception: class
173
// ----------------------------------------------------------------------------
175
wxSQLite3Exception::wxSQLite3Exception(int errorCode, const wxString& errorMsg)
176
: m_errorCode(errorCode)
178
m_errorMessage = ErrorCodeAsString(errorCode) + _T("[") +
179
wxString::Format(_T("%d"), errorCode) + _T("]: ") +
180
wxGetTranslation(errorMsg);
183
wxSQLite3Exception::wxSQLite3Exception(const wxSQLite3Exception& e)
184
: m_errorCode(e.m_errorCode), m_errorMessage(e.m_errorMessage)
188
const wxString wxSQLite3Exception::ErrorCodeAsString(int errorCode)
192
case SQLITE_OK : return _T("SQLITE_OK");
193
case SQLITE_ERROR : return _T("SQLITE_ERROR");
194
case SQLITE_INTERNAL : return _T("SQLITE_INTERNAL");
195
case SQLITE_PERM : return _T("SQLITE_PERM");
196
case SQLITE_ABORT : return _T("SQLITE_ABORT");
197
case SQLITE_BUSY : return _T("SQLITE_BUSY");
198
case SQLITE_LOCKED : return _T("SQLITE_LOCKED");
199
case SQLITE_NOMEM : return _T("SQLITE_NOMEM");
200
case SQLITE_READONLY : return _T("SQLITE_READONLY");
201
case SQLITE_INTERRUPT : return _T("SQLITE_INTERRUPT");
202
case SQLITE_IOERR : return _T("SQLITE_IOERR");
203
case SQLITE_CORRUPT : return _T("SQLITE_CORRUPT");
204
case SQLITE_NOTFOUND : return _T("SQLITE_NOTFOUND");
205
case SQLITE_FULL : return _T("SQLITE_FULL");
206
case SQLITE_CANTOPEN : return _T("SQLITE_CANTOPEN");
207
case SQLITE_PROTOCOL : return _T("SQLITE_PROTOCOL");
208
case SQLITE_EMPTY : return _T("SQLITE_EMPTY");
209
case SQLITE_SCHEMA : return _T("SQLITE_SCHEMA");
210
case SQLITE_TOOBIG : return _T("SQLITE_TOOBIG");
211
case SQLITE_CONSTRAINT : return _T("SQLITE_CONSTRAINT");
212
case SQLITE_MISMATCH : return _T("SQLITE_MISMATCH");
213
case SQLITE_MISUSE : return _T("SQLITE_MISUSE");
214
case SQLITE_NOLFS : return _T("SQLITE_NOLFS");
215
case SQLITE_AUTH : return _T("SQLITE_AUTH");
216
case SQLITE_FORMAT : return _T("SQLITE_FORMAT");
217
case SQLITE_RANGE : return _T("SQLITE_RANGE");
218
case SQLITE_NOTADB : return _T("SQLITE_NOTADB");
219
case SQLITE_ROW : return _T("SQLITE_ROW");
220
case SQLITE_DONE : return _T("SQLITE_DONE");
221
// Extended error codes
222
case SQLITE_IOERR_READ : return _T("SQLITE_IOERR_READ");
223
case SQLITE_IOERR_SHORT_READ : return _T("SQLITE_IOERR_SHORT_READ");
224
case SQLITE_IOERR_WRITE : return _T("SQLITE_IOERR_WRITE");
225
case SQLITE_IOERR_FSYNC : return _T("SQLITE_IOERR_FSYNC");
226
case SQLITE_IOERR_DIR_FSYNC : return _T("SQLITE_IOERR_DIR_FSYNC");
227
case SQLITE_IOERR_TRUNCATE : return _T("SQLITE_IOERR_TRUNCATE");
228
case SQLITE_IOERR_FSTAT : return _T("SQLITE_IOERR_FSTAT");
229
case SQLITE_IOERR_UNLOCK : return _T("SQLITE_IOERR_UNLOCK");
230
case SQLITE_IOERR_RDLOCK : return _T("SQLITE_IOERR_RDLOCK");
231
case SQLITE_IOERR_DELETE : return _T("SQLITE_IOERR_DELETE");
232
#if SQLITE_VERSION_NUMBER >= 3004000
233
case SQLITE_IOERR_BLOCKED : return _T("SQLITE_IOERR_BLOCKED");
235
#if SQLITE_VERSION_NUMBER >= 3005001
236
case SQLITE_IOERR_NOMEM : return _T("SQLITE_IOERR_NOMEM");
238
#if SQLITE_VERSION_NUMBER >= 3006000
239
case SQLITE_IOERR_ACCESS : return _T("SQLITE_IOERR_ACCESS");
240
case SQLITE_IOERR_CHECKRESERVEDLOCK : return _T("SQLITE_IOERR_CHECKRESERVEDLOCK");
242
#if SQLITE_VERSION_NUMBER >= 3006002
243
case SQLITE_IOERR_LOCK : return _T("SQLITE_IOERR_LOCK");
246
case WXSQLITE_ERROR : return _T("WXSQLITE_ERROR");
247
default : return _T("UNKNOWN_ERROR");
251
wxSQLite3Exception::~wxSQLite3Exception()
255
// ----------------------------------------------------------------------------
256
// wxSQLite3StatementBuffer: class providing a statement buffer
257
// for use with the SQLite3 vmprintf function
258
// ----------------------------------------------------------------------------
260
wxSQLite3StatementBuffer::wxSQLite3StatementBuffer()
265
wxSQLite3StatementBuffer::~wxSQLite3StatementBuffer()
270
void wxSQLite3StatementBuffer::Clear()
274
sqlite3_free(m_buffer);
280
const char* wxSQLite3StatementBuffer::Format(const char* format, ...)
284
va_start(va, format);
285
m_buffer = sqlite3_vmprintf(format, va);
290
// ----------------------------------------------------------------------------
291
// wxSQLite3ResultSet: class providing access to the result set of a query
292
// ----------------------------------------------------------------------------
294
wxSQLite3ResultSet::wxSQLite3ResultSet()
303
wxSQLite3ResultSet::wxSQLite3ResultSet(const wxSQLite3ResultSet& resultSet)
305
m_stmt = resultSet.m_stmt;
306
// Only one object can own the statement
307
const_cast<wxSQLite3ResultSet&>(resultSet).m_stmt = 0;
308
m_eof = resultSet.m_eof;
309
m_first = resultSet.m_first;
310
m_cols = resultSet.m_cols;
311
m_ownStmt = resultSet.m_ownStmt;
314
wxSQLite3ResultSet::wxSQLite3ResultSet(void* db,
318
bool ownStmt /*=true*/)
324
m_cols = sqlite3_column_count((sqlite3_stmt*) m_stmt);
328
wxSQLite3ResultSet::~wxSQLite3ResultSet()
339
wxSQLite3ResultSet& wxSQLite3ResultSet::operator=(const wxSQLite3ResultSet& resultSet)
348
m_stmt = resultSet.m_stmt;
349
// Only one object can own the statement
350
const_cast<wxSQLite3ResultSet&>(resultSet).m_stmt = 0;
351
m_eof = resultSet.m_eof;
352
m_first = resultSet.m_first;
353
m_cols = resultSet.m_cols;
354
m_ownStmt = resultSet.m_ownStmt;
358
int wxSQLite3ResultSet::GetColumnCount()
364
wxString wxSQLite3ResultSet::GetAsString(int columnIndex)
368
if (columnIndex < 0 || columnIndex > m_cols-1)
370
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
373
const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
374
return UTF8toWxString(localValue);
377
wxString wxSQLite3ResultSet::GetAsString(const wxString& columnName)
379
int columnIndex = FindColumnIndex(columnName);
380
const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
381
return UTF8toWxString(localValue);
384
int wxSQLite3ResultSet::GetInt(int columnIndex, int nullValue /* = 0 */)
386
if (GetColumnType(columnIndex) == SQLITE_NULL)
392
return sqlite3_column_int((sqlite3_stmt*) m_stmt, columnIndex);
397
int wxSQLite3ResultSet::GetInt(const wxString& columnName, int nullValue /* = 0 */)
399
int columnIndex = FindColumnIndex(columnName);
400
return GetInt(columnIndex, nullValue);
403
wxLongLong wxSQLite3ResultSet::GetInt64(int columnIndex, wxLongLong nullValue /* = 0 */)
405
if (GetColumnType(columnIndex) == SQLITE_NULL)
411
return wxLongLong(sqlite3_column_int64((sqlite3_stmt*) m_stmt, columnIndex));
415
wxLongLong wxSQLite3ResultSet::GetInt64(const wxString& columnName, wxLongLong nullValue /* = 0 */)
417
int columnIndex = FindColumnIndex(columnName);
418
return GetInt64(columnIndex, nullValue);
421
double wxSQLite3ResultSet::GetDouble(int columnIndex, double nullValue /* = 0.0 */)
423
if (GetColumnType(columnIndex) == SQLITE_NULL)
429
return sqlite3_column_double((sqlite3_stmt*) m_stmt, columnIndex);
433
double wxSQLite3ResultSet::GetDouble(const wxString& columnName, double nullValue /* = 0.0 */)
435
int columnIndex = FindColumnIndex(columnName);
436
return GetDouble(columnIndex, nullValue);
439
wxString wxSQLite3ResultSet::GetString(int columnIndex, const wxString& nullValue /* = wxEmptyString */)
441
if (GetColumnType(columnIndex) == SQLITE_NULL)
447
const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
448
return UTF8toWxString(localValue);
452
wxString wxSQLite3ResultSet::GetString(const wxString& columnName, const wxString& nullValue /* = wxEmptyString */)
454
int columnIndex = FindColumnIndex(columnName);
455
return GetString(columnIndex, nullValue);
458
const unsigned char* wxSQLite3ResultSet::GetBlob(int columnIndex, int& len)
462
if (columnIndex < 0 || columnIndex > m_cols-1)
464
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
467
len = sqlite3_column_bytes((sqlite3_stmt*) m_stmt, columnIndex);
468
return (const unsigned char*) sqlite3_column_blob((sqlite3_stmt*) m_stmt, columnIndex);
471
const unsigned char* wxSQLite3ResultSet::GetBlob(const wxString& columnName, int& len)
473
int columnIndex = FindColumnIndex(columnName);
474
return GetBlob(columnIndex, len);
477
wxMemoryBuffer& wxSQLite3ResultSet::GetBlob(int columnIndex, wxMemoryBuffer& buffer)
481
if (columnIndex < 0 || columnIndex > m_cols-1)
483
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
486
int len = sqlite3_column_bytes((sqlite3_stmt*) m_stmt, columnIndex);
487
const void* blob = sqlite3_column_blob((sqlite3_stmt*) m_stmt, columnIndex);
488
buffer.AppendData((void*) blob, (size_t) len);
492
wxMemoryBuffer& wxSQLite3ResultSet::GetBlob(const wxString& columnName, wxMemoryBuffer& buffer)
494
int columnIndex = FindColumnIndex(columnName);
495
return GetBlob(columnIndex, buffer);
498
wxDateTime wxSQLite3ResultSet::GetDate(int columnIndex)
500
if (GetColumnType(columnIndex) == SQLITE_NULL)
502
return wxInvalidDateTime;
507
if (date.ParseDate(GetString(columnIndex)) != NULL)
513
return wxInvalidDateTime;
518
wxDateTime wxSQLite3ResultSet::GetDate(const wxString& columnName)
520
int columnIndex = FindColumnIndex(columnName);
521
return GetDate(columnIndex);
525
wxDateTime wxSQLite3ResultSet::GetTime(int columnIndex)
527
if (GetColumnType(columnIndex) == SQLITE_NULL)
529
return wxInvalidDateTime;
534
if (date.ParseTime(GetString(columnIndex)) != NULL)
540
return wxInvalidDateTime;
545
wxDateTime wxSQLite3ResultSet::GetTime(const wxString& columnName)
547
int columnIndex = FindColumnIndex(columnName);
548
return GetTime(columnIndex);
551
wxDateTime wxSQLite3ResultSet::GetDateTime(int columnIndex)
553
if (GetColumnType(columnIndex) == SQLITE_NULL)
555
return wxInvalidDateTime;
560
if (date.ParseDateTime(GetString(columnIndex)) != NULL)
562
date.SetMillisecond(0);
567
return wxInvalidDateTime;
572
wxDateTime wxSQLite3ResultSet::GetDateTime(const wxString& columnName)
574
int columnIndex = FindColumnIndex(columnName);
575
return GetDateTime(columnIndex);
578
wxDateTime wxSQLite3ResultSet::GetTimestamp(int columnIndex)
580
if (GetColumnType(columnIndex) == SQLITE_NULL)
582
return wxInvalidDateTime;
587
if (date.ParseDateTime(GetString(columnIndex)) != NULL)
593
return wxInvalidDateTime;
598
wxDateTime wxSQLite3ResultSet::GetTimestamp(const wxString& columnName)
600
int columnIndex = FindColumnIndex(columnName);
601
return GetTimestamp(columnIndex);
604
wxDateTime wxSQLite3ResultSet::GetNumericDateTime(int columnIndex)
606
if (GetColumnType(columnIndex) == SQLITE_NULL)
608
return wxInvalidDateTime;
612
wxLongLong value = GetInt64(columnIndex);
613
return wxDateTime(value);
617
wxDateTime wxSQLite3ResultSet::GetNumericDateTime(const wxString& columnName)
619
int columnIndex = FindColumnIndex(columnName);
620
return GetNumericDateTime(columnIndex);
623
wxDateTime wxSQLite3ResultSet::GetJulianDayNumber(int columnIndex)
625
if (GetColumnType(columnIndex) == SQLITE_NULL)
627
return wxInvalidDateTime;
631
double value = GetDouble(columnIndex);
632
return wxDateTime(value);
636
wxDateTime wxSQLite3ResultSet::GetJulianDayNumber(const wxString& columnName)
638
int columnIndex = FindColumnIndex(columnName);
639
return GetJulianDayNumber(columnIndex);
642
bool wxSQLite3ResultSet::GetBool(int columnIndex)
644
return GetInt(columnIndex) != 0;
647
bool wxSQLite3ResultSet::GetBool(const wxString& columnName)
649
int columnIndex = FindColumnIndex(columnName);
650
return GetBool(columnIndex);
653
bool wxSQLite3ResultSet::IsNull(int columnIndex)
655
return (GetColumnType(columnIndex) == SQLITE_NULL);
658
bool wxSQLite3ResultSet::IsNull(const wxString& columnName)
660
int columnIndex = FindColumnIndex(columnName);
661
return (GetColumnType(columnIndex) == SQLITE_NULL);
664
int wxSQLite3ResultSet::FindColumnIndex(const wxString& columnName)
668
wxCharBuffer strColumnName = wxConvUTF8.cWC2MB(columnName.wc_str(*wxConvCurrent));
669
const char* localColumnName = strColumnName;
671
if (columnName.Len() > 0)
673
for (int columnIndex = 0; columnIndex < m_cols; columnIndex++)
675
const char* temp = sqlite3_column_name((sqlite3_stmt*) m_stmt, columnIndex);
677
if (strcmp(localColumnName, temp) == 0)
684
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
687
wxString wxSQLite3ResultSet::GetColumnName(int columnIndex)
691
if (columnIndex < 0 || columnIndex > m_cols-1)
693
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
696
const char* localValue = sqlite3_column_name((sqlite3_stmt*) m_stmt, columnIndex);
697
return UTF8toWxString(localValue);
700
wxString wxSQLite3ResultSet::GetDeclaredColumnType(int columnIndex)
704
if (columnIndex < 0 || columnIndex > m_cols-1)
706
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
709
const char* localValue = sqlite3_column_decltype((sqlite3_stmt*) m_stmt, columnIndex);
710
return UTF8toWxString(localValue);
713
int wxSQLite3ResultSet::GetColumnType(int columnIndex)
717
if (columnIndex < 0 || columnIndex > m_cols-1)
719
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
722
return sqlite3_column_type((sqlite3_stmt*) m_stmt, columnIndex);
725
bool wxSQLite3ResultSet::Eof()
731
bool wxSQLite3ResultSet::NextRow()
739
rc = (m_eof) ? SQLITE_DONE : SQLITE_ROW;
743
rc = sqlite3_step((sqlite3_stmt*) m_stmt);
746
if (rc == SQLITE_DONE) // no more rows
751
else if (rc == SQLITE_ROW) // more rows
757
rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
759
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
760
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
764
void wxSQLite3ResultSet::Finalize()
766
if (m_stmt && m_ownStmt)
768
int rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
772
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
773
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
778
wxString wxSQLite3ResultSet::GetSQL()
780
wxString sqlString = wxEmptyString;
781
#if SQLITE_VERSION_NUMBER >= 3005003
783
const char* sqlLocal = sqlite3_sql((sqlite3_stmt*) m_stmt);
784
if (sqlLocal != NULL) sqlString = UTF8toWxString(sqlLocal);
789
bool wxSQLite3ResultSet::IsOk()
791
return (m_db != 0) && (m_stmt != 0);
794
void wxSQLite3ResultSet::CheckStmt()
798
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSTMT);
802
wxString wxSQLite3ResultSet::GetDatabaseName(int columnIndex)
804
#if WXSQLITE3_HAVE_METADATA
806
if (columnIndex < 0 || columnIndex > m_cols-1)
808
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
811
const char* localValue = sqlite3_column_database_name((sqlite3_stmt*) m_stmt, columnIndex);
812
if (localValue != NULL)
813
return UTF8toWxString(localValue);
815
return wxEmptyString;
817
wxUnusedVar(columnIndex);
818
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
822
wxString wxSQLite3ResultSet::GetTableName(int columnIndex)
824
#if WXSQLITE3_HAVE_METADATA
826
if (columnIndex < 0 || columnIndex > m_cols-1)
828
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
831
const char* localValue = sqlite3_column_table_name((sqlite3_stmt*) m_stmt, columnIndex);
832
if (localValue != NULL)
833
return UTF8toWxString(localValue);
835
return wxEmptyString;
837
wxUnusedVar(columnIndex);
838
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
842
wxString wxSQLite3ResultSet::GetOriginName(int columnIndex)
844
#if WXSQLITE3_HAVE_METADATA
846
if (columnIndex < 0 || columnIndex > m_cols-1)
848
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
851
const char* localValue = sqlite3_column_origin_name((sqlite3_stmt*) m_stmt, columnIndex);
852
if (localValue != NULL)
853
return UTF8toWxString(localValue);
855
return wxEmptyString;
857
wxUnusedVar(columnIndex);
858
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
862
// ----------------------------------------------------------------------------
863
// wxSQLite3Table: class holding the complete result set of a query
864
// ----------------------------------------------------------------------------
866
wxSQLite3Table::wxSQLite3Table()
874
wxSQLite3Table::wxSQLite3Table(const wxSQLite3Table& table)
876
m_results = table.m_results;
877
// Only one object can own the results
878
const_cast<wxSQLite3Table&>(table).m_results = 0;
879
m_rows = table.m_rows;
880
m_cols = table.m_cols;
881
m_currentRow = table.m_currentRow;
884
wxSQLite3Table::wxSQLite3Table(char** results, int rows, int cols)
892
wxSQLite3Table::~wxSQLite3Table()
903
wxSQLite3Table& wxSQLite3Table::operator=(const wxSQLite3Table& table)
912
m_results = table.m_results;
913
// Only one object can own the results
914
const_cast<wxSQLite3Table&>(table).m_results = 0;
915
m_rows = table.m_rows;
916
m_cols = table.m_cols;
917
m_currentRow = table.m_currentRow;
921
void wxSQLite3Table::Finalize()
925
sqlite3_free_table(m_results);
930
int wxSQLite3Table::GetColumnCount()
936
int wxSQLite3Table::GetRowCount()
942
int wxSQLite3Table::FindColumnIndex(const wxString& columnName)
946
wxCharBuffer strColumnName = wxConvUTF8.cWC2MB(columnName.wc_str(*wxConvCurrent));
947
const char* localColumnName = strColumnName;
949
if (columnName.Len() > 0)
951
for (int columnIndex = 0; columnIndex < m_cols; columnIndex++)
953
if (strcmp(localColumnName, m_results[columnIndex]) == 0)
960
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_NAME);
963
wxString wxSQLite3Table::GetAsString(int columnIndex)
965
if (columnIndex < 0 || columnIndex > m_cols-1)
967
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
970
int nIndex = (m_currentRow*m_cols) + m_cols + columnIndex;
971
const char* localValue = m_results[nIndex];
972
return UTF8toWxString(localValue);
975
wxString wxSQLite3Table::GetAsString(const wxString& columnName)
977
int index = FindColumnIndex(columnName);
978
return GetAsString(index);
981
int wxSQLite3Table::GetInt(int columnIndex, int nullValue /* = 0 */)
983
if (IsNull(columnIndex))
989
long value = nullValue;
990
GetAsString(columnIndex).ToLong(&value);
995
int wxSQLite3Table::GetInt(const wxString& columnName, int nullValue /* = 0 */)
997
if (IsNull(columnName))
1003
long value = nullValue;
1004
GetAsString(columnName).ToLong(&value);
1009
wxLongLong wxSQLite3Table::GetInt64(int columnIndex, wxLongLong nullValue /* = 0 */)
1011
if (IsNull(columnIndex))
1017
return ConvertStringToLongLong(GetAsString(columnIndex), nullValue);
1021
wxLongLong wxSQLite3Table::GetInt64(const wxString& columnName, wxLongLong nullValue /* = 0 */)
1023
if (IsNull(columnName))
1029
return ConvertStringToLongLong(GetAsString(columnName), nullValue);
1033
// Since SQLite uses internally a locale independent string representation
1034
// of double values, we need to provide our own conversion procedure using
1035
// always a point as the decimal separator.
1036
// The following code duplicates a SQLite utility function with minor modifications.
1038
static double wxSQLite3AtoF(const char *z)
1041
long double v1 = 0.0;
1042
int nSignificant = 0;
1043
while (isspace(*(unsigned char*)z))
1060
while (isdigit(*(unsigned char*)z))
1062
v1 = v1*10.0 + (*z - '0');
1068
long double divisor = 1.0;
1070
if (nSignificant == 0)
1078
while (isdigit(*(unsigned char*)z))
1080
if (nSignificant < 18)
1082
v1 = v1*10.0 + (*z - '0');
1090
if (*z=='e' || *z=='E')
1094
long double scale = 1.0;
1105
while (isdigit(*(unsigned char*)z))
1107
eval = eval*10 + *z - '0';
1110
while (eval >= 64) { scale *= 1.0e+64; eval -= 64; }
1111
while (eval >= 16) { scale *= 1.0e+16; eval -= 16; }
1112
while (eval >= 4) { scale *= 1.0e+4; eval -= 4; }
1113
while (eval >= 1) { scale *= 1.0e+1; eval -= 1; }
1123
return (double) ((sign < 0) ? -v1 : v1);
1126
double wxSQLite3Table::GetDouble(int columnIndex, double nullValue /* = 0.0 */)
1128
if (IsNull(columnIndex))
1134
if (columnIndex < 0 || columnIndex > m_cols-1)
1136
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
1138
int nIndex = (m_currentRow*m_cols) + m_cols + columnIndex;
1139
return wxSQLite3AtoF(m_results[nIndex]);
1143
double wxSQLite3Table::GetDouble(const wxString& columnName, double nullValue /* = 0.0 */)
1145
int index = FindColumnIndex(columnName);
1146
return GetDouble(index, nullValue);
1149
wxString wxSQLite3Table::GetString(int columnIndex, const wxString& nullValue /* = wxEmptyString */)
1151
if (IsNull(columnIndex))
1157
return GetAsString(columnIndex);
1161
wxString wxSQLite3Table::GetString(const wxString& columnName, const wxString& nullValue /* = wxEmptyString */)
1163
if (IsNull(columnName))
1169
return GetAsString(columnName);
1173
wxDateTime wxSQLite3Table::GetDate(int columnIndex)
1176
if (date.ParseDate(GetString(columnIndex)) != NULL)
1182
return wxInvalidDateTime;
1186
wxDateTime wxSQLite3Table::GetDate(const wxString& columnName)
1188
int columnIndex = FindColumnIndex(columnName);
1189
return GetDate(columnIndex);
1192
wxDateTime wxSQLite3Table::GetTime(int columnIndex)
1195
if (date.ParseTime(GetString(columnIndex)) != NULL)
1201
return wxInvalidDateTime;
1205
wxDateTime wxSQLite3Table::GetTime(const wxString& columnName)
1207
int columnIndex = FindColumnIndex(columnName);
1208
return GetTime(columnIndex);
1211
wxDateTime wxSQLite3Table::GetDateTime(int columnIndex)
1214
if (date.ParseDateTime(GetString(columnIndex)) != NULL)
1220
return wxInvalidDateTime;
1224
wxDateTime wxSQLite3Table::GetDateTime(const wxString& columnName)
1226
int columnIndex = FindColumnIndex(columnName);
1227
return GetDateTime(columnIndex);
1230
bool wxSQLite3Table::GetBool(int columnIndex)
1232
return GetInt(columnIndex) != 0;
1235
bool wxSQLite3Table::GetBool(const wxString& columnName)
1237
int columnIndex = FindColumnIndex(columnName);
1238
return GetBool(columnIndex);
1241
bool wxSQLite3Table::IsNull(int columnIndex)
1245
if (columnIndex < 0 || columnIndex > m_cols-1)
1247
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
1250
int index = (m_currentRow*m_cols) + m_cols + columnIndex;
1251
const char* localValue = m_results[index];
1252
return (localValue == 0);
1255
bool wxSQLite3Table::IsNull(const wxString& columnName)
1257
int index = FindColumnIndex(columnName);
1258
return IsNull(index);
1261
wxString wxSQLite3Table::GetColumnName(int columnIndex)
1265
if (columnIndex < 0 || columnIndex > m_cols-1)
1267
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
1270
const char* localValue = m_results[columnIndex];
1271
return UTF8toWxString(localValue);
1274
void wxSQLite3Table::SetRow(int row)
1278
if (row < 0 || row > m_rows-1)
1280
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_ROW);
1286
bool wxSQLite3Table::IsOk()
1288
return (m_results != 0);
1291
void wxSQLite3Table::CheckResults()
1295
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NORESULT);
1299
// ----------------------------------------------------------------------------
1300
// wxSQLite3Statement: class holding a prepared statement
1301
// ----------------------------------------------------------------------------
1303
wxSQLite3Statement::wxSQLite3Statement()
1309
wxSQLite3Statement::wxSQLite3Statement(const wxSQLite3Statement& statement)
1311
m_db = statement.m_db;
1312
m_stmt = statement.m_stmt;
1313
// Only one object can own prepared statement
1314
const_cast<wxSQLite3Statement&>(statement).m_stmt = 0;
1317
wxSQLite3Statement::wxSQLite3Statement(void* db, void* stmt)
1323
wxSQLite3Statement::~wxSQLite3Statement()
1334
wxSQLite3Statement& wxSQLite3Statement::operator=(const wxSQLite3Statement& statement)
1336
m_db = statement.m_db;
1337
m_stmt = statement.m_stmt;
1338
// Only one object can own prepared statement
1339
const_cast<wxSQLite3Statement&>(statement).m_stmt = 0;
1343
int wxSQLite3Statement::ExecuteUpdate()
1348
const char* localError=0;
1350
int rc = sqlite3_step((sqlite3_stmt*) m_stmt);
1352
if (rc == SQLITE_DONE)
1354
int rowsChanged = sqlite3_changes((sqlite3*) m_db);
1356
rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
1358
if (rc != SQLITE_OK)
1360
localError = sqlite3_errmsg((sqlite3*) m_db);
1361
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
1368
rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
1369
localError = sqlite3_errmsg((sqlite3*) m_db);
1370
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
1374
wxSQLite3ResultSet wxSQLite3Statement::ExecuteQuery()
1379
int rc = sqlite3_step((sqlite3_stmt*) m_stmt);
1381
if (rc == SQLITE_DONE) // no more rows
1383
return wxSQLite3ResultSet(m_db, m_stmt, true/*eof*/, true/*first*/, false);
1385
else if (rc == SQLITE_ROW) // one or more rows
1387
return wxSQLite3ResultSet(m_db, m_stmt, false/*eof*/, true/*first*/, false);
1391
rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
1392
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1393
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
1397
int wxSQLite3Statement::GetParamCount()
1400
return sqlite3_bind_parameter_count((sqlite3_stmt*) m_stmt);
1403
int wxSQLite3Statement::GetParamIndex(const wxString& paramName)
1407
wxCharBuffer strParamName = wxConvUTF8.cWC2MB(paramName.wc_str(*wxConvCurrent));
1408
const char* localParamName = strParamName;
1410
return sqlite3_bind_parameter_index((sqlite3_stmt*) m_stmt, localParamName);
1413
wxString wxSQLite3Statement::GetParamName(int paramIndex)
1416
const char* localParamName = sqlite3_bind_parameter_name((sqlite3_stmt*) m_stmt, paramIndex);
1417
return UTF8toWxString(localParamName);
1420
void wxSQLite3Statement::Bind(int paramIndex, const wxString& stringValue)
1424
wxCharBuffer strStringValue = wxConvUTF8.cWC2MB(stringValue.wc_str(*wxConvCurrent));
1425
const char* localStringValue = strStringValue;
1427
int rc = sqlite3_bind_text((sqlite3_stmt*) m_stmt, paramIndex, localStringValue, -1, SQLITE_TRANSIENT);
1429
if (rc != SQLITE_OK)
1431
throw wxSQLite3Exception(rc, wxERRMSG_BIND_STR);
1435
void wxSQLite3Statement::Bind(int paramIndex, int intValue)
1438
int rc = sqlite3_bind_int((sqlite3_stmt*) m_stmt, paramIndex, intValue);
1440
if (rc != SQLITE_OK)
1442
throw wxSQLite3Exception(rc, wxERRMSG_BIND_INT);
1446
void wxSQLite3Statement::Bind(int paramIndex, wxLongLong int64Value)
1449
int rc = sqlite3_bind_int64((sqlite3_stmt*) m_stmt, paramIndex, int64Value.GetValue());
1451
if (rc != SQLITE_OK)
1453
throw wxSQLite3Exception(rc, wxERRMSG_BIND_INT64);
1457
void wxSQLite3Statement::Bind(int paramIndex, double doubleValue)
1460
int rc = sqlite3_bind_double((sqlite3_stmt*) m_stmt, paramIndex, doubleValue);
1462
if (rc != SQLITE_OK)
1464
throw wxSQLite3Exception(rc, wxERRMSG_BIND_DBL);
1468
void wxSQLite3Statement::Bind(int paramIndex, const char* charValue)
1471
int rc = sqlite3_bind_text((sqlite3_stmt*) m_stmt, paramIndex, charValue, -1, SQLITE_TRANSIENT);
1473
if (rc != SQLITE_OK)
1475
throw wxSQLite3Exception(rc, wxERRMSG_BIND_STR);
1479
void wxSQLite3Statement::Bind(int paramIndex, const unsigned char* blobValue, int blobLen)
1482
int rc = sqlite3_bind_blob((sqlite3_stmt*) m_stmt, paramIndex,
1483
(const void*)blobValue, blobLen, SQLITE_TRANSIENT);
1485
if (rc != SQLITE_OK)
1487
throw wxSQLite3Exception(rc, wxERRMSG_BIND_BLOB);
1491
void wxSQLite3Statement::Bind(int paramIndex, const wxMemoryBuffer& blobValue)
1494
int blobLen = (int) blobValue.GetDataLen();
1495
int rc = sqlite3_bind_blob((sqlite3_stmt*) m_stmt, paramIndex,
1496
(const void*)blobValue.GetData(), blobLen, SQLITE_TRANSIENT);
1498
if (rc != SQLITE_OK)
1500
throw wxSQLite3Exception(rc, wxERRMSG_BIND_BLOB);
1504
void wxSQLite3Statement::BindDate(int paramIndex, const wxDateTime& date)
1508
Bind(paramIndex,date.FormatISODate());
1512
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
1516
void wxSQLite3Statement::BindTime(int paramIndex, const wxDateTime& time)
1520
Bind(paramIndex,time.FormatISOTime());
1524
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
1528
void wxSQLite3Statement::BindDateTime(int paramIndex, const wxDateTime& datetime)
1530
if (datetime.IsValid())
1532
Bind(paramIndex,datetime.Format(_T("%Y-%m-%d %H:%M:%S")));
1536
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
1540
void wxSQLite3Statement::BindTimestamp(int paramIndex, const wxDateTime& timestamp)
1542
if (timestamp.IsValid())
1544
Bind(paramIndex,timestamp.Format(_T("%Y-%m-%d %H:%M:%S.%l")));
1548
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
1552
void wxSQLite3Statement::BindNumericDateTime(int paramIndex, const wxDateTime& datetime)
1554
if (datetime.IsValid())
1556
Bind(paramIndex, datetime.GetValue());
1560
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
1564
void wxSQLite3Statement::BindJulianDayNumber(int paramIndex, const wxDateTime& datetime)
1566
if (datetime.IsValid())
1568
Bind(paramIndex, datetime.GetJulianDayNumber());
1572
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
1576
void wxSQLite3Statement::BindBool(int paramIndex, bool value)
1578
Bind(paramIndex, value ? 1 : 0);
1581
void wxSQLite3Statement::BindNull(int paramIndex)
1584
int rc = sqlite3_bind_null((sqlite3_stmt*) m_stmt, paramIndex);
1586
if (rc != SQLITE_OK)
1588
throw wxSQLite3Exception(rc, wxERRMSG_BIND_NULL);
1592
void wxSQLite3Statement::BindZeroBlob(int paramIndex, int blobSize)
1594
#if SQLITE_VERSION_NUMBER >= 3004000
1596
int rc = sqlite3_bind_zeroblob((sqlite3_stmt*) m_stmt, paramIndex, blobSize);
1597
if (rc != SQLITE_OK)
1599
throw wxSQLite3Exception(rc, wxERRMSG_BIND_ZEROBLOB);
1602
wxUnusedVar(paramIndex);
1603
wxUnusedVar(blobSize);
1604
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
1608
void wxSQLite3Statement::ClearBindings()
1611
#if 0 // missing in SQLite DLL
1612
int rc = sqlite3_clear_bindings((sqlite3_stmt*) m_stmt);
1614
if (rc != SQLITE_OK)
1616
throw wxSQLite3Exception(rc, wxERRMSG_BIND_CLEAR);
1619
for (int paramIndex = 1; paramIndex <= GetParamCount(); paramIndex++)
1621
BindNull(paramIndex);
1626
wxString wxSQLite3Statement::GetSQL()
1628
wxString sqlString = wxEmptyString;
1629
#if SQLITE_VERSION_NUMBER >= 3005003
1631
const char* sqlLocal = sqlite3_sql((sqlite3_stmt*) m_stmt);
1632
if (sqlLocal != NULL) sqlString = UTF8toWxString(sqlLocal);
1637
void wxSQLite3Statement::Reset()
1641
int rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
1643
if (rc != SQLITE_OK)
1645
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1646
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
1651
void wxSQLite3Statement::Finalize()
1655
int rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
1658
if (rc != SQLITE_OK)
1660
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1661
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
1666
bool wxSQLite3Statement::IsOk()
1668
return (m_db != 0) && (m_stmt != 0);
1671
void wxSQLite3Statement::CheckDatabase()
1675
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NODB);
1679
void wxSQLite3Statement::CheckStmt()
1683
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSTMT);
1689
wxSQLite3Blob::wxSQLite3Blob()
1697
wxSQLite3Blob::wxSQLite3Blob(const wxSQLite3Blob& blob)
1700
m_blob = blob.m_blob;
1702
m_writable = blob.m_writable;
1705
wxSQLite3Blob& wxSQLite3Blob::operator=(const wxSQLite3Blob& blob)
1715
m_blob = blob.m_blob;
1717
m_writable = blob.m_writable;
1718
// only one blob can own the blob handle
1719
const_cast<wxSQLite3Blob&>(blob).m_ok = false;
1724
wxSQLite3Blob::wxSQLite3Blob(void* db, void* blobHandle, bool writable)
1727
m_blob = blobHandle;
1729
m_writable = writable;
1731
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
1733
void sqlite3_result_zeroblob(sqlite3_context*, int n);
1738
wxSQLite3Blob::~wxSQLite3Blob()
1749
wxMemoryBuffer& wxSQLite3Blob::Read(wxMemoryBuffer& blobValue, int length, int offset)
1751
#if SQLITE_VERSION_NUMBER >= 3004000
1753
char* localBuffer = new char[length];
1754
int rc = sqlite3_blob_read((sqlite3_blob*) m_blob, localBuffer, length, offset);
1756
if (rc != SQLITE_OK)
1758
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1759
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
1762
blobValue.AppendData((void*) localBuffer, (size_t) length);
1763
delete [] localBuffer;
1765
wxUnusedVar(blobValue);
1766
wxUnusedVar(length);
1767
wxUnusedVar(offset);
1768
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
1773
void wxSQLite3Blob::Write(const wxMemoryBuffer& blobValue, int offset)
1775
#if SQLITE_VERSION_NUMBER >= 3004000
1779
int blobLen = (int) blobValue.GetDataLen();
1780
int rc = sqlite3_blob_write((sqlite3_blob*) m_blob,
1781
(const void*) blobValue.GetData(), blobLen, offset);
1783
if (rc != SQLITE_OK)
1785
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1786
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
1791
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_BLOB);
1794
wxUnusedVar(blobValue);
1795
wxUnusedVar(offset);
1796
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
1800
bool wxSQLite3Blob::IsOk()
1805
bool wxSQLite3Blob::IsReadOnly()
1810
int wxSQLite3Blob::GetSize()
1812
#if SQLITE_VERSION_NUMBER >= 3004000
1814
return sqlite3_blob_bytes((sqlite3_blob*) m_blob);
1816
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
1821
void wxSQLite3Blob::Finalize()
1823
#if SQLITE_VERSION_NUMBER >= 3004000
1826
int rc = sqlite3_blob_close((sqlite3_blob*) m_blob);
1829
if (rc != SQLITE_OK)
1831
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1832
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
1836
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
1840
void wxSQLite3Blob::CheckBlob()
1844
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_BLOB);
1848
// ----------------------------------------------------------------------------
1849
// wxSQLite3Database: class holding a SQLite3 database object
1850
// ----------------------------------------------------------------------------
1852
bool wxSQLite3Database::ms_sharedCacheEnabled = false;
1855
wxSQLite3Database::SetSharedCache(bool enable)
1857
int flag = (enable) ? 1 : 0;
1858
int rc = sqlite3_enable_shared_cache(flag);
1859
if (rc != SQLITE_OK)
1861
throw wxSQLite3Exception(rc, wxERRMSG_SHARED_CACHE);
1863
ms_sharedCacheEnabled = enable;
1866
#if WXSQLITE3_HAVE_CODEC
1867
bool wxSQLite3Database::ms_hasEncryptionSupport = true;
1869
bool wxSQLite3Database::ms_hasEncryptionSupport = false;
1872
#if WXSQLITE3_HAVE_METADATA
1873
bool wxSQLite3Database::ms_hasMetaDataSupport = true;
1875
bool wxSQLite3Database::ms_hasMetaDataSupport = false;
1878
#if WXSQLITE3_HAVE_LOAD_EXTENSION
1879
bool wxSQLite3Database::ms_hasLoadExtSupport = true;
1881
bool wxSQLite3Database::ms_hasLoadExtSupport = false;
1884
#if SQLITE_VERSION_NUMBER >= 3004000
1885
bool wxSQLite3Database::ms_hasIncrementalBlobSupport = true;
1887
bool wxSQLite3Database::ms_hasIncrementalBlobSupport = false;
1890
#if SQLITE_VERSION_NUMBER >= 3006008
1891
bool wxSQLite3Database::ms_hasSavepointSupport = true;
1893
bool wxSQLite3Database::ms_hasSavepointSupport = false;
1897
wxSQLite3Database::HasEncryptionSupport()
1899
return ms_hasEncryptionSupport;
1903
wxSQLite3Database::HasMetaDataSupport()
1905
return ms_hasMetaDataSupport;
1909
wxSQLite3Database::HasLoadExtSupport()
1911
return ms_hasLoadExtSupport;
1915
wxSQLite3Database::HasIncrementalBlobSupport()
1917
return ms_hasIncrementalBlobSupport;
1921
wxSQLite3Database::HasSavepointSupport()
1923
return ms_hasSavepointSupport;
1926
wxSQLite3Database::wxSQLite3Database()
1929
m_busyTimeoutMs = 60000; // 60 seconds
1930
m_isEncrypted = false;
1933
wxSQLite3Database::wxSQLite3Database(const wxSQLite3Database& db)
1936
m_busyTimeoutMs = 60000; // 60 seconds
1937
m_isEncrypted = false;
1940
wxSQLite3Database::~wxSQLite3Database()
1945
wxSQLite3Database& wxSQLite3Database::operator=(const wxSQLite3Database& db)
1948
m_busyTimeoutMs = 60000; // 60 seconds
1949
m_isEncrypted = db.m_isEncrypted;
1953
void wxSQLite3Database::Open(const wxString& fileName, const wxString& key)
1955
wxCharBuffer strLocalKey = wxConvUTF8.cWC2MB(key.wc_str(*wxConvCurrent));
1956
const char* localKey = strLocalKey;
1957
wxMemoryBuffer binaryKey;
1958
if (key.Length() > 0)
1960
binaryKey.AppendData((void*) localKey, strlen(localKey));
1962
Open(fileName, binaryKey);
1965
void wxSQLite3Database::Open(const wxString& fileName, const wxMemoryBuffer& key)
1967
wxCharBuffer strFileName = wxConvUTF8.cWC2MB(fileName.wc_str(*wxConvCurrent));
1968
const char* localFileName = strFileName;
1970
int rc = sqlite3_open((const char*) localFileName, (sqlite3**) &m_db);
1972
if (rc != SQLITE_OK)
1975
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1976
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
1979
rc = sqlite3_extended_result_codes((sqlite3*) m_db, 1);
1980
if (rc != SQLITE_OK)
1983
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1984
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
1987
#if WXSQLITE3_HAVE_CODEC
1988
if (key.GetDataLen() > 0)
1990
rc = sqlite3_key((sqlite3*) m_db, key.GetData(), (int) key.GetDataLen());
1991
if (rc != SQLITE_OK)
1994
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1995
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
1997
m_isEncrypted = true;
2003
SetBusyTimeout(m_busyTimeoutMs);
2006
bool wxSQLite3Database::IsOpen() const
2008
return (m_db != NULL);
2011
void wxSQLite3Database::Close()
2015
#if SQLITE_VERSION_NUMBER >= 3006000
2016
// Unfortunately the following code leads to a crash if the RTree module is used
2017
// therefore it is disabled for now
2019
// Finalize all unfinalized prepared statements
2020
sqlite3_stmt *pStmt;
2021
while( (pStmt = sqlite3_next_stmt((sqlite3*) m_db, 0))!=0 )
2023
sqlite3_finalize(pStmt);
2027
sqlite3_close((sqlite3*) m_db);
2029
m_isEncrypted = false;
2033
void wxSQLite3Database::Begin(wxSQLite3TransactionType transactionType)
2036
switch (transactionType)
2038
case WXSQLITE_TRANSACTION_DEFERRED:
2039
sql << _T("begin deferred transaction");
2041
case WXSQLITE_TRANSACTION_IMMEDIATE:
2042
sql << _T("begin immediate transaction");
2044
case WXSQLITE_TRANSACTION_EXCLUSIVE:
2045
sql << _T("begin exclusive transaction");
2048
sql << _T("begin transaction");
2054
void wxSQLite3Database::Commit()
2056
ExecuteUpdate("commit transaction");
2059
void wxSQLite3Database::Rollback(const wxString& savepointName)
2061
#if SQLITE_VERSION_NUMBER >= 3006008
2062
if (savepointName.IsEmpty())
2065
ExecuteUpdate("rollback transaction");
2066
#if SQLITE_VERSION_NUMBER >= 3006008
2070
ExecuteUpdate(wxString(_T("rollback transaction to savepoint "))+savepointName);
2075
bool wxSQLite3Database::GetAutoCommit()
2078
return sqlite3_get_autocommit((sqlite3*) m_db) != 0;
2081
void wxSQLite3Database::Savepoint(const wxString& savepointName)
2083
#if SQLITE_VERSION_NUMBER >= 3006008
2084
ExecuteUpdate(wxString(_T("savepoint "))+savepointName);
2086
wxUnusedVar(savepointName);
2087
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSAVEPOINT);
2091
void wxSQLite3Database::ReleaseSavepoint(const wxString& savepointName)
2093
#if SQLITE_VERSION_NUMBER >= 3006008
2094
ExecuteUpdate(wxString(_T("release savepoint "))+savepointName);
2096
wxUnusedVar(savepointName);
2097
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSAVEPOINT);
2101
wxSQLite3Statement wxSQLite3Database::PrepareStatement(const wxString& sql)
2103
wxCharBuffer strSql = wxConvUTF8.cWC2MB(sql.wc_str(*wxConvCurrent));
2104
const char* localSql = strSql;
2105
return PrepareStatement(localSql);
2108
wxSQLite3Statement wxSQLite3Database::PrepareStatement(const wxSQLite3StatementBuffer& sql)
2110
return PrepareStatement((const char*) sql);
2113
wxSQLite3Statement wxSQLite3Database::PrepareStatement(const char* sql)
2116
sqlite3_stmt* stmt = (sqlite3_stmt*) Prepare(sql);
2117
return wxSQLite3Statement(m_db, stmt);
2120
bool wxSQLite3Database::TableExists(const wxString& tableName, const wxString& databaseName)
2123
if (databaseName.IsEmpty())
2125
sql = _T("select count(*) from sqlite_master where type='table' and name like ?");
2129
sql = wxString(_T("select count(*) from ")) + databaseName + wxString(_T(".sqlite_master where type='table' and name like ?"));
2131
wxSQLite3Statement stmt = PrepareStatement(sql);
2132
stmt.Bind(1, tableName);
2133
wxSQLite3ResultSet resultSet = stmt.ExecuteQuery();
2135
resultSet.GetAsString(0).ToLong(&value);
2139
bool wxSQLite3Database::TableExists(const wxString& tableName, wxArrayString& databaseNames)
2141
wxArrayString databaseList;
2142
GetDatabaseList(databaseList);
2145
size_t count = databaseList.GetCount();
2149
for (j = 0; j < count; j++)
2151
if (TableExists(tableName, databaseList.Item(j)))
2154
databaseNames.Add(databaseList.Item(j));
2161
void wxSQLite3Database::GetDatabaseList(wxArrayString& databaseNames)
2163
databaseNames.Empty();
2164
wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA database_list;");
2165
while (resultSet.NextRow())
2167
databaseNames.Add(resultSet.GetString(1));
2171
void wxSQLite3Database::GetDatabaseList(wxArrayString& databaseNames, wxArrayString& databaseFiles)
2173
databaseNames.Empty();
2174
databaseFiles.Empty();
2175
wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA database_list;");
2176
while (resultSet.NextRow())
2178
databaseNames.Add(resultSet.GetString(1));
2179
databaseFiles.Add(resultSet.GetString(2));
2183
bool wxSQLite3Database::CheckSyntax(const wxString& sql)
2185
wxCharBuffer strSql = wxConvUTF8.cWC2MB(sql.wc_str(*wxConvCurrent));
2186
const char* localSql = strSql;
2187
return CheckSyntax(localSql);
2190
bool wxSQLite3Database::CheckSyntax(const wxSQLite3StatementBuffer& sql)
2192
return CheckSyntax((const char*) sql);
2195
bool wxSQLite3Database::CheckSyntax(const char* sql)
2197
return sqlite3_complete(sql) != 0;
2200
int wxSQLite3Database::ExecuteUpdate(const wxString& sql)
2202
wxCharBuffer strSql = wxConvUTF8.cWC2MB(sql.wc_str(*wxConvCurrent));
2203
const char* localSql = strSql;
2204
return ExecuteUpdate(localSql);
2207
int wxSQLite3Database::ExecuteUpdate(const wxSQLite3StatementBuffer& sql)
2209
return ExecuteUpdate((const char*) sql);
2212
int wxSQLite3Database::ExecuteUpdate(const char* sql)
2218
int rc = sqlite3_exec((sqlite3*) m_db, sql, 0, 0, &localError);
2220
if (rc == SQLITE_OK)
2222
return sqlite3_changes((sqlite3*) m_db);
2226
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
2230
wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const wxString& sql)
2232
wxCharBuffer strSql = wxConvUTF8.cWC2MB(sql.wc_str(*wxConvCurrent));
2233
const char* localSql = strSql;
2234
return ExecuteQuery(localSql);
2237
wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const wxSQLite3StatementBuffer& sql)
2239
return ExecuteQuery((const char*) sql);
2242
wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const char* sql)
2246
sqlite3_stmt* stmt = (sqlite3_stmt*) Prepare(sql);
2248
int rc = sqlite3_step(stmt);
2250
if (rc == SQLITE_DONE) // no rows
2252
return wxSQLite3ResultSet(m_db, stmt, true /* eof */);
2254
else if (rc == SQLITE_ROW) // one or more rows
2256
return wxSQLite3ResultSet(m_db, stmt, false /* eof */);
2260
rc = sqlite3_finalize(stmt);
2261
const char* localError= sqlite3_errmsg((sqlite3*) m_db);
2262
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
2266
int wxSQLite3Database::ExecuteScalar(const wxString& sql)
2268
wxCharBuffer strSql = wxConvUTF8.cWC2MB(sql.wc_str(*wxConvCurrent));
2269
const char* localSql = strSql;
2270
return ExecuteScalar(localSql);
2273
int wxSQLite3Database::ExecuteScalar(const wxSQLite3StatementBuffer& sql)
2275
return ExecuteScalar((const char*) sql);
2278
int wxSQLite3Database::ExecuteScalar(const char* sql)
2280
wxSQLite3ResultSet resultSet = ExecuteQuery(sql);
2282
if (resultSet.Eof() || resultSet.GetColumnCount() < 1)
2284
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_QUERY);
2288
resultSet.GetAsString(0).ToLong(&value);
2292
wxSQLite3Table wxSQLite3Database::GetTable(const wxString& sql)
2294
wxCharBuffer strSql = wxConvUTF8.cWC2MB(sql.wc_str(*wxConvCurrent));
2295
const char* localSql = strSql;
2296
return GetTable(localSql);
2299
wxSQLite3Table wxSQLite3Database::GetTable(const wxSQLite3StatementBuffer& sql)
2301
return GetTable((const char*) sql);
2304
wxSQLite3Table wxSQLite3Database::GetTable(const char* sql)
2314
rc = sqlite3_get_table((sqlite3*) m_db, sql, &results, &rows, &cols, &localError);
2316
if (rc == SQLITE_OK)
2318
return wxSQLite3Table(results, rows, cols);
2322
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
2326
wxLongLong wxSQLite3Database::GetLastRowId()
2329
return wxLongLong(sqlite3_last_insert_rowid((sqlite3*) m_db));
2332
wxSQLite3Blob wxSQLite3Database::GetReadOnlyBlob(wxLongLong rowId,
2333
const wxString& columnName,
2334
const wxString& tableName,
2335
const wxString& dbName)
2337
return GetBlob(rowId, columnName, tableName, dbName, false);
2340
wxSQLite3Blob wxSQLite3Database::GetWritableBlob(wxLongLong rowId,
2341
const wxString& columnName,
2342
const wxString& tableName,
2343
const wxString& dbName)
2345
return GetBlob(rowId, columnName, tableName, dbName, true);
2348
wxSQLite3Blob wxSQLite3Database::GetBlob(wxLongLong rowId,
2349
const wxString& columnName,
2350
const wxString& tableName,
2351
const wxString& dbName,
2354
#if SQLITE_VERSION_NUMBER >= 3004000
2355
wxCharBuffer strColumnName = wxConvUTF8.cWC2MB(columnName.wc_str(*wxConvCurrent));
2356
const char* localColumnName = strColumnName;
2357
wxCharBuffer strTableName = wxConvUTF8.cWC2MB(tableName.wc_str(*wxConvCurrent));
2358
const char* localTableName = strTableName;
2359
wxCharBuffer strDbName = wxConvUTF8.cWC2MB(dbName.wc_str(*wxConvCurrent));
2360
const char* localDbName = (!dbName.IsEmpty()) ? (const char*) strDbName : (const char*) NULL;
2361
int flags = (writable) ? 1 : 0;
2362
sqlite3_blob* blobHandle;
2364
int rc = sqlite3_blob_open((sqlite3*) m_db, localDbName, localTableName, localColumnName, rowId.GetValue(), flags, &blobHandle);
2365
if (rc != SQLITE_OK)
2367
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2368
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
2370
return wxSQLite3Blob(m_db, (void*) blobHandle, writable);
2373
wxUnusedVar(columnName);
2374
wxUnusedVar(tableName);
2375
wxUnusedVar(dbName);
2376
wxUnusedVar(writable);
2377
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
2382
void wxSQLite3Database::Interrupt()
2385
sqlite3_interrupt((sqlite3*) m_db);
2388
void wxSQLite3Database::SetBusyTimeout(int nMillisecs)
2391
m_busyTimeoutMs = nMillisecs;
2392
sqlite3_busy_timeout((sqlite3*) m_db, m_busyTimeoutMs);
2395
wxString wxSQLite3Database::GetVersion()
2397
return UTF8toWxString(sqlite3_libversion());
2400
bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3ScalarFunction& function)
2403
wxCharBuffer strFuncName = wxConvUTF8.cWC2MB(funcName.wc_str(*wxConvCurrent));
2404
const char* localFuncName = strFuncName;
2405
int rc = sqlite3_create_function((sqlite3*) m_db, localFuncName, argCount,
2406
SQLITE_UTF8, &function,
2407
(void (*)(sqlite3_context*,int,sqlite3_value**)) wxSQLite3FunctionContext::ExecScalarFunction, NULL, NULL);
2408
return rc == SQLITE_OK;
2411
bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3AggregateFunction& function)
2414
wxCharBuffer strFuncName = wxConvUTF8.cWC2MB(funcName.wc_str(*wxConvCurrent));
2415
const char* localFuncName = strFuncName;
2416
int rc = sqlite3_create_function((sqlite3*) m_db, localFuncName, argCount,
2417
SQLITE_UTF8, &function,
2419
(void (*)(sqlite3_context*,int,sqlite3_value**)) wxSQLite3FunctionContext::ExecAggregateStep,
2420
(void (*)(sqlite3_context*)) wxSQLite3FunctionContext::ExecAggregateFinalize);
2421
return rc == SQLITE_OK;
2424
bool wxSQLite3Database::SetAuthorizer(wxSQLite3Authorizer& authorizer)
2427
int rc = sqlite3_set_authorizer((sqlite3*) m_db, wxSQLite3FunctionContext::ExecAuthorizer, &authorizer);
2428
return rc == SQLITE_OK;
2431
void wxSQLite3Database::SetCommitHook(wxSQLite3Hook* commitHook)
2436
sqlite3_commit_hook((sqlite3*) m_db, (int(*)(void*)) wxSQLite3FunctionContext::ExecCommitHook, commitHook);
2440
sqlite3_commit_hook((sqlite3*) m_db, (int(*)(void*)) NULL, NULL);
2444
void wxSQLite3Database::SetRollbackHook(wxSQLite3Hook* rollbackHook)
2449
sqlite3_rollback_hook((sqlite3*) m_db, (void(*)(void*)) wxSQLite3FunctionContext::ExecRollbackHook, rollbackHook);
2453
sqlite3_rollback_hook((sqlite3*) m_db, (void(*)(void*)) NULL, NULL);
2457
void wxSQLite3Database::SetUpdateHook(wxSQLite3Hook* updateHook)
2462
sqlite3_update_hook((sqlite3*) m_db, (void(*)(void*,int,const char*,const char*, wxsqlite_int64)) wxSQLite3FunctionContext::ExecUpdateHook, updateHook);
2466
sqlite3_update_hook((sqlite3*) m_db, (void(*)(void*,int,const char*,const char*, wxsqlite_int64)) NULL, NULL);
2470
void wxSQLite3Database::SetCollation(const wxString& collationName, wxSQLite3Collation* collation)
2473
wxCharBuffer strCollationName = wxConvUTF8.cWC2MB(collationName.wc_str(*wxConvCurrent));
2474
const char* localCollationName = strCollationName;
2478
rc = sqlite3_create_collation((sqlite3*) m_db, localCollationName, SQLITE_UTF8, collation, (int(*)(void*,int,const void*,int,const void*)) wxSQLite3Database::ExecComparisonWithCollation);
2482
rc = sqlite3_create_collation((sqlite3*) m_db, localCollationName, SQLITE_UTF8, NULL, (int(*)(void*,int,const void*,int,const void*)) NULL);
2486
void wxSQLite3Database::SetCollationNeededCallback()
2489
int rc = sqlite3_collation_needed((sqlite3*) m_db, this, (void(*)(void*,sqlite3*,int,const char*)) wxSQLite3Database::ExecCollationNeeded);
2490
if (rc != SQLITE_OK)
2492
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2493
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
2497
void wxSQLite3Database::CheckDatabase()
2501
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NODB);
2505
void* wxSQLite3Database::Prepare(const char* sql)
2512
int rc = sqlite3_prepare_v2((sqlite3*) m_db, sql, -1, &stmt, &tail);
2514
if (rc != SQLITE_OK)
2516
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2517
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
2524
int wxSQLite3Database::ExecComparisonWithCollation(void* collation,
2525
int len1, const void* text1,
2526
int len2, const void* text2)
2529
wxString locText1((const char*) text1, wxConvUTF8, (size_t) len1);
2530
wxString locText2((const char*) text2, wxConvUTF8, (size_t) len2);
2532
size_t len = (len1 > len2) ? len1 : len2;
2533
char* buffer = new char[len+1];
2534
memcpy(buffer, text1, len1);
2535
buffer[len1] = '\0';
2536
wxString locText1(wxConvUTF8.cMB2WC((const char*) buffer), *wxConvCurrent);
2537
memcpy(buffer, text2, len2);
2538
buffer[len2] = '\0';
2539
wxString locText2(wxConvUTF8.cMB2WC((const char*) buffer), *wxConvCurrent);
2542
return ((wxSQLite3Collation*) collation)->Compare(locText1, locText2);
2545
void wxSQLite3Database::ExecCollationNeeded(void* db, void*, int, const char* collationName)
2548
wxString locCollation((const char*) collationName, wxConvUTF8);
2550
wxString locCollation(wxConvUTF8.cMB2WC((const char*) collationName), *wxConvCurrent);
2552
((wxSQLite3Database*) db)->SetNeededCollation(locCollation);
2555
void wxSQLite3Database::GetMetaData(const wxString& databaseName, const wxString& tableName, const wxString& columnName,
2556
wxString* dataType, wxString* collation, bool* notNull, bool* primaryKey, bool* autoIncrement)
2558
#if WXSQLITE3_HAVE_METADATA
2559
wxCharBuffer strDatabaseName = wxConvUTF8.cWC2MB(databaseName.wc_str(*wxConvCurrent));
2560
const char* localDatabaseName = strDatabaseName;
2561
if (databaseName == wxEmptyString) localDatabaseName = NULL;
2562
wxCharBuffer strTableName = wxConvUTF8.cWC2MB(tableName.wc_str(*wxConvCurrent));
2563
const char* localTableName = strTableName;
2564
wxCharBuffer strColumnName = wxConvUTF8.cWC2MB(columnName.wc_str(*wxConvCurrent));
2565
const char* localColumnName = strColumnName;
2566
const char* localDataType;
2567
const char* localCollation;
2569
int localPrimaryKey;
2570
int localAutoIncrement;
2571
int rc = sqlite3_table_column_metadata((sqlite3*) m_db, localDatabaseName, localTableName, localColumnName,
2572
&localDataType, &localCollation, &localNotNull, &localPrimaryKey, &localAutoIncrement);
2574
if (rc != SQLITE_OK)
2576
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2577
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
2580
if (dataType != NULL) *dataType = UTF8toWxString(localDataType);
2581
if (collation != NULL) *collation = UTF8toWxString(localCollation);
2583
if (notNull != NULL) *notNull = (localNotNull != 0);
2584
if (primaryKey != NULL) *primaryKey = (localPrimaryKey != 0);
2585
if (autoIncrement != NULL) *autoIncrement = (localAutoIncrement != 0);
2587
wxUnusedVar(databaseName);
2588
wxUnusedVar(tableName);
2589
wxUnusedVar(columnName);
2590
wxUnusedVar(dataType);
2591
wxUnusedVar(collation);
2592
wxUnusedVar(notNull);
2593
wxUnusedVar(primaryKey);
2594
wxUnusedVar(autoIncrement);
2595
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
2599
void wxSQLite3Database::LoadExtension(const wxString& fileName, const wxString& entryPoint)
2601
#if WXSQLITE3_HAVE_LOAD_EXTENSION
2602
wxCharBuffer strFileName = wxConvUTF8.cWC2MB(fileName.wc_str(*wxConvCurrent));
2603
const char* localFileName = strFileName;
2604
wxCharBuffer strEntryPoint = wxConvUTF8.cWC2MB(entryPoint.wc_str(*wxConvCurrent));
2605
const char* localEntryPoint = strEntryPoint;
2607
int rc = sqlite3_load_extension((sqlite3 *) m_db, localFileName, localEntryPoint, NULL);
2608
if (rc != SQLITE_OK)
2610
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2611
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
2614
wxUnusedVar(fileName);
2615
wxUnusedVar(entryPoint);
2616
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOLOADEXT);
2620
void wxSQLite3Database::EnableLoadExtension(bool enable)
2622
#if WXSQLITE3_HAVE_LOAD_EXTENSION
2623
int onoff = (enable) ? 1 : 0;
2624
int rc = sqlite3_enable_load_extension((sqlite3 *) m_db, onoff);
2625
if (rc != SQLITE_OK)
2627
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2628
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
2631
wxUnusedVar(enable);
2632
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOLOADEXT);
2636
void wxSQLite3Database::ReKey(const wxString& newKey)
2638
#if WXSQLITE3_HAVE_CODEC
2639
wxCharBuffer strLocalNewKey = wxConvUTF8.cWC2MB(newKey.wc_str(*wxConvCurrent));
2640
const char* localNewKey = strLocalNewKey;
2641
wxMemoryBuffer binaryNewKey;
2642
if (newKey.Length() > 0)
2644
binaryNewKey.AppendData((void*) localNewKey, strlen(localNewKey));
2646
ReKey(binaryNewKey);
2648
wxUnusedVar(newKey);
2649
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOCODEC);
2653
void wxSQLite3Database::ReKey(const wxMemoryBuffer& newKey)
2655
#if WXSQLITE3_HAVE_CODEC
2656
int rc = sqlite3_rekey((sqlite3*) m_db, newKey.GetData(), (int) newKey.GetDataLen());
2657
if (rc != SQLITE_OK)
2659
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2660
throw wxSQLite3Exception(rc, UTF8toWxString(localError));
2663
wxUnusedVar(newKey);
2664
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOCODEC);
2668
int wxSQLite3Database::GetLimit(wxSQLite3LimitType id)
2671
#if SQLITE_VERSION_NUMBER >= 3005008
2673
if (id >= WXSQLITE_LIMIT_LENGTH && id <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
2675
value = sqlite3_limit((sqlite3 *) m_db, id, -1);
2683
int wxSQLite3Database::SetLimit(wxSQLite3LimitType id, int newValue)
2686
#if SQLITE_VERSION_NUMBER >= 3005008
2688
if (id >= WXSQLITE_LIMIT_LENGTH && id <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
2690
value = sqlite3_limit((sqlite3 *) m_db, id, newValue);
2694
wxUnusedVar(newValue);
2699
static const wxChar* limitCodeString[] =
2700
{ _T("SQLITE_LIMIT_LENGTH"), _T("SQLITE_LIMIT_SQL_LENGTH"),
2701
_T("SQLITE_LIMIT_COLUMN"), _T("SQLITE_LIMIT_EXPR_DEPTH"),
2702
_T("SQLITE_LIMIT_COMPOUND_SELECT"), _T("SQLITE_LIMIT_VDBE_OP"),
2703
_T("SQLITE_LIMIT_FUNCTION_ARG"), _T("SQLITE_LIMIT_ATTACHED"),
2704
_T("SQLITE_LIMIT_LIKE_PATTERN_LENGTH"), _T("SQLITE_LIMIT_VARIABLE_NUMBER")
2709
wxString wxSQLite3Database::LimitTypeToString(wxSQLite3LimitType type)
2711
const wxChar* limitString = _T("Unknown");
2712
if (type >= WXSQLITE_LIMIT_LENGTH && type <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
2714
limitString = limitCodeString[type];
2716
return wxString(limitString);
2720
void wxSQLite3Database::InitializeSQLite()
2722
#if SQLITE_VERSION_NUMBER >= 3006000
2723
int rc = sqlite3_initialize();
2724
if (rc != SQLITE_OK)
2726
throw wxSQLite3Exception(rc, wxERRMSG_INITIALIZE);
2732
void wxSQLite3Database::ShutdownSQLite()
2734
#if SQLITE_VERSION_NUMBER >= 3006000
2735
int rc = sqlite3_shutdown();
2736
if (rc != SQLITE_OK)
2738
throw wxSQLite3Exception(rc, wxERRMSG_SHUTDOWN);
2744
bool wxSQLite3Database::Randomness(int n, wxMemoryBuffer& random)
2747
#if SQLITE_VERSION_NUMBER >= 3005008
2750
void* buffer = random.GetWriteBuf(n);
2751
sqlite3_randomness(n, buffer);
2752
random.UngetWriteBuf(n);
2757
wxUnusedVar(random);
2762
// ----------------------------------------------------------------------------
2763
// wxSQLite3FunctionContext: class providing the function context
2764
// for user defined functions
2765
// ----------------------------------------------------------------------------
2767
int wxSQLite3FunctionContext::GetArgCount()
2772
int wxSQLite3FunctionContext::GetArgType(int argIndex)
2774
if (argIndex >= 0 && argIndex < m_argc)
2776
return sqlite3_value_type((sqlite3_value*) m_argv[argIndex]);
2784
bool wxSQLite3FunctionContext::IsNull(int argIndex)
2786
if (argIndex >= 0 && argIndex < m_argc)
2788
return sqlite3_value_type((sqlite3_value*) m_argv[argIndex]) == SQLITE_NULL;
2796
int wxSQLite3FunctionContext::GetInt(int argIndex, int nullValue)
2798
if (argIndex >= 0 && argIndex < m_argc)
2800
if (!IsNull(argIndex))
2802
return sqlite3_value_int((sqlite3_value*) m_argv[argIndex]);
2815
wxLongLong wxSQLite3FunctionContext::GetInt64(int argIndex, wxLongLong nullValue)
2817
if (argIndex >= 0 && argIndex < m_argc)
2819
if (!IsNull(argIndex))
2821
return wxLongLong(sqlite3_value_int64((sqlite3_value*) m_argv[argIndex]));
2834
double wxSQLite3FunctionContext::GetDouble(int argIndex, double nullValue)
2836
if (argIndex >= 0 && argIndex < m_argc)
2838
if (!IsNull(argIndex))
2840
return sqlite3_value_double((sqlite3_value*) m_argv[argIndex]);
2853
wxString wxSQLite3FunctionContext::GetString(int argIndex, const wxString& nullValue)
2855
if (argIndex >= 0 && argIndex < m_argc)
2857
if (!IsNull(argIndex))
2859
const char* localValue = (const char*) sqlite3_value_text((sqlite3_value*) m_argv[argIndex]);
2860
return UTF8toWxString(localValue);
2873
wxMemoryBuffer& wxSQLite3FunctionContext::GetBlob(int argIndex, wxMemoryBuffer& buffer)
2875
if (argIndex >= 0 && argIndex < m_argc)
2877
if (!IsNull(argIndex))
2879
int len = sqlite3_value_bytes((sqlite3_value*) m_argv[argIndex]);
2880
const void* blob = sqlite3_value_blob((sqlite3_value*) m_argv[argIndex]);
2881
buffer.AppendData((void*) blob, (size_t) len);
2887
void wxSQLite3FunctionContext::SetResult(int value)
2889
sqlite3_result_int((sqlite3_context*) m_ctx, value);
2892
void wxSQLite3FunctionContext::SetResult(wxLongLong value)
2894
sqlite3_result_int64((sqlite3_context*) m_ctx, value.GetValue());
2897
void wxSQLite3FunctionContext::SetResult(double value)
2899
sqlite3_result_double((sqlite3_context*) m_ctx, value);
2902
void wxSQLite3FunctionContext::SetResult(const wxString& value)
2904
wxCharBuffer strValue = wxConvUTF8.cWC2MB(value.wc_str(*wxConvCurrent));
2905
const char* localValue = strValue;
2906
sqlite3_result_text((sqlite3_context*) m_ctx, localValue, -1, SQLITE_TRANSIENT);
2909
void wxSQLite3FunctionContext::SetResult(unsigned char* value, int len)
2911
sqlite3_result_blob((sqlite3_context*) m_ctx, value, len, SQLITE_TRANSIENT);
2914
void wxSQLite3FunctionContext::SetResult(const wxMemoryBuffer& buffer)
2916
sqlite3_result_blob((sqlite3_context*) m_ctx, buffer.GetData(), (int) buffer.GetDataLen(), SQLITE_TRANSIENT);
2919
void wxSQLite3FunctionContext::SetResultNull()
2921
sqlite3_result_null((sqlite3_context*) m_ctx);
2924
void wxSQLite3FunctionContext::SetResultZeroBlob(int blobSize)
2926
#if SQLITE_VERSION_NUMBER >= 3004000
2927
sqlite3_result_zeroblob((sqlite3_context*) m_ctx, blobSize);
2931
void wxSQLite3FunctionContext::SetResultArg(int argIndex)
2933
if (argIndex >= 0 && argIndex < m_argc) {
2934
sqlite3_result_value((sqlite3_context*) m_ctx, (sqlite3_value*) m_argv[argIndex]);
2936
sqlite3_result_null((sqlite3_context*) m_ctx);
2940
void wxSQLite3FunctionContext::SetResultError(const wxString& errmsg)
2942
wxCharBuffer strErrmsg = wxConvUTF8.cWC2MB(errmsg.wc_str(*wxConvCurrent));
2943
const char* localErrmsg = strErrmsg;
2944
sqlite3_result_error((sqlite3_context*) m_ctx, localErrmsg, -1);
2947
int wxSQLite3FunctionContext::GetAggregateCount()
2959
void* wxSQLite3FunctionContext::GetAggregateStruct(int len)
2963
return sqlite3_aggregate_context((sqlite3_context*) m_ctx, len);
2972
void wxSQLite3FunctionContext::ExecScalarFunction(void* ctx, int argc, void** argv)
2974
wxSQLite3FunctionContext context(ctx, false, argc, argv);
2975
wxSQLite3ScalarFunction* func = (wxSQLite3ScalarFunction*) sqlite3_user_data((sqlite3_context*) ctx);
2976
func->Execute(context);
2980
void wxSQLite3FunctionContext::ExecAggregateStep(void* ctx, int argc, void** argv)
2982
wxSQLite3FunctionContext context(ctx, true, argc, argv);
2983
wxSQLite3AggregateFunction* func = (wxSQLite3AggregateFunction*) sqlite3_user_data((sqlite3_context*) ctx);
2985
context.m_count = func->m_count;
2986
func->Aggregate(context);
2990
void wxSQLite3FunctionContext::ExecAggregateFinalize(void* ctx)
2992
wxSQLite3FunctionContext context(ctx, true, 0, NULL);
2993
wxSQLite3AggregateFunction* func = (wxSQLite3AggregateFunction*) sqlite3_user_data((sqlite3_context*) ctx);
2994
context.m_count = func->m_count;
2995
func->Finalize(context);
2999
int wxSQLite3FunctionContext::ExecAuthorizer(void* func, int type,
3000
const char* arg1, const char* arg2,
3001
const char* arg3, const char* arg4)
3004
wxString locArg1(arg1, wxConvUTF8);
3005
wxString locArg2(arg2, wxConvUTF8);
3006
wxString locArg3(arg3, wxConvUTF8);
3007
wxString locArg4(arg4, wxConvUTF8);
3009
wxString locArg1(wxConvUTF8.cMB2WC(arg1), *wxConvCurrent);
3010
wxString locArg2(wxConvUTF8.cMB2WC(arg2), *wxConvCurrent);
3011
wxString locArg3(wxConvUTF8.cMB2WC(arg3), *wxConvCurrent);
3012
wxString locArg4(wxConvUTF8.cMB2WC(arg4), *wxConvCurrent);
3014
wxSQLite3Authorizer::wxAuthorizationCode localType = (wxSQLite3Authorizer::wxAuthorizationCode) type;
3015
return (int) ((wxSQLite3Authorizer*) func)->Authorize(localType, locArg1, locArg2, locArg3, locArg3);
3019
int wxSQLite3FunctionContext::ExecCommitHook(void* hook)
3021
return (int) ((wxSQLite3Hook*) hook)->CommitCallback();
3025
void wxSQLite3FunctionContext::ExecRollbackHook(void* hook)
3027
((wxSQLite3Hook*) hook)->RollbackCallback();
3031
void wxSQLite3FunctionContext::ExecUpdateHook(void* hook, int type,
3032
const char* database, const char* table,
3033
wxsqlite_int64 rowid)
3036
wxString locDatabase(database, wxConvUTF8);
3037
wxString locTable(table, wxConvUTF8);
3039
wxString locDatabase(wxConvUTF8.cMB2WC(database), *wxConvCurrent);
3040
wxString locTable(wxConvUTF8.cMB2WC(table), *wxConvCurrent);
3042
wxSQLite3Hook::wxUpdateType locType = (wxSQLite3Hook::wxUpdateType) type;
3043
wxLongLong locRowid = rowid;
3044
((wxSQLite3Hook*) hook)->UpdateCallback(locType, locDatabase, locTable, locRowid);
3047
wxSQLite3FunctionContext::wxSQLite3FunctionContext(void* ctx, bool isAggregate, int argc, void** argv)
3048
: m_ctx(ctx), m_isAggregate(isAggregate), m_count(0), m_argc(argc), m_argv(argv)
3052
static const wxChar* authCodeString[] =
3053
{ _T("SQLITE_COPY"), _T("SQLITE_CREATE_INDEX"), _T("SQLITE_CREATE_TABLE"),
3054
_T("SQLITE_CREATE_TEMP_INDEX"), _T("SQLITE_CREATE_TEMP_TABLE"), _T("SQLITE_CREATE_TEMP_TRIGGER"),
3055
_T("SQLITE_CREATE_TEMP_VIEW"), _T("SQLITE_CREATE_TRIGGER"), _T("SQLITE_CREATE_VIEW"),
3056
_T("SQLITE_DELETE"), _T("SQLITE_DROP_INDEX"), _T("SQLITE_DROP_TABLE"),
3057
_T("SQLITE_DROP_TEMP_INDEX"), _T("SQLITE_DROP_TEMP_TABLE"), _T("SQLITE_DROP_TEMP_TRIGGER"),
3058
_T("SQLITE_DROP_TEMP_VIEW"), _T("SQLITE_DROP_TRIGGER"), _T("SQLITE_DROP_VIEW"),
3059
_T("SQLITE_INSERT"), _T("SQLITE_PRAGMA"), _T("SQLITE_READ"),
3060
_T("SQLITE_SELECT"), _T("SQLITE_TRANSACTION"), _T("SQLITE_UPDATE"),
3061
_T("SQLITE_ATTACH"), _T("SQLITE_DETACH"), _T("SQLITE_ALTER_TABLE"),
3062
_T("SQLITE_REINDEX"), _T("SQLITE_ANALYZE"), _T("SQLITE_CREATE_VTABLE"),
3063
_T("SQLITE_DROP_VTABLE"), _T("SQLITE_FUNCTION"), _T("SQLITE_SAVEPOINT")
3068
wxString wxSQLite3Authorizer::AuthorizationCodeToString(wxSQLite3Authorizer::wxAuthorizationCode type)
3070
const wxChar* authString = _T("Unknown");
3071
if (type >= SQLITE_COPY && type <= SQLITE_MAX_CODE)
3073
authString = authCodeString[type];
3075
return wxString(authString);
3078
// ----------------------------------------------------------------------------
3079
// wxSQLite3Transaction
3080
// ----------------------------------------------------------------------------
3082
wxSQLite3Transaction::wxSQLite3Transaction(wxSQLite3Database* db, wxSQLite3TransactionType transactionType)
3088
m_database->Begin(transactionType);
3092
m_database = NULL; // Flag that transaction is not active
3096
wxSQLite3Transaction::~wxSQLite3Transaction()
3098
if (m_database != NULL)
3100
m_database->Rollback();
3104
void wxSQLite3Transaction::Commit()
3108
m_database->Commit();
3112
m_database->Rollback();
3117
void wxSQLite3Transaction::Rollback()
3121
m_database->Rollback();
3125
m_database->Rollback();