Fix bugs associated with the codec. (CVS 1846)
FossilOrigin-Name: b0a3becd82b9a4203c23f35dc5a5fd725e046f21
diff --git a/src/attach.c b/src/attach.c
index cd36936..4fa8447 100644
--- a/src/attach.c
+++ b/src/attach.c
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
-** $Id: attach.c,v 1.24 2004/07/22 02:40:38 drh Exp $
+** $Id: attach.c,v 1.25 2004/07/22 15:02:25 drh Exp $
*/
#include "sqliteInt.h"
@@ -23,7 +23,13 @@
** The pFilename and pDbname arguments are the tokens that define the
** filename and dbname in the ATTACH statement.
*/
-void sqlite3Attach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey){
+void sqlite3Attach(
+ Parse *pParse, /* The parser context */
+ Token *pFilename, /* Name of database file */
+ Token *pDbname, /* Name of the database to use internally */
+ int keyType, /* 0: no key. 1: TEXT, 2: BLOB */
+ Token *pKey /* Text of the key for keytype 2 and 3 */
+){
Db *aNew;
int rc, i;
char *zFile, *zName;
@@ -91,14 +97,32 @@
sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
}
#if SQLITE_HAS_CODEC
- assert( pKey!=0 );
- if( pKey->n>0 ){
- extern int sqlite3CodecAttach(sqlite*, int, void*, int);
- char *zKey = 0;
+ {
+ extern int sqlite3CodecAttach(sqlite3*, int, void*, int);
+ char *zKey;
int nKey;
+ if( keyType==0 ){
+ /* No key specified. Use the key from the main database */
+ extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
+ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
+ }else if( keyType==1 ){
+ /* Key specified as text */
+ zKey = sqlite3NameFromToken(pKey);
+ nKey = strlen(zKey);
+ }else{
+ /* Key specified as a BLOB */
+ char *zTemp;
+ assert( keyType==2 );
+ pKey->z++;
+ pKey->n--;
+ zTemp = sqlite3NameFromToken(pKey);
+ zKey = sqlite3HexToBlob(zTemp);
+ sqliteFree(zTemp);
+ }
sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
- zKey = sqlite3NameFromToken(pKey);
- nKey = strlen(zKey);
+ if( keyType ){
+ sqliteFree(zKey);
+ }
}
#endif
sqliteFree(zFile);
diff --git a/src/pager.c b/src/pager.c
index fc7bce9..36445b4 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.152 2004/07/22 01:19:35 drh Exp $
+** @(#) $Id: pager.c,v 1.153 2004/07/22 15:02:25 drh Exp $
*/
#include "os.h" /* Must be first to enable large file support */
#include "sqliteInt.h"
@@ -1001,8 +1001,8 @@
sqlite3OsSeek(&pPager->fd, pPager->pageSize*(off_t)(pPg->pgno-1));
rc = sqlite3OsRead(&pPager->fd, zBuf, pPager->pageSize);
TRACE2("REFETCH page %d\n", pPg->pgno);
- CODEC(pPager, zBuf, pPg->pgno, 2);
if( rc ) break;
+ CODEC(pPager, zBuf, pPg->pgno, 2);
}else{
memset(zBuf, 0, pPager->pageSize);
}
@@ -2516,12 +2516,13 @@
}
pPg->inJournal = 1;
}else{
- u32 cksum = pager_cksum(pPager, pPg->pgno, pData);
+ u32 cksum;
+ CODEC(pPager, pData, pPg->pgno, 7);
+ cksum = pager_cksum(pPager, pPg->pgno, pData);
saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager);
store32bits(cksum, pPg, pPager->pageSize);
szPg = pPager->pageSize+8;
store32bits(pPg->pgno, pPg, -4);
- CODEC(pPager, pData, pPg->pgno, 7);
rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
pPager->journalOff += szPg;
TRACE3("JOURNAL page %d needSync=%d\n", pPg->pgno, pPg->needSync);
diff --git a/src/parse.y b/src/parse.y
index 260e0f2..efb2420 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
-** @(#) $Id: parse.y,v 1.130 2004/07/20 14:06:52 drh Exp $
+** @(#) $Id: parse.y,v 1.131 2004/07/22 15:02:25 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
@@ -54,6 +54,11 @@
*/
struct TrigEvent { int a; IdList * b; };
+/*
+** An instance of this structure holds the ATTACH key and the key type.
+*/
+struct AttachKey { int type; Token key; };
+
} // end %include
// These are extra tokens used by the lexer but never seen by the
@@ -893,11 +898,14 @@
//////////////////////// ATTACH DATABASE file AS name /////////////////////////
cmd ::= ATTACH database_kw_opt ids(F) AS nm(D) key_opt(K). {
- sqlite3Attach(pParse, &F, &D, &K);
+ sqlite3Attach(pParse, &F, &D, K.type, &K.key);
}
-%type key_opt {Token}
-key_opt(A) ::= USING ids(X). { A = X; }
-key_opt(A) ::= . { A.z = 0; A.n = 0; }
+%type key_opt {struct AttachKey}
+key_opt(A) ::= . { A.type = 0; }
+%ifdef SQLITE_HAS_CODEC
+key_opt(A) ::= KEY ids(X). { A.type=1; A.key = X; }
+key_opt(A) ::= KEY BLOB(X). { A.type=2; A.Key = X; }
+%endif
database_kw_opt ::= DATABASE.
database_kw_opt ::= .
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 1db96f2..d6cde4e 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.307 2004/07/22 01:19:35 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.308 2004/07/22 15:02:25 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -1330,7 +1330,7 @@
# define sqlite3AuthContextPush(a,b,c)
# define sqlite3AuthContextPop(a) ((void)(a))
#endif
-void sqlite3Attach(Parse*, Token*, Token*, Token*);
+void sqlite3Attach(Parse*, Token*, Token*, int, Token*);
void sqlite3Detach(Parse*, Token*);
int sqlite3BtreeFactory(const sqlite *db, const char *zFilename,
int omitJournal, int nCache, Btree **ppBtree);
diff --git a/src/test1.c b/src/test1.c
index 852a164..61758fc 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
-** $Id: test1.c,v 1.94 2004/07/17 21:56:10 drh Exp $
+** $Id: test1.c,v 1.95 2004/07/22 15:02:26 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -305,6 +305,62 @@
}
/*
+** Usage: sqlite3_key DB KEY
+**
+** Set the codec key.
+*/
+static int test_key(
+ void *NotUsed,
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int argc, /* Number of arguments */
+ char **argv /* Text of each argument */
+){
+ sqlite *db;
+ const char *zKey;
+ int nKey;
+ if( argc!=3 ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " FILENAME\"", 0);
+ return TCL_ERROR;
+ }
+ if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
+ zKey = argv[2];
+ nKey = strlen(zKey);
+#ifdef SQLITE_HAS_CODEC
+ sqlite3_key(db, zKey, nKey);
+#endif
+ return TCL_OK;
+}
+
+/*
+** Usage: sqlite3_rekey DB KEY
+**
+** Change the codec key.
+*/
+static int test_rekey(
+ void *NotUsed,
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int argc, /* Number of arguments */
+ char **argv /* Text of each argument */
+){
+ sqlite *db;
+ const char *zKey;
+ int nKey;
+ if( argc!=3 ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " FILENAME\"", 0);
+ return TCL_ERROR;
+ }
+ if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
+ zKey = argv[2];
+ nKey = strlen(zKey);
+#ifdef SQLITE_HAS_CODEC
+ sqlite3_rekey(db, zKey, nKey);
+#endif
+ return TCL_OK;
+}
+
+/*
** Usage: sqlite3_close DB
**
** Closes the database opened by sqlite3_open.
@@ -2328,8 +2384,10 @@
{ "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail },
{ "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat },
#endif
- { "sqlite_bind", (Tcl_CmdProc*)test_bind },
- { "breakpoint", (Tcl_CmdProc*)test_breakpoint },
+ { "sqlite_bind", (Tcl_CmdProc*)test_bind },
+ { "breakpoint", (Tcl_CmdProc*)test_breakpoint },
+ { "sqlite3_key", (Tcl_CmdProc*)test_key },
+ { "sqlite3_rekey", (Tcl_CmdProc*)test_rekey },
};
static struct {
char *zName;