8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 22:03:03 +01:00

Ported code changes from fb1

This commit is contained in:
skywalker 2002-06-29 16:35:19 +00:00
parent 1a2e4d0cfb
commit 6eaa5d6ef9
10 changed files with 1357 additions and 0 deletions

View File

@ -0,0 +1,37 @@
========================================================================
DYNAMIC LINK LIBRARY : fbudf
========================================================================
AppWizard has created this fbudf DLL for you.
This file contains a summary of what you will find in each of the files that
make up your fbudf application.
fbudf.dsp
This file (the project file) contains information at the project level and
is used to build a single project or subproject. Other users can share the
project (.dsp) file, but they should export the makefiles locally.
fbudf.cpp
This is the main DLL source file.
fbudf.h
This file contains your DLL exports.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named fbudf.pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////

663
src/extlib/fbudf/fbudf.cpp Normal file
View File

@ -0,0 +1,663 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's 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.ibphoenix.com/idpl.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 Claudio Valderama C. for IBPhoenix.
* The development of the Original Code was sponsored by Craig Leonardi.
*
* Copyright (c) 2001 IBPhoenix
* All Rights Reserved.
*
* 2002.01.07 Claudio Valderrama: change the impolite way truncate and round work,
* make null handling more consistent and add dpower(x,y).
* Beware the SQL declaration for those functions has changed.
* 2002.01.20 Claudio Valderrama: addMonth should work with negative values, too.
*/
// fbudf.cpp : Defines the entry point for the DLL application.
//
/*
CVC: The MS way of doing things puts the includes in stdafx. I expect
that you can continue this trend without problems on other compilers
or platforms. Since I conditioned the Windows-related includes, it should
be easy to add needed headers to stdafx.h after a makefile is built.
*/
#include "stdafx.h"
#define FBUDF_EXPORTS
#include "fbudf.h"
//Original code for this library was written by Claudio Valderrama
// on July 2001 for IBPhoenix.
// Define this symbol if you want truncate and round to be symmetric wr to zero.
//#define SYMMETRIC_MATH
#if defined (_WIN32)
/*
BOOL APIENTRY DllMain( HANDLE ,//hModule,
DWORD ul_reason_for_call,
LPVOID //lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
*/
#endif
const long seconds_in_day = 86400;
const long tenthmsec_in_day = seconds_in_day * ISC_TIME_SECONDS_PRECISION;
const short varchar_indicator = sizeof(unsigned short);
// This function shouldn't be defined in production.
FBUDF_API paramdsc* testreflect(paramdsc* rc)
{
rc->dsc_address = 0;
rc->dsc_flags = 1 | 4; //DSC_null | DSC_nullable;
return rc;
}
namespace internal
{
// This definition comes from jrd\val.h and is equivalent to helper
// functions {get/set}_varchar_len defined below.
typedef struct vvary {
unsigned short vary_length;
unsigned char vary_string [1];
} VVARY;
/*
inline short get_varchar_len(char* vchar)
{
return static_cast<short>((static_cast<short>(vchar[1]) << 8) + vchar[0]);
}
*/
inline short get_varchar_len(unsigned char* vchar)
{
return static_cast<short>((static_cast<short>(vchar[1]) << 8) + vchar[0]);
}
inline void set_varchar_len(char* vchar, short len)
{
vchar[1] = static_cast<char>(len >> 8);
vchar[0] = static_cast<char>(len);
}
inline void set_varchar_len(unsigned char* vchar, short len)
{
vchar[1] = static_cast<unsigned char>(len >> 8);
vchar[0] = static_cast<unsigned char>(len);
}
short get_int_type(const paramdsc* v, ISC_INT64& rc)
{
short s = -1;
switch(v->dsc_dtype)
{
case dtype_short:
rc = *reinterpret_cast<short*>(v->dsc_address);
s = sizeof(short);
break;
case dtype_long:
rc = *reinterpret_cast<ISC_LONG*>(v->dsc_address);
s = sizeof(ISC_LONG);
break;
case dtype_int64:
rc = *reinterpret_cast<ISC_INT64*>(v->dsc_address);
s = sizeof(ISC_INT64);
break;
default:
break;
}
return s;
}
void set_int_type(paramdsc* v, const ISC_INT64 iv)
{
switch(v->dsc_dtype)
{
case dtype_short:
*reinterpret_cast<short*>(v->dsc_address) = static_cast<short>(iv);
break;
case dtype_long:
*reinterpret_cast<ISC_LONG*>(v->dsc_address) = static_cast<ISC_LONG>(iv);
break;
case dtype_int64:
*reinterpret_cast<ISC_INT64*>(v->dsc_address) = iv;
break;
}
}
short get_double_type(const paramdsc* v, double& rc)
{
short s = -1;
switch(v->dsc_dtype)
{
case dtype_real:
rc = static_cast<double>(*reinterpret_cast<float*>(v->dsc_address));
s = sizeof(float);
break;
case dtype_double:
rc = *reinterpret_cast<double*>(v->dsc_address);
s = sizeof(double);
break;
default:
break;
}
return s;
}
void set_double_type(paramdsc* v, const double iv)
{
switch(v->dsc_dtype)
{
case dtype_real:
*reinterpret_cast<float*>(v->dsc_address) = static_cast<float>(iv);
break;
case dtype_double:
*reinterpret_cast<double*>(v->dsc_address) = iv;
break;
}
}
short get_string_type(const paramdsc* v, unsigned char*& text)
{
short len = v->dsc_length;
switch(v->dsc_dtype)
{
case dtype_text:
text = v->dsc_address;
break;
case dtype_cstring:
text = v->dsc_address;
if (len && text)
{
unsigned char* p = text; //strlen(v->dsc_address);
while (*p) ++p; // couldn't use strlen!
if (p - text < len)
len = static_cast<short>(p - text);
}
break;
case dtype_varying:
len -= varchar_indicator;
text = reinterpret_cast<vvary*>(v->dsc_address)->vary_string;
{
short x = get_varchar_len(v->dsc_address);
if (x < len)
len = x;
}
break;
default:
len = -1;
break;
}
return len;
}
void set_string_type(paramdsc* v, const short len, unsigned char* text = 0)
{
switch(v->dsc_dtype)
{
case dtype_text:
v->dsc_length = len;
if (text)
memcpy(v->dsc_address, text, len);
break;
case dtype_cstring:
v->dsc_length = len;
if (text)
memcpy(v->dsc_address, text, len);
v->dsc_address[len] = 0;
break;
case dtype_varying:
v->dsc_length = static_cast<short>(len + varchar_indicator);
set_varchar_len(v->dsc_address, len);
if (text)
memcpy(v->dsc_address + varchar_indicator, text, len);
break;
}
}
bool isnull(const paramdsc* v)
{
return !v || !v->dsc_address || (v->dsc_flags & DSC_null);
}
paramdsc* setnull(paramdsc* v)
{
if (v)
v->dsc_flags |= DSC_null;
return v;
}
short get_scaled_double(const paramdsc* v, double& rc)
{
ISC_INT64 iv;
short rct = get_int_type(v, iv);
if (rct < 0)
rct = get_double_type(v, rc);
else
{
rc = static_cast<double>(iv);
signed char scale = v->dsc_scale;
for (; scale < 0; ++scale)
rc /= 10;
for (; scale > 0; --scale)
rc *= 10;
}
return rct;
}
} // namespace internal
FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2)
{
if (!internal::isnull(v))
return v;
return v2;
}
FBUDF_API paramdsc* sNvl(paramdsc* v, paramdsc* v2, paramdsc* rc)
{
if (!internal::isnull(v))
{
unsigned char *sv = 0;
short len = internal::get_string_type(v, sv);
internal::set_string_type(rc, len, sv);
return rc;
}
if (!internal::isnull(v2))
{
unsigned char *sv2 = 0;
short len = internal::get_string_type(v2, sv2);
internal::set_string_type(rc, len, sv2);
return rc;
}
return internal::setnull(rc);
}
FBUDF_API paramdsc* iNullIf(paramdsc* v, paramdsc* v2)
{
if (internal::isnull(v) || internal::isnull(v2))
return 0;
ISC_INT64 iv, iv2;
short rc = internal::get_int_type(v, iv);
short rc2 = internal::get_int_type(v2, iv2);
if (rc < 0 || rc2 < 0)
return v;
if (iv == iv2 && v->dsc_scale == v2->dsc_scale)
return 0;
return v;
}
FBUDF_API paramdsc* dNullIf(paramdsc* v, paramdsc* v2)
{
if (internal::isnull(v) || internal::isnull(v2))
return 0;
double iv, iv2;
short rc = internal::get_double_type(v, iv);
short rc2 = internal::get_double_type(v2, iv2);
if (rc < 0 || rc2 < 0)
return v;
if (iv == iv2) // && v->dsc_scale == v2->dsc_scale) double w/o scale
return 0;
return v;
}
FBUDF_API paramdsc* sNullIf(paramdsc* v, paramdsc* v2, paramdsc* rc)
{
if (internal::isnull(v) || internal::isnull(v2))
return internal::setnull(rc);
unsigned char *sv, *sv2;
short len = internal::get_string_type(v, sv);
short len2 = internal::get_string_type(v2, sv2);
if (len < 0 || len2 < 0) // good luck with the result, we can't do more.
return v;
if (len == len2 && (!len || !memcmp(sv, sv2, len)) &&
(v->dsc_ttype == v2->dsc_ttype ||
!v->dsc_ttype || !v2->dsc_ttype))
return internal::setnull(rc);
internal::set_string_type(rc, len, sv);
return rc;
}
namespace internal
{
enum day_format {day_short, day_long};
const size_t day_len[] = {4, 14};
const char* day_fmtstr[] = {"%a", "%A"};
char* get_DOW(ISC_TIMESTAMP* v, char* rc, const day_format df)
{
tm times;
//ISC_TIMESTAMP timestamp;
//timestamp.timestamp_date = *v;
//timestamp.timestamp_time = 0;
//isc_decode_timestamp(&timestamp, &times);
isc_decode_timestamp(v, &times);
//isc_decode_sql_date(v, &times);
int dow = times.tm_wday;
if (dow >= 0 && dow <= 6)
{
size_t name_len = day_len[df];
const char* name_fmt = day_fmtstr[df];
if (!strcmp(setlocale(LC_TIME, NULL), "C"))
setlocale(LC_ALL, "");
name_len = strftime(rc + varchar_indicator, name_len, name_fmt, &times);
if (name_len)
{
// There's no clarity in the docs whether '\0' is counted or not; be safe.
char *p = rc + varchar_indicator + name_len - 1;
if (!*p)
--name_len;
set_varchar_len(rc, static_cast<short>(name_len));
return rc;
}
}
set_varchar_len(rc, 5);
memcpy(rc + varchar_indicator, "ERROR", 5);
return rc;
}
} // namespace internal
FBUDF_API char* DOW(ISC_TIMESTAMP* v, char* rc)
{
return internal::get_DOW(v, rc, internal::day_long);
}
FBUDF_API char* SDOW(ISC_TIMESTAMP* v, char* rc)
{
return internal::get_DOW(v, rc, internal::day_short);
}
FBUDF_API paramdsc* right(paramdsc* v, short* rl, paramdsc* rc)
{
if (internal::isnull(v))
return internal::setnull(rc);
unsigned char* text = 0;
short len = internal::get_string_type(v, text), diff = static_cast<short>(len - *rl);
if (*rl < len)
len = *rl;
if (len < 0)
return internal::setnull(rc);
if (diff > 0)
text += diff;
internal::set_string_type(rc, len, text);
return rc;
}
FBUDF_API ISC_TIMESTAMP* addDay(ISC_TIMESTAMP* v, int& ndays)
{
//tm times;
v->timestamp_date += ndays;
return v;
}
FBUDF_API ISC_TIMESTAMP* addWeek(ISC_TIMESTAMP* v, int& nweeks)
{
//tm times;
v->timestamp_date += nweeks * 7;
return v;
}
FBUDF_API ISC_TIMESTAMP* addMonth(ISC_TIMESTAMP* v, int& nmonths)
{
tm times;
isc_decode_timestamp(v, &times);
int y = nmonths / 12, m = nmonths % 12;
times.tm_year += y;
if ((times.tm_mon += m) > 11)
{
times.tm_year++;
times.tm_mon -= 12;
}
else if (times.tm_mon < 1)
{
times.tm_year--;
times.tm_mon += 12;
}
int md[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int ly = times.tm_year + 1900;
if (ly % 4 == 0 && ly % 100 != 0 || ly % 400 == 0)
md[1]++;
if (times.tm_mday > md[times.tm_mon])
times.tm_mday = md[times.tm_mon];
isc_encode_timestamp(&times, v);
return v;
}
FBUDF_API ISC_TIMESTAMP* addYear(ISC_TIMESTAMP* v, int& nyears)
{
tm times;
isc_decode_timestamp(v, &times);
times.tm_year += nyears;
isc_encode_timestamp(&times, v);
return v;
}
namespace internal
{
ISC_TIMESTAMP* addTenthMSec(ISC_TIMESTAMP* v, int tenthmilliseconds, int multiplier)
{
long full = tenthmilliseconds * multiplier;
long days = full / tenthmsec_in_day, secs = full % tenthmsec_in_day;
v->timestamp_date += days;
// Time portion is unsigned, so we avoid unsigned rolling over negative values
// that only produce a new unsigned number with the wrong result.
if (secs < 0 && static_cast<unsigned long>(-secs) > v->timestamp_time)
{
v->timestamp_date--;
v->timestamp_time += tenthmsec_in_day + secs;
}
else if ((v->timestamp_time += secs) >= tenthmsec_in_day)
{
v->timestamp_date++;
v->timestamp_time -= tenthmsec_in_day;
}
return v;
}
}
FBUDF_API ISC_TIMESTAMP* addMilliSecond(ISC_TIMESTAMP* v, int& nmseconds)
{
return internal::addTenthMSec(v, nmseconds, ISC_TIME_SECONDS_PRECISION / 1000);
}
FBUDF_API ISC_TIMESTAMP* addSecond(ISC_TIMESTAMP* v, int& nseconds)
{
return internal::addTenthMSec(v, nseconds, ISC_TIME_SECONDS_PRECISION);
}
FBUDF_API ISC_TIMESTAMP* addMinute(ISC_TIMESTAMP* v, int& nminutes)
{
return internal::addTenthMSec(v, nminutes, 60 * ISC_TIME_SECONDS_PRECISION);
}
FBUDF_API ISC_TIMESTAMP* addHour(ISC_TIMESTAMP* v, int& nhours)
{
return internal::addTenthMSec(v, nhours, 3600 * ISC_TIME_SECONDS_PRECISION);
}
FBUDF_API ISC_TIMESTAMP* getExactTimestamp(ISC_TIMESTAMP* rc)
{
//time_t now;
//time(&now);
#if defined(_WIN32)
_timeb timebuffer;
_ftime(&timebuffer);
// localtime uses thread local storage in NT, no need to lock threads.
// Of course, this facility is only available in multithreaded builds.
tm times = *localtime(&timebuffer.time);
isc_encode_timestamp(&times, rc);
rc->timestamp_time += timebuffer.millitm * 10;
#else
#ifdef HAVE_PTHREAD_H
pthread_mutex_t loctimelock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&loctimelock); // ctime critical section start
#endif
timeval tv;
gettimeofday(&tv, NULL);
tm times = *localtime(&tv.tv_sec);
#ifdef HAVE_PTHREAD_H
pthread_mutex_unlock(&loctimelock); // ctime critical section end
#endif
isc_encode_timestamp(&times, rc);
rc->timestamp_time += tv.tv_usec / 100;
#endif
return rc;
}
FBUDF_API paramdsc* truncate(paramdsc* v, paramdsc* rc)
{
if (internal::isnull(v))
return internal::setnull(rc);
ISC_INT64 iv;
short rct = internal::get_int_type(v, iv);
if (rct < 0 || v->dsc_scale > 0)
return internal::setnull(rc);
if (!v->dsc_scale /*|| !v->dsc_sub_type*/) //second test won't work with ODS9
{
internal::set_int_type(rc, iv);
rc->dsc_scale = 0;
return rc;
}
// truncate(0.9) => 0
// truncate(-0.9) => -1
// truncate(-0.9) => 0 ### SYMMETRIC_MATH defined.
signed char scale = v->dsc_scale;
#if defined(SYMMETRIC_MATH)
while (scale++ < 0)
iv /= 10;
#else
bool gt = false;
while (scale++ < 0)
{
if (iv % 10)
gt = true;
iv /= 10;
}
if (gt)
{
if (iv < 0)
--iv;
}
#endif
internal::set_int_type(rc, iv);
rc->dsc_scale = 0;
return rc;
}
FBUDF_API paramdsc* fbround(paramdsc* v, paramdsc* rc)
{
if (internal::isnull(v))
return internal::setnull(rc);
ISC_INT64 iv;
short rct = internal::get_int_type(v, iv);
if (rct < 0 || v->dsc_scale > 0)
return internal::setnull(rc);
if (!v->dsc_scale /*|| !v->dsc_sub_type*/) //second test won't work with ODS9
{
internal::set_int_type(rc, iv);
rc->dsc_scale = 0;
return rc;
}
// round(0.3) => 0 ### round(0.5) => 1
// round(-0.3) => 0 ### round(-0.5) => 0
// round(-0.3) => 0 ### round(-0.5) => -1 ### SYMMETRIC_MATH defined.
bool gt = false;
signed char scale = v->dsc_scale;
while(scale++ < 0)
{
if (!scale)
{
short dig = static_cast<short>(iv % 10);
#if defined(SYMMETRIC_MATH)
if (dig >= 5 || dig <= -5)
gt = true;
#else
if (dig >= 5 || dig < -5)
gt = true;
#endif
}
iv /= 10;
}
if (gt)
{
if (iv < 0)
--iv;
else ++iv;
}
internal::set_int_type(rc, iv);
rc->dsc_scale = 0;
return rc;
}
FBUDF_API paramdsc* power(paramdsc* v, paramdsc* v2, paramdsc* rc)
{
if (internal::isnull(v) || internal::isnull(v2))
return internal::setnull(rc);
double d, d2;
short rct = internal::get_scaled_double(v, d);
short rct2 = internal::get_scaled_double(v2, d2);
// If we cause a div by zero, SS shutdowns in response.
// The doc I read says 0^0 will produce 1, so it's not tested below.
if (rct < 0 || rct2 < 0 || !d && d2 < 0)
return internal::setnull(rc);
internal::set_double_type(rc, pow(d, d2));
rc->dsc_scale = 0;
return rc;
}
FBUDF_API blobcallback* string2blob(paramdsc* v, blobcallback* outblob)
{
if (internal::isnull(v))
return 0;
unsigned char* text = 0;
short len = internal::get_string_type(v, text);
if (len < 0)
return 0;
if (!outblob || !outblob->blob_handle)
return 0;
outblob->blob_put_segment(outblob->blob_handle, text, len);
return outblob;
}

