[svn-commits] r42 - in drivers: . python python/trunk python/trunk/dbi python/trunk/hdr
crogr01 at ingres.com
crogr01 at ingres.com
Thu Jun 5 10:33:35 PDT 2008
Author: crogr01
Date: 2008-06-05 10:33:35 -0700 (Thu, 05 Jun 2008)
New Revision: 42
Added:
drivers/python/
drivers/python/branches/
drivers/python/tags/
drivers/python/trunk/
drivers/python/trunk/CHANGELOG
drivers/python/trunk/LICENSE
drivers/python/trunk/PKG-INFO
drivers/python/trunk/README.html
drivers/python/trunk/dbi/
drivers/python/trunk/dbi/iidbiconn.c
drivers/python/trunk/dbi/iidbicurs.c
drivers/python/trunk/dbi/iidbiutil.c
drivers/python/trunk/dbi/ingresdbi.c
drivers/python/trunk/hdr/
drivers/python/trunk/hdr/iidbi.h
drivers/python/trunk/hdr/iidbiconn.h
drivers/python/trunk/hdr/iidbicurs.h
drivers/python/trunk/hdr/iidbiutil.h
drivers/python/trunk/setup.py
Log:
Import the python tree
Added: drivers/python/trunk/CHANGELOG
===================================================================
--- drivers/python/trunk/CHANGELOG (rev 0)
+++ drivers/python/trunk/CHANGELOG 2008-06-05 17:33:35 UTC (rev 42)
@@ -0,0 +1,77 @@
+IngresDBI CHANGELOG
+
+09-May-2006 - 2.0.0
+ Incremented version to 2.0.0.
+ Fixed a number of memory leaks and negative reference counts.
+ Added cursor.setinputsize(), cursor.setoutputsizes(),
+ cursor.errorhandler, connection.errorhandler, connection exception
+ objects, warnings for extended attributes, cursor.messages, and
+ connection.messages.
+
+10-Mar-2006 - 1.9.4
+ Incorporated markdown utility for generation of README.html. Fixed
+ various memory leaks related to Curosr.close().
+
+26-Jan-2006 - 1.9.3
+ Fixed reference count in Cursor.next() method.
+
+22-Nov-2005 - 1.9.2
+ Implemented extended cursor methods __iter__() and next().
+ Implemented extended cursor attribute rownumber.
+
+16-Nov-2005 - 1.9.1
+ Populated cursor description attributes display size, internal size,
+ precision, and scale. Updated README.html file.
+
+24-Jun-2005 - 1.9.0
+ Added cursor.callproc(). Added datetime support. Note that the 2.4
+ version of Python is now required to support the Ingres DBI.
+
+19-May-2005 - 1.5.0
+ Implemented cursor.executemany(). Upgraded cursor.callproc() to
+ support row-returning procedures and to return the input parameters.
+
+23-Feb-2005 - 1.0.8
+ Implemented cursor.fetchmany(). First phase of support for
+ cursor.callproc(): no support for BYREF or return parameters,
+ but does support input parameters.
+
+16-Feb-2005 - 1.0.7
+ Tightened up INCREF and DECREF's to improve memory efficiency.
+
+31-Jan-2005 - 1.0.6
+ Fixed fetch of long varchars in dbi_cursorFetchone().
+
+10-Jan-2004 - 1.0.5
+ Added dbi_freeData() routine to help resolve massive memory leaks.
+
+21-Dec-2004 - 1.0.4
+ - Added module descriptor attributes BINARY, NUMBER, STRING, and DATETIME.
+ Added full support for "None" update parameters (Note: this requires an
+ Ingres ODBC driver at level 3.50.00.46 or later).
+ - Added connection attribute "autocommit".
+
+17-Nov-2004 - 1.0.3
+ - Fixed random GPF occuring due to memory corruption
+
+08-Nov-2004 - 1.0.2
+ - Fixed data truncation of char/varchar types
+
+05-Nov-2004 - 1.0.1
+ - Fix memory leak in connection class
+
+04-Nov-2004 - 1.0.0
+ - Fetch blobs of type LONG VARCHAR into SQL_C_CHAR, otherwise data corruption happens.
+ - Changed default driver to allow DSN less connections. removed references to ingres.lib preventing build with Windows.
+ - Added support for BigInt
+ - Added TRUE/FALSE defines for Linux
+ - Made float4/8 support functional
+ - Added version attribute to ingresdbi class.
+
+23-Sept-2004 - 0.9.1
+ - Fixed support for INTEGER1
+ - Fixed miscellaneous problems that arose when performing
+ conformance testing including hangs and access violations.
+
+20-Sept-2004
+ - Initial Version
Added: drivers/python/trunk/LICENSE
===================================================================
--- drivers/python/trunk/LICENSE (rev 0)
+++ drivers/python/trunk/LICENSE 2008-06-05 17:33:35 UTC (rev 42)
@@ -0,0 +1,258 @@
+GNU GENERAL PUBLIC LICENSE
+Version 2, June 1991
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+Preamble
+The licenses for most software are designed to take away your freedom
+to share and change it. By contrast, the GNU General Public License is
+intended to guarantee your freedom to share and change free software--to
+make sure the software is free for all its users. This General Public
+License applies to most of the Free Software Foundation's software and
+to any other program whose authors commit to using it. (Some other Free
+Software Foundation software is covered by the GNU Lesser General Public
+License instead.) You can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it in
+new free programs; and that you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone
+to deny you these rights or to ask you to surrender the rights. These
+restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or
+for a fee, you must give the recipients all the rights that you have. You
+must make sure that they, too, receive or can get the source code. And
+you must show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on,
+we want its recipients to know that what they have is not the original,
+so that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and
+modification follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of running
+the Program is not restricted, and the output from the Program is covered
+only if its contents constitute a work based on the Program (independent
+of having been made by running the Program). Whether that is true depends
+on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously
+and appropriately publish on each copy an appropriate copyright notice
+and disclaimer of warranty; keep intact all the notices that refer to
+this License and to the absence of any warranty; and give any other
+recipients of the Program a copy of this License along with the Program.
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of
+it, thus forming a work based on the Program, and copy and distribute
+such modifications or work under the terms of Section 1 above, provided
+that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices stating
+ that you changed the files and the date of any change.
+ b) You must cause any work that you distribute or publish, that in whole
+ or in part contains or is derived from the Program or any part thereof,
+ to be licensed as a whole at no charge to all third parties under the
+ terms of this License.
+ c) If the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use in
+ the most ordinary way, to print or display an announcement including an
+ appropriate copyright notice and a notice that there is no warranty (or
+ else, saying that you provide a warranty) and that users may redistribute
+ the program under these conditions, and telling the user how to view a
+ copy of this License. (Exception: if the Program itself is interactive
+ but does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Program, and can be
+reasonably considered independent and separate works in themselves,
+then this License, and its terms, do not apply to those sections when
+you distribute them as separate works. But when you distribute the same
+sections as part of a whole which is a work based on the Program, the
+distribution of the whole must be on the terms of this License, whose
+permissions for other licensees extend to the entire whole, and thus to
+each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise
+the right to control the distribution of derivative or collective works
+based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of a
+storage or distribution medium does not bring the other work under the
+scope of this License.
+
+3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable source
+ code, which must be distributed under the terms of Sections 1 and 2
+ above on a medium customarily used for software interchange; or,
+ b) Accompany it with a written offer, valid for at least three years, to
+ give any third party, for a charge no more than your cost of physically
+ performing source distribution, a complete machine-readable copy of the
+ corresponding source code, to be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+ c) Accompany it with the information you received as to the offer to
+ distribute corresponding source code. (This alternative is allowed only
+ for noncommercial distribution and only if you received the program
+ in object code or executable form with such an offer, in accord with
+ Subsection b above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it. For an executable work, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the executable. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major components
+(compiler, kernel, and so on) of the operating system on which the
+executable runs, unless that component itself accompanies the executable.
+If distribution of executable or object code is made by offering access
+to copy from a designated place, then offering equivalent access to
+copy the source code from the same place counts as distribution of the
+source code, even though third parties are not compelled to copy the
+source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt otherwise
+to copy, modify, sublicense or distribute the Program is void, and will
+automatically terminate your rights under this License. However, parties
+who have received copies, or rights, from you under this License will
+not have their licenses terminated so long as such parties remain in
+full compliance.
+
+5. You are not required to accept this License, since you have not signed
+it. However, nothing else grants you permission to modify or distribute
+the Program or its derivative works. These actions are prohibited
+by law if you do not accept this License. Therefore, by modifying or
+distributing the Program (or any work based on the Program), you indicate
+your acceptance of this License to do so, and all its terms and conditions
+for copying, distributing or modifying the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further restrictions
+on the recipients' exercise of the rights granted herein. You are not
+responsible for enforcing compliance by third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot distribute
+so as to satisfy simultaneously your obligations under this License
+and any other pertinent obligations, then as a consequence you may not
+distribute the Program at all. For example, if a patent license would
+not permit royalty-free redistribution of the Program by all those who
+receive copies directly or indirectly through you, then the only way you
+could satisfy both it and this License would be to refrain entirely from
+distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply
+and the section as a whole is intended to apply in other circumstances.
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any such
+claims; this section has the sole purpose of protecting the integrity of
+the free software distribution system, which is implemented by public
+license practices. Many people have made generous contributions to the
+wide range of software distributed through that system in reliance on
+consistent application of that system; it is up to the author/donor to
+decide if he or she is willing to distribute software through any other
+system and a licensee cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Program under this License may add an
+explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail
+to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Program does not specify a version
+number of this License, you may choose any version ever published by
+the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software
+and of promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
+DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING
+BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
+LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
+TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY
+HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+END OF TERMS AND CONDITIONS
Added: drivers/python/trunk/PKG-INFO
===================================================================
--- drivers/python/trunk/PKG-INFO (rev 0)
+++ drivers/python/trunk/PKG-INFO 2008-06-05 17:33:35 UTC (rev 42)
@@ -0,0 +1,10 @@
+Metadata-Version: 1.0
+Name: ingresdbi
+Version: 2.0.0
+Summary: Ingres DBI 2.0 Python Driver
+Home-page: http://ingres.com
+Author: Ralph Loen
+Author-email: Ralph.Loen at ingres.com
+License: GPL
+Description: Ingres DBI 2.0 Python driver offers access to Ingres databases, Ingres gateways, and EDBC servers.
+Platform: UNKNOWN
Added: drivers/python/trunk/README.html
===================================================================
--- drivers/python/trunk/README.html (rev 0)
+++ drivers/python/trunk/README.html 2008-06-05 17:33:35 UTC (rev 42)
@@ -0,0 +1,433 @@
+<HTML>
+<HEAD>
+<!-- Created with DOC2HTML, v585 (12/13/2005) -->
+<title>Ingres Python DBI Driver Version 2.0.0</title>
+<META HTTP-EQUIV="Content-Type" Content="text-html; charset=Windows-1252">
+<style>
+<!--
+A:link { text-decoration: underline; font-weight: bold; color: #336699 }
+A:visited { text-decoration: underline; font-weight: bold; color: #336699 }
+BODY { font-family: Verdana, "Bitstream Vera Sans", Arial, Helvetica, Sans Serif; font-size: 80%; font-weight: normal; color: 00000 }
+TABLE { font-family: Verdana, "Bitstream Vera Sans", Arial, Helvetica, Sans Serif; font-size: 100%; color: 000000; }
+P { font-family: Verdana, "Bitstream Vera Sans", Arial, Helvetica, Sans Serif; font-weight: normal; color: #000000 }
+H1 { font-size: 180%; font-weight: bold; color: #336699 }
+H2 { font-size: 155%; font-weight: normal; font-family: Verdana, "Bitstream Vera Sans", Arial, Helvetica, Sans Serif; color: #336699 }
+H3 { font-size: 130%; font-weight: bold; font-family: Verdana, "Bitstream Vera Sans", Arial, Helvetica, Sans Serif; color: #336699 }
+H4 { font-size: 130%; font-weight: bold; font-family: Verdana, "Bitstream Vera Sans", Arial, Helvetica, Sans Serif; color: #336699 }
+ol, ul ol, ul ul ol { list-style-type: decimal; list-style-image : none; }
+ol ol, ul ol ol, ol ul ol { list-style-type: lower-alpha; list-style-image: none; }
+ul, ol ul, ol ol ul { list-style-type: disc; list-style-image: none; }
+ul ul, ol ul ul, ul ol ul { list-style-type: circle; list-style-image: none;}
+ul ul ul { list-style-type: square; list-style-image: none; }
+ol ol ol { list-style-type: upper-roman; list-style-image: none; }
+B { font-weight: bold }
+STRONG { font-weight: bold }
+I { font-style: italic }
+EM { font-style: italic }
+INPUT { color: #336699; font-family: Verdana, "Bitstream Vera Sans", Arial, Helvetica, Sans Serif; font-size: 90%; } /* Special */
+TEXTAREA { color: #336699; font-family: Verdana, "Bitstream Vera Sans", Arial, Helvetica, Sans Serif; font-size: 90%; } /* Special */
+BLOCKQUOTE { font-size: 80%; }
+PRE { font-family: "courier new", courier, monospace; font-size: 100% }
+table, td { font-family: Verdana, "Bitstream Vera Sans", Arial, Helvetica, Sans Serif; font-weight: normal; color: #000000; vertical-align: top; border: 1px solid #EBEBEB; border-collapse: collapse; font-size: 12px; padding: 2px;}
+table.invis, td.invis { font-family: Verdana, "Bitstream Vera Sans", Arial, Helvetica, Sans Serif; font-weight: normal; color: #000000; vertical-align: middle; border: 0px; border-collapse: collapse; font-size: 12px; padding: 2px;}
+th { font-family: Verdana, "Bitstream Vera Sans", Arial, Helvetica, Sans Serif; font-weight: bold; color: #000000; vertical-align: top; border: 1px solid #FFFFFF; background-color: #006699; color:#FFFFFF; text-align: left; padding: 2px;}
+tr.alt { background-color : #F1F5FA;}
+.computerassoc { font-family: Verdana, "Bitstream Vera Sans", Arial, Helvetica, Sans Serif; color: #FFFFFF; text-decoration: none; background-color: #336699; font-size: 130%; font-weight: bold; }
+hr { color: #CCCCCC; height:1px; }
+-->
+</style>
+</HEAD>
+<BODY>
+<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td class="computerassoc">Ingres Corporation</td></tr></table>
+<h1><a name="ingres_python_dbi_driver_version_2_0_0">Ingres Python DBI Driver Version 2.0.0</a></h1>
+<p>
+<hr>
+<nobr>
+<p><b><a href="#welcome">1.0 Welcome</a></b>
+<br><a href="#new_in_this_release">1.1 New in This Release</a>
+<p><b><a href="#operating_system_support">2.0 Operating System Support</a></b>
+<p><b><a href="#installation_considerations">3.0 Installation Considerations</a></b>
+<p><b><a href="#general_considerations">4.0 General Considerations</a></b>
+<br><a href="#features_not_included">4.1 Features Not Included</a>
+<br><a href="#syntax_for_the_ingresdbi_connect_method">4.2 Syntax for the ingresdbi.connect() Method</a>
+<br><a href="#syntax_for_the_ingres_extension_cursor_prepared_attribute">4.3 Syntax for the Ingres Extension Cursor.prepared Attribute</a>
+<p><b><a href="#building_and_installing_the_ingres_python_dbi_driver">5.0 Building and Installing the Ingres Python DBI Driver</a></b>
+<br><a href="#building_the_driver">5.1 Building the Driver</a>
+<br><a href="#installing_the_driver">5.2 Installing the Driver</a>
+<p><b><a href="#example_code">6.0 Example Code</a></b>
+<p><b><a href="#known_issues">7.0 Known Issues</a></b>
+<p><b><a href="#contact_customer_support">8.0 Contact Customer Support</a></b>
+</nobr>
+<p>
+<hr>
+<h2><a name="welcome">1.0 Welcome</a></h2>
+<p>This readme contains all the documentation on the Ingres
+Python DBI driver.
+<p>Please review this readme before building or installing
+this software. We encourage users to test the software and
+provide feedback.
+<p>
+<hr>
+<h3><a name="new_in_this_release">1.1 New in This Release</a></h3>
+<p>The latest additions to the Ingres DBI 2.0.0 driver
+bring the driver to nearly 100% compliance to the DBI 2.0
+specification, including both core and extended
+specifications. These additions to the Ingres Python DBI
+driver ease application migration.
+<p>The following changes have been made to the driver since
+its last release:
+<ul>
+<p><li>Expansion of Connection string attributes to include
+all of the Connection string attributes of the Ingres ODBC
+driver.
+<p><li>Support for the "messages" extended Cursor and
+Connection attributes.
+<p><li>Warnings for all extended DBI attributes and methods.
+<p><li>DBI exceptions are now visible on Connection objects.
+<p><li>Support for the "errorhandler" Cursor and Connection
+attributes.
+<p><li>Support for pooled ODBC connections (Windows only).
+<p><li>Support for the "prepared" Cursor attribute. This is
+an Ingres extension to the PEP 249 specification, according
+to the requirements of Ingres.
+<p><li>Support for the "setinputsizes" and "setoutputsize"
+Cursor methods.
+</ul>
+<p>
+<hr>
+<h2><a name="operating_system_support">2.0 Operating System Support</a></h2>
+<p>This Ingres Python DBI driver supports all of the
+platforms supported by Ingres, including:
+<ul>
+<p><li>Solaris
+<p><li>HP-UX
+<p><li>AIX
+<p><li>Linux
+<p><li>Windows
+<p><li>SCO UnixWare
+<p><li>SCO OpenServer
+</ul>
+<p>
+<hr>
+<h2><a name="installation_considerations">3.0 Installation Considerations</a></h2>
+<p>To build and install the Ingres Python DBI interface,
+the following components are needed:
+<ul>
+<p><li>Ingres r3 or above, including Ingres 2006. For a
+list of binary downloads, see <a href="http://www.ingres.com" target="_blank">http://www.ingres.com</a>. For a source listing if you wish to build Ingres
+from source code, see <a href="http://www.ingres.com" target="_blank">http://www.ingres.com</a>.
+<p><li>C compiler (for example, GNU/C or Microsoft Visual
+Studio)
+<p><li>Python interpreter version 2.4 or above
+<p><li>The Ingres Python DBI source code
+</ul>
+<p>
+<hr>
+<h2><a name="general_considerations">4.0 General Considerations</a></h2>
+<p>
+<hr>
+<h3><a name="features_not_included">4.1 Features Not Included</a></h3>
+<p>The following features are currently not included in the
+Ingres Open Source Python DBI driver:
+<ul>
+<p><li>Connection pooling (non-Windows only)
+<p><li>The following extended Cursor attributes and methods:
+<ul>
+<p><li>messages
+<p><li>lastrowid
+<p><li>scroll
+</ul>
+<p><li>Due to the limitations of the Ingres ODBC driver,
+the following items are not supported:
+<ul>
+<p><li>Executing functions asynchronously
+<p><li>Cursor direction other than forward-only
+<p><li>Support for Ingres SQL command "COPY TABLE"
+<p><li>Support for Ingres SQL command "SAVEPOINT"
+</ul>
+<p><li>Due to syntax limitations of the Cursor.callproc()
+method, BYREF and output parameters are not supported in
+stored procedures. Row-returning procedures, however, are
+supported.
+</ul>
+<p>
+<hr>
+<h3><a name="syntax_for_the_ingresdbi_connect_method">4.2 Syntax for the ingresdbi.connect() Method</a></h3>
+<p>Connection objects are constructed using the
+ingresdbi.connect() method. The following keywords are
+valid:
+<ul>
+<p><li>dsn - the ODBC Data Source Name
+<p><li>database - the target database
+<p><li>connectstr - alternate connection string
+<p><li>vnode - vnode definition as defined in the Ingres
+netutil utility. For more information, see the <i>Ingres
+Connectivity Guide</i>.
+<p><li>uid - user login ID
+<p><li>pwd - user password
+<p><li>servertype - the type of the target database
+<p><li>trace - enables optional tracing of the DBI driver
+<p><li>rolename - role name
+<p><li>rolepwd - role password
+<p><li>group - group
+<p><li>dbms_pwd - DBMS password
+<p><li>selectloops - fetches using select loops instead of
+the default cursor loops
+<p><li>autocommit - whether autocommit is enabled.
+Autocommit is off by default.
+<p><li>catschemanull - whether to disable underscores in
+wildcard searches
+<p><li>catconnect - whether to use separate sessions for
+catalog operations
+<p><li>numeric_overflow - whether to ignore or fail numeric
+overflows
+</ul>
+<p>If the "dsn" keyword is specified, the other keywords
+are optional. If the database is specified, the other
+keywords are optional. If the vnode keyword is specified,
+and the connection is local, the value "(LOCAL)" can be
+used as the vnode definition, or the vnode attribute can be
+omitted.
+<p>If the "connectstr" keyword is specified, the other
+keywords are optional. The "connectstr" keyword specifies
+an ODBC connection string. For examples of valid Ingres
+ODBC connection strings, see the <i>Ingres Connectivity
+Guide</i>.
+<p>All of the above keywords reference string values except
+for the "trace" keyword. The "trace" keyword references a
+tuple with two members. The first member is the tracing
+level, which can be a value of 0 through 7. The second
+member is a string that describes the trace file. If the
+second member has a value of "None", the tracing is written
+to the standard output.
+<p>The following values are valid for the "autocommit",
+"selectloops", "catconnect", "catschemanull", and
+"numeric_overflow" keyword attributes:
+<ul>
+<p><li>"on"
+<p><li>"off"
+<p><li>"y"
+<p><li>"n"
+<p><li>"Yes"
+<p><li>"No"
+</ul>
+<p>The following values are valid for the "servertype"
+keyword:
+<ul>
+<p><li>"INGRES"
+<p><li>"DCOM"
+<p><li>"IDMS"
+<p><li>"DB2"
+<p><li>"IMS"
+<p><li>"ODBC"
+<p><li>"VSAM"
+<p><li>"RDB"
+<p><li>"STAR"
+<p><li>"RMS"
+<p><li>"ORACLE"
+<p><li>"INFORMIX"
+<p><li>"SYBASE"
+<p><li>"MSSQL"
+<p><li>"DB2UDB"
+</ul>
+<p>If "INGRES" is not specified, the "servertype" values
+require access to an Ingres (that is, Enterprise Access) or
+EDBC gateway server. Otherwise, no gateway is required. The
+default is "INGRES".
+<p>Select loops usually have the best performance. However,
+only one select loop can be active at a time. Cursor loops
+support unlimited multiple active result sets, but can be
+slower in performance.
+<p>Following is an example of a valid instantiation of the
+ingresdbi connection object, using all keywords:
+<pre>
+conn = ingresdbi.connect(dsn ="myDSN",
+ database "myDB",
+ vnode = "(LOCAL)",
+ uid = "myUID",
+ pwd = "myPWD",
+ dbms_pwd = "myDbmsPWD",
+ group = "myGroup",
+ rolename = "myRoleName",
+ rolepwd = "myRolePwd",
+ selectloops = "Y",
+ autocommit = "Y",
+ servertype = "INGRES",
+ driver = "Ingres",
+ catschemanull = "off",
+ catconnect = "Off",
+ numeric_overflow = "yes",
+ connectStr = "DSN=myDSN",
+ trace = (7, "dbi.log")
+ )
+</pre>
+<p>Connection objects can be constructed without keywords.
+If keywords are not used, arguments must follow the order:
+dsn, database, vnode, uid, pwd, selectloops, autocommit,
+servertype, and trace. An example without keywords is shown
+here:
+<pre>
+conn = ingresdbi.connect("myDSN", "myDB", "(LOCAL)", "MnyUID", "myPWD",
+ "Y", "Yes", "INGRES", "Ingres 3.0", "myRoleName",
+ "myrolePWD", "myGroup", "n", "NO", "YES", "yes", "N",
+ "myDbmsPwd", "DSN=myDSN", (7, "dbi.log"))
+</pre>
+<p>
+<hr>
+<h3><a name="syntax_for_the_ingres_extension_cursor_prepared_attribute">4.3 Syntax for the Ingres Extension Cursor.prepared Attribute</a></h3>
+<p>Although PEP 249 requires all queries to be prepared,
+the Ingres DBI driver does not prepare queries by default.
+Instead, the Cursor attribute "prepared" can be deployed.
+<p>If Cursor.prepared is set to "y", "yes", or "on",
+subsequent queries specified in the Cursor.execute() or
+Cursor.executemany() methods are executed as prepared.
+However, only one query string is allowed for each cursor
+instantiation. If the query string is changed, a warning is
+issued, and the Ingres DBI driver resorts to direct query
+execution.
+<p>The Cursor.callproc() method raises an exception if the
+Cursor.prepared attribute is set to "y", "yes", or "on".
+<p>The following values (entered in either uppercase or
+lowercase) are valid for the Cursor.prepared attribute:
+<ul>
+<p><li>"on"
+<p><li>"off"
+<p><li>"y"
+<p><li>"n"
+<p><li>"Yes"
+<p><li>"No"
+</ul>
+<p>
+<hr>
+<h2><a name="building_and_installing_the_ingres_python_dbi_driver">5.0 Building and Installing the Ingres Python DBI Driver</a></h2>
+<p>
+<hr>
+<h3><a name="building_the_driver">5.1 Building the Driver</a></h3>
+<p>The build process has been simplified by the use of the
+Python DistUtils package. Start the build process by
+extracting the necessary files from the Ingres DBI
+compressed archive:
+<p><b>Linux and Non-Windows</b>
+<pre>
+tar zxvf ingresdbi-1.9.6.tar.gz
+</pre>
+<p><b>Windows</b>
+<ol>
+<p><li>Use WinZip (or similar product) to extract the
+directories and files from ingresdbi-1.9.6.zip.
+<p><li>Enter the newly created source directory,
+ingresdbi-1.9.6:
+<pre>
+cd ingresdbi-1.9.6
+</pre>
+<p><li>Initiate the build process.
+<pre>
+python setup.py build
+</pre>
+<p><b>Note:</b> You can skip this and jump straight to the
+install process as this will automatically build.
+<p><b>Note for Microsoft Windows:</b> Make sure the
+Microsoft Visual Tools environment is set up before this
+step.
+</ol>
+<p>
+<hr>
+<h3><a name="installing_the_driver">5.2 Installing the Driver</a></h3>
+<p>As with the build process, the installation process
+makes use of DistUtils. By default, the Ingres Python DBI
+driver is installed into Python's site-packages directory.
+The ability to provide alternate installation locations has
+not been investigated at this time. The only requirement
+for installing is to be able to write to the site-packages
+directory.
+<p>To install, execute the following command:
+<pre>
+python setup.py install
+</pre>
+<p>To create a deliverable source package, execute the
+following command:
+<pre>
+python setup.py sdist
+</pre>
+<p>
+<hr>
+<h2><a name="example_code">6.0 Example Code</a></h2>
+<p>The following code provides a simple Python database
+example using the Ingres Python DBI driver:
+<pre>
+import ingresdbi
+import pprint
+"""
+import os
+username=os.getenv('test_username')
+password=os.getenv('test_password')
+vnode=os.getenv('test_vnode')
+database=os.getenv('test_database')
+trace=None
+"""
+enable_trace = 0
+if enable_trace == 1:
+ trace=(7, None)
+else:
+ trace=(0, None)
+database='iidbdb'
+vnode='(local)'
+prog_str = 'DEMO SIMPLE SELECT'
+print prog_str, "connecting to database: " + database
+dc=ingresdbi.connect(database=database, vnode=vnode, trace=trace)
+print prog_str, "Creating new cursor()"
+c=dc.cursor()
+print prog_str, "About to call cursor.execute()"
+c.execute("select * from iidbconstants")
+print "cursor.description = "
+description = c.description
+pprint.pprint (description )
+print prog_str, "cursor.fetchall()"
+rows = c.fetchall()
+print "rows = ", rows
+row_count = 0
+for row in rows:
+ row_count = row_count + 1
+print 'Row #', row_count
+count = 0
+for column in row:
+ print description[count][0] , ': ', column
+ count = count + 1
+print "-----------------------------"
+print prog_str, "connection.commit()"
+dc.commit()
+print prog_str, "connection.close()"
+dc.close()
+</pre>
+<p>
+<hr>
+<h2><a name="known_issues">7.0 Known Issues</a></h2>
+<p>Known issues are as follows:
+<ul>
+<p><li>There is no support for installing to an alternate
+directory other than the default site-packages.
+<p><li>win32 only/Python 2.3 only - If distutils fails with:
+<pre>
+error: Python was built with version 6 of Visual Studio,
+and extensions need to be built with the same version of the
+compiler, but it isn't installed.
+</pre>
+<p>and you do have Visual Studio version 6 installed, run
+Microsoft Visual C++ 6.0 msdev.exe (the GUI), quit out, and
+then retry the build. For further information, see Python
+mailing list <a href="http://mail.python.org/pipermail/python-dev/2003-November/040478.html" target="_blank">http://mail.python.org/pipermail/python-dev/2003-November/040478.html</a>.
+</ul>
+<p>
+<hr>
+<h2><a name="contact_customer_support">8.0 Contact Customer Support</a></h2>
+<p>For online technical assistance and a complete list of
+locations, primary service hours, and telephone numbers,
+contact technical support at <a href="http://ingres.com/support" target="_blank">http://ingres.com/support</a>.
+<p>
+<hr>
+<font size=-2>
+© 2006 Ingres Corporation.
+All rights reserved.
+</font>
+</BODY>
+</HTML>
Added: drivers/python/trunk/dbi/iidbiconn.c
===================================================================
--- drivers/python/trunk/dbi/iidbiconn.c (rev 0)
+++ drivers/python/trunk/dbi/iidbiconn.c 2008-06-05 17:33:35 UTC (rev 42)
@@ -0,0 +1,611 @@
+/*
+** Copyright (c) 2006 Ingres Corporation
+**
+*/
+
+# ifdef WIN32
+# include <windows.h>
+# endif
+# include <sql.h>
+# include <sqlext.h>
+# include <iidbi.h>
+# include <iidbiconn.h>
+# include <iidbiutil.h>
+
+# ifndef TRUE
+# define TRUE 0
+# endif
+
+# ifndef FALSE
+# define FALSE 0
+# endif
+
+/**
+** Name: iidbiconn.c - Ingres Python DB API connection functions
+**
+** Description:
+** This file defines:
+**(E
+** dbi_connect() Create a connection to the specified database.
+** dbi_connectionClose() Close the connection & issue a rollback.
+** dbi_connectionCommit() Commit the current transaction.
+** dbi_connectionCursor() Declare a cursor. Return the handle.
+** dbi_connectionRollback() Rollback the transaction.
+**
+**)E
+**
+** History:
+** 08-jul-04 (peeje01)
+** Created.
+** 10-Jul-2004 (raymond.fan at ca.com)
+** Add ODBC body to stubs.
+** 10-Jul-2004 (raymond.fan at ca.com)
+** Moved print_err to iidbiutil.c.
+** 10-Jul-2004 (raymond.fan at ca.com)
+** Pointer (self) from python was not declared to be pointer.
+** Corrected indirection error and replaced use of global IIDBIenv
+** with (self).
+** 11-Jul-2004 (raymond.fan at ca.com)
+** Correct multiple connection handling.
+** 11-Jul-2004 (raymond.fan at ca.com)
+** Add iidbutil.h for internal tracing.
+** 12-Jul-2004 (raymond.fan at ca.com)
+** Add return and tracing of SQL errors.
+** 13-Jul-2004 (chris.clark at ca.com)
+** Centralize the determination of returned error status.
+** 14-Jul-2004 (raymond.fan at ca.com)
+** Add pdbc references to the trace prints to show owners.
+** 21-Oct-2004 (grant.croker at ca.com)
+** Corrected driver to call with an r3 installation
+** 04-Nov-2004 (ralph.loen at ca.com)
+** In dbi_connectionClose(), free the connection handle
+** after disconnection.
+** 21-Dec-2004 (ralph.loen at ca.com)
+** Added connection attribute "autocommit".
+** 15-dec-2005 (loera01)
+** Changed dbi_connect() so that only one argument is passed.
+** Add selectloops connection attribute.
+** 26-jul-2005 (loera01)
+** Add servertype connection attribute.
+**/
+
+/*{
+** Name: dbi_alloc_env
+**
+** Description:
+**
+**
+** Inputs:
+** penv - DBI environment handle.
+** pdbc - DBI connectio handle.
+**
+** Outputs:
+** New ODBC environment handle.
+**
+** Returns:
+** SQL_SUCCESS
+** SQL_INVALID_HANDLE
+** SQL_ERROR
+**
+** Side Effects:
+** Updates global DBI environment handle.
+**
+** History:
+** 05-June-2006 (loera01)
+** Created.
+}*/
+
+RETCODE
+dbi_alloc_env( IIDBI_ENV *penv, IIDBI_DBC *pdbc)
+{
+ HENV henv;
+ RETCODE rc, return_code = DBI_SQL_SUCCESS;
+ IIDBI_CONNECTION *conn = pdbc->conn;
+
+ DBPRINTF(DBI_TRC_ENTRY)( "%p: dbi_alloc_env }}}1\n", pdbc );
+
+ for (;;)
+ {
+ if (conn->pooled)
+ {
+ rc = SQLSetEnvAttr(SQL_NULL_HANDLE, SQL_ATTR_CONNECTION_POOLING,
+ (SQLPOINTER)SQL_CP_ONE_PER_HENV, sizeof(SQLINTEGER));
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL, NULL, &pdbc->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = SQLSetEnvAttr (%d) %s %s %x\n",
+ pdbc, rc, __LINE__, pdbc->hdr.err.sqlState,
+ pdbc->hdr.err.messageText,
+ pdbc->hdr.err.native );
+ break;
+ }
+ }
+ rc = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, henv, NULL, NULL, &pdbc->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = SQLAllocHandle SQL_HANDLE_ENV (%d) %s %s %x\n", pdbc,
+ rc, __LINE__, pdbc->hdr.err.sqlState, pdbc->hdr.err.messageText,
+ pdbc->hdr.err.native );
+ break;
+ }
+
+ penv->hdr.handle = henv;
+
+ rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
+ (void*)SQL_OV_ODBC3, 0);
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, henv, NULL, NULL, &pdbc->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = SQLSetEnvAttr (%d) %s %s %x\n", pdbc,
+ rc, __LINE__, pdbc->hdr.err.sqlState, pdbc->hdr.err.messageText,
+ pdbc->hdr.err.native );
+ break;
+ }
+ break;
+ }
+ DBPRINTF(DBI_TRC_ENTRY)( "%p: dbi_alloc_env {{{1\n", pdbc );
+ return return_code;
+}
+
+/*{
+** Name: dbi_connect -Create a connection to the specified database.
+**
+** Description:
+** Create a connection to the specified database.
+** The parameter dsn is the only required parameter, all others
+** are optional. The parameter list is DBMS dependent/defined(?)
+**
+** Assumptions:
+** The following global variables must be set:
+**(E
+** Name Meaning (possible values)
+** apilevel -DB API Level ('1.0' or '2.0')
+** thread safety -Thread safety (0, 1, 2, 3)
+** paramstyle -Parameter style ('qmark', 'numeric', 'format', 'pyformat')
+**)E
+**
+** Inputs:
+** IIDBI_DBC pdbc Control block
+** char *dsn Data Source Name
+** char *user User name
+** char *password Password
+** char *host Hostname
+** char *database Database
+**
+** Outputs:
+** Returns:
+** Database Connection
+** Exceptions:
+** Warning E.G. for data truncations
+** InterfaceError Database interface errors
+** DatabaseError Database errors
+** OperationalError Errors in database operation
+** IntegrityError Relational Integrity failure
+** InternalError Internal DB error
+** ProgrammingError Nonexistant Table, syntax, ...
+** NotSupportedError Unsupported API method used
+** Error All other errors
+**
+** Side Effects:
+**
+** History:
+** 08-Jul-2004 (peeje01)
+** Created.
+** 10-Jul-2004 (raymond.fan at ca.com)
+** Add ODBC connect code from clach04, loera01
+** 11-Jul-2004 (raymond.fan at ca.com)
+** Assign IIDBIenv with initial value on initialization.
+** Initialize henv from IIDBIenv.
+}*/
+RETCODE
+dbi_connect( IIDBI_DBC *pdbc)
+{
+ RETCODE rc = SQL_SUCCESS;
+ HDBC hdbc=NULL;
+ HENV henv=pdbc->env;
+ IIDBI_CONNECTION *conn = pdbc->conn;
+ char szConnStrIn[300]= "\0";
+ char szConnStrOut[300] = "\0";
+ SQLSMALLINT cbConnStrOut;
+ char *serverStr="SERVER=%s;";
+ char *dsnStr="DSN=%s;";
+ char *uidStr="UID=%s;";
+ char *pwdStr="PWD=%s;";
+ char *dbStr="DATABASE=%s;";
+ char *sloopStr="SELECTLOOPS=%s;";
+ char *stypeStr="SERVERTYPE=%s;";
+ char *driverStr="DRIVER=%s;";
+ char *rolenameStr="ROLENAME=%s;";
+ char *rolepwdStr="ROLEPWD=%s;";
+ char *groupStr="GROUP=%s;";
+ char *blankdateStr="BLANKDATE=%s;";
+ char *date1582Str="DATE1582=%s;";
+ char *catconnectStr="CATCONNECT=%s;";
+ char *numeric_overflowStr="NUMERIC_OVERFLOW=%s;";
+ char *catschemanullStr="CATSCHEMANULL=%s;";
+ char *dbms_pwdStr="DBMS_PWD=%s;";
+ char connStr[300];
+ int return_code = DBI_SQL_ERROR;
+
+ DBPRINTF(DBI_TRC_ENTRY)( "%p: dbi_connect {{{1\n", pdbc );
+ for(;;)
+ {
+ conn = (IIDBI_CONNECTION *)pdbc->conn;
+ rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
+ if (rc == SQL_INVALID_HANDLE)
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = SQLAllocHandle SQL_HANDLE_DBC (%d)\n", pdbc,
+ rc, __LINE__ );
+ return_code = DBI_INTERNAL_ERROR;
+ (void) dbi_error_withtext( rc, NULL, NULL, NULL, &pdbc->hdr.err, "SQLAllocHandle - Invalid handle." );
+ break;
+ }
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR(rc, NULL, hdbc, NULL, &pdbc->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = SQLDriverConnect (%d) %s %s %x\n", pdbc,
+ rc, __LINE__, pdbc->hdr.err.sqlState, pdbc->hdr.err.messageText,
+ pdbc->hdr.err.native );
+ break;
+ }
+
+ if (conn->connectstr && *conn->connectstr)
+ {
+ strcpy(szConnStrIn, conn->connectstr);
+ }
+ else
+ {
+ if (conn->dsn && *conn->dsn)
+ {
+ sprintf(szConnStrIn, dsnStr, conn->dsn);
+ }
+ else if (!conn->driver)
+ {
+ sprintf(szConnStrIn, "%s", "DRIVER=INGRES 3.0;");
+ }
+ else if (conn->driver && *conn->driver)
+ {
+ sprintf(connStr, driverStr, conn->driver);
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->vnode && *conn->vnode)
+ {
+ sprintf(connStr, serverStr, conn->vnode);
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->database && *conn->database)
+ {
+ sprintf(connStr, dbStr, conn->database);
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->uid && *conn->uid)
+ {
+ sprintf(connStr, uidStr, conn->uid);
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->pwd && *conn->pwd)
+ {
+ sprintf(connStr, pwdStr, conn->pwd);
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->selectloops)
+ {
+ sprintf(connStr, sloopStr, "Y");
+ strcat(szConnStrIn, connStr);
+ }
+ else
+ {
+ sprintf(connStr, sloopStr, "N");
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->blankdate)
+ {
+ sprintf(connStr, blankdateStr, "N");
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->date1582)
+ {
+ sprintf(connStr, date1582Str, "N");
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->catconnect)
+ {
+ sprintf(connStr, catconnectStr, "N");
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->numeric_overflow)
+ {
+ sprintf(connStr, numeric_overflowStr, "N");
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->catschemanull)
+ {
+ sprintf(connStr, catschemanullStr, "N");
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->servertype && *conn->servertype)
+ {
+ sprintf(connStr, stypeStr, conn->servertype);
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->rolename && *conn->rolename)
+ {
+ sprintf(connStr, rolenameStr, conn->rolename);
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->rolepwd && *conn->rolepwd)
+ {
+ sprintf(connStr, rolepwdStr, conn->rolepwd);
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->group && *conn->group)
+ {
+ sprintf(connStr, groupStr, conn->group);
+ strcat(szConnStrIn, connStr);
+ }
+ if (conn->dbms_pwd && *conn->dbms_pwd)
+ {
+ sprintf(connStr, dbms_pwdStr, conn->dbms_pwd);
+ strcat(szConnStrIn, connStr);
+ }
+ }
+ DBPRINTF(DBI_TRC_STAT)( "%p: Connecting to %s (%d)\n", pdbc, szConnStrIn, __LINE__ );
+ rc = SQLDriverConnect(hdbc, 0,
+ (SQLCHAR *)szConnStrIn, SQL_NTS, (SQLCHAR *)szConnStrOut,
+ sizeof(szConnStrOut), &cbConnStrOut,
+ SQL_DRIVER_NOPROMPT);
+ if (rc == SQL_INVALID_HANDLE)
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = SQLDriverConnect (%d)\n", pdbc, rc, __LINE__ );
+ return_code = DBI_INTERNAL_ERROR;
+ (void) dbi_error_withtext( rc, NULL, NULL, NULL, &pdbc->hdr.err, "SQLDriverConnect - Invalid handle." );
+ break;
+ }
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, hdbc, NULL, &pdbc->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = SQLDriverConnect (%d) %s %s %x\n", pdbc,
+ rc, __LINE__, pdbc->hdr.err.sqlState, pdbc->hdr.err.messageText,
+ pdbc->hdr.err.native );
+ break;
+ }
+ DBPRINTF(DBI_TRC_STAT)( "%p: Connected to %s (%d)\n", pdbc, szConnStrOut, __LINE__ );
+ pdbc->hdr.handle = hdbc;
+ if (conn->autocommit)
+ {
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%p: Connected. Setting autocommit to ON (%d)\n", pdbc,
+ __LINE__ );
+ rc = SQLSetConnectAttr(hdbc,SQL_ATTR_AUTOCOMMIT,
+ (SQLPOINTER)SQL_AUTOCOMMIT_ON, sizeof(SQLINTEGER));
+ }
+ else
+ {
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%p: Connected. Setting autocommit to OFF (%d)\n", pdbc,
+ __LINE__ );
+ rc = SQLSetConnectAttr(hdbc,SQL_ATTR_AUTOCOMMIT,
+ (SQLPOINTER)SQL_AUTOCOMMIT_OFF, sizeof(SQLINTEGER));
+ }
+ if (rc == SQL_INVALID_HANDLE)
+ {
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%p: %d = SQLSetConnectAttr SQL_ATTR_AUTOCOMMIT (%d)\n", pdbc,
+ rc, __LINE__ );
+ return_code = DBI_INTERNAL_ERROR;
+ (void) dbi_error_withtext( rc, NULL, NULL, NULL,
+ &pdbc->hdr.err, "SQLSetConnectAttr - Invalid handle." );
+ break;
+ }
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, hdbc, NULL, &pdbc->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = SQLConnectAttr SQL_AUTOCOMMIT_OFF (%d) %s %s %x\n", pdbc,
+ rc, __LINE__, pdbc->hdr.err.sqlState, pdbc->hdr.err.messageText,
+ pdbc->hdr.err.native );
+ break;
+ }
+ return_code = DBI_SQL_SUCCESS;
+ break;
+ }
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_connect }}}1\n", pdbc);
+ return return_code;
+}
+
+/*{
+** Name: dbi_connectionClose - Issue a rollback and close the connection.
+**
+Corrected driver to call with an r3 installatioCorrected driver to call with an r3 installation
+** Inputs:
+** None.
+**
+** Outputs:
+** None.
+**
+** Side Effects:
+**
+** History:
+** 08-Jul-2004 (peeje01)
+** Created.
+** 10-Jul-2004 (raymond.fan at ca.com)
+** Add ODBC connect code from clach04, loera01
+}*/
+RETCODE
+dbi_connectionClose( IIDBI_DBC *pdbc )
+{
+ RETCODE rc;
+ HDBC hdbc = pdbc->hdr.handle;
+ int return_code = DBI_SQL_SUCCESS;
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_connectionClose {{{1\n", pdbc);
+
+ if (hdbc)
+ {
+ rc = SQLDisconnect(hdbc);
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, hdbc, NULL, &pdbc->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = SQLDisconnect (%d) %s %s %x\n", pdbc,
+ rc, __LINE__, pdbc->hdr.err.sqlState, pdbc->hdr.err.messageText,
+ pdbc->hdr.err.native );
+ }
+ else
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: Disconnected successfully (%d)\n", pdbc, __LINE__ );
+ }
+ }
+
+ rc = SQLFreeConnect( hdbc );
+ if (rc == SQL_INVALID_HANDLE)
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: Invalid ODBC connection handle (%d)\n",
+ pdbc, __LINE__ );
+ if (return_code == DBI_SQL_SUCCESS)
+ return_code = DBI_INTERNAL_ERROR;
+ }
+ else if (rc == SQL_ERROR)
+ {
+ if (return_code == DBI_SQL_SUCCESS)
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pdbc, &pdbc->hdr.err );
+
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = dbi_connectionClose (%d) %s %s %x\n",
+ pdbc, rc, __LINE__, pdbc->hdr.err.sqlState,
+ pdbc->hdr.err.messageText, pdbc->hdr.err.native );
+ }
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_connectionClose }}}1\n", pdbc);
+ return return_code;
+}
+
+/*{
+** Name: dbi_connectionCommit -Issue a commit
+**
+** Description:
+** Commit pending transaction.
+**
+** Inputs:
+** None.
+**
+** Outputs:
+** None.
+** Returns:
+** void
+** Exceptions:
+** None.
+**
+** Side Effects:
+** None.
+**
+** History:
+** 08-Jul-2004 (peeje01)
+** Created.
+** 10-Jul-2004 (raymond.fan at ca.com)
+** Add ODBC connect code from clach04, loera01
+}*/
+RETCODE
+dbi_connectionCommit( IIDBI_DBC *pdbc )
+{
+ RETCODE rc;
+ HDBC hdbc = pdbc->hdr.handle;
+ int return_code = DBI_SQL_ERROR;
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_connectionCommit {{{1\n", pdbc);
+ rc = SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, hdbc, NULL, &pdbc->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = SQLEndTran SQL_COMMIT (%d) %s %s %x\n", pdbc,
+ rc, __LINE__, pdbc->hdr.err.sqlState, pdbc->hdr.err.messageText,
+ pdbc->hdr.err.native );
+ }
+ else
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: Committed successfully (%d)\n", pdbc, __LINE__ );
+ return_code = DBI_SQL_SUCCESS;
+ }
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_connectionCommit }}}1\n", pdbc);
+ return return_code;
+}
+
+/*{
+** Name: dbi_connectionCursor - Return a cursor object
+**
+** Description:
+** Return a new cursor object using the connection.
+**
+** Inputs:
+** None.
+**
+** Outputs:
+** None.
+** Returns:
+** The new cursor object.
+** Exceptions:
+** None.
+**
+** Side Effects:
+**
+** History:
+** 08-Jul-2004 (peeje01)
+** Created.
+}*/
+RETCODE
+dbi_connectionCursor( IIDBI_DBC *pdbc )
+{
+ int return_code = DBI_SQL_SUCCESS;
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_connectionCursor {{{1\n", pdbc);
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_connectionCursor }}}1\n", pdbc);
+ return(return_code);
+}
+
+/*{
+** Name: dbi_connectionRollback - Issue a rollabck
+**
+** Description:
+** Issue a rollback on the connection
+**
+** Inputs:
+** None.
+**
+** Outputs:
+** None.
+** Returns:
+** None.
+** Exceptions:
+** None.
+**
+** Side Effects:
+**
+** History:
+** 08-Jul-2004 (peeje01)
+** Created.
+** 10-Jul-2004 (raymond.fan at ca.com)
+** Corrected iiDBIenv to resolve.
+}*/
+RETCODE
+dbi_connectionRollback( IIDBI_DBC *pdbc )
+{
+ RETCODE rc;
+ HDBC hdbc = pdbc->hdr.handle;
+ int return_code = DBI_SQL_ERROR;
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_connectionRollback {{{1\n", pdbc);
+
+ rc = SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_ROLLBACK);
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, hdbc, NULL, &pdbc->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = SQLEndTran SQL_ROLLBACK (%d) %s %s %x\n", pdbc,
+ rc, __LINE__, pdbc->hdr.err.sqlState, pdbc->hdr.err.messageText,
+ pdbc->hdr.err.native );
+ }
+ else
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: Rolled back successfully (%d)\n", pdbc, __LINE__ );
+ return_code = DBI_SQL_SUCCESS;
+ }
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_connectionRollback }}}1\n", pdbc);
+ return return_code;
+}
Added: drivers/python/trunk/dbi/iidbicurs.c
===================================================================
--- drivers/python/trunk/dbi/iidbicurs.c (rev 0)
+++ drivers/python/trunk/dbi/iidbicurs.c 2008-06-05 17:33:35 UTC (rev 42)
@@ -0,0 +1,2007 @@
+/*
+** Copyright (c) 2006 Ingres Corporation
+**
+*/
+# ifdef WIN32
+# include <windows.h>
+# endif
+# include <sql.h>
+# include <sqlext.h>
+# include <iidbi.h>
+# include <iidbicurs.h>
+# include <iidbiutil.h>
+
+#define MAX_DISPLAY_SIZE 0x7fffffff
+/**
+** Name: iidbicurs.c - Ingres Python DB API cursor functions
+**
+** Description:
+** This file defines:
+**(E
+** dbi_cursorClose() Close the cursor.
+** dbi_cursorExecute() Prepare and execute a statement with vargs.
+** dbi_cursorFetchone() Fetch one row from a cursor.
+** dbi_cursorFetchall() Fetch all rows from a cursor.
+**
+**)E
+**
+** History:
+** 08-jul-04 (peeje01)
+** Created.
+** 11-Jul-2004 (raymond.fan at ca.com)
+** Add trace messages.
+** 13-Jul-2004 (raymond.fan at ca.com)
+** Allow reuse same python cursor for SQL statements.
+** 14-Jul-2004 (raymond.fan at ca.com)
+** Add pstmt references to the trace prints to show owners.
+** 16-Jul-2004 (raymond.fan at ca.com)
+** Fix up heap and memory corruptions.
+** 17-Jul-2004 (komve01 at ca.com)
+** Fixed the float and real data type interpretation.
+** 17-Jul-2004 (komve01 at ca.com)
+** Fixed dbi_freeDescriptor. Clean parameter if isParam is one.
+** else clean descriptor block.
+** 17-Jul-2004 (raymond.fan at ca.com)
+** First attempt at select of binary data, as long as the blob fits
+** in the initial segment.
+** 17-Jul-2004 (komve01 at ca.com)
+** Added support for float,real and double type parameters in
+** BindParameters.
+** 19-Jul-2004 (komve01 at ca.com)
+** Added support for long BindParameters.
+** 19-Jul-2004 (raymond.fan at ca.com)
+** Add bind parameter handling of binary types and handing of
+** passing data as part of the execute.
+** 19-Jul-2004 (raymond.fan at ca.com)
+** Keep track of amount of data retrieved from the database for
+** binary types.
+** 19-Jul-2004 (raymond.fan at .ca.com)
+** Correct function sequence error caused by early termination of
+** an SQLPutParam loop.
+** 20-Jul-2004 (chris.clark at .ca.com)
+** Return errors if Execute fail (i.e. errors from DBMS for any
+** reason), e.g. Syntax errors, duplicate key on insert, etc.
+** 21-Jul-2004 (raymond.fan at ca.com)
+** Use memcpy for binary copies.
+** 21-Jul-2004 (raymond.fan at ca.com)
+** Modifed select of binary types to enable blobs greater then the
+** specfied segment size.
+** 22-Jul-2004 (raymond.fan at ca.com)
+** Modified put data loop to remove memcpy.
+** 22-Jul-2004 (komve01 at ca.com)
+** Fixed BIGINT conversion.
+** 23-Jul-2004 (komve01 at ca.com)
+** Commented a debug printf statement.
+** 17-Sep-2004 (Ralph.Loen at ca.com)
+** In dbi_fetchone(), added support for BIGINT.
+** 21-Oct-2004 (Ralph.Loen at ca.com)
+** Cleaned up treatment of SQLBindParameter() for ints and bigints.
+** Set new "fetchDone" flag in the cursor statement handle so that
+** unnecessary calls to SQLCancel() are prevented.
+** 22-Oct-2004 (Ralph.Loen at ca.com)
+** Fixed up support for FLOAT4 and FLOAT8.
+** 08-Nov-2004 (grant.croker at ca.com)
+** Fixed data truncation in SQL_CHAR and SQL_VARCHAR types.
+** 13-Dec-2004 (Ralph.Loen at ca.com)
+** Bind "None" parameters as typeless nulls.
+** 07-Jan-2004 (Ralph.Loen at ca.com)
+** Add dbi_freeData().
+** 14-Jan-2005 (Ralph.Loen at ca.com)
+** Initial support for Unicode data types.
+** 31-Jan-2005 (Ralph.Loen at ca.com)
+** In dbi_cursorFetchone(), allow for terminating character in
+** segments when fetching long varchars.
+** 01-Feb-2005 (Ralph.Loen at ca.com)
+** Added cursor rowcount attribute.
+** 07-Feb-2004 (Ralph.Loen at ca.com)
+** Increased blob segment size to 100,000 and changed some calloc's to
+** malloc's to improve performance.
+** 19-may-2005 (Ralph.Loen at ca.com)
+** Added support for row-returning procedures in Cursor.callproc().
+** Return input parameters. Output and BYREF parameters are still
+** not supported because the DBI specs aren't flexible enough to
+** work with Ingres limitations.:
+** 22-nov-2005 (loera01)
+** Initialize rowcount to -1.
+** 26-jan-2006 (loera01)
+** Set the cursor description's "display size" attribute to -1 if
+** specified as 2G (applies to blobs).
+** 27-Feb-2006 (Ralph.Loen at ingres.com)
+** Added detail to dbi_allocDescriptor() and dbi_freeDescriptor()
+** DBI trace messages.
+** 20-may-2006 (Ralph.Loen at ingres.com)
+** Added cursor.setinputsizes() and cursor.setoutputsize().
+**/
+
+RETCODE BindParameters(IIDBI_STMT *pstmt, unsigned char isProc);
+
+/*{
+** Name: dbi_cursorClose - Close the cursor
+**
+** Description:
+** Close the cursor
+**
+** Inputs:
+** None.
+**
+** Outputs:
+** None.
+** Returns:
+** None.
+** Exceptions:
+** None.
+**
+** Side Effects:
+**
+** History:
+** 08-Jul-2004 (peeje01)
+** Created.
+}*/
+
+RETCODE
+dbi_cursorClose( IIDBI_STMT* pstmt )
+{
+ RETCODE rc = SQL_SUCCESS, return_code = DBI_SQL_SUCCESS;
+ HSTMT hstmt = NULL;
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_cursorClose {{{1\n", pstmt);
+ if (!pstmt)
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: Invalid cursor statement handle (%d)\n",
+ pstmt, __LINE__ );
+ return_code = DBI_INTERNAL_ERROR;
+ goto exitCloseCursor;
+ }
+ pstmt->rowCount = -1;
+ hstmt = pstmt->hdr.handle;
+ if (hstmt)
+ {
+ if (pstmt->hasResultSet)
+ {
+ if (!pstmt->fetchDone)
+ {
+ rc = SQLCancel(hstmt);
+ if (rc == SQL_INVALID_HANDLE)
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: Invalid ODBC statement handle (%d)\n",
+ pstmt, __LINE__ );
+ return_code = DBI_INTERNAL_ERROR;
+ goto exitCloseCursor;
+ }
+ if (rc == SQL_ERROR)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = dbi_cursorClose (%d) %s %s %x\n",
+ pstmt, rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native );
+ goto exitCloseCursor;
+ }
+ }
+ pstmt->hasResultSet = 0;
+ }
+exitCloseCursor:
+ if (hstmt)
+ {
+ rc = SQLFreeStmt( hstmt, SQL_DROP );
+ if (rc == SQL_INVALID_HANDLE)
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: Invalid ODBC statement handle (%d)\n",
+ pstmt, __LINE__ );
+ if (return_code == DBI_SQL_SUCCESS)
+ return_code = DBI_INTERNAL_ERROR;
+ }
+ else if (rc == SQL_ERROR)
+ {
+ if (return_code == DBI_SQL_SUCCESS)
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+
+ DBPRINTF(DBI_TRC_STAT)( "%p: %d = dbi_cursorClose (%d) %s %s %x\n",
+ pstmt, rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native );
+ }
+ }
+ }
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_cursorClose }}}1\n", pstmt);
+ return( return_code );
+}
+
+/*{
+** Name: dbi_cursorExecute - Execute an (optionally prepared) statement
+**
+** Description:
+** Execute an SQL statement. Parameters may be provided as a
+** sequence or mapping and will be bound to variables in the operation.
+**
+** The cursor retains a reference to the operation (object?). If the
+** same operation object is passed in again, the cursor can optimize
+** its behaviour.
+**
+** If so requested, prepare the statement prior to execution.
+**
+** Example:
+**(E
+** my_cur.execute('SELECT :a FROM t1 WHERE :a = :b', a='name', b='fred');
+**)E
+** Inputs:
+** char *operation The statement to be executed
+** char *parameter Optional parameter(s) to be passed to the statement
+**
+** Outputs:
+** <param name> <output value description>
+** Returns:
+** <function return values>
+** Exceptions:
+** <exception codes>
+**
+** Side Effects:
+**
+** History:
+** 08-Jul-2004 (peeje01)
+** Created.
+** 11-Jul-2004 (raymond.fan at ca.com)
+** Replace initialization of henv with python object rather than
+** global environment.
+** 13-Jul-2004 (raymond.fan at ca.com)
+** Initialize hstmt if we determine that there is already
+** a statement handle allocated.
+** 15-Jul-2004 (raymond.fan at ca.com)
+** Removed bigint type code to return value as bigint.
+** Instead use default code to return as string and have
+** a wrapper in the host language layer.
+** This overcomes mapping deficiencies in our SWIG implementation.
+** 20-Jul-2004 (raymond.fan at ca.com)
+** Update put data loop to correct function execute sequence errors.
+** 21-Jul-2004 (raymond.fan at ca.com)
+** Replace strncpy with memcpy.
+** 22-Jul-2004 (raymond.fan at ca.com)
+** Restructured to remove memcpy on put data.
+** 22-Jul-2004 (raymond.fan at ca.com)
+** For blobs where the last segment does not fall on a segment
+** boundary include an increment of the data pointer.
+}*/
+
+RETCODE
+dbi_cursorExecute( IIDBI_DBC* pdbc, IIDBI_STMT* pstmt, char *stmnt,
+ unsigned char isProc )
+{
+ HDBC hdbc = NULL;
+ HSTMT hstmt = NULL;
+ RETCODE rc = SQL_SUCCESS;
+#define PUTSEGMENT_SIZE 100000
+ SQLUINTEGER colNbr;
+ SQLSMALLINT numCols = 0;
+ SQLINTEGER numRows = -1;
+ int return_code = DBI_SQL_SUCCESS;
+ int lenCntr = 0;
+ int idx=0;
+ IIDBI_DESCRIPTOR **parameter = pstmt->parameter;
+ char* data;
+ int len=0;
+ int colPrev = -1;
+ int putSegmentSize = 0;
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_cursorExecute {{{1\n", pstmt);
+
+ if (pdbc)
+ hdbc = pdbc->hdr.handle;
+ else
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: Invalid connection handle (%d)\n",
+ pdbc, __LINE__ );
+ return DBI_INTERNAL_ERROR;
+ }
+
+ for(;;)
+ {
+ hstmt = pstmt->hdr.handle ? pstmt->hdr.handle : NULL;
+ pstmt->rowCount = -1;
+ if (pstmt->hasResultSet)
+ {
+ if (!pstmt->fetchDone)
+ rc = SQLCancel(hstmt);
+ pstmt->hasResultSet = 0;
+ }
+ if (pstmt->descCount)
+ {
+ rc = dbi_freeDescriptor(pstmt, 0);
+ pstmt->hasResultSet = 0;
+ }
+ if (!pstmt->prepareRequested)
+ {
+ if (hstmt)
+ {
+ rc = SQLFreeStmt(hstmt, SQL_DROP);
+ if (rc == SQL_INVALID_HANDLE)
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: Invalid ODBC handle (%d)\n",
+ pstmt, __LINE__ );
+ return_code = DBI_INTERNAL_ERROR;
+ break;
+ }
+
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, hdbc, NULL,
+ &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = SQLAllocHandle SQL_HANDLE_STMT (%d) %s %s %x\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText, pstmt->hdr.err.native );
+ break;
+ }
+ }
+ rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
+ if (rc == SQL_INVALID_HANDLE)
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: Invalid ODBC handle (%d)\n", pstmt, __LINE__ );
+ return_code = DBI_INTERNAL_ERROR;
+ break;
+ }
+
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, hdbc, NULL,
+ &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = SQLAllocHandle SQL_HANDLE_STMT (%d) %s %s %x\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText, pstmt->hdr.err.native );
+ break;
+ }
+
+ pstmt->hdr.handle = hstmt;
+ } /* if (!pstmt->prepareRequested */
+ else
+ {
+ if (!hstmt)
+ {
+ rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
+ if (rc == SQL_INVALID_HANDLE)
+ {
+ DBPRINTF(DBI_TRC_STAT)( "%p: Invalid ODBC handle (%d)\n",
+ pstmt, __LINE__ );
+ return_code = DBI_INTERNAL_ERROR;
+ break;
+ }
+
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, hdbc, NULL,
+ &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = SQLAllocHandle SQL_HANDLE_STMT (%d) %s %s %x\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText, pstmt->hdr.err.native );
+ break;
+ }
+ pstmt->hdr.handle = hstmt;
+ }
+ if (!pstmt->prepareCompleted)
+ {
+ DBPRINTF(DBI_TRC_STAT)("Preparing the query %s\n",stmnt);
+ rc = SQLPrepare(hstmt, (SQLCHAR *)stmnt, SQL_NTS);
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL, hstmt,
+ &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = SQLPrepare SQL_HANDLE_STMT (%d) %s %s %x\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText, pstmt->hdr.err.native );
+ pstmt->prepareRequested = FALSE;
+ break;
+ }
+ pstmt->prepareCompleted = TRUE;
+ }
+ }
+ if (pstmt->parmCount)
+ return_code = BindParameters(pstmt, isProc);
+
+ DBPRINTF(DBI_TRC_STAT)("Executing the query %s\n",stmnt);
+
+ if (pstmt->prepareCompleted)
+ rc = SQLExecute(hstmt);
+ else
+ rc = SQLExecDirect(hstmt, (SQLCHAR *)stmnt, SQL_NTS);
+ if( rc == SQL_NEED_DATA)
+ {
+ while(rc == SQL_NEED_DATA)
+ {
+ rc = SQLParamData( hstmt, (SQLPOINTER)&colNbr );
+ if (rc == SQL_NEED_DATA)
+ {
+ if (colPrev > 0 && colNbr != colPrev)
+ len = 0;
+ colPrev = colNbr;
+
+ /*
+ ** Bindparameter stored a '1' based index of parameter
+ ** passed. Use this number to get the parameter
+ ** descriptor
+ */
+ idx = (int)colNbr - 1;
+ data = parameter[idx]->data;
+ lenCntr = parameter[idx]->precision;
+ /*
+ ** Use do/while loop. A zero length binary would cause
+ ** a function execute error
+ */
+ if (pstmt->inputSegmentSize && pstmt->inputSegmentLen &&
+ colNbr <= pstmt->inputSegmentLen)
+ putSegmentSize = pstmt->inputSegmentSize[colNbr - 1];
+ else
+ putSegmentSize = PUTSEGMENT_SIZE;
+
+ do
+ {
+ int putrc;
+ if (lenCntr < putSegmentSize)
+ {
+ /*
+ ** Bump the data pointer for the last write.
+ */
+ data += len;
+ len = lenCntr;
+ lenCntr = 0;
+ }
+ else
+ {
+ if (len)
+ data += len;
+ if (lenCntr < putSegmentSize)
+ len = lenCntr;
+ else
+ len = putSegmentSize;
+ lenCntr -= len;
+ }
+ /*
+ ** Don't update rc from the SQLPutData as the
+ ** loop relies on rc and early termination of the
+ ** loop, without error, causes an execute sequence
+ ** error.
+ */
+ if ((putrc = SQLPutData( hstmt, data, len)) ==
+ SQL_ERROR)
+ {
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = IIDBIExecute (%d) %s %s %x\n %s\n",
+ putrc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native, stmnt );
+ /*
+ ** Error returned. Change return code to break loop
+ */
+ rc = putrc;
+ break;
+ }
+ }while (lenCntr);
+ } /* if (rc == SQL_NEED_DATA) from SQLParamData */
+ } /* while rc == SQL_NEED_DATA */
+ }
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL, hstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = IIDBIExecute (%d) %s %s %x\n %s\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText, pstmt->hdr.err.native, stmnt );
+ break;
+ }
+ if ( !isProc && pstmt->parmCount)
+ {
+ rc = dbi_freeDescriptor(pstmt, 1);
+ }
+ rc = SQLNumResultCols(hstmt, &numCols);
+ if (SQL_SUCCEEDED(rc) && numCols)
+ {
+ DBPRINTF(DBI_TRC_STAT)
+ ("Number of cols is %d\n",numCols);
+ pstmt->hasResultSet = 1;
+ pstmt->descCount = numCols;
+ break;
+ }
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL, hstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = IIDBIExecute (%d) %s %s %x\n %s\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText, pstmt->hdr.err.native, stmnt );
+ break;
+ }
+ rc = SQLRowCount(hstmt, &numRows);
+ if (SQL_SUCCEEDED(rc) && numRows)
+ {
+ DBPRINTF(DBI_TRC_STAT)
+ ("Number of rows is %d\n",numRows);
+ pstmt->rowCount = numRows;
+ break;
+ }
+ else
+ pstmt->rowCount = -1;
+
+ if (rc != SQL_SUCCESS)
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL, hstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = IIDBIExecute (%d) %s %s %x\n %s\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText, pstmt->hdr.err.native, stmnt );
+ break;
+ }
+
+ break;
+
+ } /* end for (;;) */
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_cursorExecute }}}1\n", pstmt);
+
+ return( return_code );
+}
+
+/*{
+** Name: dbi_cursorFetchone - Fetch one row from a statement
+**
+** Description:
+** Fetch one (remaining) row returned from a statement
+**
+** Inputs:
+** None.
+**
+** Outputs:
+** Returns the tuple
+** Returns:
+** ODBC error status
+**
+** Exceptions:
+** An error is raised if the previous call to executeXXX() did
+** not produce any result set or no call was issued yet.
+**
+** Side Effects:
+**
+** History:
+** 08-Jul-2004 (peeje01)
+** Created.
+** 12-Jul-2004 (loera01 at ca.com)
+** Implemented IIDBI_DESCRIPTOR.
+** 17-Jul-2004 (komve01 at ca.com)
+** Fixed the float and real data type interpretation.
+** 17-Jul-2004 (raymond.fan at ca.com)
+** Change C type for LONGVARBINARY.
+** 19-Jul-2004 (loera01 at ca.com)
+** Added puts of binary blob data.
+** 19-Jul-2004 (raymond.fan at ca.com)
+** Add tracking of length to binary objects and report total length
+** in descriptor field.
+** 20-Jul-2004 (loera01 at ca.com)
+** Fixed puts of binary blob data.
+** 21-Jul-2004 (raymond.fan at ca.com)
+** Modified the alogorithm for selecting blobs greater than segment
+** size. Fetch direct into the memory buffer - remove copies.
+** Uses realloc call - this may be problematic when we want to move
+** to the CL.
+** 21-Jul-2004 (Ralph.Loen at ca.com)
+** When binding blobs, do not invoke SQL_DATA_LEN_AT_EXEC macro if
+** the blob has zero length.
+** 23-Jul-2004 (Ralph.Loen at ca.com)
+** 19-Oct-2004 (Ralph.Loen at ca.com)
+** Fetch long varchars into SQL_C_CHAR, not SQL_C_BINARY.
+** 31-Jan-2005 (Ralph.Loen at ca.com)
+** Allow for terminating character in segments when fetching long
+** varchars.
+}*/
+RETCODE
+dbi_cursorFetchone( IIDBI_STMT *pstmt )
+{
+ RETCODE rc, return_code;
+ HSTMT hstmt = pstmt->hdr.handle;
+ int i, nType;
+ SQLINTEGER orind;
+#define SEGMENT_SIZE 1000000
+ char *segment = NULL;
+ int count;
+ char* ptr;
+ int newalloc = 0;
+ int segment_size = 0;
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_cursorFetchone {{{1\n", pstmt);
+ rc = SQLFetch(hstmt);
+ if (rc == SQL_NO_DATA)
+ {
+ pstmt->fetchDone = TRUE;
+ return DBI_SQL_NO_DATA;
+ }
+ else
+ pstmt->fetchDone = FALSE;
+
+ if (SQL_SUCCEEDED(rc))
+ {
+ if (pstmt->rowCount == -1)
+ pstmt->rowCount = 1;
+ else
+ pstmt->rowCount++;
+
+ for (i = 0; i < pstmt->descCount; i++)
+ {
+ switch (pstmt->descriptor[i]->type)
+ {
+ case SQL_WVARCHAR:
+ case SQL_WCHAR:
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_WCHAR,
+ pstmt->descriptor[i]->data,
+ pstmt->descriptor[i]->precision +
+ sizeof (SQLWCHAR),
+ &orind);
+ if (orind == SQL_NULL_DATA)
+ pstmt->descriptor[i]->isNull = 1;
+ else
+ pstmt->descriptor[i]->isNull = 0;
+
+ if (rc == SQL_NO_DATA)
+ pstmt->fetchDone = TRUE;
+
+ if (SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA)
+ {
+ rc = DBI_SQL_SUCCESS;
+ break;
+ }
+ else
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = dbi_cursorFetchone (%d) %s %s %x\n\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native);
+ return return_code;
+ }
+ break;
+
+ case SQL_WLONGVARCHAR:
+ /*
+ ** Initialization of descriptor and temporaries
+ */
+ count = 0;
+ pstmt->descriptor[i]->data = NULL;
+ pstmt->descriptor[i]->isNull = 0;
+ pstmt->descriptor[i]->precision = 0;
+ if (pstmt->outputColumnIndex && (i+1) ==
+ pstmt->outputColumnIndex)
+ segment_size = pstmt->outputSegmentSize;
+ else if (pstmt->outputColumnIndex && (i+1) !=
+ pstmt->outputColumnIndex)
+ segment_size = SEGMENT_SIZE;
+ else if (pstmt->outputSegmentSize)
+ segment_size = pstmt->outputSegmentSize;
+ else
+ segment_size = SEGMENT_SIZE;
+ segment = malloc( segment_size + 1);
+ ptr = segment;
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_WCHAR,
+ ptr, segment_size, &orind);
+ if (orind == SQL_NULL_DATA)
+ {
+ if (segment != NULL)
+ {
+ free( segment );
+ }
+ pstmt->descriptor[i]->isNull = 1;
+ rc = SQL_SUCCESS;
+ }
+ else
+ {
+ while(SQL_SUCCEEDED(rc))
+ {
+ /*
+ ** orind contains length of data left in the driver
+ ** Not sure that this is correct.
+ */
+ if (orind > segment_size)
+ {
+ /*
+ ** We have segment_size in the buffer
+ */
+ count += segment_size;
+ /*
+ ** Add another segment to the buffer
+ ** include adjustment for null terminator
+ ** for long varchar.
+ */
+ newalloc = count + segment_size + 1;
+ segment = realloc( segment, newalloc );
+ ptr = segment + count;
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_CHAR,
+ ptr, segment_size, &orind);
+ }
+ else
+ {
+ count += orind;
+ break;
+ }
+ }
+ if (SQL_SUCCEEDED(rc))
+ {
+ pstmt->descriptor[i]->data = segment;
+ pstmt->descriptor[i]->precision = count;
+ }
+ }
+ if (!SQL_SUCCEEDED(rc))
+ {
+ if (segment != NULL)
+ {
+ free( segment );
+ }
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+ }
+ break;
+
+
+ case SQL_LONGVARCHAR:
+ /*
+ ** Initialization of descriptor and temporaries
+ */
+ count = 0;
+ pstmt->descriptor[i]->data = NULL;
+ pstmt->descriptor[i]->isNull = 0;
+ pstmt->descriptor[i]->precision = 0;
+ if (pstmt->outputColumnIndex && (i+1) ==
+ pstmt->outputColumnIndex)
+ segment_size = pstmt->outputSegmentSize;
+ else if (pstmt->outputColumnIndex && (i+1) !=
+ pstmt->outputColumnIndex)
+ segment_size = SEGMENT_SIZE;
+ else if (pstmt->outputSegmentSize)
+ segment_size = pstmt->outputSegmentSize;
+ else
+ segment_size = SEGMENT_SIZE;
+ segment = malloc( segment_size + 1);
+ ptr = segment;
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_CHAR,
+ ptr, segment_size, &orind);
+ if (orind == SQL_NULL_DATA)
+ {
+ if (segment != NULL)
+ {
+ free( segment );
+ }
+ pstmt->descriptor[i]->isNull = 1;
+ rc = SQL_SUCCESS;
+ }
+ else if (rc == SQL_SUCCESS)
+ {
+ pstmt->descriptor[i]->data = segment;
+ pstmt->descriptor[i]->precision = orind;
+ }
+ else
+ {
+ while(SQL_SUCCEEDED(rc))
+ {
+ /*
+ ** Orind contains length of data left in the driver.
+ */
+ if (orind >= segment_size)
+ {
+ /*
+ ** We have segment_size in the buffer
+ */
+ count += segment_size - 1;
+ /*
+ ** Add another segment to the buffer
+ ** include adjustment for null terminator
+ ** for long varchar.
+ */
+ newalloc = count + segment_size;
+ segment = realloc( segment, newalloc );
+ ptr = segment + count;
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_CHAR,
+ ptr, segment_size, &orind);
+ }
+ else
+ {
+ count += orind;
+ break;
+ }
+ }
+ if (SQL_SUCCEEDED(rc))
+ {
+ pstmt->descriptor[i]->data = segment;
+ pstmt->descriptor[i]->precision = count;
+ }
+ }
+ if (!SQL_SUCCEEDED(rc))
+ {
+ if (segment != NULL)
+ {
+ free( segment );
+ }
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+ }
+ break;
+
+ case SQL_LONGVARBINARY:
+ /*
+ ** Initialization of descriptor and temporaries
+ */
+ count = 0;
+ pstmt->descriptor[i]->data = NULL;
+ pstmt->descriptor[i]->isNull = 0;
+ pstmt->descriptor[i]->precision = 0;
+ if (pstmt->outputColumnIndex && (i+1) ==
+ pstmt->outputColumnIndex)
+ segment_size = pstmt->outputSegmentSize;
+ else if (pstmt->outputColumnIndex && (i+1) !=
+ pstmt->outputColumnIndex)
+ segment_size = SEGMENT_SIZE;
+ else if (pstmt->outputSegmentSize)
+ segment_size = pstmt->outputSegmentSize;
+ else
+ segment_size = SEGMENT_SIZE;
+ segment = malloc( segment_size + 1);
+ ptr = segment;
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_BINARY,
+ ptr, segment_size, &orind);
+ if (orind == SQL_NULL_DATA)
+ {
+ if (segment != NULL)
+ {
+ free( segment );
+ }
+ pstmt->descriptor[i]->isNull = 1;
+ rc = SQL_SUCCESS;
+ }
+ else
+ {
+ while(SQL_SUCCEEDED(rc))
+ {
+ /*
+ ** orind contains length of data left in the driver
+ ** Not sure that this is correct.
+ */
+ if (orind > segment_size)
+ {
+ /*
+ ** We have segment_size in the buffer
+ */
+ count += segment_size;
+ /*
+ ** Add another segment to the buffer
+ ** include adjustment for null terminator
+ ** for long varchar.
+ */
+ newalloc = count + segment_size + 1;
+ segment = realloc( segment, newalloc );
+ ptr = segment + count;
+ rc = SQLGetData(pstmt->hdr.handle, i+1,
+ SQL_C_BINARY, ptr, segment_size, &orind);
+ }
+ else
+ {
+ count += orind;
+ break;
+ }
+ }
+ if (SQL_SUCCEEDED(rc))
+ {
+ pstmt->descriptor[i]->data = segment;
+ pstmt->descriptor[i]->precision = count;
+ }
+ }
+ if (!SQL_SUCCEEDED(rc))
+ {
+ if (segment != NULL)
+ {
+ free( segment );
+ }
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+ }
+ break;
+
+ case SQL_FLOAT:
+ case SQL_REAL:
+ case SQL_DOUBLE:
+ nType = pstmt->descriptor[i]->type;
+
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_DOUBLE,
+ pstmt->descriptor[i]->data,
+ pstmt->descriptor[i]->precision,
+ &orind);
+ if (orind == SQL_NULL_DATA)
+ pstmt->descriptor[i]->isNull = 1;
+ else
+ pstmt->descriptor[i]->isNull = 0;
+ if (rc == SQL_NO_DATA)
+ pstmt->fetchDone = TRUE;
+ if (SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA)
+ {
+ rc = DBI_SQL_SUCCESS;
+ break;
+ }
+ else
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = dbi_cursorFetchone (%d) %s %s %x\n\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native);
+ if (segment)
+ {
+ free(segment);
+ segment = 0;
+ }
+ return return_code;
+ }
+ break;
+
+ case SQL_BIGINT:
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_SBIGINT,
+ pstmt->descriptor[i]->data,
+ pstmt->descriptor[i]->precision,
+ &orind);
+ if (orind == SQL_NULL_DATA)
+ pstmt->descriptor[i]->isNull = 1;
+ else
+ pstmt->descriptor[i]->isNull = 0;
+ if (rc == SQL_NO_DATA)
+ pstmt->fetchDone = TRUE;
+ if (SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA)
+ {
+ rc = DBI_SQL_SUCCESS;
+ break;
+ }
+ else
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = dbi_cursorFetchone (%d) %s %s %x\n\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native);
+ return return_code;
+ }
+ break;
+
+
+ case SQL_INTEGER:
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_LONG,
+ pstmt->descriptor[i]->data,
+ pstmt->descriptor[i]->precision,
+ &orind);
+ if (orind == SQL_NULL_DATA)
+ pstmt->descriptor[i]->isNull = 1;
+ else
+ pstmt->descriptor[i]->isNull = 0;
+ if (rc == SQL_NO_DATA)
+ pstmt->fetchDone = TRUE;
+ if (SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA)
+ {
+ rc = DBI_SQL_SUCCESS;
+ break;
+ }
+ else
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = dbi_cursorFetchone (%d) %s %s %x\n\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native);
+ return return_code;
+ }
+ break;
+
+ case SQL_TINYINT:
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_TINYINT,
+ pstmt->descriptor[i]->data,
+ pstmt->descriptor[i]->precision,
+ &orind);
+ if (orind == SQL_NULL_DATA)
+ pstmt->descriptor[i]->isNull = 1;
+ else
+ pstmt->descriptor[i]->isNull = 0;
+ if (rc == SQL_NO_DATA)
+ pstmt->fetchDone = TRUE;
+ if (SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA)
+ {
+ rc = DBI_SQL_SUCCESS;
+ break;
+ }
+ else
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = dbi_cursorFetchone (%d) %s %s %x\n\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native);
+ return return_code;
+ }
+ break;
+
+ case SQL_BIT:
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_BIT,
+ pstmt->descriptor[i]->data,
+ pstmt->descriptor[i]->precision,
+ &orind);
+ if (orind == SQL_NULL_DATA)
+ pstmt->descriptor[i]->isNull = 1;
+ else
+ pstmt->descriptor[i]->isNull = 0;
+ if (rc == SQL_NO_DATA)
+ pstmt->fetchDone = TRUE;
+ if (SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA)
+ {
+ rc = DBI_SQL_SUCCESS;
+ break;
+ }
+ else
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = dbi_cursorFetchone (%d) %s %s %x\n\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native);
+ return return_code;
+ }
+ break;
+
+ case SQL_SMALLINT:
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_SHORT,
+ pstmt->descriptor[i]->data,
+ pstmt->descriptor[i]->precision,
+ &orind);
+ if (orind == SQL_NULL_DATA)
+ pstmt->descriptor[i]->isNull = 1;
+ else
+ pstmt->descriptor[i]->isNull = 0;
+ if (rc == SQL_NO_DATA)
+ pstmt->fetchDone = TRUE;
+ if (SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA)
+ {
+ rc = DBI_SQL_SUCCESS;
+ break;
+ }
+ else
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = dbi_cursorFetchone (%d) %s %s %x\n\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native);
+ return return_code;
+ }
+ break;
+
+ case SQL_TYPE_DATE:
+ case SQL_TYPE_TIME:
+ case SQL_TYPE_TIMESTAMP:
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_TIMESTAMP,
+ pstmt->descriptor[i]->data,
+ pstmt->descriptor[i]->precision,
+ &orind);
+ if (orind == SQL_NULL_DATA)
+ pstmt->descriptor[i]->isNull = 1;
+ else
+ pstmt->descriptor[i]->isNull = 0;
+ if (rc == SQL_NO_DATA)
+ pstmt->fetchDone = TRUE;
+ if (SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA)
+ {
+ rc = DBI_SQL_SUCCESS;
+ break;
+ }
+ else
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = dbi_cursorFetchone (%d) %s %s %x\n\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native);
+ return return_code;
+ }
+ break;
+
+ default:
+ rc = SQLGetData(pstmt->hdr.handle, i+1, SQL_C_CHAR,
+ pstmt->descriptor[i]->data,
+ pstmt->descriptor[i]->precision+1,
+ &orind);
+ if (orind == SQL_NULL_DATA)
+ pstmt->descriptor[i]->isNull = 1;
+ else
+ pstmt->descriptor[i]->isNull = 0;
+ if (rc == SQL_NO_DATA)
+ pstmt->fetchDone = TRUE;
+ if (SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA)
+ {
+ rc = DBI_SQL_SUCCESS;
+ break;
+ }
+ else
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL,
+ pstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT)
+ ( "%d = dbi_cursorFetchone (%d) %s %s %x\n\n",
+ rc, __LINE__, pstmt->hdr.err.sqlState,
+ pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native);
+ return return_code;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ return_code = IIDBI_ERROR( rc, NULL, NULL, pstmt, &pstmt->hdr.err );
+ DBPRINTF(DBI_TRC_STAT) ( "%p: %d = dbi_cursorFetchone (%d) %s %s %x\n\n", pstmt,
+ rc, __LINE__, pstmt->hdr.err.sqlState, pstmt->hdr.err.messageText,
+ pstmt->hdr.err.native);
+ return return_code;
+ }
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_cursorFetchone }}}1\n", pstmt);
+ return(DBI_SQL_SUCCESS);
+}
+
+/*{
+** Name: dbi_getDescriptor - Get column descriptor info
+**
+** Description:
+** Get descriptor information from the tuple descriptor array.
+**
+** Inputs:
+** None.
+**
+** Outputs:
+** Returns:
+** Pointer to IIDBI_DESCRIPTOR.
+**
+** Exceptions:
+** An error is raised if the previous call to executeXXX() did
+** not produce any result set or no call was issued yet.
+**
+** Side Effects:
+**
+** History:
+** 13-Jul-2004 (loera01)
+** Created.
+}*/
+
+IIDBI_DESCRIPTOR *dbi_getDescriptor ( IIDBI_STMT *pstmt, int colNbr,
+ unsigned char isParam )
+{
+ DBPRINTF(DBI_TRC_STAT)("Getting the descriptor from %p\n",pstmt->descriptor);
+ if (!pstmt)
+ return 0;
+
+ if (isParam)
+ {
+ if (!pstmt->parameter )
+ return 0;
+ return pstmt->parameter[colNbr];
+ }
+
+ if (!pstmt->descriptor )
+ return 0;
+ return pstmt->descriptor[colNbr];
+}
+
+/*{
+** Name: dbi_cursorFetchall - Fetch all rows from a statement
+**
+** Description:
+** Fetch all (remaining) rows returned from a statement
+**
+** Inputs:
+** None.
+**
+** Outputs:
+** Returns the tuples
+** Returns:
+** Tuple structure
+**
+** Exceptions:
+** An error is raised if the previous call to executeXXX() did
+** not produce any result set or no call was issued yet.
+**
+** Side Effects:
+**
+** History:
+** 08-Jul-2004 (peeje01)
+** Created.
+}*/
+RETCODE
+dbi_cursorFetchall( IIDBI_STMT *pstmt )
+{
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_cursorFetchall {{{1\n", pstmt);
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_cursorFetchall }}}1\n", pstmt);
+ return(DBI_SQL_SUCCESS);
+}
+
+/*{
+** Name: dbi_freeDescriptor - Free a tuple descriptor
+**
+** Description:
+** Frees all memory associated with a tuple descriptor.
+**
+** Inputs:
+** pstmt - pointer to DBI statement structure.
+**
+** Outputs:
+** Returns:
+** All memory for tuple descriptor structure array is freed.
+**
+** Exceptions:
+** An error is raised if memory problems.
+**
+** Side Effects:
+**
+** History:
+** 15-Jul-2004 (loera01 at ca.com)
+** Created.
+** 17-Jul-2004 (komve01 at ca.com)
+** Fixed dbi_freeDescriptor. Clean parameter if isParam is one.
+** else clean descriptor block.
+}*/
+
+RETCODE dbi_freeDescriptor(IIDBI_STMT *pstmt, unsigned char isParam)
+{
+ int i;
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_freeDescriptor isParam[%u]{{{1\n", pstmt, isParam);
+
+ if (!pstmt)
+ return DBI_INTERNAL_ERROR;
+
+ if (isParam)
+ {
+ if (!pstmt->parmCount)
+ return DBI_SQL_SUCCESS;
+
+ if (!pstmt->parameter)
+ {
+ pstmt->parmCount = 0;
+ pstmt->rowCount = -1;
+ return DBI_INTERNAL_ERROR;
+ }
+ for (i = 0; i < pstmt->parmCount; i++)
+ {
+ /*
+ ** Since the data for long data types was retrieved from
+ ** PyBufferFromObject(), we rely on Python to free the
+ ** memory for the data. Same for ASCII and Unicode.
+ */
+ if (pstmt->parameter[i]->data)
+ {
+ switch (pstmt->parameter[i]->type)
+ {
+ case SQL_LONGVARCHAR:
+ case SQL_LONGVARBINARY:
+ case SQL_WLONGVARCHAR:
+ case SQL_CHAR:
+ case SQL_VARCHAR:
+ case SQL_WVARCHAR:
+ case SQL_WCHAR:
+ break;
+
+ default:
+ free (pstmt->parameter[i]->data);
+ break;
+ }
+ }
+ free (pstmt->parameter[i]);
+ }
+ free(pstmt->parameter);
+ pstmt->parameter = 0;
+ pstmt->parmCount = 0;
+ pstmt->rowCount = -1;
+ }
+ else
+ {
+ dbi_freeData(pstmt);
+ for (i = 0; i < pstmt->descCount; i++)
+ {
+ DBPRINTF(DBI_TRC_STAT)("Freeing descriptor[%i]\n", i);
+ free(pstmt->descriptor[i]->columnName);
+ free (pstmt->descriptor[i]);
+ }
+ free(pstmt->descriptor);
+ pstmt->descriptor = 0;
+ pstmt->descCount = 0;
+ pstmt->rowCount = -1;
+ }
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_freeDescriptor }}}1\n", pstmt);
+ return DBI_SQL_SUCCESS;
+}
+
+/*{
+** Name: dbi_allocDescriptor - Allocate tuple descriptor
+**
+** Description:
+** Allocate tuple descriptor.
+**
+** Inputs:
+** pstmt - pointer to DBI statement structure.
+**
+** Outputs:
+** Returns:
+** pstmt has allocated data for the tuple descriptor.
+**
+** Exceptions:
+** An error is raised if memory problems.
+**
+** Side Effects:
+**
+** History:
+** 15-Jul-2004 (loera01 at ca.com)
+** Created.
+}*/
+
+RETCODE
+dbi_allocDescriptor(IIDBI_STMT *pstmt, int numCols, unsigned char isParam )
+{
+ int i;
+ int return_code = DBI_SQL_SUCCESS;
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_allocDescriptor numCols[%i] isParam[%u] {{{1\n", pstmt, numCols, isParam);
+
+ if (!pstmt)
+ return DBI_INTERNAL_ERROR;
+
+ if (!numCols)
+ return DBI_SQL_SUCCESS;
+
+ if (isParam)
+ {
+ pstmt->parmCount = numCols;
+
+ pstmt->parameter = calloc(1,sizeof(IIDBI_DESCRIPTOR *) * numCols);
+ if (!pstmt->parameter)
+ {
+ pstmt->parameter = 0;
+ return DBI_INTERNAL_ERROR;
+ }
+ for (i = 0; i < pstmt->parmCount; i++)
+ {
+ pstmt->parameter[i] = calloc(1,sizeof(IIDBI_DESCRIPTOR));
+ if (!pstmt->parameter[i])
+ {
+ int k;
+ for (k=0; k <= i; k++)
+ {
+ if (pstmt->parameter[k])
+ free (pstmt->parameter[k]);
+ }
+ free(pstmt->parameter);
+ return_code = DBI_INTERNAL_ERROR;
+ break;
+ }
+ }
+ }
+ else
+ {
+ pstmt->descCount = numCols;
+ pstmt->rowCount = -1;
+
+ pstmt->descriptor = calloc(1,sizeof(IIDBI_DESCRIPTOR *) * numCols);
+ if (!pstmt->descriptor)
+ {
+ pstmt->descCount = 0;
+ return DBI_INTERNAL_ERROR;
+ }
+ for (i = 0; i < pstmt->descCount; i++)
+ {
+ pstmt->descriptor[i] = calloc(1,sizeof(IIDBI_DESCRIPTOR));
+ if (!pstmt->descriptor[i])
+ {
+ int k;
+ for (k=0; k <= i; k++)
+ {
+ if (pstmt->descriptor[k])
+ free (pstmt->descriptor[k]);
+ }
+ free(pstmt->descriptor);
+ return_code = DBI_INTERNAL_ERROR;
+ break;
+ }
+ }
+ }
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_allocDescriptor }}}1\n", pstmt);
+ return return_code;
+}
+
+/*{
+** Name: dbi_allocData - Allocate data in tuple descriptor
+**
+** Description:
+** Allocate data in tuple descriptor.
+**
+** Inputs:
+** pstmt - pointer to DBI statement structure.
+**
+** Outputs:
+** Returns:
+** pstmt has allocated data for non-blob columns.
+**
+** Exceptions:
+** An error is raised if memory problems.
+**
+** Side Effects:
+**
+** History:
+** 15-Jul-2004 (loera01 at ca.com)
+** Created.
+** 16-Jul-2004 (raymond.fan at ca.com)
+** Use precision value for sizeof data.
+}*/
+RETCODE
+dbi_allocData ( IIDBI_STMT *pstmt)
+{
+ int i;
+ int return_code = DBI_SQL_SUCCESS;
+ int dataLen;
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_allocData {{{1\n", pstmt);
+
+ if (!pstmt)
+ return DBI_INTERNAL_ERROR;
+
+ if (!pstmt->descCount)
+ return DBI_SQL_SUCCESS;
+
+ for (i = 0; i < pstmt->descCount; i++)
+ {
+ dataLen = pstmt->descriptor[i]->precision;
+ switch (pstmt->descriptor[i]->type)
+ {
+ case SQL_LONGVARCHAR:
+ case SQL_LONGVARBINARY:
+ case SQL_WLONGVARCHAR:
+ pstmt->descriptor[i]->data = NULL;
+ break;
+
+ default:
+ if ((pstmt->descriptor[i]->type == SQL_CHAR) ||
+ (pstmt->descriptor[i]->type == SQL_VARCHAR))
+ {
+ dataLen += 1;
+ }
+ if ((pstmt->descriptor[i]->type == SQL_WCHAR) ||
+ (pstmt->descriptor[i]->type == SQL_WVARCHAR))
+ {
+ dataLen += sizeof(SQLWCHAR);
+ }
+ pstmt->descriptor[i]->data =
+ calloc(1, dataLen);
+ if (!pstmt->descriptor[i]->data)
+ {
+ int k=i;
+ return_code = DBI_INTERNAL_ERROR;
+ for (i=0; i <= k; i++)
+ {
+ if (pstmt->descriptor[i]->data)
+ free (pstmt->descriptor[i]->data);
+ }
+ }
+ break;
+ }
+ }
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_allocData }}}1\n", pstmt);
+ return return_code;
+}
+
+/*{
+** Name: dbi_freeData - Free data in tuple descriptor
+**
+** Description:
+** Free data in tuple descriptor.
+**
+** Inputs:
+** pstmt - pointer to DBI statement structure.
+**
+** Outputs:
+** Returns:
+** Pstmt has freed data, but not the descriptor count or
+** descriptor.
+**
+** Exceptions:
+** An error is raised if memory problems.
+**
+** Side Effects:
+**
+** History:
+** 07-Jan-2005 (loera01 at ca.com)
+** Created.
+}*/
+RETCODE
+dbi_freeData ( IIDBI_STMT *pstmt)
+{
+ int i;
+
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_freeData {{{1\n", pstmt);
+
+ if (!pstmt)
+ return DBI_SQL_SUCCESS;
+
+ if (!pstmt->descriptor)
+ return DBI_SQL_SUCCESS;
+
+ if (!pstmt->descCount)
+ return DBI_SQL_SUCCESS;
+
+ for (i = 0; i < pstmt->descCount; i++)
+ {
+ if (pstmt->descriptor[i]->data)
+ {
+ if (pstmt->descriptor[i]->data)
+ {
+ free(pstmt->descriptor[i]->data);
+ pstmt->descriptor[i]->data = 0;
+ }
+ }
+ }
+ DBPRINTF(DBI_TRC_ENTRY)("%p: dbi_freeData }}}1\n", pstmt);
+ return DBI_SQL_SUCCESS;
+}
+
+
+/*{
+** Name: BindParameters - Associates parameter descriptors with a statement.
+**
+** Description:
+** Associates parameters with a statement by calling SQLBindParameter.
+** Parameters are either input or output depending on the statement.
+**
+** Inputs:
+** pstmt - pointer to DBI statement structure.
+**
+** Outputs:
+** None.
+**
+** Returns:
+** DBI_SQL_SUCCESS
+** DBI_SQL_ERROR
+** DBI_INTERNAL_ERROR
+**
+** Exceptions:
+** None.
+**
+** Side Effects:
+**
+** History:
+** 16-Jul-2004 (raymond.fan at ca.com)
+** History.
+** Use precision value for sizeof data.
+** 17-Jul-2004 (komve01 at ca.com)
+** Added support for float,real and double type parameters
+** 19-Jul-2004 (komve01 at ca.com)
+** Added support for long type parameters
+**