File: adaodbc.html

package info (click to toggle)
gnade 1.5.1-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 5,084 kB
  • ctags: 308
  • sloc: ada: 21,567; sh: 3,648; makefile: 843; sql: 378; awk: 29; xml: 9
file content (310 lines) | stat: -rw-r--r-- 8,720 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML
><HEAD
><TITLE
>Ada95 aspects of the ODBC binding</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="GNADE User's Guide"
HREF="gnade.html"><LINK
REL="UP"
TITLE="ODBC bindings for Ada 95"
HREF="odbc.html"><LINK
REL="PREVIOUS"
TITLE="Building ODBC based programs"
HREF="odbc_ch02.html"><LINK
REL="NEXT"
TITLE="Native Bindings"
HREF="bindings.html"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>GNADE User's Guide: GNADE, The GNat Ada Database Environment; Version 1.5.0; Document Revision $Revision: 1.42 $</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="odbc_ch02.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="bindings.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="ADAODBC"
></A
>Chapter 16. Ada95 aspects of the ODBC binding</H1
><P
>The ODBC API typically maintains a set of resources on behalf of the
calling application, such as an ODBC Environment, Connections, Statements
etc. All those resources have attributes that can be set or get by an
application. These attributes have different data types.</P
><P
>As a rather low level API ODBC is oriented to wards low level languages like C.
For the above mentioned access to the attributes of various resources the API
implements calls in such a way that you have to specify a pointer to a chunk 
of memory and a parameter containing the length of this area in bytes and 
then the API fills the area of memory with data or reads data from the area. 
It's up to the caller to make sure that the so described memory area contains 
valid data of a type expected by the call. A "C" language prototype of a
typical call of this category looks like this:
<PRE
CLASS="PROGRAMLISTING"
>SQLRETURN SQLGetConnectAttr(
   SQLHDBC ConnectionHandle,
   SQLINTEGER Attribute, 
   SQLPOINTER Value,
   SQLINTEGER BufferLength, 
   SQLINTEGER *StringLength);

SQLRETURN SQLSetConnectAttr(
   SQLHDBC ConnectionHandle,
   SQLINTEGER Attribute,
   SQLPOINTER Value,
   SQLINTEGER StringLength);</PRE
