Hi Everyone,

I have patched my SQLite3.exe source (shell.c) to have an ".import" 
function witch can read ".mod csv" exports :


- can read QUOTE + TEXT + CRLF + TEXT + QUOTE
- can read QUOTE + SEPARATOR + QUOTE
- can read QUOTE + TEXT + SEPARATOR + TEXT + QUOTE
- can read QUOTE + TEXT + 2QUOTES + TEXT + QUOTE

So, I can export my table like this :
.mod csv
.output table.csv
select * from table;
.output stdout

And import like this :

.mod csv
.import table.csv table

example of csv file :

1,"this is ok",
2,"this is
a new line",""
3,"look ! , the coma ..."," and the ""quotes"" !"


Patch source code of shell.c :
==============================


/* patch for shell.c version 3_6_23_1 */


// I modified the local_getline() function

// from line 41:

#if defined(HAVE_READLINE) && HAVE_READLINE==1
# include <readline/readline.h>
# include <readline/history.h>
#else
# define readline(p) local_getline(p,stdin,0)
# define add_history(X)
# define read_history(X)
# define write_history(X)
# define stifle_history(X)
#endif


// from line 368:

static char *one_input_line(const char *zPrior, FILE *in){
char *zPrompt;
char *zResult;
if( in!=0 ){
return local_getline(0, in, 0); /* not in csv mode */
}


// function local_getline(), from line 320 :

/* NB: bCsvMode = 1, if the function is used by the .import command */

static char *local_getline(char *zPrompt, FILE *in, const int bCsvMode){
char *zLine;
int nLine;
int n;
int eol;
int bEscaped; /* Escape CRLF when quoted */

if( zPrompt && *zPrompt ){
printf("%s",zPrompt);
fflush(stdout);
}
nLine = 100;
zLine = malloc( nLine );
if( zLine==0 ) return 0;
n = 0;
eol = 0;
bEscaped = 0;
while( !eol ){
if( n+100>nLine ){
nLine = nLine*2 + 100;
zLine = realloc(zLine, nLine);
if( zLine==0 ) return 0;
}
if( fgets(&zLine[n], nLine - n, in)==0 ){
if( n==0 ){
free(zLine);
return 0;
}
zLine[n] = 0;
eol = 1;
break;
}
while( zLine[n] ){
if( zLine[n]=='"' && bCsvMode ) bEscaped = 1 - bEscaped;
n++;
}
if( !bEscaped && n>0 && zLine[n-1]=='\n' ){
n--;
if( n>0 && zLine[n-1]=='\r' ) n--;
zLine[n] = 0;
eol = 1;
}
}
zLine = realloc( zLine, n+1 );
return zLine;
}




// and from line 1628 :


sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
zCommit = "COMMIT";
while( (zLine = local_getline(0, in, 1))!=0 ){ /* csv mode */
char *z;
char *q;
int bEscaped; /* to escape quote + comma + quote */
int bFieldQuoted;
bEscaped = 0;
i = 0;
lineno++;
if( *zLine=='"' ){
azCol[0] = zLine + 1; /* ignore the first quote */
bFieldQuoted = 1;
}else{
azCol[0] = zLine;
bFieldQuoted = 0;
}
for(i=0, z=zLine, q=zLine; *z ; z++){
if( *z=='"' ) bEscaped = 1 - bEscaped;
if( bEscaped==0 && *z==p->separator[0] && strncmp(z, p->separator, 
nSep)==0 ){
if( bFieldQuoted==1 && *q=='"') *q = 0; /* ignore the last quote */
*z = 0;
i++;
if( i<nCol ){
azCol[i] = &z[nSep];
if( *azCol[i]=='"' ){
azCol[i]++; /* ignore the first quote */
bFieldQuoted = 1;
}else{
bFieldQuoted = 0;
}
z += nSep-1;
}
}
q = z;
} /* end for */
if( bEscaped==0 && bFieldQuoted==1 && *q=='"' ) *q = 0; /* ignore the 
last quote */
*z = 0;
if( i+1!=nCol ){
fprintf(stderr,
"Error: %s line %d: expected %d columns of data but found %d\n",
zFile, lineno, nCol, i+1);
zCommit = "ROLLBACK";
free(zLine);
rc = 1;
break; /* from while */
}
for(i=0; i<nCol; i++){
/* find and reduce double quotes */
for( bEscaped=0, z=azCol[i], q=azCol[i]; *z ; z++, q++){
if( *z=='"' ) z++;
*q = *z;
}
*q = 0;
sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
}
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
free(zLine);


// end


It works, I can import and export csv file with this litle patch (few 
lines of code).


_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to