Hot To Add SRB Functions

From SRB

To add a new function (a client/server call) to the SRB one needs 
to perform the following steps:

1. src/include/clStubExtern.h
        add   documentation for the client call 
        add   interface definition for client call 


2. src/include/obj**.h  (use relevant ones)
        add   interface definition for server call
        add   interface definition for _server call

3. src/include/distribExtern.h
        add   interface definition for remote call

4. src/include/stubdef.h
       add the FunctionId as a #define

5. src/include/functionHandler.h
        add  a row to functionTable

6. src/client/clStub.c
	code the client call

7. src/back/obj**.c (use relevant ones)
	code the server call 
	code the _server call (and its attendant functions)

8. back/distrib.c
        code the remote function call
              as per that added in src/include/distribExtern.h

Two examples using this is given below.
-------------------------------------------------------------------
Example: modifyZoneInfo

/***********************************************************************/
/***********************************************************************/
1. src/include/clStubExtern.h
        add   documentation for the client call 
        add   interface definition for client call 

/*
 * srbModifyZone - Modify and Insert SRB zone and zone information in the
 *  Metadata Catalog. Information about the operation  performed is 
 *  also logged in the audit  trail (if turned on). This is a
 *  privileged function and should be called only by a 
 *  srbAdmin user.
 *
 *
 * Input - srbConn* conn    - From clConnect ().
 *         int catType      - catalog type. e,g., MDAS_CATALOG.
 *         char *zone_name  - name of the zone
 *         char *dataValue1 - Input value 1.
 *         char *dataValue2 - Input value 2.
 *         char *dataValue3 - Input value 3.
 *         char *dataValue4 - Input value 4.
 *         char *dataValue5 - Input value 5.
 *         int  actionType  - The type of action. performed
 *                  values supported are:
 *
 *                 Z_INSERT_NEW_LOCAL_ZONE
 *                     dv1 = locn_desc
 *                     dv2 = port_number
 *                     dv3 = username@domain   of remote MCAT admin
 *                     dv4 = zone_contact
 *                     dv5 = zone_comment
 *                 Z_INSERT_NEW_ALIEN_ZONE
 *                     dv1-5 = same as for INSERT_NEW_LOCAL_ZONE
 *                 Z_MODIFY_ZONE_INFO
 *                     dv1-5 = same as for INSERT_NEW_LOCAL_ZONE
 *                           empty string implies no change.
 *                 Z_MODIFY_ZONE_FOR_USER
 *                     dv1 = user_name
 *                     dv2 = domain_name
 *                 Z_CHANGE_ZONE_NAME
 *                     dv1 = new name
 *                 Z_MODIFY_ZONE_LOCAL_FLAG
 *                     dv1 = new value (integer)
 *                 Z_MODIFY_ZONE_STATUS
 *                     dv1 = new value (integer)
 *
 * Output - Returns 0 - success.
 *          Returns negative - failure.
 */

extern int srbModifyZone (srbConn* conn, int catType,
char *zoneName, char *dataValue1, char *dataValue2,
char *dataValue3, char *dataValue4, char *dataValue5, int actionType);

/***********************************************************************/
/***********************************************************************/
2. src/include/srbObjFunctExtern.h
        add   interface definition for server call
        add   interface definition for _server call


extern int svrModifyZone (int catType, 
			  struct varlena *vZoneName,
			  struct varlena *vDataValue1, 
			  struct varlena *vDataValue2,
			  struct varlena *vDataValue3, 
			  struct varlena *vDataValue4, 
			  struct varlena *vDataValue5, 
			  int actionType);
extern int _svrModifyZone (int catType, 
			   char *zoneName, 
			   char *dataValue1, 
			   char *dataValue2, 
			   char *dataValue3, 
			   char *dataValue4, 
			   char *dataValue5, 
			   int actionType);

/***********************************************************************/
/***********************************************************************/
3. src/include/distribExtern.h
        add   interface definition for remote call

extern int remoteModifyZone (int catType, char *zoneName,
       char *dataValue1, char *dataValue2, char *dataValue3, char *dataValue4,
       char *dataValue5, int actionType, struct hostElement  *hostTabPtr);

