Fossil

Diff
Login

Differences From Artifact [d1a2e5b594]:

To Artifact [3aca6e397d]:


12129
12130
12131
12132
12133
12134
12135


12136
12137
12138
12139
12140
12141
12142
  ".quit                    Exit this program",
  ".read FILE               Read input from FILE",
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
  ".recover                 Recover as much data as possible from corrupt db.",
  "   --freelist-corrupt       Assume the freelist is corrupt",
  "   --recovery-db NAME       Store recovery metadata in database file NAME",
  "   --lost-and-found TABLE   Alternative name for the lost-and-found table",


#endif
  ".restore ?DB? FILE       Restore content of DB (default \"main\") from FILE",
  ".save FILE               Write in-memory database into FILE",
  ".scanstats on|off        Turn sqlite3_stmt_scanstatus() metrics on or off",
  ".schema ?PATTERN?        Show the CREATE statements matching PATTERN",
  "     Options:",
  "         --indent            Try to pretty-print the schema",







>
>







12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139
12140
12141
12142
12143
12144
  ".quit                    Exit this program",
  ".read FILE               Read input from FILE",
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
  ".recover                 Recover as much data as possible from corrupt db.",
  "   --freelist-corrupt       Assume the freelist is corrupt",
  "   --recovery-db NAME       Store recovery metadata in database file NAME",
  "   --lost-and-found TABLE   Alternative name for the lost-and-found table",
  "   --no-rowids              Do not attempt to recover rowid values",
  "                            that are not also INTEGER PRIMARY KEYs",
#endif
  ".restore ?DB? FILE       Restore content of DB (default \"main\") from FILE",
  ".save FILE               Write in-memory database into FILE",
  ".scanstats on|off        Turn sqlite3_stmt_scanstatus() metrics on or off",
  ".schema ?PATTERN?        Show the CREATE statements matching PATTERN",
  "     Options:",
  "         --indent            Try to pretty-print the schema",
15133
15134
15135
15136
15137
15138
15139

15140
15141
15142
15143
15144
15145
15146
15147
15148
15149
15150
15151
15152
15153
15154



15155
15156
15157
15158
15159
15160
15161
  const char *zRecoveryDb = "";   /* Name of "recovery" database */
  const char *zLostAndFound = "lost_and_found";
  int i;
  int nOrphan = -1;
  RecoverTable *pOrphan = 0;

  int bFreelist = 1;              /* 0 if --freelist-corrupt is specified */

  for(i=1; i<nArg; i++){
    char *z = azArg[i];
    int n;
    if( z[0]=='-' && z[1]=='-' ) z++;
    n = strlen30(z);
    if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){
      bFreelist = 0;
    }else
    if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){
      i++;
      zRecoveryDb = azArg[i];
    }else
    if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
      i++;
      zLostAndFound = azArg[i];



    }
    else{
      utf8_printf(stderr, "unexpected option: %s\n", azArg[i]); 
      showHelp(pState->out, azArg[0]);
      return 1;
    }
  }







>















>
>
>







15135
15136
15137
15138
15139
15140
15141
15142
15143
15144
15145
15146
15147
15148
15149
15150
15151
15152
15153
15154
15155
15156
15157
15158
15159
15160
15161
15162
15163
15164
15165
15166
15167
  const char *zRecoveryDb = "";   /* Name of "recovery" database */
  const char *zLostAndFound = "lost_and_found";
  int i;
  int nOrphan = -1;
  RecoverTable *pOrphan = 0;

  int bFreelist = 1;              /* 0 if --freelist-corrupt is specified */
  int bRowids = 1;                /* 0 if --no-rowids */
  for(i=1; i<nArg; i++){
    char *z = azArg[i];
    int n;
    if( z[0]=='-' && z[1]=='-' ) z++;
    n = strlen30(z);
    if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){
      bFreelist = 0;
    }else
    if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){
      i++;
      zRecoveryDb = azArg[i];
    }else
    if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
      i++;
      zLostAndFound = azArg[i];
    }else
    if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
      bRowids = 0;
    }
    else{
      utf8_printf(stderr, "unexpected option: %s\n", azArg[i]); 
      showHelp(pState->out, azArg[0]);
      return 1;
    }
  }
15313
15314
15315
15316
15317
15318
15319

15320
15321


15322
15323
15324
15325
15326
15327
15328
  }
  shellFinalize(&rc, pLoop);
  pLoop = 0;

  shellPrepare(pState->db, &rc,
      "SELECT pgno FROM recovery.map WHERE root=?", &pPages
  );

  shellPrepare(pState->db, &rc,
      "SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')"


      ", min(field) "
      "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
      "GROUP BY cell", &pCells
  );

  /* Loop through each root page. */
  shellPrepare(pState->db, &rc, 







>

|
>
>







15319
15320
15321
15322
15323
15324
15325
15326
15327
15328
15329
15330
15331
15332
15333
15334
15335
15336
15337
  }
  shellFinalize(&rc, pLoop);
  pLoop = 0;

  shellPrepare(pState->db, &rc,
      "SELECT pgno FROM recovery.map WHERE root=?", &pPages
  );

  shellPrepare(pState->db, &rc,
      "SELECT max(field), group_concat(shell_escape_crnl(quote"
      "(case when (? AND field<0) then NULL else value end)"
      "), ', ')"
      ", min(field) "
      "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
      "GROUP BY cell", &pCells
  );

  /* Loop through each root page. */
  shellPrepare(pState->db, &rc, 
15349
15350
15351
15352
15353
15354
15355





15356
15357
15358
15359
15360
15361
15362
15363
15364
15365
15366
15367
      if( pTab==0 ) break;
    }

    if( 0==sqlite3_stricmp(pTab->zQuoted, "\"sqlite_sequence\"") ){
      raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
    }
    sqlite3_bind_int(pPages, 1, iRoot);





    sqlite3_bind_int(pCells, 2, pTab->iPk);

    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
      int iPgno = sqlite3_column_int(pPages, 0);
      sqlite3_bind_int(pCells, 1, iPgno);
      while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
        int nField = sqlite3_column_int(pCells, 0);
        int iMin = sqlite3_column_int(pCells, 2);
        const char *zVal = (const char*)sqlite3_column_text(pCells, 1);

        RecoverTable *pTab2 = pTab;
        if( pTab!=pOrphan && (iMin<0)!=bIntkey ){







>
>
>
>
>
|



|







15358
15359
15360
15361
15362
15363
15364
15365
15366
15367
15368
15369
15370
15371
15372
15373
15374
15375
15376
15377
15378
15379
15380
15381
      if( pTab==0 ) break;
    }

    if( 0==sqlite3_stricmp(pTab->zQuoted, "\"sqlite_sequence\"") ){
      raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
    }
    sqlite3_bind_int(pPages, 1, iRoot);
    if( bRowids==0 && pTab->iPk<0 ){
      sqlite3_bind_int(pCells, 1, 1);
    }else{
      sqlite3_bind_int(pCells, 1, 0);
    }
    sqlite3_bind_int(pCells, 3, pTab->iPk);

    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
      int iPgno = sqlite3_column_int(pPages, 0);
      sqlite3_bind_int(pCells, 2, iPgno);
      while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
        int nField = sqlite3_column_int(pCells, 0);
        int iMin = sqlite3_column_int(pCells, 2);
        const char *zVal = (const char*)sqlite3_column_text(pCells, 1);

        RecoverTable *pTab2 = pTab;
        if( pTab!=pOrphan && (iMin<0)!=bIntkey ){