Example field procedure program that masks data
Add field procedure FP1 to column C1. The field procedure FP1 expects an additional parameter which it uses to indicate a version level for the field procedure.
ALTER TABLE TESTTAB ALTER C1 SET FIELDPROC FP1(1)
#include "string.h"
#include <QSYSINC/H/SQLFP>
void reverse(char *in, char *out, long length);
main(int argc, void *argv[])
{
short *funccode = argv[1];
sqlfpFieldProcedureParameterList_T *optionalParms = argv[2];
char *sqlstate = argv[7];
sqlfpMessageText_T *msgtext = argv[8];
int version;
sqlfpOptionalParameterValueDescriptor_T *optionalParmPtr;
sqlfpInformation_T *info = argv[9];
int masked;
if (optionalParms->sqlfpNumberOfOptionalParms != 1)
{
memcpy(sqlstate,"38001",5);
return;
}
optionalParmPtr = (void *)&(optionalParms->sqlfpParmList);
version = *((int *)&optionalParmPtr->sqlfpParmData);
/*******************************************************************/
/* CREATE CALL */
/*******************************************************************/
if (*funccode == 8) /* create time */
{
sqlfpParameterDescription_T *inDataType = argv[3];
sqlfpParameterDescription_T *outDataType = argv[5];
if (inDataType->sqlfpSqlType !=452 &&
inDataType->sqlfpSqlType !=453 ) /* only support fixed length char */
{
memcpy(sqlstate,"38002",5);
return;
}
/* an example of how an optional parm could be used */
/* In this case it is used to add version support if it is */
/* expected that the fieldproc program may support multiple */
/* versions */
if (version != 1) /* only support version 1 at this time */
{
memcpy(sqlstate,"38003",5);
return;
}
/* do something here to determine the result data type */
/* ..... */
/* in this example input and output types are exactly the same */
/* so just copy */
memcpy(outDataType, inDataType, sizeof(sqlfpParameterDescription_T));
}
/*******************************************************************/
/* ENCODE (WRITE) CALL */
/*******************************************************************/
else if (*funccode == 0) /* encode */
{
sqlfpParameterDescription_T *decodedDataType = argv[3];
char *decodedData = argv[4];
char *encodedData = argv[6];
/* Detect that the value passed on encode is masked. */
/* Return 09501 to tell DB that: */
/* - The field should not be updated for an update operation */
/* - The default value should be used for an insert operation*/
if ( memcmp(decodedData, "XXXXXXXXXXXX", 12) == 0 )
{
memcpy(sqlstate,"09501",5);
}
else
{
reverse(decodedData, encodedData, decodedDataType->sqlfpByteLength);
}
}
/*******************************************************************/
/* DECODE (READ) CALL */
/*******************************************************************/
else if (*funccode == 4) /* decode */
{
char *decodedData = argv[4];
sqlfpParameterDescription_T *encodedDataType = argv[5];
char *encodedData = argv[6];
/* The 9th paramter indicates that the column must not be */
/* masked. For example, during ALTER TABLE or RGZPFM. */
if ( info->sqlfpNoMask == '1' )
{
reverse(encodedData, decodedData, encodedDataType->sqlfpByteLength);
return;
}
else
{
reverse(encodedData, decodedData, encodedDataType->sqlfpByteLength);
/* Mask the data when appropriate */
/* Assume mask is set to 0 when it should not be masked */
/* and 1 when it shoulbe be masked */
if (masked == 1)
{
memcpy(decodedData, "XXXXXXXXXXXX",
encodedDataType->sqlfpByteLength);
}
}
return;
}
/*******************************************************************/
/* ERROR- UNSUPPORTED OPTION */
/*******************************************************************/
else /* unsupported option -- error */
memcpy(sqlstate, "38003",5);
}
/*******************************************************************/
/* REVERSE */
/*******************************************************************/
void reverse(char *in, char *out, long length)
{
int i;
for (i=0;i<length; ++i) {
out[length - (i+1)] = in[i];
}
}