Exemplo n.º 1
0
/*{
** Name: PSQ_TCNVT	- convert db_data_value to text form
**
** Description:
**      This routine takes any user supplied db_data_value and converts
**  it to the value's textual representation.  This is required for the
**  iiqrytext catalog.  It is assumed that all datavalues can be written
**  into a character representation. 
**
** Inputs:
**	sess_cb				session control block
**	    .pss_adfcb			adf session control block for output
**					arguments.
**      header                          Pointer to chain header
**	dbval				db_data_value
**	result				Place to put pointer to new piece
**	err_blk				Filled in if an error happens
**
** Outputs:
**      result                          Filled in with pointer to chain element
**	err_blk				Filled in if an error happens
**	Returns:
**	    E_DB_OK			Success
**	    E_DB_ERROR			Non-catastrophic failure
**	    E_DB_FATAL			Catastrophic failure
**	Exceptions:
**	    none
**
** Side Effects:
**	    Allocates memory
**
** History:
**      29-jun-87 (daved)
**          written
**	28-jan-91 (andre)
**	    fix bug 35446: size of a new piece should include quotes, if they
**	    were added.
**	18-nov-91 (rog)
**	    Fixed bug 40869, et alia: the above fix missed adding the quotes
**	    to the total size and not just the piece size.
**	23-Sep-2009 (kiria01) b122578
**	    Initialise the ADF_FN_BLK .adf_fi_desc and adf_dv_n members.
**	19-Aug-2010 (kschendel) b124282
**	    Make sure fi-desc is always set to something.
*/
DB_STATUS
psq_tcnvt(
	PSS_SESBLK	   *sess_cb,
	PTR                header,
	DB_DATA_VALUE	   *dbval,
	PTR		   *result,
	DB_ERROR	   *err_blk)
{
    PSQ_THEAD           *hp;
    PSQ_TEXT		*tp;
    i4		err_code;
    DB_STATUS		status;
    ADF_CB		*adf_cb;
    ADF_FN_BLK		adffn;
    i4			dv_size;
    i4			count;
    char		*cptr;
    char		*quote_char;
    DB_TEXT_STRING      *string;
    ADI_DT_NAME		dt_fname;
    ADI_DT_NAME		dt_tname;
    char		f4_style;
    char		f8_style;
    i4			f4_width;
    i4			f8_width;
    i4			f4_prec;
    i4			f8_prec;
    i4			totype;
    i4			is_string;

    hp	    = (PSQ_THEAD *) header;
    adf_cb  = (ADF_CB *) sess_cb->pss_adfcb;
    status  = E_DB_OK;
    totype  = (DB_DT_ID) DB_LTXT_TYPE;

    adffn.adf_r_dv.db_datatype = totype;
    if (dbval->db_datatype == totype)
	dv_size = dbval->db_length;
    else
	dv_size = 0;

    /* JRBCMT -- PSF is not allowed to know this!!  First of all, date is   */
    /* missing from the list below and decimal will soon need to be on it.  */
    /* But also, we need to fix this code so that it doesn't make	    */
    /* assumptions about what types exist.  I think the proper approach is  */
    /* to quote all non-intrinsic types, but this should be investigated.   */

    /* are we dealing with a string type (incoming). */
    if (abs(dbval->db_datatype) == DB_INT_TYPE ||
        abs(dbval->db_datatype) == DB_FLT_TYPE ||
	abs(dbval->db_datatype) == DB_MNY_TYPE ||
	abs(dbval->db_datatype) == DB_BOO_TYPE)
    {
	is_string = FALSE;
	quote_char = (char *) NULL;
    }
    else
    {
	is_string = TRUE;
	quote_char = (sess_cb->pss_lang == DB_SQL) ? "\'" : "\"";
    }
    

    /* set the floating point conversion display */
    f4_style = adf_cb->adf_outarg.ad_f4style;
    f8_style = adf_cb->adf_outarg.ad_f8style;
    f4_width = adf_cb->adf_outarg.ad_f4width;
    f8_width = adf_cb->adf_outarg.ad_f8width;
    f4_prec  = adf_cb->adf_outarg.ad_f4prec;
    f8_prec  = adf_cb->adf_outarg.ad_f8prec;

    adf_cb->adf_outarg.ad_f4style = 'n';
    adf_cb->adf_outarg.ad_f8style = 'n';
    adf_cb->adf_outarg.ad_f4width = 20;
    adf_cb->adf_outarg.ad_f8width = 20;
    adf_cb->adf_outarg.ad_f4prec  = 10;
    adf_cb->adf_outarg.ad_f8prec  = 10;

    /* get the function instance id for this conversion */
    status = adi_ficoerce(adf_cb, dbval->db_datatype, totype, &adffn.adf_fi_id);
    if (status != E_DB_OK)
    {
	goto exit;
    }         

    /* determine the result size. */
    status = adi_fidesc(adf_cb, adffn.adf_fi_id, &adffn.adf_fi_desc);
    if (status != E_DB_OK)
    {
	goto exit;
    }
    if (!dv_size)
    {
	/* Now lets fill in the datatype length info and allocate space for the 
	** data.
	*/
	status = adi_0calclen(adf_cb, &adffn.adf_fi_desc->adi_lenspec, 1, &dbval, 
		&adffn.adf_r_dv);
	dv_size = adffn.adf_r_dv.db_length;

	if (status != E_DB_OK)
	{
	     goto exit;
	}
    }
    /* if string, add room for quotes */
    if (is_string)
	dv_size += 2 * CMbytecnt(quote_char);

    /* Allocate enough space for PSQ_TEXT structure containing piece */
    hp->psq_tmem.ulm_psize = dv_size + sizeof(PSQ_TEXT) - 1;
    status = ulm_palloc(&hp->psq_tmem);
    if (status != E_DB_OK)
    {
	if (hp->psq_tmem.ulm_error.err_code == E_UL0005_NOMEM)
	{
	    psf_error(E_PS0F02_MEMORY_FULL, 0L, PSF_CALLERR, 
		&err_code, err_blk, 0);
	}
	else
	    (VOID) psf_error(E_PS0371_ALLOC_TEXT_CHAIN,
		hp->psq_tmem.ulm_error.err_code, PSF_INTERR,
		&err_code, err_blk, 0);
	return (status);
    }
    *result = hp->psq_tmem.ulm_pptr;
    tp	    = (PSQ_TEXT*) *result;

    string	  = (DB_TEXT_STRING*) tp->psq_tval;
    /* Fill in text piece */
    adffn.adf_r_dv.db_length	= dv_size;
    adffn.adf_r_dv.db_data	= (PTR) string;
    adffn.adf_dv_n		= 1;
    STRUCT_ASSIGN_MACRO(*dbval, adffn.adf_1_dv);
    adffn.adf_pat_flags		= AD_PAT_DOESNT_APPLY;
    if ((status = adf_func(adf_cb, &adffn)) != E_DB_OK)
    {
	goto exit;
    }
    /* CAUTION: entering tricky code.
    ** string is a variable containing a text datatype. We want to convert
    ** to a C datatype.  We also want to add quote characters if the datatype
    ** was a string type.  We grab the count from the string variable first.
    ** we can then use the 2 byte count for character data.
    */
    count = string->db_t_count;
    cptr = (char *)  string;
    if (is_string)
    {
	/*
	** for strings, copy the opening quote (" or ', depending on language)
	*/ 
	CMcpychar(quote_char, cptr);
	cptr += CMbytecnt(quote_char);
    }
    MEcopy((PTR) string->db_t_text, count, (PTR) cptr);
    cptr += count;
    if (is_string)
    {
	/*
	** for strings, copy the closing quote (" or ', depending on language)
	*/ 
	CMcpychar(quote_char, cptr);
    }

    /* if storing a string, do not forget to account for quotes (bug 35446) */
    tp->psq_psize = (is_string) ? count + 2 * CMbytecnt(quote_char) : count;

    /* Hook it up to the chain */
    tp->psq_next = (PSQ_TEXT *) NULL;
    if (hp->psq_last != (PSQ_TEXT *) NULL)
    {
	hp->psq_last->psq_next = tp;
	tp->psq_prev = hp->psq_last;
    }
    else
    {
	tp->psq_prev = NULL;
    }
    hp->psq_last = tp;
    if (hp->psq_first == (PSQ_TEXT *) NULL)
	hp->psq_first = tp;

    /* Add in the length to the total for the chain */
    hp->psq_tsize += tp->psq_psize;

exit:
    /* set the floating point conversion display */
    adf_cb->adf_outarg.ad_f4style = f4_style;
    adf_cb->adf_outarg.ad_f8style = f8_style;
    adf_cb->adf_outarg.ad_f4width = f4_width;
    adf_cb->adf_outarg.ad_f8width = f8_width;
    adf_cb->adf_outarg.ad_f4prec  = f4_prec;
    adf_cb->adf_outarg.ad_f8prec  = f8_prec;

    if (status != E_DB_OK)
    {
	(VOID) adi_tyname(adf_cb, dbval->db_datatype, &dt_fname);
	(VOID) adi_tyname(adf_cb, totype, &dt_tname);
	(VOID) psf_error(2911L, 0L, PSF_USERERR,
	    &err_code, err_blk, 3, sizeof (sess_cb->pss_lineno),
	    &sess_cb->pss_lineno, 
	    psf_trmwhite(sizeof(dt_fname), (char *) &dt_fname), &dt_fname, 
	    psf_trmwhite(sizeof (dt_tname), (char *) &dt_tname), &dt_tname);
        return (E_DB_ERROR);    
    }
    return (status);
}
Exemplo n.º 2
0
DB_STATUS
adi_cpficoerce(
ADF_CB              *adf_scb,
DB_DT_ID            adi_from_did,
DB_DT_ID            adi_into_did,
ADI_FI_ID           *adi_fid)
{
    DB_DT_ID		from_bdt = abs(adi_from_did);
    DB_DT_ID		into_bdt = abs(adi_into_did);
    ADI_FI_DESC	        *fi_desc_ptr;
    i4		        found = FALSE;
    DB_STATUS		db_stat;
    DB_DT_ID		minto_bdt;
    DB_DT_ID		mfrom_bdt;
    
    mfrom_bdt = ADI_DT_MAP_MACRO(from_bdt);
    minto_bdt = ADI_DT_MAP_MACRO(into_bdt);

    for (;;)
    {
	/* Check the validity of the datatype ids */

        if (   (mfrom_bdt <= 0 || mfrom_bdt > ADI_MXDTS)
	    || (minto_bdt <= 0 || minto_bdt > ADI_MXDTS)
	    || Adf_globs->Adi_dtptrs[mfrom_bdt] == NULL
	    || Adf_globs->Adi_dtptrs[minto_bdt] == NULL
	   )
	{
	    return (adu_error(adf_scb, E_AD2004_BAD_DTID, 0));
	}

	/* Search for the appropriate COPY COERCION function instance id */
	for (fi_desc_ptr = (ADI_FI_DESC *)&Adf_globs->Adi_fis[Adf_globs->
						   Adi_copy_coercion_fis];
		(   fi_desc_ptr->adi_fitype == ADI_COPY_COERCION
		 && fi_desc_ptr->adi_finstid != ADFI_ENDTAB
		);
	     fi_desc_ptr++
	    )
	{
	    if (fi_desc_ptr->adi_finstid == ADI_NOFI)
		continue;   /* Hole in fitab ... skip this one. */

	    if (fi_desc_ptr->adi_dtresult == into_bdt
		&& fi_desc_ptr->adi_dt[0] == from_bdt
	       )
	    {
		*adi_fid = fi_desc_ptr->adi_finstid;
		found = TRUE;
		return (E_DB_OK);
	    }
	}
	break;

    }	/* end of for(;;) stmt */


    /* Attempt to find normal COERCION function instance ID */

    if (db_stat = adi_ficoerce(adf_scb, from_bdt, into_bdt, adi_fid))
    {
	if (adf_scb->adf_errcb.ad_errcode == E_AD2009_NOCOERCION)
	    db_stat = adu_error(adf_scb, E_AD200A_NOCOPYCOERCION, 0);
    }
    return (db_stat);
}