~s-cecilio/lenmus/v5.3

« back to all changes in this revision

Viewing changes to packages/wxSQLite3/src/wxsqlite3.cpp

  • Committer: cecilios
  • Date: 2012-09-11 16:59:18 UTC
  • Revision ID: svn-v4:2587a929-2f0e-0410-ae78-fe6f687d5efe:branches/TRY-5.0:730
Paths: fixed problem with installation folders. Fixed Chinese ISO language code

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
//wxWidgets
 
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/wxsqlite3.h"
 
29
#include "wx/wxsqlite3opt.h"
 
30
 
 
31
// Suppress some Visual C++ warnings regarding the default constructor
 
32
// for a C struct used only in SQLite modules
 
33
#ifdef __VISUALC__
 
34
#pragma warning (disable:4510)
 
35
#pragma warning (disable:4610)
 
36
#endif
 
37
 
 
38
#include "sqlite3.h"
 
39
 
 
40
// Dynamic loading of the SQLite library
 
41
 
 
42
#if wxUSE_DYNAMIC_SQLITE3_LOAD
 
43
 
 
44
#include "wx/dynlib.h"
 
45
 
 
46
#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
 
47
  typedef rtype (*p##fname) farg ; \
 
48
  static p##fname s_##fname = NULL;
 
49
#include "wx/wxsqlite3dyn.h"
 
50
#undef DYNFUNC
 
51
 
 
52
static wxDynamicLibrary s_dll;
 
53
 
 
54
static void InitSQLite3DLL()
 
55
{
 
56
  if (s_dll.IsLoaded())
 
57
  {
 
58
    return;
 
59
  }
 
60
 
 
61
#ifdef __WIN32__
 
62
  if (! s_dll.Load(wxT("sqlite3")))
 
63
#else
 
64
  if (! s_dll.Load(wxT("libsqlite3")))
 
65
#endif
 
66
  {
 
67
    throw wxSQLite3Exception(-1, wxT("error loading dynamic library"));
 
68
  }
 
69
 
 
70
#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
 
71
  s_##fname = (p##fname) s_dll.GetSymbol(wxT(#fname));\
 
72
  if (! s_##fname)\
 
73
  {\
 
74
    s_dll.Unload();\
 
75
    throw wxSQLite3Exception(-1, wxT("error getting symbol <") wxT(#fname) wxT(">"));\
 
76
  }
 
77
#include "wx/wxsqlite3dyn.h"
 
78
#undef DYNFUNC
 
79
 
 
80
};
 
81
 
 
82
#define DYNFUNC(rcode, rtype, fname, farg, farguse) \
 
83
  rtype fname farg \
 
84
  {\
 
85
    InitSQLite3DLL();\
 
86
    rcode s_##fname farguse;\
 
87
  };
 
88
#include "wx/wxsqlite3dyn.h"
 
89
#undef DYNFUNC
 
90
 
 
91
#endif // wxUSE_DYNAMIC_SQLITE3_LOAD
 
92
 
 
93
// Error messages
 
94
 
 
95
const wxChar* wxERRMSG_NODB          = wxTRANSLATE("No Database opened");
 
96
const wxChar* wxERRMSG_NOSTMT        = wxTRANSLATE("Statement not accessible");
 
97
const wxChar* wxERRMSG_NOMEM         = wxTRANSLATE("Out of memory");
 
98
const wxChar* wxERRMSG_DECODE        = wxTRANSLATE("Cannot decode binary");
 
99
const wxChar* wxERRMSG_INVALID_INDEX = wxTRANSLATE("Invalid field index");
 
100
const wxChar* wxERRMSG_INVALID_NAME  = wxTRANSLATE("Invalid field name");
 
101
const wxChar* wxERRMSG_INVALID_ROW   = wxTRANSLATE("Invalid row index");
 
102
const wxChar* wxERRMSG_INVALID_QUERY = wxTRANSLATE("Invalid scalar query");
 
103
const wxChar* wxERRMSG_INVALID_BLOB  = wxTRANSLATE("Invalid BLOB handle");
 
104
 
 
105
const wxChar* wxERRMSG_NORESULT      = wxTRANSLATE("Null Results pointer");
 
106
const wxChar* wxERRMSG_BIND_STR      = wxTRANSLATE("Error binding string param");
 
107
const wxChar* wxERRMSG_BIND_INT      = wxTRANSLATE("Error binding int param");
 
108
const wxChar* wxERRMSG_BIND_INT64    = wxTRANSLATE("Error binding int64 param");
 
109
const wxChar* wxERRMSG_BIND_DBL      = wxTRANSLATE("Error binding double param");
 
110
const wxChar* wxERRMSG_BIND_BLOB     = wxTRANSLATE("Error binding blob param");
 
111
const wxChar* wxERRMSG_BIND_DATETIME = wxTRANSLATE("Error binding date/time param");
 
112
const wxChar* wxERRMSG_BIND_NULL     = wxTRANSLATE("Error binding NULL param");
 
113
const wxChar* wxERRMSG_BIND_ZEROBLOB = wxTRANSLATE("Error binding zero blob param");
 
114
const wxChar* wxERRMSG_BIND_CLEAR    = wxTRANSLATE("Error clearing bindings");
 
115
 
 
116
const wxChar* wxERRMSG_NOMETADATA    = wxTRANSLATE("Meta data support not available");
 
117
const wxChar* wxERRMSG_NOCODEC       = wxTRANSLATE("Encryption support not available");
 
118
const wxChar* wxERRMSG_NOLOADEXT     = wxTRANSLATE("Loadable extension support not available");
 
119
const wxChar* wxERRMSG_NOINCBLOB     = wxTRANSLATE("Incremental BLOB support not available");
 
120
const wxChar* wxERRMSG_NOSAVEPOINT   = wxTRANSLATE("Savepoint support not available");
 
121
 
 
122
const wxChar* wxERRMSG_SHARED_CACHE  = wxTRANSLATE("Setting SQLite shared cache mode failed");
 
123
 
 
124
const wxChar* wxERRMSG_INITIALIZE    = wxTRANSLATE("Initialization of SQLite failed");
 
125
const wxChar* wxERRMSG_SHUTDOWN      = wxTRANSLATE("Shutdown of SQLite failed");
 
126
 
 
127
// ----------------------------------------------------------------------------
 
128
// inline conversion from UTF8 strings to wxStringe
 
129
// ----------------------------------------------------------------------------
 
130
 
 
131
inline wxString UTF8toWxString(const char* localValue)
 
132
{
 
133
#if wxUSE_UNICODE
 
134
  return wxString(localValue, wxConvUTF8);
 
135
#else
 
136
  return wxString(wxConvUTF8.cMB2WC(localValue), *wxConvCurrent);
 
137
#endif
 
138
}
 
139
 
 
140
// ----------------------------------------------------------------------------
 
141
// inline conversion from wxString to wxLongLong
 
142
// ----------------------------------------------------------------------------
 
143
 
 
144
inline wxLongLong ConvertStringToLongLong(const wxString& str, wxLongLong defValue /*=0*/)
 
145
{
 
146
  size_t n = str.Length();
 
147
  size_t j = 0;
 
148
  wxLongLong value = 0;
 
149
  bool negative = false;
 
150
 
 
151
  if (str[j] == '-')
 
152
  {
 
153
    negative = true;
 
154
    j++;
 
155
  }
 
156
 
 
157
  while (j < n)
 
158
  {
 
159
    if (str[j] < '0' || str[j] > '9')
 
160
    {
 
161
      return defValue;
 
162
    }
 
163
    value *= 10;
 
164
    value += (str[j] - '0');
 
165
    j++;
 
166
  }
 
167
 
 
168
  return negative ? -value : value;
 
169
}
 
170
 
 
171
// ----------------------------------------------------------------------------
 
172
// wxSQLite3Exception: class 
 
173
// ----------------------------------------------------------------------------
 
174
 
 
175
wxSQLite3Exception::wxSQLite3Exception(int errorCode, const wxString& errorMsg)
 
176
  : m_errorCode(errorCode)
 
177
{
 
178
  m_errorMessage = ErrorCodeAsString(errorCode) + _T("[") +
 
179
                   wxString::Format(_T("%d"), errorCode) + _T("]: ") +
 
180
                   wxGetTranslation(errorMsg);
 
181
}
 
182
 
 
183
wxSQLite3Exception::wxSQLite3Exception(const wxSQLite3Exception&  e)
 
184
  : m_errorCode(e.m_errorCode), m_errorMessage(e.m_errorMessage)
 
185
{
 
186
}
 
187
 
 
188
const wxString wxSQLite3Exception::ErrorCodeAsString(int errorCode)
 
189
{
 
190
  switch (errorCode)
 
191
  {
 
192
    case SQLITE_OK          : return _T("SQLITE_OK");
 
193
    case SQLITE_ERROR       : return _T("SQLITE_ERROR");
 
194
    case SQLITE_INTERNAL    : return _T("SQLITE_INTERNAL");
 
195
    case SQLITE_PERM        : return _T("SQLITE_PERM");
 
196
    case SQLITE_ABORT       : return _T("SQLITE_ABORT");
 
197
    case SQLITE_BUSY        : return _T("SQLITE_BUSY");
 
198
    case SQLITE_LOCKED      : return _T("SQLITE_LOCKED");
 
199
    case SQLITE_NOMEM       : return _T("SQLITE_NOMEM");
 
200
    case SQLITE_READONLY    : return _T("SQLITE_READONLY");
 
201
    case SQLITE_INTERRUPT   : return _T("SQLITE_INTERRUPT");
 
202
    case SQLITE_IOERR       : return _T("SQLITE_IOERR");
 
203
    case SQLITE_CORRUPT     : return _T("SQLITE_CORRUPT");
 
204
    case SQLITE_NOTFOUND    : return _T("SQLITE_NOTFOUND");
 
205
    case SQLITE_FULL        : return _T("SQLITE_FULL");
 
206
    case SQLITE_CANTOPEN    : return _T("SQLITE_CANTOPEN");
 
207
    case SQLITE_PROTOCOL    : return _T("SQLITE_PROTOCOL");
 
208
    case SQLITE_EMPTY       : return _T("SQLITE_EMPTY");
 
209
    case SQLITE_SCHEMA      : return _T("SQLITE_SCHEMA");
 
210
    case SQLITE_TOOBIG      : return _T("SQLITE_TOOBIG");
 
211
    case SQLITE_CONSTRAINT  : return _T("SQLITE_CONSTRAINT");
 
212
    case SQLITE_MISMATCH    : return _T("SQLITE_MISMATCH");
 
213
    case SQLITE_MISUSE      : return _T("SQLITE_MISUSE");
 
214
    case SQLITE_NOLFS       : return _T("SQLITE_NOLFS");
 
215
    case SQLITE_AUTH        : return _T("SQLITE_AUTH");
 
216
    case SQLITE_FORMAT      : return _T("SQLITE_FORMAT");
 
217
    case SQLITE_RANGE       : return _T("SQLITE_RANGE");
 
218
    case SQLITE_NOTADB      : return _T("SQLITE_NOTADB");
 
219
    case SQLITE_ROW         : return _T("SQLITE_ROW");
 
220
    case SQLITE_DONE        : return _T("SQLITE_DONE");
 
221
    // Extended error codes
 
222
    case SQLITE_IOERR_READ       : return _T("SQLITE_IOERR_READ");
 
223
    case SQLITE_IOERR_SHORT_READ : return _T("SQLITE_IOERR_SHORT_READ");
 
224
    case SQLITE_IOERR_WRITE      : return _T("SQLITE_IOERR_WRITE");
 
225
    case SQLITE_IOERR_FSYNC      : return _T("SQLITE_IOERR_FSYNC");
 
226
    case SQLITE_IOERR_DIR_FSYNC  : return _T("SQLITE_IOERR_DIR_FSYNC");
 
227
    case SQLITE_IOERR_TRUNCATE   : return _T("SQLITE_IOERR_TRUNCATE");
 
228
    case SQLITE_IOERR_FSTAT      : return _T("SQLITE_IOERR_FSTAT");
 
229
    case SQLITE_IOERR_UNLOCK     : return _T("SQLITE_IOERR_UNLOCK");
 
230
    case SQLITE_IOERR_RDLOCK     : return _T("SQLITE_IOERR_RDLOCK");
 
231
    case SQLITE_IOERR_DELETE     : return _T("SQLITE_IOERR_DELETE");
 
232
#if SQLITE_VERSION_NUMBER >= 3004000
 
233
    case SQLITE_IOERR_BLOCKED    : return _T("SQLITE_IOERR_BLOCKED");
 
234
#endif
 
235
#if SQLITE_VERSION_NUMBER >= 3005001
 
236
    case SQLITE_IOERR_NOMEM      : return _T("SQLITE_IOERR_NOMEM");
 
237
#endif
 
238
#if SQLITE_VERSION_NUMBER >= 3006000
 
239
    case SQLITE_IOERR_ACCESS     : return _T("SQLITE_IOERR_ACCESS");
 
240
    case SQLITE_IOERR_CHECKRESERVEDLOCK : return _T("SQLITE_IOERR_CHECKRESERVEDLOCK");
 
241
#endif
 
242
#if SQLITE_VERSION_NUMBER >= 3006002
 
243
    case SQLITE_IOERR_LOCK     : return _T("SQLITE_IOERR_LOCK");
 
244
#endif
 
245
 
 
246
    case WXSQLITE_ERROR     : return _T("WXSQLITE_ERROR");
 
247
    default                 : return _T("UNKNOWN_ERROR");
 
248
  }
 
249
}
 
250
 
 
251
wxSQLite3Exception::~wxSQLite3Exception()
 
252
{
 
253
}
 
254
 
 
255
// ----------------------------------------------------------------------------
 
256
// wxSQLite3StatementBuffer: class providing a statement buffer
 
257
//                           for use with the SQLite3 vmprintf function
 
258
// ----------------------------------------------------------------------------
 
259
 
 
260
wxSQLite3StatementBuffer::wxSQLite3StatementBuffer()
 
261
{
 
262
  m_buffer = 0;
 
263
}
 
264
 
 
265
wxSQLite3StatementBuffer::~wxSQLite3StatementBuffer()
 
266
{
 
267
  Clear();
 
268
}
 
269
 
 
270
void wxSQLite3StatementBuffer::Clear()
 
271
{
 
272
  if (m_buffer)
 
273
  {
 
274
    sqlite3_free(m_buffer);
 
275
    m_buffer = 0;
 
276
  }
 
277
 
 
278
}
 
279
 
 
280
const char* wxSQLite3StatementBuffer::Format(const char* format, ...)
 
281
{
 
282
  Clear();
 
283
  va_list va;
 
284
  va_start(va, format);
 
285
  m_buffer = sqlite3_vmprintf(format, va);
 
286
  va_end(va);
 
287
  return m_buffer;
 
288
}
 
289
 
 
290
// ----------------------------------------------------------------------------
 
291
// wxSQLite3ResultSet: class providing access to the result set of a query
 
292
// ----------------------------------------------------------------------------
 
293
 
 
294
wxSQLite3ResultSet::wxSQLite3ResultSet()
 
295
{
 
296
  m_stmt = 0;
 
297
  m_eof = true;
 
298
  m_first = true;
 
299
  m_cols = 0;
 
300
  m_ownStmt = false;
 
301
}
 
302
 
 
303
wxSQLite3ResultSet::wxSQLite3ResultSet(const wxSQLite3ResultSet& resultSet)
 
304
{
 
305
  m_stmt = resultSet.m_stmt;
 
306
  // Only one object can own the statement
 
307
  const_cast<wxSQLite3ResultSet&>(resultSet).m_stmt = 0;
 
308
  m_eof = resultSet.m_eof;
 
309
  m_first = resultSet.m_first;
 
310
  m_cols = resultSet.m_cols;
 
311
  m_ownStmt = resultSet.m_ownStmt;
 
312
}
 
313
 
 
314
wxSQLite3ResultSet::wxSQLite3ResultSet(void* db,
 
315
                                       void* stmt,
 
316
                                       bool eof,
 
317
                                       bool first,
 
318
                                       bool ownStmt /*=true*/)
 
319
{
 
320
  m_db = db;
 
321
  m_stmt = stmt;
 
322
  m_eof = eof;
 
323
  m_first = first;
 
324
  m_cols = sqlite3_column_count((sqlite3_stmt*) m_stmt);
 
325
  m_ownStmt = ownStmt;
 
326
}
 
327
 
 
328
wxSQLite3ResultSet::~wxSQLite3ResultSet()
 
329
{
 
330
  try
 
331
  {
 
332
    Finalize();
 
333
  }
 
334
  catch (...)
 
335
  {
 
336
  }
 
337
}
 
338
 
 
339
wxSQLite3ResultSet& wxSQLite3ResultSet::operator=(const wxSQLite3ResultSet& resultSet)
 
340
{
 
341
  try
 
342
  {
 
343
    Finalize();
 
344
  }
 
345
  catch (...)
 
346
  {
 
347
  }
 
348
  m_stmt = resultSet.m_stmt;
 
349
  // Only one object can own the statement
 
350
  const_cast<wxSQLite3ResultSet&>(resultSet).m_stmt = 0;
 
351
  m_eof = resultSet.m_eof;
 
352
  m_first = resultSet.m_first;
 
353
  m_cols = resultSet.m_cols;
 
354
  m_ownStmt = resultSet.m_ownStmt;
 
355
  return *this;
 
356
}
 
357
 
 
358
int wxSQLite3ResultSet::GetColumnCount()
 
359
{
 
360
  CheckStmt();
 
361
  return m_cols;
 
362
}
 
363
 
 
364
wxString wxSQLite3ResultSet::GetAsString(int columnIndex)
 
365
{
 
366
  CheckStmt();
 
367
 
 
368
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
369
  {
 
370
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
371
  }
 
372
 
 
373
  const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
 
374
  return UTF8toWxString(localValue);
 
375
}
 
376
 
 
377
wxString wxSQLite3ResultSet::GetAsString(const wxString& columnName)
 
378
{
 
379
  int columnIndex = FindColumnIndex(columnName);
 
380
  const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
 
381
  return UTF8toWxString(localValue);
 
382
}
 
383
 
 
384
int wxSQLite3ResultSet::GetInt(int columnIndex, int nullValue /* = 0 */)
 
385
{
 
386
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
387
  {
 
388
    return nullValue;
 
389
  }
 
390
  else
 
391
  {
 
392
    return sqlite3_column_int((sqlite3_stmt*) m_stmt, columnIndex);
 
393
  }
 
394
}
 
395
 
 
396
 
 
397
int wxSQLite3ResultSet::GetInt(const wxString& columnName, int nullValue /* = 0 */)
 
398
{
 
399
  int columnIndex = FindColumnIndex(columnName);
 
400
  return GetInt(columnIndex, nullValue);
 
401
}
 
402
 
 
403
wxLongLong wxSQLite3ResultSet::GetInt64(int columnIndex, wxLongLong nullValue /* = 0 */)
 
404
{
 
405
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
406
  {
 
407
    return nullValue;
 
408
  }
 
409
  else
 
410
  {
 
411
    return wxLongLong(sqlite3_column_int64((sqlite3_stmt*) m_stmt, columnIndex));
 
412
  }
 
413
}
 
414
 
 
415
wxLongLong wxSQLite3ResultSet::GetInt64(const wxString& columnName, wxLongLong nullValue /* = 0 */)
 
416
{
 
417
  int columnIndex = FindColumnIndex(columnName);
 
418
  return GetInt64(columnIndex, nullValue);
 
419
}
 
420
 
 
421
double wxSQLite3ResultSet::GetDouble(int columnIndex, double nullValue /* = 0.0 */)
 
422
{
 
423
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
424
  {
 
425
    return nullValue;
 
426
  }
 
427
  else
 
428
  {
 
429
    return sqlite3_column_double((sqlite3_stmt*) m_stmt, columnIndex);
 
430
  }
 
431
}
 
432
 
 
433
double wxSQLite3ResultSet::GetDouble(const wxString& columnName, double nullValue /* = 0.0 */)
 
434
{
 
435
  int columnIndex = FindColumnIndex(columnName);
 
436
  return GetDouble(columnIndex, nullValue);
 
437
}
 
438
 
 
439
wxString wxSQLite3ResultSet::GetString(int columnIndex, const wxString& nullValue /* = wxEmptyString */)
 
440
{
 
441
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
442
  {
 
443
    return nullValue;
 
444
  }
 
445
  else
 
446
  {
 
447
    const char* localValue = (const char*) sqlite3_column_text((sqlite3_stmt*) m_stmt, columnIndex);
 
448
    return UTF8toWxString(localValue);
 
449
  }
 
450
}
 
451
 
 
452
wxString wxSQLite3ResultSet::GetString(const wxString& columnName, const wxString& nullValue /* = wxEmptyString */)
 
453
{
 
454
  int columnIndex = FindColumnIndex(columnName);
 
455
  return GetString(columnIndex, nullValue);
 
456
}
 
457
 
 
458
const unsigned char* wxSQLite3ResultSet::GetBlob(int columnIndex, int& len)
 
459
{
 
460
  CheckStmt();
 
461
 
 
462
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
463
  {
 
464
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
465
  }
 
466
 
 
467
  len = sqlite3_column_bytes((sqlite3_stmt*) m_stmt, columnIndex);
 
468
  return (const unsigned char*) sqlite3_column_blob((sqlite3_stmt*) m_stmt, columnIndex);
 
469
}
 
470
 
 
471
const unsigned char* wxSQLite3ResultSet::GetBlob(const wxString& columnName, int& len)
 
472
{
 
473
  int columnIndex = FindColumnIndex(columnName);
 
474
  return GetBlob(columnIndex, len);
 
475
}
 
476
 
 
477
wxMemoryBuffer& wxSQLite3ResultSet::GetBlob(int columnIndex, wxMemoryBuffer& buffer)
 
478
{
 
479
  CheckStmt();
 
480
 
 
481
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
482
  {
 
483
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
484
  }
 
485
 
 
486
  int len = sqlite3_column_bytes((sqlite3_stmt*) m_stmt, columnIndex);
 
487
  const void* blob = sqlite3_column_blob((sqlite3_stmt*) m_stmt, columnIndex);
 
488
  buffer.AppendData((void*) blob, (size_t) len);
 
489
  return buffer;
 
490
}
 
491
 
 
492
wxMemoryBuffer& wxSQLite3ResultSet::GetBlob(const wxString& columnName, wxMemoryBuffer& buffer)
 
493
{
 
494
  int columnIndex = FindColumnIndex(columnName);
 
495
  return GetBlob(columnIndex, buffer);
 
496
}
 
497
 
 
498
wxDateTime wxSQLite3ResultSet::GetDate(int columnIndex)
 
499
{
 
500
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
501
  {
 
502
    return wxInvalidDateTime;
 
503
  }
 
504
  else
 
505
  {
 
506
    wxDateTime date;
 
507
    if (date.ParseDate(GetString(columnIndex)) != NULL)
 
508
    {
 
509
      return date;
 
510
    }
 
511
    else
 
512
    {
 
513
      return wxInvalidDateTime;
 
514
    }
 
515
  }
 
516
}
 
517
 
 
518
wxDateTime wxSQLite3ResultSet::GetDate(const wxString& columnName)
 
519
{
 
520
  int columnIndex = FindColumnIndex(columnName);
 
521
  return GetDate(columnIndex);
 
522
}
 
523
 
 
524
 
 
525
wxDateTime wxSQLite3ResultSet::GetTime(int columnIndex)
 
526
{
 
527
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
528
  {
 
529
    return wxInvalidDateTime;
 
530
  }
 
531
  else
 
532
  {
 
533
    wxDateTime date;
 
534
    if (date.ParseTime(GetString(columnIndex)) != NULL)
 
535
    {
 
536
      return date;
 
537
    }
 
538
    else
 
539
    {
 
540
      return wxInvalidDateTime;
 
541
    }
 
542
  }
 
543
}
 
544
 
 
545
wxDateTime wxSQLite3ResultSet::GetTime(const wxString& columnName)
 
546
{
 
547
  int columnIndex = FindColumnIndex(columnName);
 
548
  return GetTime(columnIndex);
 
549
}
 
550
 
 
551
wxDateTime wxSQLite3ResultSet::GetDateTime(int columnIndex)
 
552
{
 
553
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
554
  {
 
555
    return wxInvalidDateTime;
 
556
  }
 
557
  else
 
558
  {
 
559
    wxDateTime date;
 
560
    if (date.ParseDateTime(GetString(columnIndex)) != NULL)
 
561
    {
 
562
      date.SetMillisecond(0);
 
563
      return date;
 
564
    }
 
565
    else
 
566
    {
 
567
      return wxInvalidDateTime;
 
568
    }
 
569
  }
 
570
}
 
571
 
 
572
wxDateTime wxSQLite3ResultSet::GetDateTime(const wxString& columnName)
 
573
{
 
574
  int columnIndex = FindColumnIndex(columnName);
 
575
  return GetDateTime(columnIndex);
 
576
}
 
577
 
 
578
wxDateTime wxSQLite3ResultSet::GetTimestamp(int columnIndex)
 
579
{
 
580
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
581
  {
 
582
    return wxInvalidDateTime;
 
583
  }
 
584
  else
 
585
  {
 
586
    wxDateTime date;
 
587
    if (date.ParseDateTime(GetString(columnIndex)) != NULL)
 
588
    {
 
589
      return date;
 
590
    }
 
591
    else
 
592
    {
 
593
      return wxInvalidDateTime;
 
594
    }
 
595
  }
 
596
}
 
597
 
 
598
wxDateTime wxSQLite3ResultSet::GetTimestamp(const wxString& columnName)
 
599
{
 
600
  int columnIndex = FindColumnIndex(columnName);
 
601
  return GetTimestamp(columnIndex);
 
602
}
 
603
 
 
604
wxDateTime wxSQLite3ResultSet::GetNumericDateTime(int columnIndex)
 
605
{
 
606
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
607
  {
 
608
    return wxInvalidDateTime;
 
609
  }
 
610
  else
 
611
  {
 
612
    wxLongLong value = GetInt64(columnIndex);
 
613
    return wxDateTime(value);
 
614
  }
 
615
}
 
616
 
 
617
wxDateTime wxSQLite3ResultSet::GetNumericDateTime(const wxString& columnName)
 
618
{
 
619
  int columnIndex = FindColumnIndex(columnName);
 
620
  return GetNumericDateTime(columnIndex);
 
621
}
 
622
 
 
623
wxDateTime wxSQLite3ResultSet::GetJulianDayNumber(int columnIndex)
 
624
{
 
625
  if (GetColumnType(columnIndex) == SQLITE_NULL)
 
626
  {
 
627
    return wxInvalidDateTime;
 
628
  }
 
629
  else
 
630
  {
 
631
    double value = GetDouble(columnIndex);
 
632
    return wxDateTime(value);
 
633
  }
 
634
}
 
635
 
 
636
wxDateTime wxSQLite3ResultSet::GetJulianDayNumber(const wxString& columnName)
 
637
{
 
638
  int columnIndex = FindColumnIndex(columnName);
 
639
  return GetJulianDayNumber(columnIndex);
 
640
}
 
641
 
 
642
bool wxSQLite3ResultSet::GetBool(int columnIndex)
 
643
{
 
644
  return GetInt(columnIndex) != 0;
 
645
}
 
646
 
 
647
bool wxSQLite3ResultSet::GetBool(const wxString& columnName)
 
648
{
 
649
  int columnIndex = FindColumnIndex(columnName);
 
650
  return GetBool(columnIndex);
 
651
}
 
652
 
 
653
bool wxSQLite3ResultSet::IsNull(int columnIndex)
 
654
{
 
655
  return (GetColumnType(columnIndex) == SQLITE_NULL);
 
656
}
 
657
 
 
658
bool wxSQLite3ResultSet::IsNull(const wxString& columnName)
 
659
{
 
660
  int columnIndex = FindColumnIndex(columnName);
 
661
  return (GetColumnType(columnIndex) == SQLITE_NULL);
 
662
}
 
663
 
 
664
int wxSQLite3ResultSet::FindColumnIndex(const wxString& columnName)
 
665
{
 
666
  CheckStmt();
 
667
 
 
668
  wxCharBuffer strColumnName = wxConvUTF8.cWC2MB(columnName.wc_str(*wxConvCurrent));
 
669
  const char* localColumnName = strColumnName;
 
670
 
 
671
  if (columnName.Len() > 0)
 
672
  {
 
673
    for (int columnIndex = 0; columnIndex < m_cols; columnIndex++)
 
674
    {
 
675
      const char* temp = sqlite3_column_name((sqlite3_stmt*) m_stmt, columnIndex);
 
676
 
 
677
      if (strcmp(localColumnName, temp) == 0)
 
678
      {
 
679
        return columnIndex;
 
680
      }
 
681
    }
 
682
  }
 
683
 
 
684
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
685
}
 
686
 
 
687
wxString wxSQLite3ResultSet::GetColumnName(int columnIndex)
 
688
{
 
689
  CheckStmt();
 
690
 
 
691
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
692
  {
 
693
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
694
  }
 
695
 
 
696
  const char* localValue = sqlite3_column_name((sqlite3_stmt*) m_stmt, columnIndex);
 
697
  return UTF8toWxString(localValue);
 
698
}
 
699
 
 
700
wxString wxSQLite3ResultSet::GetDeclaredColumnType(int columnIndex)
 
701
{
 
702
  CheckStmt();
 
703
 
 
704
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
705
  {
 
706
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
707
  }
 
708
 
 
709
  const char* localValue = sqlite3_column_decltype((sqlite3_stmt*) m_stmt, columnIndex);
 
710
  return UTF8toWxString(localValue);
 
711
}
 
712
 
 
713
int wxSQLite3ResultSet::GetColumnType(int columnIndex)
 
714
{
 
715
  CheckStmt();
 
716
 
 
717
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
718
  {
 
719
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
720
  }
 
721
 
 
722
  return sqlite3_column_type((sqlite3_stmt*) m_stmt, columnIndex);
 
723
}
 
724
 
 
725
bool wxSQLite3ResultSet::Eof()
 
726
{
 
727
  CheckStmt();
 
728
  return m_eof;
 
729
}
 
730
 
 
731
bool wxSQLite3ResultSet::NextRow()
 
732
{
 
733
  CheckStmt();
 
734
 
 
735
  int rc;
 
736
  if (m_first)
 
737
  {
 
738
    m_first = false;
 
739
    rc = (m_eof) ? SQLITE_DONE : SQLITE_ROW;
 
740
  }
 
741
  else
 
742
  {
 
743
    rc = sqlite3_step((sqlite3_stmt*) m_stmt);
 
744
  }
 
745
 
 
746
  if (rc == SQLITE_DONE) // no more rows
 
747
  {
 
748
    m_eof = true;
 
749
    return false;
 
750
  }
 
751
  else if (rc == SQLITE_ROW) // more rows
 
752
  {
 
753
    return true;
 
754
  }
 
755
  else
 
756
  {
 
757
    rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
 
758
    m_stmt = 0;
 
759
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
760
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
761
  }
 
762
}
 
763
 
 
764
void wxSQLite3ResultSet::Finalize()
 
765
{
 
766
  if (m_stmt && m_ownStmt)
 
767
  {
 
768
    int rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
 
769
    m_stmt = 0;
 
770
    if (rc != SQLITE_OK)
 
771
    {
 
772
      const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
773
      throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
774
    }
 
775
  }
 
776
}
 
777
 
 
778
wxString wxSQLite3ResultSet::GetSQL()
 
779
{
 
780
  wxString sqlString = wxEmptyString;
 
781
#if SQLITE_VERSION_NUMBER >= 3005003
 
782
  CheckStmt();
 
783
  const char* sqlLocal = sqlite3_sql((sqlite3_stmt*) m_stmt);
 
784
  if (sqlLocal != NULL) sqlString = UTF8toWxString(sqlLocal);
 
785
#endif
 
786
  return sqlString;
 
787
}
 
788
 
 
789
bool wxSQLite3ResultSet::IsOk()
 
790
{
 
791
  return (m_db != 0) && (m_stmt != 0);
 
792
}
 
793
 
 
794
void wxSQLite3ResultSet::CheckStmt()
 
795
{
 
796
  if (m_stmt == 0)
 
797
  {
 
798
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSTMT);
 
799
  }
 
800
}
 
801
 
 
802
wxString wxSQLite3ResultSet::GetDatabaseName(int columnIndex)
 
803
{
 
804
#if WXSQLITE3_HAVE_METADATA
 
805
  CheckStmt();
 
806
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
807
  {
 
808
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
809
  }
 
810
 
 
811
  const char* localValue = sqlite3_column_database_name((sqlite3_stmt*) m_stmt, columnIndex);
 
812
  if (localValue != NULL)
 
813
    return UTF8toWxString(localValue);
 
814
  else
 
815
    return wxEmptyString;
 
816
#else
 
817
  wxUnusedVar(columnIndex);
 
818
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
 
819
#endif
 
820
}
 
821
 
 
822
wxString wxSQLite3ResultSet::GetTableName(int columnIndex)
 
823
{
 
824
#if WXSQLITE3_HAVE_METADATA
 
825
  CheckStmt();
 
826
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
827
  {
 
828
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
829
  }
 
830
 
 
831
  const char* localValue = sqlite3_column_table_name((sqlite3_stmt*) m_stmt, columnIndex);
 
832
  if (localValue != NULL)
 
833
    return UTF8toWxString(localValue);
 
834
  else
 
835
    return wxEmptyString;
 
836
#else
 
837
  wxUnusedVar(columnIndex);
 
838
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
 
839
#endif
 
840
}
 
841
 
 
842
wxString wxSQLite3ResultSet::GetOriginName(int columnIndex)
 
843
{
 
844
#if WXSQLITE3_HAVE_METADATA
 
845
  CheckStmt();
 
846
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
847
  {
 
848
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
849
  }
 
850
 
 
851
  const char* localValue = sqlite3_column_origin_name((sqlite3_stmt*) m_stmt, columnIndex);
 
852
  if (localValue != NULL)
 
853
    return UTF8toWxString(localValue);
 
854
  else
 
855
    return wxEmptyString;
 
856
#else
 
857
  wxUnusedVar(columnIndex);
 
858
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
 
859
#endif
 
860
}
 
861
 
 
862
// ----------------------------------------------------------------------------
 
863
// wxSQLite3Table: class holding the complete result set of a query
 
864
// ----------------------------------------------------------------------------
 
865
 
 
866
wxSQLite3Table::wxSQLite3Table()
 
867
{
 
868
  m_results = 0;
 
869
  m_rows = 0;
 
870
  m_cols = 0;
 
871
  m_currentRow = 0;
 
872
}
 
873
 
 
874
wxSQLite3Table::wxSQLite3Table(const wxSQLite3Table& table)
 
875
{
 
876
  m_results = table.m_results;
 
877
  // Only one object can own the results
 
878
  const_cast<wxSQLite3Table&>(table).m_results = 0;
 
879
  m_rows = table.m_rows;
 
880
  m_cols = table.m_cols;
 
881
  m_currentRow = table.m_currentRow;
 
882
}
 
883
 
 
884
wxSQLite3Table::wxSQLite3Table(char** results, int rows, int cols)
 
885
{
 
886
  m_results = results;
 
887
  m_rows = rows;
 
888
  m_cols = cols;
 
889
  m_currentRow = 0;
 
890
}
 
891
 
 
892
wxSQLite3Table::~wxSQLite3Table()
 
893
{
 
894
  try
 
895
  {
 
896
    Finalize();
 
897
  }
 
898
  catch (...)
 
899
  {
 
900
  }
 
901
}
 
902
 
 
903
wxSQLite3Table& wxSQLite3Table::operator=(const wxSQLite3Table& table)
 
904
{
 
905
  try
 
906
  {
 
907
    Finalize();
 
908
  }
 
909
  catch (...)
 
910
  {
 
911
  }
 
912
  m_results = table.m_results;
 
913
  // Only one object can own the results
 
914
  const_cast<wxSQLite3Table&>(table).m_results = 0;
 
915
  m_rows = table.m_rows;
 
916
  m_cols = table.m_cols;
 
917
  m_currentRow = table.m_currentRow;
 
918
  return *this;
 
919
}
 
920
 
 
921
void wxSQLite3Table::Finalize()
 
922
{
 
923
  if (m_results)
 
924
  {
 
925
    sqlite3_free_table(m_results);
 
926
    m_results = 0;
 
927
  }
 
928
}
 
929
 
 
930
int wxSQLite3Table::GetColumnCount()
 
931
{
 
932
  CheckResults();
 
933
  return m_cols;
 
934
}
 
935
 
 
936
int wxSQLite3Table::GetRowCount()
 
937
{
 
938
  CheckResults();
 
939
  return m_rows;
 
940
}
 
941
 
 
942
int wxSQLite3Table::FindColumnIndex(const wxString& columnName)
 
943
{
 
944
  CheckResults();
 
945
 
 
946
  wxCharBuffer strColumnName = wxConvUTF8.cWC2MB(columnName.wc_str(*wxConvCurrent));
 
947
  const char* localColumnName = strColumnName;
 
948
 
 
949
  if (columnName.Len() > 0)
 
950
  {
 
951
    for (int columnIndex = 0; columnIndex < m_cols; columnIndex++)
 
952
    {
 
953
      if (strcmp(localColumnName, m_results[columnIndex]) == 0)
 
954
      {
 
955
        return columnIndex;
 
956
      }
 
957
    }
 
958
  }
 
959
 
 
960
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_NAME);
 
961
}
 
962
 
 
963
wxString wxSQLite3Table::GetAsString(int columnIndex)
 
964
{
 
965
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
966
  {
 
967
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
968
  }
 
969
 
 
970
  int nIndex = (m_currentRow*m_cols) + m_cols + columnIndex;
 
971
  const char* localValue = m_results[nIndex];
 
972
  return UTF8toWxString(localValue);
 
973
}
 
974
 
 
975
wxString wxSQLite3Table::GetAsString(const wxString& columnName)
 
976
{
 
977
  int index = FindColumnIndex(columnName);
 
978
  return GetAsString(index);
 
979
}
 
980
 
 
981
int wxSQLite3Table::GetInt(int columnIndex, int nullValue /* = 0 */)
 
982
{
 
983
  if (IsNull(columnIndex))
 
984
  {
 
985
    return nullValue;
 
986
  }
 
987
  else
 
988
  {
 
989
    long value = nullValue;
 
990
    GetAsString(columnIndex).ToLong(&value);
 
991
    return (int) value;
 
992
  }
 
993
}
 
994
 
 
995
int wxSQLite3Table::GetInt(const wxString& columnName, int nullValue /* = 0 */)
 
996
{
 
997
  if (IsNull(columnName))
 
998
  {
 
999
    return nullValue;
 
1000
  }
 
1001
  else
 
1002
  {
 
1003
    long value = nullValue;
 
1004
    GetAsString(columnName).ToLong(&value);
 
1005
    return (int) value;
 
1006
  }
 
1007
}
 
1008
 
 
1009
wxLongLong wxSQLite3Table::GetInt64(int columnIndex, wxLongLong nullValue /* = 0 */)
 
1010
{
 
1011
  if (IsNull(columnIndex))
 
1012
  {
 
1013
    return nullValue;
 
1014
  }
 
1015
  else
 
1016
  {
 
1017
    return ConvertStringToLongLong(GetAsString(columnIndex), nullValue);
 
1018
  }
 
1019
}
 
1020
 
 
1021
wxLongLong wxSQLite3Table::GetInt64(const wxString& columnName, wxLongLong nullValue /* = 0 */)
 
1022
{
 
1023
  if (IsNull(columnName))
 
1024
  {
 
1025
    return nullValue;
 
1026
  }
 
1027
  else
 
1028
  {
 
1029
    return ConvertStringToLongLong(GetAsString(columnName), nullValue);
 
1030
  }
 
1031
}
 
1032
 
 
1033
// Since SQLite uses internally a locale independent string representation
 
1034
// of double values, we need to provide our own conversion procedure using
 
1035
// always a point as the decimal separator.
 
1036
// The following code duplicates a SQLite utility function with minor modifications.
 
1037
 
 
1038
static double wxSQLite3AtoF(const char *z)
 
1039
{
 
1040
  int sign = 1;
 
1041
  long double v1 = 0.0;
 
1042
  int nSignificant = 0;
 
1043
  while (isspace(*(unsigned char*)z))
 
1044
  {
 
1045
    ++z;
 
1046
  }
 
1047
  if (*z == '-')
 
1048
  {
 
1049
    sign = -1;
 
1050
    ++z;
 
1051
  }
 
1052
  else if (*z == '+')
 
1053
  {
 
1054
    ++z;
 
1055
  }
 
1056
  while (*z == '0')
 
1057
  {
 
1058
    ++z;
 
1059
  }
 
1060
  while (isdigit(*(unsigned char*)z))
 
1061
  {
 
1062
    v1 = v1*10.0 + (*z - '0');
 
1063
    ++z;
 
1064
    ++nSignificant;
 
1065
  }
 
1066
  if (*z == '.')
 
1067
  {
 
1068
    long double divisor = 1.0;
 
1069
    ++z;
 
1070
    if (nSignificant == 0)
 
1071
    {
 
1072
      while (*z == '0')
 
1073
      {
 
1074
        divisor *= 10.0;
 
1075
        ++z;
 
1076
      }
 
1077
    }
 
1078
    while (isdigit(*(unsigned char*)z))
 
1079
    {
 
1080
      if (nSignificant < 18)
 
1081
      {
 
1082
        v1 = v1*10.0 + (*z - '0');
 
1083
        divisor *= 10.0;
 
1084
        ++nSignificant;
 
1085
      }
 
1086
      ++z;
 
1087
    }
 
1088
    v1 /= divisor;
 
1089
  }
 
1090
  if (*z=='e' || *z=='E')
 
1091
  {
 
1092
    int esign = 1;
 
1093
    int eval = 0;
 
1094
    long double scale = 1.0;
 
1095
    ++z;
 
1096
    if (*z == '-')
 
1097
    {
 
1098
      esign = -1;
 
1099
      ++z;
 
1100
    }
 
1101
    else if (*z == '+')
 
1102
    {
 
1103
      ++z;
 
1104
    }
 
1105
    while (isdigit(*(unsigned char*)z))
 
1106
    {
 
1107
      eval = eval*10 + *z - '0';
 
1108
      ++z;
 
1109
    }
 
1110
    while (eval >= 64) { scale *= 1.0e+64; eval -= 64; }
 
1111
    while (eval >= 16) { scale *= 1.0e+16; eval -= 16; }
 
1112
    while (eval >=  4) { scale *= 1.0e+4;  eval -= 4; }
 
1113
    while (eval >=  1) { scale *= 1.0e+1;  eval -= 1; }
 
1114
    if (esign < 0)
 
1115
    {
 
1116
      v1 /= scale;
 
1117
    }
 
1118
    else
 
1119
    {
 
1120
      v1 *= scale;
 
1121
    }
 
1122
  }
 
1123
  return (double) ((sign < 0) ? -v1 : v1);
 
1124
}
 
1125
 
 
1126
double wxSQLite3Table::GetDouble(int columnIndex, double nullValue /* = 0.0 */)
 
1127
{
 
1128
  if (IsNull(columnIndex))
 
1129
  {
 
1130
    return nullValue;
 
1131
  }
 
1132
  else
 
1133
  {
 
1134
    if (columnIndex < 0 || columnIndex > m_cols-1)
 
1135
    {
 
1136
      throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
1137
    }
 
1138
    int nIndex = (m_currentRow*m_cols) + m_cols + columnIndex;
 
1139
    return wxSQLite3AtoF(m_results[nIndex]);
 
1140
  }
 
1141
}
 
1142
 
 
1143
double wxSQLite3Table::GetDouble(const wxString& columnName, double nullValue /* = 0.0 */)
 
1144
{
 
1145
  int index = FindColumnIndex(columnName);
 
1146
  return GetDouble(index, nullValue);
 
1147
}
 
1148
 
 
1149
wxString wxSQLite3Table::GetString(int columnIndex, const wxString& nullValue /* = wxEmptyString */)
 
1150
{
 
1151
  if (IsNull(columnIndex))
 
1152
  {
 
1153
    return nullValue;
 
1154
  }
 
1155
  else
 
1156
  {
 
1157
    return GetAsString(columnIndex);
 
1158
  }
 
1159
}
 
1160
 
 
1161
wxString wxSQLite3Table::GetString(const wxString& columnName, const wxString& nullValue /* = wxEmptyString */)
 
1162
{
 
1163
  if (IsNull(columnName))
 
1164
  {
 
1165
    return nullValue;
 
1166
  }
 
1167
  else
 
1168
  {
 
1169
    return GetAsString(columnName);
 
1170
  }
 
1171
}
 
1172
 
 
1173
wxDateTime wxSQLite3Table::GetDate(int columnIndex)
 
1174
{
 
1175
  wxDateTime date;
 
1176
  if (date.ParseDate(GetString(columnIndex)) != NULL)
 
1177
  {
 
1178
    return date;
 
1179
  }
 
1180
  else
 
1181
  {
 
1182
    return wxInvalidDateTime;
 
1183
  }
 
1184
}
 
1185
 
 
1186
wxDateTime wxSQLite3Table::GetDate(const wxString& columnName)
 
1187
{
 
1188
  int columnIndex = FindColumnIndex(columnName);
 
1189
  return GetDate(columnIndex);
 
1190
}
 
1191
 
 
1192
wxDateTime wxSQLite3Table::GetTime(int columnIndex)
 
1193
{
 
1194
  wxDateTime date;
 
1195
  if (date.ParseTime(GetString(columnIndex)) != NULL)
 
1196
  {
 
1197
    return date;
 
1198
  }
 
1199
  else
 
1200
  {
 
1201
    return wxInvalidDateTime;
 
1202
  }
 
1203
}
 
1204
 
 
1205
wxDateTime wxSQLite3Table::GetTime(const wxString& columnName)
 
1206
{
 
1207
  int columnIndex = FindColumnIndex(columnName);
 
1208
  return GetTime(columnIndex);
 
1209
}
 
1210
 
 
1211
wxDateTime wxSQLite3Table::GetDateTime(int columnIndex)
 
1212
{
 
1213
  wxDateTime date;
 
1214
  if (date.ParseDateTime(GetString(columnIndex)) != NULL)
 
1215
  {
 
1216
    return date;
 
1217
  }
 
1218
  else
 
1219
  {
 
1220
    return wxInvalidDateTime;
 
1221
  }
 
1222
}
 
1223
 
 
1224
wxDateTime wxSQLite3Table::GetDateTime(const wxString& columnName)
 
1225
{
 
1226
  int columnIndex = FindColumnIndex(columnName);
 
1227
  return GetDateTime(columnIndex);
 
1228
}
 
1229
 
 
1230
bool wxSQLite3Table::GetBool(int columnIndex)
 
1231
{
 
1232
  return GetInt(columnIndex) != 0;
 
1233
}
 
1234
 
 
1235
bool wxSQLite3Table::GetBool(const wxString& columnName)
 
1236
{
 
1237
  int columnIndex = FindColumnIndex(columnName);
 
1238
  return GetBool(columnIndex);
 
1239
}
 
1240
 
 
1241
bool wxSQLite3Table::IsNull(int columnIndex)
 
1242
{
 
1243
  CheckResults();
 
1244
 
 
1245
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
1246
  {
 
1247
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
1248
  }
 
1249
 
 
1250
  int index = (m_currentRow*m_cols) + m_cols + columnIndex;
 
1251
  const char* localValue = m_results[index];
 
1252
  return (localValue == 0);
 
1253
}
 
1254
 
 
1255
bool wxSQLite3Table::IsNull(const wxString& columnName)
 
1256
{
 
1257
  int index = FindColumnIndex(columnName);
 
1258
  return IsNull(index);
 
1259
}
 
1260
 
 
1261
wxString wxSQLite3Table::GetColumnName(int columnIndex)
 
1262
{
 
1263
  CheckResults();
 
1264
 
 
1265
  if (columnIndex < 0 || columnIndex > m_cols-1)
 
1266
  {
 
1267
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_INDEX);
 
1268
  }
 
1269
 
 
1270
  const char* localValue = m_results[columnIndex];
 
1271
  return UTF8toWxString(localValue);
 
1272
}
 
1273
 
 
1274
void wxSQLite3Table::SetRow(int row)
 
1275
{
 
1276
  CheckResults();
 
1277
 
 
1278
  if (row < 0 || row > m_rows-1)
 
1279
  {
 
1280
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_ROW);
 
1281
  }
 
1282
 
 
1283
  m_currentRow = row;
 
1284
}
 
