SQLite

Check-in [9dc2eaa64b]
Login

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

Overview
Comment:Add experimental sqlite3_reconfig() interface to more fully support the SQLITE_CONFIG_READONLY option.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | configReadOnly
Files: files | file ages | folders
SHA1: 9dc2eaa64b6a9f69bd6f3ff28de2c97682a69e0a
User & Date: mistachkin 2012-10-03 20:20:15.903
Context
2012-10-03
20:25
Merge updates from trunk. (check-in: 1138815c62 user: mistachkin tags: configReadOnly)
20:20
Add experimental sqlite3_reconfig() interface to more fully support the SQLITE_CONFIG_READONLY option. (check-in: 9dc2eaa64b user: mistachkin tags: configReadOnly)
2012-09-25
12:45
Merge updates from trunk. (check-in: 4a470741b6 user: mistachkin tags: configReadOnly)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
477
478
479
480
481
482
483


































484
485
486
487
488
489
490

    case SQLITE_CONFIG_COVERING_INDEX_SCAN: {
      sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
      break;
    }

    case SQLITE_CONFIG_READONLY: {


































      sqlite3GlobalConfig.bReadOnly = va_arg(ap, int);
      break;
    }

    default: {
      rc = SQLITE_ERROR;
      break;







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







477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524

    case SQLITE_CONFIG_COVERING_INDEX_SCAN: {
      sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
      break;
    }

    case SQLITE_CONFIG_READONLY: {
      sqlite3GlobalConfig.bReadOnly = va_arg(ap, int);
      break;
    }

    default: {
      rc = SQLITE_ERROR;
      break;
    }
  }
  va_end(ap);
  return rc;
}

