modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/misc/memvfs.c (about)

     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 is an in-memory read-only VFS implementation.  The application
    14  ** supplies a block of memory which is the database file, and this VFS
    15  ** uses that block of memory.
    16  **
    17  ** Because there is no place to store journals and no good way to lock
    18  ** the "file", this VFS is read-only.
    19  **
    20  ** USAGE:
    21  **
    22  **    sqlite3_open_v2("file:/whatever?ptr=0xf05538&sz=14336", &db,
    23  **                    SQLITE_OPEN_READONLY | SQLITE_OPEN_URI,
    24  **                    "memvfs");
    25  **
    26  ** The ptr= and sz= query parameters are required or the open will fail.
    27  ** The ptr= parameter gives the memory address of the buffer holding the
    28  ** read-only database and sz= gives the size of the database.  The parameter
    29  ** values may be in hexadecimal or decimal.  The filename is ignored.
    30  */
    31  #include <sqlite3ext.h>
    32  SQLITE_EXTENSION_INIT1
    33  #include <string.h>
    34  #include <assert.h>
    35  
    36  
    37  /*
    38  ** Forward declaration of objects used by this utility
    39  */
    40  typedef struct sqlite3_vfs MemVfs;
    41  typedef struct MemFile MemFile;
    42  
    43  /* Access to a lower-level VFS that (might) implement dynamic loading,
    44  ** access to randomness, etc.
    45  */
    46  #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
    47  
    48  /* An open file */
    49  struct MemFile {
    50    sqlite3_file base;              /* IO methods */
    51    sqlite3_int64 sz;               /* Size of the file */
    52    unsigned char *aData;           /* content of the file */
    53  };
    54  
    55  /*
    56  ** Methods for MemFile
    57  */
    58  static int memClose(sqlite3_file*);
    59  static int memRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
    60  static int memWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
    61  static int memTruncate(sqlite3_file*, sqlite3_int64 size);
    62  static int memSync(sqlite3_file*, int flags);
    63  static int memFileSize(sqlite3_file*, sqlite3_int64 *pSize);
    64  static int memLock(sqlite3_file*, int);
    65  static int memUnlock(sqlite3_file*, int);
    66  static int memCheckReservedLock(sqlite3_file*, int *pResOut);
    67  static int memFileControl(sqlite3_file*, int op, void *pArg);
    68  static int memSectorSize(sqlite3_file*);
    69  static int memDeviceCharacteristics(sqlite3_file*);
    70  static int memShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
    71  static int memShmLock(sqlite3_file*, int offset, int n, int flags);
    72  static void memShmBarrier(sqlite3_file*);
    73  static int memShmUnmap(sqlite3_file*, int deleteFlag);
    74  static int memFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
    75  static int memUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
    76  
    77  /*
    78  ** Methods for MemVfs
    79  */
    80  static int memOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
    81  static int memDelete(sqlite3_vfs*, const char *zName, int syncDir);
    82  static int memAccess(sqlite3_vfs*, const char *zName, int flags, int *);
    83  static int memFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
    84  static void *memDlOpen(sqlite3_vfs*, const char *zFilename);
    85  static void memDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
    86  static void (*memDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
    87  static void memDlClose(sqlite3_vfs*, void*);
    88  static int memRandomness(sqlite3_vfs*, int nByte, char *zOut);
    89  static int memSleep(sqlite3_vfs*, int microseconds);
    90  static int memCurrentTime(sqlite3_vfs*, double*);
    91  static int memGetLastError(sqlite3_vfs*, int, char *);
    92  static int memCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
    93  
    94  static sqlite3_vfs mem_vfs = {
    95    2,                           /* iVersion */
    96    0,                           /* szOsFile (set when registered) */
    97    1024,                        /* mxPathname */
    98    0,                           /* pNext */
    99    "memvfs",                    /* zName */
   100    0,                           /* pAppData (set when registered) */ 
   101    memOpen,                     /* xOpen */
   102    memDelete,                   /* xDelete */
   103    memAccess,                   /* xAccess */
   104    memFullPathname,             /* xFullPathname */
   105    memDlOpen,                   /* xDlOpen */
   106    memDlError,                  /* xDlError */
   107    memDlSym,                    /* xDlSym */
   108    memDlClose,                  /* xDlClose */
   109    memRandomness,               /* xRandomness */
   110    memSleep,                    /* xSleep */
   111    memCurrentTime,              /* xCurrentTime */
   112    memGetLastError,             /* xGetLastError */
   113    memCurrentTimeInt64          /* xCurrentTimeInt64 */
   114  };
   115  
   116  static const sqlite3_io_methods mem_io_methods = {
   117    3,                              /* iVersion */
   118    memClose,                      /* xClose */
   119    memRead,                       /* xRead */
   120    memWrite,                      /* xWrite */
   121    memTruncate,                   /* xTruncate */
   122    memSync,                       /* xSync */
   123    memFileSize,                   /* xFileSize */
   124    memLock,                       /* xLock */
   125    memUnlock,                     /* xUnlock */
   126    memCheckReservedLock,          /* xCheckReservedLock */
   127    memFileControl,                /* xFileControl */
   128    memSectorSize,                 /* xSectorSize */
   129    memDeviceCharacteristics,      /* xDeviceCharacteristics */
   130    memShmMap,                     /* xShmMap */
   131    memShmLock,                    /* xShmLock */
   132    memShmBarrier,                 /* xShmBarrier */
   133    memShmUnmap,                   /* xShmUnmap */
   134    memFetch,                      /* xFetch */
   135    memUnfetch                     /* xUnfetch */
   136  };
   137  
   138  
   139  
   140  /*
   141  ** Close an mem-file.
   142  **
   143  ** The pData pointer is owned by the application, so there is nothing
   144  ** to free.
   145  */
   146  static int memClose(sqlite3_file *pFile){
   147    return SQLITE_OK;
   148  }
   149  
   150  /*
   151  ** Read data from an mem-file.
   152  */
   153  static int memRead(
   154    sqlite3_file *pFile, 
   155    void *zBuf, 
   156    int iAmt, 
   157    sqlite_int64 iOfst
   158  ){
   159    MemFile *p = (MemFile *)pFile;
   160    memcpy(zBuf, p->aData+iOfst, iAmt);
   161    return SQLITE_OK;
   162  }
   163  
   164  /*
   165  ** Write data to an mem-file.
   166  */
   167  static int memWrite(
   168    sqlite3_file *pFile,
   169    const void *z,
   170    int iAmt,
   171    sqlite_int64 iOfst
   172  ){
   173    return SQLITE_READONLY;
   174  }
   175  
   176  /*
   177  ** Truncate an mem-file.
   178  */
   179  static int memTruncate(sqlite3_file *pFile, sqlite_int64 size){
   180    return SQLITE_READONLY;
   181  }
   182  
   183  /*
   184  ** Sync an mem-file.
   185  */
   186  static int memSync(sqlite3_file *pFile, int flags){
   187    return SQLITE_READONLY;
   188  }
   189  
   190  /*
   191  ** Return the current file-size of an mem-file.
   192  */
   193  static int memFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
   194    MemFile *p = (MemFile *)pFile;
   195    *pSize = p->sz;
   196    return SQLITE_OK;
   197  }
   198  
   199  /*
   200  ** Lock an mem-file.
   201  */
   202  static int memLock(sqlite3_file *pFile, int eLock){
   203    return SQLITE_READONLY;
   204  }
   205  
   206  /*
   207  ** Unlock an mem-file.
   208  */
   209  static int memUnlock(sqlite3_file *pFile, int eLock){
   210    return SQLITE_OK;
   211  }
   212  
   213  /*
   214  ** Check if another file-handle holds a RESERVED lock on an mem-file.
   215  */
   216  static int memCheckReservedLock(sqlite3_file *pFile, int *pResOut){
   217    *pResOut = 0;
   218    return SQLITE_OK;
   219  }
   220  
   221  /*
   222  ** File control method. For custom operations on an mem-file.
   223  */
   224  static int memFileControl(sqlite3_file *pFile, int op, void *pArg){
   225    MemFile *p = (MemFile *)pFile;
   226    int rc = SQLITE_NOTFOUND;
   227    if( op==SQLITE_FCNTL_VFSNAME ){
   228      *(char**)pArg = sqlite3_mprintf("mem(%p,%lld)", p->aData, p->sz);
   229      rc = SQLITE_OK;
   230    }
   231    return rc;
   232  }
   233  
   234  /*
   235  ** Return the sector-size in bytes for an mem-file.
   236  */
   237  static int memSectorSize(sqlite3_file *pFile){
   238    return 1024;
   239  }
   240  
   241  /*
   242  ** Return the device characteristic flags supported by an mem-file.
   243  */
   244  static int memDeviceCharacteristics(sqlite3_file *pFile){
   245    return SQLITE_IOCAP_IMMUTABLE;
   246  }
   247  
   248  /* Create a shared memory file mapping */
   249  static int memShmMap(
   250    sqlite3_file *pFile,
   251    int iPg,
   252    int pgsz,
   253    int bExtend,
   254    void volatile **pp
   255  ){
   256    return SQLITE_READONLY;
   257  }
   258  
   259  /* Perform locking on a shared-memory segment */
   260  static int memShmLock(sqlite3_file *pFile, int offset, int n, int flags){
   261    return SQLITE_READONLY;
   262  }
   263  
   264  /* Memory barrier operation on shared memory */
   265  static void memShmBarrier(sqlite3_file *pFile){
   266    return;
   267  }
   268  
   269  /* Unmap a shared memory segment */
   270  static int memShmUnmap(sqlite3_file *pFile, int deleteFlag){
   271    return SQLITE_OK;
   272  }
   273  
   274  /* Fetch a page of a memory-mapped file */
   275  static int memFetch(
   276    sqlite3_file *pFile,
   277    sqlite3_int64 iOfst,
   278    int iAmt,
   279    void **pp
   280  ){
   281    MemFile *p = (MemFile *)pFile;
   282    *pp = (void*)(p->aData + iOfst);
   283    return SQLITE_OK;
   284  }
   285  
   286  /* Release a memory-mapped page */
   287  static int memUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
   288    return SQLITE_OK;
   289  }
   290  
   291  /*
   292  ** Open an mem file handle.
   293  */
   294  static int memOpen(
   295    sqlite3_vfs *pVfs,
   296    const char *zName,
   297    sqlite3_file *pFile,
   298    int flags,
   299    int *pOutFlags
   300  ){
   301    MemFile *p = (MemFile*)pFile;
   302    memset(p, 0, sizeof(*p));
   303    if( (flags & SQLITE_OPEN_MAIN_DB)==0 ) return SQLITE_CANTOPEN;
   304    p->aData = (unsigned char*)sqlite3_uri_int64(zName,"ptr",0);
   305    if( p->aData==0 ) return SQLITE_CANTOPEN;
   306    p->sz = sqlite3_uri_int64(zName,"sz",0);
   307    if( p->sz<0 ) return SQLITE_CANTOPEN;
   308    pFile->pMethods = &mem_io_methods;
   309    return SQLITE_OK;
   310  }
   311  
   312  /*
   313  ** Delete the file located at zPath. If the dirSync argument is true,
   314  ** ensure the file-system modifications are synced to disk before
   315  ** returning.
   316  */
   317  static int memDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
   318    return SQLITE_READONLY;
   319  }
   320  
   321  /*
   322  ** Test for access permissions. Return true if the requested permission
   323  ** is available, or false otherwise.
   324  */
   325  static int memAccess(
   326    sqlite3_vfs *pVfs, 
   327    const char *zPath, 
   328    int flags, 
   329    int *pResOut
   330  ){
   331    /* The spec says there are three possible values for flags.  But only
   332    ** two of them are actually used */
   333    assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE );
   334    if( flags==SQLITE_ACCESS_READWRITE ){
   335      *pResOut = 0;
   336    }else{
   337      *pResOut = 1;
   338    }
   339    return SQLITE_OK;
   340  }
   341  
   342  /*
   343  ** Populate buffer zOut with the full canonical pathname corresponding
   344  ** to the pathname in zPath. zOut is guaranteed to point to a buffer
   345  ** of at least (INST_MAX_PATHNAME+1) bytes.
   346  */
   347  static int memFullPathname(
   348    sqlite3_vfs *pVfs, 
   349    const char *zPath, 
   350    int nOut, 
   351    char *zOut
   352  ){
   353    sqlite3_snprintf(nOut, zOut, "%s", zPath);
   354    return SQLITE_OK;
   355  }
   356  
   357  /*
   358  ** Open the dynamic library located at zPath and return a handle.
   359  */
   360  static void *memDlOpen(sqlite3_vfs *pVfs, const char *zPath){
   361    return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
   362  }
   363  
   364  /*
   365  ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
   366  ** utf-8 string describing the most recent error encountered associated 
   367  ** with dynamic libraries.
   368  */
   369  static void memDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
   370    ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
   371  }
   372  
   373  /*
   374  ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
   375  */
   376  static void (*memDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
   377    return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
   378  }
   379  
   380  /*
   381  ** Close the dynamic library handle pHandle.
   382  */
   383  static void memDlClose(sqlite3_vfs *pVfs, void *pHandle){
   384    ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
   385  }
   386  
   387  /*
   388  ** Populate the buffer pointed to by zBufOut with nByte bytes of 
   389  ** random data.
   390  */
   391  static int memRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
   392    return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
   393  }
   394  
   395  /*
   396  ** Sleep for nMicro microseconds. Return the number of microseconds 
   397  ** actually slept.
   398  */
   399  static int memSleep(sqlite3_vfs *pVfs, int nMicro){
   400    return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
   401  }
   402  
   403  /*
   404  ** Return the current time as a Julian Day number in *pTimeOut.
   405  */
   406  static int memCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
   407    return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
   408  }
   409  
   410  static int memGetLastError(sqlite3_vfs *pVfs, int a, char *b){
   411    return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
   412  }
   413  static int memCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
   414    return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
   415  }
   416  
   417  #ifdef MEMVFS_TEST
   418  /*
   419  **       memload(FILENAME)
   420  **
   421  ** This an SQL function used to help in testing the memvfs VFS.  The
   422  ** function reads the content of a file into memory and then returns
   423  ** a string that gives the locate and size of the in-memory buffer.
   424  */
   425  #include <stdio.h>
   426  static void memvfsMemloadFunc(
   427    sqlite3_context *context,
   428    int argc,
   429    sqlite3_value **argv
   430  ){
   431    unsigned char *p;
   432    sqlite3_int64 sz;
   433    FILE *in;
   434    const char *zFilename = (const char*)sqlite3_value_text(argv[0]);
   435    char zReturn[100];
   436  
   437    if( zFilename==0 ) return;
   438    in = fopen(zFilename, "rb");
   439    if( in==0 ) return;
   440    fseek(in, 0, SEEK_END);
   441    sz = ftell(in);
   442    rewind(in);
   443    p = sqlite3_malloc( sz );
   444    if( p==0 ){
   445      fclose(in);
   446      sqlite3_result_error_nomem(context);
   447      return;
   448    }
   449    fread(p, sz, 1, in);
   450    fclose(in);
   451    sqlite3_snprintf(sizeof(zReturn),zReturn,"ptr=%lld&sz=%lld",
   452                     (sqlite3_int64)p, sz);
   453    sqlite3_result_text(context, zReturn, -1, SQLITE_TRANSIENT);
   454  }
   455  /* Called for each new database connection */
   456  static int memvfsRegister(
   457    sqlite3 *db,
   458    const char **pzErrMsg,
   459    const struct sqlite3_api_routines *pThunk
   460  ){
   461    return sqlite3_create_function(db, "memload", 1, SQLITE_UTF8, 0,
   462                                   memvfsMemloadFunc, 0, 0);
   463  }
   464  #endif /* MEMVFS_TEST */
   465  
   466    
   467  #ifdef _WIN32
   468  __declspec(dllexport)
   469  #endif
   470  /* 
   471  ** This routine is called when the extension is loaded.
   472  ** Register the new VFS.
   473  */
   474  int sqlite3_memvfs_init(
   475    sqlite3 *db, 
   476    char **pzErrMsg, 
   477    const sqlite3_api_routines *pApi
   478  ){
   479    int rc = SQLITE_OK;
   480    SQLITE_EXTENSION_INIT2(pApi);
   481    mem_vfs.pAppData = sqlite3_vfs_find(0);
   482    mem_vfs.szOsFile = sizeof(MemFile);
   483    rc = sqlite3_vfs_register(&mem_vfs, 1);
   484  #ifdef MEMVFS_TEST
   485    if( rc==SQLITE_OK ){
   486      rc = sqlite3_auto_extension((void(*)(void))memvfsRegister);
   487    }
   488  #endif
   489    if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
   490    return rc;
   491  }