/ Check-in [f07e97ae]
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:Improved documentation for sqlite3_serialize() and sqlite3_deserialize(). Change the name of the compile-time option to enable these interfaces from SQLITE_ENABLE_MEMDB to SQLITE_ENABLE_DESERIALIZE.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | memdb
Files: files | file ages | folders
SHA3-256: f07e97aed435b02e1473053c0257ec5c89bf0b3e46076b7a9382de432bbc2497
User & Date: drh 2018-03-06 21:43:19
Context
2018-03-07
01:37
Mark an unreachable branch using NEVER(). Closed-Leaf check-in: fadbc5e2 user: drh tags: memdb
2018-03-06
21:43
Improved documentation for sqlite3_serialize() and sqlite3_deserialize(). Change the name of the compile-time option to enable these interfaces from SQLITE_ENABLE_MEMDB to SQLITE_ENABLE_DESERIALIZE. check-in: f07e97ae user: drh tags: memdb
20:54
Handle some boundary cases in memdb associated with OOM faults. check-in: b58ca4cb user: drh tags: memdb
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/attach.c.

    80     80   
    81     81     UNUSED_PARAMETER(NotUsed);
    82     82     zFile = (const char *)sqlite3_value_text(argv[0]);
    83     83     zName = (const char *)sqlite3_value_text(argv[1]);
    84     84     if( zFile==0 ) zFile = "";
    85     85     if( zName==0 ) zName = "";
    86     86   
    87         -#ifdef SQLITE_ENABLE_MEMDB
           87  +#ifdef SQLITE_ENABLE_DESERIALIZE
    88     88   # define REOPEN_AS_MEMDB(db)  (db->init.reopenMemdb)
    89     89   #else
    90     90   # define REOPEN_AS_MEMDB(db)  (0)
    91     91   #endif
    92     92   
    93     93     if( REOPEN_AS_MEMDB(db) ){
    94     94       /* This is not a real ATTACH.  Instead, this routine is being called

Changes to src/main.c.

   235    235       if( sqlite3GlobalConfig.isPCacheInit==0 ){
   236    236         rc = sqlite3PcacheInitialize();
   237    237       }
   238    238       if( rc==SQLITE_OK ){
   239    239         sqlite3GlobalConfig.isPCacheInit = 1;
   240    240         rc = sqlite3OsInit();
   241    241       }
   242         -#ifdef SQLITE_ENABLE_MEMDB
          242  +#ifdef SQLITE_ENABLE_DESERIALIZE
   243    243       if( rc==SQLITE_OK ){
   244    244         rc = sqlite3MemdbInit();
   245    245       }
   246    246   #endif
   247    247       if( rc==SQLITE_OK ){
   248    248         sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, 
   249    249             sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);

Changes to src/memdb.c.

    12     12   **
    13     13   ** This file implements in-memory VFS.  A database is held as a contiguous
    14     14   ** block of memory.
    15     15   **
    16     16   ** This file also implements interface sqlite3_serialize() and
    17     17   ** sqlite3_deserialize().
    18     18   */
    19         -#ifdef SQLITE_ENABLE_MEMDB
           19  +#ifdef SQLITE_ENABLE_DESERIALIZE
    20     20   #include "sqliteInt.h"
    21     21   
    22     22   /*
    23     23   ** Forward declaration of objects used by this utility
    24     24   */
    25     25   typedef struct sqlite3_vfs MemVfs;
    26     26   typedef struct MemFile MemFile;
................................................................................
   564    564     sqlite3_vfs *pLower = sqlite3_vfs_find(0);
   565    565     int sz = pLower->szOsFile;
   566    566     memdb_vfs.pAppData = pLower;
   567    567     if( sz<sizeof(MemFile) ) sz = sizeof(MemFile);
   568    568     memdb_vfs.szOsFile = sz;
   569    569     return sqlite3_vfs_register(&memdb_vfs, 0);
   570    570   }
   571         -#endif /* SQLITE_ENABLE_MEMDB */
          571  +#endif /* SQLITE_ENABLE_DESERIALIZE */

