From 3216c8de03038260e482b4ac5d7904037f33d445 Mon Sep 17 00:00:00 2001 From: Vladimir Rutsky Date: Thu, 19 Feb 2015 21:02:15 +0300 Subject: [PATCH] output all non-binary fields as unicode strings and binary fields as MongoDB extended JSON binary field Now mdb-exportjson output can be successfully imported into MongoDB with mongoimport even if: * columns have unicode names * there are fields of binary types (e.g. OLE) --- src/util/mdb-exportjson.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/util/mdb-exportjson.c b/src/util/mdb-exportjson.c index b4724a2..3c1fdbb 100644 --- a/src/util/mdb-exportjson.c +++ b/src/util/mdb-exportjson.c @@ -18,6 +18,8 @@ #include "mdbtools.h" +#include "base64.h" + #ifdef DMALLOC #include "dmalloc.h" #endif @@ -61,7 +63,7 @@ print_quoted_value(FILE *outfile, char* value, int bin_len) { value += orig_escape_len; #endif } else if ((unsigned char)*value < 0x20) { - if (!is_binary || drop_nonascii) { + if (drop_nonascii) { putc(' ', outfile); ++value; } else { @@ -75,15 +77,30 @@ print_quoted_value(FILE *outfile, char* value, int bin_len) { fputs(quote_char, outfile); } +static void +print_binary_value(FILE *outfile, char const * value, int bin_len) { + fputs("{\"$binary\": \"", outfile); + size_t const base64_buf_len = (bin_len / 3 + 1) * 4 + 1; + char * base64_buf = g_malloc(base64_buf_len); + if (base64encode(value, bin_len, base64_buf, base64_buf_len) != 0) { + fprintf(stderr, "Error: Base64 serialization failed.\n"); + } + fputs(base64_buf, outfile); + g_free(base64_buf); + fputs("\", \"$type\": \"00\"}", outfile); +} + static void print_col(FILE *outfile, char* col_name, gchar *col_val, int col_type, int bin_len) { print_quoted_value(outfile, col_name, -1); fputs(separator_char, outfile); if (is_quote_type(col_type)) { - if (!is_binary_type(col_type)) { + if (is_binary_type(col_type)) { + print_binary_value(outfile, col_val, bin_len); bin_len = -1; + } else { + print_quoted_value(outfile, col_val, bin_len); } - print_quoted_value(outfile, col_val, bin_len); } else fputs(col_val, outfile); }