Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Modify the sqlite shell program so that the ".dump" command does not give up if it encounters an SQLITE_CORRUPT error. It tries to keep going in order to extract as much information as it can from the corrupt database. (CVS 1919) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d3f3acb77f4e9f597af5afac565916b9 |
User & Date: | drh 2004-08-30 01:54:05.000 |
Context
2004-08-30
| ||
14:22 | Remove the \001 character that lemon inserts automatically in its output file. The need for this character has expired and it creates confusion for users. Ticket #877 (CVS 1920) (check-in: acfc59186a user: drh tags: trunk) | |
01:54 | Modify the sqlite shell program so that the ".dump" command does not give up if it encounters an SQLITE_CORRUPT error. It tries to keep going in order to extract as much information as it can from the corrupt database. (CVS 1919) (check-in: d3f3acb77f user: drh tags: trunk) | |
2004-08-29
| ||
23:42 | Change the name of the global variable to sqlite3_temp_directory to avoid a naming conflict with version 2.8. (CVS 1918) (check-in: 431f7436a6 user: drh tags: trunk) | |
Changes
Changes to src/shell.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** ** $Id: shell.c,v 1.112 2004/08/30 01:54:05 drh Exp $ */ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <assert.h> #include "sqlite3.h" #include <ctype.h> |
︙ | ︙ | |||
551 552 553 554 555 556 557 558 559 560 561 562 563 564 | }else{ memcpy(&zIn[nIn], zAppend, nAppend); zIn[len-1] = '\0'; } return zIn; } /* ** This is a different callback routine used for dumping the database. ** Each row received by this callback consists of a table name, ** the table type ("index" or "table") and SQL to create the table. ** This routine should print text sufficient to recreate the table. */ | > > > > > > > > > > > > > > > > > > > > > | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 | }else{ memcpy(&zIn[nIn], zAppend, nAppend); zIn[len-1] = '\0'; } return zIn; } /* ** Execute a query statement that has a single result column. Print ** that result column on a line by itself with a semicolon terminator. */ static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){ sqlite3_stmt *pSelect; int rc; rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0); if( rc!=SQLITE_OK || !pSelect ){ return rc; } rc = sqlite3_step(pSelect); while( rc==SQLITE_ROW ){ fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0)); rc = sqlite3_step(pSelect); } return sqlite3_finalize(pSelect); } /* ** This is a different callback routine used for dumping the database. ** Each row received by this callback consists of a table name, ** the table type ("index" or "table") and SQL to create the table. ** This routine should print text sufficient to recreate the table. */ |
︙ | ︙ | |||
574 575 576 577 578 579 580 | zType = azArg[1]; zSql = azArg[2]; fprintf(p->out, "%s;\n", zSql); if( strcmp(zType, "table")==0 ){ sqlite3_stmt *pTableInfo = 0; | < | 595 596 597 598 599 600 601 602 603 604 605 606 607 608 | zType = azArg[1]; zSql = azArg[2]; fprintf(p->out, "%s;\n", zSql); if( strcmp(zType, "table")==0 ){ sqlite3_stmt *pTableInfo = 0; char *zSelect = 0; char *zTableInfo = 0; char *zTmp = 0; zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0); zTableInfo = appendText(zTableInfo, zTable, '"'); zTableInfo = appendText(zTableInfo, ");", 0); |
︙ | ︙ | |||
614 615 616 617 618 619 620 | if( rc!=SQLITE_OK ){ if( zSelect ) free(zSelect); return 1; } zSelect = appendText(zSelect, "|| ')' FROM ", 0); zSelect = appendText(zSelect, zTable, '"'); | < < < < < | < | | | | > | > > > > > > > > > > > > > > > > > > > > > > > | | 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 | if( rc!=SQLITE_OK ){ if( zSelect ) free(zSelect); return 1; } zSelect = appendText(zSelect, "|| ')' FROM ", 0); zSelect = appendText(zSelect, zTable, '"'); rc = run_table_dump_query(p->out, p->db, zSelect); if( rc==SQLITE_CORRUPT ){ zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0); rc = run_table_dump_query(p->out, p->db, zSelect); } if( zSelect ) free(zSelect); if( rc!=SQLITE_OK ){ return 1; } } return 0; } /* ** Run zQuery. Update dump_callback() as the callback routine. ** If we get a SQLITE_CORRUPT error, rerun the query after appending ** "ORDER BY rowid DESC" to the end. */ static int run_schema_dump_query( struct callback_data *p, const char *zQuery, char **pzErrMsg ){ int rc; rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg); if( rc==SQLITE_CORRUPT ){ char *zQ2; int len = strlen(zQuery); if( pzErrMsg ) sqlite3_free(*pzErrMsg); zQ2 = malloc( len+100 ); if( zQ2==0 ) return rc; sprintf(zQ2, "%s ORDER BY rowid DESC", zQuery); rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg); free(zQ2); } return rc; } /* ** Text of a help message */ static char zHelp[] = ".databases List names and files of attached databases\n" ".dump ?TABLE? ... Dump the database in an SQL text format\n" |
︙ | ︙ | |||
795 796 797 798 799 800 801 | }else if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ char *zErrMsg = 0; open_db(p); fprintf(p->out, "BEGIN TRANSACTION;\n"); if( nArg==1 ){ | | | | | > > | | | | | < > > > | 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 | }else if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ char *zErrMsg = 0; open_db(p); fprintf(p->out, "BEGIN TRANSACTION;\n"); if( nArg==1 ){ run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE sql NOT NULL AND type=='table'", 0 ); run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE sql NOT NULL AND type!='table' AND type!='meta'", 0 ); }else{ int i; for(i=1; i<nArg; i++){ zShellStatic = azArg[i]; run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE tbl_name LIKE shellstatic() AND type=='table'" " AND sql NOT NULL", 0); run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE tbl_name LIKE shellstatic() AND type!='table'" " AND type!='meta' AND sql NOT NULL", 0); zShellStatic = 0; } } if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ |
︙ | ︙ |