~ubuntu-branches/ubuntu/wily/ginkgocadx/wily-proposed

« back to all changes in this revision

Viewing changes to src/cadxcore/wx/wxsqlite3/wxsqlite3.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Tille
  • Date: 2011-05-02 08:09:26 UTC
  • Revision ID: james.westby@ubuntu.com-20110502080926-bql5wep49c7hg91t
Tags: upstream-2.4.1.1
ImportĀ upstreamĀ versionĀ 2.4.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////////
 
2
// Name:        wxsqlite3.cpp
 
3
// Purpose:     Implementation of wxSQLite3 classes
 
4
// Author:      Ulrich Telle
 
5
// Modified by:
 
6
// Created:     2005-07-06
 
7
// Copyright:   (c) Ulrich Telle
 
8
// Licence:     wxWindows licence
 
9
///////////////////////////////////////////////////////////////////////////////
 
10
 
 
11
/// \file wxsqlite3.cpp Implementation of the wxSQLite3 class
 
12
 
 
13
#if defined(__GNUG__) && !defined(__APPLE__)
 
14
#pragma implementation "wxsqlite3.h"
 
15
#endif
 
16
 
 
17
// For compilers that support precompilation, includes "wx/wx.h".
 
18
#include "wx/wxprec.h"
 
19
 
 
20
#ifdef __BORLANDC__
 
21
#pragma hdrstop
 
22
#endif
 
23
 
 
24
#ifndef WX_PRECOMP
 
25
#include "wx/wx.h"
 
26
#endif
 
27
 
 
28
#include "wx/regex.h"
 
29
 
 
30
#include "wxsqlite3.h"
 
31
#include "wxsqlite3opt.h"
 
32
 
 
33
// Suppress some Visual C++ warnings regarding the default constructor
 
34
// for a C struct used only in SQLite modules
 
35
#ifdef __VISUALC__
 
36
#pragma warning (disable:4510)
 
37
#pragma warning (disable:4610)
 
38
#endif
 
39
 
 
40
#if WXSQLITE3_HAVE_CODEC
 
41
#define SQLITE_HAS_CODEC 1
 
42
#else
 
43
#define SQLITE_HAS_CODEC 0
 
44
#endif
 
45
 
 
46
#include "sqlite/sqlite3.h"
 
47
 
 
48
// Dynamic loading of the SQLite library
 
49
 
 
50
#if wxUSE_DYNAMIC_SQLITE3_LOAD
 
51
 
 
52
#include "wx/dynlib.h"
 
53
 
 
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"
 
58
#undef DYNFUNC
 
59
 
 
60
static wxDynamicLibrary s_dll;
 
61
 
 
62
static void InitSQLite3DLL()
 
63
{
 
64
  if (s_dll.IsLoaded())
 
65
  {
 
66
    return;
 
67
  }
 
68
 
 
69
#ifdef __WIN32__
 
70
  if (! s_dll.Load(wxT("sqlite3")))
 
71
#else
 
72
  if (! s_dll.Load(wxT("libsqlite3")))
 
73
#endif
 
74
  {
 
75
    throw wxSQLite3Exception(-1, wxT("error loading dynamic library"));
 
76
  }
 
77
 
 
78
#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
 
79
  s_##fname = (p##fname) s_dll.GetSymbol(wxT(#fname));\
 
80
  if (! s_##fname)\
 
81
  {\
 
82
    s_dll.Unload();\
 
83
    throw wxSQLite3Exception(-1, wxT("error getting symbol <") wxT(#fname) wxT(">"));\
 
84
  }
 
85
#include "wx/wxsqlite3dyn.h"
 
86
#undef DYNFUNC
 
87
 
 
88
};
 
89
 
 
90
#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
 
91
  rtype fname farg \
 
92
  {\
 
93
    InitSQLite3DLL();\
 
94
    rcode s_##fname farguse;\
 
95
  };
 
96
#include "wx/wxsqlite3dyn.h"
 
97
#undef DYNFUNC
 
98
 
 
99
#endif // wxUSE_DYNAMIC_SQLITE3_LOAD
 
100
 
 
101
// Error messages
 
102
 
 
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");
 
113
 
 
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");
 
125
 
 
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");
 
135
 
 
136
const char* wxERRMSG_SHARED_CACHE  = wxTRANSLATE("Setting SQLite shared cache mode failed");
 
137
 
 
138
const char* wxERRMSG_INITIALIZE    = wxTRANSLATE("Initialization of SQLite failed");
 
139
const char* wxERRMSG_SHUTDOWN      = wxTRANSLATE("Shutdown of SQLite failed");
 
140
 
 
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");
 
144
#else
 
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");
 
154
 
 
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");
 
166
 
 
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");
 
176
 
 
177
const wxChar* wxERRMSG_SHARED_CACHE  = wxTRANSLATE("Setting SQLite shared cache mode failed");
 
178
 
 
179
const wxChar* wxERRMSG_INITIALIZE    = wxTRANSLATE("Initialization of SQLite failed");
 
180
const wxChar* wxERRMSG_SHUTDOWN      = wxTRANSLATE("Shutdown of SQLite failed");
 
181
 
 
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");
 
185
#endif
 
186
 
 
187
// ----------------------------------------------------------------------------
 
188
// inline conversion from wxString to wxLongLong
 
189
// ----------------------------------------------------------------------------
 
190
 
 
191
inline wxLongLong ConvertStringToLongLong(const wxString& str, wxLongLong defValue /*=0*/)
 
192
{
 
193
  size_t n = str.Length();
 
194
  size_t j = 0;
 
195
  wxLongLong value = 0;
 
196
  bool negative = false;
 
197
 
 
198
  if (str[j] == '-')
 
199
  {
 
200
    negative = true;
 
201
    j++;
 
202
  }
 
203
 
 
204
  while (j < n)
 
205
  {
 
206
    if (str[j] < '0' || str[j] > '9')
 
207
    {
 
208
      return defValue;
 
209
    }
 
210
    value *= 10;
 
211
    value += (str[j] - '0');
 
212
    j++;
 
213
  }
 
214
 
 
215
  return negative ? -value : value;
 
216
}
 
217
 
 
218
// ----------------------------------------------------------------------------
 
219
// wxSQLite3Exception: class
 
220
// ----------------------------------------------------------------------------
 
221
 
 
222
wxSQLite3Exception::wxSQLite3Exception(int errorCode, const wxString& errorMsg)
 
223
  : m_errorCode(errorCode)
 
224
{
 
225
  m_errorMessage = ErrorCodeAsString(errorCode) + wxT("[") +
 
226
                   wxString::Format(wxT("%d"), errorCode) + wxT("]: ") +
 
227
                   wxGetTranslation(errorMsg);
 
228
}
 
229
 
 
230
wxSQLite3Exception::wxSQLite3Exception(const wxSQLite3Exception&  e)
 
231
  : m_errorCode(e.m_errorCode), m_errorMessage(e.m_errorMessage)
 
232
{
 
233
}
 
234
 
 
235
const wxString wxSQLite3Exception::ErrorCodeAsString(int errorCode)
 
236
{
 
237
  switch (errorCode)
 
238
  {
 
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");
 
281
#endif
 
282
#if SQLITE_VERSION_NUMBER >= 3005001
 
283
    case SQLITE_IOERR_NOMEM      : return wxT("SQLITE_IOERR_NOMEM");
 
284
#endif
 
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");
 
288
#endif
 
289
#if SQLITE_VERSION_NUMBER >= 3006002
 
290
    case SQLITE_IOERR_LOCK       : return wxT("SQLITE_IOERR_LOCK");
 
291
#endif
 
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");
 
295
#endif
 
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");
 
303
#endif
 
304
 
 
305
    case WXSQLITE_ERROR     : return wxT("WXSQLITE_ERROR");
 
306
    default                 : return wxT("UNKNOWN_ERROR");
 
307
  }
 
308
}
 
309
 
 
310
wxSQLite3Exception::~wxSQLite3Exception()
 
311
{
 
312
}
 
313
 
 
314
// ----------------------------------------------------------------------------
 
315
// wxSQLite3StatementBuffer: class providing a statement buffer
 
316
//                           for use with the SQLite3 vmprintf function
 
317
// ----------------------------------------------------------------------------
 
318
 
 
319
wxSQLite3StatementBuffer::wxSQLite3StatementBuffer()
 
320
{
 
321
  m_buffer = 0;
 
322
}
 
323
 
 
324
wxSQLite3StatementBuffer::~wxSQLite3StatementBuffer()
 
325
{
 
326
  Clear();
 
327
}
 
328
 
 
329
void wxSQLite3StatementBuffer::Clear()
 
330
{
 
331
  if (m_buffer)
 
332
  {
 
333
    sqlite3_free(m_buffer);
 
334
    m_buffer = 0;
 
335
  }
 
336
 
 
337
}
 
338
 
 
339
const char* wxSQLite3StatementBuffer::Format(const char* format, ...)
 
340
{
 
341
  Clear();
 
342
  va_list va;
 
343
  va_start(va, format);
 
344
  m_buffer = sqlite3_vmprintf(format, va);
 
345
  va_end(va);
 
346
  return m_buffer;
 
347
}
 
348
 
 
349
const char* wxSQLite3StatementBuffer::FormatV(const char* format, va_list va)
 
350
{
 
351
  Clear();
 
352
  m_buffer = sqlite3_vmprintf(format, va);
 
353
  return m_buffer;
 
354
}
 
355
 
 
356
// ----------------------------------------------------------------------------
 
357
// wxSQLite3ResultSet: class providing access to the result set of a query
 
358
// ----------------------------------------------------------------------------
 
359
 
 
360
wxSQLite3ResultSet::wxSQLite3ResultSet()
 
361
{
 
362
  m_db = 0;
 
363
  m_stmt = 0;
 
364
  m_eof = true;
 
365
  m_first = true;
 
366
  m_cols = 0;
 
367
  m_ownStmt = false;
 
368
}
 
369
 
 
370
wxSQLite3ResultSet::wxSQLite3ResultSet(const wxSQLite3ResultSet& resultSet)
 
371
{
 
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;
 
380
}
 
381
 
 
382
wxSQLite3ResultSet::wxSQLite3ResultSet(void* db,
 
383
                                       void* stmt,
 
384
                                       bool eof,
 
385
                                       bool first,
 
386
                                       bool ownStmt /*=true*/)
 
387
{
 
388
  m_db = db;
 
389
  m_stmt = stmt;
 
390
  m_eof = eof;
 
391
  m_first = first;
 
392
  m_cols = sqlite3_column_count((sqlite3_stmt*) m_stmt);
 
393
  m_ownStmt = ownStmt;
 
394
}
 
395
 
 
396
wxSQLite3ResultSet::~wxSQLite3ResultSet()
 
397
{
 
398
  try
 
399
  {
 
400
    Finalize();
 
401
  }
 
402
  catch (...)
 
403
  {
 
404
  }
 
405
}
 
406
 
 
407
wxSQLite3ResultSet& wxSQLite3ResultSet::operator=(const wxSQLite3ResultSet& resultSet)
 
408
{
 
409
  if (this != &resultSet)
 
410
  {
 
411
    try
 
412
    {
 
413
      Finalize();
 
414
    }
 
415
    catch (...)
 
416
    {
 
417
    }
 
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;
 
426
  }
 
427
  return *this;
 
428
}
 
429
 
 
430
int wxSQLite3ResultSet::GetColumnCount()
 
431
{
 
432
  CheckStmt();
 
433
  return m_cols;
 
434
}
 
435
 
 
436
wxString wxSQLite3ResultSet::GetAsString(int columnIndex)
 
437
{
 
438
  CheckStmt();
 
439
 
 
440
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
441
  {
 
442
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
443
  }
 
444
 
 
445
  const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
 
446
  return wxString::FromUTF8(localValue);
 
447
}
 
448
 
 
449
wxString wxSQLite3ResultSet::GetAsString(const wxString& columnName)
 
450
{
 
451
  int columnIndex = FindColumnIndex(columnName);
 
452
  const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
 
453
  return wxString::FromUTF8(localValue);
 
454
}
 
455
 
 
456
int wxSQLite3ResultSet::GetInt(int columnIndex, int nullValue /* = 0 */)
 
457
{
 
458
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
459
  {
 
460
    return nullValue;
 
461
  }
 
462
  else
 
463
  {
 
464
    return sqlite3_column_int((sqlite3_stmt*) m_stmt, columnIndex);
 
465
  }
 
466
}
 
467
 
 
468
 
 
469
int wxSQLite3ResultSet::GetInt(const wxString& columnName, int nullValue /* = 0 */)
 
470
{
 
471
  int columnIndex = FindColumnIndex(columnName);
 
472
  return GetInt(columnIndex, nullValue);
 
473
}
 
474
 
 
475
wxLongLong wxSQLite3ResultSet::GetInt64(int columnIndex, wxLongLong nullValue /* = 0 */)
 
476
{
 
477
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
478
  {
 
479
    return nullValue;
 
480
  }
 
481
  else
 
482
  {
 
483
    return wxLongLong(sqlite3_column_int64((sqlite3_stmt*) m_stmt, columnIndex));
 
484
  }
 
485
}
 
486
 
 
487
wxLongLong wxSQLite3ResultSet::GetInt64(const wxString& columnName, wxLongLong nullValue /* = 0 */)
 
488
{
 
489
  int columnIndex = FindColumnIndex(columnName);
 
490
  return GetInt64(columnIndex, nullValue);
 
491
}
 
492
 
 
493
double wxSQLite3ResultSet::GetDouble(int columnIndex, double nullValue /* = 0.0 */)
 
494
{
 
495
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
496
  {
 
497
    return nullValue;
 
498
  }
 
499
  else
 
500
  {
 
501
    return sqlite3_column_double((sqlite3_stmt*) m_stmt, columnIndex);
 
502
  }
 
503
}
 
504
 
 
505
double wxSQLite3ResultSet::GetDouble(const wxString& columnName, double nullValue /* = 0.0 */)
 
506
{
 
507
  int columnIndex = FindColumnIndex(columnName);
 
508
  return GetDouble(columnIndex, nullValue);
 
509
}
 
510
 
 
511
wxString wxSQLite3ResultSet::GetString(int columnIndex, const wxString& nullValue /* = wxEmptyString */)
 
512
{
 
513
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
514
  {
 
515
    return nullValue;
 
516
  }
 
517
  else
 
518
  {
 
519
    const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
 
520
    return wxString::FromUTF8(localValue);
 
521
  }
 
522
}
 
523
 
 
524
wxString wxSQLite3ResultSet::GetString(const wxString& columnName, const wxString& nullValue /* = wxEmptyString */)
 
525
{
 
526
  int columnIndex = FindColumnIndex(columnName);
 
527
  return GetString(columnIndex, nullValue);
 
528
}
 
529
 
 
530
const unsigned char* wxSQLite3ResultSet::GetBlob(int columnIndex, int& len)
 
531
{
 
532
  CheckStmt();
 
533
 
 
534
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
535
  {
 
536
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
537
  }
 
538
 
 
539
  len = sqlite3_column_bytes((sqlite3_stmt*) m_stmt, columnIndex);
 
540
  return (const unsigned char*) sqlite3_column_blob((sqlite3_stmt*) m_stmt, columnIndex);
 
541
}
 
542
 
 
543
const unsigned char* wxSQLite3ResultSet::GetBlob(const wxString& columnName, int& len)
 
544
{
 
545
  int columnIndex = FindColumnIndex(columnName);
 
546
  return GetBlob(columnIndex, len);
 
547
}
 
548
 
 
549
wxMemoryBuffer& wxSQLite3ResultSet::GetBlob(int columnIndex, wxMemoryBuffer& buffer)
 
550
{
 
551
  CheckStmt();
 
552
 
 
553
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
554
  {
 
555
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
556
  }
 
557
 
 
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);
 
561
  return buffer;
 
562
}
 
563
 
 
564
wxMemoryBuffer& wxSQLite3ResultSet::GetBlob(const wxString& columnName, wxMemoryBuffer& buffer)
 
565
{
 
566
  int columnIndex = FindColumnIndex(columnName);
 
567
  return GetBlob(columnIndex, buffer);
 
568
}
 
569
 
 
570
wxDateTime wxSQLite3ResultSet::GetDate(int columnIndex)
 
571
{
 
572
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
573
  {
 
574
    return wxInvalidDateTime;
 
575
  }
 
576
  else
 
577
  {
 
578
    wxDateTime date;
 
579
    const wxChar* result = date.ParseDate(GetString(columnIndex));
 
580
    if (result != NULL)
 
581
    {
 
582
      return date;
 
583
    }
 
584
    else
 
585
    {
 
586
      return wxInvalidDateTime;
 
587
    }
 
588
  }
 
589
}
 
590
 
 
591
wxDateTime wxSQLite3ResultSet::GetDate(const wxString& columnName)
 
592
{
 
593
  int columnIndex = FindColumnIndex(columnName);
 
594
  return GetDate(columnIndex);
 
595
}
 
596
 
 
597
 
 
598
wxDateTime wxSQLite3ResultSet::GetTime(int columnIndex)
 
599
{
 
600
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
601
  {
 
602
    return wxInvalidDateTime;
 
603
  }
 
604
  else
 
605
  {
 
606
    wxDateTime date;
 
607
    const wxChar* result = date.ParseTime(GetString(columnIndex));
 
608
    if (result != NULL)
 
609
    {
 
610
      return date;
 
611
    }
 
612
    else
 
613
    {
 
614
      return wxInvalidDateTime;
 
615
    }
 
616
  }
 
617
}
 
618
 
 
619
wxDateTime wxSQLite3ResultSet::GetTime(const wxString& columnName)
 
620
{
 
621
  int columnIndex = FindColumnIndex(columnName);
 
622
  return GetTime(columnIndex);
 
623
}
 
624
 
 
625
wxDateTime wxSQLite3ResultSet::GetDateTime(int columnIndex)
 
626
{
 
627
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
628
  {
 
629
    return wxInvalidDateTime;
 
630
  }
 
631
  else
 
632
  {
 
633
    wxDateTime date;
 
634
    const wxChar* result = date.ParseDateTime(GetString(columnIndex));
 
635
    if (result != NULL)
 
636
    {
 
637
      date.SetMillisecond(0);
 
638
      return date;
 
639
    }
 
640
    else
 
641
    {
 
642
      return wxInvalidDateTime;
 
643
    }
 
644
  }
 
645
}
 
646
 
 
647
wxDateTime wxSQLite3ResultSet::GetDateTime(const wxString& columnName)
 
648
{
 
649
  int columnIndex = FindColumnIndex(columnName);
 
650
  return GetDateTime(columnIndex);
 
651
}
 
652
 
 
653
wxDateTime wxSQLite3ResultSet::GetTimestamp(int columnIndex)
 
654
{
 
655
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
656
  {
 
657
    return wxInvalidDateTime;
 
658
  }
 
659
  else
 
660
  {
 
661
    wxDateTime date;
 
662
    const wxChar* result = date.ParseDateTime(GetString(columnIndex));
 
663
    if (result != NULL)
 
664
    {
 
665
      return date;
 
666
    }
 
667
    else
 
668
    {
 
669
      return wxInvalidDateTime;
 
670
    }
 
671
  }
 
672
}
 
673
 
 
674
wxDateTime wxSQLite3ResultSet::GetTimestamp(const wxString& columnName)
 
675
{
 
676
  int columnIndex = FindColumnIndex(columnName);
 
677
  return GetTimestamp(columnIndex);
 
678
}
 
679
 
 
680
wxDateTime wxSQLite3ResultSet::GetNumericDateTime(int columnIndex)
 
681
{
 
682
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
683
  {
 
684
    return wxInvalidDateTime;
 
685
  }
 
686
  else
 
687
  {
 
688
    wxLongLong value = GetInt64(columnIndex);
 
689
    return wxDateTime(value);
 
690
  }
 
691
}
 
692
 
 
693
wxDateTime wxSQLite3ResultSet::GetNumericDateTime(const wxString& columnName)
 
694
{
 
695
  int columnIndex = FindColumnIndex(columnName);
 
696
  return GetNumericDateTime(columnIndex);
 
697
}
 
698
 
 
699
wxDateTime wxSQLite3ResultSet::GetJulianDayNumber(int columnIndex)
 
700
{
 
701
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
702
  {
 
703
    return wxInvalidDateTime;
 
704
  }
 
705
  else
 
706
  {
 
707
    double value = GetDouble(columnIndex);
 
708
    return wxDateTime(value);
 
709
  }
 
710
}
 
711
 
 
712
wxDateTime wxSQLite3ResultSet::GetJulianDayNumber(const wxString& columnName)
 
713
{
 
714
  int columnIndex = FindColumnIndex(columnName);
 
715
  return GetJulianDayNumber(columnIndex);
 
716
}
 
717
 
 
718
bool wxSQLite3ResultSet::GetBool(int columnIndex)
 
719
{
 
720
  return GetInt(columnIndex) != 0;
 
721
}
 
722
 
 
723
bool wxSQLite3ResultSet::GetBool(const wxString& columnName)
 
724
{
 
725
  int columnIndex = FindColumnIndex(columnName);
 
726
  return GetBool(columnIndex);
 
727
}
 
728
 
 
729
bool wxSQLite3ResultSet::IsNull(int columnIndex)
 
730
{
 
731
  return (GetColumnType(columnIndex) == SQLITE_NULL);
 
732
}
 
733
 
 
734
bool wxSQLite3ResultSet::IsNull(const wxString& columnName)
 
735
{
 
736
  int columnIndex = FindColumnIndex(columnName);
 
737
  return (GetColumnType(columnIndex) == SQLITE_NULL);
 
738
}
 
739
 
 
740
int wxSQLite3ResultSet::FindColumnIndex(const wxString& columnName)
 
741
{
 
742
  CheckStmt();
 
743
 
 
744
  wxCharBuffer strColumnName = columnName.ToUTF8();
 
745
  const char* localColumnName = strColumnName;
 
746
 
 
747
  if (columnName.Len() > 0)
 
748
  {
 
749
    for (int columnIndex = 0; columnIndex < m_cols; columnIndex++)
 
750
    {
 
751
      const char* temp = sqlite3_column_name((sqlite3_stmt*) m_stmt, columnIndex);
 
752
 
 
753
      if (strcmp(localColumnName, temp) == 0)
 
754
      {
 
755
        return columnIndex;
 
756
      }
 
757
    }
 
758
  }
 
759
 
 
760
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
761
}
 
762
 
 
763
wxString wxSQLite3ResultSet::GetColumnName(int columnIndex)
 
764
{
 
765
  CheckStmt();
 
766
 
 
767
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
768
  {
 
769
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
770
  }
 
771
 
 
772
  const char* localValue = sqlite3_column_name((sqlite3_stmt*) m_stmt, columnIndex);
 
773
  return wxString::FromUTF8(localValue);
 
774
}
 
775
 
 
776
wxString wxSQLite3ResultSet::GetDeclaredColumnType(int columnIndex)
 
777
{
 
778
  CheckStmt();
 
779
 
 
780
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
781
  {
 
782
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
783
  }
 
784
 
 
785
  const char* localValue = sqlite3_column_decltype((sqlite3_stmt*) m_stmt, columnIndex);
 
786
  return wxString::FromUTF8(localValue);
 
787
}
 
788
 
 
789
int wxSQLite3ResultSet::GetColumnType(int columnIndex)
 
790
{
 
791
  CheckStmt();
 
792
 
 
793
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
794
  {
 
795
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
796
  }
 
797
 
 
798
  return sqlite3_column_type((sqlite3_stmt*) m_stmt, columnIndex);
 
799
}
 
800
 
 
801
bool wxSQLite3ResultSet::Eof()
 
802
{
 
803
  CheckStmt();
 
804
  return m_eof;
 
805
}
 
806
 
 
807
bool wxSQLite3ResultSet::NextRow()
 
808
{
 
809
  CheckStmt();
 
810
 
 
811
  int rc;
 
812
  if (m_first)
 
813
  {
 
814
    m_first = false;
 
815
    rc = (m_eof) ? SQLITE_DONE : SQLITE_ROW;
 
816
  }
 
817
  else
 
818
  {
 
819
    rc = sqlite3_step((sqlite3_stmt*) m_stmt);
 
820
  }
 
821
 
 
822
  if (rc == SQLITE_DONE) // no more rows
 
823
  {
 
824
    m_eof = true;
 
825
    return false;
 
826
  }
 
827
  else if (rc == SQLITE_ROW) // more rows
 
828
  {
 
829
    return true;
 
830
  }
 
831
  else
 
832
  {
 
833
    rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
 
834
    m_stmt = 0;
 
835
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
836
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
837
  }
 
838
}
 
839
 
 
840
void wxSQLite3ResultSet::Finalize()
 
841
{
 
842
  if (m_stmt && m_ownStmt)
 
843
  {
 
844
    int rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
 
845
    m_stmt = 0;
 
846
    if (rc != SQLITE_OK)
 
847
    {
 
848
      const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
849
      throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
850
    }
 
851
  }
 
852
}
 
853
 
 
854
wxString wxSQLite3ResultSet::GetSQL()
 
855
{
 
856
  wxString sqlString = wxEmptyString;
 
857
#if SQLITE_VERSION_NUMBER >= 3005003
 
858
  CheckStmt();
 
859
  const char* sqlLocal = sqlite3_sql((sqlite3_stmt*) m_stmt);
 
860
  if (sqlLocal != NULL) sqlString = wxString::FromUTF8(sqlLocal);
 
861
#endif
 
862
  return sqlString;
 
863
}
 
864
 
 
865
bool wxSQLite3ResultSet::IsOk()
 
866
{
 
867
  return (m_db != 0) && (m_stmt != 0);
 
868
}
 
869
 
 
870
void wxSQLite3ResultSet::CheckStmt()
 
871
{
 
872
  if (m_stmt == 0)
 
873
  {
 
874
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSTMT);
 
875
  }
 
876
}
 
877
 
 
878
wxString wxSQLite3ResultSet::GetDatabaseName(int columnIndex)
 
879
{
 
880
#if WXSQLITE3_HAVE_METADATA
 
881
  CheckStmt();
 
882
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
883
  {
 
884
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
885
  }
 
886
 
 
887
  const char* localValue = sqlite3_column_database_name((sqlite3_stmt*) m_stmt, columnIndex);
 
888
  if (localValue != NULL)
 
889
    return wxString::FromUTF8(localValue);
 
890
  else
 
891
    return wxEmptyString;
 
892
#else
 
893
  wxUnusedVar(columnIndex);
 
894
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
 
895
#endif
 
896
}
 
897
 
 
898
wxString wxSQLite3ResultSet::GetTableName(int columnIndex)
 
899
{
 
900
#if WXSQLITE3_HAVE_METADATA
 
901
  CheckStmt();
 
902
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
903
  {
 
904
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
905
  }
 
906
 
 
907
  const char* localValue = sqlite3_column_table_name((sqlite3_stmt*) m_stmt, columnIndex);
 
908
  if (localValue != NULL)
 
909
    return wxString::FromUTF8(localValue);
 
910
  else
 
911
    return wxEmptyString;
 
912
#else
 
913
  wxUnusedVar(columnIndex);
 
914
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
 
915
#endif
 
916
}
 
917
 
 
918
wxString wxSQLite3ResultSet::GetOriginName(int columnIndex)
 
919
{
 
920
#if WXSQLITE3_HAVE_METADATA
 
921
  CheckStmt();
 
922
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
923
  {
 
924
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
925
  }
 
926
 
 
927
  const char* localValue = sqlite3_column_origin_name((sqlite3_stmt*) m_stmt, columnIndex);
 
928
  if (localValue != NULL)
 
929
    return wxString::FromUTF8(localValue);
 
930
  else
 
931
    return wxEmptyString;
 
932
#else
 
933
  wxUnusedVar(columnIndex);
 
934
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
 
935
#endif
 
936
}
 
937
 
 
938
// ----------------------------------------------------------------------------
 
939
// wxSQLite3Table: class holding the complete result set of a query
 
940
// ----------------------------------------------------------------------------
 
941
 
 
942
wxSQLite3Table::wxSQLite3Table()
 
943
{
 
944
  m_results = 0;
 
945
  m_rows = 0;
 
946
  m_cols = 0;
 
947
  m_currentRow = 0;
 
948
}
 
949
 
 
950
wxSQLite3Table::wxSQLite3Table(const wxSQLite3Table& table)
 
951
{
 
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;
 
958
}
 
959
 
 
960
wxSQLite3Table::wxSQLite3Table(char** results, int rows, int cols)
 
961
{
 
962
  m_results = results;
 
963
  m_rows = rows;
 
964
  m_cols = cols;
 
965
  m_currentRow = 0;
 
966
}
 
967
 
 
968
wxSQLite3Table::~wxSQLite3Table()
 
969
{
 
970
  try
 
971
  {
 
972
    Finalize();
 
973
  }
 
974
  catch (...)
 
975
  {
 
976
  }
 
977
}
 
978
 
 
979
wxSQLite3Table& wxSQLite3Table::operator=(const wxSQLite3Table& table)
 
980
{
 
981
  if (this != &table)
 
982
  {
 
983
    try
 
984
    {
 
985
      Finalize();
 
986
    }
 
987
    catch (...)
 
988
    {
 
989
    }
 
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;
 
996
  }
 
997
  return *this;
 
998
}
 
999
 
 
1000
void wxSQLite3Table::Finalize()
 
1001
{
 
1002
  if (m_results)
 
1003
  {
 
1004
    sqlite3_free_table(m_results);
 
1005
    m_results = 0;
 
1006
  }
 
1007
}
 
1008
 
 
1009
int wxSQLite3Table::GetColumnCount()
 
1010
{
 
1011
  CheckResults();
 
1012
  return m_cols;
 
1013
}
 
1014
 
 
1015
int wxSQLite3Table::GetRowCount()
 
1016
{
 
1017
  CheckResults();
 
1018
  return m_rows;
 
1019
}
 
1020
 
 
1021
int wxSQLite3Table::FindColumnIndex(const wxString& columnName)
 
1022
{
 
1023
  CheckResults();
 
1024
 
 
1025
  wxCharBuffer strColumnName = columnName.ToUTF8();
 
1026
  const char* localColumnName = strColumnName;
 
1027
 
 
1028
  if (columnName.Len() > 0)
 
1029
  {
 
1030
    for (int columnIndex = 0; columnIndex < m_cols; columnIndex++)
 
1031
    {
 
1032
      if (strcmp(localColumnName, m_results[columnIndex]) == 0)
 
1033
      {
 
1034
        return columnIndex;
 
1035
      }
 
1036
    }
 
1037
  }
 
1038
 
 
1039
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_NAME);
 
1040
}
 
