Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add additional error messages and a progress spinner to the ".clone" command. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | dd0db3f0cef1be46cea16d4e61ea3348 |
User & Date: | drh 2014-02-06 02:46:08 |
Context
2014-02-06
| ||
13:18 | Change the spellfix1 virtual table to deterministically names its shadow tables. check-in: 5219cdfc user: drh tags: trunk | |
02:46 | Add additional error messages and a progress spinner to the ".clone" command. check-in: dd0db3f0 user: drh tags: trunk | |
01:15 | Rename the '.repair' shell command to '.clone'. check-in: 4f9d9562 user: mistachkin tags: trunk | |
Changes
Changes to src/shell.c.
1539 1539 1540 1540 /* 1541 1541 ** Text of a help message 1542 1542 */ 1543 1543 static char zHelp[] = 1544 1544 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" 1545 1545 ".bail ON|OFF Stop after hitting an error. Default OFF\n" 1546 + ".clone NEWDB Clone data into NEWDB from the existing database\n" 1546 1547 ".databases List names and files of attached databases\n" 1547 1548 ".dump ?TABLE? ... Dump the database in an SQL text format\n" 1548 1549 " If TABLE specified, only dump tables matching\n" 1549 1550 " LIKE pattern TABLE.\n" 1550 1551 ".echo ON|OFF Turn command echo on or off\n" 1551 1552 ".exit Exit this program\n" 1552 1553 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n" ................................................................................ 1577 1578 ".open ?FILENAME? Close existing database and reopen FILENAME\n" 1578 1579 ".output FILENAME Send output to FILENAME\n" 1579 1580 ".output stdout Send output to the screen\n" 1580 1581 ".print STRING... Print literal STRING\n" 1581 1582 ".prompt MAIN CONTINUE Replace the standard prompts\n" 1582 1583 ".quit Exit this program\n" 1583 1584 ".read FILENAME Execute SQL in FILENAME\n" 1584 - ".clone NEWDB Clone data into NEWDB from the existing database\n" 1585 1585 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" 1586 1586 ".schema ?TABLE? Show the CREATE statements\n" 1587 1587 " If TABLE specified, only show tables matching\n" 1588 1588 " LIKE pattern TABLE.\n" 1589 1589 ".separator STRING Change separator used by output mode and .import\n" 1590 1590 ".show Show the current values for various settings\n" 1591 1591 ".stats ON|OFF Turn stats on or off\n" ................................................................................ 1894 1894 p->cTerm = c; 1895 1895 } 1896 1896 if( p->z ) p->z[p->n] = 0; 1897 1897 return p->z; 1898 1898 } 1899 1899 1900 1900 /* 1901 -** Try to transfer data for table zTable 1901 +** Try to transfer data for table zTable. If an error is seen while 1902 +** moving forward, try to go backwards. The backwards movement won't 1903 +** work for WITHOUT ROWID tables. 1902 1904 */ 1903 1905 static void tryToCloneData( 1904 1906 struct callback_data *p, 1905 1907 sqlite3 *newDb, 1906 1908 const char *zTable 1907 1909 ){ 1908 1910 sqlite3_stmt *pQuery = 0; ................................................................................ 1909 1911 sqlite3_stmt *pInsert = 0; 1910 1912 char *zQuery = 0; 1911 1913 char *zInsert = 0; 1912 1914 int rc; 1913 1915 int i, j, n; 1914 1916 int nTable = (int)strlen(zTable); 1915 1917 int k = 0; 1918 + int cnt = 0; 1919 + const int spinRate = 10000; 1916 1920 1917 1921 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable); 1918 1922 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); 1919 1923 if( rc ){ 1920 - fprintf(stderr, "Error: (%d) %s on [%s]\n", 1924 + fprintf(stderr, "Error %d: %s on [%s]\n", 1921 1925 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), 1922 1926 zQuery); 1923 1927 goto end_data_xfer; 1924 1928 } 1925 1929 n = sqlite3_column_count(pQuery); 1926 1930 zInsert = sqlite3_malloc(200 + nTable + n*3); 1927 1931 if( zInsert==0 ){ ................................................................................ 1934 1938 for(j=1; j<n; j++){ 1935 1939 memcpy(zInsert+i, ",?", 2); 1936 1940 i += 2; 1937 1941 } 1938 1942 memcpy(zInsert+i, ");", 3); 1939 1943 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0); 1940 1944 if( rc ){ 1941 - fprintf(stderr, "Error: (%d) %s on [%s]\n", 1945 + fprintf(stderr, "Error %d: %s on [%s]\n", 1942 1946 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), 1943 1947 zQuery); 1944 1948 goto end_data_xfer; 1945 1949 } 1946 1950 for(k=0; k<2; k++){ 1947 1951 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ 1948 1952 for(i=0; i<n; i++){ ................................................................................ 1969 1973 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i), 1970 1974 sqlite3_column_bytes(pQuery,i), 1971 1975 SQLITE_STATIC); 1972 1976 break; 1973 1977 } 1974 1978 } 1975 1979 } /* End for */ 1976 - sqlite3_step(pInsert); 1980 + rc = sqlite3_step(pInsert); 1981 + if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ 1982 + fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb), 1983 + sqlite3_errmsg(newDb)); 1984 + } 1977 1985 sqlite3_reset(pInsert); 1986 + cnt++; 1987 + if( (cnt%spinRate)==0 ){ 1988 + printf("%c\b", "|/-\\"[(cnt/spinRate)%4]); 1989 + fflush(stdout); 1990 + } 1978 1991 } /* End while */ 1979 1992 if( rc==SQLITE_DONE ) break; 1980 1993 sqlite3_finalize(pQuery); 1981 1994 sqlite3_free(zQuery); 1982 1995 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;", 1983 1996 zTable); 1984 1997 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); 1985 1998 if( rc ){ 1986 - fprintf(stderr, "Error: (%d) %s on [%s]\n", 1987 - sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), 1988 - zQuery); 1989 - goto end_data_xfer; 1999 + fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable); 2000 + break; 1990 2001 } 1991 2002 } /* End for(k=0...) */ 1992 2003 1993 2004 end_data_xfer: 1994 2005 sqlite3_finalize(pQuery); 1995 2006 sqlite3_finalize(pInsert); 1996 2007 sqlite3_free(zQuery); ................................................................................ 1997 2008 sqlite3_free(zInsert); 1998 2009 } 1999 2010 2000 2011 2001 2012 /* 2002 2013 ** Try to transfer all rows of the schema that match zWhere. For 2003 2014 ** each row, invoke xForEach() on the object defined by that row. 2015 +** If an error is encountered while moving forward through the 2016 +** sqlite_master table, try again moving backwards. 2004 2017 */ 2005 2018 static void tryToCloneSchema( 2006 2019 struct callback_data *p, 2007 2020 sqlite3 *newDb, 2008 2021 const char *zWhere, 2009 2022 void (*xForEach)(struct callback_data*,sqlite3*,const char*) 2010 2023 ){ 2011 2024 sqlite3_stmt *pQuery = 0; 2012 2025 char *zQuery = 0; 2013 2026 int rc; 2014 2027 const unsigned char *zName; 2015 2028 const unsigned char *zSql; 2029 + char *zErrMsg = 0; 2016 2030 2017 2031 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" 2018 2032 " WHERE %s", zWhere); 2019 2033 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); 2020 2034 if( rc ){ 2021 2035 fprintf(stderr, "Error: (%d) %s on [%s]\n", 2022 2036 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), ................................................................................ 2023 2037 zQuery); 2024 2038 goto end_schema_xfer; 2025 2039 } 2026 2040 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ 2027 2041 zName = sqlite3_column_text(pQuery, 0); 2028 2042 zSql = sqlite3_column_text(pQuery, 1); 2029 2043 printf("%s... ", zName); fflush(stdout); 2030 - sqlite3_exec(newDb, (const char*)zSql, 0, 0, 0); 2044 + sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); 2045 + if( zErrMsg ){ 2046 + fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); 2047 + sqlite3_free(zErrMsg); 2048 + zErrMsg = 0; 2049 + } 2031 2050 if( xForEach ){ 2032 2051 xForEach(p, newDb, (const char*)zName); 2033 2052 } 2034 2053 printf("done\n"); 2035 2054 } 2036 2055 if( rc!=SQLITE_DONE ){ 2037 2056 sqlite3_finalize(pQuery); ................................................................................ 2045 2064 zQuery); 2046 2065 goto end_schema_xfer; 2047 2066 } 2048 2067 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ 2049 2068 zName = sqlite3_column_text(pQuery, 0); 2050 2069 zSql = sqlite3_column_text(pQuery, 1); 2051 2070 printf("%s... ", zName); fflush(stdout); 2052 - sqlite3_exec(newDb, (const char*)zSql, 0, 0, 0); 2071 + sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); 2072 + if( zErrMsg ){ 2073 + fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); 2074 + sqlite3_free(zErrMsg); 2075 + zErrMsg = 0; 2076 + } 2053 2077 if( xForEach ){ 2054 2078 xForEach(p, newDb, (const char*)zName); 2055 2079 } 2056 2080 printf("done\n"); 2057 2081 } 2058 2082 } 2059 2083 end_schema_xfer: