예제 #1
0
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;
}
예제 #2
0
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;
}