impexp.c
Go to the documentation of this file.
1
183#ifdef STANDALONE
184#include <sqlite3.h>
185#define sqlite3_api_routines void
186#else
187#include <sqlite3ext.h>
188static SQLITE_EXTENSION_INIT1
189#endif
190
191#include <stdlib.h>
192#include <string.h>
193#include <stdio.h>
194#include <stddef.h>
195
196#ifdef _WIN32
197#include <windows.h>
198#define strcasecmp _stricmp
199#define strncasecmp _strnicmp
200#else
201#include <unistd.h>
202#endif
203
204#include "impexp.h"
205
212typedef struct {
214 void *parg;
215} json_pfs;
216
217static const char space_chars[] = " \f\n\r\t\v";
218
219#define ISSPACE(c) ((c) && (strchr(space_chars, (c)) != 0))
220
228static char *
230{
231 char *line, *tmp;
232 int nline;
233 int n;
234 int eol;
235
236 nline = 256;
237 line = sqlite3_malloc(nline);
238 if (!line) {
239 return 0;
240 }
241 n = 0;
242 eol = 0;
243 while (!eol) {
244 if (n + 256 > nline) {
245 nline = nline * 2 + 256;
246 tmp = sqlite3_realloc(line, nline);
247 if (!tmp) {
248 sqlite3_free(line);
249 return 0;
250 }
251 line = tmp;
252 }
253 if (!fgets(line + n, nline - n, fin)) {
254 if (n == 0) {
255 sqlite3_free(line);
256 return 0;
257 }
258 line[n] = 0;
259 eol = 1;
260 break;
261 }
262 while (line[n]) {
263 n++;
264 }
265 if ((n > 0) && (line[n-1] == '\n')) {
266 n--;
267 line[n] = 0;
268 eol = 1;
269 }
270 }
271 tmp = sqlite3_realloc(line, n + 1);
272 if (!tmp) {
273 sqlite3_free(line);
274 }
275 return tmp;
276}
277
285static int
286ends_with_semicolon(const char *str, int n)
287{
288 while ((n > 0) && ISSPACE(str[n - 1])) {
289 n--;
290 }
291 return (n > 0) && (str[n - 1] == ';');
292}
293
300static int
301all_whitespace(const char *str)
302{
303 for (; str[0]; str++) {
304 if (ISSPACE(str[0])) {
305 continue;
306 }
307 if ((str[0] == '/') && (str[1] == '*')) {
308 str += 2;
309 while (str[0] && ((str[0] != '*') || (str[1] != '/'))) {
310 str++;
311 }
312 if (!str[0]) {
313 return 0;
314 }
315 str++;
316 continue;
317 }
318 if ((str[0] == '-') && (str[1] == '-')) {
319 str += 2;
320 while (str[0] && (str[0] != '\n')) {
321 str++;
322 }
323 if (!str[0]) {
324 return 1;
325 }
326 continue;
327 }
328 return 0;
329 }
330 return 1;
331}
332
340static int
341process_input(sqlite3 *db, FILE *fin)
342{
343 char *line = 0;
344 char *sql = 0;
345 int nsql = 0;
346 int rc;
347 int errors = 0;
348
349 while (1) {
350 line = one_input_line(fin);
351 if (!line) {
352 break;
353 }
354 if ((!sql || !sql[0]) && all_whitespace(line)) {
355 continue;
356 }
357 if (!sql) {
358 int i;
359 for (i = 0; line[i] && ISSPACE(line[i]); i++) {
360 /* empty loop body */
361 }
362 if (line[i]) {
363 nsql = strlen(line);
364 sql = sqlite3_malloc(nsql + 1);
365 if (!sql) {
366 errors++;
367 break;
368 }
369 strcpy(sql, line);
370 }
371 } else {
372 int len = strlen(line);
373 char *tmp;
374
375 tmp = sqlite3_realloc(sql, nsql + len + 2);
376 if (!tmp) {
377 errors++;
378 break;
379 }
380 sql = tmp;
381 strcpy(sql + nsql, "\n");
382 nsql++;
383 strcpy(sql + nsql, line);
384 nsql += len;
385 }
386 sqlite3_free(line);
387 line = 0;
388 if (sql && ends_with_semicolon(sql, nsql) && sqlite3_complete(sql)) {
389 rc = sqlite3_exec(db, sql, 0, 0, 0);
390 if (rc != SQLITE_OK) {
391 errors++;
392 }
393 sqlite3_free(sql);
394 sql = 0;
395 nsql = 0;
396 }
397 }
398 if (sql) {
399 sqlite3_free(sql);
400 }
401 if (line) {
402 sqlite3_free(line);
403 }
404 return errors;
405}
406
419static void
420quote_func(sqlite3_context *context, int argc, sqlite3_value **argv)
421{
422 int mode = 0;
423
424 if (argc < 1) {
425 return;
426 }
427 if (argc > 1) {
428 mode = sqlite3_value_int(argv[1]);
429 }
430 switch (sqlite3_value_type(argv[0])) {
431 case SQLITE_NULL: {
432 sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
433 break;
434 }
435 case SQLITE_INTEGER:
436 case SQLITE_FLOAT: {
437 sqlite3_result_value(context, argv[0]);
438 break;
439 }
440 case SQLITE_BLOB: {
441 char *text = 0;
442 unsigned char *blob = (unsigned char *) sqlite3_value_blob(argv[0]);
443 int nblob = sqlite3_value_bytes(argv[0]);
444
445 if (2 * nblob + 4 > 1000000000) {
446 sqlite3_result_error(context, "value too large", -1);
447 return;
448 }
449 text = (char *) sqlite3_malloc((2 * nblob) + 4);
450 if (!text) {
451 sqlite3_result_error(context, "out of memory", -1);
452 } else {
453 int i, k = 0;
454 static const char xdigits[] = "0123456789ABCDEF";
455
456 if (mode == 1) {
457 /* ORACLE enclosed in '' */
458 text[k++] = '\'';
459 } else if (mode == 2) {
460 /* SQL Server 0x prefix */
461 text[k++] = '0';
462 text[k++] = 'x';
463 } else if (mode == 3) {
464 /* MySQL x'..' */
465 text[k++] = 'x';
466 text[k++] = '\'';
467 } else {
468 /* default */
469 text[k++] = 'X';
470 text[k++] = '\'';
471 }
472 for (i = 0; i < nblob; i++) {
473 text[k++] = xdigits[(blob[i] >> 4 ) & 0x0F];
474 text[k++] = xdigits[blob[i] & 0x0F];
475 }
476 if (mode == 1) {
477 /* ORACLE enclosed in '' */
478 text[k++] = '\'';
479 } else if (mode == 2) {
480 /* SQL Server 0x prefix */
481 } else if (mode == 3) {
482 /* MySQL x'..' */
483 text[k++] = '\'';
484 } else {
485 /* default */
486 text[k++] = '\'';
487 }
488 text[k] = '\0';
489 sqlite3_result_text(context, text, k, SQLITE_TRANSIENT);
490 sqlite3_free(text);
491 }
492 break;
493 }
494 case SQLITE_TEXT: {
495 int i, n;
496 const unsigned char *arg = sqlite3_value_text(argv[0]);
497 char *p;
498
499 if (!arg) {
500 return;
501 }
502 for (i = 0, n = 0; arg[i]; i++) {
503 if (arg[i] == '\'') {
504 n++;
505 }
506 }
507 if (i + n + 3 > 1000000000) {
508 sqlite3_result_error(context, "value too large", -1);
509 return;
510 }
511 p = sqlite3_malloc(i + n + 3);
512 if (!p) {
513 sqlite3_result_error(context, "out of memory", -1);
514 return;
515 }
516 p[0] = '\'';
517 for (i = 0, n = 1; arg[i]; i++) {
518 p[n++] = arg[i];
519 if (arg[i] == '\'') {
520 p[n++] = '\'';
521 }
522 }
523 p[n++] = '\'';
524 p[n] = 0;
525 sqlite3_result_text(context, p, n, SQLITE_TRANSIENT);
526 sqlite3_free(p);
527 break;
528 }
529 }
530}
531
539static void
540quote_csv_func(sqlite3_context *context, int argc, sqlite3_value **argv)
541{
542 if (argc < 1) {
543 return;
544 }
545 switch (sqlite3_value_type(argv[0])) {
546 case SQLITE_NULL: {
547 sqlite3_result_text(context, "", 0, SQLITE_STATIC);
548 break;
549 }
550 case SQLITE_INTEGER:
551 case SQLITE_FLOAT: {
552 sqlite3_result_value(context, argv[0]);
553 break;
554 }
555 case SQLITE_BLOB: {
556 char *text = 0;
557 unsigned char *blob = (unsigned char *) sqlite3_value_blob(argv[0]);
558 int nblob = sqlite3_value_bytes(argv[0]);
559
560 if (2 * nblob + 4 > 1000000000) {
561 sqlite3_result_error(context, "value too large", -1);
562 return;
563 }
564 text = (char *) sqlite3_malloc((2 * nblob) + 4);
565 if (!text) {
566 sqlite3_result_error(context, "out of memory", -1);
567 } else {
568 int i, k = 0;
569 static const char xdigits[] = "0123456789ABCDEF";
570
571 text[k++] = '"';
572 for (i = 0; i < nblob; i++) {
573 text[k++] = xdigits[(blob[i] >> 4 ) & 0x0F];
574 text[k++] = xdigits[blob[i] & 0x0F];
575 }
576 text[k++] = '"';
577 text[k] = '\0';
578 sqlite3_result_text(context, text, k, SQLITE_TRANSIENT);
579 sqlite3_free(text);
580 }
581 break;
582 }
583 case SQLITE_TEXT: {
584 int i, n;
585 const unsigned char *arg = sqlite3_value_text(argv[0]);
586 char *p;
587
588 if (!arg) {
589 return;
590 }
591 for (i = 0, n = 0; arg[i]; i++) {
592 if (arg[i] == '"') {
593 n++;
594 }
595 }
596 if (i + n + 3 > 1000000000) {
597 sqlite3_result_error(context, "value too large", -1);
598 return;
599 }
600 p = sqlite3_malloc(i + n + 3);
601 if (!p) {
602 sqlite3_result_error(context, "out of memory", -1);
603 return;
604 }
605 p[0] = '"';
606 for (i = 0, n = 1; arg[i]; i++) {
607 p[n++] = arg[i];
608 if (arg[i] == '"') {
609 p[n++] = '"';
610 }
611 }
612 p[n++] = '"';
613 p[n] = 0;
614 sqlite3_result_text(context, p, n, SQLITE_TRANSIENT);
615 sqlite3_free(p);
616 break;
617 }
618 }
619}
620
628static void
629indent_xml_func(sqlite3_context *context, int argc, sqlite3_value **argv)
630{
631 static const char spaces[] = " ";
632 int n = 0;
633
634 if (argc > 0) {
635 n = sqlite3_value_int(argv[0]);
636 if (n > 32) {
637 n = 32;
638 } else if (n < 0) {
639 n = 0;
640 }
641 }
642 sqlite3_result_text(context, spaces, n, SQLITE_STATIC);
643}
644
652static void
653quote_xml_func(sqlite3_context *context, int argc, sqlite3_value **argv)
654{
655 static const char xdigits[] = "0123456789ABCDEF";
656 int type, addtype = 0;
657
658 if (argc < 1) {
659 return;
660 }
661 if (argc > 1) {
662 addtype = sqlite3_value_int(argv[1]);
663 }
664 type = sqlite3_value_type(argv[0]);
665 switch (type) {
666 case SQLITE_NULL: {
667 if (addtype > 0) {
668 sqlite3_result_text(context, " TYPE=\"NULL\">", -1, SQLITE_STATIC);
669 } else {
670 sqlite3_result_text(context, "", 0, SQLITE_STATIC);
671 }
672 break;
673 }
674 case SQLITE_INTEGER:
675 case SQLITE_FLOAT: {
676 if (addtype > 0) {
677 char *text = (char *) sqlite3_malloc(128);
678 int k;
679
680 if (!text) {
681 sqlite3_result_error(context, "out of memory", -1);
682 return;
683 }
684 strcpy(text, (type == SQLITE_FLOAT) ? " TYPE=\"REAL\">" :
685 " TYPE=\"INTEGER\">");
686 k = strlen(text);
687 strcpy(text + k, (char *) sqlite3_value_text(argv[0]));
688 k = strlen(text);
689 sqlite3_result_text(context, text, k, SQLITE_TRANSIENT);
690 sqlite3_free(text);
691 } else {
692 sqlite3_result_value(context, argv[0]);
693 }
694 break;
695 }
696 case SQLITE_BLOB: {
697 char *text = 0;
698 unsigned char *blob = (unsigned char *) sqlite3_value_blob(argv[0]);
699 int nblob = sqlite3_value_bytes(argv[0]);
700 int i, k = 0;
701
702 if (6 * nblob + 34 > 1000000000) {
703 sqlite3_result_error(context, "value too large", -1);
704 return;
705 }
706 text = (char *) sqlite3_malloc((6 * nblob) + 34);
707 if (!text) {
708 sqlite3_result_error(context, "out of memory", -1);
709 return;
710 }
711 if (addtype > 0) {
712 strcpy(text, " TYPE=\"BLOB\">");
713 k = strlen(text);
714 }
715 for (i = 0; i < nblob; i++) {
716 text[k++] = '&';
717 text[k++] = '#';
718 text[k++] = 'x';
719 text[k++] = xdigits[(blob[i] >> 4 ) & 0x0F];
720 text[k++] = xdigits[blob[i] & 0x0F];
721 text[k++] = ';';
722 }
723 text[k] = '\0';
724 sqlite3_result_text(context, text, k, SQLITE_TRANSIENT);
725 sqlite3_free(text);
726 break;
727 }
728 case SQLITE_TEXT: {
729 int i, n;
730 const unsigned char *arg = sqlite3_value_text(argv[0]);
731 char *p;
732
733 if (!arg) {
734 return;
735 }
736 for (i = 0, n = 0; arg[i]; i++) {
737 if ((arg[i] == '"') || (arg[i] == '\'') ||
738 (arg[i] == '<') || (arg[i] == '>') ||
739 (arg[i] == '&') || (arg[i] < ' ')) {
740 n += 5;
741 }
742 }
743 if (i + n + 32 > 1000000000) {
744 sqlite3_result_error(context, "value too large", -1);
745 return;
746 }
747 p = sqlite3_malloc(i + n + 32);
748 if (!p) {
749 sqlite3_result_error(context, "out of memory", -1);
750 return;
751 }
752 n = 0;
753 if (addtype > 0) {
754 strcpy(p, " TYPE=\"TEXT\">");
755 n = strlen(p);
756 }
757 for (i = 0; arg[i]; i++) {
758 if (arg[i] == '"') {
759 p[n++] = '&';
760 p[n++] = 'q';
761 p[n++] = 'u';
762 p[n++] = 'o';
763 p[n++] = 't';
764 p[n++] = ';';
765 } else if (arg[i] == '\'') {
766 p[n++] = '&';
767 p[n++] = 'a';
768 p[n++] = 'p';
769 p[n++] = 'o';
770 p[n++] = 's';
771 p[n++] = ';';
772 } else if (arg[i] == '<') {
773 p[n++] = '&';
774 p[n++] = 'l';
775 p[n++] = 't';
776 p[n++] = ';';
777 } else if (arg[i] == '>') {
778 p[n++] = '&';
779 p[n++] = 'g';
780 p[n++] = 't';
781 p[n++] = ';';
782 } else if (arg[i] == '&') {
783 p[n++] = '&';
784 p[n++] = 'a';
785 p[n++] = 'm';
786 p[n++] = 'p';
787 p[n++] = ';';
788 } else if (arg[i] < ' ') {
789 p[n++] = '&';
790 p[n++] = '#';
791 p[n++] = 'x';
792 p[n++] = xdigits[(arg[i] >> 4 ) & 0x0F];
793 p[n++] = xdigits[arg[i] & 0x0F];
794 p[n++] = ';';
795 } else if (addtype < 0 && (arg[i] == ' ')) {
796 p[n++] = '&';
797 p[n++] = '#';
798 p[n++] = 'x';
799 p[n++] = xdigits[(arg[i] >> 4 ) & 0x0F];
800 p[n++] = xdigits[arg[i] & 0x0F];
801 p[n++] = ';';
802 } else {
803 p[n++] = arg[i];
804 }
805 }
806 p[n] = '\0';
807 sqlite3_result_text(context, p, n, SQLITE_TRANSIENT);
808 sqlite3_free(p);
809 break;
810 }
811 }
812}
813
821static void
822import_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
823{
824 sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx);
825 int changes0 = sqlite3_changes(db);
826 char *filename = 0;
827 FILE *fin;
828#ifdef _WIN32
829 char fnbuf[MAX_PATH];
830#endif
831
832 if (nargs > 0) {
833 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
834 filename = (char *) sqlite3_value_text(args[0]);
835 }
836 }
837#ifdef _WIN32
838 if (!filename) {
839 OPENFILENAME ofn;
840
841 memset(&ofn, 0, sizeof (ofn));
842 memset(fnbuf, 0, sizeof (fnbuf));
843 ofn.lStructSize = sizeof (ofn);
844 ofn.lpstrFile = fnbuf;
845 ofn.nMaxFile = MAX_PATH;
846 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST |
847 OFN_EXPLORER | OFN_PATHMUSTEXIST;
848 if (GetOpenFileName(&ofn)) {
849 filename = fnbuf;
850 }
851 }
852#endif
853 if (!filename) {
854 goto done;
855 }
856 fin = fopen(filename, "r");
857 if (!fin) {
858 goto done;
859 }
860 process_input(db, fin);
861 fclose(fin);
862done:
863 sqlite3_result_int(ctx, sqlite3_changes(db) - changes0);
864}
865
866/* see doc in impexp.h */
867
868int
869impexp_import_sql(sqlite3 *db, char *filename)
870{
871 int changes0;
872 FILE *fin;
873#ifdef _WIN32
874 char fnbuf[MAX_PATH];
875#endif
876
877 if (!db) {
878 return 0;
879 }
880 changes0 = sqlite3_changes(db);
881#ifdef _WIN32
882 if (!filename) {
883 OPENFILENAME ofn;
884
885 memset(&ofn, 0, sizeof (ofn));
886 memset(fnbuf, 0, sizeof (fnbuf));
887 ofn.lStructSize = sizeof (ofn);
888 ofn.lpstrFile = fnbuf;
889 ofn.nMaxFile = MAX_PATH;
890 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST |
891 OFN_EXPLORER | OFN_PATHMUSTEXIST;
892 if (GetOpenFileName(&ofn)) {
893 filename = fnbuf;
894 }
895 }
896#endif
897 if (!filename) {
898 goto done;
899 }
900 fin = fopen(filename, "r");
901 if (!fin) {
902 goto done;
903 }
904 process_input(db, fin);
905 fclose(fin);
906done:
907 return sqlite3_changes(db) - changes0;
908}
909
916typedef struct {
917 sqlite3 *db;
920 char *where;
921 int nlines;
922 int indent;
923 FILE *out;
924} DUMP_DATA;
925
931static void
933{
934 int i;
935
936 for (i = 0; i < dd->indent; i++) {
937 fputc(' ', dd->out);
938 }
939}
940
951static int
952table_dump(DUMP_DATA *dd, char **errp, int fmt, const char *query, ...)
953{
954 sqlite3_stmt *select = 0;
955 int rc;
956 const char *rest, *q = query;
957 va_list ap;
958
959 if (errp && *errp) {
960 sqlite3_free(*errp);
961 *errp = 0;
962 }
963 if (fmt) {
964 va_start(ap, query);
965 q = sqlite3_vmprintf(query, ap);
966 va_end(ap);
967 if (!q) {
968 return SQLITE_NOMEM;
969 }
970 }
971#if defined(HAVE_SQLITE3PREPAREV2) && HAVE_SQLITE3PREPAREV2
972 rc = sqlite3_prepare_v2(dd->db, q, -1, &select, &rest);
973#else
974 rc = sqlite3_prepare(dd->db, q, -1, &select, &rest);
975#endif
976 if (fmt) {
977 sqlite3_free((char *) q);
978 }
979 if ((rc != SQLITE_OK) || !select) {
980 return rc;
981 }
982 rc = sqlite3_step(select);
983 while (rc == SQLITE_ROW) {
984 if (fputs((char *) sqlite3_column_text(select, 0), dd->out) > 0) {
985 dd->nlines++;
986 }
987 if (dd->quote_mode >= 0) {
988 fputc(';', dd->out);
989 }
990 if (dd->quote_mode == -1) {
991 fputc('\r', dd->out);
992 }
993 if (dd->quote_mode >= -1) {
994 fputc('\n', dd->out);
995 }
996 rc = sqlite3_step(select);
997 }
998 rc = sqlite3_finalize(select);
999 if (rc != SQLITE_OK) {
1000 if (errp) {
1001 *errp = sqlite3_mprintf("%s", sqlite3_errmsg(dd->db));
1002 }
1003 }
1004 return rc;
1005}
1006
1012static void
1013append_free(char **in)
1014{
1015 long *p = (long *) *in;
1016
1017 if (p) {
1018 p -= 2;
1019 sqlite3_free(p);
1020 *in = 0;
1021 }
1022}
1023
1033static char *
1034append(char **in, char const *append, char quote)
1035{
1036 long *p = (long *) *in;
1037 long len, maxlen, actlen;
1038 int i;
1039 char *pp;
1040 int nappend = append ? strlen(append) : 0;
1041
1042 if (p) {
1043 p -= 2;
1044 maxlen = p[0];
1045 actlen = p[1];
1046 } else {
1047 maxlen = actlen = 0;
1048 }
1049 len = nappend + actlen;
1050 if (quote) {
1051 len += 2;
1052 for (i = 0; i < nappend; i++) {
1053 if (append[i] == quote) {
1054 len++;
1055 }
1056 }
1057 } else if (!nappend) {
1058 return *in;
1059 }
1060 if (len >= maxlen - 1) {
1061 long *q;
1062
1063 maxlen = (len + 0x03ff) & (~0x3ff);
1064 q = (long *) sqlite3_realloc(p, maxlen + 1 + 2 * sizeof (long));
1065 if (!q) {
1066 return 0;
1067 }
1068 if (!p) {
1069 q[1] = 0;
1070 }
1071 p = q;
1072 p[0] = maxlen;
1073 *in = (char *) (p + 2);
1074 }
1075 pp = *in + actlen;
1076 if (quote) {
1077 *pp++ = quote;
1078 for (i = 0; i < nappend; i++) {
1079 *pp++ = append[i];
1080 if (append[i] == quote) {
1081 *pp++ = quote;
1082 }
1083 }
1084 *pp++ = quote;
1085 *pp = '\0';
1086 } else {
1087 if (nappend) {
1088 memcpy(pp, append, nappend);
1089 pp += nappend;
1090 *pp = '\0';
1091 }
1092 }
1093 p[1] = pp - *in;
1094 return *in;
1095}
1096
1103static void
1105{
1106 static const char xdigits[] = "0123456789ABCDEF";
1107 int i;
1108
1109 if (!str) {
1110 return;
1111 }
1112 for (i = 0; str[i]; i++) {
1113 if (str[i] == '"') {
1114 fputs("&quot;", dd->out);
1115 } else if (str[i] == '\'') {
1116 fputs("&apos;", dd->out);
1117 } else if (str[i] == '<') {
1118 fputs("&lt;", dd->out);
1119 } else if (str[i] == '>') {
1120 fputs("&gt;", dd->out);
1121 } else if (str[i] == '&') {
1122 fputs("&amp;", dd->out);
1123 } else if ((unsigned char) str[i] <= ' ') {
1124 char buf[8];
1125
1126 buf[0] = '&';
1127 buf[1] = '&';
1128 buf[2] = '#';
1129 buf[3] = 'x';
1130 buf[4] = xdigits[(str[i] >> 4 ) & 0x0F];
1131 buf[5] = xdigits[str[i] & 0x0F];
1132 buf[6] = ';';
1133 buf[7] = '\0';
1134 fputs(buf, dd->out);
1135 } else {
1136 fputc(str[i], dd->out);
1137 }
1138 }
1139}
1140
1150static int
1151dump_cb(void *udata, int nargs, char **args, char **cols)
1152{
1153 int rc;
1154 const char *table, *type, *sql;
1155 DUMP_DATA *dd = (DUMP_DATA *) udata;
1156
1157 if ((nargs != 3) || (args == NULL)) {
1158 return 1;
1159 }
1160 table = args[0];
1161 type = args[1];
1162 sql = args[2];
1163 if (strcmp(table, "sqlite_sequence") == 0) {
1164 if (dd->with_schema) {
1165 if (fputs("DELETE FROM sqlite_sequence;\n", dd->out) >= 0) {
1166 dd->nlines++;
1167 }
1168 }
1169 } else if (strcmp(table, "sqlite_stat1") == 0) {
1170 if (dd->with_schema) {
1171 if (fputs("ANALYZE sqlite_master;\n", dd->out) >= 0) {
1172 dd->nlines++;
1173 }
1174 }
1175 } else if (strncmp(table, "sqlite_", 7) == 0) {
1176 return 0;
1177 } else if (strncmp(sql, "CREATE VIRTUAL TABLE", 20) == 0) {
1178 if (dd->with_schema) {
1179 sqlite3_stmt *stmt = 0;
1180 char *creat = 0, *table_info = 0;
1181
1182 append(&table_info, "PRAGMA table_info(", 0);
1183 append(&table_info, table, '"');
1184 append(&table_info, ")", 0);
1185#if defined(HAVE_SQLITE3PREPAREV2) && HAVE_SQLITE3PREPAREV2
1186 rc = sqlite3_prepare_v2(dd->db, table_info, -1, &stmt, 0);
1187#else
1188 rc = sqlite3_prepare(dd->db, table_info, -1, &stmt, 0);
1189#endif
1190 append_free(&table_info);
1191 if ((rc != SQLITE_OK) || !stmt) {
1192bailout0:
1193 if (stmt) {
1194 sqlite3_finalize(stmt);
1195 }
1196 append_free(&creat);
1197 return 1;
1198 }
1199 append(&creat, table, '"');
1200 append(&creat, "(", 0);
1201 rc = sqlite3_step(stmt);
1202 while (rc == SQLITE_ROW) {
1203 const char *p;
1204
1205 p = (const char *) sqlite3_column_text(stmt, 1);
1206 append(&creat, p, '"');
1207 append(&creat, " ", 0);
1208 p = (const char *) sqlite3_column_text(stmt, 2);
1209 if (p && p[0]) {
1210 append(&creat, p, 0);
1211 }
1212 if (sqlite3_column_int(stmt, 5)) {
1213 append(&creat, " PRIMARY KEY", 0);
1214 }
1215 if (sqlite3_column_int(stmt, 3)) {
1216 append(&creat, " NOT NULL", 0);
1217 }
1218 p = (const char *) sqlite3_column_text(stmt, 4);
1219 if (p && p[0]) {
1220 append(&creat, " DEFAULT ", 0);
1221 append(&creat, p, 0);
1222 }
1223 rc = sqlite3_step(stmt);
1224 if (rc == SQLITE_ROW) {
1225 append(&creat, ",", 0);
1226 }
1227 }
1228 if (rc != SQLITE_DONE) {
1229 goto bailout0;
1230 }
1231 sqlite3_finalize(stmt);
1232 append(&creat, ")", 0);
1233 if (creat && fprintf(dd->out, "CREATE TABLE %s;\n", creat) > 0) {
1234 dd->nlines++;
1235 }
1236 append_free(&creat);
1237 }
1238 } else {
1239 if (dd->with_schema) {
1240 if (fprintf(dd->out, "%s;\n", sql) > 0) {
1241 dd->nlines++;
1242 }
1243 }
1244 }
1245 if ((strcmp(type, "table") == 0) ||
1246 ((dd->quote_mode < 0) && (strcmp(type, "view") == 0))) {
1247 sqlite3_stmt *stmt = 0;
1248 char *select = 0, *hdr = 0, *table_info = 0;
1249 char buffer[256];
1250
1251 append(&table_info, "PRAGMA table_info(", 0);
1252 append(&table_info, table, '"');
1253 append(&table_info, ")", 0);
1254#if defined(HAVE_SQLITE3PREPAREV2) && HAVE_SQLITE3PREPAREV2
1255 rc = sqlite3_prepare_v2(dd->db, table_info, -1, &stmt, 0);
1256#else
1257 rc = sqlite3_prepare(dd->db, table_info, -1, &stmt, 0);
1258#endif
1259 append_free(&table_info);
1260 if ((rc != SQLITE_OK) || !stmt) {
1261bailout1:
1262 if (stmt) {
1263 sqlite3_finalize(stmt);
1264 }
1265 append_free(&hdr);
1266 append_free(&select);
1267 return 1;
1268 }
1269 if (dd->quote_mode < -1) {
1270 if (dd->where) {
1271 append(&select, "SELECT ", 0);
1272 sprintf(buffer, "indent_xml(%d)", dd->indent);
1273 append(&select, buffer, 0);
1274 append(&select, " || '<' || quote_xml(", 0);
1275 append(&select, dd->where, '"');
1276 append(&select, ",-1) || '>\n' || ", 0);
1277 } else {
1278 append(&select, "SELECT ", 0);
1279 }
1280 } else if (dd->quote_mode < 0) {
1281 if (dd->where) {
1282 append(&select, "SELECT quote_csv(", 0);
1283 append(&select, dd->where, '"');
1284 append(&select, ") || ',' || ", 0);
1285 } else {
1286 append(&select, "SELECT ", 0);
1287 }
1288 if (dd->indent) {
1289 append(&hdr, select, 0);
1290 }
1291 } else {
1292 char *tmp = 0;
1293
1294 if (dd->with_schema) {
1295 append(&select, "SELECT 'INSERT INTO ' || ", 0);
1296 } else {
1297 append(&select, "SELECT 'INSERT OR REPLACE INTO ' || ", 0);
1298 }
1299 append(&tmp, table, '"');
1300 if (tmp) {
1301 append(&select, tmp, '\'');
1302 append_free(&tmp);
1303 }
1304 }
1305 if ((dd->quote_mode >= 0) && !dd->with_schema) {
1306 char *tmp = 0;
1307
1308 append(&select, " || ' (' || ", 0);
1309 rc = sqlite3_step(stmt);
1310 while (rc == SQLITE_ROW) {
1311 const char *text = (const char *) sqlite3_column_text(stmt, 1);
1312
1313 append(&tmp, text, '"');
1314 if (tmp) {
1315 append(&select, tmp, '\'');
1316 append_free(&tmp);
1317 }
1318 rc = sqlite3_step(stmt);
1319 if (rc == SQLITE_ROW) {
1320 append(&select, " || ',' || ", 0);
1321 }
1322 }
1323 if (rc != SQLITE_DONE) {
1324 goto bailout1;
1325 }
1326 sqlite3_reset(stmt);
1327 append(&select, "|| ')'", 0);
1328 }
1329 if ((dd->quote_mode == -1) && dd->indent) {
1330 rc = sqlite3_step(stmt);
1331 while (rc == SQLITE_ROW) {
1332 const char *text = (const char *) sqlite3_column_text(stmt, 1);
1333
1334 append(&hdr, "quote_csv(", 0);
1335 append(&hdr, text, '"');
1336 rc = sqlite3_step(stmt);
1337 if (rc == SQLITE_ROW) {
1338 append(&hdr, ") || ',' || ", 0);
1339 } else {
1340 append(&hdr, ")", 0);
1341 }
1342 }
1343 if (rc != SQLITE_DONE) {
1344 goto bailout1;
1345 }
1346 sqlite3_reset(stmt);
1347 }
1348 if (dd->quote_mode >= 0) {
1349 append(&select, " || ' VALUES(' || ", 0);
1350 }
1351 rc = sqlite3_step(stmt);
1352 while (rc == SQLITE_ROW) {
1353 const char *text = (const char *) sqlite3_column_text(stmt, 1);
1354 const char *type = (const char *) sqlite3_column_text(stmt, 2);
1355 int tlen = strlen(type ? type : "");
1356
1357 if (dd->quote_mode < -1) {
1358 sprintf(buffer, "indent_xml(%d)", dd->indent + 1);
1359 append(&select, buffer, 0);
1360 append(&select, "|| '<' || quote_xml(", 0);
1361 append(&select, text, '\'');
1362 append(&select, ",-1) || quote_xml(", 0);
1363 append(&select, text, '"');
1364 append(&select, ",1) || '</' || quote_xml(", 0);
1365 append(&select, text, '\'');
1366 append(&select, ",-1) || '>\n'", 0);
1367 } else if (dd->quote_mode < 0) {
1368 /* leave out BLOB columns */
1369 if (((tlen >= 4) && (strncasecmp(type, "BLOB", 4) == 0)) ||
1370 ((tlen >= 6) && (strncasecmp(type, "BINARY", 6) == 0))) {
1371 rc = sqlite3_step(stmt);
1372 if (rc != SQLITE_ROW) {
1373 tlen = strlen(select);
1374 if (tlen > 10) {
1375 select[tlen - 10] = '\0';
1376 }
1377 }
1378 continue;
1379 }
1380 append(&select, "quote_csv(", 0);
1381 append(&select, text, '"');
1382 } else {
1383 append(&select, "quote_sql(", 0);
1384 append(&select, text, '"');
1385 if (dd->quote_mode) {
1386 char mbuf[32];
1387
1388 sprintf(mbuf, ",%d", dd->quote_mode);
1389 append(&select, mbuf, 0);
1390 }
1391 }
1392 rc = sqlite3_step(stmt);
1393 if (rc == SQLITE_ROW) {
1394 if (dd->quote_mode >= -1) {
1395 append(&select, ") || ',' || ", 0);
1396 } else {
1397 append(&select, " || ", 0);
1398 }
1399 } else {
1400 if (dd->quote_mode >= -1) {
1401 append(&select, ") ", 0);
1402 } else {
1403 append(&select, " ", 0);
1404 }
1405 }
1406 }
1407 if (rc != SQLITE_DONE) {
1408 goto bailout1;
1409 }
1410 sqlite3_finalize(stmt);
1411 stmt = 0;
1412 if (dd->quote_mode >= 0) {
1413 append(&select, "|| ')' FROM ", 0);
1414 } else {
1415 if ((dd->quote_mode < -1) && dd->where) {
1416 sprintf(buffer, " || indent_xml(%d)", dd->indent);
1417 append(&select, buffer, 0);
1418 append(&select, " || '</' || quote_xml(", 0);
1419 append(&select, dd->where, '"');
1420 append(&select, ",-1) || '>\n' FROM ", 0);
1421 } else {
1422 append(&select, "FROM ", 0);
1423 }
1424 }
1425 append(&select, table, '"');
1426 if ((dd->quote_mode >= 0) && dd->where) {
1427 append(&select, " ", 0);
1428 append(&select, dd->where, 0);
1429 }
1430 if (hdr) {
1431 rc = table_dump(dd, 0, 0, hdr);
1432 append_free(&hdr);
1433 hdr = 0;
1434 }
1435 rc = table_dump(dd, 0, 0, select);
1436 if (rc == SQLITE_CORRUPT) {
1437 append(&select, " ORDER BY rowid DESC", 0);
1438 rc = table_dump(dd, 0, 0, select);
1439 }
1440 append_free(&select);
1441 }
1442 return 0;
1443}
1444
1454static int
1455schema_dump(DUMP_DATA *dd, char **errp, const char *query, ...)
1456{
1457 int rc;
1458 char *q;
1459 va_list ap;
1460
1461 if (errp) {
1462 sqlite3_free(*errp);
1463 *errp = 0;
1464 }
1465 va_start(ap, query);
1466 q = sqlite3_vmprintf(query, ap);
1467 va_end(ap);
1468 if (!q) {
1469 return SQLITE_NOMEM;
1470 }
1471 rc = sqlite3_exec(dd->db, q, dump_cb, dd, errp);
1472 if (rc == SQLITE_CORRUPT) {
1473 char *tmp;
1474
1475 tmp = sqlite3_mprintf("%s ORDER BY rowid DESC", q);
1476 sqlite3_free(q);
1477 if (!tmp) {
1478 return rc;
1479 }
1480 q = tmp;
1481 if (errp) {
1482 sqlite3_free(*errp);
1483 *errp = 0;
1484 }
1485 rc = sqlite3_exec(dd->db, q, dump_cb, dd, errp);
1486 }
1487 sqlite3_free(q);
1488 return rc;
1489}
1490
1498static void
1499export_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
1500{
1501 DUMP_DATA dd0, *dd = &dd0;
1502 sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx);
1503 int i, mode = 0;
1504 char *filename = 0;
1505#ifdef _WIN32
1506 char fnbuf[MAX_PATH];
1507#endif
1508
1509 dd->db = db;
1510 dd->where = 0;
1511 dd->nlines = -1;
1512 dd->indent = 0;
1513 if (nargs > 0) {
1514 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
1515 filename = (char *) sqlite3_value_text(args[0]);
1516 }
1517 }
1518#ifdef _WIN32
1519 if (!filename) {
1520 OPENFILENAME ofn;
1521
1522 memset(&ofn, 0, sizeof (ofn));
1523 memset(fnbuf, 0, sizeof (fnbuf));
1524 ofn.lStructSize = sizeof (ofn);
1525 ofn.lpstrFile = fnbuf;
1526 ofn.nMaxFile = MAX_PATH;
1527 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
1528 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
1529 if (GetSaveFileName(&ofn)) {
1530 filename = fnbuf;
1531 }
1532 }
1533#endif
1534 if (!filename) {
1535 goto done;
1536 }
1537 dd->out = fopen(filename, "w");
1538 if (!dd->out) {
1539 goto done;
1540 }
1541 if (nargs > 1) {
1542 mode = sqlite3_value_int(args[1]);
1543 }
1544 dd->with_schema = !(mode & 1);
1545 dd->quote_mode = (mode >> 8) & 3;
1546 dd->nlines = 0;
1547 if (fputs("BEGIN TRANSACTION;\n", dd->out) >= 0) {
1548 dd->nlines++;
1549 }
1550 if (nargs <= 2) {
1551 schema_dump(dd, 0,
1552 "SELECT name, type, sql FROM sqlite_master"
1553 " WHERE sql NOT NULL AND type = 'table'");
1554 if (dd->with_schema) {
1555 table_dump(dd, 0, 0,
1556 "SELECT sql FROM sqlite_master WHERE"
1557 " sql NOT NULL AND type IN ('index','trigger','view')");
1558 }
1559 } else {
1560 for (i = 2; i < nargs; i += (mode & 2) ? 2 : 1) {
1561 dd->where = 0;
1562 if ((mode & 2) && (i + 1 < nargs)) {
1563 dd->where = (char *) sqlite3_value_text(args[i + 1]);
1564 }
1565 schema_dump(dd, 0,
1566 "SELECT name, type, sql FROM sqlite_master"
1567 " WHERE tbl_name LIKE %Q AND type = 'table'"
1568 " AND sql NOT NULL",
1569 sqlite3_value_text(args[i]));
1570 if (dd->with_schema) {
1571 table_dump(dd, 0, 1,
1572 "SELECT sql FROM sqlite_master"
1573 " WHERE sql NOT NULL"
1574 " AND type IN ('index','trigger','view')"
1575 " AND tbl_name LIKE %Q",
1576 sqlite3_value_text(args[i]));
1577 }
1578 }
1579 }
1580 if (fputs("COMMIT;\n", dd->out) >= 0) {
1581 dd->nlines++;
1582 }
1583 fclose(dd->out);
1584done:
1585 sqlite3_result_int(ctx, dd->nlines);
1586}
1587
1595static void
1596export_csv_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
1597{
1598 DUMP_DATA dd0, *dd = &dd0;
1599 sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx);
1600 int i;
1601 char *filename = 0;
1602#ifdef _WIN32
1603 char fnbuf[MAX_PATH];
1604#endif
1605
1606 dd->db = db;
1607 dd->where = 0;
1608 dd->nlines = -1;
1609 dd->indent = 0;
1610 dd->with_schema = 0;
1611 dd->quote_mode = -1;
1612 if (nargs > 0) {
1613 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
1614 filename = (char *) sqlite3_value_text(args[0]);
1615 }
1616 }
1617#ifdef _WIN32
1618 if (!filename) {
1619 OPENFILENAME ofn;
1620
1621 memset(&ofn, 0, sizeof (ofn));
1622 memset(fnbuf, 0, sizeof (fnbuf));
1623 ofn.lStructSize = sizeof (ofn);
1624 ofn.lpstrFile = fnbuf;
1625 ofn.nMaxFile = MAX_PATH;
1626 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
1627 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
1628 if (GetSaveFileName(&ofn)) {
1629 filename = fnbuf;
1630 }
1631 }
1632#endif
1633 if (!filename) {
1634 goto done;
1635 }
1636#ifdef _WIN32
1637 dd->out = fopen(filename, "wb");
1638#else
1639 dd->out = fopen(filename, "w");
1640#endif
1641 if (!dd->out) {
1642 goto done;
1643 }
1644 dd->nlines = 0;
1645 if (nargs > 1) {
1646 if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
1647 if (sqlite3_value_int(args[1])) {
1648 dd->indent = 1;
1649 }
1650 }
1651 }
1652 for (i = 2; i <= nargs - 3; i += 3) {
1653 char *schema = 0, *sql;
1654
1655 dd->where = 0;
1656 if (sqlite3_value_type(args[i]) != SQLITE_NULL) {
1657 dd->where = (char *) sqlite3_value_text(args[i]);
1658 if (dd->where && !dd->where[0]) {
1659 dd->where = 0;
1660 }
1661 }
1662 if (sqlite3_value_type(args[i + 2]) != SQLITE_NULL) {
1663 schema = (char *) sqlite3_value_text(args[i + 2]);
1664 }
1665 if (!schema || (schema[0] == '\0')) {
1666 schema = "sqlite_master";
1667 }
1668 sql = sqlite3_mprintf("SELECT name, type, sql FROM %s"
1669 " WHERE tbl_name LIKE %%Q AND "
1670 " (type = 'table' OR type = 'view')"
1671 " AND sql NOT NULL", schema);
1672 if (sql) {
1673 schema_dump(dd, 0, sql, sqlite3_value_text(args[i + 1]));
1674 sqlite3_free(sql);
1675 }
1676 }
1677 fclose(dd->out);
1678done:
1679 sqlite3_result_int(ctx, dd->nlines);
1680}
1681
1689static void
1690export_xml_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
1691{
1692 DUMP_DATA dd0, *dd = &dd0;
1693 sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx);
1694 int i;
1695 char *filename = 0;
1696 char *openmode = "w";
1697#ifdef _WIN32
1698 char fnbuf[MAX_PATH];
1699#endif
1700
1701 dd->db = db;
1702 dd->where = 0;
1703 dd->nlines = -1;
1704 dd->indent = 0;
1705 dd->with_schema = 0;
1706 dd->quote_mode = -2;
1707 if (nargs > 0) {
1708 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
1709 filename = (char *) sqlite3_value_text(args[0]);
1710 }
1711 }
1712#ifdef _WIN32
1713 if (!filename) {
1714 OPENFILENAME ofn;
1715
1716 memset(&ofn, 0, sizeof (ofn));
1717 memset(fnbuf, 0, sizeof (fnbuf));
1718 ofn.lStructSize = sizeof (ofn);
1719 ofn.lpstrFile = fnbuf;
1720 ofn.nMaxFile = MAX_PATH;
1721 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
1722 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
1723 if (GetSaveFileName(&ofn)) {
1724 filename = fnbuf;
1725 }
1726 }
1727#endif
1728 if (!filename) {
1729 goto done;
1730 }
1731 if (nargs > 1) {
1732 if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
1733 if (sqlite3_value_int(args[1])) {
1734 openmode = "a";
1735 }
1736 }
1737 }
1738 if (nargs > 2) {
1739 if (sqlite3_value_type(args[2]) != SQLITE_NULL) {
1740 dd->indent = sqlite3_value_int(args[2]);
1741 if (dd->indent < 0) {
1742 dd->indent = 0;
1743 }
1744 }
1745 }
1746 dd->out = fopen(filename, openmode);
1747 if (!dd->out) {
1748 goto done;
1749 }
1750 dd->nlines = 0;
1751 for (i = 3; i <= nargs - 4; i += 4) {
1752 char *root = 0, *schema = 0, *sql;
1753
1754 if (sqlite3_value_type(args[i]) != SQLITE_NULL) {
1755 root = (char *) sqlite3_value_text(args[i]);
1756 if (root && !root[0]) {
1757 root = 0;
1758 }
1759 }
1760 dd->where = 0;
1761 if (sqlite3_value_type(args[i + 1]) != SQLITE_NULL) {
1762 dd->where = (char *) sqlite3_value_text(args[i + 1]);
1763 if (dd->where && !dd->where[0]) {
1764 dd->where = 0;
1765 }
1766 }
1767 if (root) {
1768 indent(dd);
1769 dd->indent++;
1770 fputs("<", dd->out);
1771 quote_xml_str(dd, root);
1772 fputs(">\n", dd->out);
1773 }
1774 if (sqlite3_value_type(args[i + 3]) != SQLITE_NULL) {
1775 schema = (char *) sqlite3_value_text(args[i + 3]);
1776 }
1777 if (!schema || (schema[0] == '\0')) {
1778 schema = "sqlite_master";
1779 }
1780 sql = sqlite3_mprintf("SELECT name, type, sql FROM %s"
1781 " WHERE tbl_name LIKE %%Q AND"
1782 " (type = 'table' OR type = 'view')"
1783 " AND sql NOT NULL", schema);
1784 if (sql) {
1785 schema_dump(dd, 0, sql, sqlite3_value_text(args[i + 2]));
1786 sqlite3_free(sql);
1787 }
1788 if (root) {
1789 dd->indent--;
1790 indent(dd);
1791 fputs("</", dd->out);
1792 quote_xml_str(dd, root);
1793 fputs(">\n", dd->out);
1794 }
1795 }
1796 fclose(dd->out);
1797done:
1798 sqlite3_result_int(ctx, dd->nlines);
1799}
1800
1801/* see doc in impexp.h */
1802
1803int
1804impexp_export_sql(sqlite3 *db, char *filename, int mode, ...)
1805{
1806 DUMP_DATA dd0, *dd = &dd0;
1807 va_list ap;
1808 char *table;
1809#ifdef _WIN32
1810 char fnbuf[MAX_PATH];
1811#endif
1812
1813 if (!db) {
1814 return 0;
1815 }
1816 dd->db = db;
1817 dd->where = 0;
1818 dd->nlines = -1;
1819#ifdef _WIN32
1820 if (!filename) {
1821 OPENFILENAME ofn;
1822
1823 memset(&ofn, 0, sizeof (ofn));
1824 memset(fnbuf, 0, sizeof (fnbuf));
1825 ofn.lStructSize = sizeof (ofn);
1826 ofn.lpstrFile = fnbuf;
1827 ofn.nMaxFile = MAX_PATH;
1828 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
1829 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
1830 if (GetSaveFileName(&ofn)) {
1831 filename = fnbuf;
1832 }
1833 }
1834#endif
1835 if (!filename) {
1836 goto done;
1837 }
1838 dd->out = fopen(filename, "w");
1839 if (!dd->out) {
1840 goto done;
1841 }
1842 dd->with_schema = !(mode & 1);
1843 dd->nlines = 0;
1844 if (fputs("BEGIN TRANSACTION;\n", dd->out) >= 0) {
1845 dd->nlines++;
1846 }
1847 va_start(ap, mode);
1848 table = va_arg(ap, char *);
1849 if (!table) {
1850 schema_dump(dd, 0,
1851 "SELECT name, type, sql FROM sqlite_master"
1852 " WHERE sql NOT NULL AND type = 'table'");
1853 if (dd->with_schema) {
1854 table_dump(dd, 0, 0,
1855 "SELECT sql FROM sqlite_master WHERE"
1856 " sql NOT NULL AND type IN ('index','trigger','view')");
1857 }
1858 } else {
1859 while (table) {
1860 dd->where = 0;
1861 if ((mode & 2)) {
1862 dd->where = va_arg(ap, char *);
1863 }
1864 schema_dump(dd, 0,
1865 "SELECT name, type, sql FROM sqlite_master"
1866 " WHERE tbl_name LIKE %Q AND type = 'table'"
1867 " AND sql NOT NULL", table);
1868 if (dd->with_schema) {
1869 table_dump(dd, 0, 1,
1870 "SELECT sql FROM sqlite_master"
1871 " WHERE sql NOT NULL"
1872 " AND type IN ('index','trigger','view')"
1873 " AND tbl_name LIKE %Q", table);
1874 }
1875 table = va_arg(ap, char *);
1876 }
1877 }
1878 va_end(ap);
1879 if (fputs("COMMIT;\n", dd->out) >= 0) {
1880 dd->nlines++;
1881 }
1882 fclose(dd->out);
1883done:
1884 return dd->nlines;
1885}
1886
1887/* see doc in impexp.h */
1888
1889int
1890impexp_export_csv(sqlite3 *db, char *filename, int hdr, ...)
1891{
1892 DUMP_DATA dd0, *dd = &dd0;
1893 va_list ap;
1894 char *prefix, *table, *schema;
1895#ifdef _WIN32
1896 char fnbuf[MAX_PATH];
1897#endif
1898
1899 if (!db) {
1900 return 0;
1901 }
1902 dd->db = db;
1903 dd->where = 0;
1904 dd->nlines = -1;
1905 dd->indent = 0;
1906 dd->with_schema = 0;
1907 dd->quote_mode = -1;
1908 dd->indent = hdr != 0;
1909#ifdef _WIN32
1910 if (!filename) {
1911 OPENFILENAME ofn;
1912
1913 memset(&ofn, 0, sizeof (ofn));
1914 memset(fnbuf, 0, sizeof (fnbuf));
1915 ofn.lStructSize = sizeof (ofn);
1916 ofn.lpstrFile = fnbuf;
1917 ofn.nMaxFile = MAX_PATH;
1918 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
1919 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
1920 if (GetSaveFileName(&ofn)) {
1921 filename = fnbuf;
1922 }
1923 }
1924#endif
1925 if (!filename) {
1926 goto done;
1927 }
1928#ifdef _WIN32
1929 dd->out = fopen(filename, "wb");
1930#else
1931 if ((hdr < 0) && access(filename, W_OK) == 0) {
1932 dd->out = fopen(filename, "a");
1933 dd->indent = 0;
1934 } else {
1935 dd->out = fopen(filename, "w");
1936 }
1937#endif
1938 if (!dd->out) {
1939 goto done;
1940 }
1941 dd->nlines = 0;
1942 va_start(ap, hdr);
1943 prefix = va_arg(ap, char *);
1944 table = va_arg(ap, char *);
1945 schema = va_arg(ap, char *);
1946 while (table != NULL) {
1947 char *sql;
1948
1949 dd->where = (prefix && prefix[0]) ? prefix : 0;
1950 if (!schema || (schema[0] == '\0')) {
1951 schema = "sqlite_master";
1952 }
1953 sql = sqlite3_mprintf("SELECT name, type, sql FROM %s"
1954 " WHERE tbl_name LIKE %%Q AND"
1955 " (type = 'table' OR type = 'view')"
1956 " AND sql NOT NULL", schema);
1957 if (sql) {
1958 schema_dump(dd, 0, sql, table);
1959 sqlite3_free(sql);
1960 }
1961 prefix = va_arg(ap, char *);
1962 table = va_arg(ap, char *);
1963 schema = va_arg(ap, char *);
1964 }
1965 va_end(ap);
1966 fclose(dd->out);
1967done:
1968 return dd->nlines;
1969}
1970
1971/* see doc in impexp.h */
1972
1973int
1974impexp_export_xml(sqlite3 *db, char *filename, int append, int indnt,
1975 char *root, char *item, char *tablename, char *schema)
1976{
1977 DUMP_DATA dd0, *dd = &dd0;
1978 char *sql;
1979#ifdef _WIN32
1980 char fnbuf[MAX_PATH];
1981#endif
1982
1983 if (!db) {
1984 return 0;
1985 }
1986 dd->db = db;
1987 dd->where = item;
1988 dd->nlines = -1;
1989 dd->indent = (indnt > 0) ? indnt : 0;
1990 dd->with_schema = 0;
1991 dd->quote_mode = -2;
1992#ifdef _WIN32
1993 if (!filename) {
1994 OPENFILENAME ofn;
1995
1996 memset(&ofn, 0, sizeof (ofn));
1997 memset(fnbuf, 0, sizeof (fnbuf));
1998 ofn.lStructSize = sizeof (ofn);
1999 ofn.lpstrFile = fnbuf;
2000 ofn.nMaxFile = MAX_PATH;
2001 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
2002 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
2003 if (GetSaveFileName(&ofn)) {
2004 filename = fnbuf;
2005 }
2006 }
2007#endif
2008 if (!filename) {
2009 goto done;
2010 }
2011 dd->out = fopen(filename, append ? "a" : "w");
2012 if (!dd->out) {
2013 goto done;
2014 }
2015 dd->nlines = 0;
2016 if (root) {
2017 indent(dd);
2018 dd->indent++;
2019 fputs("<", dd->out);
2020 quote_xml_str(dd, root);
2021 fputs(">\n", dd->out);
2022 }
2023 if (!schema || (schema[0] == '\0')) {
2024 schema = "sqlite_master";
2025 }
2026 sql = sqlite3_mprintf("SELECT name, type, sql FROM %s"
2027 " WHERE tbl_name LIKE %%Q AND"
2028 " (type = 'table' OR type = 'view')"
2029 " AND sql NOT NULL", schema);
2030 if (sql) {
2031 schema_dump(dd, 0, sql, tablename);
2032 sqlite3_free(sql);
2033 }
2034 if (root) {
2035 dd->indent--;
2036 indent(dd);
2037 fputs("</", dd->out);
2038 quote_xml_str(dd, root);
2039 fputs(">\n", dd->out);
2040 }
2041 fclose(dd->out);
2042done:
2043 return dd->nlines;
2044}
2045
2052static void
2053json_pstr(const char *string, json_pfs *pfs)
2054{
2055 while (*string) {
2056 pfs->pfunc(*string, pfs->parg);
2057 string++;
2058 }
2059}
2060
2067static void
2068json_pstrq(const char *string, json_pfs *pfs)
2069{
2070 impexp_putc pfunc = pfs->pfunc;
2071 void *parg = pfs->parg;
2072 char buf[64];
2073
2074 if (!string) {
2075 json_pstr("null", pfs);
2076 return;
2077 }
2078 pfunc('"', parg);
2079 while (*string) {
2080 switch (*string) {
2081 case '"':
2082 case '\\':
2083 pfunc('\\', parg);
2084 pfunc(*string, parg);
2085 break;
2086 case '\b':
2087 pfunc('\\', parg);
2088 pfunc('b', parg);
2089 break;
2090 case '\f':
2091 pfunc('\\', parg);
2092 pfunc('f', parg);
2093 break;
2094 case '\n':
2095 pfunc('\\', parg);
2096 pfunc('n', parg);
2097 break;
2098 case '\r':
2099 pfunc('\\', parg);
2100 pfunc('r', parg);
2101 break;
2102 case '\t':
2103 pfunc('\\', parg);
2104 pfunc('t', parg);
2105 break;
2106 default:
2107 if (((*string < ' ') && (*string > 0)) || (*string == 0x7f)) {
2108 sprintf(buf, "\\u%04x", *string);
2109 json_pstr(buf, pfs);
2110 } else if (*string < 0) {
2111 unsigned char c = string[0];
2112 unsigned long uc = 0;
2113
2114 if (c < 0xc0) {
2115 uc = c;
2116 } else if (c < 0xe0) {
2117 if ((string[1] & 0xc0) == 0x80) {
2118 uc = ((c & 0x1f) << 6) | (string[1] & 0x3f);
2119 ++string;
2120 } else {
2121 uc = c;
2122 }
2123 } else if (c < 0xf0) {
2124 if (((string[1] & 0xc0) == 0x80) &&
2125 ((string[2] & 0xc0) == 0x80)) {
2126 uc = ((c & 0x0f) << 12) |
2127 ((string[1] & 0x3f) << 6) | (string[2] & 0x3f);
2128 string += 2;
2129 } else {
2130 uc = c;
2131 }
2132 } else if (c < 0xf8) {
2133 if (((string[1] & 0xc0) == 0x80) &&
2134 ((string[2] & 0xc0) == 0x80) &&
2135 ((string[3] & 0xc0) == 0x80)) {
2136 uc = ((c & 0x03) << 18) |
2137 ((string[1] & 0x3f) << 12) |
2138 ((string[2] & 0x3f) << 6) |
2139 (string[4] & 0x3f);
2140 string += 3;
2141 } else {
2142 uc = c;
2143 }
2144 } else if (c < 0xfc) {
2145 if (((string[1] & 0xc0) == 0x80) &&
2146 ((string[2] & 0xc0) == 0x80) &&
2147 ((string[3] & 0xc0) == 0x80) &&
2148 ((string[4] & 0xc0) == 0x80)) {
2149 uc = ((c & 0x01) << 24) |
2150 ((string[1] & 0x3f) << 18) |
2151 ((string[2] & 0x3f) << 12) |
2152 ((string[4] & 0x3f) << 6) |
2153 (string[5] & 0x3f);
2154 string += 4;
2155 } else {
2156 uc = c;
2157 }
2158 } else {
2159 /* ignore */
2160 ++string;
2161 }
2162 if (uc < 0x10000) {
2163 sprintf(buf, "\\u%04lx", uc);
2164 } else if (uc < 0x100000) {
2165 uc -= 0x10000;
2166
2167 sprintf(buf, "\\u%04lx", 0xd800 | ((uc >> 10) & 0x3ff));
2168 json_pstr(buf, pfs);
2169 sprintf(buf, "\\u%04lx", 0xdc00 | (uc & 0x3ff));
2170 } else {
2171 strcpy(buf, "\\ufffd");
2172 }
2173 json_pstr(buf, pfs);
2174 } else {
2175 pfunc(*string, parg);
2176 }
2177 break;
2178 }
2179 ++string;
2180 }
2181 pfunc('"', parg);
2182}
2183
2190static void
2191json_pstrc(const char *string, json_pfs *pfs)
2192{
2193 if (*string && strchr(".0123456789-+", *string)) {
2194 json_pstr(string, pfs);
2195 } else {
2196 json_pstrq(string, pfs);
2197 }
2198}
2199
2207static void
2208json_pb64(const unsigned char *blk, int len, json_pfs *pfs)
2209{
2210 impexp_putc pfunc = pfs->pfunc;
2211 void *parg = pfs->parg;
2212 int i, reg[5];
2213 char buf[16];
2214 static const char *b64 =
2215 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
2216
2217 if (!blk) {
2218 json_pstr("null", pfs);
2219 return;
2220 }
2221 buf[4] = '\0';
2222 pfunc('"', parg);
2223 for (i = 0; i < len; i += 3) {
2224 reg[1] = reg[2] = reg[3] = reg[4] = 0;
2225 reg[0] = blk[i];
2226 if (i + 1 < len) {
2227 reg[1] = blk[i + 1];
2228 reg[3] = 1;
2229 }
2230 if (i + 2 < len) {
2231 reg[2] = blk[i + 2];
2232 reg[4] = 1;
2233 }
2234 buf[0] = b64[reg[0] >> 2];
2235 buf[1] = b64[((reg[0] << 4) & 0x30) | (reg[1] >> 4)];
2236 if (reg[3]) {
2237 buf[2] = b64[((reg[1] << 2) & 0x3c) | (reg[2] >> 6)];
2238 } else {
2239 buf[2] = '=';
2240 }
2241 if (reg[4]) {
2242 buf[3] = b64[reg[2] & 0x3f];
2243 } else {
2244 buf[3] = '=';
2245 }
2246 json_pstr(buf, pfs);
2247 }
2248 pfunc('"', parg);
2249}
2250
2260static int
2261json_output(sqlite3 *db, char *sql, impexp_putc pfunc, void *parg)
2262{
2263 json_pfs pfs0, *pfs = &pfs0;
2264 const char *tail = sql;
2265 int i, nresults = 0, result = SQLITE_ERROR;
2266
2267 pfs->pfunc = pfunc;
2268 pfs->parg = parg;
2269 json_pstr("{\"sql\":", pfs);
2270 json_pstrq(sql, pfs);
2271 json_pstr(",\"results\":[", pfs);
2272 do {
2273 sqlite3_stmt *stmt;
2274 int firstrow = 1, nrows = 0;
2275 char buf[256];
2276
2277 ++nresults;
2278 json_pstr((nresults == 1) ? "{" : ",{", pfs);
2279 result = sqlite3_prepare(db, tail, -1, &stmt, &tail);
2280 if (result != SQLITE_OK) {
2281doerr:
2282 if (nrows == 0) {
2283 json_pstr("\"columns\":null,\"rows\":null,\"changes\":0,"
2284 "\"last_insert_rowid\":null,", pfs);
2285 }
2286 json_pstr("\"error:\"", pfs);
2287 json_pstrq(sqlite3_errmsg(db), pfs);
2288 pfunc('}', parg);
2289 break;
2290 }
2291 result = sqlite3_step(stmt);
2292 while ((result == SQLITE_ROW) || (result == SQLITE_DONE)) {
2293 if (firstrow) {
2294 for (i = 0; i < sqlite3_column_count(stmt); i++) {
2295 char *type;
2296
2297 json_pstr((i == 0) ? "\"columns\":[" : ",", pfs);
2298 json_pstr("{\"name\":", pfs);
2299 json_pstrq(sqlite3_column_name(stmt, i), pfs);
2300 json_pstr(",\"decltype\":", pfs);
2301 json_pstrq(sqlite3_column_decltype(stmt, i), pfs);
2302 json_pstr(",\"type\":", pfs);
2303 switch (sqlite3_column_type(stmt, i)) {
2304 case SQLITE_INTEGER:
2305 type = "integer";
2306 break;
2307 case SQLITE_FLOAT:
2308 type = "float";
2309 break;
2310 case SQLITE_BLOB:
2311 type = "blob";
2312 break;
2313 case SQLITE_TEXT:
2314 type = "text";
2315 break;
2316 case SQLITE_NULL:
2317 type = "null";
2318 break;
2319 default:
2320 type = "unknown";
2321 break;
2322 }
2323 json_pstrq(type, pfs);
2324 pfunc('}', parg);
2325 }
2326 if (i) {
2327 pfunc(']', parg);
2328 }
2329 firstrow = 0;
2330 }
2331 if (result == SQLITE_DONE) {
2332 break;
2333 }
2334 ++nrows;
2335 json_pstr((nrows == 1) ? ",\"rows\":[" : ",", pfs);
2336 for (i = 0; i < sqlite3_column_count(stmt); i++) {
2337 pfunc((i == 0) ? '[' : ',', parg);
2338 switch (sqlite3_column_type(stmt, i)) {
2339 case SQLITE_INTEGER:
2340 json_pstr((char *) sqlite3_column_text(stmt, i), pfs);
2341 break;
2342 case SQLITE_FLOAT:
2343 json_pstrc((char *) sqlite3_column_text(stmt, i), pfs);
2344 break;
2345 case SQLITE_BLOB:
2346 json_pb64((unsigned char *) sqlite3_column_blob(stmt, i),
2347 sqlite3_column_bytes(stmt, i), pfs);
2348 break;
2349 case SQLITE_TEXT:
2350 json_pstrq((char *) sqlite3_column_text(stmt, i), pfs);
2351 break;
2352 case SQLITE_NULL:
2353 default:
2354 json_pstr("null", pfs);
2355 break;
2356 }
2357 }
2358 json_pstr((i == 0) ? "null]" : "]", pfs);
2359 result = sqlite3_step(stmt);
2360 }
2361 if (nrows > 0) {
2362 pfunc(']', parg);
2363 }
2364 result = sqlite3_finalize(stmt);
2365 if (result != SQLITE_OK) {
2366 if (nrows > 0) {
2367 sprintf(buf,
2368#ifdef _WIN32
2369 ",\"changes\":%d,\"last_insert_rowid\":%I64d",
2370#else
2371 ",\"changes\":%d,\"last_insert_rowid\":%lld",
2372#endif
2373 sqlite3_changes(db),
2374 sqlite3_last_insert_rowid(db));
2375 json_pstr(buf, pfs);
2376 }
2377 goto doerr;
2378 }
2379 if (nrows == 0) {
2380 json_pstr("\"columns\":null,\"rows\":null", pfs);
2381 }
2382 sprintf(buf,
2383#ifdef _WIN32
2384 ",\"changes\":%d,\"last_insert_rowid\":%I64d",
2385#else
2386 ",\"changes\":%d,\"last_insert_rowid\":%lld",
2387#endif
2388 sqlite3_changes(db),
2389 sqlite3_last_insert_rowid(db));
2390 json_pstr(buf, pfs);
2391 json_pstr(",\"error\":null}", pfs);
2392 } while (tail && *tail);
2393 json_pstr("]}", pfs);
2394 return result;
2395}
2396
2404static void
2405export_json_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
2406{
2407 sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx);
2408 int result = -1;
2409 char *filename = 0;
2410 char *sql = 0;
2411 FILE *out = 0;
2412#ifdef _WIN32
2413 char fnbuf[MAX_PATH];
2414#endif
2415
2416 if (nargs > 0) {
2417 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
2418 filename = (char *) sqlite3_value_text(args[0]);
2419 }
2420 }
2421#ifdef _WIN32
2422 if (!filename) {
2423 OPENFILENAME ofn;
2424
2425 memset(&ofn, 0, sizeof (ofn));
2426 memset(fnbuf, 0, sizeof (fnbuf));
2427 ofn.lStructSize = sizeof (ofn);
2428 ofn.lpstrFile = fnbuf;
2429 ofn.nMaxFile = MAX_PATH;
2430 ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER |
2431 OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
2432 if (GetSaveFileName(&ofn)) {
2433 filename = fnbuf;
2434 }
2435 }
2436#endif
2437 if (!filename) {
2438 goto done;
2439 }
2440 out = fopen(filename, "w");
2441 if (!out) {
2442 goto done;
2443 }
2444 if (nargs > 1) {
2445 sql = (char *) sqlite3_value_text(args[1]);
2446 }
2447 if (sql) {
2448 result = json_output(db, sql, (impexp_putc) fputc, out);
2449 }
2450 fclose(out);
2451done:
2452 sqlite3_result_int(ctx, result);
2453}
2454
2455/* see doc in impexp.h */
2456
2457int
2458impexp_export_json(sqlite3 *db, char *sql, impexp_putc pfunc,
2459 void *parg)
2460{
2461 return json_output(db, sql, pfunc, parg);
2462}
2463
2472#ifdef STANDALONE
2473static int
2474#else
2475int
2476#endif
2477sqlite3_extension_init(sqlite3 *db, char **errmsg,
2478 const sqlite3_api_routines *api)
2479{
2480 int rc, i;
2481 static const struct {
2482 const char *name;
2483 void (*func)(sqlite3_context *, int, sqlite3_value **);
2484 int nargs;
2485 int textrep;
2486 } ftab[] = {
2487 { "quote_sql", quote_func, -1, SQLITE_UTF8 },
2488 { "import_sql", import_func, -1, SQLITE_UTF8 },
2489 { "export_sql", export_func, -1, SQLITE_UTF8 },
2490 { "quote_csv", quote_csv_func, -1, SQLITE_UTF8 },
2491 { "export_csv", export_csv_func, -1, SQLITE_UTF8 },
2492 { "indent_xml", indent_xml_func, 1, SQLITE_UTF8 },
2493 { "quote_xml", quote_xml_func, -1, SQLITE_UTF8 },
2494 { "export_xml", export_xml_func, -1, SQLITE_UTF8 },
2495 { "export_json", export_json_func, -1, SQLITE_UTF8 }
2496 };
2497
2498#ifndef STANDALONE
2499 if (api != NULL) {
2500 SQLITE_EXTENSION_INIT2(api);
2501 }
2502#endif
2503
2504 for (i = 0; i < sizeof (ftab) / sizeof (ftab[0]); i++) {
2505 rc = sqlite3_create_function(db, ftab[i].name, ftab[i].nargs,
2506 ftab[i].textrep, db, ftab[i].func, 0, 0);
2507 if (rc != SQLITE_OK) {
2508 for (--i; i >= 0; --i) {
2509 sqlite3_create_function(db, ftab[i].name, ftab[i].nargs,
2510 ftab[i].textrep, 0, 0, 0, 0);
2511 }
2512 break;
2513 }
2514 }
2515 return rc;
2516}
2517
2518/* see doc in impexp.h */
2519
2520int
2521impexp_init(sqlite3 *db)
2522{
2523 return sqlite3_extension_init(db, NULL, NULL);
2524}
int impexp_export_xml(sqlite3 *db, char *filename, int append, int indnt, char *root, char *item, char *tablename, char *schema)
Writes a table as simple XML to provided filename.
Definition impexp.c:1974
int impexp_export_csv(sqlite3 *db, char *filename, int hdr,...)
Writes entire tables as CSV to provided filename.
Definition impexp.c:1890
static int process_input(sqlite3 *db, FILE *fin)
Process contents of FILE pointer as SQL commands.
Definition impexp.c:341
static int json_output(sqlite3 *db, char *sql, impexp_putc pfunc, void *parg)
Execute SQL and write output as JSON.
Definition impexp.c:2261
static void json_pstr(const char *string, json_pfs *pfs)
Write string using JSON output function.
Definition impexp.c:2053
static char * one_input_line(FILE *fin)
Read one line of input into dynamically allocated buffer which the caller must free with sqlite3_free...
Definition impexp.c:229
static void export_xml_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function for XML output, see impexp_export_xml.
Definition impexp.c:1690
static int ends_with_semicolon(const char *str, int n)
Test if string ends with a semicolon.
Definition impexp.c:286
static char * append(char **in, char const *append, char quote)
Append a string to dynamically allocated string buffer with optional quoting.
Definition impexp.c:1034
static void json_pb64(const unsigned char *blk, int len, json_pfs *pfs)
Write a blob as base64 string using JSON output function.
Definition impexp.c:2208
static int table_dump(DUMP_DATA *dd, char **errp, int fmt, const char *query,...)
Execute SQL to dump contents of one table.
Definition impexp.c:952
static void quote_xml_str(DUMP_DATA *dd, char *str)
Quote string for XML output during dump.
Definition impexp.c:1104
int impexp_export_sql(sqlite3 *db, char *filename, int mode,...)
Writes SQL to filename similar to SQLite's shell ".dump" meta command.
Definition impexp.c:1804
static void json_pstrq(const char *string, json_pfs *pfs)
Quote and write string using JSON output function.
Definition impexp.c:2068
static void append_free(char **in)
Free dynamically allocated string buffer.
Definition impexp.c:1013
static void indent_xml_func(sqlite3_context *context, int argc, sqlite3_value **argv)
SQLite function to make XML indentation.
Definition impexp.c:629
static int schema_dump(DUMP_DATA *dd, char **errp, const char *query,...)
Execute SQL on sqlite_master table in order to dump data.
Definition impexp.c:1455
static void export_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function for SQL output, see impexp_export_sql.
Definition impexp.c:1499
int sqlite3_extension_init(sqlite3 *db, char **errmsg, const sqlite3_api_routines *api)
Initializer for SQLite extension load mechanism.
Definition impexp.c:2477
static void json_pstrc(const char *string, json_pfs *pfs)
Conditionally quote and write string using JSON output function.
Definition impexp.c:2191
static int all_whitespace(const char *str)
Test if string contains entirely whitespace or SQL comment.
Definition impexp.c:301
static void indent(DUMP_DATA *dd)
Write indentation to dump.
Definition impexp.c:932
static void quote_func(sqlite3_context *context, int argc, sqlite3_value **argv)
SQLite function to quote SQLite value depending on optional quote mode.
Definition impexp.c:420
int impexp_init(sqlite3 *db)
Registers the SQLite functions.
Definition impexp.c:2521
int impexp_export_json(sqlite3 *db, char *sql, impexp_putc pfunc, void *parg)
Executes arbitrary SQL statements and formats the result in JavaScript Object Notation (JSON).
Definition impexp.c:2458
static int dump_cb(void *udata, int nargs, char **args, char **cols)
Callback for sqlite3_exec() to dump one data row.
Definition impexp.c:1151
static void import_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function to read and process SQL commands from a file.
Definition impexp.c:822
static void export_csv_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function for CSV output, see impexp_export_csv.
Definition impexp.c:1596
static void export_json_func(sqlite3_context *ctx, int nargs, sqlite3_value **args)
SQLite function for JSON output, see impexp_export_json.
Definition impexp.c:2405
#define ISSPACE(c)
Definition impexp.c:219
int impexp_import_sql(sqlite3 *db, char *filename)
Reads SQL commands from filename and executes them against the current database.
Definition impexp.c:869
static const char space_chars[]
Definition impexp.c:217
static void quote_csv_func(sqlite3_context *context, int argc, sqlite3_value **argv)
SQLite function to quote an SQLite value in CSV format.
Definition impexp.c:540
static void quote_xml_func(sqlite3_context *context, int argc, sqlite3_value **argv)
SQLite function to quote a string for XML.
Definition impexp.c:653
SQLite extension module for importing/exporting database information from/to SQL source text and expo...
void(* impexp_putc)(int c, void *arg)
The function pointer for the output function to "impexp_export_json" has a signature compatible with ...
Definition impexp.h:177
static const char * xdigits
Structure for dump callback.
Definition impexp.c:916
int with_schema
if true, output schema
Definition impexp.c:918
int quote_mode
mode for quoting data
Definition impexp.c:919
int nlines
counter for output lines
Definition impexp.c:921
sqlite3 * db
SQLite database pointer.
Definition impexp.c:917
char * where
optional where clause of dump
Definition impexp.c:920
FILE * out
output file pointer
Definition impexp.c:923
int indent
current indent level
Definition impexp.c:922
JSON output helper structure.
Definition impexp.c:212
impexp_putc pfunc
function like fputc()
Definition impexp.c:213
void * parg
argument to function
Definition impexp.c:214
Driver internal structure representing SQL statement (HSTMT).

Generated on Sun Nov 26 2023 by doxygen.
Contact: chw@ch-werner.de