/ Check-in [8eaa0c71]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Add the journal_mode pragma. This is currently just syntax - it is not operational. (CVS 5024)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8eaa0c71023ac428f6f9f8091341584caa773ab9
User & Date: drh 2008-04-17 17:02:01
Context
2008-04-17
17:03
Fix a typo in the documentation for sqlite3_bind_text. Ticket #3056. (CVS 5025) check-in: 79571e2c user: drh tags: trunk
17:02
Add the journal_mode pragma. This is currently just syntax - it is not operational. (CVS 5024) check-in: 8eaa0c71 user: drh tags: trunk
14:16
In exclusive locking mode, commit by zeroing the first 28 bytes of the journal file, not by truncating the journal. Overwriting is much faster than truncating. (CVS 5023) check-in: 8efb7f4f user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/attach.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148


149
150
151
152
153
154
155
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.74 2008/03/20 14:03:29 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_ATTACH
/*
** Resolve an expression that was part of an ATTACH or DETACH statement. This
** is slightly different from resolving a normal SQL expression, because simple
................................................................................
  ** it to obtain the database schema. At this point the schema may
  ** or may not be initialised.
  */
  rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE,
                           db->openFlags | SQLITE_OPEN_MAIN_DB,
                           &aNew->pBt);
  if( rc==SQLITE_OK ){

    aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
    if( !aNew->pSchema ){
      rc = SQLITE_NOMEM;
    }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
      sqlite3_snprintf(sizeof(zErr), zErr, 
        "attached databases must use the same text encoding as main database");
      goto attach_error;
    }
    sqlite3PagerLockingMode(sqlite3BtreePager(aNew->pBt), db->dfltLockMode);


  }
  aNew->zName = sqlite3DbStrDup(db, zName);
  aNew->safety_level = 3;

#if SQLITE_HAS_CODEC
  {
    extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);







|







 







>








|
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.75 2008/04/17 17:02:01 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_ATTACH
/*
** Resolve an expression that was part of an ATTACH or DETACH statement. This
** is slightly different from resolving a normal SQL expression, because simple
................................................................................
  ** it to obtain the database schema. At this point the schema may
  ** or may not be initialised.
  */
  rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE,
                           db->openFlags | SQLITE_OPEN_MAIN_DB,
                           &aNew->pBt);
  if( rc==SQLITE_OK ){
    Pager *pPager;
    aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
    if( !aNew->pSchema ){
      rc = SQLITE_NOMEM;
    }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
      sqlite3_snprintf(sizeof(zErr), zErr, 
        "attached databases must use the same text encoding as main database");
      goto attach_error;
    }
    pPager = sqlite3BtreePager(aNew->pBt);
    sqlite3PagerLockingMode(pPager, db->dfltLockMode);
    sqlite3PagerJournalMode(pPager, db->dfltJournalMode);
  }
  aNew->zName = sqlite3DbStrDup(db, zName);
  aNew->safety_level = 3;

#if SQLITE_HAS_CODEC
  {
    extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
346
347
348
349
350
351
352

353
354
355
356
357
358
359
....
5198
5199
5200
5201
5202
5203
5204






















5205
5206
5207
5208
5209
5210
5211
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.427 2008/04/17 14:16:42 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
................................................................................
  u8 needSync;                /* True if an fsync() is needed on the journal */
  u8 dirtyCache;              /* True if cached pages have changed */
  u8 alwaysRollback;          /* Disable DontRollback() for all pages */
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  u8 doNotSync;               /* Boolean. While true, do not spill the cache */
  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */

  u8 changeCountDone;         /* Set after incrementing the change-counter */
  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
  int errCode;                /* One of several kinds of errors */
  int dbSize;                 /* Number of pages in the file */
  int origDbSize;             /* dbSize before the current change */
  int stmtSize;               /* Size of database (in pages) at stmt_begin() */
  int nRec;                   /* Number of pages written to the journal */
................................................................................
  assert( PAGER_LOCKINGMODE_QUERY<0 );
  assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 );
  if( eMode>=0 && !pPager->tempFile ){
    pPager->exclusiveMode = eMode;
  }
  return (int)pPager->exclusiveMode;
}