1041
 
 
1042
wxString wxSQLite3Table::GetAsString(int columnIndex)
 
1043
{
 
1044
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
1045
  {
 
1046
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
1047
  }
 
1048
 
 
1049
  int nIndex = (m_currentRow*m_cols) + m_cols + columnIndex;
 
1050
  const char* localValue = m_results[nIndex];
 
1051
  return wxString::FromUTF8(localValue);
 
1052
}
 
1053
 
 
1054
wxString wxSQLite3Table::GetAsString(const wxString& columnName)
 
1055
{
 
1056
  int index = FindColumnIndex(columnName);
 
1057
  return GetAsString(index);
 
1058
}
 
1059
 
 
1060
int wxSQLite3Table::GetInt(int columnIndex, int nullValue /* = 0 */)
 
1061
{
 
1062
  if (IsNull(columnIndex))
 
1063
  {
 
1064
    return nullValue;
 
1065
  }
 
1066
  else
 
1067
  {
 
1068
    long value = nullValue;
 
1069
    GetAsString(columnIndex).ToLong(&value);
 
1070
    return (int) value;
 
1071
  }
 
1072
}
 
1073
 
 
1074
int wxSQLite3Table::GetInt(const wxString& columnName, int nullValue /* = 0 */)
 
1075
{
 
1076
  if (IsNull(columnName))
 
1077
  {
 
1078
    return nullValue;
 
1079
  }
 
1080
  else
 
1081
  {
 
1082
    long value = nullValue;
 
1083
    GetAsString(columnName).ToLong(&value);
 
1084
    return (int) value;
 
1085
  }
 
1086
}
 
1087
 
 
1088
wxLongLong wxSQLite3Table::GetInt64(int columnIndex, wxLongLong nullValue /* = 0 */)
 
1089
{
 
1090
  if (IsNull(columnIndex))
 
1091
  {
 
1092
    return nullValue;
 
1093
  }
 
1094
  else
 
1095
  {
 
1096
    return ConvertStringToLongLong(GetAsString(columnIndex), nullValue);
 
1097
  }
 
1098
}
 
1099
 
 
1100
wxLongLong wxSQLite3Table::GetInt64(const wxString& columnName, wxLongLong nullValue /* = 0 */)
 
1101
{
 
1102
  if (IsNull(columnName))
 
1103
  {
 
1104
    return nullValue;
 
1105
  }
 
1106
  else
 
1107
  {
 
1108
    return ConvertStringToLongLong(GetAsString(columnName), nullValue);
 
1109
  }
 
1110
}
 
1111
 
 
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.
 
1116
 
 
1117
static double wxSQLite3AtoF(const char *z)
 
1118
{
 
1119
  int sign = 1;
 
1120
  long double v1 = 0.0;
 
1121
  int nSignificant = 0;
 
1122
  while (isspace(*(unsigned char*)z))
 
1123
  {
 
1124
    ++z;
 
1125
  }
 
1126
  if (*z == '-')
 
1127
  {
 
1128
    sign = -1;
 
1129
    ++z;
 
1130
  }
 
1131
  else if (*z == '+')
 
1132
  {
 
1133
    ++z;
 
1134
  }
 
1135
  while (*z == '0')
 
1136
  {
 
1137
    ++z;
 
1138
  }
 
1139
  while (isdigit(*(unsigned char*)z))
 
1140
  {
 
1141
    v1 = v1*10.0 + (*z - '0');
 
1142
    ++z;
 
1143
    ++nSignificant;
 
1144
  }
 
1145
  if (*z == '.')
 
1146
  {
 
1147
    long double divisor = 1.0;
 
1148
    ++z;
 
1149
    if (nSignificant == 0)
 
1150
    {
 
1151
      while (*z == '0')
 
1152
      {
 
1153
        divisor *= 10.0;
 
1154
        ++z;
 
1155
      }
 
1156
    }
 
1157
    while (isdigit(*(unsigned char*)z))
 
1158
    {
 
1159
      if (nSignificant < 18)
 
1160
      {
 
1161
        v1 = v1*10.0 + (*z - '0');
 
1162
        divisor *= 10.0;
 
1163
        ++nSignificant;
 
1164
      }
 
1165
      ++z;
 
1166
    }
 
1167
    v1 /= divisor;
 
1168
  }
 
1169
  if (*z=='e' || *z=='E')
 
1170
  {
 
1171
    int esign = 1;
 
1172
    int eval = 0;
 
1173
    long double scale = 1.0;
 
1174
    ++z;
 
1175
    if (*z == '-')
 
1176
    {
 
1177
      esign = -1;
 
1178
      ++z;
 
1179
    }
 
1180
    else if (*z == '+')
 
1181
    {
 
1182
      ++z;
 
1183
    }
 
1184
    while (isdigit(*(unsigned char*)z))
 
1185
    {
 
1186
      eval = eval*10 + *z - '0';
 
1187
      ++z;
 
1188
    }
 
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; }
 
1193
    if (esign < 0)
 
1194
    {
 
1195
      v1 /= scale;
 
1196
    }
 
1197
    else
 
1198
    {
 
1199
      v1 *= scale;
 
1200
    }
 
1201
  }
 
1202
  return (double) ((sign < 0) ? -v1 : v1);
 
1203
}
 
1204
 
 
1205
double wxSQLite3Table::GetDouble(int columnIndex, double nullValue /* = 0.0 */)
 
1206
{
 
1207
  if (IsNull(columnIndex))
 
1208
  {
 
1209
    return nullValue;
 
1210
  }
 
1211
  else
 
1212
  {
 
1213
    if (columnIndex < 0 || columnIndex > m_cols-1)
 
1214
    {
 
1215
      throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
1216
    }
 
1217
    int nIndex = (m_currentRow*m_cols) + m_cols + columnIndex;
 
1218
    return wxSQLite3AtoF(m_results[nIndex]);
 
1219
  }
 
1220
}
 
1221
 
 
1222
double wxSQLite3Table::GetDouble(const wxString& columnName, double nullValue /* = 0.0 */)
 
1223
{
 
1224
  int index = FindColumnIndex(columnName);
 
1225
  return GetDouble(index, nullValue);
 
1226
}
 
1227
 
 
1228
wxString wxSQLite3Table::GetString(int columnIndex, const wxString& nullValue /* = wxEmptyString */)
 
1229
{
 
1230
  if (IsNull(columnIndex))
 
1231
  {
 
1232
    return nullValue;
 
1233
  }
 
1234
  else
 
1235
  {
 
1236
    return GetAsString(columnIndex);
 
1237
  }
 
1238
}
 
1239
 
 
1240
wxString wxSQLite3Table::GetString(const wxString& columnName, const wxString& nullValue /* = wxEmptyString */)
 
1241
{
 
1242
  if (IsNull(columnName))
 
1243
  {
 
1244
    return nullValue;
 
1245
  }
 
1246
  else
 
1247
  {
 
1248
    return GetAsString(columnName);
 
1249
  }
 
1250
}
 
