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