At 18:25 30/08/2009, you wrote:
´¯¯¯
>When we load an extension it invokes  sqlite3_extension_init(). Lets 
>say, in
>addition to creating functions, the loaded extension library also does 
>some
>internal data structure allocations,  initializations etc here.
>
>Now, when the database is closed the loaded extension needs  to do 
>cleanup.
>To do that:
>1. Is it possible to register a callback which is invoked on database 
>close?
>2. or is there a plan to add something like: sqlite3_extension_end() which
>can be used for this?
>3.  and if answer to 2 is yes, how about add an 'unload' command for
>extensions as well so that we can unload extensions when they are no more
>needed?
>
>4. If none of the above functionality exists yet, is there a workaround
>available today to achieve this?
`---

As a sidenote to what Roger just disclosed (umm, what a strange 
"hack"!), it is possible that a more conventional way exist.  From what 
I can tell, it all depends on the environment.  At least there is one 
clean way in the case of a .dll extension under Windows.  It's quite 
possible that a similar way could work for other systems as well.

What is your environment?


In the Windows .dll case, you can have the extension registered in 
several ways:

   1a) your app calls sqlite3_load_extension()
or
   1b) your app issues a "SELECT load_extension('yourext.dll'[, 
'entry_point']);"

and your .dll has code like this:

DLL_EXPORT int sqlite3_extension_init(       // std name of entry point
   sqlite3 *db,
   char **pzErrMsg,
   const sqlite3_api_routines *pApi
){
   SQLITE_EXTENSION_INIT2(pApi)
   // calls to sqlite3_create_function(db, ...)
   // and/or calls to sqlite3_create_collation(db, ...)
   return SQLITE_OK; // or SQLITE_ERROR
}

      The drawback is that the extension is registered for the calling 
connection
      only. Besides what Roger suggested there's no official callback 
for cleanup
      (again on a connection-basis).

   2) your app issues a call to 
sqlite_auto_extension(entry_point).  Then the extension
      will be available for any _new_ DB connection.
      You can invoke sqlite3_reset_auto_extension() to free memory 
allocated to
      manage the extension, but I believe you don't have an official 
hook to clean
      anything else of your own.

   3) your app loads the extension as 1a) or 1b) and your load entry 
point looks like

DLL_EXPORT int sqlite3_extension_init(
   sqlite3 *db,
   char **pzErrMsg,
   const sqlite3_api_routines *pApi
){
   return SQLITE_OK;
}

Yes, it's a noop, BUT wait a minute, your .dll also contains this:

// the DllMain will be called by Windows upon first .dll invokation, 
i.e. when you call the noop function above
// it will be called again when closing the .dll, which gives you the 
opportunity to clean up things

#if ((defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || 
defined(__MINGW32__) || defined(__BORLANDC__)) && (!defined(SQLITE_CORE)))
int __stdcall DllMain(void *hinstDLL, unsigned long fdwReason, void 
*lpReserved)
{
   if (fdwReason == 1) {                // DLL_PROCESS_ATTACH
     //
     // <=== insert here code to set up your own mess
     //
     sqlite3_auto_extension((void*)sqlite3_extension_load);
   } else if (fdwReason == 0) {         // DLL_PROCESS_DETACH
     //
     // <=== insert here code to clean up your own mess
     //
     sqlite3_reset_auto_extension();
   };
   return 1;
}
#endif


// SQLite core will call this on every new DB connection
DLL_EXPORT int sqlite3_extension_load(
   sqlite3 *db,
   char **pzErrMsg,
   const sqlite3_api_routines *pApi
){
   SQLITE_EXTENSION_INIT2(pApi)
   return sqlite3_auto_extension((void*)your_ext_register);
}


DLL_EXPORT int your_ext_register(
   sqlite3 *db,
   char **pzErrMsg,
   const sqlite3_api_routines *pApi
){
   SQLITE_EXTENSION_INIT2(pApi)
   //
   // more mess setup
   //
   // calls to sqlite3_create_function(db, ...)
   // and/or calls to sqlite3_create_collation(db, ...)
   return SQLITE_OK; // or SQLITE_ERROR
}

I hope I didn't make mistakes in the excerpt.  Anyway this gets you two 
birds with one stone.  You can also use this trick if you're using a 
third-party SQLite manager, provided it allows you to load 
extensions.  If you're lucky enough your non-Windows OS will have a 
similar hook which you can use.




_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to