** Perform one step (sqlite3_recover_step()) of work for the connection ** passed as the only argument, which is guaranteed to be in ** RECOVER_STATE_WRITING state - during which tables recovered from the ** schema of the input database are populated with recovered data. */
| 15182 | ** schema of the input database are populated with recovered data. |
| 15183 | */ |
| 15184 | static int recoverWriteDataStep(sqlite3_recover *p){ |
| 15185 | RecoverStateW1 *p1 = &p->w1; |
| 15186 | sqlite3_stmt *pSel = p1->pSel; |
| 15187 | sqlite3_value **apVal = p1->apVal; |
| 15188 | |
| 15189 | if( p->errCode==SQLITE_OK && p1->pTab==0 ){ |
| 15190 | if( sqlite3_step(p1->pTbls)==SQLITE_ROW ){ |
| 15191 | i64 iRoot = sqlite3_column_int64(p1->pTbls, 0); |
| 15192 | p1->pTab = recoverFindTable(p, iRoot); |
| 15193 | |
| 15194 | recoverFinalize(p, p1->pInsert); |
| 15195 | p1->pInsert = 0; |
| 15196 | |
| 15197 | /* If this table is unknown, return early. The caller will invoke this |
| 15198 | ** function again and it will move on to the next table. */ |
| 15199 | if( p1->pTab==0 ) return p->errCode; |
| 15200 | |
| 15201 | /* If this is the sqlite_sequence table, delete any rows added by |
| 15202 | ** earlier INSERT statements on tables with AUTOINCREMENT primary |
| 15203 | ** keys before recovering its contents. The p1->pTbls SELECT statement |
| 15204 | ** is rigged to deliver "sqlite_sequence" last of all, so we don't |
| 15205 | ** worry about it being modified after it is recovered. */ |
| 15206 | if( sqlite3_stricmp("sqlite_sequence", p1->pTab->zTab)==0 ){ |
| 15207 | recoverExec(p, p->dbOut, "DELETE FROM sqlite_sequence"); |
| 15208 | recoverSqlCallback(p, "DELETE FROM sqlite_sequence"); |
| 15209 | } |
| 15210 | |
| 15211 | /* Bind the root page of this table within the original database to |
| 15212 | ** SELECT statement p1->pSel. The SELECT statement will then iterate |
| 15213 | ** through cells that look like they belong to table pTab. */ |
| 15214 | sqlite3_bind_int64(pSel, 1, iRoot); |
| 15215 | |
| 15216 | p1->nVal = 0; |
| 15217 | p1->bHaveRowid = 0; |
| 15218 | p1->iPrevPage = -1; |
| 15219 | p1->iPrevCell = -1; |
| 15220 | }else{ |
| 15221 | return SQLITE_DONE; |
| 15222 | } |
| 15223 | } |
| 15224 | assert( p->errCode!=SQLITE_OK || p1->pTab ); |
| 15225 | |
| 15226 | if( p->errCode==SQLITE_OK && sqlite3_step(pSel)==SQLITE_ROW ){ |
| 15227 | RecoverTable *pTab = p1->pTab; |
| 15228 | |
| 15229 | i64 iPage = sqlite3_column_int64(pSel, 0); |
| 15230 | int iCell = sqlite3_column_int(pSel, 1); |
| 15231 | int iField = sqlite3_column_int(pSel, 2); |
| 15232 | sqlite3_value *pVal = sqlite3_column_value(pSel, 3); |
| 15233 | int bNewCell = (p1->iPrevPage!=iPage || p1->iPrevCell!=iCell); |
| 15234 | |
| 15235 | assert( bNewCell==0 || (iField==-1 || iField==0) ); |
| 15236 | assert( bNewCell || iField==p1->nVal || p1->nVal==pTab->nCol ); |
| 15237 | |
| 15238 | if( bNewCell ){ |
| 15239 | int ii = 0; |
| 15240 | if( p1->nVal>=0 ){ |
| 15241 | if( p1->pInsert==0 || p1->nVal!=p1->nInsert ){ |
no test coverage detected