LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/sqlite - ogrsqlitevfs.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 143 91 63.6 %
Date: 2011-12-18 Functions: 25 13 52.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrsqlitevfs.cpp 23346 2011-11-06 15:27:58Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements SQLite VFS
       6                 :  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
       7                 : 
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2011, Even Rouault, <even dot rouault at mines dash paris dot org>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_sqlite.h"
      31                 : 
      32                 : CPL_CVSID("$Id: ogrsqlitevfs.cpp 23346 2011-11-06 15:27:58Z rouault $");
      33                 : 
      34                 : //#define DEBUG_IO 1
      35                 : 
      36                 : #ifdef HAVE_SQLITE_VFS
      37                 : 
      38                 : typedef struct
      39                 : {
      40                 :     const struct sqlite3_io_methods *pMethods;
      41                 :     VSILFILE                        *fp;
      42                 :     int                              bDeleteOnClose;
      43                 :     char                            *pszFilename;
      44                 : } OGRSQLiteFileStruct;
      45                 : 
      46              68 : static int OGRSQLiteIOClose(sqlite3_file* pFile)
      47                 : {
      48              68 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
      49                 : #ifdef DEBUG_IO
      50                 :     CPLDebug("SQLITE", "OGRSQLiteIOClose(%p (%s))", pMyFile->fp, pMyFile->pszFilename);
      51                 : #endif
      52              68 :     VSIFCloseL(pMyFile->fp);
      53              68 :     if (pMyFile->bDeleteOnClose)
      54              23 :         VSIUnlink(pMyFile->pszFilename);
      55              68 :     CPLFree(pMyFile->pszFilename);
      56              68 :     return SQLITE_OK;
      57                 : }
      58                 : 
      59              82 : static int OGRSQLiteIORead(sqlite3_file* pFile, void* pBuffer, int iAmt, sqlite3_int64 iOfst)
      60                 : {
      61              82 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
      62                 : #ifdef DEBUG_IO
      63                 :     CPLDebug("SQLITE", "OGRSQLiteIORead(%p, %d, %d)", pMyFile->fp, iAmt, (int)iOfst);
      64                 : #endif
      65              82 :     VSIFSeekL(pMyFile->fp, (vsi_l_offset) iOfst, SEEK_SET);
      66              82 :     int nRead = (int)VSIFReadL(pBuffer, 1, iAmt, pMyFile->fp);
      67              82 :     if (nRead < iAmt)
      68                 :     {
      69               2 :         memset(((char*)pBuffer) + nRead, 0, iAmt - nRead);
      70               2 :         return SQLITE_IOERR_SHORT_READ;
      71                 :     }
      72              80 :     return SQLITE_OK;
      73                 : }
      74                 : 
      75             508 : static int OGRSQLiteIOWrite(sqlite3_file* pFile, const void* pBuffer, int iAmt, sqlite3_int64 iOfst)
      76                 : {
      77             508 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
      78                 : #ifdef DEBUG_IO
      79                 :     CPLDebug("SQLITE", "OGRSQLiteIOWrite(%p, %d, %d)", pMyFile->fp, iAmt, (int)iOfst);
      80                 : #endif
      81             508 :     VSIFSeekL(pMyFile->fp, (vsi_l_offset) iOfst, SEEK_SET);
      82             508 :     int nWritten = (int)VSIFWriteL(pBuffer, 1, iAmt, pMyFile->fp);
      83             508 :     if (nWritten < iAmt)
      84                 :     {
      85               0 :         return SQLITE_IOERR_WRITE;
      86                 :     }
      87             508 :     return SQLITE_OK;
      88                 : }
      89                 : 
      90              46 : static int OGRSQLiteIOTruncate(sqlite3_file* pFile, sqlite3_int64 size)
      91                 : {
      92              46 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
      93                 : #ifdef DEBUG_IO
      94                 :     CPLDebug("SQLITE", "OGRSQLiteIOTruncate(%p)", pMyFile->fp);
      95                 : #endif
      96              46 :     int nRet = VSIFTruncateL(pMyFile->fp, size);
      97              46 :     return (nRet == 0) ? SQLITE_OK : SQLITE_IOERR_TRUNCATE;
      98                 : }
      99                 : 
     100               0 : static int OGRSQLiteIOSync(sqlite3_file* pFile, int flags)
     101                 : {
     102                 : #ifdef DEBUG_IO
     103                 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
     104                 :     CPLDebug("SQLITE", "OGRSQLiteIOSync(%p, %d)", pMyFile->fp, flags);
     105                 : #endif
     106               0 :     return SQLITE_OK;
     107                 : }
     108                 : 
     109              77 : static int OGRSQLiteIOFileSize(sqlite3_file* pFile, sqlite3_int64 *pSize)
     110                 : {
     111              77 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
     112                 : #ifdef DEBUG_IO
     113                 :     CPLDebug("SQLITE", "OGRSQLiteIOFileSize(%p)", pMyFile->fp);
     114                 : #endif
     115              77 :     vsi_l_offset nCurOffset = VSIFTellL(pMyFile->fp);
     116              77 :     VSIFSeekL(pMyFile->fp, 0, SEEK_END);
     117              77 :     *pSize = VSIFTellL(pMyFile->fp);
     118              77 :     VSIFSeekL(pMyFile->fp, nCurOffset, SEEK_SET);
     119              77 :     return SQLITE_OK;
     120                 : }
     121                 : 
     122             160 : static int OGRSQLiteIOLock(sqlite3_file* pFile, int flags)
     123                 : {
     124                 : #ifdef DEBUG_IO
     125                 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
     126                 :     CPLDebug("SQLITE", "OGRSQLiteIOLock(%p)", pMyFile->fp);
     127                 : #endif
     128             160 :     return SQLITE_OK;
     129                 : }
     130                 : 
     131             122 : static int OGRSQLiteIOUnlock(sqlite3_file* pFile, int flags)
     132                 : {
     133                 : #ifdef DEBUG_IO
     134                 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
     135                 :     CPLDebug("SQLITE", "OGRSQLiteIOUnlock(%p)", pMyFile->fp);
     136                 : #endif
     137             122 :     return SQLITE_OK;
     138                 : }
     139                 : 
     140               0 : static int OGRSQLiteIOCheckReservedLock(sqlite3_file* pFile, int *pResOut)
     141                 : {
     142                 : #ifdef DEBUG_IO
     143                 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
     144                 :     CPLDebug("SQLITE", "OGRSQLiteIOCheckReservedLock(%p)", pMyFile->fp);
     145                 : #endif
     146               0 :     *pResOut = 0;
     147               0 :     return SQLITE_OK;
     148                 : }
     149                 : 
     150               0 : static int OGRSQLiteIOFileControl(sqlite3_file* pFile, int op, void *pArg)
     151                 : {
     152                 : #ifdef DEBUG_IO
     153                 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
     154                 :     CPLDebug("SQLITE", "OGRSQLiteIOFileControl(%p)", pMyFile->fp);
     155                 : #endif
     156               0 :     return SQLITE_OK;
     157                 : }
     158                 : 
     159               5 : static int OGRSQLiteIOSectorSize(sqlite3_file* pFile)
     160                 : {
     161                 : #ifdef DEBUG_IO
     162                 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
     163                 :     CPLDebug("SQLITE", "OGRSQLiteIOSectorSize(%p)", pMyFile->fp);
     164                 : #endif
     165               5 :     return 0;
     166                 : }
     167                 : 
     168               0 : static int OGRSQLiteIODeviceCharacteristics(sqlite3_file* pFile)
     169                 : {
     170                 : #ifdef DEBUG_IO
     171                 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
     172                 :     CPLDebug("SQLITE", "OGRSQLiteIODeviceCharacteristics(%p)", pMyFile->fp);
     173                 : #endif
     174               0 :     return 0;
     175                 : }
     176                 : 
     177                 : static const sqlite3_io_methods OGRSQLiteIOMethods =
     178                 : {
     179                 :     1,
     180                 :     OGRSQLiteIOClose,
     181                 :     OGRSQLiteIORead,
     182                 :     OGRSQLiteIOWrite,
     183                 :     OGRSQLiteIOTruncate,
     184                 :     OGRSQLiteIOSync,
     185                 :     OGRSQLiteIOFileSize,
     186                 :     OGRSQLiteIOLock,
     187                 :     OGRSQLiteIOUnlock,
     188                 :     OGRSQLiteIOCheckReservedLock,
     189                 :     OGRSQLiteIOFileControl,
     190                 :     OGRSQLiteIOSectorSize,
     191                 :     OGRSQLiteIODeviceCharacteristics
     192                 : };
     193                 : 
     194              68 : static int OGRSQLiteVFSOpen(sqlite3_vfs* pVFS,
     195                 :                             const char *zName,
     196                 :                             sqlite3_file* pFile,
     197                 :                             int flags,
     198                 :                             int *pOutFlags)
     199                 : {
     200                 : #ifdef DEBUG_IO
     201                 :     CPLDebug("SQLITE", "OGRSQLiteVFSOpen(%s, %d)", zName ? zName : "(null)", flags);
     202                 : #endif
     203                 : 
     204              68 :     if (zName == NULL)
     205                 :         //return SQLITE_IOERR;
     206              23 :         zName = CPLSPrintf("/vsimem/sqlite/%p", pVFS);
     207                 : 
     208              68 :     OGRSQLiteFileStruct* pMyFile = (OGRSQLiteFileStruct*) pFile;
     209              68 :     pMyFile->pMethods = NULL;
     210              68 :     pMyFile->bDeleteOnClose = FALSE;
     211              68 :     pMyFile->pszFilename = NULL;
     212              68 :     if ( flags & SQLITE_OPEN_READONLY )
     213               1 :         pMyFile->fp = VSIFOpenL(zName, "rb");
     214              67 :     else if ( flags & SQLITE_OPEN_CREATE )
     215              67 :         pMyFile->fp = VSIFOpenL(zName, "wb+");
     216               0 :     else if ( flags & SQLITE_OPEN_READWRITE )
     217               0 :         pMyFile->fp = VSIFOpenL(zName, "rb+");
     218                 :     else
     219               0 :         pMyFile->fp = NULL;
     220                 : 
     221              68 :     if (pMyFile->fp == NULL)
     222               0 :         return SQLITE_CANTOPEN;
     223                 : 
     224                 : #ifdef DEBUG_IO
     225                 :     CPLDebug("SQLITE", "OGRSQLiteVFSOpen() = %p", pMyFile->fp);
     226                 : #endif
     227                 : 
     228              68 :     pMyFile->pMethods = &OGRSQLiteIOMethods;
     229              68 :     pMyFile->bDeleteOnClose = ( flags & SQLITE_OPEN_DELETEONCLOSE );
     230              68 :     pMyFile->pszFilename = CPLStrdup(zName);
     231                 : 
     232              68 :     if (pOutFlags != NULL)
     233               3 :         *pOutFlags = flags;
     234                 : 
     235              68 :     return SQLITE_OK;
     236                 : }
     237                 : 
     238              42 : static int OGRSQLiteVFSDelete(sqlite3_vfs* pVFS, const char *zName, int syncDir)
     239                 : {
     240                 : #ifdef DEBUG_IO
     241                 :     CPLDebug("SQLITE", "OGRSQLiteVFSDelete(%s)", zName);
     242                 : #endif
     243              42 :     VSIUnlink(zName);
     244              42 :     return SQLITE_OK;
     245                 : }
     246                 : 
     247              77 : static int OGRSQLiteVFSAccess (sqlite3_vfs* pVFS, const char *zName, int flags, int *pResOut)
     248                 : {
     249                 : #ifdef DEBUG_IO
     250                 :     CPLDebug("SQLITE", "OGRSQLiteVFSAccess(%s, %d)", zName, flags);
     251                 : #endif
     252                 :     VSIStatBufL sStatBufL;
     253                 :     int nRet;
     254              77 :     if (flags == SQLITE_ACCESS_EXISTS)
     255              77 :         nRet = VSIStatExL(zName, &sStatBufL, VSI_STAT_EXISTS_FLAG);
     256               0 :     else if (flags == SQLITE_ACCESS_READ)
     257                 :     {
     258               0 :         VSILFILE* fp = VSIFOpenL(zName, "rb");
     259               0 :         nRet = fp ? 0 : -1;
     260               0 :         if (fp)
     261               0 :             VSIFCloseL(fp);
     262                 :     }
     263               0 :     else if (flags == SQLITE_ACCESS_READWRITE)
     264                 :     {
     265               0 :         VSILFILE* fp = VSIFOpenL(zName, "rb+");
     266               0 :         nRet = fp ? 0 : -1;
     267               0 :         if (fp)
     268               0 :             VSIFCloseL(fp);
     269                 :     }
     270                 :     else
     271               0 :         nRet = -1;
     272              77 :     *pResOut = (nRet == 0);
     273              77 :     return SQLITE_OK;
     274                 : }
     275                 : 
     276               3 : static int OGRSQLiteVFSFullPathname (sqlite3_vfs* pVFS, const char *zName, int nOut, char *zOut)
     277                 : {
     278               3 :     sqlite3_vfs* pUnderlyingVFS = (sqlite3_vfs* )pVFS->pAppData;
     279                 : #ifdef DEBUG_IO
     280                 :     CPLDebug("SQLITE", "OGRSQLiteVFSFullPathname(%s)", zName);
     281                 : #endif
     282               3 :     if (zName[0] == '/')
     283                 :     {
     284               3 :         strncpy(zOut, zName, nOut);
     285               3 :         zOut[nOut-1] = '\0';
     286               3 :         return SQLITE_OK;
     287                 :     }
     288               0 :     return pUnderlyingVFS->xFullPathname(pUnderlyingVFS, zName, nOut, zOut);
     289                 : }
     290                 : 
     291               0 : static void* OGRSQLiteVFSDlOpen (sqlite3_vfs* pVFS, const char *zFilename)
     292                 : {
     293               0 :     sqlite3_vfs* pUnderlyingVFS = (sqlite3_vfs* )pVFS->pAppData;
     294                 :     //CPLDebug("SQLITE", "OGRSQLiteVFSDlOpen(%s)", zFilename);
     295               0 :     return pUnderlyingVFS->xDlOpen(pUnderlyingVFS, zFilename);
     296                 : }
     297                 : 
     298               0 : static void OGRSQLiteVFSDlError (sqlite3_vfs* pVFS, int nByte, char *zErrMsg)
     299                 : {
     300               0 :     sqlite3_vfs* pUnderlyingVFS = (sqlite3_vfs* )pVFS->pAppData;
     301                 :     //CPLDebug("SQLITE", "OGRSQLiteVFSDlError()");
     302               0 :     pUnderlyingVFS->xDlError(pUnderlyingVFS, nByte, zErrMsg);
     303               0 : }
     304                 : 
     305               0 : static void (*OGRSQLiteVFSDlSym (sqlite3_vfs* pVFS,void* pHandle, const char *zSymbol))(void)
     306                 : {
     307               0 :     sqlite3_vfs* pUnderlyingVFS = (sqlite3_vfs* )pVFS->pAppData;
     308                 :     //CPLDebug("SQLITE", "OGRSQLiteVFSDlSym(%s)", zSymbol);
     309               0 :     return pUnderlyingVFS->xDlSym(pUnderlyingVFS, pHandle, zSymbol);
     310                 : }
     311                 : 
     312               0 : static void OGRSQLiteVFSDlClose (sqlite3_vfs* pVFS, void* pHandle)
     313                 : {
     314               0 :     sqlite3_vfs* pUnderlyingVFS = (sqlite3_vfs* )pVFS->pAppData;
     315                 :     //CPLDebug("SQLITE", "OGRSQLiteVFSDlClose(%p)", pHandle);
     316               0 :     pUnderlyingVFS->xDlClose(pUnderlyingVFS, pHandle);
     317               0 : }
     318                 : 
     319               0 : static int OGRSQLiteVFSRandomness (sqlite3_vfs* pVFS, int nByte, char *zOut)
     320                 : {
     321               0 :     sqlite3_vfs* pUnderlyingVFS = (sqlite3_vfs* )pVFS->pAppData;
     322                 :     //CPLDebug("SQLITE", "OGRSQLiteVFSRandomness()");
     323               0 :     return pUnderlyingVFS->xRandomness(pUnderlyingVFS, nByte, zOut);
     324                 : }
     325                 : 
     326               0 : static int OGRSQLiteVFSSleep (sqlite3_vfs* pVFS, int microseconds)
     327                 : {
     328               0 :     sqlite3_vfs* pUnderlyingVFS = (sqlite3_vfs* )pVFS->pAppData;
     329                 :     //CPLDebug("SQLITE", "OGRSQLiteVFSSleep()");
     330               0 :     return pUnderlyingVFS->xSleep(pUnderlyingVFS, microseconds);
     331                 : }
     332                 : 
     333               0 : static int OGRSQLiteVFSCurrentTime (sqlite3_vfs* pVFS, double* p1)
     334                 : {
     335               0 :     sqlite3_vfs* pUnderlyingVFS = (sqlite3_vfs* )pVFS->pAppData;
     336                 :     //CPLDebug("SQLITE", "OGRSQLiteVFSCurrentTime()");
     337               0 :     return pUnderlyingVFS->xCurrentTime(pUnderlyingVFS, p1);
     338                 : }
     339                 : 
     340               0 : static int OGRSQLiteVFSGetLastError (sqlite3_vfs* pVFS, int p1, char *p2)
     341                 : {
     342               0 :     sqlite3_vfs* pUnderlyingVFS = (sqlite3_vfs* )pVFS->pAppData;
     343                 :     //CPLDebug("SQLITE", "OGRSQLiteVFSGetLastError()");
     344               0 :     return pUnderlyingVFS->xGetLastError(pUnderlyingVFS, p1, p2);
     345                 : }
     346                 : 
     347               3 : sqlite3_vfs* OGRSQLiteCreateVFS()
     348                 : {
     349               3 :     sqlite3_vfs* pDefaultVFS = sqlite3_vfs_find(NULL);
     350               3 :     sqlite3_vfs* pMyVFS = (sqlite3_vfs*) CPLCalloc(1, sizeof(sqlite3_vfs));
     351               3 :     pMyVFS->iVersion = 1;
     352               3 :     pMyVFS->szOsFile = sizeof(OGRSQLiteFileStruct);
     353               3 :     pMyVFS->mxPathname = pDefaultVFS->mxPathname;
     354               3 :     pMyVFS->zName = "myvfs";
     355               3 :     pMyVFS->pAppData = pDefaultVFS;
     356               3 :     pMyVFS->xOpen = OGRSQLiteVFSOpen;
     357               3 :     pMyVFS->xDelete = OGRSQLiteVFSDelete;
     358               3 :     pMyVFS->xAccess = OGRSQLiteVFSAccess;
     359               3 :     pMyVFS->xFullPathname = OGRSQLiteVFSFullPathname;
     360               3 :     pMyVFS->xDlOpen = OGRSQLiteVFSDlOpen;
     361               3 :     pMyVFS->xDlError = OGRSQLiteVFSDlError;
     362               3 :     pMyVFS->xDlSym = OGRSQLiteVFSDlSym;
     363               3 :     pMyVFS->xDlClose = OGRSQLiteVFSDlClose;
     364               3 :     pMyVFS->xRandomness = OGRSQLiteVFSRandomness;
     365               3 :     pMyVFS->xSleep = OGRSQLiteVFSSleep;
     366               3 :     pMyVFS->xCurrentTime = OGRSQLiteVFSCurrentTime;
     367               3 :     pMyVFS->xGetLastError = OGRSQLiteVFSGetLastError;
     368               3 :     return pMyVFS;
     369                 : }
     370                 : 
     371                 : #endif // HAVE_SQLITE_VFS

Generated by: LCOV version 1.7