0% found this document useful (0 votes)
63 views32 pages

Impexp.c: Main Page Alphabetical List Data Structures File List Data Fields Globals

This document contains source code for the impexp.c file. The code defines functions for processing SQL statements from an input file line by line, including functions for reading a line, checking if it ends with a semicolon, checking if a line contains only whitespace, and a function to quote and escape blob values.

Uploaded by

Nitin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
63 views32 pages

Impexp.c: Main Page Alphabetical List Data Structures File List Data Fields Globals

This document contains source code for the impexp.c file. The code defines functions for processing SQL statements from an input file line by line, including functions for reading a line, checking if it ends with a semicolon, checking if a line contains only whitespace, and a function to quote and escape blob values.

Uploaded by

Nitin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

10/02/2017 impexp.

c Source File

Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

impexp.c
Go to the documentation of this file.
00001  
00183 #ifdef STANDALONE 
00184 #include <sqlite3.h> 
00185 #define sqlite3_api_routines void 
00186 #else 
00187 #include <sqlite3ext.h> 
00188 static SQLITE_EXTENSION_INIT1 
00189 #endif 
00190  
00191 #include <stdlib.h> 
00192 #include <string.h> 
00193 #include <stdio.h> 
00194 #include <stddef.h> 
00195  
00196 #ifdef _WIN32 
00197 #include <windows.h> 
00198 #define strcasecmp  _stricmp
00199 #define strncasecmp _strnicmp 
00200 #else 
00201 #include <unistd.h> 
00202 #endif 
00203  
00204 #include "impexp.h" 
00205  
00212 typedef struct { 
00213     impexp_putc pfunc;   
00214     void *parg;          
00215 } json_pfs; 
00216  
00217 static const char space_chars[] = " \f\n\r\t\v"; 
00218  
00219 #define ISSPACE(c) ((c) && (strchr(space_chars, (c)) != 0)) 
00220  
00228 static char * 
00229 one_input_line(FILE *fin) 
00230 { 
00231     char *line, *tmp; 
00232     int nline; 
00233     int n; 
00234     int eol; 
00235  
00236     nline = 256; 
00237     line = sqlite3_malloc(nline); 
00238     if (!line) { 
00239         return 0; 
00240     } 
00241     n = 0; 
00242     eol = 0; 
00243     while (!eol) { 
00244         if (n + 256 > nline) { 
00245             nline = nline * 2 + 256; 
00246             tmp = sqlite3_realloc(line, nline); 
00247             if (!tmp) { 
00248                 sqlite3_free(line); 
00249                 return 0; 
00250             } 
00251             line = tmp; 
00252         } 
00253         if (!fgets(line + n, nline ‐ n, fin)) { 

http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 1/32
10/02/2017 impexp.c Source File

00254             if (n == 0) { 
00255                 sqlite3_free(line); 
00256                 return 0; 
00257             } 
00258             line[n] = 0; 
00259             eol = 1; 
00260             break; 
00261         } 
00262         while (line[n]) { 
00263             n++; 
00264         } 
00265         if ((n > 0) && (line[n‐1] == '\n')) { 
00266             n‐‐; 
00267             line[n] = 0; 
00268             eol = 1; 
00269         } 
00270     } 
00271     tmp = sqlite3_realloc(line, n + 1); 
00272     if (!tmp) { 
00273         sqlite3_free(line); 
00274     } 
00275     return tmp; 
00276 } 
00277  
00285 static int 
00286 ends_with_semicolon(const char *str, int n) 
00287 { 
00288     while ((n > 0) && ISSPACE(str[n ‐ 1])) { 
00289         n‐‐; 
00290     } 
00291     return (n > 0) && (str[n ‐ 1] == ';'); 
00292 } 
00293  
00300 static int 
00301 all_whitespace(const char *str) 
00302 { 
00303     for (; str[0]; str++) { 
00304         if (ISSPACE(str[0])) { 
00305             continue; 
00306         } 
00307         if ((str[0] == '/') && (str[1] == '*')) { 
00308             str += 2; 
00309             while (str[0] && ((str[0] != '*') || (str[1] != '/'))) { 
00310                 str++; 
00311             } 
00312             if (!str[0]) { 
00313                 return 0; 
00314             } 
00315             str++; 
00316             continue; 
00317         } 
00318         if ((str[0] == '‐') && (str[1] == '‐')) { 
00319             str += 2; 
00320             while (str[0] && (str[0] != '\n')) { 
00321                 str++; 
00322             } 
00323             if (!str[0]) { 
00324                 return 1; 
00325             } 
00326             continue; 
00327         } 
00328         return 0; 
00329     } 
00330     return 1; 
00331 } 
00332  
00340 static int 
00341 process_input(sqlite3 *db, FILE *fin) 
00342 { 

00343     char *line = 0; 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 2/32
10/02/2017 impexp.c Source File

00343     char *line = 0; 
00344     char *sql = 0; 
00345     int nsql = 0; 
00346     int rc; 
00347     int errors = 0; 
00348  
00349     while (1) { 
00350         line = one_input_line(fin); 
00351         if (!line) { 
00352             break; 
00353         } 
00354         if ((!sql || !sql[0]) && all_whitespace(line)) { 
00355             continue; 
00356         } 
00357         if (!sql) { 
00358             int i; 
00359             for (i = 0; line[i] && ISSPACE(line[i]); i++) { 
00360                 /* empty loop body */ 
00361             } 
00362             if (line[i]) { 
00363                 nsql = strlen(line); 
00364                 sql = sqlite3_malloc(nsql + 1); 
00365                 if (!sql) { 
00366                     errors++; 
00367                     break; 
00368                 } 
00369                 strcpy(sql, line); 
00370             } 
00371         } else { 
00372             int len = strlen(line); 
00373             char *tmp; 
00374  
00375             tmp = sqlite3_realloc(sql, nsql + len + 2); 
00376             if (!tmp) { 
00377                 errors++; 
00378                 break; 
00379             } 
00380             sql = tmp; 
00381             strcpy(sql + nsql, "\n"); 
00382             nsql++; 
00383             strcpy(sql + nsql, line); 
00384             nsql += len; 
00385         } 
00386         sqlite3_free(line); 
00387         line = 0; 
00388         if (sql && ends_with_semicolon(sql, nsql) && sqlite3_complete(sql)) { 
00389             rc = sqlite3_exec(db, sql, 0, 0, 0); 
00390             if (rc != SQLITE_OK) { 
00391                 errors++; 
00392             } 
00393             sqlite3_free(sql); 
00394             sql = 0; 
00395             nsql = 0; 
00396         } 
00397     } 
00398     if (sql) { 
00399         sqlite3_free(sql); 
00400     } 
00401     if (line) { 
00402         sqlite3_free(line); 
00403     } 
00404     return errors; 
00405 } 
00406  
00419 static void 
00420 quote_func(sqlite3_context *context, int argc, sqlite3_value **argv) 
00421 { 
00422     int mode = 0; 
00423  
00424     if (argc < 1) { 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 3/32
10/02/2017 impexp.c Source File

00424     if (argc < 1) { 
00425         return; 
00426     } 
00427     if (argc > 1) { 
00428         mode = sqlite3_value_int(argv[1]); 
00429     } 
00430     switch (sqlite3_value_type(argv[0])) { 
00431     case SQLITE_NULL: { 
00432         sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC); 
00433         break; 
00434     } 
00435     case SQLITE_INTEGER: 
00436     case SQLITE_FLOAT: { 
00437         sqlite3_result_value(context, argv[0]); 
00438         break; 
00439     } 
00440     case SQLITE_BLOB: { 
00441         char *text = 0; 
00442         unsigned char *blob = (unsigned char *) sqlite3_value_blob(argv[0]); 
00443         int nblob = sqlite3_value_bytes(argv[0]); 
00444  
00445         if (2 * nblob + 4 > 1000000000) { 
00446             sqlite3_result_error(context, "value too large", ‐1); 
00447             return; 
00448         } 
00449         text = (char *) sqlite3_malloc((2 * nblob) + 4); 
00450         if (!text) { 
00451             sqlite3_result_error(context, "out of memory", ‐1); 
00452         } else { 
00453             int i, k = 0; 
00454             static const char xdigits[] = "0123456789ABCDEF"; 
00455  
00456             if (mode == 1) { 
00457                 /* ORACLE enclosed in '' */ 
00458                 text[k++] = '\''; 
00459             } else if (mode == 2) {
00460                 /* SQL Server 0x prefix */ 
00461                 text[k++] = '0'; 
00462                 text[k++] = 'x'; 
00463             } else if (mode == 3) {
00464                 /* MySQL x'..' */ 
00465                 text[k++] = 'x'; 
00466                 text[k++] = '\''; 
00467             } else { 
00468                 /* default */ 
00469                 text[k++] = 'X'; 
00470                 text[k++] = '\''; 
00471             } 
00472             for (i = 0; i < nblob; i++) { 
00473                 text[k++] = xdigits[(blob[i] >> 4 ) & 0x0F]; 
00474                 text[k++] = xdigits[blob[i] & 0x0F]; 
00475             } 
00476             if (mode == 1) { 
00477                 /* ORACLE enclosed in '' */ 
00478                 text[k++] = '\''; 
00479             } else if (mode == 2) {
00480                 /* SQL Server 0x prefix */ 
00481             } else if (mode == 3) {
00482                 /* MySQL x'..' */ 
00483                 text[k++] = '\''; 
00484             } else { 
00485                 /* default */ 
00486                 text[k++] = '\''; 
00487             } 
00488             text[k] = '\0'; 
00489             sqlite3_result_text(context, text, k, SQLITE_TRANSIENT); 
00490             sqlite3_free(text); 
00491         } 
00492         break; 

00493     } 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 4/32
10/02/2017 impexp.c Source File

00493     } 
00494     case SQLITE_TEXT: { 
00495         int i, n; 
00496         const unsigned char *arg = sqlite3_value_text(argv[0]); 
00497         char *p; 
00498  
00499         if (!arg) { 
00500             return; 
00501         } 
00502         for (i = 0, n = 0; arg[i]; i++) { 
00503             if (arg[i] == '\'') { 
00504                 n++; 
00505             } 
00506         } 
00507         if (i + n + 3 > 1000000000) { 
00508             sqlite3_result_error(context, "value too large", ‐1); 
00509             return; 
00510         } 
00511         p = sqlite3_malloc(i + n + 3); 
00512         if (!p) { 
00513             sqlite3_result_error(context, "out of memory", ‐1); 
00514             return; 
00515         } 
00516         p[0] = '\''; 
00517         for (i = 0, n = 1; arg[i]; i++) { 
00518             p[n++] = arg[i];
00519             if (arg[i] == '\'') { 
00520                 p[n++] = '\''; 
00521             } 
00522         } 
00523         p[n++] = '\''; 
00524         p[n] = 0; 
00525         sqlite3_result_text(context, p, n, SQLITE_TRANSIENT); 
00526         sqlite3_free(p); 
00527         break; 
00528     } 
00529     } 
00530 } 
00531  
00539 static void 
00540 quote_csv_func(sqlite3_context *context, int argc, sqlite3_value **argv) 
00541 { 
00542     if (argc < 1) { 
00543         return; 
00544     } 
00545     switch (sqlite3_value_type(argv[0])) { 
00546     case SQLITE_NULL: { 
00547         sqlite3_result_text(context, "", 0, SQLITE_STATIC); 
00548         break; 
00549     } 
00550     case SQLITE_INTEGER: 
00551     case SQLITE_FLOAT: { 
00552         sqlite3_result_value(context, argv[0]); 
00553         break; 
00554     } 
00555     case SQLITE_BLOB: { 
00556         char *text = 0; 
00557         unsigned char *blob = (unsigned char *) sqlite3_value_blob(argv[0]); 
00558         int nblob = sqlite3_value_bytes(argv[0]); 
00559  
00560         if (2 * nblob + 4 > 1000000000) { 
00561             sqlite3_result_error(context, "value too large", ‐1); 
00562             return; 
00563         } 
00564         text = (char *) sqlite3_malloc((2 * nblob) + 4); 
00565         if (!text) { 
00566             sqlite3_result_error(context, "out of memory", ‐1); 
00567         } else { 
00568             int i, k = 0; 

00569             static const char xdigits[] = "0123456789ABCDEF"; 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 5/32
10/02/2017 impexp.c Source File

00569             static const char xdigits[] = "0123456789ABCDEF"; 
00570  
00571             text[k++] = '"';
00572             for (i = 0; i < nblob; i++) { 
00573                 text[k++] = xdigits[(blob[i] >> 4 ) & 0x0F]; 
00574                 text[k++] = xdigits[blob[i] & 0x0F]; 
00575             } 
00576             text[k++] = '"';
00577             text[k] = '\0'; 
00578             sqlite3_result_text(context, text, k, SQLITE_TRANSIENT); 
00579             sqlite3_free(text); 
00580         } 
00581         break; 
00582     } 
00583     case SQLITE_TEXT: { 
00584         int i, n; 
00585         const unsigned char *arg = sqlite3_value_text(argv[0]); 
00586         char *p; 
00587  
00588         if (!arg) { 
00589             return; 
00590         } 
00591         for (i = 0, n = 0; arg[i]; i++) { 
00592             if (arg[i] == '"') { 
00593                 n++; 
00594             } 
00595         } 
00596         if (i + n + 3 > 1000000000) { 
00597             sqlite3_result_error(context, "value too large", ‐1); 
00598             return; 
00599         } 
00600         p = sqlite3_malloc(i + n + 3); 
00601         if (!p) { 
00602             sqlite3_result_error(context, "out of memory", ‐1); 
00603             return; 
00604         } 
00605         p[0] = '"'; 
00606         for (i = 0, n = 1; arg[i]; i++) { 
00607             p[n++] = arg[i];
00608             if (arg[i] == '"') { 
00609                 p[n++] = '"'; 
00610             } 
00611         } 
00612         p[n++] = '"'; 
00613         p[n] = 0; 
00614         sqlite3_result_text(context, p, n, SQLITE_TRANSIENT); 
00615         sqlite3_free(p); 
00616         break; 
00617     } 
00618     } 
00619 } 
00620  
00628 static void 
00629 indent_xml_func(sqlite3_context *context, int argc, sqlite3_value **argv) 
00630 { 
00631     static const char spaces[] = "                                "; 
00632     int n = 0; 
00633  
00634     if (argc > 0) { 
00635         n = sqlite3_value_int(argv[0]); 
00636         if (n > 32) { 
00637             n = 32; 
00638         } else if (n < 0) { 
00639             n = 0; 
00640         } 
00641     } 
00642     sqlite3_result_text(context, spaces, n, SQLITE_STATIC); 
00643 } 
00644  

