Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge two "wal" leaves. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | wal |
Files: | files | file ages | folders |
SHA1: |
13d2d5a66e9eaa81aa6314354201ee1f |
User & Date: | dan 2010-04-28 17:49:57.000 |
Context
2010-04-28
| ||
18:17 | Add a test to walthread.test for changing between WAL and rollback modes. (check-in: da229e44bd user: dan tags: wal) | |
17:49 | Merge two "wal" leaves. (check-in: 13d2d5a66e user: dan tags: wal) | |
17:48 | Change walthread.test so that tests can be run with either multiple threads or multiple processes. (check-in: 25f85f6872 user: dan tags: wal) | |
17:21 | Changes to the interface design for the xShmLock method of the VFS. (check-in: 348409de26 user: drh tags: wal) | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
1186 1187 1188 1189 1190 1191 1192 | return pRet; } /* ** Register a callback to be invoked each time a transaction is written ** into the write-ahead-log by this database connection. */ | | | 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 | return pRet; } /* ** Register a callback to be invoked each time a transaction is written ** into the write-ahead-log by this database connection. */ void *sqlite3_wal_hook( sqlite3 *db, /* Attach the hook to this db handle */ int(*xCallback)(void *, sqlite3*, const char*, int), void *pArg /* First argument passed to xCallback() */ ){ void *pRet; sqlite3_mutex_enter(db->mutex); pRet = db->pLogArg; |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
4693 4694 4695 4696 4697 4698 4699 | } /* ** Create or release a lock on shared memory. */ static int unixShmLock( sqlite3_shm *pSharedMem, /* Pointer from unixShmOpen() */ | | | | < < < < < < < < < < < < < < < | | 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 | } /* ** Create or release a lock on shared memory. */ static int unixShmLock( sqlite3_shm *pSharedMem, /* Pointer from unixShmOpen() */ int desiredLock, /* The locking state desired */ int *pGotLock, /* The locking state actually obtained */ int shouldBlock /* Block for the lock if true and possible */ ){ return SQLITE_OK; } /* ** Delete a shared-memory segment from the system. */ static int unixShmDelete(sqlite3_vfs *pVfs, const char *zName){ return pVfs->xDelete(pVfs, zName, 0); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
844 845 846 847 848 849 850 | ** definition. Those that follow are added in version 2 or later */ int (*xShmOpen)(sqlite3_vfs*, const char *zName, sqlite3_shm**); int (*xShmSize)(sqlite3_shm*, int reqSize, int *pNewSize, char**); int (*xShmRelease)(sqlite3_shm*); int (*xShmPush)(sqlite3_shm*); int (*xShmPull)(sqlite3_shm*); | | | 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 | ** definition. Those that follow are added in version 2 or later */ int (*xShmOpen)(sqlite3_vfs*, const char *zName, sqlite3_shm**); int (*xShmSize)(sqlite3_shm*, int reqSize, int *pNewSize, char**); int (*xShmRelease)(sqlite3_shm*); int (*xShmPush)(sqlite3_shm*); int (*xShmPull)(sqlite3_shm*); int (*xShmLock)(sqlite3_shm*, int desiredLock, int *gotLock, int shouldBlock); int (*xShmClose)(sqlite3_shm*); int (*xShmDelete)(sqlite3_vfs*, const char *zName); int (*xRename)(sqlite3_vfs*, const char *zOld, const char *zNew, int dirSync); int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); /* ** The methods above are in versions 1 and 2 of the sqlite_vfs object. ** New fields may be appended in figure versions. The iVersion |
︙ | ︙ | |||
876 877 878 879 880 881 882 | #define SQLITE_ACCESS_EXISTS 0 #define SQLITE_ACCESS_READWRITE 1 #define SQLITE_ACCESS_READ 2 /* ** CAPI3REF: Flags for the xShmLock VFS method ** | | | | | < < | > | > | | | > > | 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 | #define SQLITE_ACCESS_EXISTS 0 #define SQLITE_ACCESS_READWRITE 1 #define SQLITE_ACCESS_READ 2 /* ** CAPI3REF: Flags for the xShmLock VFS method ** ** These integer constants define the various locking states that ** an sqlite3_shm object can be in. The SQLITE_SHM_QUERY integer ** is not a valid data - it is a constant pasted to the ** sqlite3_vfs.xShmLock() method for querying the current lock ** state. */ #define SQLITE_SHM_UNLOCK 0 #define SQLITE_SHM_READ_PREFIX 1 #define SQLITE_SHM_READ_FULL 2 #define SQLITE_SHM_WRITE 3 #define SQLITE_SHM_PENDING 4 #define SQLITE_SHM_CHECKPOINT 5 #define SQLITE_SHM_RECOVER 6 #define SQLITE_SHM_QUERY (-1) /* ** CAPI3REF: Initialize The SQLite Library ** ** ^The sqlite3_initialize() routine initializes the ** SQLite library. ^The sqlite3_shutdown() routine ** deallocates any resources that were allocated by sqlite3_initialize(). |
︙ | ︙ | |||
5757 5758 5759 5760 5761 5762 5763 | ** a fixed-length buffer on the stack. If the log message is longer than ** a few hundred characters, it will be truncated to the length of the ** buffer. */ void sqlite3_log(int iErrCode, const char *zFormat, ...); /* | | | | | | | 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 | ** a fixed-length buffer on the stack. If the log message is longer than ** a few hundred characters, it will be truncated to the length of the ** buffer. */ void sqlite3_log(int iErrCode, const char *zFormat, ...); /* ** CAPI3REF: Write-Ahead Log Commit Hook ** ** The [sqlite3_wal_hook()] function is used to register a callback that ** will be invoked each time a database connection commits data to a ** write-ahead-log (i.e. whenever a transaction is committed in ** journal_mode=WAL mode). ** ** The callback is invoked by SQLite after the commit has taken place and ** the associated write-lock on the database released, so the implementation ** may read, write or checkpoint the database as required. ** ** The first parameter passed to the callback function when it is invoked ** is a copy of the third parameter passed to sqlite3_wal_hook() when ** registering the callback. The second is a copy of the database handle. ** The third parameter is the name of the database that was written to - ** either "main" or the name of an ATTACHed database. The fourth parameter ** is the number of pages currently in the log file, including those that ** were just committed. ** ** If an invocation of the callback function returns non-zero, then a ** checkpoint is automatically run on the database. If zero is returned, ** no special action is taken. ** ** A single database handle may have at most a single log callback ** registered at one time. Calling [sqlite3_wal_hook()] replaces any ** previously registered log callback. */ void *sqlite3_wal_hook( sqlite3*, int(*)(void *,sqlite3*,const char*,int), void* ); /* ** Undo the hack that converts floating point types to integer for |
︙ | ︙ |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
1566 1567 1568 1569 1570 1571 1572 | static const char *DB_strs[] = { "authorizer", "backup", "busy", "cache", "changes", "close", "collate", "collation_needed", "commit_hook", "complete", "copy", "enable_load_extension", "errorcode", "eval", "exists", "function", "incrblob", "interrupt", | | | | | | | | | | | | | | 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 | static const char *DB_strs[] = { "authorizer", "backup", "busy", "cache", "changes", "close", "collate", "collation_needed", "commit_hook", "complete", "copy", "enable_load_extension", "errorcode", "eval", "exists", "function", "incrblob", "interrupt", "last_insert_rowid", "nullvalue", "onecolumn", "profile", "progress", "rekey", "restore", "rollback_hook", "status", "timeout", "total_changes", "trace", "transaction", "unlock_notify", "update_hook", "version", "wal_hook", 0 }; enum DB_enum { DB_AUTHORIZER, DB_BACKUP, DB_BUSY, DB_CACHE, DB_CHANGES, DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK, DB_COMPLETE, DB_COPY, DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE, DB_EVAL, DB_EXISTS, DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN, DB_PROFILE, DB_PROGRESS, DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); return TCL_ERROR; } |
︙ | ︙ | |||
2756 2757 2758 2759 2760 2761 2762 | } } #endif break; } /* | | | | | 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 | } } #endif break; } /* ** $db wal_hook ?script? ** $db update_hook ?script? ** $db rollback_hook ?script? */ case DB_WAL_HOOK: case DB_UPDATE_HOOK: case DB_ROLLBACK_HOOK: { /* set ppHook to point at pUpdateHook or pRollbackHook, depending on ** whether [$db update_hook] or [$db rollback_hook] was invoked. */ Tcl_Obj **ppHook; if( choice==DB_UPDATE_HOOK ){ ppHook = &pDb->pUpdateHook; }else if( choice==DB_WAL_HOOK ){ ppHook = &pDb->pLogHook; }else{ ppHook = &pDb->pRollbackHook; } if( objc!=2 && objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); |
︙ | ︙ | |||
2797 2798 2799 2800 2801 2802 2803 | *ppHook = objv[2]; Tcl_IncrRefCount(*ppHook); } } sqlite3_update_hook(pDb->db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb); sqlite3_rollback_hook(pDb->db,(pDb->pRollbackHook?DbRollbackHandler:0),pDb); | | | 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 | *ppHook = objv[2]; Tcl_IncrRefCount(*ppHook); } } sqlite3_update_hook(pDb->db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb); sqlite3_rollback_hook(pDb->db,(pDb->pRollbackHook?DbRollbackHandler:0),pDb); sqlite3_wal_hook(pDb->db,(pDb->pLogHook?DbLogHandler:0),pDb); break; } /* $db version ** ** Return the version string for this database. |
︙ | ︙ |
Changes to src/wal.h.
︙ | ︙ | |||
15 16 17 18 19 20 21 | */ #ifndef _WAL_H_ #define _WAL_H_ #include "sqliteInt.h" | > | > | | > > > > > > | > > > > > > > > | > > > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | */ #ifndef _WAL_H_ #define _WAL_H_ #include "sqliteInt.h" /* Connection to a write-ahead log (WAL) file. ** There is one object of this type for each pager. */ typedef struct Log Log; /* Open and close a connection to a write-ahead log. */ int sqlite3WalOpen(sqlite3_vfs*, const char *zDb, Log **ppLog); int sqlite3WalClose(Log *pLog, sqlite3_file *pFd, int sync_flags, u8 *zBuf); /* Used by readers to open (lock) and close (unlock) a snapshot. A ** snapshot is like a read-transaction. It is the state of the database ** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and ** preserves the current state even if the other threads or processes ** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the ** transaction and releases the lock. */ int sqlite3WalOpenSnapshot(Log *pLog, int *); void sqlite3WalCloseSnapshot(Log *pLog); /* Read a page from the write-ahead log, if it is present. */ int sqlite3WalRead(Log *pLog, Pgno pgno, int *pInLog, u8 *pOut); /* Return the size of the database as it existed at the beginning ** of the snapshot */ void sqlite3WalDbsize(Log *pLog, Pgno *pPgno); /* Obtain or release the WRITER lock. */ int sqlite3WalWriteLock(Log *pLog, int op); /* Undo any frames written (but not committed) to the log */ int sqlite3WalUndo(Log *pLog, int (*xUndo)(void *, Pgno), void *pUndoCtx); /* Return an integer that records the current (uncommitted) write ** position in the WAL */ u32 sqlite3WalSavepoint(Log *pLog); /* Move the write position of the WAL back to iFrame. Called in ** response to a ROLLBACK TO command. */ int sqlite3WalSavepointUndo(Log *pLog, u32 iFrame); /* Return true if data has been written but not committed to the log file. */ int sqlite3WalDirty(Log *pLog); /* Write a frame or frames to the log. */ int sqlite3WalFrames(Log *pLog, int, PgHdr *, Pgno, int, int); /* Copy pages from the log to the database file */ int sqlite3WalCheckpoint( Log *pLog, /* Log connection */ sqlite3_file *pFd, /* File descriptor open on db file */ int sync_flags, /* Flags to sync db file with (or 0) */ u8 *zBuf, /* Temporary buffer to use */ int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ ); /* Return the value to pass to a sqlite3_wal_hook callback, the ** number of frames in the WAL at the point of the last commit since ** sqlite3WalCallback() was called. If no commits have occurred since ** the last call, then return 0. */ int sqlite3WalCallback(Log *pLog); #endif /* _WAL_H_ */ |
Changes to test/tclsqlite.test.
︙ | ︙ | |||
31 32 33 34 35 36 37 | set v [catch {sqlite3 bogus} msg] regsub {really_sqlite3} $msg {sqlite3} msg lappend v $msg } [list 1 "wrong # args: should be \"$r\""] do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | set v [catch {sqlite3 bogus} msg] regsub {really_sqlite3} $msg {sqlite3} msg lappend v $msg } [list 1 "wrong # args: should be \"$r\""] do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg } {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, transaction, unlock_notify, update_hook, version, or wal_hook}} do_test tcl-1.2.1 { set v [catch {db cache bogus} msg] lappend v $msg } {1 {bad option "bogus": must be flush or size}} do_test tcl-1.2.2 { set v [catch {db cache} msg] lappend v $msg |
︙ | ︙ |
Changes to test/walhook.test.
︙ | ︙ | |||
21 22 23 24 25 26 27 | [lindex $args 0] eval { PRAGMA journal_mode = wal; PRAGMA synchronous = normal; PRAGMA page_size = 1024; } } sqlite3_wal db test.db | | | | | | | | | | | < | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | [lindex $args 0] eval { PRAGMA journal_mode = wal; PRAGMA synchronous = normal; PRAGMA page_size = 1024; } } sqlite3_wal db test.db db wal_hook wal_hook set ::wal_hook [list] proc wal_hook {zDb nEntry} { lappend ::wal_hook $zDb $nEntry return 0 } do_test walhook-1.1 { execsql { CREATE TABLE t1(i PRIMARY KEY, j) } set ::wal_hook } {main 3} do_test walhook-1.2 { set ::wal_hook [list] execsql { INSERT INTO t1 VALUES(1, 'one') } set ::wal_hook } {main 5} do_test walhook-1.3 { proc wal_hook {args} { return 1 } execsql { INSERT INTO t1 VALUES(2, 'two') } file size test.db } [expr 3*1024] do_test walhook-1.4 { proc wal_hook {zDb nEntry} { execsql { PRAGMA checkpoint } return 0 } execsql { CREATE TABLE t2(a, b) } file size test.db } [expr 4*1024] do_test walhook-1.5 { sqlite3_wal db2 test.db proc wal_hook {zDb nEntry} { execsql { PRAGMA checkpoint } db2 return 0 } execsql { CREATE TABLE t3(a PRIMARY KEY, b) } file size test.db } [expr 6*1024] catch { db2 close } catch { db close } finish_test |