📄 otl2.htm
字号:
<html>
<head>
<title>One-Page Oracle API, Oracle Call Interface Template Library
(OTL), Version 2.0.0</title>
</head>
<body>
<h1>One-Page Oracle API, Oracle Call Interface Template Library (OTL),
Version 2.0.0</h1>
<p><i>Sergei Kuchin, email:
<a href="mailto:skuchin@aceweb.com">skuchin@aceweb.com</a>,
<a href="mailto:skuchin@gmail.com">skuchin@gmail.comgmail</i>
<xmp>
Copyright (C) Sergei Kuchin, 1996, 1997, 1998
Permission to use, copy, modify and redistribute this
document for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all
copies.
</xmp>
<h1>Table of Contents</h1>
<ul>
<li><a href="#sec1">1. Introduction</a>
<li><a href="#sec11">1.1. SQL streams</a>
<li><a href="#sec2">2. <i>One-page</i> Oracle API</a>
<ul>
<li><a href="#sec21">2.1. Connect object</a>
<li><a href="#sec22">2.2. otl_stream class</a>
<ul>
<li><a href="#sec221">2.2.1. Stream bind variables declaration</a>
</ul>
<li><a href="#sec23">2.3. Exception handling</a>
<li><a href="#sec24">2.4. Constant SQL statement or PL/SQL block</a>
<li><a href="#sec25">2.5. Examples</a>
</ul>
<li><a href="#sec3">3. STL-compliant iterators for otl_stream</a>
<ul>
<li><a href="#sec31">3.1. Example</a>
</ul>
<li><a href="#app_a">Appendix A. How to download the source code</a>
<li><a href="#app_b">Appendix B. OTL exception list</a>
</ul>
<h1><a name="sec1"> 1. Introduction</h1>
<p>
This document describes the Oracle Call Interface Template Library,
Version 2.0.0 (OTL). The library introduces a <i>one-page</i> Oracle
API in the form of <a href="#sec11">SQL streams</a>.
</p>
<p>
OTL is a new kind of C++ libraries, similar to the <a
href="http://www.sgi.com/Technology/STL/">Standard Template
Library</a>. This kind of libraries is easy to use, since the user
needs only to include C++ header files which contain template classes
and inlinr functions. There is no need to link additional object
modules into C++ applications. The code instantiated from template
classes and inline functions is efficient and reliable in terms of
runtime performance and C++ strict type checking.
</p>
<p>
OTL automatically uses Oracle Array Interface (<a href="#sec11">SQL
streams</a> are buffered by definition) and has a higher runtime
performance than Pro*C because there is no overhead on caching cursors
and filling out the SQLCA global structure before every single SQL
statement embedded into the program. Runtime performance can be
improved even further by increasing the stream buffer size.
</p>
<p>
OTL provides an exception handling mechanism in the format of the <a
href="#sec23">otl_exception</a> class. This mechanism takes advantage
of C++ exception handling compared to coding database applications in
plain C. The user does not need to check out return codes after each
function call. The code, instantiated from the OTL templates and
inline functions is much nicer and cleaner in comparison with the code
generated by the Pro*C precompiler.
</p>
<p>
Also, OTL integrates with the <a
href="http://www.sgi.com/Technology/STL/">Standard Template
Library</a> by means of <a href="#sec3">STL-compliant iterator
classes</a>. This feature is very powerful because it allows to
combine the power of <a
href="http://www.metabyte.com/~fbp/stl/readings.html">generic
programming</a> and Oracle database backend into compact, reliable,
top performance and easy-to-maintain C++ database applications.
</p>
<p>
This version of OTL is available for both Oracle 7.x and Oracle
8.x. Both implemetations use native OCIs:
</p>
<ul>
<li>OTL for Oracle 7 uses native OCI7
</li>
<li>OTL for Oracle 8 uses native OCI8
</li>
</ul>
<p>
It provides smooth transition from Oracle 7 to Oracle 8 with no
changes to the custom source code. Besides, OTL compiles by many C++
compilers on major brands of Unix as well as Windows NT and Windows
95/98.
</p>
<p>
The fact that OTL is available in source code adds more value to this
material -- folks new to OCI can use the OTL source code to learn both
OCI7 and OCI8 . Moreover, OTL can be used a guidance for migrating
programs from native OCI7 to native OCI8.
</p>
<h2><a name="sec11">1.1. SQL stream classes</h2>
<p>
OTL introduces the concept of SQL streams. The idea here is to
combine streams and SQL. Any SQL statement or PL/SQL block can be
treated as a functional element with input/output parameters. There
are functions to put objects into a stream, that is, to assign values
to input variables of the SQL statement. Also, there are functions to
get objects from the stream, that is, to get values from output
variables of the SQL statement.
</p>
<center>
<img src="otl.gif">
</center>
<p>
When values of all input variables of the functional element
are filled out then the element is executed. Resulting
values are assigned to the output variables right after the
execution. Sets of input and output variables are allowed to
overlap.
</p>
<p>
Logically, a SQL stream is a structured stream with input
and output rows. The format of the input row is defined by a
set of output variables of the stream. Similarly, the output
row is defined by input variables of the stream. When
objects are written into the stream, values are actually
assigned to the input variables. Likewise, when objects are
read from the stream, values are read from the output
variables of the stream.
</p>
<p>
SQL streams are similar to buffered files. A SQL statement
or PL/SQL block is opened as an ordinary buffered file. The
logic of the SQL stream operations remains the same as the
file operations with the only exception -- the SQL stream
has separate input and output buffers which may overlap.
</p>
<p>
The SQL stream has a flush function for flushing its input buffer when
the buffer gets full and a collection of >> and << operators for
reading and writing object of different data types. The most important
advantage of the SQL streams is their unified interface to SQL
statements and PL/ SQL blocks of any kind. This means that the
application developer needs to remember just a few syntactical
constructs and function names which he already got familiar with when
he started working with C++ streams.
</p>
<p>
Inside the SQL stream there is a small parser for parsing <a
href="#sec221">declarations of bind variables</a> and their data
types. There is no need to declare C/C++ host variables and bind them
with placeholders by special bind function calls. All necessary
buffers are created dynamically inside the stream. The stream just
needs to be opened for reading input values and writing output values.
</p>
<p>
The OTL stream interface requires use of the OTL exceptions. This
means that potentially any OTL stream operation can throw an exception
of the <a href="#sec23">otl_exception</a> type. In order to intercept
the exception and prevent the program from aborting, wrap up the OTL
stream code with the corresponding try & catch block.
</p>
<h1><a name="sec2">2. <i>One-page</i> Oracle API</h1>
<h2><a name="sec21">2.1. Connect object</h2>
<p>
This class encapsulates the Oracle Call Interface <i>connect</i>
functions: connect, commit, roll back, etc. In other words,
otl_connect is the class for creating "connect" objects.
</p>
<a name="ref002"></a><xmp>
class otl_connect{
public:
</xmp>
<ul>
<li> Constants to initialize OCI. oci_threaded is needed in case of
multithreaded program. oci_default is the default mode.
<xmp>
enum {oci_default,oci_threaded};
</xmp>
<li><a name="ref006"></a>Initialize OCI program. This function needs to be called only once
before connecting to the database for the first time. The function is
static in class.
<xmp>
static void otl_initialize(const int mode=oci_default);
</xmp>
<li>Create "connect" object.
<xmp>
otl_connect();
</xmp>
<li>Create "connect" object and connect to Oracle using the
"connect_str" connect string.
<xmp>
otl_connect(const char* connect_str);
</xmp>
<li>Destructor
<xmp>
~otl_connect();
</xmp>
<li><a name="ref007"></a>Concurrent logon; OCI application is allowed to have more than one
concurrent logon. Returns 1 on success, 0 on failure.
<xmp>
int rlogon(const char* connect_str);
</xmp>
<li><a name="ref009"></a>Disconnect from / log off Oracle. Returns 1 on success, 0 on
failure.
<xmp>
int logoff(void);
</xmp>
<li>Commit current transaction. Returns 1 on success, 0 on failure.
<xmp>
int commit(void);
</xmp>
<li>Roll back current transaction. Returns 1 on success, 0 on failure.
<xmp>
int rollback(void);
</xmp>
</ul>
<xmp>
};
</xmp>
<h2><a name="sec22">2.2. otl_stream class</h2>
<p>
OTL introduces the otl_stream class which is the actual implementation of
the <a href="#sec11">SQL Stream</a> concept. It is unified for any SQL
statement or PL/SQL block which potentially may have input/output bind
variables (placeholders). otl_stream provides the same interface for
both straight SELECT statements and SELECT statements to be returned
via a referenced cursor. Though, implementations are quite different.
</p>
<p>
An OTL stream needs to have at least one <a href="#sec221">bind
variable</a>. See <a href="#sec24">2.4.</a> for more information on
how to execute a constant SQL statement or PL/SQL block.
</p>
<xmp>
class otl_stream{
public:
</xmp>
<ul>
<li><a name="ref001"></a>General conctructor. SQL statement is parsed, all host input and
output host variables are automatically allocated and bound. This
constructor allows the user to use <a href="#sec221">extended
placeholder declarations</a>.
<xmp>
otl_stream(
short arr_size, // host array size
const char* sqlstm, // SQL statement
otl_connect& db, // connect object
const char* ref_cur_placeholder=0
// reference cursor placeholder, e.g. ":cur"
);
</xmp>
<li>Default constructor
<xmp>
otl_stream();
</xmp>
<li>Destructor
<xmp>
~otl_stream();
</xmp>
<li><a name="ref005"></a>Test if all data has been already read from the stream
<xmp>
int eof(void);
</xmp>
<li><a name="ref010"></a>Flush stream's output buffer. It actually means to execute the SQL
statement as many times as rows entered to the output buffer. The
stream is automatically flushed when the buffer gets full.
<xmp>
void flush(void);
</xmp>
<li>Clean up buffer without flushing it.
<xmp>
void clean(void);
</xmp>
<li>Rewind stream
<xmp>
void rewind(void);
</xmp>
<li>Test if NULL was fetched from the stream
<xmp>
int is_null(void);
</xmp>
<li>Set "auto-commit" flag. When the buffer is flushed, current
transaction is automatically commited, if the flag is set. By default,
the flag is set. In order to prevent current transaction from
"auto-committing", unset the flag using this function.<br>
This auto-commit flag has nothing to do with the Oracle auto-commit
mode. This auto-commit is otl_stream specific. If it is more
convenient to have "auto-commit off" by default then it makes sense to
derive another stream class from otl_stream and unset the flag in
constructors of the derived class.
<xmp>
void set_commit(int auto_commit=0);
</xmp>
<li>Open stream
<xmp>
void open(
short arr_size, // host array size
const char* sqlstm, // SQL statement
otl_connect& db, // connect object
const char* ref_cur_placeholder=0
// reference cursor placeholder, e.g. ":cur"
);
</xmp>
<li>Close stream
<xmp>
void close(void);
</xmp>
<li>Test if the stream was opened okay
<xmp>
int good(void);
</xmp>
<li><a name="ref004"></a>Read objects from stream
<xmp>
otl_stream& operator>>(char& c);
otl_stream& operator>>(unsigned char& c);
otl_stream& operator>>(char* s);
otl_stream& operator>>(unsigned char* s);
otl_stream& operator>>(int& n);
otl_stream& operator>>(unsigned& u);
otl_stream& operator>>(short& sh);
otl_stream& operator>>(long int& l);
otl_stream& operator>>(float& f);
otl_stream& operator>>(double& d);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -