Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | If errors are encountered while processing the ".dump" command in the command-line shell, print error messages as comments in the output and ROLLBACK at the end rather than committing. Ticket [ee19e690ec9a5a2] |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8a8dcd6bd043d82dc04b6ad0614c64d2 |
User & Date: | drh 2011-10-13 00:41:49.789 |
Context
2011-10-13
| ||
01:01 | Fix a harmless compiler warning introduced into os_unix.c by one of the recent changes. (check-in: 4bf4d5ebfb user: drh tags: trunk) | |
00:41 | If errors are encountered while processing the ".dump" command in the command-line shell, print error messages as comments in the output and ROLLBACK at the end rather than committing. Ticket [ee19e690ec9a5a2] (check-in: 8a8dcd6bd0 user: drh tags: trunk) | |
00:11 | Be sure to allocate plenty of space for error messages coming out of sqlite3_load_extension(), so that filenames and procedure names are not truncated. Ticket [7d32c69b50f89d] (check-in: af8bcdd951 user: drh tags: trunk) | |
Changes
Changes to src/shell.c.
︙ | ︙ | |||
403 404 405 406 407 408 409 410 411 412 413 414 415 416 | */ struct callback_data { sqlite3 *db; /* The database */ int echoOn; /* True to echo input commands */ int statsOn; /* True to display memory stats before each finalize */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ int mode; /* An output mode setting */ int writableSchema; /* True if PRAGMA writable_schema=ON */ int showHeader; /* True to show column names in List or Column mode */ char *zDestTable; /* Name of destination table when MODE_Insert */ char separator[20]; /* Separator character for MODE_List */ int colWidth[100]; /* Requested width of each column when in column mode*/ int actualWidth[100]; /* Actual width of each column */ | > | 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | */ struct callback_data { sqlite3 *db; /* The database */ int echoOn; /* True to echo input commands */ int statsOn; /* True to display memory stats before each finalize */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ int nErr; /* Number of errors seen */ int mode; /* An output mode setting */ int writableSchema; /* True if PRAGMA writable_schema=ON */ int showHeader; /* True to show column names in List or Column mode */ char *zDestTable; /* Name of destination table when MODE_Insert */ char separator[20]; /* Separator character for MODE_List */ int colWidth[100]; /* Requested width of each column when in column mode*/ int actualWidth[100]; /* Actual width of each column */ |
︙ | ︙ | |||
928 929 930 931 932 933 934 | ** Execute a query statement that has a single result column. Print ** that result column on a line by itself with a semicolon terminator. ** ** This is used, for example, to show the schema of the database by ** querying the SQLITE_MASTER table. */ static int run_table_dump_query( | | < | | | > > | | | > > > > > | 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 | ** Execute a query statement that has a single result column. Print ** that result column on a line by itself with a semicolon terminator. ** ** This is used, for example, to show the schema of the database by ** querying the SQLITE_MASTER table. */ static int run_table_dump_query( struct callback_data *p, /* Query context */ const char *zSelect, /* SELECT statement to extract content */ const char *zFirstRow /* Print before first row, if not NULL */ ){ sqlite3_stmt *pSelect; int rc; rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0); if( rc!=SQLITE_OK || !pSelect ){ fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db)); p->nErr++; return rc; } rc = sqlite3_step(pSelect); while( rc==SQLITE_ROW ){ if( zFirstRow ){ fprintf(p->out, "%s", zFirstRow); zFirstRow = 0; } fprintf(p->out, "%s;\n", sqlite3_column_text(pSelect, 0)); rc = sqlite3_step(pSelect); } rc = sqlite3_finalize(pSelect); if( rc!=SQLITE_OK ){ fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db)); p->nErr++; } return rc; } /* ** Allocate space and save off current error string. */ static char *save_err_msg( sqlite3 *db /* Database to query */ |
︙ | ︙ | |||
1274 1275 1276 1277 1278 1279 1280 | if( rc!=SQLITE_OK || nRow==0 ){ free(zSelect); return 1; } zSelect = appendText(zSelect, "|| ')' FROM ", 0); zSelect = appendText(zSelect, zTable, '"'); | | | | < > | > > > | > > | > > > > > > | 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 | if( rc!=SQLITE_OK || nRow==0 ){ free(zSelect); return 1; } zSelect = appendText(zSelect, "|| ')' FROM ", 0); zSelect = appendText(zSelect, zTable, '"'); rc = run_table_dump_query(p, zSelect, zPrepStmt); if( rc==SQLITE_CORRUPT ){ zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0); run_table_dump_query(p, zSelect, 0); } if( zSelect ) free(zSelect); } return 0; } /* ** Run zQuery. Use dump_callback() as the callback routine so that ** the contents of the query are output as SQL statements. ** ** 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 ){ int rc; char *zErr = 0; rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr); if( rc==SQLITE_CORRUPT ){ char *zQ2; int len = strlen30(zQuery); fprintf(p->out, "/****** CORRUPTION ERROR *******/\n"); if( zErr ){ fprintf(p->out, "/****** %s ******/\n", zErr); sqlite3_free(zErr); zErr = 0; } zQ2 = malloc( len+100 ); if( zQ2==0 ) return rc; sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery); rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); if( rc ){ fprintf(p->out, "/****** ERROR: %s ******/\n", zErr); }else{ rc = SQLITE_CORRUPT; } sqlite3_free(zErr); free(zQ2); } return rc; } /* ** Text of a help message |
︙ | ︙ | |||
1551 1552 1553 1554 1555 1556 1557 | fprintf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); rc = 1; } }else if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){ | < > | | | | | < < < < | < | 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 | fprintf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); rc = 1; } }else if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){ open_db(p); /* When playing back a "dump", the content might appear in an order ** which causes immediate foreign key constraints to be violated. ** So disable foreign-key constraint enforcement to prevent problems. */ fprintf(p->out, "PRAGMA foreign_keys=OFF;\n"); fprintf(p->out, "BEGIN TRANSACTION;\n"); p->writableSchema = 0; sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0); p->nErr = 0; if( nArg==1 ){ run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" ); run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE name=='sqlite_sequence'" ); run_table_dump_query(p, "SELECT sql FROM sqlite_master " "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 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"); run_table_dump_query(p, "SELECT sql FROM sqlite_master " "WHERE sql NOT NULL" " AND type IN ('index','trigger','view')" " AND tbl_name LIKE shellstatic()", 0 ); zShellStatic = 0; } } if( p->writableSchema ){ fprintf(p->out, "PRAGMA writable_schema=OFF;\n"); p->writableSchema = 0; } sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0); fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); }else if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){ p->echoOn = booleanValue(azArg[1]); }else if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){ |
︙ | ︙ |