Adding source code to the templates generated by BladeSmith

About this task

You must implement the following functions for the RowCircle DataBlade® module, which you can see in Visual C++ under the Globals node in the Class view:
  • rciDistance()
  • rciContains()

These functions are all in the udr.c file. Do not modify the other generated functions that begin with a Gen_ prefix.

To implement the rciDistance() and rciContains() functions:

Procedure

  1. Double-click rciDistance() in the Class view and scroll to the beginning of the udr.c file.
  2. Add the following statement to the #include statements to include the C math library:
    #include <math.h>

    Because the rciContains() function calls the rciDistance() function, you must have a definition of the rciDistance() function in the udr.c file before the code for the rciContains() function.

  3. Add the following rciDistance() function prototype directly after the #include statements in udr.c:
    UDREXPORT mi_double_precision *rciDistance 
     (
      MI_ROW      * point1,
      MI_ROW      * point2,
      MI_FPARAM   * Gen_fparam
      );
  4. Implement the rciDistance() function:
    1. Following the comment containing Your_Code ... BEGIN, find the comment that begins with TO DO: Remove this comment. Remove the comment and the mi_db_error_raise() statement and replace them with the following code:
      {
      MI_DATUM x1, y1;
      MI_DATUM x2, y2;
      mi_integer retlen, retval;
      /* Fetch values from rows */
      retval = mi_value(point1, 0, &x1, &retlen);
      retval = mi_value(point1, 1, &y1, &retlen);
      retval = mi_value(point2, 0, &x2, &retlen);
      retval = mi_value(point2, 1, &y2, &retlen); 

      The elements of the rciPoint row data type, the x- and y-coordinates of a point, are extracted by using the mi_value() statement and are stored in variables of type MI_DATUM. See the Informix® DataBlade API Programmer's Guide for information about handling data in row types.

    2. Look at the mi_alloc() statement that follows the code you entered. BladeSmith generates this mi_alloc() statement to take care of memory allocation for the return value of the function, Gen_RetVal:
      Gen_RetVal = 
          (mi_double_precision *)mi_alloc( sizeof( mi_double_precision ));
    3. Find the comment TO DO: Compute and store your value into Gen_RetVal. Add the following code after it:
      *Gen_RetVal = 
            sqrt((*(mi_double_precision *)x1 - *(mi_double_precision *)x2) * 
            (*(mi_double_precision *)x1 - *(mi_double_precision *)x2) +     
            (*(mi_double_precision *)y1 - *(mi_double_precision *)y2) *     
            (*(mi_double_precision *)y1 - *(mi_double_precision *)y2));      
      }

      This statement calculates the distance between two points by using the Pythagorean formula.

      The coordinates of each of the two points are cast from MI_DATUM to mi_double_precision values for the calculation.

  5. Implement the rciContains() function by replacing the code between the comment containing Your_Code ... BEGIN and the comment containing Your_Code ... END with the following code fragment:
    {  
      mi_double_precision * dist;      
      mi_integer retlen;       
      MI_DATUM center, radius;          
         
      /* 
      ** Fetch values from rows        
      */        
      mi_value( circle, 0, &center, &retlen );    
      mi_value( circle, 1, &radius, &retlen );    
    
      /* 
      ** Computes the distance between         
      ** the center of the circle and        
      ** the point.        
      */        
      dist = rciDistance( point, center, Gen_fparam );   
    
      /* Is the distance within the radius? */       
      if ((*dist - *(mi_double_precision *)radius) <= 0)       
       {        
          Gen_RetVal = 1;     
       }     
      else      
       {       
          Gen_RetVal = 0;    
       } 
     } 

    BladeSmith makes the return value an mi_integer type, which is the closest available C data type to the SQL Boolean return type you defined. This mismatch between the C and SQL type systems is known as impedance. The C code in user-defined routines must map the arguments of the routine and return values between the two type systems.

    The elements of the rciCircle row data type, the radius and center of a circle, are extracted by using the mi_value() statement and are stored in variables of type MI_DATUM. See the Informix DataBlade API Programmer's Guide for information about handling row types in C.

    To determine whether the point is contained within the circle, the rciContains() function first uses the rciDistance() function to calculate the distance between the center of the circle and the point. Then the rciContains() function subtracts the radius from the distance. If the result is negative, the point is contained by the circle; if the result is positive, the point is outside the circle.

    In the subtraction, the radius is cast from an MI_DATUM type to an mi_double_precision type.

  6. Check your source code against the final version of udr.c.
  7. Save the changes to udr.c.