1251
 
 
1252
wxDateTime wxSQLite3Table::GetDate(int columnIndex)
 
1253
{
 
1254
  wxDateTime date;
 
1255
  const wxChar* result = date.ParseDate(GetString(columnIndex));
 
1256
  if (result != NULL)
 
1257
  {
 
1258
    return date;
 
1259
  }
 
1260
  else
 
1261
  {
 
1262
    return wxInvalidDateTime;
 
1263
  }
 
1264
}
 
1265
 
 
1266
wxDateTime wxSQLite3Table::GetDate(const wxString& columnName)
 
1267
{
 
1268
  int columnIndex = FindColumnIndex(columnName);
 
1269
  return GetDate(columnIndex);
 
1270
}
 
1271
 
 
1272
wxDateTime wxSQLite3Table::GetTime(int columnIndex)
 
1273
{
 
1274
  wxDateTime date;
 
1275
  const wxChar* result = date.ParseTime(GetString(columnIndex));
 
1276
  if (result != NULL)
 
1277
  {
 
1278
    return date;
 
1279
  }
 
1280
  else
 
1281
  {
 
1282
    return wxInvalidDateTime;
 
1283
  }
 
1284
}
 
1285
 
 
1286
wxDateTime wxSQLite3Table::GetTime(const wxString& columnName)
 
1287
{
 
1288
  int columnIndex = FindColumnIndex(columnName);
 
1289
  return GetTime(columnIndex);
 
1290
}
 
1291
 
 
1292
wxDateTime wxSQLite3Table::GetDateTime(int columnIndex)
 
1293
{
 
1294
  wxDateTime date;
 
1295
  const wxChar* result = date.ParseDateTime(GetString(columnIndex));
 
1296
  if (result != NULL)
 
1297
  {
 
1298
    return date;
 
1299
  }
 
1300
  else
 
1301
  {
 
1302
    return wxInvalidDateTime;
 
1303
  }
 
1304
}
 
1305
 
 
1306
wxDateTime wxSQLite3Table::GetDateTime(const wxString& columnName)
 
1307
{
 
1308
  int columnIndex = FindColumnIndex(columnName);
 
1309
  return GetDateTime(columnIndex);
 
1310
}
 
1311
 
 
1312
bool wxSQLite3Table::GetBool(int columnIndex)
 
1313
{
 
1314
  return GetInt(columnIndex) != 0;
 
1315
}
 
1316
 
 
1317
bool wxSQLite3Table::GetBool(const wxString& columnName)
 
1318
{
 
1319
  int columnIndex = FindColumnIndex(columnName);
 
1320
  return GetBool(columnIndex);
 
1321
}
 
1322
 
 
1323
bool wxSQLite3Table::IsNull(int columnIndex)
 
1324
{
 
1325
  CheckResults();
 
1326
 
 
1327
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
1328
  {
 
1329
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
1330
  }
 
1331
 
 
1332
  int index = (m_currentRow*m_cols) + m_cols + columnIndex;
 
1333
  const char* localValue = m_results[index];
 
1334
  return (localValue == 0);
 
1335
}
 
1336
 
 
1337
bool wxSQLite3Table::IsNull(const wxString& columnName)
 
1338
{
 
1339
  int index = FindColumnIndex(columnName);
 
1340
  return IsNull(index);
 
1341
}
 
1342
 
 
1343
wxString wxSQLite3Table::GetColumnName(int columnIndex)
 
1344
{
 
1345
  CheckResults();
 
1346
 
 
1347
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
1348
  {
 
1349
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
1350
  }
 
1351
 
 
1352
  const char* localValue = m_results[columnIndex];
 
1353
  return wxString::FromUTF8(localValue);
 
1354
}
 
1355
 
 
1356
void wxSQLite3Table::SetRow(int row)
 
1357
{
 
1358
  CheckResults();
 
1359
 
 
1360
  if (row < 0 || row > m_rows-1)
 
1361
  {
 
1362
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_ROW);
 
1363
  }
 
1364
 
 
1365
  m_currentRow = row;
 
1366
}
 
1367
 
 
1368
bool wxSQLite3Table::IsOk()
 
1369
{
 
1370
  return (m_results != 0);
 
1371
}
 
1372
 
 
1373
void wxSQLite3Table::CheckResults()
 
1374
{
 
1375
  if (m_results == 0)
 
1376
  {
 
1377
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NORESULT);
 
1378
  }
 
1379
}
 
1380
 
 
1381
// ----------------------------------------------------------------------------
 
1382
// wxSQLite3Statement: class holding a prepared statement
 
1383
// ----------------------------------------------------------------------------
 
1384
 
 
1385
wxSQLite3Statement::wxSQLite3Statement()
 
1386
{
 
1387
  m_db = 0;
 
1388
  m_stmt = 0;
 
1389
  m_hasOwnership = false;
 
1390
}
 
1391
 
 
1392
wxSQLite3Statement::wxSQLite3Statement(const wxSQLite3Statement& statement)
 
1393
{
 
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;
 
1399
}
 
1400
 
 
1401
wxSQLite3Statement::wxSQLite3Statement(void* db, void* stmt)
 
1402
{
 
1403
  m_db = db;
 
1404
  m_stmt = stmt;
 
1405
  m_hasOwnership = true;
 
1406
}
 
1407
 
 
1408
wxSQLite3Statement::~wxSQLite3Statement()
 
1409
{
 
1410
  try
 
1411
  {
 
1412
    Finalize();
 
1413
  }
 
1414
  catch (...)
 
1415
  {
 
1416
  }
 
1417
}
 
1418
 
 
1419
wxSQLite3Statement& wxSQLite3Statement::operator=(const wxSQLite3Statement& statement)
 
1420
{
 
1421
  if (this != &statement)
 
1422
  {
 
1423
    try
 
1424
    {
 
1425
      Finalize();
 
1426
    }
 
1427
    catch (...)
 
1428
    {
 
1429
    }
 
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;
 
1435
  }
 
1436
  return *this;
 
1437
}
 
1438
 
 
1439
int wxSQLite3Statement::ExecuteUpdate()
 
1440
{
 
1441
  CheckDatabase();
 
1442
  CheckStmt();
 
1443
 
 
1444
  const char* localError=0;
 
1445
 
 
1446
  int rc = sqlite3_step((sqlite3_stmt*) m_stmt);
 
1447
 
 
1448
  if (rc == SQLITE_DONE)
 
1449
  {
 
1450
    int rowsChanged = sqlite3_changes((sqlite3*) m_db);
 
1451
 
 
1452
    rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
 
1453
 
 
1454
    if (rc != SQLITE_OK)
 
1455
    {
 
1456
      localError = sqlite3_errmsg((sqlite3*) m_db);
 
1457
      throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
1458
    }
 
1459
 
 
1460
    return rowsChanged;
 
1461
  }
 
1462
  else
 
1463
  {
 
1464
    rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
 
1465
    localError = sqlite3_errmsg((sqlite3*) m_db);
 
1466
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
1467
  }
 
1468
}
 
1469
 
 
1470
wxSQLite3ResultSet wxSQLite3Statement::ExecuteQuery(bool transferStatementOwnership)
 
1471
{
 
1472
  CheckDatabase();
 
1473
  CheckStmt();
 
1474
  if (transferStatementOwnership)
 
1475
  {
 
1476
    if (m_hasOwnership)
 
1477
    {
 
1478
      m_hasOwnership = false;
 
1479
    }
 
1480
    else
 
1481
    {
 
1482
      throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOTOWNED);
 
1483
    }
 
1484
  }
 
1485
 
 
1486
  int rc = sqlite3_step((sqlite3_stmt*) m_stmt);
 
1487
 
 
1488
  if (rc == SQLITE_DONE)  // no more rows
 
1489
  {
 
1490
    return wxSQLite3ResultSet(m_db, m_stmt, true/*eof*/, true/*first*/, transferStatementOwnership);
 
1491
  }
 
1492
  else if (rc == SQLITE_ROW)  // one or more rows
 
1493
  {
 
1494
    return wxSQLite3ResultSet(m_db, m_stmt, false/*eof*/, true/*first*/, transferStatementOwnership);
 
1495
  }
 
1496
  else
 
1497
  {
 
1498
    rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
 
1499
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1500
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
1501
  }
 
1502
}
 
1503
 
 
1504
int wxSQLite3Statement::ExecuteScalar()
 
1505
{
 
1506
  wxSQLite3ResultSet resultSet = ExecuteQuery(true);
 
1507
 
 
1508
  if (resultSet.Eof() || resultSet.GetColumnCount() < 1)
 
1509
  {
 
1510
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_QUERY);
 
1511
  }
 
1512
 
 
1513
  long value = 0;
 
1514
  resultSet.GetAsString(0).ToLong(&value);
 
1515
  return (int) value;
 
1516
}
 
1517
 
 
1518
int wxSQLite3Statement::GetParamCount()
 
1519
{
 
1520
  CheckStmt();
 
1521
  return sqlite3_bind_parameter_count((sqlite3_stmt*) m_stmt);
 
1522
}
 
1523
 
 
1524
int wxSQLite3Statement::GetParamIndex(const wxString& paramName)
 
1525
{
 
1526
  CheckStmt();
 
1527
 
 
1528
  wxCharBuffer strParamName = paramName.ToUTF8();
 
1529
  const char* localParamName = strParamName;
 
1530
 
 
1531
  return sqlite3_bind_parameter_index((sqlite3_stmt*) m_stmt, localParamName);
 
1532
}
 
1533
 
 
1534
wxString wxSQLite3Statement::GetParamName(int paramIndex)
 
1535
{
 
1536
  CheckStmt();
 
1537
  const char* localParamName = sqlite3_bind_parameter_name((sqlite3_stmt*) m_stmt, paramIndex);
 
1538
  return wxString::FromUTF8(localParamName);
 
1539
}
 
1540
 
 
1541
void wxSQLite3Statement::Bind(int paramIndex, const wxString& stringValue)
 
1542
{
 
1543
  CheckStmt();
 
1544
 
 
1545
  wxCharBuffer strStringValue = stringValue.ToUTF8();
 
1546
  const char* localStringValue = strStringValue;
 
1547
 
 
1548
  int rc = sqlite3_bind_text((sqlite3_stmt*) m_stmt, paramIndex, localStringValue, -1, SQLITE_TRANSIENT);
 
1549
 
 
1550
  if (rc != SQLITE_OK)
 
1551
  {
 
1552
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_STR);
 
1553
  }
 
1554
}
 
1555
 
 
1556
void wxSQLite3Statement::Bind(int paramIndex, int intValue)
 
1557
{
 
1558
  CheckStmt();
 
1559
  int rc = sqlite3_bind_int((sqlite3_stmt*) m_stmt, paramIndex, intValue);
 
1560
 
 
1561
  if (rc != SQLITE_OK)
 
1562
  {
 
1563
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_INT);
 
1564
  }
 
1565
}
 
1566
 
 
1567
void wxSQLite3Statement::Bind(int paramIndex, wxLongLong int64Value)
 
1568
{
 
1569
  CheckStmt();
 
1570
  int rc = sqlite3_bind_int64((sqlite3_stmt*) m_stmt, paramIndex, int64Value.GetValue());
 
1571
 
 
1572
  if (rc != SQLITE_OK)
 
1573
  {
 
1574
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_INT64);
 
1575
  }
 
1576
}
 
1577
 
 
1578
void wxSQLite3Statement::Bind(int paramIndex, double doubleValue)
 
1579
{
 
1580
  CheckStmt();
 
1581
  int rc = sqlite3_bind_double((sqlite3_stmt*) m_stmt, paramIndex, doubleValue);
 
1582
 
 
1583
  if (rc != SQLITE_OK)
 
1584
  {
 
1585
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_DBL);
 
1586
  }
 
1587
}
 
1588
 
 
1589
void wxSQLite3Statement::Bind(int paramIndex, const char* charValue)
 
1590
{
 
1591
  CheckStmt();
 
1592
  int rc = sqlite3_bind_text((sqlite3_stmt*) m_stmt, paramIndex, charValue, -1, SQLITE_TRANSIENT);
 
1593
 
 
1594
  if (rc != SQLITE_OK)
 
1595
  {
 
1596
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_STR);
 
1597
  }
 
1598
}
 
1599
 
 
1600
void wxSQLite3Statement::Bind(int paramIndex, const unsigned char* blobValue, int blobLen)
 
1601
{
 
1602
  CheckStmt();
 
1603
  int rc = sqlite3_bind_blob((sqlite3_stmt*) m_stmt, paramIndex,
 
1604
                             (const void*)blobValue, blobLen, SQLITE_TRANSIENT);
 
1605
 
 
1606
  if (rc != SQLITE_OK)
 
1607
  {
 
1608
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_BLOB);
 
1609
  }
 
1610
}
 
1611
 
 
1612
void wxSQLite3Statement::Bind(int paramIndex, const wxMemoryBuffer& blobValue)
 
1613
{
 
1614
  CheckStmt();
 
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);
 
1618
 
 
1619
  if (rc != SQLITE_OK)
 
1620
  {
 
1621
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_BLOB);
 
1622
  }
 
1623
}
 
1624
 
 
1625
void wxSQLite3Statement::BindDate(int paramIndex, const wxDateTime& date)
 
1626
{
 
1627
  if (date.IsValid())
 
1628
  {
 
1629
    Bind(paramIndex,date.FormatISODate());
 
1630
  }
 
1631
  else
 
1632
  {
 
1633
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
 
1634
  }
 
1635
}
 
1636
 
 
1637
void wxSQLite3Statement::BindTime(int paramIndex, const wxDateTime& time)
 
1638
{
 
1639
  if (time.IsValid())
 
1640
  {
 
1641
    Bind(paramIndex,time.FormatISOTime());
 
1642
  }
 
1643
  else
 
1644
  {
 
1645
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
 
1646
  }
 
1647
}
 
1648
 
 
1649
void wxSQLite3Statement::BindDateTime(int paramIndex, const wxDateTime& datetime)
 
1650
{
 
1651
  if (datetime.IsValid())
 
1652
  {
 
1653
    Bind(paramIndex,datetime.Format(wxT("%Y-%m-%d %H:%M:%S")));
 
1654
  }
 
1655
  else
 
1656
  {
 
1657
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
 
1658
  }
 
1659
}
 
1660
 
 
1661
void wxSQLite3Statement::BindTimestamp(int paramIndex, const wxDateTime& timestamp)
 
1662
{
 
1663
  if (timestamp.IsValid())
 
1664
  {
 
1665
    Bind(paramIndex,timestamp.Format(wxT("%Y-%m-%d %H:%M:%S.%l")));
 
1666
  }
 
1667
  else
 
1668
  {
 
1669
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
 
1670
  }
 
1671
}
 
1672
 
 
1673
void wxSQLite3Statement::BindNumericDateTime(int paramIndex, const wxDateTime& datetime)
 
1674
{
 
1675
  if (datetime.IsValid())
 
1676
  {
 
1677
    Bind(paramIndex, datetime.GetValue());
 
1678
  }
 
1679
  else
 
1680
  {
 
1681
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
 
1682
  }
 
1683
}
 
1684
 
 
1685
void wxSQLite3Statement::BindJulianDayNumber(int paramIndex, const wxDateTime& datetime)
 
1686
{
 
1687
  if (datetime.IsValid())
 
1688
  {
 
1689
    Bind(paramIndex, datetime.GetJulianDayNumber());
 
1690
  }
 
1691
  else
 
1692
  {
 
1693
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
 
1694
  }
 
1695
}
 
1696
 
 
1697
void wxSQLite3Statement::BindBool(int paramIndex, bool value)
 
1698
{
 
1699
  Bind(paramIndex, value ? 1 : 0);
 
1700
}
 
1701
 
 
1702
void wxSQLite3Statement::BindNull(int paramIndex)
 
1703
{
 
1704
  CheckStmt();
 
1705
  int rc = sqlite3_bind_null((sqlite3_stmt*) m_stmt, paramIndex);
 
1706
 
 
1707
  if (rc != SQLITE_OK)
 
1708
  {
 
1709
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_NULL);
 
1710
  }
 
1711
}
 
1712
 
 
1713
void wxSQLite3Statement::BindZeroBlob(int paramIndex, int blobSize)
 
1714
{
 
1715
#if SQLITE_VERSION_NUMBER >= 3004000
 
1716
  CheckStmt();
 
1717
  int rc = sqlite3_bind_zeroblob((sqlite3_stmt*) m_stmt, paramIndex, blobSize);
 
1718
  if (rc != SQLITE_OK)
 
1719
  {
 
1720
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_ZEROBLOB);
 
1721
  }
 
1722
#else
 
1723
  wxUnusedVar(paramIndex);
 
1724
  wxUnusedVar(blobSize);
 
1725
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
 
1726
#endif
 
1727
}
 
1728
 
 
1729
void wxSQLite3Statement::ClearBindings()
 
1730
{
 
1731
  CheckStmt();
 
1732
#if 0 // missing in SQLite DLL
 
1733
  int rc = sqlite3_clear_bindings((sqlite3_stmt*) m_stmt);
 
1734
 
 
1735
  if (rc != SQLITE_OK)
 
1736
  {
 
1737
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_CLEAR);
 
1738
  }
 
1739
#else
 
1740
  for (int paramIndex = 1; paramIndex <= GetParamCount(); paramIndex++)
 
1741
  {
 
1742
    BindNull(paramIndex);
 
1743
  }
 
1744
#endif
 
1745
}
 
1746
 
 
1747
wxString wxSQLite3Statement::GetSQL()
 
1748
{
 
1749
  wxString sqlString = wxEmptyString;
 
1750
#if SQLITE_VERSION_NUMBER >= 3005003
 
1751
  CheckStmt();
 
1752
  const char* sqlLocal = sqlite3_sql((sqlite3_stmt*) m_stmt);
 
1753
  if (sqlLocal != NULL) sqlString = wxString::FromUTF8(sqlLocal);
 
1754
#endif
 
1755
  return sqlString;
 
1756
}
 
1757
 
 
1758
void wxSQLite3Statement::Reset()
 
1759
{
 
1760
  if (m_stmt)
 
1761
  {
 
1762
    int rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
 
1763
 
 
1764
    if (rc != SQLITE_OK)
 
1765
    {
 
1766
      const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1767
      throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
1768
    }
 
1769
  }
 
1770
}
 
1771
 
 
1772
bool wxSQLite3Statement::IsReadOnly()
 
1773
{
 
1774
#if SQLITE_VERSION_NUMBER >= 3007004
 
1775
  CheckStmt();
 
1776
  return sqlite3_stmt_readonly((sqlite3_stmt*) m_stmt) != 0;
 
1777
#else
 
1778
  return false;
 
1779
#endif
 
1780
}
 
1781
 
 
1782
void wxSQLite3Statement::Finalize()
 
1783
{
 
1784
  if (m_stmt && m_hasOwnership)
 
1785
  {
 
1786
    int rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
 
1787
    m_stmt = 0;
 
1788
    m_hasOwnership = false;
 
1789
 
 
1790
    if (rc != SQLITE_OK)
 
1791
    {
 
1792
      const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1793
      throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
1794
    }
 
1795
  }
 
1796
}
 
1797
 
 
1798
bool wxSQLite3Statement::IsOk()
 
1799
{
 
1800
  return (m_db != 0) && (m_stmt != 0);
 
1801
}
 
1802
 
 
1803
void wxSQLite3Statement::CheckDatabase()
 
1804
{
 
1805
  if (m_db == 0)
 
1806
  {
 
1807
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NODB);
 
1808
  }
 
1809
}
 
1810
 
 
1811
void wxSQLite3Statement::CheckStmt()
 
1812
{
 
1813
  if (m_stmt == 0)
 
1814
  {
 
1815
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSTMT);
 
1816
  }
 
1817
}
 
1818
 
 
1819
//
 
1820
 
 
1821
wxSQLite3Blob::wxSQLite3Blob()
 
1822
{
 
1823
  m_db   = NULL;
 
1824
  m_blob = NULL;
 
1825
  m_ok   = false;
 
1826
  m_writable = false;
 
1827
}
 
1828
 
 
1829
wxSQLite3Blob::wxSQLite3Blob(const wxSQLite3Blob& blob)
 
1830
{
 
1831
  m_db   = blob.m_db;
 
1832
  m_blob = blob.m_blob;
 
1833
  m_ok   = blob.m_ok;
 
1834
  m_writable = blob.m_writable;
 
1835
}
 
1836
 
 
1837
wxSQLite3Blob& wxSQLite3Blob::operator=(const wxSQLite3Blob& blob)
 
1838
{
 
1839
  if (this != &blob)
 
1840
  {
 
1841
    try
 
1842
    {
 
1843
      Finalize();
 
1844
    }
 
1845
    catch (...)
 
1846
    {
 
1847
    }
 
1848
    m_db   = blob.m_db;
 
1849
    m_blob = blob.m_blob;
 
1850
    m_ok   = blob.m_ok;
 
1851
    m_writable = blob.m_writable;
 
1852
    // only one blob can own the blob handle
 
1853
    const_cast<wxSQLite3Blob&>(blob).m_ok = false;
 
1854
  }
 
1855
  return *this;
 
1856
}
 
1857
 
 
1858
wxSQLite3Blob::wxSQLite3Blob(void* db, void* blobHandle, bool writable)
 
1859
{
 
1860
  m_db   = db;
 
1861
  m_blob = blobHandle;
 
1862
  m_ok   = true;
 
1863
  m_writable = writable;
 
1864
}
 
1865
 
 
1866
wxSQLite3Blob::~wxSQLite3Blob()
 
1867
{
 
1868
  try
 
1869
  {
 
1870
    Finalize();
 
1871
  }
 
1872
  catch (...)
 
1873
  {
 
1874
  }
 
1875
}
 
1876
 
 
1877
wxMemoryBuffer& wxSQLite3Blob::Read(wxMemoryBuffer& blobValue, int length, int offset)
 
1878
{
 
1879
#if SQLITE_VERSION_NUMBER >= 3004000
 
1880
  CheckBlob();
 
1881
  char* localBuffer = (char*) blobValue.GetAppendBuf((size_t) length);
 
1882
  int rc = sqlite3_blob_read((sqlite3_blob*) m_blob, localBuffer, length, offset);
 
1883
 
 
1884
  if (rc != SQLITE_OK)
 
1885
  {
 
1886
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1887
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
1888
  }
 
1889
 
 
1890
  blobValue.UngetAppendBuf((size_t) length);
 
1891
#else
 
1892
  wxUnusedVar(blobValue);
 
1893
  wxUnusedVar(length);
 
1894
  wxUnusedVar(offset);
 
1895
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
 
1896
#endif
 
1897
  return blobValue;
 
1898
}
 
1899
 
 
1900
void wxSQLite3Blob::Write(const wxMemoryBuffer& blobValue, int offset)
 
1901
{
 
1902
#if SQLITE_VERSION_NUMBER >= 3004000
 
1903
  CheckBlob();
 
1904
  if (m_writable)
 
1905
  {
 
1906
    int blobLen = (int) blobValue.GetDataLen();
 
1907
    int rc = sqlite3_blob_write((sqlite3_blob*) m_blob,
 
1908
                                (const void*) blobValue.GetData(), blobLen, offset);
 
1909
 
 
1910
    if (rc != SQLITE_OK)
 
1911
    {
 
1912
      const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1913
      throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
1914
    }
 
1915
  }
 
1916
  else
 
1917
  {
 
1918
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_BLOB);
 
1919
  }
 
1920
#else
 
1921
  wxUnusedVar(blobValue);
 
1922
  wxUnusedVar(offset);
 
1923
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
 
1924
#endif
 
1925
}
 
1926
 
 
1927
bool wxSQLite3Blob::IsOk()
 
1928
{
 
1929
  return m_ok;
 
1930
}
 
1931
 
 
1932
bool wxSQLite3Blob::IsReadOnly()
 
1933
{
 
1934
  return !m_writable;
 
1935
}
 
1936
 
 
1937
int wxSQLite3Blob::GetSize()
 
1938
{
 
1939
#if SQLITE_VERSION_NUMBER >= 3004000
 
1940
  CheckBlob();
 
1941
  return sqlite3_blob_bytes((sqlite3_blob*) m_blob);
 
1942
#else
 
1943
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
 
1944
  return 0;
 
1945
#endif
 
1946
}
 
1947
 
 
1948
void wxSQLite3Blob::Rebind(wxLongLong rowid)
 
1949
{
 
1950
#if SQLITE_VERSION_NUMBER >= 3007004
 
1951
  CheckBlob();
 
1952
  int rc = sqlite3_blob_reopen((sqlite3_blob*) m_blob, rowid.GetValue());
 
1953
  if (rc != SQLITE_OK)
 
1954
  {
 
1955
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1956
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
1957
  }
 
1958
#else
 
1959
  wxUnusedVar(rowid);
 
1960
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOBLOBREBIND);
 
1961
#endif
 
1962
}
 
1963
 
 
1964
void wxSQLite3Blob::Finalize()
 
1965
{
 
1966
#if SQLITE_VERSION_NUMBER >= 3004000
 
1967
  if (m_ok)
 
1968
  {
 
1969
    int rc = sqlite3_blob_close((sqlite3_blob*) m_blob);
 
1970
    m_blob = NULL;
 
1971
    m_ok = false;
 
1972
    if (rc != SQLITE_OK)
 
1973
    {
 
1974
      const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1975
      throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
1976
    }
 
1977
  }
 
1978
#else
 
1979
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
 
1980
#endif
 
1981
}
 
1982
 
 
1983
void wxSQLite3Blob::CheckBlob()
 
1984
{
 
1985
  if (!m_ok)
 
1986
  {
 
1987
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_BLOB);
 
1988
  }
 
1989
}
 
1990
 
 
1991
// ----------------------------------------------------------------------------
 
1992
// wxSQLite3Database: class holding a SQLite3 database object
 
1993
// ----------------------------------------------------------------------------
 
1994
 
 
1995
bool wxSQLite3Database::ms_sharedCacheEnabled = false;
 
1996
 
 
1997
void
 
1998
wxSQLite3Database::SetSharedCache(bool enable)
 
1999
{
 
2000
  int flag = (enable) ? 1 : 0;
 
2001
  int rc = sqlite3_enable_shared_cache(flag);
 
2002
  if (rc != SQLITE_OK)
 
2003
  {
 
2004
    throw wxSQLite3Exception(rc, wxERRMSG_SHARED_CACHE);
 
2005
  }
 
2006
  ms_sharedCacheEnabled = enable;
 
2007
}
 
2008
 
 
2009
#if WXSQLITE3_HAVE_CODEC
 
2010
bool wxSQLite3Database::ms_hasEncryptionSupport = true;
 
2011
#else
 
2012
bool wxSQLite3Database::ms_hasEncryptionSupport = false;
 
2013
#endif
 
2014
 
 
2015
#if WXSQLITE3_HAVE_METADATA
 
2016
bool wxSQLite3Database::ms_hasMetaDataSupport = true;
 
2017
#else
 
2018
bool wxSQLite3Database::ms_hasMetaDataSupport = false;
 
2019
#endif
 
2020
 
 
2021
#if WXSQLITE3_HAVE_LOAD_EXTENSION
 
2022
bool wxSQLite3Database::ms_hasLoadExtSupport = true;
 
2023
#else
 
2024
bool wxSQLite3Database::ms_hasLoadExtSupport = false;
 
2025
#endif
 
2026
 
 
2027
#if WXSQLITE3_USE_NAMED_COLLECTIONS
 
2028
bool wxSQLite3Database::ms_hasNamedCollectionSupport = true;
 
2029
#else
 
2030
bool wxSQLite3Database::ms_hasNamedCollectionSupport = false;
 
2031
#endif
 
2032
 
 
2033
#if SQLITE_VERSION_NUMBER >= 3004000
 
2034
bool wxSQLite3Database::ms_hasIncrementalBlobSupport = true;
 
2035
#else
 
2036
bool wxSQLite3Database::ms_hasIncrementalBlobSupport = false;
 
2037
#endif
 
2038
 
 
2039
#if SQLITE_VERSION_NUMBER >= 3006008
 
2040
bool wxSQLite3Database::ms_hasSavepointSupport = true;
 
2041
#else
 
2042
bool wxSQLite3Database::ms_hasSavepointSupport = false;
 
2043
#endif
 
2044
 
 
2045
#if SQLITE_VERSION_NUMBER >= 3006011
 
2046
bool wxSQLite3Database::ms_hasBackupSupport = true;
 
2047
#else
 
2048
bool wxSQLite3Database::ms_hasBackupSupport = false;
 
2049
#endif
 
2050
 
 
2051
#if SQLITE_VERSION_NUMBER >= 3007000
 
2052
bool wxSQLite3Database::ms_hasWriteAheadLogSupport = true;
 
2053
#else
 
2054
bool wxSQLite3Database::ms_hasWriteAheadLogSupport = false;
 
2055
#endif
 
2056
 
 
2057
bool
 
2058
wxSQLite3Database::HasEncryptionSupport()
 
2059
{
 
2060
  return ms_hasEncryptionSupport;
 
2061
}
 
2062
 
 
2063
bool
 
2064
wxSQLite3Database::HasMetaDataSupport()
 
2065
{
 
2066
  return ms_hasMetaDataSupport;
 
2067
}
 
2068
 
 
2069
bool
 
2070
wxSQLite3Database::HasLoadExtSupport()
 
2071
{
 
2072
  return ms_hasLoadExtSupport;
 
2073
}
 
2074
 
 
2075
bool
 
2076
wxSQLite3Database::HasNamedCollectionSupport()
 
2077
{
 
2078
  return ms_hasNamedCollectionSupport;
 
2079
}
 
2080
 
 
2081
bool
 
2082
wxSQLite3Database::HasIncrementalBlobSupport()
 
2083
{
 
2084
  return ms_hasIncrementalBlobSupport;
 
2085
}
 
2086
 
 
2087
bool
 
2088
wxSQLite3Database::HasSavepointSupport()
 
2089
{
 
2090
  return ms_hasSavepointSupport;
 
2091
}
 
2092
 
 
2093
bool
 
2094
wxSQLite3Database::HasBackupSupport()
 
2095
{
 
2096
  return ms_hasBackupSupport;
 
2097
}
 
2098
 
 
2099
bool
 
2100
wxSQLite3Database::HasWriteAheadLogSupport()
 
2101
{
 
2102
  return ms_hasWriteAheadLogSupport;
 
2103
}
 
2104
 
 
2105
wxSQLite3Database::wxSQLite3Database()
 
2106
{
 
2107
  m_db = 0;
 
2108
  m_busyTimeoutMs = 60000; // 60 seconds
 
2109
  m_isEncrypted = false;
 
2110
}
 
2111
 
 
2112
wxSQLite3Database::wxSQLite3Database(const wxSQLite3Database& db)
 
2113
{
 
2114
  m_db = db.m_db;
 
2115
  m_busyTimeoutMs = 60000; // 60 seconds
 
2116
  m_isEncrypted = false;
 
2117
}
 
2118
 
 
2119
wxSQLite3Database::~wxSQLite3Database()
 
2120
{
 
2121
  Close();
 
2122
}
 
2123
 
 
2124
wxSQLite3Database& wxSQLite3Database::operator=(const wxSQLite3Database& db)
 
2125
{
 
2126
  if (this != &db)
 
2127
  {
 
2128
    if (m_db == 0)
 
2129
    {
 
2130
      m_db = db.m_db;
 
2131
      m_busyTimeoutMs = 60000; // 60 seconds
 
2132
      m_isEncrypted = db.m_isEncrypted;
 
2133
    }
 
2134
    else
 
2135
    {
 
2136
      throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_DBASSIGN_FAILED);
 
2137
    }
 
2138
  }
 
2139
  return *this;
 
2140
}
 
2141
 
 
2142
void wxSQLite3Database::Open(const wxString& fileName, const wxString& key, int flags)
 
2143
{
 
2144
  wxCharBuffer strLocalKey = key.ToUTF8();
 
2145
  const char* localKey = strLocalKey;
 
2146
  wxMemoryBuffer binaryKey;
 
2147
  if (key.Length() > 0)
 
2148
  {
 
2149
    binaryKey.AppendData((void*) localKey, strlen(localKey));
 
2150
  }
 
2151
  Open(fileName, binaryKey, flags);
 
2152
}
 
2153
 
 
2154
void wxSQLite3Database::Open(const wxString& fileName, const wxMemoryBuffer& key, int flags)
 
2155
{
 
2156
  wxCharBuffer strFileName = fileName.ToUTF8();
 
2157
  const char* localFileName = strFileName;
 
2158
 
 
2159
  int rc = sqlite3_open_v2((const char*) localFileName, (sqlite3**) &m_db, flags, NULL);
 
2160
 
 
2161
  if (rc != SQLITE_OK)
 
2162
  {
 
2163
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2164
    Close();
 
2165
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2166
  }
 
2167
 
 
2168
  rc = sqlite3_extended_result_codes((sqlite3*) m_db, 1);
 
2169
  if (rc != SQLITE_OK)
 
2170
  {
 
2171
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2172
    Close();
 
2173
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2174
  }
 
2175
 
 
2176
#if WXSQLITE3_HAVE_CODEC
 
2177
  if (key.GetDataLen() > 0)
 
2178
  {
 
2179
    rc = sqlite3_key((sqlite3*) m_db, key.GetData(), (int) key.GetDataLen());
 
2180
    if (rc != SQLITE_OK)
 
2181
    {
 
2182
      const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2183
      Close();
 
2184
      throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2185
    }
 
2186
    m_isEncrypted = true;
 
2187
  }
 
2188
#else
 
2189
  wxUnusedVar(key);
 
2190
#endif
 
2191
 
 
2192
  SetBusyTimeout(m_busyTimeoutMs);
 
2193
}
 
2194
 
 
2195
bool wxSQLite3Database::IsOpen() const
 
2196
{
 
2197
  return (m_db != NULL);
 
2198
}
 
2199
 
 
2200
void wxSQLite3Database::Close()
 
2201
{
 
2202
  if (m_db)
 
2203
  {
 
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
 
2207
#if 0
 
2208
    // Finalize all unfinalized prepared statements
 
2209
    sqlite3_stmt *pStmt;
 
2210
    while( (pStmt = sqlite3_next_stmt((sqlite3*) m_db, 0))!=0 )
 
2211
    {
 
2212
      sqlite3_finalize(pStmt);
 
2213
    }
 
2214
#endif
 
2215
#endif
 
2216
    sqlite3_close((sqlite3*) m_db);
 
2217
    m_db = 0;
 
2218
    m_isEncrypted = false;
 
2219
  }
 
2220
}
 
2221
 
 
2222
void wxSQLite3Database::Backup(const wxString& targetFileName, const wxString& key, const wxString& sourceDatabaseName)
 
2223
{
 
2224
  wxCharBuffer strLocalKey = key.ToUTF8();
 
2225
  const char* localKey = strLocalKey;
 
2226
  wxMemoryBuffer binaryKey;
 
2227
  if (key.Length() > 0)
 
2228
  {
 
2229
    binaryKey.AppendData((void*) localKey, strlen(localKey));
 
2230
  }
 
2231
  Backup(targetFileName, binaryKey, sourceDatabaseName);
 
2232
}
 
2233
 
 
2234
void wxSQLite3Database::Backup(const wxString& targetFileName, const wxMemoryBuffer& key, const wxString& sourceDatabaseName)
 
2235
{
 
2236
#if SQLITE_VERSION_NUMBER >= 3006011
 
2237
  CheckDatabase();
 
2238
 
 
2239
  wxCharBuffer strFileName = targetFileName.ToUTF8();
 
2240
  const char* localTargetFileName = strFileName;
 
2241
  wxCharBuffer strDatabaseName = sourceDatabaseName.ToUTF8();
 
2242
  const char* localSourceDatabaseName = strDatabaseName;
 
2243
 
 
2244
  sqlite3* pDest;
 
2245
  sqlite3_backup* pBackup;
 
2246
  int rc;
 
2247
  rc = sqlite3_open(localTargetFileName, &pDest);
 
2248
  if (rc != SQLITE_OK)
 
2249
  {
 
2250
    sqlite3_close(pDest);
 
2251
    throw wxSQLite3Exception(rc, wxERRMSG_DBOPEN_FAILED);
 
2252
  }
 
2253
#if WXSQLITE3_HAVE_CODEC
 
2254
  if (key.GetDataLen() > 0)
 
2255
  {
 
2256
    rc = sqlite3_key(pDest, key.GetData(), (int) key.GetDataLen());
 
2257
    if (rc != SQLITE_OK)
 
2258
    {
 
2259
      const char* localError = sqlite3_errmsg((sqlite3*) pDest);
 
2260
      sqlite3_close(pDest);
 
2261
      throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2262
    }
 
2263
  }
 
2264
#else
 
2265
  wxUnusedVar(key);
 
2266
#endif
 
2267
 
 
2268
  pBackup = sqlite3_backup_init(pDest, "main", (sqlite3*) m_db, localSourceDatabaseName);
 
2269
  if (pBackup == 0)
 
2270
  {
 
2271
    const char* localError = sqlite3_errmsg(pDest);
 
2272
    sqlite3_close(pDest);
 
2273
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2274
  }
 
2275
 
 
2276
  do
 
2277
  {
 
2278
    rc = sqlite3_backup_step(pBackup, 10);
 
2279
#if 0
 
2280
    xProgress(sqlite3_backup_remaining(pBackup),
 
2281
              sqlite3_backup_pagecount(pBackup));
 
2282
#endif
 
2283
    if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED)
 
2284
    {
 
2285
      sqlite3_sleep(250);
 
2286
    }
 
2287
  }
 
