Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: third_party/sqlite/src/test_onefile.c

Issue 3108030: Move bundled copy of sqlite one level deeper to better separate it... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/sqlite/src/test_mutex.c ('k') | third_party/sqlite/src/test_osinst.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 ** 2007 September 14
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: test_onefile.c,v 1.12 2009/04/07 11:21:29 danielk1977 Exp $
14 **
15 ** OVERVIEW:
16 **
17 ** This file contains some example code demonstrating how the SQLite
18 ** vfs feature can be used to have SQLite operate directly on an
19 ** embedded media, without using an intermediate file system.
20 **
21 ** Because this is only a demo designed to run on a workstation, the
22 ** underlying media is simulated using a regular file-system file. The
23 ** size of the file is fixed when it is first created (default size 10 MB).
24 ** From SQLite's point of view, this space is used to store a single
25 ** database file and the journal file.
26 **
27 ** Any statement journal created is stored in volatile memory obtained
28 ** from sqlite3_malloc(). Any attempt to create a temporary database file
29 ** will fail (SQLITE_IOERR). To prevent SQLite from attempting this,
30 ** it should be configured to store all temporary database files in
31 ** main memory (see pragma "temp_store" or the SQLITE_TEMP_STORE compile
32 ** time option).
33 **
34 ** ASSUMPTIONS:
35 **
36 ** After it has been created, the blob file is accessed using the
37 ** following three functions only:
38 **
39 ** mediaRead(); - Read a 512 byte block from the file.
40 ** mediaWrite(); - Write a 512 byte block to the file.
41 ** mediaSync(); - Tell the media hardware to sync.
42 **
43 ** It is assumed that these can be easily implemented by any "real"
44 ** media vfs driver adapting this code.
45 **
46 ** FILE FORMAT:
47 **
48 ** The basic principle is that the "database file" is stored at the
49 ** beginning of the 10 MB blob and grows in a forward direction. The
50 ** "journal file" is stored at the end of the 10MB blob and grows
51 ** in the reverse direction. If, during a transaction, insufficient
52 ** space is available to expand either the journal or database file,
53 ** an SQLITE_FULL error is returned. The database file is never allowed
54 ** to consume more than 90% of the blob space. If SQLite tries to
55 ** create a file larger than this, SQLITE_FULL is returned.
56 **
57 ** No allowance is made for "wear-leveling", as is required by.
58 ** embedded devices in the absence of equivalent hardware features.
59 **
60 ** The first 512 block byte of the file is reserved for storing the
61 ** size of the "database file". It is updated as part of the sync()
62 ** operation. On startup, it can only be trusted if no journal file
63 ** exists. If a journal-file does exist, then it stores the real size
64 ** of the database region. The second and subsequent blocks store the
65 ** actual database content.
66 **
67 ** The size of the "journal file" is not stored persistently in the
68 ** file. When the system is running, the size of the journal file is
69 ** stored in volatile memory. When recovering from a crash, this vfs
70 ** reports a very large size for the journal file. The normal journal
71 ** header and checksum mechanisms serve to prevent SQLite from
72 ** processing any data that lies past the logical end of the journal.
73 **
74 ** When SQLite calls OsDelete() to delete the journal file, the final
75 ** 512 bytes of the blob (the area containing the first journal header)
76 ** are zeroed.
77 **
78 ** LOCKING:
79 **
80 ** File locking is a no-op. Only one connection may be open at any one
81 ** time using this demo vfs.
82 */
83
84 #include "sqlite3.h"
85 #include <assert.h>
86 #include <string.h>
87
88 /*
89 ** Maximum pathname length supported by the fs backend.
90 */
91 #define BLOCKSIZE 512
92 #define BLOBSIZE 10485760
93
94 /*
95 ** Name used to identify this VFS.
96 */
97 #define FS_VFS_NAME "fs"
98
99 typedef struct fs_real_file fs_real_file;
100 struct fs_real_file {
101 sqlite3_file *pFile;
102 const char *zName;
103 int nDatabase; /* Current size of database region */
104 int nJournal; /* Current size of journal region */
105 int nBlob; /* Total size of allocated blob */
106 int nRef; /* Number of pointers to this structure */
107 fs_real_file *pNext;
108 fs_real_file **ppThis;
109 };
110
111 typedef struct fs_file fs_file;
112 struct fs_file {
113 sqlite3_file base;
114 int eType;
115 fs_real_file *pReal;
116 };
117
118 typedef struct tmp_file tmp_file;
119 struct tmp_file {
120 sqlite3_file base;
121 int nSize;
122 int nAlloc;
123 char *zAlloc;
124 };
125
126 /* Values for fs_file.eType. */
127 #define DATABASE_FILE 1
128 #define JOURNAL_FILE 2
129
130 /*
131 ** Method declarations for fs_file.
132 */
133 static int fsClose(sqlite3_file*);
134 static int fsRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
135 static int fsWrite(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst);
136 static int fsTruncate(sqlite3_file*, sqlite3_int64 size);
137 static int fsSync(sqlite3_file*, int flags);
138 static int fsFileSize(sqlite3_file*, sqlite3_int64 *pSize);
139 static int fsLock(sqlite3_file*, int);
140 static int fsUnlock(sqlite3_file*, int);
141 static int fsCheckReservedLock(sqlite3_file*, int *pResOut);
142 static int fsFileControl(sqlite3_file*, int op, void *pArg);
143 static int fsSectorSize(sqlite3_file*);
144 static int fsDeviceCharacteristics(sqlite3_file*);
145
146 /*
147 ** Method declarations for tmp_file.
148 */
149 static int tmpClose(sqlite3_file*);
150 static int tmpRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
151 static int tmpWrite(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst);
152 static int tmpTruncate(sqlite3_file*, sqlite3_int64 size);
153 static int tmpSync(sqlite3_file*, int flags);
154 static int tmpFileSize(sqlite3_file*, sqlite3_int64 *pSize);
155 static int tmpLock(sqlite3_file*, int);
156 static int tmpUnlock(sqlite3_file*, int);
157 static int tmpCheckReservedLock(sqlite3_file*, int *pResOut);
158 static int tmpFileControl(sqlite3_file*, int op, void *pArg);
159 static int tmpSectorSize(sqlite3_file*);
160 static int tmpDeviceCharacteristics(sqlite3_file*);
161
162 /*
163 ** Method declarations for fs_vfs.
164 */
165 static int fsOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
166 static int fsDelete(sqlite3_vfs*, const char *zName, int syncDir);
167 static int fsAccess(sqlite3_vfs*, const char *zName, int flags, int *);
168 static int fsFullPathname(sqlite3_vfs*, const char *zName, int nOut,char *zOut);
169 static void *fsDlOpen(sqlite3_vfs*, const char *zFilename);
170 static void fsDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
171 static void (*fsDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void);
172 static void fsDlClose(sqlite3_vfs*, void*);
173 static int fsRandomness(sqlite3_vfs*, int nByte, char *zOut);
174 static int fsSleep(sqlite3_vfs*, int microseconds);
175 static int fsCurrentTime(sqlite3_vfs*, double*);
176
177
178 typedef struct fs_vfs_t fs_vfs_t;
179 struct fs_vfs_t {
180 sqlite3_vfs base;
181 fs_real_file *pFileList;
182 sqlite3_vfs *pParent;
183 };
184
185 static fs_vfs_t fs_vfs = {
186 {
187 1, /* iVersion */
188 0, /* szOsFile */
189 0, /* mxPathname */
190 0, /* pNext */
191 FS_VFS_NAME, /* zName */
192 0, /* pAppData */
193 fsOpen, /* xOpen */
194 fsDelete, /* xDelete */
195 fsAccess, /* xAccess */
196 fsFullPathname, /* xFullPathname */
197 fsDlOpen, /* xDlOpen */
198 fsDlError, /* xDlError */
199 fsDlSym, /* xDlSym */
200 fsDlClose, /* xDlClose */
201 fsRandomness, /* xRandomness */
202 fsSleep, /* xSleep */
203 fsCurrentTime /* xCurrentTime */
204 },
205 0, /* pFileList */
206 0 /* pParent */
207 };
208
209 static sqlite3_io_methods fs_io_methods = {
210 1, /* iVersion */
211 fsClose, /* xClose */
212 fsRead, /* xRead */
213 fsWrite, /* xWrite */
214 fsTruncate, /* xTruncate */
215 fsSync, /* xSync */
216 fsFileSize, /* xFileSize */
217 fsLock, /* xLock */
218 fsUnlock, /* xUnlock */
219 fsCheckReservedLock, /* xCheckReservedLock */
220 fsFileControl, /* xFileControl */
221 fsSectorSize, /* xSectorSize */
222 fsDeviceCharacteristics /* xDeviceCharacteristics */
223 };
224
225
226 static sqlite3_io_methods tmp_io_methods = {
227 1, /* iVersion */
228 tmpClose, /* xClose */
229 tmpRead, /* xRead */
230 tmpWrite, /* xWrite */
231 tmpTruncate, /* xTruncate */
232 tmpSync, /* xSync */
233 tmpFileSize, /* xFileSize */
234 tmpLock, /* xLock */
235 tmpUnlock, /* xUnlock */
236 tmpCheckReservedLock, /* xCheckReservedLock */
237 tmpFileControl, /* xFileControl */
238 tmpSectorSize, /* xSectorSize */
239 tmpDeviceCharacteristics /* xDeviceCharacteristics */
240 };
241
242 /* Useful macros used in several places */
243 #define MIN(x,y) ((x)<(y)?(x):(y))
244 #define MAX(x,y) ((x)>(y)?(x):(y))
245
246
247 /*
248 ** Close a tmp-file.
249 */
250 static int tmpClose(sqlite3_file *pFile){
251 tmp_file *pTmp = (tmp_file *)pFile;
252 sqlite3_free(pTmp->zAlloc);
253 return SQLITE_OK;
254 }
255
256 /*
257 ** Read data from a tmp-file.
258 */
259 static int tmpRead(
260 sqlite3_file *pFile,
261 void *zBuf,
262 int iAmt,
263 sqlite_int64 iOfst
264 ){
265 tmp_file *pTmp = (tmp_file *)pFile;
266 if( (iAmt+iOfst)>pTmp->nSize ){
267 return SQLITE_IOERR_SHORT_READ;
268 }
269 memcpy(zBuf, &pTmp->zAlloc[iOfst], iAmt);
270 return SQLITE_OK;
271 }
272
273 /*
274 ** Write data to a tmp-file.
275 */
276 static int tmpWrite(
277 sqlite3_file *pFile,
278 const void *zBuf,
279 int iAmt,
280 sqlite_int64 iOfst
281 ){
282 tmp_file *pTmp = (tmp_file *)pFile;
283 if( (iAmt+iOfst)>pTmp->nAlloc ){
284 int nNew = 2*(iAmt+iOfst+pTmp->nAlloc);
285 char *zNew = sqlite3_realloc(pTmp->zAlloc, nNew);
286 if( !zNew ){
287 return SQLITE_NOMEM;
288 }
289 pTmp->zAlloc = zNew;
290 pTmp->nAlloc = nNew;
291 }
292 memcpy(&pTmp->zAlloc[iOfst], zBuf, iAmt);
293 pTmp->nSize = MAX(pTmp->nSize, iOfst+iAmt);
294 return SQLITE_OK;
295 }
296
297 /*
298 ** Truncate a tmp-file.
299 */
300 static int tmpTruncate(sqlite3_file *pFile, sqlite_int64 size){
301 tmp_file *pTmp = (tmp_file *)pFile;
302 pTmp->nSize = MIN(pTmp->nSize, size);
303 return SQLITE_OK;
304 }
305
306 /*
307 ** Sync a tmp-file.
308 */
309 static int tmpSync(sqlite3_file *pFile, int flags){
310 return SQLITE_OK;
311 }
312
313 /*
314 ** Return the current file-size of a tmp-file.
315 */
316 static int tmpFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
317 tmp_file *pTmp = (tmp_file *)pFile;
318 *pSize = pTmp->nSize;
319 return SQLITE_OK;
320 }
321
322 /*
323 ** Lock a tmp-file.
324 */
325 static int tmpLock(sqlite3_file *pFile, int eLock){
326 return SQLITE_OK;
327 }
328
329 /*
330 ** Unlock a tmp-file.
331 */
332 static int tmpUnlock(sqlite3_file *pFile, int eLock){
333 return SQLITE_OK;
334 }
335
336 /*
337 ** Check if another file-handle holds a RESERVED lock on a tmp-file.
338 */
339 static int tmpCheckReservedLock(sqlite3_file *pFile, int *pResOut){
340 *pResOut = 0;
341 return SQLITE_OK;
342 }
343
344 /*
345 ** File control method. For custom operations on a tmp-file.
346 */
347 static int tmpFileControl(sqlite3_file *pFile, int op, void *pArg){
348 return SQLITE_OK;
349 }
350
351 /*
352 ** Return the sector-size in bytes for a tmp-file.
353 */
354 static int tmpSectorSize(sqlite3_file *pFile){
355 return 0;
356 }
357
358 /*
359 ** Return the device characteristic flags supported by a tmp-file.
360 */
361 static int tmpDeviceCharacteristics(sqlite3_file *pFile){
362 return 0;
363 }
364
365 /*
366 ** Close an fs-file.
367 */
368 static int fsClose(sqlite3_file *pFile){
369 int rc = SQLITE_OK;
370 fs_file *p = (fs_file *)pFile;
371 fs_real_file *pReal = p->pReal;
372
373 /* Decrement the real_file ref-count. */
374 pReal->nRef--;
375 assert(pReal->nRef>=0);
376
377 /* When the ref-count reaches 0, destroy the structure */
378 if( pReal->nRef==0 ){
379 *pReal->ppThis = pReal->pNext;
380 if( pReal->pNext ){
381 pReal->pNext->ppThis = pReal->ppThis;
382 }
383 rc = pReal->pFile->pMethods->xClose(pReal->pFile);
384 sqlite3_free(pReal);
385 }
386
387 return rc;
388 }
389
390 /*
391 ** Read data from an fs-file.
392 */
393 static int fsRead(
394 sqlite3_file *pFile,
395 void *zBuf,
396 int iAmt,
397 sqlite_int64 iOfst
398 ){
399 int rc = SQLITE_OK;
400 fs_file *p = (fs_file *)pFile;
401 fs_real_file *pReal = p->pReal;
402 sqlite3_file *pF = pReal->pFile;
403
404 if( (p->eType==DATABASE_FILE && (iAmt+iOfst)>pReal->nDatabase)
405 || (p->eType==JOURNAL_FILE && (iAmt+iOfst)>pReal->nJournal)
406 ){
407 rc = SQLITE_IOERR_SHORT_READ;
408 }else if( p->eType==DATABASE_FILE ){
409 rc = pF->pMethods->xRead(pF, zBuf, iAmt, iOfst+BLOCKSIZE);
410 }else{
411 /* Journal file. */
412 int iRem = iAmt;
413 int iBuf = 0;
414 int ii = iOfst;
415 while( iRem>0 && rc==SQLITE_OK ){
416 int iRealOff = pReal->nBlob - BLOCKSIZE*((ii/BLOCKSIZE)+1) + ii%BLOCKSIZE;
417 int iRealAmt = MIN(iRem, BLOCKSIZE - (iRealOff%BLOCKSIZE));
418
419 rc = pF->pMethods->xRead(pF, &((char *)zBuf)[iBuf], iRealAmt, iRealOff);
420 ii += iRealAmt;
421 iBuf += iRealAmt;
422 iRem -= iRealAmt;
423 }
424 }
425
426 return rc;
427 }
428
429 /*
430 ** Write data to an fs-file.
431 */
432 static int fsWrite(
433 sqlite3_file *pFile,
434 const void *zBuf,
435 int iAmt,
436 sqlite_int64 iOfst
437 ){
438 int rc = SQLITE_OK;
439 fs_file *p = (fs_file *)pFile;
440 fs_real_file *pReal = p->pReal;
441 sqlite3_file *pF = pReal->pFile;
442
443 if( p->eType==DATABASE_FILE ){
444 if( (iAmt+iOfst+BLOCKSIZE)>(pReal->nBlob-pReal->nJournal) ){
445 rc = SQLITE_FULL;
446 }else{
447 rc = pF->pMethods->xWrite(pF, zBuf, iAmt, iOfst+BLOCKSIZE);
448 if( rc==SQLITE_OK ){
449 pReal->nDatabase = MAX(pReal->nDatabase, iAmt+iOfst);
450 }
451 }
452 }else{
453 /* Journal file. */
454 int iRem = iAmt;
455 int iBuf = 0;
456 int ii = iOfst;
457 while( iRem>0 && rc==SQLITE_OK ){
458 int iRealOff = pReal->nBlob - BLOCKSIZE*((ii/BLOCKSIZE)+1) + ii%BLOCKSIZE;
459 int iRealAmt = MIN(iRem, BLOCKSIZE - (iRealOff%BLOCKSIZE));
460
461 if( iRealOff<(pReal->nDatabase+BLOCKSIZE) ){
462 rc = SQLITE_FULL;
463 }else{
464 rc = pF->pMethods->xWrite(pF, &((char *)zBuf)[iBuf], iRealAmt,iRealOff);
465 ii += iRealAmt;
466 iBuf += iRealAmt;
467 iRem -= iRealAmt;
468 }
469 }
470 if( rc==SQLITE_OK ){
471 pReal->nJournal = MAX(pReal->nJournal, iAmt+iOfst);
472 }
473 }
474
475 return rc;
476 }
477
478 /*
479 ** Truncate an fs-file.
480 */
481 static int fsTruncate(sqlite3_file *pFile, sqlite_int64 size){
482 fs_file *p = (fs_file *)pFile;
483 fs_real_file *pReal = p->pReal;
484 if( p->eType==DATABASE_FILE ){
485 pReal->nDatabase = MIN(pReal->nDatabase, size);
486 }else{
487 pReal->nJournal = MIN(pReal->nJournal, size);
488 }
489 return SQLITE_OK;
490 }
491
492 /*
493 ** Sync an fs-file.
494 */
495 static int fsSync(sqlite3_file *pFile, int flags){
496 fs_file *p = (fs_file *)pFile;
497 fs_real_file *pReal = p->pReal;
498 sqlite3_file *pRealFile = pReal->pFile;
499 int rc = SQLITE_OK;
500
501 if( p->eType==DATABASE_FILE ){
502 unsigned char zSize[4];
503 zSize[0] = (pReal->nDatabase&0xFF000000)>>24;
504 zSize[1] = (pReal->nDatabase&0x00FF0000)>>16;
505 zSize[2] = (pReal->nDatabase&0x0000FF00)>>8;
506 zSize[3] = (pReal->nDatabase&0x000000FF);
507 rc = pRealFile->pMethods->xWrite(pRealFile, zSize, 4, 0);
508 }
509 if( rc==SQLITE_OK ){
510 rc = pRealFile->pMethods->xSync(pRealFile, flags&(~SQLITE_SYNC_DATAONLY));
511 }
512
513 return rc;
514 }
515
516 /*
517 ** Return the current file-size of an fs-file.
518 */
519 static int fsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
520 fs_file *p = (fs_file *)pFile;
521 fs_real_file *pReal = p->pReal;
522 if( p->eType==DATABASE_FILE ){
523 *pSize = pReal->nDatabase;
524 }else{
525 *pSize = pReal->nJournal;
526 }
527 return SQLITE_OK;
528 }
529
530 /*
531 ** Lock an fs-file.
532 */
533 static int fsLock(sqlite3_file *pFile, int eLock){
534 return SQLITE_OK;
535 }
536
537 /*
538 ** Unlock an fs-file.
539 */
540 static int fsUnlock(sqlite3_file *pFile, int eLock){
541 return SQLITE_OK;
542 }
543
544 /*
545 ** Check if another file-handle holds a RESERVED lock on an fs-file.
546 */
547 static int fsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
548 *pResOut = 0;
549 return SQLITE_OK;
550 }
551
552 /*
553 ** File control method. For custom operations on an fs-file.
554 */
555 static int fsFileControl(sqlite3_file *pFile, int op, void *pArg){
556 return SQLITE_OK;
557 }
558
559 /*
560 ** Return the sector-size in bytes for an fs-file.
561 */
562 static int fsSectorSize(sqlite3_file *pFile){
563 return BLOCKSIZE;
564 }
565
566 /*
567 ** Return the device characteristic flags supported by an fs-file.
568 */
569 static int fsDeviceCharacteristics(sqlite3_file *pFile){
570 return 0;
571 }
572
573 /*
574 ** Open an fs file handle.
575 */
576 static int fsOpen(
577 sqlite3_vfs *pVfs,
578 const char *zName,
579 sqlite3_file *pFile,
580 int flags,
581 int *pOutFlags
582 ){
583 fs_vfs_t *pFsVfs = (fs_vfs_t *)pVfs;
584 fs_file *p = (fs_file *)pFile;
585 fs_real_file *pReal = 0;
586 int eType;
587 int nName;
588 int rc = SQLITE_OK;
589
590 if( 0==(flags&(SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_MAIN_JOURNAL)) ){
591 tmp_file *p = (tmp_file *)pFile;
592 memset(p, 0, sizeof(*p));
593 p->base.pMethods = &tmp_io_methods;
594 return SQLITE_OK;
595 }
596
597 eType = ((flags&(SQLITE_OPEN_MAIN_DB))?DATABASE_FILE:JOURNAL_FILE);
598 p->base.pMethods = &fs_io_methods;
599 p->eType = eType;
600
601 assert(strlen("-journal")==8);
602 nName = strlen(zName)-((eType==JOURNAL_FILE)?8:0);
603 pReal=pFsVfs->pFileList;
604 for(; pReal && strncmp(pReal->zName, zName, nName); pReal=pReal->pNext);
605
606 if( !pReal ){
607 int real_flags = (flags&~(SQLITE_OPEN_MAIN_DB))|SQLITE_OPEN_TEMP_DB;
608 sqlite3_int64 size;
609 sqlite3_file *pRealFile;
610 sqlite3_vfs *pParent = pFsVfs->pParent;
611 assert(eType==DATABASE_FILE);
612
613 pReal = (fs_real_file *)sqlite3_malloc(sizeof(*pReal)+pParent->szOsFile);
614 if( !pReal ){
615 rc = SQLITE_NOMEM;
616 goto open_out;
617 }
618 memset(pReal, 0, sizeof(*pReal)+pParent->szOsFile);
619 pReal->zName = zName;
620 pReal->pFile = (sqlite3_file *)(&pReal[1]);
621
622 rc = pParent->xOpen(pParent, zName, pReal->pFile, real_flags, pOutFlags);
623 if( rc!=SQLITE_OK ){
624 goto open_out;
625 }
626 pRealFile = pReal->pFile;
627
628 rc = pRealFile->pMethods->xFileSize(pRealFile, &size);
629 if( rc!=SQLITE_OK ){
630 goto open_out;
631 }
632 if( size==0 ){
633 rc = pRealFile->pMethods->xWrite(pRealFile, "\0", 1, BLOBSIZE-1);
634 pReal->nBlob = BLOBSIZE;
635 }else{
636 unsigned char zS[4];
637 pReal->nBlob = size;
638 rc = pRealFile->pMethods->xRead(pRealFile, zS, 4, 0);
639 pReal->nDatabase = (zS[0]<<24)+(zS[1]<<16)+(zS[2]<<8)+zS[3];
640 if( rc==SQLITE_OK ){
641 rc = pRealFile->pMethods->xRead(pRealFile, zS, 4, pReal->nBlob-4);
642 if( zS[0] || zS[1] || zS[2] || zS[3] ){
643 pReal->nJournal = pReal->nBlob;
644 }
645 }
646 }
647
648 if( rc==SQLITE_OK ){
649 pReal->pNext = pFsVfs->pFileList;
650 if( pReal->pNext ){
651 pReal->pNext->ppThis = &pReal->pNext;
652 }
653 pReal->ppThis = &pFsVfs->pFileList;
654 pFsVfs->pFileList = pReal;
655 }
656 }
657
658 open_out:
659 if( pReal ){
660 if( rc==SQLITE_OK ){
661 p->pReal = pReal;
662 pReal->nRef++;
663 }else{
664 if( pReal->pFile->pMethods ){
665 pReal->pFile->pMethods->xClose(pReal->pFile);
666 }
667 sqlite3_free(pReal);
668 }
669 }
670 return rc;
671 }
672
673 /*
674 ** Delete the file located at zPath. If the dirSync argument is true,
675 ** ensure the file-system modifications are synced to disk before
676 ** returning.
677 */
678 static int fsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
679 int rc = SQLITE_OK;
680 fs_vfs_t *pFsVfs = (fs_vfs_t *)pVfs;
681 fs_real_file *pReal;
682 sqlite3_file *pF;
683 int nName = strlen(zPath) - 8;
684
685 assert(strlen("-journal")==8);
686 assert(strcmp("-journal", &zPath[nName])==0);
687
688 pReal = pFsVfs->pFileList;
689 for(; pReal && strncmp(pReal->zName, zPath, nName); pReal=pReal->pNext);
690 if( pReal ){
691 pF = pReal->pFile;
692 rc = pF->pMethods->xWrite(pF, "\0\0\0\0", 4, pReal->nBlob-BLOCKSIZE);
693 if( rc==SQLITE_OK ){
694 pReal->nJournal = 0;
695 }
696 }
697 return rc;
698 }
699
700 /*
701 ** Test for access permissions. Return true if the requested permission
702 ** is available, or false otherwise.
703 */
704 static int fsAccess(
705 sqlite3_vfs *pVfs,
706 const char *zPath,
707 int flags,
708 int *pResOut
709 ){
710 fs_vfs_t *pFsVfs = (fs_vfs_t *)pVfs;
711 fs_real_file *pReal;
712 int isJournal = 0;
713 int nName = strlen(zPath);
714
715 if( flags!=SQLITE_ACCESS_EXISTS ){
716 sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent;
717 return pParent->xAccess(pParent, zPath, flags, pResOut);
718 }
719
720 assert(strlen("-journal")==8);
721 if( nName>8 && strcmp("-journal", &zPath[nName-8])==0 ){
722 nName -= 8;
723 isJournal = 1;
724 }
725
726 pReal = pFsVfs->pFileList;
727 for(; pReal && strncmp(pReal->zName, zPath, nName); pReal=pReal->pNext);
728
729 *pResOut = (pReal && (!isJournal || pReal->nJournal>0));
730 return SQLITE_OK;
731 }
732
733 /*
734 ** Populate buffer zOut with the full canonical pathname corresponding
735 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
736 ** of at least (FS_MAX_PATHNAME+1) bytes.
737 */
738 static int fsFullPathname(
739 sqlite3_vfs *pVfs, /* Pointer to vfs object */
740 const char *zPath, /* Possibly relative input path */
741 int nOut, /* Size of output buffer in bytes */
742 char *zOut /* Output buffer */
743 ){
744 sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent;
745 return pParent->xFullPathname(pParent, zPath, nOut, zOut);
746 }
747
748 /*
749 ** Open the dynamic library located at zPath and return a handle.
750 */
751 static void *fsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
752 sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent;
753 return pParent->xDlOpen(pParent, zPath);
754 }
755
756 /*
757 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
758 ** utf-8 string describing the most recent error encountered associated
759 ** with dynamic libraries.
760 */
761 static void fsDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
762 sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent;
763 pParent->xDlError(pParent, nByte, zErrMsg);
764 }
765
766 /*
767 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
768 */
769 static void (*fsDlSym(sqlite3_vfs *pVfs, void *pH, const char *zSym))(void){
770 sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent;
771 return pParent->xDlSym(pParent, pH, zSym);
772 }
773
774 /*
775 ** Close the dynamic library handle pHandle.
776 */
777 static void fsDlClose(sqlite3_vfs *pVfs, void *pHandle){
778 sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent;
779 pParent->xDlClose(pParent, pHandle);
780 }
781
782 /*
783 ** Populate the buffer pointed to by zBufOut with nByte bytes of
784 ** random data.
785 */
786 static int fsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
787 sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent;
788 return pParent->xRandomness(pParent, nByte, zBufOut);
789 }
790
791 /*
792 ** Sleep for nMicro microseconds. Return the number of microseconds
793 ** actually slept.
794 */
795 static int fsSleep(sqlite3_vfs *pVfs, int nMicro){
796 sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent;
797 return pParent->xSleep(pParent, nMicro);
798 }
799
800 /*
801 ** Return the current time as a Julian Day number in *pTimeOut.
802 */
803 static int fsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
804 sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent;
805 return pParent->xCurrentTime(pParent, pTimeOut);
806 }
807
808 /*
809 ** This procedure registers the fs vfs with SQLite. If the argument is
810 ** true, the fs vfs becomes the new default vfs. It is the only publicly
811 ** available function in this file.
812 */
813 int fs_register(void){
814 if( fs_vfs.pParent ) return SQLITE_OK;
815 fs_vfs.pParent = sqlite3_vfs_find(0);
816 fs_vfs.base.mxPathname = fs_vfs.pParent->mxPathname;
817 fs_vfs.base.szOsFile = MAX(sizeof(tmp_file), sizeof(fs_file));
818 return sqlite3_vfs_register(&fs_vfs.base, 0);
819 }
820
821 #ifdef SQLITE_TEST
822 int SqlitetestOnefile_Init() {return fs_register();}
823 #endif
OLDNEW
« no previous file with comments | « third_party/sqlite/src/test_mutex.c ('k') | third_party/sqlite/src/test_osinst.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698