165
src/extlib/fbudf/fbudf.dsp Normal file
View File

@ -0,0 +1,165 @@
# Microsoft Developer Studio Project File - Name="fbudf" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=fbudf - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "fbudf.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "fbudf.mak" CFG="fbudf - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "fbudf - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "fbudf - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "fbudf - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FBUDF_EXPORTS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "H:\ibdev\fbbuild\interbase\interbase\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FBUDF_EXPORTS" /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x340a /d "NDEBUG"
# ADD RSC /l 0x340a /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 GDS32_MS.LIB /nologo /dll /machine:I386 /libpath:"H:\ibdev\fbbuild\interbase\interbase\lib"
# SUBTRACT LINK32 /nodefaultlib
!ELSEIF "$(CFG)" == "fbudf - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FBUDF_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MDd /W4 /Gm /GX /ZI /Od /I "H:\ibdev\fbbuild\interbase\interbase\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FBUDF_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x340a /d "_DEBUG"
# ADD RSC /l 0x340a /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 GDS32_MS.LIB /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"H:\ibdev\fbbuild\interbase\interbase\lib"
# SUBTRACT LINK32 /nodefaultlib
!ENDIF
# Begin Target
# Name "fbudf - Win32 Release"
# Name "fbudf - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\fbudf.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\fbudf.h
# End Source File
# Begin Source File
SOURCE=..\..\ibdev\fbbuild\interbase\jrd\ibase.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# Begin Source File
SOURCE=.\fbudf.sql
!IF "$(CFG)" == "fbudf - Win32 Release"
!ELSEIF "$(CFG)" == "fbudf - Win32 Debug"
# PROP Exclude_From_Build 1
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\fbudf.txt
!IF "$(CFG)" == "fbudf - Win32 Release"
!ELSEIF "$(CFG)" == "fbudf - Win32 Debug"
# PROP Exclude_From_Build 1
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\MSReadMe.txt
!IF "$(CFG)" == "fbudf - Win32 Release"
!ELSEIF "$(CFG)" == "fbudf - Win32 Debug"
# PROP Exclude_From_Build 1
!ENDIF
# End Source File
# End Target
# End Project