/*
** This API allows applications to modify the global configuration of
** the SQLite library at run-time.
**
** This routine differs from sqlite3_config() in that it may be called when
** there are outstanding database connections and/or memory allocations.
** This routine is threadsafe.
*/
int sqlite3_reconfig(int op, ...){
  va_list ap;
  int rc = SQLITE_OK;

  va_start(ap, op);
  switch( op ){
    case SQLITE_CONFIG_READONLY: {
      /*
      ** On platforms where assignment of an integer value is atomic, there
      ** is no need for a mutex here.  On other platforms, there could be a
      ** subtle race condition here; however, the effect would simply be that
      ** a call to open a database would fail with SQLITE_READONLY.
      */
      sqlite3GlobalConfig.bReadOnly = va_arg(ap, int);
      break;
    }

    default: {
      rc = SQLITE_ERROR;
      break;
Changes to src/sqlite.h.in.
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241




1242
1243
1244
1245
1246
1247
1248

1249
1250
1251
1252

1253
1254
1255
1256
1257
1258
1259
int sqlite3_shutdown(void);
int sqlite3_os_init(void);
int sqlite3_os_end(void);

/*
** CAPI3REF: Configuring The SQLite Library
**
** The sqlite3_config() interface is used to make global configuration
** changes to SQLite in order to tune SQLite to the specific needs of
** the application.  The default configuration is recommended for most
** applications and so this routine is usually not necessary.  It is
** provided to support rare applications with unusual needs.
**
** The sqlite3_config() interface is not threadsafe.  The application
** must insure that no other SQLite interfaces are invoked by other
** threads while sqlite3_config() is running.  Furthermore, sqlite3_config()
** may only be invoked prior to library initialization using
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
** [sqlite3_shutdown()] then it will return SQLITE_MISUSE.
** Note, however, that ^sqlite3_config() can be called as part of the
** implementation of an application-defined [sqlite3_os_init()].
**




** The first argument to sqlite3_config() is an integer
** [configuration option] that determines
** what property of SQLite is to be configured.  Subsequent arguments
** vary depending on the [configuration option]
** in the first argument.
**
** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].

** ^If the option is unknown or SQLite is unable to set the option
** then this routine returns a non-zero [error code].
*/
int sqlite3_config(int, ...);


/*
** CAPI3REF: Configure database connections
**
** The sqlite3_db_config() interface is used to make configuration
** changes to a [database connection].  The interface is similar to
** [sqlite3_config()] except that the changes apply to a single







|
|
|
|
|











>
>
>
>
|
|




|
>

|


>







1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
int sqlite3_shutdown(void);
int sqlite3_os_init(void);
int sqlite3_os_end(void);

/*
** CAPI3REF: Configuring The SQLite Library
**
** The sqlite3_config() and sqlite3_reconfig() interfaces are used to make
** global configuration changes to SQLite in order to tune SQLite to the
** specific needs of the application.  The default configuration is recommended
** for most applications and so this routine is usually not necessary.  They
** are provided to support rare applications with unusual needs.
**
** The sqlite3_config() interface is not threadsafe.  The application
** must insure that no other SQLite interfaces are invoked by other
** threads while sqlite3_config() is running.  Furthermore, sqlite3_config()
** may only be invoked prior to library initialization using
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
** [sqlite3_shutdown()] then it will return SQLITE_MISUSE.
** Note, however, that ^sqlite3_config() can be called as part of the
** implementation of an application-defined [sqlite3_os_init()].
**
** The sqlite3_reconfig() interface is threadsafe and may be called at any
** time.  However, it supports only a small subset of the configuration
** options available for use with sqlite3_config().
**
** The first argument to both sqlite3_config() and sqlite3_reconfig() is an
** integer [configuration option] that determines
** what property of SQLite is to be configured.  Subsequent arguments
** vary depending on the [configuration option]
** in the first argument.
**
** ^When a configuration option is set, both sqlite3_config() and
** sqlite3_reconfig() return [SQLITE_OK].
** ^If the option is unknown or SQLite is unable to set the option
** then these routines returns a non-zero [error code].
*/
int sqlite3_config(int, ...);
int sqlite3_reconfig(int, ...);

/*
** CAPI3REF: Configure database connections
**
** The sqlite3_db_config() interface is used to make configuration
** changes to a [database connection].  The interface is similar to
** [sqlite3_config()] except that the changes apply to a single
Changes to src/test_malloc.c.
1224
1225
1226
1227
1228
1229
1230

1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250


1251











1252
1253
1254
1255
1256
1257
1258
  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);

  return TCL_OK;
}

/*
** Usage:    sqlite3_config_readonly  BOOLEAN

**
** Enables or disables global read-only mode using SQLITE_CONFIG_READONLY.
*/
static int test_config_readonly(
  void * clientData, 
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc;
  int bReadOnly;

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
    return TCL_ERROR;
  }
  if( Tcl_GetBooleanFromObj(interp, objv[1], &bReadOnly) ){
    return TCL_ERROR;
  }



  rc = sqlite3_config(SQLITE_CONFIG_READONLY, bReadOnly);











  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);

  return TCL_OK;
}

/*
** Usage:    sqlite3_dump_memsys3  FILENAME







>




















>
>
|
>
>
>
>
>
>
>
>
>
>
>







1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);

  return TCL_OK;
}

/*
** Usage:    sqlite3_config_readonly  BOOLEAN
**           sqlite3_reconfig_readonly  BOOLEAN
**
** Enables or disables global read-only mode using SQLITE_CONFIG_READONLY.
*/
static int test_config_readonly(
  void * clientData, 
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc;
  int bReadOnly;

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
    return TCL_ERROR;
  }
  if( Tcl_GetBooleanFromObj(interp, objv[1], &bReadOnly) ){
    return TCL_ERROR;
  }

  switch( SQLITE_PTR_TO_INT(clientData) ){
    case 0: {
      rc = sqlite3_config(SQLITE_CONFIG_READONLY, bReadOnly);
      break;
    }
    case 1: {
      rc = sqlite3_reconfig(SQLITE_CONFIG_READONLY, bReadOnly);
      break;
    }
    default: {
      rc = SQLITE_ERROR;
      break;
    }
  }
  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);

  return TCL_OK;
}

