xref: /sqlite-3.40.0/src/memdb.c (revision fb32c44e)
1 /*
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 **
13 ** This file implements an in-memory VFS. A database is held as a contiguous
14 ** block of memory.
15 **
16 ** This file also implements interface sqlite3_serialize() and
17 ** sqlite3_deserialize().
18 */
19 #ifdef SQLITE_ENABLE_DESERIALIZE
20 #include "sqliteInt.h"
21 
22 /*
23 ** Forward declaration of objects used by this utility
24 */
25 typedef struct sqlite3_vfs MemVfs;
26 typedef struct MemFile MemFile;
27 
28 /* Access to a lower-level VFS that (might) implement dynamic loading,
29 ** access to randomness, etc.
30 */
31 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
32 
33 /* An open file */
34 struct MemFile {
35   sqlite3_file base;              /* IO methods */
36   sqlite3_int64 sz;               /* Size of the file */
37   sqlite3_int64 szMax;            /* Space allocated to aData */
38   unsigned char *aData;           /* content of the file */
39   int nMmap;                      /* Number of memory mapped pages */
40   unsigned mFlags;                /* Flags */
41   int eLock;                      /* Most recent lock against this file */
42 };
43 
44 /*
45 ** Methods for MemFile
46 */
47 static int memdbClose(sqlite3_file*);
48 static int memdbRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
49 static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
50 static int memdbTruncate(sqlite3_file*, sqlite3_int64 size);
51 static int memdbSync(sqlite3_file*, int flags);
52 static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize);
53 static int memdbLock(sqlite3_file*, int);
54 /* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */
55 static int memdbFileControl(sqlite3_file*, int op, void *pArg);
56 /* static int memdbSectorSize(sqlite3_file*); // not used */
57 static int memdbDeviceCharacteristics(sqlite3_file*);
58 static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
59 static int memdbUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
60 
61 /*
62 ** Methods for MemVfs
63 */
64 static int memdbOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
65 /* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */
66 static int memdbAccess(sqlite3_vfs*, const char *zName, int flags, int *);
67 static int memdbFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
68 static void *memdbDlOpen(sqlite3_vfs*, const char *zFilename);
69 static void memdbDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
70 static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
71 static void memdbDlClose(sqlite3_vfs*, void*);
72 static int memdbRandomness(sqlite3_vfs*, int nByte, char *zOut);
73 static int memdbSleep(sqlite3_vfs*, int microseconds);
74 /* static int memdbCurrentTime(sqlite3_vfs*, double*); */
75 static int memdbGetLastError(sqlite3_vfs*, int, char *);
76 static int memdbCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
77 
78 static sqlite3_vfs memdb_vfs = {
79   2,                           /* iVersion */
80   0,                           /* szOsFile (set when registered) */
81   1024,                        /* mxPathname */
82   0,                           /* pNext */
83   "memdb",                     /* zName */
84   0,                           /* pAppData (set when registered) */
85   memdbOpen,                   /* xOpen */
86   0, /* memdbDelete, */        /* xDelete */
87   memdbAccess,                 /* xAccess */
88   memdbFullPathname,           /* xFullPathname */
89   memdbDlOpen,                 /* xDlOpen */
90   memdbDlError,                /* xDlError */
91   memdbDlSym,                  /* xDlSym */
92   memdbDlClose,                /* xDlClose */
93   memdbRandomness,             /* xRandomness */
94   memdbSleep,                  /* xSleep */
95   0, /* memdbCurrentTime, */   /* xCurrentTime */
96   memdbGetLastError,           /* xGetLastError */
97   memdbCurrentTimeInt64        /* xCurrentTimeInt64 */
98 };
99 
100 static const sqlite3_io_methods memdb_io_methods = {
101   3,                              /* iVersion */
102   memdbClose,                      /* xClose */
103   memdbRead,                       /* xRead */
104   memdbWrite,                      /* xWrite */
105   memdbTruncate,                   /* xTruncate */
106   memdbSync,                       /* xSync */
107   memdbFileSize,                   /* xFileSize */
108   memdbLock,                       /* xLock */
109   memdbLock,                       /* xUnlock - same as xLock in this case */
110   0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */
111   memdbFileControl,                /* xFileControl */
112   0, /* memdbSectorSize,*/         /* xSectorSize */
113   memdbDeviceCharacteristics,      /* xDeviceCharacteristics */
114   0,                               /* xShmMap */
115   0,                               /* xShmLock */
116   0,                               /* xShmBarrier */
117   0,                               /* xShmUnmap */
118   memdbFetch,                      /* xFetch */
119   memdbUnfetch                     /* xUnfetch */
120 };
121 
122 
123 
124 /*
125 ** Close an memdb-file.
126 **
127 ** The pData pointer is owned by the application, so there is nothing
128 ** to free.
129 */
130 static int memdbClose(sqlite3_file *pFile){
131   MemFile *p = (MemFile *)pFile;
132   if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData);
133   return SQLITE_OK;
134 }
135 
136 /*
137 ** Read data from an memdb-file.
138 */
139 static int memdbRead(
140   sqlite3_file *pFile,
141   void *zBuf,
142   int iAmt,
143   sqlite_int64 iOfst
144 ){
145   MemFile *p = (MemFile *)pFile;
146   if( iOfst+iAmt>p->sz ){
147     memset(zBuf, 0, iAmt);
148     if( iOfst<p->sz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst);
149     return SQLITE_IOERR_SHORT_READ;
150   }
151   memcpy(zBuf, p->aData+iOfst, iAmt);
152   return SQLITE_OK;
153 }
154 
155 /*
156 ** Try to enlarge the memory allocation to hold at least sz bytes
157 */
158 static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
159   unsigned char *pNew;
160   if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
161     return SQLITE_FULL;
162   }
163   pNew = sqlite3_realloc64(p->aData, newSz);
164   if( pNew==0 ) return SQLITE_NOMEM;
165   p->aData = pNew;
166   p->szMax = newSz;
167   return SQLITE_OK;
168 }
169 
170 /*
171 ** Write data to an memdb-file.
172 */
173 static int memdbWrite(
174   sqlite3_file *pFile,
175   const void *z,
176   int iAmt,
177   sqlite_int64 iOfst
178 ){
179   MemFile *p = (MemFile *)pFile;
180   if( iOfst+iAmt>p->sz ){
181     int rc;
182     if( iOfst+iAmt>p->szMax
183      && (rc = memdbEnlarge(p, (iOfst+iAmt)*2))!=SQLITE_OK
184     ){
185       return rc;
186     }
187     if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz);
188     p->sz = iOfst+iAmt;
189   }
190   memcpy(p->aData+iOfst, z, iAmt);
191   return SQLITE_OK;
192 }
193 
194 /*
195 ** Truncate an memdb-file.
196 **
197 ** In rollback mode (which is always the case for memdb, as it does not
198 ** support WAL mode) the truncate() method is only used to reduce
199 ** the size of a file, never to increase the size.
200 */
201 static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
202   MemFile *p = (MemFile *)pFile;
203   if( NEVER(size>p->sz) ) return SQLITE_FULL;
204   p->sz = size;
205   return SQLITE_OK;
206 }
207 
208 /*
209 ** Sync an memdb-file.
210 */
211 static int memdbSync(sqlite3_file *pFile, int flags){
212   return SQLITE_OK;
213 }
214 
215 /*
216 ** Return the current file-size of an memdb-file.
217 */
218 static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
219   MemFile *p = (MemFile *)pFile;
220   *pSize = p->sz;
221   return SQLITE_OK;
222 }
223 
224 /*
225 ** Lock an memdb-file.
226 */
227 static int memdbLock(sqlite3_file *pFile, int eLock){
228   MemFile *p = (MemFile *)pFile;
229   p->eLock = eLock;
230   return SQLITE_OK;
231 }
232 
233 #if 0 /* Never used because memdbAccess() always returns false */
234 /*
235 ** Check if another file-handle holds a RESERVED lock on an memdb-file.
236 */
237 static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
238   *pResOut = 0;
239   return SQLITE_OK;
240 }
241 #endif
242 
243 /*
244 ** File control method. For custom operations on an memdb-file.
245 */
246 static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
247   MemFile *p = (MemFile *)pFile;
248   int rc = SQLITE_NOTFOUND;
249   if( op==SQLITE_FCNTL_VFSNAME ){
250     *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
251     rc = SQLITE_OK;
252   }
253   return rc;
254 }
255 
256 #if 0  /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */
257 /*
258 ** Return the sector-size in bytes for an memdb-file.
259 */
260 static int memdbSectorSize(sqlite3_file *pFile){
261   return 1024;
262 }
263 #endif
264 
265 /*
266 ** Return the device characteristic flags supported by an memdb-file.
267 */
268 static int memdbDeviceCharacteristics(sqlite3_file *pFile){
269   return SQLITE_IOCAP_ATOMIC |
270          SQLITE_IOCAP_POWERSAFE_OVERWRITE |
271          SQLITE_IOCAP_SAFE_APPEND |
272          SQLITE_IOCAP_SEQUENTIAL;
273 }
274 
275 /* Fetch a page of a memory-mapped file */
276 static int memdbFetch(
277   sqlite3_file *pFile,
278   sqlite3_int64 iOfst,
279   int iAmt,
280   void **pp
281 ){
282   MemFile *p = (MemFile *)pFile;
283   p->nMmap++;
284   *pp = (void*)(p->aData + iOfst);
285   return SQLITE_OK;
286 }
287 
288 /* Release a memory-mapped page */
289 static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
290   MemFile *p = (MemFile *)pFile;
291   p->nMmap--;
292   return SQLITE_OK;
293 }
294 
295 /*
296 ** Open an mem file handle.
297 */
298 static int memdbOpen(
299   sqlite3_vfs *pVfs,
300   const char *zName,
301   sqlite3_file *pFile,
302   int flags,
303   int *pOutFlags
304 ){
305   MemFile *p = (MemFile*)pFile;
306   if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
307     return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFile, flags, pOutFlags);
308   }
309   memset(p, 0, sizeof(*p));
310   p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
311   assert( pOutFlags!=0 );  /* True because flags==SQLITE_OPEN_MAIN_DB */
312   *pOutFlags = flags | SQLITE_OPEN_MEMORY;
313   p->base.pMethods = &memdb_io_methods;
314   return SQLITE_OK;
315 }
316 
317 #if 0 /* Only used to delete rollback journals, master journals, and WAL
318       ** files, none of which exist in memdb.  So this routine is never used */
319 /*
320 ** Delete the file located at zPath. If the dirSync argument is true,
321 ** ensure the file-system modifications are synced to disk before
322 ** returning.
323 */
324 static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
325   return SQLITE_IOERR_DELETE;
326 }
327 #endif
328 
329 /*
330 ** Test for access permissions. Return true if the requested permission
331 ** is available, or false otherwise.
332 **
333 ** With memdb, no files ever exist on disk.  So always return false.
334 */
335 static int memdbAccess(
336   sqlite3_vfs *pVfs,
337   const char *zPath,
338   int flags,
339   int *pResOut
340 ){
341   *pResOut = 0;
342   return SQLITE_OK;
343 }
344 
345 /*
346 ** Populate buffer zOut with the full canonical pathname corresponding
347 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
348 ** of at least (INST_MAX_PATHNAME+1) bytes.
349 */
350 static int memdbFullPathname(
351   sqlite3_vfs *pVfs,
352   const char *zPath,
353   int nOut,
354   char *zOut
355 ){
356   sqlite3_snprintf(nOut, zOut, "%s", zPath);
357   return SQLITE_OK;
358 }
359 
360 /*
361 ** Open the dynamic library located at zPath and return a handle.
362 */
363 static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){
364   return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
365 }
366 
367 /*
368 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
369 ** utf-8 string describing the most recent error encountered associated
370 ** with dynamic libraries.
371 */
372 static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
373   ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
374 }
375 
376 /*
377 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
378 */
379 static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
380   return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
381 }
382 
383 /*
384 ** Close the dynamic library handle pHandle.
385 */
386 static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){
387   ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
388 }
389 
390 /*
391 ** Populate the buffer pointed to by zBufOut with nByte bytes of
392 ** random data.
393 */
394 static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
395   return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
396 }
397 
398 /*
399 ** Sleep for nMicro microseconds. Return the number of microseconds
400 ** actually slept.
401 */
402 static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){
403   return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
404 }
405 
406 #if 0  /* Never used.  Modern cores only call xCurrentTimeInt64() */
407 /*
408 ** Return the current time as a Julian Day number in *pTimeOut.
409 */
410 static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
411   return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
412 }
413 #endif
414 
415 static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){
416   return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
417 }
418 static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
419   return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
420 }
421 
422 /*
423 ** Translate a database connection pointer and schema name into a
424 ** MemFile pointer.
425 */
426 static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
427   MemFile *p = 0;
428   int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p);
429   if( rc ) return 0;
430   if( p->base.pMethods!=&memdb_io_methods ) return 0;
431   return p;
432 }
433 
434 /*
435 ** Return the serialization of a database
436 */
437 unsigned char *sqlite3_serialize(
438   sqlite3 *db,              /* The database connection */
439   const char *zSchema,      /* Which database within the connection */
440   sqlite3_int64 *piSize,    /* Write size here, if not NULL */
441   unsigned int mFlags       /* Maybe SQLITE_SERIALIZE_NOCOPY */
442 ){
443   MemFile *p;
444   int iDb;
445   Btree *pBt;
446   sqlite3_int64 sz;
447   int szPage = 0;
448   sqlite3_stmt *pStmt = 0;
449   unsigned char *pOut;
450   char *zSql;
451   int rc;
452 
453 #ifdef SQLITE_ENABLE_API_ARMOR
454   if( !sqlite3SafetyCheckOk(db) ){
455     (void)SQLITE_MISUSE_BKPT;
456     return 0;
457   }
458 #endif
459 
460   if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
461   p = memdbFromDbSchema(db, zSchema);
462   iDb = sqlite3FindDbName(db, zSchema);
463   if( piSize ) *piSize = -1;
464   if( iDb<0 ) return 0;
465   if( p ){
466     if( piSize ) *piSize = p->sz;
467     if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
468       pOut = p->aData;
469     }else{
470       pOut = sqlite3_malloc64( p->sz );
471       if( pOut ) memcpy(pOut, p->aData, p->sz);
472     }
473     return pOut;
474   }
475   pBt = db->aDb[iDb].pBt;
476   if( pBt==0 ) return 0;
477   szPage = sqlite3BtreeGetPageSize(pBt);
478   zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema);
479   rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM;
480   sqlite3_free(zSql);
481   if( rc ) return 0;
482   rc = sqlite3_step(pStmt);
483   if( rc!=SQLITE_ROW ){
484     pOut = 0;
485   }else{
486     sz = sqlite3_column_int64(pStmt, 0)*szPage;
487     if( piSize ) *piSize = sz;
488     if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
489       pOut = 0;
490     }else{
491       pOut = sqlite3_malloc64( sz );
492       if( pOut ){
493         int nPage = sqlite3_column_int(pStmt, 0);
494         Pager *pPager = sqlite3BtreePager(pBt);
495         int pgno;
496         for(pgno=1; pgno<=nPage; pgno++){
497           DbPage *pPage = 0;
498           unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1);
499           rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0);
500           if( rc==SQLITE_OK ){
501             memcpy(pTo, sqlite3PagerGetData(pPage), szPage);
502           }else{
503             memset(pTo, 0, szPage);
504           }
505           sqlite3PagerUnref(pPage);
506         }
507       }
508     }
509   }
510   sqlite3_finalize(pStmt);
511   return pOut;
512 }
513 
514 /* Convert zSchema to a MemDB and initialize its content.
515 */
516 int sqlite3_deserialize(
517   sqlite3 *db,            /* The database connection */
518   const char *zSchema,    /* Which DB to reopen with the deserialization */
519   unsigned char *pData,   /* The serialized database content */
520   sqlite3_int64 szDb,     /* Number bytes in the deserialization */
521   sqlite3_int64 szBuf,    /* Total size of buffer pData[] */
522   unsigned mFlags         /* Zero or more SQLITE_DESERIALIZE_* flags */
523 ){
524   MemFile *p;
525   char *zSql;
526   sqlite3_stmt *pStmt = 0;
527   int rc;
528   int iDb;
529 
530 #ifdef SQLITE_ENABLE_API_ARMOR
531   if( !sqlite3SafetyCheckOk(db) ){
532     return SQLITE_MISUSE_BKPT;
533   }
534   if( szDb<0 ) return SQLITE_MISUSE_BKPT;
535   if( szBuf<0 ) return SQLITE_MISUSE_BKPT;
536 #endif
537 
538   sqlite3_mutex_enter(db->mutex);
539   if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
540   iDb = sqlite3FindDbName(db, zSchema);
541   if( iDb<0 ){
542     rc = SQLITE_ERROR;
543     goto end_deserialize;
544   }
545   zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
546   rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
547   sqlite3_free(zSql);
548   if( rc ) goto end_deserialize;
549   db->init.iDb = (u8)iDb;
550   db->init.reopenMemdb = 1;
551   rc = sqlite3_step(pStmt);
552   db->init.reopenMemdb = 0;
553   if( rc!=SQLITE_DONE ){
554     rc = SQLITE_ERROR;
555     goto end_deserialize;
556   }
557   p = memdbFromDbSchema(db, zSchema);
558   if( p==0 ){
559     rc = SQLITE_ERROR;
560   }else{
561     p->aData = pData;
562     p->sz = szDb;
563     p->szMax = szBuf;
564     p->mFlags = mFlags;
565     rc = SQLITE_OK;
566   }
567 
568 end_deserialize:
569   sqlite3_finalize(pStmt);
570   sqlite3_mutex_leave(db->mutex);
571   return rc;
572 }
573 
574 /*
575 ** This routine is called when the extension is loaded.
576 ** Register the new VFS.
577 */
578 int sqlite3MemdbInit(void){
579   sqlite3_vfs *pLower = sqlite3_vfs_find(0);
580   int sz = pLower->szOsFile;
581   memdb_vfs.pAppData = pLower;
582   /* In all known configurations of SQLite, the size of a default
583   ** sqlite3_file is greater than the size of a memdb sqlite3_file.
584   ** Should that ever change, remove the following NEVER() */
585   if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile);
586   memdb_vfs.szOsFile = sz;
587   return sqlite3_vfs_register(&memdb_vfs, 0);
588 }
589 #endif /* SQLITE_ENABLE_DESERIALIZE */
590