1285
 
 
1286
bool wxSQLite3Table::IsOk()
 
1287
{
 
1288
  return (m_results != 0);
 
1289
}
 
1290
 
 
1291
void wxSQLite3Table::CheckResults()
 
1292
{
 
1293
  if (m_results == 0)
 
1294
  {
 
1295
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NORESULT);
 
1296
  }
 
1297
}
 
1298
 
 
1299
// ----------------------------------------------------------------------------
 
1300
// wxSQLite3Statement: class holding a prepared statement
 
1301
// ----------------------------------------------------------------------------
 
1302
 
 
1303
wxSQLite3Statement::wxSQLite3Statement()
 
1304
{
 
1305
  m_db = 0;
 
1306
  m_stmt = 0;
 
1307
}
 
1308
 
 
1309
wxSQLite3Statement::wxSQLite3Statement(const wxSQLite3Statement& statement)
 
1310
{
 
1311
  m_db = statement.m_db;
 
1312
  m_stmt = statement.m_stmt;
 
1313
  // Only one object can own prepared statement
 
1314
  const_cast<wxSQLite3Statement&>(statement).m_stmt = 0;
 
1315
}
 
1316
 
 
1317
wxSQLite3Statement::wxSQLite3Statement(void* db, void* stmt)
 
1318
{
 
1319
  m_db = db;
 
1320
  m_stmt = stmt;
 
1321
}
 
