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