rc_t matcher_execute( matcher* self, const p_matcher_input in ) { VSchema * dflt_schema; const VTable * src_table; rc_t rc; if ( self == NULL ) return RC( rcExe, rcNoTarg, rcResolving, rcSelf, rcNull ); if ( in->manager == NULL || in->add_schemas == NULL || in->cfg == NULL || in->columns == NULL || in->src_path == NULL || in->dst_path == NULL || in->dst_tabname == NULL ) return RC( rcExe, rcNoTarg, rcResolving, rcParam, rcNull ); rc = matcher_build_column_vector( self, in->columns ); if ( rc != 0 ) return rc; rc = matcher_exclude_columns( self, in->excluded_columns ); if ( rc != 0 ) return rc; rc = helper_parse_schema( in->manager, &dflt_schema, in->add_schemas ); if ( rc != 0 ) return rc; rc = VDBManagerOpenTableRead( in->manager, &src_table, dflt_schema, "%s", in->src_path ); if ( rc == 0 ) { const VSchema * src_schema; rc = VTableOpenSchema ( src_table, &src_schema ); if ( rc == 0 ) { rc = matcher_read_src_types( self, src_table, src_schema ); if ( rc == 0 ) { if ( in->legacy_schema != NULL ) rc = VSchemaParseFile ( dflt_schema, "%s", in->legacy_schema ); if ( rc == 0 ) { VTable * dst_table; KCreateMode cmode = kcmParents; const VSchema * dst_schema = src_schema; if ( in->legacy_schema != NULL ) dst_schema = dflt_schema; if ( in->force_unlock ) VDBManagerUnlock ( in->manager, "%s", in->dst_path ); if ( in->force_kcmInit ) cmode |= kcmInit; else cmode |= kcmCreate; rc = VDBManagerCreateTable( in->manager, &dst_table, dst_schema, in->dst_tabname, cmode, "%s", in->dst_path ); if ( rc == 0 ) { rc = matcher_read_dst_types( self, dst_table, dst_schema ); if ( rc == 0 ) { rc = matcher_make_type_matrix( self ); if ( rc == 0 ) rc = matcher_match_matrix( self, src_schema, in->cfg ); } VTableRelease( dst_table ); if ( !(in->force_kcmInit) ) KDirectoryRemove ( in->dir, true, "%s", in->dst_path ); } } } VSchemaRelease( src_schema ); } VTableRelease( src_table ); } VSchemaRelease( dflt_schema ); return rc; }
static rc_t populate_cursors ( VTable *dtbl, VCursor *dcurs, const VCursor *scurs, vtblcp_column_map *cm, const Vector *v, uint32_t *rd_filt ) { uint32_t end = VectorLength ( v ); uint32_t i = VectorStart ( v ); BSTree stype_tbl, rftype_tbl; const VSchema *schema; rc_t rc = VTableOpenSchema ( dtbl, & schema ); if ( rc != 0 ) { LOGERR ( klogInt, rc, "failed to open destination table schema" ); return rc; } /* populate sensitive type table */ rc = populate_stype_tbl ( & stype_tbl, schema ); if ( rc != 0 ) { VSchemaRelease ( schema ); return rc; } /* populate read filter type table */ rc = populate_rdfilt_tbl ( & rftype_tbl, schema ); if ( rc != 0 ) { BSTreeWhack ( & stype_tbl, stype_id_whack, NULL ); VSchemaRelease ( schema ); return rc; } for ( end += i, rc = 0, * rd_filt = 0; i < end; ++ i ) { VTypedecl td; char typedecl [ 128 ]; const char *spec = ( const void* ) VectorGet ( v, i ); /* request column in destination */ rc = VCursorAddColumn ( dcurs, & cm [ i ] . wr, spec ); if ( rc != 0 ) { PLOGERR ( klogErr, (klogErr, rc, "failed to add '$(spec)' to destination cursor", "spec=%s", spec )); break; } /* always retrieve data type */ rc = VCursorDatatype ( dcurs, cm [ i ] . wr, & td, NULL ); if ( rc != 0 ) { PLOGERR ( klogInt, (klogInt, rc, "failed to determine datatype of destination column '$(name)'", "name=%s", spec )); break; } /* mark column as sensitive or not */ rc = mark_type_sensitivity ( & stype_tbl, schema, & td, & cm [ i ] ); if ( rc != 0 ) break; /* if spec is already typed, request it in source */ if ( spec [ 0 ] == '(' ) { rc = VCursorAddColumn ( scurs, & cm [ i ] . rd, spec ); if ( rc != 0 ) { PLOGERR ( klogErr, (klogErr, rc, "failed to add '$(spec)' to source cursor", "spec=%s", spec )); break; } } else { rc = VTypedeclToText ( & td, schema, typedecl, sizeof typedecl ); if ( rc != 0 ) { PLOGERR ( klogInt, (klogInt, rc, "failed to print datatype of destination column '$(name)'", "name=%s", spec )); break; } rc = VCursorAddColumn ( scurs, & cm [ i ] . rd, "(%s)%s", typedecl, spec ); if ( rc != 0 ) { PLOGERR ( klogErr, (klogErr, rc, "failed to add '$(spec)' to source cursor", "spec=(%s)%s", typedecl, spec )); break; } } /* check if column is a read filter */ cm [ i ] . rd_filter = false; if ( ! cm [ i ] . sensitive ) { if ( BSTreeFind ( & rftype_tbl, & td, stype_id_cmp ) != NULL ) { if ( * rd_filt != 0 ) { rc = RC ( rcExe, rcColumn, rcOpening, rcColumn, rcExists ); PLOGERR ( klogInt, (klogInt, rc, "can't use column '$(name)' as read filter", "name=%s", spec )); break; } * rd_filt = cm [ i ] . rd; cm [ i ] . rd_filter = true; } } } BSTreeWhack ( & rftype_tbl, stype_id_whack, NULL ); BSTreeWhack ( & stype_tbl, stype_id_whack, NULL ); VSchemaRelease ( schema ); /* add read filter to input if not already there in some way */ if ( * rd_filt == 0 ) { rc = VCursorAddColumn ( scurs, rd_filt, "RD_FILTER" ); if ( rc != 0 && GetRCState ( rc ) == rcNotFound ) rc = 0; } return rc; }