aboutsummaryrefslogtreecommitdiff
path: root/src/tclsqlite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tclsqlite.c')
-rw-r--r--src/tclsqlite.c99
1 files changed, 77 insertions, 22 deletions
diff --git a/src/tclsqlite.c b/src/tclsqlite.c
index 70706306a..6fb3c3add 100644
--- a/src/tclsqlite.c
+++ b/src/tclsqlite.c
@@ -11,7 +11,7 @@
*************************************************************************
** A TCL Interface to SQLite
**
-** $Id: tclsqlite.c,v 1.54 2004/01/15 02:44:03 drh Exp $
+** $Id: tclsqlite.c,v 1.55 2004/02/01 01:22:52 drh Exp $
*/
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
@@ -486,19 +486,21 @@ static int auth_callback(
static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
SqliteDb *pDb = (SqliteDb*)cd;
int choice;
+ int rc = TCL_OK;
static const char *DB_strs[] = {
"authorizer", "busy", "changes",
"close", "commit_hook", "complete",
"errorcode", "eval", "function",
"last_insert_rowid", "onecolumn", "progress",
- "timeout", "trace", 0
+ "rekey", "timeout", "trace",
+ 0
};
enum DB_enum {
DB_AUTHORIZER, DB_BUSY, DB_CHANGES,
DB_CLOSE, DB_COMMIT_HOOK, DB_COMPLETE,
DB_ERRORCODE, DB_EVAL, DB_FUNCTION,
DB_LAST_INSERT_ROWID, DB_ONECOLUMN, DB_PROGRESS,
- DB_TIMEOUT, DB_TRACE,
+ DB_REKEY, DB_TIMEOUT, DB_TRACE,
};
if( objc<2 ){
@@ -747,7 +749,6 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
CallbackData cbData;
char *zErrMsg;
char *zSql;
- int rc;
#ifdef UTF_TRANSLATION_NEEDED
Tcl_DString dSql;
int i;
@@ -865,7 +866,6 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
** Return a single column from a single row of the given SQL query.
*/
case DB_ONECOLUMN: {
- int rc;
char *zSql;
char *zErrMsg = 0;
if( objc!=3 ){
@@ -875,7 +875,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
zSql = Tcl_GetStringFromObj(objv[2], 0);
rc = sqlite_exec(pDb->db, zSql, DbEvalCallback3, interp, &zErrMsg);
if( rc==SQLITE_ABORT ){
- /* Do nothing. This is normal. */
+ rc = SQLITE_OK;
}else if( zErrMsg ){
Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
free(zErrMsg);
@@ -888,6 +888,29 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}
/*
+ ** $db rekey KEY
+ **
+ ** Change the encryption key on the currently open database.
+ */
+ case DB_REKEY: {
+ int nKey;
+ void *pKey;
+ if( objc!=3 ){
+ Tcl_WrongNumArgs(interp, 2, objv, "KEY");
+ return TCL_ERROR;
+ }
+ pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
+#ifdef SQLITE_HAS_CRYPTO
+ rc = sqlite_rekey(pDb->db, pKey, nKey);
+ if( rc ){
+ Tcl_AppendResult(interp, sqlite_error_string(rc), 0);
+ rc = TCL_ERROR;
+ }
+#endif
+ break;
+ }
+
+ /*
** $db timeout MILLESECONDS
**
** Delay for the number of milliseconds specified when a file is locked.
@@ -940,11 +963,11 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}
} /* End of the SWITCH statement */
- return TCL_OK;
+ return rc;
}
/*
-** sqlite DBNAME FILENAME ?MODE?
+** sqlite DBNAME FILENAME ?MODE? ?-key KEY?
**
** This is the main Tcl command. When the "sqlite" Tcl command is
** invoked, this routine runs to process that command.
@@ -974,21 +997,34 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
** not. Used by tests to make sure the library was compiled
** correctly.
*/
-static int DbMain(void *cd, Tcl_Interp *interp, int argc, char **argv){
+static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
int mode;
SqliteDb *p;
+ void *pKey = 0;
+ int nKey = 0;
+ const char *zArg;
char *zErrMsg;
+ const char *zFile;
char zBuf[80];
- if( argc==2 ){
- if( strcmp(argv[1],"-encoding")==0 ){
+ if( objc==2 ){
+ zArg = Tcl_GetStringFromObj(objv[1], 0);
+ if( strcmp(zArg,"-encoding")==0 ){
Tcl_AppendResult(interp,sqlite_encoding,0);
return TCL_OK;
}
- if( strcmp(argv[1],"-version")==0 ){
+ if( strcmp(zArg,"-version")==0 ){
Tcl_AppendResult(interp,sqlite_version,0);
return TCL_OK;
}
- if( strcmp(argv[1],"-tcl-uses-utf")==0 ){
+ if( strcmp(zArg,"-has-crypto")==0 ){
+#ifdef SQLITE_HAS_CRYPTO
+ Tcl_AppendResult(interp,"1",0);
+#else
+ Tcl_AppendResult(interp,"0",0);
+#endif
+ return TCL_OK;
+ }
+ if( strcmp(zArg,"-tcl-uses-utf")==0 ){
#ifdef TCL_UTF_MAX
Tcl_AppendResult(interp,"1",0);
#else
@@ -997,14 +1033,26 @@ static int DbMain(void *cd, Tcl_Interp *interp, int argc, char **argv){
return TCL_OK;
}
}
- if( argc!=3 && argc!=4 ){
- Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
- " HANDLE FILENAME ?MODE?\"", 0);
+ if( objc==5 || objc==6 ){
+ zArg = Tcl_GetStringFromObj(objv[objc-2], 0);
+ if( strcmp(zArg,"-key")==0 ){
+ pKey = Tcl_GetByteArrayFromObj(objv[objc-1], &nKey);
+ objc -= 2;
+ }
+ }
+ if( objc!=3 && objc!=4 ){
+ Tcl_WrongNumArgs(interp, 1, objv,
+#ifdef SQLITE_HAS_CRYPTO
+ "HANDLE FILENAME ?-key CRYPTOKEY?"
+#else
+ "HANDLE FILENAME ?MODE?"
+#endif
+ );
return TCL_ERROR;
}
- if( argc==3 ){
+ if( objc==3 ){
mode = 0666;
- }else if( Tcl_GetInt(interp, argv[3], &mode)!=TCL_OK ){
+ }else if( Tcl_GetIntFromObj(interp, objv[3], &mode)!=TCL_OK ){
return TCL_ERROR;
}
zErrMsg = 0;
@@ -1014,14 +1062,21 @@ static int DbMain(void *cd, Tcl_Interp *interp, int argc, char **argv){
return TCL_ERROR;
}
memset(p, 0, sizeof(*p));
- p->db = sqlite_open(argv[2], mode, &zErrMsg);
+ zFile = Tcl_GetStringFromObj(objv[2], 0);
+#ifdef SQLITE_HAS_CRYPTO
+ if( nKey>0 ){
+ p->db = sqlite_open_encrypted(zFile, pKey, nKey, &zErrMsg);
+ }else
+#endif
+ p->db = sqlite_open(zFile, mode, &zErrMsg);
if( p->db==0 ){
Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
Tcl_Free((char*)p);
free(zErrMsg);
return TCL_ERROR;
}
- Tcl_CreateObjCommand(interp, argv[1], DbObjCmd, (char*)p, DbDeleteCmd);
+ zArg = Tcl_GetStringFromObj(objv[1], 0);
+ Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
/* The return value is the value of the sqlite* pointer
*/
@@ -1063,13 +1118,13 @@ static int DbMain(void *cd, Tcl_Interp *interp, int argc, char **argv){
*/
int Sqlite_Init(Tcl_Interp *interp){
Tcl_InitStubs(interp, "8.0", 0);
- Tcl_CreateCommand(interp, "sqlite", (Tcl_CmdProc*)DbMain, 0, 0);
+ Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
Tcl_PkgProvide(interp, "sqlite", "2.0");
return TCL_OK;
}
int Tclsqlite_Init(Tcl_Interp *interp){
Tcl_InitStubs(interp, "8.0", 0);
- Tcl_CreateCommand(interp, "sqlite", (Tcl_CmdProc*)DbMain, 0, 0);
+ Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
Tcl_PkgProvide(interp, "sqlite", "2.0");
return TCL_OK;
}