1322
 
 
1323
wxSQLite3Statement::~wxSQLite3Statement()
 
1324
{
 
1325
  try
 
1326
  {
 
1327
    Finalize();
 
1328
  }
 
1329
  catch (...)
 
1330
  {
 
1331
  }
 
1332
}
 
1333
 
 
1334
wxSQLite3Statement& wxSQLite3Statement::operator=(const wxSQLite3Statement& statement)
 
1335
{
 
1336
  m_db = statement.m_db;
 
1337
  m_stmt = statement.m_stmt;
 
1338
  // Only one object can own prepared statement
 
1339
  const_cast<wxSQLite3Statement&>(statement).m_stmt = 0;
 
1340
  return *this;
 
1341
}
 
1342
 
 
1343
int wxSQLite3Statement::ExecuteUpdate()
 
1344
{
 
1345
  CheckDatabase();
 
1346
  CheckStmt();
 
1347
 
 
1348
  const char* localError=0;
 
1349
 
 
1350
  int rc = sqlite3_step((sqlite3_stmt*) m_stmt);
 
1351
 
 
1352
  if (rc == SQLITE_DONE)
 
1353
  {
 
1354
    int rowsChanged = sqlite3_changes((sqlite3*) m_db);
 
1355
 
 
1356
    rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
 
1357
 
 
1358
    if (rc != SQLITE_OK)
 
1359
    {
 
1360
      localError = sqlite3_errmsg((sqlite3*) m_db);
 
1361
      throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
1362
    }
 
1363
 
 
1364
    return rowsChanged;
 
1365
  }
 
1366
  else
 
1367
  {
 
1368
    rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
 
1369
    localError = sqlite3_errmsg((sqlite3*) m_db);
 
1370
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
1371
  }
 
1372
}
 
