journal.c
上传用户:sunhongbo
上传日期:2022-01-25
资源大小:3010k
文件大小:6k
源码类别:

数据库系统

开发平台:

C/C++

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