Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#6150 closed enhancement (fixed)

support named memory databases in sqlite driver

Reported by: joker99 Owned by: warmerdam
Priority: normal Milestone: 2.1.0
Component: OGR_SF Version: unspecified
Severity: normal Keywords: sqlite
Cc:

Description

SQLite supports memory databases that can be shared in the same process using file:somename?mode=memory&cache=chared naming convention.

To support it, you need to change only two files: Allow opening of "file:" pathes in ogr\ogrsf_frmts\sqlite\ogrsqlitedriver.cpp Pass SQLITE_OPEN_URI flag to sqlite3_open_v2 in ogr\ogrsf_frmts\sqlite\ogrsqlitedatasource.cpp

Something like this:

ogrsqlitedriver.cpp, OGRSQLiteDriverIdentify function, add the following code before checking for magic string in file header (at line 74)

	// this code enables support for named mememory databases in sqlite. 
	// Named memory databses use file name format file:name?mode=memory&cache=shared
	// SQLITE_USE_URI is checked only to enable backward compatibility, in case we accidently hijacked some other format
	int bUseURI = CSLTestBoolean(CPLGetConfigOption("SQLITE_USE_URI", "YES"));
    if (bUseURI && EQUALN(poOpenInfo->pszFilename, "file:", strlen("file:")))
    {
        char * queryparams = strchr(poOpenInfo->pszFilename, '?');
        if (queryparams)
        {
            if (strstr(queryparams, "mode=memory") != NULL)
                return TRUE;
        }
    }

ogrsqlitedatasource.cpp, OpenOrCreateDB function, replace lines 565-580 with the following code (basically check for config option and if set, pass SQLITE_OPEN_URI flag)

	// this code enables support for named mememory databases in sqlite. 
	// SQLITE_USE_URI is checked only to enable backward compatibility, in case we accidently hijacked some other format
	int bUseURI = CSLTestBoolean(CPLGetConfigOption("SQLITE_USE_URI", "YES"));
	int additionalFlags = bUseURI ? SQLITE_OPEN_URI : 0;
	
#ifdef HAVE_SQLITE_VFS
    if( bRegisterOGR2SQLiteExtensions )
        OGR2SQLITE_Register();

    int bUseOGRVFS = CSLTestBoolean(CPLGetConfigOption("SQLITE_USE_OGR_VFS", "NO"));
    if (bUseOGRVFS || strncmp(m_pszFilename, "/vsi", 4) == 0)
    {
        pMyVFS = OGRSQLiteCreateVFS(OGRSQLiteBaseDataSourceNotifyFileOpened, this);
        sqlite3_vfs_register(pMyVFS, 0);
        rc = sqlite3_open_v2( m_pszFilename, &hDB, flags | additionalFlags, pMyVFS->zName );
    }
    else
        rc = sqlite3_open_v2( m_pszFilename, &hDB, flags | additionalFlags, NULL );
#else
    //rc = sqlite3_open( m_pszFilename, &hDB );
    rc = sqlite3_open_v2( m_pszFilename, &hDB, flags | additionalFlags, NULL );
#endif

Change History (6)

comment:1 by Even Rouault, 8 years ago

A properly formatted patch would be simpler to review and apply. I'd note you can also use the /vsimem/some_file.db mechanism.

comment:2 by joker99, 8 years ago

How do I create a properly formatted patch?

comment:3 by joker99, 8 years ago

Also, /vsimem is not good enough, since I want an interopabilty between .Net code writing to sqlite database and some third party component reading it using GDAL.

So using SQLite build-in support for named memory db looks like the best fit.

comment:4 by joker99, 8 years ago

By properly formatted patch, did you mean something like this?

--- //alon2/c$/engine/gdal-2.0.0rc1/ogr/ogrsf_frmts/sqlite/ogrsqlitedatasource.orig.cpp	Fri Jun 05 15:17:49 2015
+++ //alon2/c$/engine/gdal-2.0.0rc1/ogr/ogrsf_frmts/sqlite/ogrsqlitedatasource.cpp	Thu Oct 15 09:35:16 2015
@@ -562,6 +562,11 @@
         sqlite3_config(SQLITE_CONFIG_MALLOC, &sDebugMemAlloc);
 #endif
 
+	// this code enables support for named mememory databases in sqlite. 
+	// SQLITE_USE_URI is checked only to enable backward compatibility, in case we accidently hijacked some other format
+	int bUseURI = CSLTestBoolean(CPLGetConfigOption("SQLITE_USE_URI", "YES"));
+	int additionalFlags = bUseURI ? SQLITE_OPEN_URI : 0;
+	
 #ifdef HAVE_SQLITE_VFS
     if( bRegisterOGR2SQLiteExtensions )
         OGR2SQLITE_Register();
@@ -571,12 +576,12 @@
     {
         pMyVFS = OGRSQLiteCreateVFS(OGRSQLiteBaseDataSourceNotifyFileOpened, this);
         sqlite3_vfs_register(pMyVFS, 0);
-        rc = sqlite3_open_v2( m_pszFilename, &hDB, flags, pMyVFS->zName );
+        rc = sqlite3_open_v2( m_pszFilename, &hDB, flags | additionalFlags, pMyVFS->zName );
     }
     else
-        rc = sqlite3_open_v2( m_pszFilename, &hDB, flags, NULL );
+        rc = sqlite3_open_v2( m_pszFilename, &hDB, flags | additionalFlags, NULL );
 #else
-    rc = sqlite3_open( m_pszFilename, &hDB );
+    rc = sqlite3_open_v2( m_pszFilename, &hDB, flags | additionalFlags, NULL );
 #endif
     if( rc != SQLITE_OK )
     {	 
--- //alon2/c$/engine/gdal-2.0.0rc1/ogr/ogrsf_frmts/sqlite/ogrsqlitedriver.orig.cpp	Fri Jun 05 15:17:49 2015
+++ //alon2/c$/engine/gdal-2.0.0rc1/ogr/ogrsf_frmts/sqlite/ogrsqlitedriver.cpp	Thu Oct 15 09:37:33 2015
@@ -71,6 +71,23 @@
 
     if( EQUAL(poOpenInfo->pszFilename, ":memory:") )
         return TRUE;
+		
+	// this code enables support for named mememory databases in sqlite. 
+	// Named memory databses use file name format file:name?mode=memory&cache=shared
+	// SQLITE_USE_URI is checked only to enable backward compatibility, in case we accidently hijacked some other format
+	int bUseURI = CSLTestBoolean(CPLGetConfigOption("SQLITE_USE_URI", "YES"));
+    if (bUseURI && EQUALN(poOpenInfo->pszFilename, "file:", strlen("file:")))
+    {
+        char * queryparams = strchr(poOpenInfo->pszFilename, '?');
+        if (queryparams)
+        {
+            if (strstr(queryparams, "mode=memory") != NULL)
+                return TRUE;
+        }
+    }
+    
+
+
 /* -------------------------------------------------------------------- */
 /*      Verify that the target is a real file, and has an               */
 /*      appropriate magic string at the beginning.                      */

comment:5 by Even Rouault, 8 years ago

Milestone: 2.1.0
Resolution: fixed
Status: newclosed

trunk r31009 "SQLite: support file:xxx URI syntax (derived from patch by joker99, #6150)"

comment:6 by Even Rouault, 8 years ago

trunk r31011 "ogr_sqlite.py: test URI only with SQLite >= 3.8.0 (#6150)"

Note: See TracTickets for help on using tickets.