Changes to src/pager.c.

  4719   4719     void (*xReinit)(DbPage*) /* Function to reinitialize pages */
  4720   4720   ){
  4721   4721     u8 *pPtr;
  4722   4722     Pager *pPager = 0;       /* Pager object to allocate and return */
  4723   4723     int rc = SQLITE_OK;      /* Return code */
  4724   4724     int tempFile = 0;        /* True for temp files (incl. in-memory files) */
  4725   4725     int memDb = 0;           /* True if this is an in-memory file */
         4726  +#ifdef SQLITE_ENABLE_DESERIALIZE
  4726   4727     int memJM = 0;           /* Memory journal mode */
         4728  +#else
         4729  +# define memJM 0
         4730  +#endif
  4727   4731     int readOnly = 0;        /* True if this is a read-only file */
  4728   4732     int journalFileSize;     /* Bytes to allocate for each journal fd */
  4729   4733     char *zPathname = 0;     /* Full path to database file */
  4730   4734     int nPathname = 0;       /* Number of bytes in zPathname */
  4731   4735     int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
  4732   4736     int pcacheSize = sqlite3PcacheSize();       /* Bytes to allocate for PCache */
  4733   4737     u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
................................................................................
  4847   4851   
  4848   4852     /* Open the pager file.
  4849   4853     */
  4850   4854     if( zFilename && zFilename[0] ){
  4851   4855       int fout = 0;                    /* VFS flags returned by xOpen() */
  4852   4856       rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
  4853   4857       assert( !memDb );
         4858  +#ifdef SQLITE_ENABLE_DESERIALIZE
  4854   4859       memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
         4860  +#endif
  4855   4861       readOnly = (fout&SQLITE_OPEN_READONLY)!=0;
  4856   4862   
  4857   4863       /* If the file was successfully opened for read/write access,
  4858   4864       ** choose a default page size in case we have to create the
  4859   4865       ** database file. The default page size is the maximum of:
  4860   4866       **
  4861   4867       **    + SQLITE_DEFAULT_PAGE_SIZE,

Changes to src/sqlite.h.in.

  8758   8758   ** The size of the database is written into *P even if the 
  8759   8759   ** SQLITE_SERIALIZE_NOCOPY bit is set but no contigious copy
  8760   8760   ** of the database exists.
  8761   8761   **
  8762   8762   ** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
  8763   8763   ** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
  8764   8764   ** allocation error occurs.
         8765  +**
         8766  +** This interface is only available if SQLite is compiled with the
         8767  +** [SQLITE_ENABLE_DESERIALIZE] option.
  8765   8768   */
  8766   8769   unsigned char *sqlite3_serialize(
  8767   8770     sqlite3 *db,           /* The database connection */
  8768   8771     const char *zSchema,   /* Which DB to serialize. ex: "main", "temp", ... */
  8769   8772     sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */
  8770   8773     unsigned int mFlags    /* Zero or more SQLITE_SERIALIZE_* flags */
  8771   8774   );
  8772   8775   
  8773   8776   /*
  8774   8777   ** CAPI3REF: Flags for sqlite3_serialize
  8775   8778   ** EXPERIMENTAL
         8779  +**
         8780  +** Zero or more of the following constants can be OR-ed together for
         8781  +** the F argument to [sqlite3_serialize(D,S,P,F)].
         8782  +**
         8783  +** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return
         8784  +** a pointer to contiguous in-memory database that it is currently using,
         8785  +** without making a copy of the database.  If SQLite is not currently using
         8786  +** a contiguous in-memory database, then this option causes
         8787  +** [sqlite3_serialize()] to return a NULL pointer.  SQLite will only be
         8788  +** using a contiguous in-memory database if it has been initialized by a
         8789  +** prior call to [sqlite3_deserialize()].
  8776   8790   */
  8777   8791   #define SQLITE_SERIALIZE_NOCOPY 0x001   /* Do no memory allocations */
  8778   8792   
  8779   8793   /*
  8780   8794   ** CAPI3REF: Deserialize a database
  8781   8795   ** EXPERIMENTAL
  8782   8796   **
................................................................................
  8798   8812   ** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
  8799   8813   ** database is currently in a read transaction or is involved in a backup
  8800   8814   ** operation.
  8801   8815   **
  8802   8816   ** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the 
  8803   8817   ** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
  8804   8818   ** [sqlite3_free()] is invoked on argument P prior to returning.
         8819  +**
         8820  +** This interface is only available if SQLite is compiled with the
         8821  +** [SQLITE_ENABLE_DESERIALIZE] option.
  8805   8822   */
  8806   8823   int sqlite3_deserialize(
  8807   8824     sqlite3 *db,            /* The database connection */
  8808   8825     const char *zSchema,    /* Which DB to reopen with the deserialization */
  8809   8826     unsigned char *pData,   /* The serialized database content */
  8810   8827     sqlite3_int64 szDb,     /* Number bytes in the deserialization */
  8811   8828     sqlite3_int64 szBuf,    /* Total size of buffer pData[] */
................................................................................
  8812   8829     unsigned mFlags         /* Zero or more SQLITE_DESERIALIZE_* flags */
  8813   8830   );
  8814   8831   
  8815   8832   /*
  8816   8833   ** CAPI3REF: Flags for sqlite3_deserialize()
  8817   8834   ** EXPERIMENTAL
  8818   8835   **
  8819         -** The following are allowed values for the 6th argument (the "flags" or "F"
  8820         -** argument) of the [sqlite3_deserialize()] interface.
         8836  +** The following are allowed values for 6th argument (the F argument) to
         8837  +** the [sqlite3_deserialize(D,S,P,N,M,F)] interface.
         8838  +**
         8839  +** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization
         8840  +** in the P argument is held in memory obtained from [sqlite3_malloc64()]
         8841  +** and that SQLite should take ownership of this memory and automatically
         8842  +** free it when it has finished using it.  Without this flag, the caller
         8843  +** is resposible for freeing any dynamically allocated memory.
         8844  +**
         8845  +** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
         8846  +** grow the size of the database usign calls to [sqlite3_realloc64()].  This
         8847  +** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used.
         8848  +** Without this flag, the deserialized database cannot increase in size beyond
         8849  +** the number of bytes specified by the M parameter.
         8850  +**
         8851  +** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database
         8852  +** should be treated as read-only.
  8821   8853   */
  8822   8854   #define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */
  8823   8855   #define SQLITE_DESERIALIZE_RESIZEABLE  2 /* Resize using sqlite3_realloc64() */
  8824   8856   #define SQLITE_DESERIALIZE_READONLY    4 /* Database is read-only */
  8825   8857   
  8826   8858   /*
  8827   8859   ** Undo the hack that converts floating point types to integer for

Changes to src/sqliteInt.h.

  4020   4020   u8 sqlite3HexToInt(int h);
  4021   4021   int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
  4022   4022   
  4023   4023   #if defined(SQLITE_NEED_ERR_NAME)
  4024   4024   const char *sqlite3ErrName(int);
  4025   4025   #endif
  4026   4026   
  4027         -#ifdef SQLITE_ENABLE_MEMDB
         4027  +#ifdef SQLITE_ENABLE_DESERIALIZE
  4028   4028   int sqlite3MemdbInit(void);
  4029   4029   #endif
  4030   4030   
  4031   4031   const char *sqlite3ErrStr(int);
  4032   4032   int sqlite3ReadSchema(Parse *pParse);
  4033   4033   CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
  4034   4034   CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);

Changes to src/tclsqlite.c.

  2416   2416   
  2417   2417     /*
  2418   2418     **     $db deserialize ?DATABASE? VALUE
  2419   2419     **
  2420   2420     ** Reopen DATABASE (default "main") using the content in $VALUE
  2421   2421     */
  2422   2422     case DB_DESERIALIZE: {
  2423         -#ifndef SQLITE_ENABLE_MEMDB
         2423  +#ifndef SQLITE_ENABLE_DESERIALIZE
  2424   2424       Tcl_AppendResult(interp, "MEMDB not available in this build",
  2425   2425                        (char*)0);
  2426   2426       rc = TCL_ERROR;
  2427   2427   #else
  2428   2428       const char *zSchema;
  2429   2429       Tcl_Obj *pValue;
  2430   2430       unsigned char *pBA;
................................................................................
  2938   2938   
  2939   2939     /*
  2940   2940     **     $db serialize ?DATABASE?
  2941   2941     **
  2942   2942     ** Return a serialization of a database.  
  2943   2943     */
  2944   2944     case DB_SERIALIZE: {
  2945         -#ifndef SQLITE_ENABLE_MEMDB
         2945  +#ifndef SQLITE_ENABLE_DESERIALIZE
  2946   2946       Tcl_AppendResult(interp, "MEMDB not available in this build",
  2947   2947                        (char*)0);
  2948   2948       rc = TCL_ERROR;
  2949   2949   #else
  2950   2950       const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main";
  2951   2951       sqlite3_int64 sz = 0;
  2952   2952       unsigned char *pData;

Changes to src/test_config.c.

   144    144   
   145    145   #ifdef SQLITE_ENABLE_HIDDEN_COLUMNS
   146    146     Tcl_SetVar2(interp, "sqlite_options", "hiddencolumns", "1", TCL_GLOBAL_ONLY);
   147    147   #else
   148    148     Tcl_SetVar2(interp, "sqlite_options", "hiddencolumns", "0", TCL_GLOBAL_ONLY);
   149    149   #endif
   150    150   
   151         -#ifdef SQLITE_ENABLE_MEMDB
   152         -  Tcl_SetVar2(interp, "sqlite_options", "memdb", "1", TCL_GLOBAL_ONLY);
          151  +#ifdef SQLITE_ENABLE_DESERIALIZE
          152  +  Tcl_SetVar2(interp, "sqlite_options", "deserialize", "1", TCL_GLOBAL_ONLY);
   153    153   #else
   154         -  Tcl_SetVar2(interp, "sqlite_options", "memdb", "0", TCL_GLOBAL_ONLY);
          154  +  Tcl_SetVar2(interp, "sqlite_options", "deserialize", "0", TCL_GLOBAL_ONLY);
   155    155   #endif
   156    156   
   157    157   #ifdef SQLITE_ENABLE_MEMSYS3
   158    158     Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY);
   159    159   #else
   160    160     Tcl_SetVar2(interp, "sqlite_options", "mem3", "0", TCL_GLOBAL_ONLY);
   161    161   #endif

Changes to test/memdb1.test.

    13     13   #
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17     17   set testprefix memdb1
    18     18   do_not_use_codec
    19     19   
    20         -ifcapable !memdb {
           20  +ifcapable !deserialize {
    21     21     finish_test
    22     22     return
    23     23   }
    24     24   
    25     25   # Create a MEMDB and populate it with some dummy data.
    26     26   # Then extract the database into the $::db1 variable.
    27     27   # Verify that the size of $::db1 is the same as the size of