1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 #include "vdb-dump-formats.h"
28 #include <sysalloc.h>
29 
30 #include <klib/rc.h>
31 #include <klib/log.h>
32 #define DISP_RC(rc,err) if( rc != 0 ) LOGERR( klogInt, rc, err );
33 
34 /*************************************************************************************
35     default ( with line-length-limitation and pretty print )
36 *************************************************************************************/
vdfo_print_col_default(void * item,void * data)37 static void CC vdfo_print_col_default( void *item, void *data )
38 {
39     p_col_def col_def = ( p_col_def )item;
40     p_row_context r_ctx = ( p_row_context )data;
41     rc_t rc;
42 
43     if ( !( col_def -> valid ) || col_def -> excluded )
44     {
45         return;
46     }
47 
48     rc = vds_clear( &( r_ctx -> s_col ) );
49     DISP_RC( rc, "dump_str_clear() failed" )
50     if ( 0 != rc )
51     {
52         return;
53     }
54 
55     if ( r_ctx -> ctx -> print_column_names )
56     {
57         rc = vds_append_fmt( &( r_ctx -> s_col ),
58                              r_ctx -> col_defs -> max_colname_chars,
59                              "%*s: ",
60                              r_ctx -> col_defs -> max_colname_chars,
61                              col_def -> name );
62         DISP_RC( rc, "dump_str_append_fmt() failed" )
63     }
64 
65     /* append the cell-content */
66     rc = vds_append_str( &( r_ctx -> s_col ), col_def -> content . buf );
67     DISP_RC( rc, "dump_str_append_str() failed" )
68     if ( 0 == rc )
69     {
70 
71         /* indent the cell-line, if requested */
72         if ( r_ctx -> ctx -> indented_line_len > 0 )
73         {
74             rc = vds_indent( &( r_ctx -> s_col ),
75                              r_ctx -> ctx -> indented_line_len,
76                              r_ctx -> col_defs -> max_colname_chars + 2 );
77             DISP_RC( rc, "dump_str_indent() failed" )
78         }
79 
80         /* print a truncate-hint at the end of the line if truncated */
81         if ( vds_truncated( &( r_ctx -> s_col ) ) )
82         {
83             rc = vds_rinsert( &( r_ctx -> s_col ), " ..." );
84             DISP_RC( rc, "dump_str_rinsert() failed" )
85         }
86     }
87 
88     /* FINALLY we print the content of a column... */
89     KOutMsg( "%s\n", r_ctx -> s_col . buf );
90 }
91 
vdfo_print_row_default(const p_row_context r_ctx)92 static rc_t vdfo_print_row_default( const p_row_context r_ctx )
93 {
94     rc_t rc = 0;
95     if ( r_ctx -> ctx -> print_row_id )
96     {
97         rc = KOutMsg( "ROW-ID = %u\n", r_ctx -> row_id );
98     }
99 
100     if ( 0 == rc )
101     {
102         VectorForEach( &( r_ctx -> col_defs -> cols ), false, vdfo_print_col_default, r_ctx );
103     }
104 
105     if ( 0 == rc && r_ctx->ctx->lf_after_row > 0 )
106     {
107         uint16_t i = 0;
108         while ( i++ < r_ctx -> ctx -> lf_after_row && 0 == rc )
109         {
110             rc = KOutMsg( "\n" );
111         }
112     }
113     return rc;
114 }
115 
116 /*************************************************************************************
117     CSV
118 *************************************************************************************/
vdfo_print_col_csv(void * item,void * data)119 static void CC vdfo_print_col_csv( void *item, void *data )
120 {
121     rc_t rc = 0;
122     p_col_def col_def = ( p_col_def )item;
123     p_row_context r_ctx = ( p_row_context )data;
124 
125     if ( !( col_def -> valid ) || col_def -> excluded )
126     {
127         return;
128     }
129 
130     if ( r_ctx -> col_nr > 0 || r_ctx -> ctx -> print_row_id )
131     {
132         rc = vds_append_str( &( r_ctx -> s_col ), "," );
133         DISP_RC( rc, "dump_str_append_str() failed" )
134     }
135     if ( 0 == rc )
136     {
137         rc = vds_2_csv( &( col_def -> content ) );
138         DISP_RC( rc, "dump_str_2_csv() failed" )
139         if ( 0 == rc )
140         {
141             rc = vds_append_str( &( r_ctx -> s_col ), col_def -> content . buf );
142             DISP_RC( rc, "dump_str_append_str() failed" )
143             r_ctx -> col_nr++;
144         }
145     }
146 }
147 
vdfo_print_row_csv(const p_row_context r_ctx)148 static rc_t vdfo_print_row_csv( const p_row_context r_ctx )
149 {
150     rc_t rc = vds_clear( &( r_ctx -> s_col ) );
151     DISP_RC( rc, "dump_str_clear() failed" )
152     if ( 0 == rc && r_ctx -> ctx -> print_row_id )
153     {
154         rc = KOutMsg( "%u", r_ctx -> row_id );
155     }
156     if ( 0 == rc )
157     {
158         r_ctx -> col_nr = 0;
159         VectorForEach( &( r_ctx -> col_defs -> cols ), false, vdfo_print_col_csv, r_ctx );
160         rc = KOutMsg( "%s\n", r_ctx -> s_col . buf );
161     }
162     return rc;
163 }
164 
165 /*************************************************************************************
166     XML
167 *************************************************************************************/
vdfo_print_col_xml(void * item,void * data)168 static void CC vdfo_print_col_xml( void *item, void *data )
169 {
170     p_col_def col_def = ( p_col_def )item;
171     if ( !( col_def -> valid ) || col_def -> excluded )
172     {
173         return;
174     }
175 
176     KOutMsg( " <%s>\n", col_def -> name );
177     KOutMsg( "%s", col_def -> content.buf );
178     KOutMsg( " </%s>\n", col_def -> name );
179 }
180 
vdfo_print_row_xml(const p_row_context r_ctx)181 static rc_t vdfo_print_row_xml( const p_row_context r_ctx )
182 {
183     rc_t rc = vds_clear( &( r_ctx -> s_col ) );
184     DISP_RC( rc, "dump_str_clear() failed" )
185     if ( 0 == rc )
186     {
187         rc = KOutMsg( "<row>\n" );
188         if ( 0 == rc )
189         {
190             VectorForEach( &( r_ctx -> col_defs -> cols ), false, vdfo_print_col_xml, r_ctx );
191             rc = KOutMsg( "</row>\n" );
192         }
193     }
194     return rc;
195 }
196 
197 /*************************************************************************************
198     JSON
199 *************************************************************************************/
vdfo_print_col_json(void * item,void * data)200 static void CC vdfo_print_col_json( void *item, void *data )
201 {
202     rc_t rc = 0;
203     p_col_def col_def = ( p_col_def )item;
204 
205     if ( !( col_def -> valid ) || col_def -> excluded )
206     {
207         return;
208     }
209 
210     if ( ( col_def -> type_desc . domain == vtdAscii )||
211          ( col_def -> type_desc . domain == vtdUnicode ) )
212     {
213         rc = vds_escape( &( col_def -> content ), '"', '\\' );
214         DISP_RC( rc, "dump_str_escape() failed" )
215         if ( 0 == rc)
216         {
217             rc = vds_enclose_string( &( col_def -> content ), '"', '"' );
218             DISP_RC( rc, "dump_str_enclose_string() failed" )
219         }
220     }
221     else
222     {
223         if ( col_def -> type_desc . intrinsic_dim > 1 )
224         {
225             rc = vds_enclose_string( &( col_def -> content ), '[', ']' );
226             DISP_RC( rc, "dump_str_enclose_string() failed" )
227         }
228     }
229 
230     if ( 0 == rc )
231         KOutMsg( ",\n\"%s\":%s", col_def -> name, col_def -> content . buf );
232 }
233 
vdfo_print_row_json(const p_row_context r_ctx)234 static rc_t vdfo_print_row_json( const p_row_context r_ctx )
235 {
236     rc_t rc = vds_clear( &( r_ctx -> s_col ) );
237     DISP_RC( rc, "dump_str_clear() failed" )
238     if ( 0 == rc )
239     {
240         rc = KOutMsg( "{\n" );
241         if ( 0 == rc )
242         {
243             rc = KOutMsg( "\"row_id\": %lu", r_ctx -> row_id );
244             if ( 0 == rc )
245             {
246                 VectorForEach( &( r_ctx -> col_defs -> cols ), false, vdfo_print_col_json, r_ctx );
247                 rc = KOutMsg( "\n},\n\n" );
248             }
249         }
250     }
251     return rc;
252 }
253 
254 
255 /*************************************************************************************
256     PIPED
257 *************************************************************************************/
vdfo_print_col_piped(void * item,void * data)258 static void CC vdfo_print_col_piped( void *item, void *data )
259 {
260     rc_t rc = 0;
261     p_col_def col_def = ( p_col_def )item;
262     p_row_context r_ctx = ( p_row_context )data;
263 
264     if ( !( col_def -> valid ) || col_def -> excluded )
265     {
266         return;
267     }
268 
269     /* first we print the row_id and the column-name for every column! */
270     KOutMsg( "%lu, %s: ", r_ctx -> row_id, col_def -> name );
271 
272     if ( ( col_def -> type_desc . domain == vtdAscii ) ||
273          ( col_def -> type_desc . domain == vtdUnicode ) )
274     {
275         rc = vds_escape( &( col_def -> content ), '"', '\\' );
276         DISP_RC( rc, "dump_str_escape() failed" )
277         if ( 0 == rc )
278         {
279             rc = vds_enclose_string( &( col_def -> content ), '"', '"' );
280             DISP_RC( rc, "dump_str_enclose_string() failed" )
281         }
282     }
283     else
284     {
285         if ( col_def -> type_desc . intrinsic_dim > 1 )
286         {
287             rc = vds_enclose_string( &( col_def -> content ), '[', ']' );
288             DISP_RC( rc, "dump_str_enclose_string() failed" )
289         }
290     }
291 
292     if ( 0 == rc )
293         KOutMsg( "%s\n", col_def -> content . buf );
294 }
295 
296 
297 /*************************************************************************************
298     like legacy sra-dump
299 *************************************************************************************/
vdfo_print_col_sra_dump(void * item,void * data)300 static void CC vdfo_print_col_sra_dump( void *item, void *data )
301 {
302     rc_t rc = 0;
303     p_col_def col_def = ( p_col_def )item;
304     p_row_context r_ctx = ( p_row_context )data;
305 
306     if ( !( col_def -> valid ) || col_def -> excluded )
307     {
308         return;
309     }
310 
311     /* first we print the row_id and the column-name for every column! */
312     KOutMsg( "%lu. %s: ", r_ctx -> row_id, col_def -> name );
313 
314     if ( 0 == rc )
315         KOutMsg( "%s\n", col_def -> content . buf );
316 }
317 
318 
319 /*************************************************************************************
320     TAB-delimited
321 *************************************************************************************/
vdfo_print_col_tab(void * item,void * data)322 static void CC vdfo_print_col_tab( void *item, void *data )
323 {
324     rc_t rc = 0;
325     p_col_def col_def = ( p_col_def )item;
326     p_row_context r_ctx = ( p_row_context )data;
327 
328     if ( !( col_def -> valid ) || col_def -> excluded )
329     {
330         return;
331     }
332 
333     if ( r_ctx -> col_nr > 0 || r_ctx -> ctx -> print_row_id )
334     {
335         rc = vds_append_str( &( r_ctx -> s_col ), "\t" );
336         DISP_RC( rc, "dump_str_append_str() failed" )
337     }
338     if ( 0 == rc )
339     {
340         rc = vds_append_str( &( r_ctx -> s_col ), col_def -> content . buf );
341         DISP_RC( rc, "dump_str_append_str() failed" )
342         r_ctx -> col_nr++;
343     }
344 }
345 
346 
vdfo_print_row_piped(const p_row_context r_ctx)347 static rc_t vdfo_print_row_piped( const p_row_context r_ctx )
348 {
349     rc_t rc = vds_clear( &( r_ctx -> s_col ) );
350     DISP_RC( rc, "dump_str_clear() failed" )
351     if ( 0 == rc )
352     {
353         VectorForEach( &( r_ctx -> col_defs -> cols ), false, vdfo_print_col_piped, r_ctx );
354         rc = KOutMsg( "\n" );
355     }
356     return rc;
357 }
358 
vdfo_print_row_sra_dump(const p_row_context r_ctx)359 static rc_t vdfo_print_row_sra_dump( const p_row_context r_ctx )
360 {
361     rc_t rc = vds_clear( &( r_ctx -> s_col ) );
362     DISP_RC( rc, "dump_str_clear() failed" )
363     if ( 0 == rc )
364     {
365         VectorForEach( &( r_ctx -> col_defs -> cols ), false, vdfo_print_col_sra_dump, r_ctx );
366         rc = KOutMsg( "\n" );
367     }
368     return rc;
369 }
370 
vdfo_print_row_tab(const p_row_context r_ctx)371 static rc_t vdfo_print_row_tab( const p_row_context r_ctx )
372 {
373     rc_t rc = vds_clear( &( r_ctx -> s_col ) );
374     DISP_RC( rc, "dump_str_clear() failed" )
375 
376     if ( 0 == rc && r_ctx -> ctx -> print_row_id )
377         rc = KOutMsg( "%u", r_ctx -> row_id );
378 
379     if ( 0 == rc )
380     {
381         r_ctx -> col_nr = 0;
382         VectorForEach( &( r_ctx -> col_defs -> cols ), false, vdfo_print_col_tab, r_ctx );
383         rc = KOutMsg( "%s\n", r_ctx -> s_col . buf );
384     }
385     return rc;
386 }
387 
388 /*************************************************************************************
389     print-format-switch
390 *************************************************************************************/
vdfo_print_row(const p_row_context r_ctx)391 rc_t vdfo_print_row( const p_row_context r_ctx )
392 {
393     rc_t rc = 0;
394     switch( r_ctx -> ctx -> format )
395     {
396         case df_default     : rc = vdfo_print_row_default( r_ctx ); break;
397         case df_csv         : rc = vdfo_print_row_csv( r_ctx ); break;
398         case df_xml         : rc = vdfo_print_row_xml( r_ctx ); break;
399         case df_json        : rc = vdfo_print_row_json( r_ctx ); break;
400         case df_piped       : rc = vdfo_print_row_piped( r_ctx ); break;
401         case df_sra_dump    : rc = vdfo_print_row_sra_dump( r_ctx ); break;
402         case df_tab         : rc = vdfo_print_row_tab( r_ctx ); break;
403         default             : rc = vdfo_print_row_default( r_ctx ); break;
404     }
405     return rc;
406 }
407