View File

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "fbudf"=.\fbudf.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

87
src/extlib/fbudf/fbudf.h Normal file
View File

@ -0,0 +1,87 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's 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.ibphoenix.com/idpl.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 Claudio Valderama C. for IBPhoenix.
* The development of the Original Code was sponsored by Craig Leonardi.
*
* Copyright (c) 2001 IBPhoenix
* All Rights Reserved.
*/
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the FBUDF_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// FBUDF_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
#if defined __WIN32__
#ifdef FBUDF_EXPORTS
#define FBUDF_API __declspec(dllexport)
#else
#define FBUDF_API __declspec(dllimport)
#endif
#else
#define FBUDF_API
#endif
//Original code for this library was written by Claudio Valderrama
// on July 2001 for IBPhoenix.
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DEV_BUILD
//This function shouldn't be defined in production.
FBUDF_API paramdsc* testreflect(paramdsc* rc);
#endif
FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2);
FBUDF_API paramdsc* sNvl(paramdsc* v, paramdsc* v2, paramdsc* rc);
FBUDF_API paramdsc* iNullIf(paramdsc* v, paramdsc* v2);
FBUDF_API paramdsc* dNullIf(paramdsc* v, paramdsc* v2);
FBUDF_API paramdsc* sNullIf(paramdsc* v, paramdsc* v2, paramdsc* rc);
FBUDF_API char* DOW(ISC_TIMESTAMP* v, char* rc);
FBUDF_API char* SDOW(ISC_TIMESTAMP* v, char* rc);
FBUDF_API paramdsc* right(paramdsc* v, short* rl, paramdsc* rc);
FBUDF_API ISC_TIMESTAMP* addDay(ISC_TIMESTAMP* v, int& ndays);
FBUDF_API ISC_TIMESTAMP* addWeek(ISC_TIMESTAMP* v, int& nweeks);
FBUDF_API ISC_TIMESTAMP* addMonth(ISC_TIMESTAMP* v, int& nmonths);
FBUDF_API ISC_TIMESTAMP* addYear(ISC_TIMESTAMP* v, int& nyears);
FBUDF_API ISC_TIMESTAMP* addMilliSecond(ISC_TIMESTAMP* v, int& nmseconds);
FBUDF_API ISC_TIMESTAMP* addSecond(ISC_TIMESTAMP* v, int& nseconds);
FBUDF_API ISC_TIMESTAMP* addMinute(ISC_TIMESTAMP* v, int& nminutes);
FBUDF_API ISC_TIMESTAMP* addHour(ISC_TIMESTAMP* v, int& nhours);
#if defined(_WIN32)
FBUDF_API ISC_TIMESTAMP* getExactTimestamp(ISC_TIMESTAMP* rc);
#endif
FBUDF_API paramdsc* truncate(paramdsc* v, paramdsc* rc);
FBUDF_API paramdsc* fbround(paramdsc* v, paramdsc* rc);
FBUDF_API paramdsc* power(paramdsc* v, paramdsc* v2, paramdsc* rc);
FBUDF_API blobcallback* string2blob(paramdsc* v, blobcallback* outblob);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: fbudf - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
fbudf.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

