/ Check-in [3a461043]
Login

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

Overview
Comment:Enhance the sqlite3_load_extension() API so that the first parameter (the "db" parameter) can be NULL. An extension that is not associated with any database connection remains loaded for the life of the process.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | persistent-extensions
Files: files | file ages | folders
SHA1: 3a461043898a77b14ffc12b5e332b3d65a8dca1d
User & Date: drh 2016-05-28 15:03:06
Context
2016-05-28
15:03
Enhance the sqlite3_load_extension() API so that the first parameter (the "db" parameter) can be NULL. An extension that is not associated with any database connection remains loaded for the life of the process. Closed-Leaf check-in: 3a461043 user: drh tags: persistent-extensions
14:53
Add the vfsstat.c loadable extension - a VFS shim that measures the amount of I/O, and an eponymous virtual table that is used to extract and view the measurements. check-in: 0987487d user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/loadext.c.

   433    433   */
   434    434   static int sqlite3LoadExtension(
   435    435     sqlite3 *db,          /* Load the extension into this database connection */
   436    436     const char *zFile,    /* Name of the shared library containing extension */
   437    437     const char *zProc,    /* Entry point.  Use "sqlite3_extension_init" if 0 */
   438    438     char **pzErrMsg       /* Put error message here if not 0 */
   439    439   ){
   440         -  sqlite3_vfs *pVfs = db->pVfs;
          440  +  sqlite3_vfs *pVfs = db ? db->pVfs : sqlite3_vfs_find(0);
   441    441     void *handle;
   442    442     int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
   443    443     char *zErrmsg = 0;
   444    444     const char *zEntry;
   445    445     char *zAltEntry = 0;
   446    446     void **aHandle;
   447    447     u64 nMsg = 300 + sqlite3Strlen30(zFile);
................................................................................
   464    464     /* Ticket #1863.  To avoid a creating security problems for older
   465    465     ** applications that relink against newer versions of SQLite, the
   466    466     ** ability to run load_extension is turned off by default.  One
   467    467     ** must call either sqlite3_enable_load_extension(db) or
   468    468     ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0)
   469    469     ** to turn on extension loading.
   470    470     */
   471         -  if( (db->flags & SQLITE_LoadExtension)==0 ){
          471  +  if( db && (db->flags & SQLITE_LoadExtension)==0 ){
   472    472       if( pzErrMsg ){
   473    473         *pzErrMsg = sqlite3_mprintf("not authorized");
   474    474       }
   475    475       return SQLITE_ERROR;
   476    476     }
   477    477   
   478    478     zEntry = zProc ? zProc : "sqlite3_extension_init";
................................................................................
   554    554       }
   555    555       sqlite3_free(zErrmsg);
   556    556       sqlite3OsDlClose(pVfs, handle);
   557    557       return SQLITE_ERROR;
   558    558     }
   559    559   
   560    560     /* Append the new shared library handle to the db->aExtension array. */
   561         -  aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1));
   562         -  if( aHandle==0 ){
   563         -    return SQLITE_NOMEM_BKPT;
          561  +  if( db ){
          562  +    aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1));
          563  +    if( aHandle==0 ){
          564  +      return SQLITE_NOMEM_BKPT;
          565  +    }
          566  +    if( db->nExtension>0 ){
          567  +      memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
          568  +    }
          569  +    sqlite3DbFree(db, db->aExtension);
          570  +    db->aExtension = aHandle;
          571  +    db->aExtension[db->nExtension++] = handle;
   564    572     }
   565         -  if( db->nExtension>0 ){
   566         -    memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
   567         -  }
   568         -  sqlite3DbFree(db, db->aExtension);
   569         -  db->aExtension = aHandle;
   570         -
   571         -  db->aExtension[db->nExtension++] = handle;
   572    573     return SQLITE_OK;
   573    574   }
   574    575   int sqlite3_load_extension(
   575    576     sqlite3 *db,          /* Load the extension into this database connection */
   576    577     const char *zFile,    /* Name of the shared library containing extension */
   577    578     const char *zProc,    /* Entry point.  Use "sqlite3_extension_init" if 0 */
   578    579     char **pzErrMsg       /* Put error message here if not 0 */
   579    580   ){
   580    581     int rc;
          582  +  if( db==0 ) return sqlite3LoadExtension(0, zFile, zProc, pzErrMsg);
   581    583     sqlite3_mutex_enter(db->mutex);
   582    584     rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg);
   583    585     rc = sqlite3ApiExit(db, rc);
   584    586     sqlite3_mutex_leave(db->mutex);
   585    587     return rc;
   586    588   }
   587    589   

Changes to src/shell.c.

  3751   3751       if( nArg<2 ){
  3752   3752         raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
  3753   3753         rc = 1;
  3754   3754         goto meta_command_exit;
  3755   3755       }
  3756   3756       zFile = azArg[1];
  3757   3757       zProc = nArg>=3 ? azArg[2] : 0;
  3758         -    open_db(p, 0);
         3758  +    /*    open_db(p, 0); */
  3759   3759       rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
  3760   3760       if( rc!=SQLITE_OK ){
  3761   3761         utf8_printf(stderr, "Error: %s\n", zErrMsg);
  3762   3762         sqlite3_free(zErrMsg);
  3763   3763         rc = 1;
  3764   3764       }
  3765   3765     }else