1373
 
 
1374
wxSQLite3ResultSet wxSQLite3Statement::ExecuteQuery()
 
1375
{
 
1376
  CheckDatabase();
 
1377
  CheckStmt();
 
1378
 
 
1379
  int rc = sqlite3_step((sqlite3_stmt*) m_stmt);
 
1380
 
 
1381
  if (rc == SQLITE_DONE)  // no more rows
 
1382
  {
 
1383
    return wxSQLite3ResultSet(m_db, m_stmt, true/*eof*/, true/*first*/, false);
 
1384
  }
 
1385
  else if (rc == SQLITE_ROW)  // one or more rows
 
1386
  {
 
1387
    return wxSQLite3ResultSet(m_db, m_stmt, false/*eof*/, true/*first*/, false);
 
1388
  }
 
1389
  else
 
1390
  {
 
1391
    rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
 
1392
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1393
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
1394
  }
 
1395
}
 
1396
 
 
1397
int wxSQLite3Statement::GetParamCount()
 
1398
{
 
1399
  CheckStmt();
 
1400
  return sqlite3_bind_parameter_count((sqlite3_stmt*) m_stmt);
 
1401
}
 
1402
 
 
1403
int wxSQLite3Statement::GetParamIndex(const wxString& paramName)
 
1404
{
 
1405
  CheckStmt();
 
1406
  
 
1407
  wxCharBuffer strParamName = wxConvUTF8.cWC2MB(paramName.wc_str(*wxConvCurrent));
 
1408
  const char* localParamName = strParamName;
 
1409
 
 
1410
  return sqlite3_bind_parameter_index((sqlite3_stmt*) m_stmt, localParamName);
 
1411
}
 
1412
 
 
1413
wxString wxSQLite3Statement::GetParamName(int paramIndex)
 
1414
{
 
1415
  CheckStmt();
 
1416
  const char* localParamName = sqlite3_bind_parameter_name((sqlite3_stmt*) m_stmt, paramIndex);
 
1417
  return UTF8toWxString(localParamName);
 
1418
}
 
1419
 
 
1420
void wxSQLite3Statement::Bind(int paramIndex, const wxString& stringValue)
 
1421
{
 
1422
  CheckStmt();
 
1423
 
 
1424
  wxCharBuffer strStringValue = wxConvUTF8.cWC2MB(stringValue.wc_str(*wxConvCurrent));
 
1425
  const char* localStringValue = strStringValue;
 
1426
 
 
1427
  int rc = sqlite3_bind_text((sqlite3_stmt*) m_stmt, paramIndex, localStringValue, -1, SQLITE_TRANSIENT);
 
1428
 
 
1429
  if (rc != SQLITE_OK)
 
1430
  {
 
1431
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_STR);
 
1432
  }
 
1433
}
 
1434
 
 
1435
void wxSQLite3Statement::Bind(int paramIndex, int intValue)
 
1436
{
 
1437
  CheckStmt();
 
1438
  int rc = sqlite3_bind_int((sqlite3_stmt*) m_stmt, paramIndex, intValue);
 
1439
 
 
1440
  if (rc != SQLITE_OK)
 
1441
  {
 
1442
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_INT);
 
1443
  }
 
1444
}
 
1445
 
 
1446
void wxSQLite3Statement::Bind(int paramIndex, wxLongLong int64Value)
 
1447
{
 
1448
  CheckStmt();
 
1449
  int rc = sqlite3_bind_int64((sqlite3_stmt*) m_stmt, paramIndex, int64Value.GetValue());
 
1450
 
 
1451
  if (rc != SQLITE_OK)
 
1452
  {
 
1453
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_INT64);
 
1454
  }
 
1455
}
 
1456
 
 
1457
void wxSQLite3Statement::Bind(int paramIndex, double doubleValue)
 
1458
{
 
1459
  CheckStmt();
 
1460
  int rc = sqlite3_bind_double((sqlite3_stmt*) m_stmt, paramIndex, doubleValue);
 
1461
 
 
1462
  if (rc != SQLITE_OK)
 
1463
  {
 
1464
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_DBL);
 
1465
  }
 
1466
}
 
1467
 
 
1468
void wxSQLite3Statement::Bind(int paramIndex, const char* charValue)
 
1469
{
 
1470
  CheckStmt();
 
1471
  int rc = sqlite3_bind_text((sqlite3_stmt*) m_stmt, paramIndex, charValue, -1, SQLITE_TRANSIENT);
 
1472
 
 
1473
  if (rc != SQLITE_OK)
 
1474
  {
 
1475
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_STR);
 
1476
  }
 
1477
}
 
1478
 
 
1479
void wxSQLite3Statement::Bind(int paramIndex, const unsigned char* blobValue, int blobLen)
 
1480
{
 
1481
  CheckStmt();
 
1482
  int rc = sqlite3_bind_blob((sqlite3_stmt*) m_stmt, paramIndex,
 
1483
                (const void*)blobValue, blobLen, SQLITE_TRANSIENT);
 
1484
 
 
1485
  if (rc != SQLITE_OK)
 
1486
  {
 
1487
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_BLOB);
 
1488
  }
 
1489
}
 
1490
 
 
1491
void wxSQLite3Statement::Bind(int paramIndex, const wxMemoryBuffer& blobValue)
 
1492
{
 
1493
  CheckStmt();
 
1494
  int blobLen = (int) blobValue.GetDataLen();
 
1495
  int rc = sqlite3_bind_blob((sqlite3_stmt*) m_stmt, paramIndex,
 
1496
                (const void*)blobValue.GetData(), blobLen, SQLITE_TRANSIENT);
 
1497
 
 
1498
  if (rc != SQLITE_OK)
 
1499
  {
 
1500
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_BLOB);
 
1501
  }
 
1502
}
 
1503
 
 
1504
void wxSQLite3Statement::BindDate(int paramIndex, const wxDateTime& date)
 
1505
{
 
1506
  if (date.IsValid())
 
1507
  {
 
1508
    Bind(paramIndex,date.FormatISODate());
 
1509
  }
 
1510
  else
 
1511
  {
 
1512
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
 
1513
  }
 
1514
}
 
1515
 
 
1516
void wxSQLite3Statement::BindTime(int paramIndex, const wxDateTime& time)
 
1517
{
 
1518
  if (time.IsValid())
 
1519
  {
 
1520
    Bind(paramIndex,time.FormatISOTime());
 
1521
  }
 
1522
  else
 
1523
  {
 
1524
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
 
1525
  }
 
1526
}
 
1527
 
 
1528
void wxSQLite3Statement::BindDateTime(int paramIndex, const wxDateTime& datetime)
 
1529
{
 
1530
  if (datetime.IsValid())
 
1531
  {
 
1532
    Bind(paramIndex,datetime.Format(_T("%Y-%m-%d %H:%M:%S")));
 
1533
  }
 
1534
  else
 
1535
  {
 
1536
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
 
1537
  }
 
1538
}
 
1539
 
 
1540
void wxSQLite3Statement::BindTimestamp(int paramIndex, const wxDateTime& timestamp)
 
1541
{
 
1542
  if (timestamp.IsValid())
 
1543
  {
 
1544
    Bind(paramIndex,timestamp.Format(_T("%Y-%m-%d %H:%M:%S.%l")));
 
1545
  }
 
1546
  else
 
1547
  {
 
1548
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
 
1549
  }
 
1550
}
 
1551
 
 
1552
void wxSQLite3Statement::BindNumericDateTime(int paramIndex, const wxDateTime& datetime)
 
1553
{
 
1554
  if (datetime.IsValid())
 
1555
  {
 
1556
    Bind(paramIndex, datetime.GetValue());
 
1557
  }
 
1558
  else
 
1559
  {
 
1560
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
 
1561
  }
 
1562
}
 
1563
 
 
1564
void wxSQLite3Statement::BindJulianDayNumber(int paramIndex, const wxDateTime& datetime)
 
1565
{
 
1566
  if (datetime.IsValid())
 
1567
  {
 
1568
    Bind(paramIndex, datetime.GetJulianDayNumber());
 
1569
  }
 
1570
  else
 
1571
  {
 
1572
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_BIND_DATETIME);
 
1573
  }
 
1574
}
 
1575
 
 
1576
void wxSQLite3Statement::BindBool(int paramIndex, bool value)
 
1577
{
 
1578
  Bind(paramIndex, value ? 1 : 0);
 
1579
}
 
1580
 
 
1581
void wxSQLite3Statement::BindNull(int paramIndex)
 
1582
{
 
1583
  CheckStmt();
 
1584
  int rc = sqlite3_bind_null((sqlite3_stmt*) m_stmt, paramIndex);
 
1585
 
 
1586
  if (rc != SQLITE_OK)
 
1587
  {
 
1588
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_NULL);
 
1589
  }
 
1590
}
 
1591
 
 
1592
void wxSQLite3Statement::BindZeroBlob(int paramIndex, int blobSize)
 
1593
{
 
1594
#if SQLITE_VERSION_NUMBER >= 3004000
 
1595
  CheckStmt();
 
1596
  int rc = sqlite3_bind_zeroblob((sqlite3_stmt*) m_stmt, paramIndex, blobSize);
 
1597
  if (rc != SQLITE_OK)
 
1598
  {
 
1599
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_ZEROBLOB);
 
1600
  }
 
1601
#else
 
1602
  wxUnusedVar(paramIndex);
 
1603
  wxUnusedVar(blobSize);
 
1604
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
 
1605
#endif
 
1606
}
 
1607
 
 
1608
void wxSQLite3Statement::ClearBindings()
 
1609
{
 
1610
  CheckStmt();
 
1611
#if 0 // missing in SQLite DLL
 
1612
  int rc = sqlite3_clear_bindings((sqlite3_stmt*) m_stmt);
 
1613
 
 
1614
  if (rc != SQLITE_OK)
 
1615
  {
 
1616
    throw wxSQLite3Exception(rc, wxERRMSG_BIND_CLEAR);
 
1617
  }
 
1618
#else
 
1619
  for (int paramIndex = 1; paramIndex <= GetParamCount(); paramIndex++)
 
1620
  {
 
1621
    BindNull(paramIndex);
 
1622
  }
 
1623
#endif
 
1624
}
 
1625
 
 
1626
wxString wxSQLite3Statement::GetSQL()
 
1627
{
 
1628
  wxString sqlString = wxEmptyString;
 
1629
#if SQLITE_VERSION_NUMBER >= 3005003
 
1630
  CheckStmt();
 
1631
  const char* sqlLocal = sqlite3_sql((sqlite3_stmt*) m_stmt);
 
1632
  if (sqlLocal != NULL) sqlString = UTF8toWxString(sqlLocal);
 
1633
#endif
 
1634
  return sqlString;
 
1635
}
 
1636
 
 
1637
void wxSQLite3Statement::Reset()
 
1638
{
 
1639
  if (m_stmt)
 
1640
  {
 
1641
    int rc = sqlite3_reset((sqlite3_stmt*) m_stmt);
 
1642
 
 
1643
    if (rc != SQLITE_OK)
 
1644
    {
 
1645
      const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1646
      throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
1647
    }
 
1648
  }
 
1649
}
 
1650
 
 
1651
void wxSQLite3Statement::Finalize()
 
1652
{
 
1653
  if (m_stmt)
 
1654
  {
 
1655
    int rc = sqlite3_finalize((sqlite3_stmt*) m_stmt);
 
1656
    m_stmt = 0;
 
1657
 
 
1658
    if (rc != SQLITE_OK)
 
1659
    {
 
1660
      const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1661
      throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
1662
    }
 
1663
  }
 
1664
}
 
1665
 
 
1666
bool wxSQLite3Statement::IsOk()
 
1667
{
 
1668
  return (m_db != 0) && (m_stmt != 0);
 
1669
}
 
1670
 
 
1671
void wxSQLite3Statement::CheckDatabase()
 
1672
{
 
1673
  if (m_db == 0)
 
1674
  {
 
1675
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NODB);
 
1676
  }
 
1677
}
 
1678
 
 
1679
void wxSQLite3Statement::CheckStmt()
 
1680
{
 
1681
  if (m_stmt == 0)
 
1682
  {
 
1683
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSTMT);
 
1684
  }
 
1685
}
 
1686
 
 
1687
//
 