184
src/extlib/fbudf/fbudf.sql Normal file
View File

@ -0,0 +1,184 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's 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.ibphoenix.com/idpl.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 Claudio Valderama C. for IBPhoenix.
* The development of the Original Code was sponsored by Craig Leonardi.
*
* Copyright (c) 2001 IBPhoenix
* All Rights Reserved.
*/
/*This file defines the new udfs for firebird.*/
set sql dialect 3;
--FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2)
declare external function invl
int by descriptor, int by descriptor
returns int by descriptor
entry_point 'idNvl' module_name 'fbudf';
--FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2)
declare external function i64nvl
numeric(18,0) by descriptor, numeric(18,0) by descriptor
returns numeric(18,0) by descriptor
entry_point 'idNvl' module_name 'fbudf';
--FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2)
declare external function dnvl
double precision by descriptor, double precision by descriptor
returns double precision by descriptor
entry_point 'idNvl' module_name 'fbudf';
--FBUDF_API paramdsc* sNvl(paramdsc* v, paramdsc* v2, paramdsc* rc)
declare external function snvl
varchar(100) by descriptor, varchar(100) by descriptor,
varchar(100) by descriptor returns parameter 3
entry_point 'sNvl' module_name 'fbudf';
--FBUDF_API paramdsc* iNullIf(paramdsc* v, paramdsc* v2)
declare external function inullif
int by descriptor, int by descriptor
returns int by descriptor
entry_point 'iNullIf' module_name 'fbudf';
--FBUDF_API paramdsc* dNullIf(paramdsc* v, paramdsc* v2)
declare external function dnullif
double precision by descriptor, double precision by descriptor
returns double precision by descriptor
entry_point 'dNullIf' module_name 'fbudf';
--FBUDF_API paramdsc* iNullIf(paramdsc* v, paramdsc* v2)
declare external function i64nullif
numeric(18,4) by descriptor, numeric(18,4) by descriptor
returns numeric(18,4) by descriptor
entry_point 'iNullIf' module_name 'fbudf';
--FBUDF_API paramdsc* sNullIf(paramdsc* v, paramdsc* v2, paramdsc* rc)
declare external function snullif
varchar(100) by descriptor, varchar(100) by descriptor,
varchar(100) by descriptor returns parameter 3
entry_point 'sNullIf' module_name 'fbudf';
--FBUDF_API char* DOW(ISC_DATE* v, char* rc)
declare external function dow
timestamp,
varchar(15) returns parameter 2
entry_point 'DOW' module_name 'fbudf';
--FBUDF_API char* SDOW(ISC_DATE* v, char* rc)
declare external function sdow
timestamp,
varchar(5) returns parameter 2
entry_point 'SDOW' module_name 'fbudf';
--FBUDF_API paramdsc* right(paramdsc*, short* rl, paramdsc* rc)
declare external function sright
varchar(100) by descriptor, smallint,
varchar(100) by descriptor returns parameter 3
entry_point 'right' module_name 'fbudf';
--FBUDF_API ISC_TIMESTAMP* addDay(ISC_TIMESTAMP* v, int ndays)
declare external function addDay
timestamp, int
returns timestamp
entry_point 'addDay' module_name 'fbudf';
--FBUDF_API ISC_TIMESTAMP* addWeek(ISC_TIMESTAMP* v, int nweeks)
declare external function addWeek
timestamp, int
returns timestamp
entry_point 'addWeek' module_name 'fbudf';
--FBUDF_API ISC_TIMESTAMP* addMonth(ISC_TIMESTAMP* v, int nmonths)
declare external function addMonth
timestamp, int
returns timestamp
entry_point 'addMonth' module_name 'fbudf';
--FBUDF_API ISC_TIMESTAMP* addYear(ISC_TIMESTAMP* v, int nyears)
declare external function addYear
timestamp, int
returns timestamp
entry_point 'addYear' module_name 'fbudf';
--FBUDF_API ISC_TIMESTAMP* addMilliSecond(ISC_TIMESTAMP* v, int nseconds)
declare external function addMilliSecond
timestamp, int
returns timestamp
entry_point 'addMilliSecond' module_name 'fbudf';
--FBUDF_API ISC_TIMESTAMP* addSecond(ISC_TIMESTAMP* v, int nseconds)
declare external function addSecond
timestamp, int
returns timestamp
entry_point 'addSecond' module_name 'fbudf';
--FBUDF_API ISC_TIMESTAMP* addMinute(ISC_TIMESTAMP* v, int nminutes)
declare external function addMinute
timestamp, int
returns timestamp
entry_point 'addMinute' module_name 'fbudf';
--FBUDF_API ISC_TIMESTAMP* addHour(ISC_TIMESTAMP* v, int nhours)
declare external function addHour
timestamp, int
returns timestamp
entry_point 'addHour' module_name 'fbudf';
--It will work only with Win32 until it's ported to another OS.
--FBUDF_API ISC_TIMESTAMP* getExactTimestamp(ISC_TIMESTAMP* rc)
declare external function getExactTimestamp
timestamp returns parameter 1
entry_point 'getExactTimestamp' module_name 'fbudf';
--FBUDF_API paramdsc* truncate(paramdsc* v, paramdsc* rc)
declare external function Truncate
int by descriptor, int by descriptor
returns parameter 2
entry_point 'truncate' module_name 'fbudf';
--FBUDF_API paramdsc* truncate(paramdsc* v, paramdsc* rc)
declare external function i64Truncate
numeric(18) by descriptor, numeric(18) by descriptor
returns parameter 2
entry_point 'truncate' module_name 'fbudf';
--FBUDF_API paramdsc* fbround(paramdsc* v, paramdsc* rc)
declare external function Round
int by descriptor, int by descriptor
returns parameter 2
entry_point 'fbround' module_name 'fbudf';
--FBUDF_API paramdsc* round(paramdsc* v, paramdsc* rc)
declare external function i64Round
numeric(18, 4) by descriptor, numeric(18, 4) by descriptor
returns parameter 2
entry_point 'round' module_name 'fbudf';
--FBUDF_API paramdsc* power(paramdsc* v, paramdsc* v2, paramdsc* rc)
declare external function dPower
double precision by descriptor, double precision by descriptor,
double precision by descriptor
returns parameter 3
entry_point 'power' module_name 'fbudf';
--FBUDF_API blobcallback* string2blob(paramdsc* v, blobcallback* outblob)
declare external function string2blob
varchar(300) by descriptor,
blob returns parameter 2
entry_point 'string2blob' module_name 'fbudf';