#ifdef SQLITE_TEST
/*
** Print a listing of all referenced pages and their ref count.
*/
void sqlite3PagerRefdump(Pager *pPager){
  PgHdr *pPg;







|







 







>







 







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







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
....
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.428 2008/04/17 17:02:01 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
................................................................................
  u8 needSync;                /* True if an fsync() is needed on the journal */
  u8 dirtyCache;              /* True if cached pages have changed */
  u8 alwaysRollback;          /* Disable DontRollback() for all pages */
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  u8 doNotSync;               /* Boolean. While true, do not spill the cache */
  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
  u8 persistJournal;          /* True if persistent_journal=ON */
  u8 changeCountDone;         /* Set after incrementing the change-counter */
  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
  int errCode;                /* One of several kinds of errors */
  int dbSize;                 /* Number of pages in the file */
  int origDbSize;             /* dbSize before the current change */
  int stmtSize;               /* Size of database (in pages) at stmt_begin() */
  int nRec;                   /* Number of pages written to the journal */
................................................................................
  assert( PAGER_LOCKINGMODE_QUERY<0 );
  assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 );
  if( eMode>=0 && !pPager->tempFile ){
    pPager->exclusiveMode = eMode;
  }
  return (int)pPager->exclusiveMode;
}

/*
** Get/set the journal-mode for this pager. Parameter eMode must be one
** of PAGER_JOURNALMODE_QUERY, PAGER_JOURNALMODE_DELETE or 
** PAGER_JOURNALMODE_PERSIST. If the parameter is not _QUERY, then
** the journal-mode is set to the value specified.
**
** The returned value is either PAGER_JOURNALMODE_DELETE or
** PAGER_JOURNALMODE_PERSIST, indicating the current (possibly updated)
** journal-mode.
*/
int sqlite3PagerJournalMode(Pager *pPager, int eMode){
  assert( eMode==PAGER_JOURNALMODE_QUERY
            || eMode==PAGER_JOURNALMODE_DELETE
            || eMode==PAGER_JOURNALMODE_PERSIST );
  assert( PAGER_JOURNALMODE_QUERY<0 );
  assert( PAGER_JOURNALMODE_DELETE>=0 && PAGER_JOURNALMODE_PERSIST>=0 );
  if( eMode>=0 && !pPager->tempFile ){
    pPager->persistJournal = eMode;
  }
  return (int)pPager->persistJournal;
}

#ifdef SQLITE_TEST
/*
** Print a listing of all referenced pages and their ref count.
*/
void sqlite3PagerRefdump(Pager *pPager){
  PgHdr *pPg;

Changes to src/pager.h.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
46
47
48
49
50
51
52








53
54
55
56
57
58
59
..
90
91
92
93
94
95
96

97
98
99
100
101
102
103
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem.  The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.70 2008/03/20 11:04:21 danielk1977 Exp $
*/

#ifndef _PAGER_H_
#define _PAGER_H_

/*
** The type used to represent a page number.  The first page in a file
................................................................................
/*
** Valid values for the second argument to sqlite3PagerLockingMode().
*/
#define PAGER_LOCKINGMODE_QUERY      -1
#define PAGER_LOCKINGMODE_NORMAL      0
#define PAGER_LOCKINGMODE_EXCLUSIVE   1









/*
** See source code comments for a detailed description of the following
** routines:
*/
int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char*, int,int,int);
void sqlite3PagerSetBusyhandler(Pager*, BusyHandler *pBusyHandler);
void sqlite3PagerSetDestructor(Pager*, void(*)(DbPage*,int));
................................................................................
const char *sqlite3PagerDirname(Pager*);
const char *sqlite3PagerJournalname(Pager*);
int sqlite3PagerNosync(Pager*);
int sqlite3PagerMovepage(Pager*,DbPage*,Pgno);
void *sqlite3PagerGetData(DbPage *); 
void *sqlite3PagerGetExtra(DbPage *); 
int sqlite3PagerLockingMode(Pager *, int);

