Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Unified Diff: third_party/sqlite/src/src/recover.c

Issue 1671043003: [sqlite] Indirect recover.c dependencies on Pager. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@zzsql_recover_empty_review
Patch Set: Fix a potential leak. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/sqlite/amalgamation/sqlite3.c ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/sqlite/src/src/recover.c
diff --git a/third_party/sqlite/src/src/recover.c b/third_party/sqlite/src/src/recover.c
index 58dd89e1f2f6f9011b028137acccd5a27e7525b8..f7e108fc6496d59ea34b5596d60e374ff927091f 100644
--- a/third_party/sqlite/src/src/recover.c
+++ b/third_party/sqlite/src/src/recover.c
@@ -370,8 +370,82 @@ static int ascii_strcasecmp(const char *s1, const char *s2){
return ascii_strncasecmp(s1, s2, strlen(s1)+1);
}
+/* Provide access to the pages of a SQLite database in a way similar to SQLite's
+** Pager. Will be re-implemented in terms of sqlite3_file.
+*/
+typedef struct RecoverPager RecoverPager;
+struct RecoverPager {
+ Pager *pSqlitePager; /* SQLite's pager. */
+};
+
+static void pagerDestroy(RecoverPager *pPager){
+ memset(pPager, 0xA5, sizeof(*pPager));
+ sqlite3_free(pPager);
+}
+
+static int pagerCreate(Pager *pSqlitePager, u32 nPageSize,
+ RecoverPager **ppPager){
+ RecoverPager *pPager = sqlite3_malloc(sizeof(RecoverPager));
+ if( !pPager ){
+ return SQLITE_NOMEM;
+ }
+
+ memset(pPager, 0, sizeof(*pPager));
+ pPager->pSqlitePager = pSqlitePager;
+ *ppPager = pPager;
+ return SQLITE_OK;
+}
+
+/* Matches DbPage (aka PgHdr) from SQLite internals. */
+typedef struct RecoverPage RecoverPage;
+struct RecoverPage {
+ DbPage *pSqlitePage; /* SQLite's page. */
+ Pgno pgno; /* Page number for this page */
+ void *pData; /* Page data */
+ RecoverPager *pPager; /* The pager this page is part of */
+};
+
+static void pageDestroy(RecoverPage *pPage){
+ sqlite3PagerUnref(pPage->pSqlitePage);
+ memset(pPage, 0xA5, sizeof(*pPage));
+ sqlite3_free(pPage);
+}
+
+static int pageCreate(RecoverPager *pPager, DbPage *pSqlitePage,
+ RecoverPage **ppPage){
+ RecoverPage *pPage = sqlite3_malloc(sizeof(RecoverPage));
+ if( !pPage ){
+ return SQLITE_NOMEM;
+ }
+
+ memset(pPage, 0, sizeof(*pPage));
+ pPage->pPager = pPager;
+ pPage->pSqlitePage = pSqlitePage;
+ pPage->pgno = pSqlitePage->pgno;
+ pPage->pData = pSqlitePage->pData;
+
+ *ppPage = pPage;
+ return SQLITE_OK;
+}
+
+static int pagerGetPage(RecoverPager *pPager, u32 iPage, RecoverPage **ppPage) {
+ DbPage *pSqlitePage;
+ int rc = sqlite3PagerGet(pPager->pSqlitePager, iPage, &pSqlitePage, 0);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+
+ rc = pageCreate(pPager, pSqlitePage, ppPage);
+ if( rc!=SQLITE_OK ){
+ sqlite3PagerUnref(pSqlitePage);
+ return rc;
+ }
+
+ return SQLITE_OK;
+}
+
/* For some reason I kept making mistakes with offset calculations. */
-static const unsigned char *PageData(DbPage *pPage, unsigned iOffset){
+static const unsigned char *PageData(RecoverPage *pPage, unsigned iOffset){
assert( iOffset<=pPage->nPageSize );
return (unsigned char *)pPage->pData + iOffset;
}
@@ -381,7 +455,7 @@ static const unsigned char *PageData(DbPage *pPage, unsigned iOffset){
* the offsets in the page's header information are relative to the
* beginning of the page, NOT the end of the page header.
*/
-static const unsigned char *PageHeader(DbPage *pPage){
+static const unsigned char *PageHeader(RecoverPage *pPage){
if( pPage->pgno==1 ){
const unsigned nDatabaseHeader = 100;
return PageData(pPage, nDatabaseHeader);
@@ -392,9 +466,10 @@ static const unsigned char *PageHeader(DbPage *pPage){
/* Helper to fetch the pager and page size for the named database. */
static int GetPager(sqlite3 *db, const char *zName,
- Pager **pPager, unsigned *pnPageSize){
+ RecoverPager **ppPager, unsigned *pnPageSize){
Btree *pBt = NULL;
- int i;
+ int i, rc;
+ RecoverPager *pPager;
for( i=0; i<db->nDb; ++i ){
if( ascii_strcasecmp(db->aDb[i].zName, zName)==0 ){
pBt = db->aDb[i].pBt;
@@ -405,7 +480,12 @@ static int GetPager(sqlite3 *db, const char *zName,
return SQLITE_ERROR;
}
- *pPager = sqlite3BtreePager(pBt);
+ rc = pagerCreate(sqlite3BtreePager(pBt), 0, &pPager);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+
+ *ppPager = pPager;
*pnPageSize =
sqlite3BtreeGetPageSize(pBt) - sqlite3BtreeGetOptimalReserve(pBt);
return SQLITE_OK;
@@ -431,7 +511,7 @@ static u32 SerialTypeLength(u64 iSerialType){
case 7 : return 8; /* 64-bit float. */
case 8 : return 0; /* Constant 0. */
case 9 : return 0; /* Constant 1. */
- case 10 : case 11 : assert( !"RESERVED TYPE"); return 0;
+ case 10 : case 11 : assert( "RESERVED TYPE"==NULL ); return 0;
}
return (u32)((iSerialType>>1) - 6);
}
@@ -457,8 +537,8 @@ static int SerialTypeIsCompatible(u64 iSerialType, unsigned char mask){
case 7 : return (mask&MASK_FLOAT)!=0;
case 8 : return (mask&MASK_INTEGER)!=0;
case 9 : return (mask&MASK_INTEGER)!=0;
- case 10 : assert( !"RESERVED TYPE"); return 0;
- case 11 : assert( !"RESERVED TYPE"); return 0;
+ case 10 : assert( "RESERVED TYPE"==NULL ); return 0;
+ case 11 : assert( "RESERVED TYPE"==NULL ); return 0;
}
return (mask&(SerialTypeIsBlob(iSerialType) ? MASK_BLOB : MASK_TEXT));
}
@@ -620,7 +700,7 @@ static int getEncoding(sqlite3 *db, const char *zDb, int* piEncoding){
typedef struct RecoverInteriorCursor RecoverInteriorCursor;
struct RecoverInteriorCursor {
RecoverInteriorCursor *pParent; /* Parent node to this node. */
- DbPage *pPage; /* Reference to leaf page. */
+ RecoverPage *pPage; /* Reference to leaf page. */
unsigned nPageSize; /* Size of page. */
unsigned nChildren; /* Number of children on the page. */
unsigned iChild; /* Index of next child to return. */
@@ -633,7 +713,7 @@ static void interiorCursorDestroy(RecoverInteriorCursor *pCursor){
pCursor = pCursor->pParent;
if( p->pPage ){
- sqlite3PagerUnref(p->pPage);
+ pageDestroy(p->pPage);
p->pPage = NULL;
}
@@ -644,13 +724,13 @@ static void interiorCursorDestroy(RecoverInteriorCursor *pCursor){
/* Internal helper. Reset storage in preparation for iterating pPage. */
static void interiorCursorSetPage(RecoverInteriorCursor *pCursor,
- DbPage *pPage){
+ RecoverPage *pPage){
const unsigned knMinCellLength = 2 + 4 + 1;
unsigned nMaxChildren;
assert( PageHeader(pPage)[kiPageTypeOffset]==kTableInteriorPage );
if( pCursor->pPage ){
- sqlite3PagerUnref(pCursor->pPage);
+ pageDestroy(pCursor->pPage);
pCursor->pPage = NULL;
}
pCursor->pPage = pPage;
@@ -681,7 +761,7 @@ static void interiorCursorSetPage(RecoverInteriorCursor *pCursor,
}
static int interiorCursorCreate(RecoverInteriorCursor *pParent,
- DbPage *pPage, int nPageSize,
+ RecoverPage *pPage, int nPageSize,
RecoverInteriorCursor **ppCursor){
RecoverInteriorCursor *pCursor =
sqlite3_malloc(sizeof(RecoverInteriorCursor));
@@ -766,7 +846,7 @@ static int interiorCursorPageInUse(RecoverInteriorCursor *pCursor,
* reverse the list during traversal.
*/
static int interiorCursorNextPage(RecoverInteriorCursor **ppCursor,
- DbPage **ppPage){
+ RecoverPage **ppPage){
RecoverInteriorCursor *pCursor = *ppCursor;
while( 1 ){
int rc;
@@ -779,7 +859,7 @@ static int interiorCursorNextPage(RecoverInteriorCursor **ppCursor,
if( interiorCursorPageInUse(pCursor, iPage) ){
fprintf(stderr, "Loop detected at %d\n", iPage);
}else{
- int rc = sqlite3PagerGet(pCursor->pPage->pPager, iPage, ppPage, 0);
+ int rc = pagerGetPage(pCursor->pPage->pPager, iPage, ppPage);
if( rc==SQLITE_OK ){
return SQLITE_ROW;
}
@@ -833,7 +913,7 @@ static int interiorCursorNextPage(RecoverInteriorCursor **ppCursor,
typedef struct RecoverOverflow RecoverOverflow;
struct RecoverOverflow {
RecoverOverflow *pNextOverflow;
- DbPage *pPage;
+ RecoverPage *pPage;
unsigned nPageSize;
};
@@ -843,7 +923,7 @@ static void overflowDestroy(RecoverOverflow *pOverflow){
pOverflow = p->pNextOverflow;
if( p->pPage ){
- sqlite3PagerUnref(p->pPage);
+ pageDestroy(p->pPage);
p->pPage = NULL;
}
@@ -870,7 +950,7 @@ static int overflowPageInUse(RecoverOverflow *pOverflow, unsigned iPage){
* overflowGetSegment() will do the right thing regardless of whether
* those values are set to be in-page or not.
*/
-static int overflowMaybeCreate(DbPage *pPage, unsigned nPageSize,
+static int overflowMaybeCreate(RecoverPage *pPage, unsigned nPageSize,
unsigned iRecordOffset, unsigned nRecordBytes,
unsigned *pnLocalRecordBytes,
RecoverOverflow **ppOverflow){
@@ -923,14 +1003,14 @@ static int overflowMaybeCreate(DbPage *pPage, unsigned nPageSize,
while( iNextPage && nBytes<nRecordBytes ){
RecoverOverflow *pOverflow; /* New overflow page for the list. */
- rc = sqlite3PagerGet(pPage->pPager, iNextPage, &pPage, 0);
+ rc = pagerGetPage(pPage->pPager, iNextPage, &pPage);
if( rc!=SQLITE_OK ){
break;
}
pOverflow = sqlite3_malloc(sizeof(RecoverOverflow));
if( !pOverflow ){
- sqlite3PagerUnref(pPage);
+ pageDestroy(pPage);
rc = SQLITE_NOMEM;
break;
}
@@ -994,7 +1074,7 @@ static int overflowMaybeCreate(DbPage *pPage, unsigned nPageSize,
* and overflow pages consistently by adjusting the values
* appropriately.
*/
-static int overflowGetSegment(DbPage *pPage, unsigned iRecordOffset,
+static int overflowGetSegment(RecoverPage *pPage, unsigned iRecordOffset,
unsigned nLocalRecordBytes,
RecoverOverflow *pOverflow,
unsigned iRequestOffset, unsigned nRequestBytes,
@@ -1101,7 +1181,8 @@ static int overflowGetSegment(DbPage *pPage, unsigned iRecordOffset,
typedef struct RecoverLeafCursor RecoverLeafCursor;
struct RecoverLeafCursor {
RecoverInteriorCursor *pParent; /* Parent node to this node. */
- DbPage *pPage; /* Reference to leaf page. */
+ RecoverPager *pPager; /* Page provider. */
+ RecoverPage *pPage; /* Current leaf page. */
unsigned nPageSize; /* Size of pPage. */
unsigned nCells; /* Number of cells in pPage. */
unsigned iCell; /* Current cell. */
@@ -1136,13 +1217,13 @@ struct RecoverLeafCursor {
* If SQLITE_OK is returned, the caller no longer owns pPage,
* otherwise the caller is responsible for discarding it.
*/
-static int leafCursorLoadPage(RecoverLeafCursor *pCursor, DbPage *pPage){
+static int leafCursorLoadPage(RecoverLeafCursor *pCursor, RecoverPage *pPage){
const unsigned char *pPageHeader; /* Header of *pPage */
unsigned nCells; /* Number of cells in the page */
/* Release the current page. */
if( pCursor->pPage ){
- sqlite3PagerUnref(pCursor->pPage);
+ pageDestroy(pCursor->pPage);
pCursor->pPage = NULL;
pCursor->iCell = pCursor->nCells = 0;
}
@@ -1164,14 +1245,14 @@ static int leafCursorLoadPage(RecoverLeafCursor *pCursor, DbPage *pPage){
/* Not a leaf page, skip it. */
if( pPageHeader[kiPageTypeOffset]!=kTableLeafPage ){
- sqlite3PagerUnref(pPage);
+ pageDestroy(pPage);
return SQLITE_OK;
}
/* Leaf contains no data, skip it. Empty tables, for instance. */
nCells = decodeUnsigned16(pPageHeader + kiPageCellCountOffset);;
if( nCells<1 ){
- sqlite3PagerUnref(pPage);
+ pageDestroy(pPage);
return SQLITE_OK;
}
@@ -1193,7 +1274,7 @@ static int leafCursorNextPage(RecoverLeafCursor *pCursor){
/* Repeatedly load the parent's next child page until a leaf is found. */
do {
- DbPage *pNextPage;
+ RecoverPage *pNextPage;
int rc = interiorCursorNextPage(&pCursor->pParent, &pNextPage);
if( rc!=SQLITE_ROW ){
assert( rc==SQLITE_DONE );
@@ -1202,7 +1283,7 @@ static int leafCursorNextPage(RecoverLeafCursor *pCursor){
rc = leafCursorLoadPage(pCursor, pNextPage);
if( rc!=SQLITE_OK ){
- sqlite3PagerUnref(pNextPage);
+ pageDestroy(pNextPage);
return rc;
}
} while( !pCursor->pPage );
@@ -1232,10 +1313,15 @@ static void leafCursorDestroy(RecoverLeafCursor *pCursor){
}
if( pCursor->pPage ){
- sqlite3PagerUnref(pCursor->pPage);
+ pageDestroy(pCursor->pPage);
pCursor->pPage = NULL;
}
+ if( pCursor->pPager ){
+ pagerDestroy(pCursor->pPager);
+ pCursor->pPager = NULL;
+ }
+
memset(pCursor, 0xA5, sizeof(*pCursor));
sqlite3_free(pCursor);
}
@@ -1253,30 +1339,31 @@ static void leafCursorDestroy(RecoverLeafCursor *pCursor){
* - pPage is a valid interior page who's leaves contain no valid cells.
* - pPage is not a valid leaf or interior page.
*/
-static int leafCursorCreate(Pager *pPager, unsigned nPageSize,
+static int leafCursorCreate(RecoverPager *pPager, unsigned nPageSize,
u32 iRootPage, RecoverLeafCursor **ppCursor){
- DbPage *pPage; /* Reference to page at iRootPage. */
+ RecoverPage *pPage; /* Reference to page at iRootPage. */
RecoverLeafCursor *pCursor; /* Leaf cursor being constructed. */
int rc;
/* Start out with the root page. */
- rc = sqlite3PagerGet(pPager, iRootPage, &pPage, 0);
+ rc = pagerGetPage(pPager, iRootPage, &pPage);
if( rc!=SQLITE_OK ){
return rc;
}
pCursor = sqlite3_malloc(sizeof(RecoverLeafCursor));
if( !pCursor ){
- sqlite3PagerUnref(pPage);
+ pageDestroy(pPage);
return SQLITE_NOMEM;
}
memset(pCursor, 0, sizeof(*pCursor));
pCursor->nPageSize = nPageSize;
+ pCursor->pPager = pPager;
rc = leafCursorLoadPage(pCursor, pPage);
if( rc!=SQLITE_OK ){
- sqlite3PagerUnref(pPage);
+ pageDestroy(pPage);
leafCursorDestroy(pCursor);
return rc;
}
@@ -1619,7 +1706,7 @@ static int recoverOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
u32 iRootPage; /* Root page of the backing table. */
int iEncoding; /* UTF encoding for backing database. */
unsigned nPageSize; /* Size of pages in backing database. */
- Pager *pPager; /* Backing database pager. */
+ RecoverPager *pPager; /* Backing database pager. */
RecoverLeafCursor *pLeafCursor; /* Cursor to read table's leaf pages. */
RecoverCursor *pCursor; /* Cursor to read rows from leaves. */
int rc;
@@ -1646,6 +1733,7 @@ static int recoverOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
rc = leafCursorCreate(pPager, nPageSize, iRootPage, &pLeafCursor);
if( rc!=SQLITE_OK ){
+ pagerDestroy(pPager);
return rc;
}
« no previous file with comments | « third_party/sqlite/amalgamation/sqlite3.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698