View File

@ -0,0 +1,47 @@
FBUDF, a small project to enhance ibudf.
The library ibudf that comes with IB5, IB6 and FB has some generic routines.
However, it lacks others and it seems a good idea to enhance it with more
functionality. The first test is to build a separate small library. When those
functions have been tested, they may be included in ibudf. This way, it's possible
to experiment with fbudf without mangling the established library.
This is initially a MSVC project for Windows. It will be generalized later.
It doesn't use ib_util because it relies on the engine providing return
arguments when they are of type string.
Originally, this library intends to offer:
NVL => one for integers and the other for strings. This way, the overhead
for strings can be avoided for integers.
NULLIF => same idea than before.
DOW (Day of Week) Monday, Tuesday, Wednesday ...
SDOW(Short Day of Week) Mon, Tue, Wed, Thu ....
(
The following two aren't necessary:
SUBSTR: It has been superseded by internal SUBSTRING in Firebird.
LEFT: You can use SUBSTRING(s from 1 for N) in Firebird
)
RIGHT: This will work only for 1-byte charsets.
TRUNCATE / ROUND
(
The following two are already in udflib:
CEILING / FLOOR
)
Date manipulation stuff ...
Add a day, week, month, year to a date.
String <-> BLOB
STRING2BLOB
(Firebird already is capable of accepting a string to populate a blob on INSERT only.)
---
Claudio Valderrama - July 2001.

