aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/sqlite/win32/journal.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/sqlite/win32/journal.c')
-rwxr-xr-xlibraries/sqlite/win32/journal.c238
1 files changed, 238 insertions, 0 deletions
diff --git a/libraries/sqlite/win32/journal.c b/libraries/sqlite/win32/journal.c
new file mode 100755
index 0000000..7cbe5bc
--- /dev/null
+++ b/libraries/sqlite/win32/journal.c
@@ -0,0 +1,238 @@
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
16#ifdef SQLITE_ENABLE_ATOMIC_WRITE
17
18/*
19** This file implements a special kind of sqlite3_file object used
20** by SQLite to create journal files if the atomic-write optimization
21** is enabled.
22**
23** The distinctive characteristic of this sqlite3_file is that the
24** actual on disk file is created lazily. When the file is created,
25** the caller specifies a buffer size for an in-memory buffer to
26** be used to service read() and write() requests. The actual file
27** on disk is not created or populated until either:
28**
29** 1) The in-memory representation grows too large for the allocated
30** buffer, or
31** 2) The xSync() method is called.
32*/
33
34#include "sqliteInt.h"
35
36
37/*
38** A JournalFile object is a subclass of sqlite3_file used by
39** as an open file handle for journal files.
40*/
41struct JournalFile {
42 sqlite3_io_methods *pMethod; /* I/O methods on journal files */
43 int nBuf; /* Size of zBuf[] in bytes */
44 char *zBuf; /* Space to buffer journal writes */
45 int iSize; /* Amount of zBuf[] currently used */
46 int flags; /* xOpen flags */
47 sqlite3_vfs *pVfs; /* The "real" underlying VFS */
48 sqlite3_file *pReal; /* The "real" underlying file descriptor */
49 const char *zJournal; /* Name of the journal file */
50};
51typedef struct JournalFile JournalFile;
52
53/*
54** If it does not already exists, create and populate the on-disk file
55** for JournalFile p.
56*/
57static int createFile(JournalFile *p){
58 int rc = SQLITE_OK;
59 if( !p->pReal ){
60 sqlite3_file *pReal = (sqlite3_file *)&p[1];
61 rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0);
62 if( rc==SQLITE_OK ){
63 p->pReal = pReal;
64 if( p->iSize>0 ){
65 assert(p->iSize<=p->nBuf);
66 rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
67 }
68 }
69 }
70 return rc;
71}
72
73/*
74** Close the file.
75*/
76static int jrnlClose(sqlite3_file *pJfd){
77 JournalFile *p = (JournalFile *)pJfd;
78 if( p->pReal ){
79 sqlite3OsClose(p->pReal);
80 }
81 sqlite3_free(p->zBuf);
82 return SQLITE_OK;
83}
84
85/*
86** Read data from the file.
87*/
88static int jrnlRead(
89 sqlite3_file *pJfd, /* The journal file from which to read */
90 void *zBuf, /* Put the results here */
91 int iAmt, /* Number of bytes to read */
92 sqlite_int64 iOfst /* Begin reading at this offset */
93){
94 int rc = SQLITE_OK;
95 JournalFile *p = (JournalFile *)pJfd;
96 if( p->pReal ){
97 rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
98 }else{
99 assert( iAmt+iOfst<=p->iSize );
100 memcpy(zBuf, &p->zBuf[iOfst], iAmt);
101 }
102 return rc;
103}
104
105/*
106** Write data to the file.
107*/
108static int jrnlWrite(
109 sqlite3_file *pJfd, /* The journal file into which to write */
110 const void *zBuf, /* Take data to be written from here */
111 int iAmt, /* Number of bytes to write */
112 sqlite_int64 iOfst /* Begin writing at this offset into the file */
113){
114 int rc = SQLITE_OK;
115 JournalFile *p = (JournalFile *)pJfd;
116 if( !p->pReal && (iOfst+iAmt)>p->nBuf ){
117 rc = createFile(p);
118 }
119 if( rc==SQLITE_OK ){
120 if( p->pReal ){
121 rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
122 }else{
123 memcpy(&p->zBuf[iOfst], zBuf, iAmt);
124 if( p->iSize<(iOfst+iAmt) ){
125 p->iSize = (iOfst+iAmt);
126 }
127 }
128 }
129 return rc;
130}
131
132/*
133** Truncate the file.
134*/
135static int jrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
136 int rc = SQLITE_OK;
137 JournalFile *p = (JournalFile *)pJfd;
138 if( p->pReal ){
139 rc = sqlite3OsTruncate(p->pReal, size);
140 }else if( size<p->iSize ){
141 p->iSize = size;
142 }
143 return rc;
144}
145
146/*
147** Sync the file.
148*/
149static int jrnlSync(sqlite3_file *pJfd, int flags){
150 int rc;
151 JournalFile *p = (JournalFile *)pJfd;
152 rc = createFile(p);
153 if( rc==SQLITE_OK ){
154 rc = sqlite3OsSync(p->pReal, flags);
155 }
156 return rc;
157}
158
159/*
160** Query the size of the file in bytes.
161*/
162static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
163 int rc = SQLITE_OK;
164 JournalFile *p = (JournalFile *)pJfd;
165 if( p->pReal ){
166 rc = sqlite3OsFileSize(p->pReal, pSize);
167 }else{
168 *pSize = (sqlite_int64) p->iSize;
169 }
170 return rc;
171}
172
173/*
174** Table of methods for JournalFile sqlite3_file object.
175*/
176static struct sqlite3_io_methods JournalFileMethods = {
177 1, /* iVersion */
178 jrnlClose, /* xClose */
179 jrnlRead, /* xRead */
180 jrnlWrite, /* xWrite */
181 jrnlTruncate, /* xTruncate */
182 jrnlSync, /* xSync */
183 jrnlFileSize, /* xFileSize */
184 0, /* xLock */
185 0, /* xUnlock */
186 0, /* xCheckReservedLock */
187 0, /* xFileControl */
188 0, /* xSectorSize */
189 0 /* xDeviceCharacteristics */
190};
191
192/*
193** Open a journal file.
194*/
195int 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*/
224int 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*/
235int sqlite3JournalSize(sqlite3_vfs *pVfs){
236 return (pVfs->szOsFile+sizeof(JournalFile));
237}
238#endif