00652 static void 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 6/32
10/02/2017 impexp.c Source File

00652 static void 
00653 quote_xml_func(sqlite3_context *context, int argc, sqlite3_value **argv) 
00654 { 
00655     static const char xdigits[] = "0123456789ABCDEF"; 
00656     int type, addtype = 0; 
00657  
00658     if (argc < 1) { 
00659         return; 
00660     } 
00661     if (argc > 1) { 
00662         addtype = sqlite3_value_int(argv[1]); 
00663     } 
00664     type = sqlite3_value_type(argv[0]); 
00665     switch (type) { 
00666     case SQLITE_NULL: { 
00667         if (addtype > 0) { 
00668             sqlite3_result_text(context, " TYPE=\"NULL\">", ‐1, SQLITE_STATIC); 
00669         } else { 
00670             sqlite3_result_text(context, "", 0, SQLITE_STATIC); 
00671         } 
00672         break; 
00673     } 
00674     case SQLITE_INTEGER: 
00675     case SQLITE_FLOAT: { 
00676         if (addtype > 0) { 
00677             char *text = (char *) sqlite3_malloc(128); 
00678             int k; 
00679  
00680             if (!text) { 
00681                 sqlite3_result_error(context, "out of memory", ‐1); 
00682                 return; 
00683             } 
00684             strcpy(text, (type == SQLITE_FLOAT) ? " TYPE=\"REAL\">" : 
00685                    " TYPE=\"INTEGER\">"); 
00686             k = strlen(text); 
00687             strcpy(text + k, (char *) sqlite3_value_text(argv[0])); 
00688             k = strlen(text); 
00689             sqlite3_result_text(context, text, k, SQLITE_TRANSIENT); 
00690             sqlite3_free(text); 
00691         } else { 
00692             sqlite3_result_value(context, argv[0]); 
00693         } 
00694         break; 
00695     } 
00696     case SQLITE_BLOB: { 
00697         char *text = 0; 
00698         unsigned char *blob = (unsigned char *) sqlite3_value_blob(argv[0]); 
00699         int nblob = sqlite3_value_bytes(argv[0]); 
00700         int i, k = 0; 
00701  
00702         if (6 * nblob + 34 > 1000000000) { 
00703             sqlite3_result_error(context, "value too large", ‐1); 
00704             return; 
00705         } 
00706         text = (char *) sqlite3_malloc((6 * nblob) + 34); 
00707         if (!text) { 
00708             sqlite3_result_error(context, "out of memory", ‐1); 
00709             return; 
00710         } 
00711         if (addtype > 0) { 
00712             strcpy(text, " TYPE=\"BLOB\">"); 
00713             k = strlen(text); 
00714         } 
00715         for (i = 0; i < nblob; i++) { 
00716             text[k++] = '&';
00717             text[k++] = '#';
00718             text[k++] = 'x';
00719             text[k++] = xdigits[(blob[i] >> 4 ) & 0x0F]; 
00720             text[k++] = xdigits[blob[i] & 0x0F]; 

00721             text[k++] = ';';
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 7/32
10/02/2017 impexp.c Source File

00721             text[k++] = ';';
00722         } 
00723         text[k] = '\0'; 
00724         sqlite3_result_text(context, text, k, SQLITE_TRANSIENT); 
00725         sqlite3_free(text); 
00726         break; 
00727     } 
00728     case SQLITE_TEXT: { 
00729         int i, n; 
00730         const unsigned char *arg = sqlite3_value_text(argv[0]); 
00731         char *p; 
00732  
00733         if (!arg) { 
00734             return; 
00735         } 
00736         for (i = 0, n = 0; arg[i]; i++) { 
00737             if ((arg[i] == '"') || (arg[i] == '\'') || 
00738                 (arg[i] == '<') || (arg[i] == '>') || 
00739                 (arg[i] == '&') || (arg[i] < ' ')) { 
00740                 n += 5; 
00741             } 
00742         } 
00743         if (i + n + 32 > 1000000000) { 
00744             sqlite3_result_error(context, "value too large", ‐1); 
00745             return; 
00746         } 
00747         p = sqlite3_malloc(i + n + 32); 
00748         if (!p) { 
00749             sqlite3_result_error(context, "out of memory", ‐1); 
00750             return; 
00751         } 
00752         n = 0; 
00753         if (addtype > 0) { 
00754             strcpy(p, " TYPE=\"TEXT\">"); 
00755             n = strlen(p); 
00756         } 
00757         for (i = 0; arg[i]; i++) { 
00758             if (arg[i] == '"') { 
00759                 p[n++] = '&'; 
00760                 p[n++] = 'q'; 
00761                 p[n++] = 'u'; 
00762                 p[n++] = 'o'; 
00763                 p[n++] = 't'; 
00764                 p[n++] = ';'; 
00765             } else if (arg[i] == '\'') { 
00766                 p[n++] = '&'; 
00767                 p[n++] = 'a'; 
00768                 p[n++] = 'p'; 
00769                 p[n++] = 'o'; 
00770                 p[n++] = 's'; 
00771                 p[n++] = ';'; 
00772             } else if (arg[i] == '<') { 
00773                 p[n++] = '&'; 
00774                 p[n++] = 'l'; 
00775                 p[n++] = 't'; 
00776                 p[n++] = ';'; 
00777             } else if (arg[i] == '>') { 
00778                 p[n++] = '&'; 
00779                 p[n++] = 'g'; 
00780                 p[n++] = 't'; 
00781                 p[n++] = ';'; 
00782             } else if (arg[i] == '&') { 
00783                 p[n++] = '&'; 
00784                 p[n++] = 'a'; 
00785                 p[n++] = 'm'; 
00786                 p[n++] = 'p'; 
00787                 p[n++] = ';'; 
00788             } else if (arg[i] < ' ') { 
00789                 p[n++] = '&'; 

00790                 p[n++] = '#'; 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 8/32
10/02/2017 impexp.c Source File

00790                 p[n++] = '#'; 
00791                 p[n++] = 'x'; 
00792                 p[n++] = xdigits[(arg[i] >> 4 ) & 0x0F]; 
00793                 p[n++] = xdigits[arg[i] & 0x0F]; 
00794                 p[n++] = ';'; 
00795             } else if (addtype < 0 && (arg[i] == ' ')) { 
00796                 p[n++] = '&'; 
00797                 p[n++] = '#'; 
00798                 p[n++] = 'x'; 
00799                 p[n++] = xdigits[(arg[i] >> 4 ) & 0x0F]; 
00800                 p[n++] = xdigits[arg[i] & 0x0F]; 
00801                 p[n++] = ';'; 
00802             } else { 
00803                 p[n++] = arg[i]; 
00804             } 
00805         } 
00806         p[n] = '\0'; 
00807         sqlite3_result_text(context, p, n, SQLITE_TRANSIENT); 
00808         sqlite3_free(p); 
00809         break; 
00810     } 
00811     } 
00812 } 
00813  
00821 static void 
00822 import_func(sqlite3_context *ctx, int nargs, sqlite3_value **args) 
00823 { 
00824     sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx); 
00825     int changes0 = sqlite3_changes(db); 
00826     char *filename = 0; 
00827     FILE *fin; 
00828 #ifdef _WIN32 
00829     char fnbuf[MAX_PATH]; 
00830 #endif 
00831  
00832     if (nargs > 0) { 
00833         if (sqlite3_value_type(args[0]) != SQLITE_NULL) { 
00834             filename = (char *) sqlite3_value_text(args[0]); 
00835         } 
00836     } 
00837 #ifdef _WIN32 
00838     if (!filename) { 
00839         OPENFILENAME ofn; 
00840  
00841         memset(&ofn, 0, sizeof (ofn)); 
00842         memset(fnbuf, 0, sizeof (fnbuf)); 
00843         ofn.lStructSize = sizeof (ofn); 
00844         ofn.lpstrFile = fnbuf; 
00845         ofn.nMaxFile = MAX_PATH; 
00846         ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST | 
00847                     OFN_EXPLORER | OFN_PATHMUSTEXIST; 
00848         if (GetOpenFileName(&ofn)) { 
00849             filename = fnbuf; 
00850         } 
00851     } 
00852 #endif 
00853     if (!filename) { 
00854         goto done; 
00855     } 
00856     fin = fopen(filename, "r"); 
00857     if (!fin) { 
00858         goto done; 
00859     } 
00860     process_input(db, fin); 
00861     fclose(fin); 
00862 done: 
00863     sqlite3_result_int(ctx, sqlite3_changes(db) ‐ changes0); 
00864 } 
00865  

