mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-19 21:43:15 +03:00
Added support for proxy file locking style
Added pragma support for controlling proxy file locking Added file control access to last errno and proxy locking Added support for TMPDIR environment variable Extended unit tests to cover new proxy locking pragmas and file control features (CVS 5934) FossilOrigin-Name: b9bc36d3d5e35821ef69c0881a84c0afed253c9e
This commit is contained in:
1207
src/os_unix.c
1207
src/os_unix.c
File diff suppressed because it is too large
Load Diff
44
src/pragma.c
44
src/pragma.c
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to implement the PRAGMA command.
|
||||
**
|
||||
** $Id: pragma.c,v 1.194 2008/11/17 19:18:55 danielk1977 Exp $
|
||||
** $Id: pragma.c,v 1.195 2008/11/21 00:10:35 aswift Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@@ -706,6 +706,48 @@ void sqlite3Pragma(
|
||||
}
|
||||
}else
|
||||
|
||||
/*
|
||||
** PRAGMA [database.]lock_proxy_file
|
||||
** PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path"
|
||||
**
|
||||
** Return or set the value of the lock_proxy_file flag. Changing
|
||||
** the value sets a specific file to be used for database access locks.
|
||||
**
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft, "lock_proxy_file")==0 ){
|
||||
if( !zRight ){
|
||||
Pager *pPager = sqlite3BtreePager(pDb->pBt);
|
||||
char *proxy_file_path = NULL;
|
||||
sqlite3_file *pFile = sqlite3PagerFile(pPager);
|
||||
sqlite3OsFileControl(pFile, SQLITE_GET_LOCKPROXYFILE,
|
||||
&proxy_file_path);
|
||||
|
||||
if( proxy_file_path ){
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
|
||||
"lock_proxy_file", SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, proxy_file_path, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
}
|
||||
}else{
|
||||
Pager *pPager = sqlite3BtreePager(pDb->pBt);
|
||||
sqlite3_file *pFile = sqlite3PagerFile(pPager);
|
||||
int res;
|
||||
if( zRight[0] ){
|
||||
res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE,
|
||||
zRight);
|
||||
} else {
|
||||
res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE,
|
||||
NULL);
|
||||
}
|
||||
if( res!=SQLITE_OK ){
|
||||
sqlite3ErrorMsg(pParse, "failed to set lock proxy file");
|
||||
goto pragma_out;
|
||||
}
|
||||
}
|
||||
}else
|
||||
|
||||
|
||||
/*
|
||||
** PRAGMA [database.]synchronous
|
||||
** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
** the version number) and changes its name to "sqlite3.h" as
|
||||
** part of the build process.
|
||||
**
|
||||
** @(#) $Id: sqlite.h.in,v 1.415 2008/11/19 01:20:26 drh Exp $
|
||||
** @(#) $Id: sqlite.h.in,v 1.416 2008/11/21 00:10:35 aswift Exp $
|
||||
*/
|
||||
#ifndef _SQLITE3_H_
|
||||
#define _SQLITE3_H_
|
||||
@@ -507,6 +507,8 @@ int sqlite3_exec(
|
||||
#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8))
|
||||
#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
|
||||
#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8))
|
||||
#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8))
|
||||
#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8))
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags For File Open Operations {H10230} <H11120> <H12700>
|
||||
@@ -723,6 +725,9 @@ struct sqlite3_io_methods {
|
||||
** is defined.
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
#define SQLITE_GET_LOCKPROXYFILE 2
|
||||
#define SQLITE_SET_LOCKPROXYFILE 3
|
||||
#define SQLITE_LAST_ERRNO 4
|
||||
|
||||
/*
|
||||
** CAPI3REF: Mutex Handle {H17110} <S20130>
|
||||
|
||||
85
src/test1.c
85
src/test1.c
@@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test1.c,v 1.329 2008/10/30 15:03:16 drh Exp $
|
||||
** $Id: test1.c,v 1.330 2008/11/21 00:10:35 aswift Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@@ -4466,9 +4466,87 @@ static int file_control_test(
|
||||
assert( rc==SQLITE_ERROR );
|
||||
rc = sqlite3_file_control(db, "temp", -1, &iArg);
|
||||
assert( rc==SQLITE_ERROR );
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** tclcmd: file_control_lasterrno_test DB
|
||||
**
|
||||
** This TCL command runs the sqlite3_file_control interface and
|
||||
** verifies correct operation of the SQLITE_LAST_ERRNO verb.
|
||||
*/
|
||||
static int file_control_lasterrno_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 *db;
|
||||
int rc;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
rc = sqlite3_file_control(db, NULL, SQLITE_LAST_ERRNO, &iArg);
|
||||
if( rc ) { Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; }
|
||||
if( iArg!=0 ) {
|
||||
Tcl_AppendResult(interp, "Unexpected non-zero errno: ",
|
||||
Tcl_GetStringFromObj(Tcl_NewIntObj(iArg), 0), " ", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: file_control_lockproxy_test DB
|
||||
**
|
||||
** This TCL command runs the sqlite3_file_control interface and
|
||||
** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
|
||||
** SQLITE_SET_LOCKPROXYFILE verbs.
|
||||
*/
|
||||
static int file_control_lockproxy_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 *db;
|
||||
int rc;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
|
||||
#ifdef SQLITE_ENABLE_LOCKING_STYLE
|
||||
{
|
||||
char *proxyPath = "test.proxy";
|
||||
char *testPath;
|
||||
rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
|
||||
if( rc ) { Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; }
|
||||
rc = sqlite3_file_control(db, NULL, SQLITE_GET_LOCKPROXYFILE, &testPath);
|
||||
if( strncmp(proxyPath,testPath,11) ) {
|
||||
Tcl_AppendResult(interp, "Lock proxy file did not match the previously assigned value", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( rc ) { Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; }
|
||||
rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
|
||||
if( rc ) { Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; }
|
||||
}
|
||||
#endif
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** tclcmd: sqlite3_vfs_list
|
||||
**
|
||||
@@ -4640,6 +4718,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
extern int sqlite3_open_file_count;
|
||||
extern int sqlite3_sort_count;
|
||||
extern int sqlite3_current_time;
|
||||
extern int sqlite3_hostid_num;
|
||||
extern int sqlite3_max_blobsize;
|
||||
extern int sqlite3BtreeSharedCacheReport(void*,
|
||||
Tcl_Interp*,int,Tcl_Obj*CONST*);
|
||||
@@ -4784,6 +4863,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "vfs_unregister_all", vfs_unregister_all, 0 },
|
||||
{ "vfs_reregister_all", vfs_reregister_all, 0 },
|
||||
{ "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 },
|
||||
{ "sqlite3_vfs_list", vfs_list, 0 },
|
||||
|
||||
/* Functions from os.h */
|
||||
@@ -4855,6 +4936,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
(char*)&sqlite3_open_file_count, TCL_LINK_INT);
|
||||
Tcl_LinkVar(interp, "sqlite_current_time",
|
||||
(char*)&sqlite3_current_time, TCL_LINK_INT);
|
||||
Tcl_LinkVar(interp, "sqlite_hostid_num",
|
||||
(char*)&sqlite3_hostid_num, TCL_LINK_INT);
|
||||
Tcl_LinkVar(interp, "sqlite3_xferopt_count",
|
||||
(char*)&sqlite3_xferopt_count, TCL_LINK_INT);
|
||||
Tcl_LinkVar(interp, "sqlite3_pager_readdb_count",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
** The focus of this file is providing the TCL testing layer
|
||||
** access to compile-time constants.
|
||||
**
|
||||
** $Id: test_config.c,v 1.42 2008/10/12 00:27:54 shane Exp $
|
||||
** $Id: test_config.c,v 1.43 2008/11/21 00:10:35 aswift Exp $
|
||||
*/
|
||||
|
||||
#include "sqliteLimit.h"
|
||||
@@ -392,6 +392,13 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
|
||||
Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_LOCKING_STYLE
|
||||
Tcl_SetVar2(interp, "sqlite_options", "lock_proxy_pragmas", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "lock_proxy_pragmas", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SQLITE_OMIT_SHARED_CACHE
|
||||
Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "0", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user