NAME

SQL::Routine::API_C - Describe the API for a C version of SQL::Routine

COPYRIGHT AND LICENSE

This file is part of the SQL::Routine database portability library.

SQL::Routine is Copyright (c) 2002-2005, Darren R. Duncan. All rights reserved. Address comments, suggestions, and bug reports to perl@DarrenDuncan.net, or visit http://www.DarrenDuncan.net/ for more information.

SQL::Routine is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (GPL) as published by the Free Software Foundation (http://www.fsf.org/); either version 2 of the License, or (at your option) any later version. You should have received a copy of the GPL as part of the SQL::Routine distribution, in the file named "GPL"; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

Linking SQL::Routine statically or dynamically with other modules is making a combined work based on SQL::Routine. Thus, the terms and conditions of the GPL cover the whole combination. As a special exception, the copyright holders of SQL::Routine give you permission to link SQL::Routine with independent modules, regardless of the license terms of these independent modules, and to copy and distribute the resulting combined work under terms of your choice, provided that every copy of the combined work is accompanied by a complete copy of the source code of SQL::Routine (the version of SQL::Routine used to produce the combined work), being distributed under the terms of the GPL plus this exception. An independent module is a module which is not derived from or based on SQL::Routine, and which is fully useable when not linked to SQL::Routine in any form.

Any versions of SQL::Routine that you modify and distribute must carry prominent notices stating that you changed the files and the date of any changes, in addition to preserving this original copyright notice and other credits. SQL::Routine is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

While it is by no means required, the copyright holders of SQL::Routine would appreciate being informed any time you create a modified version of SQL::Routine that you are willing to distribute, because that is a practical way of suggesting improvements to the standard version.

DESCRIPTION

The first releases of SQL::Routine are being implemented in pure Perl 5 thanks mainly to the heritage of original intention for using it with Perl programs, and otherwise to the fact that Perl is great for rapid prototyping, and has a large existing support for talking to databases, via the mature DBI framework, upon which to build. One longer term goal, however, is that SQL::Routine will be a pure ANSI C library which has optional bindings for multiple other languages, such as C++, Objective-C, Perl 5 (most importantly), Parrot and Perl 6, Python, PHP 4+, Java, and whatever else users want.

This has practical benefits such as compatability with databases for which there is no existing Perl support (all database drivers already have C support), and the ability to use it with any favorite programming language (which can bring in developers from those communities aka Parrot). Moreover, and most easily guessed, C is a lot more efficient in both CPU and memory considering the huge amount of data processing that SQL::Routine has to do. There are good reasons for things like LIBXML, GD, and DBI to be written in C which are applicable to SQL::Routine also. To that end, SQL::Routine is being designed from the ground up to be easily implemented in either Perl 5 or C, in both cases using an object-oriented conceptual process.

This document is a reference for a SQL::Routine C API that is being planned, consisting mainly of the C header files (struct definitions and function declarations) that the actual SQL::Routine core will end up being. After all, SQL::Routine is actually more of an interface or protocol definition than an actual implementation (although it includes those parts too). This is intended to give programmers an idea why the design is going the way that it is and why details that pure Perl programs don't necessarily have to know about are being considered. While pure C is not object oriented at all, the SQL::Routine API is designed to be as object-like as possible, such that each C struct for storing data will have a corresponding set of functions for interfacing with it, and the details for memory allocation and deallocation are handled by those also.

Note that the core libraries are intended to not have any external dependencies, except for data type handling libraries such as for string or sparse list handling. These classes do not do any I/O and they do not talk to the operating system, so they should be fully portable. All such things are relegated to extensions like the Engines.

Note also that the following should be considered almost-C rather than perfect C. The reasoning is that my experience in writing C is rusty at the moment and I haven't necessarily tried to compile these yet. For the moment they are just a type of documentation. They will be improved.

AN ALTERNATIVE SECOND VERSION

Inspired by the recent (February 2004) formation of dbdi-dev@perl.org, a group which aims to make a Parrot-native database access framework for all Parrot hosted languages, and that can talk to native database drivers through Parrot's Native Call Interface, meaning that the Parrot database project doesn't need any parts written in C, I may decide to take the same approach with the next major version of SQL::Routine and related projects, implementing it in IMC instead of C.

More recently (March 2005), considering that a working Perl 6 engine is already taking shape separately from Parrot (see Autrijus Tang's "Pugs" distribution), I will probably just make the second version in Perl 6 instead. If an IMC version is made, it will be done later for the sake of better performance.

CONTENT OF libSQLRT.h

#ifndef _libSQLRT_h
#define _libSQLRT_h

/************************************************************************/
/* define some simple data types here */

typedef unsigned char sqlrt_dt_flag; /* stores only two values: 0 (false) or 1 (true) */
typedef unsigned char sqlrt_dt_octet; /* a generic eight-bit value */
typedef unsigned int  sqlrt_dt_scale; /* a precise integer between 0 and +4,294,967,295 */
typedef struct {
	sqlrt_dt_octet* string_data; /* not null terminated */
	sqlrt_dt_scale  used_octets;
	sqlrt_dt_scale  buff_octets;
} sqlrt_dt_label; /* an arbitrary sized UTF-8 character string, up to 4 gigabytes */

typedef enum { 
	SQLRT_LITP_NUM_INT  , /* an exact integral or whole number/numeric */
	SQLRT_LITP_NUM_EXA  , /* an exact decimal or fractional number/numeric */
	SQLRT_LITP_NUM_APR  , /* an approximately represented number/numeric (eg: floating point) */
	SQLRT_LITP_STR_BIT  , /* a string of bits or generic binary data (can store anything) */
	SQLRT_LITP_STR_CHAR , /* a string of characters (encoding spec defined separately) */
	SQLRT_LITP_BOOLEAN  , /* only two values: false or true */
	SQLRT_LITP_DATM_FULL, /* a full datetime ('timestamp') having both YMD and HMS components */
	SQLRT_LITP_DATM_DATE, /* a valid Gregorian (says the 2003,1999 standard) date having just YMD */
	SQLRT_LITP_DATM_TIME, /* a valid time of day having just HMS components */
	SQLRT_LITP_INTRVL_YM, /* a time duration having year-month (YM) intervals (year or month or both) */
	SQLRT_LITP_INTRVL_DT  /* a time duration having day-time (DHMS) intervals (but not year or month) */
} sqlrt_dt_literal_type; 

typedef enum { 
	SQLRT_CHENTP_UTF8  , /* unicode UTF-8 (always byte-order preserving; no big/little endian, usually 1 octet) */
	SQLRT_CHENTP_UTF16 , /* unicode UTF-16 (has big/little endian versions) */
	SQLRT_CHENTP_UTF32 , /* unicode UTF-32 (has big/little endian versions) */
	SQLRT_CHENTP_ASCII , /* 8-bit ascii */
	SQLRT_CHENTP_EBSDIC  /* 8-bit ebsdic */
	/* others will be added as appropriate */
} sqlrt_dt_char_enc_type; 

typedef struct {
	sqlrt_dt_literal_type  literal_type ; /* says how to interpret other struct properties */
	sqlrt_dt_scale         fixed_octets ; /* when literal is NUM_INT, NUM_APR; usu 1,2,4,8 */
	sqlrt_dt_char_enc_type char_enc_type; /* when literal is a STR_CHAR, how it is encoded */
	sqlrt_dt_octet*        literal_data ; /* not null terminated (or null part of trail junk) */
		/* above never ref'd by mult structs; struct itself can be ref'd by multiple vars */
	sqlrt_dt_scale         used_octets  ; /* doesn't include any trailing null with strings */
	sqlrt_dt_scale         buff_octets  ; /* does include or surpass any trailing null */
	/* other metadata may be added as appropriate; we may embed some fixed width type data */
	sqlrt_dt_scale         malcvar_refs ; /* count of refs to this struct from malloc'd vars */
} sqlrt_dt_literal; 

/************************************************************************/
/* define some simple data types here */

typedef enum {
	SQLRT_ENST_FOO, /* replace with semi-long actual list of generic enumerated value sets */
	SQLRT_ENST_BAR
} sqlrt_dt_enum_set;

typedef enum {
	SQLRT_ENIT_FOO, /* replace with long actual list of generic enumerated value set members */
	SQLRT_ENIT_BAR  /* this enum may need repl w const list or ml en union, if sev key can't have same int */
} sqlrt_dt_enum_item;

typedef enum {
	SQLRT_NDTP_FOO, /* replace with semi-short actual list of Node Types */
	SQLRT_NDTP_BAR
} sqlrt_dt_node_type;

typedef enum {
	SQLRT_NDATNM_FOO, /* replace with actual list of Node Attribute Names */
	SQLRT_NDATNM_BAR  /* this enum may need repl w const list or ml en union, if sev key can't have same int */
} sqlrt_dt_node_atnm;

typedef struct {
	sqlrt_dt_node_type  node_type       ; /* what type of Node this is */
	sqlrt_dt_scale      node_id         ; /* uniq ident for Node within Container+Type */
	sqlrt_dt_node*      pp_nref         ; /* (ref) primary-parent ('pp') Node attr */
	sqlrt_dt_literal*   at_literals     ; /* (array) attrs of Node which are literals */
	sqlrt_dt_enum_item* at_enums        ; /* (array) attrs of Node which are enumerated values */
	sqlrt_dt_node*      at_nrefs        ; /* (array of ref) attrs of Node which are Nodes */
		/* Note: if it would be better, we may combine all at* into one longer union list */
	sqlrt_dt_container* container       ; /* (ref) what Container this Node lives in, if any */
	sqlrt_dt_node_dll*  prim_child_nrefs; /* (list of refs) recipr to Nodes whose pp_nref ref to us */
	sqlrt_dt_node_dll*  link_child_nrefs; /* (list of refs) recipr to Nodes whose at_nodes ref to us */
} sqlrt_dt_node;

typedef struct {
	sqlrt_dt_node*     item; /* the actual Node represented by this list item */
	sqlrt_dt_node_dll* next; /* next Node in list, if any */
	sqlrt_dt_node_dll* prev; /* previous Node in list, if any */
} sqlrt_dt_node_dll; /* doubly-linked-list; use when number of list items not known in advance */

typedef struct {
	sqlrt_dt_node_dll* all_nodes; /* (list of refs) all Nodes in this Container */
} sqlrt_dt_container;

/************************************************************************/
/* define some accessor functions here */

/************************************************************************/

#endif /* _libSQLRT_h */

SEE ALSO

SQL::Routine and the various other modules mentioned in its SEE ALSO.