00866 /* see doc in impexp.h */ 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 9/32
10/02/2017 impexp.c Source File

00866 /* see doc in impexp.h */ 
00867  
00868 int 
00869 impexp_import_sql(sqlite3 *db, char *filename) 
00870 { 
00871     int changes0; 
00872     FILE *fin; 
00873 #ifdef _WIN32 
00874     char fnbuf[MAX_PATH]; 
00875 #endif 
00876  
00877     if (!db) { 
00878         return 0; 
00879     } 
00880     changes0 = sqlite3_changes(db); 
00881 #ifdef _WIN32 
00882     if (!filename) { 
00883         OPENFILENAME ofn; 
00884  
00885         memset(&ofn, 0, sizeof (ofn)); 
00886         memset(fnbuf, 0, sizeof (fnbuf)); 
00887         ofn.lStructSize = sizeof (ofn); 
00888         ofn.lpstrFile = fnbuf; 
00889         ofn.nMaxFile = MAX_PATH; 
00890         ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST | 
00891                     OFN_EXPLORER | OFN_PATHMUSTEXIST; 
00892         if (GetOpenFileName(&ofn)) { 
00893             filename = fnbuf; 
00894         } 
00895     } 
00896 #endif 
00897     if (!filename) { 
00898         goto done; 
00899     } 
00900     fin = fopen(filename, "r"); 
00901     if (!fin) { 
00902         goto done; 
00903     } 
00904     process_input(db, fin); 
00905     fclose(fin); 
00906 done: 
00907     return sqlite3_changes(db) ‐ changes0; 
00908 } 
00909  
00916 typedef struct { 
00917     sqlite3 *db;         
00918     int with_schema;     
00919     int quote_mode;      
00920     char *where;         
00921     int nlines;          
00922     int indent;          
00923     FILE *out;           
00924 } DUMP_DATA; 
00925  
00931 static void 
00932 indent(DUMP_DATA *dd) 
00933 { 
00934     int i; 
00935  
00936     for (i = 0; i < dd‐>indent; i++) { 
00937         fputc(' ', dd‐>out); 
00938     } 
00939 } 
00940  
00951 static int 
00952 table_dump(DUMP_DATA *dd, char **errp, int fmt, const char *query, ...) 
00953 { 
00954     sqlite3_stmt *select = 0; 
00955     int rc; 

00956     const char *rest, *q = query; 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 10/32
10/02/2017 impexp.c Source File

00956     const char *rest, *q = query; 
00957     va_list ap; 
00958  
00959     if (errp && *errp) { 
00960         sqlite3_free(*errp);
00961         *errp = 0; 
00962     } 
00963     if (fmt) { 
00964         va_start(ap, query);
00965         q = sqlite3_vmprintf(query, ap); 
00966         va_end(ap); 
00967         if (!q) { 
00968             return SQLITE_NOMEM; 
00969         } 
00970     } 
00971 #if defined(HAVE_SQLITE3PREPAREV2) && HAVE_SQLITE3PREPAREV2 
00972     rc = sqlite3_prepare_v2(dd‐>db, q, ‐1, &select, &rest); 
00973 #else 
00974     rc = sqlite3_prepare(dd‐>db, q, ‐1, &select, &rest); 
00975 #endif 
00976     if (fmt) { 
00977         sqlite3_free((char *) q); 
00978     } 
00979     if ((rc != SQLITE_OK) || !select) { 
00980         return rc; 
00981     } 
00982     rc = sqlite3_step(select); 
00983     while (rc == SQLITE_ROW) { 
00984         if (fputs((char *) sqlite3_column_text(select, 0), dd‐>out) > 0) { 
00985             dd‐>nlines++; 
00986         } 
00987         if (dd‐>quote_mode >= 0) { 
00988             fputc(';', dd‐>out); 
00989         } 
00990         if (dd‐>quote_mode == ‐1) {
00991             fputc('\r', dd‐>out); 
00992         } 
00993         if (dd‐>quote_mode >= ‐1) {
00994             fputc('\n', dd‐>out); 
00995         } 
00996         rc = sqlite3_step(select); 
00997     } 
00998     rc = sqlite3_finalize(select); 
00999     if (rc != SQLITE_OK) { 
01000         if (errp) { 
01001             *errp = sqlite3_mprintf("%s", sqlite3_errmsg(dd‐>db)); 
01002         } 
01003     } 
01004     return rc; 
01005 } 
01006  
01012 static void 
01013 append_free(char **in) 
01014 { 
01015     long *p = (long *) *in; 
01016  
01017     if (p) { 
01018         p ‐= 2; 
01019         sqlite3_free(p); 
01020         *in = 0; 
01021     } 
01022 } 
01023  
01033 static char * 
01034 append(char **in, char const *append, char quote)
01035 { 
01036     long *p = (long *) *in; 
01037     long len, maxlen, actlen; 
01038     int i; 
01039     char *pp; 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 11/32
10/02/2017 impexp.c Source File

01039     char *pp; 
01040     int nappend = append ? strlen(append) : 0; 
01041  
01042     if (p) { 
01043         p ‐= 2; 
01044         maxlen = p[0]; 
01045         actlen = p[1]; 
01046     } else { 
01047         maxlen = actlen = 0;
01048     } 
01049     len = nappend + actlen; 
01050     if (quote) { 
01051         len += 2; 
01052         for (i = 0; i < nappend; i++) { 
01053             if (append[i] == quote) { 
01054                 len++; 
01055             } 
01056         } 
01057     } else if (!nappend) { 
01058         return *in; 
01059     } 
01060     if (len >= maxlen ‐ 1) { 
01061         long *q; 
01062  
01063         maxlen = (len + 0x03ff) & (~0x3ff); 
01064         q = (long *) sqlite3_realloc(p, maxlen + 1 + 2 * sizeof (long)); 
01065         if (!q) { 
01066             return 0; 
01067         } 
01068         if (!p) { 
01069             q[1] = 0; 
01070         } 
01071         p = q; 
01072         p[0] = maxlen; 
01073         *in = (char *) (p + 2); 
01074     } 
01075     pp = *in + actlen; 
01076     if (quote) { 
01077         *pp++ = quote; 
01078         for (i = 0; i < nappend; i++) { 
01079             *pp++ = append[i]; 
01080             if (append[i] == quote) { 
01081                 *pp++ = quote; 
01082             } 
01083         } 
01084         *pp++ = quote; 
01085         *pp = '\0'; 
01086     } else { 
01087         if (nappend) { 
01088             memcpy(pp, append, nappend); 
01089             pp += nappend; 
01090             *pp = '\0'; 
01091         } 
01092     } 
01093     p[1] = pp ‐ *in; 
01094     return *in; 
01095 } 
01096  
01103 static void 
01104 quote_xml_str(DUMP_DATA *dd, char *str) 
01105 { 
01106     static const char xdigits[] = "0123456789ABCDEF"; 
01107     int i; 
01108  
01109     if (!str) { 
01110         return; 
01111     } 
01112     for (i = 0; str[i]; i++) { 
01113         if (str[i] == '"') { 
01114             fputs("&quot;", dd‐>out); 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 12/32
10/02/2017 impexp.c Source File

01114             fputs("&quot;", dd‐>out); 
01115         } else if (str[i] == '\'') { 
01116             fputs("&apos;", dd‐>out); 
01117         } else if (str[i] == '<') {
01118             fputs("&lt;", dd‐>out);
01119         } else if (str[i] == '>') {
01120             fputs("&gt;", dd‐>out);
01121         } else if (str[i] == '&') {
01122             fputs("&amp;", dd‐>out); 
01123         } else if ((unsigned char) str[i] <= ' ') { 
01124             char buf[8]; 
01125  
01126             buf[0] = '&'; 
01127             buf[1] = '&'; 
01128             buf[2] = '#'; 
01129             buf[3] = 'x'; 
01130             buf[4] = xdigits[(str[i] >> 4 ) & 0x0F]; 
01131             buf[5] = xdigits[str[i] & 0x0F]; 
01132             buf[6] = ';'; 
01133             buf[7] = '\0'; 
01134             fputs(buf, dd‐>out); 
01135         } else { 
01136             fputc(str[i], dd‐>out); 
01137         } 
01138     } 
01139 } 
01140  
01150 static int 
01151 dump_cb(void *udata, int nargs, char **args, char **cols) 
01152 { 
01153     int rc; 
01154     const char *table, *type, *sql; 
01155     DUMP_DATA *dd = (DUMP_DATA *) udata; 
01156  
01157     if ((nargs != 3) || (args == NULL)) { 
01158         return 1; 
01159     } 
01160     table = args[0]; 
01161     type = args[1]; 
01162     sql = args[2]; 
01163     if (strcmp(table, "sqlite_sequence") == 0) { 
01164         if (dd‐>with_schema) { 
01165             if (fputs("DELETE FROM sqlite_sequence;\n", dd‐>out) >= 0) { 
01166                 dd‐>nlines++; 
01167             } 
01168         } 
01169     } else if (strcmp(table, "sqlite_stat1") == 0) { 
01170         if (dd‐>with_schema) { 
01171             if (fputs("ANALYZE sqlite_master;\n", dd‐>out) >= 0) { 
01172                 dd‐>nlines++; 
01173             } 
01174         } 
01175     } else if (strncmp(table, "sqlite_", 7) == 0) { 
01176         return 0; 
01177     } else if (strncmp(sql, "CREATE VIRTUAL TABLE", 20) == 0) { 
01178         if (dd‐>with_schema) { 
01179             sqlite3_stmt *stmt = 0; 
01180             char *creat = 0, *table_info = 0; 
01181  
01182             append(&table_info, "PRAGMA table_info(", 0); 
01183             append(&table_info, table, '"'); 
01184             append(&table_info, ")", 0); 
01185 #if defined(HAVE_SQLITE3PREPAREV2) && HAVE_SQLITE3PREPAREV2 
01186             rc = sqlite3_prepare_v2(dd‐>db, table_info, ‐1, &stmt, 0); 
01187 #else 
01188             rc = sqlite3_prepare(dd‐>db, table_info, ‐1, &stmt, 0); 
01189 #endif 
01190             append_free(&table_info); 
01191             if ((rc != SQLITE_OK) || !stmt) { 
01192 bailout0: 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 13/32
10/02/2017 impexp.c Source File

01192 bailout0: 
01193                 if (stmt) { 
01194                     sqlite3_finalize(stmt); 
01195                 } 
01196                 append_free(&creat); 
01197                 return 1; 
01198             } 
01199             append(&creat, table, '"'); 
01200             append(&creat, "(", 0);
01201             rc = sqlite3_step(stmt); 
01202             while (rc == SQLITE_ROW) { 
01203                 const char *p; 
01204  
01205                 p = (const char *) sqlite3_column_text(stmt, 1); 
01206                 append(&creat, p, '"'); 
01207                 append(&creat, " ", 0); 
01208                 p = (const char *) sqlite3_column_text(stmt, 2); 
01209                 if (p && p[0]) { 
01210                     append(&creat, p, 0); 
01211                 } 
01212                 if (sqlite3_column_int(stmt, 5)) { 
01213                     append(&creat, " PRIMARY KEY", 0); 
01214                 } 
01215                 if (sqlite3_column_int(stmt, 3)) { 
01216                     append(&creat, " NOT NULL", 0); 
01217                 } 
01218                 p = (const char *) sqlite3_column_text(stmt, 4); 
01219                 if (p && p[0]) { 
01220                     append(&creat, " DEFAULT ", 0); 
01221                     append(&creat, p, 0); 
01222                 } 
01223                 rc = sqlite3_step(stmt); 
01224                 if (rc == SQLITE_ROW) { 
01225                     append(&creat, ",", 0); 
01226                 } 
01227             } 
01228             if (rc != SQLITE_DONE) { 
01229                 goto bailout0; 
01230             } 
01231             sqlite3_finalize(stmt); 
01232             append(&creat, ")", 0);
01233             if (creat && fprintf(dd‐>out, "CREATE TABLE %s;\n", creat) > 0) { 
01234                 dd‐>nlines++; 
01235             } 
01236             append_free(&creat); 
01237         } 
01238     } else { 
01239         if (dd‐>with_schema) { 
01240             if (fprintf(dd‐>out, "%s;\n", sql) > 0) { 
01241                 dd‐>nlines++; 
01242             } 
01243         } 
01244     } 
01245     if ((strcmp(type, "table") == 0) || 
01246         ((dd‐>quote_mode < 0) && (strcmp(type, "view") == 0))) { 
01247         sqlite3_stmt *stmt = 0; 
01248         char *select = 0, *hdr = 0, *table_info = 0; 
01249         char buffer[256]; 
01250  
01251         append(&table_info, "PRAGMA table_info(", 0); 
01252         append(&table_info, table, '"'); 
01253         append(&table_info, ")", 0); 
01254 #if defined(HAVE_SQLITE3PREPAREV2) && HAVE_SQLITE3PREPAREV2 
01255         rc = sqlite3_prepare_v2(dd‐>db, table_info, ‐1, &stmt, 0); 
01256 #else 
01257         rc = sqlite3_prepare(dd‐>db, table_info, ‐1, &stmt, 0); 
01258 #endif 
01259         append_free(&table_info); 
01260         if ((rc != SQLITE_OK) || !stmt) { 
01261 bailout1: 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 14/32
10/02/2017 impexp.c Source File

01261 bailout1: 
01262             if (stmt) { 
01263                 sqlite3_finalize(stmt); 
01264             } 
01265             append_free(&hdr); 
01266             append_free(&select); 
01267             return 1; 
01268         } 
01269         if (dd‐>quote_mode < ‐1) { 
01270             if (dd‐>where) { 
01271                 append(&select, "SELECT ", 0); 
01272                 sprintf(buffer, "indent_xml(%d)", dd‐>indent); 
01273                 append(&select, buffer, 0); 
01274                 append(&select, " || '<' || quote_xml(", 0); 
01275                 append(&select, dd‐>where, '"'); 
01276                 append(&select, ",‐1) || '>\n' || ", 0); 
01277             } else { 
01278                 append(&select, "SELECT ", 0); 
01279             } 
01280         } else if (dd‐>quote_mode < 0) { 
01281             if (dd‐>where) { 
01282                 append(&select, "SELECT quote_csv(", 0); 
01283                 append(&select, dd‐>where, '"'); 
01284                 append(&select, ") || ',' || ", 0); 
01285             } else { 
01286                 append(&select, "SELECT ", 0); 
01287             } 
01288             if (dd‐>indent) { 
01289                 append(&hdr, select, 0); 
01290             } 
01291         } else { 
01292             char *tmp = 0; 
01293  
01294             if (dd‐>with_schema) { 
01295                 append(&select, "SELECT 'INSERT INTO ' || ", 0); 
01296             } else { 
01297                 append(&select, "SELECT 'INSERT OR REPLACE INTO ' || ", 0); 
01298             } 
01299             append(&tmp, table, '"'); 
01300             if (tmp) { 
01301                 append(&select, tmp, '\''); 
01302                 append_free(&tmp); 
01303             } 
01304         } 
01305         if ((dd‐>quote_mode >= 0) && !dd‐>with_schema) { 
01306             char *tmp = 0; 
01307  
01308             append(&select, " || ' (' || ", 0); 
01309             rc = sqlite3_step(stmt); 
01310             while (rc == SQLITE_ROW) { 
01311                 const char *text = (const char *) sqlite3_column_text(stmt, 1); 
01312  
01313                 append(&tmp, text, '"'); 
01314                 if (tmp) { 
01315                     append(&select, tmp, '\''); 
01316                     append_free(&tmp); 
01317                 } 
01318                 rc = sqlite3_step(stmt); 
01319                 if (rc == SQLITE_ROW) { 
01320                     append(&select, " || ',' || ", 0); 
01321                 } 
01322             } 
01323             if (rc != SQLITE_DONE) { 
01324                 goto bailout1; 
01325             } 
01326             sqlite3_reset(stmt); 
01327             append(&select, "|| ')'", 0); 
01328         } 
01329         if ((dd‐>quote_mode == ‐1) && dd‐>indent) { 
01330             rc = sqlite3_step(stmt); 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 15/32
10/02/2017 impexp.c Source File

01330             rc = sqlite3_step(stmt); 
01331             while (rc == SQLITE_ROW) { 
01332                 const char *text = (const char *) sqlite3_column_text(stmt, 1); 
01333  
01334                 append(&hdr, "quote_csv(", 0); 
01335                 append(&hdr, text, '"'); 
01336                 rc = sqlite3_step(stmt); 
01337                 if (rc == SQLITE_ROW) { 
01338                     append(&hdr, ") || ',' || ", 0); 
01339                 } else { 
01340                     append(&hdr, ")", 0); 
01341                 } 
01342             } 
01343             if (rc != SQLITE_DONE) { 
01344                 goto bailout1; 
01345             } 
01346             sqlite3_reset(stmt); 
01347         } 
01348         if (dd‐>quote_mode >= 0) { 
01349             append(&select, " || ' VALUES(' || ", 0); 
01350         } 
01351         rc = sqlite3_step(stmt); 
01352         while (rc == SQLITE_ROW) { 
01353             const char *text = (const char *) sqlite3_column_text(stmt, 1); 
01354             const char *type = (const char *) sqlite3_column_text(stmt, 2); 
01355             int tlen = strlen(type ? type : ""); 
01356  
01357             if (dd‐>quote_mode < ‐1) { 
01358                 sprintf(buffer, "indent_xml(%d)", dd‐>indent + 1); 
01359                 append(&select, buffer, 0); 
01360                 append(&select, "|| '<' || quote_xml(", 0); 
01361                 append(&select, text, '\''); 
01362                 append(&select, ",‐1) || quote_xml(", 0); 
01363                 append(&select, text, '"'); 
01364                 append(&select, ",1) || '</' || quote_xml(", 0); 
01365                 append(&select, text, '\''); 
01366                 append(&select, ",‐1) || '>\n'", 0); 
01367             } else if (dd‐>quote_mode < 0) { 
01368                 /* leave out BLOB columns */ 
01369                 if (((tlen >= 4) && (strncasecmp(type, "BLOB", 4) == 0)) || 
01370                     ((tlen >= 6) && (strncasecmp(type, "BINARY", 6) == 0))) { 
01371                     rc = sqlite3_step(stmt); 
01372                     if (rc != SQLITE_ROW) { 
01373                         tlen = strlen(select); 
01374                         if (tlen > 10) { 
01375                             select[tlen ‐ 10] = '\0'; 
01376                         } 
01377                     } 
01378                     continue; 
01379                 } 
01380                 append(&select, "quote_csv(", 0); 
01381                 append(&select, text, '"'); 
01382             } else { 
01383                 append(&select, "quote_sql(", 0); 
01384                 append(&select, text, '"'); 
01385                 if (dd‐>quote_mode) { 
01386                     char mbuf[32]; 
01387  
01388                     sprintf(mbuf, ",%d", dd‐>quote_mode); 
01389                     append(&select, mbuf, 0); 
01390                 } 
01391             } 
01392             rc = sqlite3_step(stmt); 
01393             if (rc == SQLITE_ROW) { 
01394                 if (dd‐>quote_mode >= ‐1) { 
01395                     append(&select, ") || ',' || ", 0); 
01396                 } else { 
01397                     append(&select, " || ", 0); 
01398                 } 
01399             } else { 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 16/32
10/02/2017 impexp.c Source File

01399             } else { 
01400                 if (dd‐>quote_mode >= ‐1) { 
01401                     append(&select, ") ", 0); 
01402                 } else { 
01403                     append(&select, " ", 0); 
01404                 } 
01405             } 
01406         } 
01407         if (rc != SQLITE_DONE) { 
01408             goto bailout1; 
01409         } 
01410         sqlite3_finalize(stmt); 
01411         stmt = 0; 
01412         if (dd‐>quote_mode >= 0) { 
01413             append(&select, "|| ')' FROM ", 0); 
01414         } else { 
01415             if ((dd‐>quote_mode < ‐1) && dd‐>where) { 
01416                 sprintf(buffer, " || indent_xml(%d)", dd‐>indent); 
01417                 append(&select, buffer, 0); 
01418                 append(&select, " || '</' || quote_xml(", 0); 
01419                 append(&select, dd‐>where, '"'); 
01420                 append(&select, ",‐1) || '>\n' FROM ", 0); 
01421             } else { 
01422                 append(&select, "FROM ", 0); 
01423             } 
01424         } 
01425         append(&select, table, '"'); 
01426         if ((dd‐>quote_mode >= 0) && dd‐>where) { 
01427             append(&select, " ", 0); 
01428             append(&select, dd‐>where, 0); 
01429         } 
01430         if (hdr) { 
01431             rc = table_dump(dd, 0, 0, hdr); 
01432             append_free(&hdr); 
01433             hdr = 0; 
01434         } 
01435         rc = table_dump(dd, 0, 0, select); 
01436         if (rc == SQLITE_CORRUPT) { 
01437             append(&select, " ORDER BY rowid DESC", 0); 
01438             rc = table_dump(dd, 0, 0, select); 
01439         } 
01440         append_free(&select); 
01441     } 
01442     return 0; 
01443 } 
01444  
01454 static int 
01455 schema_dump(DUMP_DATA *dd, char **errp, const char *query, ...) 
01456 { 
01457     int rc; 
01458     char *q; 
01459     va_list ap; 
01460  
01461     if (errp) { 
01462         sqlite3_free(*errp);
01463         *errp = 0; 
01464     } 
01465     va_start(ap, query); 
01466     q = sqlite3_vmprintf(query, ap); 
01467     va_end(ap); 
01468     if (!q) { 
01469         return SQLITE_NOMEM;
01470     } 
01471     rc = sqlite3_exec(dd‐>db, q, dump_cb, dd, errp); 
01472     if (rc == SQLITE_CORRUPT) { 
01473         char *tmp; 
01474  
01475         tmp = sqlite3_mprintf("%s ORDER BY rowid DESC", q); 
01476         sqlite3_free(q); 
01477         if (!tmp) { 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 17/32
10/02/2017 impexp.c Source File

01477         if (!tmp) { 
01478             return rc; 
01479         } 
01480         q = tmp; 
01481         if (errp) { 
01482             sqlite3_free(*errp); 
01483             *errp = 0; 
01484         } 
01485         rc = sqlite3_exec(dd‐>db, q, dump_cb, dd, errp); 
01486     } 
01487     sqlite3_free(q); 
01488     return rc; 
01489 } 
01490  
01498 static void 
01499 export_func(sqlite3_context *ctx, int nargs, sqlite3_value **args) 
01500 { 
01501     DUMP_DATA dd0, *dd = &dd0; 
01502     sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx); 
01503     int i, mode = 0; 
01504     char *filename = 0; 
01505 #ifdef _WIN32 
01506     char fnbuf[MAX_PATH]; 
01507 #endif 
01508  
01509     dd‐>db = db; 
01510     dd‐>where = 0; 
01511     dd‐>nlines = ‐1; 
01512     dd‐>indent = 0; 
01513     if (nargs > 0) { 
01514         if (sqlite3_value_type(args[0]) != SQLITE_NULL) { 
01515             filename = (char *) sqlite3_value_text(args[0]); 
01516         } 
01517     } 
01518 #ifdef _WIN32 
01519     if (!filename) { 
01520         OPENFILENAME ofn; 
01521  
01522         memset(&ofn, 0, sizeof (ofn)); 
01523         memset(fnbuf, 0, sizeof (fnbuf)); 
01524         ofn.lStructSize = sizeof (ofn); 
01525         ofn.lpstrFile = fnbuf; 
01526         ofn.nMaxFile = MAX_PATH; 
01527         ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER | 
01528                     OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; 
01529         if (GetSaveFileName(&ofn)) { 
01530             filename = fnbuf; 
01531         } 
01532     } 
01533 #endif 
01534     if (!filename) { 
01535         goto done; 
01536     } 
01537     dd‐>out = fopen(filename, "w"); 
01538     if (!dd‐>out) { 
01539         goto done; 
01540     } 
01541     if (nargs > 1) { 
01542         mode = sqlite3_value_int(args[1]); 
01543     } 
01544     dd‐>with_schema = !(mode & 1); 
01545     dd‐>quote_mode = (mode >> 8) & 3; 
01546     dd‐>nlines = 0; 
01547     if (fputs("BEGIN TRANSACTION;\n", dd‐>out) >= 0) { 
01548         dd‐>nlines++; 
01549     } 
01550     if (nargs <= 2) { 
01551         schema_dump(dd, 0, 
01552                     "SELECT name, type, sql FROM sqlite_master" 
01553                     " WHERE sql NOT NULL AND type = 'table'");
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 18/32
10/02/2017 impexp.c Source File

01553                     " WHERE sql NOT NULL AND type = 'table'");
01554         if (dd‐>with_schema) { 
01555             table_dump(dd, 0, 0, 
01556                        "SELECT sql FROM sqlite_master WHERE" 
01557                        " sql NOT NULL AND type IN ('index','trigger','view')"); 
01558         } 
01559     } else { 
01560         for (i = 2; i < nargs; i += (mode & 2) ? 2 : 1) { 
01561             dd‐>where = 0; 
01562             if ((mode & 2) && (i + 1 < nargs)) { 
01563                 dd‐>where = (char *) sqlite3_value_text(args[i + 1]); 
01564             } 
01565             schema_dump(dd, 0, 
01566                         "SELECT name, type, sql FROM sqlite_master" 
01567                         " WHERE tbl_name LIKE %Q AND type = 'table'" 
01568                         " AND sql NOT NULL", 
01569                         sqlite3_value_text(args[i])); 
01570             if (dd‐>with_schema) { 
01571                 table_dump(dd, 0, 1, 
01572                            "SELECT sql FROM sqlite_master" 
01573                            " WHERE sql NOT NULL" 
01574                            " AND type IN ('index','trigger','view')" 
01575                            " AND tbl_name LIKE %Q", 
01576                            sqlite3_value_text(args[i])); 
01577             } 
01578         } 
01579     } 
01580     if (fputs("COMMIT;\n", dd‐>out) >= 0) { 
01581         dd‐>nlines++; 
01582     } 
01583     fclose(dd‐>out); 
01584 done: 
01585     sqlite3_result_int(ctx, dd‐>nlines); 
01586 } 
01587  
01595 static void 
01596 export_csv_func(sqlite3_context *ctx, int nargs, sqlite3_value **args) 
01597 { 
01598     DUMP_DATA dd0, *dd = &dd0; 
01599     sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx); 
01600     int i; 
01601     char *filename = 0; 
01602 #ifdef _WIN32 
01603     char fnbuf[MAX_PATH]; 
01604 #endif 
01605  
01606     dd‐>db = db; 
01607     dd‐>where = 0; 
01608     dd‐>nlines = ‐1; 
01609     dd‐>indent = 0; 
01610     dd‐>with_schema = 0; 
01611     dd‐>quote_mode = ‐1; 
01612     if (nargs > 0) { 
01613         if (sqlite3_value_type(args[0]) != SQLITE_NULL) { 
01614             filename = (char *) sqlite3_value_text(args[0]); 
01615         } 
01616     } 
01617 #ifdef _WIN32 
01618     if (!filename) { 
01619         OPENFILENAME ofn; 
01620  
01621         memset(&ofn, 0, sizeof (ofn)); 
01622         memset(fnbuf, 0, sizeof (fnbuf)); 
01623         ofn.lStructSize = sizeof (ofn); 
01624         ofn.lpstrFile = fnbuf; 
01625         ofn.nMaxFile = MAX_PATH; 
01626         ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER | 
01627                     OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; 
01628         if (GetSaveFileName(&ofn)) { 
01629             filename = fnbuf; 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 19/32
10/02/2017 impexp.c Source File

01629             filename = fnbuf; 
01630         } 
01631     } 
01632 #endif 
01633     if (!filename) { 
01634         goto done; 
01635     } 
01636 #ifdef _WIN32 
01637     dd‐>out = fopen(filename, "wb"); 
01638 #else 
01639     dd‐>out = fopen(filename, "w");
01640 #endif 
01641     if (!dd‐>out) { 
01642         goto done; 
01643     } 
01644     dd‐>nlines = 0; 
01645     if (nargs > 1) { 
01646         if (sqlite3_value_type(args[1]) != SQLITE_NULL) { 
01647             if (sqlite3_value_int(args[1])) { 
01648                 dd‐>indent = 1; 
01649             } 
01650         } 
01651     } 
01652     for (i = 2; i <= nargs ‐ 3; i += 3) { 
01653         char *schema = 0, *sql; 
01654  
01655         dd‐>where = 0; 
01656         if (sqlite3_value_type(args[i]) != SQLITE_NULL) { 
01657             dd‐>where = (char *) sqlite3_value_text(args[i]); 
01658             if (dd‐>where && !dd‐>where[0]) { 
01659                 dd‐>where = 0; 
01660             } 
01661         } 
01662         if (sqlite3_value_type(args[i + 2]) != SQLITE_NULL) { 
01663             schema = (char *) sqlite3_value_text(args[i + 2]);
01664         } 
01665         if (!schema || (schema[0] == '\0')) { 
01666             schema = "sqlite_master"; 
01667         } 
01668         sql = sqlite3_mprintf("SELECT name, type, sql FROM %s" 
01669                               " WHERE tbl_name LIKE %%Q AND " 
01670                               " (type = 'table' OR type = 'view')" 
01671                               " AND sql NOT NULL", schema); 
01672         if (sql) { 
01673             schema_dump(dd, 0, sql, sqlite3_value_text(args[i + 1])); 
01674             sqlite3_free(sql); 
01675         } 
01676     } 
01677     fclose(dd‐>out); 
01678 done: 
01679     sqlite3_result_int(ctx, dd‐>nlines); 
01680 } 
01681  
01689 static void 
01690 export_xml_func(sqlite3_context *ctx, int nargs, sqlite3_value **args) 
01691 { 
01692     DUMP_DATA dd0, *dd = &dd0; 
01693     sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx); 
01694     int i; 
01695     char *filename = 0; 
01696     char *openmode = "w"; 
01697 #ifdef _WIN32 
01698     char fnbuf[MAX_PATH]; 
01699 #endif 
01700  
01701     dd‐>db = db; 
01702     dd‐>where = 0; 
01703     dd‐>nlines = ‐1; 
01704     dd‐>indent = 0; 

