1.1 --- a/extensions/sqlite/sqlite-source/journal.c Fri Mar 28 06:21:34 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,238 +0,0 @@
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$
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 - rc = createFile(p);
1.156 - if( rc==SQLITE_OK ){
1.157 - rc = sqlite3OsSync(p->pReal, flags);
1.158 - }
1.159 - return rc;
1.160 -}
1.161 -
1.162 -/*
1.163 -** Query the size of the file in bytes.
1.164 -*/
1.165 -static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
1.166 - int rc = SQLITE_OK;
1.167 - JournalFile *p = (JournalFile *)pJfd;
1.168 - if( p->pReal ){
1.169 - rc = sqlite3OsFileSize(p->pReal, pSize);
1.170 - }else{
1.171 - *pSize = (sqlite_int64) p->iSize;
1.172 - }
1.173 - return rc;
1.174 -}
1.175 -
1.176 -/*
1.177 -** Table of methods for JournalFile sqlite3_file object.
1.178 -*/
1.179 -static struct sqlite3_io_methods JournalFileMethods = {
1.180 - 1, /* iVersion */
1.181 - jrnlClose, /* xClose */
1.182 - jrnlRead, /* xRead */
1.183 - jrnlWrite, /* xWrite */
1.184 - jrnlTruncate, /* xTruncate */
1.185 - jrnlSync, /* xSync */
1.186 - jrnlFileSize, /* xFileSize */
1.187 - 0, /* xLock */
1.188 - 0, /* xUnlock */
1.189 - 0, /* xCheckReservedLock */
1.190 - 0, /* xFileControl */
1.191 - 0, /* xSectorSize */
1.192 - 0 /* xDeviceCharacteristics */
1.193 -};
1.194 -
1.195 -/*
1.196 -** Open a journal file.
1.197 -*/
1.198 -int sqlite3JournalOpen(
1.199 - sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */
1.200 - const char *zName, /* Name of the journal file */
1.201 - sqlite3_file *pJfd, /* Preallocated, blank file handle */
1.202 - int flags, /* Opening flags */
1.203 - int nBuf /* Bytes buffered before opening the file */
1.204 -){
1.205 - JournalFile *p = (JournalFile *)pJfd;
1.206 - memset(p, 0, sqlite3JournalSize(pVfs));
1.207 - if( nBuf>0 ){
1.208 - p->zBuf = sqlite3MallocZero(nBuf);
1.209 - if( !p->zBuf ){
1.210 - return SQLITE_NOMEM;
1.211 - }
1.212 - }else{
1.213 - return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
1.214 - }
1.215 - p->pMethod = &JournalFileMethods;
1.216 - p->nBuf = nBuf;
1.217 - p->flags = flags;
1.218 - p->zJournal = zName;
1.219 - p->pVfs = pVfs;
1.220 - return SQLITE_OK;
1.221 -}
1.222 -
1.223 -/*
1.224 -** If the argument p points to a JournalFile structure, and the underlying
1.225 -** file has not yet been created, create it now.
1.226 -*/
1.227 -int sqlite3JournalCreate(sqlite3_file *p){
1.228 - if( p->pMethods!=&JournalFileMethods ){
1.229 - return SQLITE_OK;
1.230 - }
1.231 - return createFile((JournalFile *)p);
1.232 -}
1.233 -
1.234 -/*
1.235 -** Return the number of bytes required to store a JournalFile that uses vfs
1.236 -** pVfs to create the underlying on-disk files.
1.237 -*/
1.238 -int sqlite3JournalSize(sqlite3_vfs *pVfs){
1.239 - return (pVfs->szOsFile+sizeof(JournalFile));
1.240 -}
1.241 -#endif