void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerSync(Pager *pPager);

#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
  int sqlite3PagerReleaseMemory(int);
#endif








|







 







>
>
>
>
>
>
>
>







 







>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
..
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem.  The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.71 2008/04/17 17:02:01 drh Exp $
*/

#ifndef _PAGER_H_
#define _PAGER_H_

/*
** The type used to represent a page number.  The first page in a file
................................................................................
/*
** Valid values for the second argument to sqlite3PagerLockingMode().
*/
#define PAGER_LOCKINGMODE_QUERY      -1
#define PAGER_LOCKINGMODE_NORMAL      0
#define PAGER_LOCKINGMODE_EXCLUSIVE   1

/*
** Valid values for the second argument to sqlite3PagerJournalMode().
*/
#define PAGER_JOURNALMODE_QUERY      -1
#define PAGER_JOURNALMODE_DELETE      0   /* Commit by deleting journal file */
#define PAGER_JOURNALMODE_PERSIST     1   /* Commit by zeroing journal header */
#define PAGER_JOURNALMODE_OFF         2   /* Journal omitted.  */

/*
** See source code comments for a detailed description of the following
** routines:
*/
int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char*, int,int,int);
void sqlite3PagerSetBusyhandler(Pager*, BusyHandler *pBusyHandler);
void sqlite3PagerSetDestructor(Pager*, void(*)(DbPage*,int));
................................................................................
const char *sqlite3PagerDirname(Pager*);
const char *sqlite3PagerJournalname(Pager*);
int sqlite3PagerNosync(Pager*);
int sqlite3PagerMovepage(Pager*,DbPage*,Pgno);
void *sqlite3PagerGetData(DbPage *); 
void *sqlite3PagerGetExtra(DbPage *); 
int sqlite3PagerLockingMode(Pager *, int);
int sqlite3PagerJournalMode(Pager *, int);
void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerSync(Pager *pPager);

#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
  int sqlite3PagerReleaseMemory(int);
#endif

Changes to src/pragma.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
420
421
422
423
424
425
426























































427
428
429
430
431
432
433
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.174 2008/03/27 22:42:52 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)
................................................................................
      zRet = "exclusive";
    }
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", P4_STATIC);
    sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zRet, 0);
    sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
  }else























