2288
  while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED);
 
2289
 
 
2290
  sqlite3_backup_finish(pBackup);
 
2291
  if (rc == SQLITE_DONE)
 
2292
  {
 
2293
    sqlite3_close(pDest);
 
2294
  }
 
2295
  else
 
2296
  {
 
2297
    const char* localError = sqlite3_errmsg(pDest);
 
2298
    sqlite3_close(pDest);
 
2299
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2300
  }
 
2301
#else
 
2302
  wxUnusedVar(targetFileName);
 
2303
  wxUnusedVar(sourceDatabaseName);
 
2304
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOBACKUP);
 
2305
#endif
 
2306
}
 
2307
 
 
2308
void wxSQLite3Database::Restore(const wxString& sourceFileName, const wxString& key, const wxString& targetDatabaseName)
 
2309
{
 
2310
  wxCharBuffer strLocalKey = key.ToUTF8();
 
2311
  const char* localKey = strLocalKey;
 
2312
  wxMemoryBuffer binaryKey;
 
2313
  if (key.Length() > 0)
 
2314
  {
 
2315
    binaryKey.AppendData((void*) localKey, strlen(localKey));
 
2316
  }
 
2317
  Restore(sourceFileName, binaryKey, targetDatabaseName);
 
2318
}
 
2319
 
 
2320
void wxSQLite3Database::Restore(const wxString& sourceFileName, const wxMemoryBuffer& key, const wxString& targetDatabaseName)
 
2321
{
 
2322
#if SQLITE_VERSION_NUMBER >= 3006011
 
2323
  CheckDatabase();
 
2324
 
 
2325
  wxCharBuffer strFileName = sourceFileName.ToUTF8();
 
2326
  const char* localSourceFileName = strFileName;
 
2327
  wxCharBuffer strDatabaseName = targetDatabaseName.ToUTF8();
 
2328
  const char* localTargetDatabaseName = strDatabaseName;
 
2329
 
 
2330
  sqlite3* pSrc;
 
2331
  sqlite3_backup* pBackup;
 
2332
  int rc;
 
2333
  int nTimeout = 0;
 
2334
 
 
2335
  rc = sqlite3_open(localSourceFileName, &pSrc);
 
2336
  if (rc != SQLITE_OK)
 
2337
  {
 
2338
    sqlite3_close(pSrc);
 
2339
    throw wxSQLite3Exception(rc, wxERRMSG_DBOPEN_FAILED);
 
2340
  }
 
2341
#if WXSQLITE3_HAVE_CODEC
 
2342
  if (key.GetDataLen() > 0)
 
2343
  {
 
2344
    rc = sqlite3_key(pSrc, key.GetData(), (int) key.GetDataLen());
 
2345
    if (rc != SQLITE_OK)
 
2346
    {
 
2347
      const char* localError = sqlite3_errmsg((sqlite3*) pSrc);
 
2348
      sqlite3_close(pSrc);
 
2349
      throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2350
    }
 
2351
  }
 
2352
#else
 
2353
  wxUnusedVar(key);
 
2354
#endif
 
2355
 
 
2356
  pBackup = sqlite3_backup_init((sqlite3*) m_db, localTargetDatabaseName, pSrc, "main");
 
2357
  if (pBackup == 0)
 
2358
  {
 
2359
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2360
    sqlite3_close(pSrc);
 
2361
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2362
  }
 
2363
  while ((rc = sqlite3_backup_step(pBackup, 100)) == SQLITE_OK || rc == SQLITE_BUSY)
 
2364
  {
 
2365
    if (rc == SQLITE_BUSY)
 
2366
    {
 
2367
      if (nTimeout++ >= 3) break;
 
2368
      sqlite3_sleep(100);
 
2369
    }
 
2370
  }
 
2371
  sqlite3_backup_finish(pBackup);
 
2372
  if (rc == SQLITE_DONE)
 
2373
  {
 
2374
    sqlite3_close(pSrc);
 
2375
  }
 
2376
  else if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED)
 
2377
  {
 
2378
    sqlite3_close(pSrc);
 
2379
    throw wxSQLite3Exception(rc, wxERRMSG_SOURCEDB_BUSY);
 
2380
  }
 
2381
  else
 
2382
  {
 
2383
    const char* localError = sqlite3_errmsg(pSrc);
 
2384
    sqlite3_close(pSrc);
 
2385
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2386
  }
 
2387
#else
 
2388
  wxUnusedVar(sourceFileName);
 
2389
  wxUnusedVar(targetDatabaseName);
 
2390
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOBACKUP);
 
2391
#endif
 
2392
}
 
2393
 
 
2394
void wxSQLite3Database::Begin(wxSQLite3TransactionType transactionType)
 
2395
{
 
2396
  wxString sql;
 
2397
  switch (transactionType)
 
2398
  {
 
2399
    case WXSQLITE_TRANSACTION_DEFERRED:
 
2400
      sql << wxT("begin deferred transaction");
 
2401
      break;
 
2402
    case WXSQLITE_TRANSACTION_IMMEDIATE:
 
2403
      sql << wxT("begin immediate transaction");
 
2404
      break;
 
2405
    case WXSQLITE_TRANSACTION_EXCLUSIVE:
 
2406
      sql << wxT("begin exclusive transaction");
 
2407
      break;
 
2408
    default:
 
2409
      sql << wxT("begin transaction");
 
2410
      break;
 
2411
  }
 
2412
  ExecuteUpdate(sql);
 
2413
}
 
2414
 
 
2415
void wxSQLite3Database::Commit()
 
2416
{
 
2417
  ExecuteUpdate("commit transaction");
 
2418
}
 
2419
 
 
2420
void wxSQLite3Database::Rollback(const wxString& savepointName)
 
2421
{
 
2422
#if SQLITE_VERSION_NUMBER >= 3006008
 
2423
  if (savepointName.IsEmpty())
 
2424
  {
 
2425
#endif
 
2426
    ExecuteUpdate("rollback transaction");
 
2427
#if SQLITE_VERSION_NUMBER >= 3006008
 
2428
  }
 
2429
  else
 
2430
  {
 
2431
    ExecuteUpdate(wxString(wxT("rollback transaction to savepoint "))+savepointName);
 
2432
  }
 
2433
#endif
 
2434
}
 
2435
 
 
2436
bool wxSQLite3Database::GetAutoCommit()
 
2437
{
 
2438
  CheckDatabase();
 
2439
  return sqlite3_get_autocommit((sqlite3*) m_db) != 0;
 
2440
}
 
2441
 
 
2442
void wxSQLite3Database::Savepoint(const wxString& savepointName)
 
2443
{
 
2444
#if SQLITE_VERSION_NUMBER >= 3006008
 
2445
  ExecuteUpdate(wxString(wxT("savepoint "))+savepointName);
 
2446
#else
 
2447
  wxUnusedVar(savepointName);
 
2448
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSAVEPOINT);
 
2449
#endif
 
2450
}
 
2451
 
 
2452
void wxSQLite3Database::ReleaseSavepoint(const wxString& savepointName)
 
2453
{
 
2454
#if SQLITE_VERSION_NUMBER >= 3006008
 
2455
  ExecuteUpdate(wxString(wxT("release savepoint "))+savepointName);
 
2456
#else
 
2457
  wxUnusedVar(savepointName);
 
2458
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSAVEPOINT);
 
2459
#endif
 
2460
}
 
2461
 
 
2462
wxSQLite3Statement wxSQLite3Database::PrepareStatement(const wxString& sql)
 
2463
{
 
2464
  wxCharBuffer strSql = sql.ToUTF8();
 
2465
  const char* localSql = strSql;
 
2466
  return PrepareStatement(localSql);
 
2467
}
 
2468
 
 
2469
wxSQLite3Statement wxSQLite3Database::PrepareStatement(const wxSQLite3StatementBuffer& sql)
 
2470
{
 
2471
  return PrepareStatement((const char*) sql);
 
2472
}
 
2473
 
 
2474
wxSQLite3Statement wxSQLite3Database::PrepareStatement(const char* sql)
 
2475
{
 
2476
  CheckDatabase();
 
2477
  sqlite3_stmt* stmt = (sqlite3_stmt*) Prepare(sql);
 
2478
  return wxSQLite3Statement(m_db, stmt);
 
2479
}
 
2480
 
 
2481
bool wxSQLite3Database::TableExists(const wxString& tableName, const wxString& databaseName)
 
2482
{
 
2483
  wxString sql;
 
2484
  if (databaseName.IsEmpty())
 
2485
  {
 
2486
    sql = wxT("select count(*) from sqlite_master where type='table' and name like ?");
 
2487
  }
 
2488
  else
 
2489
  {
 
2490
    sql = wxString(wxT("select count(*) from ")) + databaseName + wxString(wxT(".sqlite_master where type='table' and name like ?"));
 
2491
  }
 
2492
  wxSQLite3Statement stmt = PrepareStatement(sql);
 
2493
  stmt.Bind(1, tableName);
 
2494
  wxSQLite3ResultSet resultSet = stmt.ExecuteQuery();
 
2495
  long value = 0;
 
2496
  resultSet.GetAsString(0).ToLong(&value);
 
2497
  return (value > 0);
 
2498
}
 
2499
 
 
2500
bool wxSQLite3Database::TableExists(const wxString& tableName, wxArrayString& databaseNames)
 
2501
{
 
2502
  wxArrayString databaseList;
 
2503
  GetDatabaseList(databaseList);
 
2504
 
 
2505
  bool found = false;
 
2506
  size_t count = databaseList.GetCount();
 
2507
  if (count > 0)
 
2508
  {
 
2509
    size_t j;
 
2510
    for (j = 0; j < count; j++)
 
2511
    {
 
2512
      if (TableExists(tableName, databaseList.Item(j)))
 
2513
      {
 
2514
        found = true;
 
2515
        databaseNames.Add(databaseList.Item(j));
 
2516
      }
 
2517
    }
 
2518
  }
 
2519
  return found;
 
2520
}
 
2521
 
 
2522
void wxSQLite3Database::GetDatabaseList(wxArrayString& databaseNames)
 
2523
{
 
2524
  databaseNames.Empty();
 
2525
  wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA database_list;");
 
2526
  while (resultSet.NextRow())
 
2527
  {
 
2528
    databaseNames.Add(resultSet.GetString(1));
 
2529
  }
 
2530
}
 
2531
 
 
2532
void wxSQLite3Database::GetDatabaseList(wxArrayString& databaseNames, wxArrayString& databaseFiles)
 
2533
{
 
2534
  databaseNames.Empty();
 
2535
  databaseFiles.Empty();
 
2536
  wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA database_list;");
 
2537
  while (resultSet.NextRow())
 
2538
  {
 
2539
    databaseNames.Add(resultSet.GetString(1));
 
2540
    databaseFiles.Add(resultSet.GetString(2));
 
2541
  }
 
2542
}
 
2543
 
 
2544
bool wxSQLite3Database::EnableForeignKeySupport(bool enable)
 
2545
{
 
2546
  if (enable)
 
2547
  {
 
2548
    ExecuteUpdate("PRAGMA foreign_keys=ON;");
 
2549
  }
 
2550
  else
 
2551
  {
 
2552
    ExecuteUpdate("PRAGMA foreign_keys=OFF;");
 
2553
  }
 
2554
  bool enabled = IsForeignKeySupportEnabled();
 
2555
  return (enable && enabled) || (!enable && !enabled);
 
2556
}
 
2557
 
 
2558
bool wxSQLite3Database::IsForeignKeySupportEnabled()
 
2559
{
 
2560
  bool enabled = false;
 
2561
  wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA foreign_keys;");
 
2562
  if (resultSet.NextRow())
 
2563
  {
 
2564
    enabled = (resultSet.GetInt(0) == 1);
 
2565
  }
 
2566
  return enabled;
 
2567
}
 
2568
 
 
2569
wxSQLite3JournalMode
 
2570
wxSQLite3Database::SetJournalMode(wxSQLite3JournalMode journalMode, const wxString& database)
 
2571
{
 
2572
  wxString mode = ConvertJournalMode(journalMode);
 
2573
  wxString query = wxT("PRAGMA ");
 
2574
  if (!database.IsEmpty())
 
2575
  {
 
2576
    query += database;
 
2577
    query += wxT(".");
 
2578
  }
 
2579
  query += wxT("journal_mode=");
 
2580
  query += mode;
 
2581
  query += wxT(";");
 
2582
  wxSQLite3ResultSet resultSet = ExecuteQuery(query);
 
2583
  if (resultSet.NextRow())
 
2584
  {
 
2585
    mode = resultSet.GetString(0);
 
2586
  }
 
2587
  return ConvertJournalMode(mode);
 
2588
}
 
2589
 
 
2590
wxSQLite3JournalMode
 
2591
wxSQLite3Database::GetJournalMode(const wxString& database)
 
2592
{
 
2593
  wxString mode = wxT("DELETE");
 
2594
  wxString query = wxT("PRAGMA ");
 
2595
  if (!database.IsEmpty())
 
2596
  {
 
2597
    query += database;
 
2598
    query += wxT(".");
 
2599
  }
 
2600
  query += wxT("journal_mode;");
 
2601
  wxSQLite3ResultSet resultSet = ExecuteQuery(query);
 
2602
  if (resultSet.NextRow())
 
2603
  {
 
2604
    mode = resultSet.GetString(0);
 
2605
  }
 
2606
  return ConvertJournalMode(mode);
 
2607
}
 
2608
 
 
2609
/* static */
 
2610
wxString wxSQLite3Database::ConvertJournalMode(wxSQLite3JournalMode mode)
 
2611
{
 
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");
 
2620
  return journalMode;
 
2621
}
 
2622
 
 
2623
/* static */
 
2624
wxSQLite3JournalMode wxSQLite3Database::ConvertJournalMode(const wxString& mode)
 
2625
{
 
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;
 
2634
  return journalMode;
 
2635
}
 
2636
 
 
2637
bool wxSQLite3Database::CheckSyntax(const wxString& sql)
 
2638
{
 
2639
  wxCharBuffer strSql = sql.ToUTF8();
 
2640
  const char* localSql = strSql;
 
2641
  return CheckSyntax(localSql);
 
2642
}
 
2643
 
 
2644
bool wxSQLite3Database::CheckSyntax(const wxSQLite3StatementBuffer& sql)
 
2645
{
 
2646
  return CheckSyntax((const char*) sql);
 
2647
}
 
2648
 
 
2649
bool wxSQLite3Database::CheckSyntax(const char* sql)
 
2650
{
 
2651
  return sqlite3_complete(sql) != 0;
 
2652
}
 
2653
 
 
2654
int wxSQLite3Database::ExecuteUpdate(const wxString& sql)
 
2655
{
 
2656
  wxCharBuffer strSql = sql.ToUTF8();
 
2657
  const char* localSql = strSql;
 
2658
  return ExecuteUpdate(localSql);
 
2659
}
 
2660
 
 
2661
int wxSQLite3Database::ExecuteUpdate(const wxSQLite3StatementBuffer& sql)
 
2662
{
 
2663
  return ExecuteUpdate((const char*) sql);
 
2664
}
 
2665
 
 
2666
int wxSQLite3Database::ExecuteUpdate(const char* sql)
 
2667
{
 
2668
  CheckDatabase();
 
2669
 
 
2670
  char* localError=0;
 
2671
 
 
2672
  int rc = sqlite3_exec((sqlite3*) m_db, sql, 0, 0, &localError);
 
2673
 
 
2674
  if (rc == SQLITE_OK)
 
2675
  {
 
2676
    return sqlite3_changes((sqlite3*) m_db);
 
2677
  }
 
2678
  else
 
2679
  {
 
2680
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2681
  }
 
2682
}
 
2683
 
 
2684
wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const wxString& sql)
 
2685
{
 
2686
  wxCharBuffer strSql = sql.ToUTF8();
 
2687
  const char* localSql = strSql;
 
2688
  return ExecuteQuery(localSql);
 
2689
}
 
2690
 
 
2691
wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const wxSQLite3StatementBuffer& sql)
 
2692
{
 
2693
  return ExecuteQuery((const char*) sql);
 
2694
}
 
2695
 
 
2696
wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const char* sql)
 
2697
{
 
2698
  CheckDatabase();
 
2699
 
 
2700
  sqlite3_stmt* stmt = (sqlite3_stmt*) Prepare(sql);
 
2701
 
 
2702
  int rc = sqlite3_step(stmt);
 
2703
 
 
2704
  if (rc == SQLITE_DONE) // no rows
 
2705
  {
 
2706
    return wxSQLite3ResultSet(m_db, stmt, true /* eof */);
 
2707
  }
 
2708
  else if (rc == SQLITE_ROW) // one or more rows
 
2709
  {
 
2710
    return wxSQLite3ResultSet(m_db, stmt, false /* eof */);
 
2711
  }
 
2712
  else
 
2713
  {
 
2714
    rc = sqlite3_finalize(stmt);
 
2715
    const char* localError= sqlite3_errmsg((sqlite3*) m_db);
 
2716
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2717
  }
 
2718
}
 
2719
 
 
2720
int wxSQLite3Database::ExecuteScalar(const wxString& sql)
 
2721
{
 
2722
  wxCharBuffer strSql = sql.ToUTF8();
 
2723
  const char* localSql = strSql;
 
2724
  return ExecuteScalar(localSql);
 
2725
}
 
2726
 
 
2727
int wxSQLite3Database::ExecuteScalar(const wxSQLite3StatementBuffer& sql)
 
2728
{
 
2729
  return ExecuteScalar((const char*) sql);
 
2730
}
 
2731
 
 
2732
int wxSQLite3Database::ExecuteScalar(const char* sql)
 
2733
{
 
2734
  wxSQLite3ResultSet resultSet = ExecuteQuery(sql);
 
2735
 
 
2736
  if (resultSet.Eof() || resultSet.GetColumnCount() < 1)
 
2737
  {
 
2738
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_QUERY);
 
2739
  }
 
2740
 
 
2741
  long value = 0;
 
2742
  resultSet.GetAsString(0).ToLong(&value);
 
2743
  return (int) value;
 
2744
}
 
2745
 
 
2746
wxSQLite3Table wxSQLite3Database::GetTable(const wxString& sql)
 
2747
{
 
2748
  wxCharBuffer strSql = sql.ToUTF8();
 
2749
  const char* localSql = strSql;
 
2750
  return GetTable(localSql);
 
2751
}
 
2752
 
 
2753
wxSQLite3Table wxSQLite3Database::GetTable(const wxSQLite3StatementBuffer& sql)
 
2754
{
 
2755
  return GetTable((const char*) sql);
 
2756
}
 
2757
 
 
2758
wxSQLite3Table wxSQLite3Database::GetTable(const char* sql)
 
