15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2010 April 7 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code. In place of 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing: 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you do good and not evil. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you find forgiveness for yourself and forgive others. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you share freely, never taking more than you give. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)************************************************************************* 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** An example of a simple VFS implementation that omits complex features 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** often not required or not possible on embedded platforms. Also includes 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** code to buffer writes to the journal file, which can be a significant 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** performance improvement on some embedded platforms. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** OVERVIEW 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The code in this file implements a minimal SQLite VFS that can be 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** used on Linux and other posix-like operating systems. The following 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** system calls are used: 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** File-system: access(), unlink(), getcwd() 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** File IO: open(), read(), write(), fsync(), close(), fstat() 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Other: sleep(), usleep(), time() 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following VFS features are omitted: 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 1. File locking. The user must ensure that there is at most one 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** connection to each database when using this VFS. Multiple 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** connections to a single shared-cache count as a single connection 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** for the purposes of the previous statement. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2. The loading of dynamic extensions (shared libraries). 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3. Temporary files. The user must configure SQLite to use in-memory 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** temp files when using this VFS. The easiest way to do this is to 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** compile with: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** -DSQLITE_TEMP_STORE=3 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4. File truncation. As of version 3.6.24, SQLite may run without 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a working xTruncate() call, providing the user does not configure 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SQLite to use "journal_mode=truncate", or use both 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** "journal_mode=persist" and ATTACHed databases. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** It is assumed that the system uses UNIX-like path-names. Specifically, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** that '/' characters are used to separate path components and that 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a path-name is a relative path unless it begins with a '/'. And that 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** no UTF-8 encoded paths are greater than 512 bytes in length. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** JOURNAL WRITE-BUFFERING 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** To commit a transaction to the database, SQLite first writes rollback 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** information into the journal file. This usually consists of 4 steps: 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 1. The rollback information is sequentially written into the journal 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** file, starting at the start of the file. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2. The journal file is synced to disk. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3. A modification is made to the first few bytes of the journal file. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4. The journal file is synced to disk again. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Most of the data is written in step 1 using a series of calls to the 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** VFS xWrite() method. The buffers passed to the xWrite() calls are of 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** various sizes. For example, as of version 3.6.24, when committing a 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** transaction that modifies 3 pages of a database file that uses 4096 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** byte pages residing on a media with 512 byte sectors, SQLite makes 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** eleven calls to the xWrite() method to create the rollback journal, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** as follows: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write offset | Bytes written 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ---------------------------- 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 0 512 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 512 4 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 516 4096 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4612 4 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4616 4 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4620 4096 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8716 4 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8720 4 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8724 4096 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 12820 4 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ++++++++++++SYNC+++++++++++ 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 0 12 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ++++++++++++SYNC+++++++++++ 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** On many operating systems, this is an efficient way to write to a file. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** However, on some embedded systems that do not cache writes in OS 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** buffers it is much more efficient to write data in blocks that are 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** an integer multiple of the sector-size in size and aligned at the 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** start of a sector. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** To work around this, the code in this file allocates a fixed size 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** buffer of SQLITE_DEMOVFS_BUFFERSZ using sqlite3_malloc() whenever a 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** journal file is opened. It uses the buffer to coalesce sequential 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** writes into aligned SQLITE_DEMOVFS_BUFFERSZ blocks. When SQLite 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** invokes the xSync() method to sync the contents of the file to disk, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** all accumulated data is written out, even if it does not constitute 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a complete block. This means the actual IO to create the rollback 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** journal for the example transaction above is this: 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write offset | Bytes written 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ---------------------------- 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 0 8192 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8192 4632 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ++++++++++++SYNC+++++++++++ 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 0 12 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ++++++++++++SYNC+++++++++++ 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Much more efficient if the underlying OS is not caching write 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** operations. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(SQLITE_TEST) || SQLITE_OS_UNIX 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sqlite3.h> 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h> 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/file.h> 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/param.h> 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h> 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Size of the write buffer used by journal files in bytes. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_DEMOVFS_BUFFERSZ 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define SQLITE_DEMOVFS_BUFFERSZ 8192 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The maximum pathname length supported by this VFS. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAXPATHNAME 512 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** When using this VFS, the sqlite3_file* handles that SQLite uses are 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** actually pointers to instances of type DemoFile. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct DemoFile DemoFile; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct DemoFile { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file base; /* Base class. Must be first. */ 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd; /* File descriptor */ 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *aBuffer; /* Pointer to malloc'd buffer */ 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nBuffer; /* Valid bytes of data in zBuffer */ 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_int64 iBufferOfst; /* Offset in file of zBuffer[0] */ 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write directly to the file passed as the first argument. Even if the 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** file has a write-buffer (DemoFile.aBuffer), ignore it. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoDirectWrite( 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DemoFile *p, /* File handle */ 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *zBuf, /* Buffer containing data to write */ 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iAmt, /* Size of data to write in bytes */ 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite_int64 iOfst /* File offset to write to */ 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) off_t ofst; /* Return value from lseek() */ 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t nWrite; /* Return value from write() */ 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ofst = lseek(p->fd, iOfst, SEEK_SET); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ofst!=iOfst ){ 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_IOERR_WRITE; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nWrite = write(p->fd, zBuf, iAmt); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nWrite!=iAmt ){ 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_IOERR_WRITE; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Flush the contents of the DemoFile.aBuffer buffer to disk. This is a 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** no-op if this particular file does not have a buffer (i.e. it is not 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a journal file) or if the buffer is currently empty. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoFlushBuffer(DemoFile *p){ 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_OK; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->nBuffer ){ 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = demoDirectWrite(p, p->aBuffer, p->nBuffer, p->iBufferOfst); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->nBuffer = 0; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Close a file. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoClose(sqlite3_file *pFile){ 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DemoFile *p = (DemoFile*)pFile; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = demoFlushBuffer(p); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p->aBuffer); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(p->fd); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Read data from a file. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoRead( 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *zBuf, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iAmt, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite_int64 iOfst 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DemoFile *p = (DemoFile*)pFile; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) off_t ofst; /* Return value from lseek() */ 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nRead; /* Return value from read() */ 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; /* Return code from demoFlushBuffer() */ 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Flush any data in the write buffer to disk in case this operation 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is trying to read data the file-region currently cached in the buffer. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** It would be possible to detect this case and possibly save an 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** unnecessary write here, but in practice SQLite will rarely read from 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** a journal file when there is data cached in the write-buffer. 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = demoFlushBuffer(p); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ){ 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ofst = lseek(p->fd, iOfst, SEEK_SET); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ofst!=iOfst ){ 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_IOERR_READ; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRead = read(p->fd, zBuf, iAmt); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nRead==iAmt ){ 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( nRead>=0 ){ 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_IOERR_SHORT_READ; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_IOERR_READ; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write data to a crash-file. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoWrite( 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *zBuf, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iAmt, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite_int64 iOfst 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DemoFile *p = (DemoFile*)pFile; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->aBuffer ){ 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *z = (char *)zBuf; /* Pointer to remaining data to write */ 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n = iAmt; /* Number of bytes at z */ 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_int64 i = iOfst; /* File offset to write to */ 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( n>0 ){ 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nCopy; /* Number of bytes to copy into buffer */ 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the buffer is full, or if this data is not being written directly 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** following the data already buffered, flush the buffer. Flushing 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the buffer is a no-op if it is empty. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->nBuffer==SQLITE_DEMOVFS_BUFFERSZ || p->iBufferOfst+p->nBuffer!=i ){ 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = demoFlushBuffer(p); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ){ 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( p->nBuffer==0 || p->iBufferOfst+p->nBuffer==i ); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->iBufferOfst = i - p->nBuffer; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Copy as much data as possible into the buffer. */ 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nCopy = SQLITE_DEMOVFS_BUFFERSZ - p->nBuffer; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nCopy>n ){ 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nCopy = n; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&p->aBuffer[p->nBuffer], z, nCopy); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->nBuffer += nCopy; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n -= nCopy; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i += nCopy; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z += nCopy; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return demoDirectWrite(p, zBuf, iAmt, iOfst); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Truncate a file. This is a no-op for this VFS (see header comments at 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the top of the file). 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoTruncate(sqlite3_file *pFile, sqlite_int64 size){ 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ftruncate(((DemoFile *)pFile)->fd, size) ) return SQLITE_IOERR_TRUNCATE; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Sync the contents of the file to the persistent media. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoSync(sqlite3_file *pFile, int flags){ 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DemoFile *p = (DemoFile*)pFile; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = demoFlushBuffer(p); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ){ 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = fsync(p->fd); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (rc==0 ? SQLITE_OK : SQLITE_IOERR_FSYNC); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write the size of the file in bytes to *pSize. 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DemoFile *p = (DemoFile*)pFile; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; /* Return code from fstat() call */ 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct stat sStat; /* Output of fstat() call */ 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Flush the contents of the buffer to disk. As with the flush in the 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** demoRead() method, it would be possible to avoid this and save a write 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** here and there. But in practice this comes up so infrequently it is 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** not worth the trouble. 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = demoFlushBuffer(p); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ){ 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = fstat(p->fd, &sStat); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=0 ) return SQLITE_IOERR_FSTAT; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pSize = sStat.st_size; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Locking functions. The xLock() and xUnlock() methods are both no-ops. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The xCheckReservedLock() always indicates that no other process holds 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a reserved lock on the database file. This ensures that if a hot-journal 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** file is found in the file-system it is rolled back. 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoLock(sqlite3_file *pFile, int eLock){ 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoUnlock(sqlite3_file *pFile, int eLock){ 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoCheckReservedLock(sqlite3_file *pFile, int *pResOut){ 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pResOut = 0; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** No xFileControl() verbs are implemented by this VFS. 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoFileControl(sqlite3_file *pFile, int op, void *pArg){ 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The xSectorSize() and xDeviceCharacteristics() methods. These two 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** may return special values allowing SQLite to optimize file-system 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** access to some extent. But it is also safe to simply return 0. 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoSectorSize(sqlite3_file *pFile){ 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoDeviceCharacteristics(sqlite3_file *pFile){ 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Open a file handle. 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoOpen( 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs, /* VFS */ 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zName, /* File to open, or 0 for a temp file */ 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile, /* Pointer to DemoFile struct to populate */ 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, /* Input SQLITE_OPEN_XXX flags */ 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *pOutFlags /* Output SQLITE_OPEN_XXX flags (or NULL) */ 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const sqlite3_io_methods demoio = { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, /* iVersion */ 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoClose, /* xClose */ 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoRead, /* xRead */ 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoWrite, /* xWrite */ 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoTruncate, /* xTruncate */ 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoSync, /* xSync */ 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoFileSize, /* xFileSize */ 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoLock, /* xLock */ 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoUnlock, /* xUnlock */ 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoCheckReservedLock, /* xCheckReservedLock */ 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoFileControl, /* xFileControl */ 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoSectorSize, /* xSectorSize */ 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoDeviceCharacteristics /* xDeviceCharacteristics */ 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DemoFile *p = (DemoFile*)pFile; /* Populate this structure */ 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int oflags = 0; /* flags to pass to open() call */ 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *aBuf = 0; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zName==0 ){ 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_IOERR; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( flags&SQLITE_OPEN_MAIN_JOURNAL ){ 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aBuf = (char *)sqlite3_malloc(SQLITE_DEMOVFS_BUFFERSZ); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !aBuf ){ 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_NOMEM; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( flags&SQLITE_OPEN_EXCLUSIVE ) oflags |= O_EXCL; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( flags&SQLITE_OPEN_CREATE ) oflags |= O_CREAT; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( flags&SQLITE_OPEN_READONLY ) oflags |= O_RDONLY; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( flags&SQLITE_OPEN_READWRITE ) oflags |= O_RDWR; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(p, 0, sizeof(DemoFile)); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->fd = open(zName, oflags, 0600); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->fd<0 ){ 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(aBuf); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_CANTOPEN; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aBuffer = aBuf; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOutFlags ){ 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pOutFlags = flags; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->base.pMethods = &demoio; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Delete the file identified by argument zPath. If the dirSync parameter 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is non-zero, then ensure the file-system modification to delete the 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** file has been synced to disk before returning. 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; /* Return code */ 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = unlink(zPath); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=0 && errno==ENOENT ) return SQLITE_OK; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==0 && dirSync ){ 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dfd; /* File descriptor open on directory */ 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; /* Iterator variable */ 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char zDir[MAXPATHNAME+1]; /* Name of directory containing file zPath */ 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Figure out the directory name from the path of the file deleted. */ 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_snprintf(MAXPATHNAME, zDir, "%s", zPath); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zDir[MAXPATHNAME] = '\0'; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=strlen(zDir); i>1 && zDir[i]!='/'; i++); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zDir[i] = '\0'; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Open a file-descriptor on the directory. Sync. Close. */ 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dfd = open(zDir, O_RDONLY, 0); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( dfd<0 ){ 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = -1; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = fsync(dfd); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(dfd); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (rc==0 ? SQLITE_OK : SQLITE_IOERR_DELETE); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef F_OK 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define F_OK 0 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef R_OK 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define R_OK 4 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef W_OK 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define W_OK 2 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Query the file-system to see if the named file exists, is readable or 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is both readable and writable. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoAccess( 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs, 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zPath, 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *pResOut 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; /* access() return code */ 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int eAccess = F_OK; /* Second argument to access() */ 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( flags==SQLITE_ACCESS_EXISTS /* access(zPath, F_OK) */ 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || flags==SQLITE_ACCESS_READ /* access(zPath, R_OK) */ 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || flags==SQLITE_ACCESS_READWRITE /* access(zPath, R_OK|W_OK) */ 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( flags==SQLITE_ACCESS_READWRITE ) eAccess = R_OK|W_OK; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( flags==SQLITE_ACCESS_READ ) eAccess = R_OK; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = access(zPath, eAccess); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pResOut = (rc==0); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Argument zPath points to a nul-terminated string containing a file path. 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If zPath is an absolute path, then it is copied as is into the output 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** buffer. Otherwise, if it is a relative path, then the equivalent full 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** path is written to the output buffer. 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This function assumes that paths are UNIX style. Specifically, that: 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 1. Path components are separated by a '/'. and 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2. Full paths begin with a '/' character. 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoFullPathname( 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs, /* VFS */ 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zPath, /* Input path (possibly a relative path) */ 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nPathOut, /* Size of output buffer in bytes */ 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zPathOut /* Pointer to output buffer */ 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char zDir[MAXPATHNAME+1]; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zPath[0]=='/' ){ 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zDir[0] = '\0'; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getcwd(zDir, sizeof(zDir)); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zDir[MAXPATHNAME] = '\0'; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_snprintf(nPathOut, zPathOut, "%s/%s", zDir, zPath); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zPathOut[nPathOut-1] = '\0'; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following four VFS methods: 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** xDlOpen 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** xDlError 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** xDlSym 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** xDlClose 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** are supposed to implement the functionality needed by SQLite to load 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** extensions compiled as shared objects. This simple VFS does not support 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** this functionality, so the following functions are no-ops. 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *demoDlOpen(sqlite3_vfs *pVfs, const char *zPath){ 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void demoDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_snprintf(nByte, zErrMsg, "Loadable extensions are not supported"); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zErrMsg[nByte-1] = '\0'; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void (*demoDlSym(sqlite3_vfs *pVfs, void *pH, const char *z))(void){ 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void demoDlClose(sqlite3_vfs *pVfs, void *pHandle){ 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Parameter zByte points to a buffer nByte bytes in size. Populate this 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** buffer with pseudo-random data. 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoRandomness(sqlite3_vfs *pVfs, int nByte, char *zByte){ 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Sleep for at least nMicro microseconds. Return the (approximate) number 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of microseconds slept for. 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoSleep(sqlite3_vfs *pVfs, int nMicro){ 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sleep(nMicro / 1000000); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) usleep(nMicro % 1000000); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return nMicro; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set *pTime to the current UTC time expressed as a Julian day. Return 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SQLITE_OK if successful, or an error code otherwise. 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** http://en.wikipedia.org/wiki/Julian_day 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This implementation is not very good. The current time is rounded to 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** an integer number of seconds. Also, assuming time_t is a signed 32-bit 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** value, it will stop working some time in the year 2038 AD (the so-called 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** "year 2038" problem that afflicts systems that store time this way). 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int demoCurrentTime(sqlite3_vfs *pVfs, double *pTime){ 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_t t = time(0); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pTime = t/86400.0 + 2440587.5; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This function returns a pointer to the VFS implemented in this file. 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** To make the VFS available to SQLite: 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3_vfs_register(sqlite3_demovfs(), 0); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sqlite3_vfs *sqlite3_demovfs(void){ 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static sqlite3_vfs demovfs = { 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, /* iVersion */ 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(DemoFile), /* szOsFile */ 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAXPATHNAME, /* mxPathname */ 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* pNext */ 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "demo", /* zName */ 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* pAppData */ 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoOpen, /* xOpen */ 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoDelete, /* xDelete */ 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoAccess, /* xAccess */ 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoFullPathname, /* xFullPathname */ 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoDlOpen, /* xDlOpen */ 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoDlError, /* xDlError */ 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoDlSym, /* xDlSym */ 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoDlClose, /* xDlClose */ 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoRandomness, /* xRandomness */ 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoSleep, /* xSleep */ 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) demoCurrentTime, /* xCurrentTime */ 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &demovfs; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !defined(SQLITE_TEST) || SQLITE_OS_UNIX */ 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_TEST 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <tcl.h> 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if SQLITE_OS_UNIX 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int register_demovfs( 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, /* Number of arguments */ 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] /* Command arguments */ 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs_register(sqlite3_demovfs(), 1); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int unregister_demovfs( 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, /* Number of arguments */ 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] /* Command arguments */ 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs_unregister(sqlite3_demovfs()); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Register commands with the TCL interpreter. 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Sqlitetest_demovfs_Init(Tcl_Interp *interp){ 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_CreateObjCommand(interp, "register_demovfs", register_demovfs, 0, 0); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_CreateObjCommand(interp, "unregister_demovfs", unregister_demovfs, 0, 0); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Sqlitetest_demovfs_Init(Tcl_Interp *interp){ return TCL_OK; } 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_TEST */ 681