LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/sqlite - ogrsqlitevfs.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 136 177 76.8 %
Date: 2024-11-25 13:07:18 Functions: 19 26 73.1 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements SQLite VFS
       5             :  * Author:   Even Rouault, <even dot rouault at spatialys.com>
       6             : 
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2011-2012, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "cpl_port.h"
      14             : #include "ogr_sqlite.h"
      15             : 
      16             : #include <cstdio>
      17             : #include <cstdlib>
      18             : #include <cstring>
      19             : 
      20             : #include "cpl_conv.h"
      21             : #include "cpl_error.h"
      22             : #include "cpl_string.h"
      23             : #include "cpl_vsi.h"
      24             : #include "ogrsqlitevfs.h"
      25             : 
      26             : #ifdef DEBUG_IO
      27             : #define DEBUG_ONLY
      28             : #else
      29             : #define DEBUG_ONLY CPL_UNUSED
      30             : #endif
      31             : 
      32             : // #define DEBUG_IO 1
      33             : 
      34             : typedef struct
      35             : {
      36             :     char szVFSName[64];
      37             :     sqlite3_vfs *pDefaultVFS;
      38             :     pfnNotifyFileOpenedType pfn;
      39             :     void *pfnUserData;
      40             : } OGRSQLiteVFSAppDataStruct;
      41             : 
      42             : #define GET_UNDERLYING_VFS(pVFS)                                               \
      43             :     static_cast<OGRSQLiteVFSAppDataStruct *>(pVFS->pAppData)->pDefaultVFS
      44             : 
      45             : typedef struct
      46             : {
      47             :     const struct sqlite3_io_methods *pMethods;
      48             :     VSILFILE *fp;
      49             :     int bDeleteOnClose;
      50             :     char *pszFilename;
      51             : } OGRSQLiteFileStruct;
      52             : 
      53       20621 : static int OGRSQLiteIOClose(sqlite3_file *pFile)
      54             : {
      55       20621 :     OGRSQLiteFileStruct *pMyFile =
      56             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
      57             : #ifdef DEBUG_IO
      58             :     CPLDebug("SQLITE", "OGRSQLiteIOClose(%p (%s))", pMyFile->fp,
      59             :              pMyFile->pszFilename);
      60             : #endif
      61       20621 :     VSIFCloseL(pMyFile->fp);
      62       20621 :     if (pMyFile->bDeleteOnClose)
      63           0 :         VSIUnlink(pMyFile->pszFilename);
      64       20621 :     CPLFree(pMyFile->pszFilename);
      65       20621 :     return SQLITE_OK;
      66             : }
      67             : 
      68      229062 : static int OGRSQLiteIORead(sqlite3_file *pFile, void *pBuffer, int iAmt,
      69             :                            sqlite3_int64 iOfst)
      70             : {
      71      229062 :     OGRSQLiteFileStruct *pMyFile =
      72             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
      73      229062 :     VSIFSeekL(pMyFile->fp, static_cast<vsi_l_offset>(iOfst), SEEK_SET);
      74      229062 :     int nRead = static_cast<int>(VSIFReadL(pBuffer, 1, iAmt, pMyFile->fp));
      75             : #ifdef DEBUG_IO
      76             :     CPLDebug("SQLITE", "OGRSQLiteIORead(%p, %d, %d) = %d", pMyFile->fp, iAmt,
      77             :              static_cast<int>(iOfst), nRead);
      78             : #endif
      79      229062 :     if (nRead < iAmt)
      80             :     {
      81        4513 :         memset(static_cast<char *>(pBuffer) + nRead, 0, iAmt - nRead);
      82        4513 :         return SQLITE_IOERR_SHORT_READ;
      83             :     }
      84      224549 :     return SQLITE_OK;
      85             : }
      86             : 
      87      412896 : static int OGRSQLiteIOWrite(sqlite3_file *pFile, const void *pBuffer, int iAmt,
      88             :                             sqlite3_int64 iOfst)
      89             : {
      90      412896 :     OGRSQLiteFileStruct *pMyFile =
      91             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
      92      412896 :     VSIFSeekL(pMyFile->fp, static_cast<vsi_l_offset>(iOfst), SEEK_SET);
      93      412896 :     int nWritten = static_cast<int>(VSIFWriteL(pBuffer, 1, iAmt, pMyFile->fp));
      94             : #ifdef DEBUG_IO
      95             :     CPLDebug("SQLITE", "OGRSQLiteIOWrite(%p, %d, %d) = %d", pMyFile->fp, iAmt,
      96             :              static_cast<int>(iOfst), nWritten);
      97             : #endif
      98      412896 :     if (nWritten < iAmt)
      99             :     {
     100          24 :         return SQLITE_IOERR_WRITE;
     101             :     }
     102      412872 :     return SQLITE_OK;
     103             : }
     104             : 
     105          23 : static int OGRSQLiteIOTruncate(sqlite3_file *pFile, sqlite3_int64 size)
     106             : {
     107          23 :     OGRSQLiteFileStruct *pMyFile =
     108             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
     109             : #ifdef DEBUG_IO
     110             :     CPLDebug("SQLITE", "OGRSQLiteIOTruncate(%p, " CPL_FRMT_GIB ")", pMyFile->fp,
     111             :              size);
     112             : #endif
     113          23 :     int nRet = VSIFTruncateL(pMyFile->fp, size);
     114          23 :     return (nRet == 0) ? SQLITE_OK : SQLITE_IOERR_TRUNCATE;
     115             : }
     116             : 
     117        6435 : static int OGRSQLiteIOSync(DEBUG_ONLY sqlite3_file *pFile, DEBUG_ONLY int flags)
     118             : {
     119             : #ifdef DEBUG_IO
     120             :     OGRSQLiteFileStruct *pMyFile =
     121             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
     122             :     CPLDebug("SQLITE", "OGRSQLiteIOSync(%p, %d)", pMyFile->fp, flags);
     123             : #endif
     124        6435 :     return SQLITE_OK;
     125             : }
     126             : 
     127       91303 : static int OGRSQLiteIOFileSize(sqlite3_file *pFile, sqlite3_int64 *pSize)
     128             : {
     129       91303 :     OGRSQLiteFileStruct *pMyFile =
     130             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
     131       91303 :     vsi_l_offset nCurOffset = VSIFTellL(pMyFile->fp);
     132       91303 :     VSIFSeekL(pMyFile->fp, 0, SEEK_END);
     133       91303 :     *pSize = VSIFTellL(pMyFile->fp);
     134       91303 :     VSIFSeekL(pMyFile->fp, nCurOffset, SEEK_SET);
     135             : #ifdef DEBUG_IO
     136             :     CPLDebug("SQLITE", "OGRSQLiteIOFileSize(%p) = " CPL_FRMT_GIB, pMyFile->fp,
     137             :              *pSize);
     138             : #endif
     139       91303 :     return SQLITE_OK;
     140             : }
     141             : 
     142      147409 : static int OGRSQLiteIOLock(DEBUG_ONLY sqlite3_file *pFile, DEBUG_ONLY int flags)
     143             : {
     144             : #ifdef DEBUG_IO
     145             :     OGRSQLiteFileStruct *pMyFile =
     146             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
     147             :     CPLDebug("SQLITE", "OGRSQLiteIOLock(%p)", pMyFile->fp);
     148             : #endif
     149      147409 :     return SQLITE_OK;
     150             : }
     151             : 
     152      122015 : static int OGRSQLiteIOUnlock(DEBUG_ONLY sqlite3_file *pFile,
     153             :                              DEBUG_ONLY int flags)
     154             : {
     155             : #ifdef DEBUG_IO
     156             :     OGRSQLiteFileStruct *pMyFile =
     157             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
     158             :     CPLDebug("SQLITE", "OGRSQLiteIOUnlock(%p)", pMyFile->fp);
     159             : #endif
     160      122015 :     return SQLITE_OK;
     161             : }
     162             : 
     163           6 : static int OGRSQLiteIOCheckReservedLock(DEBUG_ONLY sqlite3_file *pFile,
     164             :                                         DEBUG_ONLY int *pResOut)
     165             : {
     166             : #ifdef DEBUG_IO
     167             :     OGRSQLiteFileStruct *pMyFile =
     168             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
     169             :     CPLDebug("SQLITE", "OGRSQLiteIOCheckReservedLock(%p)", pMyFile->fp);
     170             : #endif
     171           6 :     *pResOut = 0;
     172           6 :     return SQLITE_OK;
     173             : }
     174             : 
     175      103548 : static int OGRSQLiteIOFileControl(DEBUG_ONLY sqlite3_file *pFile,
     176             :                                   DEBUG_ONLY int op, DEBUG_ONLY void *pArg)
     177             : {
     178             : #ifdef DEBUG_IO
     179             :     OGRSQLiteFileStruct *pMyFile =
     180             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
     181             :     CPLDebug("SQLITE", "OGRSQLiteIOFileControl(%p, %d)", pMyFile->fp, op);
     182             : #endif
     183      103548 :     return SQLITE_NOTFOUND;
     184             : }
     185             : 
     186        4708 : static int OGRSQLiteIOSectorSize(DEBUG_ONLY sqlite3_file *pFile)
     187             : {
     188             : #ifdef DEBUG_IO
     189             :     OGRSQLiteFileStruct *pMyFile =
     190             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
     191             :     CPLDebug("SQLITE", "OGRSQLiteIOSectorSize(%p)", pMyFile->fp);
     192             : #endif
     193        4708 :     return 0;
     194             : }
     195             : 
     196      105644 : static int OGRSQLiteIODeviceCharacteristics(DEBUG_ONLY sqlite3_file *pFile)
     197             : {
     198             : #ifdef DEBUG_IO
     199             :     OGRSQLiteFileStruct *pMyFile =
     200             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
     201             :     CPLDebug("SQLITE", "OGRSQLiteIODeviceCharacteristics(%p)", pMyFile->fp);
     202             : #endif
     203      105644 :     return 0;
     204             : }
     205             : 
     206             : static const sqlite3_io_methods OGRSQLiteIOMethods = {
     207             :     1,
     208             :     OGRSQLiteIOClose,
     209             :     OGRSQLiteIORead,
     210             :     OGRSQLiteIOWrite,
     211             :     OGRSQLiteIOTruncate,
     212             :     OGRSQLiteIOSync,
     213             :     OGRSQLiteIOFileSize,
     214             :     OGRSQLiteIOLock,
     215             :     OGRSQLiteIOUnlock,
     216             :     OGRSQLiteIOCheckReservedLock,
     217             :     OGRSQLiteIOFileControl,
     218             :     OGRSQLiteIOSectorSize,
     219             :     OGRSQLiteIODeviceCharacteristics,
     220             :     nullptr,  // xShmMap
     221             :     nullptr,  // xShmLock
     222             :     nullptr,  // xShmBarrier
     223             :     nullptr,  // xShmUnmap
     224             :     nullptr,  // xFetch
     225             :     nullptr,  // xUnfetch
     226             : };
     227             : 
     228       20626 : static int OGRSQLiteVFSOpen(sqlite3_vfs *pVFS, const char *zNameIn,
     229             :                             sqlite3_file *pFile, int flags, int *pOutFlags)
     230             : {
     231             : #ifdef DEBUG_IO
     232             :     CPLDebug("SQLITE", "OGRSQLiteVFSOpen(%s, %d)", zNameIn ? zNameIn : "(null)",
     233             :              flags);
     234             : #endif
     235             : 
     236       20626 :     OGRSQLiteVFSAppDataStruct *pAppData =
     237             :         static_cast<OGRSQLiteVFSAppDataStruct *>(pVFS->pAppData);
     238             : 
     239             :     const std::string osName(
     240       41252 :         zNameIn ? zNameIn : VSIMemGenerateHiddenFilename("sqlitevfs"));
     241             : 
     242       20626 :     OGRSQLiteFileStruct *pMyFile =
     243             :         reinterpret_cast<OGRSQLiteFileStruct *>(pFile);
     244       20626 :     pMyFile->pMethods = nullptr;
     245       20626 :     pMyFile->bDeleteOnClose = FALSE;
     246       20626 :     pMyFile->pszFilename = nullptr;
     247       20626 :     if (flags & SQLITE_OPEN_READONLY)
     248         833 :         pMyFile->fp = VSIFOpenL(osName.c_str(), "rb");
     249       19793 :     else if (flags & SQLITE_OPEN_CREATE)
     250             :     {
     251             :         VSIStatBufL sStatBufL;
     252       19023 :         if (VSIStatExL(osName.c_str(), &sStatBufL, VSI_STAT_EXISTS_FLAG) == 0)
     253          56 :             pMyFile->fp = VSIFOpenL(osName.c_str(), "rb+");
     254             :         else
     255       18967 :             pMyFile->fp = VSIFOpenL(osName.c_str(), "wb+");
     256             :     }
     257         770 :     else if (flags & SQLITE_OPEN_READWRITE)
     258         770 :         pMyFile->fp = VSIFOpenL(osName.c_str(), "rb+");
     259             :     else
     260           0 :         pMyFile->fp = nullptr;
     261             : 
     262       20626 :     if (pMyFile->fp == nullptr)
     263           4 :         return SQLITE_CANTOPEN;
     264             : 
     265             : #ifdef DEBUG_IO
     266             :     CPLDebug("SQLITE", "OGRSQLiteVFSOpen() = %p", pMyFile->fp);
     267             : #endif
     268             : 
     269       20622 :     pfnNotifyFileOpenedType pfn = pAppData->pfn;
     270       20622 :     if (pfn)
     271             :     {
     272       20199 :         pfn(pAppData->pfnUserData, osName.c_str(), pMyFile->fp);
     273             :     }
     274             : 
     275       20622 :     pMyFile->pMethods = &OGRSQLiteIOMethods;
     276       20622 :     pMyFile->bDeleteOnClose = (flags & SQLITE_OPEN_DELETEONCLOSE);
     277       20622 :     pMyFile->pszFilename = CPLStrdup(osName.c_str());
     278             : 
     279       20622 :     if (pOutFlags != nullptr)
     280        2758 :         *pOutFlags = flags;
     281             : 
     282       20622 :     return SQLITE_OK;
     283             : }
     284             : 
     285       17864 : static int OGRSQLiteVFSDelete(DEBUG_ONLY sqlite3_vfs *pVFS, const char *zName,
     286             :                               int DEBUG_ONLY syncDir)
     287             : {
     288             : #ifdef DEBUG_IO
     289             :     CPLDebug("SQLITE", "OGRSQLiteVFSDelete(%s)", zName);
     290             : #endif
     291       17864 :     VSIUnlink(zName);
     292       17864 :     return SQLITE_OK;
     293             : }
     294             : 
     295      182274 : static int OGRSQLiteVFSAccess(DEBUG_ONLY sqlite3_vfs *pVFS, const char *zName,
     296             :                               int flags, int *pResOut)
     297             : {
     298             : #ifdef DEBUG_IO
     299             :     CPLDebug("SQLITE", "OGRSQLiteVFSAccess(%s, %d)", zName, flags);
     300             : #endif
     301             :     VSIStatBufL sStatBufL;
     302             :     int nRet;  // TODO(schwehr): Cleanup nRet and pResOut.  bools?
     303      182274 :     if (flags == SQLITE_ACCESS_EXISTS)
     304             :     {
     305             :         /* Do not try to check the presence of a journal or a wal on /vsicurl !
     306             :          */
     307      182274 :         if ((STARTS_WITH(zName, "/vsicurl/") ||
     308      182106 :              STARTS_WITH(zName, "/vsitar/") ||
     309      182106 :              STARTS_WITH(zName, "/vsizip/")) &&
     310         300 :             ((strlen(zName) > strlen("-journal") &&
     311         300 :               strcmp(zName + strlen(zName) - strlen("-journal"), "-journal") ==
     312         150 :                   0) ||
     313         150 :              (strlen(zName) > strlen("-wal") &&
     314         150 :               strcmp(zName + strlen(zName) - strlen("-wal"), "-wal") == 0)))
     315             :         {
     316         300 :             nRet = -1;
     317             :         }
     318             :         else
     319             :         {
     320      181974 :             nRet = VSIStatExL(zName, &sStatBufL, VSI_STAT_EXISTS_FLAG);
     321             :         }
     322             :     }
     323           0 :     else if (flags == SQLITE_ACCESS_READ)
     324             :     {
     325           0 :         VSILFILE *fp = VSIFOpenL(zName, "rb");
     326           0 :         nRet = fp ? 0 : -1;
     327           0 :         if (fp)
     328           0 :             VSIFCloseL(fp);
     329             :     }
     330           0 :     else if (flags == SQLITE_ACCESS_READWRITE)
     331             :     {
     332           0 :         VSILFILE *fp = VSIFOpenL(zName, "rb+");
     333           0 :         nRet = fp ? 0 : -1;
     334           0 :         if (fp)
     335           0 :             VSIFCloseL(fp);
     336             :     }
     337             :     else
     338             :     {
     339           0 :         nRet = -1;
     340             :     }
     341      182274 :     *pResOut = (nRet == 0);
     342      182274 :     return SQLITE_OK;
     343             : }
     344             : 
     345        2750 : static int OGRSQLiteVFSFullPathname(sqlite3_vfs *pVFS, const char *zName,
     346             :                                     int nOut, char *zOut)
     347             : {
     348        2750 :     sqlite3_vfs *pUnderlyingVFS = GET_UNDERLYING_VFS(pVFS);
     349             : #ifdef DEBUG_IO
     350             :     CPLDebug("SQLITE", "OGRSQLiteVFSFullPathname(%s)", zName);
     351             : #endif
     352        2750 :     if (zName[0] == '/')
     353             :     {
     354        2748 :         if (static_cast<int>(strlen(zName)) >= nOut)
     355             :         {
     356             :             // The +8 comes from the fact that sqlite3 does this check as
     357             :             // it needs to be able to append .journal to the filename
     358           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     359             :                      "Maximum pathname length reserved for SQLite3 VFS "
     360             :                      "isn't large enough. Try raising "
     361             :                      "OGR_SQLITE_VFS_MAXPATHNAME to at least %d",
     362           0 :                      static_cast<int>(strlen(zName)) + 8);
     363           0 :             return SQLITE_CANTOPEN;
     364             :         }
     365        2748 :         strncpy(zOut, zName, nOut);
     366        2748 :         zOut[nOut - 1] = '\0';
     367        2748 :         return SQLITE_OK;
     368             :     }
     369           2 :     return pUnderlyingVFS->xFullPathname(pUnderlyingVFS, zName, nOut, zOut);
     370             : }
     371             : 
     372           0 : static void *OGRSQLiteVFSDlOpen(sqlite3_vfs *pVFS, const char *zFilename)
     373             : {
     374           0 :     sqlite3_vfs *pUnderlyingVFS = GET_UNDERLYING_VFS(pVFS);
     375             :     // CPLDebug("SQLITE", "OGRSQLiteVFSDlOpen(%s)", zFilename);
     376           0 :     return pUnderlyingVFS->xDlOpen(pUnderlyingVFS, zFilename);
     377             : }
     378             : 
     379           0 : static void OGRSQLiteVFSDlError(sqlite3_vfs *pVFS, int nByte, char *zErrMsg)
     380             : {
     381           0 :     sqlite3_vfs *pUnderlyingVFS = GET_UNDERLYING_VFS(pVFS);
     382             :     // CPLDebug("SQLITE", "OGRSQLiteVFSDlError()");
     383           0 :     pUnderlyingVFS->xDlError(pUnderlyingVFS, nByte, zErrMsg);
     384           0 : }
     385             : 
     386           0 : static void (*OGRSQLiteVFSDlSym(sqlite3_vfs *pVFS, void *pHandle,
     387             :                                 const char *zSymbol))(void)
     388             : {
     389           0 :     sqlite3_vfs *pUnderlyingVFS = GET_UNDERLYING_VFS(pVFS);
     390             :     // CPLDebug("SQLITE", "OGRSQLiteVFSDlSym(%s)", zSymbol);
     391           0 :     return pUnderlyingVFS->xDlSym(pUnderlyingVFS, pHandle, zSymbol);
     392             : }
     393             : 
     394           0 : static void OGRSQLiteVFSDlClose(sqlite3_vfs *pVFS, void *pHandle)
     395             : {
     396           0 :     sqlite3_vfs *pUnderlyingVFS = GET_UNDERLYING_VFS(pVFS);
     397             :     // CPLDebug("SQLITE", "OGRSQLiteVFSDlClose(%p)", pHandle);
     398           0 :     pUnderlyingVFS->xDlClose(pUnderlyingVFS, pHandle);
     399           0 : }
     400             : 
     401           0 : static int OGRSQLiteVFSRandomness(sqlite3_vfs *pVFS, int nByte, char *zOut)
     402             : {
     403           0 :     sqlite3_vfs *pUnderlyingVFS = GET_UNDERLYING_VFS(pVFS);
     404             :     // CPLDebug("SQLITE", "OGRSQLiteVFSRandomness()");
     405           0 :     return pUnderlyingVFS->xRandomness(pUnderlyingVFS, nByte, zOut);
     406             : }
     407             : 
     408           0 : static int OGRSQLiteVFSSleep(sqlite3_vfs *pVFS, int microseconds)
     409             : {
     410           0 :     sqlite3_vfs *pUnderlyingVFS = GET_UNDERLYING_VFS(pVFS);
     411             :     // CPLDebug("SQLITE", "OGRSQLiteVFSSleep()");
     412           0 :     return pUnderlyingVFS->xSleep(pUnderlyingVFS, microseconds);
     413             : }
     414             : 
     415             : // Derived for sqlite3.c implementation of unixCurrentTime64 and
     416             : // winCurrentTime64
     417             : #ifdef _WIN32
     418             : #include <windows.h>
     419             : 
     420             : static int OGRSQLiteVFSCurrentTimeInt64(sqlite3_vfs * /*pVFS*/,
     421             :                                         sqlite3_int64 *piNow)
     422             : {
     423             :     FILETIME ft;
     424             :     constexpr sqlite3_int64 winFiletimeEpoch =
     425             :         23058135 * static_cast<sqlite3_int64>(8640000);
     426             :     constexpr sqlite3_int64 max32BitValue =
     427             :         static_cast<sqlite3_int64>(2000000000) +
     428             :         static_cast<sqlite3_int64>(2000000000) +
     429             :         static_cast<sqlite3_int64>(294967296);
     430             : 
     431             : #if defined(_WIN32_WCE)
     432             :     SYSTEMTIME time;
     433             :     GetSystemTime(&time);
     434             :     /* if SystemTimeToFileTime() fails, it returns zero. */
     435             :     if (!SystemTimeToFileTime(&time, &ft))
     436             :     {
     437             :         return SQLITE_ERROR;
     438             :     }
     439             : #else
     440             :     GetSystemTimeAsFileTime(&ft);
     441             : #endif
     442             :     *piNow = winFiletimeEpoch +
     443             :              ((static_cast<sqlite3_int64>(ft.dwHighDateTime) * max32BitValue) +
     444             :               static_cast<sqlite3_int64>(ft.dwLowDateTime)) /
     445             :                  static_cast<sqlite3_int64>(10000);
     446             :     return SQLITE_OK;
     447             : }
     448             : #else
     449             : #include <sys/time.h>
     450             : 
     451        4092 : static int OGRSQLiteVFSCurrentTimeInt64(sqlite3_vfs * /*pVFS*/,
     452             :                                         sqlite3_int64 *piNow)
     453             : {
     454             :     struct timeval sNow;
     455        4092 :     constexpr sqlite3_int64 unixEpoch =
     456             :         24405875 * static_cast<sqlite3_int64>(8640000);
     457        4092 :     (void)gettimeofday(&sNow, nullptr); /* Cannot fail given valid arguments */
     458        4092 :     *piNow = unixEpoch + 1000 * static_cast<sqlite3_int64>(sNow.tv_sec) +
     459        4092 :              sNow.tv_usec / 1000;
     460             : 
     461        4092 :     return SQLITE_OK;
     462             : }
     463             : #endif
     464             : 
     465           0 : static int OGRSQLiteVFSCurrentTime(sqlite3_vfs * /*pVFS*/, double *p1)
     466             : {
     467           0 :     sqlite3_int64 i = 0;
     468           0 :     int rc = OGRSQLiteVFSCurrentTimeInt64(nullptr, &i);
     469           0 :     *p1 = i / 86400000.0;
     470           0 :     return rc;
     471             : }
     472             : 
     473          28 : static int OGRSQLiteVFSGetLastError(sqlite3_vfs *pVFS, int p1, char *p2)
     474             : {
     475          28 :     sqlite3_vfs *pUnderlyingVFS = GET_UNDERLYING_VFS(pVFS);
     476             :     // CPLDebug("SQLITE", "OGRSQLiteVFSGetLastError()");
     477          28 :     return pUnderlyingVFS->xGetLastError(pUnderlyingVFS, p1, p2);
     478             : }
     479             : 
     480        2627 : sqlite3_vfs *OGRSQLiteCreateVFS(pfnNotifyFileOpenedType pfn, void *pfnUserData)
     481             : {
     482        2627 :     sqlite3_vfs *pDefaultVFS = sqlite3_vfs_find(nullptr);
     483             :     sqlite3_vfs *pMyVFS =
     484        2627 :         static_cast<sqlite3_vfs *>(CPLCalloc(1, sizeof(sqlite3_vfs)));
     485             : 
     486             :     OGRSQLiteVFSAppDataStruct *pVFSAppData =
     487             :         static_cast<OGRSQLiteVFSAppDataStruct *>(
     488        2627 :             CPLCalloc(1, sizeof(OGRSQLiteVFSAppDataStruct)));
     489             :     char szPtr[32];
     490        2627 :     snprintf(szPtr, sizeof(szPtr), "%p", pVFSAppData);
     491        2627 :     snprintf(pVFSAppData->szVFSName, sizeof(pVFSAppData->szVFSName),
     492             :              "OGRSQLITEVFS_%s", szPtr);
     493        2627 :     pVFSAppData->pDefaultVFS = pDefaultVFS;
     494        2627 :     pVFSAppData->pfn = pfn;
     495        2627 :     pVFSAppData->pfnUserData = pfnUserData;
     496             : 
     497        2627 :     pMyVFS->iVersion = 2;
     498        2627 :     pMyVFS->szOsFile = sizeof(OGRSQLiteFileStruct);
     499             :     // must be large enough to hold potentially very long names like
     500             :     // /vsicurl/.... with AWS S3 security tokens
     501        2627 :     pMyVFS->mxPathname =
     502        2627 :         atoi(CPLGetConfigOption("OGR_SQLITE_VFS_MAXPATHNAME", "2048"));
     503        2627 :     pMyVFS->zName = pVFSAppData->szVFSName;
     504        2627 :     pMyVFS->pAppData = pVFSAppData;
     505        2627 :     pMyVFS->xOpen = OGRSQLiteVFSOpen;
     506        2627 :     pMyVFS->xDelete = OGRSQLiteVFSDelete;
     507        2627 :     pMyVFS->xAccess = OGRSQLiteVFSAccess;
     508        2627 :     pMyVFS->xFullPathname = OGRSQLiteVFSFullPathname;
     509        2627 :     pMyVFS->xDlOpen = OGRSQLiteVFSDlOpen;
     510        2627 :     pMyVFS->xDlError = OGRSQLiteVFSDlError;
     511        2627 :     pMyVFS->xDlSym = OGRSQLiteVFSDlSym;
     512        2627 :     pMyVFS->xDlClose = OGRSQLiteVFSDlClose;
     513        2627 :     pMyVFS->xRandomness = OGRSQLiteVFSRandomness;
     514        2627 :     pMyVFS->xSleep = OGRSQLiteVFSSleep;
     515        2627 :     pMyVFS->xCurrentTime = OGRSQLiteVFSCurrentTime;
     516        2627 :     pMyVFS->xGetLastError = OGRSQLiteVFSGetLastError;
     517        2627 :     pMyVFS->xCurrentTimeInt64 = OGRSQLiteVFSCurrentTimeInt64;
     518             : 
     519        2627 :     return pMyVFS;
     520             : }

Generated by: LCOV version 1.14