static void CC vdcd_add_1_to_cursor( void *item, void *data )
{
    rc_t rc;
    p_col_def my_col_def = (p_col_def)item;
    p_add_2_cur_context ctx = (p_add_2_cur_context)data;

    if ( my_col_def == NULL ) return;
    if ( ctx == NULL ) return;
    if ( ctx->my_cursor == NULL ) return;
    rc = VCursorAddColumn( ctx->my_cursor, &(my_col_def->idx), my_col_def->name );
    DISP_RC( rc, "VCursorAddColumn() failed" );

    /***************************************************************************
    !!! extract type information !!!
    **************************************************************************/
    if ( rc == 0 )
    {
        rc = VCursorDatatype( ctx->my_cursor, my_col_def->idx,
                              &(my_col_def->type_decl), &(my_col_def->type_desc) );
        DISP_RC( rc, "VCursorDatatype() failed" );
        if ( rc == 0 )
        {
            ctx->count++;
            my_col_def->valid = true;
        }
    }
}
Example #2
0
rc_t SRATableColDatatype ( const SRATable *self,
        uint32_t idx, VTypedecl *type, VTypedef *def )
{
    rc_t rc;
    if ( type == NULL && def == NULL )
        rc = RC ( rcSRA, rcColumn, rcAccessing, rcParam, rcNull );
    else
    {
        union { VTypedecl td; VTypedef def; } dummy;
        if ( type == NULL )
            type = & dummy . td;
        else if ( def == NULL )
            def = & dummy . def;

        if ( idx == 0 )
            rc = RC ( rcSRA, rcColumn, rcAccessing, rcSelf, rcNull );
        else if ( self == NULL )
            rc = RC ( rcSRA, rcTable, rcAccessing, rcSelf, rcNull );
        else
        {
            VTypedesc desc;
            rc = VCursorDatatype ( self -> curs, idx, type, & desc );
            if ( rc == 0 )
            {
                rc = VSchemaDescribeTypedef ( VCursorGetSchema(self -> curs), def, type -> type_id );
                if ( rc == 0 )
                    return 0;
            }
        }

        memset ( type, 0, sizeof * type );
        memset ( def, 0, sizeof * def );
    }
    return rc;
}
Example #3
0
/*
 * walks the list of column-definitions and tries to add all off them
 * to the given cursor, it stops if one of them fails to be added
 * for every column it detects type_decl and type_desc
 * if both calls are successful the column-def is marked as valid
*/
rc_t col_defs_add_to_rd_cursor( col_defs* defs, const VCursor *cursor, bool show )
{
    rc_t rc = 0;
    uint32_t idx, len;
    
    if ( defs == NULL )
        return RC( rcExe, rcNoTarg, rcResolving, rcSelf, rcNull );
    if ( cursor == NULL )
        return RC( rcExe, rcNoTarg, rcResolving, rcParam, rcNull );

    len = VectorLength( &(defs->cols) );
    for ( idx = 0;  idx < len && rc == 0; ++idx )
    {
        p_col_def col = (p_col_def) VectorGet ( &(defs->cols), idx );
        if ( col != NULL )
        {
            if ( col->src_cast != NULL )
            {
                rc = VCursorAddColumn( cursor, &(col->src_idx), "%s", col->src_cast );
                DISP_RC( rc, "col_defs_add_to_cursor:VCursorAddColumn() failed" );
                if ( rc == 0 )
                {
                    rc = VCursorDatatype( cursor, col->src_idx,
                              &(col->type_decl), &(col->type_desc) );
                    DISP_RC( rc, "col_defs_add_to_cursor:VCursorDatatype() failed" );
                    col->src_valid = ( rc == 0 );
                    if ( show && col->src_valid )
                        KOutMsg( "added to rd-cursor: >%s<\n", col->name );
                }

            }
        }
    }
    return rc;
}
Example #4
0
bool vdcd_extract_from_table( col_defs* defs, const VTable *my_table )
{
    bool col_defs_found = false;
    KNamelist *names;
    rc_t rc = VTableListCol( my_table, &names );
    DISP_RC( rc, "VTableListCol() failed" );
    if ( rc == 0 )
    {
        const VCursor *my_cursor;
        rc = VTableCreateCursorRead( my_table, &my_cursor );
        DISP_RC( rc, "VTableCreateCursorRead() failed" );
        if ( rc == 0 )
        {
            uint32_t n;
            uint32_t found = 0;
            rc = KNamelistCount( names, &n );
            DISP_RC( rc, "KNamelistCount() failed" );
            if ( rc == 0 )
            {
                uint32_t i;
                for ( i = 0; i < n && rc ==0; ++i )
                {
                    const char *col_name;
                    rc = KNamelistGet( names, i, &col_name );
                    DISP_RC( rc, "KNamelistGet() failed" );
                    if ( rc == 0 )
                    {
                        p_col_def def = vdcd_append_col( defs, col_name );
                        rc = VCursorAddColumn( my_cursor, &(def->idx), def->name );
                        DISP_RC( rc, "VCursorAddColumn() failed" );
                        if ( rc == 0 )
                        {
                            rc = VCursorDatatype( my_cursor, def->idx,
                                      &(def->type_decl), &(def->type_desc) );
                            DISP_RC( rc, "VCursorDatatype() failed" );
                            if ( rc == 0 )
                            {
                                found++;
                            }
                        }
                    }
                }
                col_defs_found = ( found > 0 );
            }
            rc = VCursorRelease( my_cursor );
            DISP_RC( rc, "VCursorRelease() failed" );
        }
        rc = KNamelistRelease( names );
        DISP_RC( rc, "KNamelistRelease() failed" );
    }
    return col_defs_found;
}
Example #5
0
/* OpenColumnWrite
 *  open a column for write
 *
 *  "idx" [ OUT ] - return parameter for 1-based column index.
 *
 *  "col" [ OUT, NULL OKAY ] - optional return parameter for
 *  newly opened column.
 *
 *  "name" [ IN ] - NUL terminated string in UTF-8 giving column name
 *
 *  "datatype" [ IN ] - NUL terminated string in ASCII
 *   describing fully qualified column data type
 */
