How to create a PostgreSQL function calling Mac OS X frameworks ?
08/07/04 11:13
I need to call some Foundation code from a new external PostgreSQL function, how to set-up my make files and how to avoid the compilation errors when including Foundation headers ?
The errors at compile time are generated by a conflicting | Size data type declared both by PosgreSQL (in header "c.h") and by MacTypes.h.
The only way to solve the problem is to split your code in two parts: a glue file will contain all your PostgreSQL specific code (the entry points of your library) that will pop the arguments and cast/convert them to external functions that will do the real job (calling Foundation).
These functions will be in another source files and of course must not depend on PostgreSQL headers. The result of the functions will be converted (if needed) back into the expected result type for the PostgreSQL backend.
Example with an external function generating an Universal ID:
The PostgreSQL glue:
#include "postgres.h"
#include "fmgr.h" /* for argument/result macros */
#include "cfuuid.h" /* our "real" job functions */
Datum uuid_createstr(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(uuid_createstr);
Datum uuid_createstr(PG_FUNCTION_ARGS)
{
BpChar *result = (BpChar *) palloc( sizeof(int) + 60 ); // 60 is big enough for a CFUUID string
cfuuid_createstr( result->vl_dat, 60 ) ;
result->vl_len = strlen( result->vl_dat ) ;
PG_RETURN_BPCHAR_P(result);
}
The header declaring our "real" function:
#ifndef _CFUUID_H_
#define _CFUUID_H_
void cfuuid_createstr(char *outBuffer, int inLen);
#endif
The code performing the real job:
#include "cfuuid.h"
#include
void cfuuid_createstr(char *outBuffer, int inLen)
{
CFUUIDRef uuidRef = CFUUIDCreate( kCFAllocatorDefault ) ;
CFStringRef stringRef = CFUUIDCreateString( kCFAllocatorDefault, uuidRef) ;
CFStringGetCString( stringRef, outBuffer, inLen, kCFStringEncodingASCII);
CFRelease(stringRef) ;
CFRelease(uuidRef) ;
}
Assuming you put the source code in ../src/tutorial of the PostgreSQL source distribution, you compile with:
gcc -no-cpp-precomp -O2 -fno-strict-aliasing -Wall -Wmissing-prototypes -Wmissing-declarations
-I../../src/include -I/usr/include -c -o uuid.o uuid.c
gcc -no-cpp-precomp -O2 -fno-strict-aliasing -Wall -Wmissing-prototypes -Wmissing-declarations
-I../../src/include -I/usr/include -c -o cfuuid.o cfuuid.c
gcc -no-cpp-precomp -framework Foundation -bundle -o uuid.so uuid.o cfuuid.o
-bundle_loader ../../src/backend/postgres
You install the uuid.so dynamic library as usual for your set-up (example: sudo cp uuid.so /usr/local/pgsql/lib).
The installation of the function in a database is as usual: (change /usr/local/pgsql/lib/ to where you put the library on your system)
CREATE FUNCTION uuid_createstr() RETURNS character AS '/usr/local/pgsql/lib/uuid' LANGUAGE C IMMUTABLE STRICT ;
Executing select uuid_createstr(); will return something like
2AE61F94-D108-11D8-B8D6-0003933F0AB6.
|
Authored by: noguru11 on Sunday, September 05 2004 @ 08:03 PM BST
Well, perhaps take a look at the NKDPostgreSQL library at www.lamarchefamily.net/nakedsoft/ or the PostgreSQL database framework at sourceforge.net/projects/pgsqlcocoa/. For a commercial PostgreSQL database design & admin tool see DataWerkz by www.uwerkz.com.