View File

@ -0,0 +1,30 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's 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.ibphoenix.com/idpl.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 Claudio Valderama C. for IBPhoenix.
* The development of the Original Code was sponsored by Craig Leonardi.
*
* Copyright (c) 2001 IBPhoenix
* All Rights Reserved.
*/
// stdafx.cpp : source file that includes just the standard includes
// fbudf.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

99
src/extlib/fbudf/stdafx.h Normal file
View File

@ -0,0 +1,99 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's 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.ibphoenix.com/idpl.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 Claudio Valderama C. for IBPhoenix.
* The development of the Original Code was sponsored by Craig Leonardi.
*
* Copyright (c) 2001 IBPhoenix
* All Rights Reserved.
*/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__F60BDFDF_7A2D_11D5_8EEB_4854E8274D24__INCLUDED_)
#define AFX_STDAFX_H__F60BDFDF_7A2D_11D5_8EEB_4854E8274D24__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#if defined (_WIN32)
// Insert your headers here
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
//#include <windows.h>
//#include <windef.h>
#endif
// TODO: reference additional headers your program requires here
#include "firebird.h"
//#ifdef __cplusplus
//extern "C" {
//#endif
#if defined (_WIN32)
#pragma warning(disable:4514) //unreferenced inline function has been removed
#endif
#ifdef HAVE_MATH_H
#include <math.h>
#endif
//#include <stdlib.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#ifdef HAVE_SYS_TIMEB_H
#include <sys/timeb.h>
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
//#include "ib_util.h"
//#include "ib_udf.h"
//#ifdef __cplusplus
//}
//#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#include "jrd/ibase.h"
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__F60BDFDF_7A2D_11D5_8EEB_4854E8274D24__INCLUDED_)