-C Fix\sa\sproblem\swith\sthe\sgeopoly_bbox()\sfunction.
-D 2021-04-02T18:59:13.666
+C Add\sexperimental\sSQLITE_FCNTL_EXTERNAL_READER\sfile\scontrol.
+D 2021-04-02T19:55:48.856
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
-F src/os_unix.c 7a9eab7b11f552ab91ead980086b312c7e3b871efdee8c0c072b682bbec6592e
+F src/os_unix.c b5b7475bd1a8f1b83b6173a81f4fe50f9e077ccbacb62ce2fe7a5cb89916bce1
F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 970691daea03f9f15e34de671bd8675c1e136232b529e21bfd36d4dba6d41753
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 2d7a1f3d9f5970962b407cb4b38416fedc1a3b55efd010b40af375088653b6ce
F src/shell.c.in dcce260883836c9b58847505fbccce8d5546af925046f7dacd9443e922ece036
-F src/sqlite.h.in 3426a080ea1f222a73e3bd91e7eacbd30570a0117c03d42c6dde606f33e5e318
+F src/sqlite.h.in 18ec33e32001721fd4e9c4705a24a85dff04956ac2c0a21775058884ba845b09
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e
F src/sqliteInt.h c5cfae5891a6e643116f66f63769bcffeba89ca51f6278732da710eb0cf092b6
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 986b6391f02cd9b53c1d688be55899f6ffddeb8e8014cd83c1b73ff912579a71
-F src/test1.c f5262c95b95aeb2b580101dc4657e7c0df5b25a5a9b7c456e2d3f463cef83fa9
+F src/test1.c 2100f4c28bae21ce83a9a0c5ec6827efd0e15d11b93b569b614daa5654b3fcf6
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159
F test/expr.test 26cd01e8485bc48c8aa6a1add598e9ce1e706b4eb4f3f554e0b0223022e8c2cf
F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
+F test/external_reader.test c7d34694f1b25c32d866f56ac80c1e29edddc42b4ef90cad589263ffac2cde0c
F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
F test/fallocate.test 37a62e396a68eeede8f8d2ecf23573a80faceb630788d314d0a073d862616717
F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P fd4ea3f626b6e4957d56c2369be711895735cfc37cfde65650a6682ad5a3eb1a
-R 6950494a507d409a31ba9db8450c7ab5
-U drh
-Z 19246c5f3c2f1a430773bc8dc29b5ece
+P f3a2eb979f1003e8249e613b34afd345f157c0d54b4f05ea0db230ef70e71351
+R 7052bf13a0b7767c57dc2a61770c6de9
+U dan
+Z 52db8ae5f9c9b6085061c878477364c6
-f3a2eb979f1003e8249e613b34afd345f157c0d54b4f05ea0db230ef70e71351
\ No newline at end of file
+e16da5af822ef31d7e05992403cf9787fbb3d9abb0b5283aba55ea07e1830a72
\ No newline at end of file
/* Forward declaration */
static int unixGetTempname(int nBuf, char *zBuf);
+static int unixFcntlExternalReader(unixFile*, int*);
/*
** Information and control of an open file handle.
return proxyFileControl(id,op,pArg);
}
#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
+
+ case SQLITE_FCNTL_EXTERNAL_READER: {
+ return unixFcntlExternalReader((unixFile*)id, (int*)pArg);
+ }
}
return SQLITE_NOTFOUND;
}
#define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */
#define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */
+/*
+** Use F_GETLK to check whether or not there are any readers with open
+** wal-mode transactions in other processes on database file pFile. If
+** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are
+** such transactions, or 0 otherwise. If an error occurs, return an
+** SQLite error code. The final value of *piOut is undefined in this
+** case.
+*/
+static int unixFcntlExternalReader(unixFile *pFile, int *piOut){
+ int rc = SQLITE_OK;
+ *piOut = 0;
+ if( pFile->pShm){
+ unixShmNode *pShmNode = pFile->pShm->pShmNode;
+ struct flock f;
+
+ memset(&f, 0, sizeof(f));
+ f.l_type = F_WRLCK;
+ f.l_whence = SEEK_SET;
+ f.l_start = UNIX_SHM_BASE + 3;
+ f.l_len = SQLITE_SHM_NLOCK - 3;
+
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
+ if( osFcntl(pShmNode->hShm, F_GETLK, &f)<0 ){
+ rc = SQLITE_IOERR_LOCK;
+ }else{
+ *piOut = (f.l_type!=F_UNLCK);
+ }
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
+ }
+
+ return rc;
+}
+
+
/*
** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
**
** file to the database file, but before the *-shm file is updated to
** record the fact that the pages have been checkpointed.
** </ul>
+**
+** <li>[[SQLITE_FCNTL_EXTERNAL_READER]]
+** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect
+** whether or not there is a database client in another process with a wal-mode
+** transaction open on the database or not. It is only available on unix.The
+** (void*) argument passed with this file-control should be a pointer to a
+** value of type (int). The integer value is set to 1 if the database is a wal
+** mode database and there exists at least one client in another process that
+** currently has an SQL transaction open on the database. It is set to 0 if
+** the database is not a wal-mode db, or if there is no such connection in any
+** other process. This opcode cannot be used to detect transactions opened
+** by clients within the current process, only within other processes.
+** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
#define SQLITE_FCNTL_RESERVE_BYTES 38
#define SQLITE_FCNTL_CKPT_START 39
+#define SQLITE_FCNTL_EXTERNAL_READER 40
+
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
return TCL_OK;
}
+/*
+** tclcmd: file_control_external_reader DB ?AUXDB?
+**
+** Return a string that is a temporary filename
+*/
+static int SQLITE_TCLAPI file_control_external_reader(
+ 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;
+ const char *zName = "main";
+ int iRes = 0;
+ int rc = SQLITE_OK;
+
+ if( objc!=2 && objc!=3 ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"",
+ Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0);
+ return TCL_ERROR;
+ }
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
+ return TCL_ERROR;
+ }
+ if( objc==3 ){
+ zName = Tcl_GetString(objv[2]);
+ }
+ rc = sqlite3_file_control(db, zName, SQLITE_FCNTL_EXTERNAL_READER, &iRes);
+ if( rc!=SQLITE_OK ){
+ Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(iRes));
+ return TCL_OK;
+}
+
/*
** tclcmd: sqlite3_vfs_list
{ "file_control_vfsname", file_control_vfsname, 0 },
{ "file_control_reservebytes", file_control_reservebytes, 0 },
{ "file_control_tempfilename", file_control_tempfilename, 0 },
+ { "file_control_external_reader", file_control_external_reader, 0 },
{ "sqlite3_vfs_list", vfs_list, 0 },
{ "sqlite3_create_function_v2", test_create_function_v2, 0 },
--- /dev/null
+# 2021 April 2
+#
+# 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.
+#
+#***********************************************************************
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+source $testdir/lock_common.tcl
+set testprefix external_reader
+
+ifcapable !wal {
+ finish_test
+ return
+}
+if {$::tcl_platform(platform)!="unix"} {
+ finish_test
+ return
+}
+
+do_multiclient_test tn {
+
+ set bExternal 1
+ if {[info commands db3]!=""} { set bExternal 0 }
+
+ do_test 1.$tn.0 {
+ sql1 {
+ PRAGMA journal_mode = wal;
+ CREATE TABLE t1(a, b);
+ INSERT INTO t1 VALUES(1, 2);
+ }
+ } {wal}
+
+ do_test 1.$tn.1 {
+ sql2 { SELECT * FROM t1 }
+ } {1 2}
+
+ do_test 1.$tn.2 {
+ code1 {
+ file_control_external_reader db
+ }
+ } {0}
+
+ do_test 1.$tn.3 {
+ sql2 {
+ BEGIN;
+ SELECT * FROM t1;
+ }
+ } {1 2}
+
+ do_test 1.$tn.4 {
+ code1 {
+ file_control_external_reader db
+ }
+ } $bExternal
+
+ do_test 1.$tn.5 {
+ sql2 { COMMIT }
+ } {}
+
+ do_test 1.$tn.6 {
+ code1 { file_control_external_reader db }
+ } 0
+
+}
+
+
+finish_test