00001
00183 #ifdef STANDALONE
00184 #include <sqlite3.h>
00185 #define sqlite3_api_routines void
00186 #else
00187 #include <sqlite3ext.h>
00188 static SQLITE_EXTENSION_INIT1
00189 #endif
00190
00191 #include <stdlib.h>
00192 #include <string.h>
00193 #include <stdio.h>
00194 #include <stddef.h>
00195
00196 #ifdef _WIN32
00197 #include <windows.h>
00198 #define strcasecmp _stricmp
00199 #define strncasecmp _strnicmp
00200 #else
00201 #include <unistd.h>
00202 #endif
00203
00204 #include "impexp.h"
00205
00212 typedef struct {
00213 impexp_putc pfunc;
00214 void *parg;
00215 } json_pfs;
00216
00217 static const char space_chars[] = " \f\n\r\t\v";
00218
00219 #define ISSPACE(c) ((c) && (strchr(space_chars, (c)) != 0))
00220
00228 static char *
00229 one_input_line(FILE *fin)
00230 {
00231 char *line, *tmp;
00232 int nline;
00233 int n;
00234 int eol;
00235
00236 nline = 256;
00237 line = sqlite3_malloc(nline);
00238 if (!line) {
00239 return 0;
00240 }
00241 n = 0;
00242 eol = 0;
00243 while (!eol) {
00244 if (n + 256 > nline) {
00245 nline = nline * 2 + 256;
00246 tmp = sqlite3_realloc(line, nline);
00247 if (!tmp) {
00248 sqlite3_free(line);
00249 return 0;
00250 }
00251 line = tmp;
00252 }
00253 if (!fgets(line + n, nline - n, fin)) {
00254 if (n == 0) {
00255 sqlite3_free(line);
00256 return 0;
00257 }
00258 line[n] = 0;
00259 eol = 1;
00260 break;
00261 }
00262 while (line[n]) {
00263 n++;
00264 }
00265 if ((n > 0) && (line[n-1] == '\n')) {
00266 n--;
00267 line[n] = 0;
00268 eol = 1;
00269 }
00270 }
00271 tmp = sqlite3_realloc(line, n + 1);
00272 if (!tmp) {
00273 sqlite3_free(line);
00274 }
00275 return tmp;
00276 }
00277
00285 static int
00286 ends_with_semicolon(const char *str, int n)
00287 {
00288 while ((n > 0) && ISSPACE(str[n - 1])) {
00289 n--;
00290 }
00291 return (n > 0) && (str[n - 1] == ';');
00292 }
00293
00300 static int
00301 all_whitespace(const char *str)
00302 {
00303 for (; str[0]; str++) {
00304 if (ISSPACE(str[0])) {
00305 continue;
00306 }
00307 if ((str[0] == '/') && (str[1] == '*')) {
00308 str += 2;
00309 while (str[0] && ((str[0] != '*') || (str[1] != '/'))) {
00310 str++;
00311 }
00312 if (!str[0]) {
00313 return 0;
00314 }
00315 str++;
00316 continue;
00317 }
00318 if ((str[0] == '-') && (str[1] == '-')) {
00319 str += 2;
00320 while (str[0] && (str[0] != '\n')) {
00321 str++;
00322 }
00323 if (!str[0]) {
00324 return 1;
00325 }
00326 continue;
00327 }
00328 return 0;
00329 }
00330 return 1;
00331 }
00332
00340 static int
00341 process_input(sqlite3 *db, FILE *fin)
00342 {
00343 char *line = 0;
00344 char *sql = 0;
00345 int nsql = 0;
00346 int rc;
00347 int errors = 0;
00348
00349 while (1) {
00350 line = one_input_line(fin);
00351 if (!line) {
00352 break;
00353 }
00354 if ((!sql || !sql[0]) && all_whitespace(line)) {
00355 continue;
00356 }
00357 if (!sql) {
00358 int i;
00359 for (i = 0; line[i] && ISSPACE(line[i]); i++) {
00360
00361 }
00362 if (line[i]) {
00363 nsql = strlen(line);
00364 sql = sqlite3_malloc(nsql + 1);
00365 if (!sql) {
00366 errors++;
00367 break;
00368 }
00369 strcpy(sql, line);
00370 }
00371 } else {
00372 int len = strlen(line);
00373 char *tmp;
00374
00375 tmp = sqlite3_realloc(sql, nsql + len + 2);
00376 if (!tmp) {
00377 errors++;
00378 break;
00379 }
00380 sql = tmp;
00381 strcpy(sql + nsql, "\n");
00382 nsql++;
00383 strcpy(sql + nsql, line);
00384 nsql += len;
00385 }
00386 sqlite3_free(line);
00387 line = 0;
00388 if (sql && ends_with_semicolon(sql, nsql) && sqlite3_complete(sql)) {
00389 rc = sqlite3_exec(db, sql, 0, 0, 0);
00390 if (rc != SQLITE_OK) {
00391 errors++;
00392 }
00393 sqlite3_free(sql);
00394 sql = 0;
00395 nsql = 0;
00396 }
00397 }
00398 if (sql) {
00399 sqlite3_free(sql);
00400 }
00401 if (line) {
00402 sqlite3_free(line);
00403 }
00404 return errors;
00405 }
00406
00419 static void
00420 quote_func(sqlite3_context *context, int argc, sqlite3_value **argv)
00421 {
00422 int mode = 0;
00423
00424 if (argc < 1) {
00425 return;
00426 }
00427 if (argc > 1) {
00428 mode = sqlite3_value_int(argv[1]);
00429 }
00430 switch (sqlite3_value_type(argv[0])) {
00431 case SQLITE_NULL: {
00432 sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
00433 break;
00434 }
00435 case SQLITE_INTEGER:
00436 case SQLITE_FLOAT: {
00437 sqlite3_result_value(context, argv[0]);
00438 break;
00439 }
00440 case SQLITE_BLOB: {
00441 char *text = 0;
00442 unsigned char *blob = (unsigned char *) sqlite3_value_blob(argv[0]);
00443 int nblob = sqlite3_value_bytes(argv[0]);
00444
00445 if (2 * nblob + 4 > 1000000000) {
00446 sqlite3_result_error(context, "value too large", -1);
00447 return;
00448 }
00449 text = (char *) sqlite3_malloc((2 * nblob) + 4);
00450 if (!text) {
00451 sqlite3_result_error(context, "out of memory", -1);
00452 } else {
00453 int i, k = 0;
00454 static const char xdigits[] = "0123456789ABCDEF";
00455
00456 if (mode == 1) {
00457
00458 text[k++] = '\'';
00459 } else if (mode == 2) {
00460
00461 text[k++] = '0';
00462 text[k++] = 'x';
00463 } else if (mode == 3) {
00464
00465 text[k++] = 'x';
00466 text[k++] = '\'';
00467 } else {
00468
00469 text[k++] = 'X';
00470 text[k++] = '\'';
00471 }
00472 for (i = 0; i < nblob; i++) {
00473 text[k++] = xdigits[(blob[i] >> 4 ) & 0x0F];
00474 text[k++] = xdigits[blob[i] & 0x0F];
00475 }
00476 if (mode == 1) {
00477
00478 text[k++] = '\'';
00479 } else if (mode == 2) {
00480
00481 } else if (mode == 3) {
00482
00483 text[k++] = '\'';
00484 } else {
00485
00486 text[k++] = '\'';
00487 }
00488 text[k] = '\0';
00489 sqlite3_result_text(context, text, k, SQLITE_TRANSIENT);
00490 sqlite3_free(text);
00491 }
00492 break;
00493 }
00494 case SQLITE_TEXT: {
00495 int i, n;
00496 const unsigned char *arg = sqlite3_value_text(argv[0]);
00497 char *p;
00498
00499 if (!arg) {
00500 return;
00501 }
00502 for (i = 0, n = 0; arg[i]; i++) {
00503 if (arg[i] == '\'') {
00504 n++;
00505 }
00506 }
00507 if (i + n + 3 > 1000000000) {
00508 sqlite3_result_error(context, "value too large", -1);
00509 return;
00510 }
00511 p = sqlite3_malloc(i + n + 3);
00512 if (!p) {
00513 sqlite3_result_error(context, "out of memory", -1);
00514 return;
00515 }
00516 p[0] = '\'';
00517 for (i = 0, n = 1; arg[i]; i++) {
00518 p[n++] = arg[i];
00519 if (arg[i] == '\'') {
00520 p[n++] = '\'';
00521 }
00522 }
00523 p[n++] = '\'';
00524 p[n] = 0;
00525 sqlite3_result_text(context, p, n, SQLITE_TRANSIENT);
00526 sqlite3_free(p);
00527 break;
00528 }
00529 }
00530 }
00531
00539 static void
00540 quote_csv_func(sqlite3_context *context, int argc, sqlite3_value **argv)
00541 {
00542 if (argc < 1) {
00543 return;
00544 }
00545 switch (sqlite3_value_type(argv[0])) {
00546 case SQLITE_NULL: {
00547 sqlite3_result_text(context, "", 0, SQLITE_STATIC);
00548 break;
00549 }
00550 case SQLITE_INTEGER:
00551 case SQLITE_FLOAT: {
00552 sqlite3_result_value(context, argv[0]);
00553 break;
00554 }
00555 case SQLITE_BLOB: {
00556 char *text = 0;
00557 unsigned char *blob = (unsigned char *) sqlite3_value_blob(argv[0]);
00558 int nblob = sqlite3_value_bytes(argv[0]);
00559
00560 if (2 * nblob + 4 > 1000000000) {
00561 sqlite3_result_error(context, "value too large", -1);
00562 return;
00563 }
00564 text = (char *) sqlite3_malloc((2 * nblob) + 4);
00565 if (!text) {
00566 sqlite3_result_error(context, "out of memory", -1);
00567 } else {
00568 int i, k = 0;
00569 static const char xdigits[] = "0123456789ABCDEF";
00570
00571 text[k++] = '"';
00572 for (i = 0; i < nblob; i++) {
00573 text[k++] = xdigits[(blob[i] >> 4 ) & 0x0F];
00574 text[k++] = xdigits[blob[i] & 0x0F];
00575 }
00576 text[k++] = '"';
00577 text[k] = '\0';
00578 sqlite3_result_text(context, text, k, SQLITE_TRANSIENT);
00579 sqlite3_free(text);
00580 }
00581 break;
00582 }
00583 case SQLITE_TEXT: {
00584 int i, n;
00585 const unsigned char *arg = sqlite3_value_text(argv[0]);
00586 char *p;
00587
00588 if (!arg) {
00589 return;
00590 }
00591 for (i = 0, n = 0; arg[i]; i++) {
00592 if (arg[i] == '"') {
00593 n++;
00594 }
00595 }
00596 if (i + n + 3 > 1000000000) {
00597 sqlite3_result_error(context, "value too large", -1);
00598 return;
00599 }
00600 p = sqlite3_malloc(i + n + 3);
00601 if (!p) {
00602 sqlite3_result_error(context, "out of memory", -1);
00603 return;
00604 }
00605 p[0] = '"';
00606 for (i = 0, n = 1; arg[i]; i++) {
00607 p[n++] = arg[i];
00608 if (arg[i] == '"') {
00609 p[n++] = '"';
00610 }
00611 }
00612 p[n++] = '"';
00613 p[n] = 0;
00614 sqlite3_result_text(context, p, n, SQLITE_TRANSIENT);
00615 sqlite3_free(p);
00616 break;
00617 }
00618 }
00619 }
00620
00628 static void
00629 indent_xml_func(sqlite3_context *context, int argc, sqlite3_value **argv)
00630 {
00631 static const char spaces[] = " ";
00632 int n = 0;
00633
00634 if (argc > 0) {
00635 n = sqlite3_value_int(argv[0]);
00636 if (n > 32) {
00637 n = 32;
00638 } else if (n < 0) {
00639 n = 0;
00640 }
00641 }
00642 sqlite3_result_text(context, spaces, n, SQLITE_STATIC);
00643 }
00644
00652 static void
00653 quote_xml_func(sqlite3_context *context, int argc, sqlite3_value **argv)
00654 {
00655 static const char xdigits[] = "0123456789ABCDEF";
00656 int type, addtype = 0;
00657
00658 if (argc < 1) {
00659 return;
00660 }
00661 if (argc > 1) {
00662 addtype = sqlite3_value_int(argv[1]);
00663 }
00664 type = sqlite3_value_type(argv[0]);
00665 switch (type) {
00666 case SQLITE_NULL: {
00667 if (addtype > 0) {
00668 sqlite3_result_text(context, " TYPE=\"NULL\">", -1, SQLITE_STATIC);
00669 } else {
00670 sqlite3_result_text(context, "", 0, SQLITE_STATIC);
00671 }
00672 break;
00673 }
00674 case SQLITE_INTEGER:
00675 case SQLITE_FLOAT: {
00676 if (addtype > 0) {
00677 char *text = (char *) sqlite3_malloc(128);
00678 int k;
00679
00680 if (!text) {
00681 sqlite3_result_error(context, "out of memory", -1);
00682 return;
00683 }
00684 strcpy(text, (type == SQLITE_FLOAT) ? " TYPE=\"REAL\">" :
00685 " TYPE=\"INTEGER\">");
00686 k = strlen(text);
00687 strcpy(text + k, (char *) sqlite3_value_text(argv[0]));
00688 k = strlen(text);
00689 sqlite3_result_text(context, text, k, SQLITE_TRANSIENT);
00690 sqlite3_free(text);
00691 } else {
00692 sqlite3_result_value(context, argv[0]);
00693 }
00694 break;
00695 }
00696 case SQLITE_BLOB: {
00697 char *text = 0;
00698 unsigned char *blob = (unsigned char *) sqlite3_value_blob(argv[0]);
00699 int nblob = sqlite3_value_bytes(argv[0]);
00700 int i, k = 0;
00701
00702 if (6 * nblob + 34 > 1000000000) {
00703 sqlite3_result_error(context, "value too large", -1);
00704 return;
00705 }
00706 text = (char *) sqlite3_malloc((6 * nblob) + 34);
00707 if (!text) {
00708 sqlite3_result_error(context, "out of memory", -1);
00709 return;
00710 }
00711 if (addtype > 0) {
00712 strcpy(text, " TYPE=\"BLOB\">");
00713 k = strlen(text);
00714 }
00715 for (i = 0; i < nblob; i++) {
00716 text[k++] = '&';
00717 text[k++] = '#';
00718 text[k++] = 'x';
00719 text[k++] = xdigits[(blob[i] >> 4 ) & 0x0F];
00720 text[k++] = xdigits[blob[i] & 0x0F];
00721 text[k++] = ';';
00722 }
00723 text[k] = '\0';
00724 sqlite3_result_text(context, text, k, SQLITE_TRANSIENT);
00725 sqlite3_free(text);
00726 break;
00727 }
00728 case SQLITE_TEXT: {
00729 int i, n;
00730 const unsigned char *arg = sqlite3_value_text(argv[0]);
00731 char *p;
00732
00733 if (!arg) {
00734 return;
00735 }
00736 for (i = 0, n = 0; arg[i]; i++) {
00737 if ((arg[i] == '"') || (arg[i] == '\'') ||
00738 (arg[i] == '<') || (arg[i] == '>') ||
00739 (arg[i] == '&') || (arg[i] < ' ')) {
00740 n += 5;
00741 }
00742 }
00743 if (i + n + 32 > 1000000000) {
00744 sqlite3_result_error(context, "value too large", -1);
00745 return;
00746 }
00747 p = sqlite3_malloc(i + n + 32);
00748 if (!p) {
00749 sqlite3_result_error(context, "out of memory", -1);
00750 return;
00751 }
00752 n = 0;
00753 if (addtype > 0) {
00754 strcpy(p, " TYPE=\"TEXT\">");
00755 n = strlen(p);
00756 }
00757 for (i = 0; arg[i]; i++) {
00758 if (arg[i] == '"') {
00759 p[n++] = '&';
00760 p[n++] = 'q';
00761 p[n++] = 'u';
00762 p[n++] = 'o';
00763 p[n++] = 't';
00764 p[n++] = ';';
00765 } else if (arg[i] == '\'') {
00766 p[n++] = '&';
00767 p[n++] = 'a';
00768 p[n++] = 'p';
00769 p[n++] = 'o';
00770 p[n++] = 's';
00771 p[n++] = ';';
00772 } else if (arg[i] == '<') {
00773 p[n++] = '&';
00774 p[n++] = 'l';
00775 p[n++] = 't';
00776 p[n++] = ';';
00777 } else if (arg[i] == '>') {
00778 p[n++] = '&';
00779 p[n++] = 'g';
00780 p[n++] = 't';
00781 p[n++] = ';';
00782 } else if (arg[i] == '&') {
00783 p[n++] = '&';
00784 p[n++] = 'a';
00785 p[n++] = 'm';
00786 p[n++] = 'p';
00787 p[n++] = ';';
00788 } else if (arg[i] < ' ') {
00789 p[n++] = '&';
00790 p[n++] = '#';
00791 p[n++] = 'x';
00792 p[n++] = xdigits[(arg[i] >> 4 ) & 0x0F];
00793 p[n++] = xdigits[arg[i] & 0x0F];
00794 p[n++] = ';';
00795 } else if (addtype < 0 && (arg[i] == ' ')) {
00796 p[n++] = '&';
00797 p[n++] = '#';
00798 p[n++] = 'x';
00799 p[n++] = xdigits[(arg[i] >> 4 ) & 0x0F];
00800 p[n++] = xdigits[arg[i] & 0x0F];
00801 p[n++] = ';';
00802 } else {
00803 p[n++] = arg[i];
00804 }
00805 }
00806 p[n] = '\0';
00807 sqlite3_result_text(context, p, n, SQLITE_TRANSIENT);
00808 sqlite3_free(p);
00809 break;
00810 }
00811 }
00812 }
00813
00821 static void
00822 import_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
00823 {
00824 sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx);
00825 int changes0 = sqlite3_changes(db);
00826 char *filename = 0;
00827 FILE *fin;
00828 #ifdef _WIN32
00829 char fnbuf[MAX_PATH];
00830 #endif
00831
00832 if (nargs > 0) {
00833 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
00834 filename = (char *) sqlite3_value_text(args[0]);
00835 }
00836 }
00837 #ifdef _WIN32
00838 if (!filename) {
00839 OPENFILENAME ofn;
00840
00841 memset(&ofn, 0, sizeof (ofn));
00842 memset(fnbuf, 0, sizeof (fnbuf));
00843 ofn.lStructSize = sizeof (ofn);
00844 ofn.lpstrFile = fnbuf;
00845 ofn.nMaxFile = MAX_PATH;
00846 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST |
00847 OFN_EXPLORER | OFN_PATHMUSTEXIST;
00848 if (GetOpenFileName(&ofn)) {
00849 filename = fnbuf;
00850 }
00851 }
00852 #endif
00853 if (!filename) {
00854 goto done;
00855 }
00856 fin = fopen(filename, "r");
00857 if (!fin) {
00858 goto done;
00859 }
00860 process_input(db, fin);
00861 fclose(fin);
00862 done:
00863 sqlite3_result_int(ctx, sqlite3_changes(db) - changes0);
00864 }
00865
00866
00867
00868 int
00869 impexp_import_sql(sqlite3 *db, char *filename)
00870 {
00871 int changes0;
00872 FILE *fin;
00873 #ifdef _WIN32
00874 char fnbuf[MAX_PATH];
00875 #endif
00876
00877 if (!db) {
00878 return 0;
00879 }
00880 changes0 = sqlite3_changes(db);
00881 #ifdef _WIN32
00882 if (!filename) {
00883 OPENFILENAME ofn;
00884
00885 memset(&ofn, 0, sizeof (ofn));
00886 memset(fnbuf, 0, sizeof (fnbuf));
00887 ofn.lStructSize = sizeof (ofn);
00888 ofn.lpstrFile = fnbuf;
00889 ofn.nMaxFile = MAX_PATH;
00890 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST |
00891 OFN_EXPLORER | OFN_PATHMUSTEXIST;
00892 if (GetOpenFileName(&ofn)) {
00893 filename = fnbuf;
00894 }
00895 }
00896 #endif
00897 if (!filename) {
00898 goto done;
00899 }
00900 fin = fopen(filename, "r");
00901 if (!fin) {
00902 goto done;
00903 }
00904 process_input(db, fin);
00905 fclose(fin);
00906 done:
00907 return sqlite3_changes(db) - changes0;
00908 }
00909
00916 typedef struct {
00917 sqlite3 *db;
00918 int with_schema;
00919 int quote_mode;
00920 char *where;
00921 int nlines;
00922 int indent;
00923 FILE *out;
00924 } DUMP_DATA;
00925
00931 static void
00932 indent(DUMP_DATA *dd)
00933 {
00934 int i;
00935
00936 for (i = 0; i < dd->indent; i++) {
00937 fputc(' ', dd->out);
00938 }
00939 }
00940
00951 static int
00952 table_dump(DUMP_DATA *dd, char **errp, int fmt, const char *query, ...)
00953 {
00954 sqlite3_stmt *select = 0;
00955 int rc;
00956 const char *rest, *q = query;
00957 va_list ap;
00958
00959 if (errp && *errp) {
00960 sqlite3_free(*errp);
00961 *errp = 0;
00962 }
00963 if (fmt) {
00964 va_start(ap, query);
00965 q = sqlite3_vmprintf(query, ap);
00966 va_end(ap);
00967 if (!q) {
00968 return SQLITE_NOMEM;
00969 }
00970 }
00971 #if defined(HAVE_SQLITE3PREPAREV2) && HAVE_SQLITE3PREPAREV2
00972 rc = sqlite3_prepare_v2(dd->db, q, -1, &select, &rest);
00973 #else
00974 rc = sqlite3_prepare(dd->db, q, -1, &select, &rest);
00975 #endif
00976 if (fmt) {
00977 sqlite3_free((char *) q);
00978 }
00979 if ((rc != SQLITE_OK) || !select) {
00980 return rc;
00981 }
00982 rc = sqlite3_step(select);
00983 while (rc == SQLITE_ROW) {
00984 if (fputs((char *) sqlite3_column_text(select, 0), dd->out) > 0) {
00985 dd->nlines++;
00986 }
00987 if (dd->quote_mode >= 0) {
00988 fputc(';', dd->out);
00989 }
00990 if (dd->quote_mode == -1) {
00991 fputc('\r', dd->out);
00992 }
00993 if (dd->quote_mode >= -1) {
00994 fputc('\n', dd->out);
00995 }
00996 rc = sqlite3_step(select);
00997 }
00998 rc = sqlite3_finalize(select);
00999 if (rc != SQLITE_OK) {
01000 if (errp) {
01001 *errp = sqlite3_mprintf("%s", sqlite3_errmsg(dd->db));
01002 }
01003 }
01004 return rc;
01005 }
01006
01012 static void
01013 append_free(char **in)
01014 {
01015 long *p = (long *) *in;
01016
01017 if (p) {
01018 p -= 2;
01019 sqlite3_free(p);
01020 *in = 0;
01021 }
01022 }
01023
01033 static char *
01034 append(char **in, char const *append, char quote)
01035 {
01036 long *p = (long *) *in;
01037 long len, maxlen, actlen;
01038 int i;
01039 char *pp;
01040 int nappend = append ? strlen(append) : 0;
01041
01042 if (p) {
01043 p -= 2;
01044 maxlen = p[0];
01045 actlen = p[1];
01046 } else {
01047 maxlen = actlen = 0;
01048 }
01049 len = nappend + actlen;
01050 if (quote) {
01051 len += 2;
01052 for (i = 0; i < nappend; i++) {
01053 if (append[i] == quote) {
01054 len++;
01055 }
01056 }
01057 } else if (!nappend) {
01058 return *in;
01059 }
01060 if (len >= maxlen - 1) {
01061 long *q;
01062
01063 maxlen = (len + 0x03ff) & (~0x3ff);
01064 q = (long *) sqlite3_realloc(p, maxlen + 1 + 2 * sizeof (long));
01065 if (!q) {
01066 return 0;
01067 }
01068 if (!p) {
01069 q[1] = 0;
01070 }
01071 p = q;
01072 p[0] = maxlen;
01073 *in = (char *) (p + 2);
01074 }
01075 pp = *in + actlen;
01076 if (quote) {
01077 *pp++ = quote;
01078 for (i = 0; i < nappend; i++) {
01079 *pp++ = append[i];
01080 if (append[i] == quote) {
01081 *pp++ = quote;
01082 }
01083 }
01084 *pp++ = quote;
01085 *pp = '\0';
01086 } else {
01087 if (nappend) {
01088 memcpy(pp, append, nappend);
01089 pp += nappend;
01090 *pp = '\0';
01091 }
01092 }
01093 p[1] = pp - *in;
01094 return *in;
01095 }
01096
01103 static void
01104 quote_xml_str(DUMP_DATA *dd, char *str)
01105 {
01106 static const char xdigits[] = "0123456789ABCDEF";
01107 int i;
01108
01109 if (!str) {
01110 return;
01111 }
01112 for (i = 0; str[i]; i++) {
01113 if (str[i] == '"') {
01114 fputs(""", dd->out);
01115 } else if (str[i] == '\'') {
01116 fputs("'", dd->out);
01117 } else if (str[i] == '<') {
01118 fputs("<", dd->out);
01119 } else if (str[i] == '>') {
01120 fputs(">", dd->out);
01121 } else if (str[i] == '&') {
01122 fputs("&", dd->out);
01123 } else if ((unsigned char) str[i] <= ' ') {
01124 char buf[8];
01125
01126 buf[0] = '&';
01127 buf[1] = '&';
01128 buf[2] = '#';
01129 buf[3] = 'x';
01130 buf[4] = xdigits[(str[i] >> 4 ) & 0x0F];
01131 buf[5] = xdigits[str[i] & 0x0F];
01132 buf[6] = ';';
01133 buf[7] = '\0';
01134 fputs(buf, dd->out);
01135 } else {
01136 fputc(str[i], dd->out);
01137 }
01138 }
01139 }
01140
01150 static int
01151 dump_cb(void *udata, int nargs, char **args, char **cols)
01152 {
01153 int rc;
01154 const char *table, *type, *sql;
01155 DUMP_DATA *dd = (DUMP_DATA *) udata;
01156
01157 if ((nargs != 3) || (args == NULL)) {
01158 return 1;
01159 }
01160 table = args[0];
01161 type = args[1];
01162 sql = args[2];
01163 if (strcmp(table, "sqlite_sequence") == 0) {
01164 if (dd->with_schema) {
01165 if (fputs("DELETE FROM sqlite_sequence;\n", dd->out) >= 0) {
01166 dd->nlines++;
01167 }
01168 }
01169 } else if (strcmp(table, "sqlite_stat1") == 0) {
01170 if (dd->with_schema) {
01171 if (fputs("ANALYZE sqlite_master;\n", dd->out) >= 0) {
01172 dd->nlines++;
01173 }
01174 }
01175 } else if (strncmp(table, "sqlite_", 7) == 0) {
01176 return 0;
01177 } else if (strncmp(sql, "CREATE VIRTUAL TABLE", 20) == 0) {
01178 if (dd->with_schema) {
01179 sqlite3_stmt *stmt = 0;
01180 char *creat = 0, *table_info = 0;
01181
01182 append(&table_info, "PRAGMA table_info(", 0);
01183 append(&table_info, table, '"');
01184 append(&table_info, ")", 0);
01185 #if defined(HAVE_SQLITE3PREPAREV2) && HAVE_SQLITE3PREPAREV2
01186 rc = sqlite3_prepare_v2(dd->db, table_info, -1, &stmt, 0);
01187 #else
01188 rc = sqlite3_prepare(dd->db, table_info, -1, &stmt, 0);
01189 #endif
01190 append_free(&table_info);
01191 if ((rc != SQLITE_OK) || !stmt) {
01192 bailout0:
01193 if (stmt) {
01194 sqlite3_finalize(stmt);
01195 }
01196 append_free(&creat);
01197 return 1;
01198 }
01199 append(&creat, table, '"');
01200 append(&creat, "(", 0);
01201 rc = sqlite3_step(stmt);
01202 while (rc == SQLITE_ROW) {
01203 const char *p;
01204
01205 p = (const char *) sqlite3_column_text(stmt, 1);
01206 append(&creat, p, '"');
01207 append(&creat, " ", 0);
01208 p = (const char *) sqlite3_column_text(stmt, 2);
01209 if (p && p[0]) {
01210 append(&creat, p, 0);
01211 }
01212 if (sqlite3_column_int(stmt, 5)) {
01213 append(&creat, " PRIMARY KEY", 0);
01214 }
01215 if (sqlite3_column_int(stmt, 3)) {
01216 append(&creat, " NOT NULL", 0);
01217 }
01218 p = (const char *) sqlite3_column_text(stmt, 4);
01219 if (p && p[0]) {
01220 append(&creat, " DEFAULT ", 0);
01221 append(&creat, p, 0);
01222 }
01223 rc = sqlite3_step(stmt);
01224 if (rc == SQLITE_ROW) {
01225 append(&creat, ",", 0);
01226 }
01227 }
01228 if (rc != SQLITE_DONE) {
01229 goto bailout0;
01230 }
01231 sqlite3_finalize(stmt);
01232 append(&creat, ")", 0);
01233 if (creat && fprintf(dd->out, "CREATE TABLE %s;\n", creat) > 0) {
01234 dd->nlines++;
01235 }
01236 append_free(&creat);
01237 }
01238 } else {
01239 if (dd->with_schema) {
01240 if (fprintf(dd->out, "%s;\n", sql) > 0) {
01241 dd->nlines++;
01242 }
01243 }
01244 }
01245 if ((strcmp(type, "table") == 0) ||
01246 ((dd->quote_mode < 0) && (strcmp(type, "view") == 0))) {
01247 sqlite3_stmt *stmt = 0;
01248 char *select = 0, *hdr = 0, *table_info = 0;
01249 char buffer[256];
01250
01251 append(&table_info, "PRAGMA table_info(", 0);
01252 append(&table_info, table, '"');
01253 append(&table_info, ")", 0);
01254 #if defined(HAVE_SQLITE3PREPAREV2) && HAVE_SQLITE3PREPAREV2
01255 rc = sqlite3_prepare_v2(dd->db, table_info, -1, &stmt, 0);
01256 #else
01257 rc = sqlite3_prepare(dd->db, table_info, -1, &stmt, 0);
01258 #endif
01259 append_free(&table_info);
01260 if ((rc != SQLITE_OK) || !stmt) {
01261 bailout1:
01262 if (stmt) {
01263 sqlite3_finalize(stmt);
01264 }
01265 append_free(&hdr);
01266 append_free(&select);
01267 return 1;
01268 }
01269 if (dd->quote_mode < -1) {
01270 if (dd->where) {
01271 append(&select, "SELECT ", 0);
01272 sprintf(buffer, "indent_xml(%d)", dd->indent);
01273 append(&select, buffer, 0);
01274 append(&select, " || '<' || quote_xml(", 0);
01275 append(&select, dd->where, '"');
01276 append(&select, ",-1) || '>\n' || ", 0);
01277 } else {
01278 append(&select, "SELECT ", 0);
01279 }
01280 } else if (dd->quote_mode < 0) {
01281 if (dd->where) {
01282 append(&select, "SELECT quote_csv(", 0);
01283 append(&select, dd->where, '"');
01284 append(&select, ") || ',' || ", 0);
01285 } else {
01286 append(&select, "SELECT ", 0);
01287 }
01288 if (dd->indent) {
01289 append(&hdr, select, 0);
01290 }
01291 } else {
01292 char *tmp = 0;
01293
01294 if (dd->with_schema) {
01295 append(&select, "SELECT 'INSERT INTO ' || ", 0);
01296 } else {
01297 append(&select, "SELECT 'INSERT OR REPLACE INTO ' || ", 0);
01298 }
01299 append(&tmp, table, '"');
01300 if (tmp) {
01301 append(&select, tmp, '\'');
01302 append_free(&tmp);
01303 }
01304 }
01305 if ((dd->quote_mode >= 0) && !dd->with_schema) {
01306 char *tmp = 0;
01307
01308 append(&select, " || ' (' || ", 0);
01309 rc = sqlite3_step(stmt);
01310 while (rc == SQLITE_ROW) {
01311 const char *text = (const char *) sqlite3_column_text(stmt, 1);
01312
01313 append(&tmp, text, '"');
01314 if (tmp) {
01315 append(&select, tmp, '\'');
01316 append_free(&tmp);
01317 }
01318 rc = sqlite3_step(stmt);
01319 if (rc == SQLITE_ROW) {
01320 append(&select, " || ',' || ", 0);
01321 }
01322 }
01323 if (rc != SQLITE_DONE) {
01324 goto bailout1;
01325 }
01326 sqlite3_reset(stmt);
01327 append(&select, "|| ')'", 0);
01328 }
01329 if ((dd->quote_mode == -1) && dd->indent) {
01330 rc = sqlite3_step(stmt);
01331 while (rc == SQLITE_ROW) {
01332 const char *text = (const char *) sqlite3_column_text(stmt, 1);
01333
01334 append(&hdr, "quote_csv(", 0);
01335 append(&hdr, text, '"');
01336 rc = sqlite3_step(stmt);
01337 if (rc == SQLITE_ROW) {
01338 append(&hdr, ") || ',' || ", 0);
01339 } else {
01340 append(&hdr, ")", 0);
01341 }
01342 }
01343 if (rc != SQLITE_DONE) {
01344 goto bailout1;
01345 }
01346 sqlite3_reset(stmt);
01347 }
01348 if (dd->quote_mode >= 0) {
01349 append(&select, " || ' VALUES(' || ", 0);
01350 }
01351 rc = sqlite3_step(stmt);
01352 while (rc == SQLITE_ROW) {
01353 const char *text = (const char *) sqlite3_column_text(stmt, 1);
01354 const char *type = (const char *) sqlite3_column_text(stmt, 2);
01355 int tlen = strlen(type ? type : "");
01356
01357 if (dd->quote_mode < -1) {
01358 sprintf(buffer, "indent_xml(%d)", dd->indent + 1);
01359 append(&select, buffer, 0);
01360 append(&select, "|| '<' || quote_xml(", 0);
01361 append(&select, text, '\'');
01362 append(&select, ",-1) || quote_xml(", 0);
01363 append(&select, text, '"');
01364 append(&select, ",1) || '</' || quote_xml(", 0);
01365 append(&select, text, '\'');
01366 append(&select, ",-1) || '>\n'", 0);
01367 } else if (dd->quote_mode < 0) {
01368
01369 if (((tlen >= 4) && (strncasecmp(type, "BLOB", 4) == 0)) ||
01370 ((tlen >= 6) && (strncasecmp(type, "BINARY", 6) == 0))) {
01371 rc = sqlite3_step(stmt);
01372 if (rc != SQLITE_ROW) {
01373 tlen = strlen(select);
01374 if (tlen > 10) {
01375 select[tlen - 10] = '\0';
01376 }
01377 }
01378 continue;
01379 }
01380 append(&select, "quote_csv(", 0);
01381 append(&select, text, '"');
01382 } else {
01383 append(&select, "quote_sql(", 0);
01384 append(&select, text, '"');
01385 if (dd->quote_mode) {
01386 char mbuf[32];
01387
01388 sprintf(mbuf, ",%d", dd->quote_mode);
01389 append(&select, mbuf, 0);
01390 }
01391 }
01392 rc = sqlite3_step(stmt);
01393 if (rc == SQLITE_ROW) {
01394 if (dd->quote_mode >= -1) {
01395 append(&select, ") || ',' || ", 0);
01396 } else {
01397 append(&select, " || ", 0);
01398 }
01399 } else {
01400 if (dd->quote_mode >= -1) {
01401 append(&select, ") ", 0);
01402 } else {
01403 append(&select, " ", 0);
01404 }
01405 }
01406 }
01407 if (rc != SQLITE_DONE) {
01408 goto bailout1;
01409 }
01410 sqlite3_finalize(stmt);
01411 stmt = 0;
01412 if (dd->quote_mode >= 0) {
01413 append(&select, "|| ')' FROM ", 0);
01414 } else {
01415 if ((dd->quote_mode < -1) && dd->where) {
01416 sprintf(buffer, " || indent_xml(%d)", dd->indent);
01417 append(&select, buffer, 0);
01418 append(&select, " || '</' || quote_xml(", 0);
01419 append(&select, dd->where, '"');
01420 append(&select, ",-1) || '>\n' FROM ", 0);
01421 } else {
01422 append(&select, "FROM ", 0);
01423 }
01424 }
01425 append(&select, table, '"');
01426 if ((dd->quote_mode >= 0) && dd->where) {
01427 append(&select, " ", 0);
01428 append(&select, dd->where, 0);
01429 }
01430 if (hdr) {
01431 rc = table_dump(dd, 0, 0, hdr);
01432 append_free(&hdr);
01433 hdr = 0;
01434 }
01435 rc = table_dump(dd, 0, 0, select);
01436 if (rc == SQLITE_CORRUPT) {
01437 append(&select, " ORDER BY rowid DESC", 0);
01438 rc = table_dump(dd, 0, 0, select);
01439 }
01440 append_free(&select);
01441 }
01442 return 0;
01443 }
01444
01454 static int
01455 schema_dump(DUMP_DATA *dd, char **errp, const char *query, ...)
01456 {
01457 int rc;
01458 char *q;
01459 va_list ap;
01460
01461 if (errp) {
01462 sqlite3_free(*errp);
01463 *errp = 0;
01464 }
01465 va_start(ap, query);
01466 q = sqlite3_vmprintf(query, ap);
01467 va_end(ap);
01468 if (!q) {
01469 return SQLITE_NOMEM;
01470 }
01471 rc = sqlite3_exec(dd->db, q, dump_cb, dd, errp);
01472 if (rc == SQLITE_CORRUPT) {
01473 char *tmp;
01474
01475 tmp = sqlite3_mprintf("%s ORDER BY rowid DESC", q);
01476 sqlite3_free(q);
01477 if (!tmp) {
01478 return rc;
01479 }
01480 q = tmp;
01481 if (errp) {
01482 sqlite3_free(*errp);
01483 *errp = 0;
01484 }
01485 rc = sqlite3_exec(dd->db, q, dump_cb, dd, errp);
01486 }
01487 sqlite3_free(q);
01488 return rc;
01489 }
01490
01498 static void
01499 export_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
01500 {
01501 DUMP_DATA dd0, *dd = &dd0;
01502 sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx);
01503 int i, mode = 0;
01504 char *filename = 0;
01505 #ifdef _WIN32
01506 char fnbuf[MAX_PATH];
01507 #endif
01508
01509 dd->db = db;
01510 dd->where = 0;
01511 dd->nlines = -1;
01512 dd->indent = 0;
01513 if (nargs > 0) {
01514 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
01515 filename = (char *) sqlite3_value_text(args[0]);
01516 }
01517 }
01518 #ifdef _WIN32
01519 if (!filename) {
01520 OPENFILENAME ofn;
01521
01522 memset(&ofn, 0, sizeof (ofn));
01523 memset(fnbuf, 0, sizeof (fnbuf));
01524 ofn.lStructSize = sizeof (ofn);
01525 ofn.lpstrFile = fnbuf;
01526 ofn.nMaxFile = MAX_PATH;
01527 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
01528 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
01529 if (GetSaveFileName(&ofn)) {
01530 filename = fnbuf;
01531 }
01532 }
01533 #endif
01534 if (!filename) {
01535 goto done;
01536 }
01537 dd->out = fopen(filename, "w");
01538 if (!dd->out) {
01539 goto done;
01540 }
01541 if (nargs > 1) {
01542 mode = sqlite3_value_int(args[1]);
01543 }
01544 dd->with_schema = !(mode & 1);
01545 dd->quote_mode = (mode >> 8) & 3;
01546 dd->nlines = 0;
01547 if (fputs("BEGIN TRANSACTION;\n", dd->out) >= 0) {
01548 dd->nlines++;
01549 }
01550 if (nargs <= 2) {
01551 schema_dump(dd, 0,
01552 "SELECT name, type, sql FROM sqlite_master"
01553 " WHERE sql NOT NULL AND type = 'table'");
01554 if (dd->with_schema) {
01555 table_dump(dd, 0, 0,
01556 "SELECT sql FROM sqlite_master WHERE"
01557 " sql NOT NULL AND type IN ('index','trigger','view')");
01558 }
01559 } else {
01560 for (i = 2; i < nargs; i += (mode & 2) ? 2 : 1) {
01561 dd->where = 0;
01562 if ((mode & 2) && (i + 1 < nargs)) {
01563 dd->where = (char *) sqlite3_value_text(args[i + 1]);
01564 }
01565 schema_dump(dd, 0,
01566 "SELECT name, type, sql FROM sqlite_master"
01567 " WHERE tbl_name LIKE %Q AND type = 'table'"
01568 " AND sql NOT NULL",
01569 sqlite3_value_text(args[i]));
01570 if (dd->with_schema) {
01571 table_dump(dd, 0, 1,
01572 "SELECT sql FROM sqlite_master"
01573 " WHERE sql NOT NULL"
01574 " AND type IN ('index','trigger','view')"
01575 " AND tbl_name LIKE %Q",
01576 sqlite3_value_text(args[i]));
01577 }
01578 }
01579 }
01580 if (fputs("COMMIT;\n", dd->out) >= 0) {
01581 dd->nlines++;
01582 }
01583 fclose(dd->out);
01584 done:
01585 sqlite3_result_int(ctx, dd->nlines);
01586 }
01587
01595 static void
01596 export_csv_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
01597 {
01598 DUMP_DATA dd0, *dd = &dd0;
01599 sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx);
01600 int i;
01601 char *filename = 0;
01602 #ifdef _WIN32
01603 char fnbuf[MAX_PATH];
01604 #endif
01605
01606 dd->db = db;
01607 dd->where = 0;
01608 dd->nlines = -1;
01609 dd->indent = 0;
01610 dd->with_schema = 0;
01611 dd->quote_mode = -1;
01612 if (nargs > 0) {
01613 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
01614 filename = (char *) sqlite3_value_text(args[0]);
01615 }
01616 }
01617 #ifdef _WIN32
01618 if (!filename) {
01619 OPENFILENAME ofn;
01620
01621 memset(&ofn, 0, sizeof (ofn));
01622 memset(fnbuf, 0, sizeof (fnbuf));
01623 ofn.lStructSize = sizeof (ofn);
01624 ofn.lpstrFile = fnbuf;
01625 ofn.nMaxFile = MAX_PATH;
01626 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
01627 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
01628 if (GetSaveFileName(&ofn)) {
01629 filename = fnbuf;
01630 }
01631 }
01632 #endif
01633 if (!filename) {
01634 goto done;
01635 }
01636 #ifdef _WIN32
01637 dd->out = fopen(filename, "wb");
01638 #else
01639 dd->out = fopen(filename, "w");
01640 #endif
01641 if (!dd->out) {
01642 goto done;
01643 }
01644 dd->nlines = 0;
01645 if (nargs > 1) {
01646 if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
01647 if (sqlite3_value_int(args[1])) {
01648 dd->indent = 1;
01649 }
01650 }
01651 }
01652 for (i = 2; i <= nargs - 3; i += 3) {
01653 char *schema = 0, *sql;
01654
01655 dd->where = 0;
01656 if (sqlite3_value_type(args[i]) != SQLITE_NULL) {
01657 dd->where = (char *) sqlite3_value_text(args[i]);
01658 if (dd->where && !dd->where[0]) {
01659 dd->where = 0;
01660 }
01661 }
01662 if (sqlite3_value_type(args[i + 2]) != SQLITE_NULL) {
01663 schema = (char *) sqlite3_value_text(args[i + 2]);
01664 }
01665 if (!schema || (schema[0] == '\0')) {
01666 schema = "sqlite_master";
01667 }
01668 sql = sqlite3_mprintf("SELECT name, type, sql FROM %s"
01669 " WHERE tbl_name LIKE %%Q AND "
01670 " (type = 'table' OR type = 'view')"
01671 " AND sql NOT NULL", schema);
01672 if (sql) {
01673 schema_dump(dd, 0, sql, sqlite3_value_text(args[i + 1]));
01674 sqlite3_free(sql);
01675 }
01676 }
01677 fclose(dd->out);
01678 done:
01679 sqlite3_result_int(ctx, dd->nlines);
01680 }
01681
01689 static void
01690 export_xml_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
01691 {
01692 DUMP_DATA dd0, *dd = &dd0;
01693 sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx);
01694 int i;
01695 char *filename = 0;
01696 char *openmode = "w";
01697 #ifdef _WIN32
01698 char fnbuf[MAX_PATH];
01699 #endif
01700
01701 dd->db = db;
01702 dd->where = 0;
01703 dd->nlines = -1;
01704 dd->indent = 0;
01705 dd->with_schema = 0;
01706 dd->quote_mode = -2;
01707 if (nargs > 0) {
01708 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
01709 filename = (char *) sqlite3_value_text(args[0]);
01710 }
01711 }
01712 #ifdef _WIN32
01713 if (!filename) {
01714 OPENFILENAME ofn;
01715
01716 memset(&ofn, 0, sizeof (ofn));
01717 memset(fnbuf, 0, sizeof (fnbuf));
01718 ofn.lStructSize = sizeof (ofn);
01719 ofn.lpstrFile = fnbuf;
01720 ofn.nMaxFile = MAX_PATH;
01721 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
01722 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
01723 if (GetSaveFileName(&ofn)) {
01724 filename = fnbuf;
01725 }
01726 }
01727 #endif
01728 if (!filename) {
01729 goto done;
01730 }
01731 if (nargs > 1) {
01732 if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
01733 if (sqlite3_value_int(args[1])) {
01734 openmode = "a";
01735 }
01736 }
01737 }
01738 if (nargs > 2) {
01739 if (sqlite3_value_type(args[2]) != SQLITE_NULL) {
01740 dd->indent = sqlite3_value_int(args[2]);
01741 if (dd->indent < 0) {
01742 dd->indent = 0;
01743 }
01744 }
01745 }
01746 dd->out = fopen(filename, openmode);
01747 if (!dd->out) {
01748 goto done;
01749 }
01750 dd->nlines = 0;
01751 for (i = 3; i <= nargs - 4; i += 4) {
01752 char *root = 0, *schema = 0, *sql;
01753
01754 if (sqlite3_value_type(args[i]) != SQLITE_NULL) {
01755 root = (char *) sqlite3_value_text(args[i]);
01756 if (root && !root[0]) {
01757 root = 0;
01758 }
01759 }
01760 dd->where = 0;
01761 if (sqlite3_value_type(args[i + 1]) != SQLITE_NULL) {
01762 dd->where = (char *) sqlite3_value_text(args[i + 1]);
01763 if (dd->where && !dd->where[0]) {
01764 dd->where = 0;
01765 }
01766 }
01767 if (root) {
01768 indent(dd);
01769 dd->indent++;
01770 fputs("<", dd->out);
01771 quote_xml_str(dd, root);
01772 fputs(">\n", dd->out);
01773 }
01774 if (sqlite3_value_type(args[i + 3]) != SQLITE_NULL) {
01775 schema = (char *) sqlite3_value_text(args[i + 3]);
01776 }
01777 if (!schema || (schema[0] == '\0')) {
01778 schema = "sqlite_master";
01779 }
01780 sql = sqlite3_mprintf("SELECT name, type, sql FROM %s"
01781 " WHERE tbl_name LIKE %%Q AND"
01782 " (type = 'table' OR type = 'view')"
01783 " AND sql NOT NULL", schema);
01784 if (sql) {
01785 schema_dump(dd, 0, sql, sqlite3_value_text(args[i + 2]));
01786 sqlite3_free(sql);
01787 }
01788 if (root) {
01789 dd->indent--;
01790 indent(dd);
01791 fputs("</", dd->out);
01792 quote_xml_str(dd, root);
01793 fputs(">\n", dd->out);
01794 }
01795 }
01796 fclose(dd->out);
01797 done:
01798 sqlite3_result_int(ctx, dd->nlines);
01799 }
01800
01801
01802
01803 int
01804 impexp_export_sql(sqlite3 *db, char *filename, int mode, ...)
01805 {
01806 DUMP_DATA dd0, *dd = &dd0;
01807 va_list ap;
01808 char *table;
01809 #ifdef _WIN32
01810 char fnbuf[MAX_PATH];
01811 #endif
01812
01813 if (!db) {
01814 return 0;
01815 }
01816 dd->db = db;
01817 dd->where = 0;
01818 dd->nlines = -1;
01819 #ifdef _WIN32
01820 if (!filename) {
01821 OPENFILENAME ofn;
01822
01823 memset(&ofn, 0, sizeof (ofn));
01824 memset(fnbuf, 0, sizeof (fnbuf));
01825 ofn.lStructSize = sizeof (ofn);
01826 ofn.lpstrFile = fnbuf;
01827 ofn.nMaxFile = MAX_PATH;
01828 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
01829 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
01830 if (GetSaveFileName(&ofn)) {
01831 filename = fnbuf;
01832 }
01833 }
01834 #endif
01835 if (!filename) {
01836 goto done;
01837 }
01838 dd->out = fopen(filename, "w");
01839 if (!dd->out) {
01840 goto done;
01841 }
01842 dd->with_schema = !(mode & 1);
01843 dd->nlines = 0;
01844 if (fputs("BEGIN TRANSACTION;\n", dd->out) >= 0) {
01845 dd->nlines++;
01846 }
01847 va_start(ap, mode);
01848 table = va_arg(ap, char *);
01849 if (!table) {
01850 schema_dump(dd, 0,
01851 "SELECT name, type, sql FROM sqlite_master"
01852 " WHERE sql NOT NULL AND type = 'table'");
01853 if (dd->with_schema) {
01854 table_dump(dd, 0, 0,
01855 "SELECT sql FROM sqlite_master WHERE"
01856 " sql NOT NULL AND type IN ('index','trigger','view')");
01857 }
01858 } else {
01859 while (table) {
01860 dd->where = 0;
01861 if ((mode & 2)) {
01862 dd->where = va_arg(ap, char *);
01863 }
01864 schema_dump(dd, 0,
01865 "SELECT name, type, sql FROM sqlite_master"
01866 " WHERE tbl_name LIKE %Q AND type = 'table'"
01867 " AND sql NOT NULL", table);
01868 if (dd->with_schema) {
01869 table_dump(dd, 0, 1,
01870 "SELECT sql FROM sqlite_master"
01871 " WHERE sql NOT NULL"
01872 " AND type IN ('index','trigger','view')"
01873 " AND tbl_name LIKE %Q", table);
01874 }
01875 table = va_arg(ap, char *);
01876 }
01877 }
01878 va_end(ap);
01879 if (fputs("COMMIT;\n", dd->out) >= 0) {
01880 dd->nlines++;
01881 }
01882 fclose(dd->out);
01883 done:
01884 return dd->nlines;
01885 }
01886
01887
01888
01889 int
01890 impexp_export_csv(sqlite3 *db, char *filename, int hdr, ...)
01891 {
01892 DUMP_DATA dd0, *dd = &dd0;
01893 va_list ap;
01894 char *prefix, *table, *schema;
01895 #ifdef _WIN32
01896 char fnbuf[MAX_PATH];
01897 #endif
01898
01899 if (!db) {
01900 return 0;
01901 }
01902 dd->db = db;
01903 dd->where = 0;
01904 dd->nlines = -1;
01905 dd->indent = 0;
01906 dd->with_schema = 0;
01907 dd->quote_mode = -1;
01908 dd->indent = hdr != 0;
01909 #ifdef _WIN32
01910 if (!filename) {
01911 OPENFILENAME ofn;
01912
01913 memset(&ofn, 0, sizeof (ofn));
01914 memset(fnbuf, 0, sizeof (fnbuf));
01915 ofn.lStructSize = sizeof (ofn);
01916 ofn.lpstrFile = fnbuf;
01917 ofn.nMaxFile = MAX_PATH;
01918 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
01919 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
01920 if (GetSaveFileName(&ofn)) {
01921 filename = fnbuf;
01922 }
01923 }
01924 #endif
01925 if (!filename) {
01926 goto done;
01927 }
01928 #ifdef _WIN32
01929 dd->out = fopen(filename, "wb");
01930 #else
01931 if ((hdr < 0) && access(filename, W_OK) == 0) {
01932 dd->out = fopen(filename, "a");
01933 dd->indent = 0;
01934 } else {
01935 dd->out = fopen(filename, "w");
01936 }
01937 #endif
01938 if (!dd->out) {
01939 goto done;
01940 }
01941 dd->nlines = 0;
01942 va_start(ap, hdr);
01943 prefix = va_arg(ap, char *);
01944 table = va_arg(ap, char *);
01945 schema = va_arg(ap, char *);
01946 while (table != NULL) {
01947 char *sql;
01948
01949 dd->where = (prefix && prefix[0]) ? prefix : 0;
01950 if (!schema || (schema[0] == '\0')) {
01951 schema = "sqlite_master";
01952 }
01953 sql = sqlite3_mprintf("SELECT name, type, sql FROM %s"
01954 " WHERE tbl_name LIKE %%Q AND"
01955 " (type = 'table' OR type = 'view')"
01956 " AND sql NOT NULL", schema);
01957 if (sql) {
01958 schema_dump(dd, 0, sql, table);
01959 sqlite3_free(sql);
01960 }
01961 prefix = va_arg(ap, char *);
01962 table = va_arg(ap, char *);
01963 schema = va_arg(ap, char *);
01964 }
01965 va_end(ap);
01966 fclose(dd->out);
01967 done:
01968 return dd->nlines;
01969 }
01970
01971
01972
01973 int
01974 impexp_export_xml(sqlite3 *db, char *filename, int append, int indnt,
01975 char *root, char *item, char *tablename, char *schema)
01976 {
01977 DUMP_DATA dd0, *dd = &dd0;
01978 char *sql;
01979 #ifdef _WIN32
01980 char fnbuf[MAX_PATH];
01981 #endif
01982
01983 if (!db) {
01984 return 0;
01985 }
01986 dd->db = db;
01987 dd->where = item;
01988 dd->nlines = -1;
01989 dd->indent = (indnt > 0) ? indnt : 0;
01990 dd->with_schema = 0;
01991 dd->quote_mode = -2;
01992 #ifdef _WIN32
01993 if (!filename) {
01994 OPENFILENAME ofn;
01995
01996 memset(&ofn, 0, sizeof (ofn));
01997 memset(fnbuf, 0, sizeof (fnbuf));
01998 ofn.lStructSize = sizeof (ofn);
01999 ofn.lpstrFile = fnbuf;
02000 ofn.nMaxFile = MAX_PATH;
02001 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
02002 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
02003 if (GetSaveFileName(&ofn)) {
02004 filename = fnbuf;
02005 }
02006 }
02007 #endif
02008 if (!filename) {
02009 goto done;
02010 }
02011 dd->out = fopen(filename, append ? "a" : "w");
02012 if (!dd->out) {
02013 goto done;
02014 }
02015 dd->nlines = 0;
02016 if (root) {
02017 indent(dd);
02018 dd->indent++;
02019 fputs("<", dd->out);
02020 quote_xml_str(dd, root);
02021 fputs(">\n", dd->out);
02022 }
02023 if (!schema || (schema[0] == '\0')) {
02024 schema = "sqlite_master";
02025 }
02026 sql = sqlite3_mprintf("SELECT name, type, sql FROM %s"
02027 " WHERE tbl_name LIKE %%Q AND"
02028 " (type = 'table' OR type = 'view')"
02029 " AND sql NOT NULL", schema);
02030 if (sql) {
02031 schema_dump(dd, 0, sql, tablename);
02032 sqlite3_free(sql);
02033 }
02034 if (root) {
02035 dd->indent--;
02036 indent(dd);
02037 fputs("</", dd->out);
02038 quote_xml_str(dd, root);
02039 fputs(">\n", dd->out);
02040 }
02041 fclose(dd->out);
02042 done:
02043 return dd->nlines;
02044 }
02045
02052 static void
02053 json_pstr(const char *string, json_pfs *pfs)
02054 {
02055 while (*string) {
02056 pfs->pfunc(*string, pfs->parg);
02057 string++;
02058 }
02059 }
02060
02067 static void
02068 json_pstrq(const char *string, json_pfs *pfs)
02069 {
02070 impexp_putc pfunc = pfs->pfunc;
02071 void *parg = pfs->parg;
02072 char buf[64];
02073
02074 if (!string) {
02075 json_pstr("null", pfs);
02076 return;
02077 }
02078 pfunc('"', parg);
02079 while (*string) {
02080 switch (*string) {
02081 case '"':
02082 case '\\':
02083 pfunc('\\', parg);
02084 pfunc(*string, parg);
02085 break;
02086 case '\b':
02087 pfunc('\\', parg);
02088 pfunc('b', parg);
02089 break;
02090 case '\f':
02091 pfunc('\\', parg);
02092 pfunc('f', parg);
02093 break;
02094 case '\n':
02095 pfunc('\\', parg);
02096 pfunc('n', parg);
02097 break;
02098 case '\r':
02099 pfunc('\\', parg);
02100 pfunc('r', parg);
02101 break;
02102 case '\t':
02103 pfunc('\\', parg);
02104 pfunc('t', parg);
02105 break;
02106 default:
02107 if (((*string < ' ') && (*string > 0)) || (*string == 0x7f)) {
02108 sprintf(buf, "\\u%04x", *string);
02109 json_pstr(buf, pfs);
02110 } else if (*string < 0) {
02111 unsigned char c = string[0];
02112 unsigned long uc = 0;
02113
02114 if (c < 0xc0) {
02115 uc = c;
02116 } else if (c < 0xe0) {
02117 if ((string[1] & 0xc0) == 0x80) {
02118 uc = ((c & 0x1f) << 6) | (string[1] & 0x3f);
02119 ++string;
02120 } else {
02121 uc = c;
02122 }
02123 } else if (c < 0xf0) {
02124 if (((string[1] & 0xc0) == 0x80) &&
02125 ((string[2] & 0xc0) == 0x80)) {
02126 uc = ((c & 0x0f) << 12) |
02127 ((string[1] & 0x3f) << 6) | (string[2] & 0x3f);
02128 string += 2;
02129 } else {
02130 uc = c;
02131 }
02132 } else if (c < 0xf8) {
02133 if (((string[1] & 0xc0) == 0x80) &&
02134 ((string[2] & 0xc0) == 0x80) &&
02135 ((string[3] & 0xc0) == 0x80)) {
02136 uc = ((c & 0x03) << 18) |
02137 ((string[1] & 0x3f) << 12) |
02138 ((string[2] & 0x3f) << 6) |
02139 (string[4] & 0x3f);
02140 string += 3;
02141 } else {
02142 uc = c;
02143 }
02144 } else if (c < 0xfc) {
02145 if (((string[1] & 0xc0) == 0x80) &&
02146 ((string[2] & 0xc0) == 0x80) &&
02147 ((string[3] & 0xc0) == 0x80) &&
02148 ((string[4] & 0xc0) == 0x80)) {
02149 uc = ((c & 0x01) << 24) |
02150 ((string[1] & 0x3f) << 18) |
02151 ((string[2] & 0x3f) << 12) |
02152 ((string[4] & 0x3f) << 6) |
02153 (string[5] & 0x3f);
02154 string += 4;
02155 } else {
02156 uc = c;
02157 }
02158 } else {
02159
02160 ++string;
02161 }
02162 if (uc < 0x10000) {
02163 sprintf(buf, "\\u%04lx", uc);
02164 } else if (uc < 0x100000) {
02165 uc -= 0x10000;
02166
02167 sprintf(buf, "\\u%04lx", 0xd800 | ((uc >> 10) & 0x3ff));
02168 json_pstr(buf, pfs);
02169 sprintf(buf, "\\u%04lx", 0xdc00 | (uc & 0x3ff));
02170 } else {
02171 strcpy(buf, "\\ufffd");
02172 }
02173 json_pstr(buf, pfs);
02174 } else {
02175 pfunc(*string, parg);
02176 }
02177 break;
02178 }
02179 ++string;
02180 }
02181 pfunc('"', parg);
02182 }
02183
02190 static void
02191 json_pstrc(const char *string, json_pfs *pfs)
02192 {
02193 if (*string && strchr(".0123456789-+", *string)) {
02194 json_pstr(string, pfs);
02195 } else {
02196 json_pstrq(string, pfs);
02197 }
02198 }
02199
02207 static void
02208 json_pb64(const unsigned char *blk, int len, json_pfs *pfs)
02209 {
02210 impexp_putc pfunc = pfs->pfunc;
02211 void *parg = pfs->parg;
02212 int i, reg[5];
02213 char buf[16];
02214 static const char *b64 =
02215 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
02216
02217 if (!blk) {
02218 json_pstr("null", pfs);
02219 return;
02220 }
02221 buf[4] = '\0';
02222 pfunc('"', parg);
02223 for (i = 0; i < len; i += 3) {
02224 reg[1] = reg[2] = reg[3] = reg[4] = 0;
02225 reg[0] = blk[i];
02226 if (i + 1 < len) {
02227 reg[1] = blk[i + 1];
02228 reg[3] = 1;
02229 }
02230 if (i + 2 < len) {
02231 reg[2] = blk[i + 2];
02232 reg[4] = 1;
02233 }
02234 buf[0] = b64[reg[0] >> 2];
02235 buf[1] = b64[((reg[0] << 4) & 0x30) | (reg[1] >> 4)];
02236 if (reg[3]) {
02237 buf[2] = b64[((reg[1] << 2) & 0x3c) | (reg[2] >> 6)];
02238 } else {
02239 buf[2] = '=';
02240 }
02241 if (reg[4]) {
02242 buf[3] = b64[reg[2] & 0x3f];
02243 } else {
02244 buf[3] = '=';
02245 }
02246 json_pstr(buf, pfs);
02247 }
02248 pfunc('"', parg);
02249 }
02250
02260 static int
02261 json_output(sqlite3 *db, char *sql, impexp_putc pfunc, void *parg)
02262 {
02263 json_pfs pfs0, *pfs = &pfs0;
02264 const char *tail = sql;
02265 int i, nresults = 0, result = SQLITE_ERROR;
02266
02267 pfs->pfunc = pfunc;
02268 pfs->parg = parg;
02269 json_pstr("{\"sql\":", pfs);
02270 json_pstrq(sql, pfs);
02271 json_pstr(",\"results\":[", pfs);
02272 do {
02273 sqlite3_stmt *stmt;
02274 int firstrow = 1, nrows = 0;
02275 char buf[256];
02276
02277 ++nresults;
02278 json_pstr((nresults == 1) ? "{" : ",{", pfs);
02279 result = sqlite3_prepare(db, tail, -1, &stmt, &tail);
02280 if (result != SQLITE_OK) {
02281 doerr:
02282 if (nrows == 0) {
02283 json_pstr("\"columns\":null,\"rows\":null,\"changes\":0,"
02284 "\"last_insert_rowid\":null,", pfs);
02285 }
02286 json_pstr("\"error:\"", pfs);
02287 json_pstrq(sqlite3_errmsg(db), pfs);
02288 pfunc('}', parg);
02289 break;
02290 }
02291 result = sqlite3_step(stmt);
02292 while ((result == SQLITE_ROW) || (result == SQLITE_DONE)) {
02293 if (firstrow) {
02294 for (i = 0; i < sqlite3_column_count(stmt); i++) {
02295 char *type;
02296
02297 json_pstr((i == 0) ? "\"columns\":[" : ",", pfs);
02298 json_pstr("{\"name\":", pfs);
02299 json_pstrq(sqlite3_column_name(stmt, i), pfs);
02300 json_pstr(",\"decltype\":", pfs);
02301 json_pstrq(sqlite3_column_decltype(stmt, i), pfs);
02302 json_pstr(",\"type\":", pfs);
02303 switch (sqlite3_column_type(stmt, i)) {
02304 case SQLITE_INTEGER:
02305 type = "integer";
02306 break;
02307 case SQLITE_FLOAT:
02308 type = "float";
02309 break;
02310 case SQLITE_BLOB:
02311 type = "blob";
02312 break;
02313 case SQLITE_TEXT:
02314 type = "text";
02315 break;
02316 case SQLITE_NULL:
02317 type = "null";
02318 break;
02319 default:
02320 type = "unknown";
02321 break;
02322 }
02323 json_pstrq(type, pfs);
02324 pfunc('}', parg);
02325 }
02326 if (i) {
02327 pfunc(']', parg);
02328 }
02329 firstrow = 0;
02330 }
02331 if (result == SQLITE_DONE) {
02332 break;
02333 }
02334 ++nrows;
02335 json_pstr((nrows == 1) ? ",\"rows\":[" : ",", pfs);
02336 for (i = 0; i < sqlite3_column_count(stmt); i++) {
02337 pfunc((i == 0) ? '[' : ',', parg);
02338 switch (sqlite3_column_type(stmt, i)) {
02339 case SQLITE_INTEGER:
02340 json_pstr((char *) sqlite3_column_text(stmt, i), pfs);
02341 break;
02342 case SQLITE_FLOAT:
02343 json_pstrc((char *) sqlite3_column_text(stmt, i), pfs);
02344 break;
02345 case SQLITE_BLOB:
02346 json_pb64((unsigned char *) sqlite3_column_blob(stmt, i),
02347 sqlite3_column_bytes(stmt, i), pfs);
02348 break;
02349 case SQLITE_TEXT:
02350 json_pstrq((char *) sqlite3_column_text(stmt, i), pfs);
02351 break;
02352 case SQLITE_NULL:
02353 default:
02354 json_pstr("null", pfs);
02355 break;
02356 }
02357 }
02358 json_pstr((i == 0) ? "null]" : "]", pfs);
02359 result = sqlite3_step(stmt);
02360 }
02361 if (nrows > 0) {
02362 pfunc(']', parg);
02363 }
02364 result = sqlite3_finalize(stmt);
02365 if (result != SQLITE_OK) {
02366 if (nrows > 0) {
02367 sprintf(buf,
02368 #ifdef _WIN32
02369 ",\"changes\":%d,\"last_insert_rowid\":%I64d",
02370 #else
02371 ",\"changes\":%d,\"last_insert_rowid\":%lld",
02372 #endif
02373 sqlite3_changes(db),
02374 sqlite3_last_insert_rowid(db));
02375 json_pstr(buf, pfs);
02376 }
02377 goto doerr;
02378 }
02379 if (nrows == 0) {
02380 json_pstr("\"columns\":null,\"rows\":null", pfs);
02381 }
02382 sprintf(buf,
02383 #ifdef _WIN32
02384 ",\"changes\":%d,\"last_insert_rowid\":%I64d",
02385 #else
02386 ",\"changes\":%d,\"last_insert_rowid\":%lld",
02387 #endif
02388 sqlite3_changes(db),
02389 sqlite3_last_insert_rowid(db));
02390 json_pstr(buf, pfs);
02391 json_pstr(",\"error\":null}", pfs);
02392 } while (tail && *tail);
02393 json_pstr("]}", pfs);
02394 return result;
02395 }
02396
02404 static void
02405 export_json_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
02406 {
02407 sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx);
02408 int result = -1;
02409 char *filename = 0;
02410 char *sql = 0;
02411 FILE *out = 0;
02412 #ifdef _WIN32
02413 char fnbuf[MAX_PATH];
02414 #endif
02415
02416 if (nargs > 0) {
02417 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
02418 filename = (char *) sqlite3_value_text(args[0]);
02419 }
02420 }
02421 #ifdef _WIN32
02422 if (!filename) {
02423 OPENFILENAME ofn;
02424
02425 memset(&ofn, 0, sizeof (ofn));
02426 memset(fnbuf, 0, sizeof (fnbuf));
02427 ofn.lStructSize = sizeof (ofn);
02428 ofn.lpstrFile = fnbuf;
02429 ofn.nMaxFile = MAX_PATH;
02430 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
02431 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
02432 if (GetSaveFileName(&ofn)) {
02433 filename = fnbuf;
02434 }
02435 }
02436 #endif
02437 if (!filename) {
02438 goto done;
02439 }
02440 out = fopen(filename, "w");
02441 if (!out) {
02442 goto done;
02443 }
02444 if (nargs > 1) {
02445 sql = (char *) sqlite3_value_text(args[1]);
02446 }
02447 if (sql) {
02448 result = json_output(db, sql, (impexp_putc) fputc, out);
02449 }
02450 fclose(out);
02451 done:
02452 sqlite3_result_int(ctx, result);
02453 }
02454
02455
02456
02457 int
02458 impexp_export_json(sqlite3 *db, char *sql, impexp_putc pfunc,
02459 void *parg)
02460 {
02461 return json_output(db, sql, pfunc, parg);
02462 }
02463
02472 #ifdef STANDALONE
02473 static int
02474 #else
02475 int
02476 #endif
02477 sqlite3_extension_init(sqlite3 *db, char **errmsg,
02478 const sqlite3_api_routines *api)
02479 {
02480 int rc, i;
02481 static const struct {
02482 const char *name;
02483 void (*func)(sqlite3_context *, int, sqlite3_value **);
02484 int nargs;
02485 int textrep;
02486 } ftab[] = {
02487 { "quote_sql", quote_func, -1, SQLITE_UTF8 },
02488 { "import_sql", import_func, -1, SQLITE_UTF8 },
02489 { "export_sql", export_func, -1, SQLITE_UTF8 },
02490 { "quote_csv", quote_csv_func, -1, SQLITE_UTF8 },
02491 { "export_csv", export_csv_func, -1, SQLITE_UTF8 },
02492 { "indent_xml", indent_xml_func, 1, SQLITE_UTF8 },
02493 { "quote_xml", quote_xml_func, -1, SQLITE_UTF8 },
02494 { "export_xml", export_xml_func, -1, SQLITE_UTF8 },
02495 { "export_json", export_json_func, -1, SQLITE_UTF8 }
02496 };
02497
02498 #ifndef STANDALONE
02499 if (api != NULL) {
02500 SQLITE_EXTENSION_INIT2(api);
02501 }
02502 #endif
02503
02504 for (i = 0; i < sizeof (ftab) / sizeof (ftab[0]); i++) {
02505 rc = sqlite3_create_function(db, ftab[i].name, ftab[i].nargs,
02506 ftab[i].textrep, db, ftab[i].func, 0, 0);
02507 if (rc != SQLITE_OK) {
02508 for (--i; i >= 0; --i) {
02509 sqlite3_create_function(db, ftab[i].name, ftab[i].nargs,
02510 ftab[i].textrep, 0, 0, 0, 0);
02511 }
02512 break;
02513 }
02514 }
02515 return rc;
02516 }
02517
02518
02519
02520 int
02521 impexp_init(sqlite3 *db)
02522 {
02523 return sqlite3_extension_init(db, NULL, NULL);
02524 }