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 : }
|