Changes to reenable codec operation and to handle memory allocation
failures within a codec. (CVS 6746)

FossilOrigin-Name: 43a6ca98b1a6aff1f0f674ecabdc929efb314db7
diff --git a/src/build.c b/src/build.c
index 40d2d50..04484af 100644
--- a/src/build.c
+++ b/src/build.c
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.549 2009/06/03 11:25:07 danielk1977 Exp $
+** $Id: build.c,v 1.550 2009/06/11 00:47:21 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -429,6 +429,15 @@
   ** schema hash tables and therefore do not have to make any changes
   ** to any of those tables.
   */
+#ifdef SQLITE_HAS_CODEC
+  for(i=0; i<db->nDb; i++){
+    struct Db *pDb = &db->aDb[i];
+    if( pDb->pBt==0 ){
+      if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
+      pDb->pAux = 0;
+    }
+  }
+#endif
   for(i=j=2; i<db->nDb; i++){
     struct Db *pDb = &db->aDb[i];
     if( pDb->pBt==0 ){
diff --git a/src/pager.c b/src/pager.c
index 16cc70c..ce8bfd2 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.591 2009/06/02 21:31:39 drh Exp $
+** @(#) $Id: pager.c,v 1.592 2009/06/11 00:47:21 drh Exp $
 */
 #ifndef SQLITE_OMIT_DISKIO
 #include "sqliteInt.h"
@@ -103,11 +103,14 @@
 ** A macro used for invoking the codec if there is one
 */
 #ifdef SQLITE_HAS_CODEC
-# define CODEC1(P,D,N,X) if( P->xCodec!=0 ){ P->xCodec(P->pCodecArg,D,N,X); }
-# define CODEC2(P,D,N,X) ((char*)(P->xCodec!=0?P->xCodec(P->pCodecArg,D,N,X):D))
+# define CODEC1(P,D,N,X,E) \
+    if( P->xCodec && P->xCodec(P->pCodecArg,D,N,X)==0 ){ E; }
+# define CODEC2(P,D,N,X,E,O) \
+    if( P->xCodec==0 ){ O=(char*)D; }else \
+    if( (O=(char*)(P->xCodec(P->pCodecArg,D,N,X)))==0 ){ E; }
 #else
-# define CODEC1(P,D,N,X) /* NO-OP */
-# define CODEC2(P,D,N,X) ((char*)D)
+# define CODEC1(P,D,N,X,E)   /* NO-OP */
+# define CODEC2(P,D,N,X,E,O) O=(char*)D
 #endif
 
 /*
@@ -1595,7 +1598,7 @@
     }
 
     /* Decode the page just read from disk */
-    CODEC1(pPager, pData, pPg->pgno, 3);
+    CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
     sqlite3PcacheRelease(pPg);
   }
   return rc;
@@ -2887,8 +2890,11 @@
     ** set (set by sqlite3PagerDontWrite()).
     */
     if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
-      i64 offset = (pgno-1)*(i64)pPager->pageSize;         /* Offset to write */
-      char *pData = CODEC2(pPager, pList->pData, pgno, 6); /* Data to write */
+      i64 offset = (pgno-1)*(i64)pPager->pageSize;   /* Offset to write */
+      char *pData;                                   /* Data to write */    
+
+      /* Encode the database */
+      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
 
       /* Write out the page data. */
       rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
@@ -2943,8 +2949,9 @@
   if( isOpen(pPager->sjfd) ){
     void *pData = pPg->pData;
     i64 offset = pPager->nSubRec*(4+pPager->pageSize);
-    char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
-  
+    char *pData2;
+
+    CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
     PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
   
     assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
@@ -3487,7 +3494,7 @@
     u8 *dbFileVers = &((u8*)pPg->pData)[24];
     memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
   }
-  CODEC1(pPager, pPg->pData, pgno, 3);
+  CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
 
   PAGER_INCR(sqlite3_pager_readdb_count);
   PAGER_INCR(pPager->nRead);
@@ -4185,7 +4192,7 @@
         ** contains the database locks.  The following assert verifies
         ** that we do not. */
         assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
-        pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
+        CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
         cksum = pager_cksum(pPager, (u8*)pData2);
         rc = write32bits(pPager->jfd, pPager->journalOff, pPg->pgno);
         if( rc==SQLITE_OK ){
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 0d6acda..57470d2 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.882 2009/06/05 14:17:23 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.883 2009/06/11 00:47:21 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -644,6 +644,10 @@
   u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
   u8 safety_level;     /* How aggressive at syncing data to disk */
   Schema *pSchema;     /* Pointer to database schema (possibly shared) */
+#ifdef SQLITE_HAS_CODEC
+  void *pAux;               /* Auxiliary data.  Usually NULL */
+  void (*xFreeAux)(void*);  /* Routine to free pAux */
+#endif
 };
 
 /*