mdb-export extention
Michael Maassen <[email protected]>
| Newsgroups | gmane.comp.db.mdb-tools.devel |
|---|---|
| Message-ID | <Pine.LNX.4.44.0704051350340.29914-200000@hefr31.physik.uni-freiburg.de> |
Hi, appended is a version of mdb-export which 1) escapes non-printable chars if an escape char is given and no quoting is wanted: ex. -X '=' -Q 2) exports large OLE-columns, which requiers mdb_ole_read_next() (please have a look in ending the loop) You can insert the patch in your dist if you like. Regards, Mic Dr. Michael Maaßen Uni Freiburg mailto:[email protected] Physikalisches Institut Abt. Prof. Herten Phone: + 49 - 761 - 203 - 5720 Hermann-Herder-Str. 3 Fax: + 49 - 761 - 203 - 5938 79104 Freiburg ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ mdbtools-dev mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mdbtools-dev
mdb-cvs.c
(text/x-csrc, 9.7 KB)
/* MDB Tools - A library for reading MS Access database file * Copyright (C) 2000 Brian Bruns * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * add binary escapes by Michael Maassen <[email protected]> */ #include "mdbtools.h" #ifdef DMALLOC #include "dmalloc.h" #endif #undef MDB_BIND_SIZE #define MDB_BIND_SIZE 20000000 #define is_text_type(x) (x==MDB_TEXT || x==MDB_MEMO || x==MDB_SDATETIME || x==MDB_OLE) //#define is_text_type(x) (x==MDB_TEXT || x==MDB_MEMO || x==MDB_SDATETIME) static char *sanitize_name(char *str, int sanitize); static char *escapes(char *s); char *delimiter = NULL; char *row_delimiter = NULL; void print_col(gchar *col_val, int quote_text, int col_type, char *quote_char, char *escape_char) { gchar *s; if (quote_text && is_text_type(col_type)) { fprintf(stdout,quote_char); for (s=col_val;*s;s++) { if (strlen(quote_char)==1 && *s==quote_char[0]) { /* double the char if no escape char passed */ if (!escape_char) { fprintf(stdout,"%s%s",quote_char,quote_char); } else { fprintf(stdout,"%s%s",escape_char,quote_char); } } else fprintf(stdout,"%c",*s); } fprintf(stdout,quote_char); } else { fprintf(stdout,"%s",col_val); } } void nprint_col(gchar *col_val, int len, int quote_text, int col_type, char *quote_char, char *escape_char) { gchar *s; int i; if (len == -1) len = strlen(col_val); if (quote_text && is_text_type(col_type)) { fprintf(stdout,quote_char); for (s=col_val;*s;s++) { if (strlen(quote_char)==1 && *s==quote_char[0]) { /* double the char if no escape char passed */ if (!escape_char) { fprintf(stdout,"%s%s",quote_char,quote_char); } else { fprintf(stdout,"%s%s",escape_char,quote_char); } } else fprintf(stdout,"%c",*s); } fprintf(stdout,quote_char); } else if (!quote_text && escape_char) { // no quoting, only escape to Hex for (i=0;i<len;i++) { s = col_val + i; if (!isprint(*s) || (*s == *escape_char) || (*s == *delimiter) || (*s == *row_delimiter) ) { fprintf(stdout,"%s%02x",escape_char,(unsigned char) *s); } else { fprintf(stdout,"%c",*s); } } } else { fprintf(stdout,"%s",col_val); } } int main(int argc, char **argv) { unsigned int j; MdbHandle *mdb; MdbTableDef *table; MdbColumn *col; char **bound_values; int *bound_lens; char *quote_char = NULL; char *escape_char = NULL; char header_row = 1; char quote_text = 1; char insert_statements = 0; char sanitize = 0; int opt; while ((opt=getopt(argc, argv, "HQq:X:d:D:R:IS"))!=-1) { switch (opt) { case 'H': header_row = 0; break; case 'Q': quote_text = 0; break; case 'q': quote_char = (char *) g_strdup(optarg); break; case 'd': delimiter = escapes(optarg); break; case 'R': row_delimiter = escapes(optarg); break; case 'I': insert_statements = 1; header_row = 0; break; case 'S': sanitize = 1; break; case 'D': mdb_set_date_fmt(optarg); break; case 'X': escape_char = (char *) g_strdup(optarg); break; default: break; } } if (!quote_char) { quote_char = (char *) g_strdup("\""); } if (!delimiter) { delimiter = (char *) g_strdup(","); } if (!row_delimiter) { row_delimiter = (char *) g_strdup("\n"); } /* ** optind is now the position of the first non-option arg, ** see getopt(3) */ if (argc-optind < 2) { fprintf(stderr,"Usage: %s [options] <file> <table>\n",argv[0]); fprintf(stderr,"where options are:\n"); fprintf(stderr," -H supress header row\n"); fprintf(stderr," -Q don't wrap text-like fields in quotes\n"); fprintf(stderr," -d <delimiter> specify a column delimiter\n"); fprintf(stderr," -R <delimiter> specify a row delimiter\n"); fprintf(stderr," -I INSERT statements (instead of CSV)\n"); fprintf(stderr," -D <format> set the date format (see strftime(3) for details)\n"); fprintf(stderr," -S Sanitize names (replace spaces etc. with underscore)\n"); fprintf(stderr," -q <char> Use <char> to wrap text-like fields. Default is \".\n"); fprintf(stderr," -X <char> Use <char> to escape quoted characters within a field. Default is doubling.\n"); g_free (delimiter); g_free (row_delimiter); g_free (quote_char); if (escape_char) g_free (escape_char); exit(1); } mdb_init(); if (!(mdb = mdb_open(argv[optind], MDB_NOFLAGS))) { g_free (delimiter); g_free (row_delimiter); g_free (quote_char); if (escape_char) g_free (escape_char); mdb_exit(); exit(1); } table = mdb_read_table_by_name(mdb, argv[argc-1], MDB_TABLE); if (!table) { fprintf(stderr, "Error: Table %s does not exist in this database.\n", argv[argc-1]); g_free (delimiter); g_free (row_delimiter); g_free (quote_char); if (escape_char) g_free (escape_char); mdb_close(mdb); mdb_exit(); exit(1); } mdb_read_columns(table); mdb_rewind_table(table); bound_values = (char **) g_malloc(table->num_cols * sizeof(char *)); bound_lens = (int *) g_malloc(table->num_cols * sizeof(int)); for (j=0;j<table->num_cols;j++) { bound_values[j] = (char *) g_malloc0(MDB_BIND_SIZE); mdb_bind_column(table, j+1, bound_values[j], &bound_lens[j]); } if (header_row) { col=g_ptr_array_index(table->columns,0); fprintf(stdout,"%s",sanitize_name(col->name,sanitize)); for (j=1;j<table->num_cols;j++) { col=g_ptr_array_index(table->columns,j); fprintf(stdout,delimiter); fprintf(stdout,"%s",sanitize_name(col->name,sanitize)); } fprintf(stdout,"\n"); } while(mdb_fetch_row(table)) { if (insert_statements) { fprintf(stdout, "INSERT INTO %s (", sanitize_name(argv[optind + 1],sanitize)); for (j=0;j<table->num_cols;j++) { if (j>0) fprintf(stdout, ", "); col=g_ptr_array_index(table->columns,j); fprintf(stdout,"%s", sanitize_name(col->name,sanitize)); } fprintf(stdout, ") VALUES ("); } for (j=0;j<table->num_cols;j++) { col=g_ptr_array_index(table->columns,j); if ((col->col_type == MDB_OLE) && ((j==0) || (col->cur_value_len))) { //int len; // bound_lens[j]=mdb_ole_read(mdb, col, bound_values[j], MDB_BIND_SIZE); gchar kkd_ptr[MDB_MEMO_OVERHEAD]; void *kkd_pg = g_malloc(200000); size_t len, pos; memcpy(kkd_ptr, bound_values[j], MDB_MEMO_OVERHEAD); //col = g_ptr_array_index(table->columns, col_num - 1); len = mdb_ole_read(mdb, col, kkd_ptr, MDB_BIND_SIZE); memcpy(kkd_pg, bound_values[j], len); bound_lens[j] = len; while ((len = mdb_ole_read_next(mdb, col, kkd_ptr))) { memcpy(kkd_pg + bound_lens[j], bound_values[j], len); bound_lens[j] += len; // FIXME: why 4076? how detect end? if (len < 4076) break; } memcpy(bound_values[j],kkd_pg,bound_lens[j]); g_free(kkd_pg); } if (j>0) { fprintf(stdout,delimiter); } if (insert_statements && !bound_lens[j]) { print_col("NULL",0,col->col_type, quote_char, escape_char); } else { #if 0 print_col(bound_values[j], quote_text, col->col_type, quote_char, escape_char); #else nprint_col(bound_values[j], bound_lens[j], quote_text, col->col_type, quote_char, escape_char); #endif } } if (insert_statements) fprintf(stdout,")"); fprintf(stdout, row_delimiter); } for (j=0;j<table->num_cols;j++) { g_free(bound_values[j]); } g_free(bound_values); g_free(bound_lens); mdb_free_tabledef(table); g_free (delimiter); g_free (row_delimiter); g_free (quote_char); if (escape_char) g_free (escape_char); mdb_close(mdb); mdb_exit(); exit(0); } static char *sanitize_name(char *str, int sanitize) { static char namebuf[256]; char *p = namebuf; if (!sanitize) return str; while (*str) { *p = isalnum(*str) ? *str : '_'; p++; str++; } *p = 0; return namebuf; } static char *escapes(char *s) { char *d = (char *) g_strdup(s); char *t = d; unsigned char encode = 0; for (;*s; s++) { if (encode) { switch (*s) { case 'n': *t++='\n'; break; case 't': *t++='\t'; break; case 'r': *t++='\r'; break; default: *t++='\\'; *t++=*s; break; } encode=0; } else if (*s=='\\') { encode=1; } else { *t++=*s; } } *t='\0'; return d; }