1688
 
 
1689
wxSQLite3Blob::wxSQLite3Blob()
 
1690
{
 
1691
  m_db   = NULL;
 
1692
  m_blob = NULL;
 
1693
  m_ok   = false;
 
1694
  m_writable = false;
 
1695
}
 
1696
 
 
1697
wxSQLite3Blob::wxSQLite3Blob(const wxSQLite3Blob& blob)
 
1698
{
 
1699
  m_db   = blob.m_db;
 
1700
  m_blob = blob.m_blob;
 
1701
  m_ok   = blob.m_ok;
 
1702
  m_writable = blob.m_writable;
 
1703
}
 
1704
 
 
1705
wxSQLite3Blob& wxSQLite3Blob::operator=(const wxSQLite3Blob& blob)
 
1706
{
 
1707
  try
 
1708
  {
 
1709
    Finalize();
 
1710
  }
 
1711
  catch (...)
 
1712
  {
 
1713
  }
 
1714
  m_db   = blob.m_db;
 
1715
  m_blob = blob.m_blob;
 
1716
  m_ok   = blob.m_ok;
 
1717
  m_writable = blob.m_writable;
 
1718
  // only one blob can own the blob handle
 
1719
  const_cast<wxSQLite3Blob&>(blob).m_ok = false;
 
1720
 
 
1721
  return *this;
 
1722
}
 
1723
 
 
1724
wxSQLite3Blob::wxSQLite3Blob(void* db, void* blobHandle, bool writable)
 
1725
{
 
1726
  m_db   = db;
 
1727
  m_blob = blobHandle;
 
1728
  m_ok   = true;
 
1729
  m_writable = writable;
 
1730
#if 0
 
1731
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
 
1732
 
 
1733
void sqlite3_result_zeroblob(sqlite3_context*, int n);
 
1734
 
 
1735
#endif
 
1736
}
 
1737
 
 
1738
wxSQLite3Blob::~wxSQLite3Blob()
 
1739
{
 
1740
  try
 
1741
  {
 
1742
    Finalize();
 
1743
  }
 
1744
  catch (...)
 
1745
  {
 
1746
  }
 
1747
}
 
1748
 
 
1749
wxMemoryBuffer& wxSQLite3Blob::Read(wxMemoryBuffer& blobValue, int length, int offset)
 
1750
{
 
1751
#if SQLITE_VERSION_NUMBER >= 3004000
 
1752
  CheckBlob();
 
1753
  char* localBuffer = new char[length];
 
1754
  int rc = sqlite3_blob_read((sqlite3_blob*) m_blob, localBuffer, length, offset);
 
1755
 
 
1756
  if (rc != SQLITE_OK)
 
1757
  {
 
1758
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1759
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
1760
  }
 
1761
 
 
1762
  blobValue.AppendData((void*) localBuffer, (size_t) length);
 
1763
  delete [] localBuffer;
 
1764
#else
 
1765
  wxUnusedVar(blobValue);
 
1766
  wxUnusedVar(length);
 
1767
  wxUnusedVar(offset);
 
1768
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
 
1769
#endif
 
1770
  return blobValue;
 
1771
}
 
1772
 
 
1773
void wxSQLite3Blob::Write(const wxMemoryBuffer& blobValue, int offset)
 
1774
{
 
1775
#if SQLITE_VERSION_NUMBER >= 3004000
 
1776
  CheckBlob();
 
1777
  if (m_writable)
 
1778
  {
 
1779
    int blobLen = (int) blobValue.GetDataLen();
 
1780
    int rc = sqlite3_blob_write((sqlite3_blob*) m_blob,
 
1781
                                (const void*) blobValue.GetData(), blobLen, offset);
 
1782
 
 
1783
    if (rc != SQLITE_OK)
 
1784
    {
 
1785
      const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1786
      throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
1787
    }
 
1788
  }
 
1789
  else
 
1790
  {
 
1791
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_BLOB);
 
1792
  }
 
1793
#else
 
1794
  wxUnusedVar(blobValue);
 
1795
  wxUnusedVar(offset);
 
1796
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
 
1797
#endif
 
1798
}
 
1799
 
 
1800
bool wxSQLite3Blob::IsOk()
 
1801
{
 
1802
  return m_ok;
 
1803
}
 
1804
 
 
1805
bool wxSQLite3Blob::IsReadOnly()
 
1806
{
 
1807
  return !m_writable;
 
1808
}
 
1809
 
 
1810
int wxSQLite3Blob::GetSize()
 
1811
{
 
1812
#if SQLITE_VERSION_NUMBER >= 3004000
 
1813
  CheckBlob();
 
1814
  return sqlite3_blob_bytes((sqlite3_blob*) m_blob);
 
1815
#else
 
1816
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
 
1817
  return 0;
 
1818
#endif
 
1819
}
 
1820
 
 
1821
void wxSQLite3Blob::Finalize()
 
1822
{
 
1823
#if SQLITE_VERSION_NUMBER >= 3004000
 
1824
  if (m_ok)
 
1825
  {
 
1826
    int rc = sqlite3_blob_close((sqlite3_blob*) m_blob);
 
1827
    m_blob = NULL;
 
1828
    m_ok = false;
 
1829
    if (rc != SQLITE_OK)
 
1830
    {
 
1831
      const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1832
      throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
1833
    }
 
1834
  }
 
1835
#else
 
1836
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
 
1837
#endif
 
1838
}
 
1839
 
 
1840
void wxSQLite3Blob::CheckBlob()
 
1841
{
 
1842
  if (!m_ok)
 
1843
  {
 
1844
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_BLOB);
 
1845
  }
 
1846
}
 
1847
 
 
1848
// ----------------------------------------------------------------------------
 
1849
// wxSQLite3Database: class holding a SQLite3 database object
 
1850
// ----------------------------------------------------------------------------
 
1851
 
 
1852
bool wxSQLite3Database::ms_sharedCacheEnabled = false;
 
1853
 
 
1854
void
 
1855
wxSQLite3Database::SetSharedCache(bool enable)
 
1856
{
 
1857
  int flag = (enable) ? 1 : 0;
 
1858
  int rc = sqlite3_enable_shared_cache(flag);
 
1859
  if (rc != SQLITE_OK)
 
1860
  {
 
1861
    throw wxSQLite3Exception(rc, wxERRMSG_SHARED_CACHE);
 
1862
  }
 
1863
  ms_sharedCacheEnabled = enable;
 
1864
}
 
1865
 
 
1866
#if WXSQLITE3_HAVE_CODEC
 
1867
bool wxSQLite3Database::ms_hasEncryptionSupport = true;
 
1868
#else
 
1869
bool wxSQLite3Database::ms_hasEncryptionSupport = false;
 
1870
#endif
 
1871
 
 
1872
#if WXSQLITE3_HAVE_METADATA
 
1873
bool wxSQLite3Database::ms_hasMetaDataSupport = true;
 
1874
#else
 
1875
bool wxSQLite3Database::ms_hasMetaDataSupport = false;
 
1876
#endif
 
1877
 
 
1878
#if WXSQLITE3_HAVE_LOAD_EXTENSION
 
1879
bool wxSQLite3Database::ms_hasLoadExtSupport = true;
 
1880
#else
 
1881
bool wxSQLite3Database::ms_hasLoadExtSupport = false;
 
1882
#endif
 
1883
 
 
1884
#if SQLITE_VERSION_NUMBER >= 3004000
 
1885
bool wxSQLite3Database::ms_hasIncrementalBlobSupport = true;
 
1886
#else
 
1887
bool wxSQLite3Database::ms_hasIncrementalBlobSupport = false;
 
1888
#endif
 
1889
 
 
1890
#if SQLITE_VERSION_NUMBER >= 3006008
 
1891
bool wxSQLite3Database::ms_hasSavepointSupport = true;
 
1892
#else
 
1893
bool wxSQLite3Database::ms_hasSavepointSupport = false;
 
1894
#endif
 
1895
 
 
1896
bool
 
1897
wxSQLite3Database::HasEncryptionSupport()
 
1898
{
 
1899
  return ms_hasEncryptionSupport;
 
1900
}
 
1901
 
 
1902
bool
 
1903
wxSQLite3Database::HasMetaDataSupport()
 
1904
{
 
1905
  return ms_hasMetaDataSupport;
 
1906
}
 
1907
 
 
1908
bool
 
1909
wxSQLite3Database::HasLoadExtSupport()
 
1910
{
 
1911
  return ms_hasLoadExtSupport;
 
1912
}
 
1913
 
 
1914
bool
 
1915
wxSQLite3Database::HasIncrementalBlobSupport()
 
1916
{
 
1917
  return ms_hasIncrementalBlobSupport;
 
1918
}
 
1919
 
 
1920
bool
 
1921
wxSQLite3Database::HasSavepointSupport()
 
1922
{
 
1923
  return ms_hasSavepointSupport;
 
1924
}
 
1925
 
 
1926
wxSQLite3Database::wxSQLite3Database()
 
1927
{
 
1928
  m_db = 0;
 
1929
  m_busyTimeoutMs = 60000; // 60 seconds
 
1930
  m_isEncrypted = false;
 
1931
}
 
1932
 
 
1933
wxSQLite3Database::wxSQLite3Database(const wxSQLite3Database& db)
 
1934
{
 
1935
  m_db = db.m_db;
 
1936
  m_busyTimeoutMs = 60000; // 60 seconds
 
1937
  m_isEncrypted = false;
 
1938
}
 
1939
 
 
1940
wxSQLite3Database::~wxSQLite3Database()
 
1941
{
 
1942
  Close();
 
1943
}
 
1944
 
 
1945
wxSQLite3Database& wxSQLite3Database::operator=(const wxSQLite3Database& db)
 
1946
{
 
1947
  m_db = db.m_db;
 
1948
  m_busyTimeoutMs = 60000; // 60 seconds
 
1949
  m_isEncrypted = db.m_isEncrypted;
 
1950
  return *this;
 
1951
}
 
1952
 
 
1953
void wxSQLite3Database::Open(const wxString& fileName, const wxString& key)
 
1954
{
 
1955
  wxCharBuffer strLocalKey = wxConvUTF8.cWC2MB(key.wc_str(*wxConvCurrent));
 
1956
  const char* localKey = strLocalKey;
 
1957
  wxMemoryBuffer binaryKey;
 
1958
  if (key.Length() > 0)
 
1959
  {
 
1960
    binaryKey.AppendData((void*) localKey, strlen(localKey));
 
1961
  }
 
1962
  Open(fileName, binaryKey);
 
1963
}
 
1964
 
 
1965
void wxSQLite3Database::Open(const wxString& fileName, const wxMemoryBuffer& key)
 
1966
{
 
1967
  wxCharBuffer strFileName = wxConvUTF8.cWC2MB(fileName.wc_str(*wxConvCurrent));
 
1968
  const char* localFileName = strFileName;
 
1969
 
 
1970
  int rc = sqlite3_open((const char*) localFileName, (sqlite3**) &m_db);
 
1971
 
 
1972
  if (rc != SQLITE_OK)
 
1973
  {
 
1974
    Close();
 
1975
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1976
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
1977
  }
 
1978
 
 
1979
  rc = sqlite3_extended_result_codes((sqlite3*) m_db, 1);
 
1980
  if (rc != SQLITE_OK)
 
1981
  {
 
1982
    Close();
 
1983
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1984
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
1985
  }
 
1986
 
 
1987
#if WXSQLITE3_HAVE_CODEC
 
1988
  if (key.GetDataLen() > 0)
 
1989
  {
 
1990
    rc = sqlite3_key((sqlite3*) m_db, key.GetData(), (int) key.GetDataLen());
 
1991
    if (rc != SQLITE_OK)
 
1992
    {
 
1993
      Close();
 
1994
      const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
1995
      throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
1996
    }
 
1997
    m_isEncrypted = true;
 
1998
  }
 
1999
#else
 
2000
  wxUnusedVar(key);
 
2001
#endif
 
2002
 
 
2003
  SetBusyTimeout(m_busyTimeoutMs);
 
2004
}
 
2005
 
 
2006
bool wxSQLite3Database::IsOpen() const
 
2007
{
 
2008
  return (m_db != NULL);
 
2009
}
 
2010
 
 
2011
void wxSQLite3Database::Close()
 
2012
{
 
2013
  if (m_db)
 
2014
  {
 
2015
#if SQLITE_VERSION_NUMBER >= 3006000
 
2016
// Unfortunately the following code leads to a crash if the RTree module is used
 
2017
// therefore it is disabled for now
 
2018
#if 0
 
2019
    // Finalize all unfinalized prepared statements
 
2020
    sqlite3_stmt *pStmt;
 
2021
    while( (pStmt = sqlite3_next_stmt((sqlite3*) m_db, 0))!=0 )
 
2022
    {
 
2023
      sqlite3_finalize(pStmt);
 
2024
    }
 
2025
#endif
 
2026
#endif
 
2027
    sqlite3_close((sqlite3*) m_db);
 
2028
    m_db = 0;
 
2029
    m_isEncrypted = false;
 
2030
  }
 
2031
}
 
2032
 
 
2033
void wxSQLite3Database::Begin(wxSQLite3TransactionType transactionType)
 
2034
{
 
2035
  wxString sql;
 
2036
  switch (transactionType)
 
2037
  {
 
2038
    case WXSQLITE_TRANSACTION_DEFERRED:
 
2039
      sql << _T("begin deferred transaction");
 
2040
      break;
 
2041
    case WXSQLITE_TRANSACTION_IMMEDIATE:
 
2042
      sql << _T("begin immediate transaction");
 
2043
      break;
 
2044
    case WXSQLITE_TRANSACTION_EXCLUSIVE:
 
2045
      sql << _T("begin exclusive transaction");
 
2046
      break;
 
2047
    default:
 
2048
      sql << _T("begin transaction");
 
2049
      break;
 
2050
  }
 
2051
  ExecuteUpdate(sql);
 
2052
}
 
2053
 
 
2054
void wxSQLite3Database::Commit()
 
2055
{
 
2056
  ExecuteUpdate("commit transaction");
 
2057
}
 
2058
 
 
2059
void wxSQLite3Database::Rollback(const wxString& savepointName)
 
2060
{
 
2061
#if SQLITE_VERSION_NUMBER >= 3006008
 
2062
  if (savepointName.IsEmpty())
 
2063
  {
 
2064
#endif
 
2065
    ExecuteUpdate("rollback transaction");
 
2066
#if SQLITE_VERSION_NUMBER >= 3006008
 
2067
  }
 
2068
  else
 
2069
  {
 
2070
    ExecuteUpdate(wxString(_T("rollback transaction to savepoint "))+savepointName);
 
2071
  }
 
2072
#endif
 
2073
}
 
2074
 
 
2075
bool wxSQLite3Database::GetAutoCommit()
 
2076
{
 
2077
  CheckDatabase();
 
2078
  return sqlite3_get_autocommit((sqlite3*) m_db) != 0;
 
2079
}
 
2080
 
 
2081
void wxSQLite3Database::Savepoint(const wxString& savepointName)
 
2082
{
 
2083
#if SQLITE_VERSION_NUMBER >= 3006008
 
2084
  ExecuteUpdate(wxString(_T("savepoint "))+savepointName);
 
2085
#else
 
2086
  wxUnusedVar(savepointName);
 
2087
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSAVEPOINT);
 
2088
#endif
 
2089
}
 
2090
 
 
2091
void wxSQLite3Database::ReleaseSavepoint(const wxString& savepointName)
 
2092
{
 
2093
#if SQLITE_VERSION_NUMBER >= 3006008
 
2094
  ExecuteUpdate(wxString(_T("release savepoint "))+savepointName);
 
2095
#else
 
2096
  wxUnusedVar(savepointName);
 
2097
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOSAVEPOINT);
 
2098
#endif
 
2099
}
 
2100
 
 
2101
wxSQLite3Statement wxSQLite3Database::PrepareStatement(const wxString& sql)
 
2102
{
 
2103
  wxCharBuffer strSql = wxConvUTF8.cWC2MB(sql.wc_str(*wxConvCurrent));
 
2104
  const char* localSql = strSql;
 
2105
  return PrepareStatement(localSql);
 
2106
}
 
2107
 
 
2108
wxSQLite3Statement wxSQLite3Database::PrepareStatement(const wxSQLite3StatementBuffer& sql)
 
2109
{
 
2110
  return PrepareStatement((const char*) sql);
 
2111
}
 
2112
 
 
2113
wxSQLite3Statement wxSQLite3Database::PrepareStatement(const char* sql)
 
2114
{
 
2115
  CheckDatabase();
 
2116
  sqlite3_stmt* stmt = (sqlite3_stmt*) Prepare(sql);
 
2117
  return wxSQLite3Statement(m_db, stmt);
 
2118
}
 
2119
 
 
2120
bool wxSQLite3Database::TableExists(const wxString& tableName, const wxString& databaseName)
 
2121
{
 
2122
  wxString sql;
 
2123
  if (databaseName.IsEmpty())
 
2124
  {
 
2125
    sql = _T("select count(*) from sqlite_master where type='table' and name like ?");
 
2126
  }
 
2127
  else
 
2128
  {
 
2129
    sql = wxString(_T("select count(*) from ")) + databaseName + wxString(_T(".sqlite_master where type='table' and name like ?"));
 
2130
  }
 
2131
  wxSQLite3Statement stmt = PrepareStatement(sql);
 
2132
  stmt.Bind(1, tableName);
 
2133
  wxSQLite3ResultSet resultSet = stmt.ExecuteQuery();
 
2134
  long value = 0;
 
2135
  resultSet.GetAsString(0).ToLong(&value);
 
2136
  return (value > 0);
 
2137
}
 
2138
 
 
2139
bool wxSQLite3Database::TableExists(const wxString& tableName, wxArrayString& databaseNames)
 
2140
{
 
2141
  wxArrayString databaseList;
 
2142
  GetDatabaseList(databaseList);
 
2143
 
 
2144
  bool found = false;
 
2145
  size_t count = databaseList.GetCount();
 
2146
  if (count > 0)
 
2147
  {
 
2148
    size_t j;
 
2149
    for (j = 0; j < count; j++)
 
2150
    {
 
2151
      if (TableExists(tableName, databaseList.Item(j)))
 
2152
      {
 
2153
        found = true;
 
2154
        databaseNames.Add(databaseList.Item(j));
 
2155
      }
 
2156
    }
 
2157
  }
 
2158
  return found;
 
2159
}
 
2160
 
 
2161
void wxSQLite3Database::GetDatabaseList(wxArrayString& databaseNames)
 
2162
{
 
2163
  databaseNames.Empty();
 
2164
  wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA database_list;");
 
2165
  while (resultSet.NextRow())
 
2166
  {
 
2167
    databaseNames.Add(resultSet.GetString(1));
 
2168
  }
 
2169
}
 
2170
 
 
2171
void wxSQLite3Database::GetDatabaseList(wxArrayString& databaseNames, wxArrayString& databaseFiles)
 
2172
{
 
2173
  databaseNames.Empty();
 
2174
  databaseFiles.Empty();
 
2175
  wxSQLite3ResultSet resultSet = ExecuteQuery("PRAGMA database_list;");
 
2176
  while (resultSet.NextRow())
 
2177
  {
 
2178
    databaseNames.Add(resultSet.GetString(1));
 
2179
    databaseFiles.Add(resultSet.GetString(2));
 
2180
  }
 
2181
}
 
2182
 
 
2183
bool wxSQLite3Database::CheckSyntax(const wxString& sql)
 
2184
{
 
2185
  wxCharBuffer strSql = wxConvUTF8.cWC2MB(sql.wc_str(*wxConvCurrent));
 
2186
  const char* localSql = strSql;
 
2187
  return CheckSyntax(localSql);
 
2188
}
 
2189
 
 
2190
bool wxSQLite3Database::CheckSyntax(const wxSQLite3StatementBuffer& sql)
 
2191
{
 
2192
  return CheckSyntax((const char*) sql);
 
2193
}
 
2194
 
 
2195
bool wxSQLite3Database::CheckSyntax(const char* sql)
 
2196
{
 
2197
  return sqlite3_complete(sql) != 0;
 
2198
}
 
2199
 
 
2200
int wxSQLite3Database::ExecuteUpdate(const wxString& sql)
 
2201
{
 
2202
  wxCharBuffer strSql = wxConvUTF8.cWC2MB(sql.wc_str(*wxConvCurrent));
 
2203
  const char* localSql = strSql;
 
2204
  return ExecuteUpdate(localSql);
 
2205
}
 
2206
 
 
2207
int wxSQLite3Database::ExecuteUpdate(const wxSQLite3StatementBuffer& sql)
 
2208
{
 
2209
  return ExecuteUpdate((const char*) sql);
 
2210
}
 
2211
 
 
2212
int wxSQLite3Database::ExecuteUpdate(const char* sql)
 
2213
{
 
2214
  CheckDatabase();
 
2215
 
 
2216
  char* localError=0;
 
2217
 
 
2218
  int rc = sqlite3_exec((sqlite3*) m_db, sql, 0, 0, &localError);
 
2219
 
 
2220
  if (rc == SQLITE_OK)
 
2221
  {
 
2222
    return sqlite3_changes((sqlite3*) m_db);
 
2223
  }
 
2224
  else
 
2225
  {
 
2226
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
2227
  }
 
2228
}
 
2229
 
 
2230
wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const wxString& sql)
 
2231
{
 
2232
  wxCharBuffer strSql = wxConvUTF8.cWC2MB(sql.wc_str(*wxConvCurrent));
 
2233
  const char* localSql = strSql;
 
2234
  return ExecuteQuery(localSql);
 
2235
}
 
2236
 
 
2237
wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const wxSQLite3StatementBuffer& sql)
 
2238
{
 
2239
  return ExecuteQuery((const char*) sql);
 
2240
}
 
2241
 
 
2242
wxSQLite3ResultSet wxSQLite3Database::ExecuteQuery(const char* sql)
 
2243
{
 
2244
  CheckDatabase();
 
2245
 
 
2246
  sqlite3_stmt* stmt = (sqlite3_stmt*) Prepare(sql);
 
2247
 
 
2248
  int rc = sqlite3_step(stmt);
 
2249
 
 
2250
  if (rc == SQLITE_DONE) // no rows
 
2251
  {
 
2252
    return wxSQLite3ResultSet(m_db, stmt, true /* eof */);
 
2253
  }
 
2254
  else if (rc == SQLITE_ROW) // one or more rows
 
2255
  {
 
2256
    return wxSQLite3ResultSet(m_db, stmt, false /* eof */);
 
2257
  }
 
2258
  else
 
2259
  {
 
2260
    rc = sqlite3_finalize(stmt);
 
2261
    const char* localError= sqlite3_errmsg((sqlite3*) m_db);
 
2262
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
2263
  }
 
2264
}
 
2265
 
 
2266
int wxSQLite3Database::ExecuteScalar(const wxString& sql)
 
2267
{
 
2268
  wxCharBuffer strSql = wxConvUTF8.cWC2MB(sql.wc_str(*wxConvCurrent));
 
2269
  const char* localSql = strSql;
 
2270
  return ExecuteScalar(localSql);
 
2271
}
 
2272
 
 
2273
int wxSQLite3Database::ExecuteScalar(const wxSQLite3StatementBuffer& sql)
 
2274
{
 
2275
  return ExecuteScalar((const char*) sql);
 
2276
}
 
2277
 
 
2278
int wxSQLite3Database::ExecuteScalar(const char* sql)
 
2279
{
 
2280
  wxSQLite3ResultSet resultSet = ExecuteQuery(sql);
 
2281
 
 
2282
  if (resultSet.Eof() || resultSet.GetColumnCount() < 1)
 
2283
  {
 
2284
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_INVALID_QUERY);
 
2285
  }
 
2286
 
 
2287
  long value = 0;
 
2288
  resultSet.GetAsString(0).ToLong(&value);
 
2289
  return (int) value;
 
2290
}
 
2291
 
 
2292
wxSQLite3Table wxSQLite3Database::GetTable(const wxString& sql)
 
2293
{
 
2294
  wxCharBuffer strSql = wxConvUTF8.cWC2MB(sql.wc_str(*wxConvCurrent));
 
2295
  const char* localSql = strSql;
 
2296
  return GetTable(localSql);
 
2297
}
 
2298
 
 
2299
wxSQLite3Table wxSQLite3Database::GetTable(const wxSQLite3StatementBuffer& sql)
 
2300
{
 
2301
  return GetTable((const char*) sql);
 
2302
}
 
2303
 
 
2304
wxSQLite3Table wxSQLite3Database::GetTable(const char* sql)
 
2305
{
 
2306
  CheckDatabase();
 
2307
 
 
2308
  char* localError=0;
 
2309
  char** results=0;
 
2310
  int rc;
 
2311
  int rows(0);
 
2312
  int cols(0);
 
2313
 
 
2314
  rc = sqlite3_get_table((sqlite3*) m_db, sql, &results, &rows, &cols, &localError);
 
2315
 
 
2316
  if (rc == SQLITE_OK)
 
2317
  {
 
2318
    return wxSQLite3Table(results, rows, cols);
 
2319
  }
 
2320
  else
 
2321
  {
 
2322
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
2323
  }
 
2324
}
 
2325
 
 
2326
wxLongLong wxSQLite3Database::GetLastRowId()
 
2327
{
 
2328
  CheckDatabase();
 
2329
  return wxLongLong(sqlite3_last_insert_rowid((sqlite3*) m_db));
 
2330
}
 
2331
 
 
2332
wxSQLite3Blob wxSQLite3Database::GetReadOnlyBlob(wxLongLong rowId, 
 
2333
                                                 const wxString& columnName, 
 
2334
                                                 const wxString& tableName, 
 
2335
                                                 const wxString& dbName)
 
2336
{
 
2337
  return GetBlob(rowId, columnName, tableName, dbName, false);
 
2338
}
 
2339
 
 
2340
wxSQLite3Blob wxSQLite3Database::GetWritableBlob(wxLongLong rowId, 
 
2341
                                                 const wxString& columnName, 
 
2342
                                                 const wxString& tableName, 
 
2343
                                                 const wxString& dbName)
 
2344
{
 
2345
  return GetBlob(rowId, columnName, tableName, dbName, true);
 
2346
}
 
2347
 
 
2348
wxSQLite3Blob wxSQLite3Database::GetBlob(wxLongLong rowId, 
 
2349
                                         const wxString& columnName, 
 
2350
                                         const wxString& tableName, 
 
2351
                                         const wxString& dbName,
 
2352
                                         bool writable)
 
2353
{
 
2354
#if SQLITE_VERSION_NUMBER >= 3004000
 
2355
  wxCharBuffer strColumnName = wxConvUTF8.cWC2MB(columnName.wc_str(*wxConvCurrent));
 
2356
  const char* localColumnName = strColumnName;
 
2357
  wxCharBuffer strTableName = wxConvUTF8.cWC2MB(tableName.wc_str(*wxConvCurrent));
 
2358
  const char* localTableName = strTableName;
 
2359
  wxCharBuffer strDbName = wxConvUTF8.cWC2MB(dbName.wc_str(*wxConvCurrent));
 
2360
  const char* localDbName = (!dbName.IsEmpty()) ? (const char*) strDbName : (const char*) NULL;
 
2361
  int flags = (writable) ? 1 : 0;
 
2362
  sqlite3_blob* blobHandle;
 
2363
  CheckDatabase();
 
2364
  int rc = sqlite3_blob_open((sqlite3*) m_db, localDbName, localTableName, localColumnName, rowId.GetValue(), flags, &blobHandle);
 
2365
  if (rc != SQLITE_OK)
 
2366
  {
 
2367
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2368
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
2369
  }
 
2370
  return wxSQLite3Blob(m_db, (void*) blobHandle, writable);
 
2371
#else
 
2372
  wxUnusedVar(rowId);
 
2373
  wxUnusedVar(columnName);
 
2374
  wxUnusedVar(tableName);
 
2375
  wxUnusedVar(dbName);
 
2376
  wxUnusedVar(writable);
 
2377
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOINCBLOB);
 
2378
  return NULL;
 
2379
#endif
 
2380
}
 
2381
 
 
2382
void wxSQLite3Database::Interrupt()
 
2383
{
 
2384
  CheckDatabase();
 
2385
  sqlite3_interrupt((sqlite3*) m_db);
 
2386
}
 
2387
 
 
2388
void wxSQLite3Database::SetBusyTimeout(int nMillisecs)
 
2389
{
 
2390
  CheckDatabase();
 
2391
  m_busyTimeoutMs = nMillisecs;
 
2392
  sqlite3_busy_timeout((sqlite3*) m_db, m_busyTimeoutMs);
 
2393
}
 
2394
 
 
2395
wxString wxSQLite3Database::GetVersion()
 
2396
{
 
2397
  return UTF8toWxString(sqlite3_libversion());
 
2398
}
 
2399
 
 
2400
bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3ScalarFunction& function)
 
2401
{
 
2402
  CheckDatabase();
 
2403
  wxCharBuffer strFuncName = wxConvUTF8.cWC2MB(funcName.wc_str(*wxConvCurrent));
 
2404
  const char* localFuncName = strFuncName;
 
2405
  int rc = sqlite3_create_function((sqlite3*) m_db, localFuncName, argCount,
 
2406
                                   SQLITE_UTF8, &function,
 
2407
                                   (void (*)(sqlite3_context*,int,sqlite3_value**)) wxSQLite3FunctionContext::ExecScalarFunction, NULL, NULL);
 
2408
  return rc == SQLITE_OK;
 
2409
}
 
2410
 
 
2411
bool wxSQLite3Database::CreateFunction(const wxString& funcName, int argCount, wxSQLite3AggregateFunction& function)
 
2412
{
 
2413
  CheckDatabase();
 
2414
  wxCharBuffer strFuncName = wxConvUTF8.cWC2MB(funcName.wc_str(*wxConvCurrent));
 
2415
  const char* localFuncName = strFuncName;
 
2416
  int rc = sqlite3_create_function((sqlite3*) m_db, localFuncName, argCount,
 
2417
                                   SQLITE_UTF8, &function,
 
2418
                                   NULL, 
 
2419
                                   (void (*)(sqlite3_context*,int,sqlite3_value**)) wxSQLite3FunctionContext::ExecAggregateStep, 
 
2420
                                   (void (*)(sqlite3_context*)) wxSQLite3FunctionContext::ExecAggregateFinalize);
 
2421
  return rc == SQLITE_OK;
 
2422
}
 
2423
 
 
2424
bool wxSQLite3Database::SetAuthorizer(wxSQLite3Authorizer& authorizer)
 
2425
{
 
2426
  CheckDatabase();
 
2427
  int rc = sqlite3_set_authorizer((sqlite3*) m_db, wxSQLite3FunctionContext::ExecAuthorizer, &authorizer);
 
2428
  return rc == SQLITE_OK;
 
2429
}
 
2430
 
 
2431
void wxSQLite3Database::SetCommitHook(wxSQLite3Hook* commitHook)
 
2432
{
 
2433
  CheckDatabase();
 
2434
  if (commitHook)
 
2435
  {
 
2436
    sqlite3_commit_hook((sqlite3*) m_db, (int(*)(void*)) wxSQLite3FunctionContext::ExecCommitHook, commitHook);
 
2437
  }
 
2438
  else
 
2439
  {
 
2440
    sqlite3_commit_hook((sqlite3*) m_db, (int(*)(void*)) NULL, NULL);
 
2441
  }
 
2442
}
 
2443
 
 
2444
void wxSQLite3Database::SetRollbackHook(wxSQLite3Hook* rollbackHook)
 
2445
{
 
2446
  CheckDatabase();
 
2447
  if (rollbackHook)
 
2448
  {
 
2449
    sqlite3_rollback_hook((sqlite3*) m_db, (void(*)(void*)) wxSQLite3FunctionContext::ExecRollbackHook, rollbackHook);
 
2450
  }
 
2451
  else
 
2452
  {
 
2453
    sqlite3_rollback_hook((sqlite3*) m_db, (void(*)(void*)) NULL, NULL);
 
2454
  }
 
2455
}
 