#endif /* SQLITE_OMIT_PAGER_PRAGMAS */

  /*
  **  PRAGMA [database.]auto_vacuum
  **  PRAGMA [database.]auto_vacuum=N
  **
  ** Get or set the (boolean) value of the database 'auto-vacuum' parameter.







|







 







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







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.175 2008/04/17 17:02:02 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)
................................................................................
      zRet = "exclusive";
    }
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", P4_STATIC);
    sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zRet, 0);
    sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
  }else

  /*
  **  PRAGMA [database.]journal_mode
  **  PRAGMA [database.]journal_mode = (delete|persist|off)
  */
  if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
    int eMode;
    static const char *azModeName[] = {"delete", "persist", "off"};

    if( zRight==0 ){
      eMode = PAGER_JOURNALMODE_QUERY;
    }else{
      int n = strlen(zRight);
      eMode = 2;
      while( eMode>=0 && sqlite3StrNICmp(zRight, azModeName[eMode], n)!=0 ){
        eMode--;
      }
    }
    if( pId2->n==0 && eMode==PAGER_JOURNALMODE_QUERY ){
      /* Simple "PRAGMA persistent_journal;" statement. This is a query for
      ** the current default journal mode (which may be different to
      ** the journal-mode of the main database).
      */
      eMode = db->dfltJournalMode;
    }else{
      Pager *pPager;
      if( pId2->n==0 ){
        /* This indicates that no database name was specified as part
        ** of the PRAGMA command. In this case the journal-mode must be
        ** set on all attached databases, as well as the main db file.
        **
        ** Also, the sqlite3.dfltJournalMode variable is set so that
        ** any subsequently attached databases also use the specified
        ** journal mode.
        */
        int ii;
        assert(pDb==&db->aDb[0]);
        for(ii=2; ii<db->nDb; ii++){
          pPager = sqlite3BtreePager(db->aDb[ii].pBt);
          sqlite3PagerJournalMode(pPager, eMode);
        }
        db->dfltJournalMode = eMode;
      }
      pPager = sqlite3BtreePager(pDb->pBt);
      eMode = sqlite3PagerJournalMode(pPager, eMode);
    }
    assert( eMode==PAGER_JOURNALMODE_DELETE
              || eMode==PAGER_JOURNALMODE_PERSIST
              || eMode==PAGER_JOURNALMODE_OFF );
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", P4_STATIC);
    sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, 
           azModeName[eMode], P4_STATIC);
    sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
  }else
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */

  /*
  **  PRAGMA [database.]auto_vacuum
  **  PRAGMA [database.]auto_vacuum=N
  **
  ** Get or set the (boolean) value of the database 'auto-vacuum' parameter.

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
549
550
551
552
553
554
555


556
557
558
559
560
561
562
...
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.693 2008/04/15 14:36:42 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if it was run
** (otherwise we get an empty default).
................................................................................
  int flags;                    /* Miscellanous flags. See below */
  int openFlags;                /* Flags passed to sqlite3_vfs.xOpen() */
  int errCode;                  /* Most recent error code (SQLITE_*) */
  int errMask;                  /* & result codes with this before returning */
  u8 autoCommit;                /* The auto-commit flag. */
  u8 temp_store;                /* 1: file 2: memory 0: default */
  u8 mallocFailed;              /* True if we have seen a malloc failure */


  signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
  int nextPagesize;             /* Pagesize after VACUUM if >0 */
  int nTable;                   /* Number of tables in the database */
  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  i64 priorNewRowid;            /* Last randomly generated ROWID */
  int magic;                    /* Magic number for detect library misuse */
................................................................................
  Hash aCollSeq;                /* All collating sequences */
  BusyHandler busyHandler;      /* Busy callback */
  int busyTimeout;              /* Busy handler timeout, in msec */
  Db aDbStatic[2];              /* Static space for the 2 default backends */
#ifdef SQLITE_SSE
  sqlite3_stmt *pFetch;         /* Used by SSE to fetch stored statements */
#endif
  u8 dfltLockMode;              /* Default locking-mode for attached dbs */
};

/*
** A macro to discover the encoding of a database.
*/
#define ENC(db) ((db)->aDb[0].pSchema->enc)








|







 







>
>







 







<







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
...
615
616
617
618
619
620
621

622
623
624
625
626
627
628
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.694 2008/04/17 17:02:02 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if it was run
** (otherwise we get an empty default).
................................................................................
  int flags;                    /* Miscellanous flags. See below */
  int openFlags;                /* Flags passed to sqlite3_vfs.xOpen() */
  int errCode;                  /* Most recent error code (SQLITE_*) */
  int errMask;                  /* & result codes with this before returning */
  u8 autoCommit;                /* The auto-commit flag. */
  u8 temp_store;                /* 1: file 2: memory 0: default */
  u8 mallocFailed;              /* True if we have seen a malloc failure */
  u8 dfltLockMode;              /* Default locking-mode for attached dbs */
  u8 dfltJournalMode;           /* Default journal mode for attached dbs */
  signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
  int nextPagesize;             /* Pagesize after VACUUM if >0 */
  int nTable;                   /* Number of tables in the database */
  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  i64 priorNewRowid;            /* Last randomly generated ROWID */
  int magic;                    /* Magic number for detect library misuse */
................................................................................
  Hash aCollSeq;                /* All collating sequences */
  BusyHandler busyHandler;      /* Busy callback */
  int busyTimeout;              /* Busy handler timeout, in msec */
  Db aDbStatic[2];              /* Static space for the 2 default backends */
#ifdef SQLITE_SSE
  sqlite3_stmt *pFetch;         /* Used by SSE to fetch stored statements */
#endif

};

/*
** A macro to discover the encoding of a database.
*/
#define ENC(db) ((db)->aDb[0].pSchema->enc)