></P
><P
>The parameter "Attribute" is actually an enumeration. An integer number denotes
the attribute you're interested in. Different attributes have different
data types and there is no rule for the mapping of attributes to their type. You
have to read the documentation!</P
><P
>We think this is not the level of type safety we should provide to Ada95 clients
of this API. We therefore implemented the following scheme to deal with this
mapping problem. We will not describe the internals of this scheme here, but
how to use it in your application.</P
><P
>The core of the mapping mechanism is the generic package GNU.DB.SQLCLI.Dispatch
which you never will instantiate directly. Lets for example take the connection
attributes of the ODBC API to demonstrate the use. You'll find the connection
attribute handling in the package GNU.DB.SQLCLI.Connection_Attribute. What you
find there is an enumeration type named SQL_CONNECTION_ATTRIBUTE. This type
represents the plain SQLINTEGER parameter of the above mentioned C API call. In
this package you'll find these instantiations:
<PRE
CLASS="PROGRAMLISTING"
>   package Connection_Attributes is
     new GNU.DB.SQLCLI.Generic_Attr (Context   =&#62; SQLHDBC,
                               T               =&#62; SQL_CONNECTION_ATTRIBUTE,
                               Base            =&#62; SQLINTEGER,
                               Get             =&#62; Get_Connect_Attr,
                               Set             =&#62; Set_Connect_Attr,
                               Default_Context =&#62; Null_Handle);
   subtype Connection_Attribute is
      Connection_Attributes.Attribute_Value_Pair;

   package Dispatch is new GNU.DB.SQLCLI (Connection_Attribute);</PRE
>
The generic package GNU.DB.SQLCLI.Generic_Attr defines an abstract tagged type
Attribute_Value_Pair. This type has a single component: "Attribute", which is of the
enumeration type to be mapped (formal parameter T in the above
instantiation). There exist derived types from this abstract type for the
various data types that are possible as attributes (bitmap, boolean,
boolean_string, context, enumerated, integer, pointer, string, unsigned). All
these derived types add one additional component to the abstract base type:
"Value" whose type is selected according to the needs of the attribute to be
mapped.</P
><P
>The dispatch package has the instantiation of the generic as parameter and does
set up internally all mappings necessary to return a correctly typed
Attribute_Value_Pair'Class for an attribute enumeration value. The C API calls
now translate into these Ada95 calls:
<PRE
CLASS="PROGRAMLISTING"
>   function SQLGetConnectAttr
     (ConnectionHandle : SQLHDBC;
      Attribute        : SQL_CONNECTION_ATTRIBUTE;
      MaxLength        : SQLSMALLINT := SQL_MAX_OPTION_STRING_LENGTH)
     return Connection_Attribute'Class;

   procedure SQLSetConnectAttr
     (ConnectionHandle : in SQLHDBC;
      AttrRec          : in Connection_Attribute'Class);</PRE
>
If you look into the package GNU.DB.SQLCLI.Connection_Attribute you for example
find there this definition
<PRE
CLASS="PROGRAMLISTING"
>   type ACCESS_MODE is (SQL_MODE_READ_WRITE,
                        SQL_MODE_READ_ONLY);
   for ACCESS_MODE'Size use SQLINTEGER'Size;

   SQL_MODE_DEFAULT : constant ACCESS_MODE := SQL_MODE_READ_WRITE;

   package Dsp_Access_Mode is new
     Dispatch.A_Enumerated (SQL_ATTR_ACCESS_MODE,
                            ACCESS_MODE,
                            SQLINTEGER,
                            "ACCESS_MODE");
   subtype Connection_Attribute_Mode is Dsp_Access_Mode.Info;</PRE
>
From this you can see that the connection attribute SQL_ATTR_ACCESS_MODE is
mapped to an enumerated type ACCESS_MODE. So a call to set the access mode looks
like this:
<PRE
CLASS="PROGRAMLISTING"
>   SQLSetConnectAttr (connHandle,
                      Connection_Attribute_Mode'(
                         Attribute =&#62; SQL_ATTR_ACCESS_MODE,
                         Value     =&#62; SQL_MODE_READ_ONLY)
                     );</PRE
>
and a call to get the attribute may look like this:
<PRE
CLASS="PROGRAMLISTING"
>   declare
      attr : Connection_Attribute_Mode;
   begin
      attr := Connection_Attribute_Mode(
                 SQLGetConnectAttr (connHandle, SQL_ATTR_ACCESS_MODE)
              );
   end;</PRE
>
Note that the type conversion is required to do the dynamic type check of the
function return which returns a Connection_Attribute'Class value.</P
><P
>You'll find this technique in these packages:
    <P
></P
><UL
><LI
STYLE="list-style-type: opencircle"
><P
>             GNU.DB.SQLCLI.Info
          </P
></LI
><LI
STYLE="list-style-type: opencircle"
><P
>             GNU.DB.SQLCLI.Connection_Attribute
          </P
></LI
><LI
STYLE="list-style-type: opencircle"
><P
>             GNU.DB.SQLCLI.Statement_Attribute
          </P
></LI
><LI
STYLE="list-style-type: opencircle"
><P
>             GNU.DB.SQLCLI.Environment_Attribute
          </P
></LI
></UL
></P
><P
>Due to the dynamic type checking implemented for the attribute handling, all
calls dealing with attributes will cost some more cycles than a direct call to
the plain C API. All other ODBC calls are a very thin layer around the C
API. As attribute set/get calls are rare compared to queries etc. this is
acceptable. But it explains while a - in theory - thin binding is compiled into
a rather huge library. This is because all the type mapping information is
compiled into the library.</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="odbc_ch02.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="gnade.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="bindings.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Building ODBC based programs</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="odbc.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Native Bindings</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>