blob: d2509a7e3283b174658eef34e09c9ae691cbdb9d [file] [log] [blame]
drhac442f42018-01-03 01:28:46 +00001/*
2** 2016-09-07
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11******************************************************************************
12**
drh840fda42018-03-28 15:06:39 +000013** This file implements an in-memory VFS. A database is held as a contiguous
drh99abe5c2018-01-03 22:48:38 +000014** block of memory.
15**
16** This file also implements interface sqlite3_serialize() and
17** sqlite3_deserialize().
drhac442f42018-01-03 01:28:46 +000018*/
drhac442f42018-01-03 01:28:46 +000019#include "sqliteInt.h"
drh8d889af2021-05-08 17:18:23 +000020#ifndef SQLITE_OMIT_DESERIALIZE
drhac442f42018-01-03 01:28:46 +000021
22/*
23** Forward declaration of objects used by this utility
24*/
25typedef struct sqlite3_vfs MemVfs;
26typedef struct MemFile MemFile;
drh2f4d0ec2021-05-10 23:48:46 +000027typedef struct MemStore MemStore;
drhac442f42018-01-03 01:28:46 +000028
29/* Access to a lower-level VFS that (might) implement dynamic loading,
30** access to randomness, etc.
31*/
32#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
33
drh2f4d0ec2021-05-10 23:48:46 +000034/* Storage for a memdb file.
35**
36** An memdb object can be shared or separate. Shared memdb objects can be
37** used by more than one database connection. Mutexes are used by shared
38** memdb objects to coordinate access. Separate memdb objects are only
39** connected to a single database connection and do not require additional
40** mutexes.
41**
42** Shared memdb objects have .zFName!=0 and .pMutex!=0. They are created
43** using "file:/name?vfs=memdb". The first character of the name must be
44** "/" or else the object will be a separate memdb object. All shared
45** memdb objects are stored in memdb_g.apMemStore[] in an arbitrary order.
46**
47** Separate memdb objects are created using a name that does not begin
48** with "/" or using sqlite3_deserialize().
49**
50** Access rules for shared MemStore objects:
51**
52** * .zFName is initialized when the object is created and afterwards
53** is unchanged until the object is destroyed. So it can be accessed
54** at any time as long as we know the object is not being destroyed,
55** which means while either the SQLITE_MUTEX_STATIC_VFS1 or
56** .pMutex is held or the object is not part of memdb_g.apMemStore[].
57**
58** * Can .pMutex can only be changed while holding the
59** SQLITE_MUTEX_STATIC_VFS1 mutex or while the object is not part
60** of memdb_g.apMemStore[].
61**
62** * Other fields can only be changed while holding the .pMutex mutex
63** or when the .nRef is less than zero and the object is not part of
64** memdb_g.apMemStore[].
65**
66** * The .aData pointer has the added requirement that it can can only
67** be changed (for resizing) when nMmap is zero.
68**
69*/
70struct MemStore {
drhac442f42018-01-03 01:28:46 +000071 sqlite3_int64 sz; /* Size of the file */
drh6ca64482019-01-22 16:06:20 +000072 sqlite3_int64 szAlloc; /* Space allocated to aData */
73 sqlite3_int64 szMax; /* Maximum allowed size of the file */
drhac442f42018-01-03 01:28:46 +000074 unsigned char *aData; /* content of the file */
drh2f4d0ec2021-05-10 23:48:46 +000075 sqlite3_mutex *pMutex; /* Used by shared stores only */
drhac442f42018-01-03 01:28:46 +000076 int nMmap; /* Number of memory mapped pages */
77 unsigned mFlags; /* Flags */
drh2f4d0ec2021-05-10 23:48:46 +000078 int nRdLock; /* Number of readers */
79 int nWrLock; /* Number of writers. (Always 0 or 1) */
80 int nRef; /* Number of users of this MemStore */
81 char *zFName; /* The filename for shared stores */
82};
83
84/* An open file */
85struct MemFile {
86 sqlite3_file base; /* IO methods */
87 MemStore *pStore; /* The storage */
drhac442f42018-01-03 01:28:46 +000088 int eLock; /* Most recent lock against this file */
89};
90
91/*
drh2f4d0ec2021-05-10 23:48:46 +000092** Global variables for holding the memdb files that are accessible
93** to multiple database connections in separate threads.
94**
95** Must hold SQLITE_MUTEX_STATIC_VFS1 to access any part of this object.
96*/
97struct MemFS {
98 int nMemStore; /* Number of shared MemStore objects */
99 MemStore **apMemStore; /* Array of all shared MemStore objects */
100} memdb_g;
101
102/*
drhac442f42018-01-03 01:28:46 +0000103** Methods for MemFile
104*/
105static int memdbClose(sqlite3_file*);
106static int memdbRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
107static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
108static int memdbTruncate(sqlite3_file*, sqlite3_int64 size);
109static int memdbSync(sqlite3_file*, int flags);
110static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize);
111static int memdbLock(sqlite3_file*, int);
drh14714162018-03-06 19:14:32 +0000112/* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */
drhac442f42018-01-03 01:28:46 +0000113static int memdbFileControl(sqlite3_file*, int op, void *pArg);
drh5f9d1922018-03-06 04:01:08 +0000114/* static int memdbSectorSize(sqlite3_file*); // not used */
drhac442f42018-01-03 01:28:46 +0000115static int memdbDeviceCharacteristics(sqlite3_file*);
drhac442f42018-01-03 01:28:46 +0000116static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
117static int memdbUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
118
119/*
120** Methods for MemVfs
121*/
122static int memdbOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
drh14714162018-03-06 19:14:32 +0000123/* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */
drhac442f42018-01-03 01:28:46 +0000124static int memdbAccess(sqlite3_vfs*, const char *zName, int flags, int *);
125static int memdbFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
126static void *memdbDlOpen(sqlite3_vfs*, const char *zFilename);
127static void memdbDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
128static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
129static void memdbDlClose(sqlite3_vfs*, void*);
130static int memdbRandomness(sqlite3_vfs*, int nByte, char *zOut);
131static int memdbSleep(sqlite3_vfs*, int microseconds);
drh14714162018-03-06 19:14:32 +0000132/* static int memdbCurrentTime(sqlite3_vfs*, double*); */
drhac442f42018-01-03 01:28:46 +0000133static int memdbGetLastError(sqlite3_vfs*, int, char *);
134static int memdbCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
135
136static sqlite3_vfs memdb_vfs = {
137 2, /* iVersion */
138 0, /* szOsFile (set when registered) */
139 1024, /* mxPathname */
140 0, /* pNext */
141 "memdb", /* zName */
142 0, /* pAppData (set when registered) */
143 memdbOpen, /* xOpen */
drh14714162018-03-06 19:14:32 +0000144 0, /* memdbDelete, */ /* xDelete */
drhac442f42018-01-03 01:28:46 +0000145 memdbAccess, /* xAccess */
146 memdbFullPathname, /* xFullPathname */
147 memdbDlOpen, /* xDlOpen */
148 memdbDlError, /* xDlError */
149 memdbDlSym, /* xDlSym */
150 memdbDlClose, /* xDlClose */
151 memdbRandomness, /* xRandomness */
152 memdbSleep, /* xSleep */
drh14714162018-03-06 19:14:32 +0000153 0, /* memdbCurrentTime, */ /* xCurrentTime */
drhac442f42018-01-03 01:28:46 +0000154 memdbGetLastError, /* xGetLastError */
155 memdbCurrentTimeInt64 /* xCurrentTimeInt64 */
156};
157
158static const sqlite3_io_methods memdb_io_methods = {
159 3, /* iVersion */
160 memdbClose, /* xClose */
161 memdbRead, /* xRead */
162 memdbWrite, /* xWrite */
163 memdbTruncate, /* xTruncate */
164 memdbSync, /* xSync */
165 memdbFileSize, /* xFileSize */
166 memdbLock, /* xLock */
167 memdbLock, /* xUnlock - same as xLock in this case */
drh14714162018-03-06 19:14:32 +0000168 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */
drhac442f42018-01-03 01:28:46 +0000169 memdbFileControl, /* xFileControl */
drh5f9d1922018-03-06 04:01:08 +0000170 0, /* memdbSectorSize,*/ /* xSectorSize */
drhac442f42018-01-03 01:28:46 +0000171 memdbDeviceCharacteristics, /* xDeviceCharacteristics */
drh99abe5c2018-01-03 22:48:38 +0000172 0, /* xShmMap */
173 0, /* xShmLock */
174 0, /* xShmBarrier */
175 0, /* xShmUnmap */
drhac442f42018-01-03 01:28:46 +0000176 memdbFetch, /* xFetch */
177 memdbUnfetch /* xUnfetch */
178};
179
drh2f4d0ec2021-05-10 23:48:46 +0000180/*
181** Enter/leave the mutex on a MemStore
182*/
183static void memdbEnter(MemStore *p){
184 sqlite3_mutex_enter(p->pMutex);
185}
186static void memdbLeave(MemStore *p){
187 sqlite3_mutex_leave(p->pMutex);
188}
189
drhac442f42018-01-03 01:28:46 +0000190
191
192/*
193** Close an memdb-file.
drh2f4d0ec2021-05-10 23:48:46 +0000194** Free the underlying MemStore object when its refcount drops to zero
195** or less.
drhac442f42018-01-03 01:28:46 +0000196*/
197static int memdbClose(sqlite3_file *pFile){
drh2f4d0ec2021-05-10 23:48:46 +0000198 MemStore *p = ((MemFile*)pFile)->pStore;
199 memdbEnter(p);
200 p->nRef--;
201 if( p->nRef<=0 ){
202 if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){
203 sqlite3_free(p->aData);
204 }
205 if( p->zFName ){
206 int i;
drh2d344f92021-05-12 02:52:20 +0000207#ifndef SQLITE_MUTEX_OMIT
drh2f4d0ec2021-05-10 23:48:46 +0000208 sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
drh2d344f92021-05-12 02:52:20 +0000209#endif
drh2f4d0ec2021-05-10 23:48:46 +0000210 sqlite3_mutex_enter(pVfsMutex);
211 for(i=0; ALWAYS(i<memdb_g.nMemStore); i++){
212 if( memdb_g.apMemStore[i]==p ){
213 memdb_g.apMemStore[i] = memdb_g.apMemStore[--memdb_g.nMemStore];
214 if( memdb_g.nMemStore==0 ){
215 sqlite3_free(memdb_g.apMemStore);
216 memdb_g.apMemStore = 0;
217 }
218 break;
219 }
220 }
221 sqlite3_mutex_leave(pVfsMutex);
222 }
223 memdbLeave(p);
224 sqlite3_mutex_free(p->pMutex);
225 sqlite3_free(p);
226 }else{
227 memdbLeave(p);
drhff01ee32020-10-17 22:13:16 +0000228 }
drhac442f42018-01-03 01:28:46 +0000229 return SQLITE_OK;
230}
231
232/*
233** Read data from an memdb-file.
234*/
235static int memdbRead(
236 sqlite3_file *pFile,
237 void *zBuf,
238 int iAmt,
239 sqlite_int64 iOfst
240){
drh2f4d0ec2021-05-10 23:48:46 +0000241 MemStore *p = ((MemFile*)pFile)->pStore;
242 memdbEnter(p);
drhac442f42018-01-03 01:28:46 +0000243 if( iOfst+iAmt>p->sz ){
244 memset(zBuf, 0, iAmt);
drhcb7d5412018-01-03 16:49:52 +0000245 if( iOfst<p->sz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst);
drh2f4d0ec2021-05-10 23:48:46 +0000246 memdbLeave(p);
drhac442f42018-01-03 01:28:46 +0000247 return SQLITE_IOERR_SHORT_READ;
248 }
249 memcpy(zBuf, p->aData+iOfst, iAmt);
drh2f4d0ec2021-05-10 23:48:46 +0000250 memdbLeave(p);
drhac442f42018-01-03 01:28:46 +0000251 return SQLITE_OK;
252}
253
254/*
255** Try to enlarge the memory allocation to hold at least sz bytes
256*/
drh2f4d0ec2021-05-10 23:48:46 +0000257static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){
drhac442f42018-01-03 01:28:46 +0000258 unsigned char *pNew;
drh5f9d1922018-03-06 04:01:08 +0000259 if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
260 return SQLITE_FULL;
261 }
drh6ca64482019-01-22 16:06:20 +0000262 if( newSz>p->szMax ){
263 return SQLITE_FULL;
264 }
265 newSz *= 2;
266 if( newSz>p->szMax ) newSz = p->szMax;
drhd924e7b2020-05-17 00:26:44 +0000267 pNew = sqlite3Realloc(p->aData, newSz);
dana3a91dd2021-04-09 20:50:40 +0000268 if( pNew==0 ) return SQLITE_IOERR_NOMEM;
drhac442f42018-01-03 01:28:46 +0000269 p->aData = pNew;
drh6ca64482019-01-22 16:06:20 +0000270 p->szAlloc = newSz;
drhac442f42018-01-03 01:28:46 +0000271 return SQLITE_OK;
272}
273
274/*
275** Write data to an memdb-file.
276*/
277static int memdbWrite(
278 sqlite3_file *pFile,
279 const void *z,
280 int iAmt,
281 sqlite_int64 iOfst
282){
drh2f4d0ec2021-05-10 23:48:46 +0000283 MemStore *p = ((MemFile*)pFile)->pStore;
284 memdbEnter(p);
drh483051c2021-05-12 02:09:01 +0000285 if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ){
286 /* Can't happen: memdbLock() will return SQLITE_READONLY before
287 ** reaching this point */
drh2f4d0ec2021-05-10 23:48:46 +0000288 memdbLeave(p);
289 return SQLITE_IOERR_WRITE;
290 }
drhac442f42018-01-03 01:28:46 +0000291 if( iOfst+iAmt>p->sz ){
drh5f9d1922018-03-06 04:01:08 +0000292 int rc;
drh6ca64482019-01-22 16:06:20 +0000293 if( iOfst+iAmt>p->szAlloc
294 && (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK
drh5f9d1922018-03-06 04:01:08 +0000295 ){
drh2f4d0ec2021-05-10 23:48:46 +0000296 memdbLeave(p);
drh5f9d1922018-03-06 04:01:08 +0000297 return rc;
drhac442f42018-01-03 01:28:46 +0000298 }
299 if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz);
300 p->sz = iOfst+iAmt;
301 }
302 memcpy(p->aData+iOfst, z, iAmt);
drh2f4d0ec2021-05-10 23:48:46 +0000303 memdbLeave(p);
drhac442f42018-01-03 01:28:46 +0000304 return SQLITE_OK;
305}
306
307/*
308** Truncate an memdb-file.
drh14714162018-03-06 19:14:32 +0000309**
310** In rollback mode (which is always the case for memdb, as it does not
311** support WAL mode) the truncate() method is only used to reduce
312** the size of a file, never to increase the size.
drhac442f42018-01-03 01:28:46 +0000313*/
314static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
drh2f4d0ec2021-05-10 23:48:46 +0000315 MemStore *p = ((MemFile*)pFile)->pStore;
316 int rc = SQLITE_OK;
317 memdbEnter(p);
318 if( NEVER(size>p->sz) ){
319 rc = SQLITE_FULL;
320 }else{
321 p->sz = size;
322 }
323 memdbLeave(p);
324 return rc;
drhac442f42018-01-03 01:28:46 +0000325}
326
327/*
328** Sync an memdb-file.
329*/
330static int memdbSync(sqlite3_file *pFile, int flags){
331 return SQLITE_OK;
332}
333
334/*
335** Return the current file-size of an memdb-file.
336*/
337static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
drh2f4d0ec2021-05-10 23:48:46 +0000338 MemStore *p = ((MemFile*)pFile)->pStore;
339 memdbEnter(p);
drhac442f42018-01-03 01:28:46 +0000340 *pSize = p->sz;
drh2f4d0ec2021-05-10 23:48:46 +0000341 memdbLeave(p);
drhac442f42018-01-03 01:28:46 +0000342 return SQLITE_OK;
343}
344
345/*
346** Lock an memdb-file.
347*/
348static int memdbLock(sqlite3_file *pFile, int eLock){
drh2f4d0ec2021-05-10 23:48:46 +0000349 MemFile *pThis = (MemFile*)pFile;
350 MemStore *p = pThis->pStore;
351 int rc = SQLITE_OK;
352 if( eLock==pThis->eLock ) return SQLITE_OK;
353 memdbEnter(p);
354 if( eLock>SQLITE_LOCK_SHARED ){
355 if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){
356 rc = SQLITE_READONLY;
357 }else if( pThis->eLock<=SQLITE_LOCK_SHARED ){
358 if( p->nWrLock ){
359 rc = SQLITE_BUSY;
360 }else{
361 p->nWrLock = 1;
362 }
363 }
364 }else if( eLock==SQLITE_LOCK_SHARED ){
365 if( pThis->eLock > SQLITE_LOCK_SHARED ){
366 assert( p->nWrLock==1 );
367 p->nWrLock = 0;
368 }else if( p->nWrLock ){
369 rc = SQLITE_BUSY;
370 }else{
371 p->nRdLock++;
372 }
373 }else{
374 assert( eLock==SQLITE_LOCK_NONE );
375 if( pThis->eLock>SQLITE_LOCK_SHARED ){
376 assert( p->nWrLock==1 );
377 p->nWrLock = 0;
378 }
379 assert( p->nRdLock>0 );
380 p->nRdLock--;
drhf186f0b2019-01-22 16:43:47 +0000381 }
drh2f4d0ec2021-05-10 23:48:46 +0000382 if( rc==SQLITE_OK ) pThis->eLock = eLock;
383 memdbLeave(p);
384 return rc;
drhac442f42018-01-03 01:28:46 +0000385}
386
drh2f4d0ec2021-05-10 23:48:46 +0000387#if 0
drhac442f42018-01-03 01:28:46 +0000388/*
drh2f4d0ec2021-05-10 23:48:46 +0000389** This interface is only used for crash recovery, which does not
390** occur on an in-memory database.
drhac442f42018-01-03 01:28:46 +0000391*/
392static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
393 *pResOut = 0;
394 return SQLITE_OK;
395}
drh14714162018-03-06 19:14:32 +0000396#endif
drhac442f42018-01-03 01:28:46 +0000397
drh2f4d0ec2021-05-10 23:48:46 +0000398
drhac442f42018-01-03 01:28:46 +0000399/*
400** File control method. For custom operations on an memdb-file.
401*/
402static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
drh2f4d0ec2021-05-10 23:48:46 +0000403 MemStore *p = ((MemFile*)pFile)->pStore;
drhac442f42018-01-03 01:28:46 +0000404 int rc = SQLITE_NOTFOUND;
drh2f4d0ec2021-05-10 23:48:46 +0000405 memdbEnter(p);
drhac442f42018-01-03 01:28:46 +0000406 if( op==SQLITE_FCNTL_VFSNAME ){
407 *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
408 rc = SQLITE_OK;
409 }
drh6ca64482019-01-22 16:06:20 +0000410 if( op==SQLITE_FCNTL_SIZE_LIMIT ){
411 sqlite3_int64 iLimit = *(sqlite3_int64*)pArg;
412 if( iLimit<p->sz ){
413 if( iLimit<0 ){
414 iLimit = p->szMax;
415 }else{
416 iLimit = p->sz;
417 }
418 }
419 p->szMax = iLimit;
420 *(sqlite3_int64*)pArg = iLimit;
421 rc = SQLITE_OK;
422 }
drh2f4d0ec2021-05-10 23:48:46 +0000423 memdbLeave(p);
drhac442f42018-01-03 01:28:46 +0000424 return rc;
425}
426
drh5f9d1922018-03-06 04:01:08 +0000427#if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */
drhac442f42018-01-03 01:28:46 +0000428/*
429** Return the sector-size in bytes for an memdb-file.
430*/
431static int memdbSectorSize(sqlite3_file *pFile){
432 return 1024;
433}
drh5f9d1922018-03-06 04:01:08 +0000434#endif
drhac442f42018-01-03 01:28:46 +0000435
436/*
437** Return the device characteristic flags supported by an memdb-file.
438*/
439static int memdbDeviceCharacteristics(sqlite3_file *pFile){
440 return SQLITE_IOCAP_ATOMIC |
441 SQLITE_IOCAP_POWERSAFE_OVERWRITE |
442 SQLITE_IOCAP_SAFE_APPEND |
443 SQLITE_IOCAP_SEQUENTIAL;
444}
445
drhac442f42018-01-03 01:28:46 +0000446/* Fetch a page of a memory-mapped file */
447static int memdbFetch(
448 sqlite3_file *pFile,
449 sqlite3_int64 iOfst,
450 int iAmt,
451 void **pp
452){
drh2f4d0ec2021-05-10 23:48:46 +0000453 MemStore *p = ((MemFile*)pFile)->pStore;
454 memdbEnter(p);
drh94f0a832019-01-25 14:16:01 +0000455 if( iOfst+iAmt>p->sz ){
drh94f0a832019-01-25 14:16:01 +0000456 *pp = 0;
457 }else{
458 p->nMmap++;
459 *pp = (void*)(p->aData + iOfst);
460 }
drh2f4d0ec2021-05-10 23:48:46 +0000461 memdbLeave(p);
drhac442f42018-01-03 01:28:46 +0000462 return SQLITE_OK;
463}
464
465/* Release a memory-mapped page */
466static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
drh2f4d0ec2021-05-10 23:48:46 +0000467 MemStore *p = ((MemFile*)pFile)->pStore;
468 memdbEnter(p);
drhac442f42018-01-03 01:28:46 +0000469 p->nMmap--;
drh2f4d0ec2021-05-10 23:48:46 +0000470 memdbLeave(p);
drhac442f42018-01-03 01:28:46 +0000471 return SQLITE_OK;
472}
473
474/*
475** Open an mem file handle.
476*/
477static int memdbOpen(
478 sqlite3_vfs *pVfs,
479 const char *zName,
drh2f4d0ec2021-05-10 23:48:46 +0000480 sqlite3_file *pFd,
drhac442f42018-01-03 01:28:46 +0000481 int flags,
482 int *pOutFlags
483){
drh2f4d0ec2021-05-10 23:48:46 +0000484 MemFile *pFile = (MemFile*)pFd;
485 MemStore *p = 0;
486 int szName;
drh5f9d1922018-03-06 04:01:08 +0000487 if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
drh2f4d0ec2021-05-10 23:48:46 +0000488 return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFd, flags, pOutFlags);
drh5f9d1922018-03-06 04:01:08 +0000489 }
drh2f4d0ec2021-05-10 23:48:46 +0000490 memset(pFile, 0, sizeof(*p));
491 szName = sqlite3Strlen30(zName);
492 if( szName>1 && zName[0]=='/' ){
493 int i;
drh2d344f92021-05-12 02:52:20 +0000494#ifndef SQLITE_MUTEX_OMIT
drh2f4d0ec2021-05-10 23:48:46 +0000495 sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
drh2d344f92021-05-12 02:52:20 +0000496#endif
drh2f4d0ec2021-05-10 23:48:46 +0000497 sqlite3_mutex_enter(pVfsMutex);
498 for(i=0; i<memdb_g.nMemStore; i++){
499 if( strcmp(memdb_g.apMemStore[i]->zFName,zName)==0 ){
500 p = memdb_g.apMemStore[i];
501 break;
502 }
503 }
504 if( p==0 ){
505 MemStore **apNew;
506 p = sqlite3Malloc( sizeof(*p) + szName + 3 );
507 if( p==0 ){
508 sqlite3_mutex_leave(pVfsMutex);
509 return SQLITE_NOMEM;
510 }
511 apNew = sqlite3Realloc(memdb_g.apMemStore,
512 sizeof(apNew[0])*(memdb_g.nMemStore+1) );
513 if( apNew==0 ){
514 sqlite3_free(p);
515 sqlite3_mutex_leave(pVfsMutex);
516 return SQLITE_NOMEM;
517 }
518 apNew[memdb_g.nMemStore++] = p;
519 memdb_g.apMemStore = apNew;
520 memset(p, 0, sizeof(*p));
521 p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE|SQLITE_DESERIALIZE_FREEONCLOSE;
522 p->szMax = sqlite3GlobalConfig.mxMemdbSize;
523 p->zFName = (char*)&p[1];
524 memcpy(p->zFName, zName, szName+1);
525 p->pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
drh2d344f92021-05-12 02:52:20 +0000526 if( p->pMutex==0 ){
527 memdb_g.nMemStore--;
528 sqlite3_free(p);
529 sqlite3_mutex_leave(pVfsMutex);
530 return SQLITE_NOMEM;
531 }
drh2f4d0ec2021-05-10 23:48:46 +0000532 p->nRef = 1;
533 memdbEnter(p);
534 }else{
535 memdbEnter(p);
536 p->nRef++;
537 }
538 sqlite3_mutex_leave(pVfsMutex);
539 }else{
540 p = sqlite3Malloc( sizeof(*p) );
541 if( p==0 ){
542 return SQLITE_NOMEM;
543 }
544 memset(p, 0, sizeof(*p));
545 p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
546 p->szMax = sqlite3GlobalConfig.mxMemdbSize;
547 }
548 pFile->pStore = p;
drh14714162018-03-06 19:14:32 +0000549 assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
550 *pOutFlags = flags | SQLITE_OPEN_MEMORY;
drh2f4d0ec2021-05-10 23:48:46 +0000551 pFd->pMethods = &memdb_io_methods;
552 memdbLeave(p);
drhac442f42018-01-03 01:28:46 +0000553 return SQLITE_OK;
554}
555
drh067b92b2020-06-19 15:24:12 +0000556#if 0 /* Only used to delete rollback journals, super-journals, and WAL
drh14714162018-03-06 19:14:32 +0000557 ** files, none of which exist in memdb. So this routine is never used */
drhac442f42018-01-03 01:28:46 +0000558/*
559** Delete the file located at zPath. If the dirSync argument is true,
560** ensure the file-system modifications are synced to disk before
561** returning.
562*/
563static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
564 return SQLITE_IOERR_DELETE;
565}
drh14714162018-03-06 19:14:32 +0000566#endif
drhac442f42018-01-03 01:28:46 +0000567
568/*
569** Test for access permissions. Return true if the requested permission
570** is available, or false otherwise.
drh14714162018-03-06 19:14:32 +0000571**
572** With memdb, no files ever exist on disk. So always return false.
drhac442f42018-01-03 01:28:46 +0000573*/
574static int memdbAccess(
575 sqlite3_vfs *pVfs,
576 const char *zPath,
577 int flags,
578 int *pResOut
579){
580 *pResOut = 0;
581 return SQLITE_OK;
582}
583
584/*
585** Populate buffer zOut with the full canonical pathname corresponding
586** to the pathname in zPath. zOut is guaranteed to point to a buffer
587** of at least (INST_MAX_PATHNAME+1) bytes.
588*/
589static int memdbFullPathname(
590 sqlite3_vfs *pVfs,
591 const char *zPath,
592 int nOut,
593 char *zOut
594){
595 sqlite3_snprintf(nOut, zOut, "%s", zPath);
596 return SQLITE_OK;
597}
598
599/*
600** Open the dynamic library located at zPath and return a handle.
601*/
602static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){
603 return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
604}
605
606/*
607** Populate the buffer zErrMsg (size nByte bytes) with a human readable
608** utf-8 string describing the most recent error encountered associated
609** with dynamic libraries.
610*/
611static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
612 ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
613}
614
615/*
616** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
617*/
618static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
619 return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
620}
621
622/*
623** Close the dynamic library handle pHandle.
624*/
625static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){
626 ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
627}
628
629/*
630** Populate the buffer pointed to by zBufOut with nByte bytes of
631** random data.
632*/
633static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
634 return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
635}
636
637/*
638** Sleep for nMicro microseconds. Return the number of microseconds
639** actually slept.
640*/
641static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){
642 return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
643}
644
drh14714162018-03-06 19:14:32 +0000645#if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */
drhac442f42018-01-03 01:28:46 +0000646/*
647** Return the current time as a Julian Day number in *pTimeOut.
648*/
649static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
650 return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
651}
drh14714162018-03-06 19:14:32 +0000652#endif
drhac442f42018-01-03 01:28:46 +0000653
654static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){
655 return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
656}
657static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
658 return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
659}
660
661/*
662** Translate a database connection pointer and schema name into a
663** MemFile pointer.
664*/
665static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
666 MemFile *p = 0;
drh2f4d0ec2021-05-10 23:48:46 +0000667 MemStore *pStore;
drhac442f42018-01-03 01:28:46 +0000668 int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p);
669 if( rc ) return 0;
670 if( p->base.pMethods!=&memdb_io_methods ) return 0;
drh2f4d0ec2021-05-10 23:48:46 +0000671 pStore = p->pStore;
672 memdbEnter(pStore);
673 if( pStore->zFName!=0 ) p = 0;
674 memdbLeave(pStore);
drhac442f42018-01-03 01:28:46 +0000675 return p;
676}
677
678/*
drhcb7d5412018-01-03 16:49:52 +0000679** Return the serialization of a database
680*/
681unsigned char *sqlite3_serialize(
682 sqlite3 *db, /* The database connection */
683 const char *zSchema, /* Which database within the connection */
684 sqlite3_int64 *piSize, /* Write size here, if not NULL */
685 unsigned int mFlags /* Maybe SQLITE_SERIALIZE_NOCOPY */
686){
drhb2194ce2018-03-01 22:18:26 +0000687 MemFile *p;
688 int iDb;
drhcb7d5412018-01-03 16:49:52 +0000689 Btree *pBt;
690 sqlite3_int64 sz;
691 int szPage = 0;
692 sqlite3_stmt *pStmt = 0;
693 unsigned char *pOut;
694 char *zSql;
695 int rc;
696
mistachkin6630f942018-03-08 19:56:52 +0000697#ifdef SQLITE_ENABLE_API_ARMOR
698 if( !sqlite3SafetyCheckOk(db) ){
699 (void)SQLITE_MISUSE_BKPT;
700 return 0;
701 }
702#endif
703
drhb2194ce2018-03-01 22:18:26 +0000704 if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
705 p = memdbFromDbSchema(db, zSchema);
706 iDb = sqlite3FindDbName(db, zSchema);
drhcb7d5412018-01-03 16:49:52 +0000707 if( piSize ) *piSize = -1;
708 if( iDb<0 ) return 0;
709 if( p ){
drh2f4d0ec2021-05-10 23:48:46 +0000710 MemStore *pStore = p->pStore;
711 assert( pStore->pMutex==0 );
712 if( piSize ) *piSize = pStore->sz;
drhcb7d5412018-01-03 16:49:52 +0000713 if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
drh2f4d0ec2021-05-10 23:48:46 +0000714 pOut = pStore->aData;
drhcb7d5412018-01-03 16:49:52 +0000715 }else{
drh2f4d0ec2021-05-10 23:48:46 +0000716 pOut = sqlite3_malloc64( pStore->sz );
717 if( pOut ) memcpy(pOut, pStore->aData, pStore->sz);
drhcb7d5412018-01-03 16:49:52 +0000718 }
719 return pOut;
720 }
721 pBt = db->aDb[iDb].pBt;
722 if( pBt==0 ) return 0;
723 szPage = sqlite3BtreeGetPageSize(pBt);
724 zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema);
725 rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM;
726 sqlite3_free(zSql);
727 if( rc ) return 0;
drh8784efa2018-03-06 20:54:27 +0000728 rc = sqlite3_step(pStmt);
729 if( rc!=SQLITE_ROW ){
drhcb7d5412018-01-03 16:49:52 +0000730 pOut = 0;
731 }else{
drh8784efa2018-03-06 20:54:27 +0000732 sz = sqlite3_column_int64(pStmt, 0)*szPage;
733 if( piSize ) *piSize = sz;
734 if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
735 pOut = 0;
736 }else{
737 pOut = sqlite3_malloc64( sz );
738 if( pOut ){
739 int nPage = sqlite3_column_int(pStmt, 0);
740 Pager *pPager = sqlite3BtreePager(pBt);
741 int pgno;
742 for(pgno=1; pgno<=nPage; pgno++){
743 DbPage *pPage = 0;
744 unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1);
745 rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0);
746 if( rc==SQLITE_OK ){
747 memcpy(pTo, sqlite3PagerGetData(pPage), szPage);
748 }else{
749 memset(pTo, 0, szPage);
750 }
751 sqlite3PagerUnref(pPage);
drhcb7d5412018-01-03 16:49:52 +0000752 }
drhcb7d5412018-01-03 16:49:52 +0000753 }
754 }
755 }
756 sqlite3_finalize(pStmt);
757 return pOut;
758}
759
drh3ec86652018-01-03 19:03:31 +0000760/* Convert zSchema to a MemDB and initialize its content.
761*/
762int sqlite3_deserialize(
763 sqlite3 *db, /* The database connection */
764 const char *zSchema, /* Which DB to reopen with the deserialization */
765 unsigned char *pData, /* The serialized database content */
766 sqlite3_int64 szDb, /* Number bytes in the deserialization */
767 sqlite3_int64 szBuf, /* Total size of buffer pData[] */
768 unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */
769){
770 MemFile *p;
771 char *zSql;
772 sqlite3_stmt *pStmt = 0;
773 int rc;
774 int iDb;
775
mistachkin6630f942018-03-08 19:56:52 +0000776#ifdef SQLITE_ENABLE_API_ARMOR
777 if( !sqlite3SafetyCheckOk(db) ){
778 return SQLITE_MISUSE_BKPT;
779 }
780 if( szDb<0 ) return SQLITE_MISUSE_BKPT;
781 if( szBuf<0 ) return SQLITE_MISUSE_BKPT;
782#endif
783
drh3ec86652018-01-03 19:03:31 +0000784 sqlite3_mutex_enter(db->mutex);
785 if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
786 iDb = sqlite3FindDbName(db, zSchema);
787 if( iDb<0 ){
788 rc = SQLITE_ERROR;
789 goto end_deserialize;
790 }
791 zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
drh672f07c2020-10-20 14:40:53 +0000792 if( zSql==0 ){
793 rc = SQLITE_NOMEM;
794 }else{
795 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
796 sqlite3_free(zSql);
797 }
drh3ec86652018-01-03 19:03:31 +0000798 if( rc ) goto end_deserialize;
799 db->init.iDb = (u8)iDb;
800 db->init.reopenMemdb = 1;
801 rc = sqlite3_step(pStmt);
802 db->init.reopenMemdb = 0;
803 if( rc!=SQLITE_DONE ){
804 rc = SQLITE_ERROR;
805 goto end_deserialize;
806 }
807 p = memdbFromDbSchema(db, zSchema);
drh8784efa2018-03-06 20:54:27 +0000808 if( p==0 ){
809 rc = SQLITE_ERROR;
810 }else{
drh2f4d0ec2021-05-10 23:48:46 +0000811 MemStore *pStore = p->pStore;
812 pStore->aData = pData;
drhff01ee32020-10-17 22:13:16 +0000813 pData = 0;
drh2f4d0ec2021-05-10 23:48:46 +0000814 pStore->sz = szDb;
815 pStore->szAlloc = szBuf;
816 pStore->szMax = szBuf;
817 if( pStore->szMax<sqlite3GlobalConfig.mxMemdbSize ){
818 pStore->szMax = sqlite3GlobalConfig.mxMemdbSize;
drh6ca64482019-01-22 16:06:20 +0000819 }
drh2f4d0ec2021-05-10 23:48:46 +0000820 pStore->mFlags = mFlags;
drh8784efa2018-03-06 20:54:27 +0000821 rc = SQLITE_OK;
822 }
823
drh3ec86652018-01-03 19:03:31 +0000824end_deserialize:
825 sqlite3_finalize(pStmt);
drhff01ee32020-10-17 22:13:16 +0000826 if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){
827 sqlite3_free(pData);
828 }
drh3ec86652018-01-03 19:03:31 +0000829 sqlite3_mutex_leave(db->mutex);
830 return rc;
831}
832
drhac442f42018-01-03 01:28:46 +0000833/*
834** This routine is called when the extension is loaded.
835** Register the new VFS.
836*/
837int sqlite3MemdbInit(void){
drh5f9d1922018-03-06 04:01:08 +0000838 sqlite3_vfs *pLower = sqlite3_vfs_find(0);
839 int sz = pLower->szOsFile;
840 memdb_vfs.pAppData = pLower;
drhf25f8d52020-05-21 20:38:39 +0000841 /* The following conditional can only be true when compiled for
842 ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave
843 ** it in, to be safe, but it is marked as NO_TEST since there
844 ** is no way to reach it under most builds. */
845 if( sz<sizeof(MemFile) ) sz = sizeof(MemFile); /*NO_TEST*/
drh5f9d1922018-03-06 04:01:08 +0000846 memdb_vfs.szOsFile = sz;
drhac442f42018-01-03 01:28:46 +0000847 return sqlite3_vfs_register(&memdb_vfs, 0);
848}
drh8d889af2021-05-08 17:18:23 +0000849#endif /* SQLITE_OMIT_DESERIALIZE */