SQLite

Changes On Branch configReadOnly
Login

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

Changes In Branch configReadOnly Excluding Merge-Ins

This is equivalent to a diff from cda79028 to f29680c4

2013-01-09
11:25
Add a test case that demonstrates ticket [c997b11c4d53a2ee9983]. (check-in: 598f5f75 user: drh tags: trunk)
2013-01-08
17:24
Merge updates from trunk. (Closed-Leaf check-in: f29680c4 user: mistachkin tags: configReadOnly)
12:48
Do not raise an error if an unknown SQL function is found in a CHECK constraint while parsing the schema of an existing database. (check-in: cda79028 user: drh tags: trunk)
2013-01-07
17:31
Merge updates from trunk. (check-in: bf90f1fb user: mistachkin tags: configReadOnly)
2013-01-05
17:17
More bug fixes to the test_regexp.c module. Bring test_regexp.c into alignment with the regexp.c file in the Fossil sources. (check-in: 7695b88f user: drh tags: trunk)

Changes to src/global.c.

143
144
145
146
147
148
149

150
151
152
153
154
155
156
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157







+







*/
SQLITE_WSD struct Sqlite3Config sqlite3Config = {
   SQLITE_DEFAULT_MEMSTATUS,  /* bMemstat */
   1,                         /* bCoreMutex */
   SQLITE_THREADSAFE==1,      /* bFullMutex */
   SQLITE_USE_URI,            /* bOpenUri */
   SQLITE_ALLOW_COVERING_INDEX_SCAN,   /* bUseCis */
   0,                         /* bReadOnly */
   0x7ffffffe,                /* mxStrlen */
   128,                       /* szLookaside */
   500,                       /* nLookaside */
   {0,0,0,0,0,0,0,0},         /* m */
   {0,0,0,0,0,0,0,0,0},       /* mutex */
   {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
   (void*)0,                  /* pHeap */

Changes to src/main.c.

491
492
493
494
495
496
497







































498
499
500
501
502
503
504
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
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    case SQLITE_CONFIG_SQLLOG: {
      typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int);
      sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t);
      sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *);
      break;
    }
#endif

    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;
    }
  }
  va_end(ap);
2221
2222
2223
2224
2225
2226
2227
2228


2229
2230
2231
2232
2233
2234
2235
2260
2261
2262
2263
2264
2265
2266

2267
2268
2269
2270
2271
2272
2273
2274
2275







-
+
+







** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"  
** is UTF-8 encoded.
*/
static int openDatabase(
  const char *zFilename, /* Database filename UTF-8 encoded */
  sqlite3 **ppDb,        /* OUT: Returned database handle */
  unsigned int flags,    /* Operational flags */
  const char *zVfs       /* Name of the VFS to use */
  const char *zVfs,      /* Name of the VFS to use */
  int defaultFlags       /* Zero if opening via sqlite3_open_v2 */
){
  sqlite3 *db;                    /* Store allocated handle here */
  int rc;                         /* Return code */
  int isThreadsafe;               /* True for threadsafe connections */
  char *zOpen = 0;                /* Filename argument to pass to BtreeOpen() */
  char *zErrMsg = 0;              /* Error message from sqlite3ParseUri() */

2290
2291
2292
2293
2294
2295
2296










2297
2298
2299
2300
2301
2302
2303
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353







+
+
+
+
+
+
+
+
+
+







               SQLITE_OPEN_TEMP_JOURNAL | 
               SQLITE_OPEN_SUBJOURNAL | 
               SQLITE_OPEN_MASTER_JOURNAL |
               SQLITE_OPEN_NOMUTEX |
               SQLITE_OPEN_FULLMUTEX |
               SQLITE_OPEN_WAL
             );

  /* Check for global read-only mode */
  if( sqlite3GlobalConfig.bReadOnly ){
    if( defaultFlags ){
      flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
      flags |= SQLITE_OPEN_READONLY;
    }else if( flags & SQLITE_OPEN_READWRITE ){
      return SQLITE_READONLY;
    }
  }

  /* Allocate the sqlite data structure */
  db = sqlite3MallocZero( sizeof(sqlite3) );
  if( db==0 ) goto opendb_out;
  if( isThreadsafe ){
    db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
    if( db->mutex==0 ){
2488
2489
2490
2491
2492
2493
2494
2495

2496
2497
2498
2499
2500
2501
2502
2503

2504
2505
2506
2507
2508
2509
2510
2538
2539
2540
2541
2542
2543
2544

2545
2546
2547
2548
2549
2550
2551
2552

2553
2554
2555
2556
2557
2558
2559
2560







-
+







-
+







** Open a new database handle.
*/
int sqlite3_open(
  const char *zFilename, 
  sqlite3 **ppDb 
){
  return openDatabase(zFilename, ppDb,
                      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
                      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0, 1);
}
int sqlite3_open_v2(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb,         /* OUT: SQLite db handle */
  int flags,              /* Flags */
  const char *zVfs        /* Name of VFS module to use */
){
  return openDatabase(filename, ppDb, (unsigned int)flags, zVfs);
  return openDatabase(filename, ppDb, (unsigned int)flags, zVfs, 0);
}

#ifndef SQLITE_OMIT_UTF16
/*
** Open a new database handle.
*/
int sqlite3_open16(
2523
2524
2525
2526
2527
2528
2529
2530

2531
2532
2533
2534
2535
2536
2537
2573
2574
2575
2576
2577
2578
2579

2580
2581
2582
2583
2584
2585
2586
2587







-
+







  if( rc ) return rc;
#endif
  pVal = sqlite3ValueNew(0);
  sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zFilename8 ){
    rc = openDatabase(zFilename8, ppDb,
                      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
                      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0, 1);
    assert( *ppDb || rc==SQLITE_NOMEM );
    if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){
      ENC(*ppDb) = SQLITE_UTF16NATIVE;
    }
  }else{
    rc = SQLITE_NOMEM;
  }

Changes to src/sqlite.h.in.

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
1273

1274
1275

1276
1277
1278
1279
1280
1281
1282
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
1273
1274

1275
1276
1277

1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288







-
-
-
-
-
+
+
+
+
+











+
+
+
+
-
-
+
+




-
+
+

-
+


+







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() 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 sqlite3_config() is an integer
** [configuration option] that determines
** 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, sqlite3_config() returns [SQLITE_OK].
** ^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 this routine returns a non-zero [error code].
** 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
1593
1594
1595
1596
1597
1598
1599













1600
1601
1602
1603
1604
1605
1606
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625







+
+
+
+
+
+
+
+
+
+
+
+
+







** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
** malfunction when the optimization is enabled.  Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.
**
** [[SQLITE_CONFIG_READONLY]] <dt>SQLITE_CONFIG_READONLY
** <dd> This option takes a single argument of type int. If non-zero, then
** read-only mode for opening databases is globally enabled. If the parameter
** is zero, then read-only mode for opening databases is globally disabled. If
** read-only mode for opening databases is globally enabled, all databases
** opened by [sqlite3_open()], [sqlite3_open16()], or specified as part of
** [ATTACH] commands will be opened in read-only mode. Additionally, all calls
** to [sqlite3_open_v2()] must have the [SQLITE_OPEN_READONLY] flag set in the
** third argument; otherwise, a [SQLITE_READONLY] error will be returned. If it
** is globally disabled, [sqlite3_open()], [sqlite3_open16()],
** [sqlite3_open_v2()], and [ATTACH] commands will function normally. By
** default, read-only mode is globally disabled.
**
** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
** <dd> These options are obsolete and should not be used by new code.
** They are retained for backwards compatibility but are now no-ops.
** </dl>
**
1637
1638
1639
1640
1641
1642
1643

1644
1645
1646
1647
1648
1649
1650
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670







+







#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
#define SQLITE_CONFIG_URI          17  /* int */
#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
#define SQLITE_CONFIG_READONLY     22  /* int */

/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite3_db_config()] interface.
**

Changes to src/sqliteInt.h.

2480
2481
2482
2483
2484
2485
2486

2487
2488
2489
2490
2491
2492
2493
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494







+







*/
struct Sqlite3Config {
  int bMemstat;                     /* True to enable memory status */
  int bCoreMutex;                   /* True to enable core mutexing */
  int bFullMutex;                   /* True to enable full mutexing */
  int bOpenUri;                     /* True to interpret filenames as URIs */
  int bUseCis;                      /* Use covering indices for full-scans */
  int bReadOnly;                    /* True to force read-only mode */
  int mxStrlen;                     /* Maximum string length */
  int szLookaside;                  /* Default lookaside buffer size */
  int nLookaside;                   /* Default lookaside buffer count */
  sqlite3_mem_methods m;            /* Low-level memory allocation interface */
  sqlite3_mutex_methods mutex;      /* Low-level mutex interface */
  sqlite3_pcache_methods2 pcache2;  /* Low-level page-cache interface */
  void *pHeap;                      /* Heap storage space */

Changes to src/test_malloc.c.

1221
1222
1223
1224
1225
1226
1227










































1228
1229
1230
1231
1232
1233
1234
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
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







  }

  rc = sqlite3_config(SQLITE_CONFIG_COVERING_INDEX_SCAN, bUseCis);
  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
**           sqlite3_dump_memsys5  FILENAME
**
** Write a summary of unfreed memsys3 allocations to FILENAME.
*/
1473
1474
1475
1476
1477
1478
1479


1480
1481
1482
1483
1484
1485
1486
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530







+
+







     { "install_malloc_faultsim",    test_install_malloc_faultsim  ,0 },
     { "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.

48
49
50
51
52
53
54
































55
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

  db eval {SELECT * FROM sqlite_master}
} {}
do_test openv2-2.2 {
  catchsql {CREATE TABLE t1(x)}
} {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
} {1 {attempt to write a readonly database}}
catch {db close}
do_test openv2-3.3 {
  list [catch {sqlite3 db :memory: -readonly 1} msg] $msg
} {0 {}}
catch {db close}
do_test openv2-3.4 {
  list [catch {sqlite3 db test.db -readonly 1} msg] $msg
} {0 {}}
catch {db close}
do_test openv2-3.5 {
  list [catch {sqlite3 db :memory: -readonly 0} msg] $msg
} {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