Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Unload shared libraries when a database connection closes. (CVS 3208) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
327e6909c9d35b651ab6f3a1a270022b |
User & Date: | drh 2006-06-08 15:48:01 |
Context
2006-06-08
| ||
16:10 | In the shell, make sure the database is opened before trying to do an ".import". Bug reported on the mailing list. (CVS 3209) check-in: 39e34278 user: drh tags: trunk | |
15:48 | Unload shared libraries when a database connection closes. (CVS 3208) check-in: 327e6909 user: drh tags: trunk | |
15:28 | New shell command ".load" and the sqlite3_load_extension() API allow new SQL functions and collating sequences to be loaded at run-time from a DLL or shared library. (CVS 3207) check-in: 4ca932d3 user: drh tags: trunk | |
Changes
Changes to src/loadext.c.
12 12 ** This file contains code used to dynamically load extensions into 13 13 ** the SQLite library. 14 14 */ 15 15 #ifndef SQLITE_OMIT_LOAD_EXTENSION 16 16 17 17 #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ 18 18 #include "sqlite3ext.h" 19 +#include "sqliteInt.h" 19 20 #include <string.h> 20 21 #include <ctype.h> 21 22 22 23 #ifndef SQLITE_ENABLE_COLUMN_METADATA 23 24 # define sqlite3_column_database_name 0 24 25 # define sqlite3_column_database_name16 0 25 26 # define sqlite3_column_table_name 0 ................................................................................ 143 144 144 145 145 146 #if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__) 146 147 # include <windows.h> 147 148 # define SQLITE_LIBRARY_TYPE HANDLE 148 149 # define SQLITE_OPEN_LIBRARY(A) LoadLibrary(A) 149 150 # define SQLITE_FIND_SYMBOL(A,B) GetProcAddress(A,B) 150 -# define SQLITE_LIBRARY_ERROR(A) FreeLibrary(A) 151 -# define SQLITE_CLOSE_LIBRARY(A) 151 +# define SQLITE_CLOSE_LIBRARY(A) FreeLibrary(A) 152 152 #endif /* windows */ 153 153 154 154 /* 155 155 ** Non-windows implementation of shared-library loaders 156 156 */ 157 157 #if defined(HAVE_DLOPEN) && !defined(SQLITE_LIBRARY_TYPE) 158 158 # include <dlfcn.h> 159 159 # define SQLITE_LIBRARY_TYPE void* 160 160 # define SQLITE_OPEN_LIBRARY(A) dlopen(A, RTLD_NOW | RTLD_GLOBAL) 161 161 # define SQLITE_FIND_SYMBOL(A,B) dlsym(A,B) 162 -# define SQLITE_LIBRARY_ERROR(A) dlclose(A) 163 -# define SQLITE_CLOSE_LIBRARY(A) 162 +# define SQLITE_CLOSE_LIBRARY(A) dlclose(A) 164 163 #endif 165 164 166 165 /* 167 166 ** Attempt to load an SQLite extension library contained in the file 168 167 ** zFile. The entry point is zProc. zProc may be 0 in which case the 169 168 ** name of the entry point is derived from the filename. 170 169 ** ................................................................................ 198 197 const char *zProc, /* Entry point. Derived from zFile if 0 */ 199 198 char **pzErrMsg /* Put error message here if not 0 */ 200 199 ){ 201 200 #ifdef SQLITE_LIBRARY_TYPE 202 201 SQLITE_LIBRARY_TYPE handle; 203 202 int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); 204 203 char *zErrmsg = 0; 204 + SQLITE_LIBRARY_TYPE *aHandle; 205 205 206 + db->nExtension++; 207 + aHandle = sqliteMalloc(sizeof(handle)*db->nExtension); 208 + if( aHandle==0 ){ 209 + return SQLITE_NOMEM; 210 + } 211 + if( db->nExtension>0 ){ 212 + memcpy(aHandle, db->aExtension, sizeof(handle)*(db->nExtension-1)); 213 + } 214 + sqliteFree(db->aExtension); 215 + db->aExtension = aHandle; 206 216 if( zProc==0 ){ 207 217 int i, j, n; 208 218 char *z; 209 219 char zBuf[200]; 210 220 n = strlen(zFile); 211 221 for(i=n-1; i>0 && zFile[i-1]!='/'; i--){} 212 222 for(j=i; zFile[j] && zFile[j]!='.'; j++){} ................................................................................ 240 250 xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) 241 251 SQLITE_FIND_SYMBOL(handle, zProc); 242 252 if( xInit==0 ){ 243 253 if( pzErrMsg ){ 244 254 *pzErrMsg = sqlite3_mprintf("no entry point [%s] in shared library [%s]", 245 255 zProc, zFile); 246 256 } 247 - SQLITE_LIBRARY_ERROR(handle); 257 + SQLITE_CLOSE_LIBRARY(handle); 248 258 return SQLITE_ERROR; 249 259 }else if( xInit(db, &zErrmsg, &sqlite3_api) ){ 250 260 if( pzErrMsg ){ 251 261 *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); 252 262 } 253 263 sqlite3_free(zErrmsg); 254 - SQLITE_LIBRARY_ERROR(handle); 264 + SQLITE_CLOSE_LIBRARY(handle); 255 265 return SQLITE_ERROR; 256 266 } 257 - SQLITE_CLOSE_LIBRARY(handle); 267 + ((SQLITE_LIBRARY_TYPE*)db->aExtension)[db->nExtension-1] = handle; 258 268 return SQLITE_OK; 259 269 #else 260 270 if( pzErrMsg ){ 261 271 *pzErrMsg = sqlite3_mprintf( 262 272 "shared library loading not enabled for this build"); 263 273 } 264 274 return SQLITE_ERROR; 265 275 #endif 266 276 } 277 + 278 +/* 279 +** Call this routine when the database connection is closing in order 280 +** to clean up loaded extensions 281 +*/ 282 +void sqlite3CloseExtensions(sqlite3 *db){ 283 + int i; 284 + for(i=0; i<db->nExtension; i++){ 285 + SQLITE_CLOSE_LIBRARY(((SQLITE_LIBRARY_TYPE*)db->aExtension)[i]); 286 + } 287 + sqliteFree(db->aExtension); 288 +} 289 + 267 290 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
Changes to src/main.c.
10 10 ** 11 11 ************************************************************************* 12 12 ** Main file for the SQLite library. The routines in this file 13 13 ** implement the programmer interface to the library. Routines in 14 14 ** other files are for internal use by SQLite and should not be 15 15 ** accessed by users of the library. 16 16 ** 17 -** $Id: main.c,v 1.340 2006/05/24 12:43:27 drh Exp $ 17 +** $Id: main.c,v 1.341 2006/06/08 15:48:01 drh Exp $ 18 18 */ 19 19 #include "sqliteInt.h" 20 20 #include "os.h" 21 21 #include <ctype.h> 22 22 23 23 /* 24 24 ** The following constant value is used by the SQLITE_BIGENDIAN and ................................................................................ 161 161 sqlite3HashClear(&db->aCollSeq); 162 162 163 163 sqlite3HashClear(&db->aFunc); 164 164 sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */ 165 165 if( db->pErr ){ 166 166 sqlite3ValueFree(db->pErr); 167 167 } 168 + sqlite3CloseExtensions(db); 168 169 169 170 db->magic = SQLITE_MAGIC_ERROR; 170 171 171 172 /* The temp-database schema is allocated differently from the other schema 172 173 ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). 173 174 ** So it needs to be freed here. Todo: Why not roll the temp schema into 174 175 ** the same sqliteMalloc() as the one that allocates the database
Changes to src/sqliteInt.h.
7 7 ** May you do good and not evil. 8 8 ** May you find forgiveness for yourself and forgive others. 9 9 ** May you share freely, never taking more than you give. 10 10 ** 11 11 ************************************************************************* 12 12 ** Internal interface definitions for SQLite. 13 13 ** 14 -** @(#) $Id: sqliteInt.h,v 1.494 2006/05/25 12:17:31 drh Exp $ 14 +** @(#) $Id: sqliteInt.h,v 1.495 2006/06/08 15:48:01 drh Exp $ 15 15 */ 16 16 #ifndef _SQLITEINT_H_ 17 17 #define _SQLITEINT_H_ 18 18 19 19 /* 20 20 ** Extra interface definitions for those who need them 21 21 */ ................................................................................ 456 456 int nChange; /* Value returned by sqlite3_changes() */ 457 457 int nTotalChange; /* Value returned by sqlite3_total_changes() */ 458 458 struct sqlite3InitInfo { /* Information used during initialization */ 459 459 int iDb; /* When back is being initialized */ 460 460 int newTnum; /* Rootpage of table being initialized */ 461 461 u8 busy; /* TRUE if currently initializing */ 462 462 } init; 463 + int nExtension; /* Number of loaded extensions */ 464 + void *aExtension; /* Array of shared libraray handles */ 463 465 struct Vdbe *pVdbe; /* List of active virtual machines */ 464 466 int activeVdbeCnt; /* Number of vdbes currently executing */ 465 467 void (*xTrace)(void*,const char*); /* Trace function */ 466 468 void *pTraceArg; /* Argument to the trace function */ 467 469 void (*xProfile)(void*,const char*,u64); /* Profiling function */ 468 470 void *pProfileArg; /* Argument to profile function */ 469 471 void *pCommitArg; /* Argument to xCommitCallback() */ ................................................................................ 1736 1738 void (*)(sqlite3_context*,int,sqlite3_value **), 1737 1739 void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*)); 1738 1740 int sqlite3ApiExit(sqlite3 *db, int); 1739 1741 int sqlite3MallocFailed(void); 1740 1742 void sqlite3FailedMalloc(void); 1741 1743 void sqlite3AbortOtherActiveVdbes(sqlite3 *, Vdbe *); 1742 1744 int sqlite3OpenTempDatabase(Parse *); 1745 +void sqlite3CloseExtensions(sqlite3*); 1743 1746 1744 1747 #ifndef SQLITE_OMIT_SHARED_CACHE 1745 1748 void sqlite3TableLock(Parse *, int, int, u8, const char *); 1746 1749 #else 1747 1750 #define sqlite3TableLock(v,w,x,y,z) 1748 1751 #endif 1749 1752