File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sqlite3 / src / journal.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:04:17 2012 UTC (12 years, 8 months ago) by misho
Branches: sqlite3, MAIN
CVS tags: v3_7_10, HEAD
sqlite3

    1: /*
    2: ** 2007 August 22
    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 a special kind of sqlite3_file object used
   14: ** by SQLite to create journal files if the atomic-write optimization
   15: ** is enabled.
   16: **
   17: ** The distinctive characteristic of this sqlite3_file is that the
   18: ** actual on disk file is created lazily. When the file is created,
   19: ** the caller specifies a buffer size for an in-memory buffer to
   20: ** be used to service read() and write() requests. The actual file
   21: ** on disk is not created or populated until either:
   22: **
   23: **   1) The in-memory representation grows too large for the allocated 
   24: **      buffer, or
   25: **   2) The sqlite3JournalCreate() function is called.
   26: */
   27: #ifdef SQLITE_ENABLE_ATOMIC_WRITE
   28: #include "sqliteInt.h"
   29: 
   30: 
   31: /*
   32: ** A JournalFile object is a subclass of sqlite3_file used by
   33: ** as an open file handle for journal files.
   34: */
   35: struct JournalFile {
   36:   sqlite3_io_methods *pMethod;    /* I/O methods on journal files */
   37:   int nBuf;                       /* Size of zBuf[] in bytes */
   38:   char *zBuf;                     /* Space to buffer journal writes */
   39:   int iSize;                      /* Amount of zBuf[] currently used */
   40:   int flags;                      /* xOpen flags */
   41:   sqlite3_vfs *pVfs;              /* The "real" underlying VFS */
   42:   sqlite3_file *pReal;            /* The "real" underlying file descriptor */
   43:   const char *zJournal;           /* Name of the journal file */
   44: };
   45: typedef struct JournalFile JournalFile;
   46: 
   47: /*
   48: ** If it does not already exists, create and populate the on-disk file 
   49: ** for JournalFile p.
   50: */
   51: static int createFile(JournalFile *p){
   52:   int rc = SQLITE_OK;
   53:   if( !p->pReal ){
   54:     sqlite3_file *pReal = (sqlite3_file *)&p[1];
   55:     rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0);
   56:     if( rc==SQLITE_OK ){
   57:       p->pReal = pReal;
   58:       if( p->iSize>0 ){
   59:         assert(p->iSize<=p->nBuf);
   60:         rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
   61:       }
   62:     }
   63:   }
   64:   return rc;
   65: }
   66: 
   67: /*
   68: ** Close the file.
   69: */
   70: static int jrnlClose(sqlite3_file *pJfd){
   71:   JournalFile *p = (JournalFile *)pJfd;
   72:   if( p->pReal ){
   73:     sqlite3OsClose(p->pReal);
   74:   }
   75:   sqlite3_free(p->zBuf);
   76:   return SQLITE_OK;
   77: }
   78: 
   79: /*
   80: ** Read data from the file.
   81: */
   82: static int jrnlRead(
   83:   sqlite3_file *pJfd,    /* The journal file from which to read */
   84:   void *zBuf,            /* Put the results here */
   85:   int iAmt,              /* Number of bytes to read */
   86:   sqlite_int64 iOfst     /* Begin reading at this offset */
   87: ){
   88:   int rc = SQLITE_OK;
   89:   JournalFile *p = (JournalFile *)pJfd;
   90:   if( p->pReal ){
   91:     rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
   92:   }else if( (iAmt+iOfst)>p->iSize ){
   93:     rc = SQLITE_IOERR_SHORT_READ;
   94:   }else{
   95:     memcpy(zBuf, &p->zBuf[iOfst], iAmt);
   96:   }
   97:   return rc;
   98: }
   99: 
  100: /*
  101: ** Write data to the file.
  102: */
  103: static int jrnlWrite(
  104:   sqlite3_file *pJfd,    /* The journal file into which to write */
  105:   const void *zBuf,      /* Take data to be written from here */
  106:   int iAmt,              /* Number of bytes to write */
  107:   sqlite_int64 iOfst     /* Begin writing at this offset into the file */
  108: ){
  109:   int rc = SQLITE_OK;
  110:   JournalFile *p = (JournalFile *)pJfd;
  111:   if( !p->pReal && (iOfst+iAmt)>p->nBuf ){
  112:     rc = createFile(p);
  113:   }
  114:   if( rc==SQLITE_OK ){
  115:     if( p->pReal ){
  116:       rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
  117:     }else{
  118:       memcpy(&p->zBuf[iOfst], zBuf, iAmt);
  119:       if( p->iSize<(iOfst+iAmt) ){
  120:         p->iSize = (iOfst+iAmt);
  121:       }
  122:     }
  123:   }
  124:   return rc;
  125: }
  126: 
  127: /*
  128: ** Truncate the file.
  129: */
  130: static int jrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
  131:   int rc = SQLITE_OK;
  132:   JournalFile *p = (JournalFile *)pJfd;
  133:   if( p->pReal ){
  134:     rc = sqlite3OsTruncate(p->pReal, size);
  135:   }else if( size<p->iSize ){
  136:     p->iSize = size;
  137:   }
  138:   return rc;
  139: }
  140: 
  141: /*
  142: ** Sync the file.
  143: */
  144: static int jrnlSync(sqlite3_file *pJfd, int flags){
  145:   int rc;
  146:   JournalFile *p = (JournalFile *)pJfd;
  147:   if( p->pReal ){
  148:     rc = sqlite3OsSync(p->pReal, flags);
  149:   }else{
  150:     rc = SQLITE_OK;
  151:   }
  152:   return rc;
  153: }
  154: 
  155: /*
  156: ** Query the size of the file in bytes.
  157: */
  158: static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
  159:   int rc = SQLITE_OK;
  160:   JournalFile *p = (JournalFile *)pJfd;
  161:   if( p->pReal ){
  162:     rc = sqlite3OsFileSize(p->pReal, pSize);
  163:   }else{
  164:     *pSize = (sqlite_int64) p->iSize;
  165:   }
  166:   return rc;
  167: }
  168: 
  169: /*
  170: ** Table of methods for JournalFile sqlite3_file object.
  171: */
  172: static struct sqlite3_io_methods JournalFileMethods = {
  173:   1,             /* iVersion */
  174:   jrnlClose,     /* xClose */
  175:   jrnlRead,      /* xRead */
  176:   jrnlWrite,     /* xWrite */
  177:   jrnlTruncate,  /* xTruncate */
  178:   jrnlSync,      /* xSync */
  179:   jrnlFileSize,  /* xFileSize */
  180:   0,             /* xLock */
  181:   0,             /* xUnlock */
  182:   0,             /* xCheckReservedLock */
  183:   0,             /* xFileControl */
  184:   0,             /* xSectorSize */
  185:   0,             /* xDeviceCharacteristics */
  186:   0,             /* xShmMap */
  187:   0,             /* xShmLock */
  188:   0,             /* xShmBarrier */
  189:   0              /* xShmUnmap */
  190: };
  191: 
  192: /* 
  193: ** Open a journal file.
  194: */
  195: int sqlite3JournalOpen(
  196:   sqlite3_vfs *pVfs,         /* The VFS to use for actual file I/O */
  197:   const char *zName,         /* Name of the journal file */
  198:   sqlite3_file *pJfd,        /* Preallocated, blank file handle */
  199:   int flags,                 /* Opening flags */
  200:   int nBuf                   /* Bytes buffered before opening the file */
  201: ){
  202:   JournalFile *p = (JournalFile *)pJfd;
  203:   memset(p, 0, sqlite3JournalSize(pVfs));
  204:   if( nBuf>0 ){
  205:     p->zBuf = sqlite3MallocZero(nBuf);
  206:     if( !p->zBuf ){
  207:       return SQLITE_NOMEM;
  208:     }
  209:   }else{
  210:     return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
  211:   }
  212:   p->pMethod = &JournalFileMethods;
  213:   p->nBuf = nBuf;
  214:   p->flags = flags;
  215:   p->zJournal = zName;
  216:   p->pVfs = pVfs;
  217:   return SQLITE_OK;
  218: }
  219: 
  220: /*
  221: ** If the argument p points to a JournalFile structure, and the underlying
  222: ** file has not yet been created, create it now.
  223: */
  224: int sqlite3JournalCreate(sqlite3_file *p){
  225:   if( p->pMethods!=&JournalFileMethods ){
  226:     return SQLITE_OK;
  227:   }
  228:   return createFile((JournalFile *)p);
  229: }
  230: 
  231: /* 
  232: ** Return the number of bytes required to store a JournalFile that uses vfs
  233: ** pVfs to create the underlying on-disk files.
  234: */
  235: int sqlite3JournalSize(sqlite3_vfs *pVfs){
  236:   return (pVfs->szOsFile+sizeof(JournalFile));
  237: }
  238: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>