root / manual / manual.tex @ fa2f5141e336496db7174e370b9ed1f2310285d2
View | Annotate | Download (369.4 KB)
| 1 | % APQ-2.2 Manual |
|---|---|
| 2 | |
| 3 | \documentclass[english,letterpaper]{book}
|
| 4 | \usepackage{times}
|
| 5 | \usepackage[T1]{fontenc}
|
| 6 | \usepackage[latin1]{inputenc}
|
| 7 | \usepackage{longtable}
|
| 8 | \usepackage{amsmath}
|
| 9 | \usepackage{amssymb}
|
| 10 | |
| 11 | \usepackage{floatflt}
|
| 12 | \usepackage{fancyhdr}
|
| 13 | |
| 14 | \pagestyle{fancy}
|
| 15 | |
| 16 | %\lhead{}
|
| 17 | %\chead{}
|
| 18 | \rhead{}
|
| 19 | |
| 20 | \lfoot{}
|
| 21 | \cfoot{\thepage}
|
| 22 | \rfoot{APQ 3.0}
|
| 23 | |
| 24 | |
| 25 | \newcommand\Ref[1]{\textsection\ref{#1} (page~\pageref{#1})}
|
| 26 | |
| 27 | \usepackage{fancyvrb}
|
| 28 | \usepackage{listings}
|
| 29 | |
| 30 | \usepackage{makeidx}
|
| 31 | \makeindex |
| 32 | |
| 33 | \IfFileExists{url.sty}{\usepackage{url}}
|
| 34 | {\newcommand{\url}{\texttt}}
|
| 35 | |
| 36 | \makeatletter |
| 37 | |
| 38 | \usepackage{babel}
|
| 39 | \makeatother |
| 40 | |
| 41 | |
| 42 | |
| 43 | %==========% |
| 44 | % HYPERREF % |
| 45 | %==========% |
| 46 | \usepackage[dvipdfm, bookmarks, colorlinks, breaklinks, pdftitle={APQ User Manual},
|
| 47 | pdfauthor={KOW Framework Project}]{hyperref}
|
| 48 | \hypersetup{
|
| 49 | linkcolor=DarkSkyBlue, |
| 50 | citecolor= DarkSkyBlue, |
| 51 | filecolor= DarkSkyBlue, |
| 52 | urlcolor= DarkSkyBlue |
| 53 | } |
| 54 | |
| 55 | |
| 56 | |
| 57 | %========================% |
| 58 | % Listings Package Setup % |
| 59 | %========================% |
| 60 | \usepackage{xcolor}
|
| 61 | \usepackage{listings}
|
| 62 | |
| 63 | |
| 64 | % COLORS (Tango) |
| 65 | \definecolor{LightButter}{rgb}{0.98,0.91,0.31}
|
| 66 | \definecolor{LightOrange}{rgb}{0.98,0.68,0.24}
|
| 67 | \definecolor{LightChocolate}{rgb}{0.91,0.72,0.43}
|
| 68 | \definecolor{LightChameleon}{rgb}{0.54,0.88,0.20}
|
| 69 | \definecolor{LightSkyBlue}{rgb}{0.45,0.62,0.81}
|
| 70 | \definecolor{LightPlum}{rgb}{0.68,0.50,0.66}
|
| 71 | \definecolor{LightScarletRed}{rgb}{0.93,0.16,0.16}
|
| 72 | \definecolor{Butter}{rgb}{0.93,0.86,0.25}
|
| 73 | \definecolor{Orange}{rgb}{0.96,0.47,0.00}
|
| 74 | \definecolor{Chocolate}{rgb}{0.75,0.49,0.07}
|
| 75 | \definecolor{Chameleon}{rgb}{0.45,0.82,0.09}
|
| 76 | \definecolor{SkyBlue}{rgb}{0.20,0.39,0.64}
|
| 77 | \definecolor{Plum}{rgb}{0.46,0.31,0.48}
|
| 78 | \definecolor{ScarletRed}{rgb}{0.80,0.00,0.00}
|
| 79 | \definecolor{DarkButter}{rgb}{0.77,0.62,0.00}
|
| 80 | \definecolor{DarkOrange}{rgb}{0.80,0.36,0.00}
|
| 81 | \definecolor{DarkChocolate}{rgb}{0.56,0.35,0.01}
|
| 82 | \definecolor{DarkChameleon}{rgb}{0.30,0.60,0.02}
|
| 83 | \definecolor{DarkSkyBlue}{rgb}{0.12,0.29,0.53}
|
| 84 | \definecolor{DarkPlum}{rgb}{0.36,0.21,0.40}
|
| 85 | \definecolor{DarkScarletRed}{rgb}{0.64,0.00,0.00}
|
| 86 | \definecolor{Aluminium1}{rgb}{0.93,0.93,0.92}
|
| 87 | \definecolor{Aluminium2}{rgb}{0.82,0.84,0.81}
|
| 88 | \definecolor{Aluminium3}{rgb}{0.73,0.74,0.71}
|
| 89 | \definecolor{Aluminium4}{rgb}{0.53,0.54,0.52}
|
| 90 | \definecolor{Aluminium5}{rgb}{0.33,0.34,0.32}
|
| 91 | \definecolor{Aluminium6}{rgb}{0.18,0.20,0.21}
|
| 92 | |
| 93 | |
| 94 | |
| 95 | |
| 96 | \lstset{
|
| 97 | keywordstyle=[1]{\color{DarkSkyBlue}},
|
| 98 | keywordstyle=[2]{\color{DarkScarletRed}},
|
| 99 | keywordstyle=[3]{\bfseries},
|
| 100 | keywordstyle=[4]{\color{DarkPlum}},
|
| 101 | keywordstyle=[5]{\color{SkyBlue}},
|
| 102 | commentstyle={\color{Aluminium4}\small},
|
| 103 | stringstyle={\color{Chocolate}},
|
| 104 | tabsize=4, |
| 105 | breaklines=true, |
| 106 | basicstyle={\ttfamily\small},
|
| 107 | xleftmargin=21pt, |
| 108 | xrightmargin=11pt, |
| 109 | frame=single, |
| 110 | rulecolor=\color{black!30},
|
| 111 | captionpos=b, |
| 112 | framesep=10pt, |
| 113 | framexleftmargin=18pt, |
| 114 | numbers=none, |
| 115 | numberstyle={\tiny},
|
| 116 | stepnumber=1, |
| 117 | numbersep=15pt |
| 118 | } |
| 119 | |
| 120 | |
| 121 | |
| 122 | \lstdefinelanguage{Ada}{%
|
| 123 | morekeywords={alfa,and,array,begin,boolean,byte,case,char,const,div,%
|
| 124 | do,downto,else,end,false,file,for,function,get,goto,if,in,% |
| 125 | integer,label,maxint,mod,new,not,of,or,pack,packed,page,program,% |
| 126 | procedure,put,read,readln,real,record,repeat,reset,rewrite,set,% |
| 127 | text,then,to,true,type,unpack,until,var,while,with,write,writeln},% |
| 128 | sensitive=false,% |
| 129 | morecomment=[s]{(*}{*)},%
|
| 130 | morecomment=[s]{\{}{\}},%
|
| 131 | morestring=[d]{'}%
|
| 132 | } |
| 133 | \lstdefinelanguage{SQL}{%
|
| 134 | morekeywords={select,insert,table,from,into,create,delete,alfa,and,array,begin,boolean,byte,case,char,const,div,%
|
| 135 | do,downto,else,end,false,file,for,function,get,goto,if,in,% |
| 136 | integer,label,maxint,mod,new,not,of,or,pack,packed,page,program,% |
| 137 | procedure,put,read,readln,real,record,repeat,reset,rewrite,set,% |
| 138 | text,then,to,true,type,unpack,until,var,while,with,write,writeln},% |
| 139 | sensitive=false,% |
| 140 | morecomment=[s]{(*}{*)},%
|
| 141 | morecomment=[s]{\{}{\}},%
|
| 142 | morestring=[d]{'},%
|
| 143 | caption=SQL% |
| 144 | } |
| 145 | |
| 146 | |
| 147 | |
| 148 | |
| 149 | \lstnewenvironment{SQL}{\lstset{language=SQL}}{}
|
| 150 | |
| 151 | \lstnewenvironment{Code}{\lstset{language=Ada}}{}
|
| 152 | |
| 153 | \lstnewenvironment{Example}{\lstset{language=Ada,title=Example}}{}
|
| 154 | \lstnewenvironment{NumberedExample}{\lstset{language=Ada,label=Example}}{}
|
| 155 | |
| 156 | |
| 157 | |
| 158 | %\DefineVerbatimEnvironment{SQL}{Verbatim}%
|
| 159 | % {frame=single,fontsize=\small,label={SQL},labelposition=topline}
|
| 160 | %\DefineVerbatimEnvironment{Code}{Verbatim}%
|
| 161 | % {frame=single,fontsize=\small}
|
| 162 | %\DefineVerbatimEnvironment{Example}{Verbatim}%
|
| 163 | % {frame=single,fontsize=\small,label={Example},labelposition=topline}
|
| 164 | %\DefineVerbatimEnvironment{NumberedExample}{Verbatim}%
|
| 165 | % {frame=single,numbers=left,fontsize=\small,label={Example},labelposition=topline,commandchars=\\\{\}}
|
| 166 | |
| 167 | |
| 168 | %==============% |
| 169 | % The document % |
| 170 | %==============% |
| 171 | |
| 172 | |
| 173 | \begin{document}
|
| 174 | |
| 175 | \title{APQ Ada95 Database Binding}
|
| 176 | \author{%
|
| 177 | Copyright (c) 2002-2004, Warren W. Gay VE3WWG\\% |
| 178 | Copyright (c) 2007-2009, KOW Framework Project |
| 179 | } |
| 180 | \date{\today}
|
| 181 | \maketitle |
| 182 | |
| 183 | \tableofcontents{}
|
| 184 | \listoftables |
| 185 | %\listoffigures |
| 186 | |
| 187 | \chapter{Introduction}
|
| 188 | |
| 189 | |
| 190 | \section{APQ Version 2.2}
|
| 191 | |
| 192 | This manual documents APQ Version 2.2, which is released under a dual |
| 193 | ACL\index{ACL} and GPL\index{GPL} (GNU Public License)\index{GNU Public
|
| 194 | License} arrangement. The dual license arrangement is designed to give |
| 195 | both the \index{distributor} and user the necessary freedoms to enjoy
|
| 196 | the fair use and distribution of the sources \index{distribution of
|
| 197 | sources} contained in this project. See file COPYING\index{copying} for
|
| 198 | more details. |
| 199 | |
| 200 | |
| 201 | \section{Supported Databases}
|
| 202 | |
| 203 | The APQ binding\index{binding} was initially created to satisfy the simple need to
|
| 204 | allow Ada\index{Ada} programs to use a PostgreSQL\index{PostgreSQL} database. However, as open
|
| 205 | sourced database technologies continue to advance, the need to allow |
| 206 | other databases to be used, becomes greater. Rather than write a unique |
| 207 | Ada binding for each one, it was conceptualized that a common API\index{API}
|
| 208 | could emerge from the APQ framework\index{framework}. To this end, the APQ binding
|
| 209 | has been reworked rather extensively for version 2.1, to permit increasing |
| 210 | levels of general support of other database technologies, including |
| 211 | MySQL\index{MySQL}.
|
| 212 | |
| 213 | In the fall of 2003 the foundation was laid for Sybase\index{Sybase} support in
|
| 214 | the unreleased APQ 2.2 software using Sybase on a trial download\index{download} basis.
|
| 215 | Sybase highlighted some new APQ design \index{design, APQ} wrinkles, which required a
|
| 216 | few new adjustments and API additions. However, this development ground |
| 217 | to a halt for a spell, until September 9, 2004 when it was announced |
| 218 | on www.slashdot.org\index{www.slashdot.org} that ``Sybase Releases Free Enterprise Database
|
| 219 | on Linux''\index{Linux}.
|
| 220 | |
| 221 | \begin{quote}
|
| 222 | ``Sybase announced today that they are releasing a free (as in |
| 223 | beer) version of their flagship database for Linux. The free version |
| 224 | is limited to 1 CPU, 2 GB of RAM, and 5 GB of data, which is more |
| 225 | than adequate for all but the most demanding applications. This release |
| 226 | provides a very attractive alternative to Microsoft SQL Server\index{Microsoft SQL Server}, and
|
| 227 | gives developers and DBAs an extremely powerful argument to use against |
| 228 | the adoption of Microsoft-based solutions.''% |
| 229 | \footnote{Posted by ``Tassach'' (tassach@rapiertech.com)}
|
| 230 | \end{quote}
|
| 231 | |
| 232 | Now there was greater reason to put enterprise class database support |
| 233 | into an Ada thick binding\index{thick binding} for databases. Sybase support in APQ would
|
| 234 | allow developers to develop real applications in using Ada, without |
| 235 | trial software expiring. Once developed, these same Ada applications |
| 236 | could be deployed within the enterprise and on a large scale. |
| 237 | |
| 238 | \begin{floatingtable}{
|
| 239 | \begin{tabular}{lccc}
|
| 240 | Database & As of APQ Version & SQL & Blob \\ |
| 241 | \hline |
| 242 | PostgreSQL & 1.x & Yes & Yes \\ |
| 243 | MySQL & 2.x & Yes & No \\ |
| 244 | Sybase 12.52 & 2.2 & Yes & No \\ |
| 245 | SQL Server & 3.0 & Yes & No \\ |
| 246 | \end{tabular}}
|
| 247 | \caption{Database Product Support}\label{t:DBSupport}
|
| 248 | \end{floatingtable}
|
| 249 | |
| 250 | |
| 251 | Thanks in part to the generosity of Sybase to developers, APQ 3.0 |
| 252 | now supports the following list of database\index{list of database technologies} technologies:
|
| 253 | Table \ref{t:DBSupport} is further described as follows:
|
| 254 | |
| 255 | \begin{description}
|
| 256 | \item [As of APQ Version]is the version where the database was first supported. |
| 257 | \item [SQL]indicates whether the common SQL functions are supported (sans blob). |
| 258 | \item [Blob]indicates whether blob support is present. |
| 259 | \end{description}
|
| 260 | |
| 261 | As the reader can observe in the table above, the support for MySQL |
| 262 | is incomplete in APQ 2.1. The blob support\index{blob support} is lacking in APQ for MySQL,
|
| 263 | because MySQL's blob interface is not as complete as provided by PostgreSQL. |
| 264 | Where PostgreSQL provides the facility for virtually limitless sized |
| 265 | blobs, a MySQL blob must fit within a ``column'', very much like |
| 266 | a text field. For this reason, the facility to perform stream oriented\index{stream oriented}
|
| 267 | I/O is lacking on a blob in APQ for MySQL.\\ |
| 268 | |
| 269 | Also, there han't been time or interest in developing Blob support in Sybase and SQL Server |
| 270 | so far. This implementation should take quite a while to be done and for now the focus of |
| 271 | the project is in providing a stable solution for database connectivity. |
| 272 | |
| 273 | |
| 274 | \subsection{The Future of Blob Support for MySQL}
|
| 275 | |
| 276 | Much investigation and research\index{research, APQ} is required to adequately resolve
|
| 277 | the blob issue in APQ. Rather than hold back the binding from general |
| 278 | use, where blob functionality may have limited use anyway, it was |
| 279 | decided to release APQ 2.0 with the common API for the two databases, |
| 280 | and leaving the resolution of the blob API for a future release. |
| 281 | |
| 282 | If you are a developer, who hopes to write portable database\index{portable database code} code,
|
| 283 | then please be aware that the PostgreSQL\index{PostgreSQL} blob\index{blob} API is subject to future
|
| 284 | revision. Potentially, this could be fairly extensively revised, but |
| 285 | every attempt will be made to leave a migration path open to the developer. |
| 286 | |
| 287 | |
| 288 | APQ 3.0 inhertis |
| 289 | |
| 290 | |
| 291 | \section{Generic Database Support}
|
| 292 | |
| 293 | One of the main goals of the APQ version 2.0 release, was to develop |
| 294 | a common API\index{API, common}, that does not discriminate based upon the database technology
|
| 295 | being selected. The ideal was to allow a developer to write a procedure |
| 296 | that would accept a classwide\index{classwide} database objects, and perform database
|
| 297 | operations without needing to be concerned whether the database being |
| 298 | used was PostgreSQL\index{PostgreSQL}, MySQL\index{MySQL} or Sybase\index{Sybase}.
|
| 299 | To a large extent, the author believes that this goal has been achieved. |
| 300 | |
| 301 | |
| 302 | \subsection{Generic Limitations}
|
| 303 | |
| 304 | It must be admited however, there are some areas where the database |
| 305 | technologies were very different. Consequently, some exceptions and |
| 306 | work-arounds will be required by the programmer. An example of this |
| 307 | is that MySQL\index{MySQL} requires that all rows be fetched from a SELECT\index{SELECT} query.
|
| 308 | A failure to do this, corrupts the communication between the server\index{communication, server}
|
| 309 | and the client. Consequently, APQ works around this by defaulting |
| 310 | to use the C library call mysql\_store\_result()\index{mysql\_store\_result()} instead of the alternative,
|
| 311 | which is mysql\_use\_result()\index{mysql\_use\_result()}. However, if the result set is large,\index{large result sets}
|
| 312 | then receiving all of the rows into the clients memory\index{memory, client} is not a suitable
|
| 313 | choice. Consequently, APQ does provide some MySQL specific ways to |
| 314 | manage this setting. |
| 315 | |
| 316 | The MySQL database software also provides the special ``LIMIT n''\index{LIMIT n}
|
| 317 | extension, if the client program is only interested in the first n |
| 318 | rows of the result. If for example, you have a price file containing |
| 319 | stock price history, you may want to query the most recent price for |
| 320 | it. The simplest way to do this would be to perform a SELECT\index{SELECT} on the
|
| 321 | table with a descending price date sort sequence (or index). But if |
| 322 | you only want the first (most recent) row \index{most recent row} returned, you do not want
|
| 323 | to retrieve the entire price history into the memory of your client! |
| 324 | This is what mysql\_store\_result()\index{mysql\_store\_result()} implies (APQ default). So the
|
| 325 | application programmer will need to plan for this, when MySQL is used. |
| 326 | He will need to do one of the following: |
| 327 | |
| 328 | \begin{itemize}
|
| 329 | \item Cause mysql\_use\_result() to be used instead (change the APQ default), |
| 330 | and then fetch all of the rows, one by one. |
| 331 | \item Use the MySQL ``LIMIT 1''\index{LIMIT n} SQL extension to limit the results to
|
| 332 | 1 row. |
| 333 | \end{itemize}
|
| 334 | |
| 335 | The problem of course, is that this type of handling must only be |
| 336 | done for MySQL\index{MySQL} databases. Consequently, APQ also provides an API so
|
| 337 | that the application may query which database is being used. |
| 338 | |
| 339 | |
| 340 | \section{The APQ Database Binding}
|
| 341 | |
| 342 | This software represents a binding\index{binding to objects} to objects and procedures that
|
| 343 | enable the Ada95\index{Ada95}%
|
| 344 | \footnote{Hereafter, we'll just refer to the language as Ada, even though the
|
| 345 | version of the language implied is Ada95.% |
| 346 | } programmer to manipulate or query a relational database.\index{relational database} This document
|
| 347 | describes the design principles and goals\index{goals of APQ} of this APQ binding. It
|
| 348 | also supplies reference documentation\index{reference documentation} to the programmer, enabling
|
| 349 | the reader to write applications using the PostgreSQL\index{PostgreSQL}, MySQL\index{MySQL}
|
| 350 | or Sybase\index{Sybase} databases,
|
| 351 | in the Ada programming language. |
| 352 | |
| 353 | The APQ binding\index{binding} was initially developed using GNAT
|
| 354 | 3.13p\index{GNAT} under FreeBSD 4.4\index{FreeBSD} release.
|
| 355 | APQ version 2.0 was developed using Debian\index{Debian Linux} Linux\index{Linux} and GNAT 3.14p. The
|
| 356 | examples presented will be tested under the same development environments. |
| 357 | |
| 358 | The source code avoids any use of GNAT\index{GNAT} specific language extensions\index{language extensions}.
|
| 359 | The possible exception to this rule is that the gnatprep\index{gnatprep} tool may
|
| 360 | be used to precompile\index{precompile} optional support of optional databases\index{optional databases}. There
|
| 361 | is some C\index{C language} language source\index{source code} code used, to facilitate Ada\index{Ada} and database
|
| 362 | C language library linkages. |
| 363 | |
| 364 | \begin{table}
|
| 365 | \begin{center}
|
| 366 | \begin{tabular}{ll}
|
| 367 | Library & Database\\ |
| 368 | \hline |
| 369 | libpq & PostgreSQL\\ |
| 370 | libmysqlclient & MySQL\\ |
| 371 | OCS-12\_5 & Sybase\\ |
| 372 | \end{tabular}
|
| 373 | \end{center}
|
| 374 | \caption{Client Libraries}\label{t:ClientLib}
|
| 375 | \end{table}
|
| 376 | |
| 377 | Table \ref{t:ClientLib}
|
| 378 | lists the C language libraries\index{libraries, C} that are
|
| 379 | used in addition to the APQ client\index{library, APQ client} library, while linking\index{linking} your
|
| 380 | application: |
| 381 | |
| 382 | GNAT specific features are avoided where possible. The exception |
| 383 | however, is the use of the GNAT\index{GNAT} specific pragma\index{pragma} statements of the form:
|
| 384 | |
| 385 | \index{Linker\_Options}
|
| 386 | \begin{Code}
|
| 387 | |
| 388 | pragma Linker_Options("-lapq");
|
| 389 | |
| 390 | \end{Code}
|
| 391 | |
| 392 | is used for example, to save the programmer from having to specify |
| 393 | linking\index{linking} arguments. Therefore those using non-ACT\index{non-ACT} vendor
|
| 394 | supplied Ada compilers\index{Ada compilers} might be able to compile and use this binding\index{binding}
|
| 395 | without a huge investment. |
| 396 | |
| 397 | A 32-bit\index{32-bit Windows} Windows library for APQ can be built for use with the PostgreSQL\index{PostgreSQL},
|
| 398 | MySQL\index{MySQL} or Sybase\index{Sybase} DLL\index{DLL} client libraries. APQ release 2.1 included the
|
| 399 | win32 build instructions necessary, but was omitted in the 2.0 release. |
| 400 | |
| 401 | |
| 402 | \subsection{General Features}
|
| 403 | |
| 404 | This binding\index{binding} supports all of the normal database functions that a
|
| 405 | programmer would want to use. Additionally blob\index{blob} support
|
| 406 | is included% |
| 407 | \footnote{For PostgreSQL only, at release 2.0.%
|
| 408 | }, and implemented using the Ada streams\index{streams, Ada} interface\index{interface}.
|
| 409 | This provides the programmer with the Ada convenience and safety of |
| 410 | the streams interface\index{streams interface} when working with blobs.
|
| 411 | |
| 412 | This binding includes the following general features: |
| 413 | |
| 414 | \begin{enumerate}
|
| 415 | \item Open and Close one or more concurrent database connections\index{connections}
|
| 416 | \item Create and Execute one or more concurrent SQL queries\index{queries, concurrent} on a selected
|
| 417 | database connection\index{connection, database}
|
| 418 | \item Begin work\index{begin work}, Commit work\index{commit work} or Rollback work\index{rollback work}
|
| 419 | \item Access error message\index{error messages} text
|
| 420 | \item Generic functions and procedures to support specialized application |
| 421 | types |
| 422 | \item The NULL indicator\index{NULL indicator} is supported
|
| 423 | \item Blob\index{blob} support using the Ada streams\index{streams, Ada} facility
|
| 424 | \item A wide range of native\index{native types} and builtin\index{builtin data types} data types are supported
|
| 425 | \item Database neutral API\index{neutral API, database} is now supported for most functions
|
| 426 | \end{enumerate}
|
| 427 | |
| 428 | \subsection{Binding Type}
|
| 429 | |
| 430 | This library represents a thick Ada binding\index{thick binding} to the PostgreSQL C\index{C programmer} programmer's
|
| 431 | libpq\index{libpq} library %
|
| 432 | \footnote{C++ programs can also make use of this library but there exists the
|
| 433 | library libpq++ for C++ native support.% |
| 434 | }, and with version 2.0, MySQL's\index{MySQL} C programming library. As a thick
|
| 435 | binding, there are consequently Ada objects\index{objects, Ada} and data types that are
|
| 436 | tailored specifically to the Ada programmer. Some data types and objects |
| 437 | exist to mirror those used in the C language, while others are provided |
| 438 | to make the binding easier or safer to apply. |
| 439 | |
| 440 | A thin binding\index{thin binding} would have required the Ada programmer to be continually
|
| 441 | dealing with C language\index{C language data types} data type issues. Conversions to and from
|
| 442 | various types and pointers\index{pointers} would be necessary making the use of the
|
| 443 | binding rather tedious. Furthermore, the resulting Ada\index{Ada} program would
|
| 444 | be much harder to read and understand. |
| 445 | |
| 446 | A thick binding\index{thick binding} introduces new objects and types in order to provide
|
| 447 | an API to the programmer. This approach however, fully insulates the |
| 448 | Ada\index{Ada} programmer from interfacing with C programs\index{C programs}, pointers\index{pointers} and strings\index{strings}.
|
| 449 | The design goal\index{design goal} has additionally been to keep the number of new objects
|
| 450 | and types to a minimum. This has been done without sacrificing convenience |
| 451 | and safety\index{safety}. Readability\index{readability} of the resulting Ada\index{Ada} program was also considered
|
| 452 | to be important. |
| 453 | |
| 454 | The objects and data types involved in the use of this binding can |
| 455 | be classified into the following main groups: |
| 456 | |
| 457 | \begin{enumerate}
|
| 458 | \item Native\index{native data types} data types and objects
|
| 459 | \item Database \index{database objects} manipulation objects
|
| 460 | \item New database related objects and types for holding data |
| 461 | \end{enumerate}
|
| 462 | |
| 463 | Native data types need no explanation in this document. The database |
| 464 | manipulation objects will be described in |
| 465 | \Ref{Database_Objects:Section}.
|
| 466 | The following section will introduce the Ada types\index{Ada types} that are used to
|
| 467 | hold data. |
| 468 | |
| 469 | |
| 470 | \section{Binding Data Types}
|
| 471 | |
| 472 | The PostgreSQL\index{PostgreSQL} database supports many standard SQL\index{SQL data types} data types as well
|
| 473 | as a few exotic ones. This section documents the database base types\index{data types, database}
|
| 474 | that are supported by the Ada\index{Ada binding} binding to the database. This list is
|
| 475 | expected to grow with time as the Ada binding continues to mature |
| 476 | in its own software development. |
| 477 | |
| 478 | The ``Data Type Name'' column in the following table refers to |
| 479 | a binding type\index{binding type} if the type name is prefixed with ``APQ\_''%
|
| 480 | \footnote{Formerly, the PostgreSQL specific types had used a PG\_ prefix.%
|
| 481 | }. These data types were designed to mimic common database data types |
| 482 | in use. They can be used as they are provided, or you may subtype |
| 483 | from them or even derive new types from them in typical Ada\index{Ada} fashion.
|
| 484 | All other data types are references to native Ada data types (for |
| 485 | some of these, the package where they are defined are shown in the |
| 486 | ``Notes'' column). |
| 487 | |
| 488 | The column labelled ``Root Type''\index{root types} documents the data type that
|
| 489 | the APQ\_ data type was derived\index{derived} from. Where they represent an Ada\index{subtype, Ada}
|
| 490 | subtype, the column ``Subtype'' indicates a ``Y''. For type |
| 491 | derivations a ``N'' is shown in this column, indicating that the |
| 492 | APQ\_ type \index{APQ\_ types} listed is made ``unique''.
|
| 493 | |
| 494 | |
| 495 | \subsection{PostgreSQL Data Types\label{PostgreSQL SQL Data Types}}
|
| 496 | |
| 497 | The ``Notes'' column of Table \ref{t:pqtypes} provides PostgreSQL notes, package names\index{package names} and
|
| 498 | PostgreSQL\index{data types, PostgreSQL} data type names where the name is given in all capitals.
|
| 499 | |
| 500 | \begin{longtable}{|l|c|c|l|}
|
| 501 | \hline |
| 502 | Data Type Name & Root Type & Subtype & PostgreSQL Notes\\ |
| 503 | \hline \hline |
| 504 | Row\_ID\_Type & - & N & Used for blobs and rows\\ |
| 505 | \hline |
| 506 | String(<>) & - & - & Native Strings\\ |
| 507 | \hline |
| 508 | String(a..b) & - & - & Fixed length strings\\ |
| 509 | \hline |
| 510 | Unbounded\_String & - & - & Ada.Strings.Unbounded\\ |
| 511 | \hline |
| 512 | Bounded\_String & - & - & Ada.Strings.Bounded\\ |
| 513 | \hline |
| 514 | APQ\_Smallint & - & N & SMALLINT\\ |
| 515 | \hline |
| 516 | APQ\_Integer & - & N & INTEGER\\ |
| 517 | \hline |
| 518 | APQ\_Bigint & - & N & BIGINT\\ |
| 519 | \hline |
| 520 | APQ\_Real & - & N & REAL\\ |
| 521 | \hline |
| 522 | APQ\_Double & - & N & DOUBLE PRECISION\\ |
| 523 | \hline |
| 524 | APQ\_Serial & - & N & SERIAL\\ |
| 525 | \hline |
| 526 | APQ\_Bigserial & - & N & BIGSERIAL\\ |
| 527 | \hline |
| 528 | APQ\_Boolean & Boolean & Y & BOOLEAN\\ |
| 529 | \hline |
| 530 | APQ\_Date & Ada.Calendar.Time & Y & DATE\\ |
| 531 | \hline |
| 532 | APQ\_Time & Ada.Calendar.Day\_Duration & Y & TIME\footnote{No timezone information}\\
|
| 533 | \hline |
| 534 | APQ\_Timestamp & Ada.Calendar.Time & N & TIMESTAMP\footnote{No timezone information}\\
|
| 535 | \hline |
| 536 | APQ\_Timezone & Integer & N & range -23..23\\ |
| 537 | \hline |
| 538 | APQ\_Bitstring & - & N & BIT or BIT VARYING\\ |
| 539 | \hline |
| 540 | Decimal\_Type & - & - & PostgreSQL.Decimal\\ |
| 541 | \hline |
| 542 | range <> & - & - & Native Integers\\ |
| 543 | \hline |
| 544 | delta <> & - & - & Native Fixed Point\\ |
| 545 | \hline |
| 546 | digits <> & - & - & Native Floating Point\\ |
| 547 | \hline |
| 548 | delta <> digits <> & - & - & Native Decimal\\ |
| 549 | \hline |
| 550 | \caption{PostgreSQL Data Types}\label{t:pqtypes}
|
| 551 | \end{longtable}
|
| 552 | |
| 553 | The data type shown as ``Decimal\_Type''\index{Decimal\_Type}
|
| 554 | is special, in that it is supported from a child package APQ\-.PostgreSQL\-.Decimal\index{APQ.PostgreSQL.Decimal}.
|
| 555 | It represents a tagged\index{tagged type} type that provides an interface to the C routines\index{C routines}
|
| 556 | used by the PostgreSQL database server, for arbitrary precision decimal\index{precision, arbitrary}
|
| 557 | values. |
| 558 | |
| 559 | |
| 560 | \subsection{MySQL Data Types\label{MySQL Data Types}}
|
| 561 | |
| 562 | Table \ref{t:mytypes} summarizes the MySQL\index{data types, MySQL} specific data types and the
|
| 563 | corresponding APQ data types. |
| 564 | |
| 565 | \begin{longtable}{|l|c|c|l|}
|
| 566 | \hline |
| 567 | APQ Data Type & Ada Spec & Subtype & Comments\\ |
| 568 | \hline |
| 569 | \hline |
| 570 | Row\_ID\_Type & unsigned 64 bits & N & For all databases\\ |
| 571 | \hline |
| 572 | APQ\_Smallint & signed 16 bits & N & SMALLINT\\ |
| 573 | \hline |
| 574 | APQ\_Integer & signed 32 bits & N & INTEGER\\ |
| 575 | \hline |
| 576 | APQ\_Bigint & signed 64 bits & N & BIGINT\\ |
| 577 | \hline |
| 578 | APQ\_Real & digits 6 & N & REAL\\ |
| 579 | \hline |
| 580 | APQ\_Double & digits 15 & N & DOUBLE PRECISION\\ |
| 581 | \hline |
| 582 | APQ\_Serial & range 1..2147483647 & N & \emph{INTEGER}\\
|
| 583 | \hline |
| 584 | APQ\_Bigserial & range 1..2{*}{*}63 & N & \emph{BIGINT}\\
|
| 585 | \hline |
| 586 | APQ\_Boolean & Boolean & Y & BOOLEAN\\ |
| 587 | \hline |
| 588 | APQ\_Date & Ada.Calendar.Time & Y & DATE\\ |
| 589 | \hline |
| 590 | APQ\_Time & Ada.Calendar.Day\_Duration & Y & TIME\\ |
| 591 | \hline |
| 592 | APQ\_Timestamp & Ada.Calendar.Time & N & TIMESTAMP\\ |
| 593 | \hline |
| 594 | APQ\_Timezone & range -23..23 & N & \emph{Not in MySQL}\\
|
| 595 | \hline |
| 596 | APQ\_Bitstring & array(Positive) of APQ\_Boolean & N & \emph{Not in MySQL}\\
|
| 597 | \hline |
| 598 | \caption{MySQL Data Types}\label{t:mytypes}
|
| 599 | \end{longtable}
|
| 600 | |
| 601 | Notice the italicized SQL keywords\index{keywords, SQL} in the table. They identify the
|
| 602 | SQL keywords that differ from PostgreSQL\index{PostgreSQL}. However, the programmer
|
| 603 | only needs to be concerned with these SQL\index{keywords, SQL} keywords when creating new
|
| 604 | tables or temporary tables. For example a column of type SERIAL\index{SERIAL} in
|
| 605 | a PostgreSQL table, should be declared as a INTEGER\index{INTEGER} type in MySQL.
|
| 606 | |
| 607 | |
| 608 | \section{Sybase Data Types}
|
| 609 | |
| 610 | The chart below outlines the mappings between APQ data types and Sybase |
| 611 | server data types\index{data types, Sybase}. The italicized SQL keywords
|
| 612 | \index{keywords, SQL} in the table identify
|
| 613 | the keywords that differ from PostgreSQL\index{PostgreSQL}. The following notes are
|
| 614 | particular to Sybase\index{Sybase}:
|
| 615 | |
| 616 | \begin{itemize}
|
| 617 | \item APQ\_Bigint is not completely range compatible with Sybase's \emph{NUMERIC}
|
| 618 | \index{APQ\_Bigint}\index{NUMERIC}\index{DECIMAL}
|
| 619 | (or \emph{DECIMAL}) server types. APQ\_Bigint will always accept Sybase server
|
| 620 | values, but the server will not be able to accept the full APQ\_Bigint range of values. |
| 621 | To comply with the database server's range, |
| 622 | the application designer should use: |
| 623 | \end{itemize}
|
| 624 | |
| 625 | \index{Sybase\_Bigint}
|
| 626 | \begin{Code}
|
| 627 | subtype Sybase_Bigint is APQ_Bigint |
| 628 | range -10**38..10**38-1; |
| 629 | \end{Code}
|
| 630 | |
| 631 | \begin{itemize}
|
| 632 | \item APQ\_Bigserial\index{APQ\_Bigserial} is not supported.
|
| 633 | \item APQ\_Boolean\index{APQ\_Boolean} maps to Sybase's data type \emph{BIT.}
|
| 634 | \item APQ\_Timezone\index{APQ\_Timezone} is not supported by any Sybase data type.
|
| 635 | \item APQ\_Bitstring\index{APQ\_Bitstring} is not supported.
|
| 636 | \end{itemize}
|
| 637 | |
| 638 | Table \ref{t:sytypes} lists the APQ types supported for Sybase.
|
| 639 | |
| 640 | \begin{longtable}{|l|c|c|l|}
|
| 641 | \hline |
| 642 | APQ Data Type & Ada Spec & Subtype & Comments\\ |
| 643 | \hline |
| 644 | \hline |
| 645 | Row\_ID\_Type & unsigned 64 bits & N & For all databases\\ |
| 646 | \hline |
| 647 | APQ\_Smallint & signed 16 bits & N & SMALLINT\\ |
| 648 | \hline |
| 649 | APQ\_Integer & signed 32 bits & N & INTEGER/INT\\ |
| 650 | \hline |
| 651 | APQ\_Bigint & signed 64 bits ($-10^{38}..$$10^{38}\textrm{-1}$) & N & \emph{NUMERIC/DECIMAL}\\
|
| 652 | \hline |
| 653 | APQ\_Real & digits 6 & N & REAL\\ |
| 654 | \hline |
| 655 | APQ\_Double & digits 15 & N & DOUBLE PRECISION\\ |
| 656 | \hline |
| 657 | APQ\_Serial & range 1..2147483647 & N & \emph{INTEGER}\\
|
| 658 | \hline |
| 659 | APQ\_Bigserial & range 1..$2^{63}$ & N & ???\\
|
| 660 | \hline |
| 661 | APQ\_Boolean & Boolean & Y & \emph{BIT}\\
|
| 662 | \hline |
| 663 | APQ\_Date & Ada.Calendar.Time & Y & DATE\\ |
| 664 | \hline |
| 665 | APQ\_Time & Ada.Calendar.Day\_Duration & Y & TIME\\ |
| 666 | \hline |
| 667 | APQ\_Timestamp & Ada.Calendar.Time & N & \emph{DATETIME}\\
|
| 668 | \hline |
| 669 | APQ\_Timezone & range -23..23 & N & \emph{Not in Sybase}\\
|
| 670 | \hline |
| 671 | APQ\_Bitstring & array(Positive) of APQ\_Boolean & N & \emph{Not in Sybase}\\
|
| 672 | \hline |
| 673 | \caption{Sybase Data Types}\label{t:sytypes}
|
| 674 | \end{longtable}
|
| 675 | |
| 676 | |
| 677 | \section{Database Objects\label{Database_Objects:Section}}
|
| 678 | |
| 679 | Much of the binding between Ada\index{Ada} and the database server is provided
|
| 680 | through the use of tagged\index{tagged record} record types. Presently the APQ binding
|
| 681 | operates through three object types\index{object types, APQ} listed in Table \ref{t:APQObj}.
|
| 682 | |
| 683 | \begin{table}
|
| 684 | \begin{center}
|
| 685 | \begin{tabular}{lll}
|
| 686 | Derived From & Object Type & Purpose\\ |
| 687 | \hline |
| 688 | Root\_Connection\_Type & Connection\_Type & Database connection\\ |
| 689 | Root\_Query\_Type & Query\_Type & SQL interface\\ |
| 690 | N/A & Blob\_Type & Blob operations\\ |
| 691 | \end{tabular}
|
| 692 | \end{center}
|
| 693 | \caption{APQ Object Types}\label{t:APQObj}
|
| 694 | \end{table}
|
| 695 | |
| 696 | The APQ objects from Table \ref{t:APQObj} are described more fully as follows:
|
| 697 | |
| 698 | \begin{description}
|
| 699 | \item[Connection\_Type] object is used with Query\_Type and Blob\_Type objects |
| 700 | to perform SQL queries and blob operations respectively. This object |
| 701 | maintains the connection to the database server. |
| 702 | \item[Query\_Type] objects are used with one Connection\_Type object |
| 703 | to perform SQL query operations. This object holds the text of the |
| 704 | SQL query, some query state and result information. To execute a |
| 705 | query, it must be used in conjunction with a Connection\_Type object. |
| 706 | \item[Blob\_Type] objects are used with one Connection\_Type object to |
| 707 | perform blob operations. This is currently only supported for PostgreSQL |
| 708 | by APQ. All blob operations must occur within a transaction. |
| 709 | \end{description}
|
| 710 | |
| 711 | \begin{floatingtable}{
|
| 712 | \begin{tabular}{lc}
|
| 713 | Object & Finalized \\ |
| 714 | \hline |
| 715 | Connection\_Type & Yes \\ |
| 716 | Query\_Type & Yes \\ |
| 717 | Blob\_Type & No \\ |
| 718 | \end{tabular}}
|
| 719 | \caption{Object Finalization Behavior}\label{t:Finalization}
|
| 720 | \end{floatingtable}
|
| 721 | |
| 722 | Table \ref{t:Finalization} lists the three APQ objects and their finalization
|
| 723 | behaviour. |
| 724 | While the Connection\_Type\index{Connection\_Type}
|
| 725 | and Query\_Type\index{Query\_Type} objects are subject to
|
| 726 | finalization, the Blob\_Type\index{Blob\_Type} is not.
|
| 727 | This is because it represents an access type to |
| 728 | a Blob\_Object. This is similar in concept to an open a file, using |
| 729 | the File\_Type data type. This design approach was necessary |
| 730 | to support Ada\index{Ada} Streams\index{streams, Ada} oriented access for blobs.
|
| 731 | |
| 732 | \subsection{Object Hierarchy}
|
| 733 | |
| 734 | Before multiple database products were supported, the APQ object hierarchy\index{hierarchy}
|
| 735 | was simple. To provide generic level support however, there are now |
| 736 | root\index{root objects} objects and derived objects\index{derived objects}. In most programming
|
| 737 | contexts, the application writer does not need to be concerned with this fact. |
| 738 | However, if you frequently inspect the spec files\index{spec files} instead of the documentation\index{documentation},
|
| 739 | you must be aware that primitives\index{primitives} for a given object may be declared
|
| 740 | in multiple places. Examine Table \ref{t:pkghier} to review the APQ package hierarchy.
|
| 741 | |
| 742 | \begin{table}
|
| 743 | \begin{center}
|
| 744 | \begin{tabular}{ll}
|
| 745 | Package Name & Description \\ |
| 746 | \hline |
| 747 | APQ & Root objects and primitives \\ |
| 748 | APQ.PostgreSQL & Declarations and constants unique to PostgreSQL \\ |
| 749 | APQ.PostgreSQL.Client & Derived objects and added primitives \\ |
| 750 | APQ.MySQL & Declarations and constants unique to MySQL \\ |
| 751 | APQ.MySQL.Client & Derived objects and added primitives \\ |
| 752 | APQ.Sybase & Declarations and constants unique to Sybase \\ |
| 753 | APQ.Sybase.Client & Derived objects and added primitves for Sybase \\ |
| 754 | \end{tabular}
|
| 755 | \end{center}
|
| 756 | \caption{APQ Package Hierarchy}\label{t:pkghier}
|
| 757 | \end{table}
|
| 758 | |
| 759 | Table \ref{t:pkghier} illustrates that support for a given database is derived\index{derived}
|
| 760 | from the APQ top level\index{top level package} package. Root objects\index{root level} are declared in APQ,
|
| 761 | with common functionality. Some primitives must be overridden\index{overridden} by the
|
| 762 | derived object in database specific packages. For example, APQ.Root\_Query\_Type |
| 763 | declares a primitive named Value (\emph{APQ.Value)} to return a string
|
| 764 | column result. If this particular method is called, the exception |
| 765 | \emph{Is\_Abstract}\index{Is\_Abstract} will be raised to indicate that it must be overriden
|
| 766 | with code to handle the specific database being used. Normally the |
| 767 | user would invoke APQ\-.MySQL\-.Client\-.Value when using the MySQL\index{MySQL} database,
|
| 768 | for example. The programmer normally need not be aware of these details, |
| 769 | since object dispatching\index{dispatching} takes care of these details.
|
| 770 | |
| 771 | For this reason, the APQ\-.MySQL\-.Query\_Type object for example, is |
| 772 | derived from the APQ\-.Root\_Query\_Type\index{Root\_Query\_Type} object. This Query\_Type\index{Query\_Type} object
|
| 773 | will provide its own implementation of the Value\index{Value} function to return
|
| 774 | a column result, and will work as required. |
| 775 | |
| 776 | Consequently, when looking for primitives\index{primitives} available to the Query\_Type
|
| 777 | object, don't forget that many common primitives\index{common primitives} will be inherited\index{inherited}
|
| 778 | from the APQ\-.Root\-\_Query\-\_Type object. The same is true for Connection\-\_Type\index{Connection\_Type}
|
| 779 | objects. A number of common primitives are inherited from the APQ\-.Root\_Connection\_Type |
| 780 | object. |
| 781 | |
| 782 | |
| 783 | \chapter{Connecting to the Database}
|
| 784 | |
| 785 | Before any useful work can be accomplished by a database client program, |
| 786 | a connection must be established between the Ada program and the database |
| 787 | server. This chapter will demonstrate how to use the APQ binding\index{binding} to
|
| 788 | enable a program to connect\index{connect} and disconnect\index{disconnect}
|
| 789 | from the database server. |
| 790 | |
| 791 | \section{The Connection\_Type}
|
| 792 | |
| 793 | The Connection\_Type\index{Connection\_Type} object holds everything that is needed to maintain
|
| 794 | a connection\index{connection} to the database server. There are seven groups of primitive\index{primitive}
|
| 795 | operations for this object: |
| 796 | |
| 797 | \begin{enumerate}
|
| 798 | \item Context\index{Context} setting operations
|
| 799 | \item Connection\index{Connection} operations
|
| 800 | \item Connection Information functions\index{information functions}
|
| 801 | \item General Information operations |
| 802 | \item Implicit operations (Finalization\index{Finalization})
|
| 803 | \item Trace Facilities\index{trace facilities}
|
| 804 | \item Generic Database Operations |
| 805 | \end{enumerate}
|
| 806 | |
| 807 | \section{Context Setting Operations}\label{Context_Setting_Operations}
|
| 808 | |
| 809 | These primitives ``configure''\index{configure} the connection\index{connection} that is
|
| 810 | to be made later. When the object is initially created, it is in the |
| 811 | disconnected\index{disconnected state} state. While disconnected, configuration changes can be
|
| 812 | made in to affect the next connection attempt. With the exception of the |
| 813 | database name\index{database name}, the application should not make configuration\index{configuration} changes
|
| 814 | while the object is in the connected state\index{connected state}.
|
| 815 | \footnote{This is not yet enforced by APQ.}
|
| 816 | |
| 817 | The configuration primitives\index{primitives} are listed in Table \ref{t:ctxops}.
|
| 818 | \footnote{The items marked ``Root'' are primitives from APQ.Root\_Query\_Type.
|
| 819 | The items marked {}``Derived'' are those overrides that are declared
|
| 820 | on the APQ.{*}.Query\_Type object.}
|
| 821 | |
| 822 | \begin{table}
|
| 823 | \begin{center}
|
| 824 | \begin{tabular}{ccll}
|
| 825 | Type & Derivation & Name & Purpose \\ |
| 826 | \hline |
| 827 | proc & Root & Set\_Host\_Name & Set server host name \\ |
| 828 | proc & Root & Set\_Host\_Address & Set server host IP address \\ |
| 829 | proc & Root & Set\_Port & Set server port number \\ |
| 830 | proc & Root & Set\_DB\_Name & Set database name \\ |
| 831 | proc & Root & Set\_User\_Password & Set userid and password \\ |
| 832 | proc & Root & Set\_Instance & Set instance name to use \\ |
| 833 | proc & Root & Set\_Options & Set userid and password \\ |
| 834 | \end{tabular}
|
| 835 | \end{center}
|
| 836 | \caption{Context Setting Primitives}\label{t:ctxops}
|
| 837 | \end{table}
|
| 838 | |
| 839 | It would be nice if all database software products worked the same |
| 840 | way but the reality is very different. Table \ref{t:ctxdiffs} indicates how
|
| 841 | the primitives apply by database product.\label{Set_Instance Support Chart}
|
| 842 | In the table you can see that PostgreSQL\index{PostgreSQL} and MySQL\index{MySQL} establish their
|
| 843 | connection by specifying the host, port and database name. Sybase |
| 844 | on the other hand, specifies this information in their \emph{interface}
|
| 845 | file. To access the appropriate Sybase\index{Sybase interface entry} interface entry requires only
|
| 846 | the \emph{instance}\index{instance} information supplied by the Set\_Instance\index{Set\_Instance} call.
|
| 847 | |
| 848 | \begin{table}
|
| 849 | \begin{center}
|
| 850 | \begin{tabular}{lccc}
|
| 851 | Primitive & PostgreSQL & MySQL & Sybase \\ |
| 852 | \hline |
| 853 | Set\_Host\_Name & Yes & Yes & Ignored \\ |
| 854 | Set\_Host\_Address & Yes & Yes & Ignored \\ |
| 855 | Set\_Port & Yes & Yes & Ignored \\ |
| 856 | Set\_DB\_Name & Yes & Yes & See Note % |
| 857 | \footnote{Set\_DB\_Name is useful after the connection is made.}\\
|
| 858 | Set\_User\_Password & Yes & Yes & Yes \\ |
| 859 | Set\_Instance & No & No & Yes \\ |
| 860 | Set\_Options & Yes & Yes & Yes \\ |
| 861 | \end{tabular}
|
| 862 | \end{center}
|
| 863 | \caption{Context Setting Differences}\label{t:ctxdiffs}
|
| 864 | \end{table}
|
| 865 | |
| 866 | \subsection{PostgreSQL Defaults}
|
| 867 | |
| 868 | The PostgreSQL database defines certain environment\index{environment, PostgreSQL} variables that
|
| 869 | can specify defaults. These and the fallback\index{fallback values} values are documented
|
| 870 | in Table \ref{t:pqdef}.
|
| 871 | |
| 872 | \begin{table}
|
| 873 | \begin{center}
|
| 874 | \begin{tabular}{cclll}
|
| 875 | Type & Derivation & Name & Default & Fallback \\ |
| 876 | \hline |
| 877 | proc & Root & Set\_Host\_Name & PGHOST & localhost\\ |
| 878 | proc & Root & Set\_Host\_Address & PGHOST & localhost\\ |
| 879 | proc & Root & Set\_Port & PGPORT & 5432\\ |
| 880 | proc & Root & Set\_DB\_Name & PGDATABASE & LOGNAME\\ |
| 881 | proc & Root & Set\_User\_Password & |
| 882 | \begin{tabular}{l}
|
| 883 | PGUSER\\ |
| 884 | PGPASSWORD\\ |
| 885 | \end{tabular}
|
| 886 | & LOGNAME\\ |
| 887 | proc & Root & Set\_Options & PGOPTIONS & ""\\ |
| 888 | \end{tabular}
|
| 889 | \end{center}
|
| 890 | \caption{PostgreSQL Context Defaults}\label{t:pqdef}
|
| 891 | \end{table}
|
| 892 | |
| 893 | The capitalized names in the table for the ``Default'' and ``Fallback'' |
| 894 | columns represent environment\index{environment} variable names.
|
| 895 | When any of the environment\index{environment variables} variables are undefined in the ``Default''
|
| 896 | column, the value used is determined by the ``Fallback'' value |
| 897 | listed. The fallback\index{fallback} variable name LOGNAME\index{LOGNAME}
|
| 898 | is simply used to represent the current user's userid\index{userid}.%
|
| 899 | \footnote{The PostgreSQL libpq library may in fact, completely ignore the LOGNAME
|
| 900 | environment variable, and simply look up the userid in the /etc/password |
| 901 | file.% |
| 902 | } When no password\index{password} value is provided and no PGPASSWORD\index{PGPASSWORD}
|
| 903 | environment variable exists, then no password is assumed. |
| 904 | |
| 905 | |
| 906 | \subsection{Procedure Set\_Host\_Name}
|
| 907 | |
| 908 | The Set\_Host\_Name\index{Set\_Host\_Name} procedure accepts the following arguments
|
| 909 | |
| 910 | \begin{Code}
|
| 911 | procedure Set_Host_Name( |
| 912 | C : in out Connection_Type; |
| 913 | Host_Name : in String |
| 914 | ); |
| 915 | \end{Code}
|
| 916 | |
| 917 | The following example configures the Connection\_Type object to connect |
| 918 | to host\index{host name} ``witherspoon'':
|
| 919 | |
| 920 | \begin{Example}
|
| 921 | declare |
| 922 | C : Connection_Type; |
| 923 | begin |
| 924 | Set_Host_Name(C,"witherspoon"); |
| 925 | \end{Example}
|
| 926 | |
| 927 | \begin{description}
|
| 928 | \item [Note:]Sybase ignores this API call. |
| 929 | \end{description}
|
| 930 | |
| 931 | \subsection{Procedure Set\_Host\_Address}
|
| 932 | |
| 933 | The procedure takes two arguments, in the same fashion as Set\_Host\_Name\index{Set\_Host\_Address}:
|
| 934 | |
| 935 | \begin{Code}
|
| 936 | procedure Set_Host_Address( |
| 937 | C : in out Connection_Type; |
| 938 | Host_Address : in String |
| 939 | ); |
| 940 | \end{Code}
|
| 941 | |
| 942 | The following example configures the Connection\_Type object to connect |
| 943 | to IP address\index{IP address} 10.0.0.7:
|
| 944 | |
| 945 | \begin{Example}
|
| 946 | declare |
| 947 | C : Connection_Type; |
| 948 | begin |
| 949 | Set_Host_Address(C,"10.0.0.7"); |
| 950 | \end{Example}
|
| 951 | |
| 952 | \begin{description}
|
| 953 | \item [Note:]Sybase ignores this API call. |
| 954 | \end{description}
|
| 955 | |
| 956 | \subsection{Procedure Set\_Port (IP)}
|
| 957 | |
| 958 | This procedure configures the port\index{port} where the database
|
| 959 | server\index{server} is listening\index{listening} (when using TCP/IP\index{TCP/IP}
|
| 960 | as the transport\index{transport}):
|
| 961 | |
| 962 | \begin{Code}
|
| 963 | procedure Set_Port( |
| 964 | C : in out Connection_Type; |
| 965 | Port_Number : in Integer |
| 966 | ); |
| 967 | \end{Code}
|
| 968 | |
| 969 | \begin{floatingtable}{
|
| 970 | \begin{tabular}{ccc}
|
| 971 | Database & Default & Port\\ |
| 972 | \hline |
| 973 | PostgreSQL & IP & 5432\\ |
| 974 | MySQL & UNIX & ?\\ |
| 975 | Sybase & N/A & Ignored\\ |
| 976 | \end{tabular}}
|
| 977 | \caption{Default Database Connections}\label{t:defdb}
|
| 978 | \end{floatingtable}
|
| 979 | |
| 980 | Table \ref{t:defdb} shows the connection defaults by database product. Some of these
|
| 981 | are influenced by APQ. For example, APQ defaults to using a TCP/IP connection for the |
| 982 | PostgreSQL standard port of 5432. |
| 983 | |
| 984 | The next example |
| 985 | shows how the port\index{port} number is configured.
|
| 986 | The example configures APQ to use TCP/IP |
| 987 | port number 5432\index{port 5432} to connect to
|
| 988 | a PostgreSQL database. |
| 989 | |
| 990 | \begin{Example}
|
| 991 | declare |
| 992 | C : Connection_Type; |
| 993 | begin |
| 994 | Set_Port(C,5432); |
| 995 | \end{Example}
|
| 996 | |
| 997 | \begin{description}
|
| 998 | \item [Note:]Sybase ignores this API call. |
| 999 | \end{description}
|
| 1000 | |
| 1001 | \subsection{Procedure Set\_Port (UNIX)}
|
| 1002 | |
| 1003 | To create a local UNIX socket connection to the database, there is |
| 1004 | an overloaded version of Set\_Port\index{Set\_Port} that accepts a string\index{string} parameter
|
| 1005 | instead of an integer\index{port, integer} port number.
|
| 1006 | |
| 1007 | \begin{Code}
|
| 1008 | procedure Set_Port( |
| 1009 | C : in out Connection_Type; |
| 1010 | Port_Number : in String |
| 1011 | ); |
| 1012 | \end{Code}
|
| 1013 | |
| 1014 | Specify a null string\index{null string} for the connection\index{connection}
|
| 1015 | to use the local\index{local socket} UNIX\index{UNIX socket} socket default.
|
| 1016 | |
| 1017 | This parameter has changed somewhat as PostgreSQL\index{PostgreSQL} evolves. If you
|
| 1018 | are experiencing trouble getting a UNIX\index{UNIX socket} socket connection to work,
|
| 1019 | check the database documentation for PostgreSQL carefully. The following |
| 1020 | example has been tested to work on PostgreSQL version 7.3.5. |
| 1021 | |
| 1022 | \begin{Example}
|
| 1023 | declare |
| 1024 | C : Connection_Type; |
| 1025 | begin |
| 1026 | Set_Port(C,"5432"); |
| 1027 | \end{Example}
|
| 1028 | |
| 1029 | See the troubleshooting chapter for tips. |
| 1030 | |
| 1031 | \subsection{Procedure Set\_DB\_Name}
|
| 1032 | |
| 1033 | This procedure call configures the name of the database that the server |
| 1034 | is to use \emph{prior} to the connection being established. Once
|
| 1035 | the connection has been established, calling Set\_DB\_Name\index{Set\_DB\_Name} switches the
|
| 1036 | connection\index{connection} to use the named database.
|
| 1037 | The calling signature for this primitive is as follows: |
| 1038 | |
| 1039 | \begin{Code}
|
| 1040 | procedure Set_DB_Name( |
| 1041 | C : in out Connection_Type; |
| 1042 | DB_Name : in String |
| 1043 | ); |
| 1044 | \end{Code}
|
| 1045 | |
| 1046 | The following code fragment shows how the database name\index{database name} is configured
|
| 1047 | to be ``production'': |
| 1048 | |
| 1049 | \begin{Example}
|
| 1050 | declare |
| 1051 | C : Connection_Type; |
| 1052 | begin |
| 1053 | Set_DB_Name(C,"production"); |
| 1054 | \end{Example}
|
| 1055 | |
| 1056 | The Set\_DB\_Name \emph{always} acts as a configuration setting \emph{prior}
|
| 1057 | to connecting to the database server. Calling Set\_DB\_Name on a Connection\_Type\index{Connection\_Type}
|
| 1058 | object that has an open server connection to the database, can result |
| 1059 | in hidden SQL commands for some databases.% |
| 1060 | \footnote{For PostgreSQL and Sybase, a USE <database> command must be executed.%
|
| 1061 | } Table \ref{t:setdb} summarizes the behaviour according to database product.
|
| 1062 | |
| 1063 | \begin{table}
|
| 1064 | \begin{center}
|
| 1065 | \begin{tabular}{llll}
|
| 1066 | Database Vendor & Before Connecting & While Connecting & After Connected\\ |
| 1067 | \hline |
| 1068 | PostgreSQL & Configuration & uses config & ``USE'' Executed\\ |
| 1069 | MySQL & Configuration & uses config. & MySQL Client Call\\ |
| 1070 | Sybase & Pending SQL & ``USE'' executed & ``USE'' Executed\\ |
| 1071 | \end{tabular}
|
| 1072 | \end{center}
|
| 1073 | \caption{Set\_DB\_Name Behaviour}\label{t:setdb}
|
| 1074 | \end{table}
|
| 1075 | |
| 1076 | From the table you can see that PostgreSQL\index{PostgreSQL} and MySQL\index{MySQL} configure the
|
| 1077 | database prior to connecting\index{connecting} (connecting also establishes the database
|
| 1078 | to be used). When Set\_\-DB\_\-Name is called after a connection has been |
| 1079 | established, the database server will switch\index{switch database} to the requested database.
|
| 1080 | For some databases, this happens through the native\index{native client API} client API library\index{library}
|
| 1081 | (MySQL), but for others, a ``USE~<database>''\index{USE database} SQL\index{SQL} command must
|
| 1082 | be executed (internally within APQ). |
| 1083 | |
| 1084 | \begin{floatingtable}{
|
| 1085 | \begin{tabular}{ll}
|
| 1086 | Exception Name & Reason\\ |
| 1087 | \hline |
| 1088 | Use\_Error & Unsuccessful doing a ``USE <database>''\\ |
| 1089 | \end{tabular}}
|
| 1090 | \caption{Set\_DB\_Name Exceptions}\label{t:sdbx}
|
| 1091 | \end{floatingtable}
|
| 1092 | |
| 1093 | Sybase\index{Sybase} is different again, because does not establish the database
|
| 1094 | at connect time\index{connect time} (Sybase will use the configured default database).
|
| 1095 | So a call to Set\_DB\_Name will queue a ``USE <database>''\index{USE database} SQL\index{SQL}
|
| 1096 | statement, to be executed by APQ, once the connection succeeds. If |
| 1097 | another Set\_DB\_Name is performed while connected, new ``USE <database>'' |
| 1098 | SQL statements are executed on the Sybase server\index{Sybase server} connection provided.
|
| 1099 | |
| 1100 | The exceptions listed in Table \ref{t:sdbx}\index{exception} are possible when
|
| 1101 | using a new database name. |
| 1102 | |
| 1103 | The case of the database name used is affected according to the case policy\index{case policy}
|
| 1104 | that is in effect for the connection\index{connection}. This is summarized in Table \ref{t:cpol}
|
| 1105 | for each database vendor product. |
| 1106 | |
| 1107 | \begin{table}
|
| 1108 | \begin{center}
|
| 1109 | \begin{tabular}{llll}
|
| 1110 | Database Product & Case Policy & Effect on DB\_Name & DB Name Sensitive\\ |
| 1111 | \hline |
| 1112 | PostgreSQL & Ignored & Case preserved & Yes\\ |
| 1113 | MySQL & Ignored & Case preserved & Yes\\ |
| 1114 | Sybase & Ignored & Case preserved & Yes\\ |
| 1115 | \end{tabular}
|
| 1116 | \end{center}
|
| 1117 | \caption{Case Policy by Product}\label{t:cpol}
|
| 1118 | \end{table}
|
| 1119 | |
| 1120 | \subsection{Procedure Set\_User\_Password}
|
| 1121 | |
| 1122 | This procedure call configures both the userid\index{userid} and the password\index{password} together.
|
| 1123 | If there is no password, then supply the null string\index{null string}:
|
| 1124 | |
| 1125 | \begin{Code}
|
| 1126 | procedure Set_User_Password( |
| 1127 | C : in out Connection_Type; |
| 1128 | User_Name : in String; |
| 1129 | User_Password : in String |
| 1130 | ); |
| 1131 | \end{Code}
|
| 1132 | |
| 1133 | The following code fragment illustrates how the userid and |
| 1134 | password is configured: |
| 1135 | |
| 1136 | \begin{Example}
|
| 1137 | declare |
| 1138 | C : Connection_Type; |
| 1139 | begin |
| 1140 | Set_User_Password(C,"myuserid","xyzzy"); |
| 1141 | \end{Example}
|
| 1142 | |
| 1143 | \subsection{Procedure Set\_Case}
|
| 1144 | |
| 1145 | One of the goals of APQ was to make writing of portable database\index{portable database code} code
|
| 1146 | possible. While this isn't completely possible, the goal remains to |
| 1147 | reduce database differences. Until the introduction of Sybase\index{Sybase} within
|
| 1148 | APQ, there was little concern for the case of SQL query\index{SQL query code} code used.
|
| 1149 | |
| 1150 | This APQ manual has always used examples where SQL code is uppercased\index{uppercased SQL code},
|
| 1151 | with Ada\index{Ada} code using normal Ada95\index{Ada95} conventions. This helps to make the
|
| 1152 | SQ\index{SQL}L code standout, and separate it from the other code. Sybase introduces
|
| 1153 | a problem however, since the Sybase server is case sensitive\index{case sensitive} when
|
| 1154 | referring to tables\index{tables} and column\index{column names} names. This feature cannot be disabled
|
| 1155 | for a Sybase server% |
| 1156 | \footnote{MySQL databases can be configured to be caseless or case sensitive.%
|
| 1157 | }. Since users of Sybase\index{Sybase} tend to use lowercase\index{lowercase names} names, this creates
|
| 1158 | a bit of a problem for portable\index{portable SQL} SQL text within APQ.
|
| 1159 | |
| 1160 | The approach that APQ 2.2 uses for Sybase\index{Sybase} (and future databases where
|
| 1161 | this matters), all SQL\index{SQL} code is changed to lowercase\index{lowercase} before being
|
| 1162 | sent to the server. Before the reader panics thinking that this won't |
| 1163 | work, it should be made clear that APQ does not change the case\index{case of SQL} of
|
| 1164 | any string\index{string} that is quoted\index{quoted} (using the Append\_Quoted\index{Append\_Quoted} functions for
|
| 1165 | example). A WHERE\index{WHERE clause} clause such as the following will preserve the text
|
| 1166 | within quotes\index{quotes}:
|
| 1167 | |
| 1168 | \begin{SQL}
|
| 1169 | |
| 1170 | where part_no = "XZ98-307" |
| 1171 | |
| 1172 | \end{SQL}
|
| 1173 | |
| 1174 | APQ keeps track of what parts of the SQL\index{SQL query} query were quoted\index{quoted} and which
|
| 1175 | parts were not. This is \emph{not} done by parsing\index{parsing} the SQL text. That
|
| 1176 | would be prone to error and would require intimate knowledge of every |
| 1177 | SQL dialect supported in APQ. Instead, the string\index{string} fragments are marked
|
| 1178 | for ``preserve''\index{preserve case} case or ``not preserve''\index{preserved, not} as the Query\_Type\index{Query\_Type}
|
| 1179 | object collects text. When the full SQL text\index{SQL text} is require by a routine
|
| 1180 | like To\_String\index{To\_String}, then the standing case policy\index{case policy} is applied to each
|
| 1181 | string\index{string fragment} fragment that has ``not preserve''\index{preserved, not}.
|
| 1182 | |
| 1183 | You can change this APQ case policy\index{case policy} for Sybase (or any other database).
|
| 1184 | The Set\_Case\index{Set\_Case} function gives you complete control over what the policy
|
| 1185 | to use for SQL case\index{SQL case}. You can choose one of the SQL\_Case\_Type\label{SQL_Case_Type Choices}
|
| 1186 | \index{SQL\_Case\_Type} options, which are listed in Table~\ref{t:cpolicies}.
|
| 1187 | |
| 1188 | \begin{table}
|
| 1189 | \begin{center}
|
| 1190 | \begin{tabular}{ll}
|
| 1191 | Case Policy & Description\\ |
| 1192 | \hline |
| 1193 | Preserve\_Case & Do not make any case changes to the SQL text\\ |
| 1194 | Lower\_Case & Force unquoted SQL text to lowercase\\ |
| 1195 | Upper\_Case & Force unquoted SQL text to uppercase\\ |
| 1196 | \end{tabular}
|
| 1197 | \end{center}
|
| 1198 | \caption{Case Policies for SQL Text}\label{t:cpolicies}
|
| 1199 | \end{table}
|
| 1200 | |
| 1201 | \begin{floatingtable}{
|
| 1202 | \begin{tabular}{ll}
|
| 1203 | Database & Default SQL Case Policy\\ |
| 1204 | \hline |
| 1205 | PostgreSQL & Upper\_Case\\ |
| 1206 | MySQL & Lower\_Case\\ |
| 1207 | Sybase & Lower\_Case\\ |
| 1208 | \end{tabular}}
|
| 1209 | \caption{Default Case Policies}\label{t:dfcpol}
|
| 1210 | \end{floatingtable}
|
| 1211 | |
| 1212 | Table~\ref{t:dfcpol} summarizes the default case policies\index{case policies} used in APQ 2.2
|
| 1213 | for the different database vendor products supported. |
| 1214 | |
| 1215 | MySQL\index{MySQL} joins Sybase\index{Sybase} in this case policy because by default, MySQL is
|
| 1216 | case sensitive. If you have configured your MySQL server to be case |
| 1217 | insenstive, then any setting will do (Upper\_Case\index{Upper\_Case} is suggested for
|
| 1218 | the benefit of the trace log displays). Most users of Sybase\index{Sybase} will
|
| 1219 | likely prefer either the Lower\_Case\index{Lower\_Case} or Preserve\_Case\index{Preserve\_Case}
|
| 1220 | policies instead. |
| 1221 | |
| 1222 | The Set\_Case\index{Set\_Case} API procedure for the Connection\_Type object is defined
|
| 1223 | as follows: |
| 1224 | |
| 1225 | \begin{Code}
|
| 1226 | procedure Set_Case( |
| 1227 | C : in out Connection_Type; |
| 1228 | SQL_Case : in SQL_Case_Type |
| 1229 | ); |
| 1230 | \end{Code}
|
| 1231 | |
| 1232 | You may also use the Get\_Case\index{Get\_Case} function primitive to find out what
|
| 1233 | the current policy in effect is. Please note that a change in policy |
| 1234 | only affects the outcome of the next call to the following |
| 1235 | pimitives of the Query\_Type\index{Query\_Type} object:
|
| 1236 | |
| 1237 | \begin{itemize}
|
| 1238 | \item To\_String |
| 1239 | \item Execute |
| 1240 | \item Execute\_Checked |
| 1241 | \end{itemize}
|
| 1242 | |
| 1243 | The Set\_Case\index{Set\_Case} call will not actually change the SQL text\index{SQL text} stored within
|
| 1244 | the Query\_Type object. It only sets the policy\index{case policy} mode.
|
| 1245 | |
| 1246 | The following example shows how to undo the Sybase default of lowercasing |
| 1247 | the SQL text: |
| 1248 | |
| 1249 | \begin{Example}
|
| 1250 | declare |
| 1251 | C : Connection_Type; |
| 1252 | Q : Query_Type; |
| 1253 | begin |
| 1254 | ... |
| 1255 | Set_Case(C,Preserve_Case); |
| 1256 | ... |
| 1257 | Append(Q,"from table Mixed_Case"); |
| 1258 | Execute(Q,C); -- SQL case is preserved here |
| 1259 | \end{Example}
|
| 1260 | |
| 1261 | \subsubsection{The Viral Nature of Connection\_Type}
|
| 1262 | |
| 1263 | Note that APQ does permit altering the case policy\index{case policy} for Query\_Type\index{Query\_Type}
|
| 1264 | objects in addition to the Connection\_Type\index{Connection\_Type} object being described
|
| 1265 | here. It should be noted however, that the setting held by the Connection\_Type |
| 1266 | is viral\index{viral nature} in nature. Whenever a Query\_Type object is used in conjunction
|
| 1267 | with a Connection\_Type object, in a \emph{Execute}\index{Execute}
|
| 1268 | or \emph{Execute\_Checked}\index{Execute\_Checked}
|
| 1269 | call for example, the Query\_Type object will inherit the setting |
| 1270 | held by the corresponding Connection\_Type object. For this reason, |
| 1271 | the best application practice is to establish your application case |
| 1272 | policy\index{case policy} in all Connection\_Type objects used by your application. It
|
| 1273 | is also best practice to use one Connection\_Type object wherever |
| 1274 | possible, since many queries can share one connection\index{shared connection}.
|
| 1275 | |
| 1276 | The only reason you should consider applying a case policy\index{case policy} directly
|
| 1277 | to a Query\_Object, is perhaps for application specific uses of the |
| 1278 | SQL text\index{SQL text}. For example, you could build a query\index{query, build a} in a Query\_Type object,
|
| 1279 | set the case policy to Upper\_Case\index{Upper\_Case}, and then use the To\_String\index{To\_String} function
|
| 1280 | primitive to extract out the SQL text for logging\index{logging} or user display\index{display}
|
| 1281 | purposes. Once however the Query\_Type is used with a Connection\_Type |
| 1282 | however, (in \emph{Execute}) the Connection\_Type's setting will not
|
| 1283 | only prevail for the primitive, but will also force the Query\_Type's |
| 1284 | policy to agree upon return from the call. |
| 1285 | |
| 1286 | |
| 1287 | \subsection{Procedure Set\_Options\label{Procedure Set_Options}}
|
| 1288 | |
| 1289 | This procedure call permits the caller to specify any specialized |
| 1290 | database server options. The options are specified in string form |
| 1291 | with this API call. The specific options, and the format\index{format} of those
|
| 1292 | options\index{options} will vary according to the database being used. See the following
|
| 1293 | subsections for additional information about the database engine\index{engine, database} specifics.
|
| 1294 | |
| 1295 | The procedure Set\_Options\index{Set\_Options} is documented as follows:
|
| 1296 | |
| 1297 | \begin{Code}
|
| 1298 | procedure Set_Options( |
| 1299 | C : in out Connection_Type; |
| 1300 | Options : in String |
| 1301 | ); |
| 1302 | \end{Code}
|
| 1303 | |
| 1304 | Exceptions\index{exceptions} can be raised if the options are being set on a connection
|
| 1305 | that is already connected. Table \ref{t:soopts} lists the exceptions that may be
|
| 1306 | raised by Set\_Options. |
| 1307 | |
| 1308 | \begin{table}
|
| 1309 | \begin{center}
|
| 1310 | \begin{tabular}{ll}
|
| 1311 | Exception Name & Reason\\ |
| 1312 | \hline |
| 1313 | Failed & The option is either unsupported or setting was rejected\\ |
| 1314 | \end{tabular}
|
| 1315 | \end{center}
|
| 1316 | \caption{Set\_Options Exceptions}\label{t:soopts}
|
| 1317 | \end{table}
|
| 1318 | |
| 1319 | If the options are configured for an unconnected\index{unconnected} Connection\_Type
|
| 1320 | object, the exceptions if any, will be raised at the time of connection |
| 1321 | (See the Connect primitive). |
| 1322 | |
| 1323 | The following PostgreSQL\index{PostgreSQL} code fragment illustrates how two options\index{options}
|
| 1324 | may be configured: |
| 1325 | |
| 1326 | \begin{Example}
|
| 1327 | declare |
| 1328 | C : Connection_Type; |
| 1329 | begin |
| 1330 | Set_Options(C,"requiressl=1 dbname=test"); |
| 1331 | \end{Example}
|
| 1332 | |
| 1333 | Note that in this example, the option string has been used to declare |
| 1334 | the database name to be used. Standard values should be set through |
| 1335 | the primitive functions provided (ie. use Set\_DB\_Name\index{Set\_DB\_Name} instead).
|
| 1336 | Otherwise, when information primitives are added, you may not get |
| 1337 | correct results. Any non-standard options like the ``requiressl''\index{requiressl}
|
| 1338 | option, should be configured as shown in this procedure call. |
| 1339 | |
| 1340 | MySQL\index{MySQL} and Sybase\index{Sybase}, use a comma delimited list\index{delimited list} of options\index{options}.
|
| 1341 | The following example shows how to get Sybase I/O\index{statistics, Sybase I/O}
|
| 1342 | and time statistics\index{statistics, time} recorded in your APQ trace\index{trace log} log:
|
| 1343 | |
| 1344 | \begin{Example}
|
| 1345 | declare |
| 1346 | C : Connection_Type; |
| 1347 | begin |
| 1348 | Set_Options(C,"STATS_IO=TRUE,STATS_TIME=TRUE"); |
| 1349 | \end{Example}
|
| 1350 | |
| 1351 | Option parsing\index{parsing} is rather limited. Everything between the '=' sign
|
| 1352 | and the next comma is the value for the parameter. Different database |
| 1353 | products will use different parameter types\index{paramater types}. For example, MySQL\index{MySQL} will
|
| 1354 | use 0 to represent False\index{false}, and 1 to represent True\index{true}. For Sybase\index{Sybase}, use
|
| 1355 | F or False, and T or True for Boolean\index{Boolean} values.
|
| 1356 | |
| 1357 | |
| 1358 | \subsubsection{PostgreSQL Options}
|
| 1359 | |
| 1360 | The documentation is not very clear about the format\index{format} of these options,
|
| 1361 | but it appears that keyword=value\index{keyword value pairs} pairs\index{keyword=value pairs}
|
| 1362 | separated by \emph{spaces} for multiple options\index{options} are
|
| 1363 | accepted. If you must include spaces or other special characters within |
| 1364 | the value component, then you must follow PostgreSQL\index{PostgreSQL} escaping rules\index{escaping rules}.
|
| 1365 | Refer to the database server documentation for these details. |
| 1366 | |
| 1367 | |
| 1368 | \subsubsection{MySQL Options}
|
| 1369 | |
| 1370 | MySQL's\index{MySQL} C interface\index{C interface} is much different than PostgreSQL's C interface
|
| 1371 | for options. MySQL uses an enumerated value\index{enumerated value} and argument pair\index{argument pair} when
|
| 1372 | setting an option\index{option}.%
|
| 1373 | \footnote{Although, some options do not use the argument.%
|
| 1374 | } To keep the APQ interface friendly and consistent, APQ will accept |
| 1375 | all options and arguments in a string\index{string} form as documented in
|
| 1376 | \Ref{Procedure Set_Options}. However, these string options\index{string options} must be
|
| 1377 | processed by APQ and digested into arguments usable by the MySQL C |
| 1378 | client interface. Consequently, APQ must anticipate these options |
| 1379 | and the option format in advance. For these reasons, the MySQL options |
| 1380 | and their arguments will be partially documented here. |
| 1381 | |
| 1382 | The format\index{format of option string} of the option string should be one or more option names
|
| 1383 | and arguments, separated by commas. Option names\index{option names} are treated as caseless\index{caseless}
|
| 1384 | (internally upcased\index{upcased}).
|
| 1385 | |
| 1386 | \begin{Example}
|
| 1387 | |
| 1388 | Set\_Options(C,"CONNECT_TIMEOUT=3,COMPRESS,LOCAL_INFIL=1"); |
| 1389 | |
| 1390 | \end{Example}
|
| 1391 | |
| 1392 | Each option should be separated by a comma. APQ processes each option |
| 1393 | in left to right fashion, making multiple MySQL C API calls for each |
| 1394 | one. Table~\ref{t:myopts} lists the APQ supported options for MySQL.
|
| 1395 | |
| 1396 | \begin{table}
|
| 1397 | \begin{center}
|
| 1398 | \begin{tabular}{lll}
|
| 1399 | Option Name & Argument Type & Comments\\ |
| 1400 | \hline |
| 1401 | CONNECT\_TIMEOUT & Unsigned & Seconds\\ |
| 1402 | COMPRESS & None & Compressed comm link\\ |
| 1403 | NAMED\_PIPE & None & Windows: use a named pipe\\ |
| 1404 | INIT\_COMMAND & String & Initialization command\\ |
| 1405 | READ\_DEFAULT\_FILE & String & See MySQL\\ |
| 1406 | READ\_DEFAULT\_GROUP & String & See MySQL\\ |
| 1407 | SET\_CHARSET\_DIR & String & See MySQL\\ |
| 1408 | SET\_CHARSET\_NAME & String & See MySQL\\ |
| 1409 | LOCAL\_INFIL & Boolean & See MySQL\\ |
| 1410 | \end{tabular}
|
| 1411 | \end{center}
|
| 1412 | \caption{MySQL Options}\label{t:myopts}
|
| 1413 | \end{table}
|
| 1414 | |
| 1415 | It is important to observe that any option that requires an argument\index{argument, option},
|
| 1416 | must have one. Any argument that requires an unsigned integer\index{unsigned}, must
|
| 1417 | have an unsigned integer (otherwise an exception\index{exception} is raised). A MySQL\index{MySQL}
|
| 1418 | Boolean\index{Boolean} argument should be the value 0 or 1. At the present time,
|
| 1419 | APQ gathers string\index{string} data up until the next comma or the end of the
|
| 1420 | string. Currently an option argument string cannot contain a comma |
| 1421 | character. |
| 1422 | \footnote{This needs to be corrected in a future release of APQ.}
|
| 1423 | |
| 1424 | |
| 1425 | \subsubsection{Sybase Options}
|
| 1426 | |
| 1427 | Sybase documents several options\index{options, Sybase} in their ``Open Client C Programmer's
|
| 1428 | Reference'' manual. All documented options are made available to |
| 1429 | the APQ developer, although some options are not recommended. |
| 1430 | |
| 1431 | \begin{floatingtable}{
|
| 1432 | \begin{tabular}{ll}
|
| 1433 | Option Value & Meaning\\ |
| 1434 | \hline |
| 1435 | TRUE & True\\ |
| 1436 | T & True\\ |
| 1437 | FALSE & False\\ |
| 1438 | F & False\\ |
| 1439 | \end{tabular}}
|
| 1440 | \caption{Boolean Option Values}\label{t:boolarg}
|
| 1441 | \end{floatingtable}
|
| 1442 | |
| 1443 | Each Sybase option value must conform to certain data type format\index{format, option}
|
| 1444 | and/or restrictions. Table~\ref{t:boolarg} lists
|
| 1445 | acceptable argument values for Boolean\index{Boolean} options, within APQ. The
|
| 1446 | case is not significant, but uppercase is recommended to make it stand out from |
| 1447 | the surrounding Ada code. |
| 1448 | |
| 1449 | The following is an example of a Boolean option setting for the Sybase option STATS\_IO: |
| 1450 | |
| 1451 | \begin{Example}
|
| 1452 | |
| 1453 | "STATS_IO=TRUE" |
| 1454 | |
| 1455 | \end{Example}
|
| 1456 | |
| 1457 | Some Sybase options require an integer\index{unsigned integer} (actually unsigned). Those
|
| 1458 | options listed in the option table\index{option table} as requiring an Unsigned value,
|
| 1459 | should be simply an unsigned value. The following is an example: |
| 1460 | |
| 1461 | \begin{Example}
|
| 1462 | |
| 1463 | "ROWCOUNT=1" |
| 1464 | |
| 1465 | \end{Example}
|
| 1466 | |
| 1467 | String value arguments\index{string value arguments} are simply textual values that are placed between
|
| 1468 | the equal sign and the next comma (or end of string). The following |
| 1469 | example illustrates: |
| 1470 | |
| 1471 | \begin{Example}
|
| 1472 | |
| 1473 | "AUTHOFF=sa" |
| 1474 | |
| 1475 | \end{Example}
|
| 1476 | |
| 1477 | Some options are identified as taking ``String/NULL''. These options |
| 1478 | will take normal string values or simply the word NULL\index{NULL options}. The value
|
| 1479 | NULL allows the system default to be used. The following is an example: |
| 1480 | |
| 1481 | \begin{Example}
|
| 1482 | |
| 1483 | "CHARSET=NULL" |
| 1484 | |
| 1485 | \end{Example}
|
| 1486 | |
| 1487 | \begin{table}
|
| 1488 | \begin{center}
|
| 1489 | \begin{tabular}{ll}
|
| 1490 | Value & Sybase Option\\ |
| 1491 | \hline |
| 1492 | SUNDAY & CS\_OPT\_SUNDAY\\ |
| 1493 | MONDAY & CS\_OPT\_MONDAY\\ |
| 1494 | TUESDAY & CS\_OPT\_TUESDAY\\ |
| 1495 | WEDNESDAY & CS\_OPT\_WEDNESDAY\\ |
| 1496 | THURSDAY & CS\_OPT\_THURSDAY\\ |
| 1497 | FRIDAY & CS\_OPT\_FRIDAY\\ |
| 1498 | SATURDAY & CS\_OPT\_SATURDAY\\ |
| 1499 | \end{tabular}
|
| 1500 | \end{center}
|
| 1501 | \caption{Weekday Option Argument Values}\label{t:wkday}
|
| 1502 | \end{table}
|
| 1503 | |
| 1504 | The DATEFIRST option\index{DATEFIRST option} accepts an argument Weekday argument. The valid
|
| 1505 | range of values are listed in Table~\ref{t:wkday}.
|
| 1506 | |
| 1507 | The following example shows how the DATEFIRST option is used: |
| 1508 | |
| 1509 | \begin{Example}
|
| 1510 | |
| 1511 | "DATEFIRST=SUNDAY" |
| 1512 | |
| 1513 | \end{Example}
|
| 1514 | |
| 1515 | \begin{table}
|
| 1516 | \begin{center}
|
| 1517 | \begin{tabular}{ll}
|
| 1518 | Value & Sybase Option\\ |
| 1519 | \hline |
| 1520 | MDY & CS\_OPT\_FMTMDY\\ |
| 1521 | DMY & CS\_OPT\_FMTDMY\\ |
| 1522 | YMD & CS\_OPT\_FMTYMD\\ |
| 1523 | YDM & CS\_OPT\_FMTYDM\\ |
| 1524 | MYD & CS\_OPT\_FMTMYD\\ |
| 1525 | DYM & CS\_OPT\_FMTDYM\\ |
| 1526 | \end{tabular}
|
| 1527 | \end{center}
|
| 1528 | \caption{Date Format Argument Values}\label{t:dtfmt}
|
| 1529 | \end{table}
|
| 1530 | |
| 1531 | One last category of Sybase option arguments is the DATEFORMAT argument\index{DATEFORMAT option}
|
| 1532 | type. The valid list of values for this type of argument are given in Table~\ref{t:dtfmt}.
|
| 1533 | |
| 1534 | The following is an example of such an option: |
| 1535 | |
| 1536 | \begin{Example}
|
| 1537 | |
| 1538 | "DATEFORMAT=YMD" |
| 1539 | |
| 1540 | \end{Example}
|
| 1541 | |
| 1542 | Table~\ref{t:syonames} lists all of the options that APQ is able to recognize for Sybase.
|
| 1543 | Each of the option names\index{option names} listed is equivalent to the
|
| 1544 | Sybase C macro\index{C macro, Sybase}
|
| 1545 | constant if the prefix CS\_OPT\_\index{CS\_OPT\_{*}} is added to the option name. Consult
|
| 1546 | the Sybase documentation for descriptions of the purpose of these |
| 1547 | options and when to apply them. |
| 1548 | |
| 1549 | \begin{longtable}{lll}
|
| 1550 | Option Name & Data Type & Notes\\ |
| 1551 | \hline |
| 1552 | ANSINULL & Boolean &\\ |
| 1553 | ANSIPERM & Boolean &\\ |
| 1554 | ARITHABORT & Boolean &\\ |
| 1555 | ARITHIGNORE & Boolean &\\ |
| 1556 | AUTHOFF & String &\\ |
| 1557 | AUTHON & String &\\ |
| 1558 | CHAINXACTS & Boolean &\\ |
| 1559 | CHARSET & String/NULL & Use NULL for default\\ |
| 1560 | CURCLOSEONXACT & Boolean &\\ |
| 1561 | DATEFIRST & Weekday &\\ |
| 1562 | DATEFORMAT & YMD/MDY/etc. & May interfere with APQ\\ |
| 1563 | FIPSFLAG & Boolean &\\ |
| 1564 | FORCEPLAN & Boolean &\\ |
| 1565 | FORMATONLY & Boolean &\\ |
| 1566 | GETDATA & Boolean &\\ |
| 1567 | IDENTITYOFF & String &\\ |
| 1568 | IDENTITYON & String &\\ |
| 1569 | IDENTITYUPD\_OFF & String &\\ |
| 1570 | IDENTITYUPD\_ON & String &\\ |
| 1571 | ISOLATION & Unsigned & 0, 1 or 3\\ |
| 1572 | NATLANG & String/NULL & Use NULL for default\\ |
| 1573 | NOCOUNT & Boolean &\\ |
| 1574 | NOEXEC & Boolean &\\ |
| 1575 | PARSEONLY & Boolean &\\ |
| 1576 | QUOTED\_IDENT & Boolean &\\ |
| 1577 | RESTREES & Boolean &\\ |
| 1578 | ROWCOUNT & Unsigned &\\ |
| 1579 | SHOWPLAN & Boolean & Use at your own risk\\ |
| 1580 | STATS\_IO & Boolean &\\ |
| 1581 | STATS\_TIME & Boolean &\\ |
| 1582 | STR\_RTRUNC & Boolean &\\ |
| 1583 | TEXTSIZE & Unsigned &\\ |
| 1584 | TRUNCIGNORE & Boolean &\\ |
| 1585 | \caption{Sybase Option Names}\label{t:syonames}
|
| 1586 | \end{longtable}
|
| 1587 | |
| 1588 | Keep in mind that not all option settings will be compatible for use |
| 1589 | with APQ. Changing server date formats\index{date formats} to anything other than year-month-day
|
| 1590 | format, is likely to cause problems within APQ, for example. |
| 1591 | |
| 1592 | |
| 1593 | \subsection{Procedure Set\_Notice\_Proc}
|
| 1594 | |
| 1595 | The PostgreSQL\index{PostgreSQL} database
|
| 1596 | \footnote{The Set\_Notice\_Proc procedure is not available with MySQL.}
|
| 1597 | server sends notice\index{notice messages} messages back to the libpq\index{libpq} C library\index{library}, that the
|
| 1598 | APQ binding uses. These are received by a callback\index{callback}, after certain
|
| 1599 | database operations have been completed. While the messages are saved |
| 1600 | in the Connection\_Type object (see also \Ref{Function Notice_Message}),
|
| 1601 | they overwrite each other as each new message comes in. For this reason, |
| 1602 | it may be desireable for some applications to also receive a callback, |
| 1603 | so that they can process the messages without losing them. The most |
| 1604 | common reason to do this is to simply display them on standard error\index{standard error}.
|
| 1605 | |
| 1606 | The callback\index{callback}\index{Set\_Notice\_Proc} procedure must be defined as follows:
|
| 1607 | \marginpar{The default setting for any new Connection\_Type object is No\_Notify.}
|
| 1608 | |
| 1609 | \begin{Code}
|
| 1610 | procedure Notice_Callback( |
| 1611 | C : in out Connection_Type; |
| 1612 | Message : in String |
| 1613 | ); |
| 1614 | \end{Code}
|
| 1615 | |
| 1616 | The Set\_Notice\_Proc takes an argument named Notify\_Proc\index{Notify\_Proc} that is
|
| 1617 | of the following type: |
| 1618 | |
| 1619 | \begin{Code}
|
| 1620 | type Notify_Proc_Type is access |
| 1621 | procedure( |
| 1622 | C : in out Connection_Type; |
| 1623 | Message : in String |
| 1624 | ); |
| 1625 | \end{Code}
|
| 1626 | |
| 1627 | Finally, the Set\_Notice\_Proc procedure has the following calling signature: |
| 1628 | \marginpar{Note that the Reset or Disconnect call will clear any
|
| 1629 | registered Notify procedure.} |
| 1630 | |
| 1631 | \begin{Code}
|
| 1632 | procedure Set_Notice_Proc( |
| 1633 | C : in out Connection_Type; |
| 1634 | Notify_Proc : in Notify_Proc_Type |
| 1635 | ); |
| 1636 | \end{Code}
|
| 1637 | |
| 1638 | This call can be made at any time to change the Notify\index{notify procedure} procedure.
|
| 1639 | The object may or may not be connected\index{connected}. The new procedure takes effect
|
| 1640 | immediately upon return, and will be used when the object is connected. |
| 1641 | The present implementation only maintains one such procedure.% |
| 1642 | \footnote{Note that the replaced procedure is not returned. A future implementation
|
| 1643 | of APQ may address this.% |
| 1644 | } |
| 1645 | |
| 1646 | |
| 1647 | \subsubsection{Disabling Notify}
|
| 1648 | |
| 1649 | The APQ\-.PostgreSQL\-.Client\index{APQ\-.PostgreSQL\-.Client} package
|
| 1650 | provides the special constant No\_Notify\index{No\_Notify}
|
| 1651 | for the application programmer to use. An example of disabling notification\index{disabling notification}
|
| 1652 | follows: |
| 1653 | |
| 1654 | \begin{Example}
|
| 1655 | declare |
| 1656 | C : Connection_Type; |
| 1657 | begin |
| 1658 | ... |
| 1659 | -- Enable notify processing |
| 1660 | Set_Notify_Proc(C,My_Notify'Access); |
| 1661 | ... |
| 1662 | -- Disable notification |
| 1663 | Set_Notify_Proc(C,No_Notify); |
| 1664 | \end{Example}
|
| 1665 | |
| 1666 | \subsubsection{Using Standard\_Error\_Notify}
|
| 1667 | |
| 1668 | During the debugging\index{debugging} phase of a database application, it may be useful
|
| 1669 | to simply have the notice messages\index{notice messages} printed on Standard\_Error\index{Standard\_Error}. To
|
| 1670 | do this, simply provide the access constant Standard\_Error\_Notify\index{Standard\_Error\_Notify}
|
| 1671 | as the second argument: |
| 1672 | |
| 1673 | \begin{Example}
|
| 1674 | declare |
| 1675 | C : Connection_Type; |
| 1676 | begin |
| 1677 | ... |
| 1678 | -- Send notices to stderr |
| 1679 | Set_Notify_Proc(C,Standard_Error_Notify); |
| 1680 | ... |
| 1681 | \end{Example}
|
| 1682 | |
| 1683 | \section{Connection Operations}
|
| 1684 | |
| 1685 | The APQ binding provides three primitives for connecting\index{connecting} and disconnecting\index{disconnecting}
|
| 1686 | from the database server. They are summarized in Table~\ref{t:conprims}.
|
| 1687 | |
| 1688 | \begin{table}
|
| 1689 | \begin{center}
|
| 1690 | \begin{tabular}{lll}
|
| 1691 | Type & Name & Purpose\\ |
| 1692 | \hline |
| 1693 | proc & Connect & Connect to the database server\\ |
| 1694 | proc & Disconnect & Disconnect from the database server\\ |
| 1695 | proc & Reset & Disconnect if connected\\ |
| 1696 | \end{tabular}
|
| 1697 | \end{center}
|
| 1698 | \caption{APQ Connection Primitives}\label{t:conprims}
|
| 1699 | \end{table}
|
| 1700 | |
| 1701 | \subsection{Procedure Connect}
|
| 1702 | |
| 1703 | This primitive initiates a connection attempt with the database server |
| 1704 | as configured by the \Ref{Context_Setting_Operations} primitives.
|
| 1705 | If the connection succeeds, the procedure call returns\index{Connect}
|
| 1706 | successfully, leaving the Connection\_Type object in a connected state. |
| 1707 | |
| 1708 | |
| 1709 | \begin{Code}
|
| 1710 | procedure Connect( |
| 1711 | C : in out Connection_Type |
| 1712 | ); |
| 1713 | \end{Code}
|
| 1714 | |
| 1715 | \begin{table}
|
| 1716 | \begin{center}
|
| 1717 | \begin{tabular}{ll}
|
| 1718 | Exception Name & Reason\\ |
| 1719 | \hline |
| 1720 | Not\_Connected & The connection attempt failed\\ |
| 1721 | Already\_Connected & There is already a connection\\ |
| 1722 | Failed & One or more configured options failed\\ |
| 1723 | Use\_Error & Connection OK, but USE database failed\\ |
| 1724 | \end{tabular}
|
| 1725 | \end{center}
|
| 1726 | \caption{Connect Exceptions}\label{t:conx}
|
| 1727 | \end{table}
|
| 1728 | |
| 1729 | Table~\ref{t:conx} summarizes the exceptions that Connect may raise.
|
| 1730 | |
| 1731 | The Already\_Connected\index{Already\_Connected} exception indicates that you need to disconnect
|
| 1732 | first, or use another Connection\_Type object if you are maintaining |
| 1733 | multiple connections\index{connections, multiple}. Failed will be raised if a pending option setting
|
| 1734 | is unsupported or its setting has been rejected. The exception Use\_Error\index{Use\_Error}
|
| 1735 | indicates that the connection itself succeeded, but the selection |
| 1736 | of the database failed. The connection will be returned in an unconnected\index{unconnected}
|
| 1737 | state when Use\_Error is raised. |
| 1738 | |
| 1739 | \begin{description}
|
| 1740 | \item[PostgreSQL Note:] \index{PostgreSQL}The Connect primitive as of APQ 1.91 automatically executes a 'SET
|
| 1741 | DATESTYLE TO ISO' \index{ISO}\index{DATESTYLE} command to guarantee that the APQ date routines
|
| 1742 | will function correctly, even when the PGDATESTYLE\index{PGDATESTYLE} environment variable
|
| 1743 | may choose something other than ISO. This implies however, that APQ |
| 1744 | applications should always format date information in the ISO format. |
| 1745 | \item[MySQL Note:]When MySQL\index{MySQL} returns dates in YYYYMMDD\index{YYYYMMDD} format, APQ
|
| 1746 | will automatically make the necessary adjustment, based upon the length |
| 1747 | of the result. |
| 1748 | \end{description}
|
| 1749 | |
| 1750 | The following is an example call: |
| 1751 | |
| 1752 | \begin{Example}
|
| 1753 | declare |
| 1754 | C : Connection_Type; |
| 1755 | begin |
| 1756 | ... |
| 1757 | begin |
| 1758 | Connect(C); |
| 1759 | exception |
| 1760 | when No_Connection => |
| 1761 | -- Handle connection failure |
| 1762 | when Already_Connected => |
| 1763 | ...; -- Indicates program logic problem |
| 1764 | when others => |
| 1765 | raise; |
| 1766 | end; |
| 1767 | \end{Example}
|
| 1768 | |
| 1769 | \subsection{Connection Cloning\label{Connection Cloning}}
|
| 1770 | |
| 1771 | Application writers may want additional connections cloned\index{cloning connections} from a
|
| 1772 | given connection. A web server may want to do this for example. This |
| 1773 | could be performed by obtaining all of the connection information |
| 1774 | from the given connection and then proceed to configure a new connection, |
| 1775 | but this is tedious and error prone. To clone a new connection from |
| 1776 | an existing connection, simply use the Connect\index{Connect} primitive with the
|
| 1777 | following calling signature (argument Same\_As is added): |
| 1778 | |
| 1779 | \begin{Code}
|
| 1780 | procedure Connect( |
| 1781 | C : in out Connection_Type; |
| 1782 | Same_As : in Connection_Type |
| 1783 | ); |
| 1784 | \end{Code}
|
| 1785 | |
| 1786 | This primitive configures object C to use the same parameters as object |
| 1787 | Same\_As\index{Same\_As}. It then creates a connection to the database using these cloned\index{cloned}
|
| 1788 | parameters. The exceptions that may be raised are listed in Table~\ref{t:cclonx}.
|
| 1789 | |
| 1790 | \begin{table}
|
| 1791 | \begin{center}
|
| 1792 | \begin{tabular}{ll}
|
| 1793 | Exception Name & Reason\\ |
| 1794 | \hline |
| 1795 | Not\_Connected & The connection attempt failed\\ |
| 1796 | Already\_Connected & There is already a connection\\ |
| 1797 | \end{tabular}
|
| 1798 | \end{center}
|
| 1799 | \caption{Connection Cloning Exceptions}\label{t:cclonx}
|
| 1800 | \end{table}
|
| 1801 | |
| 1802 | The Not\_Connected\index{Not\_Connected} exception can be raised if the Same\_As connection
|
| 1803 | is not connected (it must be connected). This same exception can be |
| 1804 | raised if the new connection fails (this should rarely happen unless |
| 1805 | your database is suddenly taken down or a network failure occurs). |
| 1806 | The Already\_Connected\index{Already\_Connected} exception is raised if \emph{C} is already
|
| 1807 | connected. |
| 1808 | |
| 1809 | \begin{description}
|
| 1810 | \item[Note:] Note that the trace settings of the Same\_As object are not |
| 1811 | carried to the new object C. You must manually configure any trace |
| 1812 | settings you require in the newly connected object C. |
| 1813 | \end{description}
|
| 1814 | |
| 1815 | The following example shows how a procedure My\_Subr can clone |
| 1816 | a new connection: |
| 1817 | |
| 1818 | \begin{Example}
|
| 1819 | procedure My_Subr(C : Connection_Type) is |
| 1820 | C2 : Connection_Type; |
| 1821 | begin |
| 1822 | Connect(C2,C); -- Clone a connection |
| 1823 | \end{Example}
|
| 1824 | |
| 1825 | \subsection{Procedure Disconnect}
|
| 1826 | |
| 1827 | The Disconnect\index{Disconnect} primitive closes the connection that was previously
|
| 1828 | established in the Connection\_Type\index{Connection\_Type} object. The Disconnect primitive
|
| 1829 | uses the following arguments: |
| 1830 | |
| 1831 | \begin{Code}
|
| 1832 | procedure Disconnect( |
| 1833 | C : in out Connection_Type |
| 1834 | ); |
| 1835 | \end{Code}
|
| 1836 | |
| 1837 | The list of possible exceptions for Disconnect are illustrated in Table~\ref{t:dconx}.
|
| 1838 | |
| 1839 | \begin{table}
|
| 1840 | \begin{center}
|
| 1841 | \begin{tabular}{ll}
|
| 1842 | Exception Name & Reason\\ |
| 1843 | \hline |
| 1844 | No\_Connection & There is no connection to disconnect\index{No\_Connection}\\
|
| 1845 | \end{tabular}
|
| 1846 | \end{center}
|
| 1847 | \caption{Disconnect Exceptions}\label{t:dconx}
|
| 1848 | \end{table}
|
| 1849 | |
| 1850 | The following code fragment shows the procedure call in action: |
| 1851 | |
| 1852 | \begin{Example}
|
| 1853 | declare |
| 1854 | C : Connection_Type; |
| 1855 | begin |
| 1856 | ... |
| 1857 | begin |
| 1858 | Disconnect(C); |
| 1859 | exception |
| 1860 | when No_Connection => |
| 1861 | ...; -- Indicates program logic problem |
| 1862 | when others => |
| 1863 | raise; |
| 1864 | end; |
| 1865 | \end{Example}
|
| 1866 | |
| 1867 | \subsection{Procedure Reset}
|
| 1868 | |
| 1869 | The Reset\index{Reset} primitive is provided so that the programmer can recycle
|
| 1870 | the Connection\_Type object for use in a subsequent connection. Without |
| 1871 | this primitive, the user would need to destroy the original and create |
| 1872 | a new Connection\_Type. The Reset primitive accepts the following |
| 1873 | arguments: |
| 1874 | |
| 1875 | \begin{Code}
|
| 1876 | procedure Reset( |
| 1877 | C : in out Connection_Type |
| 1878 | ); |
| 1879 | \end{Code}
|
| 1880 | |
| 1881 | In addition to closing the current connection, if it is open, the |
| 1882 | notification procedure is also deregistered (if there was a Set\_Notify\_Proc\index{Set\_Notify\_Proc}
|
| 1883 | performed). |
| 1884 | |
| 1885 | No exceptions should occur. If there is a connection pending\index{pending connection}, it is
|
| 1886 | disconnected\index{disconnected}. If there is no connection pending, the call is ignored.
|
| 1887 | The following shows an example of its use: |
| 1888 | |
| 1889 | \begin{Example}
|
| 1890 | declare |
| 1891 | C : Connection_Type; |
| 1892 | begin |
| 1893 | ... |
| 1894 | Reset(C); -- C is now ready for re-use |
| 1895 | \end{Example}
|
| 1896 | |
| 1897 | \section{Connection Information Operations}
|
| 1898 | |
| 1899 | A modular\index{modular software} piece of software may get handed a Connection\_Type object
|
| 1900 | as a parameter, and have a need to inquire about the details of the |
| 1901 | provided connection. The function primitives that return information |
| 1902 | about the connection are listed in Table~\ref{t:cinfp}.
|
| 1903 | |
| 1904 | \begin{table}
|
| 1905 | \begin{center}
|
| 1906 | \begin{tabular}{ll}
|
| 1907 | Function Name & Information Returned\\ |
| 1908 | \hline |
| 1909 | Host\_Name & Host name of the connection\\ |
| 1910 | Port & Port Number or Port Pathname\\ |
| 1911 | DB\_Name & Database name\\ |
| 1912 | User & User name for the database\\ |
| 1913 | Password & Password for the database\\ |
| 1914 | Instance & Instance name for the database\\ |
| 1915 | Options & Database option parameters\\ |
| 1916 | \end{tabular}
|
| 1917 | \end{center}
|
| 1918 | \caption{Connection Information Primitives}\label{t:cinfp}
|
| 1919 | \end{table}
|
| 1920 | |
| 1921 | These function primitive specifications are listed below: |
| 1922 | |
| 1923 | \begin{Code}
|
| 1924 | function Host_Name( |
| 1925 | C : Connection_Type; |
| 1926 | ) return String; |
| 1927 | \end{Code}
|
| 1928 | |
| 1929 | \begin{Code}
|
| 1930 | function Port( |
| 1931 | C : Connection_Type; |
| 1932 | ) return String; -- UNIX path |
| 1933 | \end{Code}
|
| 1934 | |
| 1935 | \begin{Code}
|
| 1936 | function Port( |
| 1937 | C : Connection_Type; |
| 1938 | ) return Integer; -- TCP/IP port |
| 1939 | \end{Code}
|
| 1940 | |
| 1941 | \begin{Code}
|
| 1942 | function DB_Name( |
| 1943 | C : Connection_Type; |
| 1944 | ) return String; |
| 1945 | \end{Code}
|
| 1946 | |
| 1947 | \begin{Code}
|
| 1948 | function User( |
| 1949 | C : Connection_Type; |
| 1950 | ) return String; |
| 1951 | \end{Code}
|
| 1952 | |
| 1953 | \begin{Code}
|
| 1954 | function Password( |
| 1955 | C : Connection_Type; |
| 1956 | ) return String; |
| 1957 | \end{Code}
|
| 1958 | |
| 1959 | \begin{Code}
|
| 1960 | function Instance( |
| 1961 | C : Connection_Type; |
| 1962 | ) return String; |
| 1963 | \end{Code}
|
| 1964 | |
| 1965 | \begin{Code}
|
| 1966 | function Options( |
| 1967 | C : Connection_Type; |
| 1968 | ) return String; |
| 1969 | \end{Code}
|
| 1970 | |
| 1971 | The Port\index{Port} primitive that returns a String is for use with database
|
| 1972 | connections using a UNIX socket\index{UNIX socket}\index{local socket}. The socket
|
| 1973 | pathname\index{pathname} is returned in this case.
|
| 1974 | \footnote{or at least a fragment of the pathname.}
|
| 1975 | |
| 1976 | When called on Connection\_Type objects without a current connection, |
| 1977 | an empty string\index{string, empty} is returned for any value that has not been configured
|
| 1978 | (for example if Set\-\_Host\-\_Name\index{Set\_Host\_Name} has not been called, Host\-\_Name\index{Host\_Name} will
|
| 1979 | return ""). If the value has been set, then that value is returned |
| 1980 | as expected. Once the Connection\-\_Type object is connected to the |
| 1981 | database however, the values will be values fetched from the library\index{library}
|
| 1982 | libpq\index{libpq} instead.
|
| 1983 | \footnote{Normally, these values should agree with what was configured.}
|
| 1984 | |
| 1985 | The following code sample shows how to extract the host name\index{host name} and database
|
| 1986 | name for the current connection. |
| 1987 | |
| 1988 | \begin{Example}
|
| 1989 | procedure My_Code(C : in out Connection_Type) is |
| 1990 | Host_Name : String := Host_Name(C); |
| 1991 | Database_Name : String := DB_Name(C); |
| 1992 | begin |
| 1993 | ... |
| 1994 | \end{Example}
|
| 1995 | |
| 1996 | \begin{description}
|
| 1997 | \item [Sybase Note:]The Instance function primitive was added to APQ support Sybase. |
| 1998 | See the support level chart for Set\_Instance\index{Set\_Instance} on page \pageref{Set_Instance Support Chart}
|
| 1999 | and other information primitives. Note also that setting and retrieving |
| 2000 | other parameters is possible in some cases, even though the information |
| 2001 | is ignored by Sybase. |
| 2002 | \end{description}
|
| 2003 | |
| 2004 | \section{General Information Operations}
|
| 2005 | |
| 2006 | Due to the modular construction of software, it is sometimes necessary |
| 2007 | to query an object for its present state. The primitives listed in Table~\ref{t:gifc}
|
| 2008 | for the Connection\_Type object are available for querying the state\index{query the state}
|
| 2009 | of the object. These are discussed in the next subsections. |
| 2010 | |
| 2011 | \begin{table}
|
| 2012 | \begin{center}
|
| 2013 | \begin{tabular}{lll}
|
| 2014 | Type & Name & Purpose\\ |
| 2015 | \hline |
| 2016 | func & Is\_Connected & Indicates connected state\\ |
| 2017 | func & Error\_Message & Returns a error message text\\ |
| 2018 | \end{tabular}
|
| 2019 | \end{center}
|
| 2020 | \caption{General Information for Connections}\label{t:gifc}
|
| 2021 | \end{table}
|
| 2022 | |
| 2023 | \subsection{Function Is\_Connected}
|
| 2024 | |
| 2025 | The Is\_Connected\index{Is\_Connected} function returns a Boolean result that indicates
|
| 2026 | the present state of the Connection\_Type object. The arguments are |
| 2027 | as follows: |
| 2028 | |
| 2029 | \begin{Code}
|
| 2030 | function Is_Connected( |
| 2031 | C : Connection_Type |
| 2032 | ) return Boolean; |
| 2033 | \end{Code}
|
| 2034 | |
| 2035 | There are no exceptions raised by this primitive. |
| 2036 | |
| 2037 | The following example shows how to test if the object C is currently |
| 2038 | supporting a connection. The example disconnects from the server, |
| 2039 | if it determines that C is connected. |
| 2040 | |
| 2041 | \begin{Example}
|
| 2042 | declare |
| 2043 | C : Connection_Type; |
| 2044 | begin |
| 2045 | ... |
| 2046 | if Is_Connected(C) then |
| 2047 | Disconnect(C); |
| 2048 | ... |
| 2049 | \end{Example}
|
| 2050 | |
| 2051 | \subsection{Function Error\_Message}
|
| 2052 | |
| 2053 | The Error\_Message\index{Error\_Message} function makes it possible for the application
|
| 2054 | to report why the connection failed. This information is often crucial |
| 2055 | to the user of a failed application. The arguments accepted are as |
| 2056 | follows: |
| 2057 | |
| 2058 | \begin{Code}
|
| 2059 | function Error_Message( |
| 2060 | C : Connection_Type |
| 2061 | ) return String; |
| 2062 | \end{Code}
|
| 2063 | |
| 2064 | There are no exceptions raised by this function. If there is no present |
| 2065 | connection or no present error to report, the null string is returned. |
| 2066 | The following example shows how the connection failure is reported: |
| 2067 | |
| 2068 | \begin{Example}
|
| 2069 | with Ada.Text_IO; |
| 2070 | ... |
| 2071 | declare |
| 2072 | use Ada.Text_IO; |
| 2073 | |
| 2074 | C : Connection_Type; |
| 2075 | begin |
| 2076 | ... |
| 2077 | begin |
| 2078 | Connect(C); |
| 2079 | exception |
| 2080 | when No_Connection => |
| 2081 | Put_Line(Standard_Error,"Connection Failed!"); |
| 2082 | Put_Line(Standard_Error,Error_Message(C)); |
| 2083 | ... |
| 2084 | when Already_Connected => |
| 2085 | ...; -- Program logic error here |
| 2086 | when others => |
| 2087 | raise; |
| 2088 | end; |
| 2089 | \end{Example}
|
| 2090 | |
| 2091 | \subsection{Function Notice\_Message\label{Function Notice_Message}}
|
| 2092 | |
| 2093 | The C libpq\index{libpq} interface library\index{library}\footnote{The Notice\_Message function is
|
| 2094 | not available for MySQL.} provides the APQ binding with certain |
| 2095 | notification messages\index{notification messages} during some calls, by means of a callback\index{callback}. Each
|
| 2096 | time one of these notifications is received from the database server, |
| 2097 | the notification message is saved in the Connection\_Type object |
| 2098 | (replacing any former notice message). The last notification message |
| 2099 | received can be retreived using the Notice\_Message\index{Notice\_Message} function:
|
| 2100 | |
| 2101 | \begin{Code}
|
| 2102 | function Notice_Message( |
| 2103 | C : Connection_Type |
| 2104 | ) return String; |
| 2105 | \end{Code}
|
| 2106 | |
| 2107 | No exception is raised, and the null string\index{null string} is returned if no notice
|
| 2108 | message has been registered. |
| 2109 | |
| 2110 | The following example illustrates one example of the Notice\_Message |
| 2111 | function: |
| 2112 | |
| 2113 | \begin{Example}
|
| 2114 | with Ada.Text_IO; |
| 2115 | ... |
| 2116 | declare |
| 2117 | use Ada.Text_IO; |
| 2118 | |
| 2119 | C : Connection_Type; |
| 2120 | begin |
| 2121 | ... |
| 2122 | declare |
| 2123 | Msg : String := Notice_Message(C); |
| 2124 | begin |
| 2125 | if Msg'Length > 0 then |
| 2126 | Put_Line(Standard_Error,Msg); |
| 2127 | ... |
| 2128 | \end{Example}
|
| 2129 | |
| 2130 | \subsection{In\_Abort\_State Function\label{In_Abort_State Function}}
|
| 2131 | |
| 2132 | \Ref{Abort_State exception} documents the Abort\_State\index{Abort\_State}
|
| 2133 | exception, which is unique to PostgreSQL\index{PostgreSQL}. This exception is raised in
|
| 2134 | response to a status flag stored in the |
| 2135 | APQ\-.PostgreSQL\-.Client\-.Connection\_Type object. When a transaction is |
| 2136 | started, any SQL error\index{SQL error} will put the PostgreSQL database server into an
|
| 2137 | ``\emph{abort state}'', where all current and future commands will be
|
| 2138 | ignored, for the connection \footnote{MySQL does not support this
|
| 2139 | concept, and so it does not go into an abort state.}. To permit the |
| 2140 | application programmer to query this status, the In\_Abort\_State\index{In\_Abort\_State}
|
| 2141 | function can be used. It returns True, if an error has occurred within a |
| 2142 | transaction, which requires a Rollback\_Work (\Ref{Begin, Commit and Rollback Work functions})
|
| 2143 | call to clear this state. The calling |
| 2144 | requirements are summarized in the following table: |
| 2145 | |
| 2146 | \begin{Code}
|
| 2147 | function In_Abort_State( |
| 2148 | C : Connection_Type |
| 2149 | ) return Boolean; |
| 2150 | \end{Code}
|
| 2151 | |
| 2152 | Exceptions for In\_Abort\_State are summarized in Table~\ref{t:iasx}.
|
| 2153 | |
| 2154 | \begin{table}
|
| 2155 | \begin{center}
|
| 2156 | \begin{tabular}{ll}
|
| 2157 | Exception Name & Reason\\ |
| 2158 | \hline |
| 2159 | Not\_Connected & There is no connection to query\\ |
| 2160 | \end{tabular}
|
| 2161 | \end{center}
|
| 2162 | \caption{In\_Abort\_State Exceptions}\label{t:iasx}
|
| 2163 | \end{table}
|
| 2164 | |
| 2165 | The following example shows how this function might be used: |
| 2166 | |
| 2167 | \begin{Example}
|
| 2168 | declare |
| 2169 | C : Connection_Type; |
| 2170 | Q : Query_Type; |
| 2171 | begin |
| 2172 | ... |
| 2173 | Begin_Work(Q,C); |
| 2174 | ... |
| 2175 | Execute(Q,C); |
| 2176 | ... |
| 2177 | if In_Abort_State(C) then |
| 2178 | Rollback(Q,C); |
| 2179 | ... |
| 2180 | end if; |
| 2181 | \end{Example}
|
| 2182 | |
| 2183 | \section{Implicit Operations}
|
| 2184 | |
| 2185 | There are a few implicit operations\index{implicit operations} that are performed that the programmer
|
| 2186 | should be aware of. They are: |
| 2187 | |
| 2188 | \begin{itemize}
|
| 2189 | \item The Connection\_Type is subject to Finalization |
| 2190 | \item A default Commit/Rollback operation can occur at Finalization |
| 2191 | \end{itemize}
|
| 2192 | |
| 2193 | The programmer is encouraged to call Commit\_Work\index{Commit\_Work} or Rollback\_Work\index{Rollback\_Work}
|
| 2194 | explicitly, whenever possible. This way, the programmer is in complete |
| 2195 | control of the transaction outcome. |
| 2196 | |
| 2197 | If a transaction has not been committed or rolled back, and the connected |
| 2198 | Connection\_Type object is finalized\index{finalization}%
|
| 2199 | \footnote{Usually because the Connection\_Type object has fallen out of scope.%
|
| 2200 | }, then the default action for commit or rollback occurs. The default |
| 2201 | for the APQ binding is to rollback the transaction, when the connection |
| 2202 | is still active. If the programmer has disconnected\index{disconnected} from the database
|
| 2203 | prior to finalization, then no further action occurs. To change or |
| 2204 | control the default action, use the Set\_Rollback\_On\_Finalize\index{Set\_Rollback\_On\_Finalize} procedure
|
| 2205 | described in the next section. |
| 2206 | |
| 2207 | |
| 2208 | \subsection{Set\_Rollback\_On\_Finalize Procedure\label{Set_Rollback_On_Finalize Procedure}}
|
| 2209 | |
| 2210 | The Set\_Rollback\_On\_Finalize primitive allows the programmer to |
| 2211 | change the default action for the Connection\_Type object. The calling |
| 2212 | requirements are summarized in the following table:% |
| 2213 | |
| 2214 | \begin{Code}
|
| 2215 | procedure Set_Rollback_On_Finalize( |
| 2216 | C : in out Connection_Type; |
| 2217 | Rollback : in Boolean |
| 2218 | ); |
| 2219 | \end{Code}
|
| 2220 | |
| 2221 | To change the default to COMMIT WORK\index{COMMIT WORK} when the Connection\_Type object
|
| 2222 | finalizes, peform the following call: |
| 2223 | |
| 2224 | \begin{Example}
|
| 2225 | declare |
| 2226 | C : Connection_Type; |
| 2227 | begin |
| 2228 | Set_Rollback_On_Finalize(C,False); -- Commit on Finalize |
| 2229 | \end{Example}
|
| 2230 | |
| 2231 | \subsection{Will\_Rollback\_On\_Finalize Function\label{Will_Rollback_On_Finalize Function}}
|
| 2232 | |
| 2233 | Programs sometimes need to inquire about the state of the Connection\_Type |
| 2234 | object that they may have been passed. To inquire about the commit |
| 2235 | or rollback default, the Will\_Rollback\_On\_Finalize\index{Will\_Rollback\_On\_Finalize} function can
|
| 2236 | be called. The following table summarizes the calling requirements: |
| 2237 | |
| 2238 | \begin{Code}
|
| 2239 | function Will_Rollback_On_Finalize( |
| 2240 | C : Connection_Type |
| 2241 | ) return Boolean; |
| 2242 | \end{Code}
|
| 2243 | |
| 2244 | \section{Trace Facilities\label{Trace Facilities}}
|
| 2245 | |
| 2246 | No matter how carefully a programmer writes a new program, problems |
| 2247 | develop that are often difficult to understand. Good tracing facilities\index{trace facilities}
|
| 2248 | allow the problem to be quickly understood and corrected. |
| 2249 | |
| 2250 | To gain trace support using APQ, it is only necessary to perform the |
| 2251 | following steps: |
| 2252 | |
| 2253 | \begin{enumerate}
|
| 2254 | \item Open a trace capture file with Open\_DB\_Trace |
| 2255 | \item Optionally enable/disable tracing at various points in the program |
| 2256 | with Set\_Trace% |
| 2257 | \footnote{Tracing is enabled by default after a Open\_DB\_Trace call.}
|
| 2258 | \item Perform your SQL operations |
| 2259 | \item Close the trace capture file with Close\_DB\_Trace% |
| 2260 | \footnote{Or allow it to be closed when the Connection\_Type object is finalized.}
|
| 2261 | \end{enumerate}
|
| 2262 | |
| 2263 | The Open\_DB\_Trace\index{Open\_DB\_Trace} procedure takes a Trace\_Mode\_Type\index{Trace\_Mode\_Type} parameter
|
| 2264 | that decides what trace content is being collected. The valid enumerated |
| 2265 | choices are listed in Table~\ref{t:tmchoic}.
|
| 2266 | |
| 2267 | \begin{table}
|
| 2268 | \begin{center}
|
| 2269 | \begin{tabular}{ll}
|
| 2270 | Value & Description\\ |
| 2271 | \hline |
| 2272 | APQ.Trace\_None & Collect no trace information (no file is written/created)\\ |
| 2273 | APQ.Trace\_DB & Collect only C library trace information% |
| 2274 | \footnote{Prior to APQ 2.0, this was Trace\_libpq.}\\
|
| 2275 | APQ.Trace\_APQ & Collect only APQ SQL trace information\\ |
| 2276 | APQ.Trace\_Full & Collect both database library and Trace\_APQ information\\ |
| 2277 | \end{tabular}
|
| 2278 | \end{center}
|
| 2279 | \caption{Trace\_Mode\_Type Choices}\label{t:tmchoic}
|
| 2280 | \end{table}
|
| 2281 | |
| 2282 | The Trace\_None\index{Trace\_None} value is provided so that the Open\_DB\_Trace procedure
|
| 2283 | does not need to be coded around if a trace variable is supplied, |
| 2284 | which may or may not request tracing. Close\_DB\_Trace\index{Close\_DB\_Trace} can be called
|
| 2285 | on a Connection\_Type\index{Connection\_Type} for which Trace\_None is in effect, without
|
| 2286 | any exception being thrown (the call is ignored). |
| 2287 | |
| 2288 | Trace\_DB\index{Trace\_DB} provides only what the C library (libpq\index{libpq} for PostgreSQL\index{PostgreSQL})
|
| 2289 | provides. This may be useful to the database software maintainers, |
| 2290 | if they want a trace of the activity that you are reporting problems |
| 2291 | with. |
| 2292 | |
| 2293 | Trace\_APQ\index{Trace\_APQ} is what the author considers to be the most useful output
|
| 2294 | format to an APQ developer. The trace output in this mode is such |
| 2295 | that the extra trace information is provided in SQL comment\index{SQL comment} form.
|
| 2296 | The actual queries that are executed are in their natural SQL form. |
| 2297 | The captured Trace\_APQ trace then, is in a format that can be played |
| 2298 | back, reproducing exactly what the application performed.% |
| 2299 | \footnote{There are limitations however, since the blob functions are not traced
|
| 2300 | at the present release.% |
| 2301 | } The full trace or portions of it then can be used to help debug SQL |
| 2302 | related problems. |
| 2303 | |
| 2304 | The following shows a sample of what the Trace\_APQ output looks like: |
| 2305 | |
| 2306 | \begin{SQL}
|
| 2307 | -- Start of Trace, Mode=TRACE_APQ |
| 2308 | -- SQL QUERY: |
| 2309 | BEGIN~WORK} |
| 2310 | ; |
| 2311 | -- Result: 'BEGIN' |
| 2312 | |
| 2313 | -- SQL QUERY: |
| 2314 | INSERT INTO DOCUMENT |
| 2315 | (NAME,DOCDATE,BLOBID,CREATED,MODIFIED,ACCESSED) |
| 2316 | VALUES ('compile.adb','2002-08-12~21:09:25',3339004,
|
| 2317 | '2002-08-12~21:59:48','2002-08-12~21:09:25', |
| 2318 | '2002-08-19~22:11:36') |
| 2319 | ; |
| 2320 | -- Result: 'INSERT 3339005 1' |
| 2321 | |
| 2322 | -- SQL QUERY: |
| 2323 | SELECT DOCID |
| 2324 | FROM DOCUMENT |
| 2325 | WHERE OID = 3339005 |
| 2326 | ; |
| 2327 | -- Result: 'SELECT' |
| 2328 | ... |
| 2329 | -- SQL QUERY: |
| 2330 | COMMIT WORK |
| 2331 | ; |
| 2332 | -- Result: 'COMMIT' |
| 2333 | -- End of Trace. |
| 2334 | \end{SQL}
|
| 2335 | |
| 2336 | The following subsections describe the primitives that provide support |
| 2337 | for trace facilities. |
| 2338 | |
| 2339 | |
| 2340 | \subsection{Procedure Open\_DB\_Trace}
|
| 2341 | |
| 2342 | To start any capture of trace\index{trace capture} information, you must specify the name
|
| 2343 | of the text file to be written to. The file must be writable to the |
| 2344 | current process. The Connection\_Type object must be connected prior |
| 2345 | to calling Open\_DB\_Trace\index{Open\_DB\_Trace}:
|
| 2346 | |
| 2347 | \begin{Code}
|
| 2348 | procedure Open_DB_Trace( |
| 2349 | C : in out Connection_Type; |
| 2350 | Filename : in String; |
| 2351 | Mode : in Trace_Mode_Type := Trace_APQ |
| 2352 | ); |
| 2353 | \end{Code}
|
| 2354 | |
| 2355 | Table \ref{t:odbtx} lists the possible exceptions for Open\_DB\_Trace.
|
| 2356 | |
| 2357 | \begin{table}
|
| 2358 | \begin{center}
|
| 2359 | \begin{tabular}{ll}
|
| 2360 | Exception Name & Reason\\ |
| 2361 | \hline |
| 2362 | Not\_Connected & There is no connection\\ |
| 2363 | Tracing\_State & Trace is already enabled\\ |
| 2364 | \end{tabular}
|
| 2365 | \end{center}
|
| 2366 | \caption{Open\_DB\_Trace Exceptions}\label{t:odbtx}
|
| 2367 | \end{table}
|
| 2368 | |
| 2369 | Upon return from the Open\_DB\_Trace procedure, a text file will be |
| 2370 | created and ready to have trace entries written to it.% |
| 2371 | \footnote{Note that trace entries are buffered by C standard I/O routines, so
|
| 2372 | trace information may be held in memory buffers before it is flushed |
| 2373 | out or closed.% |
| 2374 | } |
| 2375 | |
| 2376 | The following example shows how a call might be coded: |
| 2377 | |
| 2378 | \begin{Example}
|
| 2379 | declare |
| 2380 | C : Connection_Type; |
| 2381 | begin |
| 2382 | ... |
| 2383 | Open_DB_Trace(C,"./bugs.sql",Trace_APQ); |
| 2384 | \end{Example}
|
| 2385 | |
| 2386 | \subsection{Procedure Close\_DB\_Trace}
|
| 2387 | |
| 2388 | Closing the tracing facility for a connection, suspends all further |
| 2389 | trace writes. Once this has been done, the effect of Set\_Trace\index{Set\_Trace} is
|
| 2390 | superceeded, preventing any further trace information being written. |
| 2391 | The calling requirements are outlined in the following table: |
| 2392 | |
| 2393 | \begin{Code}
|
| 2394 | procedure Close_DB_Trace( |
| 2395 | C : in out Connection_Type |
| 2396 | ); |
| 2397 | \end{Code}
|
| 2398 | |
| 2399 | If the Open\_DB\_Trace call was made with the Mode parameter set to |
| 2400 | Trace\_None, then the call to Close\_DB\_Trace\index{Close\_DB\_Trace} has no effect and is
|
| 2401 | ignored for programmer convenience. |
| 2402 | |
| 2403 | No exceptions are raised. |
| 2404 | |
| 2405 | An example call is shown below: |
| 2406 | |
| 2407 | \begin{Example}
|
| 2408 | declare |
| 2409 | C : Connection_Type; |
| 2410 | begin |
| 2411 | ... |
| 2412 | Open_DB_Trace(C,"./bugs.sql",Trace_APQ); |
| 2413 | ... |
| 2414 | Close_DB_Trace(C); |
| 2415 | \end{Example}
|
| 2416 | |
| 2417 | \subsection{Procedure Set\_Trace}
|
| 2418 | |
| 2419 | In large applications where large numbers of SQL statements are executed, |
| 2420 | it may be desirable to trace only certain parts of its execution in |
| 2421 | a dynamic fashion. The Set\_Trace\index{Set\_Trace} primitive gives the programmer a
|
| 2422 | way to disable and re-enable tracing at strategic\index{strategic tracing} points within the
|
| 2423 | application. The calling requirements are summarized as follows: |
| 2424 | |
| 2425 | \begin{Code}
|
| 2426 | procedure Set_Trace( |
| 2427 | C : in out Connection_Type; |
| 2428 | Trace_On : in Boolean := True |
| 2429 | ); |
| 2430 | \end{Code}
|
| 2431 | |
| 2432 | Tracing is enabled by default, after a successful call to Open\_DB\_Trace |
| 2433 | is made (unless Mode was Trace\_None\index{Trace\_None}).
|
| 2434 | |
| 2435 | There are no exceptions raised. |
| 2436 | |
| 2437 | Note that it is considered safe to invoke Set\_Trace, even if a former |
| 2438 | Open\_DB\_Trace call was not successfully performed, or the trace |
| 2439 | mode was Trace\_None. This allows the application to retain strategic |
| 2440 | Set\_Trace calls without having to remove them, when the Open\_DB\_Trace |
| 2441 | call is disabled% |
| 2442 | \footnote{Setting Mode to Trace\_None effectively disables the trace facility
|
| 2443 | without requiring any code changes.% |
| 2444 | } or commented out. |
| 2445 | |
| 2446 | |
| 2447 | \subsection{Function Is\_Trace}
|
| 2448 | |
| 2449 | It may be helpful to the developer that is tracking down a problem |
| 2450 | to know when tracing is enabled or not. The Is\_Trace\index{Is\_Trace} function returns
|
| 2451 | true when the trace collection file is receiving trace information. |
| 2452 | The calling arguments are listed below:% |
| 2453 | |
| 2454 | Note that the returned value tracks the last value provided by |
| 2455 | Set\_Trace, whether or not an open trace file has been created/opened. |
| 2456 | |
| 2457 | \begin{Code}
|
| 2458 | function Is_Trace( |
| 2459 | C : Connection_Type; |
| 2460 | ) return Boolean; |
| 2461 | \end{Code}
|
| 2462 | |
| 2463 | Note that the initial state of the Connection\_Type object is to have |
| 2464 | Is\_Trace to return True. Also after a successful Open\_DB\_Trace, |
| 2465 | Is\_Trace will return True. |
| 2466 | |
| 2467 | An example showing its use is given below: |
| 2468 | |
| 2469 | \begin{Example}
|
| 2470 | declare |
| 2471 | C : Connection_Type; |
| 2472 | begin |
| 2473 | ... |
| 2474 | Open_DB_Trace(C,"./bugs.sql",Trace_APQ); |
| 2475 | ... |
| 2476 | if Is_Trace(C) then |
| 2477 | -- We are collecting trace info.. |
| 2478 | \end{Example}
|
| 2479 | |
| 2480 | \section{Generic Database Operations}
|
| 2481 | |
| 2482 | APQ 2.0 and later is designed so that all but the most specialized |
| 2483 | database operations, can be performed, given only a Root\_Connection\_Type'Class\index{Root\_Connection\_Type'Class}
|
| 2484 | object (declared in top level package APQ). The following sections |
| 2485 | describe some generic database related primitives that are necessary |
| 2486 | for successful generic database support. |
| 2487 | |
| 2488 | |
| 2489 | \subsection{Package APQ}
|
| 2490 | |
| 2491 | Root object support\index{root object support} is provided in the package APQ\index{APQ, package}. Generic database
|
| 2492 | code will normally only use this package: |
| 2493 | |
| 2494 | \begin{Code}
|
| 2495 | with APQ; |
| 2496 | |
| 2497 | use APQ; -- Optional use clause |
| 2498 | \end{Code}
|
| 2499 | |
| 2500 | The data types that will be used will be: |
| 2501 | |
| 2502 | \begin{itemize}
|
| 2503 | \item APQ.Root\_Connection\_Type'Class |
| 2504 | \item APQ.Root\_Query\_Type'Class\index{Root\_Query\_Type'Class}
|
| 2505 | \end{itemize}
|
| 2506 | |
| 2507 | The generic primitives that will be covered in the next section are: |
| 2508 | |
| 2509 | \begin{itemize}
|
| 2510 | \item APQ.Engine\_Of |
| 2511 | \item APQ.New\_Query |
| 2512 | \end{itemize}
|
| 2513 | |
| 2514 | \subsection{Predicate Engine\_Of\label{Generic Database Engine_Of}}
|
| 2515 | |
| 2516 | Given a Root\_Connection\_Type'Class object, generic database code |
| 2517 | sometimes needs to determine which specific database is being used. |
| 2518 | This allows the code to make special SQL syntax changes, depending |
| 2519 | upon the technology being used (for example, MySQL\index{MySQL} permits the use
|
| 2520 | of a \emph{LIMIT}\index{LIMIT} keyword in queries).
|
| 2521 | |
| 2522 | The Engine\_Of\index{Engine\_Of} primitive (dispatching) will identify the
|
| 2523 | database technology that is being used: |
| 2524 | |
| 2525 | \begin{Code}
|
| 2526 | type Database_Type is ( |
| 2527 | Engine_PostgreSQL, |
| 2528 | Engine_MySQL, |
| 2529 | Engine_Sybase |
| 2530 | ); |
| 2531 | |
| 2532 | function Engine_Of( |
| 2533 | C : Connection_Type |
| 2534 | ) return Database_Type; |
| 2535 | \end{Code}
|
| 2536 | |
| 2537 | The following example code shows how to test if a PostgreSQL\index{PostgreSQL} database
|
| 2538 | is being used: |
| 2539 | |
| 2540 | \begin{Example}
|
| 2541 | with APQ; use APQ; |
| 2542 | ... |
| 2543 | procedure App(C : Root_Connection_Type'Class) is |
| 2544 | begin |
| 2545 | ... |
| 2546 | if Engine_Of(C) = Engine_PostgreSQL then |
| 2547 | ... |
| 2548 | \end{Example}
|
| 2549 | |
| 2550 | \subsection{Primitive New\_Query\label{Query_Type Factories}}
|
| 2551 | |
| 2552 | Normally, an application database procedure will receive a connection |
| 2553 | object as one of its input parameters. Generally, this connection |
| 2554 | is established in the main program and then used by the program components |
| 2555 | as required. However, to pass the parameter in a generic way (allowing |
| 2556 | for polymorphism), you would declare the procedure's argument as receiving |
| 2557 | data type Root\_Connection\_Type'Class. |
| 2558 | |
| 2559 | Within the called procedure however, you will need a Query\_Type object. |
| 2560 | This too could be passed in as an argument, but this is unnecessary. |
| 2561 | At other times, you may need additional Query\_Type objects for temporary |
| 2562 | use. What you need is a convenient way to create a Query\_Type object |
| 2563 | that matches the connection that you have received as a parameter. This |
| 2564 | is done by the New\_Query function\index{New\_Query}.
|
| 2565 | |
| 2566 | If your connection object is a: |
| 2567 | |
| 2568 | \begin{Code}
|
| 2569 | |
| 2570 | APQ.PostgreSQL.Client.Connection_Type |
| 2571 | |
| 2572 | \end{Code}
|
| 2573 | |
| 2574 | object, then your application will want to create a: |
| 2575 | |
| 2576 | \begin{Code}
|
| 2577 | |
| 2578 | APQ.PostgreSQL.Client.Query_Type |
| 2579 | |
| 2580 | \end{Code}
|
| 2581 | |
| 2582 | object. You want to avoid tests like: |
| 2583 | |
| 2584 | \begin{Example}
|
| 2585 | |
| 2586 | if Connection is in APQ.PostgreSQL.Client.Connection_Type then |
| 2587 | ... |
| 2588 | elsif Connection is in APQ.MySQL.Client.Connection_Type then |
| 2589 | ... |
| 2590 | elsif Connection is in APQ.Sybase.Client.Connection_Type then |
| 2591 | ... |
| 2592 | |
| 2593 | \end{Example}
|
| 2594 | |
| 2595 | The above example code would force your portable code to also ``with''\index{with}
|
| 2596 | the following packages: |
| 2597 | |
| 2598 | \begin{Example}
|
| 2599 | with APQ.PostgreSQL.Client; |
| 2600 | with APQ.MySQL.Client; |
| 2601 | ... |
| 2602 | \end{Example}
|
| 2603 | |
| 2604 | which would be very inconvenient and unnecessary. |
| 2605 | |
| 2606 | To make portable\index{portable} database programming easier, APQ provides a dispatching\index{dispatching}
|
| 2607 | Query\_Type object factory primitive that can be used for this purpose. |
| 2608 | For example: |
| 2609 | |
| 2610 | \begin{NumberedExample}
|
| 2611 | with APQ; |
| 2612 | use APQ; |
| 2613 | |
| 2614 | procedure My_Generic_App(C : Root_Connection_Type'Class) is |
| 2615 | Q : Root_Query_Type'Class := New_Query(C);\label{Ex:New_Query_Assgn}
|
| 2616 | begin |
| 2617 | Prepare(Q,"SELECT NAME,INCOME"); |
| 2618 | Append_Line(Q,"FROM~SALARIES"); |
| 2619 | \end{NumberedExample}
|
| 2620 | |
| 2621 | The assignment to Q in line~\ref{Ex:New_Query_Assgn}, shows the
|
| 2622 | application of the primitive New\_Query. This dispatching |
| 2623 | primitive returns the correct Query\_Type object that matches the |
| 2624 | connection that was given. The primitive New\_Query is more formally |
| 2625 | presented as follows: |
| 2626 | |
| 2627 | \begin{Code}
|
| 2628 | function New_Query( |
| 2629 | C : Root_Connection_Type |
| 2630 | ) return Root_Query_Type'Class; |
| 2631 | \end{Code}
|
| 2632 | |
| 2633 | \subsection{Query\_Type Assignment\label{Query_Type Cloning}}
|
| 2634 | |
| 2635 | Prior to APQ version 2.0, the Query\_Type object was a \emph{limited}\index{limited tagged type}
|
| 2636 | tagged type. This meant that the Query\_Type object was never able |
| 2637 | to be assigned to another Query\_Type object. With the need for a |
| 2638 | factory\index{factory} primitive like \textbf{New\_Query} it was necessary to lift
|
| 2639 | that restriction (otherwise the factory was unable to return the created |
| 2640 | object). So the Root\_Query\_Type and derived forms, permit assignment |
| 2641 | as of APQ version 2.0 and later. |
| 2642 | |
| 2643 | When a Query\_Type is assigned in APQ, nothing spectacular happens. |
| 2644 | In fact, the contents of the object on the right hand side are effectively |
| 2645 | ignored, leaving a new object on the left side. The following example |
| 2646 | shows how Q1 and Q2 are essentially the same: |
| 2647 | |
| 2648 | \begin{NumberedExample}
|
| 2649 | declare |
| 2650 | Q0 : Query_Type; |
| 2651 | Q1 : Query_Type; |
| 2652 | Q2 : Query_Type; |
| 2653 | begin |
| 2654 | ... |
| 2655 | Q1 := Q0; -- Q1 becomes initialized (Q0 ignored)\label{Ex:Q1}
|
| 2656 | Clear(Q2); -- Initialize Q2\label{Ex:Q2}
|
| 2657 | \end{NumberedExample}
|
| 2658 | |
| 2659 | In this example, both Q1~(line~\ref{Ex:Q1}) and Q2~(line~\ref{Ex:Q2})
|
| 2660 | end up in the same state, and no state information is taken from Q0. You |
| 2661 | might wonder why this would be implemented. The following example code |
| 2662 | fragment illustrates why this is convenient and useful: |
| 2663 | |
| 2664 | \begin{NumberedExample}
|
| 2665 | with APQ; |
| 2666 | usse APQ; |
| 2667 | |
| 2668 | procedure My_Generic_App(C : Root_Connection_Type'Class) is |
| 2669 | Q : Root_Query_Type'Class := New_Query(C); |
| 2670 | begin |
| 2671 | Prepare(Q,"SELECT NAME, INCOME"); |
| 2672 | Append(Q, "FROM~SALARIES"); |
| 2673 | Execute(Q,C); |
| 2674 | ... |
| 2675 | declare |
| 2676 | Q2 : Root_Query_Type'Class := Q;\label{Ex:Q_Clone}
|
| 2677 | begin |
| 2678 | ... |
| 2679 | end; |
| 2680 | \end{NumberedExample}
|
| 2681 | |
| 2682 | The example illustrates that the assignment (line~\ref{Ex:Q_Clone}) is
|
| 2683 | simply a convenient factory of its own kind. It is also likely to be |
| 2684 | slightly more efficient than the New\_Query primitive on the |
| 2685 | connection. Think of assignment of Query\_Type objects as cloning\index{cloning}
|
| 2686 | operations. The assigned object becomes a fresh initialized clone of the |
| 2687 | Query\_Type object on the right hand side of the assignment. |
| 2688 | |
| 2689 | \chapter{SQL Query Support}
|
| 2690 | |
| 2691 | Once a database connection has been established, the application is |
| 2692 | ready to invoke operations on the database server. To ease the programmer's |
| 2693 | burden in keeping track of the various components involved in these |
| 2694 | transactions, the Query\_Type object is provided. The Query\_Type\index{Query\_Type}
|
| 2695 | object and the Connection\_Type object are used together when it comes |
| 2696 | time to execute the query. Some operations require the connection |
| 2697 | object, while others do not. |
| 2698 | |
| 2699 | There are a large number of primitives associated with the Query\_Type |
| 2700 | object. Most of them are related to the large number of data types |
| 2701 | that are supported. These Query\_Type primitives fall into the following |
| 2702 | basic categories: |
| 2703 | |
| 2704 | \begin{enumerate}
|
| 2705 | \item Object initialization |
| 2706 | \item SQL Query building |
| 2707 | \item SQL Execution on the Database server |
| 2708 | \item Transaction operations |
| 2709 | \item Fetch operations |
| 2710 | \item Column information functions |
| 2711 | \item Value fetching functions |
| 2712 | \item Value and Indicator fetching procedures |
| 2713 | \item Information operations |
| 2714 | \end{enumerate}
|
| 2715 | |
| 2716 | In addition to these, are a number of generic functions and procedures |
| 2717 | that permit the APQ user to custom tailor the API to his own specialized |
| 2718 | Ada data types. This allows applications to continue the follow the |
| 2719 | healthy tradition of using strong data types. There is no need for |
| 2720 | a database application to take a back seat to safety\index{safety}.
|
| 2721 | |
| 2722 | \section{Initialization \label{SQL Initialization}}
|
| 2723 | |
| 2724 | The Query\_Type object is initialized when the object is created. |
| 2725 | However, the Query\-\_Type object can be re-used as various SQL\index{SQL}
|
| 2726 | operations are performed by the program. To re-use the Query\_Type |
| 2727 | object, one of the primitives in Table~\ref{t:qinit} may be used to recycle it for
|
| 2728 | re-use. |
| 2729 | |
| 2730 | \begin{table}
|
| 2731 | \begin{center}
|
| 2732 | \begin{tabular}{lll}
|
| 2733 | Type & Name & Purpose\\ |
| 2734 | \hline |
| 2735 | proc & Clear & Clear object and re-initialize\\ |
| 2736 | proc & Prepare & Reinitialize with start of new SQL query\\ |
| 2737 | \end{tabular}
|
| 2738 | \end{center}
|
| 2739 | \caption{Query Initialization}\label{t:qinit}
|
| 2740 | \end{table}
|
| 2741 | |
| 2742 | The Clear\index{Clear} procedure does the initialization of the Query\_Type object.
|
| 2743 | The Prepare primitive implicitly invokes Clear |
| 2744 | \footnote{Consequently, your application need not invoke Clear() prior to calling
|
| 2745 | Prepare().} and additionally starts the building of an SQL query. Very short |
| 2746 | SQL statements may comletely specified by the Prepare API call. Longer |
| 2747 | queries can be completed with some of the other primitives to be discussed |
| 2748 | in this section. |
| 2749 | |
| 2750 | \subsection{Procedure Clear}
|
| 2751 | |
| 2752 | With one exception, the Clear\index{Clear} primitive completely resets the state
|
| 2753 | of the Query\_Type object. This function primitive serves to basic |
| 2754 | purposes: |
| 2755 | |
| 2756 | \begin{enumerate}
|
| 2757 | \item Resets the object to its initial state so that it can be reused for a new query. |
| 2758 | \item Releases any results of the current query (close cursors etc.) |
| 2759 | \end{enumerate}
|
| 2760 | |
| 2761 | When performed after a query has been executed, this primitive releases |
| 2762 | all results from the query. For Sybase, this can include issuing a |
| 2763 | cancel back to the server and flushing all pending row results that |
| 2764 | have not been retrieved by the APQ client program. |
| 2765 | |
| 2766 | Clear accepts the Query\_Type object as its only argument: |
| 2767 | |
| 2768 | \begin{Code}
|
| 2769 | procedure Clear( |
| 2770 | Q : in out Query_Type |
| 2771 | ); |
| 2772 | \end{Code}
|
| 2773 | |
| 2774 | The one exception to clearing state however, is that the SQL case\index{case policy}
|
| 2775 | policy remains unchanged. If prior to the clear, the SQL case policy |
| 2776 | is set to Preserve\_Case\index{Preserve\_Case}, it will remain so after the Clear call.
|
| 2777 | |
| 2778 | There are no exceptions raised by this call. |
| 2779 | |
| 2780 | The use of the Clear primitive is recommended after all SQL processing |
| 2781 | related to the query has been completed. This permits any database |
| 2782 | server results to be released. Think of it as ``closing''\index{closing a query} the
|
| 2783 | query. Note however, that object finalization\index{finalization} will take care of this,
|
| 2784 | if the job is left unfinished by the programmer. |
| 2785 | |
| 2786 | The following example illustrates it's use: |
| 2787 | |
| 2788 | \begin{Example}
|
| 2789 | declare |
| 2790 | C : Connection_Type; |
| 2791 | Q : Query_Type; |
| 2792 | begin |
| 2793 | ... |
| 2794 | Clear(Q); |
| 2795 | \end{Example}
|
| 2796 | |
| 2797 | \subsubsection{Performance Issue}
|
| 2798 | |
| 2799 | There is one particular case where calling Clear is vitally important |
| 2800 | for some database products. Let's use an example where you are fetching |
| 2801 | the most recent stock price from a price history file. Here is the |
| 2802 | table declaration: |
| 2803 | |
| 2804 | \begin{SQL}
|
| 2805 | CREATE TABLE PRICE_HIST ( |
| 2806 | SECURITY CHAR(10) NOT NULL, |
| 2807 | PRICE_DATE DATE NOT NULL, |
| 2808 | PRICE REAL, |
| 2809 | PRIMARY KEY (SECURITY,PRICE_DATE) |
| 2810 | ); |
| 2811 | \end{SQL}
|
| 2812 | |
| 2813 | With this table holding price history, keyed by the security name |
| 2814 | and date, we can lookup the most recent price with a subroutine something |
| 2815 | like the following: |
| 2816 | |
| 2817 | \begin{NumberedExample}
|
| 2818 | procedure Last_Price( |
| 2819 | C : in out Root_Connection_Type'Class; |
| 2820 | Security : in String; |
| 2821 | Price : out APQ_Double |
| 2822 | ) is |
| 2823 | function Value is new Float_Value(APQ_Double); |
| 2824 | |
| 2825 | Q : Root_Query_Type'Class := New_Query(C);\label{Ex:TheQ}
|
| 2826 | begin |
| 2827 | |
| 2828 | Begin_Work(Q,C); |
| 2829 | |
| 2830 | Prepare(Q, "SELECT SECURITY,PRICE_DATE,PRICE"); |
| 2831 | Append_Line(Q,"FROM PRICE_HIST"); |
| 2832 | Append(Q, "WHERE SECURITY = "); |
| 2833 | Append_Quoted(Q,C,Security,Line_Feed); |
| 2834 | Append_Line(Q,"ORDER BY SECURITY,PRICE_DATE DESC");\label{Ex:OrderBy}
|
| 2835 | |
| 2836 | if Engine_Of(C) = Engine_MySQL then |
| 2837 | Append_Line(Q,"LIMIT 1");\label{Ex:Limit1}
|
| 2838 | end if; |
| 2839 | |
| 2840 | Execute(Q,C); |
| 2841 | |
| 2842 | begin |
| 2843 | Fetch(Q); |
| 2844 | exception |
| 2845 | when No_Tuple => |
| 2846 | raise; -- No price found! |
| 2847 | end; |
| 2848 | |
| 2849 | Price := Value(Q,3); |
| 2850 | Clear(Q);\label{Ex:Clear}
|
| 2851 | |
| 2852 | end Last_Price; |
| 2853 | \end{NumberedExample}
|
| 2854 | |
| 2855 | In this example, you can see that MySQL\index{MySQL} is covered by adding the "LIMIT 1"\index{LIMIT}
|
| 2856 | clause in line~\ref{Ex:Limit1}.\footnote{MySQL will limit the results to 1 row, if any.}
|
| 2857 | PostgreSQL\index{PostgreSQL} does not have a problem with this type of query because each row is
|
| 2858 | fetched on demand. Sybase\index{Sybase} however, will start returning all the rows
|
| 2859 | that it has available, in the order specified by the "ORDER BY"\index{ORDER BY} clause
|
| 2860 | (line~\ref{Ex:OrderBy}).
|
| 2861 | |
| 2862 | Given that the routine Last\_Price only calls Fetch\index{Fetch}
|
| 2863 | once, there is no point in the Sybase server producing and sending |
| 2864 | more row data down the connection to the APQ client program. For this |
| 2865 | reason, a call to Clear\index{Clear} (line~\ref{Ex:Clear}) will send a cancel notice to the Sybase server
|
| 2866 | to stop producing additional rows. It will also clear out any row data on |
| 2867 | the connection that has not been fetched by the client program. |
| 2868 | |
| 2869 | In this particular example, the Query\_Type object Q (line~\ref{Ex:TheQ}) would have been
|
| 2870 | finalized\index{finalized} anyway upon return from Last\_Price. Finalized Query\_Type
|
| 2871 | objects always perform the equivalent of a call to Clear prior to |
| 2872 | releasing the object storage. However, it is important to explicitly |
| 2873 | call Clear\index{Clear} if you have many other operations that follow the query
|
| 2874 | performed in order to allow a timely cancel if necessary and to release |
| 2875 | any pending query results. |
| 2876 | |
| 2877 | |
| 2878 | \subsection{Procedure Prepare\label{Procedure Prepare}}
|
| 2879 | |
| 2880 | The Prepare\index{Prepare} primitive goes one step further than Clear
|
| 2881 | in that it readies the object for the start of an SQL\index{SQL} statement build.
|
| 2882 | If the query is short, this will be the only building step required. |
| 2883 | As in the case of Clear, the SQL case policy\index{case policy} is unchanged however.
|
| 2884 | |
| 2885 | The Prepare procedure takes the following arguments: |
| 2886 | |
| 2887 | \begin{Code}
|
| 2888 | procedure Prepare( |
| 2889 | Q : in out Query_Type; |
| 2890 | SQL : in String; |
| 2891 | After : in String := Line_Feed |
| 2892 | ); |
| 2893 | \end{Code}
|
| 2894 | |
| 2895 | The SQL argument defines the start of your SQL\index{SQL} statement. The
|
| 2896 | After argument may supply either the default (line feed)\index{line feed} or
|
| 2897 | some other text to append to the SQL text\index{SQL text}.
|
| 2898 | It is provided as a programmer convenience, since many times the |
| 2899 | programmer will need to append a comma for example. |
| 2900 | |
| 2901 | There are no exceptions raised by this call. |
| 2902 | |
| 2903 | The following code shows an example of building a query to drop a |
| 2904 | table: |
| 2905 | |
| 2906 | \begin{Example}
|
| 2907 | declare |
| 2908 | Q : Query_Type; |
| 2909 | begin |
| 2910 | ... |
| 2911 | Prepare(Q,"DROP TABLE DEAD_WEIGHT"); |
| 2912 | \end{Example}
|
| 2913 | |
| 2914 | \section{SQL Query Building \label{SQL Query Building}}
|
| 2915 | |
| 2916 | The previous section primitives ``cleared'' the Query\_Type for |
| 2917 | a new query. The primitives provided in this section help to build |
| 2918 | a new SQL query or to continue (append to)\index{append} the one started by the
|
| 2919 | Prepare call in \Ref{Procedure Prepare}. The programmer may
|
| 2920 | start\index{start} with a Prepare call and follow it by a number of ``append''
|
| 2921 | calls, or call Clear and build upon an empty query\index{empty query} and skip the
|
| 2922 | Prepare. ``PREPARE''\index{PREPARE} however, is a traditional first step
|
| 2923 | in embedded SQL\index{embedded SQL} software, so this tradition comes recommended
|
| 2924 | by the author. |
| 2925 | |
| 2926 | There are two broad categories of support for creating SQL queries\index{SQL queries}.
|
| 2927 | They are: |
| 2928 | |
| 2929 | \begin{enumerate}
|
| 2930 | \item Append\index{Append} a value to the SQL query
|
| 2931 | \item Encode\index{Encode} a value or NULL\index{NULL}, to the SQL query.
|
| 2932 | \end{enumerate}
|
| 2933 | |
| 2934 | Both of these categories append to the current query. Primitives in |
| 2935 | category 2 , are prefixed with Encode and will be described |
| 2936 | later in the present chapter. |
| 2937 | |
| 2938 | The Append category of support is useful for values that are never |
| 2939 | \emph{NULL} (in SQL terms these columns that are declared as ``NOT
|
| 2940 | NULL''\index{NOT NULL}). The Encode category of support is provided for values in
|
| 2941 | your application that may be in the NULL\index{NULL} state. It is not absolutely
|
| 2942 | required that the Encode support be used, since it is possible for |
| 2943 | the application to test for a NULL value. However, the programmer |
| 2944 | will find that the Encode support provides application coding convenience |
| 2945 | and economy of expression. With compact code, better readability\index{readability} and
|
| 2946 | safety\index{safety} is normally obtained.
|
| 2947 | |
| 2948 | Within category 1, there are five groups of primitives% |
| 2949 | \footnote{The generic procedures have been lumped in with the primitives.%
|
| 2950 | } that build on the present query. They are: |
| 2951 | |
| 2952 | \begin{enumerate}
|
| 2953 | \item Append a string |
| 2954 | \item Append a string and a \emph{{}``newline''}
|
| 2955 | \item Append a quoted string% |
| 2956 | \footnote{Quoted values are always spared from any automatic case conversions,
|
| 2957 | if any are applied.} |
| 2958 | \item Append non string types |
| 2959 | \item Append using generic procedures for custom types |
| 2960 | \end{enumerate}
|
| 2961 | |
| 2962 | Encode\index{Encode} support on the other hand, only provides for the needs of variables
|
| 2963 | that must be communicated to the database server. As a result, the |
| 2964 | encode procedures consist only of the following two groups: |
| 2965 | |
| 2966 | \begin{enumerate}
|
| 2967 | \item Encode non-string\index{non-string types} types
|
| 2968 | \item Encode using generic procedures for custom types\index{custom types}
|
| 2969 | \end{enumerate}
|
| 2970 | |
| 2971 | Presently only the second group is provided for by the APQ binding.% |
| 2972 | \footnote{The reasoning is that most of the time, the user will want to instantiate
|
| 2973 | the generic procedures anyway. This permits both the data type and |
| 2974 | the null indicator\index{null indicator} type to be a custom application type.%
|
| 2975 | } A future release may expand on category 1 support. |
| 2976 | |
| 2977 | The append procedures (category 1) will be described first and then |
| 2978 | followed by the encode procedures (category 2). |
| 2979 | |
| 2980 | |
| 2981 | \subsection{Append SQL String}
|
| 2982 | |
| 2983 | The Append\index{Append} procedure permits the programmer to append text to the
|
| 2984 | SQL query being saved in the Query\_Type object. Unlike Prepare\index{Prepare},
|
| 2985 | Append does not clear the object. Append continues to add |
| 2986 | SQL text\index{SQL text} to the query already gathered by the object Q (below):
|
| 2987 | |
| 2988 | \begin{Code}
|
| 2989 | procedure Append( |
| 2990 | Q : in out Query_Type; |
| 2991 | SQL : in String; |
| 2992 | After : in String := "" |
| 2993 | ); |
| 2994 | \end{Code}
|
| 2995 | |
| 2996 | \begin{Code}
|
| 2997 | procedure Append( |
| 2998 | Q : in out Query_Type; |
| 2999 | SQL : in Ada.Strings.Unbounded.Unbounded_String; |
| 3000 | After : in String := "" |
| 3001 | ); |
| 3002 | \end{Code}
|
| 3003 | |
| 3004 | There are no exceptions raised by this call. |
| 3005 | |
| 3006 | The following example shows how Append is used: |
| 3007 | |
| 3008 | \begin{Example}
|
| 3009 | declare |
| 3010 | Q : Query_Type; |
| 3011 | begin |
| 3012 | ... |
| 3013 | Prepare(Q,"SELECT CUSTNO,CUST_NAME"); |
| 3014 | Append(Q, "FROM CUSTOMER"); |
| 3015 | \end{Example}
|
| 3016 | |
| 3017 | Note that the Prepare\index{Prepare} call uses a default argument After=New\_Line\index{After}\index{New\_Line},
|
| 3018 | while Append uses a null string\index{null string} default.
|
| 3019 | You can put a line break in the SQL query by supplying the |
| 3020 | value New\_Line in the argument "After" if you like. |
| 3021 | The following example illustrates the use of Prepare and Append: |
| 3022 | |
| 3023 | \begin{Example}
|
| 3024 | declare |
| 3025 | Q : Query_Type; |
| 3026 | Col_Name_1 : constant String := "CUSTNO"; |
| 3027 | Col_Name_2 : constant String := "CUST_NAME"; |
| 3028 | begin |
| 3029 | ... |
| 3030 | Prepare(Q,"SELECT "); |
| 3031 | Append(Q,Col_Name_1,","); |
| 3032 | Append(Q,Col_Name_2,Line_Feed); |
| 3033 | Append(Q,"FROM CUSTOMER"); |
| 3034 | \end{Example}
|
| 3035 | |
| 3036 | This example builds up the same query that the previous example did, |
| 3037 | except that the column names were provided by string variables\index{string variables}.
|
| 3038 | |
| 3039 | \subsection{Append SQL Line\label{Append SQL Line}}
|
| 3040 | |
| 3041 | The Append\_Line\index{Append\_Line} procedure is provided for added convenience and program
|
| 3042 | readability\index{readability}. The same effect can be had with a string Append call,
|
| 3043 | using string APQ.Line\_Feed supplied as the After\index{After} argument.
|
| 3044 | The Append\_Line procedure has the following specification: |
| 3045 | |
| 3046 | \begin{Code}
|
| 3047 | procedure Append_Line( |
| 3048 | Q : in out Query_Type; |
| 3049 | SQL : in String; |
| 3050 | ); |
| 3051 | \end{Code}
|
| 3052 | |
| 3053 | The Append\_Line procedure is one of the few that does not sport an |
| 3054 | \emph{After} argument.
|
| 3055 | |
| 3056 | |
| 3057 | \subsection{Append Quoted SQL String}
|
| 3058 | |
| 3059 | Don't quote\index{quoted strings} your own strings at home. There are several reasons why
|
| 3060 | supplying your own quotes to a call to the normal Append call is a |
| 3061 | bad idea: |
| 3062 | |
| 3063 | \begin{enumerate}
|
| 3064 | \item Some characters must be encoded\index{encoded} or escaped\index{escaped}, if they occur in the string.
|
| 3065 | \item SQL portability\index{portability} is enhanced, since encoding and escaping\index{escaping} varies from
|
| 3066 | database vendor to vendor. |
| 3067 | \item Internationalization\index{Internationalization} chosen by the user may require different processing.
|
| 3068 | \item Quoted\index{quoted strings} strings should not be changed to upper or lowercase\index{lowercase} (by APQ).
|
| 3069 | \end{enumerate}
|
| 3070 | |
| 3071 | The Append\_Quoted\index{Append\_Quoted} procedure call is designed to make it easier for
|
| 3072 | the programmer to supply a string value that may contain special characters |
| 3073 | within it. Since a string value is already supplied by APQ with outer\index{outer quotes}
|
| 3074 | quotes, any quote\index{quote} appearing within the string must be quoted. The
|
| 3075 | Append\_Quoted procedure provides the necessary outer quotes\index{quotes}
|
| 3076 | for the sring value and escapes\index{escapes} any special characters\index{special characters}
|
| 3077 | occuring within it as well. |
| 3078 | |
| 3079 | Another very important reason for using this API call for quoted strings |
| 3080 | is that this will prevent the APQ library from changing the case of\index{case of SQL}
|
| 3081 | any SQL text that is created. This is true no matter what the current |
| 3082 | SQL case policy\index{case policy} is (see type APQ\-.SQL\-\_Case\-\_Type on page \pageref{SQL_Case_Type Choices}).
|
| 3083 | Any string segment\index{string segment} that was added to the query with this API call
|
| 3084 | will not have its case changed when the query is executed or the text |
| 3085 | of the SQL is returned in a call to the To\_String\index{To\_String} function.
|
| 3086 | |
| 3087 | There are two Append\_Quoted procedures, which differ only in the data |
| 3088 | type of the \emph{SQL} argument:
|
| 3089 | |
| 3090 | \begin{Code}
|
| 3091 | procedure Append_Quoted( |
| 3092 | Q : in out Query_Type; |
| 3093 | Connection : in out Root_Connection_Type'Class; |
| 3094 | SQL : in String; |
| 3095 | After : in String := "" |
| 3096 | ); |
| 3097 | \end{Code}
|
| 3098 | |
| 3099 | \begin{Code}
|
| 3100 | procedure Append_Quoted( |
| 3101 | Q : in out Query_Type; |
| 3102 | Connection : in out Root_Connection_Type'Class; |
| 3103 | SQL : in Ada.Strings.Unbounded.Unbounded_String; |
| 3104 | After : in String := "" |
| 3105 | ); |
| 3106 | \end{Code}
|
| 3107 | |
| 3108 | Notice that this particular API call requires a connection\index{connection}. The reason
|
| 3109 | for this is that some databases require the server to make the appropriate |
| 3110 | choices dealing with internationalized\index{internationalized} character sets\index{character sets}. The quoting\index{quoting}
|
| 3111 | conventions also vary from database to database, so APQ relies upon |
| 3112 | the database vendor software to perform the quoting for you. |
| 3113 | |
| 3114 | The following example illustrates the use of this call (using the |
| 3115 | String type): |
| 3116 | |
| 3117 | \begin{Example}
|
| 3118 | declare |
| 3119 | C : Connection_Type; |
| 3120 | Q : Query_Type; |
| 3121 | Freds_Emporium : String := "Fred's Emporium"; |
| 3122 | begin |
| 3123 | ... |
| 3124 | Prepare(Q, "SELECT COMPNO,COMPANY_NAME"); |
| 3125 | Append_Line(Q,"FROM SUPPLIER"); |
| 3126 | Append(Q, "WHERE COMPANY_NAME = "); |
| 3127 | Append_Quoted(Q,C,Freds_Emporium,New_Line); |
| 3128 | \end{Example}
|
| 3129 | |
| 3130 | The effect of these calls is to build an SQL query\index{SQL} that looks as follows
|
| 3131 | (for PostgreSQL\index{PostgreSQL}):
|
| 3132 | |
| 3133 | \begin{SQL}
|
| 3134 | SELECT COMPNO,COMPANY_NAME |
| 3135 | FROM SUPPLIER |
| 3136 | WHERE COMPANY_NAME = 'Fred\'s Emporium' |
| 3137 | \end{SQL}
|
| 3138 | |
| 3139 | Notice how the quote character was escaped for use by the PostgreSQL\index{PostgreSQL}
|
| 3140 | database server. Note also that even though the SQL case policy\index{case policy} was to
|
| 3141 | use Upper\_Case\index{Upper\_Case}, the case of the quoted text was preserved.
|
| 3142 | |
| 3143 | APQ will automatically adjust the quoting conventions\index{quoting conventions} to match the
|
| 3144 | database being used. The same example above when used for Sybase\index{Sybase},
|
| 3145 | would produce the following SQL text\index{SQL text} instead:
|
| 3146 | |
| 3147 | \begin{SQL}
|
| 3148 | SELECT COMPNO,COMPANY_NAME |
| 3149 | FROM SUPPLIER |
| 3150 | WHERE COMPANY_NAME = 'Fred''s Emporium' |
| 3151 | \end{SQL}
|
| 3152 | |
| 3153 | Sybase uses a doubled-up quote\index{doubled-up quote} instead.
|
| 3154 | |
| 3155 | Using APQ's Append\_Quoted frees the programmer from worrying about |
| 3156 | quoting conventions and guarantees that the case of the text will be |
| 3157 | preserved. |
| 3158 | |
| 3159 | \subsection{Append Non-String Types to SQL Query}
|
| 3160 | |
| 3161 | A fairly large set of builtin non-string\index{non-string types} data types are supported by varied
|
| 3162 | Append calls that differ in the second argument V. The following |
| 3163 | is a list of their specifications: |
| 3164 | |
| 3165 | \begin{Code}
|
| 3166 | procedure Append( |
| 3167 | Q : in out Query_Type; |
| 3168 | V : in APQ_Boolean; |
| 3169 | After : in String := "" |
| 3170 | ); |
| 3171 | \end{Code}
|
| 3172 | |
| 3173 | \begin{Code}
|
| 3174 | procedure Append( |
| 3175 | Q : in out Query_Type; |
| 3176 | V : in APQ_Date; |
| 3177 | After : in String := "" |
| 3178 | ); |
| 3179 | \end{Code}
|
| 3180 | |
| 3181 | \begin{Code}
|
| 3182 | procedure Append( |
| 3183 | Q : in out Query_Type; |
| 3184 | V : in APQ_Time; |
| 3185 | After : in String := "" |
| 3186 | ); |
| 3187 | \end{Code}
|
| 3188 | |
| 3189 | \begin{Code}
|
| 3190 | procedure Append( |
| 3191 | Q : in out Query_Type; |
| 3192 | V : in APQ_Timestamp; |
| 3193 | After : in String := "" |
| 3194 | ); |
| 3195 | \end{Code}
|
| 3196 | |
| 3197 | \begin{Code}
|
| 3198 | procedure Append( |
| 3199 | Q : in out Query_Type; |
| 3200 | V : in APQ_Bitstring; |
| 3201 | After : in String := "" |
| 3202 | ); |
| 3203 | \end{Code}
|
| 3204 | |
| 3205 | \begin{Code}
|
| 3206 | procedure Append( |
| 3207 | Q : in out Query_Type; |
| 3208 | V : in Row_ID_Type; |
| 3209 | After : in String := "" |
| 3210 | ); |
| 3211 | \end{Code}
|
| 3212 | |
| 3213 | These Append\index{Append} procedure calls automatically convert\index{convert} the supplied data
|
| 3214 | type in argument V, internally into a string\index{string} using the To\_String\index{To\_String} function
|
| 3215 | appropriate to the data type. Internally, the string Append procedure |
| 3216 | is then utilized to perform the remaining work. The following example |
| 3217 | illustrates their use: |
| 3218 | |
| 3219 | \begin{Example}
|
| 3220 | declare |
| 3221 | Q : Query_Type; |
| 3222 | Ship_Date : APQ_Date; |
| 3223 | begin |
| 3224 | ... |
| 3225 | Prepare(Q, "SELECT COMPNO,COMPANY_NAME,SHIP_DATE"); |
| 3226 | Append_Line(Q,"FROM SUPPLIER"); |
| 3227 | Append(Q, "WHERE SHIP_DATE = "); |
| 3228 | Append(Q,Ship_Date,New_Line); |
| 3229 | \end{Example}
|
| 3230 | |
| 3231 | The example presented builds an SQL query that looks like this: |
| 3232 | |
| 3233 | \begin{SQL}
|
| 3234 | SELECT COMPNO,COMPANY_NAME,SHIP_DATE |
| 3235 | FROM SUPPLIER |
| 3236 | WHERE SHIP_DATE = '2002-07-21' |
| 3237 | \end{SQL}
|
| 3238 | |
| 3239 | Notice that the Append call for APQ\_Date\index{APQ\_Date} automatically supplies the
|
| 3240 | necessary quotes to the SQL query\index{SQL query} (if needed for the database being
|
| 3241 | used). All of the data types supported are molded into a format that |
| 3242 | is acceptable in the native database SQL syntax\index{SQL syntax}.
|
| 3243 | |
| 3244 | There is one additional Append procedure call that has a special set |
| 3245 | of arguments in order to support dates\index{dates} with time zones\index{time zones}. The arguments
|
| 3246 | for this procedure call are as follows: |
| 3247 | |
| 3248 | \begin{Code}
|
| 3249 | procedure Append( |
| 3250 | Q : in out Query_Type; |
| 3251 | TS : in APQ_Timestamp; |
| 3252 | TZ : in APQ_Timezone; |
| 3253 | After : in String := "" |
| 3254 | ); |
| 3255 | \end{Code}
|
| 3256 | |
| 3257 | Apart from the different argument names TS and TZ, this |
| 3258 | procedure works in the same fashion as the former Append\index{Append} procedure
|
| 3259 | call. The TZ argument simply supplies the additional time zone\index{time zone}
|
| 3260 | information to be added to the timestamp\index{timestamp}.
|
| 3261 | |
| 3262 | \begin{description}
|
| 3263 | \item [Note:] Not all databases support the use of timezone values. |
| 3264 | \end{description}
|
| 3265 | |
| 3266 | \subsection{Generic Append SQL Procedures}
|
| 3267 | |
| 3268 | Ada programmers often take advantage of the strong typing \index{strong typing}that
|
| 3269 | is available in the language. To accomodate this programming aspect, |
| 3270 | generic procedures are available so that type conversions\index{type conversions}
|
| 3271 | are unnecessary. The following table documents the generic procedures |
| 3272 | that accept one generic argument named Val\_Type and the data |
| 3273 | types that they support: |
| 3274 | |
| 3275 | \begin{Code}
|
| 3276 | generic |
| 3277 | type Val_Type is new Boolean; |
| 3278 | procedure Append_Boolean( |
| 3279 | Q : in out Root_Query_Type'Class; |
| 3280 | V : in Val_Type; |
| 3281 | After : in String := "" |
| 3282 | ); |
| 3283 | \end{Code}
|
| 3284 | |
| 3285 | \begin{Code}
|
| 3286 | generic |
| 3287 | type Val_Type is range <>; |
| 3288 | procedure Append_Integer( |
| 3289 | Q : in out Root_Query_Type'Class; |
| 3290 | V : in Val_Type; |
| 3291 | After : in String := "" |
| 3292 | ); |
| 3293 | \end{Code}
|
| 3294 | |
| 3295 | \begin{Code}
|
| 3296 | generic |
| 3297 | type Val_Type is mod <>; |
| 3298 | procedure Append_Modular( |
| 3299 | Q : in out Root_Query_Type'Class; |
| 3300 | V : in Val_Type; |
| 3301 | After : in String := "" |
| 3302 | ); |
| 3303 | \end{Code}
|
| 3304 | |
| 3305 | \begin{Code}
|
| 3306 | generic |
| 3307 | type Val_Type is digits <>; |
| 3308 | procedure Append_Float( |
| 3309 | Q : in out Root_Query_Type'Class; |
| 3310 | V : in Val_Type; |
| 3311 | After : in String := "" |
| 3312 | ); |
| 3313 | \end{Code}
|
| 3314 | |
| 3315 | \begin{Code}
|
| 3316 | generic |
| 3317 | type Val_Type is delta <>; |
| 3318 | procedure Append_Fixed( |
| 3319 | Q : in out Root_Query_Type'Class; |
| 3320 | V : in Val_Type; |
| 3321 | After : in String := "" |
| 3322 | ); |
| 3323 | \end{Code}
|
| 3324 | |
| 3325 | \begin{Code}
|
| 3326 | generic |
| 3327 | type Val_Type is delta <> digits <>; |
| 3328 | procedure Append_Decimal( |
| 3329 | Q : in out Root_Query_Type'Class; |
| 3330 | V : in Val_Type; |
| 3331 | After : in String := "" |
| 3332 | ); |
| 3333 | \end{Code}
|
| 3334 | |
| 3335 | \begin{Code}
|
| 3336 | generic |
| 3337 | type Val_Type is new Ada.Calendar.Time; |
| 3338 | procedure Append_Date( |
| 3339 | Q : in out Root_Query_Type'Class; |
| 3340 | V : in Val_Type; |
| 3341 | After : in String := "" |
| 3342 | ); |
| 3343 | \end{Code}
|
| 3344 | |
| 3345 | \begin{Code}
|
| 3346 | generic |
| 3347 | type Val_Type is new Ada.Calendar.Day_Duration; |
| 3348 | procedure Append_Time( |
| 3349 | Q : in out Root_Query_Type'Class; |
| 3350 | V : in Val_Type; |
| 3351 | After : in String := "" |
| 3352 | ); |
| 3353 | \end{Code}
|
| 3354 | |
| 3355 | \begin{Code}
|
| 3356 | generic |
| 3357 | type Val_Type is new APQ_Timestamp; |
| 3358 | procedure Append_Timestamp( |
| 3359 | Q : in out Root_Query_Type'Class; |
| 3360 | V : in Val_Type; |
| 3361 | After : in String := "" |
| 3362 | ); |
| 3363 | \end{Code}
|
| 3364 | |
| 3365 | \begin{Code}
|
| 3366 | generic |
| 3367 | type Val_Type is new APQ_Bitstring; |
| 3368 | procedure Append_Bitstring( |
| 3369 | Q : in out Root_Query_Type'Class; |
| 3370 | V : in Val_Type; |
| 3371 | After : in String := "" |
| 3372 | ); |
| 3373 | \end{Code}
|
| 3374 | |
| 3375 | Each of the resulting instantiated procedures provide the following |
| 3376 | calling signature: |
| 3377 | |
| 3378 | \begin{Code}
|
| 3379 | procedure Append( |
| 3380 | Q : in out Query_Type; |
| 3381 | V : in Val_Type; |
| 3382 | After : in String := "" |
| 3383 | ); |
| 3384 | \end{Code}
|
| 3385 | |
| 3386 | The following code fragment illustrates how these are instantiated\index{instantiated} and used:
|
| 3387 | |
| 3388 | \begin{NumberedExample}
|
| 3389 | declare |
| 3390 | type Price_Type is delta 0.01 digits 12;\label{Ex:TypeDef}
|
| 3391 | procedure Append is new Append_Decimal(Price_Type);\label{Ex:Inst}
|
| 3392 | |
| 3393 | Q : Query_Type; |
| 3394 | Selling_Price : Price_Type; |
| 3395 | begin |
| 3396 | ... |
| 3397 | Prepare(Q,"UPDATE SUPPL_ORDER"); |
| 3398 | Append(Q."SET SELLING_PRICE = "); |
| 3399 | Append(Q,Selling_Price,New_Line);\label{Ex:InstUse}
|
| 3400 | Append_Line(Q,"WHERE ..."); |
| 3401 | \end{NumberedExample}
|
| 3402 | |
| 3403 | In this example, the application defines its own type Price\_Type |
| 3404 | in line~\ref{Ex:TypeDef}. After instantiating the Append\_Decimal
|
| 3405 | generic procedure as Append\index{Append} (line~\ref{Ex:Inst}), the application is
|
| 3406 | free to neatly append a price value from Selling\_Price in |
| 3407 | line~\ref{Ex:InstUse}, as if it were natively supported.
|
| 3408 | |
| 3409 | |
| 3410 | \subsection{Generic Append\_Timezone}
|
| 3411 | |
| 3412 | The Append\_Timezone\index{Append\_Timezone} has an additional generic paramter. The instantiated\index{instantiated}
|
| 3413 | procedure also has a slightly different set of calling arguments. The generic |
| 3414 | parameters are specified as follows: |
| 3415 | |
| 3416 | \begin{Code}
|
| 3417 | generic |
| 3418 | type Date_Type is new Ada.Claendar.Time; |
| 3419 | type Zone_Type is new APQ_Timezone; |
| 3420 | procedure Append_Timezone( |
| 3421 | Q : in out Root_Query_Type'Class; |
| 3422 | V : in Date_Type; |
| 3423 | Z : in Zone_Type; |
| 3424 | After : in String := "" |
| 3425 | ); |
| 3426 | \end{Code}
|
| 3427 | |
| 3428 | The instantiated procedure has the following calling signature: |
| 3429 | |
| 3430 | \begin{Code}
|
| 3431 | procedure Append( |
| 3432 | Q : in out Root_Query_Type'Class; |
| 3433 | V : in Date_Type; |
| 3434 | Z : in Zone_Type; |
| 3435 | After : in String := "" |
| 3436 | ); |
| 3437 | \end{Code}
|
| 3438 | |
| 3439 | The following shows an example of its use: |
| 3440 | |
| 3441 | \begin{NumberedExample}
|
| 3442 | declare |
| 3443 | type Ship_Date_Type is new APQ_Timestamp; |
| 3444 | type Ship_Zone_Type is new APQ_Timezone; |
| 3445 | |
| 3446 | procedure Append is new Append_Timezone(\label{Ex:InstTZ}
|
| 3447 | Ship_Date_Type,Ship_Zone_Type); |
| 3448 | |
| 3449 | Q : Query_Type; |
| 3450 | Ship_Date : Ship_Date_Type; |
| 3451 | Ship_Zone : Ship_Zone_Type; |
| 3452 | begin |
| 3453 | ... |
| 3454 | Prepare(Q,"SELECT COUNT(*)"); |
| 3455 | Append_Line(Q,"FROM ORDER"); |
| 3456 | Append(Q,"WHERE SHIP_DATE = "); |
| 3457 | Append(Q,Ship_Date,Ship_Zone,New_Line);\label{Ex:UseInstTZ}
|
| 3458 | ... |
| 3459 | \end{NumberedExample}
|
| 3460 | |
| 3461 | The example shows how the application's types Ship\_Date\_Type |
| 3462 | and Ship\_Zone\_Type are accomodated by the Append\index{Append} instantiation\index{instantiation}
|
| 3463 | of the generic procedure (line~\ref{Ex:InstTZ}). The instantiated
|
| 3464 | Append routine is applied in line~\ref{Ex:UseInstTZ}.
|
| 3465 | |
| 3466 | |
| 3467 | \subsection{Generic Append of Bounded SQL Text}
|
| 3468 | |
| 3469 | To accomodate the use of the package Ada\-.Strings\-.Bounded\index{Ada.Strings.Bounded},
|
| 3470 | the generic procedure Append\_Bounded\index{Append\_Bounded} was provided. Its instantiation
|
| 3471 | requirements differ from the preceeding ones because the instantiation |
| 3472 | of the Bounded\_String\index{Bounded\_String} type must be provided to the Append\_Bounded
|
| 3473 | generic procedure. The generic procedure is defined as follows: |
| 3474 | |
| 3475 | \begin{Code}
|
| 3476 | generic |
| 3477 | with package P |
| 3478 | is new Ada.Strings.Bounded.Generic_Bounded_Length(<>); |
| 3479 | procedure Append_Bounded( |
| 3480 | Q : in out Query_Type; |
| 3481 | SQL : in P.Bounded_String; |
| 3482 | After : in String |
| 3483 | ); |
| 3484 | \end{Code}
|
| 3485 | |
| 3486 | In other words, Append\_Bounded can be instantiated from any instantiation |
| 3487 | of the Ada.Strings.Bounded.Generic\_Bounded\_Length package. The following |
| 3488 | example makes this easier to understand: |
| 3489 | |
| 3490 | \begin{NumberedExample}
|
| 3491 | with Ada.Strings.Bounded; |
| 3492 | ... |
| 3493 | declare |
| 3494 | package B80 |
| 3495 | is new Ada.Strings.Bounded.Generic_Bounded_Length(80); |
| 3496 | package B20 |
| 3497 | is new Ada.Strings.Bounded.Generic_Bounded_Length(20); |
| 3498< |