home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 July / Chip_1998-07_cd.bin / zkuste / JBuilder / JBuild / libs / disk1 / DATA.1 / udflib.c < prev    next >
C/C++ Source or Header  |  1996-10-16  |  11KB  |  452 lines

  1. /*====================================================================
  2.   File Name:    udflib.c
  3.   Description:
  4.   This module contains some user defined functions (UDF).  
  5.   The test suite for UDF will use udf.sql
  6.   to define UDF to the database using SQL statements.
  7. ====================================================================== */
  8.  
  9. #include <stdlib.h>
  10. #include <time.h>
  11. #include <string.h>
  12. #include <math.h>
  13. #include <ibase.h>
  14. #include "example.h"
  15.  
  16. #define BADVAL -9999L
  17. #define MYBUF_LEN 15        /* number of chars to get for */
  18.  
  19. typedef struct blob {
  20.     short    (*blob_get_segment) ();
  21.     void    *blob_handle;
  22.     long    blob_number_segments;
  23.     long    blob_max_segment;
  24.     long    blob_total_length;
  25.     void    (*blob_put_segment) ();
  26. } *BLOB;
  27.  
  28. time_t    time();
  29. char    *ctime();
  30.  
  31. /* variable to return values in.  Needs to be static so it doesn't go 
  32.    away as soon as the function invocation is finished */
  33.  
  34. char    buffer[256];
  35. char    buffer2[512];    /* for string concatenation */
  36. char    datebuf[12];    /* for date string */
  37.  
  38. long    r_long;
  39. double    r_double;
  40. float    r_float;
  41. short    r_short;
  42.  
  43. struct    tm *tbuf;
  44. long    time_sec;
  45.  
  46. ISC_QUAD newdate;
  47.  
  48.  
  49. /*===============================================================
  50.  fn_lower_c() - Puts its argument longo lower case, for C programs
  51.  Input is of VARCHAR, output is of CSTRING.
  52.  Not international or non-ascii friendly.
  53. ================================================================= */
  54. char* EXPORT fn_lower_c (ARG(char*, s))
  55. ARGLIST(char *s)            /* VARCHAR input */
  56. {
  57.     char *buf;
  58.     short length = 0;
  59.  
  60.     length = (short)*s;
  61.     s += 2;
  62.     buf = buffer;
  63.     while (*s)
  64.         if (*s >= 'A' && *s <= 'Z')
  65.             *buf++ = *s++ - 'A' + 'a';
  66.         else
  67.             *buf++ = *s++;
  68.  
  69.     *buf = '\0';
  70.     buffer [length] = '\0';
  71.  
  72.     return buffer;
  73. }
  74.  
  75. /*===============================================================
  76.  fn_strcat(s1, s2) - Returns concatenated string. 
  77.     s1 and s2 are varchar to get a length count
  78. ================================================================= */
  79.  
  80. char* EXPORT fn_strcat(ARG(char*, s1), ARG(char*, s2))
  81. ARGLIST(char *s1)
  82. ARGLIST(char *s2)
  83. {
  84.         short j = 0;
  85.     short length1, length2;
  86.     char *p;
  87.  
  88.     length1 = (short)*s1;
  89.     length2 = (short)*s2;
  90.  
  91.     s1 += 2;
  92.     s2 += 2;
  93.  
  94.     /* strip trailing blanks of s1 */
  95.     p = s1 + length1 - 1;
  96.     while (*p  && *p == ' ')
  97.         p--;
  98.     p++;
  99.     *p = '\0';
  100.  
  101.     p = buffer2;
  102.     while (*s1)
  103.         *p++ = *s1++;
  104.  
  105.     for (j = 0; j < length2; j++)
  106.         if (*s2)
  107.             *p++ = *s2++;
  108.  
  109.     *p = '\0';
  110.         return buffer2; 
  111. }
  112.  
  113. /*===============================================================
  114.  fn_substr(s, m, n) - Returns the substr starting m ending n in s. 
  115. ================================================================= */
  116. char* EXPORT fn_substr(ARG(char*, s), ARG(short*, m), ARG(short*, n))
  117. ARGLIST(char *s)
  118. ARGLIST(short *m)        /* starting position */
  119. ARGLIST(short *n)        /* ending position */
  120. {
  121.         short i = 0;
  122.     short j = 0;
  123.  
  124.         if (*m > *n || *m < 1 || *n < 1) return "Bad parameters in substring"; 
  125.  
  126.         while (*s && i++ < *m-1) /* skip */
  127.                 s++;
  128.  
  129.         while (*s && i++ <= *n)  /* copy */
  130.                 buffer[j++] = *s++;
  131.         buffer[j] = '\0';
  132.  
  133.         return buffer;
  134. }
  135.  
  136. /*===============================================================
  137.  fn_trim(s) - Returns string that has leading blanks trimmed. 
  138. ================================================================= */
  139. char* EXPORT fn_trim(ARG(char*, s))
  140. ARGLIST(char *s)
  141. {
  142.     short j = 0;
  143.  
  144.         while (*s == ' ')       /* skip leading blanks */
  145.                 s++;
  146.  
  147.         while (*s)        /* copy the rest */
  148.                 buffer[j++] = *s++;
  149.  
  150.         buffer[j] = '\0';
  151.  
  152.         return buffer;
  153. }
  154.  
  155. /*===============================================================
  156.  fn_trunc(s, m) - Returns the string truncated at position m; 
  157.  Input is of CSTRING, output is of VARCHAR.
  158. ================================================================= */
  159. char* EXPORT fn_trunc(ARG(char*, s), ARG(short*, m))
  160. ARGLIST(char *s)
  161. ARGLIST(short *m)
  162. {
  163.     short j = 2;    /* leave 1st 2 bytes for VARCHAR output */
  164.  
  165.     while (*s && j < *m + 2)    /* need to add 2 */
  166.         buffer[j++] = *s++;
  167.  
  168.     buffer[j] = '\0';
  169.  
  170.     buffer[0] = (unsigned short) strlen(s) + 2;
  171.     buffer[1] = ' ';    /* anything other than \0 */
  172.  
  173. /*
  174.     *((unsigned short *)buffer) = (unsigned short) (strlen(buffer) + 2);
  175. */
  176.  
  177.         return buffer;        /* VARCHAR output */
  178. }
  179.  
  180.  
  181. /* ==============================================================
  182.    fn_doy() return the nth day of the year, by value.
  183.    ============================================================== */
  184. long EXPORT fn_doy()
  185. {
  186.     char buf[4];    /* for day */
  187.     long i;
  188.  
  189.         time (&time_sec);
  190.         tbuf = localtime(&time_sec);
  191.  
  192.     i = strftime(buf, 4, "%j", tbuf);
  193.     return atoi (buf);
  194. }
  195.  
  196. /* ==============================================================
  197.    fn_moy() return the nth month of the year. e.g. 1,2,3,...12.
  198.    Return by reference.
  199.    ============================================================== */
  200. short* EXPORT fn_moy()
  201. {
  202.         time (&time_sec);
  203.         tbuf = localtime(&time_sec);
  204.     r_short = (short) tbuf->tm_mon + 1;
  205.  
  206.     return &r_short;
  207. }
  208.  
  209. /* ==============================================================
  210.    fn_dow() return the day of today. e.g., Monday, Friday. ...
  211.    ============================================================== */
  212. char* EXPORT fn_dow()
  213. {
  214.         time (&time_sec);
  215.         tbuf = localtime(&time_sec);
  216.  
  217.         switch (tbuf->tm_wday) {
  218.         case 1: return "Monday";
  219.         case 2: return "Tuesday";
  220.         case 3: return "Wednesday";
  221.         case 4: return "Thursday";
  222.         case 5: return "Friday";
  223.         case 6: return "Saturday";
  224.         case 7: return "Sunday";
  225.         default: return "Error in Date";
  226.         }
  227. }
  228.  
  229. /*===============================================================
  230.  fn_sysdate() - Returns the system date in the "MMM-DD-YYYY" format.
  231. ================================================================= */
  232. char* EXPORT fn_sysdate()
  233. {
  234.         short len, i, j = 0;
  235.  
  236.         char *time_str;
  237.  
  238.         time (&time_sec);
  239.         time_str = ctime (&time_sec);
  240.         len = strlen(time_str);
  241.  
  242.         for (i = 4; i <= 10; i++) {
  243.                 if (*(time_str + i) != ' ')
  244.                         datebuf[j++] = *(time_str+i);
  245.                 else if (i == 7 || i == 10)
  246.                         datebuf[j++] = '-';
  247.                 else
  248.                         datebuf[j++] = '0';
  249.         }
  250.         for (i = 20; i < len-1 ; i++)
  251.                 datebuf[j++] = *(time_str+i);
  252.  
  253.         datebuf[j] = '\0';
  254.         return datebuf;
  255. }
  256.  
  257.  
  258.  
  259. /* ==============================================
  260.   fn_add2 (a, b) - returns a + b
  261.   =============================================== */
  262.  
  263. long EXPORT fn_add2 (ARG(long*, a), ARG(long*, b))
  264. ARGLIST(long *a)
  265. ARGLIST(long *b)
  266. {
  267.     return (*a + *b);
  268. }
  269.  
  270.  
  271. /* ==================================================
  272.   fn_mul (a, b) - returns a * b
  273.  =================================================== */
  274.  
  275. double EXPORT fn_mul (ARG(double*, a), ARG(double*, b))
  276. ARGLIST(double *a)
  277. ARGLIST(double *b)
  278. {
  279.     return (*a * *b);
  280. }
  281.  
  282.  
  283. /* ==============================================
  284.   fn_fact (n) - return factorial of n
  285.  ================================================ */
  286.  
  287. double EXPORT fn_fact (ARG(double*, n))
  288. ARGLIST(double *n)
  289. {
  290.     double k;
  291.  
  292.     if (*n > 100) return BADVAL;
  293.         if (*n < 0) return BADVAL;   
  294.  
  295.         if (*n == 0) return 1L;
  296.  
  297.         else {
  298.         k = *n - 1L;
  299.         return (*n * fn_fact(&k));
  300.     }
  301. }
  302.  
  303. /*===============================================================
  304.  fn_abs() - returns the absolute value of its argument.
  305. ================================================================= */
  306. double EXPORT fn_abs(ARG(double*, x))
  307. ARGLIST(double    *x)
  308. {
  309.     return (*x < 0.0) ? -*x : *x;
  310. }
  311.  
  312.  
  313. /*===============================================================
  314.  fn_max() - Returns the greater of its two arguments
  315. ================================================================ */
  316. double EXPORT fn_max(ARG(double*, a), ARG(double*, b))
  317. ARGLIST(double    *a)
  318. ARGLIST(double    *b)
  319. {      
  320.     return  (*a > *b) ? *a : *b;
  321. }
  322.  
  323.  
  324.  
  325. /*===============================================================
  326.  fn_sqrt() - Returns square root of n
  327. ================================================================ */
  328. double* EXPORT fn_sqrt(ARG(double*, n))
  329. ARGLIST(double *n)
  330. {
  331.     r_double = sqrt(*n);
  332.     return &r_double;
  333.  
  334.  
  335.  
  336.  
  337. /*=============================================================
  338.  fn_blob_linecount() returns the number of lines in a blob 
  339.   =============================================================*/
  340.  
  341. long EXPORT fn_blob_linecount (ARG(BLOB, b))
  342. ARGLIST(BLOB b)
  343. {
  344.         char *buf, *p;
  345.     short length, actual_length;
  346.  
  347.     /* Null values */
  348.     if (!b->blob_handle)
  349.         return 0L;
  350.  
  351.     length = b->blob_max_segment + 1L;
  352.     buf = (char *) malloc (length); 
  353.  
  354.     r_long = 0;
  355.         while ((*b->blob_get_segment) (b->blob_handle, buf, length, &actual_length)) 
  356.         {
  357.         buf [actual_length] = 0;
  358.         p = buf;
  359.                 while (*p)  
  360.             if (*p++  == '\n')
  361.                 r_long++;
  362.         }
  363.  
  364.         free (buf); 
  365.         return r_long;  
  366. }
  367.  
  368. /*=============================================================
  369.  fn_blob_bytecount() returns the number of bytes in a blob 
  370.  do not count newlines, so get rid of the newlines. 
  371.  ==============================================================*/
  372.  
  373. long EXPORT fn_blob_bytecount (ARG(BLOB, b))
  374. ARGLIST(BLOB b)
  375. {
  376.     /* Null values */
  377.     if (!b->blob_handle)
  378.         return 0L;
  379.  
  380.         return (b->blob_total_length - fn_blob_linecount(b));  
  381. }
  382.  
  383.  
  384.  
  385. /*=============================================================
  386.  fn_substr_blob() returns portion of TEXT blob beginning at m th
  387.  character and ended at n th character. 
  388.  Newlines are eliminated to make for better printing.
  389.   =============================================================*/
  390.  
  391. char* EXPORT fn_blob_substr(ARG(BLOB, b), ARG(long*, m), ARG(long*, n))
  392. ARGLIST(BLOB b)
  393. ARGLIST(long *m)
  394. ARGLIST(long *n)
  395. {
  396.     char *buf, *p, *q;
  397.     long i = 0;
  398.     long curr_bytecount = 0;
  399.         long begin, end; 
  400.     short length, actual_length;
  401.  
  402.     if (!b->blob_handle)
  403.         return "<null>";
  404.     length = b->blob_max_segment + 1L;
  405.     buf = (char *) malloc (length); 
  406.  
  407.  
  408.         if (*m > *n || *m < 1L || *n < 1L) 
  409.         return "";
  410.     if (b->blob_total_length < (long)*m) 
  411.         return "";
  412.  
  413.     begin = *m;                /* beginning position */
  414.  
  415.     if (b->blob_total_length < (long)*n) 
  416.         end = b->blob_total_length;    /* ending position */
  417.     else
  418.         end = *n;
  419.  
  420.     /* Limit the return string to 255 bytes */
  421.     if (end - begin + 1L > 255L)
  422.         end = begin + 254L;
  423.     q = buffer;
  424.  
  425.         while ((*b->blob_get_segment) (b->blob_handle, buf, length, 
  426.         &actual_length))
  427.         {    
  428.         buf [actual_length] = 0;
  429.  
  430.         p = buf;
  431.         while (*p && (curr_bytecount <= end))
  432.             {
  433.             curr_bytecount++;
  434.             if (*p == '\n')
  435.                 *p = ' ';
  436.             if (curr_bytecount >= begin)
  437.                 *q++ = *p;
  438.             p++;
  439.             }
  440.         if (curr_bytecount >= end) 
  441.             {
  442.             *q = 0;
  443.             break;
  444.             }
  445.         }
  446.  
  447.     free (buf);
  448.         return buffer;
  449. }
  450.  
  451.