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"
17
// For compilers that support precompilation, includes "wx/wx.h".
18
#include "wx/wxprec.h"
30
#include "wxsqlite3.h"
31
#include "wxsqlite3opt.h"
33
// Suppress some Visual C++ warnings regarding the default constructor
34
// for a C struct used only in SQLite modules
36
#pragma warning (disable:4510)
37
#pragma warning (disable:4610)
40
#if WXSQLITE3_HAVE_CODEC
41
#define SQLITE_HAS_CODEC 1
43
#define SQLITE_HAS_CODEC 0
46
#include "sqlite/sqlite3.h"
48
// Dynamic loading of the SQLite library
50
#if wxUSE_DYNAMIC_SQLITE3_LOAD
52
#include "wx/dynlib.h"
54
#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
55
typedef rtype (*p##fname) farg ; \
56
static p##fname s_##fname = NULL;
57
#include "wx/wxsqlite3dyn.h"
60
static wxDynamicLibrary s_dll;
62
static void InitSQLite3DLL()
70
if (! s_dll.Load(wxT("sqlite3")))
72
if (! s_dll.Load(wxT("libsqlite3")))
75
throw wxSQLite3Exception(-1, wxT("error loading dynamic library"));
78
#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
79
s_##fname = (p##fname) s_dll.GetSymbol(wxT(#fname));\
83
throw wxSQLite3Exception(-1, wxT("error getting symbol <") wxT(#fname) wxT(">"));\
85
#include "wx/wxsqlite3dyn.h"
90
#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
94
rcode s_##fname farguse;\
96
#include "wx/wxsqlite3dyn.h"
99
#endif // wxUSE_DYNAMIC_SQLITE3_LOAD
103
#if wxCHECK_VERSION(2,9,0)
104
const char* wxERRMSG_NODB = wxTRANSLATE("No Database opened");
105
const char* wxERRMSG_NOSTMT = wxTRANSLATE("Statement not accessible");
106
const char* wxERRMSG_NOMEM = wxTRANSLATE("Out of memory");
107
const char* wxERRMSG_DECODE = wxTRANSLATE("Cannot decode binary");
108
const char* wxERRMSG_INVALID_INDEX = wxTRANSLATE("Invalid field index");
109
const char* wxERRMSG_INVALID_NAME = wxTRANSLATE("Invalid field name");
110
const char* wxERRMSG_INVALID_ROW = wxTRANSLATE("Invalid row index");
111
const char* wxERRMSG_INVALID_QUERY = wxTRANSLATE("Invalid scalar query");
112
const char* wxERRMSG_INVALID_BLOB = wxTRANSLATE("Invalid BLOB handle");
114
const char* wxERRMSG_NORESULT = wxTRANSLATE("Null Results pointer");
115
const char* wxERRMSG_BIND_STR = wxTRANSLATE("Error binding string param");
116
const char* wxERRMSG_BIND_INT = wxTRANSLATE("Error binding int param");
117
const char* wxERRMSG_BIND_INT64 = wxTRANSLATE("Error binding int64 param");
118
const char* wxERRMSG_BIND_DBL = wxTRANSLATE("Error binding double param");
119
const char* wxERRMSG_BIND_BLOB = wxTRANSLATE("Error binding blob param");
120
const char* wxERRMSG_BIND_DATETIME = wxTRANSLATE("Error binding date/time param");
121
const char* wxERRMSG_BIND_NULL = wxTRANSLATE("Error binding NULL param");
122
const char* wxERRMSG_BIND_ZEROBLOB = wxTRANSLATE("Error binding zero blob param");
123
const char* wxERRMSG_BIND_CLEAR = wxTRANSLATE("Error clearing bindings");
124
const char* wxERRMSG_NOTOWNED = wxTRANSLATE("Transfer of statement ownership not possible");
126
const char* wxERRMSG_NOMETADATA = wxTRANSLATE("Meta data support not available");
127
const char* wxERRMSG_NOCODEC = wxTRANSLATE("Encryption support not available");
128
const char* wxERRMSG_NOLOADEXT = wxTRANSLATE("Loadable extension support not available");
129
const char* wxERRMSG_NOINCBLOB = wxTRANSLATE("Incremental BLOB support not available");
130
const char* wxERRMSG_NOBLOBREBIND = wxTRANSLATE("Rebind BLOB support not available");
131
const char* wxERRMSG_NOSAVEPOINT = wxTRANSLATE("Savepoint support not available");
132
const char* wxERRMSG_NOBACKUP = wxTRANSLATE("Backup/restore support not available");
133
const char* wxERRMSG_NOWAL = wxTRANSLATE("Write Ahead Log support not available");
134
const char* wxERRMSG_NOCOLLECTIONS = wxTRANSLATE("Named collection support not available");
136
const char* wxERRMSG_SHARED_CACHE = wxTRANSLATE("Setting SQLite shared cache mode failed");
138
const char* wxERRMSG_INITIALIZE = wxTRANSLATE("Initialization of SQLite failed");
139
const char* wxERRMSG_SHUTDOWN = wxTRANSLATE("Shutdown of SQLite failed");
141
const char* wxERRMSG_SOURCEDB_BUSY = wxTRANSLATE("Source database is busy");
142
const char* wxERRMSG_DBOPEN_FAILED = wxTRANSLATE("Database open failed");
143
const char* wxERRMSG_DBASSIGN_FAILED = wxTRANSLATE("Database assignment failed");
145
const wxChar* wxERRMSG_NODB = wxTRANSLATE("No Database opened");
146
const wxChar* wxERRMSG_NOSTMT = wxTRANSLATE("Statement not accessible");
147
const wxChar* wxERRMSG_NOMEM = wxTRANSLATE("Out of memory");
148
const wxChar* wxERRMSG_DECODE = wxTRANSLATE("Cannot decode binary");
149
const wxChar* wxERRMSG_INVALID_INDEX = wxTRANSLATE("Invalid field index");
150
const wxChar* wxERRMSG_INVALID_NAME = wxTRANSLATE("Invalid field name");
151
const wxChar* wxERRMSG_INVALID_ROW = wxTRANSLATE("Invalid row index");
152
const wxChar* wxERRMSG_INVALID_QUERY = wxTRANSLATE("Invalid scalar query");
153
const wxChar* wxERRMSG_INVALID_BLOB = wxTRANSLATE("Invalid BLOB handle");
155
const wxChar* wxERRMSG_NORESULT = wxTRANSLATE("Null Results pointer");
156
const wxChar* wxERRMSG_BIND_STR = wxTRANSLATE("Error binding string param");
157
const wxChar* wxERRMSG_BIND_INT = wxTRANSLATE("Error binding int param");
158
const wxChar* wxERRMSG_BIND_INT64 = wxTRANSLATE("Error binding int64 param");
159
const wxChar* wxERRMSG_BIND_DBL = wxTRANSLATE("Error binding double param");
160
const wxChar* wxERRMSG_BIND_BLOB = wxTRANSLATE("Error binding blob param");
161
const wxChar* wxERRMSG_BIND_DATETIME = wxTRANSLATE("Error binding date/time param");
162
const wxChar* wxERRMSG_BIND_NULL = wxTRANSLATE("Error binding NULL param");
163
const wxChar* wxERRMSG_BIND_ZEROBLOB = wxTRANSLATE("Error binding zero blob param");
164
const wxChar* wxERRMSG_BIND_CLEAR = wxTRANSLATE("Error clearing bindings");
165
const wxChar* wxERRMSG_NOTOWNED = wxTRANSLATE("Transfer of statement ownership not possible");
167
const wxChar* wxERRMSG_NOMETADATA = wxTRANSLATE("Meta data support not available");
168
const wxChar* wxERRMSG_NOCODEC = wxTRANSLATE("Encryption support not available");
169
const wxChar* wxERRMSG_NOLOADEXT = wxTRANSLATE("Loadable extension support not available");
170
const wxChar* wxERRMSG_NOINCBLOB = wxTRANSLATE("Incremental BLOB support not available");
171
const wxChar* wxERRMSG_NOBLOBREBIND = wxTRANSLATE("Rebind BLOB support not available");
172
const wxChar* wxERRMSG_NOSAVEPOINT = wxTRANSLATE("Savepoint support not available");
173
const wxChar* wxERRMSG_NOBACKUP = wxTRANSLATE("Backup/restore support not available");
174
const wxChar* wxERRMSG_NOWAL = wxTRANSLATE("Write Ahead Log support not available");
175
const wxChar* wxERRMSG_NOCOLLECTIONS = wxTRANSLATE("Named collection support not available");
177
const wxChar* wxERRMSG_SHARED_CACHE = wxTRANSLATE("Setting SQLite shared cache mode failed");
179
const wxChar* wxERRMSG_INITIALIZE = wxTRANSLATE("Initialization of SQLite failed");
180
const wxChar* wxERRMSG_SHUTDOWN = wxTRANSLATE("Shutdown of SQLite failed");
182
const wxChar* wxERRMSG_SOURCEDB_BUSY = wxTRANSLATE("Source database is busy");
183
const wxChar* wxERRMSG_DBOPEN_FAILED = wxTRANSLATE("Database open failed");
184
const wxChar* wxERRMSG_DBASSIGN_FAILED = wxTRANSLATE("Database assignment failed");
187
// ----------------------------------------------------------------------------
188
// inline conversion from wxString to wxLongLong
189
// ----------------------------------------------------------------------------
191
inline wxLongLong ConvertStringToLongLong(const wxString& str, wxLongLong defValue /*=0*/)
193
size_t n = str.Length();
195
wxLongLong value = 0;
196
bool negative = false;
206
if (str[j] < '0' || str[j] > '9')
211
value += (str[j] - '0');
215
return negative ? -value : value;
218
// ----------------------------------------------------------------------------
219
// wxSQLite3Exception: class
220
// ----------------------------------------------------------------------------
222
wxSQLite3Exception::wxSQLite3Exception(int errorCode, const wxString& errorMsg)
223
: m_errorCode(errorCode)
225
m_errorMessage = ErrorCodeAsString(errorCode) + wxT("[") +
226
wxString::Format(wxT("%d"), errorCode) + wxT("]: ") +
227
wxGetTranslation(errorMsg);
230
wxSQLite3Exception::wxSQLite3Exception(const wxSQLite3Exception& e)
231
: m_errorCode(e.m_errorCode), m_errorMessage(e.m_errorMessage)
235
const wxString wxSQLite3Exception::ErrorCodeAsString(int errorCode)
239
case SQLITE_OK : return wxT("SQLITE_OK");
240
case SQLITE_ERROR : return wxT("SQLITE_ERROR");
241
case SQLITE_INTERNAL : return wxT("SQLITE_INTERNAL");
242
case SQLITE_PERM : return wxT("SQLITE_PERM");
243
case SQLITE_ABORT : return wxT("SQLITE_ABORT");
244
case SQLITE_BUSY : return wxT("SQLITE_BUSY");
245
case SQLITE_LOCKED : return wxT("SQLITE_LOCKED");
246
case SQLITE_NOMEM : return wxT("SQLITE_NOMEM");
247
case SQLITE_READONLY : return wxT("SQLITE_READONLY");
248
case SQLITE_INTERRUPT : return wxT("SQLITE_INTERRUPT");
249
case SQLITE_IOERR : return wxT("SQLITE_IOERR");
250
case SQLITE_CORRUPT : return wxT("SQLITE_CORRUPT");
251
case SQLITE_NOTFOUND : return wxT("SQLITE_NOTFOUND");
252
case SQLITE_FULL : return wxT("SQLITE_FULL");
253
case SQLITE_CANTOPEN : return wxT("SQLITE_CANTOPEN");
254
case SQLITE_PROTOCOL : return wxT("SQLITE_PROTOCOL");
255
case SQLITE_EMPTY : return wxT("SQLITE_EMPTY");
256
case SQLITE_SCHEMA : return wxT("SQLITE_SCHEMA");
257
case SQLITE_TOOBIG : return wxT("SQLITE_TOOBIG");
258
case SQLITE_CONSTRAINT : return wxT("SQLITE_CONSTRAINT");
259
case SQLITE_MISMATCH : return wxT("SQLITE_MISMATCH");
260
case SQLITE_MISUSE : return wxT("SQLITE_MISUSE");
261
case SQLITE_NOLFS : return wxT("SQLITE_NOLFS");
262
case SQLITE_AUTH : return wxT("SQLITE_AUTH");
263
case SQLITE_FORMAT : return wxT("SQLITE_FORMAT");
264
case SQLITE_RANGE : return wxT("SQLITE_RANGE");
265
case SQLITE_NOTADB : return wxT("SQLITE_NOTADB");
266
case SQLITE_ROW : return wxT("SQLITE_ROW");
267
case SQLITE_DONE : return wxT("SQLITE_DONE");
268
// Extended error codes
269
case SQLITE_IOERR_READ : return wxT("SQLITE_IOERR_READ");
270
case SQLITE_IOERR_SHORT_READ : return wxT("SQLITE_IOERR_SHORT_READ");
271
case SQLITE_IOERR_WRITE : return wxT("SQLITE_IOERR_WRITE");
272
case SQLITE_IOERR_FSYNC : return wxT("SQLITE_IOERR_FSYNC");
273
case SQLITE_IOERR_DIR_FSYNC : return wxT("SQLITE_IOERR_DIR_FSYNC");
274
case SQLITE_IOERR_TRUNCATE : return wxT("SQLITE_IOERR_TRUNCATE");
275
case SQLITE_IOERR_FSTAT : return wxT("SQLITE_IOERR_FSTAT");
276
case SQLITE_IOERR_UNLOCK : return wxT("SQLITE_IOERR_UNLOCK");
277
case SQLITE_IOERR_RDLOCK : return wxT("SQLITE_IOERR_RDLOCK");
278
case SQLITE_IOERR_DELETE : return wxT("SQLITE_IOERR_DELETE");
279
#if SQLITE_VERSION_NUMBER >= 3004000
280
case SQLITE_IOERR_BLOCKED : return wxT("SQLITE_IOERR_BLOCKED");
282
#if SQLITE_VERSION_NUMBER >= 3005001
283
case SQLITE_IOERR_NOMEM : return wxT("SQLITE_IOERR_NOMEM");
285
#if SQLITE_VERSION_NUMBER >= 3006000
286
case SQLITE_IOERR_ACCESS : return wxT("SQLITE_IOERR_ACCESS");
287
case SQLITE_IOERR_CHECKRESERVEDLOCK : return wxT("SQLITE_IOERR_CHECKRESERVEDLOCK");
289
#if SQLITE_VERSION_NUMBER >= 3006002
290
case SQLITE_IOERR_LOCK : return wxT("SQLITE_IOERR_LOCK");
292
#if SQLITE_VERSION_NUMBER >= 3006007
293
case SQLITE_IOERR_CLOSE : return wxT("SQLITE_IOERR_CLOSE");
294
case SQLITE_IOERR_DIR_CLOSE : return wxT("SQLITE_IOERR_DIR_CLOSE");
296
#if SQLITE_VERSION_NUMBER >= 3007000
297
case SQLITE_IOERR_SHMOPEN : return wxT("SQLITE_IOERR_SHMOPEN");
298
case SQLITE_IOERR_SHMSIZE : return wxT("SQLITE_IOERR_SHMSIZE");
299
case SQLITE_IOERR_SHMLOCK : return wxT("SQLITE_IOERR_SHMLOCK");
300
case SQLITE_LOCKED_SHAREDCACHE : return wxT("SQLITE_LOCKED_SHAREDCACHE");
301
case SQLITE_BUSY_RECOVERY : return wxT("SQLITE_BUSY_RECOVERY");
302
case SQLITE_CANTOPEN_NOTEMPDIR : return wxT("SQLITE_CANTOPEN_NOTEMPDIR");
305
case WXSQLITE_ERROR : return wxT("WXSQLITE_ERROR");
306
default : return wxT("UNKNOWN_ERROR");
310
wxSQLite3Exception::~wxSQLite3Exception()
314
// ----------------------------------------------------------------------------
315
// wxSQLite3StatementBuffer: class providing a statement buffer
316
// for use with the SQLite3 vmprintf function
317
// ----------------------------------------------------------------------------
319
wxSQLite3StatementBuffer::wxSQLite3StatementBuffer()
324
wxSQLite3StatementBuffer::~wxSQLite3StatementBuffer()
329
void wxSQLite3StatementBuffer::Clear()
333
sqlite3_free(m_buffer);
339
const char* wxSQLite3StatementBuffer::Format(const char* format, ...)
343
va_start(va, format);
344
m_buffer = sqlite3_vmprintf(format, va);
349
const char* wxSQLite3StatementBuffer::FormatV(const char* format, va_list va)
352
m_buffer = sqlite3_vmprintf(format, va);
356
// ----------------------------------------------------------------------------
357
// wxSQLite3ResultSet: class providing access to the result set of a query
358
// ----------------------------------------------------------------------------
360
wxSQLite3ResultSet::wxSQLite3ResultSet()
370
wxSQLite3ResultSet::wxSQLite3ResultSet(const wxSQLite3ResultSet& resultSet)
372
m_db = resultSet.m_db;
373
m_stmt = resultSet.m_stmt;
374
// Only one object can own the statement
375
const_cast<wxSQLite3ResultSet&>(resultSet).m_stmt = 0;
376
m_eof = resultSet.m_eof;
377
m_first = resultSet.m_first;
378
m_cols = resultSet.m_cols;
379
m_ownStmt = resultSet.m_ownStmt;
382
wxSQLite3ResultSet::wxSQLite3ResultSet(void* db,
386
bool ownStmt /*=true*/)
392
m_cols = sqlite3_column_count((sqlite3_stmt*) m_stmt);
396
wxSQLite3ResultSet::~wxSQLite3ResultSet()
407
wxSQLite3ResultSet& wxSQLite3ResultSet::operator=(const wxSQLite3ResultSet& resultSet)
409
if (this != &resultSet)
418
m_db = resultSet.m_db;
419
m_stmt = resultSet.m_stmt;
420
// Only one object can own the statement
421
const_cast<wxSQLite3ResultSet&>(resultSet).m_stmt = 0;
422
m_eof = resultSet.m_eof;
423
m_first = resultSet.m_first;
424
m_cols = resultSet.m_cols;
425
m_ownStmt = resultSet.m_ownStmt;
430
int wxSQLite3ResultSet::GetColumnCount()
436
wxString wxSQLite3ResultSet::GetAsString(int columnIndex)
440
if (columnIndex < 0 || columnIndex > m_cols-1)
442
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
445
const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
446
return wxString::FromUTF8(localValue);
449
wxString wxSQLite3ResultSet::GetAsString(const wxString& columnName)
451
int columnIndex = FindColumnIndex(columnName);
452
const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
453
return wxString::FromUTF8(localValue);
456
int wxSQLite3ResultSet::GetInt(int columnIndex, int nullValue /* = 0 */)
458
if (GetColumnType(columnIndex) == SQLITE_NULL)
464
return sqlite3_column_int((sqlite3_stmt*) m_stmt, columnIndex);
469
int wxSQLite3ResultSet::GetInt(const wxString& columnName, int nullValue /* = 0 */)
471
int columnIndex = FindColumnIndex(columnName);
472
return GetInt(columnIndex, nullValue);
475
wxLongLong wxSQLite3ResultSet::GetInt64(int columnIndex, wxLongLong nullValue /* = 0 */)
477
if (GetColumnType(columnIndex) == SQLITE_NULL)
483
return wxLongLong(sqlite3_column_int64((sqlite3_stmt*) m_stmt, columnIndex));
487
wxLongLong wxSQLite3ResultSet::GetInt64(const wxString& columnName, wxLongLong nullValue /* = 0 */)
489
int columnIndex = FindColumnIndex(columnName);
490
return GetInt64(columnIndex, nullValue);
493
double wxSQLite3ResultSet::GetDouble(int columnIndex, double nullValue /* = 0.0 */)
495
if (GetColumnType(columnIndex) == SQLITE_NULL)
501
return sqlite3_column_double((sqlite3_stmt*) m_stmt, columnIndex);
505
double wxSQLite3ResultSet::GetDouble(const wxString& columnName, double nullValue /* = 0.0 */)
507
int columnIndex = FindColumnIndex(columnName);
508
return GetDouble(columnIndex, nullValue);
511
wxString wxSQLite3ResultSet::GetString(int columnIndex, const wxString& nullValue /* = wxEmptyString */)
513
if (GetColumnType(columnIndex) == SQLITE_NULL)
519
const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
520
return wxString::FromUTF8(localValue);
524
wxString wxSQLite3ResultSet::GetString(const wxString& columnName, const wxString& nullValue /* = wxEmptyString */)
526
int columnIndex = FindColumnIndex(columnName);
527
return GetString(columnIndex, nullValue);
530
const unsigned char* wxSQLite3ResultSet::GetBlob(int columnIndex, int& len)
534
if (columnIndex < 0 || columnIndex > m_cols-1)
536
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
539
len = sqlite3_column_bytes((sqlite3_stmt*) m_stmt, columnIndex);
540
return (const unsigned char*) sqlite3_column_blob((sqlite3_stmt*) m_stmt, columnIndex);
543
const unsigned char* wxSQLite3ResultSet::GetBlob(const wxString& columnName, int& len)
545
int columnIndex = FindColumnIndex(columnName);
546
return GetBlob(columnIndex, len);
549
wxMemoryBuffer& wxSQLite3ResultSet::GetBlob(int columnIndex, wxMemoryBuffer& buffer)
553
if (columnIndex < 0 || columnIndex > m_cols-1)
555
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
558
int len = sqlite3_column_bytes((sqlite3_stmt*) m_stmt, columnIndex);
559
const void* blob = sqlite3_column_blob((sqlite3_stmt*) m_stmt, columnIndex);
560
buffer.AppendData((void*) blob, (size_t) len);
564
wxMemoryBuffer& wxSQLite3ResultSet::GetBlob(const wxString& columnName, wxMemoryBuffer& buffer)
566
int columnIndex = FindColumnIndex(columnName);
567
return GetBlob(columnIndex, buffer);
570
wxDateTime wxSQLite3ResultSet::GetDate(int columnIndex)
572
if (GetColumnType(columnIndex) == SQLITE_NULL)
574
return wxInvalidDateTime;
579
const wxChar* result = date.ParseDate(GetString(columnIndex));
586
return wxInvalidDateTime;
591
wxDateTime wxSQLite3ResultSet::GetDate(const wxString& columnName)
593
int columnIndex = FindColumnIndex(columnName);
594
return GetDate(columnIndex);
598
wxDateTime wxSQLite3ResultSet::GetTime(int columnIndex)
600
if (GetColumnType(columnIndex) == SQLITE_NULL)
602
return wxInvalidDateTime;
607
const wxChar* result = date.ParseTime(GetString(columnIndex));
614
return wxInvalidDateTime;
619
wxDateTime wxSQLite3ResultSet::GetTime(const wxString& columnName)
621
int columnIndex = FindColumnIndex(columnName);
622
return GetTime(columnIndex);
625
wxDateTime wxSQLite3ResultSet::GetDateTime(int columnIndex)
627
if (GetColumnType(columnIndex) == SQLITE_NULL)
629
return wxInvalidDateTime;
634
const wxChar* result = date.ParseDateTime(GetString(columnIndex));
637
date.SetMillisecond(0);
642
return wxInvalidDateTime;
647
wxDateTime wxSQLite3ResultSet::GetDateTime(const wxString& columnName)
649
int columnIndex = FindColumnIndex(columnName);
650
return GetDateTime(columnIndex);
653
wxDateTime wxSQLite3ResultSet::GetTimestamp(int columnIndex)
655
if (GetColumnType(columnIndex) == SQLITE_NULL)
657
return wxInvalidDateTime;
662
const wxChar* result = date.ParseDateTime(GetString(columnIndex));
669
return wxInvalidDateTime;
674
wxDateTime wxSQLite3ResultSet::GetTimestamp(const wxString& columnName)
676
int columnIndex = FindColumnIndex(columnName);
677
return GetTimestamp(columnIndex);
680
wxDateTime wxSQLite3ResultSet::GetNumericDateTime(int columnIndex)
682
if (GetColumnType(columnIndex) == SQLITE_NULL)
684
return wxInvalidDateTime;
688
wxLongLong value = GetInt64(columnIndex);
689
return wxDateTime(value);
693
wxDateTime wxSQLite3ResultSet::GetNumericDateTime(const wxString& columnName)
695
int columnIndex = FindColumnIndex(columnName);
696
return GetNumericDateTime(columnIndex);
699
wxDateTime wxSQLite3ResultSet::GetJulianDayNumber(int columnIndex)
701
if (GetColumnType(columnIndex) == SQLITE_NULL)
703
return wxInvalidDateTime;
707
double value = GetDouble(columnIndex);
708
return wxDateTime(value);
712
wxDateTime wxSQLite3ResultSet::GetJulianDayNumber(const wxString& columnName)
714
int columnIndex = FindColumnIndex(columnName);
715
return GetJulianDayNumber(columnIndex);
718
bool wxSQLite3ResultSet::GetBool(int columnIndex)
720
return GetInt(columnIndex) != 0;
723
bool wxSQLite3ResultSet::GetBool(const wxString& columnName)
725
int columnIndex = FindColumnIndex(columnName);
726
return GetBool(columnIndex);
729
bool wxSQLite3ResultSet::IsNull(int columnIndex)
731
return (GetColumnType(columnIndex) == SQLITE_NULL);
734
bool wxSQLite3ResultSet::IsNull(const wxString& columnName)
736
int columnIndex = FindColumnIndex(columnName);
737
return (GetColumnType(columnIndex) == SQLITE_NULL);
740
int wxSQLite3ResultSet::FindColumnIndex(const wxString& columnName)
744
wxCharBuffer strColumnName = columnName.ToUTF8();
745
const char* localColumnName = strColumnName;
747
if (columnName.Len() > 0)
749
for (int columnIndex = 0; columnIndex < m_cols; columnIndex++)
751
const char* temp = sqlite3_column_name((sqlite3_stmt*) m_stmt, columnIndex);
753
if (strcmp(localColumnName, temp) == 0)
760
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
763
wxString wxSQLite3ResultSet::GetColumnName(int columnIndex)
767
if (columnIndex < 0 || columnIndex > m_cols-1)
769
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
772
const char* localValue = sqlite3_column_name((sqlite3_stmt*) m_stmt, columnIndex);
773
return wxString::FromUTF8(localValue);
776
wxString wxSQLite3ResultSet::GetDeclaredColumnType(int columnIndex)
780
if (columnIndex < 0 || columnIndex > m_cols-1)
782
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
785
const char* localValue = sqlite3_column_decltype((sqlite3_stmt*) m_stmt, columnIndex);
786
return wxString::FromUTF8(localValue);
789
int wxSQLite3ResultSet::GetColumnType(int columnIndex)
793
if (columnIndex < 0 || columnIndex > m_cols-1)
795
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
798
return sqlite3_column_type((sqlite3_stmt*) m_stmt, columnIndex);
801
bool wxSQLite3ResultSet::Eof()
807
bool wxSQLite3ResultSet::NextRow()
815
rc = (m_eof) ? SQLITE_DONE : SQLITE_ROW;
819
rc = sqlite3_step((sqlite3_stmt*) m_stmt);
822
if (rc == SQLITE_DONE) // no more rows
827
else if (rc == SQLITE_ROW) // more rows
833
rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
835
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
836
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
840
void wxSQLite3ResultSet::Finalize()
842
if (m_stmt && m_ownStmt)
844
int rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
848
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
849
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
854
wxString wxSQLite3ResultSet::GetSQL()
856
wxString sqlString = wxEmptyString;
857
#if SQLITE_VERSION_NUMBER >= 3005003
859
const char* sqlLocal = sqlite3_sql((sqlite3_stmt*) m_stmt);
860
if (sqlLocal != NULL) sqlString = wxString::FromUTF8(sqlLocal);
865
bool wxSQLite3ResultSet::IsOk()
867
return (m_db != 0) && (m_stmt != 0);
870
void wxSQLite3ResultSet::CheckStmt()
874
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSTMT);
878
wxString wxSQLite3ResultSet::GetDatabaseName(int columnIndex)
880
#if WXSQLITE3_HAVE_METADATA
882
if (columnIndex < 0 || columnIndex > m_cols-1)
884
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
887
const char* localValue = sqlite3_column_database_name((sqlite3_stmt*) m_stmt, columnIndex);
888
if (localValue != NULL)
889
return wxString::FromUTF8(localValue);
891
return wxEmptyString;
893
wxUnusedVar(columnIndex);
894
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
898
wxString wxSQLite3ResultSet::GetTableName(int columnIndex)
900
#if WXSQLITE3_HAVE_METADATA
902
if (columnIndex < 0 || columnIndex > m_cols-1)
904
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
907
const char* localValue = sqlite3_column_table_name((sqlite3_stmt*) m_stmt, columnIndex);
908
if (localValue != NULL)
909
return wxString::FromUTF8(localValue);
911
return wxEmptyString;
913
wxUnusedVar(columnIndex);
914
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
918
wxString wxSQLite3ResultSet::GetOriginName(int columnIndex)
920
#if WXSQLITE3_HAVE_METADATA
922
if (columnIndex < 0 || columnIndex > m_cols-1)
924
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
927
const char* localValue = sqlite3_column_origin_name((sqlite3_stmt*) m_stmt, columnIndex);
928
if (localValue != NULL)
929
return wxString::FromUTF8(localValue);
931
return wxEmptyString;
933
wxUnusedVar(columnIndex);
934
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
938
// ----------------------------------------------------------------------------
939
// wxSQLite3Table: class holding the complete result set of a query
940
// ----------------------------------------------------------------------------
942
wxSQLite3Table::wxSQLite3Table()
950
wxSQLite3Table::wxSQLite3Table(const wxSQLite3Table& table)
952
m_results = table.m_results;
953
// Only one object can own the results
954
const_cast<wxSQLite3Table&>(table).m_results = 0;
955
m_rows = table.m_rows;
956
m_cols = table.m_cols;
957
m_currentRow = table.m_currentRow;
960
wxSQLite3Table::wxSQLite3Table(char** results, int rows, int cols)
968
wxSQLite3Table::~wxSQLite3Table()
979
wxSQLite3Table& wxSQLite3Table::operator=(const wxSQLite3Table& table)
990
m_results = table.m_results;
991
// Only one object can own the results
992
const_cast<wxSQLite3Table&>(table).m_results = 0;
993
m_rows = table.m_rows;
994
m_cols = table.m_cols;
995
m_currentRow = table.m_currentRow;
1000
void wxSQLite3Table::Finalize()
1004
sqlite3_free_table(m_results);
1009
int wxSQLite3Table::GetColumnCount()
1015
int wxSQLite3Table::GetRowCount()
1021
int wxSQLite3Table::FindColumnIndex(const wxString& columnName)
1025
wxCharBuffer strColumnName = columnName.ToUTF8();
1026
const char* localColumnName = strColumnName;
1028
if (columnName.Len() > 0)
1030
for (int columnIndex = 0; columnIndex < m_cols; columnIndex++)
1032
if (strcmp(localColumnName, m_results[columnIndex]) == 0)
1039
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_NAME);
1042
wxString wxSQLite3Table::GetAsString(int columnIndex)
1044
if (columnIndex < 0 || columnIndex > m_cols-1)
1046
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
1049
int nIndex = (m_currentRow*m_cols) + m_cols + columnIndex;
1050
const char* localValue = m_results[nIndex];
1051
return wxString::FromUTF8(localValue);
1054
wxString wxSQLite3Table::GetAsString(const wxString& columnName)
1056
int index = FindColumnIndex(columnName);
1057
return GetAsString(index);
1060
int wxSQLite3Table::GetInt(int columnIndex, int nullValue /* = 0 */)
1062
if (IsNull(columnIndex))
1068
long value = nullValue;
1069
GetAsString(columnIndex).ToLong(&value);
1074
int wxSQLite3Table::GetInt(const wxString& columnName, int nullValue /* = 0 */)
1076
if (IsNull(columnName))
1082
long value = nullValue;
1083
GetAsString(columnName).ToLong(&value);
1088
wxLongLong wxSQLite3Table::GetInt64(int columnIndex, wxLongLong nullValue /* = 0 */)
1090
if (IsNull(columnIndex))
1096
return ConvertStringToLongLong(GetAsString(columnIndex), nullValue);
1100
wxLongLong wxSQLite3Table::GetInt64(const wxString& columnName, wxLongLong nullValue /* = 0 */)
1102
if (IsNull(columnName))
1108
return ConvertStringToLongLong(GetAsString(columnName), nullValue);
1112
// Since SQLite uses internally a locale independent string representation
1113
// of double values, we need to provide our own conversion procedure using
1114
// always a point as the decimal separator.
1115
// The following code duplicates a SQLite utility function with minor modifications.
1117
static double wxSQLite3AtoF(const char *z)
1120
long double v1 = 0.0;
1121
int nSignificant = 0;
1122
while (isspace(*(unsigned char*)z))
1139
while (isdigit(*(unsigned char*)z))
1141
v1 = v1*10.0 + (*z - '0');
1147
long double divisor = 1.0;
1149
if (nSignificant == 0)
1157
while (isdigit(*(unsigned char*)z))
1159
if (nSignificant < 18)
1161
v1 = v1*10.0 + (*z - '0');
1169
if (*z=='e' || *z=='E')
1173
long double scale = 1.0;
1184
while (isdigit(*(unsigned char*)z))
1186
eval = eval*10 + *z - '0';
1189
while (eval >= 64) { scale *= 1.0e+64; eval -= 64; }
1190
while (eval >= 16) { scale *= 1.0e+16; eval -= 16; }
1191
while (eval >= 4) { scale *= 1.0e+4; eval -= 4; }
1192
while (eval >= 1) { scale *= 1.0e+1; eval -= 1; }
1202
return (double) ((sign < 0) ? -v1 : v1);
1205
double wxSQLite3Table::GetDouble(int columnIndex, double nullValue /* = 0.0 */)
1207
if (IsNull(columnIndex))
1213
if (columnIndex < 0 || columnIndex > m_cols-1)
1215
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
1217
int nIndex = (m_currentRow*m_cols) + m_cols + columnIndex;
1218
return wxSQLite3AtoF(m_results[nIndex]);
1222
double wxSQLite3Table::GetDouble(const wxString& columnName, double nullValue /* = 0.0 */)
1224
int index = FindColumnIndex(columnName);
1225
return GetDouble(index, nullValue);
1228
wxString wxSQLite3Table::GetString(int columnIndex, const wxString& nullValue /* = wxEmptyString */)
1230
if (IsNull(columnIndex))
1236
return GetAsString(columnIndex);
1240
wxString wxSQLite3Table::GetString(const wxString& columnName, const wxString& nullValue /* = wxEmptyString */)
1242
if (IsNull(columnName))
1248
return GetAsString(columnName);
1252
wxDateTime wxSQLite3Table::GetDate(int columnIndex)
1255
const wxChar* result = date.ParseDate(GetString(columnIndex));
1262
return wxInvalidDateTime;
1266
wxDateTime wxSQLite3Table::GetDate(const wxString& columnName)
1268
int columnIndex = FindColumnIndex(columnName);
1269
return GetDate(columnIndex);
1272
wxDateTime wxSQLite3Table::GetTime(int columnIndex)
1275
const wxChar* result = date.ParseTime(GetString(columnIndex));
1282
return wxInvalidDateTime;
1286
wxDateTime wxSQLite3Table::GetTime(const wxString& columnName)
1288
int columnIndex = FindColumnIndex(columnName);
1289
return GetTime(columnIndex);
1292
wxDateTime wxSQLite3Table::GetDateTime(int columnIndex)
1295
const wxChar* result = date.ParseDateTime(GetString(columnIndex));
1302
return wxInvalidDateTime;
1306
wxDateTime wxSQLite3Table::GetDateTime(const wxString& columnName)
1308
int columnIndex = FindColumnIndex(columnName);
1309
return GetDateTime(columnIndex);
1312
bool wxSQLite3Table::GetBool(int columnIndex)
1314
return GetInt(columnIndex) != 0;
1317
bool wxSQLite3Table::GetBool(const wxString& columnName)
1319
int columnIndex = FindColumnIndex(columnName);
1320
return GetBool(columnIndex);
1323
bool wxSQLite3Table::IsNull(int columnIndex)
1327
if (columnIndex < 0 || columnIndex > m_cols-1)
1329
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
1332
int index = (m_currentRow*m_cols) + m_cols + columnIndex;
1333
const char* localValue = m_results[index];
1334
return (localValue == 0);
1337
bool wxSQLite3Table::IsNull(const wxString& columnName)
1339
int index = FindColumnIndex(columnName);
1340
return IsNull(index);
1343
wxString wxSQLite3Table::GetColumnName(int columnIndex)
1347
if (columnIndex < 0 || columnIndex > m_cols-1)
1349
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
1352
const char* localValue = m_results[columnIndex];
1353
return wxString::FromUTF8(localValue);
1356
void wxSQLite3Table::SetRow(int row)
1360
if (row < 0 || row > m_rows-1)
1362
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_ROW);
1368
bool wxSQLite3Table::IsOk()
1370
return (m_results != 0);
1373
void wxSQLite3Table::CheckResults()
1377
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NORESULT);
1381
// ----------------------------------------------------------------------------
1382
// wxSQLite3Statement: class holding a prepared statement
1383
// ----------------------------------------------------------------------------
1385
wxSQLite3Statement::wxSQLite3Statement()
1389
m_hasOwnership = false;
1392
wxSQLite3Statement::wxSQLite3Statement(const wxSQLite3Statement& statement)
1394
m_db = statement.m_db;
1395
m_stmt = statement.m_stmt;
1396
m_hasOwnership = statement.m_hasOwnership;
1397
// Only one object can own prepared statement
1398
const_cast<wxSQLite3Statement&>(statement).m_hasOwnership = false;
1401
wxSQLite3Statement::wxSQLite3Statement(void* db, void* stmt)
1405
m_hasOwnership = true;
1408
wxSQLite3Statement::~wxSQLite3Statement()
1419
wxSQLite3Statement& wxSQLite3Statement::operator=(const wxSQLite3Statement& statement)
1421
if (this != &statement)
1430
m_db = statement.m_db;
1431
m_stmt = statement.m_stmt;
1432
m_hasOwnership = statement.m_hasOwnership;
1433
// Only one object can own prepared statement
1434
const_cast<wxSQLite3Statement&>(statement).m_hasOwnership = false;
1439
int wxSQLite3Statement::ExecuteUpdate()
1444
const char* localError=0;
1446
int rc = sqlite3_step((sqlite3_stmt*) m_stmt);
1448
if (rc == SQLITE_DONE)
1450
int rowsChanged = sqlite3_changes((sqlite3*) m_db);
1452
rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
1454
if (rc != SQLITE_OK)
1456
localError = sqlite3_errmsg((sqlite3*) m_db);
1457
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
1464
rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
1465
localError = sqlite3_errmsg((sqlite3*) m_db);
1466
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
1470
wxSQLite3ResultSet wxSQLite3Statement::ExecuteQuery(bool transferStatementOwnership)
1474
if (transferStatementOwnership)
1478
m_hasOwnership = false;
1482
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOTOWNED);
1486
int rc = sqlite3_step((sqlite3_stmt*) m_stmt);
1488
if (rc == SQLITE_DONE) // no more rows
1490
return wxSQLite3ResultSet(m_db, m_stmt, true/*eof*/, true/*first*/, transferStatementOwnership);
1492
else if (rc == SQLITE_ROW) // one or more rows
1494
return wxSQLite3ResultSet(m_db, m_stmt, false/*eof*/, true/*first*/, transferStatementOwnership);
1498
rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
1499
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1500
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
1504
int wxSQLite3Statement::ExecuteScalar()
1506
wxSQLite3ResultSet resultSet = ExecuteQuery(true);
1508
if (resultSet.Eof() || resultSet.GetColumnCount() < 1)
1510
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_QUERY);
1514
resultSet.GetAsString(0).ToLong(&value);
1518
int wxSQLite3Statement::GetParamCount()
1521
return sqlite3_bind_parameter_count((sqlite3_stmt*) m_stmt);
1524
int wxSQLite3Statement::GetParamIndex(const wxString& paramName)
1528
wxCharBuffer strParamName = paramName.ToUTF8();
1529
const char* localParamName = strParamName;
1531
return sqlite3_bind_parameter_index((sqlite3_stmt*) m_stmt, localParamName);
1534
wxString wxSQLite3Statement::GetParamName(int paramIndex)
1537
const char* localParamName = sqlite3_bind_parameter_name((sqlite3_stmt*) m_stmt, paramIndex);
1538
return wxString::FromUTF8(localParamName);
1541
void wxSQLite3Statement::Bind(int paramIndex, const wxString& stringValue)
1545
wxCharBuffer strStringValue = stringValue.ToUTF8();
1546
const char* localStringValue = strStringValue;
1548
int rc = sqlite3_bind_text((sqlite3_stmt*) m_stmt, paramIndex, localStringValue, -1, SQLITE_TRANSIENT);
1550
if (rc != SQLITE_OK)
1552
throw wxSQLite3Exception(rc, wxERRMSG_BIND_STR);
1556
void wxSQLite3Statement::Bind(int paramIndex, int intValue)
1559
int rc = sqlite3_bind_int((sqlite3_stmt*) m_stmt, paramIndex, intValue);
1561
if (rc != SQLITE_OK)
1563
throw wxSQLite3Exception(rc, wxERRMSG_BIND_INT);
1567
void wxSQLite3Statement::Bind(int paramIndex, wxLongLong int64Value)
1570
int rc = sqlite3_bind_int64((sqlite3_stmt*) m_stmt, paramIndex, int64Value.GetValue());
1572
if (rc != SQLITE_OK)
1574
throw wxSQLite3Exception(rc, wxERRMSG_BIND_INT64);
1578
void wxSQLite3Statement::Bind(int paramIndex, double doubleValue)
1581
int rc = sqlite3_bind_double((sqlite3_stmt*) m_stmt, paramIndex, doubleValue);
1583
if (rc != SQLITE_OK)
1585
throw wxSQLite3Exception(rc, wxERRMSG_BIND_DBL);
1589
void wxSQLite3Statement::Bind(int paramIndex, const char* charValue)
1592
int rc = sqlite3_bind_text((sqlite3_stmt*) m_stmt, paramIndex, charValue, -1, SQLITE_TRANSIENT);
1594
if (rc != SQLITE_OK)
1596
throw wxSQLite3Exception(rc, wxERRMSG_BIND_STR);
1600
void wxSQLite3Statement::Bind(int paramIndex, const unsigned char* blobValue, int blobLen)
1603
int rc = sqlite3_bind_blob((sqlite3_stmt*) m_stmt, paramIndex,
1604
(const void*)blobValue, blobLen, SQLITE_TRANSIENT);
1606
if (rc != SQLITE_OK)
1608
throw wxSQLite3Exception(rc, wxERRMSG_BIND_BLOB);
1612
void wxSQLite3Statement::Bind(int paramIndex, const wxMemoryBuffer& blobValue)
1615
int blobLen = (int) blobValue.GetDataLen();
1616
int rc = sqlite3_bind_blob((sqlite3_stmt*) m_stmt, paramIndex,
1617
(const void*)blobValue.GetData(), blobLen, SQLITE_TRANSIENT);
1619
if (rc != SQLITE_OK)
1621
throw wxSQLite3Exception(rc, wxERRMSG_BIND_BLOB);
1625
void wxSQLite3Statement::BindDate(int paramIndex, const wxDateTime& date)
1629
Bind(paramIndex,date.FormatISODate());
1633
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
1637
void wxSQLite3Statement::BindTime(int paramIndex, const wxDateTime& time)
1641
Bind(paramIndex,time.FormatISOTime());
1645
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
1649
void wxSQLite3Statement::BindDateTime(int paramIndex, const wxDateTime& datetime)
1651
if (datetime.IsValid())
1653
Bind(paramIndex,datetime.Format(wxT("%Y-%m-%d %H:%M:%S")));
1657
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
1661
void wxSQLite3Statement::BindTimestamp(int paramIndex, const wxDateTime& timestamp)
1663
if (timestamp.IsValid())
1665
Bind(paramIndex,timestamp.Format(wxT("%Y-%m-%d %H:%M:%S.%l")));
1669
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
1673
void wxSQLite3Statement::BindNumericDateTime(int paramIndex, const wxDateTime& datetime)
1675
if (datetime.IsValid())
1677
Bind(paramIndex, datetime.GetValue());
1681
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
1685
void wxSQLite3Statement::BindJulianDayNumber(int paramIndex, const wxDateTime& datetime)
1687
if (datetime.IsValid())
1689
Bind(paramIndex, datetime.GetJulianDayNumber());
1693
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
1697
void wxSQLite3Statement::BindBool(int paramIndex, bool value)
1699
Bind(paramIndex, value ? 1 : 0);
1702
void wxSQLite3Statement::BindNull(int paramIndex)
1705
int rc = sqlite3_bind_null((sqlite3_stmt*) m_stmt, paramIndex);
1707
if (rc != SQLITE_OK)
1709
throw wxSQLite3Exception(rc, wxERRMSG_BIND_NULL);
1713
void wxSQLite3Statement::BindZeroBlob(int paramIndex, int blobSize)
1715
#if SQLITE_VERSION_NUMBER >= 3004000
1717
int rc = sqlite3_bind_zeroblob((sqlite3_stmt*) m_stmt, paramIndex, blobSize);
1718
if (rc != SQLITE_OK)
1720
throw wxSQLite3Exception(rc, wxERRMSG_BIND_ZEROBLOB);
1723
wxUnusedVar(paramIndex);
1724
wxUnusedVar(blobSize);
1725
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
1729
void wxSQLite3Statement::ClearBindings()
1732
#if 0 // missing in SQLite DLL
1733
int rc = sqlite3_clear_bindings((sqlite3_stmt*) m_stmt);
1735
if (rc != SQLITE_OK)
1737
throw wxSQLite3Exception(rc, wxERRMSG_BIND_CLEAR);
1740
for (int paramIndex = 1; paramIndex <= GetParamCount(); paramIndex++)
1742
BindNull(paramIndex);
1747
wxString wxSQLite3Statement::GetSQL()
1749
wxString sqlString = wxEmptyString;
1750
#if SQLITE_VERSION_NUMBER >= 3005003
1752
const char* sqlLocal = sqlite3_sql((sqlite3_stmt*) m_stmt);
1753
if (sqlLocal != NULL) sqlString = wxString::FromUTF8(sqlLocal);
1758
void wxSQLite3Statement::Reset()
1762
int rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
1764
if (rc != SQLITE_OK)
1766
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1767
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
1772
bool wxSQLite3Statement::IsReadOnly()
1774
#if SQLITE_VERSION_NUMBER >= 3007004
1776
return sqlite3_stmt_readonly((sqlite3_stmt*) m_stmt) != 0;
1782
void wxSQLite3Statement::Finalize()
1784
if (m_stmt && m_hasOwnership)
1786
int rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
1788
m_hasOwnership = false;
1790
if (rc != SQLITE_OK)
1792
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1793
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
1798
bool wxSQLite3Statement::IsOk()
1800
return (m_db != 0) && (m_stmt != 0);
1803
void wxSQLite3Statement::CheckDatabase()
1807
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NODB);
1811
void wxSQLite3Statement::CheckStmt()
1815
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSTMT);
1821
wxSQLite3Blob::wxSQLite3Blob()
1829
wxSQLite3Blob::wxSQLite3Blob(const wxSQLite3Blob& blob)
1832
m_blob = blob.m_blob;
1834
m_writable = blob.m_writable;
1837
wxSQLite3Blob& wxSQLite3Blob::operator=(const wxSQLite3Blob& blob)
1849
m_blob = blob.m_blob;
1851
m_writable = blob.m_writable;
1852
// only one blob can own the blob handle
1853
const_cast<wxSQLite3Blob&>(blob).m_ok = false;
1858
wxSQLite3Blob::wxSQLite3Blob(void* db, void* blobHandle, bool writable)
1861
m_blob = blobHandle;
1863
m_writable = writable;
1866
wxSQLite3Blob::~wxSQLite3Blob()
1877
wxMemoryBuffer& wxSQLite3Blob::Read(wxMemoryBuffer& blobValue, int length, int offset)
1879
#if SQLITE_VERSION_NUMBER >= 3004000
1881
char* localBuffer = (char*) blobValue.GetAppendBuf((size_t) length);
1882
int rc = sqlite3_blob_read((sqlite3_blob*) m_blob, localBuffer, length, offset);
1884
if (rc != SQLITE_OK)
1886
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1887
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
1890
blobValue.UngetAppendBuf((size_t) length);
1892
wxUnusedVar(blobValue);
1893
wxUnusedVar(length);
1894
wxUnusedVar(offset);
1895
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
1900
void wxSQLite3Blob::Write(const wxMemoryBuffer& blobValue, int offset)
1902
#if SQLITE_VERSION_NUMBER >= 3004000
1906
int blobLen = (int) blobValue.GetDataLen();
1907
int rc = sqlite3_blob_write((sqlite3_blob*) m_blob,
1908
(const void*) blobValue.GetData(), blobLen, offset);
1910
if (rc != SQLITE_OK)
1912
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1913
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
1918
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_BLOB);
1921
wxUnusedVar(blobValue);
1922
wxUnusedVar(offset);
1923
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
1927
bool wxSQLite3Blob::IsOk()
1932
bool wxSQLite3Blob::IsReadOnly()
1937
int wxSQLite3Blob::GetSize()
1939
#if SQLITE_VERSION_NUMBER >= 3004000
1941
return sqlite3_blob_bytes((sqlite3_blob*) m_blob);
1943
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
1948
void wxSQLite3Blob::Rebind(wxLongLong rowid)
1950
#if SQLITE_VERSION_NUMBER >= 3007004
1952
int rc = sqlite3_blob_reopen((sqlite3_blob*) m_blob, rowid.GetValue());
1953
if (rc != SQLITE_OK)
1955
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1956
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
1960
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOBLOBREBIND);
1964
void wxSQLite3Blob::Finalize()
1966
#if SQLITE_VERSION_NUMBER >= 3004000
1969
int rc = sqlite3_blob_close((sqlite3_blob*) m_blob);
1972
if (rc != SQLITE_OK)
1974
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
1975
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
1979
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
1983
void wxSQLite3Blob::CheckBlob()
1987
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_BLOB);
1991
// ----------------------------------------------------------------------------
1992
// wxSQLite3Database: class holding a SQLite3 database object
1993
// ----------------------------------------------------------------------------
1995
bool wxSQLite3Database::ms_sharedCacheEnabled = false;
1998
wxSQLite3Database::SetSharedCache(bool enable)
2000
int flag = (enable) ? 1 : 0;
2001
int rc = sqlite3_enable_shared_cache(flag);
2002
if (rc != SQLITE_OK)
2004
throw wxSQLite3Exception(rc, wxERRMSG_SHARED_CACHE);
2006
ms_sharedCacheEnabled = enable;
2009
#if WXSQLITE3_HAVE_CODEC
2010
bool wxSQLite3Database::ms_hasEncryptionSupport = true;
2012
bool wxSQLite3Database::ms_hasEncryptionSupport = false;
2015
#if WXSQLITE3_HAVE_METADATA
2016
bool wxSQLite3Database::ms_hasMetaDataSupport = true;
2018
bool wxSQLite3Database::ms_hasMetaDataSupport = false;
2021
#if WXSQLITE3_HAVE_LOAD_EXTENSION
2022
bool wxSQLite3Database::ms_hasLoadExtSupport = true;
2024
bool wxSQLite3Database::ms_hasLoadExtSupport = false;
2027
#if WXSQLITE3_USE_NAMED_COLLECTIONS
2028
bool wxSQLite3Database::ms_hasNamedCollectionSupport = true;
2030
bool wxSQLite3Database::ms_hasNamedCollectionSupport = false;
2033
#if SQLITE_VERSION_NUMBER >= 3004000
2034
bool wxSQLite3Database::ms_hasIncrementalBlobSupport = true;
2036
bool wxSQLite3Database::ms_hasIncrementalBlobSupport = false;
2039
#if SQLITE_VERSION_NUMBER >= 3006008
2040
bool wxSQLite3Database::ms_hasSavepointSupport = true;
2042
bool wxSQLite3Database::ms_hasSavepointSupport = false;
2045
#if SQLITE_VERSION_NUMBER >= 3006011
2046
bool wxSQLite3Database::ms_hasBackupSupport = true;
2048
bool wxSQLite3Database::ms_hasBackupSupport = false;
2051
#if SQLITE_VERSION_NUMBER >= 3007000
2052
bool wxSQLite3Database::ms_hasWriteAheadLogSupport = true;
2054
bool wxSQLite3Database::ms_hasWriteAheadLogSupport = false;
2058
wxSQLite3Database::HasEncryptionSupport()
2060
return ms_hasEncryptionSupport;
2064
wxSQLite3Database::HasMetaDataSupport()
2066
return ms_hasMetaDataSupport;
2070
wxSQLite3Database::HasLoadExtSupport()
2072
return ms_hasLoadExtSupport;
2076
wxSQLite3Database::HasNamedCollectionSupport()
2078
return ms_hasNamedCollectionSupport;
2082
wxSQLite3Database::HasIncrementalBlobSupport()
2084
return ms_hasIncrementalBlobSupport;
2088
wxSQLite3Database::HasSavepointSupport()
2090
return ms_hasSavepointSupport;
2094
wxSQLite3Database::HasBackupSupport()
2096
return ms_hasBackupSupport;
2100
wxSQLite3Database::HasWriteAheadLogSupport()
2102
return ms_hasWriteAheadLogSupport;
2105
wxSQLite3Database::wxSQLite3Database()
2108
m_busyTimeoutMs = 60000; // 60 seconds
2109
m_isEncrypted = false;
2112
wxSQLite3Database::wxSQLite3Database(const wxSQLite3Database& db)
2115
m_busyTimeoutMs = 60000; // 60 seconds
2116
m_isEncrypted = false;
2119
wxSQLite3Database::~wxSQLite3Database()
2124
wxSQLite3Database& wxSQLite3Database::operator=(const wxSQLite3Database& db)
2131
m_busyTimeoutMs = 60000; // 60 seconds
2132
m_isEncrypted = db.m_isEncrypted;
2136
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_DBASSIGN_FAILED);
2142
void wxSQLite3Database::Open(const wxString& fileName, const wxString& key, int flags)
2144
wxCharBuffer strLocalKey = key.ToUTF8();
2145
const char* localKey = strLocalKey;
2146
wxMemoryBuffer binaryKey;
2147
if (key.Length() > 0)
2149
binaryKey.AppendData((void*) localKey, strlen(localKey));
2151
Open(fileName, binaryKey, flags);
2154
void wxSQLite3Database::Open(const wxString& fileName, const wxMemoryBuffer& key, int flags)
2156
wxCharBuffer strFileName = fileName.ToUTF8();
2157
const char* localFileName = strFileName;
2159
int rc = sqlite3_open_v2((const char*) localFileName, (sqlite3**) &m_db, flags, NULL);
2161
if (rc != SQLITE_OK)
2163
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2165
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2168
rc = sqlite3_extended_result_codes((sqlite3*) m_db, 1);
2169
if (rc != SQLITE_OK)
2171
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2173
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2176
#if WXSQLITE3_HAVE_CODEC
2177
if (key.GetDataLen() > 0)
2179
rc = sqlite3_key((sqlite3*) m_db, key.GetData(), (int) key.GetDataLen());
2180
if (rc != SQLITE_OK)
2182
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2184
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2186
m_isEncrypted = true;
2192
SetBusyTimeout(m_busyTimeoutMs);
2195
bool wxSQLite3Database::IsOpen() const
2197
return (m_db != NULL);
2200
void wxSQLite3Database::Close()
2204
#if SQLITE_VERSION_NUMBER >= 3006000
2205
// Unfortunately the following code leads to a crash if the RTree module is used
2206
// therefore it is disabled for now
2208
// Finalize all unfinalized prepared statements
2209
sqlite3_stmt *pStmt;
2210
while( (pStmt = sqlite3_next_stmt((sqlite3*) m_db, 0))!=0 )
2212
sqlite3_finalize(pStmt);
2216
sqlite3_close((sqlite3*) m_db);
2218
m_isEncrypted = false;
2222
void wxSQLite3Database::Backup(const wxString& targetFileName, const wxString& key, const wxString& sourceDatabaseName)
2224
wxCharBuffer strLocalKey = key.ToUTF8();
2225
const char* localKey = strLocalKey;
2226
wxMemoryBuffer binaryKey;
2227
if (key.Length() > 0)
2229
binaryKey.AppendData((void*) localKey, strlen(localKey));
2231
Backup(targetFileName, binaryKey, sourceDatabaseName);
2234
void wxSQLite3Database::Backup(const wxString& targetFileName, const wxMemoryBuffer& key, const wxString& sourceDatabaseName)
2236
#if SQLITE_VERSION_NUMBER >= 3006011
2239
wxCharBuffer strFileName = targetFileName.ToUTF8();
2240
const char* localTargetFileName = strFileName;
2241
wxCharBuffer strDatabaseName = sourceDatabaseName.ToUTF8();
2242
const char* localSourceDatabaseName = strDatabaseName;
2245
sqlite3_backup* pBackup;
2247
rc = sqlite3_open(localTargetFileName, &pDest);
2248
if (rc != SQLITE_OK)
2250
sqlite3_close(pDest);
2251
throw wxSQLite3Exception(rc, wxERRMSG_DBOPEN_FAILED);
2253
#if WXSQLITE3_HAVE_CODEC
2254
if (key.GetDataLen() > 0)
2256
rc = sqlite3_key(pDest, key.GetData(), (int) key.GetDataLen());
2257
if (rc != SQLITE_OK)
2259
const char* localError = sqlite3_errmsg((sqlite3*) pDest);
2260
sqlite3_close(pDest);
2261
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2268
pBackup = sqlite3_backup_init(pDest, "main", (sqlite3*) m_db, localSourceDatabaseName);
2271
const char* localError = sqlite3_errmsg(pDest);
2272
sqlite3_close(pDest);
2273
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2278
rc = sqlite3_backup_step(pBackup, 10);
2280
xProgress(sqlite3_backup_remaining(pBackup),
2281
sqlite3_backup_pagecount(pBackup));
2283
if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED)
2288
while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED);
2290
sqlite3_backup_finish(pBackup);
2291
if (rc == SQLITE_DONE)
2293
sqlite3_close(pDest);
2297
const char* localError = sqlite3_errmsg(pDest);
2298
sqlite3_close(pDest);
2299
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2302
wxUnusedVar(targetFileName);
2303
wxUnusedVar(sourceDatabaseName);
2304
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOBACKUP);
2308
void wxSQLite3Database::Restore(const wxString& sourceFileName, const wxString& key, const wxString& targetDatabaseName)
2310
wxCharBuffer strLocalKey = key.ToUTF8();
2311
const char* localKey = strLocalKey;
2312
wxMemoryBuffer binaryKey;
2313
if (key.Length() > 0)
2315
binaryKey.AppendData((void*) localKey, strlen(localKey));
2317
Restore(sourceFileName, binaryKey, targetDatabaseName);
2320
void wxSQLite3Database::Restore(const wxString& sourceFileName, const wxMemoryBuffer& key, const wxString& targetDatabaseName)
2322
#if SQLITE_VERSION_NUMBER >= 3006011
2325
wxCharBuffer strFileName = sourceFileName.ToUTF8();
2326
const char* localSourceFileName = strFileName;
2327
wxCharBuffer strDatabaseName = targetDatabaseName.ToUTF8();
2328
const char* localTargetDatabaseName = strDatabaseName;
2331
sqlite3_backup* pBackup;
2335
rc = sqlite3_open(localSourceFileName, &pSrc);
2336
if (rc != SQLITE_OK)
2338
sqlite3_close(pSrc);
2339
throw wxSQLite3Exception(rc, wxERRMSG_DBOPEN_FAILED);
2341
#if WXSQLITE3_HAVE_CODEC
2342
if (key.GetDataLen() > 0)
2344
rc = sqlite3_key(pSrc, key.GetData(), (int) key.GetDataLen());
2345
if (rc != SQLITE_OK)
2347
const char* localError = sqlite3_errmsg((sqlite3*) pSrc);
2348
sqlite3_close(pSrc);
2349
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2356
pBackup = sqlite3_backup_init((sqlite3*) m_db, localTargetDatabaseName, pSrc, "main");
2359
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2360
sqlite3_close(pSrc);
2361
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2363
while ((rc = sqlite3_backup_step(pBackup, 100)) == SQLITE_OK || rc == SQLITE_BUSY)
2365
if (rc == SQLITE_BUSY)
2367
if (nTimeout++ >= 3) break;
2371
sqlite3_backup_finish(pBackup);
2372
if (rc == SQLITE_DONE)
2374
sqlite3_close(pSrc);
2376
else if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED)
2378
sqlite3_close(pSrc);
2379
throw wxSQLite3Exception(rc, wxERRMSG_SOURCEDB_BUSY);
2383
const char* localError = sqlite3_errmsg(pSrc);
2384
sqlite3_close(pSrc);
2385
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2388
wxUnusedVar(sourceFileName);
2389
wxUnusedVar(targetDatabaseName);
2390
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOBACKUP);
2394
void wxSQLite3Database::Begin(wxSQLite3TransactionType transactionType)
2397
switch (transactionType)
2399
case WXSQLITE_TRANSACTION_DEFERRED:
2400
sql << wxT("begin deferred transaction");
2402
case WXSQLITE_TRANSACTION_IMMEDIATE:
2403
sql << wxT("begin immediate transaction");
2405
case WXSQLITE_TRANSACTION_EXCLUSIVE:
2406
sql << wxT("begin exclusive transaction");
2409
sql << wxT("begin transaction");
2415
void wxSQLite3Database::Commit()
2417
ExecuteUpdate("commit transaction");
2420
void wxSQLite3Database::Rollback(const wxString& savepointName)
2422
#if SQLITE_VERSION_NUMBER >= 3006008
2423
if (savepointName.IsEmpty())
2426
ExecuteUpdate("rollback transaction");
2427
#if SQLITE_VERSION_NUMBER >= 3006008
2431
ExecuteUpdate(wxString(wxT("rollback transaction to savepoint "))+savepointName);
2436
bool wxSQLite3Database::GetAutoCommit()
2439
return sqlite3_get_autocommit((sqlite3*) m_db) != 0;
2442
void wxSQLite3Database::Savepoint(const wxString& savepointName)
2444
#if SQLITE_VERSION_NUMBER >= 3006008
2445
ExecuteUpdate(wxString(wxT("savepoint "))+savepointName);
2447
wxUnusedVar(savepointName);
2448
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSAVEPOINT);
2452
void wxSQLite3Database::ReleaseSavepoint(const wxString& savepointName)
2454
#if SQLITE_VERSION_NUMBER >= 3006008
2455
ExecuteUpdate(wxString(wxT("release savepoint "))+savepointName);
2457
wxUnusedVar(savepointName);
2458
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSAVEPOINT);
2462
wxSQLite3Statement wxSQLite3Database::PrepareStatement(const wxString& sql)
2464
wxCharBuffer strSql = sql.ToUTF8();
2465
const char* localSql = strSql;
2466
return PrepareStatement(localSql);
2469
wxSQLite3Statement wxSQLite3Database::PrepareStatement(const wxSQLite3StatementBuffer& sql)
2471
return PrepareStatement((const char*) sql);
2474
wxSQLite3Statement wxSQLite3Database::PrepareStatement(const char* sql)
2477
sqlite3_stmt* stmt = (sqlite3_stmt*) Prepare(sql);
2478
return wxSQLite3Statement(m_db, stmt);
2481
bool wxSQLite3Database::TableExists(const wxString& tableName, const wxString& databaseName)
2484
if (databaseName.IsEmpty())
2486
sql = wxT("select count(*) from sqlite_master where type='table' and name like ?");
2490
sql = wxString(wxT("select count(*) from ")) + databaseName + wxString(wxT(".sqlite_master where type='table' and name like ?"));
2492
wxSQLite3Statement stmt = PrepareStatement(sql);
2493
stmt.Bind(1, tableName);
2494
wxSQLite3ResultSet resultSet = stmt.ExecuteQuery();
2496
resultSet.GetAsString(0).ToLong(&value);
2500
bool wxSQLite3Database::TableExists(const wxString& tableName, wxArrayString& databaseNames)
2502
wxArrayString databaseList;
2503
GetDatabaseList(databaseList);
2506
size_t count = databaseList.GetCount();
2510
for (j = 0; j < count; j++)
2512
if (TableExists(tableName, databaseList.Item(j)))
2515
databaseNames.Add(databaseList.Item(j));
2522
void wxSQLite3Database::GetDatabaseList(wxArrayString& databaseNames)
2524
databaseNames.Empty();
2525
wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA database_list;");
2526
while (resultSet.NextRow())
2528
databaseNames.Add(resultSet.GetString(1));
2532
void wxSQLite3Database::GetDatabaseList(wxArrayString& databaseNames, wxArrayString& databaseFiles)
2534
databaseNames.Empty();
2535
databaseFiles.Empty();
2536
wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA database_list;");
2537
while (resultSet.NextRow())
2539
databaseNames.Add(resultSet.GetString(1));
2540
databaseFiles.Add(resultSet.GetString(2));
2544
bool wxSQLite3Database::EnableForeignKeySupport(bool enable)
2548
ExecuteUpdate("PRAGMA foreign_keys=ON;");
2552
ExecuteUpdate("PRAGMA foreign_keys=OFF;");
2554
bool enabled = IsForeignKeySupportEnabled();
2555
return (enable && enabled) || (!enable && !enabled);
2558
bool wxSQLite3Database::IsForeignKeySupportEnabled()
2560
bool enabled = false;
2561
wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA foreign_keys;");
2562
if (resultSet.NextRow())
2564
enabled = (resultSet.GetInt(0) == 1);
2569
wxSQLite3JournalMode
2570
wxSQLite3Database::SetJournalMode(wxSQLite3JournalMode journalMode, const wxString& database)
2572
wxString mode = ConvertJournalMode(journalMode);
2573
wxString query = wxT("PRAGMA ");
2574
if (!database.IsEmpty())
2579
query += wxT("journal_mode=");
2582
wxSQLite3ResultSet resultSet = ExecuteQuery(query);
2583
if (resultSet.NextRow())
2585
mode = resultSet.GetString(0);
2587
return ConvertJournalMode(mode);
2590
wxSQLite3JournalMode
2591
wxSQLite3Database::GetJournalMode(const wxString& database)
2593
wxString mode = wxT("DELETE");
2594
wxString query = wxT("PRAGMA ");
2595
if (!database.IsEmpty())
2600
query += wxT("journal_mode;");
2601
wxSQLite3ResultSet resultSet = ExecuteQuery(query);
2602
if (resultSet.NextRow())
2604
mode = resultSet.GetString(0);
2606
return ConvertJournalMode(mode);
2610
wxString wxSQLite3Database::ConvertJournalMode(wxSQLite3JournalMode mode)
2612
wxString journalMode;
2613
if (mode == WXSQLITE_JOURNALMODE_DELETE) journalMode = wxT("DELETE");
2614
else if (mode == WXSQLITE_JOURNALMODE_PERSIST) journalMode = wxT("PERSIST");
2615
else if (mode == WXSQLITE_JOURNALMODE_OFF) journalMode = wxT("OFF");
2616
else if (mode == WXSQLITE_JOURNALMODE_TRUNCATE) journalMode = wxT("TRUNCATE");
2617
else if (mode == WXSQLITE_JOURNALMODE_MEMORY) journalMode = wxT("MEMORY");
2618
else if (mode == WXSQLITE_JOURNALMODE_WAL) journalMode = wxT("WAL");
2619
else journalMode = wxT("DELETE");
2624
wxSQLite3JournalMode wxSQLite3Database::ConvertJournalMode(const wxString& mode)
2626
wxSQLite3JournalMode journalMode;
2627
if (mode.IsSameAs(wxT("DELETE"))) journalMode = WXSQLITE_JOURNALMODE_DELETE;
2628
else if (mode.IsSameAs(wxT("PERSIST"))) journalMode = WXSQLITE_JOURNALMODE_PERSIST;
2629
else if (mode.IsSameAs(wxT("OFF"))) journalMode = WXSQLITE_JOURNALMODE_OFF;
2630
else if (mode.IsSameAs(wxT("TRUNCATE"))) journalMode = WXSQLITE_JOURNALMODE_TRUNCATE;
2631
else if (mode.IsSameAs(wxT("MEMORY"))) journalMode = WXSQLITE_JOURNALMODE_MEMORY;
2632
else if (mode.IsSameAs(wxT("WAL"))) journalMode = WXSQLITE_JOURNALMODE_WAL;
2633
else journalMode = WXSQLITE_JOURNALMODE_DELETE;
2637
bool wxSQLite3Database::CheckSyntax(const wxString& sql)
2639
wxCharBuffer strSql = sql.ToUTF8();
2640
const char* localSql = strSql;
2641
return CheckSyntax(localSql);
2644
bool wxSQLite3Database::CheckSyntax(const wxSQLite3StatementBuffer& sql)
2646
return CheckSyntax((const char*) sql);
2649
bool wxSQLite3Database::CheckSyntax(const char* sql)
2651
return sqlite3_complete(sql) != 0;
2654
int wxSQLite3Database::ExecuteUpdate(const wxString& sql)
2656
wxCharBuffer strSql = sql.ToUTF8();
2657
const char* localSql = strSql;
2658
return ExecuteUpdate(localSql);
2661
int wxSQLite3Database::ExecuteUpdate(const wxSQLite3StatementBuffer& sql)
2663
return ExecuteUpdate((const char*) sql);
2666
int wxSQLite3Database::ExecuteUpdate(const char* sql)
2672
int rc = sqlite3_exec((sqlite3*) m_db, sql, 0, 0, &localError);
2674
if (rc == SQLITE_OK)
2676
return sqlite3_changes((sqlite3*) m_db);
2680
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2684
wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const wxString& sql)
2686
wxCharBuffer strSql = sql.ToUTF8();
2687
const char* localSql = strSql;
2688
return ExecuteQuery(localSql);
2691
wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const wxSQLite3StatementBuffer& sql)
2693
return ExecuteQuery((const char*) sql);
2696
wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const char* sql)
2700
sqlite3_stmt* stmt = (sqlite3_stmt*) Prepare(sql);
2702
int rc = sqlite3_step(stmt);
2704
if (rc == SQLITE_DONE) // no rows
2706
return wxSQLite3ResultSet(m_db, stmt, true /* eof */);
2708
else if (rc == SQLITE_ROW) // one or more rows
2710
return wxSQLite3ResultSet(m_db, stmt, false /* eof */);
2714
rc = sqlite3_finalize(stmt);
2715
const char* localError= sqlite3_errmsg((sqlite3*) m_db);
2716
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2720
int wxSQLite3Database::ExecuteScalar(const wxString& sql)
2722
wxCharBuffer strSql = sql.ToUTF8();
2723
const char* localSql = strSql;
2724
return ExecuteScalar(localSql);
2727
int wxSQLite3Database::ExecuteScalar(const wxSQLite3StatementBuffer& sql)
2729
return ExecuteScalar((const char*) sql);
2732
int wxSQLite3Database::ExecuteScalar(const char* sql)
2734
wxSQLite3ResultSet resultSet = ExecuteQuery(sql);
2736
if (resultSet.Eof() || resultSet.GetColumnCount() < 1)
2738
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_QUERY);
2742
resultSet.GetAsString(0).ToLong(&value);
2746
wxSQLite3Table wxSQLite3Database::GetTable(const wxString& sql)
2748
wxCharBuffer strSql = sql.ToUTF8();
2749
const char* localSql = strSql;
2750
return GetTable(localSql);
2753
wxSQLite3Table wxSQLite3Database::GetTable(const wxSQLite3StatementBuffer& sql)
2755
return GetTable((const char*) sql);
2758
wxSQLite3Table wxSQLite3Database::GetTable(const char* sql)
2768
rc = sqlite3_get_table((sqlite3*) m_db, sql, &results, &rows, &cols, &localError);
2770
if (rc == SQLITE_OK)
2772
return wxSQLite3Table(results, rows, cols);
2776
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2780
wxLongLong wxSQLite3Database::GetLastRowId()
2783
return wxLongLong(sqlite3_last_insert_rowid((sqlite3*) m_db));
2786
wxSQLite3Blob wxSQLite3Database::GetReadOnlyBlob(wxLongLong rowId,
2787
const wxString& columnName,
2788
const wxString& tableName,
2789
const wxString& dbName)
2791
return GetBlob(rowId, columnName, tableName, dbName, false);
2794
wxSQLite3Blob wxSQLite3Database::GetWritableBlob(wxLongLong rowId,
2795
const wxString& columnName,
2796
const wxString& tableName,
2797
const wxString& dbName)
2799
return GetBlob(rowId, columnName, tableName, dbName, true);
2802
wxSQLite3Blob wxSQLite3Database::GetBlob(wxLongLong rowId,
2803
const wxString& columnName,
2804
const wxString& tableName,
2805
const wxString& dbName,
2808
#if SQLITE_VERSION_NUMBER >= 3004000
2809
wxCharBuffer strColumnName = columnName.ToUTF8();
2810
const char* localColumnName = strColumnName;
2811
wxCharBuffer strTableName = tableName.ToUTF8();
2812
const char* localTableName = strTableName;
2813
wxCharBuffer strDbName = dbName.ToUTF8();
2814
const char* localDbName = (!dbName.IsEmpty()) ? (const char*) strDbName : (const char*) NULL;
2815
int flags = (writable) ? 1 : 0;
2816
sqlite3_blob* blobHandle;
2818
int rc = sqlite3_blob_open((sqlite3*) m_db, localDbName, localTableName, localColumnName, rowId.GetValue(), flags, &blobHandle);
2819
if (rc != SQLITE_OK)
2821
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2822
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2824
return wxSQLite3Blob(m_db, (void*) blobHandle, writable);
2827
wxUnusedVar(columnName);
2828
wxUnusedVar(tableName);
2829
wxUnusedVar(dbName);
2830
wxUnusedVar(writable);
2831
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
2836
void wxSQLite3Database::Interrupt()
2839
sqlite3_interrupt((sqlite3*) m_db);
2842
void wxSQLite3Database::SetBusyTimeout(int nMillisecs)
2845
m_busyTimeoutMs = nMillisecs;
2846
sqlite3_busy_timeout((sqlite3*) m_db, m_busyTimeoutMs);
2849
wxString wxSQLite3Database::GetVersion()
2851
return wxString::FromUTF8(sqlite3_libversion());
2854
wxString wxSQLite3Database::GetSourceId()
2856
#if SQLITE_VERSION_NUMBER >= 3006018
2857
return wxString::FromUTF8(sqlite3_sourceid());
2859
return wxEmptyString;
2863
bool wxSQLite3Database::CompileOptionUsed(const wxString& optionName)
2865
#if SQLITE_VERSION_NUMBER >= 3006023
2866
wxCharBuffer strOption = optionName.ToUTF8();
2867
const char* localOption = strOption;
2868
return sqlite3_compileoption_used(localOption) == 1;
2874
wxString wxSQLite3Database::GetCompileOptionName(int optionIndex)
2876
#if SQLITE_VERSION_NUMBER >= 3006023
2877
const char* unknownOption = "";
2878
const char* optionName = sqlite3_compileoption_get(optionIndex);
2879
if (optionName == NULL)
2881
optionName = unknownOption;
2883
return wxString::FromUTF8(optionName);
2885
return wxEmptyString;
2889
bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3ScalarFunction& function)
2892
wxCharBuffer strFuncName = funcName.ToUTF8();
2893
const char* localFuncName = strFuncName;
2894
int rc = sqlite3_create_function((sqlite3*) m_db, localFuncName, argCount,
2895
SQLITE_UTF8, &function,
2896
(void (*)(sqlite3_context*,int,sqlite3_value**)) wxSQLite3FunctionContext::ExecScalarFunction, NULL, NULL);
2897
return rc == SQLITE_OK;
2900
bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3AggregateFunction& function)
2903
wxCharBuffer strFuncName = funcName.ToUTF8();
2904
const char* localFuncName = strFuncName;
2905
int rc = sqlite3_create_function((sqlite3*) m_db, localFuncName, argCount,
2906
SQLITE_UTF8, &function,
2908
(void (*)(sqlite3_context*,int,sqlite3_value**)) wxSQLite3FunctionContext::ExecAggregateStep,
2909
(void (*)(sqlite3_context*)) wxSQLite3FunctionContext::ExecAggregateFinalize);
2910
return rc == SQLITE_OK;
2913
bool wxSQLite3Database::SetAuthorizer(wxSQLite3Authorizer& authorizer)
2916
int rc = sqlite3_set_authorizer((sqlite3*) m_db, wxSQLite3FunctionContext::ExecAuthorizer, &authorizer);
2917
return rc == SQLITE_OK;
2920
void wxSQLite3Database::SetCommitHook(wxSQLite3Hook* commitHook)
2925
sqlite3_commit_hook((sqlite3*) m_db, (int(*)(void*)) wxSQLite3FunctionContext::ExecCommitHook, commitHook);
2929
sqlite3_commit_hook((sqlite3*) m_db, (int(*)(void*)) NULL, NULL);
2933
void wxSQLite3Database::SetRollbackHook(wxSQLite3Hook* rollbackHook)
2938
sqlite3_rollback_hook((sqlite3*) m_db, (void(*)(void*)) wxSQLite3FunctionContext::ExecRollbackHook, rollbackHook);
2942
sqlite3_rollback_hook((sqlite3*) m_db, (void(*)(void*)) NULL, NULL);
2946
void wxSQLite3Database::SetUpdateHook(wxSQLite3Hook* updateHook)
2951
sqlite3_update_hook((sqlite3*) m_db, (void(*)(void*,int,const char*,const char*, wxsqlite_int64)) wxSQLite3FunctionContext::ExecUpdateHook, updateHook);
2955
sqlite3_update_hook((sqlite3*) m_db, (void(*)(void*,int,const char*,const char*, wxsqlite_int64)) NULL, NULL);
2959
void wxSQLite3Database::SetWriteAheadLogHook(wxSQLite3Hook* walHook)
2961
#if SQLITE_VERSION_NUMBER >= 3007000
2965
walHook->SetDatabase(this);
2966
sqlite3_wal_hook((sqlite3*) m_db, (int(*)(void *,sqlite3*,const char*,int)) wxSQLite3FunctionContext::ExecWriteAheadLogHook, walHook);
2970
sqlite3_wal_hook((sqlite3*) m_db, (int(*)(void *,sqlite3*,const char*,int)) NULL, NULL);
2973
wxUnusedVar(walHook);
2974
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOWAL);
2978
void wxSQLite3Database::WriteAheadLogCheckpoint(const wxString& database, int mode,
2979
int* logFrameCount, int* ckptFrameCount)
2981
#if SQLITE_VERSION_NUMBER >= 3007000
2983
wxCharBuffer strDatabase = database.ToUTF8();
2984
const char* localDatabase = strDatabase;
2985
#if SQLITE_VERSION_NUMBER >= 3007006
2986
int rc = sqlite3_wal_checkpoint_v2((sqlite3*) m_db, localDatabase, mode, logFrameCount, ckptFrameCount);
2988
int rc = sqlite3_wal_checkpoint((sqlite3*) m_db, localDatabase);
2989
if (logFrameCount != NULL) *logFrameCount = 0;
2990
if (ckptFrameCount != NULL) *ckptFrameCount = 0;
2993
if (rc != SQLITE_OK)
2995
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
2996
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
2999
wxUnusedVar(database);
3000
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOWAL);
3004
void wxSQLite3Database::AutoWriteAheadLogCheckpoint(int frameCount)
3006
#if SQLITE_VERSION_NUMBER >= 3007000
3008
int rc = sqlite3_wal_autocheckpoint((sqlite3*) m_db, frameCount);
3010
if (rc != SQLITE_OK)
3012
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
3013
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
3016
wxUnusedVar(frameCount);
3017
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOWAL);
3021
void wxSQLite3Database::SetCollation(const wxString& collationName, wxSQLite3Collation* collation)
3024
wxCharBuffer strCollationName = collationName.ToUTF8();
3025
const char* localCollationName = strCollationName;
3029
rc = sqlite3_create_collation((sqlite3*) m_db, localCollationName, SQLITE_UTF8, collation, (int(*)(void*,int,const void*,int,const void*)) wxSQLite3Database::ExecComparisonWithCollation);
3033
rc = sqlite3_create_collation((sqlite3*) m_db, localCollationName, SQLITE_UTF8, NULL, (int(*)(void*,int,const void*,int,const void*)) NULL);
3037
void wxSQLite3Database::SetCollationNeededCallback()
3040
int rc = sqlite3_collation_needed((sqlite3*) m_db, this, (void(*)(void*,sqlite3*,int,const char*)) wxSQLite3Database::ExecCollationNeeded);
3041
if (rc != SQLITE_OK)
3043
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
3044
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
3048
void wxSQLite3Database::CheckDatabase()
3052
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NODB);
3056
void* wxSQLite3Database::Prepare(const char* sql)
3063
int rc = sqlite3_prepare_v2((sqlite3*) m_db, sql, -1, &stmt, &tail);
3065
if (rc != SQLITE_OK)
3067
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
3068
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
3075
int wxSQLite3Database::ExecComparisonWithCollation(void* collation,
3076
int len1, const void* text1,
3077
int len2, const void* text2)
3079
wxString locText1 = wxString::FromUTF8((const char*) text1, (size_t) len1);
3080
wxString locText2 = wxString::FromUTF8((const char*) text2, (size_t) len2);
3081
return ((wxSQLite3Collation*) collation)->Compare(locText1, locText2);
3084
void wxSQLite3Database::ExecCollationNeeded(void* db, void*, int, const char* collationName)
3086
wxString locCollation = wxString::FromUTF8((const char*) collationName);
3087
((wxSQLite3Database*) db)->SetNeededCollation(locCollation);
3090
void wxSQLite3Database::GetMetaData(const wxString& databaseName, const wxString& tableName, const wxString& columnName,
3091
wxString* dataType, wxString* collation, bool* notNull, bool* primaryKey, bool* autoIncrement)
3093
#if WXSQLITE3_HAVE_METADATA
3094
wxCharBuffer strDatabaseName = databaseName.ToUTF8();
3095
const char* localDatabaseName = strDatabaseName;
3096
if (databaseName == wxEmptyString) localDatabaseName = NULL;
3097
wxCharBuffer strTableName = tableName.ToUTF8();
3098
const char* localTableName = strTableName;
3099
wxCharBuffer strColumnName = columnName.ToUTF8();
3100
const char* localColumnName = strColumnName;
3101
const char* localDataType;
3102
const char* localCollation;
3104
int localPrimaryKey;
3105
int localAutoIncrement;
3106
int rc = sqlite3_table_column_metadata((sqlite3*) m_db, localDatabaseName, localTableName, localColumnName,
3107
&localDataType, &localCollation, &localNotNull, &localPrimaryKey, &localAutoIncrement);
3109
if (rc != SQLITE_OK)
3111
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
3112
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
3115
if (dataType != NULL) *dataType = wxString::FromUTF8(localDataType);
3116
if (collation != NULL) *collation = wxString::FromUTF8(localCollation);
3118
if (notNull != NULL) *notNull = (localNotNull != 0);
3119
if (primaryKey != NULL) *primaryKey = (localPrimaryKey != 0);
3120
if (autoIncrement != NULL) *autoIncrement = (localAutoIncrement != 0);
3122
wxUnusedVar(databaseName);
3123
wxUnusedVar(tableName);
3124
wxUnusedVar(columnName);
3125
wxUnusedVar(dataType);
3126
wxUnusedVar(collation);
3127
wxUnusedVar(notNull);
3128
wxUnusedVar(primaryKey);
3129
wxUnusedVar(autoIncrement);
3130
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
3134
void wxSQLite3Database::LoadExtension(const wxString& fileName, const wxString& entryPoint)
3136
#if WXSQLITE3_HAVE_LOAD_EXTENSION
3137
wxCharBuffer strFileName = fileName.ToUTF8();
3138
const char* localFileName = strFileName;
3139
wxCharBuffer strEntryPoint = entryPoint.ToUTF8();
3140
const char* localEntryPoint = strEntryPoint;
3142
int rc = sqlite3_load_extension((sqlite3 *) m_db, localFileName, localEntryPoint, NULL);
3143
if (rc != SQLITE_OK)
3145
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
3146
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
3149
wxUnusedVar(fileName);
3150
wxUnusedVar(entryPoint);
3151
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOLOADEXT);
3155
void wxSQLite3Database::EnableLoadExtension(bool enable)
3157
#if WXSQLITE3_HAVE_LOAD_EXTENSION
3158
int onoff = (enable) ? 1 : 0;
3159
int rc = sqlite3_enable_load_extension((sqlite3 *) m_db, onoff);
3160
if (rc != SQLITE_OK)
3162
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
3163
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
3166
wxUnusedVar(enable);
3167
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOLOADEXT);
3171
void wxSQLite3Database::ReKey(const wxString& newKey)
3173
#if WXSQLITE3_HAVE_CODEC
3174
wxCharBuffer strLocalNewKey = newKey.ToUTF8();
3175
const char* localNewKey = strLocalNewKey;
3176
wxMemoryBuffer binaryNewKey;
3177
if (newKey.Length() > 0)
3179
binaryNewKey.AppendData((void*) localNewKey, strlen(localNewKey));
3181
ReKey(binaryNewKey);
3183
wxUnusedVar(newKey);
3184
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOCODEC);
3188
void wxSQLite3Database::ReKey(const wxMemoryBuffer& newKey)
3190
#if WXSQLITE3_HAVE_CODEC
3191
int rc = sqlite3_rekey((sqlite3*) m_db, newKey.GetData(), (int) newKey.GetDataLen());
3192
if (rc != SQLITE_OK)
3194
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
3195
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
3198
wxUnusedVar(newKey);
3199
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOCODEC);
3203
int wxSQLite3Database::GetLimit(wxSQLite3LimitType id)
3206
#if SQLITE_VERSION_NUMBER >= 3005008
3208
if (id >= WXSQLITE_LIMIT_LENGTH && id <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
3210
value = sqlite3_limit((sqlite3 *) m_db, id, -1);
3218
int wxSQLite3Database::SetLimit(wxSQLite3LimitType id, int newValue)
3221
#if SQLITE_VERSION_NUMBER >= 3005008
3223
if (id >= WXSQLITE_LIMIT_LENGTH && id <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
3225
value = sqlite3_limit((sqlite3 *) m_db, id, newValue);
3229
wxUnusedVar(newValue);
3234
static const wxChar* limitCodeString[] =
3235
{ wxT("SQLITE_LIMIT_LENGTH"), wxT("SQLITE_LIMIT_SQL_LENGTH"),
3236
wxT("SQLITE_LIMIT_COLUMN"), wxT("SQLITE_LIMIT_EXPR_DEPTH"),
3237
wxT("SQLITE_LIMIT_COMPOUND_SELECT"), wxT("SQLITE_LIMIT_VDBE_OP"),
3238
wxT("SQLITE_LIMIT_FUNCTION_ARG"), wxT("SQLITE_LIMIT_ATTACHED"),
3239
wxT("SQLITE_LIMIT_LIKE_PATTERN_LENGTH"), wxT("SQLITE_LIMIT_VARIABLE_NUMBER"),
3240
wxT("SQLITE_LIMIT_TRIGGER_DEPTH")
3245
wxString wxSQLite3Database::LimitTypeToString(wxSQLite3LimitType type)
3247
const wxChar* limitString = wxT("Unknown");
3248
if (type >= WXSQLITE_LIMIT_LENGTH && type <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
3250
limitString = limitCodeString[type];
3252
return wxString(limitString);
3256
void wxSQLite3Database::InitializeSQLite()
3258
#if SQLITE_VERSION_NUMBER >= 3006000
3259
int rc = sqlite3_initialize();
3260
if (rc != SQLITE_OK)
3262
throw wxSQLite3Exception(rc, wxERRMSG_INITIALIZE);
3268
void wxSQLite3Database::ShutdownSQLite()
3270
#if SQLITE_VERSION_NUMBER >= 3006000
3271
int rc = sqlite3_shutdown();
3272
if (rc != SQLITE_OK)
3274
throw wxSQLite3Exception(rc, wxERRMSG_SHUTDOWN);
3280
bool wxSQLite3Database::Randomness(int n, wxMemoryBuffer& random)
3283
#if SQLITE_VERSION_NUMBER >= 3005008
3286
void* buffer = random.GetWriteBuf(n);
3287
sqlite3_randomness(n, buffer);
3288
random.UngetWriteBuf(n);
3293
wxUnusedVar(random);
3298
// ----------------------------------------------------------------------------
3299
// wxSQLite3FunctionContext: class providing the function context
3300
// for user defined functions
3301
// ----------------------------------------------------------------------------
3303
int wxSQLite3FunctionContext::GetArgCount()
3308
int wxSQLite3FunctionContext::GetArgType(int argIndex)
3310
if (argIndex >= 0 && argIndex < m_argc)
3312
return sqlite3_value_type((sqlite3_value*) m_argv[argIndex]);
3320
bool wxSQLite3FunctionContext::IsNull(int argIndex)
3322
if (argIndex >= 0 && argIndex < m_argc)
3324
return sqlite3_value_type((sqlite3_value*) m_argv[argIndex]) == SQLITE_NULL;
3332
int wxSQLite3FunctionContext::GetInt(int argIndex, int nullValue)
3334
if (argIndex >= 0 && argIndex < m_argc)
3336
if (!IsNull(argIndex))
3338
return sqlite3_value_int((sqlite3_value*) m_argv[argIndex]);
3351
wxLongLong wxSQLite3FunctionContext::GetInt64(int argIndex, wxLongLong nullValue)
3353
if (argIndex >= 0 && argIndex < m_argc)
3355
if (!IsNull(argIndex))
3357
return wxLongLong(sqlite3_value_int64((sqlite3_value*) m_argv[argIndex]));
3370
double wxSQLite3FunctionContext::GetDouble(int argIndex, double nullValue)
3372
if (argIndex >= 0 && argIndex < m_argc)
3374
if (!IsNull(argIndex))
3376
return sqlite3_value_double((sqlite3_value*) m_argv[argIndex]);
3389
wxString wxSQLite3FunctionContext::GetString(int argIndex, const wxString& nullValue)
3391
if (argIndex >= 0 && argIndex < m_argc)
3393
if (!IsNull(argIndex))
3395
const char* localValue = (const char*) sqlite3_value_text((sqlite3_value*) m_argv[argIndex]);
3396
return wxString::FromUTF8(localValue);
3409
wxMemoryBuffer& wxSQLite3FunctionContext::GetBlob(int argIndex, wxMemoryBuffer& buffer)
3411
if (argIndex >= 0 && argIndex < m_argc)
3413
if (!IsNull(argIndex))
3415
int len = sqlite3_value_bytes((sqlite3_value*) m_argv[argIndex]);
3416
const void* blob = sqlite3_value_blob((sqlite3_value*) m_argv[argIndex]);
3417
buffer.AppendData((void*) blob, (size_t) len);
3423
void wxSQLite3FunctionContext::SetResult(int value)
3425
sqlite3_result_int((sqlite3_context*) m_ctx, value);
3428
void wxSQLite3FunctionContext::SetResult(wxLongLong value)
3430
sqlite3_result_int64((sqlite3_context*) m_ctx, value.GetValue());
3433
void wxSQLite3FunctionContext::SetResult(double value)
3435
sqlite3_result_double((sqlite3_context*) m_ctx, value);
3438
void wxSQLite3FunctionContext::SetResult(const wxString& value)
3440
wxCharBuffer strValue = value.ToUTF8();
3441
const char* localValue = strValue;
3442
sqlite3_result_text((sqlite3_context*) m_ctx, localValue, -1, SQLITE_TRANSIENT);
3445
void wxSQLite3FunctionContext::SetResult(unsigned char* value, int len)
3447
sqlite3_result_blob((sqlite3_context*) m_ctx, value, len, SQLITE_TRANSIENT);
3450
void wxSQLite3FunctionContext::SetResult(const wxMemoryBuffer& buffer)
3452
sqlite3_result_blob((sqlite3_context*) m_ctx, buffer.GetData(), (int) buffer.GetDataLen(), SQLITE_TRANSIENT);
3455
void wxSQLite3FunctionContext::SetResultNull()
3457
sqlite3_result_null((sqlite3_context*) m_ctx);
3460
void wxSQLite3FunctionContext::SetResultZeroBlob(int blobSize)
3462
#if SQLITE_VERSION_NUMBER >= 3004000
3463
sqlite3_result_zeroblob((sqlite3_context*) m_ctx, blobSize);
3467
void wxSQLite3FunctionContext::SetResultArg(int argIndex)
3469
if (argIndex >= 0 && argIndex < m_argc) {
3470
sqlite3_result_value((sqlite3_context*) m_ctx, (sqlite3_value*) m_argv[argIndex]);
3472
sqlite3_result_null((sqlite3_context*) m_ctx);
3476
void wxSQLite3FunctionContext::SetResultError(const wxString& errmsg)
3478
wxCharBuffer strErrmsg = errmsg.ToUTF8();
3479
const char* localErrmsg = strErrmsg;
3480
sqlite3_result_error((sqlite3_context*) m_ctx, localErrmsg, -1);
3483
int wxSQLite3FunctionContext::GetAggregateCount()
3495
void* wxSQLite3FunctionContext::GetAggregateStruct(int len)
3499
return sqlite3_aggregate_context((sqlite3_context*) m_ctx, len);
3508
void wxSQLite3FunctionContext::ExecScalarFunction(void* ctx, int argc, void** argv)
3510
wxSQLite3FunctionContext context(ctx, false, argc, argv);
3511
wxSQLite3ScalarFunction* func = (wxSQLite3ScalarFunction*) sqlite3_user_data((sqlite3_context*) ctx);
3512
func->Execute(context);
3516
void wxSQLite3FunctionContext::ExecAggregateStep(void* ctx, int argc, void** argv)
3518
wxSQLite3FunctionContext context(ctx, true, argc, argv);
3519
wxSQLite3AggregateFunction* func = (wxSQLite3AggregateFunction*) sqlite3_user_data((sqlite3_context*) ctx);
3521
context.m_count = func->m_count;
3522
func->Aggregate(context);
3526
void wxSQLite3FunctionContext::ExecAggregateFinalize(void* ctx)
3528
wxSQLite3FunctionContext context(ctx, true, 0, NULL);
3529
wxSQLite3AggregateFunction* func = (wxSQLite3AggregateFunction*) sqlite3_user_data((sqlite3_context*) ctx);
3530
context.m_count = func->m_count;
3531
func->Finalize(context);
3535
int wxSQLite3FunctionContext::ExecAuthorizer(void* func, int type,
3536
const char* arg1, const char* arg2,
3537
const char* arg3, const char* arg4)
3539
wxString locArg1 = wxString::FromUTF8(arg1);
3540
wxString locArg2 = wxString::FromUTF8(arg2);
3541
wxString locArg3 = wxString::FromUTF8(arg3);
3542
wxString locArg4 = wxString::FromUTF8(arg4);
3543
wxSQLite3Authorizer::wxAuthorizationCode localType = (wxSQLite3Authorizer::wxAuthorizationCode) type;
3544
return (int) ((wxSQLite3Authorizer*) func)->Authorize(localType, locArg1, locArg2, locArg3, locArg3);
3548
int wxSQLite3FunctionContext::ExecCommitHook(void* hook)
3550
return (int) ((wxSQLite3Hook*) hook)->CommitCallback();
3554
void wxSQLite3FunctionContext::ExecRollbackHook(void* hook)
3556
((wxSQLite3Hook*) hook)->RollbackCallback();
3560
void wxSQLite3FunctionContext::ExecUpdateHook(void* hook, int type,
3561
const char* database, const char* table,
3562
wxsqlite_int64 rowid)
3564
wxString locDatabase = wxString::FromUTF8(database);
3565
wxString locTable = wxString::FromUTF8(table);
3566
wxSQLite3Hook::wxUpdateType locType = (wxSQLite3Hook::wxUpdateType) type;
3567
wxLongLong locRowid = rowid;
3568
((wxSQLite3Hook*) hook)->UpdateCallback(locType, locDatabase, locTable, locRowid);
3571
wxSQLite3FunctionContext::wxSQLite3FunctionContext(void* ctx, bool isAggregate, int argc, void** argv)
3572
: m_ctx(ctx), m_isAggregate(isAggregate), m_count(0), m_argc(argc), m_argv(argv)
3577
int wxSQLite3FunctionContext::ExecWriteAheadLogHook(void* hook, void* dbHandle,
3578
const char* database, int numPages)
3580
wxString locDatabase = wxString::FromUTF8(database);
3581
wxUnusedVar(dbHandle);
3582
return (int) ((wxSQLite3Hook*) hook)->WriteAheadLogCallback(locDatabase, numPages);
3585
static const wxChar* authCodeString[] =
3586
{ wxT("SQLITE_COPY"), wxT("SQLITE_CREATE_INDEX"), wxT("SQLITE_CREATE_TABLE"),
3587
wxT("SQLITE_CREATE_TEMP_INDEX"), wxT("SQLITE_CREATE_TEMP_TABLE"), wxT("SQLITE_CREATE_TEMP_TRIGGER"),
3588
wxT("SQLITE_CREATE_TEMP_VIEW"), wxT("SQLITE_CREATE_TRIGGER"), wxT("SQLITE_CREATE_VIEW"),
3589
wxT("SQLITE_DELETE"), wxT("SQLITE_DROP_INDEX"), wxT("SQLITE_DROP_TABLE"),
3590
wxT("SQLITE_DROP_TEMP_INDEX"), wxT("SQLITE_DROP_TEMP_TABLE"), wxT("SQLITE_DROP_TEMP_TRIGGER"),
3591
wxT("SQLITE_DROP_TEMP_VIEW"), wxT("SQLITE_DROP_TRIGGER"), wxT("SQLITE_DROP_VIEW"),
3592
wxT("SQLITE_INSERT"), wxT("SQLITE_PRAGMA"), wxT("SQLITE_READ"),
3593
wxT("SQLITE_SELECT"), wxT("SQLITE_TRANSACTION"), wxT("SQLITE_UPDATE"),
3594
wxT("SQLITE_ATTACH"), wxT("SQLITE_DETACH"), wxT("SQLITE_ALTER_TABLE"),
3595
wxT("SQLITE_REINDEX"), wxT("SQLITE_ANALYZE"), wxT("SQLITE_CREATE_VTABLE"),
3596
wxT("SQLITE_DROP_VTABLE"), wxT("SQLITE_FUNCTION"), wxT("SQLITE_SAVEPOINT")
3601
wxString wxSQLite3Authorizer::AuthorizationCodeToString(wxSQLite3Authorizer::wxAuthorizationCode type)
3603
const wxChar* authString = wxT("Unknown");
3604
if (type >= SQLITE_COPY && type <= SQLITE_MAX_CODE)
3606
authString = authCodeString[type];
3608
return wxString(authString);
3611
// ----------------------------------------------------------------------------
3612
// wxSQLite3Transaction
3613
// ----------------------------------------------------------------------------
3615
wxSQLite3Transaction::wxSQLite3Transaction(wxSQLite3Database* db, wxSQLite3TransactionType transactionType)
3621
m_database->Begin(transactionType);
3625
m_database = NULL; // Flag that transaction is not active
3629
wxSQLite3Transaction::~wxSQLite3Transaction()
3631
if (m_database != NULL)
3633
m_database->Rollback();
3637
void wxSQLite3Transaction::Commit()
3641
m_database->Commit();
3645
m_database->Rollback();
3650
void wxSQLite3Transaction::Rollback()
3654
m_database->Rollback();
3658
m_database->Rollback();
3663
// --- User defined function classes
3667
wxSQLite3RegExpOperator::wxSQLite3RegExpOperator(int flags) : m_flags(flags)
3671
wxSQLite3RegExpOperator::~wxSQLite3RegExpOperator()
3675
void wxSQLite3RegExpOperator::Execute(wxSQLite3FunctionContext& ctx)
3677
int argCount = ctx.GetArgCount();
3680
wxString exprStr = ctx.GetString(0);
3681
wxString textStr = ctx.GetString(1);
3682
if (!m_exprStr.IsSameAs(exprStr))
3684
m_exprStr = exprStr;
3685
m_regEx.Compile(m_exprStr, m_flags);
3687
if (m_regEx.IsValid())
3689
int rc = (m_regEx.Matches(textStr)) ? 1 : 0;
3694
ctx.SetResultError(wxString(_("Regular expression invalid: '"))+exprStr+_T("'."));
3699
ctx.SetResultError(wxString::Format(_("REGEXP called with wrong number of arguments: %d instead of 2."), argCount));
3705
// --- Support for named collections
3707
#if WXSQLITE3_USE_NAMED_COLLECTIONS
3709
// The following code is based on the SQLite test_intarray source code.
3714
/// Definition of the sqlite3_intarray object (internal)
3715
struct sqlite3_intarray
3717
int n; // Number of elements in the array
3718
sqlite3_int64* a; // Contents of the array
3719
void (*xFree)(void*); // Function used to free a[]
3722
// Objects used internally by the virtual table implementation
3723
typedef struct intarray_vtab intarray_vtab;
3724
typedef struct intarray_cursor intarray_cursor;
3726
/// Definition of intarray table object (internal)
3727
struct intarray_vtab
3729
sqlite3_vtab base; // Base class
3730
sqlite3_intarray* pContent; // Content of the integer array
3733
/// Definition of intarray cursor object (internal)
3734
struct intarray_cursor
3736
sqlite3_vtab_cursor base; // Base class
3737
int i; // Current cursor position
3740
// Free an sqlite3_intarray object.
3741
static void intarrayFree(sqlite3_intarray* p)
3743
if (p->a != NULL && p->xFree)
3750
// Table destructor for the intarray module.
3751
static int intarrayDestroy(sqlite3_vtab* p)
3753
intarray_vtab* pVtab = (intarray_vtab*)p;
3754
sqlite3_free(pVtab);
3758
// Table constructor for the intarray module.
3759
static int intarrayCreate(sqlite3* db, // Database where module is created
3760
void* pAux, // clientdata for the module
3761
int /*argc*/, // Number of arguments
3762
const char* const* /*argv*/, // Value for all arguments
3763
sqlite3_vtab** ppVtab, // Write the new virtual table object here
3764
char** /*pzErr*/) // Put error message text here
3766
int rc = SQLITE_NOMEM;
3767
intarray_vtab* pVtab = (intarray_vtab*) sqlite3_malloc(sizeof(intarray_vtab));
3771
memset(pVtab, 0, sizeof(intarray_vtab));
3772
pVtab->pContent = (sqlite3_intarray*)pAux;
3773
rc = sqlite3_declare_vtab(db, "CREATE TABLE x(value INTEGER PRIMARY KEY)");
3775
*ppVtab = (sqlite3_vtab*)pVtab;
3779
// Open a new cursor on the intarray table.
3780
static int intarrayOpen(sqlite3_vtab* /*pVTab*/, sqlite3_vtab_cursor** ppCursor)
3782
int rc = SQLITE_NOMEM;
3783
intarray_cursor* pCur = (intarray_cursor*) sqlite3_malloc(sizeof(intarray_cursor));
3786
memset(pCur, 0, sizeof(intarray_cursor));
3787
*ppCursor = (sqlite3_vtab_cursor *)pCur;
3793
// Close a intarray table cursor.
3794
static int intarrayClose(sqlite3_vtab_cursor* cur)
3796
intarray_cursor* pCur = (intarray_cursor*)cur;
3801
// Retrieve a column of data.
3802
static int intarrayColumn(sqlite3_vtab_cursor* cur, sqlite3_context* ctx, int /*i*/)
3804
intarray_cursor* pCur = (intarray_cursor*)cur;
3805
intarray_vtab* pVtab = (intarray_vtab*)cur->pVtab;
3806
if (pCur->i >= 0 && pCur->i < pVtab->pContent->n)
3808
sqlite3_result_int64(ctx, pVtab->pContent->a[pCur->i]);
3813
// Retrieve the current rowid.
3814
static int intarrayRowid(sqlite3_vtab_cursor* cur, sqlite_int64* pRowid)
3816
intarray_cursor* pCur = (intarray_cursor*)cur;
3821
static int intarrayEof(sqlite3_vtab_cursor* cur)
3823
intarray_cursor* pCur = (intarray_cursor*)cur;
3824
intarray_vtab* pVtab = (intarray_vtab*)cur->pVtab;
3825
return pCur->i >= pVtab->pContent->n;
3828
// Advance the cursor to the next row.
3829
static int intarrayNext(sqlite3_vtab_cursor* cur)
3831
intarray_cursor* pCur = (intarray_cursor*)cur;
3836
// Reset a intarray table cursor.
3837
static int intarrayFilter(sqlite3_vtab_cursor* pVtabCursor,
3838
int /*idxNum*/, const char* /*idxStr*/,
3839
int /*argc*/, sqlite3_value** /*argv*/)
3841
intarray_cursor *pCur = (intarray_cursor *)pVtabCursor;
3846
// Analyse the WHERE condition.
3847
static int intarrayBestIndex(sqlite3_vtab* /*tab*/, sqlite3_index_info* /*pIdxInfo*/)
3852
// Definition of a virtual table module for integer collections
3853
static sqlite3_module intarrayModule =
3856
intarrayCreate, // xCreate - create a new virtual table
3857
intarrayCreate, // xConnect - connect to an existing vtab
3858
intarrayBestIndex, // xBestIndex - find the best query index
3859
intarrayDestroy, // xDisconnect - disconnect a vtab
3860
intarrayDestroy, // xDestroy - destroy a vtab
3861
intarrayOpen, // xOpen - open a cursor
3862
intarrayClose, // xClose - close a cursor
3863
intarrayFilter, // xFilter - configure scan constraints
3864
intarrayNext, // xNext - advance a cursor
3865
intarrayEof, // xEof
3866
intarrayColumn, // xColumn - read data
3867
intarrayRowid, // xRowid - read data
3877
/// Definition of the sqlite3_chararray object (internal)
3878
struct sqlite3_chararray
3880
int n; // Number of elements in the array
3881
char** a; // Contents of the array
3882
void (*xFree)(void*); // Function used to free a[]
3885
// Objects used internally by the virtual table implementation
3886
typedef struct chararray_vtab chararray_vtab;
3887
typedef struct chararray_cursor chararray_cursor;
3889
/// Definition of chararray table object (internal)
3890
struct chararray_vtab
3892
sqlite3_vtab base; // Base class
3893
sqlite3_chararray* pContent; // Content of the char array
3896
/// Definition of chararray cursor object (internal)
3897
struct chararray_cursor
3899
sqlite3_vtab_cursor base; // Base class
3900
int i; // Current cursor position
3903
// Free an sqlite3_chararray object.
3904
static void chararrayFree(sqlite3_chararray* p)
3906
if (p->a != NULL && p->xFree)
3909
for (j = 0; j < p->n; ++j)
3918
// Table destructor for the chararray module.
3919
static int chararrayDestroy(sqlite3_vtab* p)
3921
chararray_vtab* pVtab = (chararray_vtab*)p;
3922
sqlite3_free(pVtab);
3926
// Table constructor for the chararray module.
3927
static int chararrayCreate(sqlite3* db, // Database where module is created
3928
void* pAux, // clientdata for the module
3929
int /*argc*/, // Number of arguments
3930
const char* const* /*argv*/, // Value for all arguments
3931
sqlite3_vtab** ppVtab, // Write the new virtual table object here
3932
char** /*pzErr*/) // Put error message text here
3934
int rc = SQLITE_NOMEM;
3935
chararray_vtab* pVtab = (chararray_vtab*) sqlite3_malloc(sizeof(chararray_vtab));
3939
memset(pVtab, 0, sizeof(chararray_vtab));
3940
pVtab->pContent = (sqlite3_chararray*)pAux;
3941
rc = sqlite3_declare_vtab(db, "CREATE TABLE x(value CHAR PRIMARY KEY)");
3943
*ppVtab = (sqlite3_vtab*)pVtab;
3947
// Open a new cursor on the chararray table.
3948
static int chararrayOpen(sqlite3_vtab* /*pVTab*/, sqlite3_vtab_cursor** ppCursor)
3950
int rc = SQLITE_NOMEM;
3951
chararray_cursor* pCur = (chararray_cursor*) sqlite3_malloc(sizeof(chararray_cursor));
3954
memset(pCur, 0, sizeof(chararray_cursor));
3955
*ppCursor = (sqlite3_vtab_cursor *)pCur;
3961
// Close a chararray table cursor.
3962
static int chararrayClose(sqlite3_vtab_cursor* cur)
3964
chararray_cursor* pCur = (chararray_cursor*)cur;
3969
// Retrieve a column of data.
3970
static int chararrayColumn(sqlite3_vtab_cursor* cur, sqlite3_context* ctx, int /*i*/)
3972
chararray_cursor* pCur = (chararray_cursor*)cur;
3973
chararray_vtab* pVtab = (chararray_vtab*)cur->pVtab;
3974
if (pCur->i >= 0 && pCur->i < pVtab->pContent->n)
3976
sqlite3_result_text(ctx, pVtab->pContent->a[pCur->i], -1, SQLITE_STATIC);
3981
// Retrieve the current rowid.
3982
static int chararrayRowid(sqlite3_vtab_cursor* cur, sqlite_int64* pRowid)
3984
chararray_cursor* pCur = (chararray_cursor*)cur;
3989
static int chararrayEof(sqlite3_vtab_cursor* cur)
3991
chararray_cursor* pCur = (chararray_cursor*)cur;
3992
chararray_vtab* pVtab = (chararray_vtab*)cur->pVtab;
3993
return pCur->i >= pVtab->pContent->n;
3996
// Advance the cursor to the next row.
3997
static int chararrayNext(sqlite3_vtab_cursor* cur)
3999
chararray_cursor* pCur = (chararray_cursor*)cur;
4004
// Reset a chararray table cursor.
4005
static int chararrayFilter(sqlite3_vtab_cursor* pVtabCursor,
4006
int /*idxNum*/, const char* /*idxStr*/,
4007
int /*argc*/, sqlite3_value** /*argv*/)
4009
chararray_cursor *pCur = (chararray_cursor *)pVtabCursor;
4014
// Analyse the WHERE condition.
4015
static int chararrayBestIndex(sqlite3_vtab* /*tab*/, sqlite3_index_info* /*pIdxInfo*/)
4020
// Definition of a virtual table module for string collections
4021
static sqlite3_module chararrayModule =
4024
chararrayCreate, // xCreate - create a new virtual table
4025
chararrayCreate, // xConnect - connect to an existing vtab
4026
chararrayBestIndex, // xBestIndex - find the best query index
4027
chararrayDestroy, // xDisconnect - disconnect a vtab
4028
chararrayDestroy, // xDestroy - destroy a vtab
4029
chararrayOpen, // xOpen - open a cursor
4030
chararrayClose, // xClose - close a cursor
4031
chararrayFilter, // xFilter - configure scan constraints
4032
chararrayNext, // xNext - advance a cursor
4033
chararrayEof, // xEof
4034
chararrayColumn, // xColumn - read data
4035
chararrayRowid, // xRowid - read data
4045
#endif // WXSQLITE3_USE_NAMED_COLLECTIONS
4047
wxSQLite3NamedCollection::wxSQLite3NamedCollection()
4049
m_name = wxEmptyString;
4053
wxSQLite3NamedCollection::wxSQLite3NamedCollection(const wxString& collectionName, void* collectionData)
4055
m_name = collectionName;
4056
m_data = collectionData;
4059
wxSQLite3NamedCollection::wxSQLite3NamedCollection(const wxSQLite3NamedCollection& collection)
4060
: m_name(collection.m_name), m_data(collection.m_data)
4064
wxSQLite3NamedCollection&
4065
wxSQLite3NamedCollection::operator=(const wxSQLite3NamedCollection& collection)
4067
if (this != &collection)
4069
m_name = collection.m_name;
4070
m_data = collection.m_data;
4075
wxSQLite3NamedCollection::~wxSQLite3NamedCollection()
4079
wxSQLite3IntegerCollection::wxSQLite3IntegerCollection()
4080
: wxSQLite3NamedCollection(wxEmptyString, NULL)
4084
wxSQLite3IntegerCollection::wxSQLite3IntegerCollection(const wxSQLite3IntegerCollection& collection)
4085
: wxSQLite3NamedCollection(collection)
4089
wxSQLite3IntegerCollection&
4090
wxSQLite3IntegerCollection::operator=(const wxSQLite3IntegerCollection& collection)
4092
if (this != &collection)
4094
wxSQLite3NamedCollection::operator=(collection);
4099
wxSQLite3IntegerCollection::wxSQLite3IntegerCollection(const wxString& collectionName, void* collectionData)
4100
: wxSQLite3NamedCollection(collectionName, collectionData)
4104
wxSQLite3IntegerCollection::~wxSQLite3IntegerCollection()
4109
wxSQLite3IntegerCollection::Bind(const wxArrayInt& integerCollection)
4111
size_t n = integerCollection.Count();
4112
sqlite3_intarray* pIntArray = (sqlite3_intarray*) m_data;
4115
if (pIntArray->a != NULL && pIntArray->xFree)
4117
pIntArray->xFree(pIntArray->a);
4123
pIntArray->a = (sqlite3_int64*) sqlite3_malloc(sizeof(sqlite3_int64)*n);
4124
pIntArray->xFree = sqlite3_free;
4128
pIntArray->a = NULL;
4129
pIntArray->xFree = NULL;
4133
for (j = 0; j < n; ++j)
4135
pIntArray->a[j] = integerCollection[j];
4140
wxSQLite3IntegerCollection::Bind(int n, int* integerCollection)
4142
sqlite3_intarray* pIntArray = (sqlite3_intarray*) m_data;
4145
if (pIntArray->a != NULL && pIntArray->xFree)
4147
pIntArray->xFree(pIntArray->a);
4153
pIntArray->a = (sqlite3_int64*) sqlite3_malloc(sizeof(sqlite3_int64)*n);
4154
pIntArray->xFree = sqlite3_free;
4158
pIntArray->a = NULL;
4159
pIntArray->xFree = NULL;
4163
for (j = 0; j < n; ++j)
4165
pIntArray->a[j] = integerCollection[j];
4169
wxSQLite3IntegerCollection
4170
wxSQLite3Database::CreateIntegerCollection(const wxString& collectionName)
4172
#if WXSQLITE3_USE_NAMED_COLLECTIONS
4174
wxCharBuffer strCollectionName = collectionName.ToUTF8();
4175
const char* zName = strCollectionName;
4176
sqlite3_intarray* p = (sqlite3_intarray*) sqlite3_malloc( sizeof(*p) );
4179
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMEM);
4184
rc = sqlite3_create_module_v2((sqlite3*)m_db, zName, &intarrayModule, p, (void(*)(void*))intarrayFree);
4185
if (rc == SQLITE_OK)
4187
wxSQLite3StatementBuffer zBuffer;
4188
const char* zSql = zBuffer.Format("CREATE VIRTUAL TABLE temp.%Q USING %Q", zName, zName);
4189
rc = sqlite3_exec((sqlite3*)m_db, zSql, 0, 0, 0);
4191
if (rc != SQLITE_OK)
4193
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
4194
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
4196
return wxSQLite3IntegerCollection(collectionName, p);
4198
wxUnusedVar(collectionName);
4199
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOCOLLECTIONS);
4200
#endif // WXSQLITE3_USE_NAMED_COLLECTIONS
4203
wxSQLite3StringCollection::wxSQLite3StringCollection()
4204
: wxSQLite3NamedCollection(wxEmptyString, NULL)
4208
wxSQLite3StringCollection::wxSQLite3StringCollection(const wxSQLite3StringCollection& collection)
4209
: wxSQLite3NamedCollection(collection)
4213
wxSQLite3StringCollection&
4214
wxSQLite3StringCollection::operator=(const wxSQLite3StringCollection& collection)
4216
if (this != &collection)
4218
wxSQLite3StringCollection::operator=(collection);
4223
wxSQLite3StringCollection::wxSQLite3StringCollection(const wxString& collectionName, void* collectionData)
4224
: wxSQLite3NamedCollection(collectionName, collectionData)
4228
wxSQLite3StringCollection::~wxSQLite3StringCollection()
4233
wxSQLite3StringCollection::Bind(const wxArrayString& stringCollection)
4235
size_t n = stringCollection.Count();
4236
sqlite3_chararray* pCharArray = (sqlite3_chararray*) m_data;
4239
if (pCharArray->a != NULL && pCharArray->xFree)
4241
pCharArray->xFree(pCharArray->a);
4247
pCharArray->a = (char**) sqlite3_malloc(sizeof(char*)*n);
4248
pCharArray->xFree = sqlite3_free;
4252
pCharArray->a = NULL;
4253
pCharArray->xFree = NULL;
4257
for (j = 0; j < n; ++j)
4259
wxCharBuffer strValue = stringCollection[j].ToUTF8();
4260
const char* zValue = strValue;
4261
size_t k = strlen(zValue) + 1;
4262
pCharArray->a[j] = (char*) sqlite3_malloc(sizeof(char)*k);
4263
strcpy(pCharArray->a[j], zValue);
4267
wxSQLite3StringCollection
4268
wxSQLite3Database::CreateStringCollection(const wxString& collectionName)
4270
#if WXSQLITE3_USE_NAMED_COLLECTIONS
4272
wxCharBuffer strCollectionName = collectionName.ToUTF8();
4273
const char* zName = strCollectionName;
4274
sqlite3_chararray* p = (sqlite3_chararray*) sqlite3_malloc( sizeof(*p) );
4277
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMEM);
4282
rc = sqlite3_create_module_v2((sqlite3*)m_db, zName, &chararrayModule, p, (void(*)(void*))chararrayFree);
4283
if (rc == SQLITE_OK)
4285
wxSQLite3StatementBuffer zBuffer;
4286
const char* zSql = zBuffer.Format("CREATE VIRTUAL TABLE temp.%Q USING %Q", zName, zName);
4287
rc = sqlite3_exec((sqlite3*)m_db, zSql, 0, 0, 0);
4289
if (rc != SQLITE_OK)
4291
const char* localError = sqlite3_errmsg((sqlite3*) m_db);
4292
throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
4294
return wxSQLite3StringCollection(collectionName, p);
4296
wxUnusedVar(collectionName);
4297
throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOCOLLECTIONS);
4298
#endif // WXSQLITE3_USE_NAMED_COLLECTIONS