/***********************************************************************/
/***********************************************************************/
4. src/include/stubdef.h
       add the FunctionId as a #define

#define F_MODIFY_ZONE   	2152

/***********************************************************************/
/***********************************************************************/
5. src/include/functionHandler.h
        add  a row to functionTable

#if defined(SRB_SERVER) && !defined(STK_SERVER)
        {F_MODIFY_ZONE, (func_ptr)svrModifyZone, 
#else
        {F_MODIFY_ZONE, (func_ptr)NULL, 
#endif
	"svrModifyZone", SIZEOF32, 8, SIZEOF32, -1, -1, -1, -1,  -1, -1, 
        SIZEOF32,  0, 0, 0, 0},

/***********************************************************************/
/***********************************************************************/
6. src/client/clStub.c
	code the client call

int srbModifyZone (srbConn* conn, int catType,
char *zoneName, char *dataValue1, char *dataValue2,
char *dataValue3, char *dataValue4, char *dataValue5, int actionType)
{
    int retval;
    srb_long_t argv[MAXFMGRARGS];
    ClOut clOut;
    int clOutVal;

    clOut.retval = (char *) &clOutVal;

    argv[0] = catType;
    argv[1] = addrToSRBLong (zoneName);
    argv[2] = addrToSRBLong (dataValue1);
    argv[3] = addrToSRBLong (dataValue2);
    argv[4] = addrToSRBLong (dataValue3);
    argv[5] = addrToSRBLong (dataValue4);
    argv[6] = addrToSRBLong (dataValue5);
    argv[7] = actionType;

    retval = clCall (conn, F_MODIFY_ZONE, argv, &clOut);
    return retval;
}

/***********************************************************************/
/***********************************************************************/

7. src/back/srbObjFunct.c
	code the server call 
	code the _server call 


int
svrModifyZone (int catType, struct varlena *vZoneName,
struct varlena *vDataValue1, struct varlena *vDataValue2,
struct varlena *vDataValue3, struct varlena *vDataValue4, 
struct varlena *vDataValue5, int actionType)
{
    char *zoneName;
    char *dataValue1;
    char *dataValue2;
    char *dataValue3;
    char *dataValue4;
    char *dataValue5;
    int retVal;

    if (TicketUserFlag) {
        elog (NOTICE, "Illegal operation for a ticket user");
        return (ILLEGAL_OPR_TICKET_USER);
    }

    zoneName = varToStr (vZoneName);
    dataValue1 = varToStr (vDataValue1);
    dataValue2 = varToStr (vDataValue2);
    dataValue3 = varToStr (vDataValue3);
    dataValue4 = varToStr (vDataValue4);
    dataValue5 = varToStr (vDataValue5);


    retVal = _svrModifyZone (catType, zoneName, dataValue1, 
    dataValue2, dataValue3, dataValue4, dataValue5, actionType);

    free (zoneName);
    free (dataValue1);
    free (dataValue2);
    free (dataValue3);
    free (dataValue4);
    free (dataValue5);

    return retVal;
}

int
_svrModifyZone (int catType, char *zoneName, char *dataValue1,
char *dataValue2, char *dataValue3, char *dataValue4, char *dataValue5, 
int actionType)
{
    int retVal;
    char *userName;
    int remoteFlag;
    struct hostElement  *hostTabPtr;

    /* Do a modify_zone_info */

    remoteFlag = getMdasEnabledHost (NULL, &hostTabPtr);

    if (remoteFlag < 0) {
	retVal = remoteFlag;
    } else if (remoteFlag == LOCAL_HOST) {      /* Can talk to mdas */
#ifdef SRB_MDAS
        userName = ClientUser->userName;
        retVal = modify_zone_info (catType, userName, ClientUser->domainName,
	  zoneName, dataValue1, dataValue2, dataValue3,
	  dataValue4, dataValue5, actionType);
	if (retVal == 0)
            commit_db2_interaction (MDAS_CAT_COMMIT);
#endif
    } else {
        retVal = remoteModifyZone (catType, zoneName,
          dataValue1, dataValue2, dataValue3, dataValue4, dataValue5, 
	  actionType, hostTabPtr);
    }

    return retVal;
}
/*** modify_zone_info   is done in the catalog ***/


/***********************************************************************/
/***********************************************************************/

8. back/distrib.c
        code the remote function call
              as per that added in src/include/distribExtern.h



int
remoteModifyZone (int catType, char *zoneName,
		  char *dataValue1, char *dataValue2, 
		  char *dataValue3, char *dataValue4,
		  char *dataValue5, int actionType,
		  struct hostElement  *hostTabPtr)
{
    int status;

    if (remoteConnect (hostTabPtr) < 0) {
        return SYS_ERR_REMOTE_CONN;
    }

    /* Do a client call to the remote host */

    status = srbModifyZone (hostTabPtr->conn, catType,
      zoneName, dataValue1, dataValue2, dataValue3, dataValue5, 
      dataValue5, actionType);

    if (status < 0) {       /* Failure */
        elog (NOTICE, "remoteModifyZone failed: %s",
          clErrorMessage(hostTabPtr->conn));
    }

    return (status);
}

/***********************************************************************/
/***********************************************************************/


-------------------------------------------------------------------
-------------------------------------------------------------------
Another Example: srbBulkQueryAnswer

/***********************************************************************/
/***********************************************************************/

1. src/include/clStubExtern.h
        add   documentation for the client call 
        add   interface definition for client call 


/*
 * srbBulkQueryAnswer -  Get answers for canned queries from MCAT.
 *
 * Input - srbConn* conn - From srbConnect ().
 *         int catType - catalog type - 0 - MCAT
 *         char *queryInfo - query information all info needed to
 *               perform the query is in this string. The semantics for
 *               the string depends upon the operation.
 *         int rowsWanted - number of rows of result wanted.
 *
 * Output:
 *         A mdasC_sql_result_struct *myresult
 *
 * Return value :
 *      0 - success; myresult->continuation_index >= 0, ==> more results from
 *          the query. Use srbGetMoreRows() to retrieve more rows.
 *      a negative value - failure
 */
extern int
srbBulkQueryAnswer (srbConn *conn, int catType, char *queryInfo,
mdasC_sql_result_struct *myresult, int rowsWanted);

/***********************************************************************/
/***********************************************************************/
2. src/include/srbObjFunctExtern.h
        add   interface definition for server call
        add   interface definition for _server call

extern struct varlena * svrBulkQueryAnswer (int catType, 
					    struct varlena *vQueryInfo,
					    int rowsWanted);

extern int _svrBulkQueryAnswer (int catType, 
			    char *queryInfo, 
			    mdasC_sql_result_struct **myresult,
			    int rowsWanted);

/***********************************************************************/
/***********************************************************************/
3. src/include/distribExtern.h
        add   interface definition for remote call

extern int remoteBulkQueryAnswer (int catType, 
				  char *queryInfo,
				  mdasC_sql_result_struct **myresult, 
				  int rowsWanted, 
				  struct hostElement  *hostTabPtr);

/***********************************************************************/
/***********************************************************************/
4. src/include/stubdef.h
       add the FunctionId as a #define

#define F_BULK_QUERY_ANSWER   	2153

/***********************************************************************/
/***********************************************************************/
5. src/include/functionHandler.h
        add  a row to functionTable

#if defined(SRB_SERVER) && !defined(STK_SERVER)
        {F_BULK_QUERY_ANSWER, (func_ptr)svrBulkQueryAnswer, 
#else
        {F_BULK_QUERY_ANSWER, (func_ptr)NULL, 
#endif
	"svrBulkQueryAnswer", -1, 3, SIZEOF32, -1,  SIZEOF32, 
	0, 0, 0, 0, 0, 0, 0, 0, 0},

/***********************************************************************/
/***********************************************************************/
6. src/client/clStub.c
	code the client call

extern int
srbBulkQueryAnswer (srbConn *conn, int catType, char *queryInfo,
mdasC_sql_result_struct *myresult, int rowsWanted)

{
    char *buf;
    int buflen;
    int retval;
    srb_long_t argv[MAXFMGRARGS];
    ClOut clOut;
    int clOutVal;
 
    argv[0] = catalog;
    argv[1] = queryInfo;
    argv[2] = rowsWanted;

    if ((buflen = getSqlResultLen (MAX_DCS_NUM, rowsWanted)) <= 0)
        return CLI_ERR_MALLOC;

    buf = malloc (buflen);
    if (buf == NULL)
        return CLI_ERR_MALLOC;

    clOut.retval = (char *) buf;

    retval = clCall (conn, F_BULK_QUERY_ANSWER, argv, &clOut);

    if (retval < 0 || rowsWanted == 0 ) {
        free (buf);
        return retval;
    }

    strToSqlResult (buf, myresult);

    free (buf);

    if (myresult->result_count > 0)
        return 0;       /* success */
    else
        return CLI_ERR_RETURN_LEN;
}

/***********************************************************************/
/***********************************************************************/
7. src/back/srbObjFunct.c
	code the server call 
	code the _server call (and its attendant functions)


struct varlena *
svrBulkQueryAnswer (int catType, 
		    struct varlena *vQueryInfo,
		    int rowsWanted)
{
    struct varlena *retval;
    int status;
    char *queryInfo;
    mdasC_sql_result_struct  *myresult = NULL;

    queryInfo = varToStr (vQueryInfo);

    status = _svrBulkQueryAnswer (catType, queryInfo, &myresult, rowsWanted);

    if (status == 0) {
        retval = sqlResultToVar (myresult, MULTI_ROW);
        freeSqlResult (myresult);
    } else {
	elog (NOTICE, "svrBulkQueryAnswer:  failed. Status = %d",
	  status);
        retval = (struct varlena *)malloc(VAROUTHDRSZ);
        VARSIZE(retval) = VAROUTHDRSZ;
        VAROUTSTAT(retval) = htonl (status);
        if (myresult != NULL)
            free (myresult);
    }

    return retval;
}



int
_svrBulkQueryAnswer (int catType, 
		 int queryInfo, 
		 mdasC_sql_result_struct **myresult,
		 int rowsWanted)
{
    int status;
    char *mcatHostHint;
    int remoteFlag;
    struct hostElement  *hostTabPtr;


    remoteFlag = getMdasEnabledHost (NULL,  &hostTabPtr);

    if (remoteFlag < 0) {
        status = remoteFlag;
    } else if (remoteFlag == LOCAL_HOST) {      /* Can talk to mdas */
#ifdef SRB_MDAS
        status = get_bulk_query_answers(catType, queryInfo,
					myresult, rowsWanted);
#endif
    } else {
        status = remoteBulkQueryAnswer (catType, queryInfo, myresult, 
					rowsWanted, hostTabPtr);
    }
    return (status);

}


/***********************************************************************/
/***********************************************************************/
8. back/distrib.c
        code the remote function call
              as per that added in src/include/distribExtern.h


int 
remoteBulkQueryAnswer (int catType, 
				  char *queryInfo,
				  mdasC_sql_result_struct **myresult, 
				  int rowsWanted, 
				  struct hostElement  *hostTabPtr)
{
    int status;

    if (remoteConnect (hostTabPtr) < 0) {
        return SYS_ERR_REMOTE_CONN;
    }
 
    /* Do a client call to the remote host */
 
    *myresult = (mdasC_sql_result_struct  *)
      malloc (sizeof (mdasC_sql_result_struct));

    memset (*myresult, 0, sizeof (mdasC_sql_result_struct));

    status = srbBulkQueryAnswer (hostTabPtr->conn, catType, queryInfo, 
      *myresult, rowsWanted);
 
    if (status < 0) {       /* Failure */
        elog (NOTICE, "Remote BulkQueryAnswer failed: %s",
          clErrorMessage(hostTabPtr->conn));
        free (*myresult);
        *myresult = NULL;
    }
 
    return status;
}


/***********************************************************************/
/***********************************************************************/