2456
 
 
2457
void wxSQLite3Database::SetUpdateHook(wxSQLite3Hook* updateHook)
 
2458
{
 
2459
  CheckDatabase();
 
2460
  if (updateHook)
 
2461
  {
 
2462
    sqlite3_update_hook((sqlite3*) m_db, (void(*)(void*,int,const char*,const char*, wxsqlite_int64)) wxSQLite3FunctionContext::ExecUpdateHook, updateHook);
 
2463
  }
 
2464
  else
 
2465
  {
 
2466
    sqlite3_update_hook((sqlite3*) m_db, (void(*)(void*,int,const char*,const char*, wxsqlite_int64)) NULL, NULL);
 
2467
  }
 
2468
}
 
2469
 
 
2470
void wxSQLite3Database::SetCollation(const wxString& collationName, wxSQLite3Collation* collation)
 
2471
{
 
2472
  CheckDatabase();
 
2473
  wxCharBuffer strCollationName = wxConvUTF8.cWC2MB(collationName.wc_str(*wxConvCurrent));
 
2474
  const char* localCollationName = strCollationName;
 
2475
  int rc;
 
2476
  if (collation)
 
2477
  {
 
2478
    rc = sqlite3_create_collation((sqlite3*) m_db, localCollationName, SQLITE_UTF8, collation, (int(*)(void*,int,const void*,int,const void*)) wxSQLite3Database::ExecComparisonWithCollation);
 
2479
  }
 
2480
  else
 
2481
  {
 
2482
    rc = sqlite3_create_collation((sqlite3*) m_db, localCollationName, SQLITE_UTF8, NULL, (int(*)(void*,int,const void*,int,const void*)) NULL);
 
2483
  }
 
2484
}
 
2485
 
 
2486
void wxSQLite3Database::SetCollationNeededCallback()
 
2487
{
 
2488
  CheckDatabase();
 
2489
  int rc = sqlite3_collation_needed((sqlite3*) m_db, this, (void(*)(void*,sqlite3*,int,const char*)) wxSQLite3Database::ExecCollationNeeded);
 
2490
  if (rc != SQLITE_OK)
 
2491
  {
 
2492
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2493
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
2494
  }
 
2495
}
 
2496
 
 
2497
void wxSQLite3Database::CheckDatabase()
 
2498
{
 
2499
  if (!m_db)
 
2500
  {
 
2501
    throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NODB);
 
2502
  }
 
2503
}
 
2504
 
 
2505
void* wxSQLite3Database::Prepare(const char* sql)
 
2506
{
 
2507
  CheckDatabase();
 
2508
 
 
2509
  const char* tail=0;
 
2510
  sqlite3_stmt* stmt;
 
2511
 
 
2512
  int rc = sqlite3_prepare_v2((sqlite3*) m_db, sql, -1, &stmt, &tail);
 
2513
 
 
2514
  if (rc != SQLITE_OK)
 
2515
  {
 
2516
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2517
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
2518
  }
 
2519
 
 
2520
  return stmt;
 
2521
}
 
2522
 
 
2523
/* static */
 
2524
int wxSQLite3Database::ExecComparisonWithCollation(void* collation,
 
2525
                                                   int len1, const void* text1,
 
2526
                                                   int len2, const void* text2)
 
2527
{
 
2528
#if wxUSE_UNICODE
 
2529
  wxString locText1((const char*) text1, wxConvUTF8, (size_t) len1);
 
2530
  wxString locText2((const char*) text2, wxConvUTF8, (size_t) len2);
 
2531
#else
 
2532
  size_t len = (len1 > len2) ? len1 : len2;
 
2533
  char* buffer = new char[len+1];
 
2534
  memcpy(buffer, text1, len1);
 
2535
  buffer[len1] = '\0';
 
2536
  wxString locText1(wxConvUTF8.cMB2WC((const char*) buffer), *wxConvCurrent);
 
2537
  memcpy(buffer, text2, len2);
 
2538
  buffer[len2] = '\0';
 
2539
  wxString locText2(wxConvUTF8.cMB2WC((const char*) buffer), *wxConvCurrent);
 
2540
  delete [] buffer;
 
2541
#endif
 
2542
  return ((wxSQLite3Collation*) collation)->Compare(locText1, locText2);
 
2543
}
 
2544
 
 
2545
void wxSQLite3Database::ExecCollationNeeded(void* db, void*, int, const char* collationName)
 
2546
{
 
2547
#if wxUSE_UNICODE
 
2548
  wxString locCollation((const char*) collationName, wxConvUTF8);
 
2549
#else
 
2550
  wxString locCollation(wxConvUTF8.cMB2WC((const char*) collationName), *wxConvCurrent);
 
2551
#endif
 
2552
  ((wxSQLite3Database*) db)->SetNeededCollation(locCollation);
 
2553
}
 
2554
 
 
2555
void wxSQLite3Database::GetMetaData(const wxString& databaseName, const wxString& tableName, const wxString& columnName,
 
2556
                                    wxString* dataType, wxString* collation, bool* notNull, bool* primaryKey, bool* autoIncrement)
 
2557
{
 
2558
#if WXSQLITE3_HAVE_METADATA
 
2559
  wxCharBuffer strDatabaseName = wxConvUTF8.cWC2MB(databaseName.wc_str(*wxConvCurrent));
 
2560
  const char* localDatabaseName = strDatabaseName;
 
2561
  if (databaseName == wxEmptyString) localDatabaseName = NULL;
 
2562
  wxCharBuffer strTableName = wxConvUTF8.cWC2MB(tableName.wc_str(*wxConvCurrent));
 
2563
  const char* localTableName = strTableName;
 
2564
  wxCharBuffer strColumnName = wxConvUTF8.cWC2MB(columnName.wc_str(*wxConvCurrent));
 
2565
  const char* localColumnName = strColumnName;
 
2566
  const char* localDataType;
 
2567
  const char* localCollation;
 
2568
  int localNotNull;
 
2569
  int localPrimaryKey;
 
2570
  int localAutoIncrement;
 
2571
  int rc = sqlite3_table_column_metadata((sqlite3*) m_db, localDatabaseName, localTableName, localColumnName,
 
2572
                                         &localDataType, &localCollation, &localNotNull, &localPrimaryKey, &localAutoIncrement);
 
2573
 
 
2574
  if (rc != SQLITE_OK)
 
2575
  {
 
2576
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2577
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
2578
  }
 
2579
 
 
2580
  if (dataType      != NULL) *dataType      = UTF8toWxString(localDataType);
 
2581
  if (collation     != NULL) *collation     = UTF8toWxString(localCollation);
 
2582
 
 
2583
  if (notNull       != NULL) *notNull       = (localNotNull       != 0);
 
2584
  if (primaryKey    != NULL) *primaryKey    = (localPrimaryKey    != 0);
 
2585
  if (autoIncrement != NULL) *autoIncrement = (localAutoIncrement != 0);
 
2586
#else
 
2587
  wxUnusedVar(databaseName);
 
2588
  wxUnusedVar(tableName);
 
2589
  wxUnusedVar(columnName);
 
2590
  wxUnusedVar(dataType);
 
2591
  wxUnusedVar(collation);
 
2592
  wxUnusedVar(notNull);
 
2593
  wxUnusedVar(primaryKey);
 
2594
  wxUnusedVar(autoIncrement);
 
2595
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOMETADATA);
 
2596
#endif
 
2597
}
 
2598
 
 
2599
void wxSQLite3Database::LoadExtension(const wxString& fileName, const wxString& entryPoint)
 
2600
{
 
2601
#if WXSQLITE3_HAVE_LOAD_EXTENSION
 
2602
  wxCharBuffer strFileName = wxConvUTF8.cWC2MB(fileName.wc_str(*wxConvCurrent));
 
2603
  const char* localFileName = strFileName;
 
2604
  wxCharBuffer strEntryPoint = wxConvUTF8.cWC2MB(entryPoint.wc_str(*wxConvCurrent));
 
2605
  const char* localEntryPoint = strEntryPoint;
 
2606
 
 
2607
  int rc = sqlite3_load_extension((sqlite3 *) m_db, localFileName, localEntryPoint, NULL);
 
2608
  if (rc != SQLITE_OK)
 
2609
  {
 
2610
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2611
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
2612
  }
 
2613
#else
 
2614
  wxUnusedVar(fileName);
 
2615
  wxUnusedVar(entryPoint);
 
2616
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOLOADEXT);
 
2617
#endif
 
2618
}
 
2619
 
 
2620
void wxSQLite3Database::EnableLoadExtension(bool enable)
 
2621
{
 
2622
#if WXSQLITE3_HAVE_LOAD_EXTENSION
 
2623
  int onoff = (enable) ? 1 : 0;
 
2624
  int rc = sqlite3_enable_load_extension((sqlite3 *) m_db, onoff);
 
2625
  if (rc != SQLITE_OK)
 
2626
  {
 
2627
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2628
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
2629
  }
 
2630
#else
 
2631
  wxUnusedVar(enable);
 
2632
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOLOADEXT);
 
2633
#endif
 
2634
}
 
2635
 
 
2636
void wxSQLite3Database::ReKey(const wxString& newKey)
 
2637
{
 
2638
#if WXSQLITE3_HAVE_CODEC
 
2639
  wxCharBuffer strLocalNewKey = wxConvUTF8.cWC2MB(newKey.wc_str(*wxConvCurrent));
 
2640
  const char* localNewKey = strLocalNewKey;
 
2641
  wxMemoryBuffer binaryNewKey;
 
2642
  if (newKey.Length() > 0)
 
2643
  {
 
2644
    binaryNewKey.AppendData((void*) localNewKey, strlen(localNewKey));
 
2645
  }
 
2646
  ReKey(binaryNewKey);
 
2647
#else
 
2648
  wxUnusedVar(newKey);
 
2649
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOCODEC);
 
2650
#endif
 
2651
}
 
2652
 
 
2653
void wxSQLite3Database::ReKey(const wxMemoryBuffer& newKey)
 
2654
{
 
2655
#if WXSQLITE3_HAVE_CODEC
 
2656
  int rc = sqlite3_rekey((sqlite3*) m_db, newKey.GetData(), (int) newKey.GetDataLen());
 
2657
  if (rc != SQLITE_OK)
 
2658
  {
 
2659
    const char* localError = sqlite3_errmsg((sqlite3*) m_db);
 
2660
    throw wxSQLite3Exception(rc, UTF8toWxString(localError));
 
2661
  }
 
2662
#else
 
2663
  wxUnusedVar(newKey);
 
2664
  throw wxSQLite3Exception(WXSQLITE_ERROR, wxERRMSG_NOCODEC);
 
2665
#endif
 
2666
}
 
2667
 
 
2668
int wxSQLite3Database::GetLimit(wxSQLite3LimitType id)
 
