1 /*
2 sybbind.c High level Sybase row loading and binding support
3
4 MODULE: sybbind
5 FILES: sybbind.c (this one) and sybbind.h.
6
7 This module provides a high-level interface to the Sybase procedures
8 for binding rows to C variables and for loading rows in form the
9 database. These procedures permit a single procedure call to bind
10 many variables in a single call. The SybaseLoad procedure call
11 adds row retrieval as well. This reduce the amounts of coding
12 detail required by lumping the dbbind() and dbnextresults() calls
13 into a single call with only a single return code to check.
14
15 Note: This module was adapted from the module of the same
16 name from the GenInfo Backbone database project. It
17 had to be slightly modified to meet Medline project
18 coding conventions. (module nomenclature)
19
20 Edit History:
21 25 July 1991 - Rand S. Huntzinger, NLM/NCBI
22 Modified to comply with Medline project coding conventions.
23
24 Original version: circa 1989-1990, Rand S. Huntzinger, NLM/NCBI
25 *
26 *
27 * RCS Modification History:
28 * $Log: sybbind.c,v $
29 * Revision 6.0 1997/08/25 18:37:01 madden
30 * Revision changed to 6.0
31 *
32 * Revision 1.2 1995/05/17 17:56:03 epstein
33 * add RCS log revision history
34 *
35 */
36
37 #include <stdarg.h>
38 #include "sybase.h"
39 #include "sybbind.h"
40
41 /*
42 VSybaseBind Bind Sybase Fields to Variables (from vector)
43
44 This procedure takes a vector of arguments which originated
45 from a variable argument list from a calling procedure and uses
46 it to call dbbind() several times to bind variables for loading
47 from a Sybase database on the next dbgetnextrow() call.
48
49 Interpretation of the argument vector:
50
51 The argument vector contains groups of four parameters defined
52 as the last four parameters in the Sybase dbbind procedure. These
53 parameters are:
54
55 Field Contents
56 ===== ========
57 field_no The field number. This must be a positive
58 integer. When this value is zero, we
59 assume we've reached the end of the list.
60
61 type The binding type of the field (see dbdind()
62 documentation for valid values).
63
64 length The length of the field. Zero can be used
65 if the length is implied by the type or
66 the buffer used to hold the input is known
67 to be long enough to hold the data.
68
69 varptr A pointer to the location where the data
70 retrieved from the database is to be
71 stored. It must be at least length bytes
72 long, or long enough to hold this type.
73
74 Note that we terminate processing when field_no is set to zero.
75 Thus, the calling program should make sure that a zero argument
76 is passed after the last valid group.
77
78 Parameters:
79
80 dbproc A pointer to the Sybase database process.
81
82 args The argument vector which is interpreted
83 as given above.
84
85 Returns:
86
87 SUCCEED if all binds are successful, or the return code of
88 first dbbind() call which does not return SUCCEED (ie. which
89 fails).
90 */
91
92 /*
93 * VSybaseBind(dbproc,args)
94 */
VSybaseBind(dbproc,args)95 RETCODE VSybaseBind( dbproc, args )
96 DBPROCESS *dbproc;
97 va_list args;
98 {
99 int field_no;
100 int type;
101 int length;
102 char *varptr;
103 RETCODE status;
104
105 /* Assume sets of field#, type, length, variable */
106
107 for( status = SUCCEED; status == SUCCEED; )
108 {
109 /* When we get to a zero field code, we're at the end of
110 the variable length input list */
111
112 field_no = va_arg( args, int );
113 if( field_no == 0 ) break;
114
115 /* Load the other arguments */
116
117 type = va_arg( args, int );
118 length = va_arg( args, int );
119 varptr = va_arg( args, char *); /* Must be a pointer! */
120
121 /* Bind us up */
122
123 status = dbbind(dbproc, field_no, type, length, varptr );
124 }
125
126 /* Done */
127
128 return( status );
129 }
130
131
132 /*
133 SybaseBind Bind Sybase Fields to Variables
134
135 This is a variable argument list procedure which repeatedly
136 calls the Sybase dbbind() procedure to bind sets of parameters
137 coded in it's variable argument list. A single zero parameter
138 following the last valid group terminates the list of arguments.
139
140 Normally, the argument list of this function is coded as a
141 table, with arguments for a single bind on each row, and the
142 parameters for each bind in the columns. This simply provides
143 a neater way of coding the binds.
144
145 Interpretation of the argument list:
146
147 The first argument passed is a pointer to the Sybase database
148 process where the binding is to be done. The remaining parameters
149 are grouped in sets of four, which are interpreted as follows:
150
151 Field Contents
152 ===== ========
153 field_no The field number. This must be a positive
154 integer. When this value is zero, we
155 assume we've reached the end of the list.
156
157 type The binding type of the field (see dbdind()
158 documentation for valid values).
159
160 length The length of the field. Zero can be used
161 if the length is implied by the type or
162 the buffer used to hold the input is known
163 to be long enough to hold the data.
164
165 varptr A pointer to the location where the data
166 retrieved from the database is to be
167 stored. It must be at least length bytes
168 long, or long enough to hold this type.
169
170 A single zero parameter following the last valid group (which
171 ends up as field_no == 0, terminates the argument list.
172
173 [NOTE: This is simply a variable argument list wrapper for
174 the VSybaseBind() procedure.]
175
176 Returns:
177
178 SUCCEED if all binds are successful, or the return code of
179 first dbbind() call which does not return SUCCEED (ie. which
180 fails).
181 */
182
183 /*
184 * SybaseBind(DBPROCESSdbproc,...)
185 */
SybaseBind(DBPROCESS * dbproc,...)186 RETCODE SybaseBind( DBPROCESS *dbproc, ... )
187 {
188 va_list args;
189 RETCODE status;
190
191 /* Extract the argument */
192
193 va_start( args, dbproc );
194
195 /* Use the vector routine to handle everything else */
196
197 status = VSybaseBind( dbproc, args );
198 va_end( args );
199
200 /* Done */
201
202 return( status );
203
204 }
205
206
207 /*
208 SybaseLoad Bind Sybase fields to data and Load a Record
209
210 This procedure is identical to Sybase bind except that the
211 dbnextrow() procedure is called after binding to load the
212 bound variables from a row in the database.
213
214 Parameters:
215
216 Identical to SybaseBind, see the comment on that procedure
217 (above) for details.
218
219 Returns:
220
221 Identical to Sybase bind except that the return code is
222 the value returned from the dbnextrow() call unless one of
223 the bind operations fail. In that case, the return code
224 is the value returned by the failed bind (should be FAIL).
225 */
226
227 /*
228 * SybaseLoad(DBPROCESSdbproc,...)
229 */
SybaseLoad(DBPROCESS * dbproc,...)230 RETCODE SybaseLoad( DBPROCESS *dbproc, ... )
231 {
232 va_list args;
233 RETCODE status;
234
235 /* Extract the 'dbproc' argument */
236
237 va_start( args, dbproc );
238
239 /* Use the vector routine to handle everything else */
240
241 status = VSybaseBind( dbproc, args );
242 va_end( args );
243 if( status != SUCCEED ) return( status );
244
245 /* Load a row from the database and exit */
246
247 return( dbnextrow( dbproc ) );
248
249 }
250