System.Data.SQLite
Check-in [937230cef0]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Experimental changes to permit the unit test suite to pass with the debug version of SQLite.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | debugInteropFix
Files: files | file ages | folders
SHA1: 937230cef025187422b69e4d7bed7aa26bfa2b1a
User & Date: mistachkin 2011-07-22 23:13:38
Context
2011-07-23
00:57
Update SQLite core to latest. Closed-Leaf check-in: ecfb121b6e user: mistachkin tags: debugInteropFix
2011-07-22
23:13
Experimental changes to permit the unit test suite to pass with the debug version of SQLite. check-in: 937230cef0 user: mistachkin tags: debugInteropFix
21:21
Fix issue with building in a Visual Studio Command Prompt window. Support building and testing the VS2010 projects using the .NET Framework 3.5. check-in: a912d7f434 user: mistachkin tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to SQLite.Interop/src/win/crypt.c.

335
336
337
338
339
340
341


342
343
344
345
346
347
348
...
401
402
403
404
405
406
407


408
409
410
411
412
413
414
    //db->aDb[0].xFreeAux = DestroyCryptBlock;
  }
  else // Change the writekey for an already-encrypted database
  {
    pBlock->hWriteKey = hKey;
  }



  // Start a transaction
  rc = sqlite3BtreeBeginTrans(pbt, 1);

  if (!rc)
  {
    // Rewrite all the pages in the database using the new encryption key
    Pgno nPage;
................................................................................

  // If the readkey and writekey are both empty, there's no need for a codec on this
  // pager anymore.  Destroy the crypt block and remove the codec from the pager.
  if (!pBlock->hReadKey && !pBlock->hWriteKey)
  {
    sqlite3PagerSetCodec(p, NULL, NULL, NULL, NULL);
  }



  return rc;
}

#endif // SQLITE_HAS_CODEC

#endif // SQLITE_OMIT_DISKIO







>
>







 







>
>







335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
...
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
    //db->aDb[0].xFreeAux = DestroyCryptBlock;
  }
  else // Change the writekey for an already-encrypted database
  {
    pBlock->hWriteKey = hKey;
  }

  sqlite3_mutex_enter(db->mutex);

  // Start a transaction
  rc = sqlite3BtreeBeginTrans(pbt, 1);

  if (!rc)
  {
    // Rewrite all the pages in the database using the new encryption key
    Pgno nPage;
................................................................................

  // If the readkey and writekey are both empty, there's no need for a codec on this
  // pager anymore.  Destroy the crypt block and remove the codec from the pager.
  if (!pBlock->hReadKey && !pBlock->hWriteKey)
  {
    sqlite3PagerSetCodec(p, NULL, NULL, NULL, NULL);
  }

  sqlite3_mutex_leave(db->mutex);

  return rc;
}

#endif // SQLITE_HAS_CODEC

#endif // SQLITE_OMIT_DISKIO

Changes to SQLite.Interop/src/win/interop.c.

8
9
10
11
12
13
14



























15
16
17
18
19
20
21
..
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
...
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
...
361
362
363
364
365
366
367




368




369
370
371
372
373
374
375
#ifdef SQLITE_OS_WIN

// Additional open flags, we use this one privately
//#define SQLITE_OPEN_SHAREDCACHE      0x01000000

typedef void (*SQLITEUSERFUNC)(sqlite3_context *, int, sqlite3_value **);
typedef void (*SQLITEFUNCFINAL)(sqlite3_context *);




























