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>
188 static 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 
212 typedef struct {
214  void *parg;
215 } json_pfs;
216 
217 static const char space_chars[] = " \f\n\r\t\v";
218 
219 #define ISSPACE(c) ((c) && (strchr(space_chars, (c)) != 0))
220 
228 static char *
229 one_input_line(FILE *fin)
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 
285 static int
286 ends_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 
300 static int
301 all_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 
340 static int
341 process_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 
419 static void
420 quote_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 
539 static void
540 quote_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 
628 static void
629 indent_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 
652 static void
653 quote_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 
821 static void
822 import_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);
862 done:
863  sqlite3_result_int(ctx, sqlite3_changes(db) - changes0);
864 }
865 
866 /* see doc in impexp.h */
867 
868 int
869 impexp_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);
906 done:
907  return sqlite3_changes(db) - changes0;
908 }
909 
916 typedef struct {
917  sqlite3 *db;
920  char *where;
921  int nlines;
922  int indent;
923  FILE *out;
924 } DUMP_DATA;
925 
931 static void
933 {
934  int i;
935 
936  for (i = 0; i < dd->indent; i++) {
937  fputc(' ', dd->out);
938  }
939 }
940 
951 static int
952 table_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 
1012 static void
1013 append_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 
1033 static char *
1034 append(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 
1103 static void
1104 quote_xml_str(DUMP_DATA *dd, char *str)
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 
1150 static int
1151 dump_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) {
1192 bailout0:
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) {
1261 bailout1:
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 
1454 static int
1455 schema_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 
1498 static void
1499 export_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);
1584 done:
1585  sqlite3_result_int(ctx, dd->nlines);
1586 }
1587 
1595 static void
1596 export_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);
1678 done:
1679  sqlite3_result_int(ctx, dd->nlines);
1680 }
1681 
1689 static void
1690 export_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);
1797 done:
1798  sqlite3_result_int(ctx, dd->nlines);
1799 }
1800 
1801 /* see doc in impexp.h */
1802 
1803 int
1804 impexp_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);
1883 done:
1884  return dd->nlines;
1885 }
1886 
1887 /* see doc in impexp.h */
1888 
1889 int
1890 impexp_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);
1967 done:
1968  return dd->nlines;
1969 }
1970 
1971 /* see doc in impexp.h */
1972 
1973 int
1974 impexp_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);
2042 done:
2043  return dd->nlines;
2044 }
2045 
2052 static void
2053 json_pstr(const char *string, json_pfs *pfs)
2054 {
2055  while (*string) {
2056  pfs->pfunc(*string, pfs->parg);
2057  string++;
2058  }
2059 }
2060 
2067 static void
2068 json_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 
2190 static void
2191 json_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 
2207 static void
2208 json_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 
2260 static int
2261 json_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) {
2281 doerr:
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 
2404 static void
2405 export_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);
2451 done:
2452  sqlite3_result_int(ctx, result);
2453 }
2454 
2455 /* see doc in impexp.h */
2456 
2457 int
2458 impexp_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
2473 static int
2474 #else
2475 int
2476 #endif
2477 sqlite3_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 
2520 int
2521 impexp_init(sqlite3 *db)
2522 {
2523  return sqlite3_extension_init(db, NULL, NULL);
2524 }
dump_cb
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
append_free
static void append_free(char **in)
Free dynamically allocated string buffer.
Definition: impexp.c:1013
indent_xml_func
static void indent_xml_func(sqlite3_context *context, int argc, sqlite3_value **argv)
SQLite function to make XML indentation.
Definition: impexp.c:629
DUMP_DATA::out
FILE * out
output file pointer
Definition: impexp.c:923
DUMP_DATA
Definition: impexp.c:916
export_json_func
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
export_csv_func
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
DUMP_DATA::indent
int indent
current indent level
Definition: impexp.c:922
all_whitespace
static int all_whitespace(const char *str)
Test if string contains entirely whitespace or SQL comment.
Definition: impexp.c:301
json_pstr
static void json_pstr(const char *string, json_pfs *pfs)
Write string using JSON output function.
Definition: impexp.c:2053
json_pfs::parg
void * parg
argument to function
Definition: impexp.c:214
DUMP_DATA::with_schema
int with_schema
if true, output schema
Definition: impexp.c:918
impexp_putc
void(* impexp_putc)(int c, void *arg)
Definition: impexp.h:177
append
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
json_pb64
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
impexp_export_csv
int impexp_export_csv(sqlite3 *db, char *filename, int hdr,...)
Writes entire tables as CSV to provided filename.
Definition: impexp.c:1890
space_chars
static const char space_chars[]
Definition: impexp.c:217
process_input
static int process_input(sqlite3 *db, FILE *fin)
Process contents of FILE pointer as SQL commands.
Definition: impexp.c:341
schema_dump
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
impexp.h
json_pfs::pfunc
impexp_putc pfunc
function like fputc()
Definition: impexp.c:213
impexp_import_sql
int impexp_import_sql(sqlite3 *db, char *filename)
Reads SQL commands from filename and executes them against the current database.
Definition: impexp.c:869
impexp_export_xml
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
one_input_line
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
export_xml_func
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
stmt
Definition: sqlite3odbc.h:231
quote_func
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
quote_csv_func
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
DUMP_DATA::db
sqlite3 * db
SQLite database pointer.
Definition: impexp.c:917
xdigits
static const char * xdigits
Definition: sqlite3odbc.c:279
quote_xml_func
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
sqlite3_extension_init
int sqlite3_extension_init(sqlite3 *db, char **errmsg, const sqlite3_api_routines *api)
Initializer for SQLite extension load mechanism.
Definition: impexp.c:2477
table_dump
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
indent
static void indent(DUMP_DATA *dd)
Write indentation to dump.
Definition: impexp.c:932
impexp_init
int impexp_init(sqlite3 *db)
Registers the SQLite functions.
Definition: impexp.c:2521
json_pstrq
static void json_pstrq(const char *string, json_pfs *pfs)
Quote and write string using JSON output function.
Definition: impexp.c:2068
impexp_export_json
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
json_pfs
Definition: impexp.c:212
DUMP_DATA::nlines
int nlines
counter for output lines
Definition: impexp.c:921
json_output
static int json_output(sqlite3 *db, char *sql, impexp_putc pfunc, void *parg)
Execute SQL and write output as JSON.
Definition: impexp.c:2261
quote_xml_str
static void quote_xml_str(DUMP_DATA *dd, char *str)
Quote string for XML output during dump.
Definition: impexp.c:1104
DUMP_DATA::quote_mode
int quote_mode
mode for quoting data
Definition: impexp.c:919
ends_with_semicolon
static int ends_with_semicolon(const char *str, int n)
Test if string ends with a semicolon.
Definition: impexp.c:286
ISSPACE
#define ISSPACE(c)
Definition: impexp.c:219
DUMP_DATA::where
char * where
optional where clause of dump
Definition: impexp.c:920
impexp_export_sql
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
import_func
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
json_pstrc
static void json_pstrc(const char *string, json_pfs *pfs)
Conditionally quote and write string using JSON output function.
Definition: impexp.c:2191
export_func
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

Generated on Mon Aug 17 2020 by doxygen.
Contact: chw@ch-werner.de