データをマスクするフィールド・プロシージャー・プログラムの例

フィールド・プロシージャー FP1 を列 C1 に追加します。 フィールド・プロシージャー FP1 には、フィールド・プロシージャーが操作の対象とする列のバイト数を示す 1 つの追加パラメーターがあります。

ALTER TABLE TESTTAB ALTER C1 SET FIELDPROC FP1(10)

#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 bytesToProcess;
  sqlfpOptionalParameterValueDescriptor_T *optionalParmPtr;
  sqlfpInformation_T *info = argv[9]; 
  int masked;

   if (optionalParms->sqlfpNumberOfOptionalParms != 1)
   {
      memcpy(sqlstate,"38001",5);
      return;
   }
   optionalParmPtr = (void *)&(optionalParms->sqlfpParmList);
   bytesToProcess = *((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;
      }
      /* 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 */
   {
      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, bytesToProcess);
      }
   }

/*******************************************************************/ 
/* DECODE (READ) CALL                                              */ 
/*******************************************************************/ 
   else if (*funccode == 4)    /* decode */
   {
     char *decodedData = argv[4];
     char *encodedData = argv[6];

     /* The 9th paramter indicates that the column must not be     */
     /* masked. For exmaple, during ALTER TABLE or RGZPFM.         */
     if ( info->sqlfpNoMask == '1' )
     {
       reverse(encodedData, decodedData, bytesToProcess);
       return;
     }

     else
     {
       reverse(encodedData, decodedData, bytesToProcess);
       /* 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", 12);
       }
     }

     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]; 
    }
}