LIB_EXPORT rc_t CC SRATableOpenColumnWrite ( SRATable *self,
    uint32_t *idx, SRAColumn **col, const char *name, const char *datatype )
{
    rc_t rc;
    SRAColumn *rslt;
    uint32_t ndx, cndx;
    
    if (self == NULL)
        return RC(RC_MODULE, RC_TARGET, rcOpening, rcSelf, rcNull);
    
    if (name == NULL || idx == NULL)
        return RC(RC_MODULE, RC_TARGET, rcOpening, rcParam, rcNull);
    
    *idx = 0;
    
    if (datatype && datatype[0])
    {
        SRADBG(("adding column (%s)%s\n", datatype, name));
        rc = VCursorAddColumn(self->curs, &ndx, "(%s)%s", datatype, name);
    }
    else
    {
        SRADBG(("adding column %s\n", name));
        rc = VCursorAddColumn(self->curs, &ndx, "%s", name);
    }
    
    if (rc != 0)
    {
        /* it's okay if the column is already there
           any other rc is a hard error */
        if (GetRCState ( rc ) != rcExists)
            return rc;
        
        if ( ! find_by_index(&self->wcol, ndx, &cndx) )
        {
            /* severe internal error */
            return RC ( RC_MODULE, RC_TARGET, rcOpening, rcNoObj, rcNotFound );
        }

        /* get the uncounted reference to column from table */
        rslt = VectorGet(&self->wcol, cndx);
    }
    else
    {
        VTypedecl type;
        VTypedesc desc;
        
        rslt = malloc(sizeof *rslt );
        if (rslt == NULL)
            return RC(RC_MODULE, rcColumn, rcConstructing, rcMemory, rcExhausted);
        
        rc = VCursorDatatype(self->curs, ndx, &type, &desc);
        if (rc == 0)
        {
            /* this object will sit uncounted within the table
               when the table goes away, it will douse the columns
               without regard to their reference count. see below */
            KRefcountInit(&rslt->refcount, 0, "SRAColumn", "OpenColumnWrite", name);

            /* the column has no reference to the table, so after this
               there will only be an uncounted reference from table to column */
            rslt->tbl = NULL;
            rslt->idx = ndx;
            rslt->read_only = false;
            rslt->elem_bits = VTypedescSizeof(&desc);

            rc = VectorAppend(&self->wcol, &cndx, rslt);
        }

        if ( rc != 0 )
        {
            free ( rslt );
            return rc;
        }
    }

    /* see if user wants a reference */
    if ( col != NULL )
    {
        /* the first column reference exported will take
           the refcount from zero to one */
        SRAColumnAddRef ( rslt );

        /* the first exported reference will need to be reflected
           to the table. this will ensure that the table never tries
           to whack its columns as long as they are held externally,
           because the table itself will be kept alive. when the last
           column reference is released, it will also release the table */
        if ( rslt -> tbl == NULL )
            rslt -> tbl = SRATableAttach ( self );

        *col = rslt;
    }

    *idx = cndx + 1;
    return rc;
}
uint32_t vdcd_parse_string( col_defs* defs, const char* src, const VTable *my_table )
{
    uint32_t count, found = 0;
    char colname[MAX_COL_NAME_LEN+1];
    size_t i_dest = 0;
    if ( defs == NULL ) return false;
    if ( src == NULL ) return false;
    while ( *src )
    {
        if ( *src == ',' )
        {
            if ( i_dest > 0 )
            {
                colname[i_dest]=0;
                vdcd_append_col( defs, colname );
            }
            i_dest = 0;
        }
        else
        {
            if ( i_dest < MAX_COL_NAME_LEN ) colname[i_dest++]=*src;
        }
        src++;
    }
    if ( i_dest > 0 )
    {
        colname[i_dest]=0;
        vdcd_append_col( defs, colname );
    }
    count = VectorLength( &defs->cols );
    if ( count > 0 && my_table != NULL )
    {
        const VCursor *my_cursor;
        rc_t rc = VTableCreateCursorRead( my_table, &my_cursor );
        DISP_RC( rc, "VTableCreateCursorRead() failed" );
        if ( rc == 0 )
        {
            uint32_t idx;
            for ( idx = 0; idx < count; ++idx )
            {
                col_def *col = ( col_def * )VectorGet( &(defs->cols), idx );
                if ( col != NULL )
                {
                    rc = VCursorAddColumn( my_cursor, &(col->idx), col->name );
                    DISP_RC( rc, "VCursorAddColumn() failed" );
                    if ( rc == 0 )
                    {
                        rc = VCursorDatatype( my_cursor, col->idx,
                                  &(col->type_decl), &(col->type_desc) );
                        DISP_RC( rc, "VCursorDatatype() failed" );
                        if ( rc == 0 )
                            found++;
                    }
                }
            }
            rc = VCursorRelease( my_cursor );
            DISP_RC( rc, "VCursorRelease() failed" );
        }
    }
    return found;
}
Example #7
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;
}