os/persistentdata/persistentstorage/sql/SQLite/journal.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sql/SQLite/journal.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,239 @@
     1.4 +/*
     1.5 +** 2007 August 22
     1.6 +**
     1.7 +** The author disclaims copyright to this source code.  In place of
     1.8 +** a legal notice, here is a blessing:
     1.9 +**
    1.10 +**    May you do good and not evil.
    1.11 +**    May you find forgiveness for yourself and forgive others.
    1.12 +**    May you share freely, never taking more than you give.
    1.13 +**
    1.14 +*************************************************************************
    1.15 +**
    1.16 +** @(#) $Id: journal.c,v 1.8 2008/05/01 18:01:47 drh Exp $
    1.17 +*/
    1.18 +
    1.19 +#ifdef SQLITE_ENABLE_ATOMIC_WRITE
    1.20 +
    1.21 +/*
    1.22 +** This file implements a special kind of sqlite3_file object used
    1.23 +** by SQLite to create journal files if the atomic-write optimization
    1.24 +** is enabled.
    1.25 +**
    1.26 +** The distinctive characteristic of this sqlite3_file is that the
    1.27 +** actual on disk file is created lazily. When the file is created,
    1.28 +** the caller specifies a buffer size for an in-memory buffer to
    1.29 +** be used to service read() and write() requests. The actual file
    1.30 +** on disk is not created or populated until either:
    1.31 +**
    1.32 +**   1) The in-memory representation grows too large for the allocated 
    1.33 +**      buffer, or
    1.34 +**   2) The xSync() method is called.
    1.35 +*/
    1.36 +
    1.37 +#include "sqliteInt.h"
    1.38 +
    1.39 +
    1.40 +/*
    1.41 +** A JournalFile object is a subclass of sqlite3_file used by
    1.42 +** as an open file handle for journal files.
    1.43 +*/
    1.44 +struct JournalFile {
    1.45 +  sqlite3_io_methods *pMethod;    /* I/O methods on journal files */
    1.46 +  int nBuf;                       /* Size of zBuf[] in bytes */
    1.47 +  char *zBuf;                     /* Space to buffer journal writes */
    1.48 +  int iSize;                      /* Amount of zBuf[] currently used */
    1.49 +  int flags;                      /* xOpen flags */
    1.50 +  sqlite3_vfs *pVfs;              /* The "real" underlying VFS */
    1.51 +  sqlite3_file *pReal;            /* The "real" underlying file descriptor */
    1.52 +  const char *zJournal;           /* Name of the journal file */
    1.53 +};
    1.54 +typedef struct JournalFile JournalFile;
    1.55 +
    1.56 +/*
    1.57 +** If it does not already exists, create and populate the on-disk file 
    1.58 +** for JournalFile p.
    1.59 +*/
    1.60 +static int createFile(JournalFile *p){
    1.61 +  int rc = SQLITE_OK;
    1.62 +  if( !p->pReal ){
    1.63 +    sqlite3_file *pReal = (sqlite3_file *)&p[1];
    1.64 +    rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0);
    1.65 +    if( rc==SQLITE_OK ){
    1.66 +      p->pReal = pReal;
    1.67 +      if( p->iSize>0 ){
    1.68 +        assert(p->iSize<=p->nBuf);
    1.69 +        rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
    1.70 +      }
    1.71 +    }
    1.72 +  }
    1.73 +  return rc;
    1.74 +}
    1.75 +
    1.76 +/*
    1.77 +** Close the file.
    1.78 +*/
    1.79 +static int jrnlClose(sqlite3_file *pJfd){
    1.80 +  JournalFile *p = (JournalFile *)pJfd;
    1.81 +  if( p->pReal ){
    1.82 +    sqlite3OsClose(p->pReal);
    1.83 +  }
    1.84 +  sqlite3_free(p->zBuf);
    1.85 +  return SQLITE_OK;
    1.86 +}
    1.87 +
    1.88 +/*
    1.89 +** Read data from the file.
    1.90 +*/
    1.91 +static int jrnlRead(
    1.92 +  sqlite3_file *pJfd,    /* The journal file from which to read */
    1.93 +  void *zBuf,            /* Put the results here */
    1.94 +  int iAmt,              /* Number of bytes to read */
    1.95 +  sqlite_int64 iOfst     /* Begin reading at this offset */
    1.96 +){
    1.97 +  int rc = SQLITE_OK;
    1.98 +  JournalFile *p = (JournalFile *)pJfd;
    1.99 +  if( p->pReal ){
   1.100 +    rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
   1.101 +  }else{
   1.102 +    assert( iAmt+iOfst<=p->iSize );
   1.103 +    memcpy(zBuf, &p->zBuf[iOfst], iAmt);
   1.104 +  }
   1.105 +  return rc;
   1.106 +}
   1.107 +
   1.108 +/*
   1.109 +** Write data to the file.
   1.110 +*/
   1.111 +static int jrnlWrite(
   1.112 +  sqlite3_file *pJfd,    /* The journal file into which to write */
   1.113 +  const void *zBuf,      /* Take data to be written from here */
   1.114 +  int iAmt,              /* Number of bytes to write */
   1.115 +  sqlite_int64 iOfst     /* Begin writing at this offset into the file */
   1.116 +){
   1.117 +  int rc = SQLITE_OK;
   1.118 +  JournalFile *p = (JournalFile *)pJfd;
   1.119 +  if( !p->pReal && (iOfst+iAmt)>p->nBuf ){
   1.120 +    rc = createFile(p);
   1.121 +  }
   1.122 +  if( rc==SQLITE_OK ){
   1.123 +    if( p->pReal ){
   1.124 +      rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
   1.125 +    }else{
   1.126 +      memcpy(&p->zBuf[iOfst], zBuf, iAmt);
   1.127 +      if( p->iSize<(iOfst+iAmt) ){
   1.128 +        p->iSize = (iOfst+iAmt);
   1.129 +      }
   1.130 +    }
   1.131 +  }
   1.132 +  return rc;
   1.133 +}
   1.134 +
   1.135 +/*
   1.136 +** Truncate the file.
   1.137 +*/
   1.138 +static int jrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
   1.139 +  int rc = SQLITE_OK;
   1.140 +  JournalFile *p = (JournalFile *)pJfd;
   1.141 +  if( p->pReal ){
   1.142 +    rc = sqlite3OsTruncate(p->pReal, size);
   1.143 +  }else if( size<p->iSize ){
   1.144 +    p->iSize = size;
   1.145 +  }
   1.146 +  return rc;
   1.147 +}
   1.148 +
   1.149 +/*
   1.150 +** Sync the file.
   1.151 +*/
   1.152 +static int jrnlSync(sqlite3_file *pJfd, int flags){
   1.153 +  int rc;
   1.154 +  JournalFile *p = (JournalFile *)pJfd;
   1.155 +  if( p->pReal ){
   1.156 +    rc = sqlite3OsSync(p->pReal, flags);
   1.157 +  }else{
   1.158 +    rc = SQLITE_OK;
   1.159 +  }
   1.160 +  return rc;
   1.161 +}
   1.162 +
   1.163 +/*
   1.164 +** Query the size of the file in bytes.
   1.165 +*/
   1.166 +static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
   1.167 +  int rc = SQLITE_OK;
   1.168 +  JournalFile *p = (JournalFile *)pJfd;
   1.169 +  if( p->pReal ){
   1.170 +    rc = sqlite3OsFileSize(p->pReal, pSize);
   1.171 +  }else{
   1.172 +    *pSize = (sqlite_int64) p->iSize;
   1.173 +  }
   1.174 +  return rc;
   1.175 +}
   1.176 +
   1.177 +/*
   1.178 +** Table of methods for JournalFile sqlite3_file object.
   1.179 +*/
   1.180 +static struct sqlite3_io_methods JournalFileMethods = {
   1.181 +  1,             /* iVersion */
   1.182 +  jrnlClose,     /* xClose */
   1.183 +  jrnlRead,      /* xRead */
   1.184 +  jrnlWrite,     /* xWrite */
   1.185 +  jrnlTruncate,  /* xTruncate */
   1.186 +  jrnlSync,      /* xSync */
   1.187 +  jrnlFileSize,  /* xFileSize */
   1.188 +  0,             /* xLock */
   1.189 +  0,             /* xUnlock */
   1.190 +  0,             /* xCheckReservedLock */
   1.191 +  0,             /* xFileControl */
   1.192 +  0,             /* xSectorSize */
   1.193 +  0              /* xDeviceCharacteristics */
   1.194 +};
   1.195 +
   1.196 +/* 
   1.197 +** Open a journal file.
   1.198 +*/
   1.199 +int sqlite3JournalOpen(
   1.200 +  sqlite3_vfs *pVfs,         /* The VFS to use for actual file I/O */
   1.201 +  const char *zName,         /* Name of the journal file */
   1.202 +  sqlite3_file *pJfd,        /* Preallocated, blank file handle */
   1.203 +  int flags,                 /* Opening flags */
   1.204 +  int nBuf                   /* Bytes buffered before opening the file */
   1.205 +){
   1.206 +  JournalFile *p = (JournalFile *)pJfd;
   1.207 +  memset(p, 0, sqlite3JournalSize(pVfs));
   1.208 +  if( nBuf>0 ){
   1.209 +    p->zBuf = sqlite3MallocZero(nBuf);
   1.210 +    if( !p->zBuf ){
   1.211 +      return SQLITE_NOMEM;
   1.212 +    }
   1.213 +  }else{
   1.214 +    return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
   1.215 +  }
   1.216 +  p->pMethod = &JournalFileMethods;
   1.217 +  p->nBuf = nBuf;
   1.218 +  p->flags = flags;
   1.219 +  p->zJournal = zName;
   1.220 +  p->pVfs = pVfs;
   1.221 +  return SQLITE_OK;
   1.222 +}
   1.223 +
   1.224 +/*
   1.225 +** If the argument p points to a JournalFile structure, and the underlying
   1.226 +** file has not yet been created, create it now.
   1.227 +*/
   1.228 +int sqlite3JournalCreate(sqlite3_file *p){
   1.229 +  if( p->pMethods!=&JournalFileMethods ){
   1.230 +    return SQLITE_OK;
   1.231 +  }
   1.232 +  return createFile((JournalFile *)p);
   1.233 +}
   1.234 +
   1.235 +/* 
   1.236 +** Return the number of bytes required to store a JournalFile that uses vfs
   1.237 +** pVfs to create the underlying on-disk files.
   1.238 +*/
   1.239 +int sqlite3JournalSize(sqlite3_vfs *pVfs){
   1.240 +  return (pVfs->szOsFile+sizeof(JournalFile));
   1.241 +}
   1.242 +#endif