/*
    The goal of this version of close is different than that of sqlite3_close(), and is designed to lend itself better to .NET's non-deterministic finalizers and
    the GC thread.  SQLite will not close a database if statements are open on it -- but for our purposes, we'd rather finalize all active statements
    and forcibly close the database.  The reason is simple -- a lot of people don't Dispose() of their objects correctly and let the garbage collector
    do it.  This leads to unexpected behavior when a user thinks they've closed a database, but it's still open because not all the statements have
    hit the GC yet.
................................................................................
  ret = sqlite3_close(db);

  if (ret == SQLITE_BUSY && db->pVdbe)
  {
    while (db->pVdbe)
    {
      // Make a copy of the first prepared statement
      Vdbe *p = (Vdbe *)sqlite3_malloc(sizeof(Vdbe));
      Vdbe *po = db->pVdbe;

      if (!p) 
      {
        ret = SQLITE_NOMEM;
        break;
      }
................................................................................

  p = (Vdbe *)stmt;
  if (p && p->magic == VDBE_MAGIC_DEAD)
  {
    db = p->db;
    if (db == NULL)
    {
      sqlite3_free(p);
      ret = SQLITE_OK;
    }
  }
  else
    ret = sqlite3_finalize(stmt);

  return ret;
................................................................................
}

__declspec(dllexport) int WINAPI sqlite3_index_column_info_interop(sqlite3 *db, const char *zDb, const char *zIndexName, const char *zColumnName, int *sortOrder, int *onError, char **pzColl, int *plen)
{
  Index *pIdx;
  Table *pTab;
  int n;




  pIdx = sqlite3FindIndex(db, zIndexName, zDb);




  if (!pIdx) return SQLITE_ERROR;

  pTab = pIdx->pTable;
  for (n = 0; n < pIdx->nColumn; n++)
  {
    int cnum = pIdx->aiColumn[n];
    if (sqlite3StrICmp(pTab->aCol[cnum].zName, zColumnName) == 0)







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|







 







>
>
>
>

>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
...
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
#ifdef SQLITE_OS_WIN

// Additional open flags, we use this one privately
//#define SQLITE_OPEN_SHAREDCACHE      0x01000000

typedef void (*SQLITEUSERFUNC)(sqlite3_context *, int, sqlite3_value **);
typedef void (*SQLITEFUNCFINAL)(sqlite3_context *);

__declspec(dllexport) void * WINAPI sqlite3DbMallocZero_interop(sqlite3 *db, int n)
{
  void *p;
  if (db) {
    sqlite3_mutex_enter(db->mutex);
  }
  p = sqlite3DbMallocZero(db,n);
  if (db) {
    sqlite3_mutex_leave(db->mutex);
  }
  return p;
}

__declspec(dllexport) void sqlite3DbFree_interop(sqlite3 *db, void *p)
{
  if (db) {
    sqlite3_mutex_enter(db->mutex);
  }
  if (p) {
    sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
  }
  sqlite3DbFree(db,p);
  if (db) {
    sqlite3_mutex_leave(db->mutex);
  }
}

/*
    The goal of this version of close is different than that of sqlite3_close(), and is designed to lend itself better to .NET's non-deterministic finalizers and
    the GC thread.  SQLite will not close a database if statements are open on it -- but for our purposes, we'd rather finalize all active statements
    and forcibly close the database.  The reason is simple -- a lot of people don't Dispose() of their objects correctly and let the garbage collector
    do it.  This leads to unexpected behavior when a user thinks they've closed a database, but it's still open because not all the statements have
    hit the GC yet.
................................................................................
  ret = sqlite3_close(db);

  if (ret == SQLITE_BUSY && db->pVdbe)
  {
    while (db->pVdbe)
    {
      // Make a copy of the first prepared statement
      Vdbe *p = (Vdbe *)sqlite3DbMallocZero_interop(db, sizeof(Vdbe));
      Vdbe *po = db->pVdbe;

      if (!p) 
      {
        ret = SQLITE_NOMEM;
        break;
      }
................................................................................

  p = (Vdbe *)stmt;
  if (p && p->magic == VDBE_MAGIC_DEAD)
  {
    db = p->db;
    if (db == NULL)
    {
      sqlite3DbFree_interop(db, p);
      ret = SQLITE_OK;
    }
  }
  else
    ret = sqlite3_finalize(stmt);

  return ret;
................................................................................
}

__declspec(dllexport) int WINAPI sqlite3_index_column_info_interop(sqlite3 *db, const char *zDb, const char *zIndexName, const char *zColumnName, int *sortOrder, int *onError, char **pzColl, int *plen)
{
  Index *pIdx;
  Table *pTab;
  int n;

  sqlite3_mutex_enter(db->mutex);
  sqlite3BtreeEnterAll(db);

  pIdx = sqlite3FindIndex(db, zIndexName, zDb);

  sqlite3BtreeLeaveAll(db);
  sqlite3_mutex_leave(db->mutex);

  if (!pIdx) return SQLITE_ERROR;

  pTab = pIdx->pTable;
  for (n = 0; n < pIdx->nColumn; n++)
  {
    int cnum = pIdx->aiColumn[n];
    if (sqlite3StrICmp(pTab->aCol[cnum].zName, zColumnName) == 0)