1/* BEGIN LICENSE BLOCK
2 * Version: CMPL 1.1
3 *
4 * The contents of this file are subject to the Cisco-style Mozilla Public
5 * License Version 1.1 (the "License"); you may not use this file except
6 * in compliance with the License.  You may obtain a copy of the License
7 * at www.eclipse-clp.org/license.
8 *
9 * Software distributed under the License is distributed on an "AS IS"
10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11 * the License for the specific language governing rights and limitations
12 * under the License.
13 *
14 * The Original Code is  The ECLiPSe Constraint Logic Programming System.
15 * The Initial Developer of the Original Code is  Cisco Systems, Inc.
16 * Portions created by the Initial Developer are
17 * Copyright (C) 1996 - 2006 Cisco Systems, Inc.  All Rights Reserved.
18 *
19 *
20 * Contributor(s): Joachim Schimpf, Stefano Novello, IC-Parc
21 *                 Kish Shen, CrossCore Optimization
22 *
23 * END LICENSE BLOCK */
24
25/*
26 *
27 * Contents:	Prolog wrappers around Oracle Call Interface Headers
28 *
29 * Author:	Stefano Novello
30 * Author:      Kish Shen, Generalised and updated from original OCI code,
31 *              intially for MySQL, Jan - Feb 2006.
32 *
33 */
34
35
36/* ----------------------------------------------------------------------
37 *  Definitions
38 * ---------------------------------------------------------------------- */
39
40/* ----------------------------------------------------------------------
41 *  Types
42 * ---------------------------------------------------------------------- */
43
44typedef struct {
45    /* filled in from Prolog side */
46    char prolog_tag;
47    int  ext_type;
48    /* filled in from DB */
49    int  dbtype;
50    word  size; /* e.g. for length of fixed len strings */
51    /*
52     * give a buffer b, this argument in the ith tuple
53     * (starting from 0) is to
54     * be found in b[offset + i * increment]
55     */
56    word  offset;
57    word  increment;
58#ifdef USE_MYSQL
59    my_bool is_null;
60#endif
61} map_t;
62
63typedef struct {
64	dident did;	/* Used to create structure functor */
65	uword arity; 	/* number of slots in type map */
66	uword tuples;	/* number of tuples stored in cursor */
67	uword from;	/* index of first valid unread tuple */
68	uword to;		/* 1 + index of last valid unread tuple */
69	map_t * map;	/* Maps prolog types to Oracle external types */
70} template_t;
71
72/* ---------------------------------------------------------------------- */
73
74
75/* ---------------------------------------------------------------------- */
76
77
78typedef struct
79{
80    /* User fields */
81    int refs;    /* How many live references to this session */
82    char closed; /* Was the session closed */
83    char in_transaction;
84    /* DB specific fields */
85#ifdef ORACLE
86    Lda_Def lda;
87    ub1 hda[256];
88#endif
89#ifdef USE_MYSQL
90    MYSQL * mysql;
91#endif
92} session_t;
93
94
95/* ---------------------------------------------------------------------- */
96
97typedef enum
98{
99	opened,
100	executed,
101	idle,
102	nodata,
103	closed,
104} cursor_state_t;
105
106/* ---------------------------------------------------------------------- */
107
108typedef enum
109{
110         direct,
111         prepared
112} sql_t;
113
114/* ---------------------------------------------------------------------- */
115
116typedef struct cursor_handle
117{
118 /* User fields */
119    sql_t sql_type;
120    word prolog_processed_count;
121    template_t * param_template;
122    template_t * tuple_template;
123    session_t * session;
124    void * param_buffer;
125    unsigned long * param_datalengths;
126    void * tuple_buffer;
127    unsigned long * tuple_datalengths;
128    cursor_state_t state;
129 /* Oracle specific fields */
130#ifdef ORACLE
131    Cda_Def cda;
132#endif
133#ifdef USE_MYSQL
134    my_bool * tuple_errors;
135    unsigned long sql_length; /* prepared or not */
136    char server_cursor;       /* server-side cursor or not */
137    char cursor_type;         /* type of cursor (prepared only) */
138    union
139    {
140	MYSQL_STMT * stmt; /* prepared SQL statement */
141	char * sql;        /* SQL statement (raw) */
142	MYSQL_RES * res;   /* result for SQL statement */
143    } s;
144#endif
145} cursor_t;
146
147#ifdef USE_MYSQL
148/* cursor types */
149#define CURSOR_NO_CURSOR 0
150#define CURSOR_READ_ONLY 1
151
152#endif
153
154#define DEFAULT_BUFFER_SIZE 1000
155
156/* ---------------------------------------------------------------------- */
157
158typedef enum
159{
160	state,
161	rows_processed_count,
162	return_code,
163	return_code_as_string,
164	warning_flags,
165	row_ID
166} field_t;
167
168#define FIELD_FIRST (state)
169#define FIELD_LAST (row_ID)
170
171
172/* free *p if it is pointing at something */
173#define TryFree(p)  {if (p) { free(p); p = NULL; } }
174
175/* dbformat header */
176#define DBF_HEADER_LEN		2
177
178static unsigned char dbformat_header[DBF_HEADER_LEN] = {'D','B'};
179
180/* ----------------------------------------------------------------------
181 *  Forward declarations
182 * ---------------------------------------------------------------------- */
183
184void
185session_init(session_t ** session);
186
187int
188session_start(session_t * session, char * username, char * host,
189              char * password, value v_opts);
190
191void
192session_error_value(session_t * session, int * code, char ** msg);
193
194int
195session_commit(session_t * session);
196
197int
198session_rollback(session_t * session);
199
200int
201session_sql_ddl(session_t *, char * SQL);
202
203int
204session_sql_delete(session_t * session, char * SQL);
205
206int
207session_sql_update(session_t * session, char * SQL);
208
209cursor_t *
210session_sql_prepare(session_t * session, char * SQL, word lenght, char use_prepared);
211
212cursor_t *
213session_sql_prep(session_t *session, template_t *template, char *SQL, word length, word N);
214
215cursor_t *
216ready_session_sql_cursor(session_t *session,
217	template_t *params, template_t *query, char *SQL, word length,
218        word N, char use_prepared);
219
220int
221session_tostr(session_t * session, char *buf, int quoted);
222
223void
224session_free(session_t * session); /* DB independent part */
225
226void
227session_close(session_t * session); /* DB dependent part */
228
229session_t *
230session_copy(session_t * session); /* DB independent */
231
232int
233cursor_set_options(cursor_t * cursor, value v_opts); /* DB dependent */
234
235int
236cursor_sql_execute(cursor_t * cursor, int with_options);
237
238int
239cursor_bind_placeholder(cursor_t * cursor, char * placeholder, char * value);
240
241int
242cursor_next_tuple(cursor_t * cursor, void ** buffer);
243
244int
245cursor_one_tuple(cursor_t *cursor);
246
247int
248cursor_N_tuples(cursor_t* cursor, word* n, pword* tuple_listp, pword** tp);
249
250int
251cursor_all_tuples(cursor_t * cursor, template_t * template, void * buffer);
252
253int
254cursor_field_value(cursor_t * cursor, field_t field, void ** value);
255
256int
257cursor_tostr(cursor_t * cursor, char *buf, int quoted);
258
259void
260cursor_free(cursor_t * cursor);
261
262
263void
264dbi_init();
265
266void
267dbi_final();
268