SQLite

Check-in [8d8af114da]
Login

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

Overview
Comment:Fix the sqlite3_db_readonly() API so that it reports true if the database is readonly because the file format write version (byte 18 of the header) is too large.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8d8af114dac301335ec10671c1e9a5a6d8266a60
User & Date: drh 2014-05-21 08:21:07.032
Context
2014-05-21
08:48
Do not burn memory remembering CHECK constraints in a read-only database. (check-in: 34ddf02d3d user: drh tags: trunk)
08:21
Fix the sqlite3_db_readonly() API so that it reports true if the database is readonly because the file format write version (byte 18 of the header) is too large. (check-in: 8d8af114da user: drh tags: trunk)
2014-05-17
16:56
Internally, use a 64-bit integers for segment level numbers. (check-in: 8180e320ee user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btree.c.
8522
8523
8524
8525
8526
8527
8528







** set the mask of hint flags for cursor pCsr. Currently the only valid
** values are 0 and BTREE_BULKLOAD.
*/
void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
  assert( mask==BTREE_BULKLOAD || mask==0 );
  pCsr->hints = mask;
}














>
>
>
>
>
>
>
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
** set the mask of hint flags for cursor pCsr. Currently the only valid
** values are 0 and BTREE_BULKLOAD.
*/
void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
  assert( mask==BTREE_BULKLOAD || mask==0 );
  pCsr->hints = mask;
}

/*
** Return true if the given Btree is read-only.
*/
int sqlite3BtreeIsReadonly(Btree *p){
  return (p->pBt->btsFlags & BTS_READ_ONLY)!=0;
}
Changes to src/btree.h.
190
191
192
193
194
195
196

197
198
199
200
201
202
203
struct Pager *sqlite3BtreePager(Btree*);

int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
void sqlite3BtreeIncrblobCursor(BtCursor *);
void sqlite3BtreeClearCursor(BtCursor *);
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);


#ifndef NDEBUG
int sqlite3BtreeCursorIsValid(BtCursor*);
#endif

#ifndef SQLITE_OMIT_BTREECOUNT
int sqlite3BtreeCount(BtCursor *, i64 *);







>







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
struct Pager *sqlite3BtreePager(Btree*);

int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
void sqlite3BtreeIncrblobCursor(BtCursor *);
void sqlite3BtreeClearCursor(BtCursor *);
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
int sqlite3BtreeIsReadonly(Btree *pBt);

#ifndef NDEBUG
int sqlite3BtreeCursorIsValid(BtCursor*);
#endif

#ifndef SQLITE_OMIT_BTREECOUNT
int sqlite3BtreeCount(BtCursor *, i64 *);
Changes to src/main.c.
3441
3442
3443
3444
3445
3446
3447
3448
3449

/*
** Return 1 if database is read-only or 0 if read/write.  Return -1 if
** no such database exists.
*/
int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
  Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
  return pBt ? sqlite3PagerIsreadonly(sqlite3BtreePager(pBt)) : -1;
}







|

3441
3442
3443
3444
3445
3446
3447
3448
3449

/*
** Return 1 if database is read-only or 0 if read/write.  Return -1 if
** no such database exists.
*/
int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
  Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
  return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
}
Changes to test/rdonly.test.
28
29
30
31
32
33
34



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49



50
51
52
53
54
55
56
do_test rdonly-1.1 {
  execsql {
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(1);
    SELECT * FROM t1;
  }
} {1}




# Changes the write version from 1 to 3.  Verify that the database
# can be read but not written.
#
do_test rdonly-1.2 {
  db close
  hexio_get_int [hexio_read test.db 18 1]
} 1
do_test rdonly-1.3 {
  hexio_write test.db 18 03
  sqlite3 db test.db
  execsql {
    SELECT * FROM t1;
  }
} {1}



do_test rdonly-1.4 {
  catchsql {
    INSERT INTO t1 VALUES(2)
  }
} {1 {attempt to write a readonly database}}

# Change the write version back to 1.  Verify that the database







>
>
>















>
>
>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
do_test rdonly-1.1 {
  execsql {
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(1);
    SELECT * FROM t1;
  }
} {1}
do_test rdonly-1.1.1 {
  sqlite3_db_readonly db main
} {0}

# Changes the write version from 1 to 3.  Verify that the database
# can be read but not written.
#
do_test rdonly-1.2 {
  db close
  hexio_get_int [hexio_read test.db 18 1]
} 1
do_test rdonly-1.3 {
  hexio_write test.db 18 03
  sqlite3 db test.db
  execsql {
    SELECT * FROM t1;
  }
} {1}
do_test rdonly-1.3.1 {
  sqlite3_db_readonly db main
} {1}
do_test rdonly-1.4 {
  catchsql {
    INSERT INTO t1 VALUES(2)
  }
} {1 {attempt to write a readonly database}}

# Change the write version back to 1.  Verify that the database