/ Check-in [22ebc668]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add an experimental busy_timeout pragma to facilitate access to the sqlite3_busy_timeout() interfaces for programmers that are working from behind a language wrapper that does not expose that interface.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | busy-timeout-pragma
Files: files | file ages | folders
SHA1: 22ebc668516bc3dd5782d6d3d42dc7fd2eed7d79
User & Date: drh 2012-09-07 16:46:59
Context
2012-09-07
18:49
Have PRAGMA busy_timeout return 0 if the busy handler has been changed or cancelled. check-in: 7be5bc36 user: drh tags: busy-timeout-pragma
16:46
Add an experimental busy_timeout pragma to facilitate access to the sqlite3_busy_timeout() interfaces for programmers that are working from behind a language wrapper that does not expose that interface. check-in: 22ebc668 user: drh tags: busy-timeout-pragma
2012-09-04
21:34
Avoid repeating calls to the sqlite3_trace() callback when the same statement is evaluted multiple times by sqlite3_step() due to an SQLITE_SCHEMA reprepare. check-in: 39f763bf user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/main.c.

1152
1153
1154
1155
1156
1157
1158

1159
1160
1161
1162
1163
1164
1165
** specified number of milliseconds before returning 0.
*/
int sqlite3_busy_timeout(sqlite3 *db, int ms){
  if( ms>0 ){
    db->busyTimeout = ms;
    sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
  }else{

    sqlite3_busy_handler(db, 0, 0);
  }
  return SQLITE_OK;
}

/*
** Cause any pending operation to stop at its earliest opportunity.







>







1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
** specified number of milliseconds before returning 0.
*/
int sqlite3_busy_timeout(sqlite3 *db, int ms){
  if( ms>0 ){
    db->busyTimeout = ms;
    sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
  }else{
    db->busyTimeout = 0;
    sqlite3_busy_handler(db, 0, 0);
  }
  return SQLITE_OK;
}

/*
** Cause any pending operation to stop at its earliest opportunity.

Changes to src/pragma.c.

1532
1533
1534
1535
1536
1537
1538
















1539
1540
1541
1542
1543
1544
1545
  ** This pragma attempts to free as much memory as possible from the
  ** current database connection.
  */
  if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){
    sqlite3_db_release_memory(db);
  }else

















#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
  /*
  ** Report the current state of file logs for all databases
  */
  if( sqlite3StrICmp(zLeft, "lock_status")==0 ){
    static const char *const azLockName[] = {
      "unlocked", "shared", "reserved", "pending", "exclusive"







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
  ** This pragma attempts to free as much memory as possible from the
  ** current database connection.
  */
  if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){
    sqlite3_db_release_memory(db);
  }else

  /*
  **   PRAGMA busy_timeout
  **   PRAGMA busy_timeout = N
  **
  ** Call sqlite3_busy_timeout(db, N).  Return the current timeout value
  ** if one is set.  If the busy handler is not set to the default 
  ** busy callback, then the return value is undefined.  A value of N
  ** which is 0 or negative disables the busy handler.
  */
  if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){
    if( zRight ){
      sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
    }
    returnSingleInt(pParse, "timeout",  db->busyTimeout);
  }else

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
  /*
  ** Report the current state of file logs for all databases
  */
  if( sqlite3StrICmp(zLeft, "lock_status")==0 ){
    static const char *const azLockName[] = {
      "unlocked", "shared", "reserved", "pending", "exclusive"

Changes to test/lock.test.

243
244
245
246
247
248
249



250
251
252
253



254

















255
256
257
258
259
260
261
#
do_test lock-2.8 {
  db2 timeout 400
  execsql BEGIN
  execsql {UPDATE t1 SET a = 0 WHERE 0}
  catchsql {BEGIN EXCLUSIVE;} db2
} {1 {database is locked}}



do_test lock-2.9 {
  db2 timeout 0
  execsql COMMIT
} {}



integrity_check lock-2.10


















# Try to start two transactions in a row
#
do_test lock-3.1 {
  execsql {BEGIN TRANSACTION}
  set r [catch {execsql {BEGIN TRANSACTION}} msg]
  execsql {ROLLBACK}







>
>
>




>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
#
do_test lock-2.8 {
  db2 timeout 400
  execsql BEGIN
  execsql {UPDATE t1 SET a = 0 WHERE 0}
  catchsql {BEGIN EXCLUSIVE;} db2
} {1 {database is locked}}
do_test lock-2.8b {
  db2 eval {PRAGMA busy_timeout}
} {400}
do_test lock-2.9 {
  db2 timeout 0
  execsql COMMIT
} {}
do_test lock-2.9b {
  db2 eval {PRAGMA busy_timeout}
} {0}
integrity_check lock-2.10
do_test lock-2.11 {
  db2 eval {PRAGMA busy_timeout(400)}
  execsql BEGIN
  execsql {UPDATE t1 SET a = 0 WHERE 0}
  catchsql {BEGIN EXCLUSIVE;} db2
} {1 {database is locked}}
do_test lock-2.11b {
  db2 eval {PRAGMA busy_timeout}
} {400}
do_test lock-2.12 {
  db2 eval {PRAGMA busy_timeout(0)}
  execsql COMMIT
} {}
do_test lock-2.11b {
  db2 eval {PRAGMA busy_timeout}
} {0}
integrity_check lock-2.12

# Try to start two transactions in a row
#
do_test lock-3.1 {
  execsql {BEGIN TRANSACTION}
  set r [catch {execsql {BEGIN TRANSACTION}} msg]
  execsql {ROLLBACK}