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 "sra-sort.h"
28 #include "db-pair.h"
29 #include "ctx.h"
30 #include "caps.h"
31 #include "mem.h"
32 #include "except.h"
33 #include "status.h"
34
35 #include <sra/sraschema.h>
36 #include <vdb/manager.h>
37 #include <vdb/schema.h>
38 #include <vdb/database.h>
39 #include <vdb/table.h>
40 #include <kfg/config.h>
41 #include <klib/text.h>
42 #include <klib/rc.h>
43
44 #include <string.h>
45
46
47 FILE_ENTRY ( run );
48
49 static
typename_to_config_path(const char * in,char * out)50 void typename_to_config_path ( const char *in, char *out )
51 {
52 bool end;
53 uint32_t i;
54
55 for ( end = false, i = 0; ! end; ++ i )
56 {
57 switch ( out [ i ] = in [ i ] )
58 {
59 case ':':
60 out [ i ] = '/';
61 break;
62 case ' ':
63 case '#':
64 out [ i ] = 0;
65 case 0:
66 end = true;
67 return;
68 }
69 }
70 }
71
72 static
map_typename_builtin(const ctx_t * ctx,const char * sub_node,const char * in,char * out,char * schema_src,size_t size)73 bool map_typename_builtin ( const ctx_t *ctx, const char *sub_node, const char *in, char *out, char *schema_src, size_t size )
74 {
75 FUNC_ENTRY ( ctx );
76
77 size_t copied;
78
79 #define ALIGN_EVIDENCE_MAP "NCBI:align:db:alignment_evidence_sorted"
80 #define ALIGN_UNSORTED_MAP "NCBI:align:db:alignment_sorted"
81 #define ALIGN_SRC "align/align.vschema"
82
83 if ( strcmp ( out, "NCBI/align/db/alignment_evidence" ) == 0 )
84 copied = string_copy ( out, size, ALIGN_EVIDENCE_MAP, sizeof ALIGN_EVIDENCE_MAP - 1 );
85 else if ( strcmp ( out, "NCBI/align/db/alignment_unsorted" ) == 0 )
86 copied = string_copy ( out, size, ALIGN_UNSORTED_MAP, sizeof ALIGN_UNSORTED_MAP - 1 );
87 else
88 {
89 strcpy ( out, in );
90 schema_src [ 0 ] = 0;
91 return false;
92 }
93
94 if ( copied != size )
95 {
96 out [ copied ] = 0;
97 copied = string_copy ( schema_src, size, ALIGN_SRC, sizeof ALIGN_SRC - 1 );
98 }
99
100 if ( copied == size )
101 {
102 rc_t rc = RC ( rcExe, rcType, rcCopying, rcBuffer, rcInsufficient );
103 INTERNAL_ERROR ( rc, "failed to copy a built-in constant" );
104 strcpy ( out, in );
105 schema_src [ 0 ] = 0;
106 return false;
107 }
108
109 #undef ALIGN_EVIDENCE_MAP
110 #undef ALIGN_UNSORTED_MAP
111 #undef ALIGN_SRC
112
113 schema_src [ copied ] = 0;
114 return true;
115 }
116
117 static
map_typename(const ctx_t * ctx,const char * sub_node,const char * in,char * out,char * schema_src,size_t size)118 bool map_typename ( const ctx_t *ctx, const char *sub_node, const char *in, char *out, char *schema_src, size_t size )
119 {
120 FUNC_ENTRY ( ctx );
121
122 rc_t rc;
123 const KConfigNode *n;
124 size_t num_read, remaining;
125
126 typename_to_config_path ( in, out );
127
128 rc = KConfigOpenNodeRead ( ctx -> caps -> cfg, & n, "sra-sort/%s/%s", sub_node, out );
129 if ( rc != 0 )
130 return map_typename_builtin ( ctx, sub_node, in, out, schema_src, size );
131
132 rc = KConfigNodeRead ( n, 0, out, size - 1, & num_read, & remaining );
133 if ( rc != 0 )
134 ERROR ( rc, "KConfigNodeRead failed" );
135 else if ( remaining != 0 )
136 {
137 rc = RC ( rcExe, rcNode, rcReading, rcBuffer, rcInsufficient );
138 ERROR ( rc, "type map of '%s' is too long", in );
139 }
140 else
141 {
142 out [ num_read ] = 0;
143 typename_to_config_path ( out, schema_src );
144
145 KConfigNodeRelease ( n );
146 rc = KConfigOpenNodeRead ( ctx -> caps -> cfg, & n, "sra-sort/schema-src/%s", schema_src );
147 if ( rc != 0 )
148 ERROR ( rc, "KConfigOpenNodeRead - failed to find entry 'sra-sort/schema-src/%s'", schema_src );
149 else
150 {
151 rc = KConfigNodeRead ( n, 0, schema_src, size - 1, & num_read, & remaining );
152 if ( rc != 0 )
153 ERROR ( rc, "KConfigNodeRead failed" );
154 else if ( remaining != 0 )
155 {
156 rc = RC ( rcExe, rcNode, rcReading, rcBuffer, rcInsufficient );
157 ERROR ( rc, "type map of '%s' is too long", in );
158 }
159 else
160 {
161 schema_src [ num_read ] = 0;
162 }
163 }
164 }
165
166 KConfigNodeRelease ( n );
167 return true;
168 }
169
170 static
map_schema_types(TypeParams * type,const ctx_t * ctx,const VSchema * src_schema)171 VSchema *map_schema_types ( TypeParams *type, const ctx_t *ctx, const VSchema *src_schema )
172 {
173 FUNC_ENTRY ( ctx );
174
175 bool mapped;
176 char schema_src [ 256 ];
177 assert ( sizeof schema_src == sizeof type -> dst_type );
178
179 TRY ( mapped = map_typename ( ctx, "out-map", type -> src_type, type -> dst_type, schema_src, sizeof schema_src ) )
180 {
181 rc_t rc;
182 VSchema *dst_schema;
183
184 if ( ! mapped )
185 {
186 type -> view_type [ 0 ] = 0;
187 rc = VSchemaAddRef ( src_schema );
188 if ( rc != 0 )
189 ERROR ( rc, "VSchemaAddRef failed" );
190 return ( VSchema* ) src_schema;
191 }
192
193 rc = VDBManagerMakeSchema ( ctx -> caps -> vdb, & dst_schema );
194 if ( rc != 0 )
195 ERROR ( rc, "VDBManagerMakeSchema failed" );
196 else
197 {
198 rc = VSchemaParseFile ( dst_schema, "%s", schema_src );
199 if ( rc != 0 )
200 ERROR ( rc, "VSchemaParseFile failed adding file '%s' for destination", src_schema );
201 else
202 {
203 TRY ( mapped = map_typename ( ctx, "view-map", type -> src_type, type -> view_type, schema_src, sizeof schema_src ) )
204 {
205 if ( ! mapped )
206 {
207 type -> view_type [ 0 ] = 0;
208 return dst_schema;
209 }
210
211 rc = VSchemaParseFile ( dst_schema, "%s", schema_src );
212 if ( rc == 0 )
213 return dst_schema;
214
215 ERROR ( rc, "VSchemaParseFile failed adding file '%s' for view", src_schema );
216 }
217 }
218
219 VSchemaRelease ( dst_schema );
220 }
221 }
222
223 return NULL;
224 }
225
226 /* open_db
227 * called from run
228 * determines the type of schema
229 * opens output object
230 * dispatches to the appropriate handler
231 */
232 static
open_db(const ctx_t * ctx,const VDatabase ** srcp)233 void open_db ( const ctx_t *ctx, const VDatabase **srcp )
234 {
235 FUNC_ENTRY ( ctx );
236
237 const VDatabase *src = *srcp;
238
239 const VSchema *src_schema;
240 rc_t rc = VDatabaseOpenSchema ( src, & src_schema );
241 if ( rc != 0 )
242 ERROR ( rc, "VDatabaseOpenSchema failed" );
243 else
244 {
245 TypeParams type;
246 rc = VDatabaseTypespec ( src, type . src_type, sizeof type . src_type );
247 if ( rc != 0 )
248 ERROR ( rc, "failed to obtain database typespec" );
249 else
250 {
251 VSchema *dst_schema;
252
253 /* map input type to output type */
254 TRY ( dst_schema = map_schema_types ( & type, ctx, src_schema ) )
255 {
256 const Tool *tp = ctx -> caps -> tool;
257
258 /* if view was remapped, reopen the database */
259 if ( type . view_type [ 0 ] != 0 )
260 {
261 VSchemaRelease ( src_schema );
262 rc = VSchemaAddRef ( dst_schema );
263 if ( rc != 0 )
264 {
265 ERROR ( rc, "VSchemaAddRef failed" );
266 src_schema = NULL;
267 }
268 else
269 {
270 src_schema = dst_schema;
271 VDatabaseRelease ( src );
272 rc = VDBManagerOpenDBRead ( ctx -> caps -> vdb, srcp, src_schema, "%s", tp -> src_path );
273 if ( rc != 0 )
274 ERROR ( rc, "VDBManagerOpenDBRead failed reopening db '%s'", tp -> src_path );
275 src = *srcp;
276 }
277 }
278
279 if ( ! FAILED () )
280 {
281 VDatabase *dst;
282 rc = VDBManagerCreateDB ( ctx -> caps -> vdb, & dst, dst_schema,
283 type . dst_type, tp -> db . cmode, "%s", tp -> dst_path );
284 if ( rc != 0 )
285 ERROR ( rc, "VDBManagerCreateDB failed to create '%s' with type '%s'", tp -> dst_path, type . dst_type );
286 else
287 {
288 rc = VDatabaseColumnCreateParams ( dst, tp -> col . cmode, tp -> col . checksum, tp -> col . pgsize );
289 if ( rc != 0 )
290 ERROR ( rc, "VDatabaseColumnCreateParams: failed to set column create params on db '%s'", tp -> dst_path );
291 else
292 {
293 DbPair *pb;
294
295 /* TBD - this has to be fixed to use proper stuff */
296 const char *name = strrchr ( tp -> src_path, '/' );
297 if ( name ++ == NULL )
298 name = tp -> src_path;
299
300 TRY ( pb = DbPairMake ( ctx, src, dst, name ) )
301 {
302 DbPairRun ( pb, ctx );
303 DbPairRelease ( pb, ctx );
304 }
305 }
306
307 rc = VDatabaseRelease ( dst );
308 if ( rc != 0 )
309 ERROR ( rc, "VDatabaseRelease failed on '%s'", tp -> dst_path );
310 }
311 }
312
313 VSchemaRelease ( dst_schema );
314 }
315 }
316
317 VSchemaRelease ( src_schema );
318 }
319 }
320
321
322 /* open_tbl
323 * called from run
324 * determines the type of schema
325 * opens output object
326 * dispatches to the appropriate handler
327 */
328 static
open_tbl(const ctx_t * ctx,const VTable ** tblp)329 void open_tbl ( const ctx_t *ctx, const VTable **tblp )
330 {
331 FUNC_ENTRY ( ctx );
332
333 rc_t rc = RC ( rcExe, rcFunction, rcExecuting, rcFunction, rcUnsupported );
334 ERROR ( rc, "unimplemented function" );
335 }
336
337 /* run
338 * called from KMain
339 * determines the type of object being copied/sorted
340 * opens input object
341 * dispatches to the appropriate handler
342 */
run(const ctx_t * ctx)343 void run ( const ctx_t *ctx )
344 {
345 FUNC_ENTRY ( ctx );
346
347 VDBManager *mgr = ctx -> caps -> vdb;
348 const Tool *tp = ctx -> caps -> tool;
349
350 const VDatabase *db;
351 rc_t rc = VDBManagerOpenDBRead ( mgr, & db, NULL, "%s", tp -> src_path );
352 if ( rc == 0 )
353 {
354 open_db ( ctx, & db );
355 VDatabaseRelease ( db );
356 }
357 else
358 {
359 const VTable *tbl;
360 rc_t rc2 = VDBManagerOpenTableRead ( mgr, & tbl, NULL, "%s", tp -> src_path );
361 if ( rc2 == 0 )
362 {
363 rc = 0;
364 open_tbl ( ctx, & tbl );
365 VTableRelease ( tbl );
366 }
367 else
368 {
369 VSchema *sra_dflt;
370 rc2 = VDBManagerMakeSRASchema ( mgr, & sra_dflt );
371 if ( rc2 == 0 )
372 {
373 rc2 = VDBManagerOpenTableRead ( mgr, & tbl, sra_dflt, "%s", tp -> src_path );
374 if ( rc2 == 0 )
375 {
376 rc = 0;
377 open_tbl ( ctx, & tbl );
378 VTableRelease ( tbl );
379 }
380
381 VSchemaRelease ( sra_dflt );
382 }
383 }
384 }
385
386 if ( rc != 0 )
387 ERROR ( rc, "failed to open object '%s'", tp -> src_path );
388 }
389