01705     dd‐>with_schema = 0; 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 20/32
10/02/2017 impexp.c Source File

01705     dd‐>with_schema = 0; 
01706     dd‐>quote_mode = ‐2; 
01707     if (nargs > 0) { 
01708         if (sqlite3_value_type(args[0]) != SQLITE_NULL) { 
01709             filename = (char *) sqlite3_value_text(args[0]); 
01710         } 
01711     } 
01712 #ifdef _WIN32 
01713     if (!filename) { 
01714         OPENFILENAME ofn; 
01715  
01716         memset(&ofn, 0, sizeof (ofn)); 
01717         memset(fnbuf, 0, sizeof (fnbuf)); 
01718         ofn.lStructSize = sizeof (ofn); 
01719         ofn.lpstrFile = fnbuf; 
01720         ofn.nMaxFile = MAX_PATH; 
01721         ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER | 
01722                     OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; 
01723         if (GetSaveFileName(&ofn)) { 
01724             filename = fnbuf; 
01725         } 
01726     } 
01727 #endif 
01728     if (!filename) { 
01729         goto done; 
01730     } 
01731     if (nargs > 1) { 
01732         if (sqlite3_value_type(args[1]) != SQLITE_NULL) { 
01733             if (sqlite3_value_int(args[1])) { 
01734                 openmode = "a"; 
01735             } 
01736         } 
01737     } 
01738     if (nargs > 2) { 
01739         if (sqlite3_value_type(args[2]) != SQLITE_NULL) { 
01740             dd‐>indent = sqlite3_value_int(args[2]); 
01741             if (dd‐>indent < 0) { 
01742                 dd‐>indent = 0; 
01743             } 
01744         } 
01745     } 
01746     dd‐>out = fopen(filename, openmode); 
01747     if (!dd‐>out) { 
01748         goto done; 
01749     } 
01750     dd‐>nlines = 0; 
01751     for (i = 3; i <= nargs ‐ 4; i += 4) { 
01752         char *root = 0, *schema = 0, *sql; 
01753  
01754         if (sqlite3_value_type(args[i]) != SQLITE_NULL) { 
01755             root = (char *) sqlite3_value_text(args[i]); 
01756             if (root && !root[0]) { 
01757                 root = 0; 
01758             } 
01759         } 
01760         dd‐>where = 0; 
01761         if (sqlite3_value_type(args[i + 1]) != SQLITE_NULL) { 
01762             dd‐>where = (char *) sqlite3_value_text(args[i + 1]); 
01763             if (dd‐>where && !dd‐>where[0]) { 
01764                 dd‐>where = 0; 
01765             } 
01766         } 
01767         if (root) { 
01768             indent(dd); 
01769             dd‐>indent++; 
01770             fputs("<", dd‐>out); 
01771             quote_xml_str(dd, root); 
01772             fputs(">\n", dd‐>out); 
01773         } 
01774         if (sqlite3_value_type(args[i + 3]) != SQLITE_NULL) { 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 21/32
10/02/2017 impexp.c Source File

01774         if (sqlite3_value_type(args[i + 3]) != SQLITE_NULL) { 
01775             schema = (char *) sqlite3_value_text(args[i + 3]);
01776         } 
01777         if (!schema || (schema[0] == '\0')) { 
01778             schema = "sqlite_master"; 
01779         } 
01780         sql = sqlite3_mprintf("SELECT name, type, sql FROM %s" 
01781                               " WHERE tbl_name LIKE %%Q AND" 
01782                               " (type = 'table' OR type = 'view')" 
01783                               " AND sql NOT NULL", schema); 
01784         if (sql) { 
01785             schema_dump(dd, 0, sql, sqlite3_value_text(args[i + 2])); 
01786             sqlite3_free(sql); 
01787         } 
01788         if (root) { 
01789             dd‐>indent‐‐; 
01790             indent(dd); 
01791             fputs("</", dd‐>out); 
01792             quote_xml_str(dd, root); 
01793             fputs(">\n", dd‐>out); 
01794         } 
01795     } 
01796     fclose(dd‐>out); 
01797 done: 
01798     sqlite3_result_int(ctx, dd‐>nlines); 
01799 } 
01800  
01801 /* see doc in impexp.h */ 
01802  
01803 int 
01804 impexp_export_sql(sqlite3 *db, char *filename, int mode, ...) 
01805 { 
01806     DUMP_DATA dd0, *dd = &dd0; 
01807     va_list ap; 
01808     char *table; 
01809 #ifdef _WIN32 
01810     char fnbuf[MAX_PATH]; 
01811 #endif 
01812  
01813     if (!db) { 
01814         return 0; 
01815     } 
01816     dd‐>db = db; 
01817     dd‐>where = 0; 
01818     dd‐>nlines = ‐1; 
01819 #ifdef _WIN32 
01820     if (!filename) { 
01821         OPENFILENAME ofn; 
01822  
01823         memset(&ofn, 0, sizeof (ofn)); 
01824         memset(fnbuf, 0, sizeof (fnbuf)); 
01825         ofn.lStructSize = sizeof (ofn); 
01826         ofn.lpstrFile = fnbuf; 
01827         ofn.nMaxFile = MAX_PATH; 
01828         ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER | 
01829                     OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; 
01830         if (GetSaveFileName(&ofn)) { 
01831             filename = fnbuf; 
01832         } 
01833     } 
01834 #endif 
01835     if (!filename) { 
01836         goto done; 
01837     } 
01838     dd‐>out = fopen(filename, "w"); 
01839     if (!dd‐>out) { 
01840         goto done; 
01841     } 
01842     dd‐>with_schema = !(mode & 1); 

01843     dd‐>nlines = 0; 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 22/32
10/02/2017 impexp.c Source File

01843     dd‐>nlines = 0; 
01844     if (fputs("BEGIN TRANSACTION;\n", dd‐>out) >= 0) { 
01845         dd‐>nlines++; 
01846     } 
01847     va_start(ap, mode); 
01848     table = va_arg(ap, char *); 
01849     if (!table) { 
01850         schema_dump(dd, 0, 
01851                     "SELECT name, type, sql FROM sqlite_master" 
01852                     " WHERE sql NOT NULL AND type = 'table'");
01853         if (dd‐>with_schema) { 
01854             table_dump(dd, 0, 0, 
01855                        "SELECT sql FROM sqlite_master WHERE" 
01856                        " sql NOT NULL AND type IN ('index','trigger','view')"); 
01857         } 
01858     } else { 
01859         while (table) { 
01860             dd‐>where = 0; 
01861             if ((mode & 2)) { 
01862                 dd‐>where = va_arg(ap, char *); 
01863             } 
01864             schema_dump(dd, 0, 
01865                         "SELECT name, type, sql FROM sqlite_master" 
01866                         " WHERE tbl_name LIKE %Q AND type = 'table'" 
01867                         " AND sql NOT NULL", table); 
01868             if (dd‐>with_schema) { 
01869                 table_dump(dd, 0, 1, 
01870                            "SELECT sql FROM sqlite_master" 
01871                            " WHERE sql NOT NULL" 
01872                            " AND type IN ('index','trigger','view')" 
01873                            " AND tbl_name LIKE %Q", table); 
01874             } 
01875             table = va_arg(ap, char *); 
01876         } 
01877     } 
01878     va_end(ap); 
01879     if (fputs("COMMIT;\n", dd‐>out) >= 0) { 
01880         dd‐>nlines++; 
01881     } 
01882     fclose(dd‐>out); 
01883 done: 
01884     return dd‐>nlines; 
01885 } 
01886  
01887 /* see doc in impexp.h */ 
01888  
01889 int 
01890 impexp_export_csv(sqlite3 *db, char *filename, int hdr, ...) 
01891 { 
01892     DUMP_DATA dd0, *dd = &dd0; 
01893     va_list ap; 
01894     char *prefix, *table, *schema; 
01895 #ifdef _WIN32 
01896     char fnbuf[MAX_PATH]; 
01897 #endif 
01898  
01899     if (!db) { 
01900         return 0; 
01901     } 
01902     dd‐>db = db; 
01903     dd‐>where = 0; 
01904     dd‐>nlines = ‐1; 
01905     dd‐>indent = 0; 
01906     dd‐>with_schema = 0; 
01907     dd‐>quote_mode = ‐1; 
01908     dd‐>indent = hdr != 0; 
01909 #ifdef _WIN32 
01910     if (!filename) { 
01911         OPENFILENAME ofn; 
01912  
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 23/32
10/02/2017 impexp.c Source File

01912  
01913         memset(&ofn, 0, sizeof (ofn)); 
01914         memset(fnbuf, 0, sizeof (fnbuf)); 
01915         ofn.lStructSize = sizeof (ofn); 
01916         ofn.lpstrFile = fnbuf; 
01917         ofn.nMaxFile = MAX_PATH; 
01918         ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER | 
01919                     OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; 
01920         if (GetSaveFileName(&ofn)) { 
01921             filename = fnbuf; 
01922         } 
01923     } 
01924 #endif 
01925     if (!filename) { 
01926         goto done; 
01927     } 
01928 #ifdef _WIN32 
01929     dd‐>out = fopen(filename, "wb"); 
01930 #else 
01931     if ((hdr < 0) && access(filename, W_OK) == 0) { 
01932         dd‐>out = fopen(filename, "a"); 
01933         dd‐>indent = 0; 
01934     } else { 
01935         dd‐>out = fopen(filename, "w"); 
01936     } 
01937 #endif 
01938     if (!dd‐>out) { 
01939         goto done; 
01940     } 
01941     dd‐>nlines = 0; 
01942     va_start(ap, hdr); 
01943     prefix = va_arg(ap, char *); 
01944     table = va_arg(ap, char *); 
01945     schema = va_arg(ap, char *); 
01946     while (table != NULL) { 
01947         char *sql; 
01948  
01949         dd‐>where = (prefix && prefix[0]) ? prefix : 0; 
01950         if (!schema || (schema[0] == '\0')) { 
01951             schema = "sqlite_master"; 
01952         } 
01953         sql = sqlite3_mprintf("SELECT name, type, sql FROM %s" 
01954                               " WHERE tbl_name LIKE %%Q AND" 
01955                               " (type = 'table' OR type = 'view')" 
01956                               " AND sql NOT NULL", schema); 
01957         if (sql) { 
01958             schema_dump(dd, 0, sql, table); 
01959             sqlite3_free(sql); 
01960         } 
01961         prefix = va_arg(ap, char *); 
01962         table = va_arg(ap, char *); 
01963         schema = va_arg(ap, char *); 
01964     } 
01965     va_end(ap); 
01966     fclose(dd‐>out); 
01967 done: 
01968     return dd‐>nlines; 
01969 } 
01970  
01971 /* see doc in impexp.h */ 
01972  
01973 int 
01974 impexp_export_xml(sqlite3 *db, char *filename, int append, int indnt, 
01975                   char *root, char *item, char *tablename, char *schema) 
01976 { 
01977     DUMP_DATA dd0, *dd = &dd0; 
01978     char *sql; 
01979 #ifdef _WIN32 
01980     char fnbuf[MAX_PATH]; 

01981 #endif 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 24/32
10/02/2017 impexp.c Source File

01981 #endif 
01982  
01983     if (!db) { 
01984         return 0; 
01985     } 
01986     dd‐>db = db; 
01987     dd‐>where = item; 
01988     dd‐>nlines = ‐1; 
01989     dd‐>indent = (indnt > 0) ? indnt : 0; 
01990     dd‐>with_schema = 0; 
01991     dd‐>quote_mode = ‐2; 
01992 #ifdef _WIN32 
01993     if (!filename) { 
01994         OPENFILENAME ofn; 
01995  
01996         memset(&ofn, 0, sizeof (ofn)); 
01997         memset(fnbuf, 0, sizeof (fnbuf)); 
01998         ofn.lStructSize = sizeof (ofn); 
01999         ofn.lpstrFile = fnbuf; 
02000         ofn.nMaxFile = MAX_PATH; 
02001         ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER | 
02002                     OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; 
02003         if (GetSaveFileName(&ofn)) { 
02004             filename = fnbuf; 
02005         } 
02006     } 
02007 #endif 
02008     if (!filename) { 
02009         goto done; 
02010     } 
02011     dd‐>out = fopen(filename, append ? "a" : "w"); 
02012     if (!dd‐>out) { 
02013         goto done; 
02014     } 
02015     dd‐>nlines = 0; 
02016     if (root) { 
02017         indent(dd); 
02018         dd‐>indent++; 
02019         fputs("<", dd‐>out); 
02020         quote_xml_str(dd, root); 
02021         fputs(">\n", dd‐>out); 
02022     } 
02023     if (!schema || (schema[0] == '\0')) { 
02024         schema = "sqlite_master"; 
02025     } 
02026     sql = sqlite3_mprintf("SELECT name, type, sql FROM %s" 
02027                           " WHERE tbl_name LIKE %%Q AND" 
02028                           " (type = 'table' OR type = 'view')" 
02029                           " AND sql NOT NULL", schema); 
02030     if (sql) { 
02031         schema_dump(dd, 0, sql, tablename); 
02032         sqlite3_free(sql); 
02033     } 
02034     if (root) { 
02035         dd‐>indent‐‐; 
02036         indent(dd); 
02037         fputs("</", dd‐>out); 
02038         quote_xml_str(dd, root); 
02039         fputs(">\n", dd‐>out); 
02040     } 
02041     fclose(dd‐>out); 
02042 done: 
02043     return dd‐>nlines; 
02044 } 
02045  
02052 static void 
02053 json_pstr(const char *string, json_pfs *pfs) 
02054 { 
02055     while (*string) { 
02056         pfs‐>pfunc(*string, pfs‐>parg); 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 25/32
10/02/2017 impexp.c Source File

02056         pfs‐>pfunc(*string, pfs‐>parg); 
02057         string++; 
02058     } 
02059 } 
02060  
02067 static void 
02068 json_pstrq(const char *string, json_pfs *pfs) 
02069 { 
02070     impexp_putc pfunc = pfs‐>pfunc; 
02071     void *parg = pfs‐>parg; 
02072     char buf[64]; 
02073  
02074     if (!string) { 
02075         json_pstr("null", pfs); 
02076         return; 
02077     } 
02078     pfunc('"', parg); 
02079     while (*string) { 
02080         switch (*string) { 
02081         case '"': 
02082         case '\\': 
02083             pfunc('\\', parg); 
02084             pfunc(*string, parg); 
02085             break; 
02086         case '\b': 
02087             pfunc('\\', parg); 
02088             pfunc('b', parg); 
02089             break; 
02090         case '\f': 
02091             pfunc('\\', parg); 
02092             pfunc('f', parg); 
02093             break; 
02094         case '\n': 
02095             pfunc('\\', parg); 
02096             pfunc('n', parg); 
02097             break; 
02098         case '\r': 
02099             pfunc('\\', parg); 
02100             pfunc('r', parg); 
02101             break; 
02102         case '\t': 
02103             pfunc('\\', parg); 
02104             pfunc('t', parg); 
02105             break; 
02106         default: 
02107             if (((*string < ' ') && (*string > 0)) || (*string == 0x7f)) { 
02108                 sprintf(buf, "\\u%04x", *string); 
02109                 json_pstr(buf, pfs); 
02110             } else if (*string < 0) { 
02111                 unsigned char c = string[0]; 
02112                 unsigned long uc = 0; 
02113  
02114                 if (c < 0xc0) { 
02115                     uc = c; 
02116                 } else if (c < 0xe0) { 
02117                     if ((string[1] & 0xc0) == 0x80) { 
02118                         uc = ((c & 0x1f) << 6) | (string[1] & 0x3f); 
02119                         ++string; 
02120                     } else { 
02121                         uc = c; 
02122                     } 
02123                 } else if (c < 0xf0) { 
02124                     if (((string[1] & 0xc0) == 0x80) && 
02125                         ((string[2] & 0xc0) == 0x80)) { 
02126                         uc = ((c & 0x0f) << 12) | 
02127                              ((string[1] & 0x3f) << 6) | (string[2] & 0x3f); 
02128                         string += 2; 
02129                     } else { 
02130                         uc = c; 

02131                     } 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 26/32
10/02/2017 impexp.c Source File

02131                     } 
02132                 } else if (c < 0xf8) { 
02133                     if (((string[1] & 0xc0) == 0x80) && 
02134                         ((string[2] & 0xc0) == 0x80) && 
02135                         ((string[3] & 0xc0) == 0x80)) { 
02136                         uc = ((c & 0x03) << 18) | 
02137                              ((string[1] & 0x3f) << 12) | 
02138                              ((string[2] & 0x3f) << 6) | 
02139                              (string[4] & 0x3f); 
02140                         string += 3; 
02141                     } else { 
02142                         uc = c; 
02143                     } 
02144                 } else if (c < 0xfc) { 
02145                     if (((string[1] & 0xc0) == 0x80) && 
02146                         ((string[2] & 0xc0) == 0x80) && 
02147                         ((string[3] & 0xc0) == 0x80) && 
02148                         ((string[4] & 0xc0) == 0x80)) { 
02149                         uc = ((c & 0x01) << 24) | 
02150                              ((string[1] & 0x3f) << 18) | 
02151                              ((string[2] & 0x3f) << 12) | 
02152                              ((string[4] & 0x3f) << 6) | 
02153                              (string[5] & 0x3f); 
02154                         string += 4; 
02155                     } else { 
02156                         uc = c; 
02157                     } 
02158                 } else { 
02159                     /* ignore */ 
02160                     ++string; 
02161                 } 
02162                 if (uc < 0x10000) { 
02163                     sprintf(buf, "\\u%04lx", uc); 
02164                 } else if (uc < 0x100000) { 
02165                     uc ‐= 0x10000; 
02166  
02167                     sprintf(buf, "\\u%04lx", 0xd800 | ((uc >> 10) & 0x3ff)); 
02168                     json_pstr(buf, pfs); 
02169                     sprintf(buf, "\\u%04lx", 0xdc00 | (uc & 0x3ff)); 
02170                 } else { 
02171                     strcpy(buf, "\\ufffd"); 
02172                 } 
02173                 json_pstr(buf, pfs); 
02174             } else { 
02175                 pfunc(*string, parg); 
02176             } 
02177             break; 
02178         } 
02179         ++string; 
02180     } 
02181     pfunc('"', parg); 
02182 } 
02183  
02190 static void 
02191 json_pstrc(const char *string, json_pfs *pfs) 
02192 { 
02193     if (*string && strchr(".0123456789‐+", *string)) { 
02194         json_pstr(string, pfs); 
02195     } else { 
02196         json_pstrq(string, pfs); 
02197     } 
02198 } 
02199  
02207 static void 
02208 json_pb64(const unsigned char *blk, int len, json_pfs *pfs) 
02209 { 
02210     impexp_putc pfunc = pfs‐>pfunc; 
02211     void *parg = pfs‐>parg; 
02212     int i, reg[5]; 
02213     char buf[16]; 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 27/32
10/02/2017 impexp.c Source File

02213     char buf[16]; 
02214     static const char *b64 = 
02215         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 
02216  
02217     if (!blk) { 
02218         json_pstr("null", pfs); 
02219         return; 
02220     } 
02221     buf[4] = '\0'; 
02222     pfunc('"', parg); 
02223     for (i = 0; i < len; i += 3) { 
02224         reg[1] = reg[2] = reg[3] = reg[4] = 0; 
02225         reg[0] = blk[i]; 
02226         if (i + 1 < len) { 
02227             reg[1] = blk[i + 1]; 
02228             reg[3] = 1; 
02229         } 
02230         if (i + 2 < len) { 
02231             reg[2] = blk[i + 2]; 
02232             reg[4] = 1; 
02233         } 
02234         buf[0] = b64[reg[0] >> 2]; 
02235         buf[1] = b64[((reg[0] << 4) & 0x30) | (reg[1] >> 4)]; 
02236         if (reg[3]) { 
02237             buf[2] = b64[((reg[1] << 2) & 0x3c) | (reg[2] >> 6)]; 
02238         } else { 
02239             buf[2] = '='; 
02240         } 
02241         if (reg[4]) { 
02242             buf[3] = b64[reg[2] & 0x3f]; 
02243         } else { 
02244             buf[3] = '='; 
02245         } 
02246         json_pstr(buf, pfs); 
02247     } 
02248     pfunc('"', parg); 
02249 } 
02250  
02260 static int 
02261 json_output(sqlite3 *db, char *sql, impexp_putc pfunc, void *parg) 
02262 { 
02263     json_pfs pfs0, *pfs = &pfs0; 
02264     const char *tail = sql; 
02265     int i, nresults = 0, result = SQLITE_ERROR; 
02266  
02267     pfs‐>pfunc = pfunc; 
02268     pfs‐>parg = parg; 
02269     json_pstr("{\"sql\":", pfs); 
02270     json_pstrq(sql, pfs); 
02271     json_pstr(",\"results\":[", pfs); 
02272     do { 
02273         sqlite3_stmt *stmt; 
02274         int firstrow = 1, nrows = 0; 
02275         char buf[256]; 
02276  
02277         ++nresults; 
02278         json_pstr((nresults == 1) ? "{" : ",{", pfs); 
02279         result = sqlite3_prepare(db, tail, ‐1, &stmt, &tail); 
02280         if (result != SQLITE_OK) { 
02281 doerr: 
02282             if (nrows == 0) { 
02283                 json_pstr("\"columns\":null,\"rows\":null,\"changes\":0," 
02284                           "\"last_insert_rowid\":null,", pfs); 
02285             } 
02286             json_pstr("\"error:\"", pfs); 
02287             json_pstrq(sqlite3_errmsg(db), pfs); 
02288             pfunc('}', parg); 
02289             break; 
02290         } 

02291         result = sqlite3_step(stmt); 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 28/32
10/02/2017 impexp.c Source File

02291         result = sqlite3_step(stmt); 
02292         while ((result == SQLITE_ROW) || (result == SQLITE_DONE)) { 
02293             if (firstrow) { 
02294                 for (i = 0; i < sqlite3_column_count(stmt); i++) { 
02295                     char *type; 
02296  
02297                     json_pstr((i == 0) ? "\"columns\":[" : ",", pfs); 
02298                     json_pstr("{\"name\":", pfs); 
02299                     json_pstrq(sqlite3_column_name(stmt, i), pfs); 
02300                     json_pstr(",\"decltype\":", pfs); 
02301                     json_pstrq(sqlite3_column_decltype(stmt, i), pfs); 
02302                     json_pstr(",\"type\":", pfs); 
02303                     switch (sqlite3_column_type(stmt, i)) { 
02304                     case SQLITE_INTEGER: 
02305                         type = "integer"; 
02306                         break; 
02307                     case SQLITE_FLOAT: 
02308                         type = "float"; 
02309                         break; 
02310                     case SQLITE_BLOB: 
02311                         type = "blob"; 
02312                         break; 
02313                     case SQLITE_TEXT: 
02314                         type = "text"; 
02315                         break; 
02316                     case SQLITE_NULL: 
02317                         type = "null"; 
02318                         break; 
02319                     default:
02320                         type = "unknown"; 
02321                         break; 
02322                     } 
02323                     json_pstrq(type, pfs); 
02324                     pfunc('}', parg); 
02325                 } 
02326                 if (i) { 
02327                     pfunc(']', parg); 
02328                 } 
02329                 firstrow = 0; 
02330             } 
02331             if (result == SQLITE_DONE) { 
02332                 break; 
02333             } 
02334             ++nrows; 
02335             json_pstr((nrows == 1) ? ",\"rows\":[" : ",", pfs); 
02336             for (i = 0; i < sqlite3_column_count(stmt); i++) { 
02337                 pfunc((i == 0) ? '[' : ',', parg); 
02338                 switch (sqlite3_column_type(stmt, i)) { 
02339                 case SQLITE_INTEGER: 
02340                     json_pstr((char *) sqlite3_column_text(stmt, i), pfs); 
02341                     break; 
02342                 case SQLITE_FLOAT: 
02343                     json_pstrc((char *) sqlite3_column_text(stmt, i), pfs); 
02344                     break; 
02345                 case SQLITE_BLOB: 
02346                     json_pb64((unsigned char *) sqlite3_column_blob(stmt, i), 
02347                               sqlite3_column_bytes(stmt, i), pfs); 
02348                     break; 
02349                 case SQLITE_TEXT: 
02350                     json_pstrq((char *) sqlite3_column_text(stmt, i), pfs); 
02351                     break; 
02352                 case SQLITE_NULL: 
02353                 default: 
02354                     json_pstr("null", pfs); 
02355                     break; 
02356                 } 
02357             } 
02358             json_pstr((i == 0) ? "null]" : "]", pfs); 
02359             result = sqlite3_step(stmt); 

02360         } 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 29/32
10/02/2017 impexp.c Source File

02360         } 
02361         if (nrows > 0) { 
02362             pfunc(']', parg); 
02363         } 
02364         result = sqlite3_finalize(stmt); 
02365         if (result != SQLITE_OK) { 
02366             if (nrows > 0) { 
02367                 sprintf(buf,
02368 #ifdef _WIN32 
02369                         ",\"changes\":%d,\"last_insert_rowid\":%I64d", 
02370 #else 
02371                         ",\"changes\":%d,\"last_insert_rowid\":%lld", 
02372 #endif 
02373                         sqlite3_changes(db), 
02374                         sqlite3_last_insert_rowid(db)); 
02375                 json_pstr(buf, pfs); 
02376             } 
02377             goto doerr; 
02378         } 
02379         if (nrows == 0) { 
02380             json_pstr("\"columns\":null,\"rows\":null", pfs); 
02381         } 
02382         sprintf(buf, 
02383 #ifdef _WIN32 
02384                 ",\"changes\":%d,\"last_insert_rowid\":%I64d",
02385 #else 
02386                 ",\"changes\":%d,\"last_insert_rowid\":%lld", 
02387 #endif 
02388                 sqlite3_changes(db), 
02389                 sqlite3_last_insert_rowid(db)); 
02390         json_pstr(buf, pfs); 
02391         json_pstr(",\"error\":null}", pfs); 
02392     } while (tail && *tail);
02393     json_pstr("]}", pfs); 
02394     return result; 
02395 } 
02396  
02404 static void 
02405 export_json_func(sqlite3_context *ctx, int nargs, sqlite3_value **args) 
02406 { 
02407     sqlite3 *db = (sqlite3 *) sqlite3_user_data(ctx); 
02408     int result = ‐1; 
02409     char *filename = 0; 
02410     char *sql = 0; 
02411     FILE *out = 0; 
02412 #ifdef _WIN32 
02413     char fnbuf[MAX_PATH]; 
02414 #endif 
02415  
02416     if (nargs > 0) { 
02417         if (sqlite3_value_type(args[0]) != SQLITE_NULL) { 
02418             filename = (char *) sqlite3_value_text(args[0]); 
02419         } 
02420     } 
02421 #ifdef _WIN32 
02422     if (!filename) { 
02423         OPENFILENAME ofn; 
02424  
02425         memset(&ofn, 0, sizeof (ofn)); 
02426         memset(fnbuf, 0, sizeof (fnbuf)); 
02427         ofn.lStructSize = sizeof (ofn); 
02428         ofn.lpstrFile = fnbuf; 
02429         ofn.nMaxFile = MAX_PATH; 
02430         ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER | 
02431                     OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; 
02432         if (GetSaveFileName(&ofn)) { 
02433             filename = fnbuf; 
02434         } 
02435     } 

02436 #endif 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 30/32
10/02/2017 impexp.c Source File

02436 #endif 
02437     if (!filename) { 
02438         goto done; 
02439     } 
02440     out = fopen(filename, "w"); 
02441     if (!out) { 
02442         goto done; 
02443     } 
02444     if (nargs > 1) { 
02445         sql = (char *) sqlite3_value_text(args[1]); 
02446     } 
02447     if (sql) { 
02448         result = json_output(db, sql, (impexp_putc) fputc, out); 
02449     } 
02450     fclose(out); 
02451 done: 
02452     sqlite3_result_int(ctx, result); 
02453 } 
02454  
02455 /* see doc in impexp.h */ 
02456  
02457 int 
02458 impexp_export_json(sqlite3 *db, char *sql, impexp_putc pfunc, 
02459                    void *parg) 
02460 { 
02461     return json_output(db, sql, pfunc, parg); 
02462 } 
02463  
02472 #ifdef STANDALONE 
02473 static int 
02474 #else 
02475 int 
02476 #endif 
02477 sqlite3_extension_init(sqlite3 *db, char **errmsg, 
02478                        const sqlite3_api_routines *api) 
02479 { 
02480     int rc, i; 
02481     static const struct { 
02482         const char *name; 
02483         void (*func)(sqlite3_context *, int, sqlite3_value **); 
02484         int nargs; 
02485         int textrep; 
02486     } ftab[] = { 
02487         { "quote_sql",   quote_func,       ‐1, SQLITE_UTF8 }, 
02488         { "import_sql",  import_func,      ‐1, SQLITE_UTF8 }, 
02489         { "export_sql",  export_func,      ‐1, SQLITE_UTF8 }, 
02490         { "quote_csv",   quote_csv_func,   ‐1, SQLITE_UTF8 }, 
02491         { "export_csv",  export_csv_func,  ‐1, SQLITE_UTF8 }, 
02492         { "indent_xml",  indent_xml_func,   1, SQLITE_UTF8 }, 
02493         { "quote_xml",   quote_xml_func,   ‐1, SQLITE_UTF8 }, 
02494         { "export_xml",  export_xml_func,  ‐1, SQLITE_UTF8 }, 
02495         { "export_json", export_json_func, ‐1, SQLITE_UTF8 } 
02496     }; 
02497  
02498 #ifndef STANDALONE 
02499     if (api != NULL) { 
02500         SQLITE_EXTENSION_INIT2(api); 
02501     } 
02502 #endif 
02503  
02504     for (i = 0; i < sizeof (ftab) / sizeof (ftab[0]); i++) { 
02505         rc = sqlite3_create_function(db, ftab[i].name, ftab[i].nargs, 
02506                                      ftab[i].textrep, db, ftab[i].func, 0, 0); 
02507         if (rc != SQLITE_OK) { 
02508             for (‐‐i; i >= 0; ‐‐i) { 
02509                 sqlite3_create_function(db, ftab[i].name, ftab[i].nargs, 
02510                                         ftab[i].textrep, 0, 0, 0, 0); 
02511             } 
02512             break; 

02513         } 
http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 31/32
10/02/2017 impexp.c Source File

02513         } 
02514     } 
02515     return rc; 
02516 } 
02517  
02518 /* see doc in impexp.h */ 
02519  
02520 int 
02521 impexp_init(sqlite3 *db) 
02522 { 
02523     return sqlite3_extension_init(db, NULL, NULL); 
02524 } 

Generated on 1 Dec 2016 by doxygen.
Contact: chw@ch­werner.de

http://www.ch­werner.de/sqliteodbc/html/impexp_8c­source.html 32/32

You might also like