/*
** Usage:    sqlite3_dump_memsys3  FILENAME
1502
1503
1504
1505
1506
1507
1508

1509
1510
1511
1512
1513
1514
1515
     { "sqlite3_config_heap",        test_config_heap              ,0 },
     { "sqlite3_config_memstatus",   test_config_memstatus         ,0 },
     { "sqlite3_config_lookaside",   test_config_lookaside         ,0 },
     { "sqlite3_config_error",       test_config_error             ,0 },
     { "sqlite3_config_uri",         test_config_uri               ,0 },
     { "sqlite3_config_cis",         test_config_cis               ,0 },
     { "sqlite3_config_readonly",    test_config_readonly          ,0 },

     { "sqlite3_db_config_lookaside",test_db_config_lookaside      ,0 },
     { "sqlite3_dump_memsys3",       test_dump_memsys3             ,3 },
     { "sqlite3_dump_memsys5",       test_dump_memsys3             ,5 },
     { "sqlite3_install_memsys3",    test_install_memsys3          ,0 },
     { "sqlite3_memdebug_vfs_oom_test", test_vfs_oom_test          ,0 },
  };
  int i;







>







1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
     { "sqlite3_config_heap",        test_config_heap              ,0 },
     { "sqlite3_config_memstatus",   test_config_memstatus         ,0 },
     { "sqlite3_config_lookaside",   test_config_lookaside         ,0 },
     { "sqlite3_config_error",       test_config_error             ,0 },
     { "sqlite3_config_uri",         test_config_uri               ,0 },
     { "sqlite3_config_cis",         test_config_cis               ,0 },
     { "sqlite3_config_readonly",    test_config_readonly          ,0 },
     { "sqlite3_reconfig_readonly",  test_config_readonly          ,1 },
     { "sqlite3_db_config_lookaside",test_db_config_lookaside      ,0 },
     { "sqlite3_dump_memsys3",       test_dump_memsys3             ,3 },
     { "sqlite3_dump_memsys5",       test_dump_memsys3             ,5 },
     { "sqlite3_install_memsys3",    test_install_memsys3          ,0 },
     { "sqlite3_memdebug_vfs_oom_test", test_vfs_oom_test          ,0 },
  };
  int i;
Changes to test/openv2.test.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
} {1 {attempt to write a readonly database}}


# Attempt to open a database with SQLITE_OPEN_READWRITE when the
# SQLITE_CONFIG_READONLY flag is enabled.
#
db close
sqlite3_shutdown
sqlite3_config_readonly 1
sqlite3_initialize
autoinstall_test_functions

do_test openv2-3.1 {
  list [catch {sqlite3 db :memory:} msg] $msg
} {1 {attempt to write a readonly database}}
catch {db close}
do_test openv2-3.2 {
  list [catch {sqlite3 db test.db} msg] $msg







<
|
<
<







52
53
54
55
56
57
58

59


60
61
62
63
64
65
66
} {1 {attempt to write a readonly database}}


# Attempt to open a database with SQLITE_OPEN_READWRITE when the
# SQLITE_CONFIG_READONLY flag is enabled.
#
db close

sqlite3_reconfig_readonly 1



do_test openv2-3.1 {
  list [catch {sqlite3 db :memory:} msg] $msg
} {1 {attempt to write a readonly database}}
catch {db close}
do_test openv2-3.2 {
  list [catch {sqlite3 db test.db} msg] $msg
82
83
84
85
86
87
88
89
90
91
92
93
} {1 {attempt to write a readonly database}}
catch {db close}
do_test openv2-3.6 {
  list [catch {sqlite3 db test.db -readonly 0} msg] $msg
} {1 {attempt to write a readonly database}}
catch {db close}

sqlite3_shutdown
sqlite3_config_readonly 0
sqlite3_initialize
autoinstall_test_functions
finish_test







<
|
<
<

79
80
81
82
83
84
85

86


87
} {1 {attempt to write a readonly database}}
catch {db close}
do_test openv2-3.6 {
  list [catch {sqlite3 db test.db -readonly 0} msg] $msg
} {1 {attempt to write a readonly database}}
catch {db close}


sqlite3_reconfig_readonly 0


finish_test