2669
{
 
2670
  int value = -1;
 
2671
#if SQLITE_VERSION_NUMBER >= 3005008
 
2672
  CheckDatabase();
 
2673
  if (id >= WXSQLITE_LIMIT_LENGTH && id <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
 
2674
  {
 
2675
    value = sqlite3_limit((sqlite3 *) m_db, id, -1);
 
2676
  }
 
2677
#else
 
2678
  wxUnusedVar(id);
 
2679
#endif
 
2680
  return value;
 
2681
}
 
2682
 
 
2683
int wxSQLite3Database::SetLimit(wxSQLite3LimitType id, int newValue)
 
2684
{
 
2685
  int value = -1;
 
2686
#if SQLITE_VERSION_NUMBER >= 3005008
 
2687
  CheckDatabase();
 
2688
  if (id >= WXSQLITE_LIMIT_LENGTH && id <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
 
2689
  {
 
2690
    value = sqlite3_limit((sqlite3 *) m_db, id, newValue);
 
2691
  }
 
2692
#else
 
2693
  wxUnusedVar(id);
 
2694
  wxUnusedVar(newValue);
 
2695
#endif
 
2696
  return value;
 
2697
}
 
2698
 
 
2699
static const wxChar* limitCodeString[] =
 
2700
{ _T("SQLITE_LIMIT_LENGTH"),              _T("SQLITE_LIMIT_SQL_LENGTH"),
 
2701
  _T("SQLITE_LIMIT_COLUMN"),              _T("SQLITE_LIMIT_EXPR_DEPTH"),
 
2702
  _T("SQLITE_LIMIT_COMPOUND_SELECT"),     _T("SQLITE_LIMIT_VDBE_OP"),
 
2703
  _T("SQLITE_LIMIT_FUNCTION_ARG"),        _T("SQLITE_LIMIT_ATTACHED"),
 
2704
  _T("SQLITE_LIMIT_LIKE_PATTERN_LENGTH"), _T("SQLITE_LIMIT_VARIABLE_NUMBER")
 
2705
};
 
2706
 
 
2707
 
 
2708
/* static */
 
2709
wxString wxSQLite3Database::LimitTypeToString(wxSQLite3LimitType type)
 
2710
{
 
2711
  const wxChar* limitString = _T("Unknown");
 
2712
  if (type >= WXSQLITE_LIMIT_LENGTH && type <= WXSQLITE_LIMIT_VARIABLE_NUMBER)
 
2713
  {
 
2714
    limitString = limitCodeString[type];
 
2715
  }
 
2716
  return wxString(limitString);
 
2717
}
 
2718
 
 
2719
/* static */
 
2720
void wxSQLite3Database::InitializeSQLite()
 
2721
{
 
2722
#if SQLITE_VERSION_NUMBER >= 3006000
 
2723
  int rc = sqlite3_initialize();
 
2724
  if (rc != SQLITE_OK)
 
2725
  {
 
2726
    throw wxSQLite3Exception(rc, wxERRMSG_INITIALIZE);
 
2727
  }
 
2728
#endif
 
2729
}
 
2730
 
 
2731
/* static */
 
2732
void wxSQLite3Database::ShutdownSQLite()
 
2733
{
 
2734
#if SQLITE_VERSION_NUMBER >= 3006000
 
2735
  int rc = sqlite3_shutdown();
 
2736
  if (rc != SQLITE_OK)
 
2737
  {
 
2738
    throw wxSQLite3Exception(rc, wxERRMSG_SHUTDOWN);
 
2739
  }
 
2740
#endif
 
2741
}
 
2742
 
 
2743
/* static */
 
2744
bool wxSQLite3Database::Randomness(int n, wxMemoryBuffer& random)
 
2745
{
 
2746
  bool ok = false;
 
2747
#if SQLITE_VERSION_NUMBER >= 3005008
 
2748
  if (n > 0)
 
2749
  {
 
2750
    void* buffer = random.GetWriteBuf(n);
 
2751
    sqlite3_randomness(n, buffer);
 
2752
    random.UngetWriteBuf(n);
 
2753
    ok = true;
 
2754
  }
 
2755
#else
 
2756
  wxUnusedVar(n);
 
2757
  wxUnusedVar(random);
 
2758
#endif
 
2759
  return ok;
 
2760
}
 
2761
 
 
2762
// ----------------------------------------------------------------------------
 
2763
// wxSQLite3FunctionContext: class providing the function context 
 
2764
//                           for user defined functions
 
2765
// ----------------------------------------------------------------------------
 
2766
 
 
2767
int wxSQLite3FunctionContext::GetArgCount()
 
2768
{
 
2769
  return m_argc;
 
2770
}
 
2771
 
 
2772
int wxSQLite3FunctionContext::GetArgType(int argIndex)
 
2773
{
 
2774
  if (argIndex >= 0 && argIndex < m_argc)
 
2775
  {
 
2776
    return sqlite3_value_type((sqlite3_value*) m_argv[argIndex]);
 
2777
  }
 
2778
  else
 
2779
  {
 
2780
    return SQLITE_NULL;
 
2781
  }
 
2782
}
 
2783
 
 
2784
bool wxSQLite3FunctionContext::IsNull(int argIndex)
 
2785
{
 
2786
  if (argIndex >= 0 && argIndex < m_argc)
 
2787
  {
 
2788
    return sqlite3_value_type((sqlite3_value*) m_argv[argIndex]) == SQLITE_NULL;
 
2789
  }
 
2790
  else
 
2791
  {
 
2792
    return true;
 
2793
  }
 
2794
}
 
2795
 
 
2796
int wxSQLite3FunctionContext::GetInt(int argIndex, int nullValue)
 
2797
{
 
2798
  if (argIndex >= 0 && argIndex < m_argc)
 
2799
  {
 
2800
    if (!IsNull(argIndex))
 
2801
    {
 
2802
      return sqlite3_value_int((sqlite3_value*) m_argv[argIndex]);
 
2803
    }
 
2804
    else
 
2805
    {
 
2806
      return nullValue;
 
2807
    }
 
2808
  }
 
2809
  else
 
2810
  {
 
2811
    return nullValue;
 
2812
  }
 
2813
}
 
2814
 
 
2815
wxLongLong wxSQLite3FunctionContext::GetInt64(int argIndex, wxLongLong nullValue)
 
2816
{
 
2817
  if (argIndex >= 0 && argIndex < m_argc)
 
2818
  {
 
2819
    if (!IsNull(argIndex))
 
2820
    {
 
2821
      return wxLongLong(sqlite3_value_int64((sqlite3_value*) m_argv[argIndex]));
 
2822
    }
 
2823
    else
 
2824
    {
 
2825
      return nullValue;
 
2826
    }
 
2827
  }
 
2828
  else
 
2829
  {
 
2830
    return nullValue;
 
2831
  }
 
2832
}
 
2833
 
 
2834
double wxSQLite3FunctionContext::GetDouble(int argIndex, double nullValue)
 
2835
{
 
2836
  if (argIndex >= 0 && argIndex < m_argc)
 
2837
  {
 
2838
    if (!IsNull(argIndex))
 
2839
    {
 
2840
      return sqlite3_value_double((sqlite3_value*) m_argv[argIndex]);
 
2841
    }
 
2842
    else
 
2843
    {
 
2844
      return nullValue;
 
2845
    }
 
2846
  }
 
2847
  else
 
2848
  {
 
2849
    return nullValue;
 
2850
  }
 
2851
}
 
2852
 
 
2853
wxString wxSQLite3FunctionContext::GetString(int argIndex, const wxString& nullValue)
 
2854
{
 
2855
  if (argIndex >= 0 && argIndex < m_argc)
 
2856
  {
 
2857
    if (!IsNull(argIndex))
 
2858
    {
 
2859
      const char* localValue = (const char*) sqlite3_value_text((sqlite3_value*) m_argv[argIndex]);
 
2860
      return UTF8toWxString(localValue);
 
2861
    }
 
2862
    else
 
2863
    {
 
2864
      return nullValue;
 
2865
    }
 
2866
  }
 
2867
  else
 
2868
  {
 
2869
    return nullValue;
 
2870
  }
 
2871
}
 
2872
 
 
2873
wxMemoryBuffer& wxSQLite3FunctionContext::GetBlob(int argIndex, wxMemoryBuffer& buffer)
 
2874
{
 
2875
  if (argIndex >= 0 && argIndex < m_argc)
 
2876
  {
 
2877
    if (!IsNull(argIndex))
 
2878
    {
 
2879
      int len = sqlite3_value_bytes((sqlite3_value*) m_argv[argIndex]);
 
2880
      const void* blob = sqlite3_value_blob((sqlite3_value*) m_argv[argIndex]);
 
2881
      buffer.AppendData((void*) blob, (size_t) len);
 
2882
    }
 
2883
  }
 
2884
  return buffer;
 
2885
}
 
2886
 
 
2887
void wxSQLite3FunctionContext::SetResult(int value)
 
2888
{
 
2889
  sqlite3_result_int((sqlite3_context*) m_ctx, value);
 
2890
}
 
2891
 
 
2892
void wxSQLite3FunctionContext::SetResult(wxLongLong value)
 
2893
{
 
2894
  sqlite3_result_int64((sqlite3_context*) m_ctx, value.GetValue());
 
2895
}
 
2896
 
 
2897
void wxSQLite3FunctionContext::SetResult(double value)
 
2898
{
 
2899
  sqlite3_result_double((sqlite3_context*) m_ctx, value);
 
2900
}
 
2901
 
 
2902
void wxSQLite3FunctionContext::SetResult(const wxString& value)
 
2903
{
 
2904
  wxCharBuffer strValue = wxConvUTF8.cWC2MB(value.wc_str(*wxConvCurrent));
 
2905
  const char* localValue = strValue;
 
2906
  sqlite3_result_text((sqlite3_context*) m_ctx, localValue, -1, SQLITE_TRANSIENT);
 
2907
}
 
2908
 
 
2909
void wxSQLite3FunctionContext::SetResult(unsigned char* value, int len)
 
2910
{
 
2911
  sqlite3_result_blob((sqlite3_context*) m_ctx, value, len, SQLITE_TRANSIENT);
 
2912
}
 
2913
 
 
2914
void wxSQLite3FunctionContext::SetResult(const wxMemoryBuffer& buffer)
 
2915
{
 
2916
  sqlite3_result_blob((sqlite3_context*) m_ctx, buffer.GetData(), (int) buffer.GetDataLen(), SQLITE_TRANSIENT);
 
2917
}
 
2918
 
 
2919
void wxSQLite3FunctionContext::SetResultNull()
 
2920
{
 
2921
  sqlite3_result_null((sqlite3_context*) m_ctx);
 
2922
}
 
2923
 
 
2924
void wxSQLite3FunctionContext::SetResultZeroBlob(int blobSize)
 
2925
{
 
2926
#if SQLITE_VERSION_NUMBER >= 3004000
 
2927
  sqlite3_result_zeroblob((sqlite3_context*) m_ctx, blobSize);
 
2928
#endif
 
2929
}
 
2930
 
 
2931
void wxSQLite3FunctionContext::SetResultArg(int argIndex)
 
2932
{
 
2933
  if (argIndex >= 0 && argIndex < m_argc) {
 
2934
    sqlite3_result_value((sqlite3_context*) m_ctx, (sqlite3_value*) m_argv[argIndex]);
 
2935
  } else {
 
2936
    sqlite3_result_null((sqlite3_context*) m_ctx);
 
2937
  }
 
2938
}
 
2939
 
 
2940
void wxSQLite3FunctionContext::SetResultError(const wxString& errmsg)
 
2941
{
 
2942
  wxCharBuffer strErrmsg = wxConvUTF8.cWC2MB(errmsg.wc_str(*wxConvCurrent));
 
2943
  const char* localErrmsg = strErrmsg;
 
2944
  sqlite3_result_error((sqlite3_context*) m_ctx, localErrmsg, -1);
 
2945
}
 
2946
 
 
2947
int wxSQLite3FunctionContext::GetAggregateCount()
 
2948
{
 
2949
  if (m_isAggregate)
 
2950
  {
 
2951
    return m_count;
 
2952
  }
 
2953
  else
 
2954
  {
 
2955
    return 0;
 
2956
  }
 
2957
}
 
2958
 
 
2959
void* wxSQLite3FunctionContext::GetAggregateStruct(int len)
 
2960
{
 
2961
  if (m_isAggregate)
 
2962
  {
 
2963
    return sqlite3_aggregate_context((sqlite3_context*) m_ctx, len);
 
2964
  }
 
2965
  else
 
2966
  {
 
2967
    return NULL;
 
2968
  }
 
2969
}
 
2970
 
 
2971
/* static */
 
2972
void wxSQLite3FunctionContext::ExecScalarFunction(void* ctx, int argc, void** argv)
 
2973
{
 
2974
  wxSQLite3FunctionContext context(ctx, false, argc, argv);
 
2975
  wxSQLite3ScalarFunction* func = (wxSQLite3ScalarFunction*) sqlite3_user_data((sqlite3_context*) ctx);
 
2976
  func->Execute(context);
 
2977
}
 
2978
 
 
2979
/* static */
 
2980
void wxSQLite3FunctionContext::ExecAggregateStep(void* ctx, int argc, void** argv)
 
2981
{
 
2982
  wxSQLite3FunctionContext context(ctx, true, argc, argv);
 
2983
  wxSQLite3AggregateFunction* func = (wxSQLite3AggregateFunction*) sqlite3_user_data((sqlite3_context*) ctx);
 
2984
  func->m_count++;
 
2985
  context.m_count = func->m_count;
 
2986
  func->Aggregate(context);
 
2987
}
 
2988
 
 
2989
/* static */
 
2990
void wxSQLite3FunctionContext::ExecAggregateFinalize(void* ctx)
 
2991
{
 
2992
  wxSQLite3FunctionContext context(ctx, true, 0, NULL);
 
2993
  wxSQLite3AggregateFunction* func = (wxSQLite3AggregateFunction*) sqlite3_user_data((sqlite3_context*) ctx);
 
2994
  context.m_count = func->m_count;
 
2995
  func->Finalize(context);
 
2996
}
 
2997
 
 
2998
/* static */
 
2999
int wxSQLite3FunctionContext::ExecAuthorizer(void* func, int type,
 
3000
                                             const char* arg1, const char* arg2,
 
3001
                                             const char* arg3, const char* arg4)
 
3002
{
 
3003
#if wxUSE_UNICODE
 
3004
  wxString locArg1(arg1, wxConvUTF8);
 
3005
  wxString locArg2(arg2, wxConvUTF8);
 
3006
  wxString locArg3(arg3, wxConvUTF8);
 
3007
  wxString locArg4(arg4, wxConvUTF8);
 
3008
#else
 
3009
  wxString locArg1(wxConvUTF8.cMB2WC(arg1), *wxConvCurrent);
 
3010
  wxString locArg2(wxConvUTF8.cMB2WC(arg2), *wxConvCurrent);
 
3011
  wxString locArg3(wxConvUTF8.cMB2WC(arg3), *wxConvCurrent);
 
3012
  wxString locArg4(wxConvUTF8.cMB2WC(arg4), *wxConvCurrent);
 
3013
#endif
 
3014
  wxSQLite3Authorizer::wxAuthorizationCode localType = (wxSQLite3Authorizer::wxAuthorizationCode) type;
 
3015
  return (int) ((wxSQLite3Authorizer*) func)->Authorize(localType, locArg1, locArg2, locArg3, locArg3);
 
3016
}
 
3017
 
 
3018
/* static */
 
3019
int wxSQLite3FunctionContext::ExecCommitHook(void* hook)
 
3020
{
 
3021
  return (int) ((wxSQLite3Hook*) hook)->CommitCallback();
 
3022
}
 
3023
 
 
3024
/* static */
 
3025
void wxSQLite3FunctionContext::ExecRollbackHook(void* hook)
 
3026
{
 
3027
  ((wxSQLite3Hook*) hook)->RollbackCallback();
 
3028
}
 
3029
 
 
3030
/* static */
 
3031
void wxSQLite3FunctionContext::ExecUpdateHook(void* hook, int type, 
 
3032
                                              const char* database, const char* table, 
 
3033
                                              wxsqlite_int64 rowid)
 
3034
{
 
3035
#if wxUSE_UNICODE
 
3036
  wxString locDatabase(database, wxConvUTF8);
 
3037
  wxString locTable(table, wxConvUTF8);
 
3038
#else
 
3039
  wxString locDatabase(wxConvUTF8.cMB2WC(database), *wxConvCurrent);
 
3040
  wxString locTable(wxConvUTF8.cMB2WC(table), *wxConvCurrent);
 
3041
#endif
 
3042
  wxSQLite3Hook::wxUpdateType locType = (wxSQLite3Hook::wxUpdateType) type;
 
3043
  wxLongLong locRowid = rowid;
 
3044
  ((wxSQLite3Hook*) hook)->UpdateCallback(locType, locDatabase, locTable, locRowid);
 
3045
}
 
3046
 
 
3047
wxSQLite3FunctionContext::wxSQLite3FunctionContext(void* ctx, bool isAggregate, int argc, void** argv)
 
3048
: m_ctx(ctx), m_isAggregate(isAggregate), m_count(0), m_argc(argc), m_argv(argv)
 
3049
{
 
3050
}
 
3051
 
 
3052
static const wxChar* authCodeString[] =
 
3053
{ _T("SQLITE_COPY"),              _T("SQLITE_CREATE_INDEX"),      _T("SQLITE_CREATE_TABLE"),
 
3054
  _T("SQLITE_CREATE_TEMP_INDEX"), _T("SQLITE_CREATE_TEMP_TABLE"), _T("SQLITE_CREATE_TEMP_TRIGGER"),
 
3055
  _T("SQLITE_CREATE_TEMP_VIEW"),  _T("SQLITE_CREATE_TRIGGER"),    _T("SQLITE_CREATE_VIEW"),
 
3056
  _T("SQLITE_DELETE"),            _T("SQLITE_DROP_INDEX"),        _T("SQLITE_DROP_TABLE"), 
 
3057
  _T("SQLITE_DROP_TEMP_INDEX"),   _T("SQLITE_DROP_TEMP_TABLE"),   _T("SQLITE_DROP_TEMP_TRIGGER"), 
 
3058
  _T("SQLITE_DROP_TEMP_VIEW"),    _T("SQLITE_DROP_TRIGGER"),      _T("SQLITE_DROP_VIEW"), 
 
3059
  _T("SQLITE_INSERT"),            _T("SQLITE_PRAGMA"),            _T("SQLITE_READ"), 
 
3060
  _T("SQLITE_SELECT"),            _T("SQLITE_TRANSACTION"),       _T("SQLITE_UPDATE"), 
 
3061
  _T("SQLITE_ATTACH"),            _T("SQLITE_DETACH"),            _T("SQLITE_ALTER_TABLE"), 
 
3062
  _T("SQLITE_REINDEX"),           _T("SQLITE_ANALYZE"),           _T("SQLITE_CREATE_VTABLE"), 
 
3063
  _T("SQLITE_DROP_VTABLE"),       _T("SQLITE_FUNCTION"),          _T("SQLITE_SAVEPOINT")
 
3064
};
 
3065
 
 
3066
 
 
3067
/* static */
 
3068
wxString wxSQLite3Authorizer::AuthorizationCodeToString(wxSQLite3Authorizer::wxAuthorizationCode type)
 
3069
{
 
3070
  const wxChar* authString = _T("Unknown");
 
3071
  if (type >= SQLITE_COPY && type <= SQLITE_MAX_CODE)
 
3072
  {
 
3073
    authString = authCodeString[type];
 
3074
  }
 
3075
  return wxString(authString);
 
3076
}
 
3077
 
 
3078
// ----------------------------------------------------------------------------
 
3079
// wxSQLite3Transaction
 
3080
// ----------------------------------------------------------------------------
 
3081
 
 
3082
wxSQLite3Transaction::wxSQLite3Transaction(wxSQLite3Database* db, wxSQLite3TransactionType transactionType)
 
3083
{
 
3084
  assert(db != NULL);
 
3085
  m_database = db;
 
3086
  try
 
3087
  {
 
3088
    m_database->Begin(transactionType);
 
3089
  } 
 
3090
  catch (...)
 
3091
  {
 
3092
    m_database = NULL; // Flag that transaction is not active
 
3093
  }
 
3094
}
 
3095
 
 
3096
wxSQLite3Transaction::~wxSQLite3Transaction()
 
3097
{
 
3098
  if (m_database != NULL)
 
3099
  {
 
3100
    m_database->Rollback();
 
3101
  }
 
3102
}
 
3103
 
 
3104
void wxSQLite3Transaction::Commit()
 
3105
{
 
3106
  try
 
3107
  {
 
3108
    m_database->Commit();
 
3109
  }
 
3110
  catch (...)
 
3111
  {
 
3112
    m_database->Rollback();             
 
3113
  }
 
3114
  m_database = NULL;
 
3115
}
 
3116
 
 
3117
void wxSQLite3Transaction::Rollback()
 
3118
{
 
3119
  try
 
3120
  {
 
3121
    m_database->Rollback();
 
3122
  }
 
3123
  catch (...)
 
3124
  {
 
3125
    m_database->Rollback();             
 
3126
  }
 
3127
  m_database = NULL;
 
3128
}