2759
{
 
2760
  CheckDatabase();
 
2761
 
 
2762
  char* localError=0;
 
2763
  char** results=0;
 
2764
  int rc;
 
2765
  int rows(0);
 
2766
  int cols(0);
 
2767
 
 
2768
  rc = sqlite3_get_table((sqlite3*) m_db, sql, &results, &rows, &cols, &localError);
 
2769
 
 
2770
  if (rc == SQLITE_OK)
 
2771
  {
 
2772
    return wxSQLite3Table(results, rows, cols);
 
2773
  }
 
2774
  else
 
2775
  {
 
2776
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2777
  }
 
2778
}
 
2779
 
 
2780
wxLongLong wxSQLite3Database::GetLastRowId()
 
2781
{
 
2782
  CheckDatabase();
 
2783
  return wxLongLong(sqlite3_last_insert_rowid((sqlite3*) m_db));
 
2784
}
 
2785
 
 
2786
wxSQLite3Blob wxSQLite3Database::GetReadOnlyBlob(wxLongLong rowId,
 
2787
                                                 const wxString& columnName,
 
2788
                                                 const wxString& tableName,
 
2789
                                                 const wxString& dbName)
 
2790
{
 
2791
  return GetBlob(rowId, columnName, tableName, dbName, false);
 
2792
}
 
2793
 
 
2794
wxSQLite3Blob wxSQLite3Database::GetWritableBlob(wxLongLong rowId,
 
2795
                                                 const wxString& columnName,
 
2796
                                                 const wxString& tableName,
 
2797
                                                 const wxString& dbName)
 
2798
{
 
2799
  return GetBlob(rowId, columnName, tableName, dbName, true);
 
2800
}
 
2801
 
 
2802
wxSQLite3Blob wxSQLite3Database::GetBlob(wxLongLong rowId,
 
2803
                                         const wxString& columnName,
 
2804
                                         const wxString& tableName,
 
2805
                                         const wxString& dbName,
 
2806
                                         bool writable)
 
2807
{
 
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;
 
2817
  CheckDatabase();
 
2818
  int rc = sqlite3_blob_open((sqlite3*) m_db, localDbName, localTableName, localColumnName, rowId.GetValue(), flags, &blobHandle);
 
2819
  if (rc != SQLITE_OK)
 
2820
  {
 
2821
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2822
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2823
  }
 
2824
  return wxSQLite3Blob(m_db, (void*) blobHandle, writable);
 
2825
#else
 
2826
  wxUnusedVar(rowId);
 
2827
  wxUnusedVar(columnName);
 
2828
  wxUnusedVar(tableName);
 
2829
  wxUnusedVar(dbName);
 
2830
  wxUnusedVar(writable);
 
2831
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
 
2832
  return NULL;
 
2833
#endif
 
2834
}
 
2835
 
 
2836
void wxSQLite3Database::Interrupt()
 
2837
{
 
2838
  CheckDatabase();
 
2839
  sqlite3_interrupt((sqlite3*) m_db);
 
2840
}
 
2841
 
 
2842
void wxSQLite3Database::SetBusyTimeout(int nMillisecs)
 
2843
{
 
2844
  CheckDatabase();
 
2845
  m_busyTimeoutMs = nMillisecs;
 
2846
  sqlite3_busy_timeout((sqlite3*) m_db, m_busyTimeoutMs);
 
2847
}
 
2848
 
 
2849
wxString wxSQLite3Database::GetVersion()
 
2850
{
 
2851
  return wxString::FromUTF8(sqlite3_libversion());
 
2852
}
 
2853
 
 
2854
wxString wxSQLite3Database::GetSourceId()
 
2855
{
 
2856
#if SQLITE_VERSION_NUMBER >= 3006018
 
2857
  return wxString::FromUTF8(sqlite3_sourceid());
 
2858
#else
 
2859
  return wxEmptyString;
 
2860
#endif
 
2861
}
 
2862
 
 
2863
bool wxSQLite3Database::CompileOptionUsed(const wxString& optionName)
 
2864
{
 
2865
#if SQLITE_VERSION_NUMBER >= 3006023
 
2866
  wxCharBuffer strOption = optionName.ToUTF8();
 
2867
  const char* localOption = strOption;
 
2868
  return sqlite3_compileoption_used(localOption) == 1;
 
2869
#else
 
2870
  return false;
 
2871
#endif
 
2872
}
 
2873
 
 
2874
wxString wxSQLite3Database::GetCompileOptionName(int optionIndex)
 
2875
{
 
2876
#if SQLITE_VERSION_NUMBER >= 3006023
 
2877
  const char* unknownOption = "";
 
2878
  const char* optionName = sqlite3_compileoption_get(optionIndex);
 
2879
  if (optionName == NULL)
 
2880
  {
 
2881
    optionName = unknownOption;
 
2882
  }
 
2883
  return wxString::FromUTF8(optionName);
 
2884
#else
 
2885
  return wxEmptyString;
 
2886
#endif
 
2887
}
 
2888
 
 
2889
bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3ScalarFunction& function)
 
2890
{
 
2891
  CheckDatabase();
 
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;
 
2898
}
 
2899
 
 
2900
bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3AggregateFunction& function)
 
2901
{
 
2902
  CheckDatabase();
 
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,
 
2907
                                   NULL,
 
2908
                                   (void (*)(sqlite3_context*,int,sqlite3_value**)) wxSQLite3FunctionContext::ExecAggregateStep,
 
2909
                                   (void (*)(sqlite3_context*)) wxSQLite3FunctionContext::ExecAggregateFinalize);
 
2910
  return rc == SQLITE_OK;
 
2911
}
 
2912
 
 
2913
bool wxSQLite3Database::SetAuthorizer(wxSQLite3Authorizer& authorizer)
 
2914
{
 
2915
  CheckDatabase();
 
2916
  int rc = sqlite3_set_authorizer((sqlite3*) m_db, wxSQLite3FunctionContext::ExecAuthorizer, &authorizer);
 
2917
  return rc == SQLITE_OK;
 
2918
}
 
2919
 
 
2920
void wxSQLite3Database::SetCommitHook(wxSQLite3Hook* commitHook)
 
2921
{
 
2922
  CheckDatabase();
 
2923
  if (commitHook)
 
2924
  {
 
2925
    sqlite3_commit_hook((sqlite3*) m_db, (int(*)(void*)) wxSQLite3FunctionContext::ExecCommitHook, commitHook);
 
2926
  }
 
2927
  else
 
2928
  {
 
2929
    sqlite3_commit_hook((sqlite3*) m_db, (int(*)(void*)) NULL, NULL);
 
2930
  }
 
2931
}
 
2932
 
 
2933
void wxSQLite3Database::SetRollbackHook(wxSQLite3Hook* rollbackHook)
 
2934
{
 
2935
  CheckDatabase();
 
2936
  if (rollbackHook)
 
2937
  {
 
2938
    sqlite3_rollback_hook((sqlite3*) m_db, (void(*)(void*)) wxSQLite3FunctionContext::ExecRollbackHook, rollbackHook);
 
2939
  }
 
2940
  else
 
2941
  {
 
2942
    sqlite3_rollback_hook((sqlite3*) m_db, (void(*)(void*)) NULL, NULL);
 
2943
  }
 
2944
}
 
2945
 
 
2946
void wxSQLite3Database::SetUpdateHook(wxSQLite3Hook* updateHook)
 
2947
{
 
2948
  CheckDatabase();
 
2949
  if (updateHook)
 
2950
  {
 
2951
    sqlite3_update_hook((sqlite3*) m_db, (void(*)(void*,int,const char*,const char*, wxsqlite_int64)) wxSQLite3FunctionContext::ExecUpdateHook, updateHook);
 
2952
  }
 
2953
  else
 
2954
  {
 
2955
    sqlite3_update_hook((sqlite3*) m_db, (void(*)(void*,int,const char*,const char*, wxsqlite_int64)) NULL, NULL);
 
2956
  }
 
2957
}
 
2958
 
 
2959
void wxSQLite3Database::SetWriteAheadLogHook(wxSQLite3Hook* walHook)
 
2960
{
 
2961
#if SQLITE_VERSION_NUMBER >= 3007000
 
2962
  CheckDatabase();
 
2963
  if (walHook)
 
2964
  {
 
2965
    walHook->SetDatabase(this);
 
2966
    sqlite3_wal_hook((sqlite3*) m_db, (int(*)(void *,sqlite3*,const char*,int)) wxSQLite3FunctionContext::ExecWriteAheadLogHook, walHook);
 
2967
  }
 
2968
  else
 
2969
  {
 
2970
    sqlite3_wal_hook((sqlite3*) m_db, (int(*)(void *,sqlite3*,const char*,int)) NULL, NULL);
 
2971
  }
 
2972
#else
 
2973
  wxUnusedVar(walHook);
 
2974
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOWAL);
 
2975
#endif
 
2976
}
 
2977
 
 
2978
void wxSQLite3Database::WriteAheadLogCheckpoint(const wxString& database, int mode, 
 
2979
                                                int* logFrameCount, int* ckptFrameCount)
 
2980
{
 
2981
#if SQLITE_VERSION_NUMBER >= 3007000
 
2982
  CheckDatabase();
 
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);
 
2987
#else
 
2988
  int rc = sqlite3_wal_checkpoint((sqlite3*) m_db, localDatabase);
 
2989
  if (logFrameCount  != NULL) *logFrameCount  = 0;
 
2990
  if (ckptFrameCount != NULL) *ckptFrameCount = 0;
 
2991
#endif
 
2992
 
 
2993
  if (rc != SQLITE_OK)
 
2994
  {
 
2995
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2996
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
2997
  }
 
2998
#else
 
2999
  wxUnusedVar(database);
 
3000
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOWAL);
 
3001
#endif
 
3002
}
 
3003
 
 
3004
void wxSQLite3Database::AutoWriteAheadLogCheckpoint(int frameCount)
 
3005
{
 
3006
#if SQLITE_VERSION_NUMBER >= 3007000
 
3007
  CheckDatabase();
 
3008
  int rc = sqlite3_wal_autocheckpoint((sqlite3*) m_db, frameCount);
 
3009
 
 
3010
  if (rc != SQLITE_OK)
 
3011
  {
 
3012
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
3013
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
3014
  }
 
3015
#else
 
3016
  wxUnusedVar(frameCount);
 
3017
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOWAL);
 
3018
#endif
 
3019
}
 
3020
 
 
3021
void wxSQLite3Database::SetCollation(const wxString& collationName, wxSQLite3Collation* collation)
 
3022
{
 
3023
  CheckDatabase();
 
3024
  wxCharBuffer strCollationName = collationName.ToUTF8();
 
3025
  const char* localCollationName = strCollationName;
 
3026
  int rc;
 
3027
  if (collation)
 
3028
  {
 
3029
    rc = sqlite3_create_collation((sqlite3*) m_db, localCollationName, SQLITE_UTF8, collation, (int(*)(void*,int,const void*,int,const void*)) wxSQLite3Database::ExecComparisonWithCollation);
 
3030
  }
 
3031
  else
 
3032
  {
 
3033
    rc = sqlite3_create_collation((sqlite3*) m_db, localCollationName, SQLITE_UTF8, NULL, (int(*)(void*,int,const void*,int,const void*)) NULL);
 
3034
  }
 
3035
}
 
3036
 
 
3037
void wxSQLite3Database::SetCollationNeededCallback()
 
3038
{
 
3039
  CheckDatabase();
 
3040
  int rc = sqlite3_collation_needed((sqlite3*) m_db, this, (void(*)(void*,sqlite3*,int,const char*)) wxSQLite3Database::ExecCollationNeeded);
 
3041
  if (rc != SQLITE_OK)
 
3042
  {
 
3043
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
3044
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
3045
  }
 
3046
}
 
3047
 
 
3048
void wxSQLite3Database::CheckDatabase()
 
3049
{
 
3050
  if (!m_db)
 
3051
  {
 
3052
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NODB);
 
3053
  }
 
3054
}
 
3055
 
 
3056
void* wxSQLite3Database::Prepare(const char* sql)
 
3057
{
 
3058
  CheckDatabase();
 
3059
 
 
3060
  const char* tail=0;
 
3061
  sqlite3_stmt* stmt;
 
3062
 
 
3063
  int rc = sqlite3_prepare_v2((sqlite3*) m_db, sql, -1, &stmt, &tail);
 
3064
 
 
3065
  if (rc != SQLITE_OK)
 
3066
  {
 
3067
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
3068
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
3069
  }
 
3070
 
 
3071
  return stmt;
 
3072
}
 
3073
 
 
3074
/* static */
 
3075
int wxSQLite3Database::ExecComparisonWithCollation(void* collation,
 
3076
                                                   int len1, const void* text1,
 
3077
                                                   int len2, const void* text2)
 
3078
{
 
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);
 
3082
}
 
3083
 
 
3084
void wxSQLite3Database::ExecCollationNeeded(void* db, void*, int, const char* collationName)
 
3085
{
 
3086
  wxString locCollation = wxString::FromUTF8((const char*) collationName);
 
3087
  ((wxSQLite3Database*) db)->SetNeededCollation(locCollation);
 
3088
}
 
3089
 
 
3090
void wxSQLite3Database::GetMetaData(const wxString& databaseName, const wxString& tableName, const wxString& columnName,
 
3091
                                    wxString* dataType, wxString* collation, bool* notNull, bool* primaryKey, bool* autoIncrement)
 
3092
{
 
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;
 
3103
  int localNotNull;
 
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);
 
3108
 
 
3109
  if (rc != SQLITE_OK)
 
3110
  {
 
3111
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
3112
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
3113
  }
 
3114
 
 
3115
  if (dataType      != NULL) *dataType      = wxString::FromUTF8(localDataType);
 
3116
  if (collation     != NULL) *collation     = wxString::FromUTF8(localCollation);
 
3117
 
 
3118
  if (notNull       != NULL) *notNull       = (localNotNull       != 0);
 
3119
  if (primaryKey    != NULL) *primaryKey    = (localPrimaryKey    != 0);
 
3120
  if (autoIncrement != NULL) *autoIncrement = (localAutoIncrement != 0);
 
3121
#else
 
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);
 
3131
#endif
 
3132
}
 
3133
 
 
3134
void wxSQLite3Database::LoadExtension(const wxString& fileName, const wxString& entryPoint)
 
3135
{
 
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;
 
3141
 
 
3142
  int rc = sqlite3_load_extension((sqlite3 *) m_db, localFileName, localEntryPoint, NULL);
 
3143
  if (rc != SQLITE_OK)
 
3144
  {
 
3145
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
3146
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
3147
  }
 
3148
#else
 
3149
  wxUnusedVar(fileName);
 
3150
  wxUnusedVar(entryPoint);
 
3151
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOLOADEXT);
 
3152
#endif
 
3153
}
 
3154
 
 
3155
void wxSQLite3Database::EnableLoadExtension(bool enable)
 
3156
{
 
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)
 
3161
  {
 
3162
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
3163
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
3164
  }
 
3165
#else
 
3166
  wxUnusedVar(enable);
 
3167
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOLOADEXT);
 
3168
#endif
 
3169
}
 
3170
 
 
3171
void wxSQLite3Database::ReKey(const wxString& newKey)
 
3172
{
 
3173
#if WXSQLITE3_HAVE_CODEC
 
3174
  wxCharBuffer strLocalNewKey = newKey.ToUTF8();
 
3175
  const char* localNewKey = strLocalNewKey;
 
3176
  wxMemoryBuffer binaryNewKey;
 
3177
  if (newKey.Length() > 0)
 
3178
  {
 
3179
    binaryNewKey.AppendData((void*) localNewKey, strlen(localNewKey));
 
3180
  }
 
3181
  ReKey(binaryNewKey);
 
3182
#else
 
3183
  wxUnusedVar(newKey);
 
3184
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOCODEC);
 
3185
#endif
 
3186
}
 
3187
 
 
3188
void wxSQLite3Database::ReKey(const wxMemoryBuffer& newKey)
 
3189
{
 
3190
#if WXSQLITE3_HAVE_CODEC
 
3191
  int rc = sqlite3_rekey((sqlite3*) m_db, newKey.GetData(), (int) newKey.GetDataLen());
 
3192
  if (rc != SQLITE_OK)
 
3193
  {
 
3194
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
3195
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
3196
  }
 
3197
#else
 
3198
  wxUnusedVar(newKey);
 
3199
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOCODEC);
 
3200
#endif
 
3201
}
 
3202
 
 
3203
int wxSQLite3Database::GetLimit(wxSQLite3LimitType id)
 
