/*{ ** Name: IIAG4get_data copy data to program variables ** ** Description: ** Copy data from a DB_DATA_VALUE to the user's program variables. ** If the data is an object, we put it into the bag of known objects, ** and give the user the bag's index. ** ** Inputs: ** dbdv DB_DATA_VALUE * Data to put ** type i4 ADF type of user variable ** length i4 data size of user variable ** ** Outputs: ** ind i2 * NULL indicator ** data PTR user variable pointer ** ** Returns: ** STATUS ** OK ** E_G4271B_DATA_CONVERSION_GET ** E_G4271A_NO_NULL_INDICATOR ** ** History: ** 15-dec-92 (davel) ** Initial version, based on W4GL version developed by MikeS. */ STATUS IIAG4get_data(DB_DATA_VALUE *dbdv, i2 *ind, i4 type, i4 length, PTR data) { STATUS status = OK; DB_DATA_VALUE int_dbdv; DB_EMBEDDED_DATA edv; i4 objno; ADF_CB *cb = FEadfcb(); /* ** See if the data is an object */ if (dbdv->db_datatype == DB_DMY_TYPE) { /* Yes. Make an i4 DBDV */ int_dbdv.db_datatype = DB_INT_TYPE; int_dbdv.db_length = sizeof(i4); int_dbdv.db_prec = 0; int_dbdv.db_data = (PTR)&objno; if ( (status = IIAG4aoAddObject(dbdv->db_data, &objno) ) != OK ) { /* convert any IIAG4aoAddObject error to the generic ** E_G42729_GETDATA_ERROR, as IIAG4aoAddObject already raised ** the specific error. */ return E_G42729_GETDATA_ERROR; } dbdv = &int_dbdv; } /* Return the data */ edv.ed_type = type; edv.ed_length = length; edv.ed_data = data; edv.ed_null = ind; if (adh_dbcvtev(cb, dbdv, &edv) != OK) { if (cb->adf_errcb.ad_errcode == E_AD1012_NULL_TO_NONNULL) status = E_G4271A_NO_NULL_INDICATOR; else status = E_G4271B_DATA_CONVERSION_GET; } return status; }
STATUS IILQasAdfcbSetup( II_THR_CB *thr_cb ) { II_LBQ_CB *IIlbqcb = thr_cb->ii_th_session; II_LBQ_CB *def = &thr_cb->ii_th_defsess; /* ** Setup the static ADF CB. */ /* ??? Semaphore protect adf_cb/FEadfcb() */ if ( ! adf_cb && ! (adf_cb = FEadfcb()) ) { IIlocerr(GE_NO_RESOURCE, E_LQ0003_ADFINIT, II_ERR, 0, (char *)0); return FAIL; } /* ** Default sessions use the static ADF CB. */ if ( ! def->ii_lq_adf ) def->ii_lq_adf = adf_cb; /* ** Real sessions receive their own copy of the ADF CB. */ if ( ! IIlbqcb->ii_lq_adf ) { if ((IIlbqcb->ii_lq_adf = (ADF_CB *)MEreqmem((u_i4)0, (u_i4)sizeof(ADF_CB), TRUE, (STATUS *) NULL)) == NULL) { char ebuf[10]; CVna(IIlbqcb->ii_lq_sid, ebuf); IIlocerr(GE_NO_RESOURCE, E_LQ00E8_ADFALLOC, II_ERR, 1, ebuf); return FAIL; } /* Fill with the default values of the static ADF control block */ MEcopy((PTR)def->ii_lq_adf, (u_i2)sizeof(ADF_CB), (PTR)IIlbqcb->ii_lq_adf); } return OK; }
i4 IIgetfldio(i2 *ind, i4 variable, i4 type, i4 len, PTR data, char *name) { char *namestr; char fbuf[MAXFRSNAME+1]; DB_EMBEDDED_DATA edv; DB_DATA_VALUE *dbvptr; DB_DATA_VALUE oper_dbv; DB_DATA_VALUE dbvcop; i4 oper; ADF_CB *cb; bool errflag = FALSE; i4 getop = 0; i4 (*oldproc)(); bool disp_msgs = TRUE; /* Check field name for validity */ namestr = IIstrconv(II_CONV, name, fbuf, (i4)MAXFRSNAME); if (namestr == NULL) { IIFDerror(RTRFFL, 2, IIfrmio->fdfrmnm, ERx("")); return(FALSE); } /* Set up an EDV to describe the caller's parameters. */ edv.ed_type = type; edv.ed_length = len; edv.ed_data = (PTR) data; edv.ed_null = ind; cb = FEadfcb(); if (IIfrscb->frs_globs->enabled & GETMSGS_OFF) { disp_msgs = FALSE; oldproc = IIseterr(IIFRgmoGetmsgsOff); } /* ** If getting an 'oper', not a value, special processing required. ** Operators are not returned from FRAME as DBV's, so we must build ** one so we can follow the normal path and convert to the final EDV. */ getop = IIgetoper( (i4) 0 ); if ( getop ) { oper_dbv.db_datatype = DB_INT_TYPE; oper_dbv.db_length = sizeof(i4); oper_dbv.db_prec = 0; oper_dbv.db_data = (PTR) &oper; /* ** Make sure the frame is in Query mode, else return NOOP. */ if (IIfrmio->fdrunmd != fdrtQRY) oper = fdNOP; else FDqryop( IIfrmio->fdrunfrm, namestr, (i4 *) oper_dbv.db_data ); dbvptr = &oper_dbv; } else if (IIfrmio->fdrunmd == fdrtQRY) { /* ** If in query mode, we must use a different routine ** to retrieve the data portion of the field. This ** routine also strips off the operator. */ if (!FDqryfld(IIfrmio->fdrunfrm, namestr, &dbvptr)) errflag = TRUE; } else { IIfrscb->frs_event->eval_aggs = TRUE; /* ** Get data portion of the field */ if (!FDgetfld(IIfrmio->fdrunfrm, namestr, &dbvptr)) errflag = TRUE; IIfrscb->frs_event->eval_aggs = FALSE; } /* ** If "errflag" is set at this point, then it was not ** possible to get the DB_DATA_VALUE pointer for a field. ** ** Trim trailing blanks on character-type fields */ if ( errflag == FALSE && ( IIftrim( dbvptr, &dbvcop ) != OK ) ) errflag = TRUE; /* ** Convert the DBV containing the field's value to an EDV */ if ( errflag == FALSE && ( adh_dbcvtev( cb, &dbvcop, &edv ) != OK ) ) { if (cb->adf_errcb.ad_errcode == E_AD1012_NULL_TO_NONNULL) { IIFDerror(RTRNLNNL, 2, IIfrmio->fdfrmnm, namestr); } else { IIFDerror(RTGFERR, 2, IIfrmio->fdfrmnm, namestr); } errflag = TRUE; } if (!disp_msgs) _VOID_ IIseterr(oldproc); if ( errflag == TRUE ) return (FALSE); else return (TRUE); }
/*{ ** Name: IIAG4set_data copy data from program variables ** ** Description: ** Copy data to a DB_DATA_VALUE from the user's program variables. ** If the target is an object, we validate that the user has specified ** a valid object handle, and that the types match. ** ** Most of the error returns use the same set of arguments, which are ** passed in as part of the G4ERRDEF argument: ** ** arg[0] = caller name ** arg[1] = type of data (constant, global, or attribute) ** arg[2] = name of constant, global, or attribute ** ** If further arguments are needed, they are filled in. If a completely ** differnet set of arguments are needed, we overwrite them here. The ** caller will not try to set arguments after calling this function. ** ** Inputs: ** dbdv DB_DATA_VALUE * Data to put ** ind i2 * NULL indicator ** isvar i4 Pased by reference? ** type i4 ADF type of user variable ** length i4 data size of user variable ** data PTR user variable pointer ** ** Outputs: ** g4errdef G4ERRDEF * Error descriptor ** ** Returns: ** STATUS ** OK ** E_G4271C_DATA_CONVERSION_SET ** E_G4271D_NULL_VALUE ** ** History: ** 15-dec-92 (davel) ** Initial version, based on W4GL version developed by MikeS. */ STATUS IIAG4set_data (DB_DATA_VALUE *dbdv, i2 *ind, i4 isvar, i4 type, i4 length, PTR data, G4ERRDEF *g4errdef) { STATUS status = OK; DB_DATA_VALUE int_dbdv; DB_DATA_VALUE *target; DB_EMBEDDED_DATA edv; i4 objno; PTR rowptr; ADF_CB *cb = FEadfcb(); /* ** See if the 4GL target is an object */ if (dbdv->db_datatype == DB_DMY_TYPE) { /* Yes. Make an i4 DBDV for the user's specification to go into */ int_dbdv.db_datatype = DB_INT_TYPE; int_dbdv.db_length = sizeof(i4); int_dbdv.db_prec = 0; int_dbdv.db_data = (PTR)&objno; target = &int_dbdv; } else { target = dbdv; } /* Get the data */ edv.ed_type = type; edv.ed_length = length; edv.ed_data = isvar ? data : (PTR)&data; edv.ed_null = ind; if (adh_evcvtdb(cb, &edv, target) != OK) { if (cb->adf_errcb.ad_errcode == E_AD1012_NULL_TO_NONNULL) status = E_G4271D_NULL_VALUE; else status = E_G4271C_DATA_CONVERSION_SET; } /* ** If we got an object number, use it. */ if (status == OK && target == &int_dbdv) { if (IIAG4gkoGetKnownObject(objno, &rowptr) != OK) { g4errdef->numargs = 4; g4errdef->args[3] = ERx("object"); status = E_G4271E_BAD_OBJECT; } else { DB_DATA_VALUE rdbv; IIAG4dbvFromObject(rowptr, &rdbv); /* an error in IIARoasObjAssign() is pretty much always a type ** mismatch. */ status = IIARoasObjAssign(&rdbv, dbdv); if (status != OK) { /* re-construct the error message. leave args[0] alone, ** and fetch the two record type names. */ AB_TYPENAME aname, rname; iiarCcnClassName(dbdv, aname, FALSE); iiarCcnClassName(&rdbv, rname, FALSE); g4errdef->numargs = 3; g4errdef->args[1] = (PTR)rname; g4errdef->args[2] = (PTR)aname; status = E_G42714_BADROWTYPE; } } } return status; }
/*{ ** Name: IIgetquery - Get query spec for field and process it. ** ** Description: ** Given a field in a form, get the query specification for that ** field and process it by calling FDrngchk(). If the field ** is a table field, then process the passed in column for the ** current row. The current row is defined by the row that ** is currently being unloaded in an "unloadtable" loop. ** ** DML compatibility level is passed in and we assume that we will ** be building the query, not just simply doing a validation ** check. Fields are assumed to be not display only. The ** DB_DATA_VALUE that is passed to FDrngchk() must be READ ** ONLY to FDrngchk() and FDrngchk() must copy the value ** if it wants to use it later on. ** ** The current code is designed not to work with range query ** buffers at the moment and only allows ONE qualification ** per field. When the switch to use range query ** buffers is made, the code below (as well as some code in ** FT) must be changed to call FTgetdisp(). Also, the use ** of an "unloadtable" loop is invalid at this point and ** another mechanism must be used to unload the range query ** buffers for a table field. ** ** Yes, the code below is looking at the forms structures ** but it is only until we go to range query buffers. ** ** Inputs: ** form {char *} Name of form containing field. ** field {char *} Name of field on which to operate. ** column {char *} Name of column if field is a table field. ** tblname {char *} Name of database table to pass to FDrngchk(). ** dml_level {nat} DML compatibility level passed to 'FDrngchk()': ** UI_DML_QUEL ** UI_DML_SQL ** UI_DML_GTWSQL ** att {char *} Name of attribute in database table to pass ** to FDrngchk(). ** prefix {char *} Special information to be passed ** to FDrngchk(). ** func {STATUS (*)()} Function reference to pass ** to FDrngchk(). ** data {PTR} Parameter to be passed to "func" by FDrnghck(). ** ** Returns: ** {STATUS} OK If everything worked. ** FAIL If something went wrong. ** ** History: ** 06/09/87 (dkh) - Initial version. ** 08/25/88 (jhw) - Fixed Jup bug #3161. Allow DISPONLY fields to ** be qualified. ** 3/21/91 (elein) (b35574) Add FALSE parameter to call to ** fmt_multi. TRUE is used internally for boxed ** messages only. They need to have control ** characters suppressed. */ STATUS IIgetquery (char *form, char *field, char *column, char *tblname, i4 dml_level, char *attr, char *prefix, STATUS (*func)(), PTR data ) { RUNFRM *runf; FIELD *fld; DB_DATA_VALUE *dispdbv; FLDVAL *val; STATUS stat; bool nonseq; DB_DATA_VALUE ldbv; TBLFLD *tbl; FLDCOL *col; DB_TEXT_STRING *text; DB_TEXT_STRING *otext; ADF_CB *ladfcb; FMT *cfmt; i4 oper; char *opchar; i4 qrycnt; DB_DATA_VALUE valdbv; i4 rows = 0; i4 columns = 0; bool reversed; i4 len; i4 cursize; i4 i; u_char *c; u_char *end; /* ** Do various checks on existence of form, field, etc. ** Return FAIL if something is missing. Assume that ** we are being called from 'C', so no need to call ** IIstrconv(). */ runf = ( form == NULL || *form == EOS ) ? IIstkfrm : RTfindfrm(form); if ( runf == NULL ) { return FAIL; } /* ** Find field in the form, return FAIL if field does not exist. ** (Allow DISPONLY fields to be qualified, however.) */ if ( (fld = FDfndfld(runf->fdrunfrm, field, &nonseq)) == NULL ) { IIFDerror( GFFLNF, 1, field ); return FAIL; } ladfcb = FEadfcb(); if ( (stat = FDfmtget(runf->fdrunfrm, field, column, 0, &cfmt)) != OK ) { return(stat); } if ( cfmt == NULL ) { return FAIL; } _VOID_ fmt_isreversed(ladfcb, cfmt, &reversed); if (qtag == 0) { qtag = FEgettag(); } if (fld->fltag == FREGULAR) { /* ** Just point to the simple field's display ** buffer. It should be good. */ val = FDgetval(fld); dispdbv = val->fvdsdbv; if (reversed) { /* ** Find out information for formatting. */ if (fmt_size(ladfcb, cfmt, val->fvdbv, &rows, &columns) != OK) { return(FAIL); } MEcopy((PTR) val->fvdsdbv, (u_i2) sizeof(DB_DATA_VALUE), (PTR) &valdbv); if ((valdbv.db_data = FEreqmem(qtag, (u_i4)valdbv.db_length, TRUE, &stat)) == NULL) { FEfree(qtag); return(FAIL); } text = (DB_TEXT_STRING *) valdbv.db_data; otext = (DB_TEXT_STRING *) val->fvdsdbv->db_data; cursize = text->db_t_count = otext->db_t_count; MEcopy((PTR)otext->db_t_text, (u_i2)cursize, (PTR)text->db_t_text); c = text->db_t_text; len = rows * columns; if (len > cursize) { MEfill((u_i2)(len - cursize), (unsigned char)' ', (PTR)(c + cursize)); text->db_t_count = len; } for (i = 0; i < rows; i++) { f_revrsbuf(columns, (bool)TRUE, c); c += columns; } /* ** Need to trim trailing blanks at this point. ** Don't need to use CM routines here, since Kanji ** and reverse don't work together. */ end = text->db_t_text; c = end + text->db_t_count - 1; while ( c >= end && *c-- == ' ' ) { --(text->db_t_count); } dispdbv = &valdbv; } } else { /* a table field */ FMT scrfmt; /* for scrolling columns */ tbl = fld->fld_var.fltblfld; /* ** Need to get value and query operator from ** dataset and then convert into a LONG_TEXT ** struct for display. First, check for ** existence of column. */ if ((col = FDfndcol(tbl, column)) == NULL) { return(FAIL); } /* ** Allocate local copies of column value and display ** buffers. */ val = tbl->tfwins + col->flhdr.fhseq; /* + ( 0 * tbl->tfcols ) */ MEcopy((PTR) val->fvdbv, (u_i2) sizeof(DB_DATA_VALUE), (PTR) &valdbv); MEcopy((PTR) val->fvdsdbv, (u_i2) sizeof(DB_DATA_VALUE), (PTR) &ldbv); if ( (valdbv.db_data = FEreqmem(qtag, (u_i4)valdbv.db_length, TRUE, &stat)) == NULL || (ldbv.db_data = FEreqmem(qtag, (u_i4)ldbv.db_length, TRUE, &stat)) == NULL ) { FEfree(qtag); return FAIL; } if (IITBcieColIsEmpty(column)) { text = (DB_TEXT_STRING *) ldbv.db_data; text->db_t_count = 0; } else { /* ** Get value for column from current row. ** Note that this is a direct call to internal routine ** and changes made must be done carefully. */ if ( !IItcogetio((i2 *) NULL, TRUE, DB_DBV_TYPE, 0, &valdbv, column) ) { FEfree(qtag); return(FAIL); } /* ** Now get query operator. */ IIgetoper(1); if ( !IItcogetio((i2 *) NULL, TRUE, DB_INT_TYPE, sizeof(oper), &oper, column) ) { FEfree(qtag); return(FAIL); } /* ** Format value. */ /* ** If it's a scrolling column, make a format for all the ** data, not just the fraction that can be displayed ** at once. */ if ((col->flhdr.fhd2flags & fdSCRLFD) != 0) { STRUCT_ASSIGN_MACRO(*cfmt, scrfmt); scrfmt.fmt_width = ldbv.db_length - 2; cfmt = &scrfmt; } /* ** Find out information for formatting. */ if (fmt_size(ladfcb, cfmt, &valdbv, &rows, &columns) != OK) { FEfree(qtag); return(FAIL); } /* ** Just format output if single line output. */ if (rows == 1) { if (fmt_format(ladfcb, cfmt, &valdbv, &ldbv, TRUE) != OK) { FEfree(qtag); return(FAIL); } } else { reg u_char *dsptr; DB_TEXT_STRING *ftext; PTR buffer; DB_DATA_VALUE wksp; i4 length = 0; wksp.db_datatype = DB_LTXT_TYPE; wksp.db_prec = 0; wksp.db_length = DB_CNTSIZE + columns; if ( (wksp.db_data = FEreqmem(qtag, (u_i4)wksp.db_length, TRUE, &stat)) == NULL ) { FEfree(qtag); return(FAIL); } fmt_workspace(ladfcb, cfmt, &valdbv, &length); if ( (buffer = FEreqmem(qtag, (u_i4)length, TRUE, &stat)) == NULL ) { FEfree(qtag); return(FAIL); } /* ** Do multi-line output. */ IIfmt_init(ladfcb, cfmt, &valdbv, buffer); text = (DB_TEXT_STRING *) ldbv.db_data; text->db_t_count = 0; dsptr = text->db_t_text; ftext = (DB_TEXT_STRING *) wksp.db_data; for (;;) { reg i4 j; reg u_char *fptr; i4 fcount; bool more = FALSE; if (fmt_multi(ladfcb, cfmt, &valdbv, buffer, &wksp,&more,TRUE, FALSE) != OK) { FEfree(qtag); return(FAIL); } if (!more) { break; } /* ** put into fields display buffer. */ fcount = ftext->db_t_count; fptr = ftext->db_t_text; for (j = 0; j < fcount; j++) { *dsptr++ = *fptr++; } text->db_t_count += fcount; } } text = (DB_TEXT_STRING *) ldbv.db_data; if (reversed) { c = text->db_t_text; cursize = text->db_t_count; len = rows * columns; if (len > cursize) { MEfill((u_i2)(len - cursize), (unsigned char)' ', (PTR)(c + cursize)); text->db_t_count = len; } for (i = 0; i < rows; i++) { f_revrsbuf(columns, (bool)TRUE, c); c += columns; } } /* ** Need to trim trailing blanks at this point. */ end = text->db_t_text; c = end + text->db_t_count - 1; while ( c >= end && *c-- == ' ' ) { --(text->db_t_count); } /* ** Insert query operators up front. */ if ( oper != fdNOP && oper != fdEQ && (qrycnt = STlength(opchar = iiugOpRep(oper))) > 0 ) { reg u_char *dsptr; reg u_char *head; reg i4 j; reg i4 cnt; head = text->db_t_text + text->db_t_count - 1; dsptr = head + qrycnt; cnt = text->db_t_count; for (j = 0; j < cnt; j++) { *dsptr-- = *head--; } text->db_t_text[0] = opchar[0]; if (qrycnt == 2) { text->db_t_text[1] = opchar[1]; } text->db_t_count += qrycnt; } } dispdbv = &ldbv; } stat = FDrngchk(runf->fdrunfrm, field, column, dispdbv, (bool) TRUE, tblname, attr, (bool) TRUE, dml_level, prefix, func, data); if (qtag != 0) { FEfree(qtag); } return stat; }