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