3204
{
 
3205
  int value = -1;
 
3206
#if SQLITE_VERSION_NUMBER >= 3005008
 
3207
  CheckDatabase();
 
3208
  if (id >= WXSQLITE_LIMIT_LENGTH && id <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
 
3209
  {
 
3210
    value = sqlite3_limit((sqlite3 *) m_db, id, -1);
 
3211
  }
 
3212
#else
 
3213
  wxUnusedVar(id);
 
3214
#endif
 
3215
  return value;
 
3216
}
 
3217
 
 
3218
int wxSQLite3Database::SetLimit(wxSQLite3LimitType id, int newValue)
 
3219
{
 
3220
  int value = -1;
 
3221
#if SQLITE_VERSION_NUMBER >= 3005008
 
3222
  CheckDatabase();
 
3223
  if (id >= WXSQLITE_LIMIT_LENGTH && id <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
 
3224
  {
 
3225
    value = sqlite3_limit((sqlite3 *) m_db, id, newValue);
 
3226
  }
 
3227
#else
 
3228
  wxUnusedVar(id);
 
3229
  wxUnusedVar(newValue);
 
3230
#endif
 
3231
  return value;
 
3232
}
 
3233
 
 
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")
 
3241
};
 
3242
 
 
3243
 
 
3244
/* static */
 
3245
wxString wxSQLite3Database::LimitTypeToString(wxSQLite3LimitType type)
 
3246
{
 
3247
  const wxChar* limitString = wxT("Unknown");
 
3248
  if (type >= WXSQLITE_LIMIT_LENGTH && type <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
 
3249
  {
 
3250
    limitString = limitCodeString[type];
 
3251
  }
 
3252
  return wxString(limitString);
 
3253
}
 
3254
 
 
3255
/* static */
 
3256
void wxSQLite3Database::InitializeSQLite()
 
3257
{
 
3258
#if SQLITE_VERSION_NUMBER >= 3006000
 
3259
  int rc = sqlite3_initialize();
 
3260
  if (rc != SQLITE_OK)
 
3261
  {
 
3262
    throw wxSQLite3Exception(rc, wxERRMSG_INITIALIZE);
 
3263
  }
 
3264
#endif
 
3265
}
 
3266
 
 
3267
/* static */
 
3268
void wxSQLite3Database::ShutdownSQLite()
 
3269
{
 
3270
#if SQLITE_VERSION_NUMBER >= 3006000
 
3271
  int rc = sqlite3_shutdown();
 
3272
  if (rc != SQLITE_OK)
 
3273
  {
 
3274
    throw wxSQLite3Exception(rc, wxERRMSG_SHUTDOWN);
 
3275
  }
 
3276
#endif
 
3277
}
 
3278
 
 
3279
/* static */
 
3280
bool wxSQLite3Database::Randomness(int n, wxMemoryBuffer& random)
 
3281
{
 
3282
  bool ok = false;
 
3283
#if SQLITE_VERSION_NUMBER >= 3005008
 
3284
  if (n > 0)
 
3285
  {
 
3286
    void* buffer = random.GetWriteBuf(n);
 
3287
    sqlite3_randomness(n, buffer);
 
3288
    random.UngetWriteBuf(n);
 
3289
    ok = true;
 
3290
  }
 
3291
#else
 
3292
  wxUnusedVar(n);
 
3293
  wxUnusedVar(random);
 
3294
#endif
 
3295
  return ok;
 
3296
}
 
3297
 
 
3298
// ----------------------------------------------------------------------------
 
3299
// wxSQLite3FunctionContext: class providing the function context
 
3300
//                           for user defined functions
 
3301
// ----------------------------------------------------------------------------
 
3302
 
 
3303
int wxSQLite3FunctionContext::GetArgCount()
 
3304
{
 
3305
  return m_argc;
 
3306
}
 
3307
 
 
3308
int wxSQLite3FunctionContext::GetArgType(int argIndex)
 
3309
{
 
3310
  if (argIndex >= 0 && argIndex < m_argc)
 
3311
  {
 
3312
    return sqlite3_value_type((sqlite3_value*) m_argv[argIndex]);
 
3313
  }
 
3314
  else
 
3315
  {
 
3316
    return SQLITE_NULL;
 
3317
  }
 
3318
}
 
3319
 
 
3320
bool wxSQLite3FunctionContext::IsNull(int argIndex)
 
3321
{
 
3322
  if (argIndex >= 0 && argIndex < m_argc)
 
3323
  {
 
3324
    return sqlite3_value_type((sqlite3_value*) m_argv[argIndex]) == SQLITE_NULL;
 
3325
  }
 
3326
  else
 
3327
  {
 
3328
    return true;
 
3329
  }
 
3330
}
 
3331
 
 
3332
int wxSQLite3FunctionContext::GetInt(int argIndex, int nullValue)
 
3333
{
 
3334
  if (argIndex >= 0 && argIndex < m_argc)
 
3335
  {
 
3336
    if (!IsNull(argIndex))
 
3337
    {
 
3338
      return sqlite3_value_int((sqlite3_value*) m_argv[argIndex]);
 
3339
    }
 
3340
    else
 
3341
    {
 
3342
      return nullValue;
 
3343
    }
 
3344
  }
 
3345
  else
 
3346
  {
 
3347
    return nullValue;
 
3348
  }
 
3349
}
 
3350
 
 
3351
wxLongLong wxSQLite3FunctionContext::GetInt64(int argIndex, wxLongLong nullValue)
 
3352
{
 
3353
  if (argIndex >= 0 && argIndex < m_argc)
 
3354
  {
 
3355
    if (!IsNull(argIndex))
 
3356
    {
 
3357
      return wxLongLong(sqlite3_value_int64((sqlite3_value*) m_argv[argIndex]));
 
3358
    }
 
3359
    else
 
3360
    {
 
3361
      return nullValue;
 
3362
    }
 
3363
  }
 
3364
  else
 
3365
  {
 
3366
    return nullValue;
 
3367
  }
 
3368
}
 
3369
 
 
3370
double wxSQLite3FunctionContext::GetDouble(int argIndex, double nullValue)
 
3371
{
 
3372
  if (argIndex >= 0 && argIndex < m_argc)
 
3373
  {
 
3374
    if (!IsNull(argIndex))
 
3375
    {
 
3376
      return sqlite3_value_double((sqlite3_value*) m_argv[argIndex]);
 
3377
    }
 
3378
    else
 
3379
    {
 
3380
      return nullValue;
 
3381
    }
 
3382
  }
 
3383
  else
 
3384
  {
 
3385
    return nullValue;
 
3386
  }
 
3387
}
 
3388
 
 
3389
wxString wxSQLite3FunctionContext::GetString(int argIndex, const wxString& nullValue)
 
3390
{
 
3391
  if (argIndex >= 0 && argIndex < m_argc)
 
3392
  {
 
3393
    if (!IsNull(argIndex))
 
3394
    {
 
3395
      const char* localValue = (const char*) sqlite3_value_text((sqlite3_value*) m_argv[argIndex]);
 
3396
      return wxString::FromUTF8(localValue);
 
3397
    }
 
3398
    else
 
3399
    {
 
3400
      return nullValue;
 
3401
    }
 
3402
  }
 
3403
  else
 
3404
  {
 
3405
    return nullValue;
 
3406
  }
 
3407
}
 
3408
 
 
3409
wxMemoryBuffer& wxSQLite3FunctionContext::GetBlob(int argIndex, wxMemoryBuffer& buffer)
 
3410
{
 
3411
  if (argIndex >= 0 && argIndex < m_argc)
 
3412
  {
 
3413
    if (!IsNull(argIndex))
 
3414
    {
 
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);
 
3418
    }
 
3419
  }
 
3420
  return buffer;
 
3421
}
 
3422
 
 
3423
void wxSQLite3FunctionContext::SetResult(int value)
 
3424
{
 
3425
  sqlite3_result_int((sqlite3_context*) m_ctx, value);
 
3426
}
 
3427
 
 
3428
void wxSQLite3FunctionContext::SetResult(wxLongLong value)
 
3429
{
 
3430
  sqlite3_result_int64((sqlite3_context*) m_ctx, value.GetValue());
 
3431
}
 
3432
 
 
3433
void wxSQLite3FunctionContext::SetResult(double value)
 
3434
{
 
3435
  sqlite3_result_double((sqlite3_context*) m_ctx, value);
 
3436
}
 
3437
 
 
3438
void wxSQLite3FunctionContext::SetResult(const wxString& value)
 
3439
{
 
3440
  wxCharBuffer strValue = value.ToUTF8();
 
3441
  const char* localValue = strValue;
 
3442
  sqlite3_result_text((sqlite3_context*) m_ctx, localValue, -1, SQLITE_TRANSIENT);
 
3443
}
 
3444
 
 
3445
void wxSQLite3FunctionContext::SetResult(unsigned char* value, int len)
 
3446
{
 
3447
  sqlite3_result_blob((sqlite3_context*) m_ctx, value, len, SQLITE_TRANSIENT);
 
3448
}
 
3449
 
 
3450
void wxSQLite3FunctionContext::SetResult(const wxMemoryBuffer& buffer)
 
3451
{
 
3452
  sqlite3_result_blob((sqlite3_context*) m_ctx, buffer.GetData(), (int) buffer.GetDataLen(), SQLITE_TRANSIENT);
 
3453
}
 
3454
 
 
3455
void wxSQLite3FunctionContext::SetResultNull()
 
3456
{
 
3457
  sqlite3_result_null((sqlite3_context*) m_ctx);
 
3458
}
 
3459
 
 
3460
void wxSQLite3FunctionContext::SetResultZeroBlob(int blobSize)
 
3461
{
 
3462
#if SQLITE_VERSION_NUMBER >= 3004000
 
3463
  sqlite3_result_zeroblob((sqlite3_context*) m_ctx, blobSize);
 
3464
#endif
 
3465
}
 
3466
 
 
3467
void wxSQLite3FunctionContext::SetResultArg(int argIndex)
 
3468
{
 
3469
  if (argIndex >= 0 && argIndex < m_argc) {
 
3470
    sqlite3_result_value((sqlite3_context*) m_ctx, (sqlite3_value*) m_argv[argIndex]);
 
3471
  } else {
 
3472
    sqlite3_result_null((sqlite3_context*) m_ctx);
 
3473
  }
 
3474
}
 
3475
 
 
3476
void wxSQLite3FunctionContext::SetResultError(const wxString& errmsg)
 
3477
{
 
3478
  wxCharBuffer strErrmsg = errmsg.ToUTF8();
 
3479
  const char* localErrmsg = strErrmsg;
 
3480
  sqlite3_result_error((sqlite3_context*) m_ctx, localErrmsg, -1);
 
3481
}
 
3482
 
 
3483
int wxSQLite3FunctionContext::GetAggregateCount()
 
3484
{
 
3485
  if (m_isAggregate)
 
3486
  {
 
3487
    return m_count;
 
3488
  }
 
3489
  else
 
3490
  {
 
3491
    return 0;
 
3492
  }
 
3493
}
 
3494
 
 
3495
void* wxSQLite3FunctionContext::GetAggregateStruct(int len)
 
3496
{
 
3497
  if (m_isAggregate)
 
3498
  {
 
3499
    return sqlite3_aggregate_context((sqlite3_context*) m_ctx, len);
 
3500
  }
 
3501
  else
 
3502
  {
 
3503
    return NULL;
 
3504
  }
 
3505
}
 
3506
 
 
3507
/* static */
 
3508
void wxSQLite3FunctionContext::ExecScalarFunction(void* ctx, int argc, void** argv)
 
3509
{
 
3510
  wxSQLite3FunctionContext context(ctx, false, argc, argv);
 
3511
  wxSQLite3ScalarFunction* func = (wxSQLite3ScalarFunction*) sqlite3_user_data((sqlite3_context*) ctx);
 
3512
  func->Execute(context);
 
3513
}
 
3514
 
 
3515
/* static */
 
3516
void wxSQLite3FunctionContext::ExecAggregateStep(void* ctx, int argc, void** argv)
 
3517
{
 
3518
  wxSQLite3FunctionContext context(ctx, true, argc, argv);
 
3519
  wxSQLite3AggregateFunction* func = (wxSQLite3AggregateFunction*) sqlite3_user_data((sqlite3_context*) ctx);
 
3520
  func->m_count++;
 
3521
  context.m_count = func->m_count;
 
3522
  func->Aggregate(context);
 
3523
}
 
3524
 
 
3525
/* static */
 
3526
void wxSQLite3FunctionContext::ExecAggregateFinalize(void* ctx)
 
3527
{
 
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);
 
3532
}
 
3533
 
 
3534
/* static */
 
3535
int wxSQLite3FunctionContext::ExecAuthorizer(void* func, int type,
 
3536
                                             const char* arg1, const char* arg2,
 
3537
                                             const char* arg3, const char* arg4)
 
3538
{
 
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);
 
3545
}
 
3546
 
 
3547
/* static */
 
3548
int wxSQLite3FunctionContext::ExecCommitHook(void* hook)
 
3549
{
 
3550
  return (int) ((wxSQLite3Hook*) hook)->CommitCallback();
 
3551
}
 
3552
 
 
3553
/* static */
 
3554
void wxSQLite3FunctionContext::ExecRollbackHook(void* hook)
 
3555
{
 
3556
  ((wxSQLite3Hook*) hook)->RollbackCallback();
 
3557
}
 
3558
 
 
3559
/* static */
 
3560
void wxSQLite3FunctionContext::ExecUpdateHook(void* hook, int type,
 
3561
                                              const char* database, const char* table,
 
3562
                                              wxsqlite_int64 rowid)
 
3563
{
 
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);
 
3569
}
 
3570
 
 
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)
 
3573
{
 
3574
}
 
3575
 
 
3576
/* static */
 
3577
int wxSQLite3FunctionContext::ExecWriteAheadLogHook(void* hook, void* dbHandle,
 
3578
                                                    const char* database, int numPages)
 
3579
{
 
3580
  wxString locDatabase = wxString::FromUTF8(database);
 
3581
  wxUnusedVar(dbHandle);
 
3582
  return (int) ((wxSQLite3Hook*) hook)->WriteAheadLogCallback(locDatabase, numPages);
 
3583
}
 
3584
 
 
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")
 
3597
};
 
3598
 
 
3599
 
 
3600
/* static */
 
3601
wxString wxSQLite3Authorizer::AuthorizationCodeToString(wxSQLite3Authorizer::wxAuthorizationCode type)
 
3602
{
 
3603
  const wxChar* authString = wxT("Unknown");
 
3604
  if (type >= SQLITE_COPY && type <= SQLITE_MAX_CODE)
 
3605
  {
 
3606
    authString = authCodeString[type];
 
3607
  }
 
3608
  return wxString(authString);
 
3609
}
 
3610
 
 
3611
// ----------------------------------------------------------------------------
 
3612
// wxSQLite3Transaction
 
3613
// ----------------------------------------------------------------------------
 
3614
 
 
3615
wxSQLite3Transaction::wxSQLite3Transaction(wxSQLite3Database* db, wxSQLite3TransactionType transactionType)
 
3616
{
 
3617
  assert(db != NULL);
 
3618
  m_database = db;
 
3619
  try
 
3620
  {
 
3621
    m_database->Begin(transactionType);
 
3622
  }
 
3623
  catch (...)
 
3624
  {
 
3625
    m_database = NULL; // Flag that transaction is not active
 
3626
  }
 
3627
}
 
3628
 
 
3629
wxSQLite3Transaction::~wxSQLite3Transaction()
 
3630
{
 
3631
  if (m_database != NULL)
 
3632
  {
 
3633
    m_database->Rollback();
 
3634
  }
 
3635
}
 
3636
 
 
3637
void wxSQLite3Transaction::Commit()
 
3638
{
 
3639
  try
 
3640
  {
 
3641
    m_database->Commit();
 
3642
  }
 
3643
  catch (...)
 
3644
  {
 
3645
    m_database->Rollback();
 
3646
  }
 
3647
  m_database = NULL;
 
3648
}
 
3649
 
 
3650
void wxSQLite3Transaction::Rollback()
 
3651
{
 
3652
  try
 
3653
  {
 
3654
    m_database->Rollback();
 
3655
  }
 
3656
  catch (...)
 
3657
  {
 
3658
    m_database->Rollback();
 
3659
  }
 
3660
  m_database = NULL;
 
3661
}
 
3662
 
 
3663
// --- User defined function classes
 
3664
 
 
3665
#if wxUSE_REGEX
 
3666
 
 
3667
wxSQLite3RegExpOperator::wxSQLite3RegExpOperator(int flags) : m_flags(flags)
 
3668
{
 
3669
}
 
3670
 
 
3671
wxSQLite3RegExpOperator::~wxSQLite3RegExpOperator()
 
3672
{
 
3673
}
 
3674
 
 
3675
void wxSQLite3RegExpOperator::Execute(wxSQLite3FunctionContext& ctx)
 
3676
{
 
3677
  int argCount = ctx.GetArgCount();
 
3678
  if (argCount == 2)
 
3679
  {
 
3680
    wxString exprStr = ctx.GetString(0);
 
3681
    wxString textStr = ctx.GetString(1);
 
3682
    if (!m_exprStr.IsSameAs(exprStr))
 
3683
    {
 
3684
      m_exprStr = exprStr;
 
3685
      m_regEx.Compile(m_exprStr, m_flags);
 
3686
    }
 
3687
    if (m_regEx.IsValid())
 
3688
    {
 
3689
      int rc = (m_regEx.Matches(textStr)) ? 1 : 0;
 
3690
      ctx.SetResult(rc);
 
3691
    }
 
3692
    else
 
3693
    {
 
3694
      ctx.SetResultError(wxString(_("Regular expression invalid: '"))+exprStr+_T("'."));
 
3695
    }
 
3696
  }
 
3697
  else
 
3698
  {
 
3699
    ctx.SetResultError(wxString::Format(_("REGEXP called with wrong number of arguments: %d instead of 2."), argCount));
 
3700
  }
 
3701
}
 
3702
 
 
3703
#endif
 
3704
 
 
3705
// --- Support for named collections
 
3706
 
 
3707
#if WXSQLITE3_USE_NAMED_COLLECTIONS
 
3708
 
 
3709
// The following code is based on the SQLite test_intarray source code.
 
3710
 
 
3711
#include <string.h>
 
3712
#include <assert.h>
 
3713
 
 
3714
/// Definition of the sqlite3_intarray object (internal)
 
3715
struct sqlite3_intarray
 
3716
{
 
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[]
 
3720
};
 
3721
 
 
3722
// Objects used internally by the virtual table implementation
 
3723
typedef struct intarray_vtab intarray_vtab;
 
3724
typedef struct intarray_cursor intarray_cursor;
 
3725
 
 
3726
/// Definition of intarray table object (internal)
 
3727
struct intarray_vtab
 
3728
{
 
3729
  sqlite3_vtab base;            // Base class
 
3730
  sqlite3_intarray* pContent;   // Content of the integer array
 
3731
};
 
3732
 
 
3733
/// Definition of  intarray cursor object (internal)
 
3734
struct intarray_cursor
 
3735
{
 
3736
  sqlite3_vtab_cursor base;    // Base class
 
3737
  int i;                       // Current cursor position
 
3738
};
 
3739
 
 
3740
// Free an sqlite3_intarray object.
 
3741
static void intarrayFree(sqlite3_intarray* p)
 
3742
{
 
3743
  if (p->a != NULL && p->xFree)
 
3744
  {
 
3745
    p->xFree(p->a);
 
3746
  }
 
3747
  sqlite3_free(p);
 
3748
}
 
3749
 
 
3750
// Table destructor for the intarray module.
 
3751
static int intarrayDestroy(sqlite3_vtab* p)
 
3752
{
 
3753
  intarray_vtab* pVtab = (intarray_vtab*)p;
 
3754
  sqlite3_free(pVtab);
 
3755
  return 0;
 
3756
}
 
3757
 
 
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
 
3765
{
 
3766
  int rc = SQLITE_NOMEM;
 
3767
  intarray_vtab* pVtab = (intarray_vtab*) sqlite3_malloc(sizeof(intarray_vtab));
 
3768
 
 
3769
  if (pVtab)
 
3770
  {
 
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)");
 
3774
  }
 
3775
  *ppVtab = (sqlite3_vtab*)pVtab;
 
3776
  return rc;
 
3777
}
 
3778
 
 
3779
// Open a new cursor on the intarray table.
 
3780
static int intarrayOpen(sqlite3_vtab* /*pVTab*/, sqlite3_vtab_cursor** ppCursor)
 
3781
{
 
3782
  int rc = SQLITE_NOMEM;
 
3783
  intarray_cursor* pCur = (intarray_cursor*) sqlite3_malloc(sizeof(intarray_cursor));
 
3784
  if (pCur)
 
3785
  {
 
3786
    memset(pCur, 0, sizeof(intarray_cursor));
 
3787
    *ppCursor = (sqlite3_vtab_cursor *)pCur;
 
3788
    rc = SQLITE_OK;
 
3789
  }
 
3790
  return rc;
 
3791
}
 
