Compare commits
115 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 33d87fcbed | |||
| 59967e2d2e | |||
| acf5e9d692 | |||
| ef39ae556c | |||
| d419d42238 | |||
| d6edcca767 | |||
| 8a9a68e2ae | |||
| b33a4fdffe | |||
| 35d09b26e2 | |||
| b9f41b4fd1 | |||
| e1436049d8 | |||
| 4e76b64969 | |||
| 78fffbf2c2 | |||
| 3314d12e03 | |||
| b2eb39ea15 | |||
| 1489c18b99 | |||
| 3aed0eb475 | |||
| ba1bce386c | |||
| 8f0e4e2a9c | |||
| 8a1c468c3c | |||
| 29b2fb1c52 | |||
| 8749d1c8e6 | |||
| fc73c50fec | |||
| 5fbe8d658f | |||
| 02d2493753 | |||
| edd972a2ed | |||
| 42b4259a4a | |||
| 8343a6bf5e | |||
| 4678255c4e | |||
| 0cb33b650c | |||
| 9817307d2f | |||
| 296c8cad4d | |||
| 40d50d1b0f | |||
| 2f1e7b8a74 | |||
| e0ba85df8b | |||
| 39ab1aef89 | |||
| 90defefb85 | |||
| 48249a7397 | |||
| ffa0ae9924 | |||
| 495cd6b419 | |||
| 7d59b89dc9 | |||
| aa09d0503d | |||
| 3a0022dad4 | |||
| 0d92f761ed | |||
| cc40f4ceb1 | |||
| aec336af26 | |||
| d74c576ee6 | |||
| 65f0fd40d6 | |||
| f9ae91deed | |||
| 8062d660f1 | |||
| b19e7036cd | |||
| 253df3a264 | |||
| 343811ce13 | |||
| 1b1b8325e1 | |||
| 027200ec51 | |||
| d819aea05f | |||
| e96ab66f34 | |||
| 2e4491d4b1 | |||
| 1b2327c509 | |||
| 66f6ad7b94 | |||
| b5f87f4394 | |||
| fbea85d6cd | |||
| b09945e64c | |||
| c3835e0208 | |||
| d736884f3d | |||
| 283f9e7ee6 | |||
| fa64665a49 | |||
| e127a2ea9f | |||
| 5be1b1f262 | |||
| 25d2380356 | |||
| 69d67f5412 | |||
| 6f7fe3ef3e | |||
| e3a4e11bcc | |||
| 67d225da53 | |||
| 5a5ced7da9 | |||
| 985be1bce6 | |||
| 99f24349ea | |||
| 890b69fb83 | |||
| f5d6f1e0c5 | |||
| 5ec0cfe070 | |||
| 3b3b1a538d | |||
| b0fa210aa3 | |||
| 801829c812 | |||
| 9b3c15e860 | |||
| 61d3bfb78b | |||
| 45d55a254b | |||
| 51e5db70b6 | |||
| f219bba933 | |||
| a0166e1873 | |||
| aff0449d8f | |||
| c55e9b815f | |||
| 03ba419b3c | |||
| c4098a3d9f | |||
| 21ce77989a | |||
| 91973abb4b | |||
| 722db051c6 | |||
| 87dd60cd8d | |||
| 7244fdc446 | |||
| 4f7e8fcded | |||
| 95063a5774 | |||
| ad7c2a87f5 | |||
| cc3ec7cb2b | |||
| 3942b4b147 | |||
| 9aa0012a08 | |||
| efd8e3b33d | |||
| 0b90b2209f | |||
| 9782039bde | |||
| 332aa832ce | |||
| bf4cad1e4c | |||
| b0c5edcd06 | |||
| 2250799f0c | |||
| ca071dfd75 | |||
| ac0c39980a | |||
| 04d4227255 | |||
| e6c3c72c1b |
+23
-10
@@ -57,7 +57,7 @@ LIBREADLINE = @TARGET_READLINE_LIBS@
|
||||
|
||||
# Should the database engine be compiled threadsafe
|
||||
#
|
||||
TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@
|
||||
#TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@
|
||||
|
||||
# Any target libraries which libsqlite must be linked against
|
||||
#
|
||||
@@ -108,7 +108,7 @@ TCLSH_CMD = @TCLSH_CMD@
|
||||
|
||||
# Where do we want to install the tcl plugin
|
||||
#
|
||||
TCLLIBDIR = @TCLLIBDIR@
|
||||
TCLLIBDIR = /System/Library/Tcl
|
||||
|
||||
# The suffix used on shared libraries. Ex: ".dll", ".so", ".dylib"
|
||||
#
|
||||
@@ -330,6 +330,9 @@ SRC += \
|
||||
SRC += \
|
||||
$(TOP)/ext/rtree/rtree.h \
|
||||
$(TOP)/ext/rtree/rtree.c
|
||||
SRC += \
|
||||
$(TOP)/ext/sqlrr/sqlrr.h \
|
||||
$(TOP)/ext/sqlrr/sqlrr.c
|
||||
|
||||
|
||||
# Generated source code files
|
||||
@@ -494,6 +497,17 @@ EXTHDR += \
|
||||
$(TOP)/ext/icu/sqliteicu.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/rtree/sqlite3rtree.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/sqlrr/sqlrr.h
|
||||
|
||||
# If using the amalgamation, use sqlite3.c directly to build the test
|
||||
# fixture. Otherwise link against libsqlite3.la. (This distinction is
|
||||
# necessary because the test fixture requires non-API symbols which are
|
||||
# hidden when the library is built via the amalgamation).
|
||||
#
|
||||
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
|
||||
TESTFIXTURE_SRC1 = sqlite3.c
|
||||
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c $(TESTFIXTURE_SRC$(USE_AMALGAMATION))
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
# are what get build when you type just "make" with no arguments.
|
||||
@@ -513,9 +527,8 @@ libsqlite3.la: $(LIBOBJ)
|
||||
libtclsqlite3.la: tclsqlite.lo libsqlite3.la
|
||||
$(LTLINK) -no-undefined -o $@ tclsqlite.lo \
|
||||
libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \
|
||||
-rpath "$(TCLLIBDIR)" \
|
||||
-version-info "8:6:8" \
|
||||
-avoid-version
|
||||
-rpath "$(TCLLIBDIR)/sqlite3" \
|
||||
-version-info "8:6:8"
|
||||
|
||||
sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
|
||||
$(LTLINK) $(READLINE_FLAGS) \
|
||||
@@ -963,12 +976,12 @@ install: sqlite3$(BEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_instal
|
||||
$(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir)
|
||||
|
||||
pkgIndex.tcl:
|
||||
echo 'package ifneeded sqlite3 $(RELEASE) [list load $(TCLLIBDIR)/libtclsqlite3.so sqlite3]' > $@
|
||||
echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join \$dir libtclsqlite3.so] Tclsqlite3]' > $@
|
||||
tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl
|
||||
$(INSTALL) -d $(DESTDIR)$(TCLLIBDIR)
|
||||
$(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)
|
||||
rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a
|
||||
$(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR)
|
||||
$(INSTALL) -d $(DESTDIR)$(TCLLIBDIR)/sqlite3
|
||||
$(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/sqlite3
|
||||
rm -f $(DESTDIR)$(TCLLIBDIR)/sqlite3/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/sqlite3/libtclsqlite3.a
|
||||
$(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR)/sqlite3
|
||||
|
||||
clean:
|
||||
rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
sqlrr - 10/19/2009
|
||||
|
||||
SQL Replay Recording
|
||||
|
||||
SUMMARY
|
||||
-------------------------------------------------------
|
||||
This extension enables recording sqlite API calls that access the database so that they can be replayed or examined.
|
||||
|
||||
USAGE
|
||||
------------------------------------------------------
|
||||
Recording is enabled by compiling sqlite with symbolic constant SQLITE_ENABLE_SQLRR defined.
|
||||
By default logs are written to /tmp/<databasename>_<pid>_<connection_number>.sqlrr, to choose another directory, set the environment variable SQLITE_REPLAY_RECORD_DIR to that path.
|
||||
|
||||
FILE FORMAT
|
||||
-----------------------------------------------------
|
||||
file: <header>[<sql-command>]*
|
||||
|
||||
header: <signature><format-version>
|
||||
signature: SQLRR (5 bytes)
|
||||
format-version: n (1 byte)
|
||||
|
||||
sql-command: <timestamp><type><arg-data>
|
||||
timestamp: n (16 bytes)
|
||||
type: n (1 byte)
|
||||
open 0
|
||||
close 1
|
||||
exec 8
|
||||
bind-text 16
|
||||
bind-double 17
|
||||
bind-int 18
|
||||
bind-null 19
|
||||
bind-value 20
|
||||
bind-clear 21
|
||||
prep 32
|
||||
step 33
|
||||
reset 34
|
||||
finalize 35
|
||||
|
||||
open-arg-data: <connection><path><flags>
|
||||
close-arg-data: <connection>
|
||||
exec-arg-data: <connection><len><statement-text>
|
||||
bind-text-arg-data: <statement-ref><index><len><data>
|
||||
bind-double-arg-data: <statement-ref><index><data>
|
||||
bind-int-arg-data: <statement-ref><index><data>
|
||||
bind-null-arg-data: <statement-ref><index>
|
||||
bind-value-arg-data: <statement-ref><index><len><data> ???
|
||||
bind-clear-arg-data: <statement-ref>
|
||||
prep-arg-data: <connection><len><statement-text>
|
||||
step-arg-data: <statement-ref>
|
||||
reset-arg-data: <statement-ref>
|
||||
finalize-arg-data: <statement-ref>
|
||||
|
||||
NOTES
|
||||
@@ -0,0 +1,581 @@
|
||||
/*
|
||||
* sqlrr.c
|
||||
*/
|
||||
|
||||
#include "sqlrr.h"
|
||||
|
||||
#if defined(SQLITE_ENABLE_SQLRR)
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
#include "sqliteInt.h"
|
||||
#include "vdbeInt.h"
|
||||
|
||||
#define LOGSUFFIXLEN 48
|
||||
|
||||
/*
|
||||
* Data types
|
||||
*/
|
||||
typedef struct SRRLogRef SRRLogRef;
|
||||
struct SRRLogRef {
|
||||
int fd;
|
||||
sqlite3 *db;
|
||||
const char *dbPath;
|
||||
char *logPath;
|
||||
int connection;
|
||||
int depth;
|
||||
SRRLogRef *nextRef;
|
||||
};
|
||||
|
||||
/*
|
||||
* Globals
|
||||
*/
|
||||
SRRLogRef *logRefHead = NULL;
|
||||
int dbLogCount = 0;
|
||||
static int srr_enabled = 1;
|
||||
pthread_mutex_t srr_log_mutex;
|
||||
static volatile int32_t srr_initialized = 0;
|
||||
|
||||
/*
|
||||
* Log management
|
||||
*/
|
||||
extern void SRRecInitialize() {
|
||||
int go = OSAtomicCompareAndSwap32Barrier(0, 1, &srr_initialized);
|
||||
if( go ){
|
||||
pthread_mutex_init(&srr_log_mutex, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static SRRLogRef *createLog(sqlite3 *db, const char *dbPath) {
|
||||
SRRLogRef *ref = NULL;
|
||||
char *baseDir = getenv("SQLITE_REPLAY_RECORD_DIR");
|
||||
char logPath[MAXPATHLEN] = "";
|
||||
char suffix[LOGSUFFIXLEN] = "";
|
||||
const char *dbName = dbPath;
|
||||
int len = 0;
|
||||
int index = 0;
|
||||
int fd = -1;
|
||||
size_t out;
|
||||
unsigned char version = SRR_FILE_VERSION;
|
||||
|
||||
SRRecInitialize();
|
||||
|
||||
/* construct the path for the log file
|
||||
* ${SQLITE_REPLAY_DIR}/<dbname>_<pid>_<connection_number>.sqlrr
|
||||
*/
|
||||
if (baseDir == NULL) {
|
||||
baseDir = "/tmp"; /* getenv(TMPDIR) */
|
||||
}
|
||||
len = strlen(baseDir);
|
||||
strlcat(logPath, baseDir, MAXPATHLEN);
|
||||
if ((len>0) && (baseDir[len-1] != '/')) {
|
||||
strlcat(logPath, "/", MAXPATHLEN);
|
||||
}
|
||||
len = strlen(dbPath);
|
||||
for (index = len-2; index >= 0; index --){
|
||||
if (dbPath[index] == '/') {
|
||||
dbName = &dbPath[index+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
strlcat(logPath, dbName, MAXPATHLEN);
|
||||
int cNum = ++dbLogCount;
|
||||
snprintf(suffix, sizeof(suffix), "_%d_%d_XXXX.sqlrr", getpid(), cNum);
|
||||
len = strlcat(logPath, suffix, MAXPATHLEN);
|
||||
/* make it unique if we have the space */
|
||||
if ((len + 1) < MAXPATHLEN) {
|
||||
fd = mkstemps(logPath, 6);
|
||||
} else {
|
||||
fprintf(stderr, "Failed to create sqlite replay log path for %s [%s]\n", dbPath, logPath);
|
||||
return NULL;
|
||||
}
|
||||
if (fd == -1) {
|
||||
fprintf(stderr, "Failed to create sqlite replay log file for %s with path %s [%s]\n", dbPath, logPath, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
fprintf(stdout, "Writing sqlite replay log file %s\n", logPath);
|
||||
out = write(fd, SRR_FILE_SIGNATURE, SRR_FILE_SIGNATURE_LEN);
|
||||
if (out!=-1) {
|
||||
out = write(fd, &version, 1);
|
||||
}
|
||||
if (out == -1){
|
||||
fprintf(stderr, "Write failure on log [%s]: %s\n", logPath, strerror(errno));
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = strlen(logPath) + 1;
|
||||
ref = (SRRLogRef *)malloc(sizeof(SRRLogRef));
|
||||
|
||||
ref->db = db;
|
||||
ref->dbPath = dbPath;
|
||||
ref->logPath = (char *)malloc(len * sizeof(char));
|
||||
strlcpy(ref->logPath, logPath, len);
|
||||
ref->fd = fd;
|
||||
ref->connection = cNum;
|
||||
ref->depth = 0;
|
||||
|
||||
pthread_mutex_lock(&srr_log_mutex);
|
||||
ref->nextRef = logRefHead;
|
||||
logRefHead = ref;
|
||||
pthread_mutex_unlock(&srr_log_mutex);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static void closeLog(sqlite3 *db) {
|
||||
SRRLogRef *ref = NULL;
|
||||
SRRLogRef *lastRef = NULL;
|
||||
|
||||
pthread_mutex_lock(&srr_log_mutex);
|
||||
for (ref = logRefHead; ref != NULL; ref = ref->nextRef) {
|
||||
if (ref->db == db) {
|
||||
if (lastRef == NULL) {
|
||||
logRefHead = ref->nextRef;
|
||||
} else {
|
||||
lastRef->nextRef = ref->nextRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&srr_log_mutex);
|
||||
|
||||
if (ref != NULL) {
|
||||
fprintf(stdout, "Closing sqlite replay log file %s\n", ref->logPath);
|
||||
close(ref->fd);
|
||||
free(ref->logPath);
|
||||
free(ref);
|
||||
}
|
||||
}
|
||||
|
||||
static SRRLogRef *getLog(sqlite3 *db) {
|
||||
pthread_mutex_lock(&srr_log_mutex);
|
||||
SRRLogRef *ref = logRefHead;
|
||||
for (ref = logRefHead; ref != NULL; ref = ref->nextRef) {
|
||||
if (ref->db == db) {
|
||||
pthread_mutex_unlock(&srr_log_mutex);
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&srr_log_mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SQLite recording API
|
||||
*/
|
||||
void SQLiteReplayRecorder(int flag) {
|
||||
srr_enabled = flag;
|
||||
}
|
||||
|
||||
// open-arg-data: <connection><len><path><flags>
|
||||
void _SRRecOpen(sqlite3 *db, const char *path, int flags) {
|
||||
if (!srr_enabled) return;
|
||||
if (db) {
|
||||
SRRLogRef *ref = createLog(db, path);
|
||||
if (ref) {
|
||||
SRRCommand code = SRROpen;
|
||||
int len = strlen(path);
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out=write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) { out=write(ref->fd, &(ref->connection), sizeof(ref->connection)); }
|
||||
if (out!=-1) { out=write(ref->fd, &len, sizeof(len)); }
|
||||
if (out!=-1) { out=write(ref->fd, path, len); }
|
||||
if (out!=-1) { out=write(ref->fd, &flags, sizeof(flags)); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing open to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//close-arg-data: <connection>
|
||||
void SRRecClose(sqlite3 *db) {
|
||||
if (!srr_enabled) return;
|
||||
if (db) {
|
||||
SRRLogRef *ref = getLog(db);
|
||||
if (ref) {
|
||||
SRRCommand code = SRRClose;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) { out = write(ref->fd, &(ref->connection), sizeof(ref->connection)); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing close to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
}
|
||||
closeLog(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// exec-arg-data: <connection><len><statement-text>
|
||||
void SRRecExec(sqlite3 *db, const char *sql) {
|
||||
if (!srr_enabled) return;
|
||||
if (db) {
|
||||
SRRLogRef *ref = getLog(db);
|
||||
if (ref) {
|
||||
if (ref->depth == 0) {
|
||||
SRRCommand code = SRRExec;
|
||||
int len = strlen(sql);
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
ref->depth = 1;
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) { out = write(ref->fd, &(ref->connection), sizeof(ref->connection)); }
|
||||
if (out!=-1) { out = write(ref->fd, &len, sizeof(len)); }
|
||||
if (out!=-1) { out = write(ref->fd, sql, len); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing exec to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(db);
|
||||
}
|
||||
} else {
|
||||
ref->depth ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SRRecExecEnd(sqlite3 *db) {
|
||||
if (!srr_enabled) return;
|
||||
if (db) {
|
||||
SRRLogRef *ref = getLog(db);
|
||||
if (ref) {
|
||||
ref->depth --;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prep-arg-data: <connection><len><statement-text><savesql><statement-ref>
|
||||
void _SRRecPrepare(sqlite3 *db, const char *sql, int nBytes, int saveSql, sqlite3_stmt *pStmt) {
|
||||
if (!srr_enabled) return;
|
||||
if ((db!=NULL)&&(pStmt!=NULL)) {
|
||||
SRRLogRef *ref = getLog(db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRPrepare;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
int sqlLen = nBytes;
|
||||
|
||||
if (sqlLen == -1) {
|
||||
sqlLen = strlen(sql);
|
||||
}
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) { out = write(ref->fd, &(ref->connection), sizeof(ref->connection)); }
|
||||
if (out!=-1) { out = write(ref->fd, &sqlLen, sizeof(sqlLen)); }
|
||||
if (out!=-1) { out = write(ref->fd, sql, sqlLen); }
|
||||
if (out!=-1) { out = write(ref->fd, &saveSql, sizeof(saveSql)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing prepare to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//step-arg-data: <statement-ref>
|
||||
void SRRecStep(sqlite3_stmt *pStmt) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref) {
|
||||
if (ref->depth == 0) {
|
||||
SRRCommand code = SRRStep;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
ref->depth = 1;
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing step to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
} else {
|
||||
ref->depth ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SRRecStepEnd(sqlite3_stmt *pStmt) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref) {
|
||||
ref->depth --;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reset-arg-data: <statement-ref>
|
||||
void SRRecReset(sqlite3_stmt *pStmt) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRReset;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing reset to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finalize-arg-data: <statement-ref>
|
||||
void SRRecFinalize(sqlite3_stmt *pStmt) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRFinalize;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing finalize to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-text-arg-data: <statement-ref><index><len><data>
|
||||
void SRRecBindText(sqlite3_stmt *pStmt, int i, const char *zData, int64_t nData) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRBindText;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
int64_t textLen = nData;
|
||||
if (textLen == -1) {
|
||||
textLen = strlen(zData);
|
||||
}
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
|
||||
if (out!=-1) { out = write(ref->fd, &textLen, sizeof(textLen)); }
|
||||
if (out!=-1) { out = write(ref->fd, zData, textLen); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing bind text to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-blob-arg-data: <statement-ref><index><len>[<data>]
|
||||
void SRRecBindBlob(sqlite3_stmt *pStmt, int i, const char *zData, int64_t nData) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRBindBlob;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
|
||||
if (zData == NULL) {
|
||||
int64_t negNData = -nData;
|
||||
if (out!=-1) { out = write(ref->fd, &negNData, sizeof(negNData)); }
|
||||
} else {
|
||||
if (out!=-1) { out = write(ref->fd, &nData, sizeof(nData)); }
|
||||
if (out!=-1) { out = write(ref->fd, zData, nData); }
|
||||
}
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing bind blob to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-double-arg-data: <statement-ref><index><data>
|
||||
void SRRecBindDouble(sqlite3_stmt *pStmt, int i, double value) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRBindDouble;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
|
||||
if (out!=-1) { out = write(ref->fd, &value, sizeof(value)); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing bind double to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-int-arg-data: <statement-ref><index><data>
|
||||
void SRRecBindInt64(sqlite3_stmt *pStmt, int i, int64_t value) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRBindInt;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
|
||||
if (out!=-1) { out = write(ref->fd, &value, sizeof(value)); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing bind int to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-null-arg-data: <statement-ref><index>
|
||||
void SRRecBindNull(sqlite3_stmt *pStmt, int i) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRBindNull;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing bind null to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-value-arg-data: <statement-ref><index><len><data> ???
|
||||
void SRRecBindValue(sqlite3_stmt *pStmt, int i, const sqlite3_value *value) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
fprintf(stderr, "SRRecBindValue(sqlite3_bind_value) is not yet supported, closing [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-clear-arg-data: <statement-ref>
|
||||
void SRRecClearBindings(sqlite3_stmt *pStmt) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRBindClear;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing clear bindings to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SQLITE_ENABLE_SQLRR */
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* sqlrr.h
|
||||
*/
|
||||
|
||||
#ifndef _SQLRR_H_
|
||||
#define _SQLRR_H_
|
||||
|
||||
/*
|
||||
** Header constants
|
||||
*/
|
||||
#define SRR_FILE_SIGNATURE "SQLRR"
|
||||
#define SRR_FILE_SIGNATURE_LEN 5
|
||||
#define SRR_FILE_VERSION 0x1
|
||||
#define SRR_FILE_VERSION_LEN 1
|
||||
|
||||
#if defined(SQLITE_ENABLE_SQLRR)
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#define SRRecOpen(A,B,C) if(!rc){_SRRecOpen(A,B,C);}
|
||||
#define SRRecPrepare(A,B,C,D,E) if(!rc){_SRRecPrepare(A,B,C,D,E);}
|
||||
|
||||
typedef enum {
|
||||
SRROpen = 0,
|
||||
SRRClose = 1,
|
||||
SRRExec = 8,
|
||||
SRRBindText = 16,
|
||||
SRRBindBlob = 17,
|
||||
SRRBindDouble = 18,
|
||||
SRRBindInt = 19,
|
||||
SRRBindNull = 20,
|
||||
SRRBindValue = 21,
|
||||
SRRBindClear = 22,
|
||||
SRRPrepare = 32,
|
||||
SRRStep = 33,
|
||||
SRRReset = 34,
|
||||
SRRFinalize = 35
|
||||
} SRRCommand;
|
||||
|
||||
extern void SQLiteReplayRecorder(int flag);
|
||||
extern void _SRRecOpen(sqlite3 *db, const char *path, int flags);
|
||||
extern void SRRecClose(sqlite3 *db);
|
||||
extern void SRRecExec(sqlite3 *db, const char *sql);
|
||||
extern void SRRecExecEnd(sqlite3 *db);
|
||||
extern void _SRRecPrepare(sqlite3 *db, const char *sql, int nBytes, int saveSql, sqlite3_stmt *stmt);
|
||||
extern void SRRecStep(sqlite3_stmt *pStmt);
|
||||
extern void SRRecStepEnd(sqlite3_stmt *pStmt);
|
||||
extern void SRRecReset(sqlite3_stmt *pStmt);
|
||||
extern void SRRecFinalize(sqlite3_stmt *pStmt);
|
||||
extern void SRRecBindText(sqlite3_stmt *pStmt, int i, const char *zData, int64_t nData);
|
||||
extern void SRRecBindBlob(sqlite3_stmt *pStmt, int i, const char *zData, int64_t nData);
|
||||
extern void SRRecBindDouble(sqlite3_stmt *pStmt, int i, double value);
|
||||
extern void SRRecBindInt64(sqlite3_stmt *pStmt, int i, int64_t value);
|
||||
extern void SRRecBindNull(sqlite3_stmt *pStmt, int i);
|
||||
extern void SRRecBindValue(sqlite3_stmt *pStmt, int i, const sqlite3_value *value);
|
||||
extern void SRRecClearBindings(sqlite3_stmt *pStmt);
|
||||
|
||||
#endif /* defined(SQLITE_ENABLE_SQLRR) */
|
||||
|
||||
#endif /* _SQLRR_H_ */
|
||||
@@ -213,6 +213,8 @@ SRC += \
|
||||
$(TOP)/ext/rtree/sqlite3rtree.h \
|
||||
$(TOP)/ext/rtree/rtree.h \
|
||||
$(TOP)/ext/rtree/rtree.c
|
||||
SRC += \
|
||||
$(TOP)/ext/sqlrr/sqlrr.c
|
||||
|
||||
|
||||
# Generated source code files
|
||||
@@ -358,22 +360,7 @@ HDR = \
|
||||
# Header files used by extensions
|
||||
#
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/fts1/fts1.h \
|
||||
$(TOP)/ext/fts1/fts1_hash.h \
|
||||
$(TOP)/ext/fts1/fts1_tokenizer.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/fts2/fts2.h \
|
||||
$(TOP)/ext/fts2/fts2_hash.h \
|
||||
$(TOP)/ext/fts2/fts2_tokenizer.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/fts3/fts3.h \
|
||||
$(TOP)/ext/fts3/fts3Int.h \
|
||||
$(TOP)/ext/fts3/fts3_hash.h \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/rtree/rtree.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/icu/sqliteicu.h
|
||||
$(TOP)/ext/sqlrr/sqlrr.h
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
# are what get build when you type just "make" with no arguments.
|
||||
@@ -402,10 +389,10 @@ sqlite3.o: sqlite3.c
|
||||
# files are automatically generated. This target takes care of
|
||||
# all that automatic generation.
|
||||
#
|
||||
target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl
|
||||
target_source: $(SRC) $(EXTHDR) $(TOP)/tool/vdbe-compress.tcl
|
||||
rm -rf tsrc
|
||||
mkdir tsrc
|
||||
cp -f $(SRC) tsrc
|
||||
cp -f $(SRC) $(EXTHDR) tsrc
|
||||
rm tsrc/sqlite.h.in tsrc/parse.y
|
||||
tclsh $(TOP)/tool/vdbe-compress.tcl $(OPTS) <tsrc/vdbe.c >vdbe.new
|
||||
mv vdbe.new tsrc/vdbe.c
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
C Fix\sa\sproblem\sthat\swas\scausing\sthe\sFTS4\sintegrity-check\scommand\sto\sfail\sif\sthe\stable\shad\sone\sor\smore\s"notindexed"\scolumns.
|
||||
D 2014-06-05T11:15:56.350
|
||||
C Detect\sand\ssuppress\san\sendless\sloops\sin\sclearDatabasePage()\sthat\smight\sresult\nfrom\sa\scorrupt\sdatabase\sfile.\s\sThis\sis\san\sedited\scherry-pick\sfrom\n[30011ad2f55c]\sand\s[395bb3e677a].
|
||||
D 2015-04-06T22:05:23.198
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670
|
||||
F Makefile.in 444faa7b5c5b3189fa674ff42be94d87a37eba9d
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc 52911c6bfeaf9b40f47ef4615ab66d98ab0f2b3d
|
||||
F Makefile.vxworks 034289efa9d591b04b1a73598623119c306cbba0
|
||||
@@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
||||
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 6f70db93e0e42c369325c5cddcf2024c5a87ca43
|
||||
F ext/rtree/rtree.c 8884ffb0db17df33084b0ae2d475427a4276e383
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
F ext/rtree/rtree1.test e2da4aaa426918d27122d1a1066c6ecf8409a514
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
@@ -141,10 +141,13 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
|
||||
F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd
|
||||
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||
F ext/sqlrr/README.txt 4239030e73023e72a2e727808cd433577d5bf730
|
||||
F ext/sqlrr/sqlrr.c 8d1e6571cd6a6beabdb5bcdfe3a0e723b914db41
|
||||
F ext/sqlrr/sqlrr.h 09e4f8929ad9bc2638732c0cc0db5eef8c417824
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt f439556c5ce01ced70987e5ee86549a45165d9ff
|
||||
F main.mk cfa185eed4e0f7e9d28a2e3167cecaa9d6cb39f3
|
||||
F main.mk 8400550fd8065095031ba4ecadf355d184a81282
|
||||
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
|
||||
F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
@@ -165,9 +168,9 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c 70c60a3807b2072982f184d9614e020d2953f89c
|
||||
F src/btree.c 02064f49cd18e8d6ca0218fce6542218fded1128
|
||||
F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a
|
||||
F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3
|
||||
F src/btreeInt.h 53a774709449d704ef72f69fa5ccba17e2acb67a
|
||||
F src/build.c 927e39b6aaf872c7b28f154f6acfeb9a05a72442
|
||||
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
|
||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||
@@ -177,17 +180,17 @@ F src/delete.c bcf8f72126cea80fc3d5bc5494cf19b3f8935aaf
|
||||
F src/expr.c 4f9e497c66e2f25a4d139357a778c84d5713207c
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c a549cff9fe8b736cdae21650ea0af6de29b77619
|
||||
F src/func.c 2e16316ec3a6365a0dc3e553c586f91b20f7f6c8
|
||||
F src/func.c 6ace0c0c0d5f0a23273a0c74b35b5f41113f09eb
|
||||
F src/global.c 1e4bd956dc2f608f87d2a929abc4a20db65f30e4
|
||||
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
|
||||
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c a038daeadfb818aaadafa854f40f5623b6929d84
|
||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
||||
F src/legacy.c 17887cec559966b62ab3673a02c427338483b147
|
||||
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
||||
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
|
||||
F src/main.c 40d0837e5d0597eadc47c3acc2fc95bdbd9250b8
|
||||
F src/main.c a0c13683598252e3d5edda0459e972cd52616b0b
|
||||
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
|
||||
@@ -201,36 +204,37 @@ F src/mutex_noop.c 7682796b7d8d39bf1c138248858efcd10c9e1553
|
||||
F src/mutex_unix.c c3a4e00f96ba068a8dbef34084465979aaf369cc
|
||||
F src/mutex_w32.c 9bcab6e699fdb20eae784237c36b299830fb3316
|
||||
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
|
||||
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
|
||||
F src/os.c 25df79baf4bec87f75a2c4e995d63361b66b918a
|
||||
F src/os.h 60d419395e32a8029fa380a80a3da2e9030f635e
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c ae4b5240af4619d711301d7992396e182585269f
|
||||
F src/os_win.c 8dbf6c11780fe2eb96c1f289e664d0c7b2911d37
|
||||
F src/os_unix.c 6a54dad9ffb25faaa81604a3eebedeb04da9b639
|
||||
F src/os_win.c 43b075157eb17440a1813a14332fc8623d7c4554
|
||||
F src/os_win.h 057344a6720b4c8405d9bd98f58cb37a6ee46c25
|
||||
F src/pager.c f6bb1fa6cdf2062f2d8aec3e64db302bca519ab8
|
||||
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
|
||||
F src/pager.c d878c40eb8c75e9ae79b00cc80ad9710679f9a31
|
||||
F src/pager.h 8feb18f845951ab37e1f65a319b2da24185173ac
|
||||
F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0
|
||||
F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2
|
||||
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
||||
F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c
|
||||
F src/pragma.c 810ef31ccfaa233201dcf100637a9777cc24e897
|
||||
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
|
||||
F src/pragma.c 039578fb7d7cad90a5a2269651ad3b1ad98451cc
|
||||
F src/prepare.c 954f80160f120ca715ffa5db5549c3262abb335e
|
||||
F src/printf.c af06f66927919730f03479fed6ae9854f73419f4
|
||||
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
|
||||
F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
|
||||
F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
|
||||
F src/select.c 6762c62e11b504aa014edceab8886495165e3a77
|
||||
F src/select.c a34db38f97bd8fe768d0bd9315397457c98be185
|
||||
F src/shell.c 98ce7f52445aa0c2eac3d4553a4cdcbb6402a670
|
||||
F src/sqlite.h.in a98eb3e8c86c934ea6f5bcfc6b69653dde2f4ed4
|
||||
F src/sqlite.h.in 69c7d92c615945a7053cb899c6ae6a6a0fc36cca
|
||||
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
||||
F src/sqlite3_private.h a81a9c5f97c095cc3e86914a05f8fabe0011f4a1
|
||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||
F src/sqliteInt.h fccdc735c27b3dc12322fec7cdad8bc76be8d00b
|
||||
F src/sqliteInt.h 6b40bb90f547ef70d78cf43d9d1b4e5656e9eb1b
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
F src/tclsqlite.c e87c99e28a145943666b51b212dacae35fcea0bd
|
||||
F src/test1.c 4edf8810c86d77ae7ac6d56d563965a9beeea2ce
|
||||
F src/test1.c f9d10a5bab1eb1b10f6f5049b68a2662a8986b6d
|
||||
F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712
|
||||
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
|
||||
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
|
||||
@@ -241,9 +245,9 @@ F src/test8.c 54ccd7b1df5062f0ecbf50a8f7b618f8b1f13b20
|
||||
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
|
||||
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
|
||||
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
|
||||
F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e
|
||||
F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803
|
||||
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
|
||||
F src/test_config.c dabaa32868974e1ae39770cc17d7e066a9c38e6d
|
||||
F src/test_config.c 15c77838d6646644362c8ec13348f9889d6e37b0
|
||||
F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9
|
||||
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
||||
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
|
||||
@@ -263,12 +267,12 @@ F src/test_osinst.c 3d0340bc31a9f3d8a3547e0272373e80f78dde25
|
||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||
F src/test_quota.c 65f6348fec0f2b3020c907247fb47556b214abb9
|
||||
F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d
|
||||
F src/test_rtree.c fdd8d29ca5165c7857987a2ba263fac5c69e231f
|
||||
F src/test_rtree.c bfe6f4386517f70054311109f3528adffec34485
|
||||
F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6
|
||||
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
||||
F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e
|
||||
F src/test_stat.c 9898687a6c2beca733b0dd6fe19163d987826d31
|
||||
F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
|
||||
F src/test_superlock.c 12e2bc484c6c2ba837327d37f2e6a6fd9d1464f8
|
||||
F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b
|
||||
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
||||
F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
|
||||
@@ -281,22 +285,22 @@ F src/update.c 01564b3c430f6c7b0a35afaf7aba7987206fa3a5
|
||||
F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c
|
||||
F src/util.c 049fe1d3c0e2209c1bee107aec2fcff6285f909f
|
||||
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
||||
F src/vdbe.c 9bfe6becfc094382ae213656fbe511055ad83a54
|
||||
F src/vdbe.c 9156499280d12b1afec8c59ef05ace8593295639
|
||||
F src/vdbe.h 394464909ed682334aa3d5831aae0c2fe2abef94
|
||||
F src/vdbeInt.h e6d83e5bfd62fc6685ba1ed6153f7099f82de9f7
|
||||
F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4
|
||||
F src/vdbeaux.c e493f38758c4b8f4ca2007cf6a700bd405d192f3
|
||||
F src/vdbeapi.c 32a443608642a93b77ca4b13e42e2a4d7b0fc123
|
||||
F src/vdbeaux.c a82cfad30a3b4c1758c28dcee2b4fc20a70cd121
|
||||
F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac
|
||||
F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447
|
||||
F src/vdbesort.c 44441d73b08b3a638dcdb725afffb87c6574ad27
|
||||
F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
|
||||
F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
|
||||
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/wal.c 29854e652a9d7dc0d7a87ff1a9dbffac0aaf2e16
|
||||
F src/wal.h 6b3a67ecd7172dcc9f18fc9cd4d76dc4c2166e68
|
||||
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
|
||||
F src/where.c a7d59dd5d5bf6d6ab905fb549567a0a11376de25
|
||||
F src/whereInt.h 929c1349b5355fd44f22cee5c14d72b3329c58a6
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/8_3_names.test 05034aadccd2253ffe6cbefb06662b8aa4600f77
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||
@@ -323,10 +327,10 @@ F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
|
||||
F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a
|
||||
F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0
|
||||
F test/atof1.test 08a61df9365c341f334a65f4348897312d8f3db7
|
||||
F test/attach.test 0d112b7713611fdf0340260192749737135fda5f
|
||||
F test/attach.test 63033baa59be42c811ef0d4e73ebd2d6dba4805c
|
||||
F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d
|
||||
F test/attach3.test 359eb65d00102cdfcef6fa4e81dc1648f8f80b27
|
||||
F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c
|
||||
F test/attach4.test faaaf33fa51f986b414520cb03cecdc7999df108
|
||||
F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0
|
||||
F test/auth.test 5bdf154eb28c0e4bbc0473f335858c0d96171768
|
||||
F test/auth2.test c3b415b76c033bedb81292118fb7c01f5f10cbcd
|
||||
@@ -349,7 +353,7 @@ F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
|
||||
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
|
||||
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
|
||||
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
|
||||
F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c
|
||||
F test/bind.test 30af0fc61bc3836034215cdbdeca46113ca1b4a1
|
||||
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
|
||||
F test/bitvec.test 75894a880520164d73b1305c1c3f96882615e142
|
||||
F test/blob.test e7ac6c7d3a985cc4678c64f325292529a69ae252
|
||||
@@ -363,7 +367,7 @@ F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983
|
||||
F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
|
||||
F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
|
||||
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
||||
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||
F test/cache.test 0bc2195f4a7207108af2617ed356e77daf4412f7
|
||||
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
|
||||
F test/capi3.test 71bcf2fbd36a9732f617766dfd752552c8e491b5
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
@@ -409,6 +413,7 @@ F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
|
||||
F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804
|
||||
F test/corruptH.test 88ed71a086e13591c917aac6de32750e7c7281cb
|
||||
F test/corruptI.test b3e4203d420490fc3d3062711597bc1dea06a789
|
||||
F test/corruptJ.test e78438baca4f2a24b2547a0e16fb462b99f42522
|
||||
F test/cost.test 19d314526616ce4473eb4e4e450fcb94499ce318
|
||||
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
|
||||
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
|
||||
@@ -426,7 +431,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
|
||||
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
|
||||
F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0
|
||||
F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
|
||||
F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2
|
||||
F test/dbstatus2.test fc968d3005b4d827eba807a06573a6c528aa119a
|
||||
F test/default.test 792c3c70836f1901e2a8cb34fa0880ed71e2c1a9
|
||||
F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701
|
||||
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
||||
@@ -459,12 +464,12 @@ F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
|
||||
F test/eqp.test 85873fa5816c48915c82c4e74cb5c35a5b48160f
|
||||
F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401
|
||||
F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
|
||||
F test/exclusive.test c7ebbc756eacf544c108b15eed64d7d4e5f86b75
|
||||
F test/exclusive.test c0d5e3c0756ac6ccd4d45e0b21ff9f01b963fa61
|
||||
F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308
|
||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
|
||||
F test/expr.test 67c9fd6f8f829e239dc8b0f4a08a73c08b09196d
|
||||
F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7
|
||||
F test/fallocate.test fe52076a43ff99da8411990dbb4f374e81e88c85
|
||||
F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a
|
||||
F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146
|
||||
F test/fkey1.test e1d1fa84cde579185ea01358436839703e415a5b
|
||||
@@ -604,12 +609,12 @@ F test/in4.test 41c1c031aa46b1eb4411df2687ed2ed498da23b5
|
||||
F test/in5.test 99f9a40af01711b06d2d614ecfe96129f334fba3
|
||||
F test/incrblob.test e81846d214f3637622620fbde7cd526781cfe328
|
||||
F test/incrblob2.test bf4d549aa4a466d7fbe3e3a3693d3861263d5600
|
||||
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
|
||||
F test/incrblob3.test 5fa6f2665ae37da05928bb16851d4f86515af78a
|
||||
F test/incrblob4.test f26502a5697893e5acea268c910f16478c2f0fab
|
||||
F test/incrblob_err.test d2562d2771ebffd4b3af89ef64c140dd44371597
|
||||
F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e
|
||||
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
|
||||
F test/incrvacuum2.test 379eeb8740b0ef60c372c439ad4cbea20b34bb9b
|
||||
F test/incrvacuum2.test a1828b6165af6c248c4eb80aeaee2bcbb45768c1
|
||||
F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
|
||||
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
|
||||
F test/index.test 4d990005a67a36984e4f1a5f1bdccea8d08da4ee
|
||||
@@ -646,7 +651,7 @@ F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
|
||||
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
|
||||
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
|
||||
F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1
|
||||
F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
|
||||
F test/journal3.test ef775301aa8c64c80efa859e6aa0207add921a93
|
||||
F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36
|
||||
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
@@ -662,12 +667,13 @@ F test/lock.test 87af515b0c4cf928576d0f89946d67d7c265dfb4
|
||||
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
|
||||
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
|
||||
F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12
|
||||
F test/lock5.test 5ad6a1f536036ff1be915cfdd41481aeafda3273
|
||||
F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5
|
||||
F test/lock5.test 71d0ba9cd23212b5ce1a433107c806203fa6d5f9
|
||||
F test/lock6.test 83434ae8ca1d1c5e2eaf74d4e44aa24ab62b291c
|
||||
F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431
|
||||
F test/lock_common.tcl 0c270b121d40959fa2f3add382200c27045b3d95
|
||||
F test/lock_proxy.test 95be9c32d79be25cf643b4e41a0aa0e53aa21621
|
||||
F test/lookaside.test 93f07bac140c5bb1d49f3892d2684decafdc7af2
|
||||
F test/main.test 39c4bb8a157f57298ed1659d6df89d9f35aaf2c8
|
||||
F test/main.test 3991157c720c2b2b9ec27254d940f06ab81aab84
|
||||
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
|
||||
F test/malloc.test fd368e31fe98d4779ed80442f311ed9f03bcd1f7
|
||||
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
|
||||
@@ -689,12 +695,12 @@ F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb
|
||||
F test/mallocI.test a88c2b9627c8506bf4703d8397420043a786cdb6
|
||||
F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e
|
||||
F test/mallocK.test d79968641d1b70d88f6c01bdb9a7eb4a55582cc9
|
||||
F test/malloc_common.tcl 58e54229c4132ef882a11fab6419ec4cd3073589
|
||||
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/malloc_common.tcl e0fbe63a9a0bb8c42fe8d3ebf502141f485acbc2
|
||||
F test/manydb.test 3cd8e52ab3112cb8365afeedd6e8231977920577
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
F test/memdb.test fcb5297b321b562084fc79d64d5a12a1cd2b639b
|
||||
F test/memdb.test da09b7f354f3dc0b74d992f5451ae03ebfb36920
|
||||
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
|
||||
F test/memsubsys1.test f97cfd0b30e85c2f1ed16d642e7ac58006be84b2
|
||||
F test/memsubsys1.test 04b6c76f91070bbb7cb8713cd51882d6e49f7530
|
||||
F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
|
||||
F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
|
||||
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
|
||||
@@ -712,7 +718,7 @@ F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b
|
||||
F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022
|
||||
F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e
|
||||
F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3
|
||||
F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256
|
||||
F test/multiplex.test 85a4be2b23e7294d468b6e3a578ec00020723bee
|
||||
F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
|
||||
F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101
|
||||
F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41
|
||||
@@ -734,20 +740,20 @@ F test/orderby5.test 8f08a54836d21fb7c70245360751aedd1c2286fb
|
||||
F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
|
||||
F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
|
||||
F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
|
||||
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
|
||||
F test/pager1.test 1c39b52a036afd0813fdd47c9d2ebc83dec8fd90
|
||||
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
||||
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
|
||||
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
|
||||
F test/pagerfault.test ae9ee0db5a30aecda9db8290ce3dd12e5f7bbaa1
|
||||
F test/pagerfault.test 3ae5dafba16772a2349af57ebc5549fcf14646b0
|
||||
F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
|
||||
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
|
||||
F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6
|
||||
F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
|
||||
F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
|
||||
F test/pcache.test 488061b5dd685df2234d690370285c9b4813377b
|
||||
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
|
||||
F test/permutations.test bc474bafb022cc5014ef3a9c3d5ab61d6d6f587c
|
||||
F test/pragma.test adb21a90875bc54a880fa939c4d7c46598905aa0
|
||||
F test/pragma.test 8ee8929dd652a5753d9cd72dbcbcb9b152bd6fd8
|
||||
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
|
||||
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
|
||||
F test/printf2.test bed79b4c3e5da08ba88ad637c0bf62586843cfb1
|
||||
@@ -802,7 +808,7 @@ F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394
|
||||
F test/selectE.test fc02a1eb04c8eb537091482644b7d778ae8759b7
|
||||
F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3
|
||||
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
|
||||
F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746
|
||||
F test/shared.test 13376ba3be1c5685ab1ec184189adabd15fa70be
|
||||
F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879
|
||||
F test/shared3.test fcd65cb11d189eff5f5c85cc4fad246fb0933108
|
||||
F test/shared4.test 72d90821e8d2fc918a08f16d32880868d8ee8e9d
|
||||
@@ -820,7 +826,7 @@ F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5
|
||||
F test/shell5.test 6b1a53c49a4ff5c3bd0bad17a85ecba505608278
|
||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
|
||||
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
|
||||
F test/shrink.test 41ab166b276af4812bcaf6f1b99c53fab4e706d0
|
||||
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||
F test/skipscan1.test 28c7faa41a0d7265040ecb0a0abd90c0904270b2
|
||||
F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
|
||||
@@ -838,13 +844,13 @@ F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
||||
F test/speedtest1.c d29c8048beb7ea9254191f3fde9414709166a920
|
||||
F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe
|
||||
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
|
||||
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
|
||||
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
|
||||
F test/stat.test 1e5faf39649a0bb368770f780f926847520ea3f4
|
||||
F test/stmt.test 78a6764439cfa5abdcbf98d4d084739e81eeec4f
|
||||
F test/subquery.test 666fdecceac258f5fd84bed09a64e49d9f37edd9
|
||||
F test/subquery2.test 91e1e364072aeff431d1f9689b15147e421d88c7
|
||||
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
|
||||
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
||||
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
|
||||
F test/superlock.test 2b27b4ae7c6b9d534b0412e0d99f989aa1f3b9cf
|
||||
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
|
||||
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
|
||||
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
|
||||
@@ -852,10 +858,10 @@ F test/table.test 580d23530187026d4502fae74a490f0408cf2cc7
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43
|
||||
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
|
||||
F test/tempdb.test 3263e5c3f0604e54d307481e8587327c54544d18
|
||||
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
|
||||
F test/tester.tcl f31bea1483ea1d39620f982130026e76f872d744
|
||||
F test/tester.tcl 8c152084186b281f2d16aa4ef7cac35e71027adf
|
||||
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -870,10 +876,10 @@ F test/threadtest3.c 0ed13e09690f6204d7455fac3b0e8ece490f6eef
|
||||
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
|
||||
F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
|
||||
F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2
|
||||
F test/tkt-2d1a5c67d.test d371279946622698ab393ff88cad9f5f6d82960b
|
||||
F test/tkt-2d1a5c67d.test 8f48335224537ac91aa16277a1d5a44c9fc1bb3d
|
||||
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
|
||||
F test/tkt-31338dca7e.test 6fb8807851964da0d24e942f2e19c7c705b9fb58
|
||||
F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac
|
||||
F test/tkt-313723c356.test 54a1558d2719e171bd88967d66c73be4c617ec55
|
||||
F test/tkt-385a5b56b9.test c0a06ada41d7f06b1686da0e718553f853771d1e
|
||||
F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678
|
||||
F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
|
||||
@@ -971,7 +977,7 @@ F test/tkt3357.test 77c37c6482b526fe89941ce951c22d011f5922ed
|
||||
F test/tkt3419.test 1bbf36d7ea03b638c15804251287c2391f5c1f6b
|
||||
F test/tkt3424.test 61f831bd2b071bd128fa5d00fbda57e656ca5812
|
||||
F test/tkt3442.test 53840ec5325bb94544792aad4c20476f81dc26b1
|
||||
F test/tkt3457.test 44e980fe5334753dcc27b94fa4deabc485a92f74
|
||||
F test/tkt3457.test 08d2d9b3fc37fcc7ad9f24e5d1e004571f2a79c8
|
||||
F test/tkt3461.test 228ea328a5a21e8663f80ee3d212a6ad92549a19
|
||||
F test/tkt3493.test 1686cbde85f8721fc1bdc0ee72f2ef2f63139218
|
||||
F test/tkt3508.test d75704db9501625c7f7deec119fcaf1696aefb7d
|
||||
@@ -1062,32 +1068,32 @@ F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
|
||||
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||
F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772
|
||||
F test/wal.test 885f32b2b390b30b4aa3dbb0e568f8f78d40f5cc
|
||||
F test/wal2.test 1f841d2048080d32f552942e333fd99ce541dada
|
||||
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
|
||||
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
||||
F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b
|
||||
F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e
|
||||
F test/wal.test 0ae504805b7e41b64a55fb5b7745de5ca2a0db2a
|
||||
F test/wal2.test 703b87c21c1e3e169d607158de414c7c2655b93e
|
||||
F test/wal3.test de822707fbc8e9d056edc895adfb8abcccee4590
|
||||
F test/wal4.test 5755887f321baa4c55de0b91066fa7d0cafcac9d
|
||||
F test/wal5.test da70332902b19fea23b74c657a941a180e1cb777
|
||||
F test/wal6.test 54ac71d59046014c70ad78957139984c5bfb7eb2
|
||||
F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8
|
||||
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
|
||||
F test/wal8.test 75c42e1bc4545c277fed212f8fc9b7723cd02216
|
||||
F test/wal7.test 18cf68ab8010ae0a2baaa48e5b59567a9503e63e
|
||||
F test/wal8.test c35dd183708148120928dca908641c361f58062c
|
||||
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
|
||||
F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe
|
||||
F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877
|
||||
F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434
|
||||
F test/walcksum.test 9afeb96240296c08c72fc524d199c912cfe34daa
|
||||
F test/walcrash.test 451d79e528add5c42764cea74aa2750754171b25
|
||||
F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36
|
||||
F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af
|
||||
F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b
|
||||
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
|
||||
F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
|
||||
F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
|
||||
F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
|
||||
F test/walro.test 34422d1d95aaff0388f0791ec20edb34e2a3ed57
|
||||
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
|
||||
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
|
||||
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
|
||||
F test/wal_common.tcl 15f152fd55703975878741beca6cfa4209d5b3b3
|
||||
F test/walbak.test 67339b9e54db0cdaaf21287349bc8056e2919f96
|
||||
F test/walbig.test 3ca3d94751b80054eed5bda20a1339ae1f619483
|
||||
F test/walcksum.test 932d12a2a36fb2765560d35e7eaa1e5f0b198385
|
||||
F test/walcrash.test 011e05e9170da888851cb9ec4276bb1894ad32e3
|
||||
F test/walcrash2.test 6eb6842d34cc5955726264c80566963c32a9cbea
|
||||
F test/walcrash3.test 279640ffafa23f7564529ccd69bfb97849ccae9d
|
||||
F test/walfault.test f4160abd02d583d06d7ea9554e7a3f749f6b3410
|
||||
F test/walhook.test 5d2bdb04fd3e220e2f96e6b566d57e00020bdaec
|
||||
F test/walmode.test aa45339b4afa435dde5d88e71a95459cc221a3f4
|
||||
F test/walnoshm.test 559b878f3aab838971d820329ca35f1caa7b038e
|
||||
F test/walpersist.test abd956d66e2f36d2d9d05d3a969f48be6d2ddbec
|
||||
F test/walro.test 256ea9380825a34be43e8ff02bd1e240f1f62e8c
|
||||
F test/walshared.test 04590b10c677f75318701818c50bc0dda5da64ab
|
||||
F test/walslow.test 658066419a92d3bd85be71a11ce477af4ffe9153
|
||||
F test/walthread.test c13f5a12fbd9d81e58f49875dc9dd8a52a84cf03
|
||||
F test/where.test 28b64e93428961b07b0d486778d63fd672948f6b
|
||||
F test/where2.test 455a2eb2666e66c1e84e2cb5815173a85e6237db
|
||||
F test/where3.test 1ad55ba900bd7747f98b6082e65bd3e442c5004e
|
||||
@@ -1142,7 +1148,7 @@ F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkpragmatab.tcl 78a77b2c554d534c6f2dc903130186ed15715460
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl 1712d3d71256ca1f297046619c89e77a4d7c8f6d
|
||||
F tool/mksqlite3c.tcl ba274df71f5e6534b0a913c7c48eabfcbd0934b6
|
||||
F tool/mksqlite3c.tcl 071ff81a618ca48c89662c0c38284d96887d09c3
|
||||
F tool/mksqlite3h.tcl ba24038056f51fde07c0079c41885ab85e2cff12
|
||||
F tool/mksqlite3internalh.tcl b6514145a7d5321b47e64e19b8116cc44f973eb1
|
||||
F tool/mkvsix.tcl 52a4c613707ac34ae9c226e5ccc69cb948556105
|
||||
@@ -1173,7 +1179,11 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P b1ed4f2a34ba66c29b130f8d13e9092758019212
|
||||
R 377d24b74ba4106b5f52a423e2a5cf2f
|
||||
U dan
|
||||
Z 2cd68ab7b6aef503eef49b559771fe52
|
||||
P 2dbdfa51703bade30b66730191e4fb286edc500b
|
||||
Q +30011ad2f55cfcacaf23a58ebcc17b17a7b9355e
|
||||
R a188aa4f8674af97d2feb2b619f358d4
|
||||
T *branch * apple-osx-385
|
||||
T *sym-apple-osx-385 *
|
||||
T -sym-apple-osx *
|
||||
U drh
|
||||
Z a19b281a5eeb2a70fceb026d7028201f
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
7123bb2605216396f65db5d156431b3613f313b5
|
||||
e5f5ef008dba226ee8611dedaa8d1c34d14227c9
|
||||
+33
@@ -87,8 +87,14 @@ static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
|
||||
** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
|
||||
*/
|
||||
int sqlite3_enable_shared_cache(int enable){
|
||||
#if defined(__APPLE__) && !defined(SQLITE_TEST) && !defined(TH3_COMPATIBILITY)
|
||||
/* Enable global shared cache function for debugging and unit tests,
|
||||
** but not for release */
|
||||
return SQLITE_MISUSE;
|
||||
#else
|
||||
sqlite3GlobalConfig.sharedCacheEnabled = enable;
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2453,6 +2459,27 @@ static int lockBtree(BtShared *pBt){
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto page1_init_failed;
|
||||
}else if( isOpen==0 ){
|
||||
#ifdef SQLITE_DEFAULT_WAL_SAFETYLEVEL
|
||||
/* Default to specified safety_level for WAL mode */
|
||||
if( pBt->db!=0 && pBt->db->aDb!=0 ){
|
||||
int iDb;
|
||||
sqlite3 *db = pBt->db;
|
||||
Db *aDb = db->aDb;
|
||||
u8 level = 0;
|
||||
for(iDb=0; iDb<db->nDb; iDb++){
|
||||
if( aDb[iDb].pBt && aDb[iDb].pBt->pBt==pBt ) break;
|
||||
}
|
||||
assert( iDb<db->nDb );
|
||||
level = db->aDb[iDb].safety_level;
|
||||
if( !SQLITE_DbSafetyLevelIsFixed(level) &&
|
||||
(SQLITE_DbSafetyLevelValue(level) != SQLITE_DEFAULT_WAL_SAFETYLEVEL) ){
|
||||
aDb[iDb].safety_level = SQLITE_DEFAULT_WAL_SAFETYLEVEL;
|
||||
sqlite3PagerSetSafetyLevel(pBt->pPager, SQLITE_DEFAULT_WAL_SAFETYLEVEL,
|
||||
(db->flags&SQLITE_FullFSync)!=0,
|
||||
(db->flags&SQLITE_CkptFullFSync)!=0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
releasePage(pPage1);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -7399,6 +7426,11 @@ static int clearDatabasePage(
|
||||
|
||||
rc = getAndInitPage(pBt, pgno, &pPage, 0);
|
||||
if( rc ) return rc;
|
||||
if( pPage->bBusy ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto cleardatabasepage_out;
|
||||
}
|
||||
pPage->bBusy = 1;
|
||||
hdr = pPage->hdrOffset;
|
||||
for(i=0; i<pPage->nCell; i++){
|
||||
pCell = findCell(pPage, i);
|
||||
@@ -7423,6 +7455,7 @@ static int clearDatabasePage(
|
||||
}
|
||||
|
||||
cleardatabasepage_out:
|
||||
pPage->bBusy = 0;
|
||||
releasePage(pPage);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -279,6 +279,7 @@ struct MemPage {
|
||||
u8 hdrOffset; /* 100 for page 1. 0 otherwise */
|
||||
u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */
|
||||
u8 max1bytePayload; /* min(maxLocal,127) */
|
||||
u8 bBusy; /* Prevent endless loop in clearDatabasePage() */
|
||||
u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
|
||||
u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */
|
||||
u16 cellOffset; /* Index in aData of first cell pointer */
|
||||
|
||||
@@ -291,6 +291,9 @@ static void substrFunc(
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef SQLITE_SUBSTR_COMPATIBILITY
|
||||
if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */
|
||||
#endif
|
||||
if( argc==3 ){
|
||||
p2 = sqlite3_value_int(argv[2]);
|
||||
if( p2<0 ){
|
||||
|
||||
+9
-1
@@ -16,6 +16,9 @@
|
||||
*/
|
||||
|
||||
#include "sqliteInt.h"
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
# include "sqlrr.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Execute SQL code. Return one of the SQLITE_ success/failure
|
||||
@@ -42,7 +45,9 @@ int sqlite3_exec(
|
||||
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
if( zSql==0 ) zSql = "";
|
||||
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecExec(db, zSql);
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
sqlite3Error(db, SQLITE_OK, 0);
|
||||
while( rc==SQLITE_OK && zSql[0] ){
|
||||
@@ -120,6 +125,9 @@ int sqlite3_exec(
|
||||
exec_out:
|
||||
if( pStmt ) sqlite3VdbeFinalize((Vdbe *)pStmt);
|
||||
sqlite3DbFree(db, azCols);
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecExecEnd(db);
|
||||
#endif
|
||||
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){
|
||||
|
||||
+159
-1
@@ -16,6 +16,9 @@
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
# include "sqlrr.h"
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_FTS3
|
||||
# include "fts3.h"
|
||||
#endif
|
||||
@@ -1000,6 +1003,10 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
||||
if( db->lookaside.bMalloced ){
|
||||
sqlite3_free(db->lookaside.pStart);
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecClose(db);
|
||||
#endif
|
||||
|
||||
sqlite3_free(db);
|
||||
}
|
||||
|
||||
@@ -2161,6 +2168,44 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
|
||||
}
|
||||
return oldLimit; /* IMP: R-53341-35419 */
|
||||
}
|
||||
#if defined(SQLITE_ENABLE_AUTO_PROFILE)
|
||||
/* stderr logging */
|
||||
void _sqlite_auto_profile(void *aux, const char *sql, u64 ns);
|
||||
void _sqlite_auto_trace(void *aux, const char *sql);
|
||||
void _sqlite_auto_profile(void *aux, const char *sql, u64 ns) {
|
||||
#pragma unused(aux)
|
||||
fprintf(stderr, "Query: %s\n Execution Time: %llu ms\n", sql, ns / 1000000);
|
||||
}
|
||||
void _sqlite_auto_trace(void *aux, const char *sql) {
|
||||
fprintf(stderr, "TraceSQL(%p): %s\n", aux, sql);
|
||||
}
|
||||
|
||||
/* syslog logging */
|
||||
#include <asl.h>
|
||||
static aslclient autolog_client = NULL;
|
||||
static void _close_asl_log() {
|
||||
if( NULL!=autolog_client ){
|
||||
asl_close(autolog_client);
|
||||
autolog_client = NULL;
|
||||
}
|
||||
}
|
||||
static void _open_asl_log() {
|
||||
if( NULL==autolog_client ){
|
||||
autolog_client = asl_open("SQLite", NULL, 0);
|
||||
atexit(_close_asl_log);
|
||||
}
|
||||
}
|
||||
|
||||
void _sqlite_auto_profile_syslog(void *aux, const char *sql, u64 ns);
|
||||
void _sqlite_auto_trace_syslog(void *aux, const char *sql);
|
||||
void _sqlite_auto_profile_syslog(void *aux, const char *sql, u64 ns) {
|
||||
#pragma unused(aux)
|
||||
asl_log(autolog_client, NULL, ASL_LEVEL_NOTICE, "Query: %s\n Execution Time: %llu ms\n", sql, ns / 1000000);
|
||||
}
|
||||
void _sqlite_auto_trace_syslog(void *aux, const char *sql) {
|
||||
asl_log(autolog_client, NULL, ASL_LEVEL_NOTICE, "TraceSQL(%p): %s\n", aux, sql);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This function is used to parse both URIs and non-URI filenames passed by the
|
||||
@@ -2394,6 +2439,57 @@ int sqlite3ParseUri(
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if defined(SQLITE_ENABLE_AUTO_PROFILE)
|
||||
#define SQLITE_AUTOLOGGING_STDERR 1
|
||||
#define SQLITE_AUTOLOGGING_SYSLOG 2
|
||||
static void enableAutoLogging(
|
||||
sqlite3 *db
|
||||
){
|
||||
char *envprofile = getenv("SQLITE_AUTO_PROFILE");
|
||||
|
||||
if( envprofile!=NULL ){
|
||||
int where = 0;
|
||||
if( !strncasecmp("1", envprofile, 1) ){
|
||||
if( isatty(2) ){
|
||||
where = SQLITE_AUTOLOGGING_STDERR;
|
||||
}else{
|
||||
where = SQLITE_AUTOLOGGING_SYSLOG;
|
||||
}
|
||||
} else if( !strncasecmp("stderr", envprofile, 6) ){
|
||||
where = SQLITE_AUTOLOGGING_STDERR;
|
||||
} else if( !strncasecmp("syslog", envprofile, 6) ){
|
||||
where = SQLITE_AUTOLOGGING_SYSLOG;
|
||||
}
|
||||
if( where==SQLITE_AUTOLOGGING_STDERR ){
|
||||
sqlite3_profile(db, _sqlite_auto_profile, db);
|
||||
}else if( where==SQLITE_AUTOLOGGING_SYSLOG ){
|
||||
_open_asl_log();
|
||||
sqlite3_profile(db, _sqlite_auto_profile_syslog, db);
|
||||
}
|
||||
}
|
||||
char *envtrace = getenv("SQLITE_AUTO_TRACE");
|
||||
if( envtrace!=NULL ){
|
||||
int where = 0;
|
||||
if( !strncasecmp("1", envtrace, 1) ){
|
||||
if( isatty(2) ){
|
||||
where = SQLITE_AUTOLOGGING_STDERR;
|
||||
}else{
|
||||
where = SQLITE_AUTOLOGGING_SYSLOG;
|
||||
}
|
||||
} else if( !strncasecmp("stderr", envtrace, 6) ){
|
||||
where = SQLITE_AUTOLOGGING_STDERR;
|
||||
} else if( !strncasecmp("syslog", envtrace, 6) ){
|
||||
where = SQLITE_AUTOLOGGING_SYSLOG;
|
||||
}
|
||||
if( where==SQLITE_AUTOLOGGING_STDERR ){
|
||||
sqlite3_trace(db, _sqlite_auto_trace, db);
|
||||
}else if( where==SQLITE_AUTOLOGGING_SYSLOG ){
|
||||
_open_asl_log();
|
||||
sqlite3_trace(db, _sqlite_auto_trace_syslog, db);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This routine does the work of opening a database on behalf of
|
||||
@@ -2501,6 +2597,9 @@ static int openDatabase(
|
||||
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
|
||||
| SQLITE_AutoIndex
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_CKPTFULLFSYNC
|
||||
| SQLITE_CkptFullFSync
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_FILE_FORMAT<4
|
||||
| SQLITE_LegacyFileFmt
|
||||
#endif
|
||||
@@ -2656,7 +2755,30 @@ opendb_out:
|
||||
}else if( rc!=SQLITE_OK ){
|
||||
db->magic = SQLITE_MAGIC_SICK;
|
||||
}
|
||||
#if defined(__APPLE__) && ENABLE_FORCE_WAL
|
||||
if( db && !rc ){
|
||||
if ((0 == access("/var/db/enableForceWAL", R_OK))) {
|
||||
#ifdef SQLITE_DEBUG
|
||||
fprintf(stderr, "SQLite WAL journal_mode ENABLED by default.\n");
|
||||
#endif
|
||||
|
||||
sqlite3_exec(db, "pragma journal_mode=wal", NULL, NULL, NULL);
|
||||
#ifdef SQLITE_DEBUG
|
||||
// } else {
|
||||
// fprintf(stderr, "SQLite WAL journal_mode NOT ENABLED by default.\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(SQLITE_ENABLE_AUTO_PROFILE)
|
||||
if( db && !rc ){
|
||||
enableAutoLogging(db);
|
||||
}
|
||||
#endif
|
||||
*ppDb = db;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecOpen(db, zFilename, flags);
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_SQLLOG
|
||||
if( sqlite3GlobalConfig.xSqllog ){
|
||||
/* Opening a db handle. Fourth parameter is passed 0. */
|
||||
@@ -3052,13 +3174,22 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
|
||||
rc = SQLITE_OK;
|
||||
}else if( fd->pMethods ){
|
||||
rc = sqlite3OsFileControl(fd, op, pArg);
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
if( (rc==SQLITE_OK)&&(op==SQLITE_FCNTL_LAST_ERRNO)&&(*(int *)pArg==0) ){
|
||||
sqlite3_file *pWalFd = sqlite3PagerWalFile(pPager);
|
||||
if( pWalFd&&(pWalFd->pMethods) ){
|
||||
rc = sqlite3OsFileControl(pWalFd, op, pArg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}else{
|
||||
rc = SQLITE_NOTFOUND;
|
||||
}
|
||||
sqlite3BtreeLeave(pBtree);
|
||||
}
|
||||
sqlite3Error(db, rc, 0);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3447,3 +3578,30 @@ int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
|
||||
Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
|
||||
return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
|
||||
}
|
||||
|
||||
#if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__)
|
||||
|
||||
#include "sqlite3_private.h"
|
||||
|
||||
/*
|
||||
** Testing a file path for sqlite locks held by a process ID.
|
||||
** Returns SQLITE_LOCKSTATE_ON if locks are present on path
|
||||
** that would prevent writing to the database.
|
||||
*/
|
||||
int _sqlite3_lockstate(const char *path, pid_t pid){
|
||||
sqlite3 *db = NULL;
|
||||
|
||||
if( sqlite3_open_v2(path, &db, SQLITE_OPEN_READONLY, NULL) == SQLITE_OK ){
|
||||
LockstatePID lockstate = {pid, -1};
|
||||
sqlite3_file_control(db, NULL, SQLITE_FCNTL_LOCKSTATE_PID, &lockstate);
|
||||
sqlite3_close(db);
|
||||
int state = lockstate.state;
|
||||
return state;
|
||||
}
|
||||
if( NULL!=db ){
|
||||
sqlite3_close(db); /* need to close even if open returns an error */
|
||||
}
|
||||
return SQLITE_LOCKSTATE_ERROR;
|
||||
}
|
||||
|
||||
#endif /* SQLITE_ENABLE_APPLE_SPI */
|
||||
|
||||
@@ -187,12 +187,18 @@ int sqlite3OsOpen(
|
||||
int *pFlagsOut
|
||||
){
|
||||
int rc;
|
||||
int openFlags;
|
||||
DO_OS_MALLOC_TEST(0);
|
||||
/* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
|
||||
** down into the VFS layer. Some SQLITE_OPEN_ flags (for example,
|
||||
** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
|
||||
** reaching the VFS. */
|
||||
rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
openFlags = flags & (0x87f7f | SQLITE_OPEN_FILEPROTECTION_MASK);
|
||||
#else
|
||||
openFlags = flags & 0x87f7f;
|
||||
#endif
|
||||
rc = pVfs->xOpen(pVfs, zPath, pFile, openFlags, pFlagsOut);
|
||||
assert( rc==SQLITE_OK || pFile->pMethods==0 );
|
||||
return rc;
|
||||
}
|
||||
|
||||
+1361
-109
File diff suppressed because it is too large
Load Diff
@@ -3147,6 +3147,15 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_FCNTL_PERSIST_WAL: {
|
||||
int bPersist = *(int*)pArg;
|
||||
if( bPersist<0 ){
|
||||
*(int*)pArg = pFile->bPersistWal;
|
||||
}else{
|
||||
pFile->bPersistWal = bPersist!=0;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_FCNTL_PERSIST_WAL: {
|
||||
winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg);
|
||||
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
|
||||
|
||||
+55
-9
@@ -2430,7 +2430,11 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
|
||||
if( !pMaster ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
|
||||
const int flags =
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
(pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)|
|
||||
#endif
|
||||
(SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
|
||||
rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
|
||||
}
|
||||
if( rc!=SQLITE_OK ) goto delmaster_out;
|
||||
@@ -2466,7 +2470,11 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
|
||||
** so, return without deleting the master journal file.
|
||||
*/
|
||||
int c;
|
||||
int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
|
||||
int flags =
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
(pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)|
|
||||
#endif
|
||||
(SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
|
||||
rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto delmaster_out;
|
||||
@@ -3527,7 +3535,11 @@ static int pagerOpentemp(
|
||||
sqlite3_opentemp_count++; /* Used for testing and analysis only */
|
||||
#endif
|
||||
|
||||
vfsFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
|
||||
vfsFlags |=
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
(pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)|
|
||||
#endif
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
|
||||
SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
|
||||
rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0);
|
||||
assert( rc!=SQLITE_OK || isOpen(pFile) );
|
||||
@@ -4775,6 +4787,9 @@ act_like_temp_file:
|
||||
pPager->readOnly = (u8)readOnly;
|
||||
assert( useJournal || pPager->tempFile );
|
||||
pPager->noSync = pPager->tempFile;
|
||||
pPager->fullSync = pPager->noSync ?0:1;
|
||||
pPager->syncFlags = pPager->noSync ? 0 : SQLITE_SYNC_NORMAL;
|
||||
pPager->ckptSyncFlags = pPager->syncFlags;
|
||||
if( pPager->noSync ){
|
||||
assert( pPager->fullSync==0 );
|
||||
assert( pPager->syncFlags==0 );
|
||||
@@ -4923,7 +4938,11 @@ static int hasHotJournal(Pager *pPager, int *pExists){
|
||||
** it can be ignored.
|
||||
*/
|
||||
if( !jrnlOpen ){
|
||||
int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL;
|
||||
int f =
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
(pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)|
|
||||
#endif
|
||||
SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL;
|
||||
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -5063,7 +5082,11 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists);
|
||||
if( rc==SQLITE_OK && bExists ){
|
||||
int fout = 0;
|
||||
int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
|
||||
int f =
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
(pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)|
|
||||
#endif
|
||||
SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
|
||||
assert( !pPager->tempFile );
|
||||
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
|
||||
assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
|
||||
@@ -5509,6 +5532,9 @@ static int pager_open_journal(Pager *pPager){
|
||||
sqlite3MemJournalOpen(pPager->jfd);
|
||||
}else{
|
||||
const int flags = /* VFS flags to open journal file */
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
(pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)|
|
||||
#endif
|
||||
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
|
||||
(pPager->tempFile ?
|
||||
(SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
|
||||
@@ -6618,6 +6644,15 @@ sqlite3_file *sqlite3PagerFile(Pager *pPager){
|
||||
return pPager->fd;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the file handle for the WAL journal file associated
|
||||
** with the pager. This might return NULL if the file has
|
||||
** not yet been opened.
|
||||
*/
|
||||
sqlite3_file *sqlite3PagerWalFile(Pager *pPager){
|
||||
return ((pPager->pWal) ? sqlite3WalFile(pPager->pWal) : (NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the full pathname of the journal file.
|
||||
*/
|
||||
@@ -7111,10 +7146,14 @@ static int pagerOpenWal(Pager *pPager){
|
||||
** (e.g. due to malloc() failure), return an error code.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3WalOpen(pPager->pVfs,
|
||||
pPager->fd, pPager->zWal, pPager->exclusiveMode,
|
||||
pPager->journalSizeLimit, &pPager->pWal
|
||||
);
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, pPager->exclusiveMode,
|
||||
pPager->journalSizeLimit, (pPager->vfsFlags & (SQLITE_OPEN_FILEPROTECTION_MASK | SQLITE_OPEN_READONLY)),
|
||||
&pPager->pWal);
|
||||
#else
|
||||
rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, pPager->exclusiveMode,
|
||||
pPager->journalSizeLimit, (pPager->vfsFlags & SQLITE_OPEN_READONLY), &pPager->pWal);
|
||||
#endif
|
||||
}
|
||||
pagerFixMaplimit(pPager);
|
||||
|
||||
@@ -7208,6 +7247,13 @@ int sqlite3PagerCloseWal(Pager *pPager){
|
||||
pPager->pageSize, (u8*)pPager->pTmpSpace);
|
||||
pPager->pWal = 0;
|
||||
pagerFixMaplimit(pPager);
|
||||
|
||||
/* Ensure that the WAL file is deleted even if the PERSIST_WAL
|
||||
** hint is enabled. */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
|
||||
if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
|
||||
@@ -177,6 +177,7 @@ int sqlite3PagerMemUsed(Pager*);
|
||||
const char *sqlite3PagerFilename(Pager*, int);
|
||||
const sqlite3_vfs *sqlite3PagerVfs(Pager*);
|
||||
sqlite3_file *sqlite3PagerFile(Pager*);
|
||||
sqlite3_file *sqlite3PagerWalFile(Pager *pPager);
|
||||
const char *sqlite3PagerJournalname(Pager*);
|
||||
int sqlite3PagerNosync(Pager*);
|
||||
void *sqlite3PagerTempSpace(Pager*);
|
||||
|
||||
+20
-4
@@ -629,11 +629,11 @@ static void setAllPagerFlags(sqlite3 *db){
|
||||
assert( SQLITE_CacheSpill==PAGER_CACHESPILL );
|
||||
assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL)
|
||||
== PAGER_FLAGS_MASK );
|
||||
assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level );
|
||||
while( (n--) > 0 ){
|
||||
if( pDb->pBt ){
|
||||
sqlite3BtreeSetPagerFlags(pDb->pBt,
|
||||
pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) );
|
||||
(pDb->safety_level & PAGER_SYNCHRONOUS_MASK)
|
||||
| (db->flags & PAGER_FLAGS_MASK) );
|
||||
}
|
||||
pDb++;
|
||||
}
|
||||
@@ -1028,6 +1028,20 @@ void sqlite3Pragma(
|
||||
iDb = 0;
|
||||
pId2->n = 1;
|
||||
}
|
||||
#ifdef SQLITE_DEFAULT_WAL_SAFETYLEVEL
|
||||
if( ! SQLITE_DbSafetyLevelIsFixed(pDb->safety_level) ){
|
||||
if( eMode == PAGER_JOURNALMODE_WAL ){
|
||||
/* when entering wal mode, immediately switch the safety_level
|
||||
** so that a query to pragma synchronous returns the correct value */
|
||||
|
||||
pDb->safety_level = SQLITE_DEFAULT_WAL_SAFETYLEVEL;
|
||||
}else{
|
||||
/* If the user hasn't overridden the synchronous setting, use the
|
||||
** default for non-wal databases */
|
||||
pDb->safety_level = 3;
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_DEFAULT_WAL_SAFETYLEVEL */
|
||||
for(ii=db->nDb-1; ii>=0; ii--){
|
||||
if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
|
||||
sqlite3VdbeUsesBtree(v, ii);
|
||||
@@ -1366,13 +1380,15 @@ void sqlite3Pragma(
|
||||
*/
|
||||
case PragTyp_SYNCHRONOUS: {
|
||||
if( !zRight ){
|
||||
returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
|
||||
returnSingleInt(pParse, "synchronous",
|
||||
SQLITE_DbSafetyLevelValue(pDb->safety_level)-1);
|
||||
}else{
|
||||
if( !db->autoCommit ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"Safety level may not be changed inside a transaction");
|
||||
}else{
|
||||
pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
|
||||
pDb->safety_level = (getSafetyLevel(zRight,0,1)+1)
|
||||
| SQLITE_SAFETYLEVEL_FIXED;
|
||||
setAllPagerFlags(db);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-1
@@ -14,6 +14,9 @@
|
||||
** from disk.
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
# include "sqlrr.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Fill the InitData structure with an error message that indicates
|
||||
@@ -780,6 +783,9 @@ int sqlite3_prepare(
|
||||
){
|
||||
int rc;
|
||||
rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail);
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecPrepare(db, zSql, nBytes, 0, *ppStmt);
|
||||
#endif
|
||||
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
|
||||
return rc;
|
||||
}
|
||||
@@ -792,6 +798,9 @@ int sqlite3_prepare_v2(
|
||||
){
|
||||
int rc;
|
||||
rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,0,ppStmt,pzTail);
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecPrepare(db, zSql, nBytes, 1, *ppStmt);
|
||||
#endif
|
||||
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
|
||||
return rc;
|
||||
}
|
||||
@@ -833,7 +842,9 @@ static int sqlite3Prepare16(
|
||||
if( zSql8 ){
|
||||
rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecPrepare(db, zSql8, -1, 1, *ppStmt);
|
||||
#endif
|
||||
if( zTail8 && pzTail ){
|
||||
/* If sqlite3_prepare returns a tail pointer, we calculate the
|
||||
** equivalent pointer into the UTF-16 string by counting the unicode
|
||||
|
||||
@@ -5314,6 +5314,9 @@ select_end:
|
||||
}
|
||||
|
||||
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
|
||||
void sqlite3PrintExpr(Expr *p);
|
||||
void sqlite3PrintExprList(ExprList *pList);
|
||||
void sqlite3PrintSelect(Select *p, int indent);
|
||||
/*
|
||||
** Generate a human-readable description of a the Select object.
|
||||
*/
|
||||
|
||||
+13
-3
@@ -529,6 +529,7 @@ int sqlite3_exec(
|
||||
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
|
||||
#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
|
||||
#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
|
||||
#define SQLITE_OPEN_FILEPROTECTION_MASK 0x00700000
|
||||
|
||||
/* Reserved: 0x00F00000 */
|
||||
|
||||
@@ -951,9 +952,9 @@ struct sqlite3_io_methods {
|
||||
** </ul>
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
#define SQLITE_GET_LOCKPROXYFILE 2
|
||||
#define SQLITE_SET_LOCKPROXYFILE 3
|
||||
#define SQLITE_LAST_ERRNO 4
|
||||
#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
|
||||
#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
|
||||
#define SQLITE_FCNTL_LAST_ERRNO 4
|
||||
#define SQLITE_FCNTL_SIZE_HINT 5
|
||||
#define SQLITE_FCNTL_CHUNK_SIZE 6
|
||||
#define SQLITE_FCNTL_FILE_POINTER 7
|
||||
@@ -972,6 +973,10 @@ struct sqlite3_io_methods {
|
||||
#define SQLITE_FCNTL_SYNC 21
|
||||
#define SQLITE_FCNTL_COMMIT_PHASETWO 22
|
||||
#define SQLITE_FCNTL_WIN32_SET_HANDLE 23
|
||||
/* deprecated names */
|
||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
|
||||
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
|
||||
|
||||
/*
|
||||
** CAPI3REF: Mutex Handle
|
||||
@@ -4976,6 +4981,11 @@ void *sqlite3_update_hook(
|
||||
** future releases of SQLite. Applications that care about shared
|
||||
** cache setting should set it explicitly.
|
||||
**
|
||||
** ^Note: This method is deprecated on MacOS X 10.7 and iOS version 5.0
|
||||
** and will always return SQLITE_MISUSE, instead of calling this function
|
||||
** shared cache mode should be enabled per-database connection via
|
||||
** sqlite3_open_v2 with SQLITE_OPEN_SHAREDCACHE instead.
|
||||
**
|
||||
** This interface is threadsafe on processors where writing a
|
||||
** 32-bit integer is atomic.
|
||||
**
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* sqlite3_private.h
|
||||
*/
|
||||
|
||||
#ifndef _SQLITE3_PRIVATE_H
|
||||
#define _SQLITE3_PRIVATE_H
|
||||
|
||||
#define SQLITE_LOCKSTATE_OFF 0
|
||||
#define SQLITE_LOCKSTATE_ON 1
|
||||
#define SQLITE_LOCKSTATE_NOTADB 2
|
||||
#define SQLITE_LOCKSTATE_ERROR -1
|
||||
|
||||
#define SQLITE_LOCKSTATE_ANYPID -1
|
||||
|
||||
/*
|
||||
** Test a file path for sqlite locks held by a process ID (-1 = any PID).
|
||||
** Returns one of the following integer codes:
|
||||
**
|
||||
** SQLITE_LOCKSTATE_OFF no active sqlite file locks match the specified pid
|
||||
** SQLITE_LOCKSTATE_ON active sqlite file locks match the specified pid
|
||||
** SQLITE_LOCKSTATE_NOTADB path points to a file that is not an sqlite db file
|
||||
** SQLITE_LOCKSTATE_ERROR path was not vaild or was unreadable
|
||||
**
|
||||
** There is no support for identifying db files encrypted via SEE encryption
|
||||
** currently. Zero byte files are tested for sqlite locks, but if no sqlite
|
||||
** locks are present then SQLITE_LOCKSTATE_NOTADB is returned.
|
||||
*/
|
||||
extern int _sqlite3_lockstate(const char *path, pid_t pid);
|
||||
|
||||
/*
|
||||
** Test an open database connection for sqlite locks held by a process ID,
|
||||
** if a process has an open database connection this will avoid trashing file
|
||||
** locks by re-using open file descriptors for the database file and support
|
||||
** files (-shm)
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE_PID 103
|
||||
|
||||
/*
|
||||
** Pass the SQLITE_TRUNCATE_DATABASE operation code to sqlite3_file_control()
|
||||
** to truncate a database and its associated journal file to zero length. The
|
||||
** SQLITE_TRUNCATE_* flags represent optional flags to safely initialize an
|
||||
** empty database in the place of the truncated database, the flags are passed
|
||||
** into sqlite3_file_control via the fourth argument using a pointer to an integer
|
||||
** configured with the ORed flags. If the fourth argument is NULL, the default
|
||||
** behavior is applied and the database file is truncated to zero bytes, a rollback
|
||||
** journal (if present) is unlinked, a WAL journal (if present) is truncated to zero
|
||||
** bytes and the first few bytes of the -shm file is scrambled to trigger existing
|
||||
** connections to rebuild the index from the database file contents.
|
||||
*/
|
||||
#define SQLITE_FCNTL_TRUNCATE_DATABASE 101
|
||||
#define SQLITE_TRUNCATE_DATABASE SQLITE_FCNTL_TRUNCATE_DATABASE
|
||||
#define SQLITE_TRUNCATE_INITIALIZE_HEADER_MASK (0x7F<<0)
|
||||
#define SQLITE_TRUNCATE_JOURNALMODE_WAL (0x1<<0)
|
||||
#define SQLITE_TRUNCATE_AUTOVACUUM_MASK (0x3<<2)
|
||||
#define SQLITE_TRUNCATE_AUTOVACUUM_OFF (0x1<<2)
|
||||
#define SQLITE_TRUNCATE_AUTOVACUUM_FULL (0x2<<2)
|
||||
#define SQLITE_TRUNCATE_AUTOVACUUM_INCREMENTAL (0x3<<2)
|
||||
#define SQLITE_TRUNCATE_PAGESIZE_MASK (0x7<<4)
|
||||
#define SQLITE_TRUNCATE_PAGESIZE_1024 (0x1<<4)
|
||||
#define SQLITE_TRUNCATE_PAGESIZE_2048 (0x2<<4)
|
||||
#define SQLITE_TRUNCATE_PAGESIZE_4096 (0x3<<4)
|
||||
#define SQLITE_TRUNCATE_PAGESIZE_8192 (0x4<<4)
|
||||
#define SQLITE_TRUNCATE_FORCE (0x1<<7)
|
||||
|
||||
/*
|
||||
** Pass the SQLITE_REPLACE_DATABASE operation code to sqlite3_file_control()
|
||||
** and a sqlite3 pointer to another open database file to safely copy the
|
||||
** contents of that database file into the receiving database.
|
||||
*/
|
||||
#define SQLITE_FCNTL_REPLACE_DATABASE 102
|
||||
#define SQLITE_REPLACE_DATABASE SQLITE_FCNTL_REPLACE_DATABASE
|
||||
|
||||
#endif
|
||||
@@ -834,6 +834,16 @@ typedef struct With With;
|
||||
#include "os.h"
|
||||
#include "mutex.h"
|
||||
|
||||
/* When using a default wal safety level, the safety level should only
|
||||
** change with the journal mode if the user hasn't manually specified
|
||||
** pragma synchronous, if they have the defaults shouldn't be applied.
|
||||
** The SQLITE_SAFETYLEVEL_FIXED value is ORed into the Db->safety_level
|
||||
** field when the user has specified a synchronous setting via pragma.
|
||||
*/
|
||||
#define SQLITE_SAFETYLEVEL_FIXED 0x10
|
||||
#define SQLITE_SAFETYLEVEL_VALUE_MASK 0x03
|
||||
#define SQLITE_DbSafetyLevelValue(level) (level&SQLITE_SAFETYLEVEL_VALUE_MASK)
|
||||
#define SQLITE_DbSafetyLevelIsFixed(level) (level&SQLITE_SAFETYLEVEL_FIXED)
|
||||
|
||||
/*
|
||||
** Each database file to be accessed by the system is an instance
|
||||
@@ -3672,4 +3682,29 @@ SQLITE_EXTERN void (*sqlite3IoTrace)(const char*,...);
|
||||
#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
|
||||
#define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */
|
||||
|
||||
|
||||
#if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__)
|
||||
|
||||
/*
|
||||
** An instance of the following structure is used to hold the process ID
|
||||
** and return-by-reference lockstate value. The SQLITE_FCNTL_LOCKSTATE_PID
|
||||
** requires the 4th argument to sqlite3_file_control to be a pointer to an
|
||||
** instance of LockstatePID initialized with a LockstatePID.pid value equal
|
||||
** to a process ID to be tested, or the special value SQLITE_LOCKSTATE_ANYPID
|
||||
** The Lockstate.state value is always set to one of the following values
|
||||
** when sqlite3_file_control returns:
|
||||
**
|
||||
** SQLITE_LOCKSTATE_OFF no active sqlite file locks match the specified pid
|
||||
** SQLITE_LOCKSTATE_ON active sqlite file locks match the specified pid
|
||||
** SQLITE_LOCKSTATE_NOTADB path points to a file that is not an sqlite db file
|
||||
** SQLITE_LOCKSTATE_ERROR path was not vaild or was unreadable
|
||||
*/
|
||||
typedef struct LockstatePID LockstatePID;
|
||||
struct LockstatePID {
|
||||
pid_t pid; /* Process ID to test */
|
||||
int state; /* The state of the lock (return value) */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _SQLITEINT_H_ */
|
||||
|
||||
+200
-1
@@ -3463,6 +3463,24 @@ static int test_clear_bindings(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_clear_bindings STMT
|
||||
**
|
||||
*/
|
||||
static int test_clear_bindings_null(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
if( objc!=1 ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
/* test for handling NULL <rdar://problem/6646331> */
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(0)));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_sleep MILLISECONDS
|
||||
*/
|
||||
@@ -5075,6 +5093,97 @@ static int file_control_lasterrno_test(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* From sqlite3_priavet.h */
|
||||
# ifndef SQLITE_TRUNCATE_DATABASE
|
||||
# define SQLITE_TRUNCATE_DATABASE 101
|
||||
# define SQLITE_TRUNCATE_JOURNALMODE_WAL (0x1<<0)
|
||||
# define SQLITE_TRUNCATE_AUTOVACUUM_MASK (0x3<<2)
|
||||
# define SQLITE_TRUNCATE_AUTOVACUUM_OFF (0x1<<2)
|
||||
# define SQLITE_TRUNCATE_AUTOVACUUM_FULL (0x2<<2)
|
||||
# define SQLITE_TRUNCATE_AUTOVACUUM_INCREMENTAL (0x3<<2)
|
||||
# define SQLITE_TRUNCATE_PAGESIZE_MASK (0x7<<4)
|
||||
# define SQLITE_TRUNCATE_PAGESIZE_1024 (0x1<<4)
|
||||
# define SQLITE_TRUNCATE_PAGESIZE_2048 (0x2<<4)
|
||||
# define SQLITE_TRUNCATE_PAGESIZE_4096 (0x3<<4)
|
||||
# define SQLITE_TRUNCATE_PAGESIZE_8192 (0x4<<4)
|
||||
# endif
|
||||
# ifndef SQLITE_REPLACE_DATABASE
|
||||
# define SQLITE_REPLACE_DATABASE 102
|
||||
# endif
|
||||
|
||||
/*
|
||||
** tclcmd: file_control_truncate_test DB
|
||||
**
|
||||
** This TCL command runs the sqlite3_file_control interface and
|
||||
** verifies correct operation of the SQLITE_TRUNCATE_DATABASE verb.
|
||||
*/
|
||||
static int file_control_truncate_test(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3 *db;
|
||||
int flags;
|
||||
int rc;
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
Tcl_GetStringFromObj(objv[0], 0), " DB FLAGS", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &flags) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = sqlite3_file_control(db, NULL, SQLITE_TRUNCATE_DATABASE, &flags);
|
||||
if( rc ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: file_control_replace_test DB
|
||||
**
|
||||
** This TCL command runs the sqlite3_file_control interface and
|
||||
** verifies correct operation of the SQLITE_REPLACE_DATABASE verb.
|
||||
*/
|
||||
static int file_control_replace_test(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
int iArg = 0;
|
||||
sqlite3 *src_db;
|
||||
sqlite3 *dst_db;
|
||||
int rc;
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
Tcl_GetStringFromObj(objv[0], 0), " DST_DB SRC_DB", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &dst_db) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[2]), &src_db) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = sqlite3_file_control(dst_db, NULL, SQLITE_REPLACE_DATABASE, src_db);
|
||||
if( rc ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
/*
|
||||
** tclcmd: file_control_chunksize_test DB DBNAME SIZE
|
||||
**
|
||||
@@ -5220,6 +5329,90 @@ static int file_control_lockproxy_test(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/errno.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
** tclcmd: path_is_local PWD
|
||||
*/
|
||||
static int path_is_local(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
#ifdef __APPLE__
|
||||
const char *zPath;
|
||||
int nPath;
|
||||
struct statfs fsInfo;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
Tcl_GetStringFromObj(objv[0], 0), " PATH", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zPath = Tcl_GetStringFromObj(objv[1], &nPath);
|
||||
if( statfs(zPath, &fsInfo) == -1 ){
|
||||
int err = errno;
|
||||
Tcl_AppendResult(interp, "Error calling statfs on path",
|
||||
Tcl_NewIntObj(err), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( fsInfo.f_flags&MNT_LOCAL ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
|
||||
}
|
||||
#else
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
|
||||
#endif
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: path_is_dos PWD
|
||||
*/
|
||||
static int path_is_dos(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
#ifdef __APPLE__
|
||||
const char *zPath;
|
||||
int nPath;
|
||||
struct statfs fsInfo;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
Tcl_GetStringFromObj(objv[0], 0), " PATH", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zPath = Tcl_GetStringFromObj(objv[1], &nPath);
|
||||
if( statfs(zPath, &fsInfo) == -1 ){
|
||||
int err = errno;
|
||||
Tcl_AppendResult(interp, "Error calling statfs on path",
|
||||
Tcl_NewIntObj(err), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
|
||||
} else if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
|
||||
}
|
||||
#else
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
|
||||
#endif
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#if SQLITE_OS_WIN
|
||||
/*
|
||||
** tclcmd: file_control_win32_av_retry DB NRETRY DELAY
|
||||
@@ -5321,7 +5514,6 @@ static int file_control_persist_wal(
|
||||
Tcl_AppendResult(interp, z, (char*)0);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: file_control_powersafe_overwrite DB PSOW-FLAG
|
||||
**
|
||||
@@ -6415,6 +6607,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_bind_parameter_name", test_bind_parameter_name, 0},
|
||||
{ "sqlite3_bind_parameter_index", test_bind_parameter_index, 0},
|
||||
{ "sqlite3_clear_bindings", test_clear_bindings, 0},
|
||||
{ "sqlite3_clear_bindings_null", test_clear_bindings_null, 0},
|
||||
{ "sqlite3_sleep", test_sleep, 0},
|
||||
{ "sqlite3_errcode", test_errcode ,0 },
|
||||
{ "sqlite3_extended_errcode", test_ex_errcode ,0 },
|
||||
@@ -6517,6 +6710,10 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "file_control_test", file_control_test, 0 },
|
||||
{ "file_control_lasterrno_test", file_control_lasterrno_test, 0 },
|
||||
{ "file_control_lockproxy_test", file_control_lockproxy_test, 0 },
|
||||
#ifdef __APPLE__
|
||||
{ "file_control_truncate_test", file_control_truncate_test, 0 },
|
||||
{ "file_control_replace_test", file_control_replace_test, 0 },
|
||||
#endif
|
||||
{ "file_control_chunksize_test", file_control_chunksize_test, 0 },
|
||||
{ "file_control_sizehint_test", file_control_sizehint_test, 0 },
|
||||
#if SQLITE_OS_WIN
|
||||
@@ -6529,6 +6726,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "file_control_tempfilename", file_control_tempfilename, 0 },
|
||||
{ "sqlite3_vfs_list", vfs_list, 0 },
|
||||
{ "sqlite3_create_function_v2", test_create_function_v2, 0 },
|
||||
{ "path_is_local", path_is_local, 0 },
|
||||
{ "path_is_dos", path_is_dos, 0 },
|
||||
|
||||
/* Functions from os.h */
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "tcl.h"
|
||||
#include <sqlite3.h>
|
||||
#include "sqlite3.h"
|
||||
#include <assert.h>
|
||||
|
||||
/* These functions are implemented in main.c. */
|
||||
|
||||
+37
-1
@@ -497,7 +497,27 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp,"sqlite_options","prefer_proxy_locking","0",TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#if defined(SQLITE_ENABLE_PURGEABLE_PCACHE) && defined(__APPLE__)
|
||||
Tcl_SetVar2(interp,"sqlite_options","enable_purgeable_pcache","1",TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp,"sqlite_options","enable_purgeable_pcache","0",TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_CKPTFULLFSYNC
|
||||
Tcl_SetVar2(interp,"sqlite_options","default_ckptfullfsync","1",TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp,"sqlite_options","default_ckptfullfsync","0",TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_WAL_SAFETYLEVEL
|
||||
Tcl_SetVar2(interp,"sqlite_options","default_wal_safetylevel",
|
||||
STRINGVALUE(SQLITE_DEFAULT_WAL_SAFETYLEVEL),TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp,"sqlite_options","default_wal_safetylevel","0",TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
#if SQLITE_ENABLE_PERSIST_WAL
|
||||
Tcl_SetVar2(interp,"sqlite_options","enable_persist_wal","1",TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp,"sqlite_options","enable_persist_wal","0",TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_SHARED_CACHE
|
||||
Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "0", TCL_GLOBAL_ONLY);
|
||||
@@ -610,6 +630,22 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "yytrackmaxstackdepth", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
# if defined(__ppc__)
|
||||
Tcl_SetVar2(interp, "os_options", "arch", "ppc", TCL_GLOBAL_ONLY);
|
||||
# elif defined(__i386__)
|
||||
Tcl_SetVar2(interp, "os_options", "arch", "i386", TCL_GLOBAL_ONLY);
|
||||
# elif defined(__x86_64__)
|
||||
Tcl_SetVar2(interp, "os_options", "arch", "x86_64", TCL_GLOBAL_ONLY);
|
||||
# elif defined(__arm__)
|
||||
Tcl_SetVar2(interp, "os_options", "arch", "arm", TCL_GLOBAL_ONLY);
|
||||
# else
|
||||
# error Unrecognized architecture for exec_options
|
||||
# endif
|
||||
#else
|
||||
Tcl_SetVar2(interp, "os_options", "arch", "unknown", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#define LINKVAR(x) { \
|
||||
static const int cv_ ## x = SQLITE_ ## x; \
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library.
|
||||
*/
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include "sqlite3.h"
|
||||
#include <tcl.h>
|
||||
|
||||
/* Solely for the UNUSED_PARAMETER() macro. */
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
** sqlite3demo_superunlock()
|
||||
*/
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include "sqlite3.h"
|
||||
#include <string.h> /* memset(), strlen() */
|
||||
#include <assert.h> /* assert() */
|
||||
|
||||
@@ -148,7 +148,7 @@ static int superlockWalLock(
|
||||
** this function must have been obtained from a successful call to
|
||||
** sqlite3demo_superlock().
|
||||
*/
|
||||
void sqlite3demo_superunlock(void *pLock){
|
||||
static void sqlite3demo_superunlock(void *pLock){
|
||||
Superlock *p = (Superlock *)pLock;
|
||||
if( p->bWal ){
|
||||
int rc; /* Return code */
|
||||
@@ -179,9 +179,10 @@ void sqlite3demo_superunlock(void *pLock){
|
||||
** until either the lock can be obtained or the busy-handler function returns
|
||||
** 0 (indicating "give up").
|
||||
*/
|
||||
int sqlite3demo_superlock(
|
||||
static int sqlite3demo_superlock(
|
||||
const char *zPath, /* Path to database file to lock */
|
||||
const char *zVfs, /* VFS to use to access database file */
|
||||
int flags, /* Additional flags to pass to sqlite3_open_v2 */
|
||||
int (*xBusy)(void*,int), /* Busy handler callback */
|
||||
void *pBusyArg, /* Context arg for busy handler */
|
||||
void **ppLock /* OUT: Context to pass to superunlock() */
|
||||
@@ -196,7 +197,7 @@ int sqlite3demo_superlock(
|
||||
|
||||
/* Open a database handle on the file to superlock. */
|
||||
rc = sqlite3_open_v2(
|
||||
zPath, &pLock->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs
|
||||
zPath, &pLock->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|flags, zVfs
|
||||
);
|
||||
|
||||
/* Install a busy-handler and execute a BEGIN EXCLUSIVE. If this is not
|
||||
@@ -331,7 +332,7 @@ static int superlock_cmd(
|
||||
xBusy = superlock_busy;
|
||||
}
|
||||
|
||||
rc = sqlite3demo_superlock(zPath, zVfs, xBusy, &busy, &pLock);
|
||||
rc = sqlite3demo_superlock(zPath, zVfs, 0, xBusy, &busy, &pLock);
|
||||
assert( rc==SQLITE_OK || pLock==0 );
|
||||
assert( rc!=SQLITE_OK || pLock!=0 );
|
||||
|
||||
|
||||
+1
-1
@@ -524,7 +524,7 @@ int sqlite3VdbeExec(
|
||||
** sqlite3_column_text16() failed. */
|
||||
goto no_mem;
|
||||
}
|
||||
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
|
||||
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || ((p->rc&0xFF) == SQLITE_LOCKED));
|
||||
assert( p->bIsReader || p->readOnly!=0 );
|
||||
p->rc = SQLITE_OK;
|
||||
p->iCurrentTime = 0;
|
||||
|
||||
+44
-1
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "vdbeInt.h"
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
# include "sqlrr.h"
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
/*
|
||||
@@ -70,6 +73,9 @@ int sqlite3_finalize(sqlite3_stmt *pStmt){
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
Vdbe *v = (Vdbe*)pStmt;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecFinalize(pStmt);
|
||||
#endif
|
||||
sqlite3 *db = v->db;
|
||||
if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
@@ -94,6 +100,9 @@ int sqlite3_reset(sqlite3_stmt *pStmt){
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
Vdbe *v = (Vdbe*)pStmt;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecReset(pStmt);
|
||||
#endif
|
||||
sqlite3_mutex_enter(v->db->mutex);
|
||||
rc = sqlite3VdbeReset(v);
|
||||
sqlite3VdbeRewind(v);
|
||||
@@ -112,7 +121,14 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
|
||||
int rc = SQLITE_OK;
|
||||
Vdbe *p = (Vdbe*)pStmt;
|
||||
#if SQLITE_THREADSAFE
|
||||
sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;
|
||||
sqlite3_mutex *mutex=NULL;
|
||||
#endif
|
||||
if( NULL==pStmt ){ return SQLITE_OK; } /* <rdar://problem/6646331> */
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecClearBindings(pStmt);
|
||||
#endif
|
||||
#if SQLITE_THREADSAFE
|
||||
mutex = ((Vdbe*)pStmt)->db->mutex;
|
||||
#endif
|
||||
sqlite3_mutex_enter(mutex);
|
||||
for(i=0; i<p->nVar; i++){
|
||||
@@ -1111,11 +1127,17 @@ int sqlite3_bind_blob(
|
||||
int nData,
|
||||
void (*xDel)(void*)
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindBlob(pStmt, i, zData, nData);
|
||||
#endif
|
||||
return bindText(pStmt, i, zData, nData, xDel, 0);
|
||||
}
|
||||
int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindDouble(pStmt, i, rValue);
|
||||
#endif
|
||||
rc = vdbeUnbind(p, i);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
|
||||
@@ -1124,11 +1146,17 @@ int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
|
||||
return rc;
|
||||
}
|
||||
int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindInt64(p, i, (i64)iValue);
|
||||
#endif
|
||||
return sqlite3_bind_int64(p, i, (i64)iValue);
|
||||
}
|
||||
int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindInt64(pStmt, i, iValue);
|
||||
#endif
|
||||
rc = vdbeUnbind(p, i);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
|
||||
@@ -1139,6 +1167,9 @@ int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
|
||||
int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe*)pStmt;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindNull(pStmt, i);
|
||||
#endif
|
||||
rc = vdbeUnbind(p, i);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_mutex_leave(p->db->mutex);
|
||||
@@ -1152,6 +1183,9 @@ int sqlite3_bind_text(
|
||||
int nData,
|
||||
void (*xDel)(void*)
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindText(pStmt, i, zData, nData);
|
||||
#endif
|
||||
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
@@ -1162,6 +1196,9 @@ int sqlite3_bind_text16(
|
||||
int nData,
|
||||
void (*xDel)(void*)
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindText(pStmt, i, zData, nData);
|
||||
#endif
|
||||
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_UTF16 */
|
||||
@@ -1185,6 +1222,9 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
|
||||
break;
|
||||
}
|
||||
case SQLITE_TEXT: {
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindText(pStmt, i, pValue->z, pValue->n);
|
||||
#endif
|
||||
rc = bindText(pStmt,i, pValue->z, pValue->n, SQLITE_TRANSIENT,
|
||||
pValue->enc);
|
||||
break;
|
||||
@@ -1199,6 +1239,9 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
|
||||
int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindBlob(pStmt, i, NULL, n);
|
||||
#endif
|
||||
rc = vdbeUnbind(p, i);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
|
||||
|
||||
@@ -1662,6 +1662,8 @@ void sqlite3VdbeMakeReady(
|
||||
assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
|
||||
p->expired = 0;
|
||||
|
||||
p->expired = 0;
|
||||
|
||||
/* Memory for registers, parameters, cursor, etc, is allocated in two
|
||||
** passes. On the first pass, we try to reuse unused space at the
|
||||
** end of the opcode array. If we are unable to satisfy all memory
|
||||
|
||||
@@ -1256,11 +1256,12 @@ int sqlite3WalOpen(
|
||||
const char *zWalName, /* Name of the WAL file */
|
||||
int bNoShm, /* True to run in heap-memory mode */
|
||||
i64 mxWalSize, /* Truncate WAL to this size on reset */
|
||||
int flags, /* VFS file protection flags */
|
||||
Wal **ppWal /* OUT: Allocated Wal handle */
|
||||
){
|
||||
int rc; /* Return Code */
|
||||
Wal *pRet; /* Object to allocate and return */
|
||||
int flags; /* Flags passed to OsOpen() */
|
||||
int vfsFlags; /* Flags passed to OsOpen() */
|
||||
|
||||
assert( zWalName && zWalName[0] );
|
||||
assert( pDbFd );
|
||||
@@ -1295,9 +1296,13 @@ int sqlite3WalOpen(
|
||||
pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);
|
||||
|
||||
/* Open file handle on the write-ahead log file. */
|
||||
flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
|
||||
rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
|
||||
if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){
|
||||
if( flags&SQLITE_OPEN_READONLY ){
|
||||
vfsFlags = flags | SQLITE_OPEN_WAL;
|
||||
} else {
|
||||
vfsFlags = flags | (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
|
||||
}
|
||||
rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, vfsFlags, &vfsFlags);
|
||||
if( rc==SQLITE_OK && vfsFlags&SQLITE_OPEN_READONLY ){
|
||||
pRet->readOnly = WAL_RDONLY;
|
||||
}
|
||||
|
||||
@@ -1917,6 +1922,9 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){
|
||||
** reordering the reads and writes.
|
||||
*/
|
||||
aHdr = walIndexHdr(pWal);
|
||||
if( aHdr==NULL ){
|
||||
return 1; /* Shouldn't be getting NULL from walIndexHdr, but we are */
|
||||
}
|
||||
memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
|
||||
walShmBarrier(pWal);
|
||||
memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
|
||||
@@ -2101,7 +2109,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
|
||||
*/
|
||||
if( cnt>5 ){
|
||||
int nDelay = 1; /* Pause time in microseconds */
|
||||
if( cnt>100 ){
|
||||
if( cnt>500 ){
|
||||
VVA_ONLY( pWal->lockError = 1; )
|
||||
return SQLITE_PROTOCOL;
|
||||
}
|
||||
@@ -2422,6 +2430,15 @@ Pgno sqlite3WalDbsize(Wal *pWal){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the file for this Wal journal (or zero, if unknown).
|
||||
*/
|
||||
sqlite3_file *sqlite3WalFile(Wal *pWal){
|
||||
if( pWal ){
|
||||
return pWal->pWalFd;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function starts a write transaction on the WAL.
|
||||
@@ -2652,6 +2669,10 @@ typedef struct WalWriter {
|
||||
sqlite3_int64 iSyncPoint; /* Fsync at this offset */
|
||||
int syncFlags; /* Flags for the fsync */
|
||||
int szPage; /* Size of one page */
|
||||
#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
|
||||
void *aFrameBuf; /* Frame buffer */
|
||||
size_t szFrameBuf; /* Size of frame buffer */
|
||||
#endif
|
||||
} WalWriter;
|
||||
|
||||
/*
|
||||
@@ -2695,17 +2716,31 @@ static int walWriteOneFrame(
|
||||
){
|
||||
int rc; /* Result code from subfunctions */
|
||||
void *pData; /* Data actually written */
|
||||
#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
|
||||
void *aFrame;
|
||||
|
||||
aFrame = p->aFrameBuf;
|
||||
#else
|
||||
u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */
|
||||
#endif
|
||||
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM;
|
||||
#else
|
||||
pData = pPage->pData;
|
||||
#endif
|
||||
|
||||
walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame);
|
||||
|
||||
#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
|
||||
memcpy(&aFrame[WAL_FRAME_HDRSIZE], pData, p->szPage);
|
||||
rc = walWriteToLog(p, aFrame, (p->szPage + WAL_FRAME_HDRSIZE), iOffset);
|
||||
#else
|
||||
rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
|
||||
if( rc ) return rc;
|
||||
/* Write the page data */
|
||||
rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame));
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2804,6 +2839,13 @@ int sqlite3WalFrames(
|
||||
w.szPage = szPage;
|
||||
iOffset = walFrameOffset(iFrame+1, szPage);
|
||||
szFrame = szPage + WAL_FRAME_HDRSIZE;
|
||||
#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
|
||||
w.aFrameBuf = (void *)malloc(szFrame);
|
||||
if( NULL==w.aFrameBuf ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Write all frames into the log file exactly once */
|
||||
for(p=pList; p; p=p->pDirty){
|
||||
@@ -2846,6 +2888,9 @@ int sqlite3WalFrames(
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
|
||||
free(w.aFrameBuf);
|
||||
#endif
|
||||
/* If this frame set completes the first transaction in the WAL and
|
||||
** if PRAGMA journal_size_limit is set, then truncate the WAL to the
|
||||
** journal size limit, if possible.
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
typedef struct Wal Wal;
|
||||
|
||||
/* Open and close a connection to a write-ahead log. */
|
||||
int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
|
||||
int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, int, Wal**);
|
||||
int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
|
||||
|
||||
/* Set the limiting size of a WAL file. */
|
||||
@@ -77,6 +77,9 @@ int sqlite3WalReadFrame(Wal *, u32, int, u8 *);
|
||||
/* If the WAL is not empty, return the size of the database. */
|
||||
Pgno sqlite3WalDbsize(Wal *pWal);
|
||||
|
||||
/* If a WAL journal file has been created, return it */
|
||||
sqlite3_file *sqlite3WalFile(Wal *pWal);
|
||||
|
||||
/* Obtain or release the WRITER lock. */
|
||||
int sqlite3WalBeginWriteTransaction(Wal *pWal);
|
||||
int sqlite3WalEndWriteTransaction(Wal *pWal);
|
||||
|
||||
@@ -146,6 +146,8 @@ ifcapable !wal {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
db close
|
||||
forcedelete test.db
|
||||
do_test 8_3_names-5.0 {
|
||||
|
||||
+18
-17
@@ -737,23 +737,24 @@ do_test attach-6.1 {
|
||||
}
|
||||
} {0 {}}
|
||||
if {$tcl_platform(platform)=="unix"} {
|
||||
do_test attach-6.2 {
|
||||
sqlite3 dbx cannot-read
|
||||
dbx eval {CREATE TABLE t1(a,b,c)}
|
||||
dbx close
|
||||
file attributes cannot-read -permission 0000
|
||||
if {[file writable cannot-read]} {
|
||||
puts "\n**** Tests do not work when run as root ****"
|
||||
forcedelete cannot-read
|
||||
exit 1
|
||||
}
|
||||
catchsql {
|
||||
ATTACH DATABASE 'cannot-read' AS noread;
|
||||
}
|
||||
} {1 {unable to open database: cannot-read}}
|
||||
do_test attach-6.2.2 {
|
||||
db errorcode
|
||||
} {14}
|
||||
sqlite3 dbx cannot-read
|
||||
dbx eval {CREATE TABLE t1(a,b,c)}
|
||||
dbx close
|
||||
file attributes cannot-read -permission 0000
|
||||
if {[file writable cannot-read]} {
|
||||
#puts "\n**** Tests do not work when run as root ****"
|
||||
forcedelete cannot-read
|
||||
#exit 1
|
||||
} else {
|
||||
do_test attach-6.2 {
|
||||
catchsql {
|
||||
ATTACH DATABASE 'cannot-read' AS noread;
|
||||
}
|
||||
} {1 {unable to open database: cannot-read}}
|
||||
do_test attach-6.2.2 {
|
||||
db errorcode
|
||||
} {14}
|
||||
}
|
||||
forcedelete cannot-read
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ foreach {name f} $files {
|
||||
set mode wal
|
||||
}
|
||||
ifcapable !wal { set mode delete }
|
||||
if ![wal_is_ok] { set mode delete }
|
||||
lappend L $mode
|
||||
append S "
|
||||
PRAGMA $name.journal_mode = WAL;
|
||||
|
||||
@@ -656,6 +656,9 @@ do_test bind-13.4 {
|
||||
[sqlite3_column_type $VM 2]
|
||||
} {NULL NULL NULL}
|
||||
sqlite3_finalize $VM
|
||||
do_test bind-13.5 {
|
||||
sqlite3_clear_bindings_null
|
||||
} {0}
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# These tests attempt to reproduce bug #3463.
|
||||
|
||||
+16
-5
@@ -107,12 +107,17 @@ do_execsql_test cache-2.3.3 {
|
||||
} {main exclusive temp closed}
|
||||
do_test cache-2.3.4 { pager_cache_size db } 2
|
||||
do_execsql_test cache-2.3.5 COMMIT
|
||||
do_test cache-2.3.6 { pager_cache_size db } 1
|
||||
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
# purgeable pcache doesn't share cache between connections
|
||||
do_test cache-2.3.6 { pager_cache_size db } 1
|
||||
}
|
||||
do_execsql_test cache-2.3.7 {
|
||||
SELECT * FROM t1 UNION SELECT * FROM t2;
|
||||
} {1 2 i j x y}
|
||||
do_test cache-2.3.8 { pager_cache_size db } 1
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
# purgeable pcache doesn't share cache between connections
|
||||
do_test cache-2.3.8 { pager_cache_size db } 1
|
||||
}
|
||||
|
||||
# Tests for cache_size = 0.
|
||||
#
|
||||
@@ -130,11 +135,17 @@ do_execsql_test cache-2.4.3 {
|
||||
do_test cache-2.4.4 { pager_cache_size db } 2
|
||||
do_execsql_test cache-2.4.5 COMMIT
|
||||
|
||||
do_test cache-2.4.6 { pager_cache_size db } 0
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
# purgeable pcache doesn't share cache between connections
|
||||
do_test cache-2.4.6 { pager_cache_size db } 0
|
||||
}
|
||||
do_execsql_test cache-2.4.7 {
|
||||
SELECT * FROM t1 UNION SELECT * FROM t2;
|
||||
} {1 2 i j x y}
|
||||
do_test cache-2.4.8 { pager_cache_size db } 0
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
# purgeable pcache doesn't share cache between connections
|
||||
do_test cache-2.4.8 { pager_cache_size db } 0
|
||||
}
|
||||
|
||||
sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# 2015-03-30
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Corruption consisting of a database page that thinks it is a child
|
||||
# of itself.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix corruptJ
|
||||
|
||||
if {[permutation]=="mmap"} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
# Do not use a codec for tests in this file, as the database file is
|
||||
# manipulated directly using tcl scripts (using the [hexio_write] command).
|
||||
#
|
||||
do_not_use_codec
|
||||
database_may_be_corrupt
|
||||
|
||||
# Initialize the database.
|
||||
#
|
||||
do_execsql_test 1.1 {
|
||||
PRAGMA page_size=1024;
|
||||
PRAGMA auto_vacuum=0;
|
||||
CREATE TABLE t1(a,b);
|
||||
WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<10)
|
||||
INSERT INTO t1(a,b) SELECT i, zeroblob(700) FROM c;
|
||||
} {}
|
||||
db close
|
||||
|
||||
# Corrupt the root page of the t1 table such that the left-child pointer
|
||||
# for the very first cell points back to the root. Then try to DROP the
|
||||
# table. The clearDatabasePage() routine should not loop.
|
||||
#
|
||||
do_test 1.2 {
|
||||
hexio_write test.db [expr {2*1024-2}] 02
|
||||
sqlite3 db test.db
|
||||
catchsql { DROP TABLE t1 }
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
# Similar test using a WITHOUT ROWID table
|
||||
#
|
||||
do_test 2.1 {
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
PRAGMA page_size=1024;
|
||||
PRAGMA auto_vacuum=0;
|
||||
CREATE TABLE t1(a,b,PRIMARY KEY(a,b)) WITHOUT ROWID;
|
||||
WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<100)
|
||||
INSERT INTO t1(a,b) SELECT i, zeroblob(200) FROM c;
|
||||
}
|
||||
} {}
|
||||
|
||||
# The table is three levels deep. Corrupt the left child of an intermediate
|
||||
# page so that it points back to the root page.
|
||||
#
|
||||
do_test 2.2 {
|
||||
db close
|
||||
hexio_read test.db [expr {9*1024+391}] 8
|
||||
} {0000000B814D0401}
|
||||
do_test 2.2b {
|
||||
hexio_write test.db [expr {9*1024+391}] 00000002
|
||||
sqlite3 db test.db
|
||||
catchsql { PRAGMA secure_delete=ON; DROP TABLE t1; }
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
finish_test
|
||||
@@ -38,6 +38,9 @@ proc db_write {db {reset 0}} {
|
||||
}
|
||||
|
||||
do_test 1.1 {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
execsql { PRAGMA mmap_size = 0 }
|
||||
|
||||
+1
-5
@@ -401,12 +401,8 @@ sqlite3 db test.db
|
||||
# if we're using proxy locks, we use 3 filedescriptors for a db
|
||||
# that is open but NOT writing changes, normally
|
||||
# sqlite uses 1 (proxy locking adds the conch and the local lock)
|
||||
set using_proxy 0
|
||||
foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
|
||||
set using_proxy $value
|
||||
}
|
||||
set extrafds 0
|
||||
if {$using_proxy!=0} {
|
||||
if {[forced_proxy_locking]} {
|
||||
set extrafds 2
|
||||
}
|
||||
|
||||
|
||||
+12
-1
@@ -76,13 +76,24 @@ set skipwaltests [expr {
|
||||
[permutation]=="journaltest" || [permutation]=="inmemory_journal"
|
||||
}]
|
||||
ifcapable !wal { set skipwaltests 1 }
|
||||
if {![wal_is_ok]} { set skipwaltests 1 }
|
||||
|
||||
if {!$skipwaltests} {
|
||||
db close
|
||||
forcedelete test.db
|
||||
ifcapable enable_persist_wal {
|
||||
forcedelete test.db-journal
|
||||
forcedelete test.db-wal
|
||||
forcedelete test.db-shm
|
||||
}
|
||||
if {[forced_proxy_locking]} {
|
||||
forcedelete .test.db-conch
|
||||
}
|
||||
sqlite3 db test.db
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
file_control_chunksize_test db main [expr 32*1024]
|
||||
|
||||
do_test fallocate-2.1 {
|
||||
execsql {
|
||||
PRAGMA page_size = 1024;
|
||||
|
||||
+11
-6
@@ -260,12 +260,17 @@ proc access_method {args} {
|
||||
return ""
|
||||
}
|
||||
|
||||
do_test incrblob3-7.2 {
|
||||
sqlite3 db test.db
|
||||
sqlite3_db_config_lookaside db 0 0 0
|
||||
list [catch {db incrblob blobs v 1} msg] $msg
|
||||
} {1 {database schema has changed}}
|
||||
db close
|
||||
#set sqlite_os_trace 1
|
||||
# AFP asserts because the "db incrblob blobs v 1" clears the file locks and the unlock fails (HFS doesn't care about a failed unlock)
|
||||
if {[path_is_local "."]} {
|
||||
|
||||
do_test incrblob3-7.2 {
|
||||
sqlite3 db test.db
|
||||
sqlite3_db_config_lookaside db 0 0 0
|
||||
list [catch {db incrblob blobs v 1} msg] $msg
|
||||
} {1 {database schema has changed}}
|
||||
db close
|
||||
}
|
||||
tvfs delete
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
# If this build of the library does not support auto-vacuum, omit this
|
||||
# whole file.
|
||||
@@ -134,6 +135,8 @@ do_test incrvacuum2-3.2 {
|
||||
|
||||
integrity_check incrvacuum2-3.3
|
||||
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
ifcapable wal {
|
||||
# At one point, when a specific page was being extracted from the b-tree
|
||||
# free-list (e.g. during an incremental-vacuum), all trunk pages that
|
||||
@@ -188,8 +191,10 @@ ifcapable wal {
|
||||
execsql {
|
||||
PRAGMA journal_mode = WAL;
|
||||
PRAGMA incremental_vacuum(1);
|
||||
PRAGMA wal_checkpoint;
|
||||
}
|
||||
} {wal}
|
||||
do_test 4.2.1 {
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
file size test.db-wal
|
||||
} [expr {32+2*(512+24)}]
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ source $testdir/malloc_common.tcl
|
||||
# If a connection is required to create a journal file, it creates it with
|
||||
# the same file-system permissions as the database file itself. Test this.
|
||||
#
|
||||
if {$::tcl_platform(platform) == "unix"} {
|
||||
if {$::tcl_platform(platform) == "unix" && ![path_is_dos "."]} {
|
||||
|
||||
# Changed on 2012-02-13: umask is deliberately ignored for -wal, -journal,
|
||||
# and -shm files.
|
||||
|
||||
+73
-69
@@ -106,87 +106,91 @@ if {[catch {sqlite3 db test.db -vfs unix-flock} msg]} {
|
||||
return
|
||||
}
|
||||
|
||||
do_test lock5-flock.1 {
|
||||
sqlite3 db test.db -vfs unix-flock
|
||||
execsql {
|
||||
CREATE TABLE t1(a, b);
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
}
|
||||
} {}
|
||||
# Only run the flock tests on a local file system
|
||||
if { [path_is_local "."] } {
|
||||
|
||||
# Make sure we are not accidentally using the dotfile locking scheme.
|
||||
do_test lock5-flock.2 {
|
||||
file exists test.db.lock
|
||||
} {0}
|
||||
do_test lock5-flock.1 {
|
||||
sqlite3 db test.db -vfs unix-flock
|
||||
execsql {
|
||||
CREATE TABLE t1(a, b);
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test lock5-flock.3 {
|
||||
catch { sqlite3 db2 test.db -vfs unix-flock }
|
||||
catchsql { SELECT * FROM t1 } db2
|
||||
} {1 {database is locked}}
|
||||
# Make sure we are not accidentally using the dotfile locking scheme.
|
||||
do_test lock5-flock.2 {
|
||||
file exists test.db.lock
|
||||
} {0}
|
||||
|
||||
do_test lock5-flock.4 {
|
||||
execsql COMMIT
|
||||
catchsql { SELECT * FROM t1 } db2
|
||||
} {0 {1 2}}
|
||||
do_test lock5-flock.3 {
|
||||
catch { sqlite3 db2 test.db -vfs unix-flock }
|
||||
catchsql { SELECT * FROM t1 } db2
|
||||
} {1 {database is locked}}
|
||||
|
||||
do_test lock5-flock.5 {
|
||||
execsql BEGIN
|
||||
catchsql { SELECT * FROM t1 } db2
|
||||
} {0 {1 2}}
|
||||
do_test lock5-flock.4 {
|
||||
execsql COMMIT
|
||||
catchsql { SELECT * FROM t1 } db2
|
||||
} {0 {1 2}}
|
||||
|
||||
do_test lock5-flock.6 {
|
||||
execsql {SELECT * FROM t1}
|
||||
catchsql { SELECT * FROM t1 } db2
|
||||
} {1 {database is locked}}
|
||||
do_test lock5-flock.5 {
|
||||
execsql BEGIN
|
||||
catchsql { SELECT * FROM t1 } db2
|
||||
} {0 {1 2}}
|
||||
|
||||
do_test lock5-flock.7 {
|
||||
db close
|
||||
catchsql { SELECT * FROM t1 } db2
|
||||
} {0 {1 2}}
|
||||
do_test lock5-flock.6 {
|
||||
execsql {SELECT * FROM t1}
|
||||
catchsql { SELECT * FROM t1 } db2
|
||||
} {1 {database is locked}}
|
||||
|
||||
do_test lock5-flock.8 {
|
||||
db2 close
|
||||
} {}
|
||||
do_test lock5-flock.7 {
|
||||
db close
|
||||
catchsql { SELECT * FROM t1 } db2
|
||||
} {0 {1 2}}
|
||||
|
||||
#####################################################################
|
||||
do_test lock5-flock.8 {
|
||||
db2 close
|
||||
} {}
|
||||
|
||||
do_test lock5-none.1 {
|
||||
sqlite3 db test.db -vfs unix-none
|
||||
sqlite3 db2 test.db -vfs unix-none
|
||||
execsql {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
}
|
||||
} {}
|
||||
do_test lock5-none.2 {
|
||||
execsql { SELECT * FROM t1 }
|
||||
} {1 2 3 4}
|
||||
do_test lock5-flock.3 {
|
||||
execsql { SELECT * FROM t1 } db2
|
||||
} {1 2}
|
||||
do_test lock5-none.4 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
SELECT * FROM t1;
|
||||
} db2
|
||||
} {1 2}
|
||||
do_test lock5-none.5 {
|
||||
execsql COMMIT
|
||||
execsql {SELECT * FROM t1} db2
|
||||
} {1 2}
|
||||
#####################################################################
|
||||
|
||||
ifcapable memorymanage {
|
||||
do_test lock5-none.6 {
|
||||
sqlite3_release_memory 1000000
|
||||
execsql {SELECT * FROM t1} db2
|
||||
do_test lock5-none.1 {
|
||||
sqlite3 db test.db -vfs unix-none
|
||||
sqlite3 db2 test.db -vfs unix-none
|
||||
execsql {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
}
|
||||
} {}
|
||||
do_test lock5-none.2 {
|
||||
execsql { SELECT * FROM t1 }
|
||||
} {1 2 3 4}
|
||||
}
|
||||
do_test lock5-flock.3 {
|
||||
execsql { SELECT * FROM t1 } db2
|
||||
} {1 2}
|
||||
do_test lock5-none.4 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
SELECT * FROM t1;
|
||||
} db2
|
||||
} {1 2}
|
||||
do_test lock5-none.5 {
|
||||
execsql COMMIT
|
||||
execsql {SELECT * FROM t1} db2
|
||||
} {1 2}
|
||||
|
||||
do_test lock5-flock.X {
|
||||
db close
|
||||
db2 close
|
||||
} {}
|
||||
ifcapable memorymanage {
|
||||
do_test lock5-none.6 {
|
||||
sqlite3_release_memory 1000000
|
||||
execsql {SELECT * FROM t1} db2
|
||||
} {1 2 3 4}
|
||||
}
|
||||
|
||||
do_test lock5-flock.X {
|
||||
db close
|
||||
db2 close
|
||||
} {}
|
||||
}
|
||||
|
||||
ifcapable lock_proxy_pragmas {
|
||||
set env(SQLITE_FORCE_PROXY_LOCKING) $::using_proxy
|
||||
|
||||
+5
-3
@@ -126,9 +126,10 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
|
||||
set lockpath
|
||||
} {{:auto: (not held)}}
|
||||
|
||||
set lpp [exec mktemp -t fail]
|
||||
do_test lock6-1.4.1 {
|
||||
execsql "PRAGMA lock_proxy_file='$lpp'"
|
||||
catchsql {
|
||||
PRAGMA lock_proxy_file="notmine";
|
||||
select * from sqlite_master;
|
||||
} db
|
||||
} {1 {database is locked}}
|
||||
@@ -137,7 +138,7 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
|
||||
execsql {
|
||||
PRAGMA lock_proxy_file;
|
||||
} db
|
||||
} {notmine}
|
||||
} $lpp
|
||||
|
||||
do_test lock6-1.5 {
|
||||
testfixture $::tf1 {
|
||||
@@ -150,9 +151,10 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
|
||||
|
||||
catch {testfixture $::tf1 {db close}}
|
||||
|
||||
set lpp [exec mktemp -t ok]
|
||||
do_test lock6-1.6 {
|
||||
execsql "PRAGMA lock_proxy_file='$lpp'"
|
||||
execsql {
|
||||
PRAGMA lock_proxy_file="mine";
|
||||
select * from sqlite_master;
|
||||
} db
|
||||
} {}
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
# 2008 June 28
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is database proxy locks.
|
||||
#
|
||||
# $Id$
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# This file is only run if using the unix backend compiled with the
|
||||
# SQLITE_ENABLE_LOCKING_STYLE macro.
|
||||
db close
|
||||
if {[catch {sqlite3 db test.db -vfs unix-none} msg]} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
db close
|
||||
file delete -force test.db.lock
|
||||
|
||||
#####################################################################
|
||||
ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
|
||||
set ::using_proxy 0
|
||||
foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
|
||||
set ::using_proxy $value
|
||||
}
|
||||
|
||||
# enable the proxy locking for these tests
|
||||
set env(SQLITE_FORCE_PROXY_LOCKING) "1"
|
||||
|
||||
# test conch file creation
|
||||
#
|
||||
|
||||
catch { file delete lock_proxy_test.db }
|
||||
catch { file delete .lock_proxy_test.db-conch }
|
||||
# test that proxy locking mode creates conch files
|
||||
do_test lock_proxy1.0 {
|
||||
sqlite3 db2 lock_proxy_test.db
|
||||
catchsql {
|
||||
create table x(y);
|
||||
} db2
|
||||
file exists .lock_proxy_test.db-conch
|
||||
} {1}
|
||||
catch { db2 close }
|
||||
|
||||
|
||||
# test proxy locking readonly file system handling
|
||||
#
|
||||
|
||||
if {[file exists /usr/bin/hdiutil]} {
|
||||
|
||||
puts "Creating readonly file system for proxy locking tests..."
|
||||
if {[file exists /Volumes/readonly]} {
|
||||
exec hdiutil detach /Volumes/readonly
|
||||
}
|
||||
if {[file exists readonly.dmg]} {
|
||||
file delete readonly.dmg
|
||||
}
|
||||
exec hdiutil create -megabytes 1 -fs HFS+ readonly.dmg -volname readonly
|
||||
exec hdiutil attach readonly.dmg
|
||||
|
||||
# create test1.db and a .test1.db-conch for host4
|
||||
set sqlite_hostid_num 4
|
||||
sqlite3 db2 /Volumes/readonly/test1.db
|
||||
execsql {
|
||||
create table x(y);
|
||||
} db2
|
||||
db2 close
|
||||
|
||||
# create test2.db and a .test2.db-conch for host5
|
||||
set sqlite_hostid_num 5
|
||||
sqlite3 db2 /Volumes/readonly/test2.db
|
||||
execsql {
|
||||
create table x(y);
|
||||
} db2
|
||||
db2 close
|
||||
|
||||
# create test3.db without a conch file
|
||||
set env(SQLITE_FORCE_PROXY_LOCKING) "0"
|
||||
sqlite3 db2 /Volumes/readonly/test3.db
|
||||
execsql {
|
||||
create table x(y);
|
||||
} db2
|
||||
db2 close
|
||||
exec hdiutil detach /Volumes/readonly
|
||||
exec hdiutil attach -readonly readonly.dmg
|
||||
|
||||
# test that an unwritable, host-mismatched conch file prevents
|
||||
# read only proxy-locking mode database access
|
||||
set env(SQLITE_FORCE_PROXY_LOCKING) "1"
|
||||
do_test lock_proxy2.0 {
|
||||
sqlite3 db2 /Volumes/readonly/test1.db
|
||||
catchsql {
|
||||
select * from sqlite_master;
|
||||
} db2
|
||||
} {1 {database is locked}}
|
||||
catch { db2 close }
|
||||
|
||||
# test that an unwritable, host-matching conch file allows
|
||||
# read only proxy-locking mode database access
|
||||
do_test lock_proxy2.1 {
|
||||
sqlite3 db2 /Volumes/readonly/test2.db
|
||||
catchsql {
|
||||
select * from sqlite_master;
|
||||
} db2
|
||||
} {0 {table x x 2 {CREATE TABLE x(y)}}}
|
||||
catch { db2 close }
|
||||
|
||||
# test that an unwritable, nonexistant conch file allows
|
||||
# read only proxy-locking mode database access
|
||||
do_test lock_proxy2.2 {
|
||||
sqlite3 db2 /Volumes/readonly/test3.db
|
||||
catchsql {
|
||||
select * from sqlite_master;
|
||||
} db2
|
||||
} {0 {table x x 2 {CREATE TABLE x(y)}}}
|
||||
catch { db2 close }
|
||||
|
||||
exec hdiutil detach /Volumes/readonly
|
||||
file delete readonly.dmg
|
||||
}
|
||||
set env(SQLITE_FORCE_PROXY_LOCKING) "0"
|
||||
set sqlite_hostid_num 0
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
|
||||
file delete -force test.db
|
||||
|
||||
ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
|
||||
set env(SQLITE_FORCE_PROXY_LOCKING) $::using_proxy
|
||||
}
|
||||
|
||||
finish_test
|
||||
+3
-3
@@ -314,7 +314,7 @@ if {[permutation] == ""} {
|
||||
#
|
||||
do_test main-3.1 {
|
||||
catch {db close}
|
||||
foreach f [glob -nocomplain testdb/*] {forcedelete $f}
|
||||
catch {foreach f [glob -nocomplain testdb/*] {forcedelete $f}}
|
||||
forcedelete testdb
|
||||
sqlite3 db testdb
|
||||
set v [catch {execsql {SELECT * from T1 where x!!5}} msg]
|
||||
@@ -322,7 +322,7 @@ do_test main-3.1 {
|
||||
} {1 {unrecognized token: "!!"}}
|
||||
do_test main-3.2 {
|
||||
catch {db close}
|
||||
foreach f [glob -nocomplain testdb/*] {forcedelete $f}
|
||||
catch {foreach f [glob -nocomplain testdb/*] {forcedelete $f}}
|
||||
forcedelete testdb
|
||||
sqlite3 db testdb
|
||||
set v [catch {execsql {SELECT * from T1 where ^x}} msg]
|
||||
@@ -442,7 +442,7 @@ do_test main-3.2.30 {
|
||||
|
||||
do_test main-3.3 {
|
||||
catch {db close}
|
||||
foreach f [glob -nocomplain testdb/*] {forcedelete $f}
|
||||
catch {foreach f [glob -nocomplain testdb/*] {forcedelete $f}}
|
||||
forcedelete testdb
|
||||
sqlite3 db testdb
|
||||
execsql {
|
||||
|
||||
@@ -434,7 +434,7 @@ proc do_malloc_test {tn args} {
|
||||
set zRepeat "transient"
|
||||
if {$::iRepeat} {set zRepeat "persistent"}
|
||||
restore_prng_state
|
||||
foreach file [glob -nocomplain test.db-mj*] {forcedelete $file}
|
||||
catch {foreach file [glob -nocomplain test.db-mj*] {forcedelete $file}}
|
||||
|
||||
do_test ${tn}.${zRepeat}.${::n} {
|
||||
|
||||
|
||||
+1
-5
@@ -22,12 +22,8 @@ set N 300
|
||||
# if we're using proxy locks, we use 5 filedescriptors for a db
|
||||
# that is open and in the middle of writing changes, normally
|
||||
# sqlite uses 3 (proxy locking adds the conch and the local lock)
|
||||
set using_proxy 0
|
||||
foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
|
||||
set using_proxy value
|
||||
}
|
||||
set num_fd_per_openwrite_db 3
|
||||
if {$using_proxy>0} {
|
||||
if {[forced_proxy_locking]} {
|
||||
set num_fd_per_openwrite_db 5
|
||||
}
|
||||
|
||||
|
||||
+21
-19
@@ -11,7 +11,6 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is in-memory database backend.
|
||||
#
|
||||
# $Id: memdb.test,v 1.19 2009/05/18 16:04:38 danielk1977 Exp $
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
@@ -407,24 +406,27 @@ do_test memdb-8.2 {
|
||||
|
||||
# Test that auto-vacuum works with in-memory databases.
|
||||
#
|
||||
ifcapable autovacuum {
|
||||
do_test memdb-9.1 {
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
db cache size 0
|
||||
execsql {
|
||||
PRAGMA auto_vacuum = full;
|
||||
CREATE TABLE t1(a);
|
||||
INSERT INTO t1 VALUES(randstr(1000,1000));
|
||||
INSERT INTO t1 VALUES(randstr(1000,1000));
|
||||
INSERT INTO t1 VALUES(randstr(1000,1000));
|
||||
}
|
||||
set memused [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
|
||||
set pgovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 1]
|
||||
execsql { DELETE FROM t1 }
|
||||
set memused2 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
|
||||
expr {($memused2 + 2048 < $memused) || $pgovfl==0}
|
||||
} {1}
|
||||
set msize [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0]
|
||||
if {[lindex $msize 2]!=0} {
|
||||
ifcapable autovacuum {
|
||||
do_test memdb-9.1 {
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
db cache size 0
|
||||
execsql {
|
||||
PRAGMA auto_vacuum = full;
|
||||
CREATE TABLE t1(a);
|
||||
INSERT INTO t1 VALUES(randstr(1000,1000));
|
||||
INSERT INTO t1 VALUES(randstr(1000,1000));
|
||||
INSERT INTO t1 VALUES(randstr(1000,1000));
|
||||
}
|
||||
set memused [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
|
||||
set pgovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 1]
|
||||
execsql { DELETE FROM t1 }
|
||||
set memused2 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1]
|
||||
expr {($memused2 + 2048 < $memused) || $pgovfl==0}
|
||||
} {1}
|
||||
}
|
||||
}
|
||||
|
||||
} ;# ifcapable memorydb
|
||||
|
||||
+56
-43
@@ -98,9 +98,11 @@ build_test_db memsubsys1-2 {PRAGMA page_size=1024; PRAGMA mmap_size=0}
|
||||
#show_memstats
|
||||
set MEMORY_MANAGEMENT $sqlite_options(memorymanage)
|
||||
ifcapable !malloc_usable_size {
|
||||
do_test memsubsys1-2.3 {
|
||||
set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
} [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024]
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
do_test memsubsys1-2.3 {
|
||||
set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
} [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024]
|
||||
}
|
||||
}
|
||||
do_test memsubsys1-2.4 {
|
||||
set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
|
||||
@@ -119,12 +121,14 @@ sqlite3_initialize
|
||||
reset_highwater_marks
|
||||
build_test_db memsubsys1-3.1 {PRAGMA page_size=1024}
|
||||
#show_memstats
|
||||
do_test memsubsys1-3.1.3 {
|
||||
set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
|
||||
} 0
|
||||
do_test memsubsys1-3.1.4 {
|
||||
set overflow [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
} $max_pagecache
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
do_test memsubsys1-3.1.3 {
|
||||
set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
|
||||
} 0
|
||||
do_test memsubsys1-3.1.4 {
|
||||
set overflow [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
} $max_pagecache
|
||||
}
|
||||
do_test memsubsys1-3.1.5 {
|
||||
set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
|
||||
} 0
|
||||
@@ -159,9 +163,11 @@ do_test memsubsys1-4.3 {
|
||||
set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
|
||||
expr {$pg_used>=45 && $pg_used<=50}
|
||||
} 1
|
||||
do_test memsubsys1-4.4 {
|
||||
set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
} 0
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
do_test memsubsys1-4.4 {
|
||||
set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
} 0
|
||||
}
|
||||
do_test memsubsys1-4.5 {
|
||||
set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
|
||||
expr {$maxreq<7000}
|
||||
@@ -184,17 +190,20 @@ build_test_db memsubsys1-5 {PRAGMA page_size=4096}
|
||||
do_test memsubsys1-5.3 {
|
||||
set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
|
||||
} 24
|
||||
do_test memsubsys1-5.4 {
|
||||
set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
|
||||
expr {$maxreq>4096}
|
||||
} 1
|
||||
do_test memsubsys1-5.5 {
|
||||
set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
|
||||
} 0
|
||||
do_test memsubsys1-5.6 {
|
||||
set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
|
||||
expr {$s_ovfl>6000}
|
||||
} 1
|
||||
set msize [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0]
|
||||
if {[lindex $msize 2]!=0} {
|
||||
do_test memsubsys1-5.4 {
|
||||
set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
|
||||
expr {$maxreq>4096}
|
||||
} 1
|
||||
do_test memsubsys1-5.5 {
|
||||
set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
|
||||
} 0
|
||||
do_test memsubsys1-5.6 {
|
||||
set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
|
||||
expr {$s_ovfl>6000}
|
||||
} 1
|
||||
}
|
||||
|
||||
# Test 6: Activate both PAGECACHE and SCRATCH with a 4k page size.
|
||||
# Make it so that SCRATCH is large enough
|
||||
@@ -241,13 +250,15 @@ do_test memsubsys1-7.3 {
|
||||
set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
|
||||
expr {$pg_used<24}
|
||||
} 1
|
||||
do_test memsubsys1-7.4 {
|
||||
set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
} 0
|
||||
do_test memsubsys1-7.5 {
|
||||
set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
|
||||
expr {$maxreq<4100}
|
||||
} 1
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
do_test memsubsys1-7.4 {
|
||||
set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
|
||||
} 0
|
||||
do_test memsubsys1-7.5 {
|
||||
set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
|
||||
expr {$maxreq<4100}
|
||||
} 1
|
||||
}
|
||||
do_test memsubsys1-7.6 {
|
||||
set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
|
||||
} 1
|
||||
@@ -270,19 +281,21 @@ do_test memsubsys1-8.1 {
|
||||
do_test memsubsys1-8.2 {
|
||||
set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
|
||||
} 0
|
||||
do_test memsubsys1-8.3 {
|
||||
sqlite3 db :memory:
|
||||
db eval {
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(zeroblob(400));
|
||||
INSERT INTO t1 VALUES(zeroblob(400));
|
||||
INSERT INTO t1 SELECT * FROM t1;
|
||||
INSERT INTO t1 SELECT * FROM t1;
|
||||
INSERT INTO t1 SELECT * FROM t1;
|
||||
}
|
||||
expr {[lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]>0}
|
||||
} 1
|
||||
db close
|
||||
if {[lindex $msize 2]!=0} {
|
||||
do_test memsubsys1-8.3 {
|
||||
sqlite3 db :memory:
|
||||
db eval {
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(zeroblob(400));
|
||||
INSERT INTO t1 VALUES(zeroblob(400));
|
||||
INSERT INTO t1 SELECT * FROM t1;
|
||||
INSERT INTO t1 SELECT * FROM t1;
|
||||
INSERT INTO t1 SELECT * FROM t1;
|
||||
}
|
||||
expr {[lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]>0}
|
||||
} 1
|
||||
db close
|
||||
}
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_memstatus 0
|
||||
sqlite3_initialize
|
||||
|
||||
@@ -14,6 +14,12 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
|
||||
# AFP doesn't like multiplex db tests
|
||||
if { ![path_is_local "."] } {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
# The tests in this file assume that SQLite is compiled without
|
||||
# ENABLE_8_3_NAMES.
|
||||
#
|
||||
|
||||
+40
-31
@@ -546,6 +546,8 @@ proc copy_on_mj_delete {method filename args} {
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
if {![forced_proxy_locking]} {
|
||||
# proxy locking uses can't deal with auto proxy file paths longer than MAXPATHLEN
|
||||
foreach {tn1 tcl} {
|
||||
1 { set prefix "test.db" }
|
||||
2 {
|
||||
@@ -677,6 +679,7 @@ foreach {tn1 tcl} {
|
||||
db close
|
||||
tv delete
|
||||
forcedelete $dirname
|
||||
}
|
||||
|
||||
|
||||
# Set up a VFS to make a copy of the file-system just before deleting a
|
||||
@@ -1159,7 +1162,7 @@ do_execsql_test pager1-6.12 { PRAGMA max_page_count } {11}
|
||||
# $ws: The expected size of the WAL file, in bytes, after executing
|
||||
# the SQL script. Or -1 if the WAL is not expected to exist.
|
||||
#
|
||||
ifcapable wal {
|
||||
if {$::sqlite_options(wal) && [wal_is_ok]} {
|
||||
faultsim_delete_and_reopen
|
||||
foreach {tn sql res js ws} [subst {
|
||||
|
||||
@@ -1195,6 +1198,9 @@ ifcapable wal {
|
||||
10 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8} 0 -1
|
||||
|
||||
}] {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
do_execsql_test pager1-7.1.$tn.1 $sql $res
|
||||
catch { set J -1 ; set J [file size test.db-journal] }
|
||||
catch { set W -1 ; set W [file size test.db-wal] }
|
||||
@@ -1964,7 +1970,7 @@ do_test pager1-20.2.2 {
|
||||
}
|
||||
} {}
|
||||
|
||||
ifcapable wal {
|
||||
if {$::sqlite_options(wal) && [wal_is_ok]} {
|
||||
do_test pager1-20.3.1 {
|
||||
faultsim_delete_and_reopen
|
||||
db func a_string a_string
|
||||
@@ -1999,7 +2005,7 @@ ifcapable wal {
|
||||
# pager1-21.1.*: The VFS has an iVersion less than 2, or
|
||||
# pager1-21.2.*: The VFS does not provide xShmXXX() methods.
|
||||
#
|
||||
ifcapable wal {
|
||||
if {$::sqlite_options(wal) && [wal_is_ok]} {
|
||||
do_test pager1-21.0 {
|
||||
faultsim_delete_and_reopen
|
||||
execsql {
|
||||
@@ -2030,33 +2036,36 @@ ifcapable wal {
|
||||
# pager1-22.1.*: is a no-op on a non-WAL db, and
|
||||
# pager1-22.2.*: does not cause xSync calls with a synchronous=off db.
|
||||
#
|
||||
ifcapable wal {
|
||||
do_test pager1-22.1.1 {
|
||||
faultsim_delete_and_reopen
|
||||
execsql {
|
||||
CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def');
|
||||
INSERT INTO ko DEFAULT VALUES;
|
||||
}
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
} {0 -1 -1}
|
||||
do_test pager1-22.2.1 {
|
||||
testvfs tv -default 1
|
||||
tv filter xSync
|
||||
tv script xSyncCb
|
||||
proc xSyncCb {args} {incr ::synccount}
|
||||
set ::synccount 0
|
||||
sqlite3 db test.db
|
||||
execsql {
|
||||
PRAGMA synchronous = off;
|
||||
PRAGMA journal_mode = WAL;
|
||||
INSERT INTO ko DEFAULT VALUES;
|
||||
}
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
set synccount
|
||||
} {0}
|
||||
db close
|
||||
tv delete
|
||||
}
|
||||
do_test pager1-22.1.1 {
|
||||
faultsim_delete_and_reopen
|
||||
execsql {
|
||||
CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def');
|
||||
INSERT INTO ko DEFAULT VALUES;
|
||||
}
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
} {0 -1 -1}
|
||||
do_test pager1-22.2.1 {
|
||||
testvfs tv -default 1
|
||||
tv filter xSync
|
||||
tv script xSyncCb
|
||||
proc xSyncCb {args} {incr ::synccount}
|
||||
sqlite3 db test.db
|
||||
|
||||
# Switch the db to WAL mode. And then execute a SELECT to make sure
|
||||
# that the WAL file is open. Note that this may change the synchronous
|
||||
# setting if DEFAULT_WAL_SAFETYLEVEL is defined.
|
||||
execsql { PRAGMA journal_mode = WAL ; SELECT * FROM ko }
|
||||
|
||||
# Set synchronous=OFF. Insert some data and run a checkpoint. Since
|
||||
# sync=off, this should not cause any calls to the xSync() method.
|
||||
set ::synccount 0
|
||||
execsql {
|
||||
PRAGMA synchronous = off;
|
||||
INSERT INTO ko DEFAULT VALUES;
|
||||
PRAGMA wal_checkpoint;
|
||||
}
|
||||
set synccount
|
||||
} {0}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Tests for changing journal mode.
|
||||
@@ -2304,7 +2313,7 @@ do_test pager1.27.1 {
|
||||
# the same database.
|
||||
#
|
||||
catch { db close }
|
||||
ifcapable wal {
|
||||
if {$::sqlite_options(wal) && [wal_is_ok]} {
|
||||
do_multiclient_test tn {
|
||||
do_test pager1-28.$tn.1 {
|
||||
sql1 {
|
||||
|
||||
@@ -1060,6 +1060,39 @@ ifcapable crashtest {
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# When a 3.7.0 client opens a write-transaction on a database file that
|
||||
# has been appended to or truncated by a pre-370 client, it updates
|
||||
# the db-size in the file header immediately. This test case provokes
|
||||
# errors during that operation.
|
||||
#
|
||||
do_test pagerfault-22-pre1 {
|
||||
faultsim_delete_and_reopen
|
||||
db func a_string a_string
|
||||
execsql {
|
||||
PRAGMA page_size = 1024;
|
||||
PRAGMA auto_vacuum = 0;
|
||||
CREATE TABLE t1(a);
|
||||
CREATE INDEX i1 ON t1(a);
|
||||
INSERT INTO t1 VALUES(a_string(3000));
|
||||
CREATE TABLE t2(a);
|
||||
INSERT INTO t2 VALUES(1);
|
||||
}
|
||||
db close
|
||||
sql36231 { INSERT INTO t1 VALUES(a_string(3000)) }
|
||||
faultsim_save_and_close
|
||||
} {}
|
||||
do_faultsim_test pagerfault-22 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
execsql { INSERT INTO t2 VALUES(2) }
|
||||
execsql { SELECT * FROM t2 }
|
||||
} -test {
|
||||
faultsim_test_result {0 {1 2}}
|
||||
faultsim_integrity_check
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# When a 3.7.0 client opens a write-transaction on a database file that
|
||||
# has been appended to or truncated by a pre-370 client, it updates
|
||||
|
||||
+6
-1
@@ -117,7 +117,9 @@ do_test pcache-1.7 {
|
||||
# page. Because the number of allocated pages is greater than the
|
||||
# configured maximum, this page should be freed immediately instead of
|
||||
# recycled.
|
||||
#
|
||||
# Note- purgable_pcache doesn't share caches between connections and these tests
|
||||
# are only useful for testing that feature.
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
do_test pcache-1.8 {
|
||||
execsql {ROLLBACK} db2
|
||||
pcache_stats
|
||||
@@ -178,5 +180,8 @@ do_test pcache-1.15 {
|
||||
}
|
||||
pcache_stats
|
||||
} {current 14 max 15 min 10 recyclable 14}
|
||||
} else {
|
||||
db2 close
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+137
-32
@@ -1326,7 +1326,12 @@ sqlite3 dbX :memory:
|
||||
dbX eval {PRAGMA temp_store_directory = ""}
|
||||
dbX close
|
||||
|
||||
ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
|
||||
set skip_lock_proxy_tests [path_is_dos "."]
|
||||
ifcapable !(lock_proxy_pragmas&&prefer_proxy_locking) {
|
||||
set skip_lock_proxy_tests 1
|
||||
}
|
||||
|
||||
if !$skip_lock_proxy_tests {
|
||||
set sqlite_hostid_num 1
|
||||
|
||||
set using_proxy 0
|
||||
@@ -1340,67 +1345,67 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
|
||||
set env(SQLITE_FORCE_PROXY_LOCKING) "0"
|
||||
|
||||
sqlite3 db test.db
|
||||
# set lock proxy name and then query it via pragma interface
|
||||
set lpp [exec mktemp -t "proxy1"]
|
||||
do_test pragma-16.1 {
|
||||
execsql {
|
||||
PRAGMA lock_proxy_file="mylittleproxy";
|
||||
select * from sqlite_master;
|
||||
}
|
||||
execsql {
|
||||
PRAGMA lock_proxy_file;
|
||||
}
|
||||
} {mylittleproxy}
|
||||
execsql "PRAGMA lock_proxy_file='$lpp'"
|
||||
execsql "select * from sqlite_master"
|
||||
execsql "PRAGMA lock_proxy_file"
|
||||
} $lpp
|
||||
|
||||
# 2 database connections can share a lock proxy file
|
||||
do_test pragma-16.2 {
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
PRAGMA lock_proxy_file="mylittleproxy";
|
||||
} db2
|
||||
execsql "PRAGMA lock_proxy_file='$lpp'" db2
|
||||
} {}
|
||||
|
||||
db2 close
|
||||
# 2nd database connection should auto-name an existing lock proxy file
|
||||
do_test pragma-16.2.1 {
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
PRAGMA lock_proxy_file=":auto:";
|
||||
select * from sqlite_master;
|
||||
} db2
|
||||
execsql {
|
||||
PRAGMA lock_proxy_file;
|
||||
} db2
|
||||
} {mylittleproxy}
|
||||
execsql "PRAGMA lock_proxy_file" db2
|
||||
} $lpp
|
||||
|
||||
db2 close
|
||||
set lpp2 [exec mktemp -t "proxy2"]
|
||||
|
||||
# 2nd database connection cannot override the lock proxy file
|
||||
do_test pragma-16.3 {
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
PRAGMA lock_proxy_file="myotherproxy";
|
||||
} db2
|
||||
execsql "PRAGMA lock_proxy_file='$lpp2'" db2
|
||||
catchsql {
|
||||
select * from sqlite_master;
|
||||
} db2
|
||||
} {1 {database is locked}}
|
||||
|
||||
set lpp3 [exec mktemp -t "proxy3"]
|
||||
|
||||
# lock proxy file can be renamed if no other connections are active
|
||||
do_test pragma-16.4 {
|
||||
db2 close
|
||||
db close
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
PRAGMA lock_proxy_file="myoriginalproxy";
|
||||
PRAGMA lock_proxy_file="myotherproxy";
|
||||
PRAGMA lock_proxy_file;
|
||||
} db2
|
||||
} {myotherproxy}
|
||||
execsql "PRAGMA lock_proxy_file='$lpp3'" db2
|
||||
execsql "PRAGMA lock_proxy_file='$lpp2'" db2
|
||||
execsql "PRAGMA lock_proxy_file" db2
|
||||
} $lpp2
|
||||
|
||||
db2 close
|
||||
set env(SQLITE_FORCE_PROXY_LOCKING) "1"
|
||||
# auto-naming should reuse the last proxy name when available
|
||||
do_test pragma-16.5 {
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
PRAGMA lock_proxy_file=":auto:";
|
||||
PRAGMA lock_proxy_file;
|
||||
} db2
|
||||
} {myotherproxy}
|
||||
} $lpp2
|
||||
|
||||
# auto-naming a new proxy should use a predictable & unique name
|
||||
do_test pragma-16.6 {
|
||||
db2 close
|
||||
sqlite3 db2 test2.db
|
||||
@@ -1412,6 +1417,7 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
|
||||
} {1}
|
||||
|
||||
set sqlite_hostid_num 2
|
||||
# db access should be limited to one host at a time (simulate 2nd host id)
|
||||
do_test pragma-16.7 {
|
||||
list [catch {
|
||||
sqlite3 db test2.db
|
||||
@@ -1423,6 +1429,7 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
|
||||
} {1 {database is locked}}
|
||||
db close
|
||||
|
||||
# default to using proxy locking (simulate network file system detection)
|
||||
do_test pragma-16.8 {
|
||||
list [catch {
|
||||
sqlite3 db test2.db
|
||||
@@ -1431,19 +1438,25 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
|
||||
} {1 {database is locked}}
|
||||
|
||||
db2 close
|
||||
set lpp4 [exec mktemp -t "proxy4"]
|
||||
|
||||
# check that db is unlocked after first host connection closes
|
||||
do_test pragma-16.8.1 {
|
||||
execsql {
|
||||
PRAGMA lock_proxy_file="yetanotherproxy";
|
||||
PRAGMA lock_proxy_file;
|
||||
}
|
||||
} {yetanotherproxy}
|
||||
execsql "PRAGMA lock_proxy_file='$lpp4'"
|
||||
execsql "select * from sqlite_master"
|
||||
execsql "PRAGMA lock_proxy_file"
|
||||
} $lpp4
|
||||
|
||||
do_test pragma-16.8.2 {
|
||||
execsql {
|
||||
create table mine(x);
|
||||
create table if not exists mine(x);
|
||||
insert into mine values (1);
|
||||
}
|
||||
} {}
|
||||
|
||||
db close
|
||||
file delete -force proxytest.db
|
||||
file delete -force .proxytest.db-conch
|
||||
do_test pragma-16.9 {
|
||||
sqlite3 db proxytest.db
|
||||
set lockpath2 [execsql {
|
||||
@@ -1453,6 +1466,98 @@ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
|
||||
string match "*proxytest.db:auto:" $lockpath2
|
||||
} {1}
|
||||
|
||||
# ensure creating directories for a lock proxy file works
|
||||
set lpp5d [exec mktemp -d -t "proxy5"]
|
||||
set lpp5 $lpp5d/sub/dir/lock
|
||||
db close
|
||||
do_test pragma-16.10.1 {
|
||||
sqlite3 db proxytest.db
|
||||
execsql "PRAGMA lock_proxy_file='$lpp5'"
|
||||
set lockpath2 [execsql {
|
||||
PRAGMA lock_proxy_file;
|
||||
} db]
|
||||
string match "*sub/dir/lock" $lockpath2
|
||||
} {1}
|
||||
|
||||
# ensure that after deleting the path, setting ":auto:" works correctly
|
||||
db close
|
||||
file delete -force $lpp5d
|
||||
do_test pragma-16.10.2 {
|
||||
sqlite3 db proxytest.db
|
||||
set lockpath3 [execsql {
|
||||
PRAGMA lock_proxy_file=":auto:";
|
||||
create table if not exists pt(y);
|
||||
PRAGMA lock_proxy_file;
|
||||
} db]
|
||||
string match "*sub/dir/lock" $lockpath3
|
||||
} {1}
|
||||
|
||||
# ensure that if the path can not be created (file instead of dir)
|
||||
# setting :auto: deals with it by creating a new autonamed lock file
|
||||
db close
|
||||
file delete -force $lpp5d
|
||||
close [open "$lpp5d" a]
|
||||
do_test pragma-16.10.3 {
|
||||
sqlite3 db proxytest.db
|
||||
set lockpath2 [execsql {
|
||||
PRAGMA lock_proxy_file=":auto:";
|
||||
create table if not exists zz(y);
|
||||
PRAGMA lock_proxy_file;
|
||||
} db]
|
||||
string match "*proxytest.db:auto:" $lockpath2
|
||||
} {1}
|
||||
|
||||
# make sure we can deal with ugly file paths correctly
|
||||
db close
|
||||
file delete -force $lpp5d
|
||||
set lpp6 [exec mktemp -d -t "proxy6"]/./././////./proxytest/../proxytest/sub/dir/lock
|
||||
do_test pragma-16.10.4 {
|
||||
sqlite3 db proxytest.db
|
||||
execsql "PRAGMA lock_proxy_file='$lpp6'"
|
||||
set lockpath4 [execsql {
|
||||
create table if not exists aa(bb);
|
||||
PRAGMA lock_proxy_file;
|
||||
} db]
|
||||
string match "*proxytest/sub/dir/lock" $lockpath4
|
||||
} {1}
|
||||
|
||||
# ensure that if the path can not be created (perm), setting :auto: deals
|
||||
db close
|
||||
file delete -force $lpp5d
|
||||
do_test pragma-16.10.5 {
|
||||
sqlite3 db proxytest.db
|
||||
execsql "PRAGMA lock_proxy_file='$lpp5'"
|
||||
execsql {
|
||||
create table if not exists bb(bb);
|
||||
}
|
||||
db close
|
||||
file delete -force $lpp5d
|
||||
file mkdir $lpp5d
|
||||
file attributes $lpp5d -permission 0000
|
||||
sqlite3 db proxytest.db
|
||||
set lockpath5 [execsql {
|
||||
PRAGMA lock_proxy_file=":auto:";
|
||||
create table if not exists cc(bb);
|
||||
PRAGMA lock_proxy_file;
|
||||
} db]
|
||||
string match "*proxytest.db:auto:" $lockpath5
|
||||
} {1}
|
||||
|
||||
# ensure that if the path can not be created, locking fails
|
||||
db close
|
||||
do_test pragma-16.10.6 {
|
||||
sqlite3 db proxytest.db
|
||||
execsql "PRAGMA lock_proxy_file='$lpp5'"
|
||||
catchsql {
|
||||
create table if not exists faily(y);
|
||||
PRAGMA lock_proxy_file;
|
||||
} db
|
||||
} {1 {database is locked}}
|
||||
db close
|
||||
|
||||
file attributes $lpp5d -permission 0777
|
||||
file delete -force $lpp5d
|
||||
|
||||
set env(SQLITE_FORCE_PROXY_LOCKING) $using_proxy
|
||||
set sqlite_hostid_num 0
|
||||
}
|
||||
|
||||
+1
-5
@@ -45,13 +45,9 @@ ifcapable autovacuum {
|
||||
# if we're using proxy locks, we use 2 filedescriptors for a db
|
||||
# that is open but NOT yet locked, after a lock is taken we'll have 3,
|
||||
# normally sqlite uses 1 (proxy locking adds the conch and the local lock)
|
||||
set using_proxy 0
|
||||
foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
|
||||
set using_proxy $value
|
||||
}
|
||||
set extrafds_prelock 0
|
||||
set extrafds_postlock 0
|
||||
if {$using_proxy>0} {
|
||||
if {[forced_proxy_locking]} {
|
||||
set extrafds_prelock 1
|
||||
set extrafds_postlock 2
|
||||
}
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# purgeable pcache tracks memory differently
|
||||
ifcapable {enable_purgeable_pcache} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
unset -nocomplain baseline
|
||||
do_test shrink-1.1 {
|
||||
db eval {
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ do_execsql_test stat-0.0 {
|
||||
SELECT * FROM stat;
|
||||
} {}
|
||||
|
||||
ifcapable wal {
|
||||
if {$::sqlite_options(wal) && [wal_is_ok]} {
|
||||
do_execsql_test stat-0.1 {
|
||||
PRAGMA journal_mode = WAL;
|
||||
PRAGMA journal_mode = delete;
|
||||
|
||||
+24
-7
@@ -30,8 +30,19 @@ if {$::TEMP_STORE==3} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
# if we're using proxy locks, we use 3 filedescriptors for a db
|
||||
# that is open but NOT writing changes, normally
|
||||
# sqlite uses 1 (proxy locking adds the conch and the local lock)
|
||||
set extrafds 0
|
||||
if {[forced_proxy_locking]} {
|
||||
set extrafds 2
|
||||
}
|
||||
|
||||
|
||||
do_test stmt-1.2 {
|
||||
set sqlite_open_file_count
|
||||
expr $sqlite_open_file_count-$extrafds
|
||||
} {1}
|
||||
do_test stmt-1.3 {
|
||||
execsql {
|
||||
@@ -40,16 +51,19 @@ do_test stmt-1.3 {
|
||||
INSERT INTO t1 VALUES(1, 1);
|
||||
}
|
||||
set sqlite_open_file_count
|
||||
expr $sqlite_open_file_count-$extrafds
|
||||
} {2}
|
||||
do_test stmt-1.4 {
|
||||
execsql {
|
||||
INSERT INTO t1 SELECT a+1, b+1 FROM t1;
|
||||
}
|
||||
set sqlite_open_file_count
|
||||
expr $sqlite_open_file_count-$extrafds
|
||||
} {3}
|
||||
do_test stmt-1.5 {
|
||||
execsql COMMIT
|
||||
set sqlite_open_file_count
|
||||
expr $sqlite_open_file_count-$extrafds
|
||||
} {1}
|
||||
do_test stmt-1.6.1 {
|
||||
execsql {
|
||||
@@ -57,34 +71,37 @@ do_test stmt-1.6.1 {
|
||||
INSERT INTO t1 SELECT a+2, b+2 FROM t1;
|
||||
}
|
||||
set sqlite_open_file_count
|
||||
expr $sqlite_open_file_count-$extrafds
|
||||
} {2}
|
||||
do_test stmt-1.6.2 {
|
||||
execsql { INSERT INTO t1 SELECT a+4, b+4 FROM t1 }
|
||||
set sqlite_open_file_count
|
||||
expr $sqlite_open_file_count-$extrafds
|
||||
} {3}
|
||||
do_test stmt-1.7 {
|
||||
execsql COMMIT
|
||||
set sqlite_open_file_count
|
||||
expr $sqlite_open_file_count-$extrafds
|
||||
} {1}
|
||||
|
||||
|
||||
proc filecount {testname sql expected} {
|
||||
proc filecount {testname sql expected extrafds} {
|
||||
uplevel [list do_test $testname [subst -nocommand {
|
||||
execsql BEGIN
|
||||
execsql { $sql }
|
||||
set ret [set sqlite_open_file_count]
|
||||
execsql ROLLBACK
|
||||
set ret
|
||||
}] $expected]
|
||||
}] [ expr $expected+$extrafds ] ]
|
||||
}
|
||||
|
||||
filecount stmt-2.1 { INSERT INTO t1 VALUES(9, 9) } 2
|
||||
filecount stmt-2.2 { REPLACE INTO t1 VALUES(9, 9) } 2
|
||||
filecount stmt-2.3 { INSERT INTO t1 SELECT 9, 9 } 2
|
||||
filecount stmt-2.1 { INSERT INTO t1 VALUES(9, 9) } 2 $extrafds
|
||||
filecount stmt-2.2 { REPLACE INTO t1 VALUES(9, 9) } 2 $extrafds
|
||||
filecount stmt-2.3 { INSERT INTO t1 SELECT 9, 9 } 2 $extrafds
|
||||
filecount stmt-2.4 {
|
||||
INSERT INTO t1 SELECT 9, 9;
|
||||
INSERT INTO t1 SELECT 10, 10;
|
||||
} 3
|
||||
} 3 $extrafds
|
||||
|
||||
do_test stmt-2.5 {
|
||||
execsql { CREATE INDEX i1 ON t1(b) }
|
||||
@@ -92,6 +109,6 @@ do_test stmt-2.5 {
|
||||
filecount stmt-2.6 {
|
||||
REPLACE INTO t1 VALUES(5, 5);
|
||||
REPLACE INTO t1 VALUES(5, 5);
|
||||
} 3
|
||||
} 3 $extrafds
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
set testprefix superlock
|
||||
|
||||
@@ -42,6 +43,11 @@ set testprefix superlock
|
||||
#
|
||||
#
|
||||
|
||||
if {[forced_proxy_locking]} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
@@ -57,6 +63,12 @@ do_test 1.2 { sqlite3demo_superlock unlock test.db } {unlock}
|
||||
do_catchsql_test 1.3 { SELECT * FROM t1 } {1 {database is locked}}
|
||||
do_test 1.4 { unlock } {}
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if { ![wal_is_ok] } {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 2.1 {
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
PRAGMA journal_mode = WAL;
|
||||
|
||||
+7
-2
@@ -52,6 +52,11 @@ do_test tempdb-1.2 {
|
||||
}
|
||||
} {}
|
||||
|
||||
set extrafds 0
|
||||
if {[forced_proxy_locking]} {
|
||||
set extrafds 2
|
||||
}
|
||||
|
||||
do_test tempdb-2.1 {
|
||||
# Set $::jrnl_in_memory if the journal file is expected to be in-memory.
|
||||
# Similarly, set $::subj_in_memory if the sub-journal file is expected
|
||||
@@ -76,7 +81,7 @@ do_test tempdb-2.2 {
|
||||
}
|
||||
catchsql { INSERT INTO t1 SELECT * FROM t2 }
|
||||
set sqlite_open_file_count
|
||||
} [expr 1 + (0==$jrnl_in_memory) + (0==$subj_in_memory)]
|
||||
} [expr 1 + $extrafds + (0==$jrnl_in_memory) + (0==$subj_in_memory)]
|
||||
do_test tempdb-2.3 {
|
||||
execsql {
|
||||
PRAGMA temp_store = 'memory';
|
||||
@@ -88,6 +93,6 @@ do_test tempdb-2.3 {
|
||||
}
|
||||
catchsql { INSERT INTO t1 SELECT * FROM t2 }
|
||||
set sqlite_open_file_count
|
||||
} [expr 1 + (0==$jrnl_in_memory)]
|
||||
} [expr 1 + $extrafds + (0==$jrnl_in_memory)]
|
||||
|
||||
finish_test
|
||||
|
||||
+46
-4
@@ -492,6 +492,23 @@ if {[info exists cmdlinearg]==0} {
|
||||
#
|
||||
sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
|
||||
|
||||
proc forced_proxy_locking {} {
|
||||
if $::sqlite_options(lock_proxy_pragmas)&&$::sqlite_options(prefer_proxy_locking) {
|
||||
set force_proxy_value 0
|
||||
set force_key "SQLITE_FORCE_PROXY_LOCKING="
|
||||
foreach {env_pair} [exec env] {
|
||||
if { [string first $force_key $env_pair] == 0} {
|
||||
set force_proxy_value [string range $env_pair [string length $force_key] end]
|
||||
}
|
||||
}
|
||||
if { "$force_proxy_value " == "1 " } {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# Create a test database
|
||||
#
|
||||
proc reset_db {} {
|
||||
@@ -499,6 +516,14 @@ proc reset_db {} {
|
||||
forcedelete test.db
|
||||
forcedelete test.db-journal
|
||||
forcedelete test.db-wal
|
||||
if {[forced_proxy_locking]} {
|
||||
sqlite3 db ./test.db
|
||||
set lock_proxy_path [db eval "PRAGMA lock_proxy_file;"]
|
||||
catch {db close}
|
||||
# puts "deleting $lock_proxy_path"
|
||||
file delete -force $lock_proxy_path
|
||||
file delete -force test.db
|
||||
}
|
||||
sqlite3 db ./test.db
|
||||
set ::DB [sqlite3_connection_pointer db]
|
||||
if {[info exists ::SETUP_SQL]} {
|
||||
@@ -970,11 +995,15 @@ proc finalize_testing {} {
|
||||
memdebug_log_sql leaks.sql
|
||||
}
|
||||
}
|
||||
foreach f [glob -nocomplain test.db-*-journal] {
|
||||
forcedelete $f
|
||||
catch {
|
||||
foreach f [glob -nocomplain test.db-*-journal] {
|
||||
forcedelete $f
|
||||
}
|
||||
}
|
||||
foreach f [glob -nocomplain test.db-mj*] {
|
||||
forcedelete $f
|
||||
catch {
|
||||
foreach f [glob -nocomplain test.db-mj*] {
|
||||
forcedelete $f
|
||||
}
|
||||
}
|
||||
exit [expr {$nErr>0}]
|
||||
}
|
||||
@@ -1767,6 +1796,19 @@ proc presql {} {
|
||||
set presql
|
||||
}
|
||||
|
||||
proc wal_is_ok {} {
|
||||
if { [forced_proxy_locking] } {
|
||||
return 1
|
||||
}
|
||||
if { ![path_is_local "."] } {
|
||||
return 0
|
||||
}
|
||||
if { [path_is_dos "."] } {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
proc slave_test_script {script} {
|
||||
|
||||
@@ -20,6 +20,7 @@ source $testdir/tester.tcl
|
||||
set testprefix tkt-2d1a5c67d
|
||||
|
||||
ifcapable {!wal || !vtab} {finish_test; return}
|
||||
if {![wal_is_ok]} {finish_test; return}
|
||||
|
||||
for {set ii 1} {$ii<=10} {incr ii} {
|
||||
do_test tkt-2d1a5c67d.1.$ii {
|
||||
|
||||
@@ -19,6 +19,7 @@ source $testdir/tester.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
|
||||
ifcapable !wal { finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
do_execsql_test tkt-313723c356.1 {
|
||||
PRAGMA page_size = 1024;
|
||||
|
||||
+22
-21
@@ -70,27 +70,28 @@ catch {
|
||||
test_syscall fault 1 1
|
||||
}
|
||||
|
||||
do_test tkt3457-1.2 {
|
||||
forcecopy bak.db-journal test.db-journal
|
||||
file attributes test.db-journal -permissions ---------
|
||||
catchsql { SELECT * FROM t1 }
|
||||
} {1 {unable to open database file}}
|
||||
do_test tkt3457-1.3 {
|
||||
forcecopy bak.db-journal test.db-journal
|
||||
file attributes test.db-journal -permissions -w--w--w-
|
||||
catchsql { SELECT * FROM t1 }
|
||||
} {1 {unable to open database file}}
|
||||
do_test tkt3457-1.4 {
|
||||
forcecopy bak.db-journal test.db-journal
|
||||
file attributes test.db-journal -permissions r--r--r--
|
||||
catchsql { SELECT * FROM t1 }
|
||||
} {1 {unable to open database file}}
|
||||
|
||||
do_test tkt3457-1.5 {
|
||||
forcecopy bak.db-journal test.db-journal
|
||||
file attributes test.db-journal -permissions rw-rw-rw-
|
||||
catchsql { SELECT * FROM t1 }
|
||||
} {0 {1 2 3 4 5 6}}
|
||||
if { ![path_is_dos "."] } {
|
||||
do_test tkt3457-1.2 {
|
||||
forcecopy bak.db-journal test.db-journal
|
||||
file attributes test.db-journal -permissions ---------
|
||||
catchsql { SELECT * FROM t1 }
|
||||
} {1 {unable to open database file}}
|
||||
do_test tkt3457-1.3 {
|
||||
forcecopy bak.db-journal test.db-journal
|
||||
file attributes test.db-journal -permissions -w--w--w-
|
||||
catchsql { SELECT * FROM t1 }
|
||||
} {1 {unable to open database file}}
|
||||
do_test tkt3457-1.4 {
|
||||
forcecopy bak.db-journal test.db-journal
|
||||
file attributes test.db-journal -permissions r--r--r--
|
||||
catchsql { SELECT * FROM t1 }
|
||||
} {1 {unable to open database file}}
|
||||
do_test tkt3457-1.5 {
|
||||
forcecopy bak.db-journal test.db-journal
|
||||
file attributes test.db-journal -permissions rw-rw-rw-
|
||||
catchsql { SELECT * FROM t1 }
|
||||
} {0 {1 2 3 4 5 6}}
|
||||
}
|
||||
|
||||
# Reenable fchmod
|
||||
catch {
|
||||
|
||||
+44
-1
@@ -22,6 +22,10 @@ source $testdir/wal_common.tcl
|
||||
set testprefix wal
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if { ![wal_is_ok] } {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
proc reopen_db {} {
|
||||
catch { db close }
|
||||
@@ -172,6 +176,9 @@ do_test wal-4.3 {
|
||||
} {a b}
|
||||
|
||||
do_test wal-4.4.1 {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
db func blob blob
|
||||
@@ -223,6 +230,9 @@ db2 close
|
||||
|
||||
do_test wal-4.5.1 {
|
||||
reopen_db
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db func blob blob
|
||||
execsql {
|
||||
PRAGMA journal_mode = WAL;
|
||||
@@ -337,6 +347,9 @@ foreach sector {512 4096} {
|
||||
forcedelete test.db test.db-wal
|
||||
do_test wal-6.$sector.$pgsz.1 {
|
||||
sqlite3 db test.db -vfs devsym
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
execsql "
|
||||
PRAGMA page_size = $pgsz;
|
||||
PRAGMA auto_vacuum = 0;
|
||||
@@ -723,6 +736,9 @@ do_test wal-11.8 {
|
||||
list [expr [file size test.db]/1024] [file size test.db-wal]
|
||||
} [list 37 [wal_file_size 41 1024]]
|
||||
do_test wal-11.9 {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
list [expr [file size test.db]/1024] [log_deleted test.db-wal]
|
||||
} {37 1}
|
||||
@@ -730,6 +746,9 @@ sqlite3_wal db test.db
|
||||
set nWal 39
|
||||
if {[permutation]!="mmap"} {set nWal 37}
|
||||
ifcapable !mmap {set nWal 37}
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
do_test wal-11.10 {
|
||||
execsql {
|
||||
PRAGMA cache_size = 10;
|
||||
@@ -777,6 +796,9 @@ do_test wal-12.1 {
|
||||
list [expr [file size test.db]/1024] [file size test.db-wal]
|
||||
} [list 1 [wal_file_size 5 1024]]
|
||||
do_test wal-12.2 {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
execsql {
|
||||
@@ -814,6 +836,9 @@ do_test wal-12.6 {
|
||||
execsql { SELECT * FROM t2 } db2
|
||||
} {B 2}
|
||||
db2 close
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -853,6 +878,9 @@ do_test wal-13.1.2 {
|
||||
execsql { SELECT * FROM t2 }
|
||||
} {B 2}
|
||||
do_test wal-13.1.3 {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
file exists test.db-wal
|
||||
} {0}
|
||||
@@ -1056,10 +1084,12 @@ foreach {tn ckpt_cmd ckpt_res ckpt_main ckpt_aux} {
|
||||
PRAGMA aux.auto_vacuum = 0;
|
||||
PRAGMA main.journal_mode = WAL;
|
||||
PRAGMA aux.journal_mode = WAL;
|
||||
SELECT count(*) FROM main.sqlite_master, aux.sqlite_master;
|
||||
PRAGMA main.synchronous = NORMAL;
|
||||
PRAGMA aux.synchronous = NORMAL;
|
||||
PRAGMA aux.synchronous = FULL;
|
||||
}
|
||||
} {wal wal}
|
||||
} {wal wal 0}
|
||||
|
||||
do_test wal-16.$tn.2 {
|
||||
execsql {
|
||||
@@ -1130,6 +1160,7 @@ foreach {tn sectorsize logsize} "
|
||||
PRAGMA page_size = 512;
|
||||
PRAGMA cache_size = -2000;
|
||||
PRAGMA journal_mode = WAL;
|
||||
SELECT * FROM sqlite_master;
|
||||
PRAGMA synchronous = FULL;
|
||||
}
|
||||
execsql {
|
||||
@@ -1345,6 +1376,9 @@ do_test wal-19.2 {
|
||||
}
|
||||
} {1 2 3 4 5 6}
|
||||
do_test wal-19.3 {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db2 0
|
||||
}
|
||||
db close
|
||||
db2 close
|
||||
file exists test.db-wal
|
||||
@@ -1495,6 +1529,9 @@ do_test wal-23.1 {
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
}
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
faultsim_save_and_close
|
||||
|
||||
sqlite3_shutdown
|
||||
@@ -1541,6 +1578,9 @@ ifcapable autovacuum {
|
||||
INSERT INTO t1 SELECT * FROM t1;
|
||||
} {wal}
|
||||
do_test 24.2 {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
execsql {
|
||||
DELETE FROM t1;
|
||||
PRAGMA wal_checkpoint;
|
||||
@@ -1569,6 +1609,9 @@ ifcapable autovacuum {
|
||||
} [wal_file_size 1 1024]
|
||||
}
|
||||
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
test_sqlite3_log
|
||||
|
||||
+59
-17
@@ -22,6 +22,7 @@ source $testdir/wal_common.tcl
|
||||
set testprefix wal2
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] {finish_test ; return }
|
||||
|
||||
set sqlite_sync_count 0
|
||||
proc cond_incr_sync_count {adj} {
|
||||
@@ -71,6 +72,13 @@ proc incr_tvfs_hdr {file idx incrval} {
|
||||
set_tvfs_hdr $file $ints
|
||||
}
|
||||
|
||||
set shmpath test.db-shm
|
||||
if {[forced_proxy_locking]} {
|
||||
sqlite3 db test.db
|
||||
set shmpath [execsql { pragma lock_proxy_file }]-shm
|
||||
db close
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test case wal2-1.*:
|
||||
@@ -571,9 +579,15 @@ do_test wal2-6.3.1 {
|
||||
list [file exists test.db-wal] [file exists test.db-journal]
|
||||
} {1 0}
|
||||
do_test wal2-6.3.2 {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
execsql { PRAGMA journal_mode = DELETE }
|
||||
file exists test.db-wal
|
||||
} {0}
|
||||
do_test wal2-6.3.2.1 {
|
||||
execsql { PRAGMA journal_mode; }
|
||||
} {delete}
|
||||
do_test wal2-6.3.3 {
|
||||
execsql { PRAGMA lock_status }
|
||||
} {main exclusive temp closed}
|
||||
@@ -720,7 +734,9 @@ foreach {tn sql res expected_locks} {
|
||||
do_test wal2-6.4.$tn.1 { execsql $S } $res
|
||||
do_test wal2-6.4.$tn.2 { set ::locks } $L
|
||||
}
|
||||
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
tvfs delete
|
||||
|
||||
@@ -951,6 +967,9 @@ do_test wal2-10.1.1 {
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
}
|
||||
if {[forced_proxy_locking]} {
|
||||
forcecopy $shmpath sv_test.db-shm
|
||||
}
|
||||
faultsim_save_and_close
|
||||
} {}
|
||||
do_test wal2-10.1.2 {
|
||||
@@ -1050,6 +1069,11 @@ tvfs delete
|
||||
# file itself. Test this.
|
||||
#
|
||||
if {$::tcl_platform(platform) == "unix"} {
|
||||
if {[forced_proxy_locking]} {
|
||||
# faultsim_delete_and_reopen doesn't know about the shm file redirect...
|
||||
forcedelete $shmpath
|
||||
}
|
||||
|
||||
faultsim_delete_and_reopen
|
||||
# Changed on 2012-02-13: umask is deliberately ignored for -wal files.
|
||||
#set umask [exec /bin/sh -c umask]
|
||||
@@ -1063,7 +1087,7 @@ if {$::tcl_platform(platform) == "unix"} {
|
||||
PRAGMA journal_mode = WAL;
|
||||
}
|
||||
db close
|
||||
list [file exists test.db-wal] [file exists test.db-shm]
|
||||
list [file exists test.db-wal] [file exists $shmpath]
|
||||
} {0 0}
|
||||
|
||||
foreach {tn permissions} {
|
||||
@@ -1078,19 +1102,22 @@ if {$::tcl_platform(platform) == "unix"} {
|
||||
file attributes test.db -permissions
|
||||
} $permissions
|
||||
do_test wal2-12.2.$tn.2 {
|
||||
list [file exists test.db-wal] [file exists test.db-shm]
|
||||
list [file exists test.db-wal] [file exists $shmpath]
|
||||
} {0 0}
|
||||
do_test wal2-12.2.$tn.3 {
|
||||
sqlite3 db test.db
|
||||
execsql { INSERT INTO tx DEFAULT VALUES }
|
||||
list [file exists test.db-wal] [file exists test.db-shm]
|
||||
list [file exists test.db-wal] [file exists $shmpath]
|
||||
} {1 1}
|
||||
do_test wal2-12.2.$tn.4 {
|
||||
list [file attr test.db-wal -perm] [file attr test.db-shm -perm]
|
||||
list [file attr test.db-wal -perm] [file attr $shmpath -perm]
|
||||
} [list $effective $effective]
|
||||
do_test wal2-12.2.$tn.5 {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
list [file exists test.db-wal] [file exists test.db-shm]
|
||||
list [file exists test.db-wal] [file exists $shmpath]
|
||||
} {0 0}
|
||||
}
|
||||
}
|
||||
@@ -1103,7 +1130,7 @@ if {$::tcl_platform(platform) == "unix"} {
|
||||
if {$::tcl_platform(platform) == "unix"} {
|
||||
proc perm {} {
|
||||
set L [list]
|
||||
foreach f {test.db test.db-wal test.db-shm} {
|
||||
foreach f {test.db test.db-wal $shmpath} {
|
||||
if {[file exists $f]} {
|
||||
lappend L [file attr $f -perm]
|
||||
} else {
|
||||
@@ -1113,6 +1140,10 @@ if {$::tcl_platform(platform) == "unix"} {
|
||||
set L
|
||||
}
|
||||
|
||||
if {[forced_proxy_locking]} {
|
||||
# faultsim_delete_and_reopen doesn't know about the shm file redirect...
|
||||
forcedelete $shmpath
|
||||
}
|
||||
faultsim_delete_and_reopen
|
||||
execsql {
|
||||
PRAGMA journal_mode = WAL;
|
||||
@@ -1121,8 +1152,11 @@ if {$::tcl_platform(platform) == "unix"} {
|
||||
INSERT INTO t1 VALUES('3.14', '2.72');
|
||||
}
|
||||
do_test wal2-13.1.1 {
|
||||
list [file exists test.db-shm] [file exists test.db-wal]
|
||||
list [file exists $shmpath] [file exists test.db-wal]
|
||||
} {1 1}
|
||||
if {[forced_proxy_locking]} {
|
||||
forcecopy $shmpath proxysv_test.db-shm
|
||||
}
|
||||
faultsim_save_and_close
|
||||
|
||||
foreach {tn db_perm wal_perm shm_perm can_open can_read can_write} {
|
||||
@@ -1136,14 +1170,17 @@ if {$::tcl_platform(platform) == "unix"} {
|
||||
9 00000 00644 00644 0 0 0
|
||||
} {
|
||||
faultsim_restore
|
||||
if {[forced_proxy_locking]} {
|
||||
forcecopy proxysv_test.db-shm $shmpath
|
||||
}
|
||||
do_test wal2-13.$tn.1 {
|
||||
file attr test.db -perm $db_perm
|
||||
file attr test.db-wal -perm $wal_perm
|
||||
file attr test.db-shm -perm $shm_perm
|
||||
file attr $shmpath -perm $shm_perm
|
||||
|
||||
set L [file attr test.db -perm]
|
||||
lappend L [file attr test.db-wal -perm]
|
||||
lappend L [file attr test.db-shm -perm]
|
||||
lappend L [file attr $shmpath -perm]
|
||||
} [list $db_perm $wal_perm $shm_perm]
|
||||
|
||||
# If $can_open is true, then it should be possible to open a database
|
||||
@@ -1189,10 +1226,10 @@ if {$::tcl_platform(platform) == "unix"} {
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that "PRAGMA checkpoint_fullsync" appears to be working.
|
||||
#
|
||||
foreach {tn sql reslist} {
|
||||
1 { } {10 0 4 0 6 0}
|
||||
2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2}
|
||||
3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0}
|
||||
foreach {tn sql reslist altreslist} {
|
||||
1 { } {10 0 4 0 6 0} {7 4 3 2 3 2}
|
||||
2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2} {7 4 3 2 3 2}
|
||||
3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0} {7 0 3 0 3 0}
|
||||
} {
|
||||
faultsim_delete_and_reopen
|
||||
|
||||
@@ -1204,6 +1241,11 @@ foreach {tn sql reslist} {
|
||||
set sqlite_sync_count 0
|
||||
set sqlite_fullsync_count 0
|
||||
|
||||
set useres $reslist
|
||||
if $::sqlite_options(default_wal_safetylevel) {
|
||||
set useres $altreslist
|
||||
}
|
||||
|
||||
do_execsql_test wal2-14.$tn.2 {
|
||||
PRAGMA wal_autocheckpoint = 10;
|
||||
CREATE TABLE t1(a, b); -- 2 wal syncs
|
||||
@@ -1219,7 +1261,7 @@ foreach {tn sql reslist} {
|
||||
do_test wal2-14.$tn.3 {
|
||||
cond_incr_sync_count 1
|
||||
list $sqlite_sync_count $sqlite_fullsync_count
|
||||
} [lrange $reslist 0 1]
|
||||
} [lrange $useres 0 1]
|
||||
|
||||
set sqlite_sync_count 0
|
||||
set sqlite_fullsync_count 0
|
||||
@@ -1227,7 +1269,7 @@ foreach {tn sql reslist} {
|
||||
do_test wal2-14.$tn.4 {
|
||||
execsql { INSERT INTO t1 VALUES(7, zeroblob(12*4096)) }
|
||||
list $sqlite_sync_count $sqlite_fullsync_count
|
||||
} [lrange $reslist 2 3]
|
||||
} [lrange $useres 2 3]
|
||||
|
||||
set sqlite_sync_count 0
|
||||
set sqlite_fullsync_count 0
|
||||
@@ -1239,7 +1281,7 @@ foreach {tn sql reslist} {
|
||||
execsql { INSERT INTO t1 VALUES(13, 14) }
|
||||
db close
|
||||
list $sqlite_sync_count $sqlite_fullsync_count
|
||||
} [lrange $reslist 4 5]
|
||||
} [lrange $useres 4 5]
|
||||
}
|
||||
|
||||
catch { db close }
|
||||
|
||||
+11
-2
@@ -19,6 +19,7 @@ source $testdir/lock_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] {finish_test ; return }
|
||||
|
||||
set a_string_counter 1
|
||||
proc a_string {n} {
|
||||
@@ -194,19 +195,27 @@ catch {db close}
|
||||
# in WAL mode the xSync method is invoked as expected for each of
|
||||
# synchronous=off, synchronous=normal and synchronous=full.
|
||||
#
|
||||
foreach {tn syncmode synccount} {
|
||||
foreach {tn syncmode synccount altsynccount} {
|
||||
1 off
|
||||
{}
|
||||
{}
|
||||
2 normal
|
||||
{test.db-wal normal test.db normal}
|
||||
{test.db-wal full test.db full}
|
||||
3 full
|
||||
{test.db-wal normal test.db-wal normal test.db-wal normal test.db normal}
|
||||
{test.db-wal normal test.db-wal normal test.db-wal full test.db full}
|
||||
} {
|
||||
|
||||
proc sync_counter {args} {
|
||||
foreach {method filename id flags} $args break
|
||||
lappend ::syncs [file tail $filename] $flags
|
||||
}
|
||||
set usecount $synccount
|
||||
if $::sqlite_options(default_wal_safetylevel) {
|
||||
set usecount $altsynccount
|
||||
}
|
||||
|
||||
do_test wal3-3.$tn {
|
||||
forcedelete test.db test.db-wal test.db-journal
|
||||
|
||||
@@ -228,7 +237,7 @@ foreach {tn syncmode synccount} {
|
||||
}
|
||||
T filter {}
|
||||
set ::syncs
|
||||
} $synccount
|
||||
} $usecount
|
||||
|
||||
db close
|
||||
T delete
|
||||
|
||||
@@ -16,6 +16,10 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if { ![wal_is_ok] || [path_is_dos "."]} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_test wal4-1.1 {
|
||||
execsql {
|
||||
|
||||
@@ -18,6 +18,7 @@ source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
set testprefix wal5
|
||||
|
||||
@@ -78,6 +79,11 @@ foreach {testprefix do_wal_checkpoint} {
|
||||
}
|
||||
|
||||
proc reopen_all {} {
|
||||
ifcapable enable_persist_wal {
|
||||
code1 { file_control_persist_wal db 0 }
|
||||
code2 { file_control_persist_wal db2 0 }
|
||||
code3 { file_control_persist_wal db3 0 }
|
||||
}
|
||||
code1 {db close}
|
||||
code2 {db2 close}
|
||||
code3 {db3 close}
|
||||
@@ -336,6 +342,11 @@ foreach {testprefix do_wal_checkpoint} {
|
||||
|
||||
do_test 3.$tn.4 { code3 { do_wal_checkpoint db3 } } {0 2 2}
|
||||
|
||||
ifcapable enable_persist_wal {
|
||||
code1 { file_control_persist_wal db 0 }
|
||||
code2 { file_control_persist_wal db2 0 }
|
||||
code3 { file_control_persist_wal db3 0 }
|
||||
}
|
||||
code1 {db close}
|
||||
code2 {db2 close}
|
||||
code3 {db3 close}
|
||||
|
||||
@@ -21,6 +21,8 @@ source $testdir/wal_common.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
ifcapable !wal {finish_test ; return }
|
||||
|
||||
if { ![wal_is_ok] } {finish_test ; return }
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Changing to WAL mode in one connection forces the change in others.
|
||||
#
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
# Case 1: No size limit. Journal can get large.
|
||||
#
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix wal8
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
db close
|
||||
forcedelete test.db test.db-wal
|
||||
|
||||
@@ -33,6 +33,20 @@ proc wal_cksum_intlist {ckv1 ckv2 intlist} {
|
||||
}
|
||||
}
|
||||
|
||||
# If the synchronous mode for the main database of db handle $db
|
||||
# is either OFF or NORMAL, return $nRight. Otherwise, if it is
|
||||
# FULL, return $nWrite+$nTrans.
|
||||
#
|
||||
proc wal_frames {db nWrite nTrans} {
|
||||
set nRet $nWrite
|
||||
switch -- [$db one {PRAGMA main.synchronous}] {
|
||||
0 { }
|
||||
1 { }
|
||||
default { incr nRet $nTrans }
|
||||
}
|
||||
set nRet
|
||||
}
|
||||
|
||||
|
||||
# This proc calculates checksums in the same way as those used by SQLite
|
||||
# in WAL files. If the $endian argument is "big", then checksums are
|
||||
|
||||
@@ -21,6 +21,7 @@ source $testdir/malloc_common.tcl
|
||||
do_not_use_codec
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if { ![wal_is_ok] } { finish_test ; return }
|
||||
|
||||
|
||||
# Test organization:
|
||||
@@ -322,6 +323,9 @@ foreach {tn src dest dest_final} {
|
||||
do_test walbak-4.$tn.1 {
|
||||
sqlite3 db test.db
|
||||
db eval "PRAGMA journal_mode = $src"
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db eval {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES('I', 'II');
|
||||
@@ -330,6 +334,9 @@ foreach {tn src dest dest_final} {
|
||||
|
||||
sqlite3 db2 test.db2
|
||||
db2 eval "PRAGMA journal_mode = $dest"
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db2 0
|
||||
}
|
||||
db2 eval {
|
||||
CREATE TABLE t2(x, y);
|
||||
INSERT INTO t2 VALUES('1', '2');
|
||||
|
||||
@@ -21,6 +21,7 @@ ifcapable !wal {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
# Do not use a codec for this file, as the database is manipulated using
|
||||
# external methods (the [fake_big_file] and [hexio_write] commands).
|
||||
@@ -32,6 +33,10 @@ ifcapable !lfs {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
if { ![wal_is_ok] } {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
set a_string_counter 1
|
||||
proc a_string {n} {
|
||||
|
||||
@@ -16,6 +16,7 @@ source $testdir/lock_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
# Read and return the contents of file $filename. Treat the content as
|
||||
# binary data.
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
db close
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if { ![wal_is_ok] } { finish_test ; return }
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@@ -18,6 +18,8 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
set testprefix walcrash3
|
||||
|
||||
db close
|
||||
|
||||
@@ -19,6 +19,7 @@ source $testdir/malloc_common.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# This test case, walfault-1-*, simulates faults while executing a
|
||||
|
||||
@@ -22,6 +22,7 @@ source $testdir/tester.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
set ::wal_hook [list]
|
||||
proc wal_hook {zDb nEntry} {
|
||||
@@ -71,8 +72,14 @@ do_test walhook-1.5 {
|
||||
} [expr 6*1024]
|
||||
|
||||
db2 close
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
do_test walhook-2.1 {
|
||||
execsql { PRAGMA synchronous = NORMAL }
|
||||
execsql { PRAGMA wal_autocheckpoint }
|
||||
|
||||
+41
-1
@@ -35,6 +35,20 @@ ifcapable !wal {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
if { ![wal_is_ok] && ![path_is_dos "."]} {
|
||||
do_test walmode-0.1 {
|
||||
execsql { PRAGMA journal_mode = wal }
|
||||
} {delete}
|
||||
do_test walmode-0.2 {
|
||||
execsql { PRAGMA main.journal_mode = wal }
|
||||
} {delete}
|
||||
do_test walmode-0.3 {
|
||||
execsql { PRAGMA main.journal_mode }
|
||||
} {delete}
|
||||
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_test walmode-1.1 {
|
||||
set sqlite_sync_count 0
|
||||
@@ -45,7 +59,15 @@ do_test walmode-1.2 {
|
||||
file size test.db
|
||||
} {1024}
|
||||
|
||||
set expected_sync_count 3
|
||||
# Determine how many sync() calls to expect from the "journal_mode=WAL"
|
||||
# command above. Note that if DEFAULT_WAL_SAFETYLEVEL is defined, the
|
||||
# safety-level may have been modified while compiling the "journal_mode=WAL"
|
||||
# statement.
|
||||
switch -- [db eval {PRAGMA main.synchronous}] {
|
||||
0 { set expected_sync_count 0 }
|
||||
1 { set expected_sync_count 2 }
|
||||
default { set expected_sync_count 3 }
|
||||
}
|
||||
if {$::tcl_platform(platform)!="windows"} {
|
||||
ifcapable dirsync {
|
||||
incr expected_sync_count
|
||||
@@ -66,6 +88,9 @@ do_test walmode-1.6 {
|
||||
file exists test.db-wal
|
||||
} {1}
|
||||
do_test walmode-1.7 {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
file exists test.db-wal
|
||||
} {0}
|
||||
@@ -82,6 +107,9 @@ do_test walmode-2.2 {
|
||||
file exists test.db-wal
|
||||
} {1}
|
||||
do_test walmode-2.3 {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
file exists test.db-wal
|
||||
} {0}
|
||||
@@ -104,6 +132,9 @@ do_test walmode-3.2 {
|
||||
#
|
||||
do_test walmode-4.1 {
|
||||
execsql { INSERT INTO t1 VALUES(1, 2) }
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
execsql { PRAGMA journal_mode = persist }
|
||||
} {persist}
|
||||
do_test walmode-4.2 {
|
||||
@@ -127,6 +158,9 @@ do_test walmode-4.5 {
|
||||
#
|
||||
do_test walmode-4.6 {
|
||||
sqlite3 db2 test.db
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db2 0
|
||||
}
|
||||
execsql { PRAGMA main.journal_mode } db2
|
||||
} {delete}
|
||||
do_test walmode-4.7 {
|
||||
@@ -144,6 +178,9 @@ do_test walmode-4.10 {
|
||||
|
||||
do_test walmode-4.11 {
|
||||
db2 close
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
execsql { PRAGMA journal_mode = delete } db
|
||||
} {delete}
|
||||
do_test walmode-4.12 {
|
||||
@@ -297,6 +334,9 @@ db close
|
||||
do_test walmode-7.0 {
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
execsql {
|
||||
PRAGMA journal_mode = WAL;
|
||||
CREATE TABLE t1(a, b);
|
||||
|
||||
@@ -17,6 +17,7 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix walnoshm
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
db close
|
||||
testvfs tvfsshm
|
||||
@@ -53,6 +54,9 @@ do_execsql_test 1.6 { INSERT INTO t1 VALUES(3, 4) }
|
||||
do_execsql_test 1.7 {
|
||||
PRAGMA locking_mode = normal;
|
||||
} {exclusive}
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
do_execsql_test 1.8 {
|
||||
PRAGMA journal_mode = delete;
|
||||
PRAGMA main.locking_mode;
|
||||
|
||||
+31
-12
@@ -21,6 +21,12 @@ ifcapable !wal {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
set shmpath test.db-shm
|
||||
if {[forced_proxy_locking]} {
|
||||
set shmpath [execsql { pragma lock_proxy_file }]-shm
|
||||
}
|
||||
|
||||
do_test walpersist-1.0 {
|
||||
db eval {
|
||||
@@ -31,22 +37,35 @@ do_test walpersist-1.0 {
|
||||
file exists test.db-wal
|
||||
} {1}
|
||||
do_test walpersist-1.1 {
|
||||
file exists test.db-shm
|
||||
file exists $shmpath
|
||||
} {1}
|
||||
do_test walpersist-1.2 {
|
||||
db close
|
||||
list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm]
|
||||
} {1 0 0}
|
||||
ifcapable enable_persist_wal {
|
||||
do_test walpersist-1.2-on {
|
||||
db close
|
||||
list [file exists test.db] [file exists test.db-wal] [file exists $shmpath]
|
||||
} {1 1 1}
|
||||
} {
|
||||
do_test walpersist-1.2-off {
|
||||
db close
|
||||
list [file exists test.db] [file exists test.db-wal] [file exists $shmpath]
|
||||
} {1 0 0}
|
||||
}
|
||||
do_test walpersist-1.3 {
|
||||
sqlite3 db test.db
|
||||
db eval {SELECT length(a) FROM t1}
|
||||
} {5000}
|
||||
do_test walpersist-1.4 {
|
||||
list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm]
|
||||
list [file exists test.db] [file exists test.db-wal] [file exists $shmpath]
|
||||
} {1 1 1}
|
||||
do_test walpersist-1.5 {
|
||||
file_control_persist_wal db -1
|
||||
} {0 0}
|
||||
ifcapable enable_persist_wal {
|
||||
do_test walpersist-1.5-on {
|
||||
file_control_persist_wal db -1
|
||||
} {0 1}
|
||||
} {
|
||||
do_test walpersist-1.5-off {
|
||||
file_control_persist_wal db -1
|
||||
} {0 0}
|
||||
}
|
||||
do_test walpersist-1.6 {
|
||||
file_control_persist_wal db 1
|
||||
} {0 1}
|
||||
@@ -64,7 +83,7 @@ do_test walpersist-1.10 {
|
||||
} {0 1}
|
||||
do_test walpersist-1.11 {
|
||||
db close
|
||||
list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm]
|
||||
list [file exists test.db] [file exists test.db-wal] [file exists $shmpath]
|
||||
} {1 1 1}
|
||||
|
||||
# Make sure the journal_size_limit works to limit the size of the
|
||||
@@ -72,7 +91,7 @@ do_test walpersist-1.11 {
|
||||
# journal_size_limit causes the WAL file to be truncated to zero bytes
|
||||
# when closing.
|
||||
#
|
||||
forcedelete test.db test.db-shm test.db-wal
|
||||
forcedelete test.db $shmpath test.db-wal
|
||||
do_test walpersist-2.1 {
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
@@ -97,7 +116,7 @@ do_test walpersist-2.3 {
|
||||
|
||||
do_test 3.1 {
|
||||
catch {db close}
|
||||
forcedelete test.db test.db-shm test.db-wal
|
||||
forcedelete test.db $shmpath test.db-wal
|
||||
sqlite3 db test.db
|
||||
execsql {
|
||||
PRAGMA page_size = 1024;
|
||||
|
||||
+25
-11
@@ -30,6 +30,14 @@ ifcapable !wal {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
set shmpath test.db-shm
|
||||
if {[forced_proxy_locking]} {
|
||||
sqlite3 db test.db
|
||||
set shmpath [execsql { pragma lock_proxy_file }]-shm
|
||||
db close
|
||||
}
|
||||
|
||||
do_multiclient_test tn {
|
||||
|
||||
@@ -62,11 +70,11 @@ do_multiclient_test tn {
|
||||
CREATE TABLE t1(x, y);
|
||||
INSERT INTO t1 VALUES('a', 'b');
|
||||
}
|
||||
file exists test.db-shm
|
||||
file exists $shmpath
|
||||
} {1}
|
||||
|
||||
do_test 1.1.2 {
|
||||
file attributes test.db-shm -permissions r--r--r--
|
||||
file attributes $shmpath -permissions r--r--r--
|
||||
code1 { sqlite3 db file:test.db?readonly_shm=1 }
|
||||
} {}
|
||||
|
||||
@@ -99,7 +107,7 @@ do_multiclient_test tn {
|
||||
do_test 1.2.1 {
|
||||
code2 { db2 close }
|
||||
code1 { db close }
|
||||
list [file exists test.db-wal] [file exists test.db-shm]
|
||||
list [file exists test.db-wal] [file exists $shmpath]
|
||||
} {1 1}
|
||||
do_test 1.2.2 {
|
||||
code1 { sqlite3 db file:test.db?readonly_shm=1 }
|
||||
@@ -108,9 +116,9 @@ do_multiclient_test tn {
|
||||
|
||||
do_test 1.2.3 {
|
||||
code1 { db close }
|
||||
file attributes test.db-shm -permissions rw-r--r--
|
||||
hexio_write test.db-shm 0 01020304
|
||||
file attributes test.db-shm -permissions r--r--r--
|
||||
file attributes $shmpath -permissions rw-r--r--
|
||||
hexio_write $shmpath 0 01020304
|
||||
file attributes $shmpath -permissions r--r--r--
|
||||
code1 { sqlite3 db file:test.db?readonly_shm=1 }
|
||||
csql1 { SELECT * FROM t1 }
|
||||
} {1 {attempt to write a readonly database}}
|
||||
@@ -119,11 +127,11 @@ do_multiclient_test tn {
|
||||
} {SQLITE_READONLY_RECOVERY}
|
||||
|
||||
do_test 1.2.5 {
|
||||
file attributes test.db-shm -permissions rw-r--r--
|
||||
file attributes $shmpath -permissions rw-r--r--
|
||||
code2 { sqlite3 db2 test.db }
|
||||
sql2 "SELECT * FROM t1"
|
||||
} {a b c d e f g h i j}
|
||||
file attributes test.db-shm -permissions r--r--r--
|
||||
file attributes $shmpath -permissions r--r--r--
|
||||
do_test 1.2.6 { sql1 "SELECT * FROM t1" } {a b c d e f g h i j}
|
||||
|
||||
do_test 1.2.7 {
|
||||
@@ -147,9 +155,13 @@ do_multiclient_test tn {
|
||||
# Also test that if the -shm file can be opened for read/write access,
|
||||
# it is not if readonly_shm=1 is present in the URI.
|
||||
do_test 1.3.2.1 {
|
||||
ifcapable enable_persist_wal {
|
||||
code1 { file_control_persist_wal db 0 }
|
||||
code2 { file_control_persist_wal db2 0 }
|
||||
}
|
||||
code1 { db close }
|
||||
code2 { db2 close }
|
||||
file exists test.db-shm
|
||||
file exists $shmpath
|
||||
} {0}
|
||||
do_test 1.3.2.2 {
|
||||
code1 { sqlite3 db file:test.db?readonly_shm=1 }
|
||||
@@ -157,8 +169,8 @@ do_multiclient_test tn {
|
||||
} {1 {unable to open database file}}
|
||||
do_test 1.3.2.3 {
|
||||
code1 { db close }
|
||||
close [open test.db-shm w]
|
||||
file attributes test.db-shm -permissions r--r--r--
|
||||
close [open $shmpath w]
|
||||
file attributes $shmpath -permissions r--r--r--
|
||||
code1 { sqlite3 db file:test.db?readonly_shm=1 }
|
||||
csql1 { SELECT * FROM t1 }
|
||||
} {1 {attempt to write a readonly database}}
|
||||
@@ -292,4 +304,6 @@ do_multiclient_test tn {
|
||||
} {}
|
||||
}
|
||||
|
||||
forcedelete $shmpath
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -17,6 +17,7 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
db close
|
||||
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
|
||||
|
||||
@@ -18,6 +18,7 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
proc reopen_db {} {
|
||||
catch { db close }
|
||||
|
||||
@@ -19,6 +19,7 @@ source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
if {[run_thread_tests]==0} { finish_test ; return }
|
||||
ifcapable !wal { finish_test ; return }
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
set sqlite_walsummary_mmap_incr 64
|
||||
|
||||
|
||||
@@ -115,6 +115,7 @@ foreach hdr {
|
||||
sqliteicu.h
|
||||
sqliteInt.h
|
||||
sqliteLimit.h
|
||||
sqlrr.h
|
||||
vdbe.h
|
||||
vdbeInt.h
|
||||
wal.h
|
||||
@@ -331,6 +332,7 @@ foreach file {
|
||||
rtree.c
|
||||
icu.c
|
||||
fts3_icu.c
|
||||
sqlrr.c
|
||||
} {
|
||||
copy_file tsrc/$file
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user