mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-17 00:35:55 +01:00
471 lines
11 KiB
C
471 lines
11 KiB
C
/*====================================================================
|
|
File Name: udflib.c
|
|
Description:
|
|
This module contains some user defined functions (UDF).
|
|
The test suite for UDF will use udf.sql
|
|
to define UDF to the database using SQL statements.
|
|
* The contents of this file are subject to the Interbase Public
|
|
* License Version 1.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy
|
|
* of the License at http://www.Inprise.com/IPL.html
|
|
*
|
|
* Software distributed under the License is distributed on an
|
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
|
* or implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code was created by Inprise Corporation
|
|
* and its predecessors. Portions created by Inprise Corporation are
|
|
* Copyright (C) Inprise Corporation.
|
|
*
|
|
* All Rights Reserved.
|
|
* Contributor(s): ______________________________________.
|
|
====================================================================== */
|
|
|
|
#include <stdlib.h>
|
|
#if TIME_WITH_SYS_TIME
|
|
# include <sys/time.h>
|
|
# include <time.h>
|
|
#else
|
|
# if HAVE_SYS_TIME_H
|
|
# include <sys/time.h>
|
|
# else
|
|
# include <time.h>
|
|
# endif
|
|
#endif
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include <ibase.h>
|
|
#include "example.h"
|
|
#include "ib_util.h"
|
|
|
|
#define BADVAL -9999L
|
|
#define MYBUF_LEN 15 /* number of chars to get for */
|
|
|
|
typedef struct blob {
|
|
short (*blob_get_segment) ();
|
|
void *blob_handle;
|
|
int blob_number_segments;
|
|
int blob_max_segment;
|
|
int blob_total_length;
|
|
void (*blob_put_segment) ();
|
|
} *BLOB;
|
|
|
|
time_t time();
|
|
char *ctime();
|
|
|
|
/* variable to return values in. Needs to be static so it doesn't go
|
|
away as soon as the function invocation is finished */
|
|
|
|
char buffer[256];
|
|
char buffer2[512]; /* for string concatenation */
|
|
char datebuf[12]; /* for date string */
|
|
|
|
int r_long;
|
|
double r_double;
|
|
float r_float;
|
|
short r_short;
|
|
|
|
struct tm *tbuf;
|
|
int time_sec;
|
|
|
|
ISC_QUAD newdate;
|
|
|
|
|
|
/*===============================================================
|
|
fn_lower_c() - Puts its argument longo lower case, for C programs
|
|
Input is of VARCHAR, output is of CSTRING.
|
|
Not international or non-ascii friendly.
|
|
================================================================= */
|
|
char* EXPORT fn_lower_c(char* s) /* VARCHAR input */
|
|
{
|
|
char *buf;
|
|
short length = 0;
|
|
|
|
char *buffer = (char *)ib_util_malloc(256);
|
|
|
|
length = (short)*s;
|
|
s += 2;
|
|
buf = buffer;
|
|
while (*s)
|
|
if (*s >= 'A' && *s <= 'Z')
|
|
*buf++ = *s++ - 'A' + 'a';
|
|
else
|
|
*buf++ = *s++;
|
|
|
|
*buf = '\0';
|
|
buffer [length] = '\0';
|
|
|
|
return buffer;
|
|
}
|
|
|
|
/*===============================================================
|
|
fn_strcat(s1, s2) - Returns concatenated string.
|
|
s1 and s2 are varchar to get a length count
|
|
================================================================= */
|
|
|
|
char* EXPORT fn_strcat(char* s1, char* s2)
|
|
{
|
|
short j = 0;
|
|
short length1, length2;
|
|
char *p;
|
|
|
|
char *buffer2 = (char *)ib_util_malloc(512);
|
|
|
|
length1 = (short)*s1;
|
|
length2 = (short)*s2;
|
|
|
|
s1 += 2;
|
|
s2 += 2;
|
|
|
|
/* strip trailing blanks of s1 */
|
|
p = s1 + length1 - 1;
|
|
while (*p && *p == ' ')
|
|
p--;
|
|
p++;
|
|
*p = '\0';
|
|
|
|
p = buffer2;
|
|
while (*s1)
|
|
*p++ = *s1++;
|
|
|
|
for (j = 0; j < length2; j++)
|
|
if (*s2)
|
|
*p++ = *s2++;
|
|
|
|
*p = '\0';
|
|
return buffer2;
|
|
}
|
|
|
|
/*===============================================================
|
|
fn_substr(s, m, n) - Returns the substr starting m ending n in s.
|
|
================================================================= */
|
|
char* EXPORT fn_substr(char* s,
|
|
short* m, /* starting position */
|
|
short* n) /* ending position */
|
|
{
|
|
short i = 0;
|
|
short j = 0;
|
|
|
|
char *buffer = (char *)ib_util_malloc(256);
|
|
|
|
if (*m > *n || *m < 1 || *n < 1) return "Bad parameters in substring";
|
|
|
|
while (*s && i++ < *m-1) /* skip */
|
|
s++;
|
|
|
|
while (*s && i++ <= *n) /* copy */
|
|
buffer[j++] = *s++;
|
|
buffer[j] = '\0';
|
|
|
|
return buffer;
|
|
}
|
|
|
|
/*===============================================================
|
|
fn_trim(s) - Returns string that has leading blanks trimmed.
|
|
================================================================= */
|
|
char* EXPORT fn_trim(char* s)
|
|
{
|
|
short j = 0;
|
|
|
|
char *buffer = (char *)ib_util_malloc(256);
|
|
|
|
while (*s == ' ') /* skip leading blanks */
|
|
s++;
|
|
|
|
while (*s) /* copy the rest */
|
|
buffer[j++] = *s++;
|
|
|
|
buffer[j] = '\0';
|
|
|
|
return buffer;
|
|
}
|
|
|
|
/*===============================================================
|
|
fn_trunc(s, m) - Returns the string truncated at position m;
|
|
Input is of CSTRING, output is of VARCHAR.
|
|
================================================================= */
|
|
char* EXPORT fn_trunc(char* s, short* m)
|
|
{
|
|
short j = 2; /* leave 1st 2 bytes for VARCHAR output */
|
|
|
|
char *buffer = (char *)ib_util_malloc(256);
|
|
|
|
while (*s && j < *m + 2) /* need to add 2 */
|
|
buffer[j++] = *s++;
|
|
|
|
buffer[j] = '\0';
|
|
|
|
buffer[0] = (unsigned short) strlen(s) + 2;
|
|
buffer[1] = ' '; /* anything other than \0 */
|
|
|
|
/*
|
|
*((unsigned short *)buffer) = (unsigned short) (strlen(buffer) + 2);
|
|
*/
|
|
|
|
return buffer; /* VARCHAR output */
|
|
}
|
|
|
|
|
|
/* ==============================================================
|
|
fn_doy() return the nth day of the year, by value.
|
|
============================================================== */
|
|
int EXPORT fn_doy()
|
|
{
|
|
char buf[4]; /* for day */
|
|
int i;
|
|
|
|
time (&time_sec);
|
|
tbuf = localtime(&time_sec);
|
|
|
|
i = strftime(buf, 4, "%j", tbuf);
|
|
return atoi (buf);
|
|
}
|
|
|
|
/* ==============================================================
|
|
fn_moy() return the nth month of the year. e.g. 1,2,3,...12.
|
|
Return by reference.
|
|
============================================================== */
|
|
short* EXPORT fn_moy()
|
|
{
|
|
time (&time_sec);
|
|
tbuf = localtime(&time_sec);
|
|
r_short = (short) tbuf->tm_mon + 1;
|
|
|
|
return &r_short;
|
|
}
|
|
|
|
/* ==============================================================
|
|
fn_dow() return the day of today. e.g., Monday, Friday. ...
|
|
============================================================== */
|
|
char* EXPORT fn_dow()
|
|
{
|
|
time (&time_sec);
|
|
tbuf = localtime(&time_sec);
|
|
|
|
switch (tbuf->tm_wday) {
|
|
case 1: return "Monday";
|
|
case 2: return "Tuesday";
|
|
case 3: return "Wednesday";
|
|
case 4: return "Thursday";
|
|
case 5: return "Friday";
|
|
case 6: return "Saturday";
|
|
case 7: return "Sunday";
|
|
default: return "Error in Date";
|
|
}
|
|
}
|
|
|
|
/*===============================================================
|
|
fn_sysdate() - Returns the system date in the "MMM-DD-YYYY" format.
|
|
================================================================= */
|
|
char* EXPORT fn_sysdate()
|
|
{
|
|
short len, i, j = 0;
|
|
|
|
char *time_str;
|
|
|
|
char *datebuf = (char *)ib_util_malloc(12);
|
|
|
|
time (&time_sec);
|
|
time_str = ctime (&time_sec);
|
|
len = strlen(time_str);
|
|
|
|
for (i = 4; i <= 10; i++) {
|
|
if (*(time_str + i) != ' ')
|
|
datebuf[j++] = *(time_str+i);
|
|
else if (i == 7 || i == 10)
|
|
datebuf[j++] = '-';
|
|
else
|
|
datebuf[j++] = '0';
|
|
}
|
|
for (i = 20; i < len-1 ; i++)
|
|
datebuf[j++] = *(time_str+i);
|
|
|
|
datebuf[j] = '\0';
|
|
return datebuf;
|
|
}
|
|
|
|
|
|
|
|
/* ==============================================
|
|
fn_add2 (a, b) - returns a + b
|
|
=============================================== */
|
|
|
|
int EXPORT fn_add2(int* a, int* b)
|
|
{
|
|
return (*a + *b);
|
|
}
|
|
|
|
|
|
/* ==================================================
|
|
fn_mul (a, b) - returns a * b
|
|
=================================================== */
|
|
|
|
double EXPORT fn_mul(double* a, double* b)
|
|
{
|
|
return (*a * *b);
|
|
}
|
|
|
|
|
|
/* ==============================================
|
|
fn_fact (n) - return factorial of n
|
|
================================================ */
|
|
|
|
double EXPORT fn_fact(double* n)
|
|
{
|
|
double k;
|
|
|
|
if (*n > 100) return BADVAL;
|
|
if (*n < 0) return BADVAL;
|
|
|
|
if (*n == 0) return 1L;
|
|
|
|
else {
|
|
k = *n - 1L;
|
|
return (*n * fn_fact(&k));
|
|
}
|
|
}
|
|
|
|
/*===============================================================
|
|
fn_abs() - returns the absolute value of its argument.
|
|
================================================================= */
|
|
double EXPORT fn_abs(double* x)
|
|
{
|
|
return (*x < 0.0) ? -*x : *x;
|
|
}
|
|
|
|
|
|
/*===============================================================
|
|
fn_max() - Returns the greater of its two arguments
|
|
================================================================ */
|
|
double EXPORT fn_max(double* a, double* b)
|
|
{
|
|
return (*a > *b) ? *a : *b;
|
|
}
|
|
|
|
|
|
|
|
/*===============================================================
|
|
fn_sqrt() - Returns square root of n
|
|
================================================================ */
|
|
double* EXPORT fn_sqrt(double* n)
|
|
{
|
|
r_double = sqrt(*n);
|
|
return &r_double;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*=============================================================
|
|
fn_blob_linecount() returns the number of lines in a blob
|
|
=============================================================*/
|
|
|
|
int EXPORT fn_blob_linecount(BLOB b)
|
|
{
|
|
char *buf, *p;
|
|
short length, actual_length;
|
|
|
|
/* Null values */
|
|
if (!b->blob_handle)
|
|
return 0L;
|
|
|
|
length = b->blob_max_segment + 1L;
|
|
buf = (char *) malloc (length);
|
|
|
|
r_long = 0;
|
|
while ((*b->blob_get_segment) (b->blob_handle, buf, length, &actual_length))
|
|
{
|
|
buf [actual_length] = 0;
|
|
p = buf;
|
|
while (*p)
|
|
if (*p++ == '\n')
|
|
r_long++;
|
|
}
|
|
|
|
free (buf);
|
|
return r_long;
|
|
}
|
|
|
|
/*=============================================================
|
|
fn_blob_bytecount() returns the number of bytes in a blob
|
|
do not count newlines, so get rid of the newlines.
|
|
==============================================================*/
|
|
|
|
int EXPORT fn_blob_bytecount(BLOB b)
|
|
{
|
|
/* Null values */
|
|
if (!b->blob_handle)
|
|
return 0L;
|
|
|
|
return (b->blob_total_length - fn_blob_linecount(b));
|
|
}
|
|
|
|
|
|
|
|
/*=============================================================
|
|
fn_substr_blob() returns portion of TEXT blob beginning at m th
|
|
character and ended at n th character.
|
|
Newlines are eliminated to make for better printing.
|
|
=============================================================*/
|
|
|
|
char* EXPORT fn_blob_substr(BLOB b, int* m, int* n)
|
|
{
|
|
char *buf, *p, *q;
|
|
int i = 0;
|
|
int curr_bytecount = 0;
|
|
int begin, end;
|
|
short length, actual_length;
|
|
|
|
char *buffer = (char *)malloc(256);
|
|
|
|
if (!b->blob_handle)
|
|
return "<null>";
|
|
length = b->blob_max_segment + 1L;
|
|
buf = (char *) malloc (length);
|
|
|
|
|
|
if (*m > *n || *m < 1L || *n < 1L)
|
|
return "";
|
|
if (b->blob_total_length < (int)*m)
|
|
return "";
|
|
|
|
begin = *m; /* beginning position */
|
|
|
|
if (b->blob_total_length < (int)*n)
|
|
end = b->blob_total_length; /* ending position */
|
|
else
|
|
end = *n;
|
|
|
|
/* Limit the return string to 255 bytes */
|
|
if (end - begin + 1L > 255L)
|
|
end = begin + 254L;
|
|
q = buffer;
|
|
|
|
while ((*b->blob_get_segment) (b->blob_handle, buf, length,
|
|
&actual_length))
|
|
{
|
|
buf [actual_length] = 0;
|
|
|
|
p = buf;
|
|
while (*p && (curr_bytecount <= end))
|
|
{
|
|
curr_bytecount++;
|
|
if (*p == '\n')
|
|
*p = ' ';
|
|
if (curr_bytecount >= begin)
|
|
*q++ = *p;
|
|
p++;
|
|
}
|
|
if (curr_bytecount >= end)
|
|
{
|
|
*q = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
free (buf);
|
|
return buffer;
|
|
}
|
|
|