3792
 
 
3793
// Close a intarray table cursor.
 
3794
static int intarrayClose(sqlite3_vtab_cursor* cur)
 
3795
{
 
3796
  intarray_cursor* pCur = (intarray_cursor*)cur;
 
3797
  sqlite3_free(pCur);
 
3798
  return SQLITE_OK;
 
3799
}
 
3800
 
 
3801
// Retrieve a column of data.
 
3802
static int intarrayColumn(sqlite3_vtab_cursor* cur, sqlite3_context* ctx, int /*i*/)
 
3803
{
 
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)
 
3807
  {
 
3808
    sqlite3_result_int64(ctx, pVtab->pContent->a[pCur->i]);
 
3809
  }
 
3810
  return SQLITE_OK;
 
3811
}
 
3812
 
 
3813
// Retrieve the current rowid.
 
3814
static int intarrayRowid(sqlite3_vtab_cursor* cur, sqlite_int64* pRowid)
 
3815
{
 
3816
  intarray_cursor* pCur = (intarray_cursor*)cur;
 
3817
  *pRowid = pCur->i;
 
3818
  return SQLITE_OK;
 
3819
}
 
3820
 
 
3821
static int intarrayEof(sqlite3_vtab_cursor* cur)
 
3822
{
 
3823
  intarray_cursor* pCur = (intarray_cursor*)cur;
 
3824
  intarray_vtab* pVtab = (intarray_vtab*)cur->pVtab;
 
3825
  return pCur->i >= pVtab->pContent->n;
 
3826
}
 
3827
 
 
3828
// Advance the cursor to the next row.
 
3829
static int intarrayNext(sqlite3_vtab_cursor* cur)
 
3830
{
 
3831
  intarray_cursor* pCur = (intarray_cursor*)cur;
 
3832
  pCur->i++;
 
3833
  return SQLITE_OK;
 
3834
}
 
3835
 
 
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*/)
 
3840
{
 
3841
  intarray_cursor *pCur = (intarray_cursor *)pVtabCursor;
 
3842
  pCur->i = 0;
 
3843
  return SQLITE_OK;
 
3844
}
 
3845
 
 
3846
// Analyse the WHERE condition.
 
3847
static int intarrayBestIndex(sqlite3_vtab* /*tab*/, sqlite3_index_info* /*pIdxInfo*/)
 
3848
{
 
3849
  return SQLITE_OK;
 
3850
}
 
3851
 
 
3852
// Definition of a virtual table module for integer collections
 
3853
static sqlite3_module intarrayModule =
 
3854
{
 
3855
  0,                           // iVersion
 
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
 
3868
  0,                           // xUpdate
 
3869
  0,                           // xBegin
 
3870
  0,                           // xSync
 
3871
  0,                           // xCommit
 
3872
  0,                           // xRollback
 
3873
  0,                           // xFindMethod
 
3874
  0,                           // xRename
 
3875
};
 
3876
 
 
3877
/// Definition of the sqlite3_chararray object (internal)
 
3878
struct sqlite3_chararray
 
3879
{
 
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[]
 
3883
};
 
3884
 
 
3885
// Objects used internally by the virtual table implementation
 
3886
typedef struct chararray_vtab chararray_vtab;
 
3887
typedef struct chararray_cursor chararray_cursor;
 
3888
 
 
3889
/// Definition of chararray table object (internal)
 
3890
struct chararray_vtab
 
3891
{
 
3892
  sqlite3_vtab base;            // Base class
 
3893
  sqlite3_chararray* pContent;  // Content of the char array
 
3894
};
 
3895
 
 
3896
/// Definition of chararray cursor object (internal)
 
3897
struct chararray_cursor
 
3898
{
 
3899
  sqlite3_vtab_cursor base;    // Base class
 
3900
  int i;                       // Current cursor position
 
3901
};
 
3902
 
 
3903
// Free an sqlite3_chararray object.
 
3904
static void chararrayFree(sqlite3_chararray* p)
 
3905
{
 
3906
  if (p->a != NULL && p->xFree)
 
3907
  {
 
3908
    int j;
 
3909
    for (j = 0; j < p->n; ++j)
 
3910
    {
 
3911
      p->xFree(p->a[j]);
 
3912
    }
 
3913
    p->xFree(p->a);
 
3914
  }
 
3915
  sqlite3_free(p);
 
3916
}
 
3917
 
 
3918
// Table destructor for the chararray module.
 
3919
static int chararrayDestroy(sqlite3_vtab* p)
 
3920
{
 
3921
  chararray_vtab* pVtab = (chararray_vtab*)p;
 
3922
  sqlite3_free(pVtab);
 
3923
  return 0;
 
3924
}
 
3925
 
 
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
 
3933
{
 
3934
  int rc = SQLITE_NOMEM;
 
3935
  chararray_vtab* pVtab = (chararray_vtab*) sqlite3_malloc(sizeof(chararray_vtab));
 
3936
 
 
3937
  if (pVtab)
 
3938
  {
 
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)");
 
3942
  }
 
3943
  *ppVtab = (sqlite3_vtab*)pVtab;
 
3944
  return rc;
 
3945
}
 
3946
 
 
3947
// Open a new cursor on the chararray table.
 
3948
static int chararrayOpen(sqlite3_vtab* /*pVTab*/, sqlite3_vtab_cursor** ppCursor)
 
3949
{
 
3950
  int rc = SQLITE_NOMEM;
 
3951
  chararray_cursor* pCur = (chararray_cursor*) sqlite3_malloc(sizeof(chararray_cursor));
 
3952
  if (pCur)
 
3953
  {
 
3954
    memset(pCur, 0, sizeof(chararray_cursor));
 
3955
    *ppCursor = (sqlite3_vtab_cursor *)pCur;
 
3956
    rc = SQLITE_OK;
 
3957
  }
 
3958
  return rc;
 
3959
}
 
3960
 
 
3961
// Close a chararray table cursor.
 
3962
static int chararrayClose(sqlite3_vtab_cursor* cur)
 
3963
{
 
3964
  chararray_cursor* pCur = (chararray_cursor*)cur;
 
3965
  sqlite3_free(pCur);
 
3966
  return SQLITE_OK;
 
3967
}
 
3968
 
 
3969
// Retrieve a column of data.
 
3970
static int chararrayColumn(sqlite3_vtab_cursor* cur, sqlite3_context* ctx, int /*i*/)
 
3971
{
 
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)
 
3975
  {
 
3976
    sqlite3_result_text(ctx, pVtab->pContent->a[pCur->i], -1, SQLITE_STATIC);
 
3977
  }
 
3978
  return SQLITE_OK;
 
3979
}
 
3980
 
 
3981
// Retrieve the current rowid.
 
3982
static int chararrayRowid(sqlite3_vtab_cursor* cur, sqlite_int64* pRowid)
 
3983
{
 
3984
  chararray_cursor* pCur = (chararray_cursor*)cur;
 
3985
  *pRowid = pCur->i;
 
3986
  return SQLITE_OK;
 
3987
}
 
3988
 
 
3989
static int chararrayEof(sqlite3_vtab_cursor* cur)
 
3990
{
 
3991
  chararray_cursor* pCur = (chararray_cursor*)cur;
 
3992
  chararray_vtab* pVtab = (chararray_vtab*)cur->pVtab;
 
3993
  return pCur->i >= pVtab->pContent->n;
 
3994
}
 
3995
 
 
3996
// Advance the cursor to the next row.
 
3997
static int chararrayNext(sqlite3_vtab_cursor* cur)
 
3998
{
 
3999
  chararray_cursor* pCur = (chararray_cursor*)cur;
 
4000
  pCur->i++;
 
4001
  return SQLITE_OK;
 
4002
}
 
4003
 
 
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*/)
 
4008
{
 
4009
  chararray_cursor *pCur = (chararray_cursor *)pVtabCursor;
 
4010
  pCur->i = 0;
 
4011
  return SQLITE_OK;
 
4012
}
 
4013
 
 
4014
// Analyse the WHERE condition.
 
4015
static int chararrayBestIndex(sqlite3_vtab* /*tab*/, sqlite3_index_info* /*pIdxInfo*/)
 
4016
{
 
4017
  return SQLITE_OK;
 
4018
}
 
4019
 
 
4020
// Definition of a virtual table module for string collections
 
4021
static sqlite3_module chararrayModule =
 
4022
{
 
4023
  0,                           // iVersion
 
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
 
4036
  0,                           // xUpdate
 
4037
  0,                           // xBegin
 
4038
  0,                           // xSync
 
4039
  0,                           // xCommit
 
4040
  0,                           // xRollback
 
4041
  0,                           // xFindMethod
 
4042
  0,                           // xRename
 
4043
};
 
4044
 
 
4045
#endif // WXSQLITE3_USE_NAMED_COLLECTIONS
 
4046
 
 
4047
wxSQLite3NamedCollection::wxSQLite3NamedCollection()
 
4048
{
 
4049
  m_name = wxEmptyString;
 
4050
  m_data = NULL;
 
4051
}
 
4052
 
 
4053
wxSQLite3NamedCollection::wxSQLite3NamedCollection(const wxString& collectionName, void* collectionData)
 
4054
{
 
4055
  m_name = collectionName;
 
4056
  m_data = collectionData;
 
4057
}
 
4058
 
 
4059
wxSQLite3NamedCollection::wxSQLite3NamedCollection(const wxSQLite3NamedCollection& collection)
 
4060
  : m_name(collection.m_name), m_data(collection.m_data)
 
4061
{
 
4062
}
 
4063
 
 
4064
wxSQLite3NamedCollection&
 
4065
wxSQLite3NamedCollection::operator=(const wxSQLite3NamedCollection& collection)
 
4066
{
 
4067
  if (this != &collection)
 
4068
  {
 
4069
    m_name = collection.m_name;
 
4070
    m_data = collection.m_data;
 
4071
  }
 
4072
  return *this;
 
4073
}
 
4074
 
 
4075
wxSQLite3NamedCollection::~wxSQLite3NamedCollection()
 
4076
{
 
4077
}
 
4078
 
 
4079
wxSQLite3IntegerCollection::wxSQLite3IntegerCollection()
 
4080
  : wxSQLite3NamedCollection(wxEmptyString, NULL)
 
4081
{
 
4082
}
 
4083
 
 
4084
wxSQLite3IntegerCollection::wxSQLite3IntegerCollection(const wxSQLite3IntegerCollection& collection)
 
4085
  : wxSQLite3NamedCollection(collection)
 
4086
{
 
4087
}
 
4088
 
 
4089
wxSQLite3IntegerCollection&
 
4090
wxSQLite3IntegerCollection::operator=(const wxSQLite3IntegerCollection& collection)
 
4091
{
 
4092
  if (this != &collection)
 
4093
  {
 
4094
    wxSQLite3NamedCollection::operator=(collection);
 
4095
  }
 
4096
  return *this;
 
4097
}
 
4098
 
 
4099
wxSQLite3IntegerCollection::wxSQLite3IntegerCollection(const wxString& collectionName, void* collectionData)
 
4100
  : wxSQLite3NamedCollection(collectionName, collectionData)
 
4101
{
 
4102
}
 
4103
 
 
4104
wxSQLite3IntegerCollection::~wxSQLite3IntegerCollection()
 
4105
{
 
4106
}
 
4107
 
 
4108
void
 
4109
wxSQLite3IntegerCollection::Bind(const wxArrayInt& integerCollection)
 
4110
{
 
4111
  size_t n = integerCollection.Count();
 
4112
  sqlite3_intarray* pIntArray = (sqlite3_intarray*) m_data;
 
4113
  if (m_data != NULL)
 
4114
  {
 
4115
    if (pIntArray->a != NULL && pIntArray->xFree)
 
4116
    {
 
4117
      pIntArray->xFree(pIntArray->a);
 
4118
    }
 
4119
  }
 
4120
  pIntArray->n = n;
 
4121
  if (n > 0)
 
4122
  {
 
4123
    pIntArray->a = (sqlite3_int64*) sqlite3_malloc(sizeof(sqlite3_int64)*n);
 
4124
    pIntArray->xFree = sqlite3_free;
 
4125
  }
 
4126
  else
 
4127
  {
 
4128
    pIntArray->a = NULL;
 
4129
    pIntArray->xFree = NULL;
 
4130
  }
 
4131
 
 
4132
  size_t j;
 
4133
  for (j = 0; j < n; ++j)
 
4134
  {
 
4135
    pIntArray->a[j] = integerCollection[j];
 
4136
  }
 
4137
}
 
4138
 
 
4139
void
 
4140
wxSQLite3IntegerCollection::Bind(int n, int* integerCollection)
 
4141
{
 
4142
  sqlite3_intarray* pIntArray = (sqlite3_intarray*) m_data;
 
4143
  if (m_data != NULL)
 
4144
  {
 
4145
    if (pIntArray->a != NULL && pIntArray->xFree)
 
4146
    {
 
4147
      pIntArray->xFree(pIntArray->a);
 
4148
    }
 
4149
  }
 
4150
  pIntArray->n = n;
 
4151
  if (n > 0)
 
4152
  {
 
4153
    pIntArray->a = (sqlite3_int64*) sqlite3_malloc(sizeof(sqlite3_int64)*n);
 
4154
    pIntArray->xFree = sqlite3_free;
 
4155
  }
 
4156
  else
 
4157
  {
 
4158
    pIntArray->a = NULL;
 
4159
    pIntArray->xFree = NULL;
 
4160
  }
 
4161
 
 
4162
  int j;
 
4163
  for (j = 0; j < n; ++j)
 
4164
  {
 
4165
    pIntArray->a[j] = integerCollection[j];
 
4166
  }
 
4167
}
 
4168
 
 
4169
wxSQLite3IntegerCollection
 
4170
wxSQLite3Database::CreateIntegerCollection(const wxString& collectionName)
 
4171
{
 
4172
#if WXSQLITE3_USE_NAMED_COLLECTIONS
 
4173
  int rc = SQLITE_OK;
 
4174
  wxCharBuffer strCollectionName = collectionName.ToUTF8();
 
4175
  const char* zName = strCollectionName;
 
4176
  sqlite3_intarray* p = (sqlite3_intarray*) sqlite3_malloc( sizeof(*p) );
 
4177
  if (p == 0)
 
4178
  {
 
4179
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMEM);
 
4180
  }
 
4181
  p->n = 0;
 
4182
  p->a= NULL;
 
4183
  p->xFree = NULL;
 
4184
  rc = sqlite3_create_module_v2((sqlite3*)m_db, zName, &intarrayModule, p, (void(*)(void*))intarrayFree);
 
4185
  if (rc == SQLITE_OK)
 
4186
  {
 
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);
 
4190
  }
 
4191
  if (rc != SQLITE_OK)
 
4192
  {
 
4193
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
4194
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
4195
  }
 
4196
  return wxSQLite3IntegerCollection(collectionName, p);
 
4197
#else
 
4198
  wxUnusedVar(collectionName);
 
4199
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOCOLLECTIONS);
 
4200
#endif // WXSQLITE3_USE_NAMED_COLLECTIONS
 
4201
}
 
4202
 
 
4203
wxSQLite3StringCollection::wxSQLite3StringCollection()
 
4204
  : wxSQLite3NamedCollection(wxEmptyString, NULL)
 
4205
{
 
4206
}
 
4207
 
 
4208
wxSQLite3StringCollection::wxSQLite3StringCollection(const wxSQLite3StringCollection& collection)
 
4209
  : wxSQLite3NamedCollection(collection)
 
4210
{
 
4211
}
 
4212
 
 
4213
wxSQLite3StringCollection&
 
4214
wxSQLite3StringCollection::operator=(const wxSQLite3StringCollection& collection)
 
4215
{
 
4216
  if (this != &collection)
 
4217
  {
 
4218
    wxSQLite3StringCollection::operator=(collection);
 
4219
  }
 
4220
  return *this;
 
4221
}
 
4222
 
 
4223
wxSQLite3StringCollection::wxSQLite3StringCollection(const wxString& collectionName, void* collectionData)
 
4224
  : wxSQLite3NamedCollection(collectionName, collectionData)
 
4225
{
 
4226
}
 
4227
 
 
4228
wxSQLite3StringCollection::~wxSQLite3StringCollection()
 
4229
{
 
4230
}
 
4231
 
 
4232
void
 
4233
wxSQLite3StringCollection::Bind(const wxArrayString& stringCollection)
 
4234
{
 
4235
  size_t n = stringCollection.Count();
 
4236
  sqlite3_chararray* pCharArray = (sqlite3_chararray*) m_data;
 
4237
  if (m_data != NULL)
 
4238
  {
 
4239
    if (pCharArray->a != NULL && pCharArray->xFree)
 
4240
    {
 
4241
      pCharArray->xFree(pCharArray->a);
 
4242
    }
 
4243
  }
 
4244
  pCharArray->n = n;
 
4245
  if (n > 0)
 
4246
  {
 
4247
    pCharArray->a = (char**) sqlite3_malloc(sizeof(char*)*n);
 
4248
    pCharArray->xFree = sqlite3_free;
 
4249
  }
 
4250
  else
 
4251
  {
 
4252
    pCharArray->a = NULL;
 
4253
    pCharArray->xFree = NULL;
 
4254
  }
 
4255
 
 
4256
  size_t j;
 
4257
  for (j = 0; j < n; ++j)
 
4258
  {
 
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);
 
4264
  }
 
4265
}
 
4266
 
 
4267
wxSQLite3StringCollection
 
4268
wxSQLite3Database::CreateStringCollection(const wxString& collectionName)
 
4269
{
 
4270
#if WXSQLITE3_USE_NAMED_COLLECTIONS
 
4271
  int rc = SQLITE_OK;
 
4272
  wxCharBuffer strCollectionName = collectionName.ToUTF8();
 
4273
  const char* zName = strCollectionName;
 
4274
  sqlite3_chararray* p = (sqlite3_chararray*) sqlite3_malloc( sizeof(*p) );
 
4275
  if (p == 0)
 
4276
  {
 
4277
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMEM);
 
4278
  }
 
4279
  p->n = 0;
 
4280
  p->a= NULL;
 
4281
  p->xFree = NULL;
 
4282
  rc = sqlite3_create_module_v2((sqlite3*)m_db, zName, &chararrayModule, p, (void(*)(void*))chararrayFree);
 
4283
  if (rc == SQLITE_OK)
 
4284
  {
 
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);
 
4288
  }
 
4289
  if (rc != SQLITE_OK)
 
4290
  {
 
4291
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
4292
    throw wxSQLite3Exception(rc, wxString::FromUTF8(localError));
 
4293
  }
 
4294
  return wxSQLite3StringCollection(collectionName, p);
 
4295
#else
 
4296
  wxUnusedVar(collectionName);
 
4297
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOCOLLECTIONS);
 
4298
#endif // WXSQLITE3_USE_NAMED_COLLECTIONS
 
4299
}
 
4300