Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch db-readonly-api Excluding Merge-Ins
This is equivalent to a diff from 0dc4cb93 to 254f99ea
2012-03-15
| ||
22:54 | Add the sqlite3_db_readonly() API to trunk. (check-in: fed134a5 user: drh tags: trunk) | |
21:28 | Add the sqlite3_db_readonly() interface. This is still tentative, pending a closer look at other ideas to accomplish the same thing. (Closed-Leaf check-in: 254f99ea user: drh tags: db-readonly-api) | |
2012-03-09
| ||
22:02 | Candidate fix for the optimizer problem described in ticket [b7c8682cc17f3] which can causes a LEFT JOIN to be changed into a INNER JOIN if there are OR terms in the WHERE clause. (check-in: 0dc4cb93 user: drh tags: trunk) | |
2012-03-08
| ||
20:28 | On Windows, make sure the returned test current directory value does not contain any backslashes. (check-in: efee39e6 user: mistachkin tags: trunk) | |
Changes to src/main.c.
︙ | ︙ | |||
2700 2701 2702 2703 2704 2705 2706 | } /* ** Invoke the xFileControl method on a particular database. */ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ int rc = SQLITE_ERROR; | > | | < < < < < < < < | | | | | | | | | | | | | | | | | < | 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 | } /* ** Invoke the xFileControl method on a particular database. */ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ int rc = SQLITE_ERROR; Btree *pBtree; sqlite3_mutex_enter(db->mutex); pBtree = sqlite3DbNameToBtree(db, zDbName); if( pBtree ){ Pager *pPager; sqlite3_file *fd; sqlite3BtreeEnter(pBtree); pPager = sqlite3BtreePager(pBtree); assert( pPager!=0 ); fd = sqlite3PagerFile(pPager); assert( fd!=0 ); if( op==SQLITE_FCNTL_FILE_POINTER ){ *(sqlite3_file**)pArg = fd; rc = SQLITE_OK; }else if( fd->pMethods ){ rc = sqlite3OsFileControl(fd, op, pArg); }else{ rc = SQLITE_NOTFOUND; } sqlite3BtreeLeave(pBtree); } sqlite3_mutex_leave(db->mutex); return rc; } /* ** Interface to the testing logic. |
︙ | ︙ | |||
3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 | const char *z = sqlite3_uri_parameter(zFilename, zParam); sqlite3_int64 v; if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){ bDflt = v; } return bDflt; } /* ** Return the filename of the database associated with a database ** connection. */ const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ | > > > > > > > > > > > > > > > < < | | | | > > > > > > | | 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 | const char *z = sqlite3_uri_parameter(zFilename, zParam); sqlite3_int64 v; if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){ bDflt = v; } return bDflt; } /* ** Return the Btree pointer identified by zDbName. Return NULL if not found. */ Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ int i; for(i=0; i<db->nDb; i++){ if( db->aDb[i].pBt && (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zName)==0) ){ return db->aDb[i].pBt; } } return 0; } /* ** Return the filename of the database associated with a database ** connection. */ const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ Btree *pBt = sqlite3DbNameToBtree(db, zDbName); return pBt ? sqlite3BtreeGetFilename(pBt) : 0; } /* ** 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; } |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 | ** ^The filename returned by this function is the output of the ** xFullPathname method of the [VFS]. ^In other words, the filename ** will be an absolute pathname, even if the filename used ** to open the database originally was a URI or relative pathname. */ const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Find the next prepared statement ** ** ^This interface returns a pointer to the next [prepared statement] after ** pStmt associated with the [database connection] pDb. ^If pStmt is NULL ** then this interface returns a pointer to the first prepared statement ** associated with the database connection pDb. ^If no prepared statement | > > > > > > > > > | 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 | ** ^The filename returned by this function is the output of the ** xFullPathname method of the [VFS]. ^In other words, the filename ** will be an absolute pathname, even if the filename used ** to open the database originally was a URI or relative pathname. */ const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Determine if a database is read-only ** ** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N ** of connection D is read-only, 0 if it is read/write, and -1 if N is not ** the name of a database in connection C. */ int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Find the next prepared statement ** ** ^This interface returns a pointer to the next [prepared statement] after ** pStmt associated with the [database connection] pDb. ^If pStmt is NULL ** then this interface returns a pointer to the first prepared statement ** associated with the database connection pDb. ^If no prepared statement |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 | void sqlite3AddCheckConstraint(Parse*, Expr*); void sqlite3AddColumnType(Parse*,Token*); void sqlite3AddDefaultValue(Parse*,ExprSpan*); void sqlite3AddCollateType(Parse*, Token*); void sqlite3EndTable(Parse*,Token*,Token*,Select*); int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); int sqlite3CodeOnce(Parse *); Bitvec *sqlite3BitvecCreate(u32); int sqlite3BitvecTest(Bitvec*, u32); int sqlite3BitvecSet(Bitvec*, u32); void sqlite3BitvecClear(Bitvec*, u32, void*); void sqlite3BitvecDestroy(Bitvec*); | > | 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 | void sqlite3AddCheckConstraint(Parse*, Expr*); void sqlite3AddColumnType(Parse*,Token*); void sqlite3AddDefaultValue(Parse*,ExprSpan*); void sqlite3AddCollateType(Parse*, Token*); void sqlite3EndTable(Parse*,Token*,Token*,Select*); int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); Btree *sqlite3DbNameToBtree(sqlite3*,const char*); int sqlite3CodeOnce(Parse *); Bitvec *sqlite3BitvecCreate(u32); int sqlite3BitvecTest(Bitvec*, u32); int sqlite3BitvecSet(Bitvec*, u32); void sqlite3BitvecClear(Bitvec*, u32, void*); void sqlite3BitvecDestroy(Bitvec*); |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 | return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; zDbName = Tcl_GetString(objv[2]); Tcl_AppendResult(interp, sqlite3_db_filename(db, zDbName), (void*)0); return TCL_OK; } /* ** Usage: sqlite3_soft_heap_limit ?N? ** ** Query or set the soft heap limit for the current thread. The ** limit is only changed if the N is present. The previous limit ** is returned. | > > > > > > > > > > > > > > > > > > > > > > > > | 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 | return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; zDbName = Tcl_GetString(objv[2]); Tcl_AppendResult(interp, sqlite3_db_filename(db, zDbName), (void*)0); return TCL_OK; } /* ** Usage: sqlite3_db_readonly DB DBNAME ** ** Return 1 or 0 if DBNAME is readonly or not. Return -1 if DBNAME does ** not exist. */ static int test_db_readonly( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3 *db; const char *zDbName; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; zDbName = Tcl_GetString(objv[2]); Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_db_readonly(db, zDbName))); return TCL_OK; } /* ** Usage: sqlite3_soft_heap_limit ?N? ** ** Query or set the soft heap limit for the current thread. The ** limit is only changed if the N is present. The previous limit ** is returned. |
︙ | ︙ | |||
6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 | { "sqlite3_stmt_readonly", test_stmt_readonly ,0 }, { "sqlite3_stmt_busy", test_stmt_busy ,0 }, { "uses_stmt_journal", uses_stmt_journal ,0 }, { "sqlite3_release_memory", test_release_memory, 0}, { "sqlite3_db_release_memory", test_db_release_memory, 0}, { "sqlite3_db_filename", test_db_filename, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, { "sqlite3_thread_cleanup", test_thread_cleanup, 0}, { "sqlite3_pager_refcounts", test_pager_refcounts, 0}, { "sqlite3_load_extension", test_load_extension, 0}, { "sqlite3_enable_load_extension", test_enable_load, 0}, { "sqlite3_extended_result_codes", test_extended_result_codes, 0}, | > | 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 | { "sqlite3_stmt_readonly", test_stmt_readonly ,0 }, { "sqlite3_stmt_busy", test_stmt_busy ,0 }, { "uses_stmt_journal", uses_stmt_journal ,0 }, { "sqlite3_release_memory", test_release_memory, 0}, { "sqlite3_db_release_memory", test_db_release_memory, 0}, { "sqlite3_db_filename", test_db_filename, 0}, { "sqlite3_db_readonly", test_db_readonly, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, { "sqlite3_thread_cleanup", test_thread_cleanup, 0}, { "sqlite3_pager_refcounts", test_pager_refcounts, 0}, { "sqlite3_load_extension", test_load_extension, 0}, { "sqlite3_enable_load_extension", test_enable_load, 0}, { "sqlite3_extended_result_codes", test_extended_result_codes, 0}, |
︙ | ︙ |
Changes to test/pager1.test.
︙ | ︙ | |||
883 884 885 886 887 888 889 890 891 892 893 894 895 896 | do_test pager1.4.7.3 { db close catch {file attributes test.db-journal -permissions rw-rw-rw-} catch {file attributes test.db-journal -readonly 0} delete_file test.db-journal file exists test.db-journal } {0} #------------------------------------------------------------------------- # The following tests deal with multi-file commits. # # pager1-5.1.*: The case where a multi-file cannot be committed because # another connection is holding a SHARED lock on one of the # files. After the SHARED lock is removed, the COMMIT succeeds. | > > > > > > > > > > > > > > > > > > | 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 | do_test pager1.4.7.3 { db close catch {file attributes test.db-journal -permissions rw-rw-rw-} catch {file attributes test.db-journal -readonly 0} delete_file test.db-journal file exists test.db-journal } {0} do_test pager1.4.8.1 { catch {file attributes test.db -permissions r--------} catch {file attributes test.db -readonly 1} sqlite3 db test.db db eval { SELECT * FROM t1 } sqlite3_db_readonly db main } {1} do_test pager1.4.8.2 { sqlite3_db_readonly db xyz } {-1} do_test pager1.4.8.3 { db close catch {file attributes test.db -permissions rw-rw-rw-} catch {file attributes test.db -readonly 0} sqlite3 db test.db db eval { SELECT * FROM t1 } sqlite3_db_readonly db main } {0} #------------------------------------------------------------------------- # The following tests deal with multi-file commits. # # pager1-5.1.*: The case where a multi-file cannot be committed because # another connection is holding a SHARED lock on one of the # files. After the SHARED lock is removed, the COMMIT succeeds. |
︙ | ︙ |