pax_global_header00006660000000000000000000000064144644171050014520gustar00rootroot0000000000000052 comment=c335dbf3fa25b524e935e98cf26b96a2e13f5c81 unixODBC-2.3.12/000077500000000000000000000000001446441710500132205ustar00rootroot00000000000000unixODBC-2.3.12/.gitignore000066400000000000000000000015611446441710500152130ustar00rootroot00000000000000*.lo *.o INSTALL /libltdl # From https://github.com/github/gitignore/blob/main/Autotools.gitignore # CC0-1.0 # http://www.gnu.org/software/automake Makefile.in /ar-lib /mdate-sh /py-compile /test-driver /ylwrap .deps/ .dirstamp # http://www.gnu.org/software/autoconf autom4te.cache /autoscan.log /autoscan-*.log /aclocal.m4 /compile /config.cache /config.guess /config.h.in /config.log /config.status /config.sub /config.h.in /configure /configure.scan /depcomp /install-sh /missing /stamp-h1 # https://www.gnu.org/software/libtool/ /ltmain.sh # http://www.gnu.org/software/texinfo /texinfo.tex # http://www.gnu.org/software/m4/ m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 # Generated Makefile # (meta build system like autotools, # can automatically generate from config.status script # (which is called by configure script)) Makefile unixODBC-2.3.12/AUTHORS000066400000000000000000000041141446441710500142700ustar00rootroot00000000000000Authors of unixODBC... Peter Harvey Nick Gorham The PostgreSQL Driver was modified from the standard PostgreSQL ODBC driver (http://www.postgresql.org) The NNTP Driver as written by Ke Jin The MySQL driver is a mirror from the MySQL folks. Other contributors include Alex Hornby Axel Reinhold Alexander Mitin Artiom Morozov Arun K Desai Bard Hustveit Bill Bouma Bill Medland Bojnourdi Kaikavous Brian Harris Bruce A Mallett Charles Morrison Charles Overbeck Chris Friesen Christian Jullien Christian Werner Constantine Filin Craig A Berry Dave Berry David Brown Dmitriy Yusupov Donnie Pinkston Emile Heitor Erik Lundqvist Frediano Ziglio Gary Bunting Geoffrey Gowan Greg Bentz Heikki Linnakangas Holger Bischoff Holger Schurig Honza Horak Hristo Hristov Hugh McMaster Ian Ashley James Dugal Jan Cihlar Jan Stanek Jason Crummack Jay Cai Jay Q. Cai Jay Van Vark Jeff Garzik Jean Louis Charton Jens Schlegel Jess Balint Jim Ziegler Joel W. Reed John C. Rood John L Miller John Moreshead Jon Kåre Hellan Jon Pounder Jon Willeke Jürgen Pfeifer Keith Woodard Lars Doelle Manush Dodunekov Markus Beth Mark Chopping Mark Hessling Mark Vanderwiel Martin Edlman Martin Evans Martin Hobbs Martin Kittel Martin Lacko Max Khon Michael Koch Michael Vetter Miloslav Marik Mike Schultz Mikko Vierula Murad Nayal Murray Todd Williams Nehal J Wani Nikolai Afanasiev Ocke Janssen Oded Comay Ola Sundell Oren Nechushtan Patrice Favre Paul Richardson Per Bengtsson Per I. Mathisen Petr Vandrovec Pierangelo Masarati Rafi Einstein Ralf Fassel Rick Flower Richard Kettlewell Ron Norman Samuel Cote Scot Loach Scott Courtney Shandy J. Brown Simon Pepping Stefan Radman Steffen Dettmer Steve Gilbert Steve Langasek Steven M. Schultz Steven Reynolds Stuart Coupe Thierry Laronde Thomas Langen Tim Roepken Tomas Zellerin Trond Eivind Glomsrød Venu Anuganti Zoltan Boszormenyi If I have omitted anyone from this let me know and I will amend it ASAP. I have removed the email address of the people on this list. If someone wants to get in touch, mail me and I will pass it on. Nick Gorham unixODBC-2.3.12/COPYING000066400000000000000000000575571446441710500142760ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, 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 and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, 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 library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library. 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 Library or any portion of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, 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 Library, 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 Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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. If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be 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. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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. 9. 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 Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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 with this License. 11. 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 Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library. 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. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser 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 Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS unixODBC-2.3.12/ChangeLog000066400000000000000000002265241446441710500150050ustar00rootroot000000000000008-Aug-2023 2.3.12 * Fix iconv handle leak with pooling * Add windows encoding patch * Avoid failed build if clock_gettime() is not available * Allow passing in a entire connection string into iusql * Allow isql to handle SQL_SUCCESS_WITH_INFO from SQLPrepare * Add extra logging for ODBCINST connect settings * Allow allocated copy (instead of fixed length) for the connection string with pooling to allow any length * Export __clear_ini_cache() from odbcinst to allow explicitly clearing the ini cache * Fix seg fault when used with SQLAPI * Add --enable-utf8ini flag to add utf8 to WCHAR conversions in SQLGetPrivateProfileStringW * Allow longer error messages via GetDiag functions * Add --enable-singleenv to enable single shared env handle when using pooling 4-May-2022 2.3.11 * Missing files has caused a problem. I am pushing a 2.3.11 to try and make versiosn match up 11-Jan-2021 2.3.10 * Add connection pooling via wide connection functions * Remove "#define VERSION" from unixodbc_conf.h * Call driver functions through prototypes * Add connection pool limit option * Add fseeko support in cursor lib * Try and prevent logging buffer overflow * Add 'echo' option to isql/iusql * Alter isql/iusql buffering * Alter unicode to ascii conversion in SQLGetDiagField * Fix pooling problem when user name and or password is not provided * Fix a couple of reported buffer overflow conditions * Fix iconv leak with timeout in pooled connection 06-Sep-2020 2.3.9 * Remove "#define UNIXODBC_SOURCE" from unixodbc_conf.h 30-Aug-2020 2.3.8 * Add configure support for editline * SQLDriversW was ignoring user config * SQLDataSources Fix termination character * Fix for pooling seg fault * Make calling SQLSetStmtAttrW call the W function in the driver if its there * Try and fix race condition clearing system odbc.ini file * Remove trailing space from isql/iusql SQL * When setting connection attributes set before connect also check if the W entry points can be used * Try calling the W error functions first if available in the driver * Add iconvperdriver configure option to allow calling unicode_setup in SQLAllocHandle * iconv handles was being lost when reusing pooled connection * Catch null copy in iniPropertyInsert * Fix a few leaks 10-Aug-2018 2.3.7 * Fix for pkg-config file update on no linux platforms * Add W entry for GUI work * Various fixes for SQLBrowseConnect/W, SQLGetConnectAttr/W,and SQLSetConnectAttr/W * Fix buffer overflows in SQLConnect/W and refine behaviour of SQLGet/WritePrivateProfileString * SQLBrowseConnect/W allow disconnecting a started browse session after error * Add --with-stats-ftok-name configure option to allow the selection of a file name used to generate the IPC id when collecting stats. Default is the system odbc.ini file * Improve diag record handling with the behavior of Windows DM and export SQLCancelHandle * bug fix when SQLGetPrivateProfileString() is called to get a list of sections or a list of keys * Connection pooling: Fix liveness check for Unicode drivers 19-March-2018 2.3.6 * Fix order of arguments in SQLWriteFileDSN.c, fix unwanted free() in iusql.c (CVE-2018-7485) * Add pkg-config files 2-Jan-2018 2.3.5 * Add configure option --enable-setlibversion set mark the libs with VERS_3.52 Linux only, so any driver built with the libs will work with closed source DM's * Add persistent storage of isql command line history if readline() is used (thanks Axel) * Rename some local mutex functions to avoid name clashes * Assorted fixes (Thanks Markus * 2) * Fix regression in ini caching * Make SQLDrivers look in user as well as system odbcinst.ini for driver attributes * If in use, clear the ini cache when a write is done via SQLWritePrivateProfileString() so the new value is read * Fix problem with pooling if the environment was released by the application * Add check for SQL_COLUMN_COUNT in SQLColAttribute * isql would not display long error messages. Fixed now. * Fix problem calling the driver to report errors if the error is from the DM and the driver has not been called * SQLSetConnectAttrW crashes when attempting to set SQL_ATTR_LOGIN_TIMEOUT * Buffer overflow in unicode_to_ansi_copy() (CVE-2018-7409) * SQLDriverConnect with not-found FILEDSN causes crash * SQLGetDescRec with null name pointer causes crash * Connection string escaping does not work * SQLDriverConnect/W with very long driver name causes crash * Connection string with trailing empty value causes crash * Freeing explicitly allocated descriptor results in writing to freed memory * Buffer overflows and missing null checks in SQLConfigDataSource, SQLInstallDriverEx, and SQLWriteFileDSN * Statement enters incorrect state upon SQLExecDirectW returning SQL_NO_DATA * SQLBulkOperations fails to exit async state after success * SQLFreeStmt causes prepared statements in S1 or S2 to erroneously transition to S3 * Buffer length fixes for SQLGetDiagField * SQLSetConnectAttrW and Unicode string pre-connect attributes do not work * SQLGetData and SQLSetPos async states are incorrect * Various string conversion and length issues in SQLColAttribute(s) * Missing buffer length check in SQLColAttribute(s)W * SQLGetStmtAttr state handling incorrect in S5, S6, and S7 (via SQLExtendedFetch) * SQLSetPos and SQLExtendedFetch state management fixes * SQLExecDirect/W erroneous transition to S1 upon error in S5 * Async SQLGetData and SQLExecDirect/W fails to restore state upon cancellation * SQLFetchScroll cannot move cursor back into the rowset * SQLSetDescField doesn't adjust the length of the buffer when converting to unicode * SQLGetDescField/W and SQLSetDescField/W do not check for negative buffer lengths * SQLSetStmtAttrW SQL_ATTR_APP_PARAM_DESC and SQL_ATTR_APP_ROW_DESC does not accept null * SQLGetData async state reentrancy issues * SQLDriversW off-by-one in enumerating driver list * SQLPrimaryKeys does not pass length in characters to driver * SQLGetConnectAttr with string attributes truncates to half buffer length * SQLTransact with autocommit enabled erroneously changes statement state * SQLDataSources/W fails to reset list position upon end * SQLGetEnvAttr successfully returns unset SQL_ATTR_ODBC_VERSION * Lack of SQL_HANDLE_SENV support * SQLAllocEnv fails to set environment version correctly * SQLMoreResults with streamed output parameters returns unexpected HY010 * Custom pre-connect pointer attributes are truncated to 32 bits * 08003 message should be "Connection not open" * SQL_ATTR_ACCESS_MODE set using SQLSetConnectOption/W before connecting does not persist after disconnecting * SQL_ATTR_AUTOCOMMIT incorrect default value before connecting * SQL_AUTOCOMMIT set using SQLSetConnectOption/W before connecting does not persist after disconnecting * SQLAllocHandle/SQLFreeHandle with invalid handle type should return SQL_INVALID_HANDLE * SQLAllocHandleStd not setting ODBC version correctly * SQLBindParameter does not ignore BufferLength for DAE parameters * SQLBindParameter does not ignore BufferLength for fixed-length parameters * SQLBindParameter returns "Invalid application buffer type" instead of " Program type out of range" * SQLCancel with 01S05 returned from driver should result in SQL_SUCCESS, not SQL_SUCCESS_WITH_INFO (see https://msdn.microsoft.com/en-us/library/aa392708(v=vs.85).aspx ) * SQLColAttribute/SQLColAttributes should return number of bytes needed for Unicode string when truncating * SQLColumnPrivileges/W differing error message precedence from Windows DM and order in ODBC spec * SQLColumns/W extraneous checks on null string's length * SQLCopyDesc does not copy descriptors across connections correctly * SQLDescribeParam extraneous checks for state * SQLDriverConnect/W adds extraneous DM prefix to diagnostic messages * SQLDriversW before ODBC version set returns incorrect SQLSTATE * SQLFetch in state S7 does not return error from DM * SQLFetchScroll missing check for SQL_FETCH_BOOKMARK * SQLForeignKeys/W missing check for null table names * SQLGetConnectAttr/W erroneously retrieves attributes with no default (SQL_ATTR_PACKET_SIZE, SQL_ATTR_QUIET_MODE) * SQLGetConnectAttr/W fails to get some set attributes before connecting * SQLGetConnectAttr/W fails to retrieve set attributes with no connection * SQLGetConnectAttrW returns incorrect value for SQL_ATTR_TRACE * SQLGetConnectOption/W cannot retrieve SQL_ODBC_CURSORS before connection * SQLGetConnectOption/W fails to retrieve SQL_LOGIN_TIMEOUT before connecting * SQLGetConnectOption/W fails to retrieve SQL_ATTR_ACCESS_MODE set with SQLSetConnectOption/W * SQLGetData and SQLSetPos async states are incorrect * SQLGetData missing check for cursor end indication; SQLSetCursorName/W fails to clear previous diagnostic records * SQLGetDiagField/W does not check record number for SQL_DIAG_ROW_COUNT and SQL_DIAG_DYNAMIC_FUNCTION_CODE * SQLGetDiagField/W missing check for negative buffer length for string fields * SQLGetDiagField/W inconsistent handling of statement-only diagnostic fields * SQLGetInstalledDrivers off-by-one length * SQLGetStmtOption various state handling issues * SQLSetConnectAttr/W SQL_ATTR_CURRENT_CATALOG extraneous check with error 24000 * SQLSetConnectAttr/W does not prevent attempts to set ODBC 3.x statement attributes * SQLSetConnectAttr/W with null string attributes causes crash * SQLSetConnectOption passes SQL_ATTR_TRACEFILE to the driver * SQLSetConnectOption/W or SQLSetConnectAttr/W missing validity checks for SQL_ATTR_TXN_ISOLATION * SQLSetConnectOption/W setting SQL_ATTR_TRACEFILE to null results in different error * SQLSetCursorName/W missing checks for negative name length * SQLSetDescField/W missing check for negative SQL_DESC_COUNT * SQLSetParam missing various error checks for invalid data types and buffer * SQLSetPos does not check for state S5 * SQLSetPos missing checks in state S7 * SQLSetScrollOptions various state handling issues * SQLSetStmtOption/W missing check for positive rowset sizes * SQLSpecialColumns/W error precedence differs from Windows DM * SQLSpecialColumns/W incorrect check for SQL_NTS string lengths * SQLStatisticsW uniqueness parameter missing validation * SQLTablePrivileges/W extraneous checks on null string's length * Various issues with SQLGetFunctions * Various string conversion and length issues in SQLColAttribute; missing buffer length check in SQLColAttributeW * As above, but for SQLColAttributes and SQLColAttributesW; incorrect check for SQL_COLUMN_COUNT * Setting SQL_ATTR_TRACEFILE to null value results in different error * check_target_type allows driver-specific C data types for ODBC < 3.8 * fix empty SQL_DIAG_SERVER_NAME field in DM-supplied diag recs * fix differing behaviour for an empty string DSN in SQLConnect/W * Alter isql to return errors from SQLMoreResults * Handle case of building on mingw-w64 3rd-Aug-2015 2.3.4 * Fix typo in the loading of the cursor lib, reports internal error, unexpected SHLIBEXT 2nd-Aug-2015 2.3.3 * Reporting of logging state was broken in SQLGetConnectAttr * Fix incorrect text against HY007 * Add -L option to isql to increase max column data display * Update automake toolset in svn * Add SQLFreeStmt( SQL_CLOSE ) function to SQLCancel * Allow SQL_NTS as a buffer length to SQLBindParameter * More manual pages for the tools * Fix buffer overrun returning long diagnostic from driver * Cross call between wide and ascii error reporting in the driver when needed * Fix some possible unchecked memory references after malloc * Prevent free( NULL ) in SQLGetDiagRecW * Add missing A->W conversion in SQLGetStmtOption * Allow iconv to convert strings into the driver with differing A and W lengthts (UTF) * SQLDataSourcesW takes buffer_lenghts as characters not bytes * Fix memory leak in SQLGetDiagRec * Allow setting custom non standard attributes via DMStmtAttr, format is: DMStmtAttr=[xxxx]=\yyy DMStmtAttr=[xxxx]={ssss} where xxxx = integer attribute to set, yyy is decimal numeric value and ssss is a string value * Add check in SQLGetData for null target value or negative buffer length * Fix memory leak when using the cursor lib * Catch incorrectly expanded SHLIBEXT * There was a bug in the ini caching, now fixed * More ODBC 3.80 additions (streaming parameters) * Check for NULL handle in __validate_xxx() * Avoid potential memory leak in SQLAllocStatement * Avoid buffer overflow via environment variamles * Fix some typos 8th-October-2013 2.3.2 * The logging of WStrings was using the incorrect length in some cases * Pass SQLDescribeCol call to driver when in state 2 (not a cursor spec). * Pass SQLMoreResults call to driver when in state 2 (not a cursor spec). Both the last two changes are not as per the original book state table but allign with the current MS driver manager * The -e option to isql got lost somewhere. Back in now * Update install-sh * SQLCancel assumed that the DM was being built with thread support * Try and speed up SQLTransact and SQLEndTran operation * Add missing \ in Postgres7.1 Makefile * Correct some potential buffer overflows * Handle SQL_NEED_DATA from a SQLMoreResults * Get the local charset via nl_langinfo(CODESET) when asking the DM to do ASCII-UNICODE conversions * Handle (and remove) leading spaces from ini entries * Fixed unicode conversion problems in SQLGetDiagField(W) * missing terminating null in iusql * add to the list of errno states that does not cause a create of the ini file * SQLSetConnactAttr() -> SQLSetConnectAttrW() was passing incorrect string length * Fix double free in SQLGetDiagFieldW * Fix Unicode/Ansi conversion problem in SQLGetDiagFieldW.c * Add support for Driver64 in SQLDriverConnectW * Add missing unicode setting when returning a connection to the pool * Tidy up leaking iconv handles if connect_part_one fails * Fix (and avoid) some out of memory problems * Wrap lt_dlinit and dlerror in the lib mutex * Add slencheck executable to try and find the sizeof(SQLLEN) from a installed driver * SQL_NO_DATA after SQL_STILL_EXECUTING in SQLExtendedFetch was not setting the state correctly * A little more 3.80 stuff being added * Added fixes found by coverity * Added man pages * Patches to update VMS build * Change mutex protection around release_env * Altered strlen to be count of bytes in SQLGetDiagFieldW * Add check for W function support in do_attr * Allow SQLDrivers to return attribute length with no supplied buffer 26th-November-2011 2.3.1 * Change type definition of a integer in SQLConnect.c, just to avoid confusion * Allow setting the DM overrive values in the connection string to SQLDriverConnect for example "DRIVER={Easysoft ODBC-SQL Server};Server=myserver;UID=user;PWD=pass;DMStmtAttr=SQL_QUERY_TIMEOUT=10;" * Error and info message order was being inverted by the driver manager * Fix memory leak in SQLDriverConnect.c (Thanks JM) * The keyword matching for DRIVER=, DSN= etc was case sensitive. Make it insensitive now * Avoid sprintf NULL pointer problem in SQLGetDiagRec * Fix typo affecting the pooling of connections, (thanks Chris) * Fix SunCC _mcount problem * Attempt to stamp version info on the libs generated. There are aps in use linked against other driver managers that expect VERS_3.52 * Fix potential buffer overrun when using SAFEFILE * Fix mutex problem in the exit from __SQLGetInfo (thanks Richard) * Allow getting SQL_DM_VER via SQLGetInfo before connecting to a driver * Generate unixodbc_conf.h using macros to allow cross compiling * Fix some libltdl problems * Fix some naming problems with the cursor lib * Fix odbcinst problems on systems without pwd.h * Change lib version to 2 to reflect SQLLEN changes in v2.3 * Fix threading problem (thanks Petr Vandrovec) * Allow use of lib name in a DRIVER= connection string * Change default threading protection to 0, most drivers should be thread safe by now. If the driver is at all thread safe, allow SQLCancel to bipass the interlock. * Performance change to handle large numbers of connection and statement handles better. Thanks for the change from the folks at Acision. * Add -k option to isql to treat the DSN as a connection string and use SQLDriverConnect isql -k "DSN=server;UID=test;PWD=test" * Couple of the SQLSetConnactAttr values are now SQLULEN instead of SQLUINTEGER * SQLSetConnectAttr was passing a char length instead of a byte length into the Driver SQLSetConnectAttr when converting from Ansi->Unicode * Driver version was not being held when a second connection was made to the driver 20th-April-2010 2.3.0 * Try and rationalise the way the connection process find the driver version and supported functions * Sort out problem in isql with blank lines * Stop libthread from being used under AIX * Move the GUI parts off into a new project http://sourceforge.net/projects/unixodbc-gui-qt/ * Strip out the GUI parts. I have also removed the spec files as they will need redoing, * Move the Test parts off into a new project http://sourceforge.net/projects/unixodbc-test/ * Add interface into odbcinstQ to allow for a dialog if SQLDriverConnect is called without a DSN= (as the MS spec) * Allow the setting of a default Threading level in the ODBC section of odbcinst.ini * Change double format string in Postgre7.1 driver * Add missing CR to output of odbcinst * add fixes to MiniSQL driver * Add missing .y in nn driver, now I need to get it to work * Assoured bux fixes and format problems, thanks Tom * SQLBindCol on metadata calls was incorrectly going via the cursor lib if it was enabled * fix isql problem with nested definitions. * Add configure option to enable building of driver config libs * Shift build to using config.h, the compile lines were so big it was hard to see warnings * Fix bug in isql when using -b option. * Check attribute values when setting connection and statement attrs * Check for valid pointers in SQLGetInfo(W) and SQLGetFunctions * Add extra checks for states in SQLCopyDesc * Add --enable-stricterror option to allow compliance with the error reporting definition, driver errors don't have the unixODBC prefix * Check for statements in the NEED_DATA state when calling SQLEndTran * Extra error check for SQLPutData * Check handle type in SQLEndTran * Prevent seg fault if there are no driver error functions * the -n option to isql was not working correctly * Stripped out all the bespoke LDTL configure stull, not just what libtoolize provides * Fix problem where ansi_to_unicode_alloc didn't leave space for the NULL and could cause memory corruption * Add the ODBC 3.80 additions that MS have produced. I am sure I remember the standard being given to XOpen, what do I know :-) * Change the file open mode for the ini file from w to w+ just in case the original open failed but the file did exist * Fix configure problem preventing the CHAR encoding from being passed * Remove white spave from ini write, not all drivers use unixODBC ini functions and can handle the spaces * Update config.guess to current GNU version including support for AIX6 * Create SVN repository at sourceforge * Add cast to fix problem in SQLSetConnectOption * Fix SQLINTEGER<->SQLLEN conversion broblem in SQLNativeSQL * Fix bug that stopped setting SQL_ATTR_CONCURRENCY to SQL_CONCUR_VALUES * Change minor version number because of the SQLLEN change * Remove unintended trailing white space from log generation 19th-Nov-2008 2.2.14 * missing protype in 2.2.13 made the build fail on some platforms 18th-Nov-2008 2.2.13 * There was a mutex around iconv that needed adding. Without this, there was a potential thread problem * Fix problem with SQLGetDiagRec/Field returning double driver errors * odbctest was using the wrong handle for SQLGetConnectOption * remove startup thread race condition * fix descriptor memory leak with UNICODE only drivers (thanks Ian) * Alter the default 64bit build mode, and change the flag to BUILD_LEGACY_64_BIT_MODE * Fix a couple of 64bit problems * create unixodbc_conf.h on install to contain compile settings * Allow the GUI parts to build with qt4 * try and deal with drivers that call internal W functions and end up in the driver manager (informix for example). Enabled by --enable-handlemap=yes when configuring * Fix leak of iconv handles * Allow the setup API to call through to the wide driver functions * Fix potential seg fault in SQLGetPrivateProfileString * Fix a couple of broken casts, and some MS 64bit changes * Add check for postgres driver getting into a spin wait * Fix logging that reported the setting of env attrs failing * Add isql option to wrap strings with quotes * Add isql option -3 to make isql use ODBC 3 calls instead of 2 * Add timestamp to logging output * Pull any errors from driver whern SQLBrowseConnect returns SQL_NEED_DATA * isql now displays any warnings from SQLMoreResults * Add include path to odbc_config --cflags output * Fix some SQLLEN/SQLINTEGER conflicts in the cursor lib * isql now checks if the driver has SQLMoreResults before calling it * A couple of tweeks in the txt driver * Fix More than 1 log msg relevant in odbcinst now * Changed UI plugin technique for odbcinst see... ODBCConfig > main.cpp, and odbcinst > SQLManageDataSources.c and odbcinstQ4 > SQLManageDataSources.cpp * Add more 64 bit changes, remove SQLROWCOUNT and its frends from 64 bit land * Couple of descriptor typo's fixed (Thanks Jess) * Add odbcinstQ4 to support pure Qt4 SQLCreateDataSource and SQLManageDataSources * Add ODBCCreateDataSourceQ4 as Qt4 based exec to SQLCreateDataSource * Add ODBCManageDataSourcesQ4 as Qt4 based exec to SQLManageDataSources * Add "-c" option to odbcinst to call SQLCreateDataSource * Add "-m" option to odbcinst to call SQLManageDataSources * Add ODBCDataManagerQ4 * Add Wrappers (C++, QtCore 4, QtGui 4 - thin wrappers to ODBC) * Add more complete set of driver config options to GUI config * Fix incorrect export file in odbcinstQ * Added some extra features to isql (thanks to Ron Norman for the ideas) * Add diag support lib for driver development and possibly DM This is very 'black-boxed' on purpose. * Fix Replaced diag code in txt driver to use new diag lib. * Add New odbctrac library. * Add Threading can not be config via Qt(4) based GUI * Add New ODBCString library. * Add odbcinst.ini -> ODBC -> TraceLibrary and corresponding GUI Qt(4) config. * prevent the cursor lib from seg faulting if the query isn't a select * Add SQLULEN size display to the output of odbcinst -j * Add mutexes in odbcinst/_logging.c * Remove the MySQL Driver, its woefully out of date now * Remove incorrect path in vms_odbc.opt * rename trace.h to odbctrace.h to avoid potential name conflicts and move to include dir * update unixODBC.spec file * Add README.CYGWIN * Fix build problem with QT4 without QWizard support * Alter how the Ansi-Unicode mapping is done, so a unicode function can be passed to the driver (if it supports it) even if a non unicode connect was done * Fix buffer overrun in SQLDriverConnectW and SQLColAttributesW * I have cut back on a lot of the GUI parts that are being added. The goal is to create a distinct set of files that contains these and other parts that are not part of the core goal of providing ODBC. Likewise the drivers will go on the next release, as most DB's now have their own folk working on their drivers and they all interoperate with unixODBC so its just adding confusion including them here (IMHO that is) * Prevent a potential buffer overrun in the DM * The processing of --enable-rtldgroup had been dropped, back now * Allow the cursor lib to handle multiple result sets 13th-Oct-2006 Release 2.2.12 * Add missing SQLSetStmtOptionA and SQLSetStmtOptionW * The config string being passed into ConfigDsn was wrong, removed semicolon, and added terminating double null * Add help help to isql * Couple of changes to make the build on OSX work better * Alter odbctest FullConnect to use SQLDriverConnect * Replace a missed flag for true 64 bit operation * Add ODBC3<->ODBC2 type mapping in SQLSetParam * Add missing SQLSetStmtOptionW.c * Tidy up the search for GUI lib code in SQLManageDatasource * Backport a couple of changes from the Debian build into the cursor lib * Add extra config settings to the MaxDB/SapDB setup lib * Fix possible exit from SQLConnect without having closed in the driver * Fix configure problem on Tru64 * Fix a build issue on Sinix * Allow calling metadata functions via the cursor lib * Alter args to SQLParamOptions * Fix bug preventing attribute length from being returned from SQLDrivers * Fix broken iusql * SQLTransact via the cursor lib has the args swapped * Remove leak in the postgres driver (error messages were not being released), and yet a different leak in convert.c * Add code to allow the Cursor lib to call SQLGetDiagRec * Updated libtool, automake and autoconf, so expect problems for the next few months... * Add new QT detection macros (Thanks Peter) * Removed some unneeded strlen's from the postgres drivers * Small change to the logging in SQLBrowseConnect * Add additional SQLGetInfo value SQL_ATTR_DRIVER_THREADING (1028) that returns a SQL_USMALLINT containing the level of thread protection afforded the driver by the driver manager * Fix small bug that prevents SQLDrivers from returning the first entry if SQL_FETCH_FIRST is not used * Make DataManagerII check the DB's quote char when creating SQL * The cursor lib wasn't correctly returning the last rowset * Fix problem with the cursor lib, rowsets and SQLExtendedFetch * Fix couple of spelling mistakes in isql * Allow decoupling of SQLHANDLES between application and driver, there is a 64bit DB2 where the driver handles are int's but unixODBC uses void *. There is a define for DRV_SQLHANDLE in DriverManager/drivermanager.h that allows this choice at build time * Add a few extra checks for only unicode API's from the driver * Check for existance of qt-mt lib before adding to link line * added missing cleanup in Postgres driver * Added a contrib directory with (so far) a new ODBCConfig and ODBCStats apps, (Thanks Fizz for those). * Ask the driver when there are no errors left in the DM's store * Add a couple of unicode fixes suppled by Oracle * Small fix for call to SQLGetDiagField * Fix silly typo that was using sizeof( SQL_WCHAR ) instead of SQLWCHAR * Add check for C_TYPE in SQLBindCol, SQLBindParameter, SQLBindParam, and SQLGetData * Fix overflow if the LOG_MESSAGE_LENGTH is increased * Save the last arg for SQLSetConnectAttr if called before connection for later passing to driver * Fix missing mutex release in SQLFreeHandle (thanks Mark) * Add missing maps from unicode in SQLSetDescFieldW and SQLSetStmtAttrW * Handle resetting statement descriptors to implicit values, by passing in NULL or the implicit descrptor to SQLSetStmtAttr with the attribute SQL_ATTR_APP_PARAM_DESC or SQL_ATTR_APP_ROW_DESC * Avoid calling SQLGetInfo for every SQLEndTran/SQLTransact * Remove inconsistency in the return value from SQLGetPrivateProfileString * Fix broken QT_VERSION detection * Add UNICODE wrapper functions in libodbcinst. The ini file is still ascii, so its not got full support at the moment, but any apps that need the W functions should build now * Add GUI support for SQLCreateDataSource * More informative error message if a invalid handle is passed to SQLAllocHandle * Add TIMESTAMP_NO_TMZONE to Postgres drivers types * The ANSI to UNICODE mapping in SQLTablePrivilges was broken * Fix incorrect buffer length in SQLGetInfo when calling unicode drivers 4-March-2005 Release 2.2.11 * Fix a couple of typo errors in postgres driver and odbctest * Fix problem where ini files could be truncated under heavy load * Fix potential hang with FILEDSN's if the connect string included a DSN= entry as well * Don't save the SAVEFILE attribute in the filedsn. * Fixed bug that prevented the setting of some attributes via the DMConnAttr method * Removed the -module entry from the cursor lib, it prevents it building on HPUX. * Add a couple of extra info types to the pull down in odbctest * SQLGetInfoW was returning the wrong length when converting from the ANSI call. The same was also going on the other way. Also fixed same thing for other calls. * Fix incorrect value in SQLFetchScroll in odbctest * Fix memory leak in odbcinstQ * Check for MOC being found, before building GUI parts * Add list of export symbols to libodbcinst * Fix a problem in the cursor lib returning blobs * SQL_DIAG_NUMBER was being stored and returned as a SQLINTEGER instead of a SQLRETURN * Check if we can include sys/stats.h in iniOpen.c * Fix potential buffer overun in SQLConfigDataSource() * Fix problem in odbctest that prevented intervals from being displayed. * Cope with SHLIBEXT not being set when finding the cursor lib * Add a couple of missing Setup64 checks * Small change in __info to conserve memory * Add odbcinst.exp to distrib * Add missing ODBC2 installer stubs * Fix typo in SQLStatistics * Not passing user names and password into isql passes NULLS not empty strings into SQLConnect * Add missing SQLPrepareA from the driver manager export file * Make the default for DontDLClose 1, it doesn't do any harm, and fixes some segfaults * Fix printf format in the postgres driver on 64 platforms 29-Sep-2004 Release 2.2.10 * Add additional check in sqltypes.h to detect AIX 64 bit * Fixed minor copypaste error in configure.in * Fixed problem in configure script that prevented it using the qt-header and qt-lib config args. And allow the QT bin dir to be set. * Add new spec file (Thanks Stefan) * Alter string initialisation in isql to reduce memory use on some platforms * Remove the parts of odbcinstext.h that only are needed in unixODBC builds from outside app builds. (Cheers Stefan) * Small fix to DataManagerII * Protect iconv handle in threaded environments * Extend cursor lib to cope with where clauses * Remove incorrect duplicate function in iniOpen.c * Strip FILEDSN from connection string before passing to driver * If using a cursor lib use "IS NULL" instead of binding nulls * Allow 32 and 64 installations to coexist using a Driver64 entry in odbcinst.ini * Fix uninitialsed value that was causing "Driver does not support the requested version" warning * Fix typo in sqltypes.h that failed when building Perl DBD::ODBC * INI cacheing is not on by default, it can lead to a memory leak * Alter the Makefile.am's so builds outside the config dir can be done * Fix possible buffer overrun in SQLConnect * Replaced crypt auth in postgres with md5 for 7.1 Postgres driver * Fix memory leak in descriptor thread support 24-Jun-2004 Release 2.2.9 * Fix problem so that if SQLGetPrivateProfileString fails because odbcinst.ini doesn't exist, it copys the default value into the output. * Avoid caling SQLFreeEnv the driver more than once. * Rename lo_xxx func in Postgres driver(s) to avoid clash with postgres lib. * Add odbc-config to find compile time options for use with other build tools * Fix call to SQLParamData in cursor lib * Add SQL_NULL_DESC to include files * Remove -M for unixware builds from libtool * Fix descriptor bug in SQLCopyDesc (Thanks Erik) * Add extra iconv targets * Fix bug that stopped RTLD_GROUP from being added to dlopen * Remove mem leak if libodbc.so is loaded using dlopen instead of linked as is normally done. * Add check for LP64 in sqltypes.h * Remove dlclose from ODBCConfig * Fix typo in the readline detection in configure * Fix potential hang with semaphore allocation in driver manager * Alter how the state is set after a SQLParamData to S5 insted of S4 * Stop the driver manager from calling SQLFreeEnv twice in the driver * Add new MySQL source from MyODBC 3.51.07 * Update the uo_fopen functions * Add some extra mutex locks around end_tran code. * Alter the flag to build real 64 bit mode to BUILD_REAL_64_BIT_MODE * Update a couple of prototypes for 64 bit builds * Fix assorted 64 bit warnings and cast issues 17-Feb-2004 Release 2.2.8 * Fix bug in SQLMoreResults that moves to incorrect state * Fix problem where metadata calls fail if in STATE_S5 * Fix bug inserting ini entry with more than one '=' * Fix some stupid leaks in the connection pooling code * Allow the driver manager to probe a pooled connection, to see if its valid. Set the query to use in the odbcinst.ini entry by setting CPProbe = SQL, for example this works well for postgres [PostgreSQL] Description = Postgres SQL Driver Driver = /usr/local/lib/libodbcpsql.so.2.0.0 Setup = /usr/local/lib/libodbcpsqlS.so CPTimeout = 1000 CPTimeToLive = 100 CPProbe = select user FileUsage = 1 DisableGetFunctions = 0 DontDLCLose = 1 * Fix the SQLGetPrivateProfile code when passing NULL sections or names. * Fix SQLGetData to avoid a problem returning unicode from ODBC2 drivers. * Make the header sqlext.h include the unicode header sqlucode.h. This matches the MS header files. * Added DriverConfig lib for Mimer. (From Mimer) * Make connection pooling check using SQLGetConnectOption as well as Attr * Fix leak if iconv is used and a connection fails * Add configure option to disable the use of readline in isql 02-Dec-2003 Release 2.2.7 * Add missing comma in Oracle setup lib * Add -l option to isql to allow setting locale * Fix problem in SQLDriverConnectW that prevented connecting to UNICODE driver. * Remove a couple of the attribute mappings from SQLColAttribute when going from V2 app to V3 driver. * Clear SQLError errors in the same was as SQLGetDiagRec (this will help PHP out somewhat). * Add a check to handle driver that don't support SQLGetEnvAttr * Allow ATTR; in set attr lists from ini file * Small change to warning dialogs in odbctest (Thanks Mark). * Fix the cursor lib to work via SQLFetch as well as the other fetches. * Update the README.OSX file to cover building the cursor lib. * Remove the SQLNumResults() call after a execute. This means the DM doesn't know if there is a result set, but it seems to match what the MS one is doing. * Fix a major mistake in the thread protection, it worked fine until the driver returned a error. * Fix write beyond string bound in SQLDriverConnect.c (Thanks Ocke) * Add call to setlocale( LC_ALL, "" ) in isql.c, can also be set using -l option * Add initial support for Microsoft Interix, details in README.INTERIX * small change to ODBCConfig to have the password field in the driver properties hide the password * Make both # and ; comments in ini files * Update README.OSX to cover changing driver libs into bundles * Fix a couple of small display problems in odbctest * minor updates to odbctest: Have the gui list match the input order and the ini file Restore the selection after Add/Remove * Expand a text buffer to avoid overflow * Add RTLD_MEMBER to dlopen args if available (AIX) * Fix bug in SQLWritePrivateProfileString 21-July-2003 Release 2.2.6 * Add SQL...A() functions as well as W * Add some 64 Bit changes * Add support for SQL_BIGINT in Postgre7.1 driver * Fix bug in libtool that fixes a call to access * Allow setting of odbcinstQ lib load with either environment variable ODBCINSTQ or in the [ODBC] section of odbcinst.ini with a odbcinstq = /path/to/libodbcinstQ.so * Alter the way SQLDataSources works (again :-) * Add configure option to force the way dlopen works * Fix bug in stats collection * Add call to endpwent() to avoid a small leak * Allow isql to handle SQLMoreResults * Add option TracePid in [ODBC] section of odbcinst.ini, setting this makes the DM treat the TracePath as a path to a directory, and creates seperate log file for eack PID in use, mainly of use when used under something like apache. * Add extra unicode string for Solaris, see README.SOLARIS * Sort error messages according to state (as per the spec) * Remove trailing \ from doc/Makefile.am * Fix memory corruption in postgres driver that caused table creation under OpenOffice to fail * Tidy up gODBCconfig so it builds with current tools (or so I hope). 26-Feb-2003 Release 2.2.5 * On error from SQLMoreResult don't change to S1 * Fix build problem with QT 3.1.1 * Fix spelling of error message * Fix bug where multiple connections give ODBC version error (thanks Jay Cai) * Increase the TEXT_FIELD_SIZE in the PG drivers * Set output handle to NULL if SQLAllocHandle call fails * Return any errors from the drivers SQLAllocConnect * Update version of automake and autoconf used to produce distributions * rebuild libtools configure to work with new autoconf 24-January-2003 Release 2.2.4 * Make the DM look in libdir for the cursor lib * Additions to DataManagerII * More thread safe issues and fixes * Fix uninitialised pointer in SQLDriverConnect.c * Fix memory leak in SQLGetDiagRec * Add missing SAG conformance SQLGetfo call in odbctest * Fix bug in SQLDriverConnect where warnings were not getting into the error stack * Add quotes to table names in DataManager * update the file "missing" * Add missing SQL_DECIMAL in logging conversions * VMS build changes... (Thanks Craig) * get caught up with changes since the original VMS port * follow the compiler warnings to fix myriad small nits throughout the sources * change the handling of shareable images so they no longer need to be placed in SYS$SHARE * improve the installation and set-up process * Make the cursor lib build without needing libodbc, it breaks on HPUX * Fix allocation problem in cursor lib * Fix potential seg fault in cursor lib, when bind is done with null indicator * Update README.QNX to cope with QNX 6.2 * Fix problem with flags to dlopen * Make the exit logging in the driver manager display unknown return codes * Fix bug in driver manager where a SQLAllocHandle in the driver can cause a seg fault * Add -s option to isql to allow the input buffer size to be set i.e. isql -s32000 dsn * Update some of the autoconf scripts to handle RH 8 * Add extra attrs to oracle setup lib * Allow DMEnvAttrs to be set in odbcinst.ini as well * Alter the way the config mode is stored, don't use putenv now, as it causes trouble if the DM is unloaded. Also malloc the strings if the environment is set via the DM, to avoid the same problem with putenv. This caused a crash of OpenOffice on Solaris 23-August-2002 Release 2.2.3 * fix bug in unicode_to_ansi_copy * DataManagerII was missed from the last release, sorry, I thought that it had been moved to DataManager. * DatamanagerII: Remove duplicate rows with drivers such as Postgres which doesn't work as expected when getting lists of Schemas * Attempt to set permissions for the file dsn directory. * Fix bug with conversion of ODBC 2 values to SQL_C_WCHAR * Make the postgres drivers return a SQL State of 01000 for a warning, not 00000 * Add option to isql (-x) to specify a separator in hex (0x09 is V tab) or octal (012) * Fix typo in pre 7.1 Postgres driver that broke bound timestamps * Fix what looks like a bug in the libtool dlopen wrapper, its fails to fail, when failing to load a lib. * Only call the ODBC 3 version of SQLGetFuctions if we have requested ODBC3 some drivers (SAPDB) that return ODBC 3 API's only return this call if the connect specified ODBC 3. * Check the attributes being passed into SQLSetConnectAttr, only pas into SQLSetConnectOption if they are ODBC 2 values. The same for SQLSetStmtAttr * Allow double clicks on dsn's to bring up the configure in ODBCConfig * Add extra thread checks for FreeBSD * Add check for SQL_NO_DATA in isql * Add code to make DM cope with SQL_NO_DATA from SQLExec(Direct) * Change UNICODE conversions, remove all inplace converts. * Add support for iconv for the UNICODE to ANSI conversions * Add code to make DM code with SQL_NO_DATA from SQLExec(Direct) * DBFIO: completed basic functionality (DBF file access library) * dbfio: completed basic functionality (test program for DBFIO) * Add checks for usage counts for loaded libs * Replicate the way the MS DM only calls SQLAllocEnv on a driver once * Add fix from John L Miller for SQLEndTran and SQLTransact * Make it try and find a working iconv set of encodings * Small fix to SQLMoreResults from John L Miller * Alter error state return in SQLCloseCursor * Allow state 07009 to be mapped to S1002 or S1093 depending on the calling function * Fix major ineffiency with text fields and the Postgres drivers * Fix incorrect return state from SQLEndTran/SQLTransact * Make rowcount return a count of -1 if its returns a error * Further AIX linking tweeks 08-July-2002 Release 2.2.2 * added -m option to isql * improved row count at end-of-result in isql * allow SQLColAttribute(s)(W) to be called with a column number of 0 to get the descriptor count * Remove -export-symbols from sample, it was causing some problems on Solaris * Add DataManagerII, this is a updated version from Mark Vanderwiel * Update libtool to escape from AIX build problem * Add fix to avoid file handle limitations * Add more UNICODE changes, it looks like it is native 16 representation after all. The old way (Fixed at BE) can be reproduced by defining UCS16BE * Add iusql, its just the same as isql but uses the wide functions * Couple of cast warnings cleaned up * Add change to libtool to clean up AIX build * Create README.AIX * Fix small bug in SQLDriverConnectW, I was allocating 1 byte two little * Fix typo in SQLConnect that wasn't allowing the driver manager to supply SQLFreeConnect for drivers that didn't support this. * Fix build on Caldera OpenUnix8 (not sure why anywone would want to go anywhere near this OS IMHO...) * Move DataManagerII to DataManager * Alter what comes back in the second field from SQLDataSources to be the description from the ODBCINST.INI entry, this matches what happens in with the windows DM. 23-Mar-2002 Release 2.2.1 * odbcinst: now tries to auto create system odbc.ini * odbcinst: implemented -n, -l, -h for -q -s * Add option to disable definition of windows types in sqltype.h * Fix small bug in ini uper case routines. * Added STMT and OPTION to MySQL driver setup * Added -j arg for odbcinst (shows INI file names) * Fixed seg fault bug in Text File driver * Fix small bug in SQLBrowseConnect * Fix check for Darwin (OSX) * Fix bug in sqltypes that stopped 64 bit builds * Fix build problem on 32 bit platforms without long long * Add option to set environment (unix) values via SQLSetEnv, this can also be done in the odbc.ini, for example [sample] Description = Test to DB2 Driver = DB2 DMEnvAttr = SQL_ATTR_UNIXODBC_ENVATTR={DB2INSTANCE=db2inst1} * Fix some cases where the trace file env value was "Trace File" * Make the readline check make sure there are headers as well as libs * Add check to use RTLD_GROUP in libltdl if present * change DWORD definition to unsigned long where applicable * Fix bug in error reporting that cound crash with multiple errors and ODBC3 * Remove C++ comment from exe/odbcinst.c * If we are not building the drivers, dont build sqp * Alter default size of odbctest window * Improve check for stats headers * Add install-data-am section back to Makefile.am to create the empty ini files * Extend naming of cursor lib to work on non linux platforms (it expected a .so) * Make Postgres driver(s) handle {oj ... } syntax * Fix some endian issues with 4 byte unicode support * Update the MySQL driver code 30-Jan-2002 Release 2.2.0 * Allow SQL_ATTR_LOGIN_TIMEOUT to be set on a connected connection doesn't make that much sense, but it mirrors what the Windows DM does. * Change DWORD in sqltypes to be a unsigned int to work on 64 bit platforms * Fix incorrect diag message in SQLSetStmtOption.c * Hack to the 7.1 postgres driver to enable SQLPrepare to be called BEFORE SQLBindParameter * Reset the stmt->prepared flag when going into a SQLParamData state after SQLExecDirect * Fix silly bug that stops odbctest adding the fidt entry on the list * Add missing tracing to SQLBrowseConnect * Fix some potential corruption in SQLGetDiagField * Add some simple cacheing to SQLGetPrivateProfileString * check for redefinition of SQL_OL_CAP to stop AIX build breaking * Add missing getGlobalDefaults in PG 7.1 driver (Thanks Rick) * Fix bug in SQLConnectW (Thanks Artiom) * More mods to SQLConnectW and SQLDriverConnectW * More MS generated 64bit changes * Add MyODBC 3.5 driver. Its a separate configure in Drivers/MySQL Release 2.1.1 2001-12-21 * started to add mac package/install dirs for PackageMaker * added qmake project files as an optional build process * ODBCConfig can build with a static odbcinstQ * Remove auto text driver setup, this breaks new installs as it can't find odbcinst * Fix mixup in SQLSetScrollOptions * Small portability fix for BSDI * Make UNIX Domain socket settable in postgres driver vua UDP= in odbc.ini dsn entry * Fix bug where some SQLGetConnectAttr values were not coming from the driver, but the driver manager * Alter odbctest to make directory select in Manage Auto Test work better * Fix browser in DataManager so that it works with drivers that don't return values from SQLRowCount * Fix some error retrieval problems * Alter the include files to match MS ODBC 3.52 with 64bit support, fix assorted warnings when building on 64bit platforms * Add option to force tracing on, this is for use with apps like StarOffice that disable tracing * Add support for MAX_ROWS in postgres drivers * Add fix to cover Darwin 1.5 (OSX) * Add DisableGetFunctions option to driver section of odbcinst.ini to cope with drivers that can't handle the call (Solid 2.2 AFAIK) * Fix 64 bit bug in Postgres driver * Add some ODBC 3 bits to the Postgres driver to make it run with Star Office 6.0 (beta) Release 2.1.0 2001-11-27 * cvs moved to Source Forge * attempts have been made to cleanup GNU auto-stuff to make the cvs code more accessable - added README.cvs - hopefully "make -f Makefile.cvs" works on more platforms * implemented more in SQLManageDataSources() - created odbcinstQ (plugin for Qt GUI support in odbcinst) - moved most code from ODBCConfig to odbcinstQ * stupid mistake on my part(Nick), left a #ifdef in isql.c that prevented displaying a list of tables * Make calls to localtime in Postgres Driver only when required * Made some changes to Postgres prototypes * Add option to get odbcinst info from stdin * Make SQLError errors clean down after each API call for ODBC 3 apps * Add mapping from SQLColAttribute attributes to ODBC2 attributes * Fix reported leak in ltdl.c * Make the path for file DSN's come from the odbcinst.ini file * If using a ODBC 3 driver call the one off version of SQLGetFunctions * Now builds better on Darwin * Reinstate conversion from wide to ansi types in SQLGetData if the driver is ODBC2, also adjust the buffer length to prevent buffer overrun. * Stop ODBCConfig setting Trace File in odbcinst.ini it should be TraceFile Release 2.0.10 2001-10-14 * odbctxt : escape special chars when read/write lines into a table * Fix bug where a Execute that errors should return to state S2 * Update README.OSX to cover a txt driver problem * Add Drivers/txt/doc to distribution * Add missing text driver setup from spec file * add missing VMS opt files * Add missing include from DataManager (Samuel Cote) * Remove LT_GLOBAL from the libtool code. This breaks perl amongst others. * Allow the display of unicode data in logs * Fix stupid WCHAR bug in SQLGetData * Move ifdef in __stats.c to allow the building of ODBCConfig under Mac OSX * Add missing args to prototype in sqlext.h (Thanks Christian) * Pass on unknown connection attributes to driver after connect * Make SQLGetPrivateProfileString return the actual len read, not + 2 * Make the OSX build cleaner, it just needs the dlcompat lib now * Allow ODBCConfig to handle attributes not described in setup libs * Stop the ODBC Version being set when there are open connections * Alter odbcinst error messages to match windows * Fix incorrect installer errors (they were offset by one...) * Create ./odbc.ini if it doesn't exist * Fix typo that stoped odbctest from building on Suns latest compiler * Slightly alter the unicode definitions in sqltypes.h * Add support for FILEDSN in driver manager, odbcinst, and ODBCConfig * Fix buffer overrun in Postgres drivers Release 2.0.9 2001-08-14 * odbctxt: tweeked - now works on PowerPC * Add auto register for text driver to Makefile.am * Add check for flex, sqp won't build with lex now * odbctxtS: now supports CaseSensitive property * Add build time option to select wchar_t UNICODE (4 bytes) as opposed to signed short UNICODE (2 byte) * Add build time option to select the length of logged strings (LOG_MESSAGE_LEN in drivermanager.h) * Fix libtool bug that caused the AIX build to not produce shared libs * Fix couple of typos that caused the build to fail on Solaris * Add conditional for 64 bit application compilation when the sizeof(long) will not have been done by configure * Fix small bug in postgres driver on debian * Add build instruction for QNX * add Slovak translation of gODBCConfig * Fixes to SQLBrowseConnect in driver manager * Get the DM to check with the driver for the CLI Year * Fix small bug in strncasecmp in extras * Add extra support for SQLSetConnectAttr before connection * rename global structure in Postgres drivers to avoid a colision * Add support for presetting Env,Conn and Stmt attributes via the ini file using the following syntax in the dsn section of odbc.ini DMConnAttr = SQL_ATTR_CONNECTION_TIMEOUT=30 DMStmtAttr = SQL_ATTR_NOSCAN=SQL_NOSCAN_OFF;*SQL_ROWSET_SIZE=20 the * indicates thats its a override attribute, so any attempt to call SQLSetStmtAttr to set the rowsize, will always set it to 20 in this example. NOTE: That at the moment, this information will be lost if ODBCConfig is used Release 2.0.8 2001-06-25 * Add definition of alphasort and checks for location of dir.h in the txt driver. * Add some missing functions from cur lib * Fix a problem in configure.in that was loosing LIB settings * Remove C++ comment from sqlext.h * sqp: now makes use of check for NOT NULL in CREATE TABLE * sqp: fixed missing pointer assignment (affected CREATE TABLE) * sqp: added more debugging messages (but turned off by default) * odbctxt: removed long log message (would cause seg fault) * odbctxt: now appends a space to each SQL statement; this is to work around a problem in the sqp lexer when last char is close quote * Fixed a bug in the driver manager that would fail if the driver returned a max size error message * sqp: now makes use of IS NULL and IS NOT NULL * sqp: now makes use of INSERT INTO table(col1,...) * sqp: now makes use of LIKE and NOT LIKE (with optional ESCAPE) * sqp: now makes use of any mix of AND, OR, () in WHERE clause * sqp: now makes use of ? for column value (used in SQLBindParameter) * sqp: now makes use of integers for column values (just mapped to string) * odbctxt: basic implementation of SQLBindParameter (only SQL_C_CHAR input allowed) * odbctxt: new syntaxes of sqp parser taken into account * odbctxt: new option CaseSensitive (Yes or No) allowed in .odbc.ini file * odbctxt: fix message length returned in SQLGetDiagRec function * odbctxt: drop statement when freeing it via SQLFreeHandle * sqp: default string length changed to 255 * Fix threading problem when multiple ENV's are in use Release 2.0.7 Peter Harvey And Nick Gorham 2001-06-06 * ODBCConfig/DataManager: Updates for Qt 3.0 * Add extra decoding of types in the log output * Fix some type problems for 64 bit platforms * Fix rogue logging in SQLGetInfo * Add correlation and alias to sqp * Add some fixes to the txt driver to enable it to work with StarOffice * Stop Ctrl-D from Segfaulting isql * Add a example autotest to the build * Make isql detect the EOF when not using readline * Tidy up the libs from autoconf * DataManager: refinements such as; logout a DSN, isql history * sqp: CREATE TABLE now supports most data types and some column options * sqp: added DROP TABLE * sqp: added ORDER BY * sqp: enhanced api with sqpOpen, sqpClose... * odbctxt: checked in rewrite (much less code now) * odbctxtS: added setup lib for odbctxt * ODBCConfig: Stats now shows PIDs * Add missing -lpthread in configure (thanks Jon Kre Hellan) * Remove C++ comments from autotest.h * Fix big in Postgres7.1 with binding a column to a double (thanks Jrgen) * Update libtool to 1.4 * Fix problem that looked like a restriction on the size of ini files, but was actually a problem when the same section appeared twice in a file * Add VMS port (Thanks Jason) * Add extra PG7.1 numeric fix (Thanks Zoltan) * Add fix to PG7.1 to allow the retrieval of more than 8K blobs, adjust the define TEXT_FIELD_SIZE in psqlodbc.h (Thanks Bojnourdi) * Fix small typo in SQLConnect (Thanks Martin) * The postgres drivers didn't recognise "Yes" in the ini files, only 1 or 0, fixed now * Avoid "broken pipe" message with postgres (Thanks Gary) * Alter check if cursor lib needed with ODBC 3 apps * Fix couple of bugs with cursor lib * Get to build on Mac OS X (without GUI bits ATM) look at README.OSX for help and hints * Fix for use with QT 3 * Remove default trace option from ODBCINSTConstructProperties * Stop ODBCConfig from accepting null DSN names Release 2.0.6 Nick Gorham 2001-04-18 * Add define for _THREAD_SAFE to help AIX builds * Fix bug in cursor lib introduced by UNICODE addon's * Make the header definitions work on 64 bit platforms * Fix a incorrect return from SQLConnect with pooling * Add support for unicode drivers that have ANSI functions renamed to the unicode versions (duh!). * If pooling, then set the flag to not close the driver handle (DontDLClose) * Add CPTimeToLive option to restrict the number of times a driver will be reused (useful with leaky drivers) * Alter logging, and support setting logging via SQLSetConnectAttr call * Add a AutoTest facility to odbctest * Fix incorrect error test in SQLBrowseConnect * Check descriptor is for a open connection * More unicode fixes Release 2.0.5 2001-03-21 Nick Gorham * Add extra autoconf checks for -pthread and -mt compiler options * Add Postgres7.1 tree for code from new postgres development * Fix retrieval of errors for SQLTables and SQLColumns call in isql * Fix mem leak in DM if SQLDisconnect was called with open statements or descriptors * Fix broken check if readline needs -lcurses * Add setup lib for SAPDB (thanks Holger Schurig) * Added locale fixes to PG7.1 driver (thanks Zoltan) * Fix configure problem on Solaris Release 2.0.4 2001-02-02 Nick Gorham * Changes to Postgres driver for operation with PG 7 and locale changes (Zoltan Boszormenyi) * Fix problem with SQLSetConnectAttr and unicode operation * Apply patch to DataManager from Christian.Werner which fixes truncated query result rows, formatting errors in HTML output, and adds a leading blank to each where expression in order to prevent SQL syntax errors in e.g. LIKE '..' or MATCHES '..'cases. * Add support for SQLDriverLoad and SQLDriverUnload functions Release 2.0.3 2001-01-13 Peter Harvey and Nick Gorham * sqp: added a yywrap() to eliminate link dependency * sqi: home dir default if no path with database file name * sqi: creates database file if not exists * ini: open fails if existing file appears not be an ini * Fixed problem where null row status array could be passed into SQLExtendedFetch * Fixed further bug in unicode_to_ansi (thanks Martin Edlman) * Fixed bug in UNICODE converison in SQLGetInfo * Added sqi/test to build tree, its moved to exe * Add extra checks for readline to see if -lcurses is needed * Add check for -lpthreads that should be ok on Tru64 * Replace printf with puts in isql to cope with columns containing '%' Release 2.0.2 2001-01-08 Peter Harvey * ODBCConfig: Repurposed 'Tracing' tab. Now is 'Advanced' and contains both Tracing and Pooling options. * Fixed bug in __info that caused SQLGetDiagRec to fail Release 2.0.1 2001-01-06 Nick Gorham * Fix bug introduced with UNICODE that corrupted the SQLSTATE from SQLError Release 2.0.0 2001-01-04 Nick Gorham * Added table browse for DataManager * Fix problem in template driver with Solaris compiler * Add msql-include option to specify search path * Fix compile problem in MiniSQL code with Solaris compiler * Fix conditional include of strings.h in ODBCConfig build * Fix tracing in SQLConnect * Alter check for DSN length in SQLConnect * Validate input handle before setting output handle * Fix error code from SQLSpecialColumns and null table names * Fix potential deadlock in SQLFreeHandle * Add change to make the Postgres driver look for the local socket in two places to cope with debian distrib * Fiddle with the MiniSQL searching again * Add sqlucode.h to headers * Fix threaded race condition in __handles.c * Revamped Credits page in ODBCConfig. * Show more useful info in DataManager tree-view * Fixed problem with DataManager 'hanging' upon exit * Added -pthread option to gcc calls when needed * Now needs QT 2.2.x, changed configure to check * Add missing identifier_type in SQLSpecialColumns log * Add some checks for long columns in isql and DataManager * Add connection pooling support to driver manager * ODBCConfig; Code cleanup. Removed extra class layer created by QtArch * ODBCConfig.Drivers.Config; driver specific options now accepted, if already exist in odbcinst.ini, as simple text fields in GUI * ODBCConfig and DataManager now attempt to save and restore state... such as window geometry. * ODBCConfig now supports connection pooling options. * ODBCConfig now has a Stats tab which is similar to CPU or mem monitor. This will be improved upon and the code will likley make its way into a dock widget * Add UNICODE support * Disable the default building of static libs * Add support for GNU portable threads Release 1.8.13 2000-11-14 Nick Gorham * Add missing line continuation char in SQLGetDiagField.c * Add fix to SQLGetDiagField to return the server name on statements and descriptors * Remove -lcrypt from all but the Postgres driver build * Remove CR/LF expansion in Postgres driver * odbctest was calling SQLPrimaryKeys when it should have been calling SQLTablePrivileges * Add SQL_DRIVER_HDESC support to SQLGetInfo * Add display of returned error text in log file * Take notice of DontDLClose when calling ConfigDataSource. * Fix duplicated log messages on failed connect * Fix incorrect arg to SQLError, change from SQLINTEGER to SQLSMALLINT (Thanks Ralf) * Updated libtool to 1.3.5 * Fixed crash in SQLConnect when NULL server and SQL_NTS passed in (Thanks Venu for the next four changes) * The error code mapping was wrong, it should only map ODBC 3 errors to ODBC 2, not the other way around * Fixed a incorrect error return in SQLPrepare when a NULL string was passed * Zero the handles when released, just to avoid reuse of values * Added readline support to isql, (thanks Tomas Zellerin) * Support the setting of SQL_AUTOCOMMIT before connecting * Fixed bug in odbctest's SQLColAttributes call * Add test in configure for localtime_r and use if present 2000-08-18 Nick Gorham Release 1.8.12 * Fix typo in Postgres driver. * Add i18n support to the Postgres driver (thanks Zoltan) * Remove fix for Postgres driver and large objects, it breaks the SQLColumns call :-( Release 1.8.11 2000-08-16 Nick Gorham * Add --enable-fastvalidate option. This reduces the safety of the handle checking but improves performance when using many handles * If SQLDriverConnect is called with a NULL con_str_in look for the DEFAULT DSN entry * Remove a underscore from odbcinst_system_file_path, it seem's to cause the linker on AIX to have problems * Remove some additional C++ comments from the postgres driver * Call SQLSetConfigMode before calling SQLConfigDataSource * Fix error handling in case of referential integrity violations in Postgres driver * Fix problem with SQLColAttributes swapping its args, and don't check the driver version before mapping to ODBC 3 values. (thanks Tomas) * Make SQLDescribeParam work in state S4 and above, when in ODBC 2 mode * Avoid potential buffer overrun in __info.c when reporting errors from SQLConnect/SQLDriverConnect * Fix potential mem corruption in SQLGetDiagField (thanks Jay) * Add fix to allow the Postgres driver to receive large objects (thanks Bill) * Fix buffer overrun in SQLGetDiagField (thanks again Jay) * Fix for SQLGetDiagField(SQL_DIAG_SUBCLASS_ORIGIN) returning a null string, it now returns something meaningful * The Postgres driver didn't shupdown the connection to the database before dropping the socket * Fix incorrect return from SQLDataSources * Make SQLDriverConnect return all errors from the driver not just the first one * Add Oracle setup lib for http://www.easysoft.org/projects/oracle * Stop isql calling SQLFetch if the query doesn't generate a result set. This stops the function sequence error * Add missing break in postgres password authentication * Add fix in SQLTables for broken version of EXCEL * Fix a bug that caused SQLTransact to fail if called with a connection handle in state C4. This caused Corel Paradox to fall over Release 1.8.10 2000-06-15 Nick Gorham * Add some fixes to make it work and compile on IRIX (Murad) * Add a couple of missing casts in odbctest (Michael) * Fix BOOL bug in postgres driver (Dmitriy) * use setenv rather that putenv if available * Fix a couple of bugs in odbctest/attr.cpp * Fix problem where info warnings could be lost * Fix a couple of problems in the Postgres driver * Fix bug that caused a success with info message from SQLExecute or SQLExecDirect to be lost if used with a ODBC 3 driver and the application called SQLGetDiagRec * Fix problem where bookmarks were failing for StarOffice 5.2 * Stop SQLDriverConnect dumping core when passed a null dsn string * Map ODBC 2 SQLSTATE values to ODBC 3 * Add missing odbcconfig.h to the install include in gODBCConfig * Fix incorrect state from Postgres Driver * Fix integer length problem with SQLExtendedFetch that manifested on big endian platforms (Sparc,Aix,HPUX etc) (Alex) * Avoid clash with definition of CHAR in GNOME XML layer * odbctest SQLExtendedFetch was using the wrong orentation value * Add define for SQLTCHAR * Fix problem in setting tracing on, and a core dump when loading the cursor lib failed (Steve) Release 1.8.9 2000-06-13 Nick Gorham * Fix a State problem when coming out of a SQLParamData cycle * Fix bug where SQLBrowseConnect may leave a connection in C1 not C2 * Pass LOGIN_TIMEOUT onto driver if it is set before the connect * Reverse the test to set DIAG_CLASS_ORIGIN * Return SQL_DIAG_SERVER_NAME and SQL_DIAG_RETURNCODE * Allow explicit allocation of Descriptors * Fix a problem with the SQLFetchScroll -> SQLExtendedFetch mapping * Fix a problem in the MiniSQL Makefile.am * Call SQLSetConfigMode before calling ConfigDSN * Fix problem in SQLCopyDesc and complete case when DM does the work * Return SQL_SUCCESS_WITH_INFO messages from SQLConnect * Added MetaDataBlockFetch connection attribute to esoob driver * Fix bug in __info.c that caused a small memory corruption when logging was on * Enable the reporting of errors on descriptors * Fix extra ] in the msql part of configure.in * Add error reporting to DataManager (Tim) * Assorted fixes to text driver (Peter) * odbctest now ready to use (hopefully) 2000-05-03 Nick Gorham * Fix bug in configure.in where disabling build of drivers also disabled build of GUI bits. * SQLDataSources should return the Driver Description, not the data source description * Add partly written odbctest GUI to project * Remove conditional around VOID typedef in sqltypes.h by default Release 1.8.8 2000-04-27 Nick Gorham * Add extra include for unixware * Added some fixes to the template driver found by Nikolai Afanasiev, and also fix the logging code to recongnise 'On' * Alter distrib to not include moc generated files * Using the env var ODBCHOME was a "real bad idea" for perl I have changed it to ODBCSYSINI * Alter logging so that if the log file fails to open stderr is not used. This caused problems in server processes. * Fix a problem with SQLDrivers * Fix a potential leak, that stopped SQLDisconnect being called * Fix problems with text driver * Improve isql (thanks Ralf) * Make gODBCConfig a proper gtk widget * Remove stray printf in the DM code * Fix a couple of daft bugs, thanks to Tim Roepken * Fix a problem where handles were not being free'd * Fix a problem that stopped StarOffice 5.2 working with a ODBC 2 driver, it failed to set SQLGetDiagRec in the output of SQLGetFunctions 2000-03-11 Nick Gorham * Adjust configure to check for limits, and use this to find max file path. It was only 14 char before under HP-UX * Make ODBCCOnfig try calling SQLConfigureDSN, for setup libs that can do it themself * Make the mutex functions static * Remove some unwanted X functions from the lib line * Remove dlfcn.h in ODBCConfig * Rationalise environment vars, ODBCHOME points to where odbc.ini and odbcinst.ini are. ODBCINI points to the user ini file (normally ~/.odbc.ini) * Fix bug causing all connection errors to be lost after connecting * Add GTK+ Based gODBCConfig 2000-03-01 Nick Gorham * Add extra defines to sqltypes.h * Fix bug in the Postgres driver with the use if the SQL_DATA_AT_EXEC value * Replace the ODBCINI with ODBCHOME environment var 2000-02-23 Nick Gorham * Remove the GLOBAL flag from the dlopen in the libtool lib. This caused problems with perl DBD::ODBC * Fix the support for threads and Solaris * Add odbcinst.ini flag to disable unloading the driver, this enables the IBM DB2 lib to be used Release 1.8.6 2000-02-21 Nick Gorham * Fix memory leak in the Postgres driver * Fix a bug in the DM when using threads and ODBC 3 drivers, SQLGetDiagField fails * Fix a situation where PHP can crash the DM by calling SQLFreeStmt after SQLDisconnect * Add support for Solaris Threada * Make building with thread support the default 2000-02-12 Nick Gorham * Add option to use ODBCINI to move the odbcinst and odbc ini file. This was asked for by applix * Add setup lib for Easysoft ODBC-ODBC bridge 2000-02-02 Nick Gorham * Add flag in odbcinst.ini to disable the SQLFetch -> SQLExtendedFetch mapping for broken drivers * Alter the ini file parsing so the right hand side can contain extra ='s * Fix a bug in SQLGetStmtAttr with a missing '&' * Added a couple of patches from Manush to improve working with the solid driver Release 1.8.4 2000-01-18 Nick Gorham * Fix bug in SQLAllocHandle where a failed stmt alloc would report a error on the statement not the connection and dump core * Make the default path when adding a driver in ODBCConfig $prefix\lib * Add the missing [unixODBC] prefix to error messages * Fix a problem in template/SQLDriverConnect found by Charles Overbeck * Update to libtool 1.3.4 * Fix problem in ODBCConfig where a cast to const char * was needed Release 1.8.3 1999-12-28 Nick Gorham * Fix a bug where a SQLDisconnect was not releasing the lib handle 1999-12-11 Nick Gorham * Merge in changes from the Postgres ODBC people to fix a problem with LONGBIN's * Mask out the password fields in log for SQLConnect and SQLDriverConnect * Change a incorrent HY004 error return to IM004 in SQLConnect Release 1.8.2 For AlphaLinux Distribution 1999-12-02 Nick Gorham * Fix some daft mistakes in odbcinst.c, and the template driver * Remove the C++ comments from the Postgres driver so it can be compiled with a C compiler * Add LIBSOCKET to the Postgres driver link line * Add strncasecmp to extras * Make the Postgres driver use the socket lib if needed 1999-11-23 Nick Gorham * Add support for encrypted passwords in the Postgre driber * Remove some remaining non-libtool dlopen code * Fix some threading problems 1999-11-19 Nick Gorham Release 1.8.1 ********** * Make the code more portable * Remove CR from Postgres source 1999-11-17 Nick Gorham * Fix a bug with the ODBC 3 error functions. * Fix a missing function_entry from SQLExecDirect(). Release 1.8 ************* 1999-11-13 Nick Gorham * Fix bug with logging that killed StarOffice * Upgrade the Postgres driver to 6.4.6, this fixes a problem with fields containing cr/lf combinations. * Change the logging so that the logging info comes from a special [ODBC] section in odbcinst.ini. This means that what goes on before the connect can be logged 1999-11-10 Nick Gorham * Make SQLError,SQLGetDiagField and SQLGetDiagRec usable with all versions of application and driver. * Add configure flag to specify where to look for the MiniSQL lib. * Add configure flag to disable the building of the drivers. 1999-11-02 Nick Gorham * Fix bug in the cursor lib introduced by the fix for the glibc bugs. * Fix bug where SQLSetConnectAttr/Option can return without clearing a connection thread lock. 1999-10-29 Nick Gorham * Make the postgres driver able to connect via UNIX domain sockets 1999-10-29 Holger Bischoff * Assorted stupid bugs fixed in the DM 1999-10-26 Nick Gorham * Started rewrite of the SQLError/SQLGetDiagSupport in the driver manager * Fix isql so that SQL_SUCCESS_WITH_INFO is a success for SQLConnect 1999-10-20 Greg Bentz * Added fix for SQLTransact, it was checking for a non null henv first, it now checks the hdbc first (Thanks Greg) * The connection_count in the environment handle was only incremented on the first connection, but decremented on all free dbc's, this caused the count to go negative at time. 1999-10-09 Nick Gorham * Added Manush's patch to map ODBC 3-2 datetime values 1999-10-05 Nick Gorham * working on getting the build to be more portable * added --enable-gui configure option to turn off all c++ and GUI bits * improved performance by removing logging core when logging is off * added extras dir to contain code for missing functions on certain platforms * first day out for the cursor lib, read only at the moment, a sample program is included in samples/cursor.c * fixed problem that if the user .odbc.ini was not found the code failed to go on to the system odbc.ini * fixed problem caused by some versions of dlsym reporting function that should be in the driver and returning the entry from the DM Release 1.7 ************* 1999-07-26 Nick Gorham * New config added, now using autoconf. * Thread safe support added. * Assorted Driver Manager bug fixes added. * default location for odbcinst.ini and odbc.ini is now /usr/local/etc to conform to GNU standards. 1999-05-15 Peter Harvey * Drivers: nn driver added 1999-05-10 Nick * DM: New Dm added. 1999-04-04 Martin Evans * Makefiles: Some changes to; a) use gcc, and b) build into other than /usr 1999-03-30 Peter Harvey * ChangeLog: Started ChangeLog unixODBC-2.3.12/DRVConfig/000077500000000000000000000000001446441710500150015ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/Makefile.am000066400000000000000000000002451446441710500170360ustar00rootroot00000000000000if DRIVERC SUBDIRS = \ drvcfg1 \ drvcfg2 \ PostgreSQL \ MiniSQL \ MySQL \ nn \ esoob \ oplodbc \ template \ tds \ txt \ Oracle \ sapdb \ Mimer endif unixODBC-2.3.12/DRVConfig/Mimer/000077500000000000000000000000001446441710500160525ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/Mimer/Makefile.am000066400000000000000000000003151446441710500201050ustar00rootroot00000000000000lib_LTLIBRARIES = libmimerS.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) libmimerS_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared libmimerS_la_SOURCES = mimerS.c unixODBC-2.3.12/DRVConfig/Mimer/mimerS.c000066400000000000000000000104611446441710500174540ustar00rootroot00000000000000/* * This file contains the ODBCINSTGetProperties function. * * It is required by unixODBC (http://www.unixodbc.org) to define DSNs. * * This version is the setup for Mimer SQL (http://developer.mimer.se). * * Revision 1.1 2004/01/21 per.bengtsson@mimer.se * */ #include #include static const char *vHost[] = { "localhost", NULL }; static const char *vPort[] = { "1360", NULL }; static const char *vUser[] = { "SYSADM", NULL }; static const char *vDescr[] = { "Mimer SQL", NULL }; static const char *vYesNo[] = { "Yes", "No", NULL }; int ODBCINSTGetProperties(HODBCINSTPROPERTY hLastProperty) { /* * Database name */ hLastProperty->pNext = (HODBCINSTPROPERTY)malloc(sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY)); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy(hLastProperty->szName, "Database", INI_MAX_PROPERTY_NAME); strncpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE); hLastProperty->pszHelp = strdup("The name of the Mimer SQL database server"); /* * Host name */ hLastProperty->pNext = (HODBCINSTPROPERTY)malloc(sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY)); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc(sizeof(vHost)); memcpy(hLastProperty->aPromptData, vHost, sizeof(vHost)); strncpy(hLastProperty->szName, "Host", INI_MAX_PROPERTY_NAME); strncpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE); hLastProperty->pszHelp = strdup("Hostname or IP address of computer running the Mimer SQL database server"); /* * Port number */ hLastProperty->pNext = (HODBCINSTPROPERTY)malloc(sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY)); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc(sizeof(vPort)); memcpy(hLastProperty->aPromptData, vPort, sizeof(vPort)); strncpy(hLastProperty->szName, "Port", INI_MAX_PROPERTY_NAME); strncpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE); hLastProperty->pszHelp = strdup("Port number (default is 1360)"); /* * User name */ hLastProperty->pNext = (HODBCINSTPROPERTY)malloc(sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY)); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc(sizeof(vUser)); memcpy(hLastProperty->aPromptData, vUser, sizeof(vUser)); strncpy(hLastProperty->szName, "User", INI_MAX_PROPERTY_NAME); strncpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE); hLastProperty->pszHelp = strdup("Database user to connect as (optional)"); /* * Password */ hLastProperty->pNext = (HODBCINSTPROPERTY)malloc(sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY)); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy(hLastProperty->szName, "Password", INI_MAX_PROPERTY_NAME); strncpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE); hLastProperty->pszHelp = strdup("Password for the database user (optional)"); /* * Trace option */ hLastProperty->pNext = (HODBCINSTPROPERTY)malloc(sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY)); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc(sizeof(vYesNo)); memcpy(hLastProperty->aPromptData, vYesNo, sizeof(vYesNo)); strncpy(hLastProperty->szName, "Trace", INI_MAX_PROPERTY_NAME); strcpy(hLastProperty->szValue, "No"); hLastProperty->pszHelp = strdup("ODBC trace feature (optional)"); /* * Trace file name */ hLastProperty->pNext = (HODBCINSTPROPERTY)malloc(sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY)); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_FILENAME; strncpy(hLastProperty->szName, "TraceFile", INI_MAX_PROPERTY_NAME); strncpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE); hLastProperty->pszHelp = strdup("ODBC trace file name (used if Trace is enabled)"); return 1; } /**************************************************/ unixODBC-2.3.12/DRVConfig/MiniSQL/000077500000000000000000000000001446441710500162555ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/MiniSQL/Makefile.am000066400000000000000000000003311446441710500203060ustar00rootroot00000000000000lib_LTLIBRARIES = libodbcminiS.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) libodbcminiS_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared libodbcminiS_la_SOURCES = odbcminiS.c unixODBC-2.3.12/DRVConfig/MiniSQL/README000066400000000000000000000017361446441710500171440ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. This software is a LinuxODBC component and * * may NOT be distributed seperately. * * * * Peter Harvey 21.FEB.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | LinuxODBC | | Driver Config for MiniSQL ODBC driver | +-------------------------------------------------------------+ Use this Driver Config when using the MiniSQL ODBC Driver. It allows ODBCConfig to prompt the user for Data Source options. ODBCConfig will read the "Setup" entry in /etc/odbcinst.ini to determine the name of the config lib to use. Peter Harvey pharvey@codebydesign.com 10.FEB.99 unixODBC-2.3.12/DRVConfig/MiniSQL/odbcminiS.c000066400000000000000000000041751446441710500203370ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include /********************************************** * HELP **********************************************/ static const char *szHelpHost = "blank is faster than localhost"; /********************************************** * STATIC LOOKUP VALUES **********************************************/ static const char *aHost[] = { "localhost", NULL }; int ODBCINSTGetProperties( HODBCINSTPROPERTY hLastProperty ) { hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof( aHost ) ); memcpy( hLastProperty->aPromptData, aHost, sizeof( aHost ) ); hLastProperty->pszHelp = (char*)strdup( szHelpHost ); strncpy( hLastProperty->szName, "Host", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Database", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_FILENAME; strncpy( hLastProperty->szName, "ConfigFile", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); return 1; } unixODBC-2.3.12/DRVConfig/MySQL/000077500000000000000000000000001446441710500157465ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/MySQL/Makefile.am000066400000000000000000000003211446441710500177760ustar00rootroot00000000000000lib_LTLIBRARIES = libodbcmyS.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) libodbcmyS_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared libodbcmyS_la_SOURCES = odbcmyS.c unixODBC-2.3.12/DRVConfig/MySQL/README000066400000000000000000000017341446441710500166330ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. This software is a LinuxODBC component and * * may NOT be distributed seperately. * * * * Peter Harvey 21.FEB.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | Driver Config for MySQL ODBC driver | +-------------------------------------------------------------+ Use this Driver Config when using the MySQL ODBC Driver. It allows ODBCConfig to prompt the user for Data Source options. ODBCConfig will read the "Setup" entry in /etc/odbcinst.ini to determine the name of the config lib to use. Peter Harvey pharvey@codebydesign.com 19.FEB.99 unixODBC-2.3.12/DRVConfig/MySQL/odbcmyS.c000066400000000000000000000127441446441710500175220ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include /********************************************** * HELP **********************************************/ /********************************************** * STATIC LOOKUP VALUES **********************************************/ static const char *aHost[] = { "localhost", NULL }; static const char *aDatabase[] = { "test", "mysql", NULL }; int ODBCINSTGetProperties( HODBCINSTPROPERTY hLastProperty ) { hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof( aHost ) ); memcpy( hLastProperty->aPromptData, aHost, sizeof( aHost ) ); strncpy( hLastProperty->szName, "Server", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = strdup( "Host name or IP address of the machine running the MySQL server." ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof( aDatabase ) ); memcpy( hLastProperty->aPromptData, aDatabase, sizeof( aDatabase ) ); strncpy( hLastProperty->szName, "Database", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "test", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = strdup( "The database you want to connect to.\nYou can use test or mysql to test this DSN." ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Port", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = strdup( "Port number. Leave blank to accept the default." ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Socket", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = strdup( "Socket number. Leave blank to accept the default." ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Option", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = strdup( "\ Add the desired option values and enter resulting number here...\n\n\ 1 The client can't handle that MyODBC returns the real width of a column.\n \ 2 The client can't handle that MySQL returns the true value of affected rows\n \ 4 Make a debug log. \ 8 Don't set any packet limit for results and parameters.\n \ 16 Don't prompt for questions even if driver would like to prompt\n \ 32 Enable or disable the dynamic cursor support. This is not allowed in MyODBC.\n \ 64 Ignore use of database name in 'database.table.column'.\n \ 128 Force use of ODBC manager cursors (experimental).\n \ 256 Disable the use of extended fetch (experimental).\n \ 512 Pad CHAR fields to full column length.\n \ 1024 SQLDescribeCol() will return fully qualified column names\n \ 2048 Use the compressed server/client protocol\n \ 4096 Tell server to ignore space after function name and before '('\n \ 8192 Connect with named pipes to a mysqld server running on NT.\n \ 16384 Change LONGLONG columns to INT columns\n \ 32768 Return 'user' as Table_qualifier and Table_owner from SQLTables\n \ 65536 Read parameters from the client and odbc groups from `my.cnf'\n \ 131072 Add some extra safety checks (should not bee needed but...)" ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Stmt", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = strdup( "statement to execute upon connect" ); return 1; } unixODBC-2.3.12/DRVConfig/Oracle/000077500000000000000000000000001446441710500162065ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/Oracle/Makefile.am000066400000000000000000000003251446441710500202420ustar00rootroot00000000000000lib_LTLIBRARIES = liboraodbcS.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) liboraodbcS_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared liboraodbcS_la_SOURCES = oraodbcS.c unixODBC-2.3.12/DRVConfig/Oracle/oraodbcS.c000066400000000000000000000076261446441710500201210ustar00rootroot00000000000000/* * This file contains the ODBCINSTGetProperties function required by * unixODBC (http://www.unixodbc.org) to define tds DSNs. * * $Log: oraodbcS.c,v $ * Revision 1.4 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2003/07/21 17:10:09 lurcher * * Start new version and add missing comma to oracle setup * * Revision 1.2 2002/12/20 11:36:46 lurcher * * Update DMEnvAttr code to allow setting in the odbcinst.ini entry * * Revision 1.1.1.1 2001/10/17 16:40:01 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 2000/08/11 12:45:38 ngorham * * Add Oracle setup * */ #include #include static const char *aYesNo[] = { "Yes", "No", NULL }; static char *help_strings[] = { "Name of the server to connect to.", "User name to connect with.", "Password of user.", "Path name of the Oracle version to use.", "Path name of the TNS files." }; int ODBCINSTGetProperties( HODBCINSTPROPERTY hLastProperty) { hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "DB", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[0]) + 1); strcpy(hLastProperty->pszHelp, help_strings[0]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "USER", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[1]) + 1); strcpy(hLastProperty->pszHelp, help_strings[1]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "PASSWORD", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[2]) + 1); strcpy(hLastProperty->pszHelp, help_strings[2]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_FILENAME; strncpy( hLastProperty->szName, "ORACLE_HOME", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[3]) + 1); strcpy(hLastProperty->pszHelp, help_strings[3]); /* Idea for the future: * make the nPromptType an ODBCINST_PROMPTTYPE_COMBOBOX and * present the user with aPromptData containing * the current value of the ORACLE_HOME environment variable * same for TNS_ADMIN below */ hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_FILENAME; strncpy( hLastProperty->szName, "TNS_ADMIN", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[4]) + 1); strcpy(hLastProperty->pszHelp, help_strings[4]); return 1; } unixODBC-2.3.12/DRVConfig/PostgreSQL/000077500000000000000000000000001446441710500170045ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/PostgreSQL/Makefile.am000066400000000000000000000003311446441710500210350ustar00rootroot00000000000000lib_LTLIBRARIES = libodbcpsqlS.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) libodbcpsqlS_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared libodbcpsqlS_la_SOURCES = odbcpsqlS.c unixODBC-2.3.12/DRVConfig/PostgreSQL/README000066400000000000000000000017411446441710500176670ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. This software is a LinuxODBC component and * * may NOT be distributed seperately. * * * * Peter Harvey 21.FEB.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | LinuxODBC | | Driver Config for PostgreSQL ODBC driver | +-------------------------------------------------------------+ Use this Driver Config when using the PostgreSQL ODBC Driver. It allows ODBCConfig to prompt the user for Data Source options. ODBCConfig will read the "Setup" entry in /etc/odbcinst.ini to determine the name of the config lib to use. Peter Harvey pharvey@codebydesign.com 02.FEB.99 unixODBC-2.3.12/DRVConfig/PostgreSQL/odbcpsqlS.c000066400000000000000000000172221446441710500211060ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include /********************************************** * HELP **********************************************/ static const char *szHelpPassword = "Your Password will be used to gain additional information from the DBMS and will not be saved anywhere."; /********************************************** * STATIC LOOKUP VALUES **********************************************/ static const char *aServer[] = { "localhost", NULL }; static const char *aPort[] = { "5432", NULL }; static const char *aProtocol[] = { "6.4", "6.3", "6.2", NULL }; static const char *aYesNo[] = { "Yes", "No", NULL }; static const char *aTrueFalse[] = { "True", "False", NULL }; int ODBCINSTGetProperties( HODBCINSTPROPERTY hLastProperty ) { hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc( sizeof(aYesNo) ); memcpy( hLastProperty->aPromptData, aYesNo, sizeof(aYesNo) ); strncpy( hLastProperty->szName, "Trace", INI_MAX_PROPERTY_NAME ); strcpy( hLastProperty->szValue, "No" ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_FILENAME; strncpy( hLastProperty->szName, "TraceFile", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Database", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof( aServer ) ); memcpy( hLastProperty->aPromptData, aServer, sizeof( aServer ) ); strncpy( hLastProperty->szName, "Servername", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "localhost", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Username", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT_PASSWORD; hLastProperty->pszHelp = (char *)strdup( szHelpPassword ); strncpy( hLastProperty->szName, "Password", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof(aPort) ); memcpy( hLastProperty->aPromptData, aPort, sizeof(aPort) ); strncpy( hLastProperty->szName, "Port", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "5432", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof(aProtocol) ); memcpy( hLastProperty->aPromptData, aProtocol, sizeof(aProtocol) ); strncpy( hLastProperty->szName, "Protocol", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "6.4", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc( sizeof(aYesNo) ); memcpy( hLastProperty->aPromptData, aYesNo, sizeof(aYesNo) ); strncpy( hLastProperty->szName, "ReadOnly", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "No", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc( sizeof(aYesNo) ); memcpy( hLastProperty->aPromptData, aYesNo, sizeof(aYesNo) ); strncpy( hLastProperty->szName, "RowVersioning", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "No", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc( sizeof(aYesNo) ); memcpy( hLastProperty->aPromptData, aYesNo, sizeof(aYesNo) ); strncpy( hLastProperty->szName, "ShowSystemTables", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "No", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc( sizeof(aYesNo) ); memcpy( hLastProperty->aPromptData, aYesNo, sizeof(aYesNo) ); strncpy( hLastProperty->szName, "ShowOidColumn", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "No", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc( sizeof(aYesNo) ); memcpy( hLastProperty->aPromptData, aYesNo, sizeof(aYesNo) ); strncpy( hLastProperty->szName, "FakeOidIndex", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "No", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "ConnSettings", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); return 1; } unixODBC-2.3.12/DRVConfig/README000066400000000000000000000022361446441710500156640ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | DRVConfig | +-------------------------------------------------------------+ These are the setup libs for the various drivers. There are two generic ones; drvcfg1 - SQL servers (host, port etc) drvcfg2 - file based (database dir) These are typically installed into the same directory as the drivers (often /usr/local/lib) and are denoted by a simple naming convention (*S.so). The driver lib and setup lib are key to registering an ODBC driver - a task which is done by a root user. +-------------------------------------------------------------+ | Peter Harvey pharvey@codebydesign.com | | http://www.unixodbc.org | +-------------------------------------------------------------+ unixODBC-2.3.12/DRVConfig/drvcfg1/000077500000000000000000000000001446441710500163355ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/drvcfg1/Makefile.am000066400000000000000000000003401446441710500203660ustar00rootroot00000000000000lib_LTLIBRARIES = libodbcdrvcfg1S.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) libodbcdrvcfg1S_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared libodbcdrvcfg1S_la_SOURCES = drvcfg1.c unixODBC-2.3.12/DRVConfig/drvcfg1/README000066400000000000000000000024731446441710500172230ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | Driver Config for basic SQL Server options | +-------------------------------------------------------------+ This is an example of a driver setup which can be called by ODBC Config to allow the driver specific options to be set. This particular example is for SQL Server type setups and can be used as a substitute for drivers which serve SQL Servers but are missing a driver setup of its own. This is the Driver Config that is used when ODBC Config does not have a specific config for an installed driver. Each driver in /etc/odbcinst.ini should have a Setup entry such as; Setup = /usr/lib/libodbcminiS.so This will allow ODBCConfig to prompt for Data Source options. +-------------------------------------------------------------+ | Peter Harvey pharvey@codebydesign.com | | http://www.unixodbc.org | +-------------------------------------------------------------+ unixODBC-2.3.12/DRVConfig/drvcfg1/drvcfg1.c000066400000000000000000000034251446441710500200410ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 18.FEB.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include static const char *aHost[] = { "localhost", NULL }; int ODBCINSTGetProperties( HODBCINSTPROPERTY hLastProperty ) { hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof( aHost ) ); memcpy( hLastProperty->aPromptData, aHost, sizeof( aHost ) ); strncpy( hLastProperty->szName, "Host", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Database", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Port", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); return 1; } unixODBC-2.3.12/DRVConfig/drvcfg2/000077500000000000000000000000001446441710500163365ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/drvcfg2/ChangeLog000066400000000000000000000001211446441710500201020ustar00rootroot000000000000001999-04-10 Peter Harvey * All: Created ChangeLog unixODBC-2.3.12/DRVConfig/drvcfg2/Makefile.am000066400000000000000000000003401446441710500203670ustar00rootroot00000000000000lib_LTLIBRARIES = libodbcdrvcfg2S.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) libodbcdrvcfg2S_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared libodbcdrvcfg2S_la_SOURCES = drvcfg2.c unixODBC-2.3.12/DRVConfig/drvcfg2/README000066400000000000000000000025331446441710500172210ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * * * * Peter Harvey 21.FEB.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | Driver Config for basic file options | +-------------------------------------------------------------+ This is an example of a driver setup which can be called by ODBC Config to allow the driver specific options to be set. This particular example is for File Based data sources. Each driver in /etc/odbcinst.ini should have a Setup entry such as; Setup = /usr/lib/libodbcminiS.so This will allow ODBCConfig to prompt for Data Source options. +-------------------------------------------------------------+ | Peter Harvey | | pharvey@codebydesign.com | | http://www.genix.net/unixODBC | | 10.APR.99 | +-------------------------------------------------------------+ unixODBC-2.3.12/DRVConfig/drvcfg2/drvcfg2.c000066400000000000000000000021241446441710500200360ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 18.FEB.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include /********************************************** * HELP **********************************************/ /********************************************** * STATIC LOOKUP VALUES **********************************************/ int ODBCINSTGetProperties( HODBCINSTPROPERTY hLastProperty ) { hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_FILENAME; strncpy( hLastProperty->szName, "Database", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); return 1; } unixODBC-2.3.12/DRVConfig/esoob/000077500000000000000000000000001446441710500161105ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/esoob/Makefile.am000066400000000000000000000003151446441710500201430ustar00rootroot00000000000000lib_LTLIBRARIES = libesoobS.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) libesoobS_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared libesoobS_la_SOURCES = esoobS.c unixODBC-2.3.12/DRVConfig/esoob/esoobS.c000066400000000000000000000212121446441710500175040ustar00rootroot00000000000000/* * Copyright (c) 1999 Easysoft Ltd. All rights reserved. * * This file contains the ODBCINSTGetProperties function required by * unixODBC (http://www.unixodbc.org) to define Easysoft ODBC-ODBC Bridge * DSNs. * * $Id: esoobS.c,v 1.2 2009/02/18 17:59:08 lurcher Exp $ * * $Log: esoobS.c,v $ * Revision 1.2 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:01 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.3 2000/06/19 15:54:53 ngorham * * Added DisguiseWide attribute to esoob. * * Revision 1.2 2001/05/27 10:35:18 ngorham * * Added MetaDataBlockFetch connection attribute to esoob driver. * * Revision 1.1 2000/02/20 10:21:08 ngorham * * Setup files for Easysoft ODBC-ODBC Bridge * * Revision 1.4 2000/02/10 17:53:50 martin * Change protocol to transport. * * Revision 1.3 1999/09/06 10:58:55 martin * Add description and copyright. * * Revision 1.2 1999/09/06 10:49:55 martin * Add BlockFetchSize, MetaData_ID_Identifier and Unquote_Catalog_Fns. * * Revision 1.1 1999/09/06 09:44:37 martin * Initial revision * */ #include #include char *help_strings[] = { "Name of the server to connect to.", "Name of the network transport to use.", "Number of the port the server is listening on.", "Name of the remote DSN to connect to.", "Name of the user to log on to server box as.", "Password of the user to log on to server box as.", "Name of the remote database user.", "Password of the remote datbase user.", "Number of rows to bind in Block-Fetch-Mode.", "Remove quotes on catalog functions (Applix's AXData).", "Tell driver to treat strings as literal and treat wildcard " "characters as literals.", "Enable (1) or Disable (0) OOB's metadata blockfetchmode", "Enable (1) or Disable (0) disguise wide characters mode" }; int ODBCINSTGetProperties( HODBCINSTPROPERTY hLastProperty) { hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Server", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[0]) + 1); strcpy(hLastProperty->pszHelp, help_strings[0]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Transport", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "TCP/IP", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[1]) + 1); strcpy(hLastProperty->pszHelp, help_strings[1]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Port", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "8888", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[2]) + 1); strcpy(hLastProperty->pszHelp, help_strings[2]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "TargetDSN", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[3]) + 1); strcpy(hLastProperty->pszHelp, help_strings[3]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "LogonUser", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[4]) + 1); strcpy(hLastProperty->pszHelp, help_strings[4]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "LogonAuth", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[5]) + 1); strcpy(hLastProperty->pszHelp, help_strings[5]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "TargetUser", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[6]) + 1); strcpy(hLastProperty->pszHelp, help_strings[6]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "TargetAuth", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[7]) + 1); strcpy(hLastProperty->pszHelp, help_strings[7]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "BlockFetchSize", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "0", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[8]) + 1); strcpy(hLastProperty->pszHelp, help_strings[8]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Unquote_Catalog_Fns", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "0", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[9]) + 1); strcpy(hLastProperty->pszHelp, help_strings[9]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "MetaData_ID_Identifiers", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "0", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[10]) + 1); strcpy(hLastProperty->pszHelp, help_strings[10]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "MetaDataBlockFetch", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "1", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[11]) + 1); strcpy(hLastProperty->pszHelp, help_strings[11]); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY)); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "DisguiseWide", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "0", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = malloc(strlen(help_strings[12]) + 1); strcpy(hLastProperty->pszHelp, help_strings[12]); return 1; } unixODBC-2.3.12/DRVConfig/nn/000077500000000000000000000000001446441710500154145ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/nn/Makefile.am000066400000000000000000000003201446441710500174430ustar00rootroot00000000000000lib_LTLIBRARIES = libodbcnnS.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) libodbcnnS_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared libodbcnnS_la_SOURCES = drvcfg.c unixODBC-2.3.12/DRVConfig/nn/README000066400000000000000000000021001446441710500162650ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | Driver Config for the Internet News Server (NN) driver | +-------------------------------------------------------------+ This is a driver setup which can be called by ODBC Config to allow the driver specific options to be set for the internet News Server (NN) ODBC driver. Each driver in /etc/odbcinst.ini should have a Setup entry such as; Setup = /usr/lib/libodbcnnS.so This will allow ODBCConfig to prompt for Data Source options. +-------------------------------------------------------------+ | Peter Harvey pharvey@codebydesign.com | | http://www.genix.net/unixODBC | +-------------------------------------------------------------+ unixODBC-2.3.12/DRVConfig/nn/drvcfg.c000066400000000000000000000021251446441710500170330ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 13.MAY.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include static const char *aServer[] = { "localhost", /* put some public news servers here */ NULL }; int ODBCINSTGetProperties( HODBCINSTPROPERTY hLastProperty ) { hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof( aServer ) ); memcpy( hLastProperty->aPromptData, aServer, sizeof( aServer ) ); strncpy( hLastProperty->szName, "Server", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); return 1; } unixODBC-2.3.12/DRVConfig/oplodbc/000077500000000000000000000000001446441710500164235ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/oplodbc/Makefile.am000066400000000000000000000003241446441710500204560ustar00rootroot00000000000000lib_LTLIBRARIES = liboplodbcS.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) liboplodbcS_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared liboplodbcS_la_SOURCES = oplodbc.c unixODBC-2.3.12/DRVConfig/oplodbc/README000066400000000000000000000014601446441710500173040ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. This software is a LinuxODBC component and * * may NOT be distributed seperately. * * * * Peter Harvey 21.FEB.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | LinuxODBC | | Driver Config for OpenLinks ODBC driver | +-------------------------------------------------------------+ Use this Driver Config when using the OpenLink ODBC Driver. Peter Harvey pharvey@codebydesign.com 25.FEB.99 unixODBC-2.3.12/DRVConfig/oplodbc/oplodbc.c000066400000000000000000000161261446441710500202170ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include /********************************************** * HELP **********************************************/ static const char *szHelpDatabase = "Databases on Server. I can try to present a list if Host, Login ID and Password are given."; static const char *szHelpPassword = "Your Password will be used to gain additional information from the DBMS and will not be saved anywhere."; /********************************************** * STATIC LOOKUP VALUES **********************************************/ static const char *aHost[] = { "localhost", NULL }; static const char *aServerType[] = { "DB2", "Informix 5", "Informix 6", "Informix 7", "Ingres 6", "Odbc", "OpenIngres 1", "OpenIngres 2", "Oracle 6", "Oracle 7", "Oracle 8", "Postgres 95", "Progress 63C", "Progress 63E", "Progress 63F", "Progress 72D", "Progress 73A", "Progress 73C", "Progress 73D", "Progress 73E", "Progress 81A", "Progress 82A", "Progress 82C", "Progress 83A", "Progress 90A", "Proxy", "Solid", "Sybase 4", "Sybase 10", "Sybase 11", "SQLServer", "Unify", "Velocis", "Virtuoso", NULL }; static const char *aProtocol[] = { "TCP/IP", NULL }; static const char *aYesNo[] = { "Yes", "No", NULL }; static const char *aTrueFalse[] = { "True", "False", NULL }; int ODBCINSTGetProperties( HODBCINSTPROPERTY hLastProperty ) { hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "ServerOptions", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Options", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; hLastProperty->pszHelp = malloc( strlen(szHelpDatabase)+1 ); strcpy( hLastProperty->pszHelp, szHelpDatabase ); strncpy( hLastProperty->szName, "Database", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof( aHost ) ); memcpy( hLastProperty->aPromptData, aHost, sizeof( aHost ) ); strncpy( hLastProperty->szName, "Host", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "UserName", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT_PASSWORD; hLastProperty->pszHelp = malloc( strlen(szHelpPassword)+1 ); strcpy( hLastProperty->pszHelp, szHelpPassword ); strncpy( hLastProperty->szName, "Password", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof(aServerType) ); memcpy( hLastProperty->aPromptData, aServerType, sizeof(aServerType) ); strncpy( hLastProperty->szName, "ServerType", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof(aProtocol) ); memcpy( hLastProperty->aPromptData, aProtocol, sizeof(aProtocol) ); strncpy( hLastProperty->szName, "Protocol", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "LastUser", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc( sizeof(aYesNo) ); memcpy( hLastProperty->aPromptData, aYesNo, sizeof(aYesNo) ); strncpy( hLastProperty->szName, "ReadOnly", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc( sizeof(aTrueFalse) ); memcpy( hLastProperty->aPromptData, aTrueFalse, sizeof(aTrueFalse) ); strncpy( hLastProperty->szName, "NoLoginBox", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "FetchBufferSize", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); return 1; } unixODBC-2.3.12/DRVConfig/sapdb/000077500000000000000000000000001446441710500160725ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/sapdb/Makefile.am000066400000000000000000000003401446441710500201230ustar00rootroot00000000000000lib_LTLIBRARIES = libsapdbS.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) libsapdbS_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared libsapdbS_la_SOURCES = sapdb.c EXTRA_DIST = README unixODBC-2.3.12/DRVConfig/sapdb/README000066400000000000000000000023321446441710500167520ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | Driver Config for SAP DB SQL Server options | +-------------------------------------------------------------+ SAP DB awaits it's odbc.ini file in /usr/spool/sql/config/odbc.ini. That's weird enought, because it's not even FHS (that would be /var/spool/...) There are two ways you can fix this: - Edit the libsqlod.so file - make a symlink from /usr/spool/sql/config/odbc.ini to /etc/odbc.ini Also note that currently (09-Mar-2001) unixODBC crashes when you use the libsqlod from the sapdb-srv or sapdb-if RPM packages. If you use the one from the sapdb-web RPM, then it works. +-------------------------------------------------------------+ | Holger Schurig holgerschurig@gmx.de | | http://home.nikocity.de/hschurig | +-------------------------------------------------------------+ unixODBC-2.3.12/DRVConfig/sapdb/sapdb.c000066400000000000000000000060411446441710500173300ustar00rootroot00000000000000/************************************************** * This code was created by Holger Schurig @ mn-logistik.de. * Released under LGPL 08.MAR.2001 * * Additional MaxDB ODBC properties added by * Martin Kittel , 08.05.2005 * ----------------------------------------------- **************************************************/ #include #include static const char *aHost[] = { "localhost", NULL }; static const char *aSqlModes[] = { "INTERNAL", "ORACLE", "ANSI", "DB2", NULL }; static const char *aIsoLevel[] = { "Uncommitted", "Committed", "Repeatable", "Serializable", NULL }; int ODBCINSTGetProperties( HODBCINSTPROPERTY hLastProperty ) { hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "ServerNode", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "localhost", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "ServerDB", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof( aSqlModes ) ); memcpy( hLastProperty->aPromptData, aSqlModes, sizeof( aSqlModes ) ); strncpy( hLastProperty->szName, "SQLMode", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "INTERNAL", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof( aIsoLevel ) ); memcpy( hLastProperty->aPromptData, aIsoLevel, sizeof( aIsoLevel ) ); strncpy( hLastProperty->szName, "IsolationLevel", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "Committed", INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_FILENAME; strncpy( hLastProperty->szName, "TraceFileName", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); return 1; } unixODBC-2.3.12/DRVConfig/tds/000077500000000000000000000000001446441710500155735ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/tds/Makefile.am000066400000000000000000000003051446441710500176250ustar00rootroot00000000000000lib_LTLIBRARIES = libtdsS.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) libtdsS_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared libtdsS_la_SOURCES = tdsS.c unixODBC-2.3.12/DRVConfig/tds/tdsS.c000066400000000000000000000066161446441710500166650ustar00rootroot00000000000000/* * This file contains the ODBCINSTGetProperties function required by * unixODBC (http://www.unixodbc.org) to define tds DSNs. * * This may be used for the FreeTDS driver or some other driver so * be careful about removing any properties. - PAH * * $Log: tdsS.c,v $ * Revision 1.4 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2003/11/13 15:12:53 lurcher * * small change to ODBCConfig to have the password field in the driver * properties hide the password * Make both # and ; comments in ini files * * Revision 1.2 2002/02/22 17:27:20 peteralexharvey * - * * Revision 1.1.1.1 2001/10/17 16:40:01 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 2000/07/09 22:17:52 ngorham * * Added tds setup lib * */ #include #include static const char *aYesNo[] = { "Yes", "No", NULL }; int ODBCINSTGetProperties( HODBCINSTPROPERTY hLastProperty) { hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Servername", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = (char*)strdup( "Name of server to connect to. This should\nmatch the name used in the interfaces\nor freetds.conf file." ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Database", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = (char*)strdup( "Default database" ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "UID", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = (char*)strdup( "User ID" ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT_PASSWORD; strncpy( hLastProperty->szName, "PWD", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = (char*)strdup( "Password" ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Port", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "4100", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = (char*)strdup( "Port to connect to (some drivers do not use)" ); return 1; } unixODBC-2.3.12/DRVConfig/template/000077500000000000000000000000001446441710500166145ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/template/Makefile.am000066400000000000000000000000001446441710500206360ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/template/README000066400000000000000000000020331446441710500174720ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. This software is a LinuxODBC component and * * may NOT be distributed seperately. * * * * Peter Harvey 21.FEB.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | LinuxODBC | | Driver Config template | +-------------------------------------------------------------+ A Driver Config is too simple. So simple in fact that it would be pointless to create a real template. So go to a working Driver Config and check it out. I recommend starting with; 1. drvcfg1 - basics for an SQL Server type data source 2. drvcfg2 - basics for a File type data source Enjoy... Peter Harvey pharvey@codebydesign.com 25.FEB.99 unixODBC-2.3.12/DRVConfig/txt/000077500000000000000000000000001446441710500156205ustar00rootroot00000000000000unixODBC-2.3.12/DRVConfig/txt/Makefile.am000066400000000000000000000003231446441710500176520ustar00rootroot00000000000000lib_LTLIBRARIES = libodbctxtS.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) libodbctxtS_la_LDFLAGS = -module -no-undefined -version-info 1:0:0 -avoid-version -shared libodbctxtS_la_SOURCES = drvcfg.c unixODBC-2.3.12/DRVConfig/txt/README000066400000000000000000000017061446441710500165040ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | Driver Config for the Text File Driver | +-------------------------------------------------------------+ This is a driver setup which can be called by ODBC Config to allow the driver specific options to be set for the Text File Driver. This will allow ODBCConfig to prompt for Data Source options. +-------------------------------------------------------------+ | Peter Harvey pharvey@codebydesign.com | | http://www.unixodbc.org | +-------------------------------------------------------------+ unixODBC-2.3.12/DRVConfig/txt/drvcfg.c000066400000000000000000000071351446441710500172450ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 10.APR.01 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include /********************************************** * HELP **********************************************/ /********************************************** * STATIC LOOKUP VALUES **********************************************/ static const char *aColumnSeparators[] = { "|", ",", NULL }; static const char *aYesNo[] = { "Yes", "No", NULL }; int ODBCINSTGetProperties( HODBCINSTPROPERTY hLastProperty ) { hLastProperty->pNext = (HODBCINSTPROPERTY)calloc( 1, sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; strncpy( hLastProperty->szName, "Directory", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = strdup( "Directory where table files can/will be found.\nLeave blank for default (~/.odbctxt)." ); hLastProperty->pNext = (HODBCINSTPROPERTY)calloc( 1, sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc( sizeof( aYesNo ) ); memcpy( hLastProperty->aPromptData, aYesNo, sizeof( aYesNo ) ); strncpy( hLastProperty->szName, "ReadOnly", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "No", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = strdup( "Set this to Yes if you do not want anyone changing the data." ); hLastProperty->pNext = (HODBCINSTPROPERTY)calloc( 1, sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc( sizeof( aYesNo ) ); memcpy( hLastProperty->aPromptData, aYesNo, sizeof( aYesNo ) ); strncpy( hLastProperty->szName, "CaseSensitive", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "Yes", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = strdup( "Yes if data is compared as case-sensitive." ); hLastProperty->pNext = (HODBCINSTPROPERTY)calloc( 1, sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc( sizeof( aYesNo ) ); memcpy( hLastProperty->aPromptData, aYesNo, sizeof( aYesNo ) ); strncpy( hLastProperty->szName, "Catalog", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "No", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = strdup( "Yes if you want to use a special file to describe all tables/columns.\n\nNo if column names on the first row are enough." ); hLastProperty->pNext = (HODBCINSTPROPERTY)calloc( 1, sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX; hLastProperty->aPromptData = malloc( sizeof( aColumnSeparators ) ); memcpy( hLastProperty->aPromptData, aColumnSeparators, sizeof( aColumnSeparators ) ); strncpy( hLastProperty->szName, "ColumnSeparators", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "|", INI_MAX_PROPERTY_VALUE ); hLastProperty->pszHelp = strdup( "Column separator character used in table files.\nCANNOT EXIST IN COLUMN VALUES." ); return 1; } unixODBC-2.3.12/DriverManager/000077500000000000000000000000001446441710500157465ustar00rootroot00000000000000unixODBC-2.3.12/DriverManager/ChangeLog000066400000000000000000000013541446441710500175230ustar00rootroot000000000000001999-05-19 Peter Harvey * ALL: Added logging for Top and Bottom of funcs... errors still need to go to log * ALL: numcols now calced for catalog funcs 1999-05-10 Peter Harvey * SQLPrepare: Code, here and elsewhere, dependent upon num result cols being known before execute has been commented out. * SQLConnect: Used to try to search-a-path for DSN but now lets odbcinst do this. 1999-05-09 Nick Gorham * ALL: Total rewrite by Nick. Has much more functionality and compliance. 1999-04-14 Peter Harvey * sqltypes.h: Changed ODBCINT64 to long long 1999-03-30 Peter Harvey * SQLDrivers.c: added unixODBC-2.3.12/DriverManager/DriverManager.exp000066400000000000000000000047251446441710500212220ustar00rootroot00000000000000SQLAllocConnect SQLAllocEnv SQLAllocHandle SQLAllocHandleStd SQLAllocStmt SQLBindCol SQLBindParam SQLBindParameter SQLBrowseConnect SQLBrowseConnectW SQLBrowseConnectA SQLBulkOperations SQLCancel SQLCancelHandle SQLCloseCursor SQLColAttribute SQLColAttributeW SQLColAttributeA SQLColAttributes SQLColAttributesW SQLColAttributesA SQLColumnPrivileges SQLColumnPrivilegesW SQLColumnPrivilegesA SQLColumns SQLColumnsW SQLColumnsA SQLConnect SQLConnectW SQLConnectA SQLCopyDesc SQLDataSources SQLDataSourcesW SQLDataSourcesA SQLDescribeCol SQLDescribeColW SQLDescribeColA SQLDescribeParam SQLDisconnect SQLDriverConnect SQLDriverConnectW SQLDriverConnectA SQLDrivers SQLDriversW SQLDriversA SQLEndTran SQLError SQLErrorW SQLErrorA SQLExecDirect SQLExecDirectW SQLExecDirectA SQLExecute SQLExtendedFetch SQLFetch SQLFetchScroll SQLForeignKeys SQLForeignKeysW SQLForeignKeysA SQLFreeConnect SQLFreeEnv SQLFreeHandle SQLFreeStmt SQLGetConnectAttr SQLGetConnectAttrW SQLGetConnectAttrA SQLGetConnectOption SQLGetConnectOptionW SQLGetConnectOptionA SQLGetCursorName SQLGetCursorNameW SQLGetCursorNameA SQLGetData SQLGetDescField SQLGetDescFieldW SQLGetDescFieldA SQLGetDescRec SQLGetDescRecW SQLGetDescRecA SQLGetDiagField SQLGetDiagFieldW SQLGetDiagFieldA SQLGetDiagRec SQLGetDiagRecW SQLGetDiagRecA SQLGetEnvAttr SQLGetFunctions SQLGetInfo SQLGetInfoW SQLGetInfoA SQLGetStmtAttr SQLGetStmtAttrW SQLGetStmtAttrA SQLGetStmtOption SQLGetTypeInfo SQLGetTypeInfoW SQLGetTypeInfoA SQLMoreResults SQLNativeSql SQLNativeSqlW SQLNativeSqlA SQLNumParams SQLNumResultCols SQLParamData SQLParamOptions SQLPrepare SQLPrepareW SQLPrepareA SQLPrimaryKeys SQLPrimaryKeysW SQLPrimaryKeysA SQLProcedureColumns SQLProcedureColumnsW SQLProcedureColumnsA SQLProcedures SQLProceduresW SQLProceduresA SQLPutData SQLRowCount SQLSetConnectAttr SQLSetConnectAttrW SQLSetConnectAttrA SQLSetConnectOption SQLSetConnectOptionW SQLSetConnectOptionA SQLSetCursorName SQLSetCursorNameW SQLSetCursorNameA SQLSetDescField SQLSetDescFieldW SQLSetDescFieldA SQLSetDescRec SQLSetEnvAttr SQLSetParam SQLSetPos SQLSetScrollOptions SQLSetStmtAttr SQLSetStmtAttrW SQLSetStmtAttrA SQLSetStmtOption SQLSetStmtOptionA SQLSetStmtOptionW SQLSpecialColumns SQLSpecialColumnsW SQLSpecialColumnsA SQLStatistics SQLStatisticsW SQLStatisticsA SQLTablePrivileges SQLTablePrivilegesW SQLTablePrivilegesA SQLTables SQLTablesW SQLTablesA SQLTransact ODBCSharedTraceFlag uodbc_open_stats uodbc_close_stats uodbc_get_stats uodbc_stats_error ODBCSetTryWaitValue ODBCGetTryWaitValue unixODBC-2.3.12/DriverManager/Makefile.am000066400000000000000000000057671446441710500200210ustar00rootroot00000000000000lib_LTLIBRARIES = libodbc.la AM_CPPFLAGS = -I@top_srcdir@/include \ $(LTDLINCL) EXTRA_DIST = \ drivermanager.h \ DriverManager.exp \ __stats.h \ drivermanager_axp.opt libodbc_la_LIBADD = \ ../lst/liblstlc.la \ ../log/libloglc.la \ ../ini/libinilc.la \ ../odbcinst/libodbcinstlc.la \ $(LIBLTDL) \ $(LIBICONV) libodbc_la_LDFLAGS = \ -version-info @LIB_VERSION@ \ -no-undefined \ -export-dynamic \ -export-symbols @srcdir@/DriverManager.exp libodbc_la_DEPENDENCIES = $(LTDLDEPS) \ ../lst/liblstlc.la \ ../log/libloglc.la \ ../ini/libinilc.la \ ../odbcinst/libodbcinstlc.la libodbc_la_SOURCES = \ SQLAllocConnect.c \ SQLAllocEnv.c \ SQLAllocHandle.c \ SQLAllocHandleStd.c \ SQLAllocStmt.c \ SQLBindCol.c \ SQLBindParam.c \ SQLBindParameter.c \ SQLBrowseConnect.c \ SQLBulkOperations.c \ SQLCancel.c \ SQLCancelHandle.c \ SQLCloseCursor.c \ SQLColAttribute.c \ SQLColAttributes.c \ SQLColumnPrivileges.c \ SQLColumns.c \ SQLConnect.c \ SQLCopyDesc.c \ SQLDataSources.c \ SQLDescribeCol.c \ SQLDescribeParam.c \ SQLDisconnect.c \ SQLDriverConnect.c \ SQLDrivers.c \ SQLEndTran.c \ SQLError.c \ SQLExecDirect.c \ SQLExecute.c \ SQLExtendedFetch.c \ SQLFetch.c \ SQLFetchScroll.c \ SQLForeignKeys.c \ SQLFreeConnect.c \ SQLFreeEnv.c \ SQLFreeHandle.c \ SQLFreeStmt.c \ SQLGetConnectAttr.c \ SQLGetConnectOption.c \ SQLGetCursorName.c \ SQLGetData.c \ SQLGetDescField.c \ SQLGetDescRec.c \ SQLGetDiagField.c \ SQLGetDiagRec.c \ SQLGetEnvAttr.c \ SQLGetFunctions.c \ SQLGetInfo.c \ SQLGetStmtAttr.c \ SQLGetStmtOption.c \ SQLGetTypeInfo.c \ SQLMoreResults.c \ SQLNativeSql.c \ SQLNumParams.c \ SQLNumResultCols.c \ SQLParamData.c \ SQLParamOptions.c \ SQLPrepare.c \ SQLPrimaryKeys.c \ SQLProcedureColumns.c \ SQLProcedures.c \ SQLPutData.c \ SQLRowCount.c \ SQLSetConnectAttr.c \ SQLSetConnectOption.c \ SQLSetCursorName.c \ SQLSetDescField.c \ SQLSetDescRec.c \ SQLSetEnvAttr.c \ SQLSetParam.c \ SQLSetPos.c \ SQLSetScrollOptions.c \ SQLSetStmtAttr.c \ SQLSetStmtOption.c \ SQLSpecialColumns.c \ SQLStatistics.c \ SQLTablePrivileges.c \ SQLTables.c \ SQLTransact.c \ SQLBrowseConnectW.c \ SQLColAttributeW.c \ SQLColAttributesW.c \ SQLColumnPrivilegesW.c \ SQLColumnsW.c \ SQLConnectW.c \ SQLDataSourcesW.c \ SQLDescribeColW.c \ SQLDriverConnectW.c \ SQLDriversW.c \ SQLErrorW.c \ SQLExecDirectW.c \ SQLForeignKeysW.c \ SQLGetConnectAttrW.c \ SQLGetConnectOptionW.c \ SQLGetCursorNameW.c \ SQLGetDescFieldW.c \ SQLGetDescRecW.c \ SQLGetDiagFieldW.c \ SQLGetDiagRecW.c \ SQLGetInfoW.c \ SQLGetStmtAttrW.c \ SQLGetTypeInfoW.c \ SQLNativeSqlW.c \ SQLPrepareW.c \ SQLPrimaryKeysW.c \ SQLProcedureColumnsW.c \ SQLProceduresW.c \ SQLSetConnectAttrW.c \ SQLSetConnectOptionW.c \ SQLSetCursorNameW.c \ SQLSetDescFieldW.c \ SQLSetStmtAttrW.c \ SQLSetStmtOptionW.c \ SQLSpecialColumnsW.c \ SQLStatisticsW.c \ SQLTablePrivilegesW.c \ SQLTablesW.c \ __connection.c \ __handles.c \ __info.c \ __stats.c \ __attribute.c unixODBC-2.3.12/DriverManager/SQLAllocConnect.c000066400000000000000000000057551446441710500210520ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLAllocConnect.c,v 1.2 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLAllocConnect.c,v $ * Revision 1.2 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:03 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/07/04 21:05:06 ngorham * * Add LGPL Headers to code * * Revision 1.1.1.1 1999/05/29 13:41:04 sShandyb * first go at it * * Revision 1.4 1999/06/02 23:48:45 ngorham * * Added more 3-2 mapping * * * Revision 1.3 1999/06/02 20:01:00 ngorham * * Attempt to fix previous botched log message * * Revision 1.2 1999/06/02 19:57:20 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.1 1999/04/25 23:02:41 nick * Initial revision * * **********************************************************************/ #include #ifdef __cplusplus #error "This code must be compiled with a C compiler," #error "not a C++ one, this is due in part to Microsoft" #error "defining SQLCHAR as unsigned, this means all the" #error "standard library code confilicts." #error "" #error "Alter the compiler line in Common.mk to ecgs or" #error "gcc and remake. This will correctly compile" #error "the C++ elements" #error "" #endif #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLAllocConnect.c,v $ $Revision: 1.2 $"; SQLRETURN SQLAllocConnect( SQLHENV environment_handle, SQLHDBC *connection_handle ) { return __SQLAllocHandle( SQL_HANDLE_DBC, environment_handle, connection_handle, SQL_OV_ODBC2 ); } unixODBC-2.3.12/DriverManager/SQLAllocEnv.c000066400000000000000000000042531446441710500202010ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLAllocEnv.c,v 1.2 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLAllocEnv.c,v $ * Revision 1.2 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:03 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/07/04 21:05:06 ngorham * * Add LGPL Headers to code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.1 1999/04/25 23:02:41 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLAllocEnv.c,v $ $Revision: 1.2 $"; SQLRETURN SQLAllocEnv( SQLHENV *environment_handle ) { return __SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HENV, environment_handle, SQL_OV_ODBC2 ); } unixODBC-2.3.12/DriverManager/SQLAllocHandle.c000066400000000000000000001341161446441710500206460ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLAllocHandle.c,v 1.13 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLAllocHandle.c,v $ * Revision 1.13 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.12 2007/12/17 13:13:03 lurcher * Fix a couple of descriptor typo's * * Revision 1.11 2007/02/12 11:49:34 lurcher * Add QT4 support to existing GUI parts * * Revision 1.10 2006/06/28 08:08:41 lurcher * Add timestamp with timezone to Postgres7.1 driver * * Revision 1.9 2005/11/21 17:25:43 lurcher * A few DM fixes for Oracle's ODBC driver * * Revision 1.8 2005/11/08 09:37:10 lurcher * Allow the driver and application to have different length handles * * Revision 1.7 2005/10/06 08:50:58 lurcher * Fix problem with SQLDrivers not returning first entry * * Revision 1.6 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2003/02/25 13:28:21 lurcher * * Allow errors on the drivers AllocHandle to be reported * Fix a problem that caused errors to not be reported in the log * Remove a redundant line from the spec file * * Revision 1.4 2002/12/12 18:21:21 lurcher * * Fix bug where if a SQLAllocHandle in the driver failed, the driver manager * seg faulted * * Revision 1.3 2002/08/12 13:17:52 lurcher * * Replicate the way the MS DM handles loading of driver libs, and allocating * handles in the driver. usage counting in the driver means that dlopen is * only called for the first use, and dlclose for the last. AllocHandle for * the driver environment is only called for the first time per driver * per application environment. * * Revision 1.2 2002/07/25 09:30:26 lurcher * * Additional unicode and iconv changes * * Revision 1.1.1.1 2001/10/17 16:40:03 lurcher * * First upload to SourceForge * * Revision 1.13 2001/09/27 17:05:48 nick * * Assorted fixes and tweeks * * Revision 1.12 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * Revision 1.11 2001/08/03 15:19:00 nick * * Add changes to set values before connect * * Revision 1.10 2001/07/31 12:03:46 nick * * Fix how the DM gets the CLI year for SQLGetInfo * Fix small bug in strncasecmp * * Revision 1.9 2001/06/04 15:24:49 nick * * Add port to MAC OSX and QT3 changes * * Revision 1.8 2001/05/15 13:33:44 jason * * Wrapped calls to stats with COLLECT_STATS * * Revision 1.7 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.6 2000/12/18 11:03:58 martin * * Add support for the collection and retrieval of handle statistics. * * Revision 1.5 2000/12/14 18:10:18 nick * * Add connection pooling * * Revision 1.4 2000/11/22 19:03:40 nick * * Fix problem with error status in SQLSpecialColumns * * Revision 1.3 2000/11/22 18:35:43 nick * * Check input handle before touching output handle * * Revision 1.2 2000/11/14 10:15:27 nick * * Add test for localtime_r * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.19 2000/06/21 11:07:35 ngorham * * Stop Errors from SQLAllocHandle being lost * * Revision 1.18 2000/05/22 17:10:34 ngorham * * Fix problems with the FetchScroll -> ExtendedFetch Mapping * * Revision 1.17 2000/05/21 21:49:18 ngorham * * Assorted fixes * * Revision 1.16 2001/04/27 01:29:35 ngorham * * Added a couple of fixes from Tim Roepken * * Revision 1.15 2000/01/03 14:24:01 ngorham * * Fix bug where a failed alloc of a statement would dump core * * Revision 1.14 2000/01/01 18:21:16 ngorham * * Fix small bug where a invalid input handle to SQLAllocHandle can cause * a seg fault. * * Revision 1.13 1999/12/01 09:20:07 ngorham * * Fix some threading problems * * Revision 1.12 1999/11/15 21:42:52 ngorham * * Remove some debug info * * Revision 1.11 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.10 1999/11/10 03:51:33 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.9 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.8 1999/10/20 23:01:41 ngorham * * Fixed problem with the connection counting * * Revision 1.7 1999/09/26 18:55:03 ngorham * * Fixed a problem where the cursor lib was being used by default * * Revision 1.6 1999/09/21 22:34:23 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.5 1999/09/19 22:24:33 ngorham * * Added support for the cursor library * * Revision 1.4 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:06 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:20 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.4 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.3 1999/05/03 19:50:43 nick * Another check point * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:02:41 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) #include "__stats.h" #include #endif static char const rcsid[]= "$RCSfile: SQLAllocHandle.c,v $ $Revision: 1.13 $"; /* * connection pooling stuff */ extern int pooling_enabled; extern int pool_max_size; extern int pool_wait_timeout; /* * this is used so that it can be called without falling * fowl of any other instances in any other modules. */ SQLRETURN __SQLAllocHandle( SQLSMALLINT handle_type, SQLHANDLE input_handle, SQLHANDLE *output_handle, SQLINTEGER requested_version ) { switch( handle_type ) { case SQL_HANDLE_ENV: case SQL_HANDLE_SENV: { DMHENV environment; char pooling_string[ 128 ]; char pool_max_size_string [ 128 ]; char pool_wait_timeout_string [ 128 ]; if ( !output_handle ) { return SQL_ERROR; } if ( input_handle ) { return SQL_INVALID_HANDLE; } /* * check connection pooling attributes */ SQLGetPrivateProfileString( "ODBC", "Pooling", "0", pooling_string, sizeof( pooling_string ), "ODBCINST.INI" ); if ( pooling_string[ 0 ] == '1' || toupper( pooling_string[ 0 ] ) == 'Y' || ( toupper( pooling_string[ 0 ] ) == 'O' && toupper( pooling_string[ 1 ] ) == 'N' )) { pooling_enabled = 1; } #ifdef WITH_SHARDENV if ( pooling_enabled ) { int first; SQLGetPrivateProfileString( "ODBC", "PoolMaxSize", "0", pool_max_size_string, sizeof( pool_max_size_string ), "ODBCINST.INI" ); pool_max_size = atoi( pool_max_size_string ); SQLGetPrivateProfileString( "ODBC", "PoolWaitTimeout", "30", pool_wait_timeout_string, sizeof( pool_wait_timeout_string ), "ODBCINST.INI" ); pool_wait_timeout = atoi( pool_wait_timeout_string ); if ( !( environment = __share_env( &first ))) { *output_handle = SQL_NULL_HENV; return SQL_ERROR; } *output_handle = (SQLHANDLE) environment; if ( first ) { /* * setup environment state */ environment -> state = STATE_E1; environment -> requested_version = requested_version; environment -> version_set = !!requested_version; environment -> sql_driver_count = -1; /* * if SQLAllocEnv is called then it's probable that * the application wants ODBC2.X type behaviour * * In this case we don't need to set the version via * SQLSetEnvAttr() * */ environment -> connection_count = 0; } } else { if ( !( environment = __alloc_env())) { *output_handle = SQL_NULL_HENV; return SQL_ERROR; } *output_handle = (SQLHANDLE) environment; /* * setup environment state */ environment -> state = STATE_E1; environment -> requested_version = requested_version; environment -> version_set = !!requested_version; environment -> sql_driver_count = -1; /* * if SQLAllocEnv is called then it's probable that * the application wants ODBC2.X type behaviour * * In this case we don't need to set the version via * SQLSetEnvAttr() * */ environment -> connection_count = 0; } #else if ( pooling_enabled ) { int first; SQLGetPrivateProfileString( "ODBC", "PoolMaxSize", "0", pool_max_size_string, sizeof( pool_max_size_string ), "ODBCINST.INI" ); pool_max_size = atoi( pool_max_size_string ); SQLGetPrivateProfileString( "ODBC", "PoolWaitTimeout", "30", pool_wait_timeout_string, sizeof( pool_wait_timeout_string ), "ODBCINST.INI" ); pool_wait_timeout = atoi( pool_wait_timeout_string ); } if ( !( environment = __alloc_env())) { *output_handle = SQL_NULL_HENV; return SQL_ERROR; } *output_handle = (SQLHANDLE) environment; /* * setup environment state */ environment -> state = STATE_E1; environment -> requested_version = requested_version; environment -> version_set = !!requested_version; environment -> sql_driver_count = -1; /* * if SQLAllocEnv is called then it's probable that * the application wants ODBC2.X type behaviour * * In this case we don't need to set the version via * SQLSetEnvAttr() * */ environment -> connection_count = 0; #endif return SQL_SUCCESS; } break; case SQL_HANDLE_DBC: { DMHENV environment = (DMHENV) input_handle; DMHDBC connection; if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } if ( output_handle ) *output_handle = SQL_NULL_HDBC; thread_protect( SQL_HANDLE_ENV, environment ); function_entry(( void * ) input_handle ); if ( log_info.log_flag ) { /* * log that we are here */ sprintf( environment -> msg, "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p", handle_type, (void*)input_handle ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } if ( !output_handle ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &environment -> error, ERROR_HY009, NULL, SQL_OV_ODBC3 ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } /* * check that a version has been requested */ if ( environment -> requested_version == 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &environment -> error, ERROR_HY010, NULL, SQL_OV_ODBC3 ); *output_handle = SQL_NULL_HDBC; return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } connection = __alloc_dbc(); if ( !connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY013" ); __post_internal_error( &environment -> error, ERROR_HY013, NULL, environment -> requested_version ); *output_handle = SQL_NULL_HDBC; return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } /* * sort out the states */ connection -> state = STATE_C2; if ( environment -> state == STATE_E1 ) { environment -> state = STATE_E2; } environment -> connection_count ++; connection -> environment = environment; connection -> cursors = SQL_CUR_DEFAULT; connection -> login_timeout = SQL_LOGIN_TIMEOUT_DEFAULT; connection -> login_timeout_set = 0; connection -> auto_commit = SQL_AUTOCOMMIT_ON; connection -> auto_commit_set = 0; connection -> async_enable = 0; connection -> async_enable_set = 0; connection -> auto_ipd = 0; connection -> auto_ipd_set = 0; connection -> connection_timeout = 0; connection -> connection_timeout_set = 0; connection -> metadata_id = 0; connection -> metadata_id_set = 0; connection -> packet_size = 0; connection -> packet_size_set = 0; connection -> quite_mode = 0; connection -> quite_mode_set = 0; connection -> txn_isolation = 0; connection -> txn_isolation_set = 0; strcpy( connection -> cli_year, "1995" ); connection -> env_attribute.count = 0; connection -> env_attribute.list = NULL; connection -> dbc_attribute.count = 0; connection -> dbc_attribute.list = NULL; connection -> stmt_attribute.count = 0; connection -> stmt_attribute.list = NULL; connection -> save_attr = NULL; #ifdef HAVE_ICONV connection -> iconv_cd_uc_to_ascii = (iconv_t)-1; connection -> iconv_cd_ascii_to_uc = (iconv_t)-1; strcpy( connection -> unicode_string, DEFAULT_ICONV_ENCODING ); #endif *output_handle = (SQLHANDLE) connection; if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tExit:[SQL_SUCCESS]\n\t\t\tOutput Handle = %p", connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) uodbc_update_stats(environment->sh, UODBC_STATS_TYPE_HDBC, (void *)1); #endif thread_release( SQL_HANDLE_ENV, environment ); return SQL_SUCCESS; } break; case SQL_HANDLE_STMT: { SQLRETURN ret, ret1; DMHDBC connection = (DMHDBC) input_handle; DMHSTMT statement; if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } if ( output_handle ) *output_handle = SQL_NULL_HSTMT; thread_protect( SQL_HANDLE_DBC, connection ); function_entry(( void * ) input_handle ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p", handle_type, (void*)input_handle ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } if ( !output_handle ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &connection -> error, ERROR_HY009, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection , SQL_ERROR ); } if ( connection -> state == STATE_C1 || connection -> state == STATE_C2 || connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); *output_handle = SQL_NULL_HSTMT; return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } statement = __alloc_stmt(); if ( !statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY013" ); __post_internal_error( &connection -> error, ERROR_HY013, NULL, connection -> environment -> requested_version ); *output_handle = SQL_NULL_HSTMT; return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * pass the call on */ if ( requested_version >= SQL_OV_ODBC3 ) { if ( CHECK_SQLALLOCHANDLE( connection )) { ret = SQLALLOCHANDLE( connection, SQL_HANDLE_STMT, connection -> driver_dbc, &statement -> driver_stmt, statement ); if ( !SQL_SUCCEEDED( ret )) __release_stmt( statement ); } else if ( CHECK_SQLALLOCSTMT( connection )) { ret = SQLALLOCSTMT( connection, connection -> driver_dbc, &statement -> driver_stmt, statement ); if ( !SQL_SUCCEEDED( ret )) __release_stmt( statement ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM003" ); __post_internal_error( &connection -> error, ERROR_IM003, NULL, connection -> environment -> requested_version ); __release_stmt( statement ); *output_handle = SQL_NULL_HSTMT; return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { if ( CHECK_SQLALLOCSTMT( connection )) { ret = SQLALLOCSTMT( connection, connection -> driver_dbc, &statement -> driver_stmt, statement ); if ( !SQL_SUCCEEDED( ret )) __release_stmt( statement ); } else if ( CHECK_SQLALLOCHANDLE( connection )) { ret = SQLALLOCHANDLE( connection, SQL_HANDLE_STMT, connection -> driver_dbc, &statement -> driver_stmt, statement ); if ( !SQL_SUCCEEDED( ret )) __release_stmt( statement ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM003" ); __post_internal_error( &connection -> error, ERROR_IM003, NULL, connection -> environment -> requested_version ); __release_stmt( statement ); *output_handle = SQL_NULL_HSTMT; return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } if ( SQL_SUCCEEDED( ret )) { /* * sort out the states */ statement -> state = STATE_S1; if ( connection -> state == STATE_C4 ) connection -> state = STATE_C5; __register_stmt ( connection, statement ); *output_handle = (SQLHANDLE) statement; statement -> metadata_id = SQL_FALSE; /* * if we are connected to a 3 driver then * we need to get the 4 implicit descriptors * so we know that they are valid */ if ( connection -> driver_act_ver == 3 && CHECK_SQLGETSTMTATTR( connection )) { DRV_SQLHDESC desc; /* * ARD */ ret1 = SQLGETSTMTATTR( connection, statement -> driver_stmt, SQL_ATTR_APP_ROW_DESC, &desc, sizeof( desc ), NULL ); if ( SQL_SUCCEEDED( ret1 )) { /* * allocate one of our descriptors * to wrap around this */ statement -> ard = __alloc_desc(); if ( !statement -> ard ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY013" ); __post_internal_error( &connection -> error, ERROR_HY013, NULL, connection -> environment -> requested_version ); __release_stmt( statement ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R1 ); } statement -> implicit_ard = statement -> ard; statement -> ard -> implicit = 1; statement -> ard -> associated_with = statement; statement -> ard -> state = STATE_D1i; statement -> ard -> driver_desc = desc; statement -> ard -> connection = connection; } /* * APD */ ret1 = SQLGETSTMTATTR( connection, statement -> driver_stmt, SQL_ATTR_APP_PARAM_DESC, &desc, sizeof( desc ), NULL ); if ( SQL_SUCCEEDED( ret1 )) { /* * allocate one of our descriptors * to wrap around this */ statement -> apd = __alloc_desc(); if ( !statement -> apd ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY013" ); __post_internal_error( &connection -> error, ERROR_HY013, NULL, connection -> environment -> requested_version ); __release_stmt( statement ); *output_handle = SQL_NULL_HSTMT; return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R1 ); } statement -> implicit_apd = statement -> apd; statement -> apd -> implicit = 1; statement -> apd -> associated_with = statement; statement -> apd -> state = STATE_D1i; statement -> apd -> driver_desc = desc; statement -> apd -> connection = connection; } /* * IRD */ ret1 = SQLGETSTMTATTR( connection, statement -> driver_stmt, SQL_ATTR_IMP_ROW_DESC, &desc, sizeof( desc ), NULL ); if ( SQL_SUCCEEDED( ret1 )) { /* * allocate one of our descriptors * to wrap around this */ statement -> ird = __alloc_desc(); if ( !statement -> ird ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY013" ); __post_internal_error( &connection -> error, ERROR_HY013, NULL, connection -> environment -> requested_version ); __release_stmt( statement ); *output_handle = SQL_NULL_HSTMT; return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R1 ); } statement -> implicit_ird = statement -> ird; statement -> ird -> implicit = 1; statement -> ird -> associated_with = statement; statement -> ird -> state = STATE_D1i; statement -> ird -> driver_desc = desc; statement -> ird -> connection = connection; } /* * IPD */ ret1 = SQLGETSTMTATTR( connection, statement -> driver_stmt, SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof( desc ), NULL ); if ( SQL_SUCCEEDED( ret1 )) { /* * allocate one of our descriptors * to wrap around this */ statement -> ipd = __alloc_desc(); if ( !statement -> ipd ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY013" ); __post_internal_error( &connection -> error, ERROR_HY013, NULL, connection -> environment -> requested_version ); __release_stmt( statement ); *output_handle = SQL_NULL_HSTMT; return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R1 ); } statement -> implicit_ipd = statement -> ipd; statement -> ipd -> implicit = 1; statement -> ipd -> associated_with = statement; statement -> ipd -> state = STATE_D1i; statement -> ipd -> driver_desc = desc; statement -> ipd -> connection = connection; } } /* Driver may only have unicode API's */ else if ( CHECK_SQLGETSTMTATTRW( connection )) { DRV_SQLHDESC desc; /* * ARD */ ret1 = SQLGETSTMTATTRW( connection, statement -> driver_stmt, SQL_ATTR_APP_ROW_DESC, &desc, sizeof( desc ), NULL ); if ( SQL_SUCCEEDED( ret1 )) { /* * allocate one of our descriptors * to wrap around this */ statement -> ard = __alloc_desc(); if ( !statement -> ard ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY013" ); __post_internal_error( &connection -> error, ERROR_HY013, NULL, connection -> environment -> requested_version ); __release_stmt( statement ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R1 ); } statement -> implicit_ard = statement -> ard; statement -> ard -> implicit = 1; statement -> ard -> associated_with = statement; statement -> ard -> state = STATE_D1i; statement -> ard -> driver_desc = desc; statement -> ard -> connection = connection; } /* * APD */ ret1 = SQLGETSTMTATTRW( connection, statement -> driver_stmt, SQL_ATTR_APP_PARAM_DESC, &desc, sizeof( desc ), NULL ); if ( SQL_SUCCEEDED( ret1 )) { /* * allocate one of our descriptors * to wrap around this */ statement -> apd = __alloc_desc(); if ( !statement -> apd ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY013" ); __post_internal_error( &connection -> error, ERROR_HY013, NULL, connection -> environment -> requested_version ); __release_stmt( statement ); *output_handle = SQL_NULL_HSTMT; return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R1 ); } statement -> implicit_apd = statement -> apd; statement -> apd -> implicit = 1; statement -> apd -> associated_with = statement; statement -> apd -> state = STATE_D1i; statement -> apd -> driver_desc = desc; statement -> apd -> connection = connection; } /* * IRD */ ret1 = SQLGETSTMTATTRW( connection, statement -> driver_stmt, SQL_ATTR_IMP_ROW_DESC, &desc, sizeof( desc ), NULL ); if ( SQL_SUCCEEDED( ret1 )) { /* * allocate one of our descriptors * to wrap around this */ statement -> ird = __alloc_desc(); if ( !statement -> ird ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY013" ); __post_internal_error( &connection -> error, ERROR_HY013, NULL, connection -> environment -> requested_version ); __release_stmt( statement ); *output_handle = SQL_NULL_HSTMT; return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R1 ); } statement -> implicit_ird = statement -> ird; statement -> ird -> implicit = 1; statement -> ird -> associated_with = statement; statement -> ird -> state = STATE_D1i; statement -> ird -> driver_desc = desc; statement -> ird -> connection = connection; } /* * IPD */ ret1 = SQLGETSTMTATTRW( connection, statement -> driver_stmt, SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof( desc ), NULL ); if ( SQL_SUCCEEDED( ret1 )) { /* * allocate one of our descriptors * to wrap around this */ statement -> ipd = __alloc_desc(); if ( !statement -> ipd ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY013" ); __post_internal_error( &connection -> error, ERROR_HY013, NULL, connection -> environment -> requested_version ); __release_stmt( statement ); *output_handle = SQL_NULL_HSTMT; return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R1 ); } statement -> implicit_ipd = statement -> ipd; statement -> ipd -> implicit = 1; statement -> ipd -> associated_with = statement; statement -> ipd -> state = STATE_D1i; statement -> ipd -> driver_desc = desc; statement -> ipd -> connection = connection; } } } /* * set any preset statement attributes */ if ( SQL_SUCCEEDED( ret )) { __set_attributes( statement, SQL_HANDLE_STMT ); } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[SQL_SUCCESS]\n\t\t\tOutput Handle = %p", statement ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) uodbc_update_stats(connection->environment->sh, UODBC_STATS_TYPE_HSTMT, (void *)1); #endif return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R1 ); } break; case SQL_HANDLE_DESC: { SQLRETURN ret; DMHDBC connection = (DMHDBC) input_handle; DMHDESC descriptor; if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } if ( output_handle ) *output_handle = SQL_NULL_HDESC; thread_protect( SQL_HANDLE_DBC, connection ); function_entry(( void * ) input_handle ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p", handle_type, (void*)input_handle ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } if ( !output_handle ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &connection -> error, ERROR_HY009, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection , SQL_ERROR ); } if ( connection -> state == STATE_C1 || connection -> state == STATE_C2 || connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); *output_handle = SQL_NULL_HDESC; return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } descriptor = __alloc_desc(); if ( !descriptor ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY013" ); __post_internal_error( &connection -> error, ERROR_HY013, NULL, connection -> environment -> requested_version ); *output_handle = SQL_NULL_HDESC; return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * pass the call on */ if ( CHECK_SQLALLOCHANDLE( connection )) { ret = SQLALLOCHANDLE( connection, SQL_HANDLE_DESC, connection -> driver_dbc, &descriptor -> driver_desc, NULL ); if ( !SQL_SUCCEEDED( ret )) __release_desc( descriptor ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM003" ); __post_internal_error( &connection -> error, ERROR_IM003, NULL, connection -> environment -> requested_version ); __release_desc( descriptor ); *output_handle = SQL_NULL_HDESC; return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( SQL_SUCCEEDED( ret )) { /* * sort out the states */ descriptor -> state = STATE_D1e; descriptor -> implicit = 0; descriptor -> associated_with = NULL; connection -> statement_count ++; descriptor -> connection = connection; *output_handle = (SQLHANDLE) descriptor; } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[SQL_SUCCESS]\n\t\t\tOutput Handle = %p", descriptor ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) uodbc_update_stats(connection->environment->sh, UODBC_STATS_TYPE_HDESC, (void *)1); #endif return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R1 ); } break; default: if ( __validate_env( (DMHENV) input_handle )) { DMHENV environment = (DMHENV) input_handle; thread_protect( SQL_HANDLE_ENV, environment ); __post_internal_error( &environment -> error, ERROR_HY092, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } else if ( __validate_dbc( (DMHDBC) input_handle )) { DMHDBC connection = (DMHDBC) input_handle; thread_protect( SQL_HANDLE_DBC, connection ); __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } break; } } SQLRETURN SQLAllocHandle( SQLSMALLINT handle_type, SQLHANDLE input_handle, SQLHANDLE *output_handle ) { /* * setting a requested version to 0 * indicates that we are ODBC3 and the application must * select ODBC2 or 3 explicitly */ return __SQLAllocHandle( handle_type, input_handle, output_handle, 0 ); } unixODBC-2.3.12/DriverManager/SQLAllocHandleStd.c000066400000000000000000000055011446441710500213140ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLAllocHandleStd.c,v 1.2 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLAllocHandleStd.c,v $ * Revision 1.2 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.4 1999/07/07 18:51:54 ngorham * * Add missing '*' * * Revision 1.3 1999/07/04 21:05:06 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/21 19:59:04 ngorham * * Fix bug in SQLAllocHandleStd.c, the wrong handle was being used to * return the allocated env handle * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:02:41 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLAllocHandleStd.c,v $ $Revision: 1.2 $"; SQLRETURN SQLAllocHandleStd( SQLSMALLINT handle_type, SQLHANDLE input_handle, SQLHANDLE *output_handle ) { SQLRETURN ret; ret = __SQLAllocHandle( handle_type, input_handle, output_handle, 0 ); if ( handle_type == SQL_HANDLE_ENV && SQL_SUCCEEDED( ret )) { DMHENV environment = (DMHENV) *output_handle; environment -> requested_version = SQL_OV_ODBC3; environment -> version_set = 1; } return ret; } unixODBC-2.3.12/DriverManager/SQLAllocStmt.c000066400000000000000000000044771446441710500204100ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLAllocStmt.c,v 1.2 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLAllocStmt.c,v $ * Revision 1.2 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.3 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.2 1999/07/04 21:05:06 ngorham * * Add LGPL Headers to code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.1 1999/04/25 23:02:41 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLAllocStmt.c,v $ $Revision: 1.2 $"; SQLRETURN SQLAllocStmt( SQLHDBC connection_handle, SQLHSTMT *statement_handle ) { return __SQLAllocHandle( SQL_HANDLE_STMT, connection_handle, statement_handle, SQL_OV_ODBC2 ); } unixODBC-2.3.12/DriverManager/SQLBindCol.c000066400000000000000000000235251446441710500200130ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLBindCol.c,v 1.8 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLBindCol.c,v $ * Revision 1.8 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.7 2007/03/05 09:49:23 lurcher * Get it to build on VMS again * * Revision 1.6 2006/04/11 10:22:56 lurcher * Fix a data type check * * Revision 1.5 2006/03/08 11:22:13 lurcher * Add check for valid C_TYPE * * Revision 1.4 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.2 2001/12/13 13:00:31 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.9 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.8 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.7 1999/10/09 00:56:16 ngorham * * Added Manush's patch to map ODBC 3-2 datetime values * * Revision 1.6 1999/10/09 00:15:58 ngorham * * Add mapping from SQL_TYPE_X to SQL_X and SQL_C_TYPE_X to SQL_C_X * when the driver is a ODBC 2 one * * Revision 1.5 1999/09/21 22:34:23 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:06 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:02:41 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLBindCol.c,v $ $Revision: 1.8 $"; int check_target_type( int c_type, int connection_mode) { /* * driver defined types */ if ( connection_mode >= SQL_OV_ODBC3_80 && c_type >= 0x4000 && c_type <= 0x7FFF ) { return 1; } switch( c_type ) { case SQL_C_CHAR: case SQL_C_LONG: case SQL_C_SHORT: case SQL_C_FLOAT: case SQL_C_NUMERIC: case SQL_C_DEFAULT: case SQL_C_DATE: case SQL_C_TIME: case SQL_C_TIMESTAMP: case SQL_C_TYPE_DATE: case SQL_C_TYPE_TIME: case SQL_C_TYPE_TIMESTAMP: case SQL_C_INTERVAL_YEAR: case SQL_C_INTERVAL_MONTH: case SQL_C_INTERVAL_DAY: case SQL_C_INTERVAL_HOUR: case SQL_C_INTERVAL_MINUTE: case SQL_C_INTERVAL_SECOND: case SQL_C_INTERVAL_YEAR_TO_MONTH: case SQL_C_INTERVAL_DAY_TO_HOUR: case SQL_C_INTERVAL_DAY_TO_MINUTE: case SQL_C_INTERVAL_DAY_TO_SECOND: case SQL_C_INTERVAL_HOUR_TO_MINUTE: case SQL_C_INTERVAL_HOUR_TO_SECOND: case SQL_C_INTERVAL_MINUTE_TO_SECOND: case SQL_C_BINARY: case SQL_C_BIT: case SQL_C_SBIGINT: case SQL_C_UBIGINT: case SQL_C_TINYINT: case SQL_C_SLONG: case SQL_C_SSHORT: case SQL_C_STINYINT: case SQL_C_ULONG: case SQL_C_USHORT: case SQL_C_UTINYINT: case SQL_C_GUID: case SQL_C_WCHAR: case SQL_ARD_TYPE: case SQL_C_DOUBLE: /* * MS Added types */ case -150: /* SQL_SS_VARIANT */ case -151: /* SQL_SS_UDT */ case -152: /* SQL_SS_XML */ case -153: /* SQL_SS_TABLE */ case -154: /* SQL_SS_TIME2 */ case -155: /* SQL_SS_TIMESTAMPOFFSET */ return 1; default: return 0; } } SQLRETURN SQLBindCol( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLSMALLINT target_type, SQLPOINTER target_value, SQLLEN buffer_length, SQLLEN *strlen_or_ind ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tColumn Number = %d\ \n\t\t\tTarget Type = %d %s\ \n\t\t\tTarget Value = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tStrLen Or Ind = %p", statement, column_number, target_type, __sql_as_text( target_type ), target_value, (int)buffer_length, (void*)strlen_or_ind ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( buffer_length < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * TO_DO * Check the type against a bookmark * check that the length is 4 for a odbc 2 bookmark * remember thats its bound for SQLGetData checks */ /* * check states */ if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S12 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check valid C_TYPE * Its possible to call with the indicator and buffer NULL to unbind without setting the type */ if (( target_value || strlen_or_ind ) && !check_target_type( target_type, statement -> connection -> environment -> requested_version )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY003" ); __post_internal_error( &statement -> error, ERROR_HY003, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( !CHECK_SQLBINDCOL( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLBINDCOL( statement -> connection , statement -> driver_stmt, column_number, __map_type(MAP_C_DM2D,statement->connection,target_type), target_value, buffer_length, strlen_or_ind ); if ( log_info.log_flag ) { SQLCHAR buf[ 128 ]; sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, buf )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLBindParam.c000066400000000000000000000235141446441710500203340ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLBindParam.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLBindParam.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2007/03/05 09:49:23 lurcher * Get it to build on VMS again * * Revision 1.7 2006/04/11 10:22:56 lurcher * Fix a data type check * * Revision 1.6 2006/03/08 11:22:13 lurcher * Add check for valid C_TYPE * * Revision 1.5 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/19 09:11:49 lurcher * * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state * * Revision 1.2 2001/12/13 13:00:31 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.9 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.8 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.7 1999/10/09 00:56:16 ngorham * * Added Manush's patch to map ODBC 3-2 datetime values * * Revision 1.6 1999/10/09 00:15:58 ngorham * * Add mapping from SQL_TYPE_X to SQL_X and SQL_C_TYPE_X to SQL_C_X * when the driver is a ODBC 2 one * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:06 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.3 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:02:41 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLBindParam.c,v $ $Revision: 1.9 $"; SQLRETURN SQLBindParam( SQLHSTMT statement_handle, SQLUSMALLINT parameter_number, SQLSMALLINT value_type, SQLSMALLINT parameter_type, SQLULEN length_precision, SQLSMALLINT parameter_scale, SQLPOINTER parameter_value, SQLLEN *strlen_or_ind) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tParam Number = %d\ \n\t\t\tValue Type = %d %s\ \n\t\t\tParameter Type = %d %s\ \n\t\t\tLength Precision = %d\ \n\t\t\tParameter Scale = %d\ \n\t\t\tParameter Value = %p\ \n\t\t\tStrLen Or Ind = %p", statement, parameter_number, value_type, __c_as_text( value_type ), parameter_type, __sql_as_text( parameter_type ), (int)length_precision, (int)parameter_scale, (void*)parameter_value, (void*)strlen_or_ind ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( parameter_number < 1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error_api( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version, SQL_API_SQLBINDPARAM ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( parameter_value == NULL && strlen_or_ind == NULL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check valid C_TYPE */ if ( !check_target_type( value_type, statement -> connection -> environment -> requested_version )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY003" ); __post_internal_error( &statement -> error, ERROR_HY003, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( CHECK_SQLBINDPARAM( statement -> connection )) { ret = SQLBINDPARAM( statement -> connection, statement -> driver_stmt, parameter_number, __map_type(MAP_C_DM2D,statement->connection,value_type), __map_type(MAP_SQL_DM2D,statement->connection,parameter_type), length_precision, parameter_scale, parameter_value, strlen_or_ind ); } else { /* * map to odbc 3 operation */ if ( !CHECK_SQLBINDPARAMETER( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * this probably needs to work out the * buffer length */ ret = SQLBINDPARAMETER( statement -> connection, statement -> driver_stmt, parameter_number, SQL_PARAM_INPUT, __map_type(MAP_C_DM2D,statement->connection,value_type), __map_type(MAP_SQL_DM2D,statement->connection,parameter_type), length_precision, parameter_scale, parameter_value, 0, strlen_or_ind ); } if ( log_info.log_flag ) { SQLCHAR buf[ 128 ]; sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, buf )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLBindParameter.c000066400000000000000000000322531446441710500212140ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLBindParameter.c,v 1.12 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLBindParameter.c,v $ * Revision 1.12 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.11 2007/03/05 09:49:23 lurcher * Get it to build on VMS again * * Revision 1.10 2006/04/18 10:24:47 lurcher * Add a couple of changes from Mark Vanderwiel * * Revision 1.9 2006/04/11 10:22:56 lurcher * Fix a data type check * * Revision 1.8 2006/03/08 11:22:13 lurcher * Add check for valid C_TYPE * * Revision 1.7 2005/09/05 09:49:48 lurcher * New QT detection macros added * * Revision 1.6 2005/04/26 08:40:35 lurcher * * Add data type mapping for SQLSetPos. * Remove out of date macro in sqlext.h * * Revision 1.5 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/19 09:11:49 lurcher * * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state * * Revision 1.2 2001/12/13 13:00:31 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.9 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.8 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.7 1999/10/09 00:56:16 ngorham * * Added Manush's patch to map ODBC 3-2 datetime values * * Revision 1.6 1999/10/09 00:15:58 ngorham * * Add mapping from SQL_TYPE_X to SQL_X and SQL_C_TYPE_X to SQL_C_X * when the driver is a ODBC 2 one * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:06 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:20 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.3 1999/05/03 19:50:43 nick * Another check point * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:02:41 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLBindParameter.c,v $ $Revision: 1.12 $"; SQLRETURN SQLBindParameter( SQLHSTMT statement_handle, SQLUSMALLINT ipar, SQLSMALLINT f_param_type, SQLSMALLINT f_c_type, SQLSMALLINT f_sql_type, SQLULEN cb_col_def, SQLSMALLINT ib_scale, SQLPOINTER rgb_value, SQLLEN cb_value_max, SQLLEN *pcb_value ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tParam Number = %d\ \n\t\t\tParam Type = %d\ \n\t\t\tC Type = %d %s\ \n\t\t\tSQL Type = %d %s\ \n\t\t\tCol Def = %d\ \n\t\t\tScale = %d\ \n\t\t\tRgb Value = %p\ \n\t\t\tValue Max = %d\ \n\t\t\tStrLen Or Ind = %p", statement, ipar, f_param_type, f_c_type, __c_as_text( f_c_type ), f_sql_type, __sql_as_text( f_sql_type ), (int)cb_col_def, (int)ib_scale, (void*)rgb_value, (int)cb_value_max, (void*)pcb_value ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( ipar < 1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error_api( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version, SQL_API_SQLBINDPARAMETER ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( ((f_c_type == SQL_C_CHAR || f_c_type == SQL_C_BINARY || f_c_type == SQL_C_WCHAR) || (f_c_type == SQL_C_DEFAULT && (f_sql_type == SQL_DEFAULT || f_sql_type == SQL_CHAR || f_sql_type == SQL_BINARY || f_sql_type == SQL_LONGVARCHAR || f_sql_type == SQL_LONGVARBINARY || f_sql_type == SQL_VARBINARY || f_sql_type == SQL_VARCHAR || f_sql_type == SQL_WCHAR || f_sql_type == SQL_WLONGVARCHAR || f_sql_type == SQL_WVARCHAR))) && cb_value_max < 0 && cb_value_max != SQL_NTS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( rgb_value == NULL && pcb_value == NULL && f_param_type != SQL_PARAM_OUTPUT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> connection -> environment -> requested_version == SQL_OV_ODBC3_80 ) { if ( f_param_type != SQL_PARAM_INPUT && f_param_type != SQL_PARAM_INPUT_OUTPUT && f_param_type != SQL_PARAM_OUTPUT && f_param_type != SQL_PARAM_OUTPUT_STREAM && f_param_type != SQL_PARAM_INPUT_OUTPUT_STREAM ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY105" ); __post_internal_error( &statement -> error, ERROR_HY105, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } else { if ( f_param_type != SQL_PARAM_INPUT && f_param_type != SQL_PARAM_INPUT_OUTPUT && f_param_type != SQL_PARAM_OUTPUT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY105" ); __post_internal_error( &statement -> error, ERROR_HY105, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * Alter the types, this is a special to cope with a AllBase bug... */ if ( f_c_type == SQL_C_SLONG && 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Map from SQL_C_SLONG,SQL_C_CHAR to SQL_C_LONG,SQL_INTEGER" ); f_c_type = SQL_C_LONG; f_sql_type = SQL_INTEGER; } /* * check states */ if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check valid C_TYPE */ if ( !check_target_type( f_c_type, statement -> connection -> environment -> requested_version )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY003" ); __post_internal_error( &statement -> error, ERROR_HY003, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( CHECK_SQLBINDPARAMETER( statement -> connection )) { ret = SQLBINDPARAMETER( statement -> connection, statement -> driver_stmt, ipar, f_param_type, __map_type(MAP_C_DM2D,statement->connection,f_c_type), __map_type(MAP_SQL_DM2D,statement->connection,f_sql_type), cb_col_def, ib_scale, rgb_value, cb_value_max, pcb_value ); } else if ( CHECK_SQLBINDPARAM( statement -> connection )) { ret = SQLBINDPARAM( statement -> connection, statement -> driver_stmt, ipar, __map_type(MAP_C_DM2D,statement->connection,f_c_type), __map_type(MAP_SQL_DM2D,statement->connection,f_sql_type), cb_col_def, ib_scale, rgb_value, pcb_value ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( log_info.log_flag ) { SQLCHAR buf[ 128 ]; sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, buf )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLBrowseConnect.c000066400000000000000000000505541446441710500212560ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLBrowseConnect.c,v 1.15 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLBrowseConnect.c,v $ * Revision 1.15 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.14 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.13 2007/10/19 10:14:05 lurcher * Pull errors from SQLBrowseConnect when it returns SQL_NEED_DATA * * Revision 1.12 2005/11/21 17:25:43 lurcher * A few DM fixes for Oracle's ODBC driver * * Revision 1.11 2005/10/06 08:50:58 lurcher * Fix problem with SQLDrivers not returning first entry * * Revision 1.10 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.9 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.8 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.7 2002/08/15 08:10:33 lurcher * * Couple of small fixes from John L Miller * * Revision 1.6 2002/07/25 09:30:26 lurcher * * Additional unicode and iconv changes * * Revision 1.5 2002/02/08 17:59:40 lurcher * * Fix threading problem in SQLBrowseConnect * * Revision 1.4 2002/02/07 20:50:04 lurcher * * Fix small bug in SQLBrowseConnect * * Revision 1.3 2002/01/21 18:00:50 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.2 2001/12/13 13:00:31 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.9 2001/07/20 12:35:09 nick * * Fix SQLBrowseConnect operation * * Revision 1.8 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.7 2001/05/15 10:57:44 nick * * Add initial support for VMS * * Revision 1.6 2001/04/16 22:35:10 nick * * More tweeks to the AutoTest code * * Revision 1.5 2001/04/16 15:41:24 nick * * Fix some problems calling non existing error funcs * * Revision 1.4 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.3 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.2 2000/10/13 15:18:49 nick * * Change string length parameter from SQLINTEGER to SQLSMALLINT * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 2000/05/21 21:49:19 ngorham * * Assorted fixes * * Revision 1.7 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/08/03 21:47:39 shandyb * Moving to automake: changed files in DriverManager * * Revision 1.3 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.2 1999/07/04 21:05:06 ngorham * * Add LGPL Headers to code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:02:41 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLBrowseConnect.c,v $ $Revision: 1.15 $"; #define BUFFER_LEN 4095 SQLRETURN SQLBrowseConnectA( SQLHDBC hdbc, SQLCHAR *conn_str_in, SQLSMALLINT len_conn_str_in, SQLCHAR *conn_str_out, SQLSMALLINT conn_str_out_max, SQLSMALLINT *ptr_conn_str_out ) { return SQLBrowseConnect( hdbc, conn_str_in, len_conn_str_in, conn_str_out, conn_str_out_max, ptr_conn_str_out ); } SQLRETURN SQLBrowseConnect( SQLHDBC hdbc, SQLCHAR *conn_str_in, SQLSMALLINT len_conn_str_in, SQLCHAR *conn_str_out, SQLSMALLINT conn_str_out_max, SQLSMALLINT *ptr_conn_str_out ) { DMHDBC connection = (DMHDBC) hdbc; struct con_struct con_struct; char *driver, *dsn; char lib_name[ INI_MAX_PROPERTY_VALUE + 1 ]; char driver_name[ INI_MAX_PROPERTY_VALUE + 1 ]; char in_str_buf[ BUFFER_LEN ]; char *in_str; SQLSMALLINT in_str_len; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN]; int warnings = 0; /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tStr In = %s\ \n\t\t\tStr Out = %p\ \n\t\t\tStr Out Max = %d\ \n\t\t\tPtr Conn Str Out = %p", connection, __string_with_length( s1, conn_str_in, len_conn_str_in ), conn_str_out, conn_str_out_max, ptr_conn_str_out ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } /* * check the state of the connection */ if ( connection -> state == STATE_C4 || connection -> state == STATE_C5 || connection -> state == STATE_C6 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08002" ); __post_internal_error( &connection -> error, ERROR_08002, NULL, connection -> environment -> requested_version ); return function_return_nodrv( IGNORE_THREAD, connection, SQL_ERROR ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( len_conn_str_in < 0 && len_conn_str_in != SQL_NTS) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * are we at the start of a connection */ if ( connection -> state == STATE_C2 ) { /* * parse the connection string */ __parse_connection_string( &con_struct, (char*)conn_str_in, len_conn_str_in ); /* * look for some keywords * have we got a DRIVER= attribute */ driver = __get_attribute_value( &con_struct, "DRIVER" ); if ( driver ) { /* * look up the driver in the ini file */ SQLGetPrivateProfileString( driver, "Driver", "", lib_name, sizeof( lib_name ), "ODBCINST.INI" ); if ( lib_name[ 0 ] == '\0' ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM002" ); __post_internal_error( &connection -> error, ERROR_IM002, NULL, connection -> environment -> requested_version ); __release_conn( &con_struct ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } strcpy( connection -> dsn, "" ); } else { dsn = __get_attribute_value( &con_struct, "DSN" ); if ( !dsn ) { dsn = "DEFAULT"; __append_pair( &con_struct, "DSN", "DEFAULT" ); } if ( strlen( dsn ) > SQL_MAX_DSN_LENGTH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM012" ); __post_internal_error( &connection -> error, ERROR_IM012, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * look up the dsn in the ini file */ if ( !__find_lib_name( dsn, lib_name, driver_name )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM002" ); __post_internal_error( &connection -> error, ERROR_IM002, NULL, connection -> environment -> requested_version ); __release_conn( &con_struct ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } strcpy( connection -> dsn, dsn ); } __generate_connection_string( &con_struct, in_str_buf, sizeof( in_str_buf )); __release_conn( &con_struct ); /* * we now have a driver to connect to */ if ( !__connect_part_one( connection, lib_name, driver_name, &warnings )) { __disconnect_part_four( connection ); /* release unicode handles */ dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: connect_part_one fails" ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( !CHECK_SQLBROWSECONNECTW( connection ) && !CHECK_SQLBROWSECONNECT( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } in_str = in_str_buf; in_str_len = strlen(in_str); } else { in_str = (char*)conn_str_in; in_str_len = len_conn_str_in == SQL_NTS ? strlen(in_str) : len_conn_str_in; } if (CHECK_SQLBROWSECONNECT( connection )) { ret = SQLBROWSECONNECT( connection, connection -> driver_dbc, (SQLCHAR*) in_str, in_str_len, conn_str_out, conn_str_out_max, ptr_conn_str_out ); connection->unicode_driver = 0; } else if (CHECK_SQLBROWSECONNECTW( connection )) { int wlen; SQLWCHAR *uc_in_str = ansi_to_unicode_alloc((SQLCHAR*)in_str,SQL_NTS,connection, &wlen); SQLWCHAR *uc_out_str = conn_str_out ? malloc( (conn_str_out_max + 1) * sizeof(SQLWCHAR) ) : 0; ret = SQLBROWSECONNECTW( connection, connection -> driver_dbc, uc_in_str, wlen, uc_out_str, conn_str_out_max, ptr_conn_str_out ); if(uc_in_str) free(uc_in_str); if(uc_out_str) { unicode_to_ansi_copy((char*) conn_str_out, conn_str_out_max, uc_out_str, SQL_NTS, connection, NULL ); if (*ptr_conn_str_out < conn_str_out_max) *ptr_conn_str_out = strlen((char*)conn_str_out); free(uc_out_str); } connection->unicode_driver = 1; } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( !SQL_SUCCEEDED( ret ) || ret == SQL_NEED_DATA ) { /* * get the error from the driver before * losing the connection */ if ( connection -> unicode_driver ) { if ( CHECK_SQLGETDIAGFIELDW( connection ) && CHECK_SQLGETDIAGRECW( connection )) { extract_diag_error_w( SQL_HANDLE_DBC, connection -> driver_dbc, connection, &connection -> error, ret, 1 ); } else if ( CHECK_SQLERRORW( connection )) { extract_sql_error_w( SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, connection, &connection -> error, ret ); } else if ( CHECK_SQLGETDIAGFIELD( connection ) && CHECK_SQLGETDIAGREC( connection )) { extract_diag_error( SQL_HANDLE_DBC, connection -> driver_dbc, connection, &connection -> error, ret, 1 ); } else if ( CHECK_SQLERROR( connection )) { extract_sql_error( SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, connection, &connection -> error, ret ); } else { __post_internal_error( &connection -> error, ERROR_HY000, "Driver returned SQL_ERROR or SQL_SUCCESS_WITH_INFO but no error reporting API found", connection -> environment -> requested_version ); } } else { if ( CHECK_SQLGETDIAGFIELD( connection ) && CHECK_SQLGETDIAGREC( connection )) { extract_diag_error( SQL_HANDLE_DBC, connection -> driver_dbc, connection, &connection -> error, ret, 1 ); } else if ( CHECK_SQLERROR( connection )) { extract_sql_error( SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, connection, &connection -> error, ret ); } else if ( CHECK_SQLGETDIAGFIELDW( connection ) && CHECK_SQLGETDIAGRECW( connection )) { extract_diag_error_w( SQL_HANDLE_DBC, connection -> driver_dbc, connection, &connection -> error, ret, 1 ); } else if ( CHECK_SQLERRORW( connection )) { extract_sql_error_w( SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, connection, &connection -> error, ret ); } else { __post_internal_error( &connection -> error, ERROR_HY000, "Driver returned SQL_ERROR or SQL_SUCCESS_WITH_INFO but no error reporting API found", connection -> environment -> requested_version ); } } if ( ret != SQL_NEED_DATA ) { /* If an error occurred during SQLBrowseConnect, we need to keep the connection in the same state (C2 or C3). This allows the application to either try the SQLBrowseConnect again, or disconnect an active browse session with SQLDisconnect. Otherwise the driver may continue to have an active connection while the DM thinks it does not, causing more errors later on. */ if ( connection -> state == STATE_C2 ) { /* only disconnect and unload if we never started browsing */ __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles - also sets state to C2 */ } } else { connection -> state = STATE_C3; } } else { /* * we should be connected now */ connection -> state = STATE_C4; if( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, connection, ret, TRUE, DEFER_R0 ); } if ( !__connect_part_two( connection )) { __disconnect_part_two( connection ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]\ \n\t\t\tconnect_part_two fails", __get_return_status( SQL_ERROR, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]\ \n\t\t\tPtr Conn Str Out = %s", __get_return_status( ret, s2 ), __sptr_as_string( s1, ptr_conn_str_out )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } if ( warnings && ret == SQL_SUCCESS ) { ret = SQL_SUCCESS_WITH_INFO; } return function_return_nodrv( SQL_HANDLE_DBC, connection, ret ); } unixODBC-2.3.12/DriverManager/SQLBrowseConnectW.c000066400000000000000000000472451446441710500214100ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLBrowseConnectW.c,v 1.13 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLBrowseConnectW.c,v $ * Revision 1.13 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.12 2007/10/19 10:14:05 lurcher * Pull errors from SQLBrowseConnect when it returns SQL_NEED_DATA * * Revision 1.11 2007/02/28 15:37:46 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.10 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.9 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.8 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.7 2002/08/15 08:10:33 lurcher * * Couple of small fixes from John L Miller * * Revision 1.6 2002/07/25 09:30:26 lurcher * * Additional unicode and iconv changes * * Revision 1.5 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.4 2002/02/08 17:59:40 lurcher * * Fix threading problem in SQLBrowseConnect * * Revision 1.3 2002/01/21 18:00:51 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.7 2001/07/20 12:35:09 nick * * Fix SQLBrowseConnect operation * * Revision 1.6 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.5 2001/05/15 10:57:44 nick * * Add initial support for VMS * * Revision 1.4 2001/04/16 15:41:24 nick * * Fix some problems calling non existing error funcs * * Revision 1.3 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/01/02 09:55:04 nick * * More unicode bits * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLBrowseConnectW.c,v $"; #define BUFFER_LEN 4095 SQLRETURN SQLBrowseConnectW( SQLHDBC hdbc, SQLWCHAR *conn_str_in, SQLSMALLINT len_conn_str_in, SQLWCHAR *conn_str_out, SQLSMALLINT conn_str_out_max, SQLSMALLINT *ptr_conn_str_out ) { DMHDBC connection = (DMHDBC) hdbc; struct con_struct con_struct; char *driver, *dsn; char lib_name[ INI_MAX_PROPERTY_VALUE + 1 ]; char driver_name[ INI_MAX_PROPERTY_VALUE + 1 ]; SQLWCHAR in_str_bufw[ BUFFER_LEN ]; SQLWCHAR *in_str; SQLSMALLINT in_str_len; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ]; int warnings = 0; /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHDBC parent_connection; parent_connection = find_parent_handle( connection, SQL_HANDLE_DBC ); if ( parent_connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLBROWSECONNECTW( parent_connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLBROWSECONNECTW( parent_connection, connection, conn_str_in, len_conn_str_in, conn_str_out, conn_str_out_max, ptr_conn_str_out ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tStr In = %s\ \n\t\t\tStr Out = %s\ \n\t\t\tPtr Conn Str Out = %p", connection, __wstring_with_length( s1, conn_str_in, len_conn_str_in ), __wstring_with_length( s2, conn_str_out, conn_str_out_max ), ptr_conn_str_out ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } /* * check the state of the connection */ if ( connection -> state == STATE_C4 || connection -> state == STATE_C5 || connection -> state == STATE_C6 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08002" ); __post_internal_error( &connection -> error, ERROR_08002, NULL, connection -> environment -> requested_version ); return function_return_nodrv( IGNORE_THREAD, connection, SQL_ERROR ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( len_conn_str_in < 0 && len_conn_str_in != SQL_NTS) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * are we at the start of a connection */ if ( connection -> state == STATE_C2 ) { char in_str_buf[ BUFFER_LEN ]; /* * parse the connection string */ __parse_connection_string_w( &con_struct, conn_str_in, len_conn_str_in ); /* * look for some keywords * have we got a DRIVER= attribute */ driver = __get_attribute_value( &con_struct, "DRIVER" ); if ( driver ) { /* * look up the driver in the ini file */ SQLGetPrivateProfileString( driver, "Driver", "", lib_name, sizeof( lib_name ), "ODBCINST.INI" ); if ( lib_name[ 0 ] == '\0' ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM002" ); __post_internal_error( &connection -> error, ERROR_IM002, NULL, connection -> environment -> requested_version ); __release_conn( &con_struct ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } strcpy( connection -> dsn, "" ); } else { dsn = __get_attribute_value( &con_struct, "DSN" ); if ( !dsn ) { dsn = "DEFAULT"; __append_pair( &con_struct, "DSN", "DEFAULT" ); } if ( strlen( dsn ) > SQL_MAX_DSN_LENGTH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM012" ); __post_internal_error( &connection -> error, ERROR_IM012, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * look up the dsn in the ini file */ if ( !__find_lib_name( dsn, lib_name, driver_name )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM002" ); __post_internal_error( &connection -> error, ERROR_IM002, NULL, connection -> environment -> requested_version ); __release_conn( &con_struct ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } strcpy( connection -> dsn, dsn ); } __generate_connection_string( &con_struct, in_str_buf, sizeof( in_str_buf )); __release_conn( &con_struct ); ansi_to_unicode_copy( in_str_bufw, in_str_buf, BUFFER_LEN, connection, 0 ); /* * we now have a driver to connect to */ if ( !__connect_part_one( connection, lib_name, driver_name, &warnings )) { __disconnect_part_four( connection ); /* release unicode handles */ dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: connect_part_one fails" ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( !CHECK_SQLBROWSECONNECTW( connection ) && !CHECK_SQLBROWSECONNECT( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } in_str = in_str_bufw; in_str_len = wide_strlen(in_str); } else { in_str = conn_str_in; in_str_len = len_conn_str_in == SQL_NTS ? wide_strlen(in_str) : len_conn_str_in; } if ( CHECK_SQLBROWSECONNECTW( connection )) { ret = SQLBROWSECONNECTW( connection, connection -> driver_dbc, in_str, in_str_len, conn_str_out, conn_str_out_max, ptr_conn_str_out ); connection -> unicode_driver = 1; } else if (CHECK_SQLBROWSECONNECT( connection )) { SQLCHAR *an_in_str = (SQLCHAR*) unicode_to_ansi_alloc( in_str, SQL_NTS, connection, 0 ); SQLCHAR *ob = conn_str_out ? malloc( (conn_str_out_max + 1) * sizeof(SQLWCHAR) ) : 0; SQLSMALLINT len; ret = SQLBROWSECONNECT( connection, connection -> driver_dbc, an_in_str, SQL_NTS, ob, conn_str_out_max, &len ); *ptr_conn_str_out = len; if(ob) { if ( ptr_conn_str_out ) { int wptr; ansi_to_unicode_copy(conn_str_out, (char*)ob, conn_str_out_max, connection, &wptr ); *ptr_conn_str_out = (SQLSMALLINT) wptr; } else { ansi_to_unicode_copy(conn_str_out, (char*)ob, conn_str_out_max, connection, NULL ); } free(ob); } free(an_in_str); connection -> unicode_driver = 0; } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( !SQL_SUCCEEDED( ret ) || ret == SQL_NEED_DATA ) { /* * get the error from the driver before * losing the connection */ if ( connection -> unicode_driver ) { if ( CHECK_SQLGETDIAGFIELDW( connection ) && CHECK_SQLGETDIAGRECW( connection )) { extract_diag_error_w( SQL_HANDLE_DBC, connection -> driver_dbc, connection, &connection -> error, ret, 1 ); } else if ( CHECK_SQLERRORW( connection )) { extract_sql_error_w( SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, connection, &connection -> error, ret ); } else if ( CHECK_SQLGETDIAGFIELD( connection ) && CHECK_SQLGETDIAGREC( connection )) { extract_diag_error( SQL_HANDLE_DBC, connection -> driver_dbc, connection, &connection -> error, ret, 1 ); } else if ( CHECK_SQLERROR( connection )) { extract_sql_error( SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, connection, &connection -> error, ret ); } else { __post_internal_error( &connection -> error, ERROR_HY000, "Driver returned SQL_ERROR or SQL_SUCCESS_WITH_INFO but no error reporting API found", connection -> environment -> requested_version ); } } else { if ( CHECK_SQLGETDIAGFIELD( connection ) && CHECK_SQLGETDIAGREC( connection )) { extract_diag_error( SQL_HANDLE_DBC, connection -> driver_dbc, connection, &connection -> error, ret, 1 ); } else if ( CHECK_SQLERROR( connection )) { extract_sql_error( SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, connection, &connection -> error, ret ); } else if ( CHECK_SQLGETDIAGFIELDW( connection ) && CHECK_SQLGETDIAGRECW( connection )) { extract_diag_error_w( SQL_HANDLE_DBC, connection -> driver_dbc, connection, &connection -> error, ret, 1 ); } else if ( CHECK_SQLERRORW( connection )) { extract_sql_error_w( SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, connection, &connection -> error, ret ); } else { __post_internal_error( &connection -> error, ERROR_HY000, "Driver returned SQL_ERROR or SQL_SUCCESS_WITH_INFO but no error reporting API found", connection -> environment -> requested_version ); } } if ( ret != SQL_NEED_DATA ) { /* If an error occurred during SQLBrowseConnect, we need to keep the connection in the same state (C2 or C3). This allows the application to either try the SQLBrowseConnect again, or disconnect an active browse session with SQLDisconnect. Otherwise the driver may continue to have an active connection while the DM thinks it does not, causing more errors later on. */ if ( connection -> state == STATE_C2 ) { /* only disconnect and unload if we never started browsing */ __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles - also sets state to C2 */ } } else { connection -> state = STATE_C3; } } else { /* * we should be connected now */ connection -> state = STATE_C4; if( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, connection, ret, TRUE, DEFER_R0 ); } if ( !__connect_part_two( connection )) { __disconnect_part_two( connection ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]\ \n\t\t\tconnect_part_two fails", __get_return_status( SQL_ERROR, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]\ \n\t\t\tPtr Conn Str Out = %s", __get_return_status( ret, s2 ), __sptr_as_string( s1, ptr_conn_str_out )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } if ( warnings && ret == SQL_SUCCESS ) { ret = SQL_SUCCESS_WITH_INFO; } return function_return_nodrv( SQL_HANDLE_DBC, connection, ret ); } unixODBC-2.3.12/DriverManager/SQLBulkOperations.c000066400000000000000000000216141446441710500214370ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLBulkOperations.c,v 1.4 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLBulkOperations.c,v $ * Revision 1.4 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.2 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:06 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.2 1999/06/02 23:48:45 ngorham * * Added more 3-2 mapping * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:02:41 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLBulkOperations.c,v $ $Revision: 1.4 $"; SQLRETURN SQLBulkOperations( SQLHSTMT statement_handle, SQLSMALLINT operation ) { DMHSTMT statement = (DMHSTMT)statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tOption = %d", statement, operation ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S2 || statement -> state == STATE_S3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S7 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLBULKOPERATIONS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) { statement -> interupted_state = statement -> state; } /* * there are a lot of conditions that should be tested here */ if ( CHECK_SQLBULKOPERATIONS( statement -> connection )) { ret = SQLBULKOPERATIONS( statement -> connection, statement -> driver_stmt, operation ); } else if ( CHECK_SQLSETPOS( statement -> connection ) && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && operation == SQL_ADD ) { ret = SQLSETPOS( statement -> connection, statement -> driver_stmt, 0, SQL_ADD, SQL_LOCK_NO_CHANGE ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLBULKOPERATIONS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else if ( ret == SQL_NEED_DATA ) { statement -> interupted_func = SQL_API_SQLBULKOPERATIONS; statement -> interupted_state = statement -> state; statement -> state = STATE_S8; } else { statement -> state = statement -> interupted_state; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLCancel.c000066400000000000000000000232611446441710500176630ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLCancel.c,v 1.4 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLCancel.c,v $ * Revision 1.4 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.2 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:06 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.1 1999/04/25 23:02:41 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLCancel.c,v $ $Revision: 1.4 $"; SQLRETURN SQLCancel( SQLHSTMT statement_handle ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p", statement ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } #if defined( HAVE_LIBPTH ) || defined( HAVE_LIBPTHREAD ) || defined( HAVE_LIBTHREAD ) /* * Allow this past the thread checks if the driver is at all thread safe, as SQLCancel can * be called across threads */ if ( statement -> connection -> protection_level == 3 ) { thread_protect( SQL_HANDLE_STMT, statement ); } #endif /* * check states */ if ( !CHECK_SQLCANCEL( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); #if defined( HAVE_LIBPTH ) || defined( HAVE_LIBPTHREAD ) || defined( HAVE_LIBTHREAD ) if ( statement -> connection -> protection_level == 3 ) { return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else { return function_return_nodrv( IGNORE_THREAD, statement, SQL_ERROR ); } #else return function_return_nodrv( IGNORE_THREAD, statement, SQL_ERROR ); #endif } ret = SQLCANCEL( statement -> connection, statement -> driver_stmt ); if ( SQL_SUCCEEDED( ret )) { if (ret == SQL_SUCCESS_WITH_INFO ) { SQLULEN nRecs = 0; SQLSMALLINT len; SQLRETURN ret2 = statement->connection->unicode_driver && CHECK_SQLGETDIAGFIELDW( statement->connection ) ? SQLGETDIAGFIELDW ( statement -> connection, SQL_HANDLE_STMT, statement->driver_stmt, 0, SQL_DIAG_NUMBER, &nRecs, 0, &len ) : SQLGETDIAGFIELD( statement -> connection, SQL_HANDLE_STMT, statement->driver_stmt, 0, SQL_DIAG_NUMBER, &nRecs, 0, &len); if ( SQL_SUCCEEDED( ret2 ) && nRecs ) { SQLSMALLINT recNo = 1; while (nRecs--) { SQLCHAR state[12]; /* use the same buffer for both, length must be long enough to hold 5 SQLWCHARs + NULL */ ret2 = statement->connection->unicode_driver && CHECK_SQLGETDIAGRECW( statement->connection ) ? SQLGETDIAGRECW( statement->connection, SQL_HANDLE_STMT, statement->driver_stmt, recNo, (SQLWCHAR*)state, NULL, NULL, 0, NULL ) : SQLGETDIAGREC( statement->connection, SQL_HANDLE_STMT, statement->driver_stmt, recNo, state, NULL, NULL, 0, NULL ) ; if ( SQL_SUCCEEDED( ret2 ) && (statement->connection->unicode_driver ? !memcmp(state, "0\0001\000S\0000\0005\0", 10) : !memcmp(state, "01S05", 5)) ) { ret = SQL_SUCCESS; break; } recNo++; } } } if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { if ( statement -> interupted_func == SQL_API_SQLEXECDIRECT ) { statement -> state = STATE_S1; } else if ( statement -> interupted_func == SQL_API_SQLEXECUTE ) { if ( statement -> hascols ) { statement -> state = STATE_S3; } else { statement -> state = STATE_S2; } } else if ( statement -> interupted_func == SQL_API_SQLBULKOPERATIONS ) { statement -> state = STATE_S6; statement -> eod = 0; } else if ( statement -> interupted_func == SQL_API_SQLSETPOS ) { if ( statement -> interupted_state == STATE_S5 || statement -> interupted_state == STATE_S6 ) { statement -> state = STATE_S6; statement -> eod = 0; } else if ( statement -> interupted_state == STATE_S7 ) { statement -> state = STATE_S7; } } } else if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { statement -> state = STATE_S12; } else { /* Same action as SQLFreeStmt( SQL_CLOSE ) */ if ( statement -> state == STATE_S4 ) { if ( statement -> prepared ) statement -> state = STATE_S2; else statement -> state = STATE_S1; } else { if ( statement -> prepared ) statement -> state = STATE_S3; else statement -> state = STATE_S1; } statement -> hascols = 0; } } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } #if defined( HAVE_LIBPTH ) || defined( HAVE_LIBPTHREAD ) || defined( HAVE_LIBTHREAD ) if ( statement -> connection -> protection_level == 3 ) { return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR, DEFER_R2 ); } else { return function_return( IGNORE_THREAD, statement, ret, DEFER_R2 ); } #else return function_return( IGNORE_THREAD, statement, ret, DEFER_R2 ); #endif } unixODBC-2.3.12/DriverManager/SQLCancelHandle.c000066400000000000000000000252061446441710500210000ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLCancel.c,v $ $Revision: 1.4 $"; SQLRETURN SQLCancelHandle( SQLSMALLINT HandleType, SQLHANDLE Handle ) { SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; switch ( HandleType ) { case SQL_HANDLE_STMT: { DMHSTMT statement = (DMHSTMT) Handle; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\n\t\t\tStatement = %p", statement ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } #if defined( HAVE_LIBPTH ) || defined( HAVE_LIBPTHREAD ) || defined( HAVE_LIBTHREAD ) /* * Allow this past the thread checks if the driver is at all thread safe, as SQLCancel can * be called across threads */ if ( statement -> connection -> protection_level == 3 ) { thread_protect( SQL_HANDLE_STMT, statement ); } #endif /* * check states */ if ( !CHECK_SQLCANCEL( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); #if defined( HAVE_LIBPTH ) || defined( HAVE_LIBPTHREAD ) || defined( HAVE_LIBTHREAD ) if ( statement -> connection -> protection_level == 3 ) { return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else { return function_return_nodrv( IGNORE_THREAD, statement, SQL_ERROR ); } #else return function_return_nodrv( IGNORE_THREAD, statement, SQL_ERROR ); #endif } ret = SQLCANCEL( statement -> connection, statement -> driver_stmt ); if ( SQL_SUCCEEDED( ret )) { if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S10 ) { if ( statement -> interupted_func == SQL_API_SQLEXECDIRECT ) { statement -> state = STATE_S1; } else if ( statement -> interupted_func == SQL_API_SQLEXECUTE ) { if ( statement -> hascols ) { statement -> state = STATE_S3; } else { statement -> state = STATE_S2; } } else if ( statement -> interupted_func == SQL_API_SQLBULKOPERATIONS ) { statement -> state = STATE_S6; statement -> eod = 0; } else if ( statement -> interupted_func == SQL_API_SQLSETPOS ) { if ( statement -> interupted_state == STATE_S5 || statement -> interupted_state == STATE_S6 ) { statement -> state = STATE_S6; statement -> eod = 0; } else if ( statement -> interupted_state == STATE_S7 ) { statement -> state = STATE_S7; } } } else if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { statement -> state = STATE_S12; } else { /* Same action as SQLFreeStmt( SQL_CLOSE ) */ if ( statement -> state == STATE_S4 ) { if ( statement -> prepared ) statement -> state = STATE_S2; else statement -> state = STATE_S1; } else { if ( statement -> prepared ) statement -> state = STATE_S3; else statement -> state = STATE_S1; } statement -> hascols = 0; } } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } #if defined( HAVE_LIBPTH ) || defined( HAVE_LIBPTHREAD ) || defined( HAVE_LIBTHREAD ) if ( statement -> connection -> protection_level == 3 ) { return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR, DEFER_R0 ); } else { return function_return( IGNORE_THREAD, statement, ret, DEFER_R0 ); } #else return function_return( IGNORE_THREAD, statement, ret, DEFER_R0 ); #endif } break; case SQL_HANDLE_DBC: { DMHDBC connection = (DMHDBC) Handle; /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\n\t\t\tConnection = %p", connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } /* * check states */ if ( !CHECK_SQLCANCELHANDLE( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( IGNORE_THREAD, connection, SQL_ERROR ); } ret = SQLCANCELHANDLE( connection, SQL_HANDLE_DBC, connection -> driver_dbc ); /* * The effect this has on connection states is not defined AFAIKS */ if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( IGNORE_THREAD, connection, ret, DEFER_R0 ); } break; default: return SQL_INVALID_HANDLE; break; } } unixODBC-2.3.12/DriverManager/SQLCloseCursor.c000066400000000000000000000154161446441710500207440ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLCloseCursor.c,v 1.5 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLCloseCursor.c,v $ * Revision 1.5 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.4 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/08/15 08:10:33 lurcher * * Couple of small fixes from John L Miller * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:06 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLCloseCursor.c,v $ $Revision: 1.5 $"; SQLRETURN SQLCloseCursor( SQLHSTMT statement_handle ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p", statement ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S2 || statement -> state == STATE_S3 || statement -> state == STATE_S4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( !CHECK_SQLCLOSECURSOR( statement -> connection )) { if ( !CHECK_SQLFREESTMT( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else { ret = SQLFREESTMT( statement -> connection, statement -> driver_stmt, SQL_CLOSE ); } } else { ret = SQLCLOSECURSOR( statement -> connection, statement -> driver_stmt ); } if ( SQL_SUCCEEDED( ret )) { if ( statement -> prepared ) statement -> state = STATE_S3; else statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLColAttribute.c000066400000000000000000000536171446441710500211070ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLColAttribute.c,v 1.19 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLColAttribute.c,v $ * Revision 1.19 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.18 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.17 2008/09/29 14:02:43 lurcher * Fix missing dlfcn group option * * Revision 1.16 2007/04/02 10:50:17 lurcher * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 ) * * Revision 1.15 2006/03/08 09:18:41 lurcher * fix silly typo that was using sizeof( SQL_WCHAR ) instead of SQLWCHAR * * Revision 1.14 2004/11/22 17:02:48 lurcher * Fix unicode/ansi conversion in the SQLGet functions * * Revision 1.13 2004/10/30 20:19:21 peteralexharvey * ODBC spec says last arg for SQLColAttribute() is SQLPOINTER not (SQLEN*). * So switched back to SQLPOINTER. * * Revision 1.12 2004/10/29 10:00:35 lurcher * Fix SQLColAttribute protype * * Revision 1.11 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.10 2003/04/10 13:45:51 lurcher * * Alter the way that SQLDataSources returns the description field (again) * * Revision 1.9 2003/04/09 08:42:18 lurcher * * Allow setting of odbcinstQ lib from odbcinst.ini and Environment * * Revision 1.8 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.7 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.6 2002/11/11 17:10:06 lurcher * * VMS changes * * Revision 1.5 2002/08/19 09:11:49 lurcher * * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state * * Revision 1.4 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.3 2002/04/25 15:16:46 lurcher * * Fix bug with SQLCOlAttribute(s)(W) where a column of zero could not be * used to get the count value * * Revision 1.2 2001/11/16 11:39:17 lurcher * * Add mapping between ODBC 2 and ODBC 3 types for SQLColAttribute(s)(W) * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.6 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.5 2001/07/02 17:09:37 nick * * Add some portability changes * * Revision 1.4 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.3 2001/04/03 16:34:12 nick * * Add support for strangly broken unicode drivers * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 2000/06/20 13:30:07 ngorham * * Fix problems when using bookmarks * * Revision 1.7 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/10/09 00:56:16 ngorham * * Added Manush's patch to map ODBC 3-2 datetime values * * Revision 1.4 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.3 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.2 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.2 1999/06/03 22:20:25 ngorham * * Finished off the ODBC3-2 mapping * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.4 1999/05/03 19:50:43 nick * Another check point * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLColAttribute.c,v $ $Revision: 1.19 $"; SQLINTEGER map_ca_odbc3_to_2( SQLINTEGER field_identifier ) { switch( field_identifier ) { case SQL_DESC_COUNT: field_identifier = SQL_COLUMN_COUNT; break; case SQL_DESC_TYPE: field_identifier = SQL_COLUMN_TYPE; break; case SQL_DESC_LENGTH: field_identifier = SQL_COLUMN_LENGTH; break; case SQL_DESC_PRECISION: field_identifier = SQL_COLUMN_PRECISION; break; case SQL_DESC_SCALE: field_identifier = SQL_COLUMN_SCALE; break; case SQL_DESC_NULLABLE: field_identifier = SQL_COLUMN_NULLABLE; break; case SQL_DESC_NAME: field_identifier = SQL_COLUMN_NAME; break; default: break; } return field_identifier; } SQLRETURN SQLColAttributeA( SQLHSTMT statement_handle, SQLSMALLINT column_number, SQLSMALLINT field_identifier, SQLPOINTER character_attribute, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLLEN *numeric_attribute ) { return SQLColAttribute( statement_handle, (SQLUSMALLINT) column_number, (SQLUSMALLINT) field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } SQLRETURN SQLColAttribute ( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLUSMALLINT field_identifier, SQLPOINTER character_attribute, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLLEN *numeric_attribute ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret = 0; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; int isStringAttr; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tColumn Number = %d\ \n\t\t\tField Identifier = %s\ \n\t\t\tCharacter Attr = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tString Length = %p\ \n\t\t\tNumeric Attribute = %p", statement, column_number, __col_attr_as_string( s1, field_identifier ), character_attribute, buffer_length, string_length, numeric_attribute ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( column_number == 0 && statement -> bookmarks_on == SQL_UB_OFF && statement -> connection -> bookmarks_on == SQL_UB_OFF && field_identifier != SQL_DESC_COUNT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error_api( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version, SQL_API_SQLCOLATTRIBUTE ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * Commented out for now because most drivers can not calc num cols * before Execute (they have no parse). - PAH * if ( field_identifier != SQL_DESC_COUNT && statement -> numcols < column_number ) { __post_internal_error( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version ); return function_return( statement, SQL_ERROR ); } */ /* * check states */ if ( statement -> state == STATE_S1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* MS Driver manager passes this to driver else if ( statement -> state == STATE_S2 && field_identifier != SQL_DESC_COUNT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07005" ); __post_internal_error( &statement -> error, ERROR_07005, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } */ else if ( statement -> state == STATE_S4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLCOLATTRIBUTE ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } switch( field_identifier ) { case SQL_DESC_AUTO_UNIQUE_VALUE: case SQL_DESC_CASE_SENSITIVE: case SQL_DESC_CONCISE_TYPE: case SQL_DESC_COUNT: case SQL_DESC_DISPLAY_SIZE: case SQL_DESC_FIXED_PREC_SCALE: case SQL_DESC_LENGTH: case SQL_DESC_NULLABLE: case SQL_DESC_NUM_PREC_RADIX: case SQL_DESC_OCTET_LENGTH: case SQL_DESC_PRECISION: case SQL_DESC_SCALE: case SQL_DESC_SEARCHABLE: case SQL_DESC_TYPE: case SQL_DESC_UNNAMED: case SQL_DESC_UNSIGNED: case SQL_DESC_UPDATABLE: isStringAttr = 0; break; case SQL_COLUMN_QUALIFIER_NAME: case SQL_COLUMN_NAME: case SQL_COLUMN_LABEL: case SQL_COLUMN_OWNER_NAME: case SQL_COLUMN_TABLE_NAME: case SQL_COLUMN_TYPE_NAME: case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: if ( buffer_length < 0 && buffer_length != SQL_NTS ) { __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } default: isStringAttr = buffer_length >= 0; break; } if ( statement -> connection -> unicode_driver ) { if ( !CHECK_SQLCOLATTRIBUTEW( statement -> connection )) { if ( CHECK_SQLCOLATTRIBUTESW( statement -> connection )) { SQLWCHAR *s1 = NULL; /* * map to the ODBC2 function */ field_identifier = map_ca_odbc3_to_2( field_identifier ); switch( field_identifier ) { case SQL_COLUMN_QUALIFIER_NAME: case SQL_COLUMN_NAME: case SQL_COLUMN_LABEL: case SQL_COLUMN_OWNER_NAME: case SQL_COLUMN_TABLE_NAME: case SQL_COLUMN_TYPE_NAME: case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: if ( SQL_SUCCEEDED( ret ) && character_attribute && buffer_length > 0 ) { s1 = calloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 ), 1); } break; default: break; } ret = SQLCOLATTRIBUTESW( statement -> connection, statement -> driver_stmt, column_number, field_identifier, s1 ? s1 : character_attribute, buffer_length, string_length, numeric_attribute ); switch( field_identifier ) { case SQL_COLUMN_QUALIFIER_NAME: case SQL_COLUMN_NAME: case SQL_COLUMN_LABEL: case SQL_COLUMN_OWNER_NAME: case SQL_COLUMN_TABLE_NAME: case SQL_COLUMN_TYPE_NAME: case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: if ( SQL_SUCCEEDED( ret ) && character_attribute && s1 ) { unicode_to_ansi_copy( character_attribute, buffer_length, s1, SQL_NTS, statement -> connection, NULL ); } if ( SQL_SUCCEEDED( ret ) && string_length ) { *string_length /= sizeof( SQLWCHAR ); } break; default: break; } if ( s1 ) { free( s1 ); } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } else { SQLWCHAR *s1 = NULL; SQLSMALLINT unibuf_len; if ( isStringAttr && character_attribute && buffer_length > 0 ) { s1 = calloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 ), 1); /* Do not overflow, since SQLSMALLINT can only hold -32768 <= x <= 32767 */ unibuf_len = buffer_length > 16383 ? buffer_length : sizeof( SQLWCHAR ) * buffer_length; } ret = SQLCOLATTRIBUTEW( statement -> connection, statement -> driver_stmt, column_number, field_identifier, s1 ? s1 : character_attribute, s1 ? unibuf_len : buffer_length, string_length, numeric_attribute ); if ( SQL_SUCCEEDED( ret ) && isStringAttr && buffer_length > 0 ) { if ( character_attribute && s1 ) { unicode_to_ansi_copy( character_attribute, buffer_length, s1, SQL_NTS, statement -> connection, NULL ); } /* BUGBUG: Windows DM returns the number of bytes for the Unicode string but only for certain ODBC-defined string fields, and when truncating */ switch ( field_identifier ) { case SQL_COLUMN_QUALIFIER_NAME: case SQL_COLUMN_NAME: case SQL_COLUMN_LABEL: case SQL_COLUMN_OWNER_NAME: case SQL_COLUMN_TABLE_NAME: case SQL_COLUMN_TYPE_NAME: case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: if ( ret == SQL_SUCCESS && string_length ) { *string_length /= sizeof( SQLWCHAR ); } break; default: if ( string_length ) { *string_length /= sizeof( SQLWCHAR ); } } } if ( s1 ) { free( s1 ); } } } else { if ( !CHECK_SQLCOLATTRIBUTE( statement -> connection )) { /* * map ODBC 3 types to ODBC 2 */ if ( CHECK_SQLCOLATTRIBUTES( statement -> connection )) { /* * map to the ODBC2 function */ field_identifier = map_ca_odbc3_to_2( field_identifier ); ret = SQLCOLATTRIBUTES( statement -> connection, statement -> driver_stmt, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } else { ret = SQLCOLATTRIBUTE( statement -> connection, statement -> driver_stmt, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } } if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLCOLATTRIBUTE; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else if ( SQL_SUCCEEDED( ret )) { /* * map ODBC 3 datetime fields to ODBC2 */ if ( field_identifier == SQL_COLUMN_TYPE && numeric_attribute ) { *(SQLINTEGER*)numeric_attribute= __map_type(MAP_SQL_D2DM, statement->connection, *(SQLINTEGER*)numeric_attribute); } } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLColAttributeW.c000066400000000000000000000430661446441710500212330ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLColAttributeW.c,v 1.14 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLColAttributeW.c,v $ * Revision 1.14 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.13 2008/08/29 08:01:38 lurcher * Alter the way W functions are passed to the driver * * Revision 1.12 2007/04/02 10:50:18 lurcher * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 ) * * Revision 1.11 2004/11/22 17:02:48 lurcher * Fix unicode/ansi conversion in the SQLGet functions * * Revision 1.10 2004/10/30 20:19:21 peteralexharvey * ODBC spec says last arg for SQLColAttribute() is SQLPOINTER not (SQLEN*). * So switched back to SQLPOINTER. * * Revision 1.9 2004/10/29 10:00:36 lurcher * Fix SQLColAttribute protype * * Revision 1.8 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.7 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.6 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.5 2002/08/19 09:11:49 lurcher * * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state * * Revision 1.4 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.3 2002/04/25 15:16:46 lurcher * * Fix bug with SQLCOlAttribute(s)(W) where a column of zero could not be * used to get the count value * * Revision 1.2 2001/11/16 11:39:17 lurcher * * Add mapping between ODBC 2 and ODBC 3 types for SQLColAttribute(s)(W) * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLColAttributeW.c,v $"; SQLRETURN SQLColAttributeW ( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLUSMALLINT field_identifier, SQLPOINTER character_attribute, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLLEN *numeric_attribute ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tColumn Number = %d\ \n\t\t\tField Identifier = %s\ \n\t\t\tCharacter Attr = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tString Length = %p\ \n\t\t\tNumeric Attribute = %p", statement, column_number, __col_attr_as_string( s1, field_identifier ), character_attribute, buffer_length, string_length, numeric_attribute ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( column_number == 0 && statement -> bookmarks_on == SQL_UB_OFF && statement -> connection -> bookmarks_on == SQL_UB_OFF && field_identifier != SQL_DESC_COUNT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error_api( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version, SQL_API_SQLCOLATTRIBUTE ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * Commented out for now because most drivers can not calc num cols * before Execute (they have no parse). - PAH * if ( field_identifier != SQL_DESC_COUNT && statement -> numcols < column_number ) { __post_internal_error( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version ); return function_return( statement, SQL_ERROR ); } */ /* * check states */ if ( statement -> state == STATE_S1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* else if ( statement -> state == STATE_S2 && field_identifier != SQL_DESC_COUNT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07005" ); __post_internal_error( &statement -> error, ERROR_07005, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } */ else if ( statement -> state == STATE_S4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLCOLATTRIBUTE ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } switch ( field_identifier ) { case SQL_COLUMN_QUALIFIER_NAME: case SQL_COLUMN_NAME: case SQL_COLUMN_LABEL: case SQL_COLUMN_OWNER_NAME: case SQL_COLUMN_TABLE_NAME: case SQL_COLUMN_TYPE_NAME: case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: if ( buffer_length < 0 && buffer_length != SQL_NTS ) { __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver || CHECK_SQLCOLATTRIBUTEW( statement -> connection ) || CHECK_SQLCOLATTRIBUTESW( statement -> connection )) { if ( !CHECK_SQLCOLATTRIBUTEW( statement -> connection )) { if ( CHECK_SQLCOLATTRIBUTESW( statement -> connection )) { /* * map to the ODBC2 function */ field_identifier = map_ca_odbc3_to_2( field_identifier ); ret = SQLCOLATTRIBUTESW( statement -> connection, statement -> driver_stmt, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } else { ret = SQLCOLATTRIBUTEW( statement -> connection, statement -> driver_stmt, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } } else { if ( !CHECK_SQLCOLATTRIBUTE( statement -> connection )) { if ( CHECK_SQLCOLATTRIBUTES( statement -> connection )) { SQLCHAR *as1 = NULL; /* * map to the ODBC2 function */ field_identifier = map_ca_odbc3_to_2( field_identifier ); switch( field_identifier ) { case SQL_COLUMN_QUALIFIER_NAME: case SQL_COLUMN_NAME: case SQL_COLUMN_LABEL: case SQL_COLUMN_OWNER_NAME: case SQL_COLUMN_TABLE_NAME: case SQL_COLUMN_TYPE_NAME: case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: buffer_length = buffer_length / 2; if ( buffer_length > 0 ) { as1 = malloc( buffer_length + 1 ); } break; } ret = SQLCOLATTRIBUTES( statement -> connection, statement -> driver_stmt, column_number, field_identifier, as1 ? as1 : character_attribute, buffer_length, string_length, numeric_attribute ); switch( field_identifier ) { case SQL_COLUMN_QUALIFIER_NAME: case SQL_COLUMN_NAME: case SQL_COLUMN_LABEL: case SQL_COLUMN_OWNER_NAME: case SQL_COLUMN_TABLE_NAME: case SQL_COLUMN_TYPE_NAME: case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: if ( SQL_SUCCEEDED( ret ) && character_attribute && as1 ) { ansi_to_unicode_copy( character_attribute, (char*) as1, SQL_NTS, statement -> connection, NULL ); } if ( SQL_SUCCEEDED( ret ) && string_length ) { *string_length *= sizeof( SQLWCHAR ); } if ( as1 ) { free( as1 ); } break; } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } else { SQLCHAR *as1 = NULL; switch( field_identifier ) { case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_CATALOG_NAME: case SQL_DESC_LABEL: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: case SQL_COLUMN_NAME: buffer_length = buffer_length / 2; if ( buffer_length > 0 ) { as1 = malloc( buffer_length + 1 ); } break; } ret = SQLCOLATTRIBUTE( statement -> connection, statement -> driver_stmt, column_number, field_identifier, as1 ? as1 : character_attribute, buffer_length, string_length, numeric_attribute ); switch( field_identifier ) { case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_CATALOG_NAME: case SQL_DESC_LABEL: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: case SQL_COLUMN_NAME: if ( SQL_SUCCEEDED( ret ) && character_attribute && as1 ) { ansi_to_unicode_copy( character_attribute, (char*) as1, SQL_NTS, statement -> connection, NULL ); } if ( SQL_SUCCEEDED( ret ) && string_length ) { *string_length *= sizeof( SQLWCHAR ); } if ( as1 ) { free( as1 ); } break; default: break; } } } if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLCOLATTRIBUTE; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else if ( SQL_SUCCEEDED( ret )) { /* * map ODBC 3 datetime fields to ODBC2 */ if ( field_identifier == SQL_COLUMN_TYPE && numeric_attribute ) { *(SQLINTEGER*)numeric_attribute= __map_type(MAP_SQL_D2DM, statement->connection, *(SQLINTEGER*)numeric_attribute); } } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLColAttributes.c000066400000000000000000000465071446441710500212720ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLColAttributes.c,v 1.15 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLColAttributes.c,v $ * Revision 1.15 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.14 2008/09/29 14:02:43 lurcher * Fix missing dlfcn group option * * Revision 1.13 2006/03/08 09:18:41 lurcher * fix silly typo that was using sizeof( SQL_WCHAR ) instead of SQLWCHAR * * Revision 1.12 2006/01/06 18:44:35 lurcher * Couple of unicode fixes * * Revision 1.11 2004/11/22 17:02:48 lurcher * Fix unicode/ansi conversion in the SQLGet functions * * Revision 1.10 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.9 2003/08/15 17:34:43 lurcher * * Remove some unneeded ODBC2->3 attribute conversions * * Revision 1.8 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.7 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.6 2002/08/19 09:11:49 lurcher * * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state * * Revision 1.5 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.4 2002/04/25 15:16:46 lurcher * * Fix bug with SQLCOlAttribute(s)(W) where a column of zero could not be * used to get the count value * * Revision 1.3 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.2 2001/11/16 11:39:17 lurcher * * Add mapping between ODBC 2 and ODBC 3 types for SQLColAttribute(s)(W) * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.11 2000/07/31 20:48:01 ngorham * * Fix bugs in SQLGetDiagField and with SQLColAttributes * * Revision 1.10 2000/07/28 16:34:52 ngorham * * Fix problems with SQLColAttributes, and SQLDescribeParam * * Revision 1.9 2000/06/20 13:30:09 ngorham * * Fix problems when using bookmarks * * Revision 1.8 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/11/10 03:51:33 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.6 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.2 1999/06/03 22:20:25 ngorham * * Finished off the ODBC3-2 mapping * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLColAttributes.c,v $ $Revision: 1.15 $"; SQLINTEGER map_ca_odbc2_to_3( SQLINTEGER field_identifier ) { switch( field_identifier ) { case SQL_COLUMN_COUNT: field_identifier = SQL_DESC_COUNT; break; /* case SQL_COLUMN_TYPE: field_identifier = SQL_DESC_TYPE; break; case SQL_COLUMN_LENGTH: field_identifier = SQL_DESC_LENGTH; break; case SQL_COLUMN_PRECISION: field_identifier = SQL_DESC_PRECISION; break; case SQL_COLUMN_SCALE: field_identifier = SQL_DESC_SCALE; break; */ case SQL_COLUMN_NULLABLE: field_identifier = SQL_DESC_NULLABLE; break; case SQL_COLUMN_NAME: field_identifier = SQL_DESC_NAME; break; default: break; } return field_identifier; } SQLRETURN SQLColAttributesA( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLUSMALLINT field_identifier, SQLPOINTER character_attribute, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLLEN *numeric_attribute ) { return SQLColAttributes( statement_handle, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } SQLRETURN SQLColAttributes( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLUSMALLINT field_identifier, SQLPOINTER character_attribute, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLLEN *numeric_attribute ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; int isStringAttr; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tColumn Number = %d\ \n\t\t\tField Identifier = %s\ \n\t\t\tCharacter Attr = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tString Length = %p\ \n\t\t\tNumeric Attribute = %p", statement, column_number, __col_attr_as_string( s1, field_identifier ), character_attribute, buffer_length, string_length, numeric_attribute ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( column_number == 0 && statement -> bookmarks_on == SQL_UB_OFF && statement -> connection -> bookmarks_on == SQL_UB_OFF && field_identifier != SQL_COLUMN_COUNT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error_api( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version, SQL_API_SQLCOLATTRIBUTES ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * Commented out for now because most drivers can not calc num cols * before Execute (they have no parse). - PAH * if ( field_identifier != SQL_DESC_COUNT && statement -> numcols < column_number ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } */ /* * check states */ if ( statement -> state == STATE_S1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* else if ( statement -> state == STATE_S2 && field_identifier != SQL_DESC_COUNT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07005" ); __post_internal_error( &statement -> error, ERROR_07005, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } */ else if ( statement -> state == STATE_S4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLCOLATTRIBUTES ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } switch( field_identifier ) { case SQL_COLUMN_AUTO_INCREMENT: case SQL_COLUMN_CASE_SENSITIVE: case SQL_COLUMN_COUNT: case SQL_COLUMN_DISPLAY_SIZE: case SQL_COLUMN_LENGTH: case SQL_COLUMN_MONEY: case SQL_COLUMN_NULLABLE: case SQL_COLUMN_PRECISION: case SQL_COLUMN_SCALE: case SQL_COLUMN_SEARCHABLE: case SQL_COLUMN_TYPE: case SQL_COLUMN_UNSIGNED: case SQL_COLUMN_UPDATABLE: isStringAttr = 0; break; case SQL_COLUMN_LABEL: case SQL_COLUMN_NAME: case SQL_COLUMN_OWNER_NAME: case SQL_COLUMN_QUALIFIER_NAME: case SQL_COLUMN_TABLE_NAME: case SQL_COLUMN_TYPE_NAME: if ( buffer_length < 0 ) { __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } default: isStringAttr = buffer_length >= 0; break; } if ( statement -> connection -> unicode_driver ) { if ( !CHECK_SQLCOLATTRIBUTESW( statement -> connection )) { if ( CHECK_SQLCOLATTRIBUTEW( statement -> connection )) { SQLWCHAR *s1 = NULL; SQLSMALLINT unibuf_len; /* * map to the ODBC3 function */ field_identifier = map_ca_odbc2_to_3( field_identifier ); if ( isStringAttr && character_attribute && buffer_length > 0 ) { s1 = calloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 ), 1); /* Do not overflow, since SQLSMALLINT can only hold -32768 <= x <= 32767 */ unibuf_len = buffer_length > 16383 ? buffer_length : sizeof( SQLWCHAR ) * buffer_length; } ret = SQLCOLATTRIBUTEW( statement -> connection, statement -> driver_stmt, column_number, field_identifier, s1 ? s1 : character_attribute, s1 ? unibuf_len : buffer_length, string_length, numeric_attribute ); if ( SQL_SUCCEEDED( ret ) && isStringAttr && character_attribute && buffer_length > 0 && s1 ) { if ( string_length && ret == SQL_SUCCESS ) { *string_length /= sizeof ( SQLWCHAR ); } unicode_to_ansi_copy( character_attribute, buffer_length, s1, SQL_NTS, statement -> connection, NULL ); } if ( s1 ) { free( s1 ); } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } else { SQLWCHAR *s1 = NULL; if ( character_attribute && buffer_length > 0 ) { s1 = calloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 ), 1); } ret = SQLCOLATTRIBUTESW( statement -> connection, statement -> driver_stmt, column_number, field_identifier, s1 ? s1 : character_attribute, buffer_length, string_length, numeric_attribute ); if ( SQL_SUCCEEDED( ret ) && character_attribute ) { unicode_to_ansi_copy( character_attribute, buffer_length, s1, SQL_NTS, statement -> connection, NULL ); } if ( SQL_SUCCEEDED( ret ) && string_length && character_attribute ) { *string_length /= sizeof( SQLWCHAR ); } if ( s1 ) { free( s1 ); } } } else { if ( !CHECK_SQLCOLATTRIBUTES( statement -> connection )) { if ( CHECK_SQLCOLATTRIBUTE( statement -> connection )) { /* * map to the ODBC3 function */ field_identifier = map_ca_odbc2_to_3( field_identifier ); ret = SQLCOLATTRIBUTE( statement -> connection, statement -> driver_stmt, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } else { ret = SQLCOLATTRIBUTES( statement -> connection, statement -> driver_stmt, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } } if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLCOLATTRIBUTES; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else if ( SQL_SUCCEEDED( ret )) { /* * map ODBC 3 datetime fields to ODBC2 */ if ( field_identifier == SQL_COLUMN_TYPE && numeric_attribute && statement -> connection -> driver_version == SQL_OV_ODBC2 ) { SQLINTEGER na; memcpy( &na, numeric_attribute, sizeof( na )); switch( na ) { case SQL_TYPE_TIME: na = SQL_TIME; memcpy( numeric_attribute, &na, sizeof( na )); break; case SQL_TYPE_DATE: na = SQL_DATE; memcpy( numeric_attribute, &na, sizeof( na )); break; case SQL_TYPE_TIMESTAMP: na = SQL_TIMESTAMP; memcpy( numeric_attribute, &na, sizeof( na )); break; } } } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLColAttributesW.c000066400000000000000000000465051446441710500214170ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLColAttributesW.c,v 1.14 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLColAttributesW.c,v $ * Revision 1.14 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.13 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.12 2008/08/29 08:01:38 lurcher * Alter the way W functions are passed to the driver * * Revision 1.11 2007/02/28 15:37:47 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.10 2004/11/22 17:02:48 lurcher * Fix unicode/ansi conversion in the SQLGet functions * * Revision 1.9 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.8 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.7 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.6 2002/08/19 09:11:49 lurcher * * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state * * Revision 1.5 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.4 2002/04/25 15:16:46 lurcher * * Fix bug with SQLCOlAttribute(s)(W) where a column of zero could not be * used to get the count value * * Revision 1.3 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.2 2001/11/16 11:39:17 lurcher * * Add mapping between ODBC 2 and ODBC 3 types for SQLColAttribute(s)(W) * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLColAttributesW.c,v $"; SQLRETURN SQLColAttributesW( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLUSMALLINT field_identifier, SQLPOINTER character_attribute, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLLEN *numeric_attribute ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLCOLATTRIBUTEW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLCOLATTRIBUTEW( parent_statement -> connection, statement_handle, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tColumn Number = %d\ \n\t\t\tField Identifier = %s\ \n\t\t\tCharacter Attr = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tString Length = %p\ \n\t\t\tNumeric Attribute = %p", statement, column_number, __col_attr_as_string( s1, field_identifier ), character_attribute, buffer_length, string_length, numeric_attribute ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( column_number == 0 && statement -> bookmarks_on == SQL_UB_OFF && statement -> connection -> bookmarks_on == SQL_UB_OFF && field_identifier != SQL_COLUMN_COUNT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error_api( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version, SQL_API_SQLCOLATTRIBUTES ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * Commented out for now because most drivers can not calc num cols * before Execute (they have no parse). - PAH * if ( field_identifier != SQL_DESC_COUNT && statement -> numcols < column_number ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } */ /* * check states */ if ( statement -> state == STATE_S1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S2 && field_identifier != SQL_DESC_COUNT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07005" ); __post_internal_error( &statement -> error, ERROR_07005, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLCOLATTRIBUTES ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } switch ( field_identifier ) { case SQL_COLUMN_LABEL: case SQL_COLUMN_NAME: case SQL_COLUMN_OWNER_NAME: case SQL_COLUMN_QUALIFIER_NAME: case SQL_COLUMN_TABLE_NAME: case SQL_COLUMN_TYPE_NAME: if ( buffer_length < 0 && buffer_length != SQL_NTS ) { __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver || CHECK_SQLCOLATTRIBUTESW( statement -> connection ) || CHECK_SQLCOLATTRIBUTEW( statement -> connection )) { if ( !CHECK_SQLCOLATTRIBUTESW( statement -> connection )) { if ( CHECK_SQLCOLATTRIBUTEW( statement -> connection )) { /* * map to the ODBC3 function */ field_identifier = map_ca_odbc2_to_3( field_identifier ); ret = SQLCOLATTRIBUTEW( statement -> connection, statement -> driver_stmt, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } else { ret = SQLCOLATTRIBUTESW( statement -> connection, statement -> driver_stmt, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } } else { if ( !CHECK_SQLCOLATTRIBUTES( statement -> connection )) { if ( CHECK_SQLCOLATTRIBUTE( statement -> connection )) { SQLCHAR *as1 = NULL; /* * map to the ODBC3 function */ field_identifier = map_ca_odbc2_to_3( field_identifier ); switch( field_identifier ) { case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_CATALOG_NAME: case SQL_DESC_LABEL: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: case SQL_COLUMN_NAME: buffer_length = buffer_length / 2; if ( buffer_length > 0 ) { as1 = malloc( buffer_length + 1 ); } break; default: break; } ret = SQLCOLATTRIBUTE( statement -> connection, statement -> driver_stmt, column_number, field_identifier, as1 ? as1 : character_attribute, buffer_length, string_length, numeric_attribute ); switch( field_identifier ) { case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_CATALOG_NAME: case SQL_DESC_LABEL: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: case SQL_COLUMN_NAME: if ( SQL_SUCCEEDED( ret ) && character_attribute && as1 ) { ansi_to_unicode_copy( character_attribute, (char*) as1, SQL_NTS, statement -> connection, NULL ); } if ( as1 ) { free( as1 ); } if ( SQL_SUCCEEDED( ret ) && string_length ) { *string_length *= sizeof( SQLWCHAR ); } break; default: break; } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } else { SQLCHAR *as1 = NULL; switch( field_identifier ) { case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_CATALOG_NAME: case SQL_DESC_LABEL: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: case SQL_COLUMN_NAME: buffer_length = buffer_length / 2; if ( buffer_length > 0 ) { as1 = malloc( buffer_length + 1 ); } break; default: break; } ret = SQLCOLATTRIBUTES( statement -> connection, statement -> driver_stmt, column_number, field_identifier, as1 ? as1 : character_attribute, buffer_length, string_length, numeric_attribute ); switch( field_identifier ) { case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_CATALOG_NAME: case SQL_DESC_LABEL: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: case SQL_COLUMN_NAME: if ( SQL_SUCCEEDED( ret ) && character_attribute && as1 ) { ansi_to_unicode_copy( character_attribute, (char*) as1, SQL_NTS, statement -> connection, NULL ); } if ( as1 ) { free( as1 ); } if ( SQL_SUCCEEDED( ret ) && string_length && character_attribute ) { *string_length *= sizeof( SQLWCHAR ); } break; default: break; } } } if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLCOLATTRIBUTES; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else if ( SQL_SUCCEEDED( ret )) { /* * map ODBC 3 datetime fields to ODBC2 */ if ( field_identifier == SQL_COLUMN_TYPE && numeric_attribute && statement -> connection -> driver_version == SQL_OV_ODBC2 ) { SQLINTEGER na; memcpy( &na, numeric_attribute, sizeof( na )); switch( na ) { case SQL_TYPE_TIME: na = SQL_TIME; memcpy( numeric_attribute, &na, sizeof( na )); break; case SQL_TYPE_DATE: na = SQL_DATE; memcpy( numeric_attribute, &na, sizeof( na )); break; case SQL_TYPE_TIMESTAMP: na = SQL_TIMESTAMP; memcpy( numeric_attribute, &na, sizeof( na )); break; } } } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLColumnPrivileges.c000066400000000000000000000307741446441710500217740ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLColumnPrivileges.c,v 1.8 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLColumnPrivileges.c,v $ * Revision 1.8 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.7 2005/11/21 17:25:43 lurcher * A few DM fixes for Oracle's ODBC driver * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.3 1999/05/03 19:50:43 nick * Another check point * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLColumnPrivileges.c,v $ $Revision: 1.8 $"; SQLRETURN SQLColumnPrivilegesA( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLCHAR *column_name, SQLSMALLINT name_length4 ) { return SQLColumnPrivileges( statement_handle, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, column_name, name_length4 ); } SQLRETURN SQLColumnPrivileges( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLCHAR *column_name, SQLSMALLINT name_length4 ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Name = %s\ \n\t\t\tColumn Name = %s", statement, __string_with_length( s1, catalog_name, name_length1 ), __string_with_length( s2, schema_name, name_length2 ), __string_with_length( s3, table_name, name_length3 ), __string_with_length( s4, column_name, name_length4 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( table_name == NULL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if (( name_length1 < 0 && name_length1 != SQL_NTS ) || ( name_length2 < 0 && name_length2 != SQL_NTS ) || ( name_length3 < 0 && name_length3 != SQL_NTS ) || ( name_length4 < 0 && name_length4 != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLCOLUMNPRIVILEGES ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1, *s2, *s3, *s4; int wlen; if ( !CHECK_SQLCOLUMNPRIVILEGESW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( catalog_name, name_length1, statement -> connection, &wlen ); name_length1 = wlen; s2 = ansi_to_unicode_alloc( schema_name, name_length2, statement -> connection, &wlen ); name_length2 = wlen; s3 = ansi_to_unicode_alloc( table_name, name_length3, statement -> connection, &wlen ); name_length3 = wlen; s4 = ansi_to_unicode_alloc( column_name, name_length4, statement -> connection, &wlen ); name_length4 = wlen; ret = SQLCOLUMNPRIVILEGESW( statement -> connection , statement -> driver_stmt, s1, name_length1, s2, name_length2, s3, name_length3, s4, name_length4 ); if( s1 ) free( s1 ); if( s2 ) free( s2 ); if( s3 ) free( s3 ); if( s4 ) free( s4 ); } else { if ( !CHECK_SQLCOLUMNPRIVILEGES( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLCOLUMNPRIVILEGES( statement -> connection , statement -> driver_stmt, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, column_name, name_length4 ); } if ( SQL_SUCCEEDED( ret )) { statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLCOLUMNPRIVILEGES; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLColumnPrivilegesW.c000066400000000000000000000300241446441710500221070ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLColumnPrivilegesW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLColumnPrivilegesW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/08/29 08:01:38 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:47 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLColumnPrivilegesW.c,v $"; SQLRETURN SQLColumnPrivilegesW( SQLHSTMT statement_handle, SQLWCHAR *catalog_name, SQLSMALLINT name_length1, SQLWCHAR *schema_name, SQLSMALLINT name_length2, SQLWCHAR *table_name, SQLSMALLINT name_length3, SQLWCHAR *column_name, SQLSMALLINT name_length4 ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLCOLUMNPRIVILEGESW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLCOLUMNPRIVILEGESW( parent_statement -> connection, statement_handle, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, column_name, name_length4 ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Name = %s\ \n\t\t\tColumn Name = %s", statement, __wstring_with_length( s1, catalog_name, name_length1 ), __wstring_with_length( s2, schema_name, name_length2 ), __wstring_with_length( s3, table_name, name_length3 ), __wstring_with_length( s4, column_name, name_length4 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( table_name == NULL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if (( name_length1 < 0 && name_length1 != SQL_NTS ) || ( name_length2 < 0 && name_length2 != SQL_NTS ) || ( name_length3 < 0 && name_length3 != SQL_NTS ) || ( name_length4 < 0 && name_length4 != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLCOLUMNPRIVILEGES ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver || CHECK_SQLCOLUMNPRIVILEGESW( statement -> connection )) { if ( !CHECK_SQLCOLUMNPRIVILEGESW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLCOLUMNPRIVILEGESW( statement -> connection , statement -> driver_stmt, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, column_name, name_length4 ); } else { SQLCHAR *as1, *as2, *as3, *as4; int clen; if ( !CHECK_SQLCOLUMNPRIVILEGES( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * The MS book says do this in place, but that causes more problems * than we need */ as1 = (SQLCHAR*) unicode_to_ansi_alloc( catalog_name, name_length1, statement -> connection, &clen ); name_length1 = clen; as2 = (SQLCHAR*) unicode_to_ansi_alloc( schema_name, name_length2, statement -> connection, &clen ); name_length2 = clen; as3 = (SQLCHAR*) unicode_to_ansi_alloc( table_name, name_length3, statement -> connection, &clen ); name_length3 = clen; as4 = (SQLCHAR*) unicode_to_ansi_alloc( column_name, name_length4, statement -> connection, &clen ); name_length4 = clen; ret = SQLCOLUMNPRIVILEGES( statement -> connection , statement -> driver_stmt, as1, name_length1, as2, name_length2, as3, name_length3, as4, name_length4 ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); if ( as3 ) free( as3 ); if ( as4 ) free( as4 ); } if ( SQL_SUCCEEDED( ret )) { statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLCOLUMNPRIVILEGES; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLColumns.c000066400000000000000000000312661446441710500201220ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLColumns.c,v 1.8 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLColumns.c,v $ * Revision 1.8 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.7 2008/08/29 08:01:38 lurcher * Alter the way W functions are passed to the driver * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.9 2000/06/20 12:43:58 ngorham * * Fix bug that caused a success with info message from SQLExecute or * SQLExecDirect to be lost if used with a ODBC 3 driver and the application * called SQLGetDiagRec * * Revision 1.8 2000/06/16 16:52:16 ngorham * * Stop info messages being lost when calling SQLExecute etc on ODBC 3 * drivers, the SQLNumResultCols were clearing the error before * function return had a chance to get to them * * Revision 1.7 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.2 1999/06/07 01:29:30 pharvey * *** empty log message *** * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.4 1999/05/03 19:50:43 nick * Another check point * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLColumns.c,v $ $Revision: 1.8 $"; SQLRETURN SQLColumnsA( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLCHAR *column_name, SQLSMALLINT name_length4 ) { return SQLColumns( statement_handle, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, column_name, name_length4 ); } SQLRETURN SQLColumns( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLCHAR *column_name, SQLSMALLINT name_length4 ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Name = %s\ \n\t\t\tColumn Name = %s", statement, __string_with_length( s1, catalog_name, name_length1 ), __string_with_length( s2, schema_name, name_length2 ), __string_with_length( s3, table_name, name_length3 ), __string_with_length( s4, column_name, name_length4 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( catalog_name && name_length1 < 0 && name_length1 != SQL_NTS ) || ( schema_name && name_length2 < 0 && name_length2 != SQL_NTS ) || ( table_name && name_length3 < 0 && name_length3 != SQL_NTS ) || ( column_name && name_length4 < 0 && name_length4 != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLCOLUMNS ) { __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1, *s2, *s3, *s4; int wlen; if ( !CHECK_SQLCOLUMNSW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( catalog_name, name_length1, statement -> connection, &wlen ); name_length1 = wlen; s2 = ansi_to_unicode_alloc( schema_name, name_length2, statement -> connection, &wlen ); name_length2 = wlen; s3 = ansi_to_unicode_alloc( table_name, name_length3, statement -> connection, &wlen ); name_length3 = wlen; s4 = ansi_to_unicode_alloc( column_name, name_length4, statement -> connection, &wlen ); name_length4 = wlen; ret = SQLCOLUMNSW( statement -> connection , statement -> driver_stmt, s1, name_length1, s2, name_length2, s3, name_length3, s4, name_length4 ); if( s1 ) free( s1 ); if( s2 ) free( s2 ); if( s3 ) free( s3 ); if( s4 ) free( s4 ); } else { if ( !CHECK_SQLCOLUMNS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLCOLUMNS( statement -> connection , statement -> driver_stmt, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, column_name, name_length4 ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /******** * Added this to get num cols from drivers which can only tell * us after execute - PAH */ /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, statement, ret, TRUE, DEFER_R1 ); } SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); /******/ #endif statement -> state = STATE_S5; statement -> hascols = 1; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLCOLUMNS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLColumnsW.c000066400000000000000000000270621446441710500202500ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLColumnsW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLColumnsW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/08/29 08:01:38 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:47 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:35 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLColumnsW.c,v $"; SQLRETURN SQLColumnsW( SQLHSTMT statement_handle, SQLWCHAR *catalog_name, SQLSMALLINT name_length1, SQLWCHAR *schema_name, SQLSMALLINT name_length2, SQLWCHAR *table_name, SQLSMALLINT name_length3, SQLWCHAR *column_name, SQLSMALLINT name_length4 ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLCOLUMNSW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLCOLUMNSW( parent_statement -> connection, statement_handle, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, column_name, name_length4 ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Name = %s\ \n\t\t\tColumn Type = %s", statement, __wstring_with_length( s1, catalog_name, name_length1 ), __wstring_with_length( s2, schema_name, name_length2 ), __wstring_with_length( s3, table_name, name_length3 ), __wstring_with_length( s4, column_name, name_length4 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( catalog_name && name_length1 < 0 && name_length1 != SQL_NTS ) || ( schema_name && name_length2 < 0 && name_length2 != SQL_NTS ) || ( table_name && name_length3 < 0 && name_length3 != SQL_NTS ) || ( column_name && name_length4 < 0 && name_length4 != SQL_NTS )) { __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLCOLUMNS ) { __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver || CHECK_SQLCOLUMNSW( statement -> connection )) { if ( !CHECK_SQLCOLUMNSW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLCOLUMNSW( statement -> connection , statement -> driver_stmt, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, column_name, name_length4 ); } else { SQLCHAR *as1, *as2, *as3, *as4; int clen; if ( !CHECK_SQLCOLUMNS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } as1 = (SQLCHAR*) unicode_to_ansi_alloc( catalog_name, name_length1, statement -> connection, &clen ); name_length1 = clen; as2 = (SQLCHAR*) unicode_to_ansi_alloc( schema_name, name_length2, statement -> connection, &clen ); name_length2 = clen; as3 = (SQLCHAR*) unicode_to_ansi_alloc( table_name, name_length3, statement -> connection, &clen ); name_length3 = clen; as4 = (SQLCHAR*) unicode_to_ansi_alloc( column_name, name_length4, statement -> connection, &clen ); name_length4 = clen; ret = SQLCOLUMNS( statement -> connection , statement -> driver_stmt, as1, name_length1, as2, name_length2, as3, name_length3, as4, name_length4 ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); if ( as3 ) free( as3 ); if ( as4 ) free( as4 ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /******** * Added this to get num cols from drivers which can only tell * us after execute - PAH */ /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, statement, ret, TRUE, DEFER_R1 ); } SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); /******/ #endif statement -> hascols = 1; statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLCOLUMNS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLConnect.c000066400000000000000000004252321446441710500200730ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLConnect.c,v 1.66 2009/05/15 15:23:56 lurcher Exp $ * * $Log: SQLConnect.c,v $ * Revision 1.66 2009/05/15 15:23:56 lurcher * Fix pooled connection thread problems * * Revision 1.65 2009/03/26 14:39:21 lurcher * Fix typo in isql * * Revision 1.64 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.63 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.62 2009/01/13 10:54:13 lurcher * Allow setting of default Threading level * * Revision 1.61 2008/11/24 12:44:23 lurcher * Try and tidu up the connection version checking * * Revision 1.60 2008/09/29 14:02:43 lurcher * Fix missing dlfcn group option * * Revision 1.59 2008/08/29 08:01:38 lurcher * Alter the way W functions are passed to the driver * * Revision 1.58 2008/06/17 16:14:13 lurcher * Fix for iconv memory leak and some fixes for CYGWIN * * Revision 1.57 2008/05/30 12:04:55 lurcher * Fix a couple of build problems and get ready for the next release * * Revision 1.56 2007/07/13 14:01:18 lurcher * Fix problem when not using iconv * * Revision 1.55 2007/03/13 10:35:38 lurcher * clear the iconv handles after use * * Revision 1.54 2007/03/07 22:53:29 lurcher * Fix pooling iconv leak, and try and allow the W entry point in a setup lib to be used * * Revision 1.53 2007/01/02 10:27:50 lurcher * Fix descriptor leak with unicode only driver * * Revision 1.52 2006/10/13 08:43:10 lurcher * * * Remove debug printf * * Revision 1.51 2006/06/28 08:08:41 lurcher * Add timestamp with timezone to Postgres7.1 driver * * Revision 1.50 2006/04/11 10:22:56 lurcher * Fix a data type check * * Revision 1.49 2005/11/08 09:37:10 lurcher * Allow the driver and application to have different length handles * * Revision 1.48 2005/10/06 08:50:58 lurcher * Fix problem with SQLDrivers not returning first entry * * Revision 1.47 2005/07/08 12:11:23 lurcher * * Fix a cursor lib problem (it was broken if you did metadata calls) * Alter the params to SQLParamOptions to use SQLULEN * * Revision 1.46 2005/05/24 16:51:57 lurcher * Fix potential for the driver to no have its handle closed * * Revision 1.45 2005/03/01 14:24:40 lurcher * Change DontDLClose default * * Revision 1.44 2005/02/01 10:24:23 lurcher * Cope if SHLIBEXT is not set * * Revision 1.43 2004/12/20 18:06:13 lurcher * Fix small typo in SQLConnect * * Revision 1.42 2004/09/22 09:13:38 lurcher * Replaced crypt auth in postgres with md5 for 7.1 Postgres driver * * Revision 1.41 2004/09/08 16:38:53 lurcher * * Get ready for a 2.2.10 release * * Revision 1.40 2004/07/25 00:42:02 peteralexharvey * for OS2 port * * Revision 1.39 2004/07/24 17:55:37 lurcher * Sync up CVS * * Revision 1.38 2004/06/16 14:42:03 lurcher * * * Fix potential corruption with threaded use and SQLEndTran * * Revision 1.37 2004/05/10 15:58:52 lurcher * * Stop the driver manager calling free handle twice * * Revision 1.36 2004/04/01 12:34:26 lurcher * * Fix minor memory leak * Add support for 64bit HPUX * * Revision 1.35 2004/02/26 15:52:03 lurcher * * Fix potential to call SQLFreeEnv in driver twice * Set default value if call to SQLGetPrivateProfileString fails because * the odbcinst.ini file is not found, and can't be created * * Revision 1.34 2004/02/18 15:47:44 lurcher * * Fix a leak in the iconv code * * Revision 1.33 2004/02/17 11:05:35 lurcher * * 2.2.8 release * * Revision 1.32 2004/02/02 10:10:45 lurcher * * Fix some connection pooling problems * Include sqlucode in sqlext * * Revision 1.31 2003/12/01 16:37:17 lurcher * * Fix a bug in SQLWritePrivateProfileString * * Revision 1.30 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.29 2003/10/06 15:43:46 lurcher * * Fix cursor lib to work with SQLFetch as well as the other fetch calls * Update README.OSX to detail building the cursor lib * * Revision 1.28 2003/09/08 15:34:29 lurcher * * A couple of small but perfectly formed fixes * * Revision 1.27 2003/08/15 17:34:43 lurcher * * Remove some unneeded ODBC2->3 attribute conversions * * Revision 1.26 2003/08/08 11:14:21 lurcher * * Fix UNICODE problem in SQLDriverConnectW * * Revision 1.25 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.24 2003/02/26 13:05:42 lurcher * * Update for new autoconf * * Revision 1.23 2003/02/25 13:28:28 lurcher * * Allow errors on the drivers AllocHandle to be reported * Fix a problem that caused errors to not be reported in the log * Remove a redundant line from the spec file * * Revision 1.22 2003/02/06 18:13:01 lurcher * * Another HP_UX twiddle * * Revision 1.21 2003/02/06 12:58:25 lurcher * * Fix a speeling problem :-) * * Revision 1.20 2002/12/20 11:36:46 lurcher * * Update DMEnvAttr code to allow setting in the odbcinst.ini entry * * Revision 1.19 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.18 2002/11/19 18:52:27 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.17 2002/11/13 15:59:20 lurcher * * More VMS changes * * Revision 1.16 2002/08/27 08:49:02 lurcher * * New version number and fix for cursor lib loading * * Revision 1.15 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.14 2002/08/12 13:17:52 lurcher * * Replicate the way the MS DM handles loading of driver libs, and allocating * handles in the driver. usage counting in the driver means that dlopen is * only called for the first use, and dlclose for the last. AllocHandle for * the driver environment is only called for the first time per driver * per application environment. * * Revision 1.13 2002/07/25 09:30:26 lurcher * * Additional unicode and iconv changes * * Revision 1.12 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.11 2002/07/12 09:01:37 lurcher * * Fix problem, with SAPDB where if the connection specifies ODBC 2, the * don't make use of the ODBC 3 method of SQLGetFunctions * * Revision 1.10 2002/07/04 17:27:56 lurcher * * Small bug fixes * * Revision 1.8 2002/05/24 12:42:49 lurcher * * Alter NEWS and ChangeLog to match their correct usage * Additional UNICODE tweeks * * Revision 1.7 2002/03/26 09:35:46 lurcher * * Extend naming of cursor lib to work on non linux platforms * (it expected a .so) * * Revision 1.6 2002/02/21 18:44:09 lurcher * * Fix bug on 32 bit platforms without long long support * Add option to set environment variables from the ini file * * Revision 1.5 2002/01/21 18:00:51 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.4 2001/12/19 15:55:53 lurcher * * Add option to disable calling of SQLGetFunctions in driver * * Revision 1.3 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.2 2001/11/21 16:58:25 lurcher * * Assorted fixes to make the MAX OSX build work nicer * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.31 2001/09/27 17:05:48 nick * * Assorted fixes and tweeks * * Revision 1.30 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * Revision 1.29 2001/08/03 15:19:00 nick * * Add changes to set values before connect * * Revision 1.28 2001/07/31 12:03:46 nick * * Fix how the DM gets the CLI year for SQLGetInfo * Fix small bug in strncasecmp * * Revision 1.27 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.26 2001/06/25 12:55:15 nick * * Fix threading problem with multiple ENV's * * Revision 1.25 2001/06/13 11:23:11 nick * * Fix a couple of portability problems * * Revision 1.24 2001/05/31 16:05:55 nick * * Fix problems with postgres closing local sockets * Make odbctest build with QT 3 (it doesn't work due to what I think are bugs * in QT 3) * Fix a couple of problems in the cursor lib * * Revision 1.23 2001/05/23 11:44:44 nick * * Fix typo * * Revision 1.22 2001/05/09 11:56:47 nick * * Add support for libtool 1.4 * * Revision 1.21 2001/04/18 15:03:37 nick * * Fix problem when going to DB2 unicode driver * * Revision 1.20 2001/04/16 22:35:10 nick * * More tweeks to the AutoTest code * * Revision 1.19 2001/04/16 15:41:24 nick * * Fix some problems calling non existing error funcs * * Revision 1.18 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.17 2001/04/04 11:30:38 nick * * Fix a memory leak in Postgre7.1 * Fix a problem with timed out pooled connections * Add time to live option for pooled connections * * Revision 1.16 2001/04/03 16:34:12 nick * * Add support for strangly broken unicode drivers * * Revision 1.15 2001/03/30 08:35:39 nick * * Fix a couple of pooling problems * * Revision 1.14 2001/03/02 14:24:23 nick * * Fix thread detection for Solaris * * Revision 1.13 2001/02/12 11:20:22 nick * * Add supoort for calling SQLDriverLoad and SQLDriverUnload * * Revision 1.12 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.11 2000/12/18 13:02:13 nick * * More buf fixes * * Revision 1.10 2000/12/17 11:02:37 nick * * Fix extra '*' * * Revision 1.9 2000/12/17 11:00:32 nick * * Add thread safe bits to pooling * * Revision 1.8 2000/12/14 18:10:19 nick * * Add connection pooling * * Revision 1.7 2000/11/29 11:26:18 nick * * Add unicode bits * * Revision 1.6 2000/11/22 18:35:43 nick * * Check input handle before touching output handle * * Revision 1.5 2000/11/22 17:19:32 nick * * Fix tracing problem in SQLConnect * * Revision 1.4 2000/11/14 10:15:27 nick * * Add test for localtime_r * * Revision 1.3 2000/10/25 08:58:55 nick * * Fix crash when null server and SQL_NTS is passed in * * Revision 1.2 2000/10/13 15:18:49 nick * * Change string length parameter from SQLINTEGER to SQLSMALLINT * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.30 2000/07/28 14:57:29 ngorham * * Don't copy the function pointers for ColAttribute, ColAttributes just * set can_supply * * Revision 1.29 2000/06/27 17:34:09 ngorham * * Fix a problem when the second part of the connect failed a seg fault * was generated in the error reporting * * Revision 1.28 2001/05/26 19:11:37 ngorham * * Add SQLCopyDesc functionality and fix bug that was stopping messages * coming out of SQLConnect * * Revision 1.27 2000/05/21 21:49:19 ngorham * * Assorted fixes * * Revision 1.26 2000/04/27 20:49:03 ngorham * * Fixes to work with Star Office 5.2 * * Revision 1.25 2000/04/19 22:00:57 ngorham * * We can always supply SQLGetFunctions * * Revision 1.24 2000/03/11 15:55:47 ngorham * * A few more changes and bug fixes (see NEWS) * * Revision 1.23 2000/02/25 00:02:00 ngorham * * Add a patch to support IBM DB2, and Solaris threads * * Revision 1.22 2000/02/02 07:55:20 ngorham * * Add flag to disable SQLFetch -> SQLExtendedFetch mapping * * Revision 1.21 1999/12/28 15:05:00 ngorham * * Fix bug that caused StarOffice to fail. A SQLConnect, SQLDisconnect, * followed by another SQLConnect on the same DBC would fail. * * Revision 1.20 1999/12/17 09:40:30 ngorham * * Change a error return from HY004 to IM004 * * Revision 1.19 1999/12/14 19:02:25 ngorham * * Mask out the password fields in the logging * * Revision 1.18 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.17 1999/11/10 03:51:33 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.16 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.15 1999/10/14 06:49:24 ngorham * * Remove @all_includes@ from Drivers/MiniSQL/Makefile.am * * Revision 1.14 1999/10/09 00:15:58 ngorham * * Add mapping from SQL_TYPE_X to SQL_X and SQL_C_TYPE_X to SQL_C_X * when the driver is a ODBC 2 one * * Revision 1.13 1999/10/07 20:39:25 ngorham * * Added .cvsignore files and fixed a couple of bugs in the DM * * Revision 1.12 1999/10/06 07:10:46 ngorham * * As the book says check dlerror after a dl func * * Revision 1.11 1999/10/06 07:01:25 ngorham * * Added more support for non linux platforms * * Revision 1.10 1999/09/26 18:55:03 ngorham * * Fixed a problem where the cursor lib was being used by default * * Revision 1.9 1999/09/24 22:54:52 ngorham * * Fixed some unchanged dlopen,dlsym,dlclose functions * * Revision 1.8 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.7 1999/09/20 21:46:49 ngorham * * Added support for libtld dlopen replace * * Revision 1.6 1999/09/19 22:24:33 ngorham * * Added support for the cursor library * * Revision 1.5 1999/08/03 21:47:39 shandyb * Moving to automake: changed files in DriverManager * * Revision 1.4 1999/07/10 21:10:15 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.4 1999/06/07 01:29:30 pharvey * *** empty log message *** * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:20 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.7 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.6 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.5 1999/05/03 19:50:43 nick * Another check point * * Revision 1.4 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.3 1999/04/29 21:40:58 nick * End of another night :-) * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #ifdef HAVE_SYS_TIME_H #include #elif defined(HAVE_TIME_H) #include #endif #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLConnect.c,v $ $Revision: 1.66 $"; #ifdef __OS2__ #define CURSOR_LIB "ODBCCR" #else #define CURSOR_LIB "libodbccr" #endif #ifndef CURSOR_LIB_VER #ifdef DEFINE_CURSOR_LIB_VER #define CURSOR_LIB_VER "2" #endif #endif /* * structure to contain the loaded lib entry points */ static struct driver_func template_func[] = { /* 00 */ { SQL_API_SQLALLOCCONNECT, "SQLAllocConnect", (void*)SQLAllocConnect }, /* 01 */ { SQL_API_SQLALLOCENV, "SQLAllocEnv", (void*)SQLAllocEnv }, /* 02 */ { SQL_API_SQLALLOCHANDLE, "SQLAllocHandle", (void*)SQLAllocHandle }, /* 03 */ { SQL_API_SQLALLOCSTMT, "SQLAllocStmt", (void*)SQLAllocStmt }, /* 04 */ { SQL_API_SQLALLOCHANDLESTD, "SQLAllocHandleStd", (void*)SQLAllocHandleStd }, /* 05 */ { SQL_API_SQLBINDCOL, "SQLBindCol", (void*)SQLBindCol }, /* 06 */ { SQL_API_SQLBINDPARAM, "SQLBindParam", (void*)SQLBindParam }, /* 07 */ { SQL_API_SQLBINDPARAMETER, "SQLBindParameter", (void*)SQLBindParameter }, /* 08 */ { SQL_API_SQLBROWSECONNECT, "SQLBrowseConnect", (void*)SQLBrowseConnect, (void*)SQLBrowseConnectW }, /* 09 */ { SQL_API_SQLBULKOPERATIONS, "SQLBulkOperations", (void*)SQLBulkOperations }, /* 10 */ { SQL_API_SQLCANCEL, "SQLCancel", (void*)SQLCancel }, /* 11 */ { SQL_API_SQLCLOSECURSOR, "SQLCloseCursor", (void*)SQLCloseCursor }, /* 12 */ { SQL_API_SQLCOLATTRIBUTE, "SQLColAttribute", (void*)SQLColAttribute, (void*)SQLColAttributeW }, /* 13 */ { SQL_API_SQLCOLATTRIBUTES, "SQLColAttributes", (void*)SQLColAttributes, (void*)SQLColAttributesW }, /* 14 */ { SQL_API_SQLCOLUMNPRIVILEGES, "SQLColumnPrivileges", (void*)SQLColumnPrivileges, (void*)SQLColumnPrivilegesW }, /* 15 */ { SQL_API_SQLCOLUMNS, "SQLColumns", (void*)SQLColumns, (void*)SQLColumnsW }, /* 16 */ { SQL_API_SQLCONNECT, "SQLConnect", (void*)SQLConnect, (void*)SQLConnectW }, /* 17 */ { SQL_API_SQLCOPYDESC, "SQLCopyDesc", (void*)SQLCopyDesc }, /* 18 */ { SQL_API_SQLDATASOURCES, "SQLDataSources", (void*)SQLDataSources, (void*)SQLDataSourcesW }, /* 19 */ { SQL_API_SQLDESCRIBECOL, "SQLDescribeCol", (void*)SQLDescribeCol, (void*)SQLDescribeColW }, /* 20 */ { SQL_API_SQLDESCRIBEPARAM, "SQLDescribeParam", (void*)SQLDescribeParam }, /* 21 */ { SQL_API_SQLDISCONNECT, "SQLDisconnect", (void*)SQLDisconnect }, /* 22 */ { SQL_API_SQLDRIVERCONNECT, "SQLDriverConnect", (void*)SQLDriverConnect, (void*)SQLDriverConnectW }, /* 23 */ { SQL_API_SQLDRIVERS, "SQLDrivers", (void*)SQLDrivers, (void*)SQLDriversW }, /* 24 */ { SQL_API_SQLENDTRAN, "SQLEndTran", (void*)SQLEndTran }, /* 25 */ { SQL_API_SQLERROR, "SQLError", (void*)SQLError, (void*)SQLErrorW }, /* 26 */ { SQL_API_SQLEXECDIRECT, "SQLExecDirect", (void*)SQLExecDirect, (void*)SQLExecDirectW }, /* 27 */ { SQL_API_SQLEXECUTE, "SQLExecute", (void*)SQLExecute }, /* 28 */ { SQL_API_SQLEXTENDEDFETCH, "SQLExtendedFetch", (void*)SQLExtendedFetch }, /* 29 */ { SQL_API_SQLFETCH, "SQLFetch", (void*)SQLFetch }, /* 30 */ { SQL_API_SQLFETCHSCROLL, "SQLFetchScroll", (void*)SQLFetchScroll }, /* 31 */ { SQL_API_SQLFOREIGNKEYS, "SQLForeignKeys", (void*)SQLForeignKeys, (void*)SQLForeignKeysW }, /* 32 */ { SQL_API_SQLFREEENV, "SQLFreeEnv", (void*)SQLFreeEnv }, /* 33 */ { SQL_API_SQLFREEHANDLE, "SQLFreeHandle", (void*)SQLFreeHandle }, /* 34 */ { SQL_API_SQLFREESTMT, "SQLFreeStmt", (void*)SQLFreeStmt }, /* 35 */ { SQL_API_SQLFREECONNECT, "SQLFreeConnect", (void*)SQLFreeConnect }, /* 36 */ { SQL_API_SQLGETCONNECTATTR, "SQLGetConnectAttr", (void*)SQLGetConnectAttr, (void*)SQLGetConnectAttrW }, /* 37 */ { SQL_API_SQLGETCONNECTOPTION, "SQLGetConnectOption", (void*)SQLGetConnectOption, (void*)SQLGetConnectOptionW }, /* 38 */ { SQL_API_SQLGETCURSORNAME, "SQLGetCursorName", (void*)SQLGetCursorName, (void*)SQLGetCursorNameW }, /* 39 */ { SQL_API_SQLGETDATA, "SQLGetData", (void*)SQLGetData }, /* 40 */ { SQL_API_SQLGETDESCFIELD, "SQLGetDescField", (void*)SQLGetDescField, (void*)SQLGetDescFieldW }, /* 41 */ { SQL_API_SQLGETDESCREC, "SQLGetDescRec", (void*)SQLGetDescRec, (void*)SQLGetDescRecW }, /* 42 */ { SQL_API_SQLGETDIAGFIELD, "SQLGetDiagField", (void*)SQLGetDiagField, (void*)SQLGetDiagFieldW }, /* 43 */ { SQL_API_SQLGETENVATTR, "SQLGetEnvAttr", (void*)SQLGetEnvAttr }, /* 44 */ { SQL_API_SQLGETFUNCTIONS, "SQLGetFunctions", (void*)SQLGetFunctions }, /* 45 */ { SQL_API_SQLGETINFO, "SQLGetInfo", (void*)SQLGetInfo, (void*)SQLGetInfoW }, /* 46 */ { SQL_API_SQLGETSTMTATTR, "SQLGetStmtAttr", (void*)SQLGetStmtAttr, (void*)SQLGetStmtAttrW }, /* 47 */ { SQL_API_SQLGETSTMTOPTION, "SQLGetStmtOption", (void*)SQLGetStmtOption }, /* 48 */ { SQL_API_SQLGETTYPEINFO, "SQLGetTypeInfo", (void*)SQLGetTypeInfo, (void*)SQLGetTypeInfoW }, /* 49 */ { SQL_API_SQLMORERESULTS, "SQLMoreResults", (void*)SQLMoreResults }, /* 50 */ { SQL_API_SQLNATIVESQL, "SQLNativeSql", (void*)SQLNativeSql, (void*)SQLNativeSqlW }, /* 51 */ { SQL_API_SQLNUMPARAMS, "SQLNumParams", (void*)SQLNumParams }, /* 52 */ { SQL_API_SQLNUMRESULTCOLS, "SQLNumResultCols", (void*)SQLNumResultCols }, /* 53 */ { SQL_API_SQLPARAMDATA, "SQLParamData", (void*)SQLParamData }, /* 54 */ { SQL_API_SQLPARAMOPTIONS, "SQLParamOptions", (void*)SQLParamOptions }, /* 55 */ { SQL_API_SQLPREPARE, "SQLPrepare", (void*)SQLPrepare, (void*)SQLPrepareW }, /* 56 */ { SQL_API_SQLPRIMARYKEYS, "SQLPrimaryKeys", (void*)SQLPrimaryKeys, (void*)SQLPrimaryKeysW }, /* 57 */ { SQL_API_SQLPROCEDURECOLUMNS, "SQLProcedureColumns", (void*)SQLProcedureColumns, (void*)SQLProcedureColumnsW }, /* 58 */ { SQL_API_SQLPROCEDURES, "SQLProcedures", (void*)SQLProcedures, (void*)SQLProceduresW }, /* 59 */ { SQL_API_SQLPUTDATA, "SQLPutData", (void*)SQLPutData }, /* 60 */ { SQL_API_SQLROWCOUNT, "SQLRowCount", (void*)SQLRowCount }, /* 61 */ { SQL_API_SQLSETCONNECTATTR, "SQLSetConnectAttr", (void*)SQLSetConnectAttr, (void*)SQLSetConnectAttrW }, /* 62 */ { SQL_API_SQLSETCONNECTOPTION, "SQLSetConnectOption", (void*)SQLSetConnectOption, (void*)SQLSetConnectOptionW }, /* 63 */ { SQL_API_SQLSETCURSORNAME, "SQLSetCursorName", (void*)SQLSetCursorName, (void*)SQLSetCursorNameW }, /* 64 */ { SQL_API_SQLSETDESCFIELD, "SQLSetDescField", (void*)SQLSetDescField, (void*)SQLSetDescFieldW }, /* 65 */ { SQL_API_SQLSETDESCREC, "SQLSetDescRec", (void*)SQLSetDescRec }, /* 66 */ { SQL_API_SQLSETENVATTR, "SQLSetEnvAttr", (void*)SQLSetEnvAttr }, /* 67 */ { SQL_API_SQLSETPARAM, "SQLSetParam", (void*)SQLSetParam }, /* 68 */ { SQL_API_SQLSETPOS, "SQLSetPos", (void*)SQLSetPos }, /* 69 */ { SQL_API_SQLSETSCROLLOPTIONS, "SQLSetScrollOptions", (void*)SQLSetScrollOptions }, /* 70 */ { SQL_API_SQLSETSTMTATTR, "SQLSetStmtAttr", (void*)SQLSetStmtAttr, (void*)SQLSetStmtAttrW }, /* 71 */ { SQL_API_SQLSETSTMTOPTION, "SQLSetStmtOption", (void*)SQLSetStmtOption }, /* 72 */ { SQL_API_SQLSPECIALCOLUMNS, "SQLSpecialColumns", (void*)SQLSpecialColumns, (void*)SQLSpecialColumnsW }, /* 73 */ { SQL_API_SQLSTATISTICS, "SQLStatistics", (void*)SQLStatistics, (void*)SQLStatisticsW }, /* 74 */ { SQL_API_SQLTABLEPRIVILEGES, "SQLTablePrivileges", (void*)SQLTablePrivileges, (void*)SQLTablePrivilegesW }, /* 75 */ { SQL_API_SQLTABLES, "SQLTables", (void*)SQLTables, (void*)SQLTablesW }, /* 76 */ { SQL_API_SQLTRANSACT, "SQLTransact", (void*)SQLTransact }, /* 77 */ { SQL_API_SQLGETDIAGREC, "SQLGetDiagRec", (void*)SQLGetDiagRec, (void*)SQLGetDiagRecW }, /* 78 */ { SQL_API_SQLCANCELHANDLE, "SQLCancelHandle", (void*)SQLCancelHandle }, }; /* * connection pooling stuff */ CPOOLHEAD *pool_head = NULL; int pooling_enabled = 0; int pool_max_size = 0; int pool_wait_timeout; /* * helper function and macro to make setting any values set before connection * simplier */ #define DO_ATTR( connection, value, attr3, attr2 ) \ do_attr( connection, connection -> value, connection -> value##_set, attr3, \ attr2 ) static void do_attr( DMHDBC connection, int value, int value_set, int attr3, int attr2 ) { if ( value_set ) { if (CHECK_SQLSETCONNECTATTR( connection )) { SQLSETCONNECTATTR(connection, connection -> driver_dbc, attr3, (SQLPOINTER)(intptr_t) value, sizeof( value )); } else if (CHECK_SQLSETCONNECTOPTION(connection) && attr2 ) { SQLSETCONNECTOPTION(connection, connection -> driver_dbc, attr2, value ); } else if (CHECK_SQLSETCONNECTATTRW( connection )) /* they are int values, so this should be safe */ { SQLSETCONNECTATTRW(connection, connection -> driver_dbc, attr3, (SQLPOINTER)(intptr_t) value, sizeof( value )); } else if (CHECK_SQLSETCONNECTOPTIONW(connection) && attr2 ) { SQLSETCONNECTOPTIONW(connection, connection -> driver_dbc, attr2, value ); } } } /* * implement reference counting for driver libs */ struct lib_count { char *lib_name; int count; void *handle; struct lib_count *next; }; /* * I hate statics, but there is little option here, there can be multiple envs * so I can't save it in them, I do use a single static instance, this avoid * a potential leak if libodbc.so is dynamically loaded */ static struct lib_count *lib_list = NULL; static struct lib_count single_lib_count; static char single_lib_name[ INI_MAX_PROPERTY_VALUE + 1 ]; static void *odbc_dlopen( char *libname, char **err ) { void *hand; struct lib_count *list; mutex_lib_entry(); /* * have we already got it ? */ list = lib_list; while( list ) { if ( strcmp( list -> lib_name, libname ) == 0 ) { break; } list = list -> next; } if ( list ) { list -> count ++; hand = list -> handle; } else { hand = lt_dlopen( libname ); if ( hand ) { /* * If only one, then use the static space */ if ( lib_list == NULL ) { list = &single_lib_count; list -> next = lib_list; lib_list = list; list -> count = 1; list -> lib_name = single_lib_name; strcpy( single_lib_name, libname ); list -> handle = hand; } else { list = malloc( sizeof( struct lib_count )); list -> next = lib_list; lib_list = list; list -> count = 1; list -> lib_name = strdup( libname ); list -> handle = hand; } } else { if ( err ) { *err = (char*) lt_dlerror(); } } } mutex_lib_exit(); return hand; } static void odbc_dlclose( void *handle ) { struct lib_count *list, *prev; mutex_lib_entry(); /* * look for list entry */ list = lib_list; prev = NULL; while( list ) { if ( list -> handle == handle ) { break; } prev = list; list = list -> next; } /* * it should always be found, but you never know... */ if ( list ) { list -> count --; if ( list -> count < 1 ) { if ( list == &single_lib_count ) { if ( prev ) { prev -> next = list -> next; } else { lib_list = list -> next; } lt_dlclose( list -> handle ); } else { free( list -> lib_name ); lt_dlclose( list -> handle ); if ( prev ) { prev -> next = list -> next; } else { lib_list = list -> next; } free( list ); } } } else { lt_dlclose( handle ); } mutex_lib_exit(); } /* * open the library, extract the names, and do setup * before the actual connect. */ int __connect_part_one( DMHDBC connection, char *driver_lib, char *driver_name, int *warnings ) { int i; int ret; int threading_level; char threading_string[ 50 ]; char mapping_string[ 50 ]; char disable_gf[ 50 ]; char fake_string[ 50 ]; int fake_unicode; char *err; struct env_lib_struct *env_lib_list, *env_lib_prev; char txt[ 256 ]; /* * check to see if we want to alter the default threading level * before opening the lib */ /* * if the driver comes from odbc.ini not via odbcinst.ini the driver name will be empty * so only look for the entry if it's set */ if ( driver_name[ 0 ] != '\0' ) { SQLGetPrivateProfileString( driver_name, "Threading", "99", threading_string, sizeof( threading_string ), "ODBCINST.INI" ); threading_level = atoi( threading_string ); sprintf( txt, "\t\tThreading Level set from Driver Entry in ODBCINST.INI %d from '%s'", threading_level, threading_string ); dm_log_write_diag( txt ); } else { threading_level = 99; } /* * look for default in [ODBC] section */ if ( threading_level == 99 ) { SQLGetPrivateProfileString( "ODBC", "Threading", "0", threading_string, sizeof( threading_string ), "ODBCINST.INI" ); threading_level = atoi( threading_string ); sprintf( txt, "\t\tThreading Level set from [ODBC] Section in ODBCINST.INI %d from '%s'", threading_level, threading_string ); dm_log_write_diag( txt ); } if ( threading_level >= 0 && threading_level <= 3 ) { dbc_change_thread_support( connection, threading_level ); } connection -> threading_level = threading_level; /* * do we want to disable the SQLFetch -> SQLExtendedFetch * mapping ? */ SQLGetPrivateProfileString( driver_name, "ExFetchMapping", "1", mapping_string, sizeof( mapping_string ), "ODBCINST.INI" ); connection -> ex_fetch_mapping = atoi( mapping_string ); if ( connection -> ex_fetch_mapping != 1 ) { sprintf( txt, "\t\tExFetchMapping set to %d from '%s'", connection -> ex_fetch_mapping, mapping_string ); dm_log_write_diag( txt ); } /* * Does the driver have support for SQLGetFunctions ? */ SQLGetPrivateProfileString( driver_name, "DisableGetFunctions", "0", disable_gf, sizeof( disable_gf ), "ODBCINST.INI" ); connection -> disable_gf = atoi( disable_gf ); if ( connection -> disable_gf != 0 ) { sprintf( txt, "\t\tDisableGetFunctions set to %d from '%s'", connection -> disable_gf, disable_gf ); dm_log_write_diag( txt ); } /* * do we want to keep hold of the lib handle, DB2 fails if we close */ SQLGetPrivateProfileString( driver_name, "DontDLClose", "1", mapping_string, sizeof( mapping_string ), "ODBCINST.INI" ); connection -> dont_dlclose = atoi( mapping_string ) != 0; if ( connection -> dont_dlclose != 1 ) { sprintf( txt, "\t\tDisableGetFunctions set to %d from '%s'", connection -> dont_dlclose, mapping_string ); dm_log_write_diag( txt ); } /* * can we pool this one */ SQLGetPrivateProfileString( driver_name, "CPTimeout", "0", mapping_string, sizeof( mapping_string ), "ODBCINST.INI" ); connection -> pooling_timeout = atoi( mapping_string ); if ( connection -> pooling_timeout != 0 ) { sprintf( txt, "\t\tCPTimeout set to %d from '%s'", connection -> pooling_timeout, mapping_string ); dm_log_write_diag( txt ); } /* * have we got a time-to-live value for the pooling */ SQLGetPrivateProfileString( driver_name, "CPTimeToLive", "0", mapping_string, sizeof( mapping_string ), "ODBCINST.INI" ); connection -> ttl = atoi( mapping_string ); if ( connection -> ttl != 0 ) { sprintf( txt, "\t\tCPTimeToLive set to %d from '%s'", connection -> ttl, mapping_string ); dm_log_write_diag( txt ); } /* * Is there a check SQL statement */ SQLGetPrivateProfileString( driver_name, "CPProbe", "", connection -> probe_sql, sizeof( connection -> probe_sql ), "ODBCINST.INI" ); if ( strlen( connection -> probe_sql ) != 0 ) { sprintf( txt, "\t\tCPProbe set to '%s'", connection -> probe_sql ); dm_log_write_diag( txt ); } /* * if pooling then leave the dlopen */ if ( connection -> pooling_timeout > 0 ) { connection -> dont_dlclose = 1; } SQLGetPrivateProfileString( driver_name, "FakeUnicode", "0", fake_string, sizeof( fake_string ), "ODBCINST.INI" ); fake_unicode = atoi( fake_string ); if ( fake_unicode != 0 ) { sprintf( txt, "\t\tFakeUnicode set to %d from '%s'", fake_unicode, fake_string ); dm_log_write_diag( txt ); } #ifdef HAVE_ICONV #ifdef ENABLE_DRIVER_ICONV SQLGetPrivateProfileString( driver_name, "IconvEncoding", DEFAULT_ICONV_ENCODING, connection->unicode_string, sizeof( connection->unicode_string ), "ODBCINST.INI" ); #endif #endif /* * initialize unicode */ if ( !unicode_setup( connection )) { char txt[ 256 ]; sprintf( txt, "Can't initiate unicode conversion" ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, txt ); __post_internal_error( &connection -> error, ERROR_IM003, txt, connection -> environment -> requested_version ); *warnings = TRUE; } /* * initialize libtool */ mutex_lib_entry(); /* warning, this doesn't protect from other libs in the application */ /* in their own threads calling dlinit(); */ lt_dlinit(); #ifdef MODULEDIR lt_dlsetsearchpath(MODULEDIR); #endif mutex_lib_exit(); /* * open the lib */ connection -> driver_env = (DRV_SQLHANDLE)NULL; connection -> driver_dbc = (DRV_SQLHANDLE)NULL; connection -> functions = NULL; connection -> dl_handle = NULL; if ( !(connection -> dl_handle = odbc_dlopen( driver_lib, &err ))) { char txt[ 2048 ]; sprintf( txt, "Can't open lib '%s' : %s", driver_lib, err ? err : "NULL ERROR RETURN" ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, txt ); __post_internal_error( &connection -> error, ERROR_01000, txt, connection -> environment -> requested_version ); return 0; } /* * try and extract the ini and fini functions, and call ini if it's * found */ connection -> ini_func.func = (SQLRETURN (*)()) lt_dlsym( connection -> dl_handle, ODBC_INI_FUNCTION ); connection -> fini_func.func = (SQLRETURN (*)()) lt_dlsym( connection -> dl_handle, ODBC_FINI_FUNCTION ); if ( connection -> ini_func.func ) { connection -> ini_func.func(); } /* * extract all the function entry points */ if ( !(connection -> functions = malloc( sizeof( template_func )))) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_HY001, NULL, connection -> environment -> requested_version ); return 0; } memcpy( connection -> functions, template_func, sizeof( template_func )); for ( i = 0; i < sizeof( template_func ) / sizeof( template_func[ 0 ] ); i ++ ) { char name[ 128 ]; connection -> functions[ i ].func = (SQLRETURN (*)()) lt_dlsym( connection -> dl_handle, connection -> functions[ i ].name ); if ( connection -> functions[ i ].dm_funcW ) { /* * get ANSI version from driver */ if ( fake_unicode ) { sprintf( name, "%sW", connection -> functions[ i ].name ); } else { sprintf( name, "%sA", connection -> functions[ i ].name ); } connection -> functions[ i ].funcA = (SQLRETURN (*)()) lt_dlsym( connection -> dl_handle, name ); if ( connection -> functions[ i ].funcA && !connection -> functions[ i ].func ) { connection -> functions[ i ].func = connection -> functions[ i ].funcA; } else if ( connection -> functions[ i ].func && !connection -> functions[ i ].funcA ) { connection -> functions[ i ].funcA = connection -> functions[ i ].func; } /* * get UNICODE version from driver */ sprintf( name, "%sW", connection -> functions[ i ].name ); connection -> functions[ i ].funcW = (SQLRETURN (*)()) lt_dlsym( connection -> dl_handle, name ); } else { connection -> functions[ i ].funcA = connection -> functions[ i ].funcW = NULL; } /* * blank out ones that are in the DM to fix a big * with glib 2.0.6 */ if ( connection -> functions[ i ].func && (void*)connection -> functions[ i ].func == (void*)connection -> functions[ i ].dm_func ) { connection -> functions[ i ].func = NULL; } if ( connection -> functions[ i ].funcW && (void*)connection -> functions[ i ].funcW == (void*)connection -> functions[ i ].dm_funcW ) { connection -> functions[ i ].funcW = NULL; } connection -> functions[ i ].can_supply = ( connection -> functions[ i ].func != NULL ) || ( connection -> functions[ i ].funcW != NULL ); } /* * check if this is the first time this driver has been loaded under this * lib, if not then reuse the env, else get the env from the driver */ mutex_lib_entry(); env_lib_list = connection -> environment -> env_lib_list; env_lib_prev = NULL; while( env_lib_list ) { if ( strcmp( driver_lib, env_lib_list -> lib_name ) == 0 ) { break; } env_lib_prev = env_lib_list; env_lib_list = env_lib_list -> next; } connection -> driver_act_ver = 0; if ( env_lib_list ) { /* * Fix by qcai@starquest.com */ SQLUINTEGER actual_version = 0; int ret; env_lib_list -> count ++; connection -> driver_env = env_lib_list -> env_handle; connection -> env_list_ent = env_lib_list; /* * Fix by qcai@starquest.com, Feb 5, 2003 * * Since the driver was already loaded before, the version number * has been properly figured out. This connection just need to get * it from priviously set value. Without it, the version number is * at initial value of 0 which causes this and subsequence connection * to return a warning message "Driver does not support the requested * version". */ /* * Change from Rafie Einstein to check SQLGETENVATTR is valid */ if ((CHECK_SQLGETENVATTR( connection ))) { ret = SQLGETENVATTR( connection, connection -> driver_env, SQL_ATTR_ODBC_VERSION, &actual_version, 0, NULL ); } else { ret = SQL_SUCCESS; actual_version = SQL_OV_ODBC2; } if ( !ret ) { connection -> driver_version = actual_version; } else { connection -> driver_version = connection -> environment -> requested_version; } /* end of fix */ /* * get value that has been pushed up by the initial connection to this driver */ connection -> driver_act_ver = env_lib_list -> driver_act_ver; } else { env_lib_list = calloc( 1, sizeof( struct env_lib_struct )); env_lib_list -> count = 1; env_lib_list -> next = connection -> environment -> env_lib_list; env_lib_list -> lib_name = strdup( driver_lib ); connection -> env_list_ent = env_lib_list; connection -> environment -> env_lib_list = env_lib_list; __set_local_attributes( connection, SQL_HANDLE_ENV ); /* * allocate a env handle */ if ( CHECK_SQLALLOCHANDLE( connection )) { ret = SQLALLOCHANDLE( connection, SQL_HANDLE_ENV, SQL_NULL_HENV, &connection -> driver_env, connection ); connection -> driver_act_ver = SQL_OV_ODBC3; } else if ( CHECK_SQLALLOCENV( connection )) { ret = SQLALLOCENV( connection, &connection -> driver_env ); connection -> driver_act_ver = SQL_OV_ODBC2; } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM004" ); __post_internal_error( &connection -> error, ERROR_IM004, NULL, connection -> environment -> requested_version ); if ( env_lib_list -> count == 1 ) { if ( env_lib_prev ) { env_lib_prev -> next = env_lib_list -> next; } else { connection -> environment -> env_lib_list = env_lib_list -> next; } free( env_lib_list -> lib_name ); free( env_lib_list ); } else { env_lib_list -> count --; } mutex_lib_exit(); return 0; } /* * push up to environment to be reused */ env_lib_list -> driver_act_ver = connection -> driver_act_ver; env_lib_list -> env_handle = connection -> driver_env; if ( ret ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM004" ); __post_internal_error( &connection -> error, ERROR_IM004, NULL, connection -> environment -> requested_version ); if ( env_lib_list -> count == 1 ) { if ( env_lib_prev ) { env_lib_prev -> next = env_lib_list -> next; } else { connection -> environment -> env_lib_list = env_lib_list -> next; } free( env_lib_list -> lib_name ); free( env_lib_list ); } else { env_lib_list -> count --; } mutex_lib_exit(); return 0; } /* * if it looks like a 3.x driver, try setting the interface type * to 3.x */ if ( connection -> driver_act_ver >= SQL_OV_ODBC3 && CHECK_SQLSETENVATTR( connection )) { ret = SQLSETENVATTR( connection, connection -> driver_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)(intptr_t) connection -> environment -> requested_version, 0 ); /* * if it don't set then assume a 2.x driver */ if ( ret ) { connection -> driver_version = SQL_OV_ODBC2; } else { if ( CHECK_SQLGETENVATTR( connection )) { SQLINTEGER actual_version; ret = SQLGETENVATTR( connection, connection -> driver_env, SQL_ATTR_ODBC_VERSION, &actual_version, 0, NULL ); if ( !ret ) { connection -> driver_version = actual_version; } else { connection -> driver_version = connection -> environment -> requested_version; } } else { connection -> driver_version = connection -> environment -> requested_version; } } } else { connection -> driver_version = SQL_OV_ODBC2; } /* * set any env attributes */ __set_attributes( connection, SQL_HANDLE_ENV ); } mutex_lib_exit(); /* * allocate a connection handle */ if ( connection -> driver_version >= SQL_OV_ODBC3 ) { ret = SQL_SUCCESS; if ( CHECK_SQLALLOCHANDLE( connection )) { ret = SQLALLOCHANDLE( connection, SQL_HANDLE_DBC, connection -> driver_env, &connection -> driver_dbc, connection ); if ( ret ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM005" ); __post_internal_error( &connection -> error, ERROR_IM005, NULL, connection -> environment -> requested_version ); } } else if ( CHECK_SQLALLOCCONNECT( connection )) { ret = SQLALLOCCONNECT( connection, connection -> driver_env, &connection -> driver_dbc ); if ( ret ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM005" ); __post_internal_error( &connection -> error, ERROR_IM005, NULL, connection -> environment -> requested_version ); } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM005" ); __post_internal_error( &connection -> error, ERROR_IM005, NULL, connection -> environment -> requested_version ); return 0; } if ( ret ) { SQLCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; /* * get the errors from the driver before * loseing the connection */ if ( CHECK_SQLGETDIAGREC( connection )) { int rec = 1; do { ret = SQLGETDIAGREC( connection, SQL_HANDLE_ENV, connection -> driver_env, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", sqlstate, message_text ); dm_log_write_diag( connection -> msg ); } } while( SQL_SUCCEEDED( ret )); } else if ( CHECK_SQLERROR( connection )) { do { ret = SQLERROR( connection, connection -> driver_env, SQL_NULL_HDBC, SQL_NULL_HSTMT, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", sqlstate, message_text ); dm_log_write_diag( connection -> msg ); } } while( SQL_SUCCEEDED( ret )); } return 0; } } else { ret = SQL_SUCCESS; if ( CHECK_SQLALLOCCONNECT( connection )) { ret = SQLALLOCCONNECT( connection, connection -> driver_env, &connection -> driver_dbc ); if ( ret ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM005" ); __post_internal_error( &connection -> error, ERROR_IM005, NULL, connection -> environment -> requested_version ); } } else if ( CHECK_SQLALLOCHANDLE( connection )) { ret = SQLALLOCHANDLE( connection, SQL_HANDLE_DBC, connection -> driver_env, &connection -> driver_dbc, connection ); if ( ret ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM005" ); __post_internal_error( &connection -> error, ERROR_IM005, NULL, connection -> environment -> requested_version ); } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM005" ); __post_internal_error( &connection -> error, ERROR_IM005, NULL, connection -> environment -> requested_version ); return 0; } if ( ret ) { SQLCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; /* * get the errors from the driver before * loseing the connection */ if ( CHECK_SQLERROR( connection )) { do { ret = SQLERROR( connection, connection -> driver_env, SQL_NULL_HDBC, SQL_NULL_HSTMT, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", sqlstate, message_text ); dm_log_write_diag( connection -> msg ); } } while( SQL_SUCCEEDED( ret )); } else if ( CHECK_SQLGETDIAGREC( connection )) { int rec = 1; do { ret = SQLGETDIAGREC( connection, SQL_HANDLE_ENV, connection -> driver_env, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", sqlstate, message_text ); dm_log_write_diag( connection -> msg ); } } while( SQL_SUCCEEDED( ret )); } return 0; } } /* * set any connection atributes */ DO_ATTR( connection, access_mode, SQL_ATTR_ACCESS_MODE, SQL_ACCESS_MODE ); DO_ATTR( connection, login_timeout, SQL_ATTR_LOGIN_TIMEOUT, SQL_LOGIN_TIMEOUT ); DO_ATTR( connection, auto_commit, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT ); DO_ATTR( connection, async_enable, SQL_ATTR_ASYNC_ENABLE, SQL_ASYNC_ENABLE ); DO_ATTR( connection, auto_ipd, SQL_ATTR_AUTO_IPD, 0 ); DO_ATTR( connection, connection_timeout, SQL_ATTR_CONNECTION_TIMEOUT, 0 ); DO_ATTR( connection, metadata_id, SQL_ATTR_METADATA_ID, 0 ); DO_ATTR( connection, packet_size, SQL_ATTR_PACKET_SIZE, SQL_PACKET_SIZE ); DO_ATTR( connection, quite_mode, SQL_ATTR_QUIET_MODE, SQL_QUIET_MODE ); DO_ATTR( connection, txn_isolation, SQL_ATTR_TXN_ISOLATION, SQL_TXN_ISOLATION ); if ( connection -> save_attr ) { struct save_attr *sa; sa = connection -> save_attr; while ( sa ) { if ( sa -> str_attr ) { if (CHECK_SQLSETCONNECTATTR( connection )) { SQLSETCONNECTATTR(connection, connection -> driver_dbc, sa -> attr_type, sa -> str_attr, sa -> str_len ); } else if (CHECK_SQLSETCONNECTOPTION(connection)) { SQLSETCONNECTOPTION(connection, connection -> driver_dbc, sa -> attr_type, (SQLULEN) sa -> str_attr ); } else if (CHECK_SQLSETCONNECTATTRW( connection )) { SQLSETCONNECTATTRW(connection, connection -> driver_dbc, sa -> attr_type, sa -> str_attr, sa -> str_len ); } else if (CHECK_SQLSETCONNECTOPTIONW(connection)) { SQLSETCONNECTOPTIONW(connection, connection -> driver_dbc, sa -> attr_type, (SQLULEN) sa -> str_attr ); } } else { if (CHECK_SQLSETCONNECTATTR( connection )) { SQLSETCONNECTATTR(connection, connection -> driver_dbc, sa -> attr_type, (SQLPOINTER) sa -> intptr_attr, sa -> str_len ); } else if (CHECK_SQLSETCONNECTOPTION(connection)) { SQLSETCONNECTOPTION(connection, connection -> driver_dbc, sa -> attr_type, sa -> intptr_attr ); } else if (CHECK_SQLSETCONNECTATTRW( connection )) { SQLSETCONNECTATTRW(connection, connection -> driver_dbc, sa -> attr_type, (SQLPOINTER) sa -> intptr_attr, sa -> str_len ); } else if (CHECK_SQLSETCONNECTOPTIONW(connection)) { SQLSETCONNECTOPTIONW(connection, connection -> driver_dbc, sa -> attr_type, sa -> intptr_attr ); } } sa = sa -> next; } } /* * set any preset connection attributes */ __set_attributes( connection, SQL_HANDLE_DBC ); return 1; } /* * extract the available functions and call SQLSetConnectAttr */ int __connect_part_two( DMHDBC connection ) { int i, use_cursor; /* * Call SQLFunctions to get the supported list and * mask out those that are exported but not supported */ if ( CHECK_SQLGETFUNCTIONS( connection ) && !connection -> disable_gf ) { SQLRETURN ret; SQLUSMALLINT supported_funcs[ SQL_API_ODBC3_ALL_FUNCTIONS_SIZE ]; SQLUSMALLINT supported_array[ 100 ]; /* * try using fast version, but only if the driver is set to ODBC 3, * some drivers (SAPDB) fail to return the correct values in this situation */ if ( connection -> driver_act_ver >= SQL_OV_ODBC3 ) { ret = SQLGETFUNCTIONS( connection, connection -> driver_dbc, SQL_API_ODBC3_ALL_FUNCTIONS, supported_funcs ); } else { ret = SQLGETFUNCTIONS( connection, connection -> driver_dbc, SQL_API_ALL_FUNCTIONS, supported_array ); } if ( ret == SQL_SUCCESS ) { for ( i = 0; i < sizeof( template_func ) / sizeof( template_func[ 0 ] ); i ++ ) { if ( connection -> functions[ i ].func ) { SQLRETURN ret; SQLUSMALLINT supported; if ( connection -> driver_act_ver >= SQL_OV_ODBC3 ) { supported = SQL_FUNC_EXISTS( supported_funcs, connection -> functions[ i ].ordinal ); if ( supported == SQL_FALSE ) { connection -> functions[ i ].func = NULL; connection -> functions[ i ].can_supply = 0; } } else { if ( connection -> functions[ i ].ordinal >= 100 ) { ret = SQLGETFUNCTIONS( connection, connection -> driver_dbc, connection -> functions[ i ].ordinal, &supported ); } else { supported = supported_array[ connection -> functions[ i ].ordinal ]; ret = SQL_SUCCESS; } if ( supported == SQL_FALSE || ret != SQL_SUCCESS ) { connection -> functions[ i ].func = NULL; connection -> functions[ i ].can_supply = 0; } } } } } else { for ( i = 0; i < sizeof( template_func ) / sizeof( template_func[ 0 ] ); i ++ ) { if ( connection -> functions[ i ].func ) { SQLRETURN ret; SQLUSMALLINT supported; ret = SQLGETFUNCTIONS( connection, connection -> driver_dbc, connection -> functions[ i ].ordinal, &supported ); if ( supported == SQL_FALSE || ret != SQL_SUCCESS ) { connection -> functions[ i ].func = NULL; connection -> functions[ i ].can_supply = 0; } } } } } /* * CoLAttributes is the same as ColAttribute */ if ( connection -> functions[ DM_SQLCOLATTRIBUTE ].func && !connection -> functions[ DM_SQLCOLATTRIBUTES ].func ) { connection -> functions[ DM_SQLCOLATTRIBUTES ].can_supply = 1; } if ( connection -> functions[ DM_SQLCOLATTRIBUTES ].func && !connection -> functions[ DM_SQLCOLATTRIBUTE ].func ) { connection -> functions[ DM_SQLCOLATTRIBUTE ].can_supply = 1; } /* * mark the functions that the driver manager does */ /* * SQLDatasources */ connection -> functions[ DM_SQLDATASOURCES ].can_supply = 1; /* * SQLDrivers */ connection -> functions[ DM_SQLDRIVERS ].can_supply = 1; /* * SQLAllocHandleStd */ connection -> functions[ DM_SQLALLOCHANDLESTD ].can_supply = 1; /* * add all the functions that are supported via ODBC 2<->3 * issues */ if ( !connection -> functions[ DM_SQLALLOCENV ].func && connection -> functions[ DM_SQLALLOCHANDLE ].func ) { connection -> functions[ DM_SQLALLOCENV ].can_supply = 1; } if ( !connection -> functions[ DM_SQLALLOCCONNECT ].func && connection -> functions[ DM_SQLALLOCHANDLE ].func ) { connection -> functions[ DM_SQLALLOCCONNECT ].can_supply = 1; } if ( !connection -> functions[ DM_SQLALLOCSTMT ].func && connection -> functions[ DM_SQLALLOCHANDLE ].func ) { connection -> functions[ DM_SQLALLOCSTMT ].can_supply = 1; } if ( !connection -> functions[ DM_SQLFREEENV ].func && connection -> functions[ DM_SQLFREEHANDLE ].func ) { connection -> functions[ DM_SQLFREEENV ].can_supply = 1; } if ( !connection -> functions[ DM_SQLFREECONNECT ].func && connection -> functions[ DM_SQLFREEHANDLE ].func ) { connection -> functions[ DM_SQLFREECONNECT ].can_supply = 1; } if ( !connection -> functions[ DM_SQLGETDIAGREC ].func && connection -> functions[ DM_SQLERROR ].func ) { connection -> functions[ DM_SQLGETDIAGREC ].can_supply = 1; } if ( !connection -> functions[ DM_SQLGETDIAGFIELD ].func && connection -> functions[ DM_SQLERROR ].func ) { connection -> functions[ DM_SQLGETDIAGFIELD ].can_supply = 1; } if ( !connection -> functions[ DM_SQLERROR ].func && connection -> functions[ DM_SQLGETDIAGREC ].func ) { connection -> functions[ DM_SQLERROR ].can_supply = 1; } /* * ODBC 3 still needs SQLFreeStmt */ /* * this is only partial, as we can't support a descriptor alloc */ if ( !connection -> functions[ DM_SQLALLOCHANDLE ].func && connection -> functions[ DM_SQLALLOCENV ].func && connection -> functions[ DM_SQLALLOCCONNECT ].func && connection -> functions[ DM_SQLALLOCHANDLE ].func ) { connection -> functions[ DM_SQLALLOCHANDLE ].can_supply = 1; } if ( !connection -> functions[ DM_SQLFREEHANDLE ].func && connection -> functions[ DM_SQLFREEENV ].func && connection -> functions[ DM_SQLFREECONNECT ].func && connection -> functions[ DM_SQLFREEHANDLE ].func ) { connection -> functions[ DM_SQLFREEHANDLE ].can_supply = 1; } if ( !connection -> functions[ DM_SQLBINDPARAM ].func && connection -> functions[ DM_SQLBINDPARAMETER ].func ) { connection -> functions[ DM_SQLBINDPARAM ].can_supply = 1; } else if ( !connection -> functions[ DM_SQLBINDPARAMETER ].func && connection -> functions[ DM_SQLBINDPARAM ].func ) { connection -> functions[ DM_SQLBINDPARAMETER ].can_supply = 1; } if ( !connection -> functions[ DM_SQLGETCONNECTOPTION ].func && connection -> functions[ DM_SQLGETCONNECTATTR ].func ) { connection -> functions[ DM_SQLGETCONNECTOPTION ].can_supply = 1; } else if ( !connection -> functions[ DM_SQLGETCONNECTATTR ].func && connection -> functions[ DM_SQLGETCONNECTOPTION ].func ) { connection -> functions[ DM_SQLGETCONNECTATTR ].can_supply = 1; } if ( !connection -> functions[ DM_SQLGETSTMTOPTION ].func && connection -> functions[ DM_SQLGETSTMTATTR ].func ) { connection -> functions[ DM_SQLGETSTMTOPTION ].can_supply = 1; } else if ( !connection -> functions[ DM_SQLGETSTMTATTR ].func && connection -> functions[ DM_SQLGETSTMTOPTION ].func ) { connection -> functions[ DM_SQLGETSTMTATTR ].can_supply = 1; } if ( !connection -> functions[ DM_SQLPARAMOPTIONS ].func && connection -> functions[ DM_SQLSETSTMTATTR ].func ) { connection -> functions[ DM_SQLPARAMOPTIONS ].can_supply = 1; } if ( !connection -> functions[ DM_SQLSETCONNECTOPTION ].func && connection -> functions[ DM_SQLSETCONNECTATTR ].func ) { connection -> functions[ DM_SQLSETCONNECTOPTION ].can_supply = 1; } else if ( !connection -> functions[ DM_SQLSETCONNECTATTR ].func && connection -> functions[ DM_SQLSETCONNECTOPTION ].func ) { connection -> functions[ DM_SQLSETCONNECTATTR ].can_supply = 1; } if ( !connection -> functions[ DM_SQLSETPARAM ].func && connection -> functions[ DM_SQLBINDPARAMETER ].func ) { connection -> functions[ DM_SQLSETPARAM ].can_supply = 1; } if ( !connection -> functions[ DM_SQLSETSCROLLOPTIONS ].func && connection -> functions[ DM_SQLSETSTMTATTR ].func ) { connection -> functions[ DM_SQLSETSCROLLOPTIONS ].can_supply = 1; } if ( !connection -> functions[ DM_SQLSETSTMTOPTION ].func && connection -> functions[ DM_SQLSETSTMTATTR ].func ) { connection -> functions[ DM_SQLSETSTMTOPTION ].can_supply = 1; } else if ( !connection -> functions[ DM_SQLSETSTMTATTR ].func && connection -> functions[ DM_SQLSETSTMTOPTION ].func ) { connection -> functions[ DM_SQLSETSTMTATTR ].can_supply = 1; } if ( !connection -> functions[ DM_SQLTRANSACT ].func && connection -> functions[ DM_SQLENDTRAN ].func ) { connection -> functions[ DM_SQLTRANSACT ].can_supply = 1; } else if ( !connection -> functions[ DM_SQLENDTRAN ].func && connection -> functions[ DM_SQLTRANSACT ].func ) { connection -> functions[ DM_SQLENDTRAN ].can_supply = 1; } /* * we can always do this */ if ( !connection -> functions[ DM_SQLGETFUNCTIONS ].func ) { connection -> functions[ DM_SQLGETFUNCTIONS ].can_supply = 1; } /* * TO_DO get some driver settings, such as the GETDATA_EXTENSTION * it supports */ if ( CHECK_SQLGETINFO( connection ) || CHECK_SQLGETINFOW( connection )) { char txt[ 20 ]; SQLRETURN ret; if ( connection -> driver_act_ver >= SQL_OV_ODBC3 ) { ret = __SQLGetInfo( connection, SQL_XOPEN_CLI_YEAR, txt, sizeof( connection -> cli_year ), NULL ); if ( SQL_SUCCEEDED( ret )) { strcpy( connection -> cli_year, txt ); } } } /* * TO_DO now we should pass any SQLSetEnvAttr settings */ /* * now we have a connection handle, and we can check to see if * we need to use the cursor library */ if ( connection -> cursors == SQL_CUR_USE_ODBC ) { use_cursor = 1; } else if ( connection -> cursors == SQL_CUR_USE_IF_NEEDED ) { /* * get scrollable info */ if ( !CHECK_SQLGETINFO( connection ) && !CHECK_SQLGETINFOW( connection )) { /* * bit of a retarded driver, better give up */ use_cursor = 0; } else { SQLRETURN ret; SQLUINTEGER val; /* * check if static cursors support scrolling */ if ( connection -> driver_act_ver >= SQL_OV_ODBC3 ) { ret = __SQLGetInfo( connection, SQL_STATIC_CURSOR_ATTRIBUTES1, &val, sizeof( val ), NULL ); if ( ret != SQL_SUCCESS ) { use_cursor = 1; } else { /* * do we need it ? */ if ( !( val & SQL_CA1_ABSOLUTE )) { use_cursor = 1; } else { use_cursor = 0; } } } else { ret = __SQLGetInfo( connection, SQL_FETCH_DIRECTION, &val, sizeof( val ), NULL ); if ( ret != SQL_SUCCESS ) { use_cursor = 1; } else { /* * are we needed */ if ( !( val & SQL_FD_FETCH_PRIOR )) { use_cursor = 1; } else { use_cursor = 0; } } } } } else { use_cursor = 0; } /* * if required connect to the cursor lib */ if ( use_cursor ) { char ext[ 32 ]; char name[ ODBC_FILENAME_MAX * 2 + 1 ]; int (*cl_connect)(void*, struct driver_helper_funcs*); char *err; struct driver_helper_funcs dh; /* * SHLIBEXT can end up unset on some distributions (suze) */ if ( strlen( SHLIBEXT ) == 0 ) { strcpy( ext, ".so" ); } else { if ( strlen( SHLIBEXT ) + 1 > sizeof( ext )) { fprintf( stderr, "internal error, unexpected SHLIBEXT value ('%s') may indicate a problem with configure\n", SHLIBEXT ); abort(); } strcpy( ext, SHLIBEXT ); } #ifdef CURSOR_LIB_VER sprintf( name, "%s%s.%s", CURSOR_LIB, ext, CURSOR_LIB_VER ); #else sprintf( name, "%s%s", CURSOR_LIB, ext ); #endif if ( !(connection -> cl_handle = odbc_dlopen( name, &err ))) { char b1[ ODBC_FILENAME_MAX + 1 ]; /* * try again */ #ifdef CURSOR_LIB_VER #ifdef __VMS sprintf( name, "%s:%s%s.%s", odbcinst_system_file_path( b1 ), CURSOR_LIB, ext, CURSOR_LIB_VER ); #else #ifdef __OS2__ /* OS/2 does not use the system_lib_path or version defines to construct a name */ sprintf( name, "%s.%s", CURSOR_LIB, ext ); #else sprintf( name, "%s/%s%s.%s", odbcinst_system_file_path( b1 ), CURSOR_LIB, ext, CURSOR_LIB_VER ); #endif #endif #else #ifdef __VMS sprintf( name, "%s:%s%s", odbcinst_system_file_path( b1 ), CURSOR_LIB, ext ); #else #ifdef __OS2__ /* OS/2 does not use the system_lib_path or version defines to construct a name */ sprintf( name, "%s%s", CURSOR_LIB, ext ); #else sprintf( name, "%s/%s%s", odbcinst_system_file_path( b1 ), CURSOR_LIB, ext ); #endif #endif #endif if ( !(connection -> cl_handle = odbc_dlopen( name, &err ))) { char txt[ 1024 ]; #ifdef HAVE_SNPRINTF snprintf( txt, sizeof( txt ), "Can't open cursor lib '%s' : %s", name, err ? err : "NULL ERROR RETURN" ); #else sprintf( txt, "Can't open cursor lib '%s' : %s", name, err ? err : "NULL ERROR RETURN" ); #endif dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, txt ); __post_internal_error( &connection -> error, ERROR_01000, txt, connection -> environment -> requested_version ); return 0; } } if ( !( cl_connect = (int(*)(void*, struct driver_helper_funcs* ))lt_dlsym( connection -> cl_handle, "CLConnect" ))) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 01000 Unable to load Cursor Lib" ); __post_internal_error( &connection -> error, ERROR_01000, "Unable to load cursor library", connection -> environment -> requested_version ); odbc_dlclose( connection -> cl_handle ); connection -> cl_handle = NULL; return 0; } /* * setup helper functions */ dh.__post_internal_error_ex = __post_internal_error_ex; dh.__post_internal_error = __post_internal_error; dh.dm_log_write = dm_log_write; if ( cl_connect( connection, &dh ) != SQL_SUCCESS ) { odbc_dlclose( connection -> cl_handle ); connection -> cl_handle = NULL; return 0; } } else { connection -> cl_handle = NULL; } return 1; } static void release_env( DMHDBC connection ) { struct env_lib_struct *env_lib_list, *env_lib_prev; int ret; if ( connection -> driver_env ) { env_lib_prev = env_lib_list = NULL; mutex_lib_entry(); if ( connection -> env_list_ent && connection -> environment ) { env_lib_list = connection -> environment -> env_lib_list; while( env_lib_list ) { if ( env_lib_list == connection -> env_list_ent ) { break; } env_lib_prev = env_lib_list; env_lib_list = env_lib_list -> next; } } if ( env_lib_list && env_lib_list -> count > 1 ) { env_lib_list -> count --; } else { if ( connection -> driver_version >= SQL_OV_ODBC3 ) { ret = SQL_ERROR; if ( CHECK_SQLFREEHANDLE( connection )) { ret = SQLFREEHANDLE( connection, SQL_HANDLE_ENV, connection -> driver_env ); } else if ( CHECK_SQLFREEENV( connection )) { ret = SQLFREEENV( connection, connection -> driver_env ); } if ( !ret ) connection -> driver_env = (DRV_SQLHANDLE)NULL; } else { ret = SQL_ERROR; if ( CHECK_SQLFREEENV( connection )) { ret = SQLFREEENV( connection, connection -> driver_env ); } else if ( CHECK_SQLFREEHANDLE( connection )) { ret = SQLFREEHANDLE( connection, SQL_HANDLE_ENV, connection -> driver_env ); } if ( !ret ) connection -> driver_env = (DRV_SQLHANDLE)NULL; } /* * remove the entry */ if ( env_lib_prev && env_lib_list ) { env_lib_prev -> next = env_lib_list -> next; } else { if ( env_lib_list ) { connection -> environment -> env_lib_list = env_lib_list -> next; } } if ( env_lib_list ) { free( env_lib_list -> lib_name ); free( env_lib_list ); } } mutex_lib_exit(); } } /* * clean up after the first part of the connect */ void __disconnect_part_one( DMHDBC connection ) { int ret = SQL_ERROR; /* * try a version 3 disconnect first on the connection */ if ( connection -> driver_dbc ) { if ( connection -> driver_version >= SQL_OV_ODBC3 ) { if ( CHECK_SQLFREEHANDLE( connection )) { ret = SQLFREEHANDLE( connection, SQL_HANDLE_DBC, connection -> driver_dbc ); } else if ( CHECK_SQLFREECONNECT( connection )) { ret = SQLFREECONNECT( connection, connection -> driver_dbc ); } if ( !ret ) { connection -> driver_dbc = (DRV_SQLHANDLE)NULL; } } else { if ( CHECK_SQLFREECONNECT( connection )) { ret = SQLFREECONNECT( connection, connection -> driver_dbc ); } else if ( CHECK_SQLFREEHANDLE( connection )) { ret = SQLFREEHANDLE( connection, SQL_HANDLE_DBC, connection -> driver_dbc ); } if ( !ret ) { connection -> driver_dbc = (DRV_SQLHANDLE)NULL; } } connection -> driver_dbc = (DRV_SQLHANDLE)NULL; } /* * now disconnect the environment, if it's the last usage on the connection */ if ( connection -> driver_env ) { release_env( connection ); } connection -> driver_env = (DRV_SQLHANDLE)NULL; /* * unload the lib */ if ( connection -> cl_handle ) { odbc_dlclose( connection -> cl_handle ); connection -> cl_handle = NULL; } if ( connection -> dl_handle ) { if ( !connection -> dont_dlclose ) { /* * call fini function if found */ if ( connection -> fini_func.func ) { connection -> fini_func.func(); } odbc_dlclose( connection -> dl_handle ); } connection -> dl_handle = NULL; } /* * free some memory */ if ( connection -> functions ) { free( connection -> functions ); connection -> functions = NULL; } } void __disconnect_part_two( DMHDBC connection ) { if ( CHECK_SQLDISCONNECT( connection )) { SQLDISCONNECT( connection, connection -> driver_dbc ); } } /* * final clean up */ void __disconnect_part_four( DMHDBC connection ) { /* * now disconnect the environment, if it's the last usage on the connection */ release_env( connection ); connection -> driver_env = (DRV_SQLHANDLE)NULL; /* * unload the lib */ if ( connection -> cl_handle ) { odbc_dlclose( connection -> cl_handle ); connection -> cl_handle = NULL; } if ( connection -> dl_handle ) { /* * this is safe, because the dlopen function will reuse the handle if we * open the same lib again */ if ( !connection -> dont_dlclose ) { if ( connection -> fini_func.func ) { connection -> fini_func.func(); } odbc_dlclose( connection -> dl_handle ); } connection -> dl_handle = NULL; } /* * free some memory */ if ( connection -> functions ) { free( connection -> functions ); connection -> functions = NULL; } connection -> state = STATE_C2; /* * now clean up any statements that are left about */ __clean_stmt_from_dbc( connection ); __clean_desc_from_dbc( connection ); } /* * normal disconnect */ void __disconnect_part_three( DMHDBC connection ) { if ( connection -> driver_version >= SQL_OV_ODBC3 ) { if ( CHECK_SQLFREEHANDLE( connection )) { SQLFREEHANDLE( connection, SQL_HANDLE_DBC, connection -> driver_dbc ); } else if ( CHECK_SQLFREECONNECT( connection )) { SQLFREECONNECT( connection, connection -> driver_dbc ); } } else { if ( CHECK_SQLFREECONNECT( connection )) { SQLFREECONNECT( connection, connection -> driver_dbc ); } else if ( CHECK_SQLFREEHANDLE( connection )) { SQLFREEHANDLE( connection, SQL_HANDLE_DBC, connection -> driver_dbc ); } } connection -> driver_dbc = (DRV_SQLHANDLE)NULL; __disconnect_part_four( connection ); } /* * interface for SQLGetFunctions */ void __check_for_function( DMHDBC connection, SQLUSMALLINT function_id, SQLUSMALLINT *supported ) { int i; if ( !supported ) { return; } if ( function_id == SQL_API_ODBC3_ALL_FUNCTIONS ) { for ( i = 0; i < SQL_API_ODBC3_ALL_FUNCTIONS_SIZE; i ++ ) { supported[ i ] = 0x0000; } for ( i = 0; i < sizeof( template_func ) / sizeof( template_func[ 0 ] ); i ++ ) { int id = connection -> functions[ i ].ordinal; if ( connection -> functions[ i ].can_supply ) supported[ id >> 4 ] |= ( 1 << ( id & 0x000F )); } } else if ( function_id == SQL_API_ALL_FUNCTIONS ) { for ( i = 0; i < 100; i ++ ) { supported[ i ] = SQL_FALSE; } for ( i = 0; i < sizeof( template_func ) / sizeof( template_func[ 0 ] ); i ++ ) { if ( connection -> functions[ i ].ordinal < 100 ) { if ( connection -> functions[ i ].can_supply ) supported[ connection -> functions[ i ].ordinal ] = SQL_TRUE; } } } else { *supported = SQL_FALSE; for ( i = 0; i < sizeof( template_func ) / sizeof( template_func[ 0 ] ); i ++ ) { if ( connection->functions[ i ].ordinal == function_id ) { if ( connection -> functions[ i ].can_supply ) *supported = SQL_TRUE; break; } } } } static int sql_strcmp( SQLCHAR *s1, SQLCHAR *s2, SQLSMALLINT l1, SQLSMALLINT l2 ) { if ( l1 != l2 ) { return 1; } if ( l1 == SQL_NTS ) { return strcmp((char*) s1, (char*)s2 ); } else { return memcmp( s1, s2, l1 ); } } static void close_pooled_connection( CPOOLENT *ptr ) { SQLRETURN ret; DMHDBC conn = &ptr -> connection; if ( conn -> driver_dbc == NULL ) { return; } /* * disconnect from the driver */ if ( !CHECK_SQLDISCONNECT( conn )) { return; } ret = SQLDISCONNECT( conn, conn -> driver_dbc ); if ( SQL_SUCCEEDED( ret )) { /* * complete disconnection from driver */ if ( conn -> driver_version >= SQL_OV_ODBC3 ) { if ( CHECK_SQLFREEHANDLE( conn )) { SQLFREEHANDLE( conn, SQL_HANDLE_DBC, conn -> driver_dbc ); } else if ( CHECK_SQLFREECONNECT( conn )) { SQLFREECONNECT( conn, conn -> driver_dbc ); } } else { if ( CHECK_SQLFREECONNECT( conn )) { SQLFREECONNECT( conn, conn -> driver_dbc ); } else if ( CHECK_SQLFREEHANDLE( conn )) { SQLFREEHANDLE( conn, SQL_HANDLE_DBC, conn -> driver_dbc ); } } conn -> driver_dbc = (DRV_SQLHANDLE)NULL; /* * Only call freeenv if it's the last connection to the driver */ release_env( conn ); conn -> driver_env = (DRV_SQLHANDLE)NULL; /* * unload the lib */ if ( conn -> cl_handle ) { odbc_dlclose( conn -> cl_handle ); conn -> cl_handle = NULL; } if ( conn -> dl_handle ) { /* * this is safe, because the dlopen function will reuse the handle if we * open the same lib again */ if ( !conn -> dont_dlclose ) { /* * call fini function if found */ if ( conn -> fini_func.func ) { conn -> fini_func.func(); } odbc_dlclose( ptr -> connection.dl_handle ); } conn -> dl_handle = NULL; } /* * free some memory */ if ( conn -> functions ) { free( conn -> functions ); conn -> functions = NULL; } } else { /* * All we can do is tidy up */ conn -> driver_dbc = (DRV_SQLHANDLE)NULL; conn -> driver_env = (DRV_SQLHANDLE)NULL; /* * unload the lib */ if ( conn -> cl_handle ) { odbc_dlclose( conn -> cl_handle ); conn -> cl_handle = NULL; } if ( conn -> dl_handle ) { /* * this is safe, because the dlopen function will reuse the handle if we * open the same lib again */ if ( !conn -> dont_dlclose ) { /* * call fini function if found */ if ( conn -> fini_func.func ) { conn -> fini_func.func(); } odbc_dlclose( conn -> dl_handle ); } conn -> dl_handle = NULL; } /* * free some memory */ if ( conn -> functions ) { free( conn -> functions ); conn -> functions = NULL; } } /* * now clean up any statements that are left about */ __clean_stmt_from_dbc( conn ); __clean_desc_from_dbc( conn ); #ifdef HAVE_ICONV if ( ptr -> connection.iconv_cd_ascii_to_uc != (iconv_t)(-1) ) { iconv_close( ptr -> connection.iconv_cd_ascii_to_uc ); ptr -> connection.iconv_cd_ascii_to_uc = (iconv_t)(-1); } if ( ptr -> connection.iconv_cd_uc_to_ascii != (iconv_t)(-1)) { iconv_close( ptr -> connection.iconv_cd_uc_to_ascii ); ptr -> connection.iconv_cd_uc_to_ascii = (iconv_t)(-1); } #endif } /* * if a environment gets released from the application, we need to remove any referenvce to that environment * in pooled connections that belong to that environment. Also if needed call the release in the driver itself */ void __strip_from_pool( DMHENV env ) { CPOOLHEAD *ptrh; mutex_pool_entry(); for( ptrh = pool_head; ptrh; ptrh = ptrh -> next ) { CPOOLENT *ptre; for ( ptre = ptrh -> entries; ptre; ptre = ptre -> next ) { if ( ptre -> connection.environment == env ) { /* * disconnect driver side connection, and when the last the driver side env */ close_pooled_connection( ptre ); ptre -> connection.environment = NULL; } } } mutex_pool_exit(); } void pool_unreserve( CPOOLHEAD *pooh ) { if ( pooh ) { mutex_pool_entry(); if ( ! -- pooh -> num_entries ) { CPOOLHEAD *head, *prev; for ( head = pool_head, prev = NULL ; head ; prev = head, head = head -> next ) { if ( head == pooh ) { if ( prev ) { prev -> next = pooh -> next; } else { pool_head = pooh -> next; } free( pooh -> _driver_connect_string ); free( pooh ); break; } } } pool_signal(); mutex_pool_exit(); } } static void copy_nts( SQLCHAR *dst, SQLCHAR *src, int *out_length, SQLSMALLINT length ) { if ( src == NULL ) { dst[ 0 ] = '\0'; } else { if ( length < 0 ) { strcpy( dst, src ); } else { memcpy( dst, src, length ); } } if ( out_length) { *out_length = length; } } static int pool_match( CPOOLHEAD *pooh, SQLCHAR *server_name, SQLSMALLINT name_length1, SQLCHAR *user_name, SQLSMALLINT name_length2, SQLCHAR *authentication, SQLSMALLINT name_length3, SQLCHAR *connect_string, SQLSMALLINT connect_string_length ) { int match = 1; if ( server_name ) { if ( pooh -> server_length == 0 ) { match = 0; } if ( pooh -> server_length != name_length1 || sql_strcmp( server_name, (SQLCHAR*)pooh -> server, name_length1, pooh -> server_length )) { match = 0; } if ( pooh -> user_length != name_length2 || sql_strcmp( user_name, (SQLCHAR*)pooh -> user, name_length2, pooh -> user_length )) { match = 0; } if ( pooh -> password_length != name_length3 || sql_strcmp( authentication, (SQLCHAR*)pooh -> password, name_length3, pooh -> password_length )) { match = 0; } } else { if ( pooh -> dsn_length == 0 ) { match = 0; } if ( pooh -> dsn_length != connect_string_length || sql_strcmp( connect_string, (SQLCHAR*)pooh -> _driver_connect_string, connect_string_length, pooh -> dsn_length )) { match = 0; } } return match; } /* int display_pool( void ) { printf( "pool_head: %p\n", pool_head ); if ( pool_head ) { CPOOLHEAD *pptr; CPOOLENT *pent; pptr = pool_head; while( pptr ) { printf( "\tpptr: %p\n", pptr ); printf( "\t\tdsn: %s\n", pptr -> _driver_connect_string ); printf( "\t\tnum_entries: %d\n", pptr -> num_entries ); printf( "\t\tentries: %p\n", pptr -> entries ); printf( "\t\tnext: %p\n", pptr -> next ); pent = pptr -> entries; while( pent ) { printf( "\t\t\tpent: %p\n", pent ); printf( "\t\t\texpiry_time: %d\n", pent -> expiry_time ); printf( "\t\t\tttl: %d\n", pent -> ttl ); printf( "\t\t\tin_use: %d\n", pent -> in_use ); printf( "\t\t\thead: %p\n", pent -> head ); printf( "\t\t\tcursors: %d\n", pent -> cursors ); printf( "\t\t\tconnection -> env: %p\n", pent -> connection.environment ); printf( "\t\t\tconnection -> driver_env: %p\n", pent -> connection.driver_env ); printf( "\t\t\tnext: %p\n", pent -> next ); printf( "\n" ); pent = pent -> next; } pptr = pptr -> next; printf( "\n" ); } } } */ /* * Search for a matching connection from the pool * Removes expired connections too Returns 0: No connection found, max size not reached (reserves an entry) 1: Connection found 2: No connection found, max size reached (pool mutex remains locked) */ int search_for_pool( DMHDBC connection, SQLCHAR *server_name, SQLSMALLINT name_length1, SQLCHAR *user_name, SQLSMALLINT name_length2, SQLCHAR *authentication, SQLSMALLINT name_length3, SQLCHAR *connect_string, SQLSMALLINT connect_string_length, CPOOLHEAD **pooh, int retrying ) { time_t current_time; SQLULEN dead; CPOOLHEAD *ptrh, *prevh, *match_head; CPOOLENT *ptre, *preve; int has_checked = 0; if ( !retrying ) { mutex_pool_entry(); } current_time = time( NULL ); /* * look in the list of connections for one that matches */ restart:; match_head = 0; for( ptrh = pool_head, prevh = NULL; ptrh; prevh = ptrh, ptrh = ptrh -> next ) { SQLRETURN ret; int conn_match; conn_match = pool_match( ptrh, server_name, name_length1, user_name, name_length2, authentication, name_length3, connect_string, connect_string_length ); if ( conn_match ) { match_head = ptrh; } for ( ptre = ptrh -> entries, preve = NULL; ptre; preve = ptre, ptre = ptre -> next ) { if ( ptre -> in_use ) { continue; } /* * has it been previously stripped */ if ( ptre -> connection.environment == NULL ) { if ( ptre == ptrh -> entries ) /* head of the list ? */ { ptrh -> entries = ptre -> next; } else { preve -> next = ptre -> next; } free( ptre ); ptrh -> num_entries --; pool_signal(); if ( ! ptrh -> num_entries ) /* free the head too */ { if ( prevh ) { prevh -> next = ptrh -> next; } else { pool_head = ptrh -> next; } free( ptrh -> _driver_connect_string ); free( ptrh ); } goto restart; } /* * has it expired ? Do some cleaning up first */ if ( ptre -> expiry_time < current_time ) { /* * disconnect and remove */ disconnect_and_remove: close_pooled_connection( ptre ); if ( ptre == ptrh -> entries ) /* head of the list ? */ { ptrh -> entries = ptre -> next; } else { preve -> next = ptre -> next; } free( ptre ); ptrh -> num_entries --; pool_signal(); if ( ! ptrh -> num_entries ) /* free the head too */ { if ( prevh ) { prevh -> next = ptrh -> next; } else { pool_head = ptrh -> next; } free( ptrh -> _driver_connect_string ); free( ptrh ); } goto restart; } /* * has the time-to-live got to one ? */ if ( ptre -> ttl == 1 ) { goto disconnect_and_remove; } else if ( ptre -> ttl > 1 ) { ptre -> ttl --; } /* * does it match ? */ if ( !conn_match ) { continue; } /* * is it the same cursor usage ? */ if ( ptre -> cursors != connection -> cursors ) { continue; } /* * we are spanning env's */ if ( ptre -> connection.environment && ptre -> connection.environment != connection -> environment ) { continue; } /* * ok so far, is it still alive ? */ has_checked = 0; /* * A pointer to memory in which to return the current value of the attribute specified by Attribute. * For integer-type attributes, some drivers may only write the lower 32-bit or 16-bit of a buffer * and leave the higher-order bit unchanged. Therefore, applications should use a buffer of SQLULEN * and initialize the value to 0 before calling this function. */ dead = 0; if ((CHECK_SQLGETCONNECTATTR(( &ptre -> connection )) && SQL_SUCCEEDED( ret = SQLGETCONNECTATTR(( &ptre -> connection ), ptre -> connection.driver_dbc, SQL_ATTR_CONNECTION_DEAD, &dead, SQL_IS_INTEGER, 0 ))) || (CHECK_SQLGETCONNECTATTRW(( &ptre -> connection )) && SQL_SUCCEEDED( ret = SQLGETCONNECTATTRW(( &ptre -> connection ), ptre -> connection.driver_dbc, SQL_ATTR_CONNECTION_DEAD, &dead, SQL_IS_INTEGER, 0 ))) || (CHECK_SQLGETCONNECTOPTION(( &ptre -> connection )) && SQL_SUCCEEDED( ret = SQLGETCONNECTOPTION(( &ptre -> connection ), ptre -> connection.driver_dbc, SQL_ATTR_CONNECTION_DEAD, &dead ))) || (CHECK_SQLGETCONNECTOPTIONW(( &ptre -> connection )) && SQL_SUCCEEDED( ret = SQLGETCONNECTOPTIONW(( &ptre -> connection ), ptre -> connection.driver_dbc, SQL_ATTR_CONNECTION_DEAD, &dead ))) ) { /* * if it failed assume that it's because it doesn't support * it, but it's ok */ if ( dead == SQL_CD_TRUE ) { goto disconnect_and_remove; } has_checked = 1; } /* * Need some other way of checking, This isn't safe to pool... * But it needs to be something thats not slower than connecting... * I have put this off, so its after the check that the server_name and all * the rest is ok to avoid waiting time, as the check could take time */ if ( !has_checked ) { if ( strlen( connection -> probe_sql ) > 0 ) { /* * Execute the query, check we have all we need */ if ( CHECK_SQLEXECDIRECT(( &ptre -> connection )) && ( CHECK_SQLALLOCHANDLE(( &ptre -> connection )) || CHECK_SQLALLOCSTMT(( &ptre -> connection ))) && CHECK_SQLNUMRESULTCOLS(( &ptre -> connection )) && CHECK_SQLFETCH(( &ptre -> connection )) && CHECK_SQLFREESTMT(( &ptre -> connection ))) { DMHSTMT statement; int ret; int check_failed = 0; statement = __alloc_stmt(); if ( CHECK_SQLALLOCHANDLE(( &ptre -> connection ))) { ret = SQLALLOCHANDLE(( &ptre -> connection ), SQL_HANDLE_STMT, ptre -> connection.driver_dbc, ( &statement -> driver_stmt ), statement ); } else { ret = SQLALLOCSTMT(( &ptre -> connection ), ptre -> connection.driver_dbc, ( &statement -> driver_stmt ), statement ); } if ( !SQL_SUCCEEDED( ret )) { check_failed = 1; } else { ret = SQLEXECDIRECT(( &ptre -> connection ), statement -> driver_stmt, connection -> probe_sql, SQL_NTS ); if ( !SQL_SUCCEEDED( ret )) { check_failed = 1; } else { SQLSMALLINT column_count; /* * Check if there is a result set */ ret = SQLNUMRESULTCOLS(( &ptre -> connection ), statement -> driver_stmt, &column_count ); if ( !SQL_SUCCEEDED( ret )) { check_failed = 1; } else if ( column_count > 0 ) { do { ret = SQLFETCH(( &ptre -> connection ), statement -> driver_stmt ); } while( SQL_SUCCEEDED( ret )); if ( ret != SQL_NO_DATA ) { check_failed = 1; } ret = SQLFREESTMT(( &ptre -> connection ), statement -> driver_stmt, SQL_CLOSE ); if ( !SQL_SUCCEEDED( ret )) { check_failed = 1; } } } ret = SQLFREESTMT(( &ptre -> connection ), statement -> driver_stmt, SQL_DROP ); if ( !SQL_SUCCEEDED( ret )) { check_failed = 1; } } __release_stmt( statement ); if ( check_failed ) { goto disconnect_and_remove; } else { has_checked = 1; } } } } if ( !has_checked ) { /* * We can't know for sure if the connection is still valid ... */ } /* * at this point we have something that should work, lets use it */ ptre -> in_use = 1; ptre -> expiry_time = current_time + ptre -> timeout; connection -> pooling_timeout = ptre -> timeout; /* * copy all the info over */ connection -> pooled_connection = ptre; connection -> state = ptre -> connection.state; connection -> dl_handle = ptre -> connection.dl_handle; connection -> functions = ptre -> connection.functions; connection -> unicode_driver = ptre -> connection.unicode_driver; connection -> driver_env = ptre -> connection.driver_env; connection -> driver_dbc = ptre -> connection.driver_dbc; connection -> driver_version = ptre -> connection.driver_version; connection -> driver_act_ver = ptre -> connection.driver_act_ver; connection -> statement_count = 0; connection -> access_mode = ptre -> connection.access_mode; connection -> access_mode_set = ptre -> connection.access_mode_set; connection -> login_timeout = ptre -> connection.login_timeout; connection -> login_timeout_set = ptre -> connection.login_timeout_set; connection -> auto_commit = ptre -> connection.auto_commit; connection -> auto_commit_set = ptre -> connection.auto_commit_set; connection -> async_enable = ptre -> connection.async_enable; connection -> async_enable_set = ptre -> connection.async_enable_set; connection -> auto_ipd = ptre -> connection.auto_ipd; connection -> auto_ipd_set = ptre -> connection.auto_ipd_set; connection -> connection_timeout = ptre -> connection.connection_timeout; connection -> connection_timeout_set = ptre -> connection.connection_timeout_set; connection -> metadata_id = ptre -> connection.metadata_id; connection -> metadata_id_set = ptre -> connection.metadata_id_set; connection -> packet_size = ptre -> connection.packet_size; connection -> packet_size_set = ptre -> connection.packet_size_set; connection -> quite_mode = ptre -> connection.quite_mode; connection -> quite_mode_set = ptre -> connection.quite_mode_set; connection -> txn_isolation = ptre -> connection.txn_isolation; connection -> txn_isolation_set = ptre -> connection.txn_isolation_set; connection -> cursors = ptre -> connection.cursors; connection -> cl_handle = ptre -> connection.cl_handle; connection -> env_list_ent = ptre -> connection.env_list_ent; strcpy( connection -> probe_sql, ptre -> connection.probe_sql ); connection -> ex_fetch_mapping = ptre -> connection.ex_fetch_mapping; connection -> dont_dlclose = ptre -> connection.dont_dlclose; connection -> bookmarks_on = ptre -> connection.bookmarks_on; #ifdef HAVE_ICONV connection -> iconv_cd_uc_to_ascii = ptre -> connection.iconv_cd_uc_to_ascii; connection -> iconv_cd_ascii_to_uc = ptre -> connection.iconv_cd_ascii_to_uc; #endif /* * copy current environment into the pooled connection */ ptre -> connection.environment = connection -> environment; strcpy( connection -> dsn, ptre -> connection.dsn ); #if defined( HAVE_LIBPTH ) || defined( HAVE_LIBPTHREAD ) || defined( HAVE_LIBTHREAD ) dbc_change_thread_support(connection, ptre -> connection.protection_level); #endif mutex_pool_exit(); return TRUE; } } /* this head is the right one, but is it full ? */ if ( match_head ) { if ( pool_max_size && match_head -> num_entries >= pool_max_size ) { /* Note we do NOT exit pool mutex here, as wait will exit it automatically */ return 2; } match_head -> num_entries ++; /* reserve an entry */ } else { /* add an empty head with 1 reserved entry */ CPOOLHEAD *newhead = calloc( sizeof( CPOOLHEAD ), 1 ); if ( newhead ) { copy_nts( newhead -> server, server_name, &newhead -> server_length, name_length1 ); copy_nts( newhead -> user, user_name, &newhead -> user_length, name_length2 ); copy_nts( newhead -> password, authentication, &newhead -> password_length, name_length3 ); if ( connect_string == NULL ) { newhead -> _driver_connect_string = calloc( 1, 1 ); } else if ( connect_string_length < 0 ) { newhead -> _driver_connect_string = calloc( strlen( connect_string ) + 1, 1 ); } else { newhead -> _driver_connect_string = calloc( connect_string_length + 1, 1 ); } copy_nts( newhead -> _driver_connect_string, connect_string, &newhead -> dsn_length, connect_string_length ); newhead -> num_entries = 1; /* reserve an entry */ newhead -> next = pool_head; pool_head = newhead; match_head = newhead; } } if ( pooh ) { *pooh = match_head; } mutex_pool_exit(); return FALSE; } int add_to_pool ( DMHDBC connection, CPOOLHEAD *pooh ) { CPOOLENT *ptr; time_t current_time; mutex_pool_entry(); current_time = time( NULL ); /* Should be new entry */ ptr = calloc( sizeof( CPOOLENT ), 1 ); if ( !ptr ) { mutex_pool_exit(); return FALSE; } /* Copy info */ ptr -> in_use = 1; ptr -> expiry_time = current_time + connection -> pooling_timeout; ptr -> timeout = connection -> pooling_timeout; ptr -> ttl = connection -> ttl; ptr -> cursors = connection -> cursors; ptr -> connection.state = connection -> state; ptr -> connection.dl_handle = connection -> dl_handle; ptr -> connection.functions = connection -> functions; ptr -> connection.driver_env = connection -> driver_env; ptr -> connection.driver_dbc = connection -> driver_dbc; ptr -> connection.driver_version = connection -> driver_version; ptr -> connection.driver_act_ver = connection -> driver_act_ver; ptr -> connection.access_mode = connection -> access_mode; ptr -> connection.access_mode_set = connection -> access_mode_set; ptr -> connection.login_timeout = connection -> login_timeout; ptr -> connection.login_timeout_set = connection -> login_timeout_set; ptr -> connection.auto_commit = connection -> auto_commit; ptr -> connection.auto_commit_set = connection -> auto_commit_set; ptr -> connection.async_enable = connection -> async_enable; ptr -> connection.async_enable_set = connection -> async_enable_set; ptr -> connection.auto_ipd = connection -> auto_ipd; ptr -> connection.auto_ipd_set = connection -> auto_ipd_set; ptr -> connection.connection_timeout = connection -> connection_timeout; ptr -> connection.connection_timeout_set = connection -> connection_timeout_set; ptr -> connection.metadata_id = connection -> metadata_id; ptr -> connection.metadata_id_set = connection -> metadata_id_set; ptr -> connection.packet_size = connection -> packet_size; ptr -> connection.packet_size_set = connection -> packet_size_set; ptr -> connection.quite_mode = connection -> quite_mode; ptr -> connection.quite_mode_set = connection -> quite_mode_set; ptr -> connection.txn_isolation = connection -> txn_isolation; ptr -> connection.txn_isolation_set = connection -> txn_isolation_set; ptr -> connection.unicode_driver = connection ->unicode_driver; ptr -> connection.cursors = connection -> cursors; ptr -> connection.cl_handle = connection -> cl_handle; #ifdef HAVE_LIBPTHREAD ptr -> connection.mutex = connection -> mutex; ptr -> connection.protection_level = connection -> protection_level; #elif HAVE_LIBTHREAD ptr -> connection.mutex = connection -> mutex; ptr -> connection.protection_level = connection -> protection_level; #endif ptr -> connection.pooling_timeout = ptr -> timeout; ptr -> connection.ex_fetch_mapping = connection -> ex_fetch_mapping; ptr -> connection.dont_dlclose = connection -> dont_dlclose; ptr -> connection.bookmarks_on = connection -> bookmarks_on; ptr -> connection.env_list_ent = connection -> env_list_ent; ptr -> connection.environment = connection -> environment; strcpy( ptr -> connection.probe_sql, connection -> probe_sql ); #ifdef HAVE_ICONV ptr -> connection.iconv_cd_uc_to_ascii = connection -> iconv_cd_uc_to_ascii; ptr -> connection.iconv_cd_ascii_to_uc = connection -> iconv_cd_ascii_to_uc; connection -> iconv_cd_uc_to_ascii = (iconv_t) -1; connection -> iconv_cd_ascii_to_uc = (iconv_t) -1; #endif /* * add to the list * no need to increment count, since that was reserved in search_for_pool */ ptr -> head = pooh; ptr -> next = pooh -> entries; pooh -> entries = ptr; connection -> pooled_connection = ptr; mutex_pool_exit(); return TRUE; } void return_to_pool( DMHDBC connection ) { CPOOLENT *ptr; time_t current_time; mutex_pool_entry(); ptr = connection -> pooled_connection; current_time = time( NULL ); /* * is it a old entry ? */ if ( connection -> pooled_connection ) { ptr -> in_use = 0; ptr -> expiry_time = current_time + ptr -> timeout; #ifdef HAVE_ICONV connection -> iconv_cd_uc_to_ascii = (iconv_t) -1; connection -> iconv_cd_ascii_to_uc = (iconv_t) -1; #endif } /* * allow the driver to reset itself if it's a 3.8 driver */ if ( connection -> driver_version == SQL_OV_ODBC3_80 ) { if ( CHECK_SQLSETCONNECTATTR( connection )) { SQLSETCONNECTATTR( connection, connection -> driver_dbc, SQL_ATTR_RESET_CONNECTION, (SQLPOINTER)(intptr_t) SQL_RESET_CONNECTION_YES, 0 ); } } /* * remove all information from the connection */ connection -> state = STATE_C2; connection -> driver_env = 0; connection -> driver_dbc = 0; connection -> dl_handle = 0; connection -> cl_handle = 0; connection -> functions = 0; connection -> pooled_connection = 0; pool_signal(); mutex_pool_exit(); } void __handle_attr_extensions( DMHDBC connection, char *dsn, char *driver_name ) { char txt[ 1024 ]; if ( dsn && strlen( dsn )) { SQLGetPrivateProfileString( dsn, "DMEnvAttr", "", txt, sizeof( txt ), "ODBC.INI" ); if ( strlen( txt )) { __parse_attribute_string( &connection -> env_attribute, txt, strlen( txt )); } SQLGetPrivateProfileString( dsn, "DMConnAttr", "", txt, sizeof( txt ), "ODBC.INI" ); if ( strlen( txt )) { __parse_attribute_string( &connection -> dbc_attribute, txt, strlen( txt )); } SQLGetPrivateProfileString( dsn, "DMStmtAttr", "", txt, sizeof( txt ), "ODBC.INI" ); if ( strlen( txt )) { __parse_attribute_string( &connection -> stmt_attribute, txt, strlen( txt )); } } if ( driver_name && strlen( driver_name )) { SQLGetPrivateProfileString( driver_name, "DMEnvAttr", "", txt, sizeof( txt ), "ODBCINST.INI" ); if ( strlen( txt )) { __parse_attribute_string( &connection -> env_attribute, txt, strlen( txt )); } } } SQLRETURN SQLConnectA( SQLHDBC connection_handle, SQLCHAR *server_name, SQLSMALLINT name_length1, SQLCHAR *user_name, SQLSMALLINT name_length2, SQLCHAR *authentication, SQLSMALLINT name_length3 ) { return SQLConnect( connection_handle, server_name, name_length1, user_name, name_length2, authentication, name_length3 ); } SQLRETURN SQLConnect( SQLHDBC connection_handle, SQLCHAR *server_name, SQLSMALLINT name_length1, SQLCHAR *user_name, SQLSMALLINT name_length2, SQLCHAR *authentication, SQLSMALLINT name_length3 ) { DMHDBC connection = (DMHDBC)connection_handle; int len, ret_from_connect; char dsn[ SQL_MAX_DSN_LENGTH + 1 ]; char lib_name[ INI_MAX_PROPERTY_VALUE + 1 ]; char driver_name[ INI_MAX_PROPERTY_VALUE + 1 ]; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ]; int warnings; CPOOLHEAD *pooh = 0; /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tServer Name = %s\ \n\t\t\tUser Name = %s\ \n\t\t\tAuthentication = %s", connection, __string_with_length( s1, server_name, name_length1 ), __string_with_length( s2, user_name, name_length2 ), __string_with_length_pass( s3, authentication, name_length3 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if (( name_length1 < 0 && name_length1 != SQL_NTS ) || ( name_length2 < 0 && name_length2 != SQL_NTS ) || ( name_length3 < 0 && name_length3 != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * check the state of the connection */ if ( connection -> state != STATE_C2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08002" ); __post_internal_error( &connection -> error, ERROR_08002, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( name_length1 && server_name ) { if ( name_length1 == SQL_NTS ) { len = strlen((char*) server_name ); if ( len > SQL_MAX_DSN_LENGTH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { len = name_length1; if ( len > SQL_MAX_DSN_LENGTH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } memcpy( dsn, server_name, len ); dsn[ len ] ='\0'; } else if ( name_length1 > SQL_MAX_DSN_LENGTH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM010" ); __post_internal_error( &connection -> error, ERROR_IM010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { strcpy( dsn, "DEFAULT" ); } /* * can we find a pooled connection to use here ? */ connection -> pooled_connection = NULL; if ( pooling_enabled ) { int retpool; int retrying = 0; time_t wait_begin = time( NULL ); retry: retpool = search_for_pool( connection, server_name, name_length1, user_name, name_length2, authentication, name_length3, NULL, 0, &pooh, retrying ); /* * found usable existing connection from pool */ if ( retpool == 1 ) { ret_from_connect = SQL_SUCCESS; if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } connection -> state = STATE_C4; return function_return_nodrv( SQL_HANDLE_DBC, connection, ret_from_connect ); } /* * pool is at capacity */ if ( retpool == 2 ) { /* * either no timeout or exceeded the timeout */ if ( ! pool_wait_timeout || time( NULL ) - wait_begin > pool_wait_timeout ) { mutex_pool_exit(); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HYT02" ); __post_internal_error( &connection -> error, ERROR_HYT02, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * wait up to 1 second for a signal and try again */ pool_timedwait( connection ); retrying = 1; goto retry; } /* * 1 pool entry has been reserved. Early exits henceforth need to unreserve. */ } /* * else safe the info for later */ if ( pooling_enabled ) { connection -> dsn_length = 0; if ( server_name ) { if ( name_length1 < 0 ) { strcpy( connection -> server, (char*)server_name ); } else { memcpy( connection -> server, server_name, name_length1 ); } } else { strcpy( connection -> server, "" ); } connection -> server_length = name_length1; if ( user_name ) { if ( name_length2 < 0 ) { strcpy( connection -> user, (char*)user_name ); } else { memcpy( connection -> user, user_name, name_length2 ); } } else { strcpy( connection -> user, "" ); } connection -> user_length = name_length2; if ( authentication ) { if ( name_length3 ) { strcpy( connection -> password, (char*)authentication ); } else { memcpy( connection -> password, authentication, name_length3 ); } } else { strcpy( connection -> password, "" ); } connection -> password_length = name_length3; } if ( !*dsn || !__find_lib_name( dsn, lib_name, driver_name )) { /* * if not found look for a default */ if ( !__find_lib_name( "DEFAULT", lib_name, driver_name )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM002" ); __post_internal_error( &connection -> error, ERROR_IM002, NULL, connection -> environment -> requested_version ); pool_unreserve( pooh ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } /* * do we have any Environment, Connection, or Statement attributes set in the ini ? */ __handle_attr_extensions( connection, dsn, driver_name ); /* * if necessary change the threading level */ warnings = 0; if ( !__connect_part_one( connection, lib_name, driver_name, &warnings )) { __disconnect_part_four( connection ); /* release unicode handles */ pool_unreserve( pooh ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( !CHECK_SQLCONNECT( connection ) && !CHECK_SQLCONNECTW( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); pool_unreserve( pooh ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( CHECK_SQLCONNECT( connection )) { /* if ( CHECK_SQLSETCONNECTATTR( connection )) { int lret; lret = SQLSETCONNECTATTR( connection, connection -> driver_dbc, SQL_ATTR_ANSI_APP, SQL_AA_TRUE, 0 ); } */ ret_from_connect = SQLCONNECT( connection, connection -> driver_dbc, (SQLCHAR*) dsn, SQL_NTS, user_name, name_length2, authentication, name_length3 ); if ( ret_from_connect != SQL_SUCCESS ) { SQLCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; /* * get the errors from the driver before * loseing the connection */ if ( CHECK_SQLERROR( connection )) { do { ret = SQLERROR( connection, SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", sqlstate, message_text ); dm_log_write_diag( connection -> msg ); } } while( SQL_SUCCEEDED( ret )); } else if ( CHECK_SQLGETDIAGREC( connection )) { int rec = 1; do { ret = SQLGETDIAGREC( connection, SQL_HANDLE_DBC, connection -> driver_dbc, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", sqlstate, message_text ); dm_log_write_diag( connection -> msg ); } } while( SQL_SUCCEEDED( ret )); } } /* * if it was a error then return now */ if ( !SQL_SUCCEEDED( ret_from_connect )) { __disconnect_part_one( connection ); __disconnect_part_four( connection ); sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, ret_from_connect, DEFER_R0 ); } connection -> unicode_driver = 0; } else { SQLWCHAR * uc_dsn, *uc_user, *uc_auth; uc_dsn = ansi_to_unicode_alloc((SQLCHAR*) dsn, SQL_NTS, connection, NULL ); uc_user = ansi_to_unicode_alloc( user_name, name_length2, connection, NULL ); uc_auth = ansi_to_unicode_alloc( authentication, name_length3, connection, NULL ); if ( CHECK_SQLSETCONNECTATTR( connection )) { SQLSETCONNECTATTR( connection, connection -> driver_dbc, SQL_ATTR_ANSI_APP, SQL_AA_FALSE, 0 ); } ret_from_connect = SQLCONNECTW( connection, connection -> driver_dbc, uc_dsn, SQL_NTS, uc_user, name_length2, uc_auth, name_length3 ); if ( uc_dsn ) free( uc_dsn ); if ( uc_user ) free( uc_user ); if ( uc_auth ) free( uc_auth ); if ( ret_from_connect != SQL_SUCCESS ) { SQLWCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLWCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; /* * get the errors from the driver before * looseing the connection */ if ( CHECK_SQLERRORW( connection )) { do { ret = SQLERRORW( connection, SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, sqlstate, &native_error, message_text, sizeof( message_text )/sizeof(SQLWCHAR), &ind ); if ( SQL_SUCCEEDED( ret )) { SQLCHAR *as1, *as2; __post_internal_error_ex_w( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); as1 = (SQLCHAR *) unicode_to_ansi_alloc( sqlstate, SQL_NTS, connection, NULL ); as2 = (SQLCHAR *) unicode_to_ansi_alloc( message_text, SQL_NTS, connection, NULL ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", as1, as2 ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); dm_log_write_diag( connection -> msg ); } } while( SQL_SUCCEEDED( ret )); } else if ( CHECK_SQLGETDIAGRECW( connection )) { int rec = 1; do { ret = SQLGETDIAGRECW( connection, SQL_HANDLE_DBC, connection -> driver_dbc, rec ++, sqlstate, &native_error, message_text, sizeof( message_text )/sizeof(SQLWCHAR), &ind ); if ( SQL_SUCCEEDED( ret )) { SQLCHAR *as1, *as2; __post_internal_error_ex_w( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); as1 = (SQLCHAR *) unicode_to_ansi_alloc( sqlstate, SQL_NTS, connection, NULL ); as2 = (SQLCHAR *) unicode_to_ansi_alloc( message_text, SQL_NTS, connection, NULL ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", as1, as2 ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); dm_log_write_diag( connection -> msg ); } } while( SQL_SUCCEEDED( ret )); } } /* * if it was a error then return now */ if ( !SQL_SUCCEEDED( ret_from_connect )) { __disconnect_part_one( connection ); __disconnect_part_four( connection ); sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, ret_from_connect, DEFER_R0 ); } connection -> unicode_driver = 1; } /* * we should be connected now */ connection -> state = STATE_C4; strcpy( connection -> dsn, dsn ); /* * did we get the type we wanted */ if ( connection -> driver_version != connection -> environment -> requested_version ) { connection -> driver_version = connection -> environment -> requested_version; __post_internal_error( &connection -> error, ERROR_01000, "Driver does not support the requested version", connection -> environment -> requested_version ); ret_from_connect = SQL_SUCCESS_WITH_INFO; } if ( !__connect_part_two( connection )) { /* * the cursor lib can kill us here, so be careful */ __disconnect_part_two( connection ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); connection -> state = STATE_C3; pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } if ( warnings && ret_from_connect == SQL_SUCCESS ) { ret_from_connect = SQL_SUCCESS_WITH_INFO; } if ( pooling_enabled && !add_to_pool( connection, pooh ) ) { pool_unreserve( pooh ); } return function_return_nodrv( SQL_HANDLE_DBC, connection, ret_from_connect ); } /* * connection pooling setup, just stubs for the moment */ BOOL ODBCSetTryWaitValue ( DWORD dwValue ) { return 0; } #ifdef __cplusplus DWORD ODBCGetTryWaitValue ( ) #else DWORD ODBCGetTryWaitValue ( void ) #endif { return 0; } unixODBC-2.3.12/DriverManager/SQLConnectW.c000066400000000000000000000653231446441710500202230ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLConnectW.c,v 1.15 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLConnectW.c,v $ * Revision 1.15 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.14 2008/09/29 14:02:44 lurcher * Fix missing dlfcn group option * * Revision 1.13 2007/02/28 15:37:47 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.12 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.11 2002/12/20 11:36:46 lurcher * * Update DMEnvAttr code to allow setting in the odbcinst.ini entry * * Revision 1.10 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.9 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.8 2002/07/25 09:30:26 lurcher * * Additional unicode and iconv changes * * Revision 1.7 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.6 2002/05/28 13:30:34 lurcher * * Tidy up for AIX * * Revision 1.5 2002/05/24 12:42:50 lurcher * * Alter NEWS and ChangeLog to match their correct usage * Additional UNICODE tweeks * * Revision 1.4 2002/04/10 11:04:36 lurcher * * Fix endian issue with 4 byte unicode support * * Revision 1.3 2002/01/21 18:00:51 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/01/04 13:16:25 nick * * Add support for GNU portable threads and tidy up some UNICODE compile * warnings * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLConnectW.c,v $"; /* * connection pooling stuff */ extern int pooling_enabled; extern CPOOLHEAD *pool_head; extern int pool_max_size; extern int pool_wait_timeout; SQLRETURN SQLConnectW( SQLHDBC connection_handle, SQLWCHAR *server_name, SQLSMALLINT name_length1, SQLWCHAR *user_name, SQLSMALLINT name_length2, SQLWCHAR *authentication, SQLSMALLINT name_length3 ) { DMHDBC connection = (DMHDBC)connection_handle; int len, ret_from_connect; SQLWCHAR dsn[ SQL_MAX_DSN_LENGTH + 1 ]; char lib_name[ INI_MAX_PROPERTY_VALUE + 1 ]; char driver_name[ INI_MAX_PROPERTY_VALUE + 1 ]; SQLCHAR ansi_dsn[ SQL_MAX_DSN_LENGTH + 1 ]; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], ansi_user[ SQL_MAX_DSN_LENGTH + 1 ], ansi_pwd[ SQL_MAX_DSN_LENGTH + 1 ]; int warnings; CPOOLHEAD *pooh = 0; /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHDBC parent_connection; parent_connection = find_parent_handle( connection, SQL_HANDLE_DBC ); if ( parent_connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLCONNECTW( parent_connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLCONNECTW( parent_connection, connection_handle, server_name, name_length1, user_name, name_length2, authentication, name_length3 ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tServer Name = %s\ \n\t\t\tUser Name = %s\ \n\t\t\tAuthentication = %s", connection, __wstring_with_length( s1, server_name, name_length1 ), __wstring_with_length( s2, user_name, name_length2 ), __wstring_with_length_pass( s3, authentication, name_length3 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if (( name_length1 < 0 && name_length1 != SQL_NTS ) || ( name_length2 < 0 && name_length2 != SQL_NTS ) || ( name_length3 < 0 && name_length3 != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * check the state of the connection */ if ( connection -> state != STATE_C2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08002" ); __post_internal_error( &connection -> error, ERROR_08002, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( name_length1 && server_name ) { if ( name_length1 == SQL_NTS ) { len = wide_strlen( server_name ); if ( len > SQL_MAX_DSN_LENGTH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { len = name_length1; if ( len > SQL_MAX_DSN_LENGTH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } memcpy( dsn, server_name, sizeof( dsn[ 0 ] ) * len ); dsn[ len ] = (SQLWCHAR) 0; } else if ( name_length1 > SQL_MAX_DSN_LENGTH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM010" ); __post_internal_error( &connection -> error, ERROR_IM010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { int i; for ( i = 0; i < 8; i ++ ) dsn[ i ] = "DEFAULT"[i]; } /* * can we find a pooled connection to use here ? */ connection -> pooled_connection = NULL; if ( pooling_enabled ) { char *ansi_server_name, *ansi_user_name, *ansi_authentication; int ansi_name_length1, ansi_name_length2, ansi_name_length3; int retpool; int retrying = 0; time_t wait_begin = time( NULL ); if ( server_name ) { ansi_server_name = unicode_to_ansi_alloc( server_name, name_length1, connection, &ansi_name_length1 ); } else { ansi_server_name = NULL; ansi_name_length1 = 0; } if ( user_name ) { ansi_user_name = unicode_to_ansi_alloc( user_name, name_length2, connection, &ansi_name_length2 ); } else { ansi_user_name = NULL; ansi_name_length2 = 0; } if ( authentication ) { ansi_authentication = unicode_to_ansi_alloc( authentication, name_length3, connection, &ansi_name_length3 ); } else { ansi_authentication = NULL; ansi_name_length3 = 0; } retry: retpool = search_for_pool( connection, ansi_server_name, ansi_name_length1, ansi_user_name, ansi_name_length2, ansi_authentication, ansi_name_length3, NULL, 0, &pooh, retrying ); /* * found usable existing connection from pool */ if ( retpool == 1 ) { ret_from_connect = SQL_SUCCESS; if ( ansi_server_name ) { free( ansi_server_name ); } if ( ansi_user_name ) { free( ansi_user_name ); } if ( ansi_authentication ) { free( ansi_authentication ); } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } connection -> state = STATE_C4; return function_return_nodrv( SQL_HANDLE_DBC, connection, ret_from_connect ); } /* * pool is at capacity */ if ( retpool == 2 ) { /* * either no timeout or exceeded the timeout */ if ( ! pool_wait_timeout || time( NULL ) - wait_begin > pool_wait_timeout ) { if ( ansi_server_name ) { free( ansi_server_name ); } if ( ansi_user_name ) { free( ansi_user_name ); } if ( ansi_authentication ) { free( ansi_authentication ); } mutex_pool_exit(); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HYT02" ); __post_internal_error( &connection -> error, ERROR_HYT02, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * wait up to 1 second for a signal and try again */ pool_timedwait( connection ); retrying = 1; goto retry; } /* * 1 pool entry has been reserved. Early exits henceforth need to unreserve. */ /* * else save the info for later */ connection -> dsn_length = 0; if ( ansi_server_name ) { if ( ansi_name_length1 < 0 ) { strcpy( connection -> server, ansi_server_name ); } else { memcpy( connection -> server, ansi_server_name, ansi_name_length1 ); } } else { strcpy( connection -> server, "" ); } connection -> server_length = ansi_name_length1; if ( ansi_user_name ) { if ( ansi_name_length2 < 0 ) { strcpy( connection -> user, ansi_user_name ); } else { memcpy( connection -> user, ansi_user_name, ansi_name_length2 ); } } else { strcpy( connection -> user, "" ); } connection -> user_length = ansi_name_length2; if ( ansi_authentication ) { if ( ansi_name_length3 ) { strcpy( connection -> password, ansi_authentication ); } else { memcpy( connection -> password, ansi_authentication, ansi_name_length3 ); } } else { strcpy( connection -> password, "" ); } connection -> password_length = ansi_name_length3; if ( ansi_server_name ) { free( ansi_server_name ); } if ( ansi_user_name ) { free( ansi_user_name ); } if ( ansi_authentication ) { free( ansi_authentication ); } } unicode_to_ansi_copy((char*) ansi_dsn, sizeof( ansi_dsn ), dsn, sizeof( ansi_dsn ), NULL, NULL ); if ( !*ansi_dsn || !__find_lib_name((char*) ansi_dsn, lib_name, driver_name )) { /* * if not found look for a default */ if ( !__find_lib_name( "DEFAULT", lib_name, driver_name )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM002" ); __post_internal_error( &connection -> error, ERROR_IM002, NULL, connection -> environment -> requested_version ); pool_unreserve( pooh ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } /* * do we have any Environment, Connection, or Statement attributes set in the ini ? */ __handle_attr_extensions( connection, (char*) ansi_dsn, driver_name ); /* * if necessary change the threading level */ warnings = 0; if ( !__connect_part_one( connection, lib_name, driver_name, &warnings )) { __disconnect_part_four( connection ); /* release unicode handles */ pool_unreserve( pooh ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( !CHECK_SQLCONNECTW( connection ) && !CHECK_SQLCONNECT( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); pool_unreserve( pooh ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( CHECK_SQLCONNECTW( connection )) { if ( CHECK_SQLSETCONNECTATTR( connection )) { SQLSETCONNECTATTR( connection, connection -> driver_dbc, SQL_ATTR_ANSI_APP, SQL_AA_FALSE, 0 ); } ret_from_connect = SQLCONNECTW( connection, connection -> driver_dbc, dsn, SQL_NTS, user_name, name_length2, authentication, name_length3 ); connection -> unicode_driver = 1; } else { if ( user_name ) { if ( name_length2 == SQL_NTS ) unicode_to_ansi_copy((char*) ansi_user, sizeof( ansi_user ),user_name, sizeof( ansi_user ), connection, NULL); else unicode_to_ansi_copy((char*) ansi_user, sizeof( ansi_user ),user_name, name_length2, connection, NULL ); } if ( authentication ) { if ( name_length3 == SQL_NTS ) unicode_to_ansi_copy((char*) ansi_pwd, sizeof( ansi_pwd ), authentication, sizeof( ansi_pwd ), connection, NULL); else unicode_to_ansi_copy((char*) ansi_pwd, sizeof( ansi_pwd ), authentication, name_length3, connection, NULL ); } /* if ( CHECK_SQLSETCONNECTATTR( connection )) { int lret; lret = SQLSETCONNECTATTR( connection, connection -> driver_dbc, SQL_ATTR_ANSI_APP, SQL_AA_TRUE, 0 ); } */ ret_from_connect = SQLCONNECT( connection, connection -> driver_dbc, ansi_dsn, SQL_NTS, user_name ? ansi_user : NULL, name_length2, authentication ? ansi_pwd : NULL, name_length3 ); connection -> unicode_driver = 0; } if ( ret_from_connect != SQL_SUCCESS ) { /* * get the errors from the driver before * loseing the connection */ if ( connection -> unicode_driver ) { SQLWCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLWCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; if ( CHECK_SQLERRORW( connection )) { do { ret = SQLERRORW( connection, SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, sqlstate, &native_error, message_text, sizeof( message_text )/sizeof(SQLWCHAR), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex_w( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } while( SQL_SUCCEEDED( ret )); } else if ( CHECK_SQLGETDIAGRECW( connection )) { int rec = 1; do { ret = SQLGETDIAGRECW( connection, SQL_HANDLE_DBC, connection -> driver_dbc, rec ++, sqlstate, &native_error, message_text, sizeof( message_text )/sizeof(SQLWCHAR), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex_w( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } while( SQL_SUCCEEDED( ret )); } } else { SQLCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; if ( CHECK_SQLERROR( connection )) { do { ret = SQLERROR( connection, SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } while( SQL_SUCCEEDED( ret )); } else if ( CHECK_SQLGETDIAGREC( connection )) { int rec = 1; do { ret = SQLGETDIAGREC( connection, SQL_HANDLE_DBC, connection -> driver_dbc, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } while( SQL_SUCCEEDED( ret )); } } /* * if it was a error then return now */ if ( !SQL_SUCCEEDED( ret_from_connect )) { __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, ret_from_connect, DEFER_R0 ); } } /* * we should be connected now */ connection -> state = STATE_C4; strcpy( connection -> dsn, (char*)ansi_dsn ); /* * did we get the type we wanted */ if ( connection -> driver_version != connection -> environment -> requested_version ) { connection -> driver_version = connection -> environment -> requested_version; __post_internal_error( &connection -> error, ERROR_01000, "Driver does not support the requested version", connection -> environment -> requested_version ); ret_from_connect = SQL_SUCCESS_WITH_INFO; } if ( !__connect_part_two( connection )) { /* * the cursor lib can kill us here, so be careful */ __disconnect_part_two( connection ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ connection -> state = STATE_C3; pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } if ( warnings && ret_from_connect == SQL_SUCCESS ) { ret_from_connect = SQL_SUCCESS_WITH_INFO; } if ( pooling_enabled && !add_to_pool( connection, pooh ) ) { pool_unreserve( pooh ); } return function_return_nodrv( SQL_HANDLE_DBC, connection, ret_from_connect ); } unixODBC-2.3.12/DriverManager/SQLCopyDesc.c000066400000000000000000000446411446441710500202140ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLCopyDesc.c,v 1.8 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLCopyDesc.c,v $ * Revision 1.8 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.7 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.6 2004/03/30 13:20:11 lurcher * * * Fix problem with SQLCopyDesc * Add additional target for iconv * * Revision 1.5 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/09/18 14:49:32 lurcher * * DataManagerII additions and some more threading fixes * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 2001/05/26 19:11:37 ngorham * * Add SQLCopyDesc functionality and fix bug that was stopping messages * coming out of SQLConnect * * Revision 1.7 1999/11/13 23:40:58 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLCopyDesc.c,v $ $Revision: 1.8 $"; struct cdesc { int field_identifier; int field_type; }; /* * note that SQL_VARCHAR indicates a pointer type, not a string */ static struct cdesc header_fields[] = { { SQL_DESC_ARRAY_SIZE, SQL_INTEGER }, { SQL_DESC_ARRAY_STATUS_PTR, SQL_VARCHAR }, { SQL_DESC_BIND_OFFSET_PTR, SQL_VARCHAR }, { SQL_DESC_BIND_TYPE, SQL_VARCHAR }, { SQL_DESC_COUNT, SQL_SMALLINT }, { SQL_DESC_ROWS_PROCESSED_PTR, SQL_VARCHAR } }; static struct cdesc rec_fields[] = { { SQL_DESC_CONCISE_TYPE, SQL_SMALLINT }, { SQL_DESC_LENGTH, SQL_INTEGER }, { SQL_DESC_OCTET_LENGTH, SQL_INTEGER }, { SQL_DESC_PARAMETER_TYPE, SQL_SMALLINT }, { SQL_DESC_NUM_PREC_RADIX, SQL_INTEGER }, { SQL_DESC_PRECISION, SQL_SMALLINT }, { SQL_DESC_SCALE, SQL_SMALLINT }, { SQL_DESC_DATETIME_INTERVAL_CODE, SQL_SMALLINT }, { SQL_DESC_DATETIME_INTERVAL_PRECISION, SQL_SMALLINT }, { SQL_DESC_DATA_PTR, SQL_VARCHAR }, { SQL_DESC_INDICATOR_PTR, SQL_VARCHAR }, { SQL_DESC_OCTET_LENGTH_PTR, SQL_VARCHAR } }; SQLRETURN SQLCopyDesc( SQLHDESC source_desc_handle, SQLHDESC target_desc_handle ) { DMHDESC src_descriptor = (DMHDESC)source_desc_handle; DMHDESC target_descriptor = (DMHDESC)target_desc_handle; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check descriptor */ if ( !__validate_desc( src_descriptor )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } if ( !__validate_desc( target_descriptor )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( src_descriptor ); function_entry( target_descriptor ); if ( log_info.log_flag ) { sprintf( src_descriptor -> msg, "\n\t\tEntry:\ \n\t\t\tSource Descriptor = %p\ \n\t\t\tTarget Descriptor = %p", src_descriptor, target_descriptor ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, src_descriptor -> msg ); } if ( src_descriptor -> associated_with ) { DMHSTMT statement = (DMHSTMT) src_descriptor -> associated_with; if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &src_descriptor -> error, ERROR_HY010, NULL, src_descriptor -> connection -> environment -> requested_version ); function_return_nodrv( SQL_HANDLE_DESC, target_descriptor, SQL_SUCCESS ); return function_return_nodrv( SQL_HANDLE_DESC, src_descriptor, SQL_ERROR ); } } if ( target_descriptor -> associated_with ) { DMHSTMT statement = (DMHSTMT) target_descriptor -> associated_with; if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &target_descriptor -> error, ERROR_HY010, NULL, target_descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( IGNORE_THREAD, src_descriptor, SQL_ERROR ); } } /* * if both descriptors are from the same driver then we can just * pass it on */ if ( (src_descriptor -> connection == target_descriptor -> connection || !strcmp(src_descriptor -> connection -> dl_name, target_descriptor -> connection -> dl_name) ) && CHECK_SQLCOPYDESC( src_descriptor -> connection )) { SQLRETURN ret; /* * protect the common connection */ thread_protect( SQL_HANDLE_DBC, src_descriptor -> connection ); ret = SQLCOPYDESC( src_descriptor -> connection, src_descriptor -> driver_desc, target_descriptor -> driver_desc ); if ( log_info.log_flag ) { sprintf( target_descriptor -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, target_descriptor -> msg ); } return function_return( IGNORE_THREAD, target_descriptor, ret, DEFER_R3 ); } else { /* * TODO copy from one to the other * protect the common environment */ SQLRETURN ret = SQL_SUCCESS; SQLSMALLINT count; SQLSMALLINT sval; SQLINTEGER ival; SQLPOINTER pval; if ( src_descriptor -> connection == target_descriptor -> connection ) thread_protect( SQL_HANDLE_DBC, src_descriptor -> connection ); else thread_protect( SQL_HANDLE_ENV, src_descriptor -> connection -> environment ); if ( !CHECK_SQLGETDESCFIELD( src_descriptor -> connection ) || !CHECK_SQLSETDESCFIELD( src_descriptor -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &target_descriptor -> error, ERROR_IM001, NULL, target_descriptor -> connection -> environment -> requested_version ); if ( src_descriptor -> connection == target_descriptor -> connection ) thread_release( SQL_HANDLE_DBC, src_descriptor -> connection ); else thread_release( SQL_HANDLE_ENV, src_descriptor -> connection -> environment ); return function_return_nodrv( IGNORE_THREAD, target_descriptor, SQL_ERROR ); } /* * get the count from the source field */ ret = SQLGETDESCFIELD( src_descriptor -> connection, src_descriptor -> driver_desc, 0, SQL_DESC_COUNT, &count, sizeof( count ), NULL ); if ( SQL_SUCCEEDED( ret )) { /* * copy the header fields */ int i; for ( i = 0; i < sizeof( header_fields ) / sizeof( header_fields[ 0 ] ); i ++ ) { if ( header_fields[ i ].field_type == SQL_INTEGER ) { ret = SQLGETDESCFIELD( src_descriptor -> connection, src_descriptor -> driver_desc, 0, header_fields[ i ].field_identifier, &ival, sizeof( ival ), NULL ); } else if ( header_fields[ i ].field_type == SQL_SMALLINT ) { ret = SQLGETDESCFIELD( src_descriptor -> connection, src_descriptor -> driver_desc, 0, header_fields[ i ].field_identifier, &sval, sizeof( sval ), NULL ); } if ( header_fields[ i ].field_type == SQL_VARCHAR ) { ret = SQLGETDESCFIELD( src_descriptor -> connection, src_descriptor -> driver_desc, 0, header_fields[ i ].field_identifier, &pval, sizeof( pval ), NULL ); } if ( SQL_SUCCEEDED( ret )) { if ( header_fields[ i ].field_type == SQL_INTEGER ) { ret = SQLSETDESCFIELD( target_descriptor -> connection, target_descriptor -> driver_desc, 0, header_fields[ i ].field_identifier, (SQLPOINTER)(intptr_t) ival, sizeof( ival )); } else if ( header_fields[ i ].field_type == SQL_SMALLINT ) { ret = SQLSETDESCFIELD( target_descriptor -> connection, target_descriptor -> driver_desc, 0, header_fields[ i ].field_identifier, (SQLPOINTER)(intptr_t) sval, sizeof( sval )); } else if ( header_fields[ i ].field_type == SQL_VARCHAR ) { ret = SQLSETDESCFIELD( target_descriptor -> connection, target_descriptor -> driver_desc, 0, header_fields[ i ].field_identifier, pval, sizeof( pval )); } } if ( !SQL_SUCCEEDED( ret )) break; } } if ( SQL_SUCCEEDED( ret )) { /* * copy the records */ int i, rec; for ( rec = 0; rec <= count; rec ++ ) { for ( i = 0; i < sizeof( rec_fields ) / sizeof( rec_fields[ 0 ] ); i ++ ) { if ( rec_fields[ i ].field_type == SQL_INTEGER ) { ret = SQLGETDESCFIELD( src_descriptor -> connection, src_descriptor -> driver_desc, rec, rec_fields[ i ].field_identifier, &ival, sizeof( ival ), NULL ); } else if ( rec_fields[ i ].field_type == SQL_SMALLINT ) { ret = SQLGETDESCFIELD( src_descriptor -> connection, src_descriptor -> driver_desc, rec, rec_fields[ i ].field_identifier, &sval, sizeof( sval ), NULL ); } if ( rec_fields[ i ].field_type == SQL_VARCHAR ) { ret = SQLGETDESCFIELD( src_descriptor -> connection, src_descriptor -> driver_desc, rec, rec_fields[ i ].field_identifier, &pval, sizeof( pval ), NULL ); } if ( SQL_SUCCEEDED( ret )) { if ( rec_fields[ i ].field_type == SQL_INTEGER ) { ret = SQLSETDESCFIELD( target_descriptor -> connection, target_descriptor -> driver_desc, rec, rec_fields[ i ].field_identifier, (SQLPOINTER)(intptr_t) ival, sizeof( ival )); } else if ( rec_fields[ i ].field_type == SQL_SMALLINT ) { ret = SQLSETDESCFIELD( target_descriptor -> connection, target_descriptor -> driver_desc, rec, rec_fields[ i ].field_identifier, (SQLPOINTER)(intptr_t) sval, sizeof( sval )); } else if ( rec_fields[ i ].field_type == SQL_VARCHAR ) { ret = SQLSETDESCFIELD( target_descriptor -> connection, target_descriptor -> driver_desc, rec, rec_fields[ i ].field_identifier, pval, sizeof( pval )); } } if ( !SQL_SUCCEEDED( ret )) break; } if ( !SQL_SUCCEEDED( ret )) break; } } if ( log_info.log_flag ) { sprintf( src_descriptor -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, src_descriptor -> msg ); } if ( src_descriptor -> connection == target_descriptor -> connection ) thread_release( SQL_HANDLE_DBC, src_descriptor -> connection ); else thread_release( SQL_HANDLE_ENV, src_descriptor -> connection -> environment ); return function_return( IGNORE_THREAD, target_descriptor, ret, DEFER_R3 ); } } unixODBC-2.3.12/DriverManager/SQLDataSources.c000066400000000000000000000267501446441710500207210ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLDataSources.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLDataSources.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/06/30 08:40:48 lurcher * Few more tweeks towards a release * * Revision 1.7 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.6 2003/04/10 13:45:51 lurcher * * Alter the way that SQLDataSources returns the description field (again) * * Revision 1.5 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/07/08 11:40:35 lurcher * * Merge two config tests * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.10 2000/08/10 15:12:17 ngorham * * Fix incorrect return from SQLDataSources * * Revision 1.9 2000/05/04 15:08:29 ngorham * * Update SQLDataSource.c * * Revision 1.8 2000/05/04 12:57:03 ngorham * * Fix problem in SQLDataSource, the description is from the Driver not the * DSN * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLDataSources.c,v $ $Revision: 1.9 $"; #define BUFFERSIZE 1024*4 SQLRETURN SQLDataSourcesA( SQLHENV environment_handle, SQLUSMALLINT direction, SQLCHAR *server_name, SQLSMALLINT buffer_length1, SQLSMALLINT *name_length1, SQLCHAR *description, SQLSMALLINT buffer_length2, SQLSMALLINT *name_length2 ) { return SQLDataSources( environment_handle, direction, server_name, buffer_length1, name_length1, description, buffer_length2, name_length2 ); } SQLRETURN SQLDataSources( SQLHENV environment_handle, SQLUSMALLINT direction, SQLCHAR *server_name, SQLSMALLINT buffer_length1, SQLSMALLINT *name_length1, SQLCHAR *description, SQLSMALLINT buffer_length2, SQLSMALLINT *name_length2 ) { DMHENV environment = (DMHENV) environment_handle; SQLRETURN ret; char buffer[ BUFFERSIZE + 1 ]; char object[ INI_MAX_OBJECT_NAME + 1 ]; char property[ INI_MAX_PROPERTY_VALUE + 1 ]; char driver[ INI_MAX_PROPERTY_VALUE + 1 ]; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( environment ); if ( log_info.log_flag ) { #ifdef HAVE_SNPRINTF snprintf( environment -> msg, sizeof( environment -> msg ), #else sprintf( environment -> msg, #endif "\n\t\tEntry:\ \n\t\t\tEnvironment = %p", environment ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } thread_protect( SQL_HANDLE_ENV, environment ); /* * check that a version has been requested */ if ( environment -> requested_version == 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &environment -> error, ERROR_HY010, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( buffer_length1 < 0 || buffer_length2 < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &environment -> error, ERROR_HY090, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( direction != SQL_FETCH_FIRST && direction != SQL_FETCH_FIRST_USER && direction != SQL_FETCH_FIRST_SYSTEM && direction != SQL_FETCH_NEXT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY103" ); __post_internal_error( &environment -> error, ERROR_HY103, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } /* * for this function USER = "~/.odbc.ini" and * SYSTEM = "/usr/odbc.ini */ if ( direction == SQL_FETCH_FIRST ) { environment -> fetch_mode = ODBC_BOTH_DSN; environment -> entry = 0; } else if ( direction == SQL_FETCH_FIRST_USER ) { environment -> fetch_mode = ODBC_USER_DSN; environment -> entry = 0; } else if ( direction == SQL_FETCH_FIRST_SYSTEM ) { environment -> fetch_mode = ODBC_SYSTEM_DSN; environment -> entry = 0; } /* * this is lifted from Peters code */ memset( buffer, 0, sizeof( buffer )); memset( object, 0, sizeof( object )); SQLSetConfigMode( environment -> fetch_mode ); SQLGetPrivateProfileString( NULL, NULL, NULL, buffer, sizeof( buffer ), "ODBC.INI" ); if ( iniElement( buffer, '\0', '\0', environment -> entry, object, sizeof( object )) != INI_SUCCESS ) { environment -> entry = 0; ret = SQL_NO_DATA; } else { memset( buffer, 0, sizeof( buffer )); memset( property, 0, sizeof( property )); memset( driver, 0, sizeof( driver )); SQLGetPrivateProfileString( object, "Driver", "", driver, sizeof( driver ), "ODBC.INI" ); if ( strlen( driver ) > 0 ) { /* * Make this return the description from the driver setup, this is * the way its done in Windows SQLGetPrivateProfileString( driver, "Description", driver, property, sizeof( property ), "ODBCINST.INI" ); */ /* * even though the string is called description, it should * actually be the driver name entry from odbcinst.ini on windows * there is no separate Description line */ strcpy( property, driver ); } else { /* * May as well try and get something */ SQLGetPrivateProfileString( object, "Description", "", property, sizeof( property ), "ODBC.INI" ); } environment -> entry++; if (( server_name && buffer_length1 <= strlen( object )) || ( description && buffer_length2 <= strlen( property ))) { __post_internal_error( &environment -> error, ERROR_01004, NULL, environment -> requested_version ); ret = SQL_SUCCESS_WITH_INFO; } else { ret = SQL_SUCCESS; } if ( server_name ) { if ( buffer_length1 <= strlen( object )) { memcpy( server_name, object, buffer_length1 ); server_name[ buffer_length1 - 1 ] = '\0'; } else { strcpy((char*) server_name, object ); } } if ( description ) { if ( buffer_length2 <= strlen( property )) { memcpy( description, property, buffer_length2 ); description[ buffer_length2 - 1 ] = '\0'; } else { strcpy((char*) description, property ); } } if ( name_length1 ) { *name_length1 = strlen( object ); } if ( name_length2 ) { *name_length2 = strlen( property ); } } /* NEVER FORGET TO RESET THIS TO ODBC_BOTH_DSN */ SQLSetConfigMode( ODBC_BOTH_DSN ); if ( log_info.log_flag ) { #ifdef HAVE_SNPRINTF snprintf( environment -> msg, sizeof( environment -> msg ), #else sprintf( environment -> msg, #endif "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } return function_return_nodrv( SQL_HANDLE_ENV, environment, ret ); } unixODBC-2.3.12/DriverManager/SQLDataSourcesW.c000066400000000000000000000222461446441710500210440ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLDataSourcesW.c,v 1.6 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLDataSourcesW.c,v $ * Revision 1.6 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/01/04 13:16:25 nick * * Add support for GNU portable threads and tidy up some UNICODE compile * warnings * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLDataSourcesW.c,v $"; #define BUFFERSIZE 1024 * 4 SQLRETURN SQLDataSourcesW( SQLHENV environment_handle, SQLUSMALLINT direction, SQLWCHAR *server_name, SQLSMALLINT buffer_length1, SQLSMALLINT *name_length1, SQLWCHAR *description, SQLSMALLINT buffer_length2, SQLSMALLINT *name_length2 ) { DMHENV environment = (DMHENV) environment_handle; SQLRETURN ret; char buffer[ BUFFERSIZE + 1 ]; char object[ INI_MAX_OBJECT_NAME + 1 ]; char property[ INI_MAX_PROPERTY_VALUE + 1 ]; char driver[ INI_MAX_PROPERTY_VALUE + 1 ]; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( environment ); if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tEntry:\ \n\t\t\tEnvironment = %p", environment ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } thread_protect( SQL_HANDLE_ENV, environment ); /* * check that a version has been requested */ if ( environment -> requested_version == 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &environment -> error, ERROR_HY010, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( buffer_length1 < 0 || buffer_length2 < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &environment -> error, ERROR_HY090, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( direction != SQL_FETCH_FIRST && direction != SQL_FETCH_FIRST_USER && direction != SQL_FETCH_FIRST_SYSTEM && direction != SQL_FETCH_NEXT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY103" ); __post_internal_error( &environment -> error, ERROR_HY103, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } /* * for this function USER = "~/.odbc.ini" and * SYSTEM = "/usr/odbc.ini */ if ( direction == SQL_FETCH_FIRST ) { environment -> fetch_mode = ODBC_BOTH_DSN; environment -> entry = 0; } else if ( direction == SQL_FETCH_FIRST_USER ) { environment -> fetch_mode = ODBC_USER_DSN; environment -> entry = 0; } else if ( direction == SQL_FETCH_FIRST_SYSTEM ) { environment -> fetch_mode = ODBC_SYSTEM_DSN; environment -> entry = 0; } /* * this is lifted from Peters code */ memset( buffer, 0, sizeof( buffer )); memset( object, 0, sizeof( object )); SQLSetConfigMode( environment -> fetch_mode ); SQLGetPrivateProfileString( NULL, NULL, NULL, buffer, sizeof( buffer ), "odbc.ini" ); if ( iniElement( buffer, '\0', '\0', environment -> entry, object, sizeof( object )) != INI_SUCCESS ) { environment -> entry = 0; ret = SQL_NO_DATA; } else { memset( buffer, 0, sizeof( buffer )); memset( property, 0, sizeof( property )); memset( driver, 0, sizeof( driver )); SQLGetPrivateProfileString( object, "Driver", "", driver, sizeof( driver ), "odbc.ini" ); if ( strlen( driver ) > 0 ) { /* SQLGetPrivateProfileString( driver, "Description", "", property, sizeof( property ), "odbcinst.ini" ); */ strcpy( property, driver ); } else { strcpy( property, "" ); } environment -> entry++; if (( server_name && buffer_length1 <= strlen( object )) || ( description && buffer_length2 <= strlen( property ))) { __post_internal_error( &environment -> error, ERROR_01004, NULL, environment -> requested_version ); ret = SQL_SUCCESS_WITH_INFO; } else { ret = SQL_SUCCESS; } if ( server_name ) { SQLWCHAR *s1; s1 = ansi_to_unicode_alloc((SQLCHAR*) object, SQL_NTS, NULL, NULL ); if ( s1 ) { if ( buffer_length1 <= strlen( object )) { memcpy( server_name, s1, buffer_length1 * 2 ); server_name[ buffer_length1 - 1 ] = 0; } else { wide_strcpy( server_name, s1 ); } free( s1 ); } } if ( description ) { SQLWCHAR *s1; s1 = ansi_to_unicode_alloc((SQLCHAR*) property, SQL_NTS, NULL, NULL ); if ( s1 ) { if ( buffer_length2 <= strlen( property )) { memcpy( description, s1, buffer_length2 * 2 ); description[ buffer_length2 - 1 ] = 0; } else { wide_strcpy( description, s1 ); } free( s1 ); } } if ( name_length1 ) { *name_length1 = strlen( object ); } if ( name_length2 ) { *name_length2 = strlen( property ); } } /* NEVER FORGET TO RESET THIS TO ODBC_BOTH_DSN */ SQLSetConfigMode( ODBC_BOTH_DSN ); if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } return function_return_nodrv( SQL_HANDLE_ENV, environment, ret ); } unixODBC-2.3.12/DriverManager/SQLDescribeCol.c000066400000000000000000000362041446441710500206550ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLDescribeCol.c,v 1.13 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLDescribeCol.c,v $ * Revision 1.13 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.12 2008/09/29 14:02:44 lurcher * Fix missing dlfcn group option * * Revision 1.11 2008/05/20 13:43:46 lurcher * Vms fixes * * Revision 1.10 2007/04/02 10:50:18 lurcher * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 ) * * Revision 1.9 2007/01/02 10:27:50 lurcher * Fix descriptor leak with unicode only driver * * Revision 1.8 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.7 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.6 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.5 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.4 2002/08/19 09:11:49 lurcher * * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state * * Revision 1.3 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.5 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.4 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.3 2001/01/02 09:55:04 nick * * More unicode bits * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.10 2000/06/20 13:30:09 ngorham * * Fix problems when using bookmarks * * Revision 1.9 1999/11/28 18:35:50 ngorham * * Add extra ODBC3/2 Date/Time mapping * * Revision 1.8 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.6 1999/10/09 00:56:16 ngorham * * Added Manush's patch to map ODBC 3-2 datetime values * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.4 1999/05/03 19:50:43 nick * Another check point * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 21:40:58 nick * End of another night :-) * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLDescribeCol.c,v $ $Revision: 1.13 $"; SQLRETURN SQLDescribeColA( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLCHAR *column_name, SQLSMALLINT buffer_length, SQLSMALLINT *name_length, SQLSMALLINT *data_type, SQLULEN *column_size, SQLSMALLINT *decimal_digits, SQLSMALLINT *nullable ) { return SQLDescribeCol( statement_handle, column_number, column_name, buffer_length, name_length, data_type, column_size, decimal_digits, nullable ); } SQLRETURN SQLDescribeCol( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLCHAR *column_name, SQLSMALLINT buffer_length, SQLSMALLINT *name_length, SQLSMALLINT *data_type, SQLULEN *column_size, SQLSMALLINT *decimal_digits, SQLSMALLINT *nullable ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s5[ 100 + LOG_MESSAGE_LEN ], s6[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tColumn Number = %d\ \n\t\t\tColumn Name = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tName Length = %p\ \n\t\t\tData Type = %p\ \n\t\t\tColumn Size = %p\ \n\t\t\tDecimal Digits = %p\ \n\t\t\tNullable = %p", statement, column_number, column_name, buffer_length, name_length, data_type, column_size, decimal_digits, nullable ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( column_number == 0 && statement -> bookmarks_on == SQL_UB_OFF && statement -> connection -> bookmarks_on == SQL_UB_OFF ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error_api( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version, SQL_API_SQLDESCRIBECOL ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * sadly we can't truct the numcols value * if ( statement -> numcols < column_number ) { __post_internal_error( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } */ if ( buffer_length < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * This seems to be down to the driver in the MS DM * else if ( statement -> state == STATE_S2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07005" ); __post_internal_error( &statement -> error, ERROR_07005, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } */ else if ( statement -> state == STATE_S4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLDESCRIBECOL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1 = NULL; if ( !CHECK_SQLDESCRIBECOLW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( column_name && buffer_length > 0 ) { s1 = malloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 )); } ret = SQLDESCRIBECOLW( statement -> connection, statement -> driver_stmt, column_number, s1 ? s1 : (SQLWCHAR*)column_name, buffer_length, name_length, data_type, column_size, decimal_digits, nullable ); if ( SQL_SUCCEEDED( ret ) && column_name && s1 ) { unicode_to_ansi_copy((char*) column_name, buffer_length, s1, SQL_NTS, statement -> connection, NULL ); } if ( s1 ) { free( s1 ); } } else { if ( !CHECK_SQLDESCRIBECOL( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLDESCRIBECOL( statement -> connection, statement -> driver_stmt, column_number, column_name, buffer_length, name_length, data_type, column_size, decimal_digits, nullable ); } if ( (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) && data_type ) { *data_type=__map_type(MAP_SQL_D2DM,statement->connection, *data_type); } if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLDESCRIBECOL; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } if ( log_info.log_flag ) { if ( !SQL_SUCCEEDED( ret )) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s6 )); } else { sprintf( statement -> msg, "\n\t\tExit:[%s]\ \n\t\t\tColumn Name = %s\ \n\t\t\tData Type = %s\ \n\t\t\tColumn Size = %s\ \n\t\t\tDecimal Digits = %s\ \n\t\t\tNullable = %s", __get_return_status( ret, s6 ), __sdata_as_string( s1, SQL_CHAR, name_length, column_name ), __sptr_as_string( s2, data_type ), __ptr_as_string( s3, (SQLLEN*)column_size ), __sptr_as_string( s4, decimal_digits ), __sptr_as_string( s5, nullable )); } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLDescribeColW.c000066400000000000000000000345471446441710500210140ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLDescribeColW.c,v 1.14 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLDescribeColW.c,v $ * Revision 1.14 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.13 2008/08/29 08:01:38 lurcher * Alter the way W functions are passed to the driver * * Revision 1.12 2008/05/20 13:43:47 lurcher * Vms fixes * * Revision 1.11 2007/04/02 10:50:18 lurcher * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 ) * * Revision 1.10 2007/02/28 15:37:47 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.9 2007/01/02 10:27:50 lurcher * Fix descriptor leak with unicode only driver * * Revision 1.8 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.7 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.6 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.5 2002/08/19 09:11:49 lurcher * * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state * * Revision 1.4 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.3 2002/05/21 14:19:44 lurcher * * * Update libtool to escape from AIX build problem * * Add fix to avoid file handle limitations * * Add more UNICODE changes, it looks like it is native 16 representation * the old way can be reproduced by defining UCS16BE * * Add iusql, its just the same as isql but uses the wide functions * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/03/21 12:26:27 nick * * Alter def for SQLDescribeColW * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLDescribeColW.c,v $"; SQLRETURN SQLDescribeColW( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLWCHAR *column_name, SQLSMALLINT buffer_length, SQLSMALLINT *name_length, SQLSMALLINT *data_type, SQLULEN *column_size, SQLSMALLINT *decimal_digits, SQLSMALLINT *nullable ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s5[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s6[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLDESCRIBECOLW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLDESCRIBECOLW( parent_statement -> connection, statement_handle, column_number, column_name, buffer_length, name_length, data_type, column_size, decimal_digits, nullable ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tColumn Number = %d\ \n\t\t\tColumn Name = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tName Length = %p\ \n\t\t\tData Type = %p\ \n\t\t\tColumn Size = %p\ \n\t\t\tDecimal Digits = %p\ \n\t\t\tNullable = %p", statement, column_number, column_name, buffer_length, name_length, data_type, column_size, decimal_digits, nullable ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( column_number == 0 && statement -> bookmarks_on == SQL_UB_OFF && statement -> connection -> bookmarks_on == SQL_UB_OFF ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error_api( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version, SQL_API_SQLDESCRIBECOL ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * sadly we can't trust the numcols value * if ( statement -> numcols < column_number ) { __post_internal_error( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } */ if ( buffer_length < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * This seems to be down to the driver in the MS DM * else if ( statement -> state == STATE_S2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07005" ); __post_internal_error( &statement -> error, ERROR_07005, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } */ else if ( statement -> state == STATE_S4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLDESCRIBECOL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver || CHECK_SQLDESCRIBECOLW( statement -> connection )) { if ( !CHECK_SQLDESCRIBECOLW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLDESCRIBECOLW( statement -> connection, statement -> driver_stmt, column_number, column_name, buffer_length, name_length, data_type, column_size, decimal_digits, nullable ); } else { SQLCHAR *as1 = NULL; if ( !CHECK_SQLDESCRIBECOL( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( buffer_length > 0 && column_name ) { as1 = malloc( buffer_length + 1 ); } ret = SQLDESCRIBECOL( statement -> connection, statement -> driver_stmt, column_number, as1 ? as1 : (SQLCHAR*)column_name, buffer_length, name_length, data_type, column_size, decimal_digits, nullable ); if ( column_name && as1 ) { ansi_to_unicode_copy( column_name, (char*) as1, SQL_NTS, statement -> connection, NULL ); } if ( as1 ) { free( as1 ); } } if ( (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) && data_type ) { *data_type=__map_type(MAP_SQL_D2DM,statement->connection, *data_type); } if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLDESCRIBECOL; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } if ( log_info.log_flag ) { if ( !SQL_SUCCEEDED( ret )) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s6 )); } else { sprintf( statement -> msg, "\n\t\tExit:[%s]\ \n\t\t\tColumn Name = %s\ \n\t\t\tData Type = %s\ \n\t\t\tColumn Size = %s\ \n\t\t\tDecimal Digits = %s\ \n\t\t\tNullable = %s", __get_return_status( ret, s6 ), __sdata_as_string( s1, SQL_WCHAR, name_length, column_name ), __sptr_as_string( s2, data_type ), __ptr_as_string( s3, (SQLLEN*)column_size ), __sptr_as_string( s4, decimal_digits ), __sptr_as_string( s5, nullable )); } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLDescribeParam.c000066400000000000000000000245551446441710500212060ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLDescribeParam.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLDescribeParam.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2008/05/20 13:43:47 lurcher * Vms fixes * * Revision 1.5 2007/04/02 10:50:19 lurcher * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 ) * * Revision 1.4 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.10 2000/07/28 16:34:52 ngorham * * Fix problems with SQLColAttributes, and SQLDescribeParam * * Revision 1.9 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.8 1999/11/10 03:51:33 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.7 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.6 1999/10/09 00:56:16 ngorham * * Added Manush's patch to map ODBC 3-2 datetime values * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.3 1999/05/03 19:50:43 nick * Another check point * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLDescribeParam.c,v $ $Revision: 1.7 $"; SQLRETURN SQLDescribeParam( SQLHSTMT statement_handle, SQLUSMALLINT ipar, SQLSMALLINT *pf_sql_type, SQLULEN *pcb_param_def, SQLSMALLINT *pib_scale, SQLSMALLINT *pf_nullable ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s6[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tParameter Number = %d\ \n\t\t\tSQL Type = %p\ \n\t\t\tParam Def = %p\ \n\t\t\tScale = %p\ \n\t\t\tNullable = %p", statement, ipar, pf_sql_type, pcb_param_def, pib_scale, pf_nullable ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( ipar < 1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if (( statement -> state == STATE_S4 || statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) && statement -> connection -> environment -> requested_version >= SQL_OV_ODBC3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if (( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) && statement -> connection -> environment -> requested_version == SQL_OV_ODBC2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLDESCRIBEPARAM ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( !CHECK_SQLDESCRIBEPARAM( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLDESCRIBEPARAM( statement -> connection, statement -> driver_stmt, ipar, pf_sql_type, pcb_param_def, pib_scale, pf_nullable ); if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLDESCRIBEPARAM; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } if ( (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) && pf_sql_type ) { *pf_sql_type = __map_type(MAP_SQL_D2DM,statement->connection, *pf_sql_type); } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]\ \n\t\t\tSQL Type = %p\ \n\t\t\tParam Def = %p\ \n\t\t\tScale = %p\ \n\t\t\tNullable = %p", __get_return_status( ret, s6 ), __sptr_as_string( s1, pf_sql_type ), __ptr_as_string( s2, (SQLLEN*)pcb_param_def ), __sptr_as_string( s3, pib_scale ), __sptr_as_string( s4, pf_nullable )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLDisconnect.c000066400000000000000000000233471446441710500205740ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLDisconnect.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLDisconnect.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2004/02/18 15:47:44 lurcher * * Fix a leak in the iconv code * * Revision 1.7 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.6 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.5 2002/08/12 13:17:52 lurcher * * Replicate the way the MS DM handles loading of driver libs, and allocating * handles in the driver. usage counting in the driver means that dlopen is * only called for the first use, and dlclose for the last. AllocHandle for * the driver environment is only called for the first time per driver * per application environment. * * Revision 1.4 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.3 2002/07/04 17:27:56 lurcher * * Small bug fixes * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.8 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.7 2001/03/21 16:12:29 nick * * Alter cleaning of stmt and desc handles if a SQLDisconnect fails * * Revision 1.6 2001/03/02 14:24:23 nick * * Fix thread detection for Solaris * * Revision 1.5 2001/02/12 11:20:22 nick * * Add supoort for calling SQLDriverLoad and SQLDriverUnload * * Revision 1.4 2000/12/18 12:53:29 nick * * More pooling tweeks * * Revision 1.3 2000/12/18 12:32:16 nick * * Fix missing return codes * * Revision 1.2 2000/12/14 18:10:19 nick * * Add connection pooling * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.13 2000/04/27 20:49:03 ngorham * * Fixes to work with Star Office 5.2 * * Revision 1.12 2001/04/27 01:33:40 ngorham * * Fix a problem where handles were not being free'd * * Revision 1.11 2001/04/05 21:15:01 ngorham * * Fix small memory leak in SQLDisconnect and the Postgres driver * * Revision 1.10 2000/02/25 00:02:00 ngorham * * Add a patch to support IBM DB2, and Solaris threads * * Revision 1.9 2000/02/22 22:14:45 ngorham * * Added support for solaris threads * Added check to overcome bug in PHP4 * Fixed bug in descriptors and ODBC 3 drivers * * Revision 1.8 1999/12/28 15:05:01 ngorham * * Fix bug that caused StarOffice to fail. A SQLConnect, SQLDisconnect, * followed by another SQLConnect on the same DBC would fail. * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLDisconnect.c,v $ $Revision: 1.9 $"; extern int pooling_enabled; SQLRETURN SQLDisconnect( SQLHDBC connection_handle ) { DMHDBC connection = (DMHDBC)connection_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p", connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); /* * check states */ if ( connection -> state == STATE_C6 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 25000" ); __post_internal_error( &connection -> error, ERROR_25000, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else if ( connection -> state == STATE_C2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * any statements that are in SQL_NEED_DATA */ if( __check_stmt_from_dbc( connection, STATE_S8 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if( __check_stmt_from_dbc( connection, STATE_S13 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * is it a pooled connection, or can it go back */ if ( connection -> pooled_connection || pooling_enabled && connection -> pooling_timeout > 0 ) { __clean_stmt_from_dbc( connection ); __clean_desc_from_dbc( connection ); return_to_pool( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_SUCCESS ); } /* * disconnect from the driver */ if ( !CHECK_SQLDISCONNECT( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } ret = SQLDISCONNECT( connection, connection -> driver_dbc ); if ( SQL_SUCCEEDED( ret )) { /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, connection, ret, TRUE, DEFER_R0 ); } /* * complete disconnection from driver */ __disconnect_part_three( connection ); } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R0 ); } unixODBC-2.3.12/DriverManager/SQLDriverConnect.c000066400000000000000000001534011446441710500212430ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLDriverConnect.c,v 1.28 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLDriverConnect.c,v $ * Revision 1.28 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.27 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.26 2009/01/16 11:02:38 lurcher * Interface to GUI for DSN selection * * Revision 1.25 2009/01/14 10:01:42 lurcher * remove debug printf * * Revision 1.24 2009/01/12 15:18:15 lurcher * Add interface into odbcinstQ to allow for a dialog if SQLDriverConnect is called without a DSN= * * Revision 1.23 2008/11/24 12:44:23 lurcher * Try and tidu up the connection version checking * * Revision 1.22 2008/09/29 14:02:44 lurcher * Fix missing dlfcn group option * * Revision 1.21 2008/08/29 08:01:38 lurcher * Alter the way W functions are passed to the driver * * Revision 1.20 2007/03/05 09:49:23 lurcher * Get it to build on VMS again * * Revision 1.19 2004/10/22 09:10:19 lurcher * Fix a couple of problems with FILEDSN's * * Revision 1.18 2004/09/08 16:38:54 lurcher * * Get ready for a 2.2.10 release * * Revision 1.17 2004/07/27 13:04:41 lurcher * * Strip FILEDSN from connection string before passing to driver * * Revision 1.16 2004/02/18 15:47:44 lurcher * * Fix a leak in the iconv code * * Revision 1.15 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.14 2003/09/08 15:34:29 lurcher * * A couple of small but perfectly formed fixes * * Revision 1.13 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.12 2003/01/23 15:33:24 lurcher * * Fix problems with using putenv() * * Revision 1.11 2002/12/20 11:36:46 lurcher * * Update DMEnvAttr code to allow setting in the odbcinst.ini entry * * Revision 1.10 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.9 2002/10/14 09:46:10 lurcher * * Remove extra return * * Revision 1.8 2002/10/02 09:28:33 lurcher * * Fix uninitialised pointer in SQLDriverConnect.c * * Revision 1.7 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.6 2002/07/25 09:30:26 lurcher * * Additional unicode and iconv changes * * Revision 1.5 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.4 2002/05/24 12:42:50 lurcher * * Alter NEWS and ChangeLog to match their correct usage * Additional UNICODE tweeks * * Revision 1.3 2002/01/21 18:00:51 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.22 2001/10/16 10:37:32 nick * * Getting ready for 2.0.10 * * Revision 1.21 2001/10/09 13:23:30 nick * * Add filedsn support to ODBCConfig * * Revision 1.20 2001/10/08 13:38:35 nick * * Add support for FILEDSN's * * Revision 1.19 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * Revision 1.18 2001/07/20 13:20:44 nick * *** empty log message *** * * Revision 1.17 2001/07/20 12:35:09 nick * * Fix SQLBrowseConnect operation * * Revision 1.16 2001/05/15 10:57:44 nick * * Add initial support for VMS * * Revision 1.15 2001/04/18 15:03:37 nick * * Fix problem when going to DB2 unicode driver * * Revision 1.14 2001/04/16 22:35:10 nick * * More tweeks to the AutoTest code * * Revision 1.13 2001/04/16 15:41:24 nick * * Fix some problems calling non existing error funcs * * Revision 1.12 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.11 2001/04/03 16:34:12 nick * * Add support for strangly broken unicode drivers * * Revision 1.10 2001/01/03 12:02:03 nick * * Add missing __ * * Revision 1.9 2001/01/03 11:57:26 nick * * Fix some name collisions * * Revision 1.8 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.7 2000/12/18 13:02:13 nick * * More buf fixes * * Revision 1.6 2000/12/18 12:53:29 nick * * More pooling tweeks * * Revision 1.5 2000/12/18 12:27:50 nick * * Fix missing check for SQL_NTS * * Revision 1.4 2000/12/14 18:10:19 nick * * Add connection pooling * * Revision 1.3 2000/10/13 15:18:49 nick * * Change string length parameter from SQLINTEGER to SQLSMALLINT * * Revision 1.2 2000/10/06 08:49:38 nick * * Fix duplicated error messages on connect * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.15 2000/08/11 12:11:27 ngorham * * Make SQLDriverConnect return all the stacked errors from the driver, not * just one * * Revision 1.14 2000/07/13 13:27:24 ngorham * * remove _ from odbcinst_system_file_path() * * Revision 1.13 2000/06/21 08:58:26 ngorham * * Stop SQLDriverConnect dumping core when passed a null dsn string * * Revision 1.12 2000/02/20 10:18:47 ngorham * * Add support for ODBCINI environment override for Applix. * * Revision 1.11 1999/12/14 19:02:25 ngorham * * Mask out the password fields in the logging * * Revision 1.10 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.9 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.8 1999/10/14 06:49:24 ngorham * * Remove @all_includes@ from Drivers/MiniSQL/Makefile.am * * Revision 1.7 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.6 1999/08/17 06:20:00 ngorham * * Remove posibility of returning without clearing the connection mutex. * * Revision 1.5 1999/08/03 21:47:39 shandyb * Moving to automake: changed files in DriverManager * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:05 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.4 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLDriverConnect.c,v $ $Revision: 1.28 $"; /* * connection pooling stuff */ extern int pooling_enabled; extern int pool_wait_timeout; void __generate_connection_string( struct con_struct *con_str, char *str, int str_len ) { struct con_pair *cp; char *tmp; str[ 0 ] = '\0'; if ( con_str -> count == 0 ) { return; } cp = con_str -> list; while( cp ) { size_t attrlen = strlen( cp -> attribute ); int use_esc = isspace( *(cp -> attribute ) ) || ( attrlen && isspace( cp->attribute[attrlen - 1] )); for ( tmp = cp -> attribute; *tmp; tmp++ ) { use_esc |= (*tmp == '{') || (*tmp == '}'); attrlen += (*tmp == '}'); } tmp = malloc( strlen( cp -> keyword ) + attrlen + 10 ); if( use_esc ) { char *tmp2 = tmp + sprintf( tmp, "%s={", cp -> keyword ); char *tmp3; for( tmp3 = cp -> attribute; *tmp3 ; tmp3++ ) { *tmp2++ = *tmp3; if ( '}' == *tmp3++ ) { *tmp2++ = '}'; } } *tmp2++ = '}'; *tmp2++ = 0; } else { sprintf( tmp, "%s=%s;", cp -> keyword, cp -> attribute ); } if ( strlen( str ) + strlen( tmp ) > str_len ) { free( tmp ); break; } else { strcat( str, tmp ); } free( tmp ); cp = cp -> next; } } void __get_attr( char ** cp, char ** keyword, char ** value ) { char * ptr; int len; *keyword = *value = NULL; while ( isspace( **cp ) || **cp == ';' ) { (*cp)++; } if ( !**cp ) return; ptr = *cp; /* * To handle the case attribute in which the attribute is of the form * "ATTR;" instead of "ATTR=VALUE;" */ while ( **cp && **cp != '=' ) { (*cp)++; } if ( !**cp ) return; len = *cp - ptr; *keyword = malloc( len + 1 ); memcpy( *keyword, ptr, len ); (*keyword)[ len ] = '\0'; (*cp)++; if ( **cp == '{' ) { /* escaped with '{' - all characters until next '}' not followed by '}', or end of string, are part of the value */ int i = 0; ptr = ++*cp; while ( **cp && (**cp != '}' || (*cp)[1] == '}') ) { if ( **cp == '}' ) (*cp)++; (*cp)++; } len = *cp - ptr; *value = malloc( len + 1 ); while( ptr < *cp ) { if ( ((*value)[i++] = *ptr++) == '}') { ptr++; } } (*value)[i] = 0; if ( **cp == '}' ) { (*cp)++; } } else { /* non-escaped: all characters until ';' or end of string are value */ ptr = *cp; while ( **cp && **cp != ';' ) { (*cp)++; } len = *cp - ptr; *value = malloc( len + 1 ); memcpy( *value, ptr, len ); (*value)[ len ] = 0; } } struct con_pair * __get_pair( char ** cp ) { char *keyword, *value; struct con_pair * con_p; __get_attr( cp, &keyword, &value ); if ( keyword ) { con_p = malloc( sizeof( *con_p )); con_p -> keyword = keyword; con_p -> attribute = value; return con_p; } else { return NULL; } } int __append_pair( struct con_struct *con_str, char *kword, char *value ) { struct con_pair *ptr, *end; /* check that the keyword is not already in the list */ end = NULL; if ( con_str -> count > 0 ) { ptr = con_str -> list; while( ptr ) { if( strcasecmp( kword, ptr -> keyword ) == 0 ) { free( ptr -> attribute ); ptr -> attribute = malloc( strlen( value ) + 1 ); strcpy( ptr -> attribute, value ); return 0; } end = ptr; ptr = ptr -> next; } } ptr = malloc( sizeof( *ptr )); ptr -> keyword = malloc( strlen( kword ) + 1 ); strcpy( ptr -> keyword, kword ); ptr -> attribute = malloc( strlen( value ) + 1 ); strcpy( ptr -> attribute, value ); con_str -> count ++; if ( con_str -> list ) { end -> next = ptr; ptr -> next = NULL; } else { ptr -> next = NULL; con_str -> list = ptr; } return 0; } int __parse_connection_string_ex( struct con_struct *con_str, char *str, int str_len, int exclude ) { struct con_pair *cp; char *local_str, *ptr; int got_dsn = 0; /* if we have a DSN then ignore any DRIVER or FILEDSN */ int got_driver = 0; /* if we have a DRIVER or FILEDSN then ignore any DSN */ con_str -> count = 0; con_str -> list = NULL; if ( str_len != SQL_NTS ) { local_str = malloc( str_len + 1 ); memcpy( local_str, str, str_len ); local_str[ str_len ] = '\0'; } else { local_str = str; } if ( !local_str || strlen( local_str ) == 0 || ( strlen( local_str ) == 1 && *local_str == ';' )) { /* connection-string ::= empty-string [;] */ if ( str_len != SQL_NTS ) free( local_str ); return 0; } ptr = local_str; while(( cp = __get_pair( &ptr )) != NULL ) { if ( strcasecmp( cp -> keyword, "DSN" ) == 0 ) { if ( got_driver && exclude ) { /* 11-29-2010 JM Modify to free the allocated memory before continuing. */ free( cp -> keyword ); free( cp -> attribute ); free( cp ); continue; } got_dsn = 1; } else if ( strcasecmp( cp -> keyword, "DRIVER" ) == 0 || strcasecmp( cp -> keyword, "FILEDSN" ) == 0 ) { if ( got_dsn && exclude ) { /* 11-29-2010 JM Modify to free the allocated memory before continuing. */ free( cp -> keyword ); free( cp -> attribute ); free( cp ); continue; } got_driver = 1; } __append_pair( con_str, cp -> keyword, cp -> attribute ); free( cp -> keyword ); free( cp -> attribute ); free( cp ); } if ( str_len != SQL_NTS ) free( local_str ); return 0; } int __parse_connection_string( struct con_struct *con_str, char *str, int str_len ) { return __parse_connection_string_ex( con_str, str, str_len, 1 ); } char * __get_attribute_value( struct con_struct * con_str, char * keyword ) { struct con_pair *cp; if ( con_str -> count == 0 ) return NULL; cp = con_str -> list; while( cp ) { if( strcasecmp( keyword, cp -> keyword ) == 0 ) { if ( cp -> attribute ) return cp -> attribute; else return ""; } cp = cp -> next; } return NULL; } void __release_conn( struct con_struct *con_str ) { struct con_pair *cp = con_str -> list; struct con_pair *save; while( cp ) { free( cp -> attribute ); free( cp -> keyword ); save = cp; cp = cp -> next; free( save ); } con_str -> count = 0; } void __handle_attr_extensions_cs( DMHDBC connection, struct con_struct *con_str ) { char *ptr; if (( ptr = __get_attribute_value( con_str, "DMEnvAttr" )) != NULL ) { __parse_attribute_string( &connection -> env_attribute, ptr, SQL_NTS ); } if (( ptr = __get_attribute_value( con_str, "DMConnAttr" )) != NULL ) { __parse_attribute_string( &connection -> dbc_attribute, ptr, SQL_NTS ); } if (( ptr = __get_attribute_value( con_str, "DMStmtAttr" )) != NULL ) { __parse_attribute_string( &connection -> stmt_attribute, ptr, SQL_NTS ); } } SQLRETURN SQLDriverConnectA( SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR *conn_str_in, SQLSMALLINT len_conn_str_in, SQLCHAR *conn_str_out, SQLSMALLINT conn_str_out_max, SQLSMALLINT *ptr_conn_str_out, SQLUSMALLINT driver_completion ) { return SQLDriverConnect( hdbc, hwnd, conn_str_in, len_conn_str_in, conn_str_out, conn_str_out_max, ptr_conn_str_out, driver_completion ); } SQLRETURN SQLDriverConnect( SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR *conn_str_in, SQLSMALLINT len_conn_str_in, SQLCHAR *conn_str_out, SQLSMALLINT conn_str_out_max, SQLSMALLINT *ptr_conn_str_out, SQLUSMALLINT driver_completion ) { DMHDBC connection = (DMHDBC)hdbc; struct con_struct con_struct; char *driver, *dsn = NULL, *filedsn, *tsavefile, savefile[ INI_MAX_PROPERTY_VALUE + 1 ]; char lib_name[ INI_MAX_PROPERTY_VALUE + 1 ]; char driver_name[ INI_MAX_PROPERTY_VALUE + 1 ]; SQLRETURN ret_from_connect; SQLCHAR s1[ 2048 ]; SQLCHAR local_conn_str_in[ 2048 ]; SQLCHAR local_out_conection[ 2048 ]; char *save_filedsn; int warnings = 0; CPOOLHEAD *pooh = 0; /* * check connection */ strcpy( driver_name, "" ); if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); /* * replace this if not set for use by SAVEFILE */ if ( !conn_str_out ) { conn_str_out = local_out_conection; conn_str_out_max = sizeof( local_out_conection ); } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tWindow Hdl = %p\ \n\t\t\tStr In = %s\ \n\t\t\tStr Out = %p\ \n\t\t\tStr Out Max = %d\ \n\t\t\tStr Out Ptr = %p\ \n\t\t\tCompletion = %d", connection, hwnd, __string_with_length_hide_pwd( s1, conn_str_in, len_conn_str_in ), conn_str_out, conn_str_out_max, ptr_conn_str_out, driver_completion ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( len_conn_str_in < 0 && len_conn_str_in != SQL_NTS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( driver_completion == SQL_DRIVER_PROMPT && hwnd == NULL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( driver_completion != SQL_DRIVER_PROMPT && driver_completion != SQL_DRIVER_COMPLETE && driver_completion != SQL_DRIVER_COMPLETE_REQUIRED && driver_completion != SQL_DRIVER_NOPROMPT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY110" ); __post_internal_error( &connection -> error, ERROR_HY110, NULL, connection -> environment -> requested_version ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } /* * check the state of the connection */ if ( connection -> state != STATE_C2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08002" ); __post_internal_error( &connection -> error, ERROR_08002, NULL, connection -> environment -> requested_version ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } /* * parse the connection string, and call the GUI if needed */ if ( driver_completion == SQL_DRIVER_NOPROMPT ) { if ( !conn_str_in ) { conn_str_in = (SQLCHAR*)"DSN=DEFAULT;"; len_conn_str_in = strlen((char*) conn_str_in ); } __parse_connection_string( &con_struct, (char*)conn_str_in, len_conn_str_in ); } else { if ( !conn_str_in ) { conn_str_in = (SQLCHAR*)""; len_conn_str_in = strlen((char*) conn_str_in ); } __parse_connection_string( &con_struct, (char*)conn_str_in, len_conn_str_in ); if ( !__get_attribute_value( &con_struct, "DSN" ) && !__get_attribute_value( &con_struct, "DRIVER" ) && !__get_attribute_value( &con_struct, "FILEDSN" )) { int ret; SQLCHAR returned_dsn[ 1025 ], *prefix, *target; /* * try and call GUI to obtain a DSN */ ret = _SQLDriverConnectPrompt( hwnd, returned_dsn, sizeof( returned_dsn )); if ( !ret || returned_dsn[ 0 ] == '\0' ) { __append_pair( &con_struct, "DSN", "DEFAULT" ); } else { prefix = returned_dsn; target = (SQLCHAR*)strchr( (char*)returned_dsn, '=' ); if ( target ) { *target = '\0'; target ++; __append_pair( &con_struct, (char*)prefix, (char*)target ); } else { __append_pair( &con_struct, "DSN", (char*)returned_dsn ); } } /* * regenerate to pass to driver */ __generate_connection_string( &con_struct, (char*)local_conn_str_in, sizeof( local_conn_str_in )); conn_str_in = local_conn_str_in; len_conn_str_in = strlen((char*) conn_str_in ); } } /* * can we find a pooled connection to use here ? */ connection -> pooled_connection = NULL; if ( pooling_enabled ) { int retpool; int retrying = 0; time_t wait_begin = time( NULL ); retry: retpool = search_for_pool( connection, NULL, 0, NULL, 0, NULL, 0, conn_str_in, len_conn_str_in, &pooh, retrying ); /* * found usable existing connection from pool */ if ( retpool == 1 ) { /* * copy the in string to the out string */ ret_from_connect = SQL_SUCCESS; if ( conn_str_out ) { if ( len_conn_str_in < 0 ) { len_conn_str_in = strlen((char*) conn_str_in ); } if ( len_conn_str_in >= conn_str_out_max ) { memcpy( conn_str_out, conn_str_in, conn_str_out_max - 1 ); conn_str_out[ conn_str_out_max - 1 ] = '\0'; if ( ptr_conn_str_out ) { *ptr_conn_str_out = len_conn_str_in; } __post_internal_error( &connection -> error, ERROR_01004, NULL, connection -> environment -> requested_version ); ret_from_connect = SQL_SUCCESS_WITH_INFO; } else { memcpy( conn_str_out, conn_str_in, len_conn_str_in ); conn_str_out[ len_conn_str_in ] = '\0'; if ( ptr_conn_str_out ) { *ptr_conn_str_out = len_conn_str_in; } } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } connection -> state = STATE_C4; __release_conn( &con_struct ); return function_return( SQL_HANDLE_DBC, connection, ret_from_connect, DEFER_R0 ); } /* * pool is at capacity */ if ( retpool == 2 ) { /* * either no timeout or exceeded the timeout */ if ( ! pool_wait_timeout || time( NULL ) - wait_begin > pool_wait_timeout ) { mutex_pool_exit(); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HYT02" ); __post_internal_error( &connection -> error, ERROR_HYT02, NULL, connection -> environment -> requested_version ); __release_conn( &con_struct ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * wait up to 1 second for a signal and try again */ pool_timedwait( connection ); retrying = 1; goto retry; } /* * 1 pool entry has been reserved. Early exits henceforth need to unreserve. */ } /* * else save the info for later */ if ( pooling_enabled ) { connection -> dsn_length = 0; strcpy( connection -> server, "" ); connection -> server_length = 0; strcpy( connection -> user, "" ); connection -> user_length = 0; strcpy( connection -> password, "" ); connection -> password_length = 0; if ( len_conn_str_in == SQL_NTS ) { connection -> _driver_connect_string = strdup((char*)conn_str_in ); } else { connection -> _driver_connect_string = calloc( len_conn_str_in, 1 ); memcpy( connection -> _driver_connect_string, conn_str_in, len_conn_str_in ); } connection -> dsn_length = len_conn_str_in; } /* * get for later */ tsavefile = __get_attribute_value( &con_struct, "SAVEFILE" ); if ( tsavefile ) { if ( strlen( tsavefile ) > INI_MAX_PROPERTY_VALUE ) { memcpy( savefile, tsavefile, INI_MAX_PROPERTY_VALUE ); savefile[ INI_MAX_PROPERTY_VALUE ] = '\0'; } else { strcpy( savefile, tsavefile ); } } else { savefile[ 0 ] = '\0'; } /* * open the file dsn, get each entry from it, if it's not in the connection * struct, add it */ filedsn = __get_attribute_value( &con_struct, "FILEDSN" ); if ( filedsn ) { char str[ 1024 * 16 ]; if ( SQLReadFileDSN( filedsn, "ODBC", NULL, str, sizeof( str ), NULL )) { struct con_struct con_struct1; save_filedsn = strdup( filedsn ); if ( strlen( str )) { strcpy((char*)local_conn_str_in, (char*)conn_str_in ); conn_str_in = local_conn_str_in; __parse_connection_string( &con_struct1, str, strlen( str )); /* * Get the attributes from the original string */ conn_str_in[ 0 ] = '\0'; if ( con_struct.count ) { struct con_pair *cp; cp = con_struct.list; while( cp ) { char *str1; /* * Don't pass FILEDSN down */ if ( strcasecmp( cp -> keyword, "FILEDSN" ) && strcasecmp( cp -> keyword, "FILEDSN" ) ) { str1 = malloc( strlen( cp -> keyword ) + strlen( cp -> attribute ) + 10 ); if ( !str1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY001" ); __post_internal_error( &connection -> error, ERROR_HY001, NULL, connection -> environment -> requested_version ); if ( save_filedsn ) { free( save_filedsn ); } pool_unreserve( pooh ); __release_conn( &con_struct ); __release_conn( &con_struct1 ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( strlen((char*) conn_str_in ) > 0 ) { sprintf( str1, ";%s=%s", cp -> keyword, cp -> attribute ); } else { sprintf( str1, "%s=%s", cp -> keyword, cp -> attribute ); } if ( strlen( (char*)conn_str_in ) + strlen( str1 ) < conn_str_out_max ) { strcat((char*) conn_str_in, str1 ); } else { warnings = 1; __post_internal_error( &connection -> error, ERROR_01004, NULL, connection -> environment -> requested_version ); } free( str1 ); } cp = cp -> next; } } if ( con_struct1.count ) { struct con_pair *cp; cp = con_struct1.list; while( cp ) { if ( !__get_attribute_value( &con_struct, cp -> keyword )) { char *str1; str1 = malloc( strlen( cp -> keyword ) + strlen( cp -> attribute ) + 10 ); if ( !str1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY001" ); __post_internal_error( &connection -> error, ERROR_HY001, NULL, connection -> environment -> requested_version ); if ( save_filedsn ) { free( save_filedsn ); } pool_unreserve( pooh ); __release_conn( &con_struct1 ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( strlen((char*) conn_str_in ) > 0 ) { sprintf( str1, ";%s=%s", cp -> keyword, cp -> attribute ); } else { sprintf( str1, "%s=%s", cp -> keyword, cp -> attribute ); } if ( strlen( (char*)conn_str_in ) + strlen( str1 ) < conn_str_out_max ) { strcat((char*) conn_str_in, str1 ); } else { warnings = 1; __post_internal_error( &connection -> error, ERROR_01004, NULL, connection -> environment -> requested_version ); } free( str1 ); } cp = cp -> next; } } len_conn_str_in = strlen((char*) conn_str_in ); __release_conn( &con_struct1 ); } /* * reparse the string */ __release_conn( &con_struct ); __parse_connection_string( &con_struct, (char*)conn_str_in, len_conn_str_in ); } else { save_filedsn = NULL; } } else { save_filedsn = NULL; } /* * look for some keywords * * have we got a DRIVER= attribute */ driver = __get_attribute_value( &con_struct, "DRIVER" ); if ( driver ) { /* * look up the driver in the ini file */ if ( strlen( driver ) >= sizeof( driver_name )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM011" ); __post_internal_error( &connection -> error, ERROR_IM011, NULL, connection -> environment -> requested_version ); if ( save_filedsn ) { free( save_filedsn ); } pool_unreserve( pooh ); __release_conn( &con_struct ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } strcpy( driver_name, driver ); #ifdef PLATFORM64 SQLGetPrivateProfileString( driver, "Driver64", "", lib_name, sizeof( lib_name ), "ODBCINST.INI" ); if ( lib_name[ 0 ] == '\0' ) { SQLGetPrivateProfileString( driver, "Driver", "", lib_name, sizeof( lib_name ), "ODBCINST.INI" ); } #else SQLGetPrivateProfileString( driver, "Driver", "", lib_name, sizeof( lib_name ), "ODBCINST.INI" ); #endif /* * Assume if it's not in a odbcinst.ini then it's a direct reference */ if ( lib_name[ 0 ] == '\0' ) { strcpy( lib_name, driver ); } strcpy( connection -> dsn, "" ); __handle_attr_extensions( connection, NULL, driver_name ); } else { dsn = __get_attribute_value( &con_struct, "DSN" ); if ( !dsn ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM002" ); __post_internal_error( &connection -> error, ERROR_IM002, NULL, connection -> environment -> requested_version ); __release_conn( &con_struct ); if ( save_filedsn ) { free( save_filedsn ); } pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( strlen( dsn ) > SQL_MAX_DSN_LENGTH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM012" ); __post_internal_error( &connection -> error, ERROR_IM012, NULL, connection -> environment -> requested_version ); __release_conn( &con_struct ); if ( save_filedsn ) { free( save_filedsn ); } pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } /* * look up the dsn in the ini file */ if ( !__find_lib_name( dsn, lib_name, driver_name )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM002" ); __post_internal_error( &connection -> error, ERROR_IM002, NULL, connection -> environment -> requested_version ); __release_conn( &con_struct ); if ( save_filedsn ) { free( save_filedsn ); } pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } strcpy( connection -> dsn, dsn ); __handle_attr_extensions( connection, dsn, driver_name ); } if ( dsn ) { /* * do we have any Environment, Connection, or Statement attributes set in the ini ? */ __handle_attr_extensions( connection, dsn, driver_name ); } else { /* * the attributes may be in the connection string */ __handle_attr_extensions_cs( connection, &con_struct ); } __release_conn( &con_struct ); /* * we have now got the name of a lib to load */ if ( !__connect_part_one( connection, lib_name, driver_name, &warnings )) { if ( save_filedsn ) { free( save_filedsn ); } __disconnect_part_four( connection ); /* release unicode handles */ pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( !CHECK_SQLDRIVERCONNECT( connection ) && !CHECK_SQLDRIVERCONNECTW( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); if ( save_filedsn ) { free( save_filedsn ); } pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( CHECK_SQLDRIVERCONNECT( connection )) { /* if ( CHECK_SQLSETCONNECTATTR( connection )) { int lret; lret = SQLSETCONNECTATTR( connection, connection -> driver_dbc, SQL_ATTR_ANSI_APP, SQL_AA_TRUE, 0 ); } */ ret_from_connect = SQLDRIVERCONNECT( connection, connection -> driver_dbc, hwnd, conn_str_in, len_conn_str_in, conn_str_out, conn_str_out_max, ptr_conn_str_out, driver_completion ); if ( ret_from_connect != SQL_SUCCESS ) { SQLCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; /* * get the errors from the driver before * loseing the connection */ if ( CHECK_SQLERROR( connection )) { do { ret = SQLERROR( connection, SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex_noprefix( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", sqlstate, message_text ); dm_log_write_diag( connection -> msg ); } } while( SQL_SUCCEEDED( ret )); } else if ( CHECK_SQLGETDIAGREC( connection )) { int rec = 1; do { ret = SQLGETDIAGREC( connection, SQL_HANDLE_DBC, connection -> driver_dbc, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex_noprefix( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", sqlstate, message_text ); dm_log_write_diag( connection -> msg ); } } while( SQL_SUCCEEDED( ret )); } } /* * if it was a error then return now */ if ( !SQL_SUCCEEDED( ret_from_connect )) { __disconnect_part_one( connection ); __disconnect_part_four( connection ); sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); if ( save_filedsn ) { free( save_filedsn ); } pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, ret_from_connect, DEFER_R0 ); } connection -> unicode_driver = 0; } else { SQLWCHAR *uc_conn_str_in, *s1 = NULL; SQLCHAR s2[ 128 ]; int wlen; uc_conn_str_in = ansi_to_unicode_alloc( conn_str_in, len_conn_str_in, connection, &wlen ); len_conn_str_in = wlen; if ( CHECK_SQLSETCONNECTATTR( connection )) { SQLSETCONNECTATTR( connection, connection -> driver_dbc, SQL_ATTR_ANSI_APP, SQL_AA_FALSE, 0 ); } if ( conn_str_out && conn_str_out_max > 0 ) { s1 = malloc( sizeof( SQLWCHAR ) * ( conn_str_out_max + 1 )); } ret_from_connect = SQLDRIVERCONNECTW( connection, connection -> driver_dbc, hwnd, uc_conn_str_in, len_conn_str_in, s1 ? s1 : (SQLWCHAR*)conn_str_out, conn_str_out_max, ptr_conn_str_out, driver_completion ); if ( uc_conn_str_in ) free( uc_conn_str_in ); if ( ret_from_connect != SQL_SUCCESS ) { SQLWCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLWCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; /* * get the errors from the driver before * loseing the connection */ if ( CHECK_SQLERRORW( connection )) { do { ret = SQLERRORW( connection, SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, sqlstate, &native_error, message_text, sizeof( message_text ) / sizeof( SQLWCHAR ), &ind ); if ( SQL_SUCCEEDED( ret )) { SQLCHAR *as1, *as2; __post_internal_error_ex_w_noprefix( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); as1 = (SQLCHAR*) unicode_to_ansi_alloc( sqlstate, SQL_NTS, connection, NULL ); as2 = (SQLCHAR*) unicode_to_ansi_alloc( message_text, SQL_NTS, connection, NULL ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", as1, as2 ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); dm_log_write_diag( connection -> msg ); } } while( SQL_SUCCEEDED( ret )); } else if ( CHECK_SQLGETDIAGRECW( connection )) { int rec = 1; do { ret = SQLGETDIAGRECW( connection, SQL_HANDLE_DBC, connection -> driver_dbc, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ) / sizeof( SQLWCHAR ), &ind ); if ( SQL_SUCCEEDED( ret )) { SQLCHAR *as1, *as2; __post_internal_error_ex_w_noprefix( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); as1 = (SQLCHAR*) unicode_to_ansi_alloc( sqlstate, SQL_NTS, connection, NULL ); as2 = (SQLCHAR*) unicode_to_ansi_alloc( message_text, SQL_NTS, connection, NULL ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", as1, as2 ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); dm_log_write_diag( connection -> msg ); } } while( SQL_SUCCEEDED( ret )); } } /* * if it was a error then return now */ if ( !SQL_SUCCEEDED( ret_from_connect )) { __disconnect_part_one( connection ); __disconnect_part_four( connection ); sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s2 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); if ( save_filedsn ) { free( save_filedsn ); } if ( s1 ) { free( s1 ); } pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, ret_from_connect, DEFER_R0 ); } else { if ( conn_str_out && s1 ) { unicode_to_ansi_copy((char*) conn_str_out, conn_str_out_max, s1, SQL_NTS, connection, NULL ); } } if ( s1 ) { free( s1 ); } connection -> unicode_driver = 1; } /* * we should be connected now */ connection -> state = STATE_C4; /* * did we get the type we wanted */ if ( connection -> driver_version != connection -> environment -> requested_version ) { connection -> driver_version = connection -> environment -> requested_version; __post_internal_error( &connection -> error, ERROR_01000, "Driver does not support the requested version", connection -> environment -> requested_version ); ret_from_connect = SQL_SUCCESS_WITH_INFO; } if ( !__connect_part_two( connection )) { __disconnect_part_two( connection ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); if ( save_filedsn ) { free( save_filedsn ); } pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( log_info.log_flag ) { if ( conn_str_out && strlen((char*) conn_str_out ) > 64 ) { sprintf( connection -> msg, "\n\t\tExit:[%s]\ \n\t\t\tConnection Out [%.64s...]", __get_return_status( ret_from_connect, s1 ), conn_str_out ); } else { sprintf( connection -> msg, "\n\t\tExit:[%s]\ \n\t\t\tConnection Out [%s]", __get_return_status( ret_from_connect, s1 ), __string_with_length_hide_pwd( s1, conn_str_out ? conn_str_out : (SQLCHAR*)"NULL", SQL_NTS )); } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } /* * If we specified FILEDSN or SAVEFILE these need adding to the * output string */ if ( strlen( savefile )) { char *str = strdup((char*) conn_str_out ); strcpy((char*) conn_str_out, "SAVEFILE=" ); strcat((char*) conn_str_out, savefile ); strcat((char*) conn_str_out, ";" ); strcat((char*) conn_str_out, str ); free( str ); if ( ptr_conn_str_out ) { *ptr_conn_str_out = strlen((char*) conn_str_out ); } } if ( save_filedsn && strlen( save_filedsn )) { char *str = strdup((char*) conn_str_out ); strcpy((char*) conn_str_out, "FILEDSN=" ); strcat((char*) conn_str_out, save_filedsn ); strcat((char*) conn_str_out, ";" ); strcat((char*) conn_str_out, str ); free( str ); if ( ptr_conn_str_out ) { *ptr_conn_str_out = strlen((char*) conn_str_out ); } } if ( save_filedsn ) { free( save_filedsn ); } /* * write the connection string out to a file */ if ( tsavefile ) { if ( SQL_SUCCEEDED( ret_from_connect )) { __parse_connection_string_ex( &con_struct, (char*)conn_str_out, conn_str_out_max, 0 ); /* * remove them */ SQLWriteFileDSN( savefile, "ODBC", NULL, NULL ); if ( con_struct.count ) { int has_driver = 0; struct con_pair *cp; cp = con_struct.list; while( cp ) { if ( strcasecmp( cp -> keyword, "PWD" ) == 0 ) { /* * don't save this */ cp = cp -> next; continue; } else if ( strcasecmp( cp -> keyword, "SAVEFILE" ) == 0 ) { /* * or this */ cp = cp -> next; continue; } else if ( strcasecmp( cp -> keyword, "DSN" ) == 0 ) { /* * don't save this either, there should be enough with the added DRIVER= * to make it work */ cp = cp -> next; continue; } else if ( strcasecmp( cp -> keyword, "DRIVER" ) == 0 ) { has_driver = 1; } SQLWriteFileDSN( savefile, "ODBC", cp -> keyword, cp -> attribute ); cp = cp -> next; } if ( !has_driver ) { SQLWriteFileDSN( savefile, "ODBC", "Driver", driver_name ); } } __release_conn( &con_struct ); } } if ( warnings && ret_from_connect == SQL_SUCCESS ) { ret_from_connect = SQL_SUCCESS_WITH_INFO; } if ( pooling_enabled && !add_to_pool( connection, pooh ) ) { pool_unreserve( pooh ); } return function_return_nodrv( SQL_HANDLE_DBC, connection, ret_from_connect ); } unixODBC-2.3.12/DriverManager/SQLDriverConnectW.c000066400000000000000000000771551446441710500214050ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLDriverConnectW.c,v 1.18 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLDriverConnectW.c,v $ * Revision 1.18 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.17 2009/01/16 11:02:38 lurcher * Interface to GUI for DSN selection * * Revision 1.16 2009/01/12 15:18:15 lurcher * Add interface into odbcinstQ to allow for a dialog if SQLDriverConnect is called without a DSN= * * Revision 1.15 2008/09/29 14:02:44 lurcher * Fix missing dlfcn group option * * Revision 1.14 2007/02/28 15:37:47 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.13 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.12 2003/08/08 11:14:21 lurcher * * Fix UNICODE problem in SQLDriverConnectW * * Revision 1.11 2002/12/20 11:36:46 lurcher * * Update DMEnvAttr code to allow setting in the odbcinst.ini entry * * Revision 1.10 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.9 2002/10/14 09:46:10 lurcher * * Remove extra return * * Revision 1.8 2002/07/25 09:30:26 lurcher * * Additional unicode and iconv changes * * Revision 1.7 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.6 2002/07/04 17:27:56 lurcher * * Small bug fixes * * Revision 1.4 2002/05/24 12:42:50 lurcher * * Alter NEWS and ChangeLog to match their correct usage * Additional UNICODE tweeks * * Revision 1.3 2002/01/21 18:00:51 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.5 2001/05/15 10:57:44 nick * * Add initial support for VMS * * Revision 1.4 2001/04/16 15:41:24 nick * * Fix some problems calling non existing error funcs * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/01/03 11:57:27 nick * * Fix some name collisions * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLDriverConnectW.c,v $"; /* * connection pooling stuff */ extern int pooling_enabled; extern int pool_wait_timeout; int __parse_connection_string_w( struct con_struct *con_str, SQLWCHAR *str, int str_len ) { struct con_pair *cp; char *local_str, *ptr; int len; int got_dsn = 0; /* if we have a DSN then ignore any DRIVER or FILEDSN */ int got_driver = 0; /* if we have a DRIVER or FILEDSN then ignore any DSN */ con_str -> count = 0; con_str -> list = NULL; if ( str_len == SQL_NTS ) { len = wide_strlen( str ); local_str = malloc( len + 1 ); } else { len = str_len; local_str = malloc( len + 1 ); } unicode_to_ansi_copy( local_str, len+1, str, len, NULL, NULL ); if ( !local_str || strlen( local_str ) == 0 || ( strlen( local_str ) == 1 && *local_str == ';' )) { /* connection-string ::= empty-string [;] */ free( local_str ); return 0; } ptr = local_str; while(( cp = __get_pair( &ptr )) != NULL ) { if ( strcasecmp( cp -> keyword, "DSN" ) == 0 ) { if ( got_driver ) continue; got_dsn = 1; } else if ( strcasecmp( cp -> keyword, "DRIVER" ) == 0 || strcasecmp( cp -> keyword, "FILEDSN" ) == 0 ) { if ( got_dsn ) continue; got_driver = 1; } __append_pair( con_str, cp -> keyword, cp -> attribute ); free( cp -> keyword ); free( cp -> attribute ); free( cp ); } free( local_str ); return 0; } SQLRETURN SQLDriverConnectW( SQLHDBC hdbc, SQLHWND hwnd, SQLWCHAR *conn_str_in, SQLSMALLINT len_conn_str_in, SQLWCHAR *conn_str_out, SQLSMALLINT conn_str_out_max, SQLSMALLINT *ptr_conn_str_out, SQLUSMALLINT driver_completion ) { DMHDBC connection = (DMHDBC)hdbc; struct con_struct con_struct; char *driver = NULL, *dsn = NULL; char lib_name[ INI_MAX_PROPERTY_VALUE + 1 ]; char driver_name[ INI_MAX_PROPERTY_VALUE + 1 ]; SQLWCHAR local_conn_string[ 1024 ]; SQLCHAR local_conn_str_in[ 1024 ]; SQLRETURN ret_from_connect; SQLCHAR s1[ 2048 ]; int warnings = 0; CPOOLHEAD *pooh = 0; /* * check connection */ strcpy( driver_name, "" ); if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHDBC parent_connection; parent_connection = find_parent_handle( connection, SQL_HANDLE_DBC ); if ( parent_connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLDRIVERCONNECTW( parent_connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLDRIVERCONNECTW( parent_connection, connection, hwnd, conn_str_in, len_conn_str_in, conn_str_out, conn_str_out_max, ptr_conn_str_out, driver_completion ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tWindow Hdl = %p\ \n\t\t\tStr In = %s\ \n\t\t\tStr Out = %p\ \n\t\t\tStr Out Max = %d\ \n\t\t\tStr Out Ptr = %p\ \n\t\t\tCompletion = %d", connection, hwnd, __wstring_with_length_hide_pwd( s1, conn_str_in, len_conn_str_in ), conn_str_out, conn_str_out_max, ptr_conn_str_out, driver_completion ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( len_conn_str_in < 0 && len_conn_str_in != SQL_NTS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( driver_completion == SQL_DRIVER_PROMPT && hwnd == NULL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( driver_completion != SQL_DRIVER_PROMPT && driver_completion != SQL_DRIVER_COMPLETE && driver_completion != SQL_DRIVER_COMPLETE_REQUIRED && driver_completion != SQL_DRIVER_NOPROMPT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY110" ); __post_internal_error( &connection -> error, ERROR_HY110, NULL, connection -> environment -> requested_version ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } /* * check the state of the connection */ if ( connection -> state != STATE_C2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08002" ); __post_internal_error( &connection -> error, ERROR_08002, NULL, connection -> environment -> requested_version ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } /* * parse the connection string */ if ( driver_completion == SQL_DRIVER_NOPROMPT ) { char *ansi_conn_str_in; if ( !conn_str_in ) { ansi_conn_str_in = "DSN=DEFAULT;"; len_conn_str_in = strlen( ansi_conn_str_in ); ansi_to_unicode_copy( local_conn_string, ansi_conn_str_in, len_conn_str_in, connection, NULL ); conn_str_in = local_conn_string; __parse_connection_string( &con_struct, ansi_conn_str_in, len_conn_str_in ); } else { __parse_connection_string_w( &con_struct, conn_str_in, len_conn_str_in ); } } else { char *ansi_conn_str_in; if ( !conn_str_in ) { ansi_conn_str_in = ""; len_conn_str_in = strlen( ansi_conn_str_in ); __parse_connection_string( &con_struct, ansi_conn_str_in, len_conn_str_in ); } else { __parse_connection_string_w( &con_struct, conn_str_in, len_conn_str_in ); } if ( !__get_attribute_value( &con_struct, "DSN" ) && !__get_attribute_value( &con_struct, "DRIVER" ) && !__get_attribute_value( &con_struct, "FILEDSN" )) { int ret; SQLWCHAR returned_wdsn[ 1025 ]; SQLCHAR *prefix, *target, returned_dsn[ 1025 ]; /* * try and call GUI to obtain a DSN */ ret = _SQLDriverConnectPromptW( hwnd, returned_wdsn, sizeof( returned_wdsn )); if ( !ret || returned_wdsn[ 0 ] == 0 ) { __append_pair( &con_struct, "DSN", "DEFAULT" ); } else { unicode_to_ansi_copy((char*) returned_dsn, sizeof( returned_dsn ), returned_wdsn, SQL_NTS, connection, NULL ); prefix = returned_dsn; target = (SQLCHAR*)strchr( (char*)returned_dsn, '=' ); if ( target ) { *target = '\0'; target ++; __append_pair( &con_struct, (char*)prefix, (char*)target ); } else { __append_pair( &con_struct, "DSN", (char*)returned_dsn ); } } /* * regenerate to pass to driver */ __generate_connection_string( &con_struct, (char*)local_conn_str_in, sizeof( local_conn_str_in )); len_conn_str_in = strlen((char*) local_conn_str_in ); ansi_to_unicode_copy( local_conn_string, (char*)local_conn_str_in, len_conn_str_in, connection, NULL ); conn_str_in = local_conn_string; } } /* * can we find a pooled connection to use here ? */ connection -> pooled_connection = NULL; if ( pooling_enabled ) { char *ansi_conn_str_in; int clen; int retpool; int retrying = 0; time_t wait_begin = time( NULL ); ansi_conn_str_in = unicode_to_ansi_alloc( conn_str_in, len_conn_str_in, connection, &clen ); retry: retpool = search_for_pool( connection, NULL, 0, NULL, 0, NULL, 0, ansi_conn_str_in, clen, &pooh, retrying ); if ( retpool == 1 ) { free( ansi_conn_str_in ); /* * copy the in string to the out string */ ret_from_connect = SQL_SUCCESS; if ( conn_str_out ) { if ( len_conn_str_in < 0 ) { len_conn_str_in = wide_strlen( conn_str_in ); } if ( len_conn_str_in >= conn_str_out_max ) { memcpy( conn_str_out, conn_str_in, ( conn_str_out_max - 1 ) * 2 ); conn_str_out[ conn_str_out_max - 1 ] = '\0'; if ( ptr_conn_str_out ) { *ptr_conn_str_out = len_conn_str_in; } __post_internal_error( &connection -> error, ERROR_01004, NULL, connection -> environment -> requested_version ); ret_from_connect = SQL_SUCCESS_WITH_INFO; } else { memcpy( conn_str_out, conn_str_in, len_conn_str_in * 2 ); conn_str_out[ len_conn_str_in ] = '\0'; if ( ptr_conn_str_out ) { *ptr_conn_str_out = len_conn_str_in; } } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } connection -> state = STATE_C4; __release_conn( &con_struct ); return function_return( SQL_HANDLE_DBC, connection, ret_from_connect, DEFER_R0 ); } /* * pool is at capacity */ if ( retpool == 2 ) { /* * either no timeout or exceeded the timeout */ if ( ! pool_wait_timeout || time( NULL ) - wait_begin > pool_wait_timeout ) { free( ansi_conn_str_in ); mutex_pool_exit(); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HYT02" ); __post_internal_error( &connection -> error, ERROR_HYT02, NULL, connection -> environment -> requested_version ); __release_conn( &con_struct ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * wait up to 1 second for a signal and try again */ pool_timedwait( connection ); retrying = 1; goto retry; } /* * 1 pool entry has been reserved. Early exits henceforth need to unreserve. */ /* * else save the info for later, not sure its used though */ connection -> dsn_length = 0; strcpy( connection -> server, "" ); connection -> server_length = 0; strcpy( connection -> user, "" ); connection -> user_length = 0; strcpy( connection -> password, "" ); connection -> password_length = 0; if ( len_conn_str_in == SQL_NTS ) { connection -> _driver_connect_string = strdup( ansi_conn_str_in ); } else { connection -> _driver_connect_string = calloc( clen, 1 ); memcpy( connection -> _driver_connect_string, ansi_conn_str_in, clen ); } connection -> dsn_length = clen; free( ansi_conn_str_in ); } /* * look for some keywords * * TO_DO FILEDSN's * * have we got a DRIVER= attribute */ driver = __get_attribute_value( &con_struct, "DRIVER" ); if ( driver ) { /* * look up the driver in the ini file */ strcpy( driver_name, driver ); #ifdef PLATFORM64 SQLGetPrivateProfileString( driver, "Driver64", "", lib_name, sizeof( lib_name ), "ODBCINST.INI" ); if ( lib_name[ 0 ] == '\0' ) { SQLGetPrivateProfileString( driver, "Driver", "", lib_name, sizeof( lib_name ), "ODBCINST.INI" ); } #else SQLGetPrivateProfileString( driver, "Driver", "", lib_name, sizeof( lib_name ), "ODBCINST.INI" ); #endif /* * Assume if it's not in a odbcinst.ini then it's a direct reference */ if ( lib_name[ 0 ] == '\0' ) { strcpy( lib_name, driver ); } strcpy( connection -> dsn, "" ); __handle_attr_extensions( connection, NULL, driver_name ); } else { dsn = __get_attribute_value( &con_struct, "DSN" ); if ( !dsn ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM002" ); __post_internal_error( &connection -> error, ERROR_IM002, NULL, connection -> environment -> requested_version ); __release_conn( &con_struct ); pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( strlen( dsn ) > SQL_MAX_DSN_LENGTH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM012" ); __post_internal_error( &connection -> error, ERROR_IM012, NULL, connection -> environment -> requested_version ); pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } /* * look up the dsn in the ini file */ if ( !__find_lib_name( dsn, lib_name, driver_name )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM002" ); __post_internal_error( &connection -> error, ERROR_IM002, NULL, connection -> environment -> requested_version ); __release_conn( &con_struct ); pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } strcpy( connection -> dsn, dsn ); __handle_attr_extensions( connection, dsn, driver_name ); } if ( dsn ) { /* * do we have any Environment, Connection, or Statement attributes set in the ini ? */ __handle_attr_extensions( connection, dsn, driver_name ); } else { /* * the attributes may be in the connection string */ __handle_attr_extensions_cs( connection, &con_struct ); } __release_conn( &con_struct ); /* * we have now got the name of a lib to load */ if ( !__connect_part_one( connection, lib_name, driver_name, &warnings )) { __disconnect_part_four( connection ); /* release unicode handles */ pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( !CHECK_SQLDRIVERCONNECTW( connection ) && !CHECK_SQLDRIVERCONNECT( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( CHECK_SQLDRIVERCONNECTW( connection )) { if ( CHECK_SQLSETCONNECTATTR( connection )) { SQLSETCONNECTATTR( connection, connection -> driver_dbc, SQL_ATTR_ANSI_APP, SQL_AA_FALSE, 0 ); } ret_from_connect = SQLDRIVERCONNECTW( connection, connection -> driver_dbc, hwnd, conn_str_in, len_conn_str_in, conn_str_out, conn_str_out_max, ptr_conn_str_out, driver_completion ); if ( ret_from_connect != SQL_SUCCESS ) { SQLWCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLWCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; /* * get the errors from the driver before * loseing the connection */ if ( CHECK_SQLERRORW( connection )) { do { ret = SQLERRORW( connection, SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, sqlstate, &native_error, message_text, sizeof( message_text ) / sizeof( SQLWCHAR ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex_w_noprefix( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } } while( SQL_SUCCEEDED( ret )); } else if ( CHECK_SQLGETDIAGRECW( connection )) { int rec = 1; do { ret = SQLGETDIAGRECW( connection, SQL_HANDLE_DBC, connection -> driver_dbc, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ) / sizeof( SQLWCHAR ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex_w_noprefix( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } } while( SQL_SUCCEEDED( ret )); } /* * if it was a error then return now */ if ( !SQL_SUCCEEDED( ret_from_connect )) { __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, ret_from_connect, DEFER_R0 ); } } connection -> unicode_driver = 1; } else { char *in_str, *out_str; int in_len, len; if ( conn_str_in ) { if ( len_conn_str_in == SQL_NTS ) { len = wide_strlen( conn_str_in ); } else { len = len_conn_str_in; } in_len = len + 1; in_str = malloc( in_len ); unicode_to_ansi_copy( in_str, in_len, conn_str_in, len, connection, NULL ); } else { in_str = NULL; } if ( conn_str_out && conn_str_out_max > 0 ) { out_str = malloc( conn_str_out_max + sizeof( SQLWCHAR ) ); } else { out_str = NULL; } ret_from_connect = SQLDRIVERCONNECT( connection, connection -> driver_dbc, hwnd, (SQLCHAR*)in_str, len_conn_str_in, (SQLCHAR*)out_str, conn_str_out_max, ptr_conn_str_out, driver_completion ); if ( in_str ) { free( in_str ); } if ( out_str ) { if ( SQL_SUCCEEDED( ret_from_connect )) { ansi_to_unicode_copy( conn_str_out, out_str, SQL_NTS, connection, NULL ); } free( out_str ); } if ( ret_from_connect != SQL_SUCCESS ) { SQLCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; /* * get the errors from the driver before * loseing the connection */ if ( CHECK_SQLERROR( connection )) { do { ret = SQLERROR( connection, SQL_NULL_HENV, connection -> driver_dbc, SQL_NULL_HSTMT, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex_noprefix( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } } while( SQL_SUCCEEDED( ret )); } else if ( CHECK_SQLGETDIAGREC( connection )) { int rec = 1; do { ret = SQLGETDIAGREC( connection, SQL_HANDLE_DBC, connection -> driver_dbc, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); if ( SQL_SUCCEEDED( ret )) { __post_internal_error_ex_noprefix( &connection -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } } while( SQL_SUCCEEDED( ret )); } /* * if it was a error then return now */ if ( !SQL_SUCCEEDED( ret_from_connect )) { __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret_from_connect, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, ret_from_connect, DEFER_R0 ); } } connection -> unicode_driver = 0; } /* * we should be connected now */ connection -> state = STATE_C4; /* * did we get the type we wanted */ if ( connection -> driver_version != connection -> environment -> requested_version ) { connection -> driver_version = connection -> environment -> requested_version; __post_internal_error( &connection -> error, ERROR_01000, "Driver does not support the requested version", connection -> environment -> requested_version ); ret_from_connect = SQL_SUCCESS_WITH_INFO; } if ( !__connect_part_two( connection )) { __disconnect_part_two( connection ); __disconnect_part_one( connection ); __disconnect_part_four( connection ); /* release unicode handles */ pool_unreserve( pooh ); return function_return( SQL_HANDLE_DBC, connection, SQL_ERROR, DEFER_R0 ); } if ( log_info.log_flag ) { if ( conn_str_out && wide_strlen( conn_str_out ) > 64 ) { sprintf( connection -> msg, "\n\t\tExit:[%s]\ \n\t\t\tConnection Out [%.64s...]", __get_return_status( ret_from_connect, s1 ), __wstring_with_length_hide_pwd( s1, conn_str_out, SQL_NTS )); } else { char null[ 20 ]; strcpy( null, "NULL" ); sprintf( connection -> msg, "\n\t\tExit:[%s]\ \n\t\t\tConnection Out [%s]", __get_return_status( ret_from_connect, s1 ), __wstring_with_length_hide_pwd( s1, conn_str_out, SQL_NTS )); } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } if ( warnings && ret_from_connect == SQL_SUCCESS ) { ret_from_connect = SQL_SUCCESS_WITH_INFO; } if ( pooling_enabled && !add_to_pool( connection, pooh ) ) { pool_unreserve( pooh ); } return function_return_nodrv( SQL_HANDLE_DBC, connection, ret_from_connect ); } unixODBC-2.3.12/DriverManager/SQLDrivers.c000066400000000000000000000360121446441710500201120ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLDrivers.c,v 1.13 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLDrivers.c,v $ * Revision 1.13 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.12 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.11 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.10 2005/10/06 08:58:19 lurcher * Fix problem with SQLDrivers not returning first entry * * Revision 1.9 2005/07/17 09:11:23 lurcher * Fix bug in SQLDrivers that was stopping the return of the attribute length * * Revision 1.8 2004/07/25 00:42:02 peteralexharvey * for OS2 port * * Revision 1.7 2003/11/13 15:12:53 lurcher * * small change to ODBCConfig to have the password field in the driver * properties hide the password * Make both # and ; comments in ini files * * Revision 1.6 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/05/21 14:19:44 lurcher * * * Update libtool to escape from AIX build problem * * Add fix to avoid file handle limitations * * Add more UNICODE changes, it looks like it is native 16 representation * the old way can be reproduced by defining UCS16BE * * Add iusql, its just the same as isql but uses the wide functions * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/05/15 10:57:44 nick * * Add initial support for VMS * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.12 2000/08/16 13:06:21 ngorham * * Fix invalid return code * * Revision 1.11 2000/07/13 13:27:24 ngorham * * remove _ from odbcinst_system_file_path() * * Revision 1.10 2001/04/04 23:10:34 ngorham * * Fix a SQLDrivers problem * * Revision 1.9 2000/02/20 10:18:47 ngorham * * Add support for ODBCINI environment override for Applix. * * Revision 1.8 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.6 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.5 1999/09/19 22:24:33 ngorham * * Added support for the cursor library * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:06 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.4 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLDrivers.c,v $ $Revision: 1.13 $"; #define BUFFERSIZE 1024 SQLRETURN SQLDriversA( SQLHENV henv, SQLUSMALLINT fdirection, SQLCHAR *sz_driver_desc, SQLSMALLINT cb_driver_desc_max, SQLSMALLINT *pcb_driver_desc, SQLCHAR *sz_driver_attributes, SQLSMALLINT cb_drvr_attr_max, SQLSMALLINT *pcb_drvr_attr ) { return SQLDrivers( henv, fdirection, sz_driver_desc, cb_driver_desc_max, pcb_driver_desc, sz_driver_attributes, cb_drvr_attr_max, pcb_drvr_attr ); } SQLRETURN SQLDrivers( SQLHENV henv, SQLUSMALLINT fdirection, SQLCHAR *sz_driver_desc, SQLSMALLINT cb_driver_desc_max, SQLSMALLINT *pcb_driver_desc, SQLCHAR *sz_driver_attributes, SQLSMALLINT cb_drvr_attr_max, SQLSMALLINT *pcb_drvr_attr ) { DMHENV environment = (DMHENV) henv; char buffer[ BUFFERSIZE + 1 ]; char object[ INI_MAX_OBJECT_NAME + 1 ]; SQLRETURN ret = SQL_SUCCESS; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( environment ); if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tEntry:\ \n\t\t\tEnvironment = %p\ \n\t\t\tDirection = %d", environment, (int)fdirection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } thread_protect( SQL_HANDLE_ENV, environment ); /* * check that a version has been requested */ if ( ! environment -> version_set ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &environment -> error, ERROR_HY010, NULL, SQL_OV_ODBC3 ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( cb_driver_desc_max < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &environment -> error, ERROR_HY090, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( cb_drvr_attr_max < 0 || cb_drvr_attr_max == 1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &environment -> error, ERROR_HY090, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( fdirection != SQL_FETCH_FIRST && fdirection != SQL_FETCH_NEXT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY103" ); __post_internal_error( &environment -> error, ERROR_HY103, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( fdirection == SQL_FETCH_FIRST ) environment -> sql_driver_count = 0; else environment -> sql_driver_count ++; try_again: memset( buffer, '\0', sizeof( buffer )); memset( object, '\0', sizeof( object )); SQLGetPrivateProfileString( NULL, NULL, NULL, buffer, sizeof( buffer ), "ODBCINST.INI" ); if ( iniElement( buffer, '\0', '\0', environment -> sql_driver_count, object, sizeof( object )) != INI_SUCCESS ) { /* * Set up for the next time */ environment -> sql_driver_count = -1; ret = SQL_NO_DATA; } else { ret = SQL_SUCCESS; /* * this section is used for internal info */ if ( strcmp( object, "ODBC" ) == 0 ) { environment -> sql_driver_count ++; goto try_again; } if ( pcb_driver_desc ) *pcb_driver_desc = strlen( object ); if ( sz_driver_desc ) { if ( strlen( object ) >= cb_driver_desc_max ) { memcpy( sz_driver_desc, object, cb_driver_desc_max - 1 ); sz_driver_desc[ cb_driver_desc_max - 1 ] = '\0'; ret = SQL_SUCCESS_WITH_INFO; } else { strcpy((char*) sz_driver_desc, object ); } } else { ret = SQL_SUCCESS; } if ( sz_driver_attributes || pcb_drvr_attr ) { HINI hIni; char szPropertyName[INI_MAX_PROPERTY_NAME+1]; char szValue[INI_MAX_PROPERTY_NAME+1]; char szIniName[ INI_MAX_OBJECT_NAME + 1 ]; char buffer[ 1024 ]; int total_len = 0; char b1[ 256 ], b2[ 256 ]; int found = 0; /* * enumerate the driver attributes, first in system odbcinst.ini and if not found in user odbcinst.ini */ sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 )); memset( buffer, '\0', sizeof( buffer )); #ifdef __OS2__ if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', FALSE, 1L ) == INI_SUCCESS ) #else if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', FALSE ) == INI_SUCCESS ) #endif { iniObjectSeek( hIni, (char *)object ); iniPropertyFirst( hIni ); while ( iniPropertyEOL( hIni ) != TRUE ) { iniProperty( hIni, szPropertyName ); iniValue( hIni, szValue ); sprintf( buffer, "%s=%s", szPropertyName, szValue ); found = 1; if ( sz_driver_attributes ) { if ( total_len + strlen( buffer ) + 1 > cb_drvr_attr_max ) { ret = SQL_SUCCESS_WITH_INFO; } else { strcpy((char*) sz_driver_attributes, buffer ); sz_driver_attributes += strlen( buffer ) + 1; } } total_len += strlen( buffer ) + 1; iniPropertyNext( hIni ); } /* * add extra null */ if ( sz_driver_attributes ) *sz_driver_attributes = '\0'; if ( pcb_drvr_attr ) { *pcb_drvr_attr = total_len; } iniClose( hIni ); } if ( !found ) { sprintf( szIniName, "%s/%s", odbcinst_user_file_path( b1 ), odbcinst_user_file_name( b2 )); memset( buffer, '\0', sizeof( buffer )); #ifdef __OS2__ if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', FALSE, 1L ) == INI_SUCCESS ) #else if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', FALSE ) == INI_SUCCESS ) #endif { iniObjectSeek( hIni, (char *)object ); iniPropertyFirst( hIni ); while ( iniPropertyEOL( hIni ) != TRUE ) { iniProperty( hIni, szPropertyName ); iniValue( hIni, szValue ); sprintf( buffer, "%s=%s", szPropertyName, szValue ); if ( sz_driver_attributes ) { if ( total_len + strlen( buffer ) + 1 > cb_drvr_attr_max ) { ret = SQL_SUCCESS_WITH_INFO; } else { strcpy((char*) sz_driver_attributes, buffer ); sz_driver_attributes += strlen( buffer ) + 1; } } total_len += strlen( buffer ) + 1; iniPropertyNext( hIni ); } /* * add extra null */ if ( sz_driver_attributes ) *sz_driver_attributes = '\0'; if ( pcb_drvr_attr ) { *pcb_drvr_attr = total_len; } iniClose( hIni ); } } } } if ( ret == SQL_SUCCESS_WITH_INFO ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 01004" ); __post_internal_error( &environment -> error, ERROR_01004, NULL, environment -> requested_version ); } if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } return function_return_nodrv( SQL_HANDLE_ENV, environment, ret ); } unixODBC-2.3.12/DriverManager/SQLDriversW.c000066400000000000000000000331761446441710500202510ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLDriversW.c,v 1.12 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLDriversW.c,v $ * Revision 1.12 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.11 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.10 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.9 2005/07/17 09:11:23 lurcher * Fix bug in SQLDrivers that was stopping the return of the attribute length * * Revision 1.8 2004/07/25 00:42:02 peteralexharvey * for OS2 port * * Revision 1.7 2003/11/13 15:12:53 lurcher * * small change to ODBCConfig to have the password field in the driver * properties hide the password * Make both # and ; comments in ini files * * Revision 1.6 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.3 2002/05/21 14:19:44 lurcher * * * Update libtool to escape from AIX build problem * * Add fix to avoid file handle limitations * * Add more UNICODE changes, it looks like it is native 16 representation * the old way can be reproduced by defining UCS16BE * * Add iusql, its just the same as isql but uses the wide functions * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/05/15 10:57:44 nick * * Add initial support for VMS * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/01/02 09:55:04 nick * * More unicode bits * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLDriversW.c,v $"; #define BUFFERSIZE 1024 SQLRETURN SQLDriversW( SQLHENV henv, SQLUSMALLINT fdirection, SQLWCHAR *sz_driver_desc, SQLSMALLINT cb_driver_desc_max, SQLSMALLINT *pcb_driver_desc, SQLWCHAR *sz_driver_attributes, SQLSMALLINT cb_drvr_attr_max, SQLSMALLINT *pcb_drvr_attr ) { DMHENV environment = (DMHENV) henv; char buffer[ BUFFERSIZE + 1 ]; char object[ INI_MAX_OBJECT_NAME + 1 ]; SQLRETURN ret = SQL_SUCCESS; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( environment ); if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tEntry:\ \n\t\t\tEnvironment = %p\ \n\t\t\tDirection = %d", environment, (int)fdirection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } thread_protect( SQL_HANDLE_ENV, environment ); /* * check that a version has been requested */ if ( ! environment -> version_set ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &environment -> error, ERROR_HY010, NULL, SQL_OV_ODBC3 ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( cb_driver_desc_max < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &environment -> error, ERROR_HY090, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( cb_drvr_attr_max < 0 || cb_drvr_attr_max == 1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &environment -> error, ERROR_HY090, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( fdirection != SQL_FETCH_FIRST && fdirection != SQL_FETCH_NEXT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY103" ); __post_internal_error( &environment -> error, ERROR_HY103, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( fdirection == SQL_FETCH_FIRST ) environment -> sql_driver_count = 0; else environment -> sql_driver_count ++; try_again: memset( buffer, '\0', sizeof( buffer )); memset( object, '\0', sizeof( object )); SQLGetPrivateProfileString( NULL, NULL, NULL, buffer, sizeof( buffer ), "ODBCINST.INI" ); if ( iniElement( buffer, '\0', '\0', environment -> sql_driver_count, object, sizeof( object )) != INI_SUCCESS ) { /* * Set up for the next time */ environment -> sql_driver_count = -1; ret = SQL_NO_DATA; } else { ret = SQL_SUCCESS; /* * this section is used for internal info */ if ( strcmp( object, "ODBC" ) == 0 ) { environment -> sql_driver_count ++; goto try_again; } if ( pcb_driver_desc ) *pcb_driver_desc = strlen( object ); if ( sz_driver_desc ) { if ( strlen( object ) >= cb_driver_desc_max ) { memcpy( sz_driver_desc, object, cb_driver_desc_max - 1 ); sz_driver_desc[ cb_driver_desc_max - 1 ] = '\0'; ret = SQL_SUCCESS_WITH_INFO; } else { SQLWCHAR *s1; s1 = ansi_to_unicode_alloc((SQLCHAR*) object, SQL_NTS, NULL, NULL ); if ( s1 ) { wide_strcpy( sz_driver_desc, s1 ); free( s1 ); } } } else { ret = SQL_SUCCESS; } if ( sz_driver_attributes || pcb_drvr_attr ) { HINI hIni; char szPropertyName[INI_MAX_PROPERTY_NAME+1]; char szValue[INI_MAX_PROPERTY_NAME+1]; char szIniName[ INI_MAX_OBJECT_NAME + 1 ]; char buffer[ 1024 ]; int total_len = 0; char b1[ 512 ], b2[ 512 ]; int found = 0; /* * enumerate the driver attributes, first in system odbcinst.ini and if not found in user odbcinst.ini */ sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 )); memset( buffer, '\0', sizeof( buffer )); #ifdef __OS2__ if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', FALSE, 1L ) == INI_SUCCESS ) #else if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', FALSE ) == INI_SUCCESS ) #endif { iniObjectSeek( hIni, (char *)object ); iniPropertyFirst( hIni ); while ( iniPropertyEOL( hIni ) != TRUE ) { iniProperty( hIni, szPropertyName ); iniValue( hIni, szValue ); sprintf( buffer, "%s=%s", szPropertyName, szValue ); found = 1; if ( sz_driver_attributes ) { if ( total_len + strlen( buffer ) + 1 > cb_drvr_attr_max ) { ret = SQL_SUCCESS_WITH_INFO; } else { SQLWCHAR *s1; s1 = ansi_to_unicode_alloc((SQLCHAR*) buffer, SQL_NTS, NULL, NULL ); if ( s1 ) { wide_strcpy( sz_driver_attributes, s1 ); free( s1 ); } sz_driver_attributes += strlen( buffer ) + 1; } } total_len += strlen( buffer ) + 1; iniPropertyNext( hIni ); } /* * add extra null */ if ( sz_driver_attributes ) *sz_driver_attributes = '\0'; if ( pcb_drvr_attr ) { *pcb_drvr_attr = total_len; } iniClose( hIni ); } if ( !found ) { sprintf( szIniName, "%s/%s", odbcinst_user_file_path( b1 ), odbcinst_user_file_name( b2 )); memset( buffer, '\0', sizeof( buffer )); #ifdef __OS2__ if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', FALSE, 1L ) == INI_SUCCESS ) #else if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', FALSE ) == INI_SUCCESS ) #endif { iniObjectSeek( hIni, (char *)object ); iniPropertyFirst( hIni ); while ( iniPropertyEOL( hIni ) != TRUE ) { iniProperty( hIni, szPropertyName ); iniValue( hIni, szValue ); sprintf( buffer, "%s=%s", szPropertyName, szValue ); if ( sz_driver_attributes ) { if ( total_len + strlen( buffer ) + 1 > cb_drvr_attr_max ) { ret = SQL_SUCCESS_WITH_INFO; } else { SQLWCHAR *s1; s1 = ansi_to_unicode_alloc((SQLCHAR*) buffer, SQL_NTS, NULL, NULL ); if ( s1 ) { wide_strcpy( sz_driver_attributes, s1 ); free( s1 ); } sz_driver_attributes += strlen( buffer ) + 1; } } total_len += strlen( buffer ) + 1; iniPropertyNext( hIni ); } /* * add extra null */ if ( sz_driver_attributes ) *sz_driver_attributes = '\0'; if ( pcb_drvr_attr ) { *pcb_drvr_attr = total_len; } iniClose( hIni ); } } } } if ( ret == SQL_SUCCESS_WITH_INFO ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 01004" ); __post_internal_error( &environment -> error, ERROR_01004, NULL, environment -> requested_version ); } if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } return function_return_nodrv( SQL_HANDLE_ENV, environment, ret ); } unixODBC-2.3.12/DriverManager/SQLEndTran.c000066400000000000000000000435471446441710500200420ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLEndTran.c,v 1.11 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLEndTran.c,v $ * Revision 1.11 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.10 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.9 2006/05/31 17:35:34 lurcher * Add unicode ODBCINST entry points * * Revision 1.8 2004/06/16 14:42:03 lurcher * * * Fix potential corruption with threaded use and SQLEndTran * * Revision 1.7 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.6 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.5 2002/09/18 14:49:32 lurcher * * DataManagerII additions and some more threading fixes * * Revision 1.3 2002/08/20 12:41:07 lurcher * * Fix incorrect return state from SQLEndTran/SQLTransact * * Revision 1.2 2002/08/12 16:20:44 lurcher * * Make it try and find a working iconv set of encodings * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.9 2000/08/16 15:57:51 ngorham * * Fix bug where it falled if called in state C4 * * Revision 1.8 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.6 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.5 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.4 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.3 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.2 1999/06/19 17:51:40 ngorham * * Applied assorted minor bug fixes * * Revision 1.1.1.1 1999/05/29 13:41:06 sShandyb * first go at it * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:20 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLEndTran.c,v $ $Revision: 1.11 $"; SQLRETURN SQLEndTran( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT completion_type ) { SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; if ( handle_type != SQL_HANDLE_ENV && handle_type != SQL_HANDLE_DBC ) { DMHSTMT statement; DMHDESC descriptor; if ( handle_type == SQL_HANDLE_STMT ) { if ( !__validate_stmt(( DMHSTMT ) handle )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } statement = (DMHSTMT) handle; function_entry( statement ); thread_protect( SQL_HANDLE_STMT, statement ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &statement -> error, ERROR_HY092, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( handle_type == SQL_HANDLE_DESC ) { if ( !__validate_desc(( DMHDESC ) handle )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } descriptor = (DMHDESC) handle; function_entry( descriptor ); thread_protect( SQL_HANDLE_DESC, descriptor ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &descriptor -> error, ERROR_HY092, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } } if ( handle_type == SQL_HANDLE_ENV ) { DMHENV environment = (DMHENV) handle; DMHDBC connection; SQLRETURN ret; if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( environment ); if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tEntry:\ \n\t\t\tEnvironment = %p\ \n\t\t\tCompletion Type = %d", (void*)environment, (int)completion_type ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } thread_protect( SQL_HANDLE_ENV, environment ); if ( completion_type != SQL_COMMIT && completion_type != SQL_ROLLBACK ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY012" ); __post_internal_error( &environment -> error, ERROR_HY012, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( environment -> state == STATE_E2 ) { /* * check that none of the connections are in a need data state */ connection = __get_dbc_root(); while( connection ) { if ( connection -> environment == environment && connection -> state > STATE_C4 ) { if( __check_stmt_from_dbc_v( connection, 8, STATE_S8, STATE_S9, STATE_S10, STATE_S11, STATE_S12, STATE_S13, STATE_S14, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &environment -> error, ERROR_HY010, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } } connection = connection -> next_class_list; } /* * for each connection on this env */ connection = __get_dbc_root(); while( connection ) { if ( connection -> environment == environment && connection -> state > STATE_C4 ) { if ( CHECK_SQLENDTRAN( connection )) { ret = SQLENDTRAN( connection, SQL_HANDLE_DBC, connection -> driver_dbc, completion_type ); if ( !SQL_SUCCEEDED( ret )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 25S01" ); __post_internal_error( &environment -> error, ERROR_25S01, NULL, environment -> requested_version ); return function_return( SQL_HANDLE_ENV, environment, SQL_ERROR, DEFER_R0 ); } } else if ( CHECK_SQLTRANSACT( connection )) { ret = SQLTRANSACT( connection, SQL_NULL_HENV, connection -> driver_dbc, completion_type ); if ( !SQL_SUCCEEDED( ret )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 25S01" ); __post_internal_error( &environment -> error, ERROR_25S01, NULL, environment -> requested_version ); return function_return( SQL_HANDLE_ENV, environment, SQL_ERROR, DEFER_R0 ); } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } } connection = connection -> next_class_list; } } sprintf( environment -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); return function_return( SQL_HANDLE_ENV, environment, SQL_SUCCESS, DEFER_R0 ); } else if ( handle_type == SQL_HANDLE_DBC ) { DMHDBC connection = (DMHDBC) handle; SQLRETURN ret; if ( !__validate_dbc( connection )) { return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tCompletion Type = %d", (void*)connection, (int)completion_type ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( connection -> state == STATE_C1 || connection -> state == STATE_C2 || connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * check status of statements belonging to this connection */ if( __check_stmt_from_dbc_v( connection, 8, STATE_S8, STATE_S9, STATE_S10, STATE_S11, STATE_S12, STATE_S13, STATE_S14, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( completion_type != SQL_COMMIT && completion_type != SQL_ROLLBACK ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY012" ); __post_internal_error( &connection -> error, ERROR_HY012, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( CHECK_SQLENDTRAN( connection )) { ret = SQLENDTRAN( connection, handle_type, connection -> driver_dbc, completion_type ); } else if ( CHECK_SQLTRANSACT( connection )) { ret = SQLTRANSACT( connection, SQL_NULL_HENV, connection -> driver_dbc, completion_type ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if( SQL_SUCCEEDED(ret) ) { SQLSMALLINT cb_value; SQLSMALLINT cb_value_length = sizeof(SQLSMALLINT); SQLRETURN ret1; /* * for each statement belonging to this connection set its state * relative to the commit or rollback behavior */ if ( connection -> cbs_found == 0 ) { /* release thread so we can get the info */ thread_release( SQL_HANDLE_DBC, connection ); ret1 = SQLGetInfo(connection, SQL_CURSOR_COMMIT_BEHAVIOR, &connection -> ccb_value, sizeof( SQLSMALLINT ), &cb_value_length); if ( SQL_SUCCEEDED( ret1 )) { ret1 = SQLGetInfo(connection, SQL_CURSOR_ROLLBACK_BEHAVIOR, &connection -> crb_value, sizeof( SQLSMALLINT ), &cb_value_length); } /* protect thread again */ thread_protect( SQL_HANDLE_DBC, connection ); if ( SQL_SUCCEEDED( ret1 )) { connection -> cbs_found = 1; } } if( completion_type == SQL_COMMIT ) { cb_value = connection -> ccb_value; } else { cb_value = connection -> crb_value; } if( connection -> cbs_found ) { __set_stmt_state( connection, cb_value ); } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R0 ); } else { /* * the book here indicates that we can return a HY092 error * here, but on what handle ? */ return SQL_INVALID_HANDLE; } } unixODBC-2.3.12/DriverManager/SQLError.c000066400000000000000000000313641446441710500175720ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLError.c,v 1.11 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLError.c,v $ * Revision 1.11 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.10 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.9 2008/05/20 13:43:47 lurcher * Vms fixes * * Revision 1.8 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.7 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.6 2002/11/11 17:10:08 lurcher * * VMS changes * * Revision 1.5 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.4 2002/07/24 08:49:51 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.3 2002/02/27 11:27:14 lurcher * * Fix bug in error reporting * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.5 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.4 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.3 2001/01/06 15:00:12 nick * * Fix bug in SQLError introduced with UNICODE * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.14 2000/06/23 16:11:35 ngorham * * Map ODBC 2 SQLSTATE values to ODBC 3 * * Revision 1.13 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.12 1999/11/10 22:15:48 ngorham * * Fix some bugs with the DM and error reporting. * * Revision 1.11 1999/11/10 03:51:33 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.10 1999/10/24 23:54:17 ngorham * * First part of the changes to the error reporting * * Revision 1.9 1999/10/14 06:49:24 ngorham * * Remove @all_includes@ from Drivers/MiniSQL/Makefile.am * * Revision 1.8 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.7 1999/08/03 21:47:39 shandyb * Moving to automake: changed files in DriverManager * * Revision 1.6 1999/07/15 06:22:33 ngorham * * Fixed spelling mistake * * Revision 1.5 1999/07/14 19:46:04 ngorham * * Fix the error logging when SQLError or SQLGetDiagRec returns SQL_NO_DATA * * Revision 1.4 1999/07/12 19:42:05 ngorham * * Finished off SQLGetDiagField.c and fixed a but that caused SQLError to * fail with Perl and PHP, connect errors were not being returned because * I was checking to the environment being set, they were setting the * statement and the environment. The order of checking has been changed. * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:06 sShandyb * first go at it * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:20 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 21:40:58 nick * End of another night :-) * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLError.c,v $ $Revision: 1.11 $"; static SQLRETURN local_extract_sql_error( EHEAD *head, SQLCHAR *sqlstate, SQLINTEGER *native_error, SQLCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length, DMHDBC connection ) { ERROR *err; SQLRETURN ret; char *str; if ( sqlstate ) strcpy((char*) sqlstate, "00000" ); if ( head -> sql_error_head.error_count < 1 ) { return SQL_NO_DATA; } err = head -> sql_error_head.error_list_head; head -> sql_error_head.error_list_head = err -> next; /* * is it the last */ if ( head -> sql_error_head.error_list_tail == err ) head -> sql_error_head.error_list_tail = NULL; /* * not empty yet */ if ( head -> sql_error_head.error_list_head ) { head -> sql_error_head.error_list_head -> prev = NULL; } head -> sql_error_head.error_count --; if ( sqlstate ) { unicode_to_ansi_copy((char*) sqlstate, 6, err -> sqlstate, SQL_NTS, connection, NULL ); } str = unicode_to_ansi_alloc( err -> msg, SQL_NTS, connection, NULL ); if ( message_text && buffer_length < strlen( str ) + 1 ) { ret = SQL_SUCCESS_WITH_INFO; } else { ret = SQL_SUCCESS; } if ( message_text ) { if ( ret == SQL_SUCCESS ) { strcpy((char*) message_text, str ); } else { memcpy( message_text, str, buffer_length ); message_text[ buffer_length - 1 ] = '\0'; } } if ( text_length ) { *text_length = strlen( str ); } if ( native_error ) { *native_error = err -> native_error; } /* * clean up */ free( err -> msg ); free( err ); if ( str ) free( str ); /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) __map_error_state( (char *)sqlstate, __get_version( head )); return ret; } SQLRETURN SQLErrorA( SQLHENV environment_handle, SQLHDBC connection_handle, SQLHSTMT statement_handle, SQLCHAR *sqlstate, SQLINTEGER *native_error, SQLCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length ) { return SQLError( environment_handle, connection_handle, statement_handle, sqlstate, native_error, message_text, buffer_length, text_length ); } SQLRETURN SQLError( SQLHENV environment_handle, SQLHDBC connection_handle, SQLHSTMT statement_handle, SQLCHAR *sqlstate, SQLINTEGER *native_error, SQLCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length ) { SQLRETURN ret; SQLCHAR s0[ 48 ], s1[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; DMHENV environment = NULL; DMHDBC connection = NULL; DMHSTMT statement = NULL; void *active_handle = NULL; EHEAD *herror; char *handle_msg; int handle_type; const char *handle_type_ptr; if ( statement_handle ) { statement = ( DMHSTMT ) statement_handle; if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } connection = statement->connection; active_handle = statement; handle_type = SQL_HANDLE_STMT; herror = &statement->error; handle_msg = statement->msg; handle_type_ptr = "Statement"; } else if (connection_handle) { connection = ( DMHDBC ) connection_handle; if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } active_handle = connection; handle_type = SQL_HANDLE_DBC; herror = &connection->error; handle_msg = connection->msg; handle_type_ptr = "Connection"; } else if ( environment_handle ) { environment = ( DMHENV ) environment_handle; if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } active_handle = environment; handle_type = SQL_HANDLE_ENV; herror = &environment->error; handle_msg = environment->msg; handle_type_ptr = "Environment"; } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } thread_protect( handle_type, active_handle ); if ( log_info.log_flag ) { #ifdef HAVE_SNPRINTF snprintf( handle_msg, LOG_MSG_MAX*2, #else sprintf( handle_msg, #endif "\n\t\tEntry:\ \n\t\t\t%s = %p\ \n\t\t\tSQLState = %p\ \n\t\t\tNative = %p\ \n\t\t\tMessage Text = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tText Len Ptr = %p", handle_type_ptr, active_handle, sqlstate, native_error, message_text, buffer_length, text_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, handle_msg ); } /* * Do diag extraction here if defer flag is set. * Clean the flag after extraction. * The defer flag will not be set for DMHENV in function_return_ex. */ if ( connection && herror->defer_extract ) { extract_error_from_driver( herror, connection, herror->ret_code_deferred, 0 ); herror->defer_extract = 0; herror->ret_code_deferred = 0; } ret = local_extract_sql_error( herror, sqlstate, native_error, message_text, buffer_length, text_length, connection ); if ( log_info.log_flag ) { if ( SQL_SUCCEEDED( ret )) { #ifdef HAVE_SNPRINTF snprintf( handle_msg, LOG_MSG_MAX*2, #else sprintf( handle_msg, #endif "\n\t\tExit:[%s]\ \n\t\t\tSQLState = %s\ \n\t\t\tNative = %s\ \n\t\t\tMessage Text = %s", __get_return_status( ret, s2 ), sqlstate, __iptr_as_string( s0, native_error ), __sdata_as_string( s1, SQL_CHAR, text_length, message_text )); } else { #ifdef HAVE_SNPRINTF snprintf( handle_msg, LOG_MSG_MAX*2, #else sprintf( handle_msg, #endif "\n\t\tExit:[%s]", __get_return_status( ret, s2 )); } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, handle_msg ); } thread_release( handle_type, active_handle ); return ret; } unixODBC-2.3.12/DriverManager/SQLErrorW.c000066400000000000000000000300651446441710500177160ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLErrorW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLErrorW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/05/20 13:43:47 lurcher * Vms fixes * * Revision 1.7 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.5 2002/07/25 09:30:26 lurcher * * Additional unicode and iconv changes * * Revision 1.4 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.3 2002/05/21 14:19:44 lurcher * * * Update libtool to escape from AIX build problem * * Add fix to avoid file handle limitations * * Add more UNICODE changes, it looks like it is native 16 representation * the old way can be reproduced by defining UCS16BE * * Add iusql, its just the same as isql but uses the wide functions * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLErrorW.c,v $"; SQLRETURN extract_parent_handle_err( int handle_type, SQLHENV environment_handle, SQLHDBC connection_handle, SQLHSTMT statement_handle, SQLWCHAR *sqlstate, SQLINTEGER *native_error, SQLWCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); if ( handle_type != SQL_HANDLE_ENV ) { #ifdef WITH_HANDLE_REDIRECT { DMHDBC *parent_handle_dbc; DMHSTMT *parent_handle_stmt; switch ( handle_type ) { case SQL_HANDLE_DBC: { parent_handle_dbc = find_parent_handle( connection_handle, handle_type ); } break; case SQL_HANDLE_STMT: { parent_handle_stmt = find_parent_handle( statement_handle, handle_type ); parent_handle_dbc = parent_handle_stmt->connection; } break; default: { return SQL_INVALID_HANDLE; } } if ( parent_handle_dbc ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLERRORW( parent_handle_dbc )) { dm_log_write(__FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLERRORW( parent_handle_dbc, environment_handle, connection_handle, statement_handle, sqlstate, native_error, message_text, buffer_length, text_length ); } } } #endif } return SQL_INVALID_HANDLE; } /* * unicode mapping function */ static SQLRETURN local_extract_sql_error_w( EHEAD *head, SQLWCHAR *sqlstate, SQLINTEGER *native_error, SQLWCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length ) { ERROR *err; SQLRETURN ret; if ( sqlstate ) { SQLWCHAR *tmp; tmp = ansi_to_unicode_alloc((SQLCHAR*) "00000", SQL_NTS, __get_connection( head ), NULL ); wide_strcpy( sqlstate, tmp ); free( tmp ); } if ( head -> sql_error_head.error_count < 1 ) { return SQL_NO_DATA; } err = head -> sql_error_head.error_list_head; head -> sql_error_head.error_list_head = err -> next; /* * is it the last */ if ( head -> sql_error_head.error_list_tail == err ) head -> sql_error_head.error_list_tail = NULL; /* * not empty yet */ if ( head -> sql_error_head.error_list_head ) { head -> sql_error_head.error_list_head -> prev = NULL; } head -> sql_error_head.error_count --; if ( sqlstate ) { wide_strcpy( sqlstate, err -> sqlstate ); } if ( message_text && buffer_length < wide_strlen( err -> msg ) + 1 ) { ret = SQL_SUCCESS_WITH_INFO; } else { ret = SQL_SUCCESS; } if ( message_text ) { if ( ret == SQL_SUCCESS ) { wide_strcpy( message_text, err -> msg ); } else { memcpy( message_text, err -> msg, buffer_length * 2 ); message_text[ buffer_length - 1 ] = 0; } } if ( text_length ) { *text_length = wide_strlen( err -> msg ); } if ( native_error ) { *native_error = err -> native_error; } /* * clean up */ free( err -> msg ); free( err ); /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) __map_error_state_w( sqlstate, __get_version( head )); return ret; } SQLRETURN SQLErrorW( SQLHENV environment_handle, SQLHDBC connection_handle, SQLHSTMT statement_handle, SQLWCHAR *sqlstate, SQLINTEGER *native_error, SQLWCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length ) { SQLRETURN ret; SQLCHAR s0[ 48 ], s1[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s3[ 100 + LOG_MESSAGE_LEN ]; DMHENV environment = NULL; DMHDBC connection = NULL; DMHSTMT statement = NULL; void *active_handle = NULL; EHEAD *herror; char *handle_msg; int handle_type; const char *handle_type_ptr; if ( statement_handle ) { statement = ( DMHSTMT ) statement_handle; handle_type = SQL_HANDLE_STMT; if ( !__validate_stmt( statement )) { return extract_parent_handle_err( handle_type, environment_handle, connection_handle, statement_handle, sqlstate, native_error, message_text, buffer_length, text_length ); } connection = statement->connection; active_handle = statement; herror = &statement->error; handle_msg = statement->msg; handle_type_ptr = "Statement"; } else if ( connection_handle ) { connection = ( DMHDBC ) connection_handle; handle_type = SQL_HANDLE_DBC; if ( !__validate_dbc( connection )) { return extract_parent_handle_err( handle_type, environment_handle, connection_handle, statement_handle, sqlstate, native_error, message_text, buffer_length, text_length ); } active_handle = connection; herror = &connection->error; handle_msg = connection->msg; handle_type_ptr = "Connection"; } else if ( environment_handle ) { environment = ( DMHENV ) environment_handle; handle_type = SQL_HANDLE_ENV; if ( !__validate_env( environment )) { return extract_parent_handle_err( handle_type, environment_handle, connection_handle, statement_handle, sqlstate, native_error, message_text, buffer_length, text_length ); } active_handle = environment; herror = &environment->error; handle_msg = environment->msg; handle_type_ptr = "Environment"; } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } thread_protect( handle_type, active_handle ); if ( log_info.log_flag ) { sprintf( handle_msg, "\n\t\tEntry:\ \n\t\t\t%s = %p\ \n\t\t\tSQLState = %p\ \n\t\t\tNative = %p\ \n\t\t\tMessage Text = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tText Len Ptr = %p", handle_type_ptr, active_handle, sqlstate, native_error, message_text, buffer_length, text_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, handle_msg ); } /* * Do diag extraction here if defer flag is set. * Clean the flag after extraction. * The defer flag will not be set for DMHENV in function_return_ex. */ if ( connection && herror->defer_extract ) { extract_error_from_driver( herror, connection, herror->ret_code_deferred, 0 ); herror->defer_extract = 0; herror->ret_code_deferred = 0; } ret = local_extract_sql_error_w( herror, sqlstate, native_error, message_text, buffer_length, text_length ); if ( log_info.log_flag ) { if ( SQL_SUCCEEDED( ret )) { char *ts1, *ts2; sprintf( handle_msg, "\n\t\tExit:[%s]\ \n\t\t\tSQLState = %s\ \n\t\t\tNative = %s\ \n\t\t\tMessage Text = %s", __get_return_status( ret, s2 ), __sdata_as_string( s3, SQL_CHAR, NULL, ts1 = unicode_to_ansi_alloc( sqlstate, SQL_NTS, connection, NULL )), __iptr_as_string( s0, native_error ), __sdata_as_string( s1, SQL_CHAR, text_length, ( ts2 = unicode_to_ansi_alloc( message_text, SQL_NTS, connection, NULL )))); free( ts1 ); free( ts2 ); } else { sprintf( handle_msg, "\n\t\tExit:[%s]", __get_return_status( ret, s2 )); } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, handle_msg ); } thread_release( handle_type, active_handle ); return ret; } unixODBC-2.3.12/DriverManager/SQLExecDirect.c000066400000000000000000000360461446441710500205220ustar00rootroot00000000000000/********************************************************************* * * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLExecDirect.c,v 1.11 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLExecDirect.c,v $ * Revision 1.11 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.10 2006/04/11 10:22:56 lurcher * Fix a data type check * * Revision 1.9 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.8 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.7 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.6 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.5 2002/07/18 15:21:56 lurcher * * Fix problem with SQLExecute/SQLExecDirect returning SQL_NO_DATA * * Revision 1.4 2002/01/21 18:00:51 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.3 2002/01/15 14:47:44 lurcher * * Reset stmt->prepared flag after entering a SQLParamData state from * SQLExecDirect * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.5 2001/08/17 11:03:35 nick * * Fix final state from SQLExecute if error happens * * Revision 1.4 2001/04/18 15:03:37 nick * * Fix problem when going to DB2 unicode driver * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.11 2000/06/20 12:43:58 ngorham * * Fix bug that caused a success with info message from SQLExecute or * SQLExecDirect to be lost if used with a ODBC 3 driver and the application * called SQLGetDiagRec * * Revision 1.10 2000/06/16 16:52:16 ngorham * * Stop info messages being lost when calling SQLExecute etc on ODBC 3 * drivers, the SQLNumResultCols were clearing the error before * function return had a chance to get to them * * Revision 1.9 1999/11/18 22:42:09 ngorham * * Fix missing function_entry in SQLExecDirect() * * Revision 1.8 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/11/10 03:51:33 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:06 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.5 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.4 1999/05/03 19:50:43 nick * Another check point * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 21:40:58 nick * End of another night :-) * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLExecDirect.c,v $ $Revision: 1.11 $"; SQLRETURN SQLExecDirectA( SQLHSTMT statement_handle, SQLCHAR *statement_text, SQLINTEGER text_length ) { return SQLExecDirect( statement_handle, statement_text, text_length ); } SQLRETURN SQLExecDirect( SQLHSTMT statement_handle, SQLCHAR *statement_text, SQLINTEGER text_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR *s1; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { /* * allocate some space for the buffer */ if ( statement_text && text_length == SQL_NTS ) { s1 = malloc( strlen((char*) statement_text ) + LOG_MESSAGE_LEN ); } else if ( statement_text ) { s1 = malloc( text_length + LOG_MESSAGE_LEN ); } else { s1 = malloc( LOG_MESSAGE_LEN ); } sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tSQL = %s", statement, __string_with_length( s1, statement_text, text_length )); free( s1 ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( !statement_text ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( text_length <= 0 && text_length != SQL_NTS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLEXECDIRECT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1; int wlen; #ifdef NR_PROBE if ( !CHECK_SQLEXECDIRECTW( statement -> connection ) || !CHECK_SQLNUMRESULTCOLS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } #else if ( !CHECK_SQLEXECDIRECTW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } #endif s1 = ansi_to_unicode_alloc( statement_text, text_length, statement -> connection, &wlen ); text_length = wlen; ret = SQLEXECDIRECTW( statement -> connection, statement -> driver_stmt, s1, text_length ); if ( s1 ) free( s1 ); } else { #ifdef NR_PROBE if ( !CHECK_SQLEXECDIRECT( statement -> connection ) || !CHECK_SQLNUMRESULTCOLS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } #else if ( !CHECK_SQLEXECDIRECT( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } #endif ret = SQLEXECDIRECT( statement -> connection, statement -> driver_stmt, statement_text, text_length ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE SQLRETURN local_ret; /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, statement, ret, TRUE, DEFER_R1 ); } local_ret = SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); if ( statement -> numcols > 0 ) { statement -> state = STATE_S5; } else { statement -> state = STATE_S4; } #else /* * We don't know for sure */ statement -> hascols = 1; statement -> state = STATE_S5; #endif statement -> prepared = 0; /* * there is a issue here with transactions, but for the * moment * statement -> connection -> state = STATE_C6; */ } else if ( ret == SQL_NO_DATA ) { statement -> state = STATE_S4; statement -> prepared = 0; } else if ( ret == SQL_NEED_DATA ) { statement -> interupted_func = SQL_API_SQLEXECDIRECT; statement -> interupted_state = statement -> state; statement -> state = STATE_S8; statement -> prepared = 0; } else if ( ret == SQL_PARAM_DATA_AVAILABLE ) { statement -> interupted_func = SQL_API_SQLEXECDIRECT; statement -> interupted_state = statement -> state; statement -> state = STATE_S13; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLEXECDIRECT; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; statement -> prepared = 0; } else if (( statement -> state >= STATE_S2 && statement -> state <= STATE_S4 ) || ( statement -> state >= STATE_S11 && statement -> state <= STATE_S12 && statement -> interupted_state >= STATE_S2 && statement -> interupted_state <= STATE_S4 )) { statement -> state = STATE_S1; } else if ( statement -> state >= STATE_S11 && statement -> state <= STATE_S12 ) { statement -> state = statement -> interupted_state; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s2 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLExecDirectW.c000066400000000000000000000326671446441710500206560ustar00rootroot00000000000000/********************************************************************* * * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLExecDirectW.c,v 1.10 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLExecDirectW.c,v $ * Revision 1.10 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.9 2008/08/29 08:01:38 lurcher * Alter the way W functions are passed to the driver * * Revision 1.8 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.7 2006/04/11 10:22:56 lurcher * Fix a data type check * * Revision 1.6 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.3 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.2 2002/01/15 14:47:44 lurcher * * Reset stmt->prepared flag after entering a SQLParamData state from * SQLExecDirect * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/01/04 13:16:25 nick * * Add support for GNU portable threads and tidy up some UNICODE compile * warnings * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLExecDirectW.c,v $"; SQLRETURN SQLExecDirectW( SQLHSTMT statement_handle, SQLWCHAR *statement_text, SQLINTEGER text_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR *s1; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLEXECDIRECTW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLEXECDIRECTW( parent_statement -> connection, statement, statement_text, text_length ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { /* * allocate some space for the buffer */ if ( statement_text && text_length == SQL_NTS ) { s1 = malloc( wide_strlen( statement_text ) * 2 + LOG_MESSAGE_LEN * 2 ); } else if ( statement_text ) { s1 = malloc( text_length + LOG_MESSAGE_LEN * 2 ); } else { s1 = malloc( LOG_MESSAGE_LEN * 2 ); } sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tSQL = %s", statement, __wstring_with_length( s1, statement_text, text_length )); free( s1 ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( !statement_text ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( text_length <= 0 && text_length != SQL_NTS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLEXECDIRECT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver || CHECK_SQLEXECDIRECTW( statement -> connection )) { #ifdef NR_PROBE if ( !CHECK_SQLEXECDIRECTW( statement -> connection ) || !CHECK_SQLNUMRESULTCOLS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } #else if ( !CHECK_SQLEXECDIRECTW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } #endif ret = SQLEXECDIRECTW( statement -> connection, statement -> driver_stmt, statement_text, text_length ); } else { SQLCHAR *as1 = NULL; int clen; #ifdef NR_PROBE if ( !CHECK_SQLEXECDIRECT( statement -> connection ) || !CHECK_SQLNUMRESULTCOLS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } #else if ( !CHECK_SQLEXECDIRECT( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } #endif as1 = (SQLCHAR*) unicode_to_ansi_alloc( statement_text, text_length, statement -> connection, &clen ); text_length = clen; ret = SQLEXECDIRECT( statement -> connection, statement -> driver_stmt, as1, text_length ); if ( as1 ) free( as1 ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE SQLRETURN local_ret; /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, statement, ret, TRUE, DEFER_R1 ); } local_ret = SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); if ( statement -> numcols > 0 ) { statement -> state = STATE_S5; } else { statement -> state = STATE_S4; } #else /* * We don't know for sure */ statement -> hascols = 1; statement -> state = STATE_S5; #endif statement -> prepared = 0; /* * there is a issue here with transactions, but for the * moment * statement -> connection -> state = STATE_C6; */ } else if ( ret == SQL_NO_DATA ) { statement -> state = STATE_S4; statement -> prepared = 0; } else if ( ret == SQL_NEED_DATA ) { statement -> interupted_func = SQL_API_SQLEXECDIRECT; statement -> interupted_state = statement -> state; statement -> state = STATE_S8; statement -> prepared = 0; } else if ( ret == SQL_PARAM_DATA_AVAILABLE ) { statement -> interupted_func = SQL_API_SQLEXECDIRECT; statement -> interupted_state = statement -> state; statement -> state = STATE_S13; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLEXECDIRECT; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; statement -> prepared = 0; } else if (( statement -> state >= STATE_S2 && statement -> state <= STATE_S4 ) || ( statement -> state >= STATE_S11 && statement -> state <= STATE_S12 && statement -> interupted_state >= STATE_S2 && statement -> interupted_state <= STATE_S4 )) { statement -> state = STATE_S1; } else if ( statement -> state >= STATE_S11 && statement -> state <= STATE_S12 ) { statement -> state = statement -> interupted_state; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s2 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLExecute.c000066400000000000000000000244401446441710500201000ustar00rootroot00000000000000/********************************************************************e * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLExecute.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLExecute.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2004/07/25 00:42:02 peteralexharvey * for OS2 port * * Revision 1.7 2004/07/24 17:55:37 lurcher * Sync up CVS * * Revision 1.6 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/07/18 15:21:57 lurcher * * Fix problem with SQLExecute/SQLExecDirect returning SQL_NO_DATA * * Revision 1.3 2002/04/22 02:03:13 peteralexharvey * - added demo flag to DM because Apple MUST have demo versions of all * software they list on their web * * Revision 1.2 2001/11/21 16:58:25 lurcher * * Assorted fixes to make the MAX OSX build work nicer * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/08/17 11:03:35 nick * * Fix final state from SQLExecute if error happens * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.11 2000/06/20 12:43:58 ngorham * * Fix bug that caused a success with info message from SQLExecute or * SQLExecDirect to be lost if used with a ODBC 3 driver and the application * called SQLGetDiagRec * * Revision 1.10 2000/06/16 16:52:17 ngorham * * Stop info messages being lost when calling SQLExecute etc on ODBC 3 * drivers, the SQLNumResultCols were clearing the error before * function return had a chance to get to them * * Revision 1.9 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.8 1999/11/10 03:51:33 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.7 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.6 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.5 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.4 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.3 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.2 1999/06/19 17:51:40 ngorham * * Applied assorted minor bug fixes * * Revision 1.1.1.1 1999/05/29 13:41:06 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.5 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.4 1999/05/03 19:50:43 nick * Another check point * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLExecute.c,v $ $Revision: 1.9 $"; SQLRETURN SQLExecute( SQLHSTMT statement_handle ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p", statement ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { if ( statement -> prepared ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); } return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S1 || statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLEXECUTE ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( !CHECK_SQLEXECUTE( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLEXECUTE( statement -> connection , statement -> driver_stmt ); if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE SQLRETURN local_ret; /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, statement, ret, TRUE, DEFER_R1 ); } local_ret = SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); if ( statement -> numcols > 0 ) statement -> state = STATE_S5; else statement -> state = STATE_S4; #else /* * We don't know for sure */ statement -> hascols = 1; statement -> state = STATE_S5; #endif } else if ( ret == SQL_NO_DATA ) { statement -> state = STATE_S4; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLEXECUTE; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else if ( ret == SQL_NEED_DATA ) { statement -> interupted_func = SQL_API_SQLEXECUTE; statement -> interupted_state = statement -> state; statement -> state = STATE_S8; } else if ( ret == SQL_PARAM_DATA_AVAILABLE ) { statement -> interupted_func = SQL_API_SQLEXECUTE; statement -> interupted_state = statement -> state; statement -> state = STATE_S13; } else { statement -> state = STATE_S2; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLExtendedFetch.c000066400000000000000000000237251446441710500212150ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLExtendedFetch.c,v 1.6 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLExtendedFetch.c,v $ * Revision 1.6 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2007/11/29 12:00:30 lurcher * Add 64 bit type changes to SQLExtendedFetch etc * * Revision 1.4 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.3 2001/01/14 09:13:21 nick * * Remove stray printf * * Revision 1.2 2000/12/05 16:49:21 nick * * Add missing identifier_type in SQLSpecialColumns log * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:06 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLExtendedFetch.c,v $ $Revision: 1.6 $"; SQLRETURN SQLExtendedFetch( SQLHSTMT statement_handle, SQLUSMALLINT f_fetch_type, SQLLEN irow, SQLULEN *pcrow, SQLUSMALLINT *rgf_row_status ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tFetch Type = %d\ \n\t\t\tRow = %d\ \n\t\t\tPcRow = %p\ \n\t\t\tRow Status = %p", statement, f_fetch_type, (int)irow, pcrow, (void*)rgf_row_status ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( f_fetch_type != SQL_FETCH_NEXT && f_fetch_type != SQL_FETCH_PRIOR && f_fetch_type != SQL_FETCH_FIRST && f_fetch_type != SQL_FETCH_LAST && f_fetch_type != SQL_FETCH_ABSOLUTE && f_fetch_type != SQL_FETCH_RELATIVE && f_fetch_type != SQL_FETCH_BOOKMARK ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY106" ); __post_internal_error( &statement -> error, ERROR_HY106, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S2 || statement -> state == STATE_S3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S6 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLEXTENDEDFETCH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( !CHECK_SQLEXTENDEDFETCH( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLEXTENDEDFETCH( statement -> connection, statement -> driver_stmt, f_fetch_type, irow, pcrow, rgf_row_status ); if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLEXTENDEDFETCH; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) { statement -> interupted_state = statement -> state; statement -> state = STATE_S11; } } else if ( SQL_SUCCEEDED( ret )) { statement -> eod = 0; statement -> state = STATE_S7; } else if ( ret == SQL_NO_DATA ) { statement -> eod = 1; statement -> state = STATE_S7; } else if (statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { statement -> state = statement -> interupted_state; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLFetch.c000066400000000000000000000242231446441710500175260ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLFetch.c,v 1.4 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLFetch.c,v $ * Revision 1.4 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.2 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.3 2001/01/14 10:09:39 nick * * Add sqi/test to build * * Revision 1.2 2001/01/09 22:33:13 nick * * Stop passing NULL into SQLExtendedFetch * Further fixes to unicode to ansi conversions * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.9 2000/02/11 00:41:46 ngorham * * Added a couple of fixes for drivers without SQLExtendedFetch * * Revision 1.8 2000/02/02 07:55:21 ngorham * * Add flag to disable SQLFetch -> SQLExtendedFetch mapping * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:06 sShandyb * first go at it * * Revision 1.2 1999/06/02 23:48:45 ngorham * * Added more 3-2 mapping * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.4 1999/05/03 19:50:43 nick * Another check point * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLFetch.c,v $ $Revision: 1.4 $"; SQLRETURN SQLFetch( SQLHSTMT statement_handle ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p", statement ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } /* * check states */ thread_protect( SQL_HANDLE_STMT, statement ); if ( statement -> state == STATE_S1 || statement -> state == STATE_S2 || statement -> state == STATE_S3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S7 || statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLFETCH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( CHECK_SQLFETCH( statement -> connection )) { /* * this is odd, but its in the book */ if ( statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && CHECK_SQLEXTENDEDFETCH( statement -> connection ) && statement -> connection -> ex_fetch_mapping ) { /* * the row_st_arr can't be null */ if ( statement -> row_st_arr ) { ret = SQLEXTENDEDFETCH( statement -> connection, statement -> driver_stmt, SQL_FETCH_NEXT, 0, statement -> row_ct_ptr, statement -> row_st_arr ); } else { SQLUSMALLINT *row_st_arr; int row_count; SQLUSMALLINT row_status; if ( statement -> row_array_size <= 1 ) { row_count = 1; row_st_arr = &row_status; } else { row_count = statement -> row_array_size; row_st_arr = malloc( sizeof( SQLUSMALLINT ) * row_count ); } ret = SQLEXTENDEDFETCH( statement -> connection, statement -> driver_stmt, SQL_FETCH_NEXT, 0, statement -> row_ct_ptr, row_st_arr ); if ( row_count > 1 ) { free( row_st_arr ); } } } else { ret = SQLFETCH( statement -> connection, statement -> driver_stmt ); if( statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && statement -> row_ct_ptr ) { if( ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO ) { *statement -> row_ct_ptr = 1; } else { *statement -> row_ct_ptr = 0; } } } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLFETCH; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else if ( SQL_SUCCEEDED( ret )) { statement -> state = STATE_S6; statement -> eod = 0; } else if ( ret == SQL_NO_DATA ) { statement -> eod = 1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLFetchScroll.c000066400000000000000000000252341446441710500207100ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLFetchScroll.c,v 1.6 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLFetchScroll.c,v $ * Revision 1.6 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2007/11/29 12:00:31 lurcher * Add 64 bit type changes to SQLExtendedFetch etc * * Revision 1.4 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 2000/05/22 17:10:34 ngorham * * Fix problems with the FetchScroll -> ExtendedFetch Mapping * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.2 1999/06/02 23:48:45 ngorham * * Added more 3-2 mapping * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLFetchScroll.c,v $ $Revision: 1.6 $"; SQLRETURN SQLFetchScroll( SQLHSTMT statement_handle, SQLSMALLINT fetch_orientation, SQLLEN fetch_offset ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tFetch Orentation = %d\ \n\t\t\tFetch Offset = %d", statement, fetch_orientation, (int)fetch_offset ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( fetch_orientation != SQL_FETCH_NEXT && fetch_orientation != SQL_FETCH_PRIOR && fetch_orientation != SQL_FETCH_FIRST && fetch_orientation != SQL_FETCH_LAST && fetch_orientation != SQL_FETCH_ABSOLUTE && fetch_orientation != SQL_FETCH_RELATIVE && fetch_orientation != SQL_FETCH_BOOKMARK ) || (fetch_orientation == SQL_FETCH_BOOKMARK && statement -> bookmarks_on == SQL_UB_OFF) ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY106" ); __post_internal_error( &statement -> error, ERROR_HY106, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S2 || statement -> state == STATE_S3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S7 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLFETCHSCROLL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( CHECK_SQLFETCHSCROLL( statement -> connection )) { ret = SQLFETCHSCROLL( statement -> connection, statement -> driver_stmt, fetch_orientation, fetch_offset ); } else if ( statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && CHECK_SQLEXTENDEDFETCH( statement -> connection )) { /* * map to ODBC 2 call */ SQLINTEGER bm_ptr = 0; if ( fetch_orientation == SQL_FETCH_BOOKMARK ) { if ( statement -> fetch_bm_ptr ) bm_ptr = *statement -> fetch_bm_ptr; ret = SQLEXTENDEDFETCH( statement -> connection, statement -> driver_stmt, fetch_orientation, bm_ptr, statement -> row_ct_ptr, statement -> row_st_arr ); } else { ret = SQLEXTENDEDFETCH( statement -> connection, statement -> driver_stmt, fetch_orientation, fetch_offset, statement -> row_ct_ptr, statement -> row_st_arr ); } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLFETCHSCROLL; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else if ( SQL_SUCCEEDED( ret )) { statement -> eod = 0; statement -> state = STATE_S6; } else if ( ret == SQL_NO_DATA ) { statement -> eod = 1; statement -> state = STATE_S6; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLForeignKeys.c000066400000000000000000000354351446441710500207310ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLForeignKeys.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLForeignKeys.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.9 2000/06/20 12:44:00 ngorham * * Fix bug that caused a success with info message from SQLExecute or * SQLExecDirect to be lost if used with a ODBC 3 driver and the application * called SQLGetDiagRec * * Revision 1.8 2000/06/16 16:52:18 ngorham * * Stop info messages being lost when calling SQLExecute etc on ODBC 3 * drivers, the SQLNumResultCols were clearing the error before * function return had a chance to get to them * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:54 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.3 1999/05/03 19:50:43 nick * Another check point * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLForeignKeys.c,v $ $Revision: 1.7 $"; SQLRETURN SQLForeignKeysA( SQLHSTMT statement_handle, SQLCHAR *szpk_catalog_name, SQLSMALLINT cbpk_catalog_name, SQLCHAR *szpk_schema_name, SQLSMALLINT cbpk_schema_name, SQLCHAR *szpk_table_name, SQLSMALLINT cbpk_table_name, SQLCHAR *szfk_catalog_name, SQLSMALLINT cbfk_catalog_name, SQLCHAR *szfk_schema_name, SQLSMALLINT cbfk_schema_name, SQLCHAR *szfk_table_name, SQLSMALLINT cbfk_table_name ) { return SQLForeignKeys( statement_handle, szpk_catalog_name, cbpk_catalog_name, szpk_schema_name, cbpk_schema_name, szpk_table_name, cbpk_table_name, szfk_catalog_name, cbfk_catalog_name, szfk_schema_name, cbfk_schema_name, szfk_table_name, cbfk_table_name ); } SQLRETURN SQLForeignKeys( SQLHSTMT statement_handle, SQLCHAR *szpk_catalog_name, SQLSMALLINT cbpk_catalog_name, SQLCHAR *szpk_schema_name, SQLSMALLINT cbpk_schema_name, SQLCHAR *szpk_table_name, SQLSMALLINT cbpk_table_name, SQLCHAR *szfk_catalog_name, SQLSMALLINT cbfk_catalog_name, SQLCHAR *szfk_schema_name, SQLSMALLINT cbfk_schema_name, SQLCHAR *szfk_table_name, SQLSMALLINT cbfk_table_name ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s5[ 100 + LOG_MESSAGE_LEN ], s6[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tPK Catalog Name = %s\ \n\t\t\tPK Schema Name = %s\ \n\t\t\tPK Table Name = %s\ \n\t\t\tFK Catalog Name = %s\ \n\t\t\tFK Schema Name = %s\ \n\t\t\tFK Table Name = %s", statement, __string_with_length( s1, szpk_catalog_name, cbpk_catalog_name ), __string_with_length( s2, szpk_schema_name, cbpk_schema_name ), __string_with_length( s3, szpk_table_name, cbpk_table_name ), __string_with_length( s4, szfk_catalog_name, cbfk_catalog_name ), __string_with_length( s5, szfk_schema_name, cbfk_schema_name ), __string_with_length( s6, szfk_table_name, cbfk_table_name )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( !szpk_table_name && !szfk_table_name ) { __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if (( cbpk_catalog_name < 0 && cbpk_catalog_name != SQL_NTS ) || ( cbpk_schema_name < 0 && cbpk_schema_name != SQL_NTS ) || ( cbpk_table_name < 0 && cbpk_table_name != SQL_NTS ) || ( cbfk_catalog_name < 0 && cbfk_catalog_name != SQL_NTS ) || ( cbfk_schema_name < 0 && cbfk_schema_name != SQL_NTS ) || ( cbfk_table_name < 0 && cbfk_table_name != SQL_NTS )) { __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLFOREIGNKEYS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1, *s2, *s3, *s4, *s5, *s6; int wlen; if ( !CHECK_SQLFOREIGNKEYSW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( szpk_catalog_name, cbpk_catalog_name, statement -> connection, &wlen ); cbpk_catalog_name = wlen; s2 = ansi_to_unicode_alloc( szpk_schema_name, cbpk_schema_name, statement -> connection, &wlen ); cbpk_schema_name = wlen; s3 = ansi_to_unicode_alloc( szpk_table_name, cbpk_table_name, statement -> connection, &wlen ); cbpk_table_name = wlen; s4 = ansi_to_unicode_alloc( szfk_catalog_name, cbfk_catalog_name, statement -> connection, &wlen ); cbfk_catalog_name = wlen; s5 = ansi_to_unicode_alloc( szfk_schema_name, cbfk_schema_name, statement -> connection, &wlen ); cbfk_schema_name = wlen; s6 = ansi_to_unicode_alloc( szfk_table_name, cbfk_table_name, statement -> connection, &wlen ); cbfk_table_name = wlen; ret = SQLFOREIGNKEYSW( statement -> connection , statement -> driver_stmt, s1, cbpk_catalog_name, s2, cbpk_schema_name, s3, cbpk_table_name, s4, cbfk_catalog_name, s5, cbfk_schema_name, s6, cbfk_table_name ); if ( s1 ) free( s1 ); if ( s2 ) free( s2 ); if ( s3 ) free( s3 ); if ( s4 ) free( s4 ); if ( s5 ) free( s5 ); if ( s6 ) free( s6 ); } else { if ( !CHECK_SQLFOREIGNKEYS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLFOREIGNKEYS( statement -> connection , statement -> driver_stmt, szpk_catalog_name, cbpk_catalog_name, szpk_schema_name, cbpk_schema_name, szpk_table_name, cbpk_table_name, szfk_catalog_name, cbfk_catalog_name, szfk_schema_name, cbfk_schema_name, szfk_table_name, cbfk_table_name ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /******** * Added this to get num cols from drivers which can only tell * us after execute - PAH */ /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, statement, ret, TRUE, DEFER_R1 ); } SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); /******/ #endif statement -> hascols = 1; statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLFOREIGNKEYS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLForeignKeysW.c000066400000000000000000000330741446441710500210550ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLForeignKeysW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLForeignKeysW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/08/29 08:01:38 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLForeignKeysW.c,v $"; SQLRETURN SQLForeignKeysW( SQLHSTMT statement_handle, SQLWCHAR *szpk_catalog_name, SQLSMALLINT cbpk_catalog_name, SQLWCHAR *szpk_schema_name, SQLSMALLINT cbpk_schema_name, SQLWCHAR *szpk_table_name, SQLSMALLINT cbpk_table_name, SQLWCHAR *szfk_catalog_name, SQLSMALLINT cbfk_catalog_name, SQLWCHAR *szfk_schema_name, SQLSMALLINT cbfk_schema_name, SQLWCHAR *szfk_table_name, SQLSMALLINT cbfk_table_name ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s5[ 100 + LOG_MESSAGE_LEN ], s6[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLFOREIGNKEYSW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLFOREIGNKEYSW( parent_statement -> connection, statement, szpk_catalog_name, cbpk_catalog_name, szpk_schema_name, cbpk_schema_name, szpk_table_name, cbpk_table_name, szfk_catalog_name, cbfk_catalog_name, szfk_schema_name, cbfk_schema_name, szfk_table_name, cbfk_table_name ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tPK Catalog Name = %s\ \n\t\t\tPK Schema Name = %s\ \n\t\t\tPK Table Name = %s\ \n\t\t\tFK Catalog Name = %s\ \n\t\t\tFK Schema Name = %s\ \n\t\t\tFK Table Name = %s", statement, __wstring_with_length( s1, szpk_catalog_name, cbpk_catalog_name ), __wstring_with_length( s2, szpk_schema_name, cbpk_schema_name ), __wstring_with_length( s3, szpk_table_name, cbpk_table_name ), __wstring_with_length( s4, szfk_catalog_name, cbfk_catalog_name ), __wstring_with_length( s5, szfk_schema_name, cbfk_schema_name ), __wstring_with_length( s6, szfk_table_name, cbfk_table_name )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( !szpk_table_name && !szfk_table_name ) { __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if (( cbpk_catalog_name < 0 && cbpk_catalog_name != SQL_NTS ) || ( cbpk_schema_name < 0 && cbpk_schema_name != SQL_NTS ) || ( cbpk_table_name < 0 && cbpk_table_name != SQL_NTS ) || ( cbfk_catalog_name < 0 && cbfk_catalog_name != SQL_NTS ) || ( cbfk_schema_name < 0 && cbfk_schema_name != SQL_NTS ) || ( cbfk_table_name < 0 && cbfk_table_name != SQL_NTS )) { __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if ( statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLFOREIGNKEYS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver || CHECK_SQLFOREIGNKEYSW( statement -> connection )) { if ( !CHECK_SQLFOREIGNKEYSW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLFOREIGNKEYSW( statement -> connection , statement -> driver_stmt, szpk_catalog_name, cbpk_catalog_name, szpk_schema_name, cbpk_schema_name, szpk_table_name, cbpk_table_name, szfk_catalog_name, cbfk_catalog_name, szfk_schema_name, cbfk_schema_name, szfk_table_name, cbfk_table_name ); } else { SQLCHAR *as1, *as2, *as3, *as4, *as5, *as6; int clen; if ( !CHECK_SQLFOREIGNKEYS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } as1 = (SQLCHAR*) unicode_to_ansi_alloc( szpk_catalog_name, cbpk_catalog_name, statement -> connection, &clen ); cbpk_catalog_name = clen; as2 = (SQLCHAR*) unicode_to_ansi_alloc( szpk_schema_name, cbpk_schema_name, statement -> connection, &clen ); cbpk_schema_name = clen; as3 = (SQLCHAR*) unicode_to_ansi_alloc( szpk_table_name, cbpk_table_name, statement -> connection, &clen ); cbpk_table_name = clen; as4 = (SQLCHAR*) unicode_to_ansi_alloc( szfk_catalog_name, cbfk_catalog_name, statement -> connection, &clen ); cbfk_catalog_name = clen; as5 = (SQLCHAR*) unicode_to_ansi_alloc( szfk_schema_name, cbfk_schema_name, statement -> connection, &clen ); cbfk_schema_name = clen; as6 = (SQLCHAR*) unicode_to_ansi_alloc( szfk_table_name, cbfk_table_name, statement -> connection, &clen ); cbfk_table_name = clen; ret = SQLFOREIGNKEYS( statement -> connection , statement -> driver_stmt, as1, cbpk_catalog_name, as2, cbpk_schema_name, as3, cbpk_table_name, as4, cbfk_catalog_name, as5, cbfk_schema_name, as6, cbfk_table_name ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); if ( as3 ) free( as3 ); if ( as4 ) free( as4 ); if ( as5 ) free( as5 ); if ( as6 ) free( as6 ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /******** * Added this to get num cols from drivers which can only tell * us after execute - PAH */ /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, statement, ret, TRUE, DEFER_R1 ); } SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); /******/ #endif statement -> hascols = 1; statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLFOREIGNKEYS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLFreeConnect.c000066400000000000000000000041771446441710500206760ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLFreeConnect.c,v 1.2 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLFreeConnect.c,v $ * Revision 1.2 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLFreeConnect.c,v $ $Revision: 1.2 $"; SQLRETURN SQLFreeConnect( SQLHDBC connection_handle ) { return __SQLFreeHandle( SQL_HANDLE_DBC, connection_handle ); } unixODBC-2.3.12/DriverManager/SQLFreeEnv.c000066400000000000000000000041611446441710500200260ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLFreeEnv.c,v 1.2 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLFreeEnv.c,v $ * Revision 1.2 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLFreeEnv.c,v $ $Revision: 1.2 $"; SQLRETURN SQLFreeEnv( SQLHENV environment_handle ) { return __SQLFreeHandle( SQL_HANDLE_ENV, environment_handle ); } unixODBC-2.3.12/DriverManager/SQLFreeHandle.c000066400000000000000000000502141446441710500204710ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLFreeHandle.c,v 1.12 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLFreeHandle.c,v $ * Revision 1.12 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.11 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.10 2007/12/17 13:13:03 lurcher * Fix a couple of descriptor typo's * * Revision 1.9 2007/01/02 10:27:50 lurcher * Fix descriptor leak with unicode only driver * * Revision 1.8 2006/04/18 10:24:47 lurcher * Add a couple of changes from Mark Vanderwiel * * Revision 1.7 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.6 2003/05/14 09:42:25 lurcher * * Fix bug in stats collection * * Revision 1.5 2003/04/09 08:42:18 lurcher * * Allow setting of odbcinstQ lib from odbcinst.ini and Environment * * Revision 1.4 2002/09/18 14:49:32 lurcher * * DataManagerII additions and some more threading fixes * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.7 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * Revision 1.6 2001/06/04 15:24:49 nick * * Add port to MAC OSX and QT3 changes * * Revision 1.5 2001/05/15 13:33:44 jason * * Wrapped calls to stats with COLLECT_STATS * * Revision 1.4 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.3 2000/12/19 10:28:29 martin * * Return "not built with stats" in uodbc_error() if stats function called * when stats not built. * Add uodbc_update_stats() calls to SQLFreeHandle. * * Revision 1.2 2000/11/23 09:43:29 nick * * Fix deadlock posibility * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.12 2000/06/27 17:34:10 ngorham * * Fix a problem when the second part of the connect failed a seg fault * was generated in the error reporting * * Revision 1.11 2000/05/21 21:49:19 ngorham * * Assorted fixes * * Revision 1.10 1999/11/17 21:11:59 ngorham * * Fix bug where the check for a valid handle was after the code had * used it. * * Revision 1.9 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.8 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.7 1999/10/09 00:15:58 ngorham * * Add mapping from SQL_TYPE_X to SQL_X and SQL_C_TYPE_X to SQL_C_X * when the driver is a ODBC 2 one * * Revision 1.6 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.5 1999/08/03 21:47:39 shandyb * Moving to automake: changed files in DriverManager * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.2 1999/06/07 01:29:31 pharvey * *** empty log message *** * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.5 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.4 1999/05/03 19:50:43 nick * Another check point * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) #include "__stats.h" #include #endif static char const rcsid[]= "$RCSfile: SQLFreeHandle.c,v $ $Revision: 1.12 $"; extern int pooling_enabled; SQLRETURN __SQLFreeHandle( SQLSMALLINT handle_type, SQLHANDLE handle ) { switch( handle_type ) { case SQL_HANDLE_ENV: case SQL_HANDLE_SENV: { DMHENV environment = (DMHENV)handle; /* * check environment, the mark_released addition is to catch what seems to be a * race error in SQLAPI where it uses a env handle in one thread while its being released * in another. releasing the handle at the end of this function is not fast enough for * the normal validation process to catch it. */ if ( !__validate_env_mark_released( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( environment ); if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p", handle_type, (void*)handle ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } thread_protect( SQL_HANDLE_ENV, environment ); #ifdef WITH_SHARDENV if ( pooling_enabled == 0 ) { /* * check states */ if ( environment -> state != STATE_E1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &environment -> error, ERROR_HY010, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } } #else /* * check states */ if ( environment -> state != STATE_E1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &environment -> error, ERROR_HY010, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } #endif thread_release( SQL_HANDLE_ENV, environment ); #ifdef WITH_SHARDENV if ( pooling_enabled == 0 ) { /* * release any pooled connections that are using this environment */ __strip_from_pool( environment ); } #else __strip_from_pool( environment ); #endif __release_env( environment ); return SQL_SUCCESS; } break; case SQL_HANDLE_DBC: { DMHDBC connection = (DMHDBC)handle; DMHENV environment; /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); environment = connection -> environment; if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p", handle_type, (void*)handle ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_ENV, environment ); /* * check states */ if ( connection -> state != STATE_C2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } environment -> connection_count --; if ( environment -> connection_count == 0 ) { environment -> state = STATE_E1; } environment = connection -> environment; __release_attr_str( &connection -> env_attribute ); __release_attr_str( &connection -> dbc_attribute ); __release_attr_str( &connection -> stmt_attribute ); __disconnect_part_one( connection ); __release_dbc( connection ); if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tExit:[SQL_SUCCESS]" ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) uodbc_update_stats(environment->sh, UODBC_STATS_TYPE_HDBC, (void *)-1); #endif thread_release( SQL_HANDLE_ENV, environment ); return SQL_SUCCESS; } break; case SQL_HANDLE_STMT: { DMHSTMT statement = (DMHSTMT)handle; DMHDBC connection; SQLRETURN ret; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); connection = statement -> connection; if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p", handle_type, (void*)handle ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( !CHECK_SQLFREEHANDLE( statement -> connection )) { if ( !CHECK_SQLFREESTMT( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else { ret = SQLFREESTMT( statement -> connection, statement -> driver_stmt, SQL_DROP ); } } else { ret = SQLFREEHANDLE( statement -> connection, handle_type, statement -> driver_stmt ); } if ( SQL_SUCCEEDED( ret )) { /* * release the implicit descriptors, * this matches the tests in SQLAllocHandle */ if (( statement -> connection -> driver_act_ver == 3 && CHECK_SQLGETSTMTATTR( connection )) || CHECK_SQLGETSTMTATTRW( connection )) { if ( statement -> implicit_ard ) __release_desc( statement -> implicit_ard ); if ( statement -> implicit_apd ) __release_desc( statement -> implicit_apd ); if ( statement -> implicit_ird ) __release_desc( statement -> implicit_ird ); if ( statement -> implicit_ipd ) __release_desc( statement -> implicit_ipd ); } statement -> connection -> statement_count --; thread_release( SQL_HANDLE_STMT, statement ); #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) uodbc_update_stats(connection->environment->sh, UODBC_STATS_TYPE_HSTMT, (void *)-1); #endif __release_stmt( statement ); } else { thread_release( SQL_HANDLE_STMT, statement ); } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[SQL_SUCCESS]" ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( IGNORE_THREAD, connection, ret, DEFER_R0 ); } break; case SQL_HANDLE_DESC: { DMHDESC descriptor = (DMHDESC)handle; DMHDBC connection; SQLRETURN ret; /* * check descriptor */ if ( !__validate_desc( descriptor )) { return SQL_INVALID_HANDLE; } function_entry( descriptor ); connection = descriptor -> connection; if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p", handle_type, (void*)handle ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } if ( descriptor -> implicit ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY017" ); __post_internal_error( &descriptor -> error, ERROR_HY017, NULL, connection -> environment -> requested_version ); return function_return_nodrv( IGNORE_THREAD, descriptor, SQL_ERROR ); } thread_protect( SQL_HANDLE_DESC, descriptor ); if ( !CHECK_SQLFREEHANDLE( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } else { ret = SQLFREEHANDLE( connection, handle_type, descriptor -> driver_desc ); } /* * check status of statements associated with this descriptor */ if( __check_stmt_from_desc( descriptor, STATE_S8 ) || __check_stmt_from_desc( descriptor, STATE_S9 ) || __check_stmt_from_desc( descriptor, STATE_S10 ) || __check_stmt_from_desc( descriptor, STATE_S11 ) || __check_stmt_from_desc( descriptor, STATE_S12 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_DESC, descriptor, SQL_ERROR, DEFER_R0 ); } thread_release( SQL_HANDLE_DESC, descriptor ); __release_desc( descriptor ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[SQL_SUCCESS]" ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) uodbc_update_stats(connection->environment->sh, UODBC_STATS_TYPE_HDESC, (void *)-1); #endif return function_return( IGNORE_THREAD, connection, SQL_SUCCESS, DEFER_R0 ); } break; default: /* * there is nothing to report a error on */ return SQL_INVALID_HANDLE; } } SQLRETURN SQLFreeHandle( SQLSMALLINT handle_type, SQLHANDLE handle ) { return __SQLFreeHandle( handle_type, handle ); } unixODBC-2.3.12/DriverManager/SQLFreeStmt.c000066400000000000000000000171401446441710500202260ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLFreeStmt.c,v 1.6 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLFreeStmt.c,v $ * Revision 1.6 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/07/04 17:27:56 lurcher * * Small bug fixes * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLFreeStmt.c,v $ $Revision: 1.6 $"; SQLRETURN SQLFreeStmt( SQLHSTMT statement_handle, SQLUSMALLINT option ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tOption = %d", statement, option ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); switch ( option ) { case SQL_CLOSE: case SQL_DROP: case SQL_RESET_PARAMS: case SQL_UNBIND: break; default: dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &statement -> error, ERROR_HY092, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( !CHECK_SQLFREESTMT( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * option has already been checked and found valid */ switch ( option ) { case SQL_CLOSE: ret = SQLFREESTMT( statement -> connection, statement -> driver_stmt, option ); if ( SQL_SUCCEEDED( ret )) { if ( statement -> state == STATE_S4 ) { if ( statement -> prepared ) statement -> state = STATE_S2; else statement -> state = STATE_S1; } else if ( statement -> state >= STATE_S5 && statement -> state <= STATE_S7 ) { if ( statement -> prepared ) statement -> state = STATE_S3; else statement -> state = STATE_S1; } statement -> hascols = 0; } break; case SQL_DROP: /* * call SQLFreeHandle(); */ thread_release( SQL_HANDLE_STMT, statement ); return function_return( IGNORE_THREAD, statement, __SQLFreeHandle( SQL_HANDLE_STMT, statement_handle), DEFER_R3); case SQL_RESET_PARAMS: case SQL_UNBIND: ret = SQLFREESTMT( statement -> connection, statement -> driver_stmt, option ); /* * TO_DO reset any information about parameters or bound columns */ break; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLGetConnectAttr.c000066400000000000000000000611611446441710500213630ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetConnectAttr.c,v 1.15 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetConnectAttr.c,v $ * Revision 1.15 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.14 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.13 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.12 2006/03/08 09:18:41 lurcher * fix silly typo that was using sizeof( SQL_WCHAR ) instead of SQLWCHAR * * Revision 1.11 2004/11/22 17:02:48 lurcher * Fix unicode/ansi conversion in the SQLGet functions * * Revision 1.10 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.9 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.8 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.7 2002/11/11 17:10:09 lurcher * * VMS changes * * Revision 1.6 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.5 2002/07/16 13:08:18 lurcher * * Filter attribute values from SQLSetStmtAttr to SQLSetStmtOption to fit * within ODBC 2 * Make DSN's double clickable in ODBCConfig * * Revision 1.4 2002/01/30 12:20:02 lurcher * * Add MyODBC 3 driver source * * Revision 1.3 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.2 2001/12/04 16:46:19 lurcher * * Allow the Unix Domain Socket to be set from the ini file (DSN) * Make the DataManager browser work with drivers that don't support * SQLRowCount * Make the directory selection from odbctest work simplier * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.5 2001/08/03 15:19:00 nick * * Add changes to set values before connect * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.6 1999/09/21 22:34:24 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.5 1999/09/19 22:24:33 ngorham * * Added support for the cursor library * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetConnectAttr.c,v $ $Revision: 1.15 $"; SQLRETURN SQLGetConnectAttrA( SQLHDBC connection_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { return SQLGetConnectAttr( connection_handle, attribute, value, buffer_length, string_length ); } SQLRETURN SQLGetConnectAttr( SQLHDBC connection_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { DMHDBC connection = (DMHDBC)connection_handle; int type = 0; char *ptr; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * doesn't require a handle */ if ( attribute == SQL_ATTR_TRACE ) { if ( value ) { if ( log_info.log_flag ) { *((SQLINTEGER*)value) = SQL_OPT_TRACE_ON; } else { *((SQLINTEGER*)value) = SQL_OPT_TRACE_OFF; } } return SQL_SUCCESS; } else if ( attribute == SQL_ATTR_TRACEFILE ) { SQLRETURN ret = SQL_SUCCESS; ptr = log_info.log_file_name; if ( log_info.log_file_name ) { if ( string_length ) { *string_length = strlen( ptr ); } if ( value ) { if ( buffer_length > strlen( log_info.log_file_name ) + 1 ) { strcpy( value, ptr ); } else { memcpy( value, log_info.log_file_name, buffer_length - 1 ); ((char*)value)[ buffer_length - 1 ] = '\0'; ret = SQL_SUCCESS_WITH_INFO; } } } else { if ( string_length ) { *string_length = 0; } if ( value ) { if ( buffer_length >= 1 ) { strcpy( value, "" ); } else { ret = SQL_SUCCESS_WITH_INFO; } } } return ret; } /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tAttribute = %s\ \n\t\t\tValue = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tStrLen = %p", connection, __con_attr_as_string( s1, attribute ), value, (int)buffer_length, (void*)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( connection -> state == STATE_C2 ) { switch ( attribute ) { case SQL_ATTR_ACCESS_MODE: case SQL_ATTR_AUTOCOMMIT: case SQL_ATTR_LOGIN_TIMEOUT: case SQL_ATTR_ODBC_CURSORS: case SQL_ATTR_TRACE: case SQL_ATTR_TRACEFILE: case SQL_ATTR_ASYNC_ENABLE: break; case SQL_ATTR_PACKET_SIZE: if ( connection -> packet_size_set ) break; case SQL_ATTR_QUIET_MODE: if ( connection -> quite_mode_set ) break; default: { struct save_attr *sa = connection -> save_attr; while (sa) { if (sa -> attr_type == attribute) { SQLRETURN rc = SQL_SUCCESS; if (sa -> str_len == SQL_NTS || sa -> str_len > 0) { SQLLEN realLen = sa->str_attr ? strlen(sa->str_attr) : 0; if(value && sa->str_attr) { strncpy(value, sa->str_attr, buffer_length - 1); ((SQLCHAR*)value)[buffer_length - 1] = 0; } if(string_length) { *string_length = realLen; } if(realLen > buffer_length - 1) { __post_internal_error( &connection -> error, ERROR_01004, NULL, connection -> environment -> requested_version ); rc = SQL_SUCCESS_WITH_INFO; } } else if(buffer_length >= sizeof(intptr_t)) { *(intptr_t*)value = sa -> intptr_attr; if(string_length) { *string_length = sizeof(intptr_t); } } else if(sa -> str_len >= SQL_IS_SMALLINT && sa -> str_len <= SQL_IS_POINTER) { SQLLEN length = 0; switch (sa -> str_len) { case SQL_IS_SMALLINT: *(SQLSMALLINT*)value = sa->intptr_attr; length = sizeof(SQLSMALLINT); break; case SQL_IS_USMALLINT: *(SQLUSMALLINT*)value = sa->intptr_attr; length = sizeof(SQLUSMALLINT); break; case SQL_IS_INTEGER: *(SQLINTEGER*)value = sa->intptr_attr; length = sizeof(SQLINTEGER); break; case SQL_IS_UINTEGER: *(SQLUINTEGER*)value = sa->intptr_attr; length = sizeof(SQLUINTEGER); break; case SQL_IS_POINTER: *(SQLPOINTER**)value = (SQLPOINTER*) sa->intptr_attr; length = sizeof(SQLPOINTER); break; } if(string_length) { *string_length = length; } } else { memcpy(value, &sa->intptr_attr, buffer_length); } return function_return_nodrv( SQL_HANDLE_DBC, connection, rc ); } sa = sa -> next; } } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } switch ( attribute ) { case SQL_ATTR_ACCESS_MODE: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> access_mode; type = 1; } break; case SQL_ATTR_AUTOCOMMIT: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> auto_commit; type = 1; } break; case SQL_ATTR_LOGIN_TIMEOUT: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> login_timeout; type = 1; } break; case SQL_ATTR_ODBC_CURSORS: *((SQLULEN*)value) = connection -> cursors; type = 1; break; case SQL_ATTR_TRACE: *((SQLINTEGER*)value) = connection -> trace; type = 1; break; case SQL_ATTR_TRACEFILE: ptr = connection -> tracefile; type = 2; break; case SQL_ATTR_ASYNC_ENABLE: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLULEN*)value) = connection -> async_enable; type = 1; } break; case SQL_ATTR_AUTO_IPD: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> auto_ipd; type = 1; } break; case SQL_ATTR_CONNECTION_TIMEOUT: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> connection_timeout; type = 1; } break; case SQL_ATTR_METADATA_ID: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> metadata_id; type = 1; } break; case SQL_ATTR_PACKET_SIZE: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> packet_size; type = 1; } break; case SQL_ATTR_QUIET_MODE: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLLEN*)value) = connection -> quite_mode; type = 1; } break; case SQL_ATTR_TXN_ISOLATION: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> txn_isolation; type = 1; } break; default: break; } /* * if type has been set we have already set the value, * so just return */ if ( type ) { SQLRETURN ret = SQL_SUCCESS; if ( type == 1 ) { if ( string_length ) { *string_length = sizeof( SQLUINTEGER ); } } else { if ( string_length ) { *string_length = strlen( ptr ); } if ( value ) { if ( buffer_length > strlen( ptr ) + 1 ) { strcpy( value, ptr ); } else { memcpy( value, ptr, buffer_length - 1 ); ((char*)value)[ buffer_length - 1 ] = '\0'; ret = SQL_SUCCESS_WITH_INFO; } } } sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); return function_return_nodrv( SQL_HANDLE_DBC, connection, ret ); } else { SQLRETURN ret = 0; /* * call the driver */ if ( connection -> unicode_driver ) { if ( !CHECK_SQLGETCONNECTATTRW( connection )) { if (( ret = CHECK_SQLGETCONNECTOPTIONW( connection ))) { SQLWCHAR *s1 = NULL; /* * Is it in the legal range of values */ if ( attribute < SQL_CONN_DRIVER_MIN && ( attribute > SQL_PACKET_SIZE || attribute < SQL_ACCESS_MODE )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } switch( attribute ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( SQL_SUCCEEDED( ret ) && value ) { s1 = malloc( sizeof( SQLWCHAR ) * ( 1024 )); } break; } ret = SQLGETCONNECTOPTIONW( connection, connection -> driver_dbc, attribute, s1 ? s1 : value ); switch( attribute ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( SQL_SUCCEEDED( ret ) && value && s1 ) { unicode_to_ansi_copy( value, buffer_length, s1, SQL_NTS, connection, NULL ); } if ( SQL_SUCCEEDED( ret ) && string_length ) { *string_length /= sizeof( SQLWCHAR ); } break; } if ( s1 ) { free( s1 ); } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { SQLWCHAR *s1 = NULL; switch( attribute ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( SQL_SUCCEEDED( ret ) && value && buffer_length > 0 ) { s1 = malloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 )); } break; } ret = SQLGETCONNECTATTRW( connection, connection -> driver_dbc, attribute, s1 ? s1 : value, s1 ? sizeof( SQLWCHAR ) * buffer_length : buffer_length, string_length ); switch( attribute ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( SQL_SUCCEEDED( ret ) && value && s1 ) { unicode_to_ansi_copy( value, buffer_length, s1, SQL_NTS, connection, NULL ); } if ( SQL_SUCCEEDED( ret ) && string_length ) { *string_length /= sizeof( SQLWCHAR ); } break; } if ( s1 ) { free( s1 ); } } } else { if ( !CHECK_SQLGETCONNECTATTR( connection )) { if ( CHECK_SQLGETCONNECTOPTION( connection )) { /* * Is it in the legal range of values */ if ( attribute < SQL_CONN_DRIVER_MIN && ( attribute > SQL_PACKET_SIZE || attribute < SQL_ACCESS_MODE )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } ret = SQLGETCONNECTOPTION( connection, connection -> driver_dbc, attribute, value ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { ret = SQLGETCONNECTATTR( connection, connection -> driver_dbc, attribute, value, buffer_length, string_length ); } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 ); } } unixODBC-2.3.12/DriverManager/SQLGetConnectAttrW.c000066400000000000000000000573441446441710500215220ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetConnectAttrW.c,v 1.14 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetConnectAttrW.c,v $ * Revision 1.14 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.13 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.12 2008/08/29 08:01:38 lurcher * Alter the way W functions are passed to the driver * * Revision 1.11 2004/11/22 17:02:48 lurcher * Fix unicode/ansi conversion in the SQLGet functions * * Revision 1.10 2003/10/30 18:20:45 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.9 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.8 2002/11/11 17:10:10 lurcher * * VMS changes * * Revision 1.7 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.6 2002/08/12 13:17:52 lurcher * * Replicate the way the MS DM handles loading of driver libs, and allocating * handles in the driver. usage counting in the driver means that dlopen is * only called for the first use, and dlclose for the last. AllocHandle for * the driver environment is only called for the first time per driver * per application environment. * * Revision 1.5 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.4 2002/07/16 13:08:18 lurcher * * Filter attribute values from SQLSetStmtAttr to SQLSetStmtOption to fit * within ODBC 2 * Make DSN's double clickable in ODBCConfig * * Revision 1.3 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.2 2001/12/04 16:46:19 lurcher * * Allow the Unix Domain Socket to be set from the ini file (DSN) * Make the DataManager browser work with drivers that don't support * SQLRowCount * Make the directory selection from odbctest work simplier * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/08/03 15:19:00 nick * * Add changes to set values before connect * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetConnectAttrW.c,v $"; SQLRETURN SQLGetConnectAttrW( SQLHDBC connection_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { DMHDBC connection = (DMHDBC)connection_handle; int type = 0; char *ptr; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * doesn't require a handle */ if ( attribute == SQL_ATTR_TRACE ) { if ( value ) { if ( log_info.log_flag ) { *((SQLINTEGER*)value) = SQL_OPT_TRACE_ON; } else { *((SQLINTEGER*)value) = SQL_OPT_TRACE_OFF; } } return SQL_SUCCESS; } else if ( attribute == SQL_ATTR_TRACEFILE ) { SQLRETURN ret = SQL_SUCCESS; ptr = log_info.log_file_name; if ( ptr ) { int len = strlen( ptr ) * sizeof( SQLWCHAR ); if ( string_length ) { *string_length = len; } if ( value ) { if ( buffer_length > len + sizeof( SQLWCHAR )) { ansi_to_unicode_copy( value, ptr, SQL_NTS, connection, NULL ); } else { ansi_to_unicode_copy( value, ptr, buffer_length - 1, connection, NULL ); ((SQLWCHAR*)value)[( buffer_length - 1 ) / sizeof( SQLWCHAR )] = 0; ret = SQL_SUCCESS_WITH_INFO; } } } else { if ( string_length ) { *string_length = 0; } if ( value ) { if ( buffer_length > 0 ) { ((SQLWCHAR*)value)[ 0 ] = 0; } else { ret = SQL_SUCCESS_WITH_INFO; } } } return ret; } /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tAttribute = %s\ \n\t\t\tValue = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tStrLen = %p", connection, __con_attr_as_string( s1, attribute ), value, (int)buffer_length, (void*)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( connection -> state == STATE_C2 ) { switch ( attribute ) { case SQL_ATTR_ACCESS_MODE: case SQL_ATTR_AUTOCOMMIT: case SQL_ATTR_LOGIN_TIMEOUT: case SQL_ATTR_ODBC_CURSORS: case SQL_ATTR_TRACE: case SQL_ATTR_TRACEFILE: case SQL_ATTR_ASYNC_ENABLE: break; case SQL_ATTR_PACKET_SIZE: if ( connection -> packet_size_set ) break; case SQL_ATTR_QUIET_MODE: if ( connection -> quite_mode_set ) break; default: { struct save_attr *sa = connection -> save_attr; while (sa) { if (sa -> attr_type == attribute) { SQLRETURN rc = SQL_SUCCESS; if (sa -> str_len == SQL_NTS || sa -> str_len > 0) { SQLLEN realLen = sa->str_attr ? strlen(sa->str_attr) : 0; if(value && sa->str_attr && buffer_length) { ansi_to_unicode_copy( value, sa->str_attr, buffer_length/sizeof(SQLWCHAR), connection, NULL ); ((SQLCHAR*)value)[buffer_length - 1] = 0; } if(string_length) { *string_length = realLen * sizeof(SQLWCHAR); } if(realLen * sizeof(SQLWCHAR) > buffer_length - 1) { __post_internal_error( &connection -> error, ERROR_01004, NULL, connection -> environment -> requested_version ); rc = SQL_SUCCESS_WITH_INFO; } } else if(buffer_length >= sizeof(SQLLEN)) { *(SQLLEN*)value = sa -> intptr_attr; if(string_length) { *string_length = sizeof(SQLLEN); } } else if(sa -> str_len >= SQL_IS_SMALLINT && sa -> str_len <= SQL_IS_POINTER) { SQLLEN length = 0; switch (sa -> str_len) { case SQL_IS_SMALLINT: *(SQLSMALLINT*)value = sa->intptr_attr; length = sizeof(SQLSMALLINT); break; case SQL_IS_USMALLINT: *(SQLUSMALLINT*)value = sa->intptr_attr; length = sizeof(SQLUSMALLINT); break; case SQL_IS_INTEGER: *(SQLINTEGER*)value = sa->intptr_attr; length = sizeof(SQLINTEGER); break; case SQL_IS_UINTEGER: *(SQLUINTEGER*)value = sa->intptr_attr; length = sizeof(SQLUINTEGER); break; case SQL_IS_POINTER: *(SQLPOINTER**)value = (SQLPOINTER) sa->intptr_attr; length = sizeof(SQLPOINTER); break; } if(string_length) { *string_length = length; } } else { memcpy(value, &sa->intptr_attr, buffer_length); } return function_return_nodrv( SQL_HANDLE_DBC, connection, rc ); } sa = sa -> next; } } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } switch ( attribute ) { case SQL_ATTR_ACCESS_MODE: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> access_mode; type = 1; } break; case SQL_ATTR_AUTOCOMMIT: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> auto_commit; type = 1; } break; case SQL_ATTR_LOGIN_TIMEOUT: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> login_timeout; type = 1; } break; case SQL_ATTR_ODBC_CURSORS: *((SQLULEN*)value) = connection -> cursors; type = 1; break; case SQL_ATTR_TRACE: *((SQLINTEGER*)value) = connection -> trace; type = 1; break; case SQL_ATTR_TRACEFILE: ptr = connection -> tracefile; type = 2; break; case SQL_ATTR_ASYNC_ENABLE: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLULEN*)value) = connection -> async_enable; type = 1; } break; case SQL_ATTR_AUTO_IPD: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> auto_ipd; type = 1; } break; case SQL_ATTR_CONNECTION_TIMEOUT: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> connection_timeout; type = 1; } break; case SQL_ATTR_METADATA_ID: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> metadata_id; type = 1; } break; case SQL_ATTR_PACKET_SIZE: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> packet_size; type = 1; } break; case SQL_ATTR_QUIET_MODE: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> quite_mode; type = 1; } break; case SQL_ATTR_TXN_ISOLATION: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> txn_isolation; type = 1; } break; default: break; } /* * if type has been set we have already set the value, * so just return */ if ( type ) { SQLRETURN ret = SQL_SUCCESS; if ( type == 1 ) { if ( string_length ) { *string_length = sizeof( SQLUINTEGER ); } } else { if ( string_length ) { *string_length = strlen( ptr ); } if ( value ) { if ( buffer_length > strlen( ptr ) + 1 ) { strcpy( value, ptr ); } else { memcpy( value, ptr, buffer_length - 1 ); ((char*)value)[ buffer_length - 1 ] = '\0'; ret = SQL_SUCCESS_WITH_INFO; } } } sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); return function_return_nodrv( SQL_HANDLE_DBC, connection, ret ); } else { SQLRETURN ret = 0; /* * call the driver */ if ( connection -> unicode_driver || CHECK_SQLGETCONNECTATTRW( connection ) || CHECK_SQLGETCONNECTOPTIONW( connection )) { if ( !CHECK_SQLGETCONNECTATTRW( connection )) { if ( CHECK_SQLGETCONNECTOPTIONW( connection )) { /* * Is it in the legal range of values */ if ( attribute < SQL_CONN_DRIVER_MIN && ( attribute > SQL_PACKET_SIZE || attribute < SQL_ACCESS_MODE )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } ret = SQLGETCONNECTOPTIONW( connection, connection -> driver_dbc, attribute, value ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { ret = SQLGETCONNECTATTRW( connection, connection -> driver_dbc, attribute, value, buffer_length, string_length ); } } else { if ( !CHECK_SQLGETCONNECTATTR( connection )) { if (( ret = CHECK_SQLGETCONNECTOPTION( connection ))) { SQLCHAR *as1 = NULL; /* * Is it in the legal range of values */ if ( attribute < SQL_CONN_DRIVER_MIN && ( attribute > SQL_PACKET_SIZE || attribute < SQL_ACCESS_MODE )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } switch( attribute ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( SQL_SUCCEEDED( ret ) && value && buffer_length > 0 ) { as1 = malloc( buffer_length + 1 ); } break; } ret = SQLGETCONNECTOPTION( connection, connection -> driver_dbc, attribute, as1 ? as1 : value ); switch( attribute ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( SQL_SUCCEEDED( ret ) && value && buffer_length > 0 && as1 ) { ansi_to_unicode_copy( value, (char*) as1, SQL_NTS, connection, NULL ); } if ( as1 ) { free( as1 ); } if ( SQL_SUCCEEDED( ret ) && string_length ) { *string_length *= sizeof( SQLWCHAR ); } break; } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { SQLCHAR *as1 = NULL; switch( attribute ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: buffer_length = buffer_length / 2; if ( buffer_length > 0 ) { as1 = malloc( buffer_length + 1 ); } break; } ret = SQLGETCONNECTATTR( connection, connection -> driver_dbc, attribute, as1 ? as1 : value, buffer_length, string_length ); switch( attribute ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( SQL_SUCCEEDED( ret ) && value && buffer_length > 0 && as1 ) { ansi_to_unicode_copy( value, (char*)as1, SQL_NTS, connection, NULL ); } if ( as1 ) { free( as1 ); } if ( SQL_SUCCEEDED( ret ) && string_length ) { *string_length *= sizeof( SQLWCHAR ); } break; } } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 ); } } unixODBC-2.3.12/DriverManager/SQLGetConnectOption.c000066400000000000000000000337621446441710500217270ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetConnectOption.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetConnectOption.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.7 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.6 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/11/11 17:10:10 lurcher * * VMS changes * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.5 2001/08/03 15:19:00 nick * * Add changes to set values before connect * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.6 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.5 1999/09/19 22:24:34 ngorham * * Added support for the cursor library * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:20 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetConnectOption.c,v $ $Revision: 1.9 $"; SQLRETURN SQLGetConnectOptionA( SQLHDBC connection_handle, SQLUSMALLINT option, SQLPOINTER value ) { return SQLGetConnectOption( connection_handle, option, value ); } SQLRETURN SQLGetConnectOption( SQLHDBC connection_handle, SQLUSMALLINT option, SQLPOINTER value ) { DMHDBC connection = (DMHDBC)connection_handle; int type = 0; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * doesn't require a handle */ if ( option == SQL_ATTR_TRACE ) { if ( value ) { *((SQLINTEGER*)value) = SQL_OPT_TRACE_ON; } return SQL_SUCCESS; } else if ( option == SQL_ATTR_TRACEFILE ) { SQLRETURN ret = SQL_SUCCESS; if ( log_info.log_file_name ) { strcpy( value, log_info.log_file_name ); } else { strcpy( value, "" ); } return ret; } /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tOption = %s\ \n\t\t\tValue = %p", connection, __con_attr_as_string( s1, option ), value ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( connection -> state == STATE_C2 ) { switch ( option ) { case SQL_ACCESS_MODE: case SQL_AUTOCOMMIT: case SQL_LOGIN_TIMEOUT: case SQL_ODBC_CURSORS: break; default: dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } switch ( option ) { case SQL_ACCESS_MODE: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> access_mode; type = 1; } break; case SQL_AUTOCOMMIT: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> auto_commit; type = 1; } break; case SQL_ODBC_CURSORS: *((SQLINTEGER*)value) = connection -> cursors; type = 1; break; case SQL_ATTR_LOGIN_TIMEOUT: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> login_timeout; type = 1; } break; default: break; } /* * if type has been set we have already set the value, * so just return */ if ( type ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_SUCCESS ); } else { SQLRETURN ret = 0; /* * call the driver */ if ( connection -> unicode_driver ) { SQLWCHAR *s1 = NULL; if (( ret = CHECK_SQLGETCONNECTOPTIONW( connection ))) { switch( option ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( SQL_SUCCEEDED( ret ) && value ) { /* * guess a length */ if ( value ) { s1 = malloc( sizeof( SQLWCHAR ) * 1024 ); } } break; } ret = SQLGETCONNECTOPTIONW( connection, connection -> driver_dbc, option, s1 ? s1 : value ); switch( option ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( SQL_SUCCEEDED( ret ) && value && s1 ) { unicode_to_ansi_copy( value, 1024, s1, SQL_NTS, connection, NULL ); } break; } if ( s1 ) { free( s1 ); } } else if ( CHECK_SQLGETCONNECTATTRW( connection )) { SQLINTEGER length, len; void * ptr; SQLWCHAR txt[ 1024 ]; switch( option ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: length = sizeof( txt ); ptr = txt; break; default: length = sizeof( SQLINTEGER ); ptr = value; break; } ret = SQLGETCONNECTATTRW( connection, connection -> driver_dbc, option, ptr, length, &len ); /* * not much else we can do here, lets assume that * there is enough space */ if ( ptr != value && SQL_SUCCEEDED( ret )) { unicode_to_ansi_copy( value, 1024, ptr, SQL_NTS, connection, NULL ); /* * are we still here ? good */ } } else { __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { if ( CHECK_SQLGETCONNECTOPTION( connection )) { ret = SQLGETCONNECTOPTION( connection, connection -> driver_dbc, option, value ); } else if ( CHECK_SQLGETCONNECTATTR( connection )) { SQLINTEGER length, len; void * ptr; char txt[ 1024 ]; switch( option ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: length = sizeof( txt ); ptr = txt; break; default: length = sizeof( SQLINTEGER ); ptr = value; break; } ret = SQLGETCONNECTATTR( connection, connection -> driver_dbc, option, ptr, length, &len ); /* * not much else we can do here, lets assume that * there is enough space */ if ( ptr != value ) { strcpy( value, ptr ); /* * are we still here ? good */ } } else { __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 ); } } unixODBC-2.3.12/DriverManager/SQLGetConnectOptionW.c000066400000000000000000000332071446441710500220500ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetConnectOptionW.c,v 1.10 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetConnectOptionW.c,v $ * Revision 1.10 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.9 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.8 2008/08/29 08:01:38 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/11/11 17:10:12 lurcher * * VMS changes * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/08/03 15:19:00 nick * * Add changes to set values before connect * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetConnectOptionW.c,v $"; SQLRETURN SQLGetConnectOptionW( SQLHDBC connection_handle, SQLUSMALLINT option, SQLPOINTER value ) { DMHDBC connection = (DMHDBC)connection_handle; int type = 0; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * doesn't require a handle */ if ( option == SQL_ATTR_TRACE ) { if ( value ) { *((SQLINTEGER*)value) = SQL_OPT_TRACE_ON; } return SQL_SUCCESS; } else if ( option == SQL_ATTR_TRACEFILE ) { SQLRETURN ret = SQL_SUCCESS; if ( log_info.log_file_name ) { ansi_to_unicode_copy( value, log_info.log_file_name, SQL_NTS, connection, NULL ); } else { ansi_to_unicode_copy( value, "", SQL_NTS, connection, NULL ); } return ret; } /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHDBC parent_connection; parent_connection = find_parent_handle( connection, SQL_HANDLE_DBC ); if ( parent_connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLGETCONNECTOPTIONW( parent_connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLGETCONNECTOPTIONW( parent_connection, connection, option, value ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tOption = %s\ \n\t\t\tValue = %p", connection, __con_attr_as_string( s1, option ), value ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( connection -> state == STATE_C2 ) { switch ( option ) { case SQL_ACCESS_MODE: case SQL_AUTOCOMMIT: case SQL_LOGIN_TIMEOUT: case SQL_ODBC_CURSORS: break; default: dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } switch ( option ) { case SQL_ACCESS_MODE: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> access_mode; type = 1; } break; case SQL_AUTOCOMMIT: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> auto_commit; type = 1; } break; case SQL_ODBC_CURSORS: *((SQLINTEGER*)value) = connection -> cursors; type = 1; break; case SQL_ATTR_LOGIN_TIMEOUT: /* * if connected, call the driver */ if ( connection -> state != STATE_C2 ) { type = 0; } else { *((SQLINTEGER*)value) = connection -> login_timeout; type = 1; } break; default: break; } /* * if type has been set we have already set the value, * so just return */ if ( type ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_SUCCESS ); } else { SQLRETURN ret = 0; /* * call the driver */ if ( connection -> unicode_driver || CHECK_SQLGETCONNECTOPTIONW( connection ) || CHECK_SQLGETCONNECTATTRW( connection )) { if ( CHECK_SQLGETCONNECTOPTIONW( connection )) { ret = SQLGETCONNECTOPTIONW( connection, connection -> driver_dbc, option, value ); } else if ( CHECK_SQLGETCONNECTATTRW( connection )) { SQLINTEGER length, len; void * ptr; SQLWCHAR txt[ 1024 ]; switch( option ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: length = sizeof( txt ); ptr = txt; break; default: length = sizeof( SQLINTEGER ); ptr = value; break; } ret = SQLGETCONNECTATTRW( connection, connection -> driver_dbc, option, ptr, length, &len ); /* * not much else we can do here, lets assume that * there is enough space */ if ( ptr != value ) { wide_strcpy( value, ptr ); /* * are we still here ? good */ } } else { __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { if (( ret = CHECK_SQLGETCONNECTOPTION( connection ))) { SQLCHAR *as1 = NULL; switch( option ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( SQL_SUCCEEDED( ret ) && value ) { /* * we need to chance out arm here, as we dont know */ as1 = malloc( 1024 ); } break; } ret = SQLGETCONNECTOPTION( connection, connection -> driver_dbc, option, as1 ? as1 : value ); switch( option ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( SQL_SUCCEEDED( ret ) && value && as1 ) { ansi_to_unicode_copy( value, (char*) as1, SQL_NTS, connection, NULL ); } if ( as1 ) { free( as1 ); } break; } } else if ( CHECK_SQLGETCONNECTATTR( connection )) { SQLINTEGER length, len; void * ptr; char txt[ 1024 ]; switch( option ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: length = sizeof( txt ); ptr = txt; break; default: length = sizeof( SQLINTEGER ); ptr = value; break; } ret = SQLGETCONNECTATTR( connection, connection -> driver_dbc, option, ptr, length, &len ); /* * not much else we can do here, lets assume that * there is enough space */ if ( ptr != value ) { SQLWCHAR *s1; s1 = ansi_to_unicode_alloc( value, SQL_NTS, connection, NULL ); if ( s1 ) { wide_strcpy( value, s1 ); free( s1 ); } /* * are we still here ? good */ } } else { __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 ); } } unixODBC-2.3.12/DriverManager/SQLGetCursorName.c000066400000000000000000000216671446441710500212240ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetCursorName.c,v 1.8 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetCursorName.c,v $ * Revision 1.8 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.7 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.6 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.5 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.4 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.3 2001/01/04 13:16:25 nick * * Add support for GNU portable threads and tidy up some UNICODE compile * warnings * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetCursorName.c,v $ $Revision: 1.8 $"; SQLRETURN SQLGetCursorNameA( SQLHSTMT statement_handle, SQLCHAR *cursor_name, SQLSMALLINT buffer_length, SQLSMALLINT *name_length ) { return SQLGetCursorName( statement_handle, cursor_name, buffer_length, name_length ); } SQLRETURN SQLGetCursorName( SQLHSTMT statement_handle, SQLCHAR *cursor_name, SQLSMALLINT buffer_length, SQLSMALLINT *name_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCursor Name = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tName Length= %p", statement, cursor_name, buffer_length, name_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( buffer_length < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1 = NULL; if ( !CHECK_SQLGETCURSORNAMEW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( cursor_name && buffer_length > 0 ) { s1 = malloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 )); } ret = SQLGETCURSORNAMEW( statement -> connection, statement -> driver_stmt, s1 ? s1 : (SQLWCHAR*) cursor_name, buffer_length, name_length ); if ( SQL_SUCCEEDED( ret ) && cursor_name && s1 ) { unicode_to_ansi_copy((char*) cursor_name, buffer_length, s1, SQL_NTS, statement -> connection, NULL ); } if ( s1 ) { free( s1 ); } } else { if ( !CHECK_SQLGETCURSORNAME( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLGETCURSORNAME( statement -> connection, statement -> driver_stmt, cursor_name, buffer_length, name_length ); } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]\ \n\t\t\tCursor Name = %s", __get_return_status( ret, s1 ), __sdata_as_string( s1, SQL_CHAR, name_length, cursor_name )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLGetCursorNameW.c000066400000000000000000000214121446441710500213370ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetCursorNameW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetCursorNameW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.3 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/01/04 13:16:25 nick * * Add support for GNU portable threads and tidy up some UNICODE compile * warnings * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetCursorNameW.c,v $"; SQLRETURN SQLGetCursorNameW( SQLHSTMT statement_handle, SQLWCHAR *cursor_name, SQLSMALLINT buffer_length, SQLSMALLINT *name_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLGETCURSORNAMEW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLGETCURSORNAMEW( parent_statement -> connection, statement_handle, cursor_name, buffer_length, name_length ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCursor Name = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tName Length= %p", statement, cursor_name, buffer_length, name_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( buffer_length < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> connection -> unicode_driver || CHECK_SQLGETCURSORNAMEW( statement -> connection )) { if ( !CHECK_SQLGETCURSORNAMEW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLGETCURSORNAMEW( statement -> connection, statement -> driver_stmt, cursor_name, buffer_length, name_length ); } else { SQLCHAR *as1 = NULL; if ( !CHECK_SQLGETCURSORNAME( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( cursor_name && buffer_length > 0 ) { as1 = malloc( buffer_length + 1 ); } ret = SQLGETCURSORNAME( statement -> connection, statement -> driver_stmt, as1 ? as1 : (SQLCHAR*) cursor_name, buffer_length, name_length ); if ( SQL_SUCCEEDED( ret ) && cursor_name && as1 ) { ansi_to_unicode_copy( cursor_name, (char*) as1, SQL_NTS, statement -> connection, NULL ); } if ( as1 ) { free( as1 ); } } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]\ \n\t\t\tCursor Name = %s", __get_return_status( ret, s1 ), __sdata_as_string( s1, SQL_WCHAR, name_length, cursor_name )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLGetData.c000066400000000000000000000376241446441710500200170ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetData.c,v 1.15 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetData.c,v $ * Revision 1.15 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.14 2007/04/02 10:50:19 lurcher * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 ) * * Revision 1.13 2006/04/11 10:22:56 lurcher * Fix a data type check * * Revision 1.12 2006/03/08 11:22:13 lurcher * Add check for valid C_TYPE * * Revision 1.11 2004/02/02 10:10:45 lurcher * * Fix some connection pooling problems * Include sqlucode in sqlext * * Revision 1.10 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.9 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.8 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.7 2002/08/19 09:11:49 lurcher * * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state * * Revision 1.6 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.5 2002/07/10 15:05:57 lurcher * * Alter the return code in the Postgres driver, for a warning, it should be * 01000 it was 00000 * Fix a problem in DriverManagerII with the postgres driver as the driver * doesn't return a propper list of schemas * Allow the delimiter to be set in isql to a hex/octal char not just a * printable one * * Revision 1.4 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.3 2001/12/04 10:16:59 lurcher * * Fix SQLSetScrollOption problem * * Revision 1.2 2001/11/22 14:27:02 lurcher * * Add UNICODE conversion fix * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.5 2001/09/27 17:05:48 nick * * Assorted fixes and tweeks * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/01/01 11:04:13 nick * * Add UNICODE conversion to SQLGetData * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.10 2000/06/20 13:30:09 ngorham * * Fix problems when using bookmarks * * Revision 1.9 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.8 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.7 1999/10/09 00:56:16 ngorham * * Added Manush's patch to map ODBC 3-2 datetime values * * Revision 1.6 1999/10/09 00:15:58 ngorham * * Add mapping from SQL_TYPE_X to SQL_X and SQL_C_TYPE_X to SQL_C_X * when the driver is a ODBC 2 one * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.4 1999/05/03 19:50:43 nick * Another check point * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetData.c,v $ $Revision: 1.15 $"; SQLRETURN SQLGetData( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLSMALLINT target_type, SQLPOINTER target_value, SQLLEN buffer_length, SQLLEN *strlen_or_ind ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ]; int unicode_switch = 0; SQLLEN ind_value; SQLCHAR *as1 = NULL; SQLCHAR s3[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tColumn Number = %d\ \n\t\t\tTarget Type = %d %s\ \n\t\t\tBuffer Length = %d\ \n\t\t\tTarget Value = %p\ \n\t\t\tStrLen Or Ind = %p", statement, column_number, target_type, __sql_as_text( target_type ), (int)buffer_length, target_value, (void*)strlen_or_ind ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( column_number == 0 && statement -> bookmarks_on == SQL_UB_OFF && statement -> connection -> bookmarks_on == SQL_UB_OFF ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error_api( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version, SQL_API_SQLGETDATA ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * can't trust the numcols value * if ( statement -> numcols < column_number ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR ); } */ /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S2 || statement -> state == STATE_S3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S4 || statement -> state == STATE_S5 || (( statement -> state == STATE_S6 || statement -> state == STATE_S7 ) && statement -> eod )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLGETDATA ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( target_value == NULL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( buffer_length < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * TO_DO assorted checks need adding here, relating to bound columns * and what sort of SQLGetData extensions the driver supports */ /* * check valid C_TYPE */ if ( !check_target_type( target_type, statement -> connection -> environment -> requested_version )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY003" ); __post_internal_error( &statement -> error, ERROR_HY003, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( !CHECK_SQLGETDATA( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if (statement -> connection -> driver_act_ver==SQL_OV_ODBC2) { switch( target_type ) { case SQL_WCHAR: target_type = SQL_CHAR; unicode_switch = 1; buffer_length = buffer_length / sizeof( SQLWCHAR ); break; case SQL_WVARCHAR: target_type = SQL_VARCHAR; unicode_switch = 1; buffer_length = buffer_length / sizeof( SQLWCHAR ); break; case SQL_WLONGVARCHAR: target_type = SQL_LONGVARCHAR; unicode_switch = 1; buffer_length = buffer_length / sizeof( SQLWCHAR ); break; } } if ( unicode_switch ) { if ( buffer_length > 0 && target_value ) { as1 = malloc( buffer_length + 1 ); ret = SQLGETDATA( statement -> connection, statement -> driver_stmt, column_number, __map_type(MAP_C_DM2D,statement->connection,target_type), as1, buffer_length, &ind_value ); } else { ret = SQLGETDATA( statement -> connection, statement -> driver_stmt, column_number, __map_type(MAP_C_DM2D,statement->connection,target_type), target_value, buffer_length, &ind_value ); } } else { ret = SQLGETDATA( statement -> connection, statement -> driver_stmt, column_number, __map_type(MAP_C_DM2D,statement->connection,target_type), target_value, buffer_length, strlen_or_ind ); } if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLGETDATA; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) { statement -> interupted_state = statement -> state; statement -> state = STATE_S11; } } else if ( SQL_SUCCEEDED( ret ) && unicode_switch ) { if ( target_value && ind_value >= 0 && as1 ) { if ( ind_value > buffer_length ) { ansi_to_unicode_copy( target_value, (char*) as1, buffer_length, statement -> connection, NULL ); } else { ansi_to_unicode_copy( target_value, (char*) as1, ind_value + 1, statement -> connection, NULL ); } } if ( as1 ) { free( as1 ); } if ( ind_value > 0 ) { ind_value *= sizeof( SQLWCHAR ); } if ( strlen_or_ind ) { *strlen_or_ind = ind_value; } } if ( ret != SQL_STILL_EXECUTING && (statement -> state == STATE_S11 || statement -> state == STATE_S12) ) { statement -> state = statement -> interupted_state; } if ( statement -> state == STATE_S14 ) { statement -> state = STATE_S15; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]\ \n\t\t\tBuffer = %s\ \n\t\t\tStrlen Or Ind = %s", __get_return_status( ret, s3 ), __data_as_string( s1, target_type, strlen_or_ind, target_value ), __ptr_as_string( s2, strlen_or_ind )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLGetDescField.c000066400000000000000000000316051446441710500207610ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetDescField.c,v 1.10 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetDescField.c,v $ * Revision 1.10 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.9 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.8 2006/03/08 09:18:41 lurcher * fix silly typo that was using sizeof( SQL_WCHAR ) instead of SQLWCHAR * * Revision 1.7 2004/11/22 17:02:49 lurcher * Fix unicode/ansi conversion in the SQLGet functions * * Revision 1.6 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.2 2002/01/21 18:00:51 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.5 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.4 2001/04/17 16:29:39 nick * * More checks and autotest fixes * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.3 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetDescField.c,v $ $Revision: 1.10 $"; SQLRETURN SQLGetDescFieldA( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT field_identifier, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { return SQLGetDescField( descriptor_handle, rec_number, field_identifier, value, buffer_length, string_length ); } SQLRETURN SQLGetDescField( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT field_identifier, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { /* * not quite sure how the descriptor can be * allocated to a statement, all the documentation talks * about state transitions on statement states, but the * descriptor may be allocated with more than one statement * at one time. Which one should I check ? */ DMHDESC descriptor = (DMHDESC) descriptor_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; int isStrField = 0; /* * check descriptor */ if ( !__validate_desc( descriptor )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( descriptor ); if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tEntry:\ \n\t\t\tDescriptor = %p\ \n\t\t\tRec Number = %d\ \n\t\t\tField Attr = %s\ \n\t\t\tValue = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tStrLen = %p", descriptor, rec_number, __desc_attr_as_string( s1, field_identifier ), value, (int)buffer_length, (void*)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } thread_protect( SQL_HANDLE_DESC, descriptor ); if ( descriptor -> connection -> state < STATE_C4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } /* * check status of statements associated with this descriptor */ if( __check_stmt_from_desc( descriptor, STATE_S8 ) || __check_stmt_from_desc( descriptor, STATE_S9 ) || __check_stmt_from_desc( descriptor, STATE_S10 ) || __check_stmt_from_desc( descriptor, STATE_S11 ) || __check_stmt_from_desc( descriptor, STATE_S12 ) || __check_stmt_from_desc( descriptor, STATE_S13 ) || __check_stmt_from_desc( descriptor, STATE_S14 ) || __check_stmt_from_desc( descriptor, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if( __check_stmt_from_desc_ird( descriptor, STATE_S1 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY007" ); __post_internal_error( &descriptor -> error, ERROR_HY007, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( rec_number < 0 ) { __post_internal_error( &descriptor -> error, ERROR_07009, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } switch ( field_identifier ) { /* Fixed-length fields: buffer_length is ignored */ case SQL_DESC_ALLOC_TYPE: case SQL_DESC_ARRAY_SIZE: case SQL_DESC_ARRAY_STATUS_PTR: case SQL_DESC_BIND_OFFSET_PTR: case SQL_DESC_BIND_TYPE: case SQL_DESC_COUNT: case SQL_DESC_ROWS_PROCESSED_PTR: case SQL_DESC_AUTO_UNIQUE_VALUE: case SQL_DESC_CASE_SENSITIVE: case SQL_DESC_CONCISE_TYPE: case SQL_DESC_DATA_PTR: case SQL_DESC_DATETIME_INTERVAL_CODE: case SQL_DESC_DATETIME_INTERVAL_PRECISION: case SQL_DESC_DISPLAY_SIZE: case SQL_DESC_FIXED_PREC_SCALE: case SQL_DESC_INDICATOR_PTR: case SQL_DESC_LENGTH: case SQL_DESC_NULLABLE: case SQL_DESC_NUM_PREC_RADIX: case SQL_DESC_OCTET_LENGTH: case SQL_DESC_OCTET_LENGTH_PTR: case SQL_DESC_PARAMETER_TYPE: case SQL_DESC_PRECISION: case SQL_DESC_ROWVER: case SQL_DESC_SCALE: case SQL_DESC_SEARCHABLE: case SQL_DESC_TYPE: case SQL_DESC_UNNAMED: case SQL_DESC_UNSIGNED: case SQL_DESC_UPDATABLE: isStrField = 0; break; /* Pointer to data: buffer_length must be valid */ case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_CATALOG_NAME: case SQL_DESC_LABEL: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: isStrField = 1; break; default: isStrField = buffer_length != SQL_IS_POINTER && buffer_length != SQL_IS_INTEGER && buffer_length != SQL_IS_UINTEGER && buffer_length != SQL_IS_SMALLINT && buffer_length != SQL_IS_USMALLINT; } if ( isStrField && buffer_length < 0 ) { __post_internal_error( &descriptor -> error, ERROR_HY090, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( descriptor -> connection -> unicode_driver ) { SQLWCHAR *s1 = NULL; if ( !CHECK_SQLGETDESCFIELDW( descriptor -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( isStrField && buffer_length > 0 && value ) { s1 = malloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 )); } ret = SQLGETDESCFIELDW( descriptor -> connection, descriptor -> driver_desc, rec_number, field_identifier, s1 ? s1 : value, s1 ? (sizeof ( SQLWCHAR ) * (buffer_length + 1)) : buffer_length, string_length ); if ( isStrField && SQL_SUCCEEDED( ret ) ) { if ( value && s1 ) { unicode_to_ansi_copy( value, buffer_length, s1, SQL_NTS, descriptor -> connection, NULL ); if ( string_length ) { *string_length /= sizeof( SQLWCHAR ); } } } if ( s1 ) { free( s1 ); } } else { if ( !CHECK_SQLGETDESCFIELD( descriptor -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } ret = SQLGETDESCFIELD( descriptor -> connection, descriptor -> driver_desc, rec_number, field_identifier, value, buffer_length, string_length ); } if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } return function_return( SQL_HANDLE_DESC, descriptor, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLGetDescFieldW.c000066400000000000000000000301261446441710500211050ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetDescFieldW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetDescFieldW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2004/11/22 17:02:49 lurcher * Fix unicode/ansi conversion in the SQLGet functions * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/17 16:29:39 nick * * More checks and autotest fixes * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetDescFieldW.c,v $"; SQLRETURN SQLGetDescFieldW( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT field_identifier, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { /* * not quite sure how the descriptor can be * allocated to a statement, all the documentation talks * about state transitions on statement states, but the * descriptor may be allocated with more than one statement * at one time. Which one should I check ? */ DMHDESC descriptor = (DMHDESC) descriptor_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; int isStrField = 0; /* * check descriptor */ if ( !__validate_desc( descriptor )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHDESC parent_desc; parent_desc = find_parent_handle( descriptor, SQL_HANDLE_DESC ); if ( parent_desc ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLGETDESCFIELDW( parent_desc -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLGETDESCFIELDW( parent_desc -> connection, descriptor, rec_number, field_identifier, value, buffer_length, string_length ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( descriptor ); if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tEntry:\ \n\t\t\tDescriptor = %p\ \n\t\t\tRec Number = %d\ \n\t\t\tField Attr = %s\ \n\t\t\tValue = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tStrLen = %p", descriptor, rec_number, __desc_attr_as_string( s1, field_identifier ), value, (int)buffer_length, (void*)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } thread_protect( SQL_HANDLE_DESC, descriptor ); if ( descriptor -> connection -> state < STATE_C4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } /* * check status of statements associated with this descriptor */ if( __check_stmt_from_desc( descriptor, STATE_S8 ) || __check_stmt_from_desc( descriptor, STATE_S9 ) || __check_stmt_from_desc( descriptor, STATE_S10 ) || __check_stmt_from_desc( descriptor, STATE_S11 ) || __check_stmt_from_desc( descriptor, STATE_S12 ) || __check_stmt_from_desc( descriptor, STATE_S13 ) || __check_stmt_from_desc( descriptor, STATE_S14 ) || __check_stmt_from_desc( descriptor, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if( __check_stmt_from_desc_ird( descriptor, STATE_S1 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY007" ); __post_internal_error( &descriptor -> error, ERROR_HY007, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( rec_number < 0 ) { __post_internal_error( &descriptor -> error, ERROR_07009, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } switch ( field_identifier ) { /* Fixed-length fields: buffer_length is ignored */ case SQL_DESC_ALLOC_TYPE: case SQL_DESC_ARRAY_SIZE: case SQL_DESC_ARRAY_STATUS_PTR: case SQL_DESC_BIND_OFFSET_PTR: case SQL_DESC_BIND_TYPE: case SQL_DESC_COUNT: case SQL_DESC_ROWS_PROCESSED_PTR: case SQL_DESC_AUTO_UNIQUE_VALUE: case SQL_DESC_CASE_SENSITIVE: case SQL_DESC_CONCISE_TYPE: case SQL_DESC_DATA_PTR: case SQL_DESC_DATETIME_INTERVAL_CODE: case SQL_DESC_DATETIME_INTERVAL_PRECISION: case SQL_DESC_DISPLAY_SIZE: case SQL_DESC_FIXED_PREC_SCALE: case SQL_DESC_INDICATOR_PTR: case SQL_DESC_LENGTH: case SQL_DESC_NULLABLE: case SQL_DESC_NUM_PREC_RADIX: case SQL_DESC_OCTET_LENGTH: case SQL_DESC_OCTET_LENGTH_PTR: case SQL_DESC_PARAMETER_TYPE: case SQL_DESC_PRECISION: case SQL_DESC_ROWVER: case SQL_DESC_SCALE: case SQL_DESC_SEARCHABLE: case SQL_DESC_TYPE: case SQL_DESC_UNNAMED: case SQL_DESC_UNSIGNED: case SQL_DESC_UPDATABLE: isStrField = 0; break; /* Pointer to data: buffer_length must be valid */ case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_CATALOG_NAME: case SQL_DESC_LABEL: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: isStrField = 1; break; default: isStrField = buffer_length != SQL_IS_POINTER && buffer_length != SQL_IS_INTEGER && buffer_length != SQL_IS_UINTEGER && buffer_length != SQL_IS_SMALLINT && buffer_length != SQL_IS_USMALLINT; } if ( isStrField && buffer_length < 0 ) { __post_internal_error( &descriptor -> error, ERROR_HY090, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( descriptor -> connection -> unicode_driver || CHECK_SQLGETDESCFIELDW( descriptor -> connection )) { if ( !CHECK_SQLGETDESCFIELDW( descriptor -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } ret = SQLGETDESCFIELDW( descriptor -> connection, descriptor -> driver_desc, rec_number, field_identifier, value, buffer_length, string_length ); } else { SQLCHAR *as1 = NULL; if ( !CHECK_SQLGETDESCFIELD( descriptor -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( isStrField && buffer_length > 0 && value ) { as1 = malloc( buffer_length + 1 ); } ret = SQLGETDESCFIELD( descriptor -> connection, descriptor -> driver_desc, rec_number, field_identifier, as1 ? as1 : value, buffer_length, string_length ); if ( isStrField && SQL_SUCCEEDED( ret ) && value ) { if ( as1 && buffer_length > 0) { ansi_to_unicode_copy( value, (char*) as1, SQL_NTS, descriptor -> connection, NULL ); } } if ( as1 ) { free( as1 ); } } if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } return function_return( SQL_HANDLE_DESC, descriptor, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLGetDescRec.c000066400000000000000000000311621446441710500204450ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetDescRec.c,v 1.13 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetDescRec.c,v $ * Revision 1.13 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.12 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.11 2007/04/02 10:50:19 lurcher * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 ) * * Revision 1.10 2007/03/05 09:49:23 lurcher * Get it to build on VMS again * * Revision 1.9 2006/01/06 18:44:35 lurcher * Couple of unicode fixes * * Revision 1.8 2004/11/22 17:02:49 lurcher * Fix unicode/ansi conversion in the SQLGet functions * * Revision 1.7 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.6 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.5 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.3 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.5 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.4 2001/04/17 16:29:39 nick * * More checks and autotest fixes * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 2001/04/27 01:29:35 ngorham * * Added a couple of fixes from Tim Roepken * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.3 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetDescRec.c,v $ $Revision: 1.13 $"; SQLRETURN SQLGetDescRecA( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLCHAR *name, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLSMALLINT *type, SQLSMALLINT *sub_type, SQLLEN *length, SQLSMALLINT *precision, SQLSMALLINT *scale, SQLSMALLINT *nullable ) { return SQLGetDescRec( descriptor_handle, rec_number, name, buffer_length, string_length, type, sub_type, length, precision, scale, nullable ); } SQLRETURN SQLGetDescRec( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLCHAR *name, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLSMALLINT *type, SQLSMALLINT *sub_type, SQLLEN *length, SQLSMALLINT *precision, SQLSMALLINT *scale, SQLSMALLINT *nullable ) { /* * not quite sure how the descriptor can be * allocated to a statement, all the documentation talks * about state transitions on statement states, but the * descriptor may be allocated with more than one statement * at one time. Which one should I check ? */ DMHDESC descriptor = (DMHDESC) descriptor_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s5[ 100 + LOG_MESSAGE_LEN ], s6[ 100 + LOG_MESSAGE_LEN ], s7[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s8[ 100 + LOG_MESSAGE_LEN ]; /* * check descriptor */ if ( !__validate_desc( descriptor )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( descriptor ); if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tEntry:\ \n\t\t\tDescriptor = %p\ \n\t\t\tRec Number = %d\ \n\t\t\tName = %p\ \n\t\t\tBuffer length = %d\ \n\t\t\tString Length = %p\ \n\t\t\tType = %p\ \n\t\t\tSub Type = %p\ \n\t\t\tLength = %p\ \n\t\t\tPrecision = %p\ \n\t\t\tScale = %p\ \n\t\t\tNullable = %p", descriptor, rec_number, name, buffer_length, string_length, type, sub_type, length, precision, scale, nullable ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } thread_protect( SQL_HANDLE_DESC, descriptor ); if ( descriptor -> connection -> state < STATE_C4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } /* * check status of statements associated with this descriptor */ if( __check_stmt_from_desc( descriptor, STATE_S8 ) || __check_stmt_from_desc( descriptor, STATE_S9 ) || __check_stmt_from_desc( descriptor, STATE_S10 ) || __check_stmt_from_desc( descriptor, STATE_S11 ) || __check_stmt_from_desc( descriptor, STATE_S12 ) || __check_stmt_from_desc( descriptor, STATE_S13 ) || __check_stmt_from_desc( descriptor, STATE_S14 ) || __check_stmt_from_desc( descriptor, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if( __check_stmt_from_desc_ird( descriptor, STATE_S1 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY007" ); __post_internal_error( &descriptor -> error, ERROR_HY007, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( descriptor -> connection -> unicode_driver ) { SQLWCHAR *s1 = NULL; if ( !CHECK_SQLGETDESCRECW( descriptor -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( name && buffer_length > 0 ) { s1 = malloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 )); } ret = SQLGETDESCRECW( descriptor -> connection, descriptor -> driver_desc, rec_number, s1 ? s1 : (SQLWCHAR*) name, buffer_length, string_length, type, sub_type, length, precision, scale, nullable ); if ( SQL_SUCCEEDED( ret ) && name && s1 ) { unicode_to_ansi_copy((char*) name, buffer_length, s1, SQL_NTS, descriptor -> connection, NULL ); } if ( s1 ) { free( s1 ); } if ( SQL_SUCCEEDED( ret ) && string_length && name ) { *string_length = strlen((char*)name); } } else { if ( !CHECK_SQLGETDESCREC( descriptor -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } ret = SQLGETDESCREC( descriptor -> connection, descriptor -> driver_desc, rec_number, name, buffer_length, string_length, type, sub_type, length, precision, scale, nullable ); } if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tExit:[%s]\ \n\t\t\tName = %s\ \n\t\t\tType = %s\ \n\t\t\tSub Type = %s\ \n\t\t\tLength = %s\ \n\t\t\tPrecision = %s\ \n\t\t\tScale = %s\ \n\t\t\tNullable = %s", __get_return_status( ret, s8 ), __sdata_as_string( s1, SQL_CHAR, string_length, name ), __sptr_as_string( s2, type ), __sptr_as_string( s3, sub_type ), __ptr_as_string( s4, length ), __sptr_as_string( s5, precision ), __sptr_as_string( s6, scale ), __sptr_as_string( s7, nullable )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } return function_return( SQL_HANDLE_DESC, descriptor, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLGetDescRecW.c000066400000000000000000000261321446441710500205750ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetDescRecW.c,v 1.11 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetDescRecW.c,v $ * Revision 1.11 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.10 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.9 2007/04/02 10:50:19 lurcher * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 ) * * Revision 1.8 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.7 2004/11/22 17:02:49 lurcher * Fix unicode/ansi conversion in the SQLGet functions * * Revision 1.6 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.3 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/01/04 13:16:25 nick * * Add support for GNU portable threads and tidy up some UNICODE compile * warnings * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetDescRecW.c,v $"; SQLRETURN SQLGetDescRecW( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLWCHAR *name, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLSMALLINT *type, SQLSMALLINT *sub_type, SQLLEN *length, SQLSMALLINT *precision, SQLSMALLINT *scale, SQLSMALLINT *nullable ) { /* * not quite sure how the descriptor can be * allocated to a statement, all the documentation talks * about state transitions on statement states, but the * descriptor may be allocated with more than one statement * at one time. Which one should I check ? */ DMHDESC descriptor = (DMHDESC) descriptor_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s5[ 100 + LOG_MESSAGE_LEN ], s6[ 100 + LOG_MESSAGE_LEN ], s7[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s8[ 100 + LOG_MESSAGE_LEN ]; /* * check descriptor */ if ( !__validate_desc( descriptor )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHDESC parent_desc; parent_desc = find_parent_handle( descriptor, SQL_HANDLE_DESC ); if ( parent_desc ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLGETDESCRECW( parent_desc -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLGETDESCRECW( parent_desc -> connection, descriptor, rec_number, name, buffer_length, string_length, type, sub_type, length, precision, scale, nullable ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( descriptor ); if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tEntry:\ \n\t\t\tDescriptor = %p\ \n\t\t\tRec Number = %d\ \n\t\t\tName = %p\ \n\t\t\tBuffer length = %d\ \n\t\t\tString Length = %p\ \n\t\t\tType = %p\ \n\t\t\tSub Type = %p\ \n\t\t\tLength = %p\ \n\t\t\tPrecision = %p\ \n\t\t\tScale = %p\ \n\t\t\tNullable = %p", descriptor, rec_number, name, buffer_length, string_length, type, sub_type, length, precision, scale, nullable ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } thread_protect( SQL_HANDLE_DESC, descriptor ); /* * check status of statements associated with this descriptor */ if( __check_stmt_from_desc( descriptor, STATE_S8 ) || __check_stmt_from_desc( descriptor, STATE_S9 ) || __check_stmt_from_desc( descriptor, STATE_S10 ) || __check_stmt_from_desc( descriptor, STATE_S11 ) || __check_stmt_from_desc( descriptor, STATE_S12 ) || __check_stmt_from_desc( descriptor, STATE_S13 ) || __check_stmt_from_desc( descriptor, STATE_S14 ) || __check_stmt_from_desc( descriptor, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if( __check_stmt_from_desc_ird( descriptor, STATE_S1 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY007" ); __post_internal_error( &descriptor -> error, ERROR_HY007, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( descriptor -> connection -> unicode_driver || CHECK_SQLGETDESCRECW( descriptor -> connection )) { if ( !CHECK_SQLGETDESCRECW( descriptor -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } ret = SQLGETDESCRECW( descriptor -> connection, descriptor -> driver_desc, rec_number, name, buffer_length, string_length, type, sub_type, length, precision, scale, nullable ); } else { SQLCHAR *as1 = NULL; if ( !CHECK_SQLGETDESCREC( descriptor -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( name && buffer_length > 0 ) { as1 = malloc( buffer_length + 1 ); } ret = SQLGETDESCREC( descriptor -> connection, descriptor -> driver_desc, rec_number, as1 ? as1 : (SQLCHAR*) name, buffer_length, string_length, type, sub_type, length, precision, scale, nullable ); if ( SQL_SUCCEEDED( ret ) && name && as1 ) { ansi_to_unicode_copy( name, (char*) as1, SQL_NTS, descriptor -> connection, NULL ); } if ( as1 ) { free( as1 ); } if ( SQL_SUCCEEDED( ret ) && string_length ) { *string_length *= sizeof( SQLWCHAR ); } } if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tExit:[%s]\ \n\t\t\tName = %s\ \n\t\t\tType = %s\ \n\t\t\tSub Type = %s\ \n\t\t\tLength = %s\ \n\t\t\tPrecision = %s\ \n\t\t\tScale = %s\ \n\t\t\tNullable = %s", __get_return_status( ret, s8 ), __sdata_as_string( s1, SQL_WCHAR, string_length, name ), __sptr_as_string( s2, type ), __sptr_as_string( s3, sub_type ), __ptr_as_string( s4, length ), __sptr_as_string( s5, precision ), __sptr_as_string( s6, scale ), __sptr_as_string( s7, nullable )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } return function_return( SQL_HANDLE_DESC, descriptor, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLGetDiagField.c000066400000000000000000000712041446441710500207460ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetDiagField.c,v 1.17 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetDiagField.c,v $ * Revision 1.17 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.16 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.15 2009/02/04 09:30:01 lurcher * Fix some SQLINTEGER/SQLLEN conflicts * * Revision 1.14 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.13 2007/03/05 09:49:24 lurcher * Get it to build on VMS again * * Revision 1.12 2006/11/27 14:08:33 lurcher * Sync up dirs * * Revision 1.11 2006/05/31 17:35:34 lurcher * Add unicode ODBCINST entry points * * Revision 1.10 2006/03/08 09:18:41 lurcher * fix silly typo that was using sizeof( SQL_WCHAR ) instead of SQLWCHAR * * Revision 1.9 2005/12/19 18:43:26 lurcher * Add new parts to contrib and alter how the errors are returned from the driver * * Revision 1.8 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.7 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.6 2002/11/11 17:10:12 lurcher * * VMS changes * * Revision 1.5 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.4 2002/01/30 12:20:02 lurcher * * Add MyODBC 3 driver source * * Revision 1.3 2002/01/21 18:00:51 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.15 2000/08/22 22:56:27 ngorham * * Add fix to SQLGetDiagField to return the server name on statements and * descriptors * * Revision 1.14 2000/08/21 10:31:58 ngorham * * Add missing line continuation char * * Revision 1.13 2000/08/09 08:48:18 ngorham * * Fix for SQLGetDiagField(SQL_DIAG_SUBCLASS_ORIGIN) returning a null string * * Revision 1.12 2000/08/03 10:49:34 ngorham * * Fix buffer overrun problem in GetDiagField * * Revision 1.11 2000/07/31 20:48:01 ngorham * * Fix bugs in SQLGetDiagField and with SQLColAttributes * * Revision 1.10 2000/06/23 16:11:35 ngorham * * Map ODBC 2 SQLSTATE values to ODBC 3 * * Revision 1.9 2000/05/21 21:49:19 ngorham * * Assorted fixes * * Revision 1.8 1999/11/17 21:08:58 ngorham * * Fix Bug with the ODBC 3 error handling * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/11/10 03:51:33 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/12 19:42:06 ngorham * * Finished off SQLGetDiagField.c and fixed a but that caused SQLError to * fail with Perl and PHP, connect errors were not being returned because * I was checking to the environment being set, they were setting the * statement and the environment. The order of checking has been changed. * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.5 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.4 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.3 1999/05/03 19:50:43 nick * Another check point * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetDiagField.c,v $ $Revision: 1.17 $"; #define ODBC30_SUBCLASS "01S00,01S01,01S02,01S06,01S07,07S01,08S01,21S01,\ 21S02,25S01,25S02,25S03,42S01,42S02,42S11,42S12,42S21,42S22,HY095,HY097,HY098,\ HY099,HY100,HY101,HY105,HY107,HY109,HY110,HY111,HYT00,HYT01,IM001,IM002,IM003,\ IM004,IM005,IM006,IM007,IM008,IM010,IM011,IM012" extern int __is_env( EHEAD * head ); /* * is it a diag identifier that we have to convert from unicode to ansi */ static int is_char_diag( int diag_identifier ) { switch( diag_identifier ) { case SQL_DIAG_CLASS_ORIGIN: case SQL_DIAG_CONNECTION_NAME: case SQL_DIAG_DYNAMIC_FUNCTION: case SQL_DIAG_MESSAGE_TEXT: case SQL_DIAG_SERVER_NAME: case SQL_DIAG_SQLSTATE: case SQL_DIAG_SUBCLASS_ORIGIN: return 1; default: return 0; } } static SQLRETURN extract_sql_error_field( EHEAD *head, SQLSMALLINT rec_number, SQLSMALLINT diag_identifier, SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length, SQLSMALLINT *string_length_ptr ) { ERROR *ptr; if ( is_char_diag( diag_identifier ) && buffer_length < 0 ) { return SQL_ERROR; } /* * check the header fields first */ switch( diag_identifier ) { case SQL_DIAG_CURSOR_ROW_COUNT: case SQL_DIAG_ROW_COUNT: { SQLLEN val; SQLRETURN ret; if ( rec_number > 0 || head -> handle_type != SQL_HANDLE_STMT ) { return SQL_ERROR; } else if ( head -> header_set ) { switch( diag_identifier ) { case SQL_DIAG_CURSOR_ROW_COUNT: if ( SQL_SUCCEEDED( head -> diag_cursor_row_count_ret ) && diag_info_ptr ) { *((SQLLEN*)diag_info_ptr) = head -> diag_cursor_row_count; } return head -> diag_cursor_row_count_ret; case SQL_DIAG_ROW_COUNT: if ( SQL_SUCCEEDED( head -> diag_row_count_ret ) && diag_info_ptr ) { *((SQLLEN*)diag_info_ptr) = head -> diag_row_count; } return head -> diag_row_count_ret; } } else if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELDW( __get_connection( head ))) { ret = SQLGETDIAGFIELDW( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELD( __get_connection( head ))) { ret = SQLGETDIAGFIELD( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else if ( CHECK_SQLROWCOUNT( __get_connection( head ))) { ret = DEF_SQLROWCOUNT( __get_connection( head ), __get_driver_handle( head ), &val ); if ( !SQL_SUCCEEDED( ret )) { return ret; } } else { val = 0; } if ( diag_info_ptr ) { memcpy( diag_info_ptr, &val, sizeof( val )); } } return SQL_SUCCESS; case SQL_DIAG_DYNAMIC_FUNCTION: { SQLRETURN ret; if ( rec_number > 0 ) { return SQL_ERROR; } else if ( head -> handle_type != SQL_HANDLE_STMT ) { if ( diag_info_ptr ) { strcpy( diag_info_ptr, "" ); } if ( string_length_ptr ) { *string_length_ptr = 0; } return SQL_SUCCESS; } else if ( head -> header_set ) { if ( SQL_SUCCEEDED( head -> diag_dynamic_function_ret ) && diag_info_ptr ) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, head -> diag_dynamic_function, SQL_NTS, __get_connection( head ), NULL ); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( head -> diag_dynamic_function ); } } return head -> diag_dynamic_function_ret; } else if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELDW( __get_connection( head ))) { SQLWCHAR *s1 = NULL; if ( buffer_length > 0 ) { s1 = malloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 )); } ret = SQLGETDIAGFIELDW( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, s1 ? s1 : diag_info_ptr, buffer_length * sizeof ( SQLWCHAR ), string_length_ptr ); if ( SQL_SUCCEEDED( ret ) && diag_info_ptr && s1 ) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, s1, buffer_length, __get_connection( head ), NULL ); } if ( string_length_ptr && *string_length_ptr > 0 ) { *string_length_ptr /= sizeof ( SQLWCHAR ); } if ( s1 ) { free( s1 ); } return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELD( __get_connection( head ))) { ret = SQLGETDIAGFIELD( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } if ( diag_info_ptr ) { strcpy( diag_info_ptr, "" ); } } return SQL_SUCCESS; case SQL_DIAG_DYNAMIC_FUNCTION_CODE: { SQLINTEGER val; SQLRETURN ret; if ( rec_number > 0 ) { return SQL_ERROR; } else if ( head -> handle_type != SQL_HANDLE_STMT ) { *((SQLINTEGER*)diag_info_ptr) = 0; return SQL_SUCCESS; } else if ( head -> header_set ) { if ( SQL_SUCCEEDED( head -> diag_dynamic_function_code_ret ) && diag_info_ptr ) { *((SQLINTEGER*)diag_info_ptr) = head -> diag_dynamic_function_code; } return head -> diag_dynamic_function_code_ret; } else if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELDW( __get_connection( head ))) { ret = SQLGETDIAGFIELDW( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELD( __get_connection( head ))) { ret = SQLGETDIAGFIELD( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else { val = SQL_DIAG_UNKNOWN_STATEMENT; } if ( diag_info_ptr ) { memcpy( diag_info_ptr, &val, sizeof( val )); } } return SQL_SUCCESS; case SQL_DIAG_NUMBER: { SQLINTEGER val; if ( rec_number > 0 ) { return SQL_ERROR; } val = head -> sql_diag_head.internal_count + head -> sql_diag_head.error_count; if ( diag_info_ptr ) { memcpy( diag_info_ptr, &val, sizeof( val )); } } return SQL_SUCCESS; case SQL_DIAG_RETURNCODE: { if ( diag_info_ptr ) { memcpy( diag_info_ptr, &head -> return_code, sizeof( head -> return_code )); } } return SQL_SUCCESS; } /* * else check the records */ if ( rec_number < 1 || (( diag_identifier == SQL_DIAG_COLUMN_NUMBER || diag_identifier == SQL_DIAG_ROW_NUMBER ) && head -> handle_type != SQL_HANDLE_STMT )) { return SQL_ERROR; } if ( rec_number <= head -> sql_diag_head.internal_count ) { /* * local errors */ ptr = head -> sql_diag_head.internal_list_head; while( rec_number > 1 ) { ptr = ptr -> next; rec_number --; } if ( !ptr ) { return SQL_NO_DATA; } } else if ( !__is_env( head ) && __get_connection( head ) -> state != STATE_C2 ) { rec_number -= head -> sql_diag_head.internal_count; if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELDW( __get_connection( head ))) { SQLRETURN ret; SQLWCHAR *s1 = NULL; if ( diag_info_ptr && buffer_length > 0 ) { s1 = malloc( ( buffer_length + 1 ) * sizeof( SQLWCHAR )); } ret = SQLGETDIAGFIELDW( __get_connection( head ), head -> handle_type, __get_driver_handle( head ), rec_number, diag_identifier, s1 ? s1 : diag_info_ptr, s1 ? ( buffer_length + 1 ) * sizeof( SQLWCHAR ) : buffer_length, string_length_ptr ); if ( SQL_SUCCEEDED( ret ) && s1 && diag_info_ptr ) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, s1, SQL_NTS, __get_connection( head ), NULL ); if ( string_length_ptr && *string_length_ptr > 0 ) { *string_length_ptr /= sizeof( SQLWCHAR ); } } if ( s1 ) { free( s1 ); } if ( SQL_SUCCEEDED( ret ) && diag_identifier == SQL_DIAG_SQLSTATE ) { /* * map 3 to 2 if required */ if ( diag_info_ptr ) { if ( diag_info_ptr ) __map_error_state( diag_info_ptr, __get_version( head )); } } return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELD( __get_connection( head ))) { SQLRETURN ret; ret = SQLGETDIAGFIELD( __get_connection( head ), head -> handle_type, __get_driver_handle( head ), rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); if ( SQL_SUCCEEDED( ret ) && diag_identifier == SQL_DIAG_SQLSTATE ) { /* * map 3 to 2 if required */ if ( diag_info_ptr ) { if ( diag_info_ptr ) __map_error_state( diag_info_ptr, __get_version( head )); } } return ret; } else { ptr = head -> sql_diag_head.error_list_head; while( rec_number > 1 ) { ptr = ptr -> next; rec_number --; } if ( !ptr ) { return SQL_NO_DATA; } } } else { return SQL_NO_DATA; } /* * if we are here ptr should point to the local error * record */ switch( diag_identifier ) { case SQL_DIAG_CLASS_ORIGIN: { if ( SQL_SUCCEEDED( ptr -> diag_class_origin_ret )) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, ptr -> diag_class_origin, SQL_NTS, __get_connection( head ), NULL ); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( ptr -> diag_class_origin ); } return ptr -> diag_class_origin_ret; } else { return ptr -> diag_class_origin_ret; } } break; case SQL_DIAG_COLUMN_NUMBER: { if ( diag_info_ptr ) { memcpy( diag_info_ptr, &ptr -> diag_column_number, sizeof( SQLINTEGER )); } return SQL_SUCCESS; } break; case SQL_DIAG_CONNECTION_NAME: { if ( SQL_SUCCEEDED( ptr -> diag_connection_name_ret )) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, ptr -> diag_connection_name, SQL_NTS, __get_connection( head ), NULL ); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( ptr -> diag_connection_name ); } return ptr -> diag_connection_name_ret; } else { return ptr -> diag_connection_name_ret; } } break; case SQL_DIAG_MESSAGE_TEXT: { char *str; int ret = SQL_SUCCESS; str = unicode_to_ansi_alloc( ptr -> msg, SQL_NTS, __get_connection( head ), NULL ); if ( diag_info_ptr ) { if ( buffer_length >= strlen( str ) + 1 ) { strcpy( diag_info_ptr, str ); } else { ret = SQL_SUCCESS_WITH_INFO; memcpy( diag_info_ptr, str, buffer_length - 1 ); (( char * ) diag_info_ptr )[ buffer_length - 1 ] = '\0'; } } if ( string_length_ptr ) { *string_length_ptr = strlen( str ); } if ( str ) { free( str ); } return ret; } break; case SQL_DIAG_NATIVE: { if ( diag_info_ptr ) { memcpy( diag_info_ptr, &ptr -> native_error, sizeof( SQLINTEGER )); } return SQL_SUCCESS; } break; case SQL_DIAG_ROW_NUMBER: { if ( diag_info_ptr ) { memcpy( diag_info_ptr, &ptr -> diag_row_number, sizeof( SQLLEN )); } return SQL_SUCCESS; } break; case SQL_DIAG_SERVER_NAME: { if ( SQL_SUCCEEDED( ptr -> diag_server_name_ret )) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, ptr -> diag_server_name, SQL_NTS, __get_connection( head ), NULL ); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( ptr -> diag_server_name ); } return ptr -> diag_server_name_ret; } else { return ptr -> diag_server_name_ret; } } break; case SQL_DIAG_SQLSTATE: { char *str; int ret = SQL_SUCCESS; str = unicode_to_ansi_alloc( ptr -> sqlstate, SQL_NTS, __get_connection( head ), NULL ); if ( diag_info_ptr ) { if ( buffer_length >= strlen( str ) + 1 ) { strcpy( diag_info_ptr, str ); } else { ret = SQL_SUCCESS_WITH_INFO; memcpy( diag_info_ptr, str, buffer_length - 1 ); (( char * ) diag_info_ptr )[ buffer_length - 1 ] = '\0'; } /* * map 3 to 2 if required */ if ( diag_info_ptr ) __map_error_state( diag_info_ptr, __get_version( head )); } if ( string_length_ptr ) { *string_length_ptr = strlen( str ); } if ( str ) { free( str ); } return ret; } break; case SQL_DIAG_SUBCLASS_ORIGIN: { if ( SQL_SUCCEEDED( ptr -> diag_subclass_origin_ret )) { unicode_to_ansi_copy( diag_info_ptr, buffer_length, ptr -> diag_subclass_origin, SQL_NTS, __get_connection( head ), NULL ); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( ptr -> diag_subclass_origin ); } return ptr -> diag_subclass_origin_ret; } else { return ptr -> diag_subclass_origin_ret; } } break; } return SQL_SUCCESS; } SQLRETURN SQLGetDiagFieldA( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT rec_number, SQLSMALLINT diag_identifier, SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length, SQLSMALLINT *string_length_ptr ) { return SQLGetDiagField( handle_type, handle, rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); } SQLRETURN SQLGetDiagField( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT rec_number, SQLSMALLINT diag_identifier, SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length, SQLSMALLINT *string_length_ptr ) { SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; DMHENV environment = ( DMHENV ) handle; DMHDBC connection = NULL; DMHSTMT statement = NULL; DMHDESC descriptor = NULL; EHEAD *herror; char *handle_msg; const char *handle_type_ptr; switch ( handle_type ) { case SQL_HANDLE_ENV: { if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } herror = &environment->error; handle_msg = environment->msg; handle_type_ptr = "Environment"; } break; case SQL_HANDLE_DBC: { connection = ( DMHDBC ) handle; if ( !__validate_dbc( connection )) { return SQL_INVALID_HANDLE; } herror = &connection->error; handle_msg = connection->msg; handle_type_ptr = "Connection"; } break; case SQL_HANDLE_STMT: { statement = ( DMHSTMT ) handle; if ( !__validate_stmt( statement )) { return SQL_INVALID_HANDLE; } connection = statement->connection; herror = &statement->error; handle_msg = statement->msg; handle_type_ptr = "Statement"; } break; case SQL_HANDLE_DESC: { descriptor = ( DMHDESC ) handle; if ( !__validate_desc( descriptor )) { return SQL_INVALID_HANDLE; } connection = descriptor->connection; herror = &descriptor->error; handle_msg = descriptor->msg; handle_type_ptr = "Descriptor"; } break; default: { return SQL_NO_DATA; } } thread_protect( handle_type, handle ); if ( log_info.log_flag ) { sprintf( handle_msg, "\n\t\tEntry:\ \n\t\t\t%s = %p\ \n\t\t\tRec Number = %d\ \n\t\t\tDiag Ident = %d\ \n\t\t\tDiag Info Ptr = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tString Len Ptr = %p", handle_type_ptr, handle, rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, handle_msg ); } /* * Do diag extraction here if defer flag is set. * Clean the flag after extraction. */ if ( connection && herror->defer_extract ) { extract_error_from_driver( herror, connection, herror->ret_code_deferred, 0 ); herror->defer_extract = 0; herror->ret_code_deferred = 0; } ret = extract_sql_error_field( herror, rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); if ( log_info.log_flag ) { sprintf( handle_msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, handle_msg ); } thread_release( handle_type, handle ); return ret; } unixODBC-2.3.12/DriverManager/SQLGetDiagFieldW.c000066400000000000000000000667451446441710500211130ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetDiagFieldW.c,v 1.10 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetDiagFieldW.c,v $ * Revision 1.10 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.9 2009/02/04 09:30:02 lurcher * Fix some SQLINTEGER/SQLLEN conflicts * * Revision 1.8 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.7 2002/12/05 17:44:30 lurcher * * Display unknown return values in return logging * * Revision 1.6 2002/11/11 17:10:14 lurcher * * VMS changes * * Revision 1.5 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.4 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.3 2002/01/21 18:00:51 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/01/04 13:16:25 nick * * Add support for GNU portable threads and tidy up some UNICODE compile * warnings * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetDiagFieldW.c,v $"; #define ODBC30_SUBCLASS "01S00,01S01,01S02,01S06,01S07,07S01,08S01,21S01,\ 21S02,25S01,25S02,25S03,42S01,42S02,42S11,42S12,42S21,42S22,HY095,HY097,HY098,\ HY099,HY100,HY101,HY105,HY107,HY109,HY110,HY111,HYT00,HYT01,IM001,IM002,IM003,\ IM004,IM005,IM006,IM007,IM008,IM010,IM011,IM012" SQLRETURN extract_parent_handle_field( SQLHANDLE handle, int handle_type, SQLSMALLINT rec_number, SQLSMALLINT diag_identifier, SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length, SQLSMALLINT *string_length_ptr ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); if ( handle_type != SQL_HANDLE_ENV ) { #ifdef WITH_HANDLE_REDIRECT { DMHDBC *parent_handle_dbc; DMHSTMT *parent_handle_stmt; DMHDESC *parent_handle_desc; switch ( handle_type ) { case SQL_HANDLE_DBC: { parent_handle_dbc = find_parent_handle( handle, handle_type ); } break; case SQL_HANDLE_STMT: { parent_handle_stmt = find_parent_handle( handle, handle_type ); parent_handle_dbc = parent_handle_stmt->connection; } break; case SQL_HANDLE_DESC: { parent_handle_desc = find_parent_handle( handle, handle_type ); parent_handle_dbc = parent_handle_desc->connection; } break; default: { return SQL_INVALID_HANDLE; } } if ( parent_handle_dbc ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLGETDIAGFIELDW( parent_handle_dbc )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLGETDIAGFIELDW( parent_handle_dbc, handle_type, handle, rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); } } } #endif } return SQL_INVALID_HANDLE; } /* * is it a diag identifier that we have to convert from unicode to ansi */ static int is_char_diag( int diag_identifier ) { switch( diag_identifier ) { case SQL_DIAG_CLASS_ORIGIN: case SQL_DIAG_CONNECTION_NAME: case SQL_DIAG_DYNAMIC_FUNCTION: case SQL_DIAG_MESSAGE_TEXT: case SQL_DIAG_SERVER_NAME: case SQL_DIAG_SQLSTATE: case SQL_DIAG_SUBCLASS_ORIGIN: return 1; default: return 0; } } static SQLRETURN extract_sql_error_field_w( EHEAD *head, SQLSMALLINT rec_number, SQLSMALLINT diag_identifier, SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length, SQLSMALLINT *string_length_ptr ) { ERROR *ptr; if ( is_char_diag( diag_identifier ) && buffer_length < 0 ) { return SQL_ERROR; } /* * check the header fields first */ switch( diag_identifier ) { case SQL_DIAG_CURSOR_ROW_COUNT: case SQL_DIAG_ROW_COUNT: { SQLLEN val; SQLRETURN ret; if ( rec_number > 0 || head -> handle_type != SQL_HANDLE_STMT ) { return SQL_ERROR; } else if ( head -> header_set ) { switch( diag_identifier ) { case SQL_DIAG_CURSOR_ROW_COUNT: if ( SQL_SUCCEEDED( head -> diag_cursor_row_count_ret ) && diag_info_ptr ) { *((SQLINTEGER*)diag_info_ptr) = head -> diag_cursor_row_count; } return head -> diag_cursor_row_count_ret; case SQL_DIAG_ROW_COUNT: if ( SQL_SUCCEEDED( head -> diag_row_count_ret ) && diag_info_ptr ) { *((SQLINTEGER*)diag_info_ptr) = head -> diag_row_count; } return head -> diag_row_count_ret; } } else if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELDW( __get_connection( head ))) { ret = SQLGETDIAGFIELDW( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELD( __get_connection( head ))) { ret = SQLGETDIAGFIELD( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else if ( CHECK_SQLROWCOUNT( __get_connection( head ))) { ret = DEF_SQLROWCOUNT( __get_connection( head ), __get_driver_handle( head ), &val ); if ( !SQL_SUCCEEDED( ret )) { return ret; } } else { val = 0; } if ( diag_info_ptr ) { memcpy( diag_info_ptr, &val, sizeof( val )); } } return SQL_SUCCESS; case SQL_DIAG_DYNAMIC_FUNCTION: { SQLRETURN ret; if ( rec_number > 0 ) { return SQL_ERROR; } else if ( head -> handle_type != SQL_HANDLE_STMT ) { if ( diag_info_ptr ) { *((SQLWCHAR*)diag_info_ptr) = 0; } if ( string_length_ptr ) { *string_length_ptr = 0; } return SQL_SUCCESS; } else if ( head -> header_set ) { if ( SQL_SUCCEEDED( head -> diag_dynamic_function_ret ) && diag_info_ptr ) { wide_strncpy( diag_info_ptr, head -> diag_dynamic_function, buffer_length ); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( head -> diag_dynamic_function ) * sizeof( SQLWCHAR ); } } return head -> diag_dynamic_function_ret; } else if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELDW( __get_connection( head ))) { ret = SQLGETDIAGFIELDW( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELD( __get_connection( head ))) { SQLCHAR *as1 = NULL; if ( buffer_length > 0 && diag_info_ptr ) { as1 = malloc( buffer_length + 1 ); } ret = SQLGETDIAGFIELD( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, as1 ? as1 : diag_info_ptr, buffer_length / 2, string_length_ptr ); if ( SQL_SUCCEEDED( ret ) && as1 && diag_info_ptr ) { ansi_to_unicode_copy( diag_info_ptr, (char*) as1, SQL_NTS, __get_connection( head ), NULL); } if ( SQL_SUCCEEDED( ret ) && string_length_ptr ) { *string_length_ptr *= sizeof( SQLWCHAR ); } if ( as1 ) { free( as1 ); } return ret; } if ( diag_info_ptr ) { strcpy( diag_info_ptr, "" ); } } return SQL_SUCCESS; case SQL_DIAG_DYNAMIC_FUNCTION_CODE: { SQLINTEGER val; SQLRETURN ret; if ( rec_number > 0 ) { return SQL_ERROR; } else if ( head -> handle_type != SQL_HANDLE_STMT ) { *((SQLINTEGER*)diag_info_ptr) = 0; return SQL_SUCCESS; } else if ( head -> header_set ) { if ( SQL_SUCCEEDED( head -> diag_dynamic_function_code_ret ) && diag_info_ptr ) { *((SQLINTEGER*)diag_info_ptr) = head -> diag_dynamic_function_code; } return head -> diag_dynamic_function_code_ret; } else if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELDW( __get_connection( head ))) { ret = SQLGETDIAGFIELDW( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELD( __get_connection( head ))) { ret = SQLGETDIAGFIELD( __get_connection( head ), SQL_HANDLE_STMT, __get_driver_handle( head ), 0, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); return ret; } else { val = SQL_DIAG_UNKNOWN_STATEMENT; } if ( diag_info_ptr ) { memcpy( diag_info_ptr, &val, sizeof( val )); } } return SQL_SUCCESS; case SQL_DIAG_NUMBER: { SQLINTEGER val; if ( rec_number > 0 ) { return SQL_ERROR; } val = head -> sql_diag_head.internal_count + head -> sql_diag_head.error_count; if ( diag_info_ptr ) { memcpy( diag_info_ptr, &val, sizeof( val )); } } return SQL_SUCCESS; case SQL_DIAG_RETURNCODE: { if ( diag_info_ptr ) { memcpy( diag_info_ptr, &head -> return_code, sizeof( head -> return_code )); } } return SQL_SUCCESS; } /* * else check the records */ if ( rec_number < 1 || (( diag_identifier == SQL_DIAG_COLUMN_NUMBER || diag_identifier == SQL_DIAG_ROW_NUMBER ) && head -> handle_type != SQL_HANDLE_STMT )) { return SQL_ERROR; } if ( rec_number <= head -> sql_diag_head.internal_count ) { /* * local errors */ ptr = head -> sql_diag_head.internal_list_head; while( rec_number > 1 ) { ptr = ptr -> next; rec_number --; } if ( !ptr ) { return SQL_NO_DATA; } } else if ( rec_number <= head -> sql_diag_head.internal_count + head -> sql_diag_head.error_count ) { rec_number -= head -> sql_diag_head.internal_count; if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELDW( __get_connection( head ))) { SQLRETURN ret; ret = SQLGETDIAGFIELDW( __get_connection( head ), head -> handle_type, __get_driver_handle( head ), rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); if ( SQL_SUCCEEDED( ret ) && diag_identifier == SQL_DIAG_SQLSTATE ) { /* * map 3 to 2 if required */ if ( diag_info_ptr ) __map_error_state_w( diag_info_ptr, __get_version( head )); } return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGFIELD( __get_connection( head ))) { SQLRETURN ret; SQLCHAR *as1 = NULL; if ( is_char_diag( diag_identifier ) && diag_info_ptr && buffer_length > 0 ) { as1 = malloc( buffer_length + 1 ); } ret = SQLGETDIAGFIELD( __get_connection( head ), head -> handle_type, __get_driver_handle( head ), rec_number, diag_identifier, as1 ? as1 : diag_info_ptr, buffer_length, string_length_ptr ); if ( SQL_SUCCEEDED( ret ) && diag_identifier == SQL_DIAG_SQLSTATE ) { /* * map 3 to 2 if required */ if ( diag_info_ptr && as1 ) { __map_error_state( (char*) as1, __get_version( head )); ansi_to_unicode_copy( diag_info_ptr, (char*) as1, SQL_NTS, __get_connection( head ), NULL ); } } if ( as1 ) { free( as1 ); } return ret; } else { ptr = head -> sql_diag_head.error_list_head; while( rec_number > 1 ) { ptr = ptr -> next; rec_number --; } if ( !ptr ) { return SQL_NO_DATA; } } } else { return SQL_NO_DATA; } /* * if we are here ptr should point to the error * record */ switch( diag_identifier ) { case SQL_DIAG_CLASS_ORIGIN: { if ( SQL_SUCCEEDED( ptr -> diag_class_origin_ret )) { wide_strncpy( diag_info_ptr, ptr -> diag_class_origin, buffer_length ); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( ptr -> diag_class_origin ) * sizeof( SQLWCHAR ); } return ptr -> diag_class_origin_ret; } else { return ptr -> diag_class_origin_ret; } } break; case SQL_DIAG_COLUMN_NUMBER: { if ( diag_info_ptr ) { memcpy( diag_info_ptr, &ptr -> diag_column_number, sizeof( SQLINTEGER )); } return SQL_SUCCESS; } break; case SQL_DIAG_CONNECTION_NAME: { if ( SQL_SUCCEEDED( ptr -> diag_connection_name_ret )) { wide_strcpy( diag_info_ptr, ptr -> diag_connection_name ); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( ptr -> diag_connection_name ) * sizeof( SQLWCHAR ); } return ptr -> diag_connection_name_ret; } else { return ptr -> diag_connection_name_ret; } } break; case SQL_DIAG_MESSAGE_TEXT: { SQLWCHAR *str; int ret = SQL_SUCCESS; str = ptr -> msg; if ( diag_info_ptr ) { if ( buffer_length >= wide_strlen( str ) + 1 ) { wide_strcpy( diag_info_ptr, str ); } else { ret = SQL_SUCCESS_WITH_INFO; memcpy( diag_info_ptr, str, ( buffer_length - 1 ) * 2 ); (( SQLWCHAR * ) diag_info_ptr )[ buffer_length - 1 ] = '\0'; } } if ( string_length_ptr ) { *string_length_ptr = wide_strlen( str ) * sizeof( SQLWCHAR ); } return ret; } break; case SQL_DIAG_NATIVE: { if ( diag_info_ptr ) { memcpy( diag_info_ptr, &ptr -> native_error, sizeof( SQLINTEGER )); } return SQL_SUCCESS; } break; case SQL_DIAG_ROW_NUMBER: { if ( diag_info_ptr ) { memcpy( diag_info_ptr, &ptr -> diag_row_number, sizeof( SQLINTEGER )); } return SQL_SUCCESS; } break; case SQL_DIAG_SERVER_NAME: { if ( SQL_SUCCEEDED( ptr -> diag_server_name_ret )) { wide_strcpy( diag_info_ptr, ptr -> diag_server_name ); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( ptr -> diag_server_name ) * sizeof( SQLWCHAR ); } return ptr -> diag_server_name_ret; } else { return ptr -> diag_server_name_ret; } } break; case SQL_DIAG_SQLSTATE: { SQLWCHAR *str; int ret = SQL_SUCCESS; str = ptr -> sqlstate; if ( diag_info_ptr ) { if ( buffer_length >= wide_strlen( str ) + 1 ) { wide_strcpy( diag_info_ptr, str ); } else { ret = SQL_SUCCESS_WITH_INFO; memcpy( diag_info_ptr, str, ( buffer_length - 1 ) * 2 ); (( SQLWCHAR * ) diag_info_ptr )[ buffer_length - 1 ] = '\0'; } /* * map 3 to 2 if required */ if ( diag_info_ptr ) __map_error_state_w( diag_info_ptr, __get_version( head )); } if ( string_length_ptr ) { *string_length_ptr = wide_strlen( str ) * sizeof( SQLWCHAR ); } return ret; } break; case SQL_DIAG_SUBCLASS_ORIGIN: { if ( SQL_SUCCEEDED( ptr -> diag_subclass_origin_ret )) { wide_strcpy( diag_info_ptr, ptr -> diag_subclass_origin ); if ( string_length_ptr ) { *string_length_ptr = wide_strlen( ptr -> diag_subclass_origin ) * sizeof( SQLWCHAR ); } return ptr -> diag_subclass_origin_ret; } else { return ptr -> diag_subclass_origin_ret; } } break; } return SQL_SUCCESS; } SQLRETURN SQLGetDiagFieldW( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT rec_number, SQLSMALLINT diag_identifier, SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length, SQLSMALLINT *string_length_ptr ) { SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; DMHENV environment = ( DMHENV ) handle; DMHDBC connection = NULL; DMHSTMT statement = NULL; DMHDESC descriptor = NULL; EHEAD *herror; char *handle_msg; const char *handle_type_ptr; switch ( handle_type ) { case SQL_HANDLE_ENV: { if ( !__validate_env( environment )) { return extract_parent_handle_field( environment, handle_type, rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); } herror = &environment->error; handle_msg = environment->msg; handle_type_ptr = "Environment"; } break; case SQL_HANDLE_DBC: { connection = ( DMHDBC ) handle; if ( !__validate_dbc( connection )) { return extract_parent_handle_field( connection, handle_type, rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); } herror = &connection->error; handle_msg = connection->msg; handle_type_ptr = "Connection"; } break; case SQL_HANDLE_STMT: { statement = ( DMHSTMT ) handle; if ( !__validate_stmt( statement )) { return extract_parent_handle_field( statement, handle_type, rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); } connection = statement->connection; herror = &statement->error; handle_msg = statement->msg; handle_type_ptr = "Statement"; } break; case SQL_HANDLE_DESC: { descriptor = ( DMHDESC ) handle; if ( !__validate_desc( descriptor )) { return extract_parent_handle_field( descriptor, handle_type, rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); } connection = descriptor->connection; herror = &descriptor->error; handle_msg = descriptor->msg; handle_type_ptr = "Descriptor"; } break; default: { return SQL_NO_DATA; } } thread_protect( handle_type, handle ); if ( log_info.log_flag ) { sprintf( handle_msg, "\n\t\tEntry:\ \n\t\t\t%s = %p\ \n\t\t\tRec Number = %d\ \n\t\t\tDiag Ident = %d\ \n\t\t\tDiag Info Ptr = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tString Len Ptr = %p", handle_type_ptr, handle, rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, handle_msg ); } /* * Do diag extraction here if defer flag is set. * Clean the flag after extraction. */ if ( connection && herror->defer_extract ) { extract_error_from_driver( herror, connection, herror->ret_code_deferred, 0 ); herror->defer_extract = 0; herror->ret_code_deferred = 0; } ret = extract_sql_error_field_w( herror, rec_number, diag_identifier, diag_info_ptr, buffer_length, string_length_ptr ); if ( log_info.log_flag ) { sprintf( handle_msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, handle_msg ); } thread_release( handle_type, handle ); return ret; } unixODBC-2.3.12/DriverManager/SQLGetDiagRec.c000066400000000000000000000462441446441710500204420ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetDiagRec.c,v 1.21 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetDiagRec.c,v $ * Revision 1.21 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.20 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.19 2009/02/04 09:30:02 lurcher * Fix some SQLINTEGER/SQLLEN conflicts * * Revision 1.18 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.17 2008/05/20 13:43:47 lurcher * Vms fixes * * Revision 1.16 2007/02/12 11:49:34 lurcher * Add QT4 support to existing GUI parts * * Revision 1.15 2006/11/27 14:08:34 lurcher * Sync up dirs * * Revision 1.14 2006/05/31 17:35:34 lurcher * Add unicode ODBCINST entry points * * Revision 1.13 2006/04/24 08:42:10 lurcher * Handle resetting statement descriptors to implicit values, by passing in NULL or the implicit descrptor to SQLSetStmtAttr with the attribute SQL_ATTR_APP_PARAM_DESC or SQL_ATTR_APP_ROW_DESC. Also catch trying to call SQLGetDescField on a closed connection * * Revision 1.12 2005/12/19 18:43:26 lurcher * Add new parts to contrib and alter how the errors are returned from the driver * * Revision 1.11 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.10 2003/02/25 13:28:30 lurcher * * Allow errors on the drivers AllocHandle to be reported * Fix a problem that caused errors to not be reported in the log * Remove a redundant line from the spec file * * Revision 1.9 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.8 2002/11/13 15:59:20 lurcher * * More VMS changes * * Revision 1.7 2002/11/11 17:10:15 lurcher * * VMS changes * * Revision 1.6 2002/10/14 09:46:10 lurcher * * Remove extra return * * Revision 1.5 2002/10/08 13:36:07 lurcher * * Fix memory leak * * Revision 1.4 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.3 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.11 2000/06/23 16:11:38 ngorham * * Map ODBC 2 SQLSTATE values to ODBC 3 * * Revision 1.10 1999/12/01 09:20:07 ngorham * * Fix some threading problems * * Revision 1.9 1999/11/17 21:08:58 ngorham * * Fix Bug with the ODBC 3 error handling * * Revision 1.8 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/11/10 22:15:48 ngorham * * Fix some bugs with the DM and error reporting. * * Revision 1.6 1999/11/10 03:51:33 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/14 19:46:04 ngorham * * Fix the error logging when SQLError or SQLGetDiagRec returns SQL_NO_DATA * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.1 1999/04/30 16:22:47 nick * Another checkpoint * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetDiagRec.c,v $ $Revision: 1.21 $"; int __is_env( EHEAD * head ) { int type; memcpy( &type, head -> owning_handle, sizeof( type )); return type == HENV_MAGIC; } DMHDBC __get_connection( EHEAD * head ) { int type; memcpy( &type, head -> owning_handle, sizeof( type )); switch ( type ) { case HDBC_MAGIC: { DMHDBC connection = ( DMHDBC ) head -> owning_handle; return connection; } case HSTMT_MAGIC: { DMHSTMT statement = ( DMHSTMT ) head -> owning_handle; return statement -> connection; } case HDESC_MAGIC: { DMHDESC descriptor = ( DMHDESC ) head -> owning_handle; return descriptor -> connection; } } return NULL; } int __get_version( EHEAD * head ) { int type; memcpy( &type, head -> owning_handle, sizeof( type )); switch ( type ) { case HENV_MAGIC: { DMHENV environment = ( DMHENV ) head -> owning_handle; return environment -> requested_version; } case HDBC_MAGIC: { DMHDBC connection = ( DMHDBC ) head -> owning_handle; return connection -> environment -> requested_version; } case HSTMT_MAGIC: { DMHSTMT statement = ( DMHSTMT ) head -> owning_handle; return statement -> connection -> environment -> requested_version; } case HDESC_MAGIC: { DMHDESC descriptor = ( DMHDESC ) head -> owning_handle; return descriptor -> connection -> environment -> requested_version; } } return 0; } DRV_SQLHANDLE __get_driver_handle( EHEAD * head ) { int type; memcpy( &type, head -> owning_handle, sizeof( type )); switch ( type ) { case HDBC_MAGIC: { DMHDBC connection = ( DMHDBC ) head -> owning_handle; return connection -> driver_dbc; } case HSTMT_MAGIC: { DMHSTMT statement = ( DMHSTMT ) head -> owning_handle; return statement -> driver_stmt; } case HDESC_MAGIC: { DMHDESC descriptor = ( DMHDESC ) head -> owning_handle; return descriptor -> driver_desc; } } return ( SQLHANDLE ) 0; } static SQLRETURN extract_sql_error_rec( EHEAD *head, SQLCHAR *sqlstate, SQLINTEGER rec_number, SQLINTEGER *native_error, SQLCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length ) { SQLRETURN ret; if ( sqlstate ) strcpy((char*) sqlstate, "00000" ); if ( rec_number <= head -> sql_diag_head.internal_count ) { ERROR *ptr; SQLCHAR *as1 = NULL; ptr = head -> sql_diag_head.internal_list_head; while( rec_number > 1 ) { ptr = ptr -> next; rec_number --; } if ( !ptr ) { return SQL_NO_DATA; } as1 = (SQLCHAR*) unicode_to_ansi_alloc( ptr -> msg, SQL_NTS, __get_connection( head ), NULL ); if ( sqlstate ) { unicode_to_ansi_copy((char*) sqlstate, 6, ptr -> sqlstate, SQL_NTS, __get_connection( head ), NULL ); } if ( buffer_length < strlen((char*) as1 ) + 1 ) { ret = SQL_SUCCESS_WITH_INFO; } else { ret = SQL_SUCCESS; } if ( message_text && as1 ) { if ( ret == SQL_SUCCESS ) { strcpy((char*) message_text, (char*) as1 ); } else { memcpy( message_text, as1, buffer_length ); message_text[ buffer_length - 1 ] = '\0'; } } if ( text_length && as1 ) { *text_length = strlen((char*) as1 ); } if ( native_error ) { *native_error = ptr -> native_error; } /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) __map_error_state( (char*) sqlstate, __get_version( head )); if ( as1 ) { free( as1 ); } return ret; } else if ( !__is_env( head ) && __get_connection( head ) -> state != STATE_C2 && head->sql_diag_head.error_count ) { ERROR *ptr; SQLWCHAR *s1 = NULL, *s2 = NULL; rec_number -= head -> sql_diag_head.internal_count; s1 = malloc( sizeof( SQLWCHAR ) * ( 6 + 1 )); if ( buffer_length > 0 ) { s2 = malloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 )); } if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGRECW( __get_connection( head ))) { ret = SQLGETDIAGRECW( __get_connection( head ), head -> handle_type, __get_driver_handle( head ), rec_number, s1, native_error, s2, buffer_length, text_length ); /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) { if ( sqlstate ) { unicode_to_ansi_copy((char*) sqlstate, 6, s1, SQL_NTS, __get_connection( head ), NULL ); __map_error_state((char*) sqlstate, __get_version( head )); } if ( message_text ) { unicode_to_ansi_copy((char*) message_text, buffer_length, s2, SQL_NTS, __get_connection( head ), NULL ); } } } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGREC( __get_connection( head ))) { ret = SQLGETDIAGREC( __get_connection( head ), head -> handle_type, __get_driver_handle( head ), rec_number, sqlstate, native_error, message_text, buffer_length, text_length ); /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) __map_error_state((char*) sqlstate, __get_version( head )); } else { SQLCHAR *as1 = NULL; ptr = head -> sql_diag_head.error_list_head; while( rec_number > 1 ) { ptr = ptr -> next; rec_number --; } if ( !ptr ) { if ( s1 ) free( s1 ); if ( s2 ) free( s2 ); return SQL_NO_DATA; } as1 = (SQLCHAR*) unicode_to_ansi_alloc( ptr -> msg, SQL_NTS, __get_connection( head ), NULL ); if ( sqlstate ) { unicode_to_ansi_copy((char*) sqlstate, 6, ptr -> sqlstate, SQL_NTS, __get_connection( head ), NULL ); } if ( as1 && buffer_length < strlen((char*) as1 ) + 1 ) { ret = SQL_SUCCESS_WITH_INFO; } else { ret = SQL_SUCCESS; } if ( message_text && as1 ) { if ( ret == SQL_SUCCESS ) { strcpy((char*) message_text,(char*) as1 ); } else { memcpy( message_text, as1, buffer_length ); message_text[ buffer_length - 1 ] = '\0'; } } if ( text_length && as1 ) { *text_length = strlen((char*) as1 ); } if ( native_error ) { *native_error = ptr -> native_error; } /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) __map_error_state((char*) sqlstate, __get_version( head )); if ( as1 ) { free( as1 ); } } if ( s1 ) free( s1 ); if ( s2 ) free( s2 ); return ret; } else { return SQL_NO_DATA; } } SQLRETURN SQLGetDiagRecA( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT rec_number, SQLCHAR *sqlstate, SQLINTEGER *native, SQLCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length_ptr ) { return SQLGetDiagRec( handle_type, handle, rec_number, sqlstate, native, message_text, buffer_length, text_length_ptr ); } SQLRETURN SQLGetDiagRec( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT rec_number, SQLCHAR *sqlstate, SQLINTEGER *native, SQLCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length_ptr ) { SQLRETURN ret; SQLCHAR s0[ 48 ], s1[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; DMHENV environment = ( DMHENV ) handle; DMHDBC connection = NULL; DMHSTMT statement = NULL; DMHDESC descriptor = NULL; EHEAD *herror; char *handle_msg; const char *handle_type_ptr; if ( rec_number < 1 ) { return SQL_ERROR; } switch ( handle_type ) { case SQL_HANDLE_ENV: { if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } herror = &environment->error; handle_msg = environment->msg; handle_type_ptr = "Environment"; } break; case SQL_HANDLE_DBC: { connection = ( DMHDBC ) handle; if (!__validate_dbc(connection)) { return SQL_INVALID_HANDLE; } herror = &connection->error; handle_msg = connection->msg; handle_type_ptr = "Connection"; } break; case SQL_HANDLE_STMT: { statement = ( DMHSTMT ) handle; if ( !__validate_stmt( statement )) { return SQL_INVALID_HANDLE; } connection = statement->connection; herror = &statement->error; handle_msg = statement->msg; handle_type_ptr = "Statement"; } break; case SQL_HANDLE_DESC: { descriptor = ( DMHDESC ) handle; if ( !__validate_desc( descriptor )) { return SQL_INVALID_HANDLE; } connection = descriptor->connection; herror = &descriptor->error; handle_msg = descriptor->msg; handle_type_ptr = "Descriptor"; } break; default: { return SQL_NO_DATA; } } thread_protect( handle_type, handle ); if ( log_info.log_flag ) { #ifdef HAVE_SNPRINTF snprintf( handle_msg, LOG_MSG_MAX*2, #else sprintf( handle_msg, #endif "\n\t\tEntry:\ \n\t\t\t%s = %p\ \n\t\t\tRec Number = %d\ \n\t\t\tSQLState = %p\ \n\t\t\tNative = %p\ \n\t\t\tMessage Text = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tText Len Ptr = %p", handle_type_ptr, handle, rec_number, sqlstate, native, message_text, buffer_length, text_length_ptr ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, handle_msg ); } /* * Do diag extraction here if defer flag is set. * Clean the flag after extraction. */ if ( connection && herror->defer_extract ) { extract_error_from_driver( herror, connection, herror->ret_code_deferred, 0 ); herror->defer_extract = 0; herror->ret_code_deferred = 0; } ret = extract_sql_error_rec( herror, sqlstate, rec_number, native, message_text, buffer_length, text_length_ptr ); if ( log_info.log_flag ) { if ( SQL_SUCCEEDED( ret )) { #ifdef HAVE_SNPRINTF snprintf( handle_msg, LOG_MSG_MAX*2, #else sprintf( handle_msg, #endif "\n\t\tExit:[%s]\ \n\t\t\tSQLState = %s\ \n\t\t\tNative = %s\ \n\t\t\tMessage Text = %s", __get_return_status( ret, s2 ), sqlstate ? sqlstate : (SQLCHAR *)"NULL", __iptr_as_string( s0, native ), __sdata_as_string( s1, SQL_CHAR, text_length_ptr, message_text )); } else { #ifdef HAVE_SNPRINTF snprintf( handle_msg, LOG_MSG_MAX*2, #else sprintf( handle_msg, #endif "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, handle_msg ); } thread_release( handle_type, handle ); return ret; } unixODBC-2.3.12/DriverManager/SQLGetDiagRecW.c000066400000000000000000000417451446441710500205720ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetDiagRecW.c,v 1.11 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetDiagRecW.c,v $ * Revision 1.11 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.10 2009/02/04 09:30:02 lurcher * Fix some SQLINTEGER/SQLLEN conflicts * * Revision 1.9 2007/11/26 11:37:23 lurcher * Sync up before tag * * Revision 1.8 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.7 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.6 2002/11/11 17:10:17 lurcher * * VMS changes * * Revision 1.5 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.4 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.3 2002/05/21 14:19:44 lurcher * * * Update libtool to escape from AIX build problem * * Add fix to avoid file handle limitations * * Add more UNICODE changes, it looks like it is native 16 representation * the old way can be reproduced by defining UCS16BE * * Add iusql, its just the same as isql but uses the wide functions * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetDiagRecW.c,v $"; extern int __is_env( EHEAD * head ); /* in SQLGetDiagRec.c */ SQLRETURN extract_parent_handle_rec( DRV_SQLHANDLE handle, int handle_type, SQLSMALLINT rec_number, SQLWCHAR *sqlstate, SQLINTEGER *native, SQLWCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length_ptr ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); if ( handle_type != SQL_HANDLE_ENV ) { #ifdef WITH_HANDLE_REDIRECT { DMHDBC *parent_handle_dbc; DMHSTMT *parent_handle_stmt; DMHDESC *parent_handle_desc; switch ( handle_type ) { case SQL_HANDLE_DBC: { parent_handle_dbc = find_parent_handle( handle, handle_type ); } break; case SQL_HANDLE_STMT: { parent_handle_stmt = find_parent_handle( handle, handle_type ); parent_handle_dbc = parent_handle_stmt->connection; } break; case SQL_HANDLE_DESC: { parent_handle_desc = find_parent_handle( handle, handle_type ); parent_handle_dbc = parent_handle_desc->connection; } break; default: { return SQL_INVALID_HANDLE; } } if ( parent_handle_dbc ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLGETDIAGRECW( parent_handle_dbc )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLGETDIAGRECW( parent_handle_dbc, handle_type, handle, rec_number, sqlstate, native, message_text, buffer_length, text_length_ptr ); } } } #endif } return SQL_INVALID_HANDLE; } static SQLRETURN extract_sql_error_rec_w( EHEAD *head, SQLWCHAR *sqlstate, SQLINTEGER rec_number, SQLINTEGER *native_error, SQLWCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length ) { SQLRETURN ret; if ( sqlstate ) { SQLWCHAR *tmp; tmp = ansi_to_unicode_alloc((SQLCHAR*) "00000", SQL_NTS, __get_connection( head ), NULL ); wide_strcpy( sqlstate, tmp ); free( tmp ); } if ( rec_number <= head -> sql_diag_head.internal_count ) { ERROR *ptr; ptr = head -> sql_diag_head.internal_list_head; while( rec_number > 1 ) { ptr = ptr -> next; rec_number --; } if ( !ptr ) { return SQL_NO_DATA; } if ( sqlstate ) { wide_strcpy( sqlstate, ptr -> sqlstate ); } if ( buffer_length < wide_strlen( ptr -> msg ) + 1 ) { ret = SQL_SUCCESS_WITH_INFO; } else { ret = SQL_SUCCESS; } if ( message_text ) { if ( ret == SQL_SUCCESS ) { wide_strcpy( message_text, ptr -> msg ); } else { memcpy( message_text, ptr -> msg, buffer_length * 2 ); message_text[ buffer_length - 1 ] = '\0'; } } if ( text_length ) { *text_length = wide_strlen( ptr -> msg ); } if ( native_error ) { *native_error = ptr -> native_error; } /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) __map_error_state_w(sqlstate, __get_version( head )); return ret; } else if ( !__is_env( head ) && __get_connection( head ) -> state != STATE_C2 && head->sql_diag_head.error_count ) { ERROR *ptr; rec_number -= head -> sql_diag_head.internal_count; if ( __get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGRECW( __get_connection( head ))) { ret = SQLGETDIAGRECW( __get_connection( head ), head -> handle_type, __get_driver_handle( head ), rec_number, sqlstate, native_error, message_text, buffer_length, text_length ); /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) { __map_error_state_w( sqlstate, __get_version( head )); } return ret; } else if ( !__get_connection( head ) -> unicode_driver && CHECK_SQLGETDIAGREC( __get_connection( head ))) { SQLCHAR *as1 = NULL, *as2 = NULL; if ( sqlstate ) { as1 = malloc( 7 ); } if ( message_text && buffer_length > 0 ) { as2 = malloc( buffer_length + 1 ); } ret = SQLGETDIAGREC( __get_connection( head ), head -> handle_type, __get_driver_handle( head ), rec_number, as1 ? as1 : (SQLCHAR *)sqlstate, native_error, as2 ? as2 : (SQLCHAR *)message_text, buffer_length, text_length ); /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) { if ( sqlstate ) { if ( as1 ) { ansi_to_unicode_copy( sqlstate,(char*) as1, SQL_NTS, __get_connection( head ), NULL ); __map_error_state_w( sqlstate, __get_version( head )); } } if ( message_text ) { if ( as2 ) { ansi_to_unicode_copy( message_text,(char*) as2, SQL_NTS, __get_connection( head ), NULL ); } } } if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); return ret; } else { ptr = head -> sql_diag_head.error_list_head; while( rec_number > 1 ) { ptr = ptr -> next; rec_number --; } if ( !ptr ) { return SQL_NO_DATA; } if ( sqlstate ) { wide_strcpy( sqlstate, ptr -> sqlstate ); } if ( buffer_length < wide_strlen( ptr -> msg ) + 1 ) { ret = SQL_SUCCESS_WITH_INFO; } else { ret = SQL_SUCCESS; } if ( message_text ) { if ( ret == SQL_SUCCESS ) { wide_strcpy( message_text, ptr -> msg ); } else { memcpy( message_text, ptr -> msg, buffer_length * 2 ); message_text[ buffer_length - 1 ] = '\0'; } } if ( text_length ) { *text_length = wide_strlen( ptr -> msg ); } if ( native_error ) { *native_error = ptr -> native_error; } /* * map 3 to 2 if required */ if ( SQL_SUCCEEDED( ret ) && sqlstate ) __map_error_state_w( sqlstate, __get_version( head )); return ret; } } else { return SQL_NO_DATA; } } SQLRETURN SQLGetDiagRecW( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT rec_number, SQLWCHAR *sqlstate, SQLINTEGER *native, SQLWCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length_ptr ) { SQLRETURN ret; SQLCHAR s0[ 48 ], s1[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s3[ 100 + LOG_MESSAGE_LEN ]; DMHENV environment = ( DMHENV ) handle; DMHDBC connection = NULL; DMHSTMT statement = NULL; DMHDESC descriptor = NULL; EHEAD *herror; char *handle_msg; const char *handle_type_ptr; if ( rec_number < 1 ) { return SQL_ERROR; } switch ( handle_type ) { case SQL_HANDLE_ENV: { if ( !__validate_env( environment )) { return extract_parent_handle_rec( environment, handle_type, rec_number, sqlstate, native, message_text, buffer_length, text_length_ptr ); } herror = &environment->error; handle_msg = environment->msg; handle_type_ptr = "Environment"; } break; case SQL_HANDLE_DBC: { connection = ( DMHDBC ) handle; if ( !__validate_dbc( connection )) { return extract_parent_handle_rec( connection, handle_type, rec_number, sqlstate, native, message_text, buffer_length, text_length_ptr); } herror = &connection->error; handle_msg = connection->msg; handle_type_ptr = "Connection"; } break; case SQL_HANDLE_STMT: { statement = ( DMHSTMT ) handle; if ( !__validate_stmt( statement )) { return extract_parent_handle_rec( statement, handle_type, rec_number, sqlstate, native, message_text, buffer_length, text_length_ptr ); } connection = statement->connection; herror = &statement->error; handle_msg = statement->msg; handle_type_ptr = "Statement"; } break; case SQL_HANDLE_DESC: { descriptor = ( DMHDESC ) handle; if ( !__validate_desc( descriptor )) { return extract_parent_handle_rec( descriptor, handle_type, rec_number, sqlstate, native, message_text, buffer_length, text_length_ptr ); } connection = descriptor->connection; herror = &descriptor->error; handle_msg = descriptor->msg; handle_type_ptr = "Descriptor"; } break; default: { return SQL_NO_DATA; } } thread_protect( handle_type, handle ); if ( log_info.log_flag ) { sprintf( handle_msg, "\n\t\tEntry:\ \n\t\t\t%s = %p\ \n\t\t\tRec Number = %d\ \n\t\t\tSQLState = %p\ \n\t\t\tNative = %p\ \n\t\t\tMessage Text = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tText Len Ptr = %p", handle_type_ptr, handle, rec_number, sqlstate, native, message_text, buffer_length, text_length_ptr ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, handle_msg ); } /* * Do diag extraction here if defer flag is set. * Clean the flag after extraction. */ if ( connection && herror->defer_extract ) { extract_error_from_driver( herror, connection, herror->ret_code_deferred, 0 ); herror->defer_extract = 0; herror->ret_code_deferred = 0; } ret = extract_sql_error_rec_w( herror, sqlstate, rec_number, native, message_text, buffer_length, text_length_ptr ); if ( log_info.log_flag ) { if ( SQL_SUCCEEDED( ret )) { char *ts1, *ts2; sprintf( handle_msg, "\n\t\tExit:[%s]\ \n\t\t\tSQLState = %s\ \n\t\t\tNative = %s\ \n\t\t\tMessage Text = %s", __get_return_status( ret, s2 ), __sdata_as_string( s3, SQL_CHAR, NULL, ts1 = unicode_to_ansi_alloc(sqlstate, SQL_NTS, connection, NULL )), __iptr_as_string( s0, native ), __sdata_as_string( s1, SQL_CHAR, text_length_ptr, ts2 = unicode_to_ansi_alloc(message_text, SQL_NTS, connection, NULL ))); if ( ts1 ) { free( ts1 ); } if ( ts2 ) { free( ts2 ); } } else { sprintf( handle_msg, "\n\t\tExit:[%s]", __get_return_status( ret, s2 )); } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, handle_msg ); } thread_release( handle_type, handle ); return ret; } unixODBC-2.3.12/DriverManager/SQLGetEnvAttr.c000066400000000000000000000170411446441710500205200ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetEnvAttr.c,v 1.6 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetEnvAttr.c,v $ * Revision 1.6 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.4 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2001/10/29 09:54:53 lurcher * * Add automake to libodbcinstQ * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:17 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetEnvAttr.c,v $ $Revision: 1.6 $"; SQLRETURN SQLGetEnvAttr( SQLHENV environment_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { DMHENV environment = (DMHENV) environment_handle; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check environment */ if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( environment ); if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tEntry:\ \n\t\t\tEnvironment = %p\ \n\t\t\tAttribute = %s\ \n\t\t\tValue = %p\ \n\t\t\tBuffer Len = %d\ \n\t\t\tStrLen = %p", environment, __env_attr_as_string( s1, attribute ), value, (int)buffer_length, (void*)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } thread_protect( SQL_HANDLE_ENV, environment ); switch ( attribute ) { case SQL_ATTR_CONNECTION_POOLING: if ( value ) { memcpy( value, &environment -> connection_pooling, sizeof( environment -> connection_pooling )); } break; case SQL_ATTR_CP_MATCH: if ( value ) { memcpy( value, &environment -> cp_match, sizeof( environment -> cp_match )); } break; case SQL_ATTR_ODBC_VERSION: if ( !environment -> version_set ) { __post_internal_error( &environment -> error, ERROR_HY010, NULL, SQL_OV_ODBC3 ); return function_return( SQL_HANDLE_ENV, environment, SQL_ERROR, DEFER_R0 ); } if ( value ) { memcpy( value, &environment -> requested_version, sizeof( environment -> requested_version )); } break; case SQL_ATTR_OUTPUT_NTS: if ( value ) { SQLINTEGER i = SQL_TRUE; memcpy( value, &i, sizeof( i )); } break; /* * unixODBC additions */ case SQL_ATTR_UNIXODBC_VERSION: if ( value ) { if ( buffer_length >= strlen( VERSION )) { strcpy( value, VERSION ); } else { memcpy( value, VERSION, buffer_length ); ((char*)value)[ buffer_length ] = '\0'; } if ( string_length ) { *string_length = strlen( VERSION ); } } break; case SQL_ATTR_UNIXODBC_SYSPATH: if ( value ) { char b1[ 512 ]; if ( buffer_length >= strlen( odbcinst_system_file_path( b1 ))) { strcpy( value, odbcinst_system_file_path( b1 )); } else { memcpy( value, odbcinst_system_file_path( b1 ), buffer_length ); ((char*)value)[ buffer_length ] = '\0'; } if ( string_length ) { *string_length = strlen( odbcinst_system_file_path( b1 )); } } break; default: dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &environment -> error, ERROR_HY092, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } return function_return( SQL_HANDLE_ENV, environment, SQL_SUCCESS, DEFER_R0 ); } unixODBC-2.3.12/DriverManager/SQLGetFunctions.c000066400000000000000000000147401446441710500211100ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetFunctions.c,v 1.5 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetFunctions.c,v $ * Revision 1.5 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.4 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetFunctions.c,v $ $Revision: 1.5 $"; SQLRETURN SQLGetFunctions( SQLHDBC connection_handle, SQLUSMALLINT function_id, SQLUSMALLINT *supported ) { DMHDBC connection = (DMHDBC)connection_handle; SQLCHAR s0[ 24 ], s1[ 100 + LOG_MESSAGE_LEN ]; /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tId = %s\ \n\t\t\tSupported = %p", connection, __fid_as_string( s1, function_id ), supported ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( function_id == SQL_API_SQLGETFUNCTIONS || function_id == SQL_API_SQLDATASOURCES || function_id == SQL_API_SQLDRIVERS || function_id == SQL_API_SQLGETENVATTR || function_id == SQL_API_SQLSETENVATTR ) { *supported = SQL_TRUE; return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_SUCCESS ); } if ( connection -> state == STATE_C3 || connection -> state == STATE_C2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if (( function_id > SQL_API_SQLBULKOPERATIONS && function_id < SQL_API_SQLCOLUMNS ) || ( function_id > SQL_API_SQLALLOCHANDLESTD && function_id < SQL_API_LOADBYORDINAL ) || ( function_id > SQL_API_LOADBYORDINAL && function_id < SQL_API_ODBC3_ALL_FUNCTIONS ) || ( function_id > SQL_API_ODBC3_ALL_FUNCTIONS && function_id < SQL_API_SQLALLOCHANDLE ) || function_id > SQL_API_SQLFETCHSCROLL ) { __post_internal_error( &connection -> error, ERROR_HY095, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } __check_for_function( connection, function_id, supported ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]\ \n\t\t\tSupported = %s", __get_return_status( SQL_SUCCESS, s0 ), __sptr_as_string( s1, (short*)supported )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_SUCCESS ); } unixODBC-2.3.12/DriverManager/SQLGetInfo.c000066400000000000000000000437111446441710500200330ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetInfo.c,v 1.14 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetInfo.c,v $ * Revision 1.14 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.13 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.12 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.11 2007/01/02 10:29:18 lurcher * Fix descriptor leak with unicode only driver * * Revision 1.10 2006/08/31 12:44:52 lurcher * Check in for 2.2.12 release * * Revision 1.9 2006/01/06 18:44:35 lurcher * Couple of unicode fixes * * Revision 1.8 2005/10/06 08:50:58 lurcher * Fix problem with SQLDrivers not returning first entry * * Revision 1.7 2004/11/22 17:02:49 lurcher * Fix unicode/ansi conversion in the SQLGet functions * * Revision 1.6 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2003/03/05 09:48:44 lurcher * * Add some 64 bit fixes * * Revision 1.4 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.9 2001/07/31 12:03:46 nick * * Fix how the DM gets the CLI year for SQLGetInfo * Fix small bug in strncasecmp * * Revision 1.8 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.7 2001/04/23 13:58:43 nick * * Assorted tweeks to text driver to get it to work with StarOffice * * Revision 1.6 2001/04/18 15:03:37 nick * * Fix problem when going to DB2 unicode driver * * Revision 1.5 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.4 2001/01/12 19:43:12 nick * * Fixed UNICODE conversion bug in SQLGetInfo * * Revision 1.3 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.2 2000/09/08 08:58:17 nick * * Add SQL_DRIVER_HDESC to SQLGetinfo * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.9 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.8 1999/11/10 03:51:34 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.7 1999/10/29 21:07:40 ngorham * * Fix some stupid bugs in the DM * Make the postgres driver work via unix sockets * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetInfo.c,v $ $Revision: 1.14 $"; SQLRETURN SQLGetInfoA( SQLHDBC connection_handle, SQLUSMALLINT info_type, SQLPOINTER info_value, SQLSMALLINT buffer_length, SQLSMALLINT *string_length ) { return SQLGetInfo( connection_handle, info_type, info_value, buffer_length, string_length ); } SQLRETURN SQLGetInfoInternal( SQLHDBC connection_handle, SQLUSMALLINT info_type, SQLPOINTER info_value, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, int do_checks ) { DMHDBC connection = (DMHDBC)connection_handle; SQLRETURN ret = SQL_SUCCESS; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; int type; SQLUSMALLINT sval; char txt[ 30 ], *cptr; SQLPOINTER *ptr; if ( do_checks ) { if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tInfo Type = %s (%d)\ \n\t\t\tInfo Value = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tStrLen = %p", connection, __info_as_string( s1, info_type ), info_type, info_value, (int)buffer_length, (void*)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( info_type != SQL_ODBC_VER && info_type != SQL_DM_VER && connection -> state == STATE_C2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else if ( connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( buffer_length < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } switch ( info_type ) { case SQL_DATA_SOURCE_NAME: type = 1; cptr = connection -> dsn; break; case SQL_DM_VER: type = 1; sprintf( txt, "%02d.%02d.%04d.%04d", SQL_SPEC_MAJOR, SQL_SPEC_MINOR, atoi( VERSION ), atoi( VERSION + 2 )); cptr = txt; break; case SQL_ODBC_VER: type = 1; sprintf( txt, "%02d.%02d", SQL_SPEC_MAJOR, SQL_SPEC_MINOR ); cptr = txt; break; case SQL_DRIVER_HDBC: type = 2; ptr = (SQLPOINTER) connection -> driver_dbc; break; case SQL_DRIVER_HENV: type = 2; ptr = (SQLPOINTER) connection -> driver_env; break; case SQL_DRIVER_HDESC: { DMHDESC hdesc; if ( info_value && __validate_desc ( hdesc = *(DMHDESC*) info_value ) ) { type = 2; ptr = (SQLPOINTER) hdesc -> driver_desc; } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return do_checks ? function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ) : SQL_ERROR; } } break; case SQL_DRIVER_HLIB: type = 2; ptr = connection -> dl_handle; break; case SQL_DRIVER_HSTMT: { DMHSTMT hstmt; if ( info_value && __validate_stmt( hstmt = *(DMHSTMT*)info_value ) ) { type = 2; ptr = (SQLPOINTER) hstmt -> driver_stmt; } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return do_checks ? function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ) : SQL_ERROR; } } break; case SQL_XOPEN_CLI_YEAR: type = 1; cptr = connection -> cli_year; break; case SQL_ATTR_DRIVER_THREADING: type = 3; sval = connection -> threading_level; break; default: /* * pass all the others on */ if ( connection -> unicode_driver ) { SQLWCHAR *s1 = NULL; if ( !CHECK_SQLGETINFOW( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return do_checks ? function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ) : SQL_ERROR; } switch( info_type ) { case SQL_ACCESSIBLE_PROCEDURES: case SQL_ACCESSIBLE_TABLES: case SQL_CATALOG_NAME: case SQL_CATALOG_NAME_SEPARATOR: case SQL_CATALOG_TERM: case SQL_COLLATION_SEQ: case SQL_COLUMN_ALIAS: case SQL_DATA_SOURCE_NAME: case SQL_DATA_SOURCE_READ_ONLY: case SQL_DATABASE_NAME: case SQL_DBMS_NAME: case SQL_DBMS_VER: case SQL_DESCRIBE_PARAMETER: case SQL_DRIVER_NAME: case SQL_DRIVER_ODBC_VER: case SQL_DRIVER_VER: case SQL_ODBC_VER: case SQL_EXPRESSIONS_IN_ORDERBY: case SQL_IDENTIFIER_QUOTE_CHAR: case SQL_INTEGRITY: case SQL_KEYWORDS: case SQL_LIKE_ESCAPE_CLAUSE: case SQL_MAX_ROW_SIZE_INCLUDES_LONG: case SQL_MULT_RESULT_SETS: case SQL_MULTIPLE_ACTIVE_TXN: case SQL_NEED_LONG_DATA_LEN: case SQL_ORDER_BY_COLUMNS_IN_SELECT: case SQL_PROCEDURE_TERM: case SQL_PROCEDURES: case SQL_ROW_UPDATES: case SQL_SCHEMA_TERM: case SQL_SEARCH_PATTERN_ESCAPE: case SQL_SERVER_NAME: case SQL_SPECIAL_CHARACTERS: case SQL_TABLE_TERM: case SQL_USER_NAME: case SQL_XOPEN_CLI_YEAR: case SQL_OUTER_JOINS: if ( info_value && buffer_length > 0 ) { buffer_length = sizeof( SQLWCHAR ) * ( buffer_length + 1 ); s1 = malloc( buffer_length ); } break; } ret = SQLGETINFOW( connection, connection -> driver_dbc, info_type, s1 ? s1 : info_value, buffer_length, string_length ); switch( info_type ) { case SQL_ACCESSIBLE_PROCEDURES: case SQL_ACCESSIBLE_TABLES: case SQL_CATALOG_NAME: case SQL_CATALOG_NAME_SEPARATOR: case SQL_CATALOG_TERM: case SQL_COLLATION_SEQ: case SQL_COLUMN_ALIAS: case SQL_DATA_SOURCE_NAME: case SQL_DATA_SOURCE_READ_ONLY: case SQL_DATABASE_NAME: case SQL_DBMS_NAME: case SQL_DBMS_VER: case SQL_DESCRIBE_PARAMETER: case SQL_DRIVER_NAME: case SQL_DRIVER_ODBC_VER: case SQL_DRIVER_VER: case SQL_ODBC_VER: case SQL_EXPRESSIONS_IN_ORDERBY: case SQL_IDENTIFIER_QUOTE_CHAR: case SQL_INTEGRITY: case SQL_KEYWORDS: case SQL_LIKE_ESCAPE_CLAUSE: case SQL_MAX_ROW_SIZE_INCLUDES_LONG: case SQL_MULT_RESULT_SETS: case SQL_MULTIPLE_ACTIVE_TXN: case SQL_NEED_LONG_DATA_LEN: case SQL_ORDER_BY_COLUMNS_IN_SELECT: case SQL_PROCEDURE_TERM: case SQL_PROCEDURES: case SQL_ROW_UPDATES: case SQL_SCHEMA_TERM: case SQL_SEARCH_PATTERN_ESCAPE: case SQL_SERVER_NAME: case SQL_SPECIAL_CHARACTERS: case SQL_TABLE_TERM: case SQL_USER_NAME: case SQL_XOPEN_CLI_YEAR: case SQL_OUTER_JOINS: if ( SQL_SUCCEEDED( ret ) && info_value && s1 ) { unicode_to_ansi_copy( info_value, buffer_length, s1, SQL_NTS, connection, NULL ); } if ( SQL_SUCCEEDED( ret ) && string_length && info_value ) { *string_length = strlen(info_value); } break; } if ( s1 ) { free( s1 ); } } else { if ( !CHECK_SQLGETINFO( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return do_checks ? function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ) : SQL_ERROR; } ret = SQLGETINFO( connection, connection -> driver_dbc, info_type, info_value, buffer_length, string_length ); } return do_checks ? function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 ) : ret; } if ( type == 1 ) { if ( string_length ) *string_length = strlen( cptr ); if ( info_value ) { if ( buffer_length > strlen( cptr ) + 1 ) { strcpy( info_value, cptr ); } else { memcpy( info_value, cptr, buffer_length - 1 ); ((char*)info_value)[ buffer_length - 1 ] = '\0'; ret = SQL_SUCCESS_WITH_INFO; } } } else if ( type == 2 ) { if ( info_value ) *((void **)info_value) = ptr; if ( string_length ) *string_length = sizeof( SQLPOINTER ); } else if ( type == 3 ) { if ( info_value ) *((SQLUSMALLINT *)info_value) = sval; if ( string_length ) *string_length = sizeof( SQLUSMALLINT ); } return do_checks ? function_return_nodrv( SQL_HANDLE_DBC, connection, ret ) : ret; } SQLRETURN __SQLGetInfo( SQLHDBC connection_handle, SQLUSMALLINT info_type, SQLPOINTER info_value, SQLSMALLINT buffer_length, SQLSMALLINT *string_length ) { return SQLGetInfoInternal( connection_handle, info_type, info_value, buffer_length, string_length, 0); } SQLRETURN SQLGetInfo( SQLHDBC connection_handle, SQLUSMALLINT info_type, SQLPOINTER info_value, SQLSMALLINT buffer_length, SQLSMALLINT *string_length ) { return SQLGetInfoInternal( connection_handle, info_type, info_value, buffer_length, string_length, 1); } unixODBC-2.3.12/DriverManager/SQLGetInfoW.c000066400000000000000000000426741446441710500201710ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetInfoW.c,v 1.14 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetInfoW.c,v $ * Revision 1.14 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.13 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.12 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.11 2005/10/06 08:50:58 lurcher * Fix problem with SQLDrivers not returning first entry * * Revision 1.10 2004/11/22 17:02:49 lurcher * Fix unicode/ansi conversion in the SQLGet functions * * Revision 1.9 2004/11/20 13:21:38 lurcher * Fix unicode bug in SQLGetInfoW * * Revision 1.8 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.7 2003/03/05 09:48:44 lurcher * * Add some 64 bit fixes * * Revision 1.6 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.5 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.4 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.3 2002/05/21 14:19:44 lurcher * * * Update libtool to escape from AIX build problem * * Add fix to avoid file handle limitations * * Add more UNICODE changes, it looks like it is native 16 representation * the old way can be reproduced by defining UCS16BE * * Add iusql, its just the same as isql but uses the wide functions * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetInfoW.c,v $"; SQLRETURN SQLGetInfoW( SQLHDBC connection_handle, SQLUSMALLINT info_type, SQLPOINTER info_value, SQLSMALLINT buffer_length, SQLSMALLINT *string_length ) { DMHDBC connection = (DMHDBC)connection_handle; SQLRETURN ret = SQL_SUCCESS; int type; char txt[ 30 ], *cptr; SQLPOINTER *ptr; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; SQLUSMALLINT sval; /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHDBC parent_connection; parent_connection = find_parent_handle( connection, SQL_HANDLE_DBC ); if ( parent_connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLGETINFOW( parent_connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLGETINFOW( parent_connection, connection_handle, info_type, info_value, buffer_length, string_length ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tInfo Type = %s\ \n\t\t\tInfo Value = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tStrLen = %p", connection, __info_as_string( s1, info_type ), info_value, (int)buffer_length, (void*)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( info_type != SQL_ODBC_VER && info_type != SQL_DM_VER && connection -> state == STATE_C2 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else if ( connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( buffer_length < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } switch ( info_type ) { case SQL_DATA_SOURCE_NAME: type = 1; cptr = connection -> dsn; break; case SQL_DM_VER: type = 1; sprintf( txt, "%02d.%02d.%04d.%04d", SQL_SPEC_MAJOR, SQL_SPEC_MINOR, atoi( VERSION ), atoi( VERSION + 2 )); cptr = txt; break; case SQL_ODBC_VER: type = 1; sprintf( txt, "%02d.%02d", SQL_SPEC_MAJOR, SQL_SPEC_MINOR ); cptr = txt; break; case SQL_DRIVER_HDBC: type = 2; ptr = (SQLPOINTER) connection -> driver_dbc; break; case SQL_DRIVER_HENV: type = 2; ptr = (SQLPOINTER) connection -> driver_env; break; case SQL_DRIVER_HDESC: { DMHDESC hdesc; if ( info_value && __validate_desc ( hdesc = *(DMHDESC*) info_value ) ) { type = 2; ptr = (SQLPOINTER) hdesc -> driver_desc; } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } break; case SQL_DRIVER_HLIB: type = 2; ptr = connection -> dl_handle; break; case SQL_DRIVER_HSTMT: { DMHSTMT hstmt; if ( info_value && __validate_stmt( hstmt = *(DMHSTMT*)info_value ) ) { type = 2; ptr = (SQLPOINTER) hstmt -> driver_stmt; } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } break; case SQL_XOPEN_CLI_YEAR: type = 1; cptr = "1994"; break; case SQL_ATTR_DRIVER_THREADING: type = 3; sval = connection -> threading_level; break; default: /* * pass all the others on */ if ( connection -> unicode_driver || CHECK_SQLGETINFOW( connection )) { if ( !CHECK_SQLGETINFOW( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } ret = SQLGETINFOW( connection, connection -> driver_dbc, info_type, info_value, buffer_length, string_length ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } } else { SQLCHAR *as1 = NULL; if ( !CHECK_SQLGETINFO( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } switch( info_type ) { case SQL_ACCESSIBLE_PROCEDURES: case SQL_ACCESSIBLE_TABLES: case SQL_CATALOG_NAME: case SQL_CATALOG_NAME_SEPARATOR: case SQL_CATALOG_TERM: case SQL_COLLATION_SEQ: case SQL_COLUMN_ALIAS: case SQL_DATA_SOURCE_NAME: case SQL_DATA_SOURCE_READ_ONLY: case SQL_DATABASE_NAME: case SQL_DBMS_NAME: case SQL_DBMS_VER: case SQL_DESCRIBE_PARAMETER: case SQL_DRIVER_NAME: case SQL_DRIVER_ODBC_VER: case SQL_DRIVER_VER: case SQL_ODBC_VER: case SQL_EXPRESSIONS_IN_ORDERBY: case SQL_IDENTIFIER_QUOTE_CHAR: case SQL_INTEGRITY: case SQL_KEYWORDS: case SQL_LIKE_ESCAPE_CLAUSE: case SQL_MAX_ROW_SIZE_INCLUDES_LONG: case SQL_MULT_RESULT_SETS: case SQL_MULTIPLE_ACTIVE_TXN: case SQL_NEED_LONG_DATA_LEN: case SQL_ORDER_BY_COLUMNS_IN_SELECT: case SQL_PROCEDURE_TERM: case SQL_PROCEDURES: case SQL_ROW_UPDATES: case SQL_SCHEMA_TERM: case SQL_SEARCH_PATTERN_ESCAPE: case SQL_SERVER_NAME: case SQL_SPECIAL_CHARACTERS: case SQL_TABLE_TERM: case SQL_USER_NAME: case SQL_XOPEN_CLI_YEAR: case SQL_OUTER_JOINS: if ( SQL_SUCCEEDED( ret ) && info_value && buffer_length > 0 ) { as1 = malloc( buffer_length + 1 ); } break; } ret = SQLGETINFO( connection, connection -> driver_dbc, info_type, as1 ? as1 : info_value, buffer_length, string_length ); switch( info_type ) { case SQL_ACCESSIBLE_PROCEDURES: case SQL_ACCESSIBLE_TABLES: case SQL_CATALOG_NAME: case SQL_CATALOG_NAME_SEPARATOR: case SQL_CATALOG_TERM: case SQL_COLLATION_SEQ: case SQL_COLUMN_ALIAS: case SQL_DATA_SOURCE_NAME: case SQL_DATA_SOURCE_READ_ONLY: case SQL_DATABASE_NAME: case SQL_DBMS_NAME: case SQL_DBMS_VER: case SQL_DESCRIBE_PARAMETER: case SQL_DRIVER_NAME: case SQL_DRIVER_ODBC_VER: case SQL_DRIVER_VER: case SQL_ODBC_VER: case SQL_EXPRESSIONS_IN_ORDERBY: case SQL_IDENTIFIER_QUOTE_CHAR: case SQL_INTEGRITY: case SQL_KEYWORDS: case SQL_LIKE_ESCAPE_CLAUSE: case SQL_MAX_ROW_SIZE_INCLUDES_LONG: case SQL_MULT_RESULT_SETS: case SQL_MULTIPLE_ACTIVE_TXN: case SQL_NEED_LONG_DATA_LEN: case SQL_ORDER_BY_COLUMNS_IN_SELECT: case SQL_PROCEDURE_TERM: case SQL_PROCEDURES: case SQL_ROW_UPDATES: case SQL_SCHEMA_TERM: case SQL_SEARCH_PATTERN_ESCAPE: case SQL_SERVER_NAME: case SQL_SPECIAL_CHARACTERS: case SQL_TABLE_TERM: case SQL_USER_NAME: case SQL_XOPEN_CLI_YEAR: case SQL_OUTER_JOINS: if ( SQL_SUCCEEDED( ret ) && info_value && as1 ) { ansi_to_unicode_copy( info_value, (char*) as1, SQL_NTS, connection, NULL ); } if ( SQL_SUCCEEDED( ret ) && string_length ) { *string_length *= sizeof( SQLWCHAR ); } break; } if ( as1 ) free( as1 ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 ); } if ( type == 1 ) { SQLWCHAR *s1; int len; s1 = ansi_to_unicode_alloc((SQLCHAR*) cptr, SQL_NTS, connection, NULL ); len = strlen( cptr ) * sizeof( SQLWCHAR ); if ( string_length ) *string_length = len; if ( info_value ) { if ( buffer_length > len + 1 ) { wide_strcpy( info_value, s1 ); } else { memcpy( info_value, s1, ( buffer_length - 1 * sizeof( SQLWCHAR ))); ((SQLWCHAR*)info_value)[ buffer_length - 1 ] = '\0'; ret = SQL_SUCCESS_WITH_INFO; } } if ( s1 ) free( s1 ); } else if ( type == 2 ) { if ( info_value ) *((void **)info_value) = ptr; if ( string_length ) *string_length = sizeof( SQLPOINTER ); } else if ( type == 3 ) { if ( info_value ) *((SQLUSMALLINT *)info_value) = sval; if ( string_length ) *string_length = sizeof( SQLUSMALLINT ); } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return_nodrv( SQL_HANDLE_DBC, connection, ret ); } unixODBC-2.3.12/DriverManager/SQLGetStmtAttr.c000066400000000000000000000403101446441710500207120ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetStmtAttr.c,v 1.8 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetStmtAttr.c,v $ * Revision 1.8 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.7 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.6 2009/02/04 09:30:02 lurcher * Fix some SQLINTEGER/SQLLEN conflicts * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/16 13:08:18 lurcher * * Filter attribute values from SQLSetStmtAttr to SQLSetStmtOption to fit * within ODBC 2 * Make DSN's double clickable in ODBCConfig * * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher * * First upload to SourceForge * * Revision 1.5 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.4 2001/04/18 15:03:37 nick * * Fix problem when going to DB2 unicode driver * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.11 2000/06/24 18:45:09 ngorham * * Fix for SQLExtendedFetch on big endian platforms. the row count pointer * was declared as a small not a int. * * Revision 1.10 2000/02/06 23:26:10 ngorham * * Fix bug with missing '&' with SQLGetStmtAttr * * Revision 1.9 1999/11/13 23:40:59 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.8 1999/10/29 21:07:40 ngorham * * Fix some stupid bugs in the DM * Make the postgres driver work via unix sockets * * Revision 1.7 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.6 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.5 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.4 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.3 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.2 1999/06/19 17:51:40 ngorham * * Applied assorted minor bug fixes * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.4 1999/06/02 23:48:45 ngorham * * Added more 3-2 mapping * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:20 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetStmtAttr.c,v $ $Revision: 1.8 $"; SQLRETURN SQLGetStmtAttrA( SQLHSTMT statement_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { return SQLGetStmtAttr( statement_handle, attribute, value, buffer_length, string_length ); } SQLRETURN SQLGetStmtAttr( SQLHSTMT statement_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tAttribute = %s\ \n\t\t\tValue = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tStrLen = %p", statement, __stmt_attr_as_string( s1, attribute ), value, (int)buffer_length, (void*)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( attribute == SQL_ATTR_ROW_NUMBER || attribute == SQL_GET_BOOKMARK ) { if ( statement -> state == STATE_S1 || statement -> state == STATE_S2 || statement -> state == STATE_S3 || statement -> state == STATE_S4 || statement -> state == STATE_S5 || (( statement -> state == STATE_S6 || statement -> state == STATE_S7 ) && statement -> eod )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * states S5 - S7 are handled by the driver */ if ( statement -> connection -> unicode_driver ) { if ( !CHECK_SQLGETSTMTATTRW( statement -> connection ) && !CHECK_SQLGETSTMTOPTIONW( statement -> connection ) && !CHECK_SQLGETSTMTATTR( statement -> connection ) && !CHECK_SQLGETSTMTOPTION( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } else { if ( !CHECK_SQLGETSTMTATTR( statement -> connection ) && !CHECK_SQLGETSTMTOPTION( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * map descriptors to our copies */ if ( attribute == SQL_ATTR_APP_ROW_DESC ) { if ( value ) memcpy( value, &statement -> ard, sizeof( statement -> ard )); ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_APP_PARAM_DESC ) { if ( value ) memcpy( value, &statement -> apd, sizeof( SQLHANDLE )); ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_IMP_ROW_DESC ) { if ( value ) memcpy( value, &statement -> ird, sizeof( SQLHANDLE )); ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_IMP_PARAM_DESC ) { if ( value ) memcpy( value, &statement -> ipd, sizeof( SQLHANDLE )); ret = SQL_SUCCESS; } /* * does the call need mapping from 3 to 2 */ else if ( attribute == SQL_ATTR_FETCH_BOOKMARK_PTR && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && CHECK_SQLEXTENDEDFETCH( statement -> connection )) { if ( value ) memcpy( value, &statement -> fetch_bm_ptr, sizeof( SQLULEN * )); ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_ROW_STATUS_PTR && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && CHECK_SQLEXTENDEDFETCH( statement -> connection )) { if ( value ) memcpy( value, &statement -> row_st_arr, sizeof( SQLULEN * )); ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_ROWS_FETCHED_PTR && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && CHECK_SQLEXTENDEDFETCH( statement -> connection )) { if ( value ) memcpy( value, &statement -> row_ct_ptr, sizeof( SQLULEN * )); ret = SQL_SUCCESS; } else if ( statement -> connection -> unicode_driver && attribute == SQL_ATTR_ROW_ARRAY_SIZE && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 ) { if ( CHECK_SQLGETSTMTATTRW( statement -> connection )) { ret = SQLGETSTMTATTRW( statement -> connection, statement -> driver_stmt, SQL_ROWSET_SIZE, value, buffer_length, string_length ); } else { ret = SQLGETSTMTATTR( statement -> connection, statement -> driver_stmt, SQL_ROWSET_SIZE, value, buffer_length, string_length ); } } else if ( !statement -> connection -> unicode_driver && attribute == SQL_ATTR_ROW_ARRAY_SIZE && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && CHECK_SQLGETSTMTATTR( statement -> connection )) { ret = SQLGETSTMTATTR( statement -> connection, statement -> driver_stmt, SQL_ROWSET_SIZE, value, buffer_length, string_length ); } else if ( attribute == SQL_ATTR_ROW_ARRAY_SIZE && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 ) { if ( statement -> connection -> unicode_driver && CHECK_SQLGETSTMTOPTIONW( statement -> connection )) { ret = SQLGETSTMTOPTIONW( statement -> connection, statement -> driver_stmt, SQL_ROWSET_SIZE, value ); } else { ret = SQLGETSTMTOPTION( statement -> connection, statement -> driver_stmt, SQL_ROWSET_SIZE, value ); } } else if ( statement -> connection -> unicode_driver && ( CHECK_SQLGETSTMTATTRW( statement -> connection ) || CHECK_SQLGETSTMTATTR( statement -> connection ))) { if ( CHECK_SQLGETSTMTATTR( statement -> connection )) { ret = SQLGETSTMTATTR( statement -> connection, statement -> driver_stmt, attribute, value, buffer_length, string_length ); } else { ret = SQLGETSTMTATTRW( statement -> connection, statement -> driver_stmt, attribute, value, buffer_length, string_length ); } } else if ( !statement -> connection -> unicode_driver && CHECK_SQLGETSTMTATTR( statement -> connection )) { ret = SQLGETSTMTATTR( statement -> connection, statement -> driver_stmt, attribute, value, buffer_length, string_length ); } else if ( statement -> connection -> unicode_driver && CHECK_SQLGETSTMTOPTIONW( statement -> connection )) { /* * Is it in the legal range of values */ if ( attribute < SQL_STMT_DRIVER_MIN && ( attribute > SQL_ROW_NUMBER || attribute < SQL_QUERY_TIMEOUT )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &statement -> error, ERROR_HY092, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLGETSTMTOPTIONW( statement -> connection, statement -> driver_stmt, attribute, value ); } else { /* * Is it in the legal range of values */ if ( attribute < SQL_STMT_DRIVER_MIN && ( attribute > SQL_ROW_NUMBER || attribute < SQL_QUERY_TIMEOUT )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &statement -> error, ERROR_HY092, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLGETSTMTOPTION( statement -> connection, statement -> driver_stmt, attribute, value ); } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLGetStmtAttrW.c000066400000000000000000000245451446441710500210550ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetStmtAttrW.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetStmtAttrW.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2009/02/04 09:30:02 lurcher * Fix some SQLINTEGER/SQLLEN conflicts * * Revision 1.5 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.4 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.3 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.2 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetStmtAttrW.c,v $"; SQLRETURN SQLGetStmtAttrW( SQLHSTMT statement_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLGETSTMTATTRW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLGETSTMTATTRW( parent_statement -> connection, statement_handle, attribute, value, buffer_length, string_length ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tAttribute = %s\ \n\t\t\tValue = %p\ \n\t\t\tBuffer Length = %d\ \n\t\t\tStrLen = %p", statement, __stmt_attr_as_string( s1, attribute ), value, (int)buffer_length, (void*)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( attribute == SQL_ATTR_ROW_NUMBER || attribute == SQL_GET_BOOKMARK ) { if ( statement -> state == STATE_S1 || statement -> state == STATE_S2 || statement -> state == STATE_S3 || statement -> state == STATE_S4 || statement -> state == STATE_S5 || (( statement -> state == STATE_S6 || statement -> state == STATE_S7 ) && statement -> eod )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * states S5 - S7 are handled by the driver */ if ( statement -> connection -> unicode_driver || CHECK_SQLGETSTMTATTRW( statement -> connection )) { if ( !CHECK_SQLGETSTMTATTRW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } else { if ( !CHECK_SQLGETSTMTATTR( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * map descriptors to our copies */ if ( attribute == SQL_ATTR_APP_ROW_DESC ) { if ( value ) memcpy( value, &statement -> ard, sizeof( statement -> ard )); ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_APP_PARAM_DESC ) { if ( value ) memcpy( value, &statement -> apd, sizeof( SQLHANDLE )); ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_IMP_ROW_DESC ) { if ( value ) memcpy( value, &statement -> ird, sizeof( SQLHANDLE )); ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_IMP_PARAM_DESC ) { if ( value ) memcpy( value, &statement -> ipd, sizeof( SQLHANDLE )); ret = SQL_SUCCESS; } /* * does the call need mapping from 3 to 2 */ else if ( attribute == SQL_ATTR_FETCH_BOOKMARK_PTR && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && CHECK_SQLEXTENDEDFETCH( statement -> connection )) { if ( value ) memcpy( value, &statement -> fetch_bm_ptr, sizeof( SQLLEN * )); ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_ROW_STATUS_PTR && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && CHECK_SQLEXTENDEDFETCH( statement -> connection )) { if ( value ) memcpy( value, &statement -> row_st_arr, sizeof( SQLLEN * )); ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_ROWS_FETCHED_PTR && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && CHECK_SQLEXTENDEDFETCH( statement -> connection )) { if ( value ) memcpy( value, &statement -> row_ct_ptr, sizeof( SQLULEN * )); ret = SQL_SUCCESS; } else { if ( statement -> connection -> unicode_driver ) { ret = SQLGETSTMTATTRW( statement -> connection, statement -> driver_stmt, attribute, value, buffer_length, string_length ); } else { /* * don't know if any string attributes to convert... */ ret = SQLGETSTMTATTR( statement -> connection, statement -> driver_stmt, attribute, value, buffer_length, string_length ); } } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLGetStmtOption.c000066400000000000000000000227531446441710500212630ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetStmtOption.c,v 1.4 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetStmtOption.c,v $ * Revision 1.4 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.2 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:07 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.4 1999/06/03 22:20:25 ngorham * * Finished off the ODBC3-2 mapping * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:20 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetStmtOption.c,v $ $Revision: 1.4 $"; SQLRETURN SQLGetStmtOption( SQLHSTMT statement_handle, SQLUSMALLINT option, SQLPOINTER value ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tOption = %s\ \n\t\t\tValue = %p", statement, __stmt_attr_as_string( s1, option ), value ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( option == SQL_ROW_NUMBER || option == SQL_GET_BOOKMARK ) { if (( statement -> state >= STATE_S1 && statement -> state <= STATE_S5 ) || (( statement -> state == STATE_S6 || statement -> state == STATE_S7 ) && statement -> eod )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * states S5 - S7 are handled by the driver */ if ( CHECK_SQLGETSTMTOPTION( statement -> connection )) { ret = SQLGETSTMTOPTION( statement -> connection, statement -> driver_stmt, option, value ); } else if ( CHECK_SQLGETSTMTATTR( statement -> connection )) { switch ( option ) { case SQL_ATTR_APP_PARAM_DESC: if ( value ) memcpy( value, &statement -> apd, sizeof( statement -> apd )); ret = SQL_SUCCESS; break; case SQL_ATTR_APP_ROW_DESC: if ( value ) memcpy( value, &statement -> ard, sizeof( statement -> ard )); ret = SQL_SUCCESS; break; case SQL_ATTR_IMP_PARAM_DESC: if ( value ) memcpy( value, &statement -> ipd, sizeof( statement -> ipd )); ret = SQL_SUCCESS; break; case SQL_ATTR_IMP_ROW_DESC: if ( value ) memcpy( value, &statement -> ird, sizeof( statement -> ird )); ret = SQL_SUCCESS; break; default: ret = SQLGETSTMTATTR( statement -> connection, statement -> driver_stmt, option, value, SQL_MAX_OPTION_STRING_LENGTH, NULL ); break; } } else if ( CHECK_SQLGETSTMTATTRW( statement -> connection )) { switch ( option ) { case SQL_ATTR_APP_PARAM_DESC: if ( value ) memcpy( value, &statement -> apd, sizeof( statement -> apd )); ret = SQL_SUCCESS; break; case SQL_ATTR_APP_ROW_DESC: if ( value ) memcpy( value, &statement -> ard, sizeof( statement -> ard )); ret = SQL_SUCCESS; break; case SQL_ATTR_IMP_PARAM_DESC: if ( value ) memcpy( value, &statement -> ipd, sizeof( statement -> ipd )); ret = SQL_SUCCESS; break; case SQL_ATTR_IMP_ROW_DESC: if ( value ) memcpy( value, &statement -> ird, sizeof( statement -> ird )); ret = SQL_SUCCESS; break; default: ret = SQLGETSTMTATTRW( statement -> connection, statement -> driver_stmt, option, value, SQL_MAX_OPTION_STRING_LENGTH, NULL ); break; } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLGetTypeInfo.c000066400000000000000000000223221446441710500206700ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetTypeInfo.c,v 1.6 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetTypeInfo.c,v $ * Revision 1.6 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.4 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.2 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.5 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.4 2001/04/18 15:03:37 nick * * Fix problem when going to DB2 unicode driver * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/05/03 19:50:43 nick * Another check point * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetTypeInfo.c,v $ $Revision: 1.6 $"; SQLRETURN SQLGetTypeInfoA( SQLHSTMT statement_handle, SQLSMALLINT data_type ) { return SQLGetTypeInfo( statement_handle, data_type ); } SQLRETURN SQLGetTypeInfo( SQLHSTMT statement_handle, SQLSMALLINT data_type ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tData Type = %s", statement, __type_as_string( s1, data_type )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLGETTYPEINFO ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver ) { if ( !CHECK_SQLGETTYPEINFOW( statement -> connection ) && !CHECK_SQLGETTYPEINFO( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( CHECK_SQLGETTYPEINFOW( statement -> connection ) ) { ret = SQLGETTYPEINFOW( statement -> connection , statement -> driver_stmt, data_type ); } else { ret = SQLGETTYPEINFO( statement -> connection , statement -> driver_stmt, data_type ); } } else { if ( !CHECK_SQLGETTYPEINFO( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLGETTYPEINFO( statement -> connection , statement -> driver_stmt, data_type ); } if ( SQL_SUCCEEDED( ret )) { statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLGETTYPEINFO; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLGetTypeInfoW.c000066400000000000000000000210611446441710500210160ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetTypeInfoW.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLGetTypeInfoW.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.5 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.4 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.3 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.2 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLGetTypeInfoW.c,v $"; SQLRETURN SQLGetTypeInfoW( SQLHSTMT statement_handle, SQLSMALLINT data_type ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLGETTYPEINFOW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLGETTYPEINFOW( parent_statement -> connection, statement_handle, data_type ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tData Type = %s", statement, __type_as_string( s1, data_type )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLGETTYPEINFO ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver || CHECK_SQLGETTYPEINFOW( statement -> connection )) { if ( !CHECK_SQLGETTYPEINFOW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLGETTYPEINFOW( statement -> connection , statement -> driver_stmt, data_type ); } else { if ( !CHECK_SQLGETTYPEINFO( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLGETTYPEINFO( statement -> connection , statement -> driver_stmt, data_type ); } if ( SQL_SUCCEEDED( ret )) { statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLGETTYPEINFO; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLMoreResults.c000066400000000000000000000225331446441710500207630ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLMoreResults.c,v 1.8 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLMoreResults.c,v $ * Revision 1.8 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.7 2006/03/08 09:18:41 lurcher * fix silly typo that was using sizeof( SQL_WCHAR ) instead of SQLWCHAR * * Revision 1.6 2003/12/19 16:25:38 lurcher * * Fix incorrect state in SQLMoreResults.c * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/01/27 15:01:01 lurcher * * On error from SQLMoreResults DONT change to S1 * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/08/15 08:10:33 lurcher * * Couple of small fixes from John L Miller * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.9 2000/06/20 12:44:00 ngorham * * Fix bug that caused a success with info message from SQLExecute or * SQLExecDirect to be lost if used with a ODBC 3 driver and the application * called SQLGetDiagRec * * Revision 1.8 2000/06/16 16:52:18 ngorham * * Stop info messages being lost when calling SQLExecute etc on ODBC 3 * drivers, the SQLNumResultCols were clearing the error before * function return had a chance to get to them * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:07 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLMoreResults.c,v $ $Revision: 1.8 $"; SQLRETURN SQLMoreResults( SQLHSTMT statement_handle ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p", statement ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( statement -> state == STATE_S1 || /* statement -> state == STATE_S2 || */ statement -> state == STATE_S3 ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_NO_DATA, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_NO_DATA ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLMORERESULTS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } #ifdef NR_PROBE if ( !CHECK_SQLMORERESULTS( statement -> connection ) || !CHECK_SQLNUMRESULTCOLS( statement -> connection )) #else if ( !CHECK_SQLMORERESULTS( statement -> connection )) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLMORERESULTS( statement -> connection , statement -> driver_stmt ); if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, statement, ret, TRUE, DEFER_R3 ); } SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); if ( statement -> numcols == 0 ) { statement -> state = STATE_S4; } else { statement -> state = STATE_S5; } #else /* * We don't know for sure */ statement -> hascols = 0; statement -> state = STATE_S5; #endif } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLEXECUTE; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else if ( ret == SQL_NO_DATA ) { if ( statement -> prepared ) { if ( statement -> state == STATE_S4 ) { statement -> state = STATE_S2; } else { statement -> state = STATE_S3; } } else { statement -> state = STATE_S1; } } else if ( ret == SQL_NEED_DATA ) { statement -> interupted_func = SQL_API_SQLMORERESULTS; statement -> interupted_state = statement -> state; statement -> state = STATE_S8; } else if ( ret == SQL_PARAM_DATA_AVAILABLE ) { statement -> interupted_func = SQL_API_SQLMORERESULTS; statement -> interupted_state = statement -> state; statement -> state = STATE_S13; } else { /* * Leave the state where it is */ } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLNativeSql.c000066400000000000000000000253451446441710500204110ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLNativeSql.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLNativeSql.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.7 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.6 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.5 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.3 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.4 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.3 2001/01/02 09:55:04 nick * * More unicode bits * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 21:40:58 nick * End of another night :-) * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLNativeSql.c,v $ $Revision: 1.9 $"; SQLRETURN SQLNativeSqlA( SQLHDBC hdbc, SQLCHAR *sz_sql_str_in, SQLINTEGER cb_sql_str_in, SQLCHAR *sz_sql_str, SQLINTEGER cb_sql_str_max, SQLINTEGER *pcb_sql_str ) { return SQLNativeSql( hdbc, sz_sql_str_in, cb_sql_str_in, sz_sql_str, cb_sql_str_max, pcb_sql_str ); } SQLRETURN SQLNativeSql( SQLHDBC hdbc, SQLCHAR *sz_sql_str_in, SQLINTEGER cb_sql_str_in, SQLCHAR *sz_sql_str, SQLINTEGER cb_sql_str_max, SQLINTEGER *pcb_sql_str ) { DMHDBC connection = (DMHDBC)hdbc; SQLRETURN ret; SQLCHAR *s1; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { /* * allocate some space for the buffer */ if ( sz_sql_str_in && cb_sql_str_in == SQL_NTS ) { s1 = malloc( strlen((char*) sz_sql_str_in ) + 100 ); } else if ( sz_sql_str_in ) { s1 = malloc( cb_sql_str_in + 100 ); } else { s1 = malloc( 101 ); } sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tSQL In = %s\ \n\t\t\tSQL Out = %p\ \n\t\t\tSQL Out Len = %d\ \n\t\t\tSQL Len Ptr = %p", connection, __string_with_length( s1, sz_sql_str_in, cb_sql_str_in ), sz_sql_str, (int)cb_sql_str_max, pcb_sql_str ); free( s1 ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( !sz_sql_str_in ) { __post_internal_error( &connection -> error, ERROR_HY009, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( cb_sql_str_in < 0 && cb_sql_str_in != SQL_NTS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( sz_sql_str && cb_sql_str_max < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( connection -> state == STATE_C2 || connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( connection -> unicode_driver ) { SQLWCHAR *s1, *s2 = NULL; if ( !CHECK_SQLNATIVESQLW( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( sz_sql_str_in, cb_sql_str_in, connection, NULL ); if ( sz_sql_str && cb_sql_str_max > 0 ) { s2 = malloc( sizeof( SQLWCHAR ) * ( cb_sql_str_max + 1 )); } ret = SQLNATIVESQLW( connection, connection -> driver_dbc, s1, cb_sql_str_in, s2, cb_sql_str_max, pcb_sql_str ); if ( SQL_SUCCEEDED( ret ) && s2 && sz_sql_str ) { unicode_to_ansi_copy((char*) sz_sql_str, cb_sql_str_max, s2, SQL_NTS, connection, NULL ); } if ( s1 ) free( s1 ); if ( s2 ) free( s2 ); } else { if ( !CHECK_SQLNATIVESQL( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } ret = SQLNATIVESQL( connection, connection -> driver_dbc, sz_sql_str_in, cb_sql_str_in, sz_sql_str, cb_sql_str_max, pcb_sql_str ); } if ( log_info.log_flag ) { /* * allocate some space for the buffer */ if ( sz_sql_str && pcb_sql_str && *pcb_sql_str == SQL_NTS ) { s1 = malloc( strlen((char*) sz_sql_str ) + 100 ); } else if ( sz_sql_str && pcb_sql_str ) { s1 = malloc( *pcb_sql_str + 100 ); } else if ( sz_sql_str ) { s1 = malloc( strlen((char*) sz_sql_str ) + 100 ); } else { s1 = malloc( 101 ); } sprintf( connection -> msg, "\n\t\tExit:[%s]\ \n\t\t\tSQL Out = %s", __get_return_status( ret, s2 ), __idata_as_string( s1, SQL_CHAR, pcb_sql_str, sz_sql_str )); free( s1 ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLNativeSqlW.c000066400000000000000000000243641446441710500205400ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLNativeSqlW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLNativeSqlW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.3 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/01/02 09:55:04 nick * * More unicode bits * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLNativeSqlW.c,v $"; SQLRETURN SQLNativeSqlW( SQLHDBC hdbc, SQLWCHAR *sz_sql_str_in, SQLINTEGER cb_sql_str_in, SQLWCHAR *sz_sql_str, SQLINTEGER cb_sql_str_max, SQLINTEGER *pcb_sql_str ) { DMHDBC connection = (DMHDBC)hdbc; SQLRETURN ret; SQLCHAR *s1; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHDBC parent_connection; parent_connection = find_parent_handle( connection, SQL_HANDLE_DBC ); if ( parent_connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLNATIVESQLW( parent_connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLNATIVESQLW( parent_connection, connection, sz_sql_str_in, cb_sql_str_in, sz_sql_str, cb_sql_str_max, pcb_sql_str ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { /* * allocate some space for the buffer */ if ( sz_sql_str_in && cb_sql_str_in == SQL_NTS ) { s1 = malloc(( wide_strlen( sz_sql_str_in ) * 2 ) + 100 ); } else if ( sz_sql_str_in ) { s1 = malloc( cb_sql_str_in + 100 ); } else { s1 = malloc( 101 ); } sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tSQL In = %s\ \n\t\t\tSQL Out = %p\ \n\t\t\tSQL Out Len = %d\ \n\t\t\tSQL Len Ptr = %p", connection, __wstring_with_length( s1, sz_sql_str_in, cb_sql_str_in ), sz_sql_str, (int)cb_sql_str_max, pcb_sql_str ); free( s1 ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( !sz_sql_str_in ) { __post_internal_error( &connection -> error, ERROR_HY009, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( cb_sql_str_in < 0 && cb_sql_str_in != SQL_NTS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( sz_sql_str && cb_sql_str_max < 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &connection -> error, ERROR_HY090, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( connection -> state == STATE_C2 || connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( connection -> unicode_driver || CHECK_SQLNATIVESQLW( connection )) { if ( !CHECK_SQLNATIVESQLW( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } ret = SQLNATIVESQLW( connection, connection -> driver_dbc, sz_sql_str_in, cb_sql_str_in, sz_sql_str, cb_sql_str_max, pcb_sql_str ); } else { SQLCHAR *as1 = NULL, *as2 = NULL; int clen; if ( !CHECK_SQLNATIVESQL( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } as1 = (SQLCHAR*) unicode_to_ansi_alloc( sz_sql_str_in, cb_sql_str_in, connection, &clen ); cb_sql_str_in = clen; if ( cb_sql_str_max > 0 && sz_sql_str ) { as2 = malloc( cb_sql_str_max + 1 ); } ret = SQLNATIVESQL( connection, connection -> driver_dbc, as1 ? as1 : (SQLCHAR*) sz_sql_str_in, cb_sql_str_in, as2 ? as2 : (SQLCHAR*) sz_sql_str, cb_sql_str_max, pcb_sql_str ); if ( SQL_SUCCEEDED( ret ) && as2 && sz_sql_str ) { ansi_to_unicode_copy( sz_sql_str, (char*) as2, SQL_NTS, connection, NULL ); } if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); } if ( log_info.log_flag ) { /* * allocate some space for the buffer */ if ( sz_sql_str && pcb_sql_str && *pcb_sql_str == SQL_NTS ) { s1 = malloc( wide_strlen( sz_sql_str ) * 2 + 100 ); } else if ( sz_sql_str && pcb_sql_str ) { s1 = malloc( *pcb_sql_str + 100 ); } else if ( sz_sql_str ) { s1 = malloc( wide_strlen( sz_sql_str ) * 2 + 100 ); } else { s1 = malloc( 101 ); } sprintf( connection -> msg, "\n\t\tExit:[%s]\ \n\t\t\tSQL Out = %s", __get_return_status( ret, s2 ), __idata_as_string( s1, SQL_CHAR, pcb_sql_str, sz_sql_str )); free( s1 ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLNumParams.c000066400000000000000000000153651446441710500204070ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLNumParams.c,v 1.4 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLNumParams.c,v $ * Revision 1.4 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.2 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLNumParams.c,v $ $Revision: 1.4 $"; SQLRETURN SQLNumParams( SQLHSTMT statement_handle, SQLSMALLINT *pcpar ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tParam Count = %p", statement, pcpar ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLNUMPARAMS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( !CHECK_SQLNUMPARAMS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLNUMPARAMS( statement -> connection, statement -> driver_stmt, pcpar ); if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLNUMPARAMS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]\ \n\t\t\tCount = %s", __get_return_status( ret, s2 ), __sptr_as_string( s1, pcpar )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLNumResultCols.c000066400000000000000000000164521446441710500212610ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLNumResultCols.c,v 1.5 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLNumResultCols.c,v $ * Revision 1.5 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.4 2007/01/02 10:27:50 lurcher * Fix descriptor leak with unicode only driver * * Revision 1.3 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.2 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.6 1999/10/14 06:49:24 ngorham * * Remove @all_includes@ from Drivers/MiniSQL/Makefile.am * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.4 1999/05/03 19:50:43 nick * Another check point * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLNumResultCols.c,v $ $Revision: 1.5 $"; SQLRETURN SQLNumResultCols( SQLHSTMT statement_handle, SQLSMALLINT *column_count ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tColumn Count = %p", statement, column_count ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLNUMRESULTCOLS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( !CHECK_SQLNUMRESULTCOLS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, column_count ); if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLNUMRESULTCOLS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } if ( log_info.log_flag ) { if ( SQL_SUCCEEDED( ret )) { sprintf( statement -> msg, "\n\t\tExit:[%s]\ \n\t\t\tCount = %s", __get_return_status( ret, s2 ), __sptr_as_string( s1, column_count )); } else { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s2 )); } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLParamData.c000066400000000000000000000246651446441710500203410ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLParamData.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLParamData.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2007/05/25 16:42:32 lurcher * Sync up * * Revision 1.5 2005/11/21 17:25:43 lurcher * A few DM fixes for Oracle's ODBC driver * * Revision 1.4 2004/05/07 09:53:13 lurcher * * * Fix potential problrm in stats if creating a semaphore fails * Alter state after SQLParamData from S4 to S5 * * Revision 1.3 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.2 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.10 2000/06/20 12:44:00 ngorham * * Fix bug that caused a success with info message from SQLExecute or * SQLExecDirect to be lost if used with a ODBC 3 driver and the application * called SQLGetDiagRec * * Revision 1.9 2000/06/16 16:52:18 ngorham * * Stop info messages being lost when calling SQLExecute etc on ODBC 3 * drivers, the SQLNumResultCols were clearing the error before * function return had a chance to get to them * * Revision 1.8 2000/05/21 21:49:19 ngorham * * Assorted fixes * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLParamData.c,v $ $Revision: 1.7 $"; SQLRETURN SQLParamData( SQLHSTMT statement_handle, SQLPOINTER *value ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tValue = %p", statement, value ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S2 || statement -> state == STATE_S3 || statement -> state == STATE_S4 || statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 || statement -> state == STATE_S9 || statement -> state == STATE_S14 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLPARAMDATA ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( !CHECK_SQLPARAMDATA( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * When a NULL is passed, driver tries to access this memory and dumps core, * so pass a vaild pointer to the driver. This mirrors what the MS DM does */ if (!value) { statement -> valueptr = NULL; value = &statement -> valueptr; } ret = SQLPARAMDATA( statement -> connection, statement -> driver_stmt, value ); if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLPARAMDATA; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else if ( SQL_SUCCEEDED( ret )) { if ( statement -> interupted_func == SQL_API_SQLEXECDIRECT || statement -> interupted_func == SQL_API_SQLEXECUTE || statement -> interupted_func == SQL_API_SQLMORERESULTS ) { #ifdef NR_PROBE SQLRETURN local_ret; /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, statement, ret, TRUE, DEFER_R0 ); } local_ret = SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> hascols ); if ( statement -> hascols > 0 ) statement -> state = STATE_S5; else statement -> state = STATE_S4; #else statement -> hascols = 1; statement -> state = STATE_S5; #endif } else if ( statement -> interupted_func == SQL_API_SQLSETPOS && statement -> interupted_state == STATE_S7 ) { statement -> state = STATE_S7; } else if ( statement -> interupted_func == SQL_API_SQLBULKOPERATIONS && statement -> interupted_state == STATE_S5 ) { statement -> state = STATE_S5; } else { statement -> state = STATE_S6; statement -> eod = 0; } } else if ( ret == SQL_NEED_DATA ) { statement -> state = STATE_S9; } else if ( ret == SQL_PARAM_DATA_AVAILABLE ) { statement -> state = STATE_S14; } else if ( ret == SQL_NO_DATA ) { statement -> interupted_func = 0; statement -> state = STATE_S4; } else { if ( statement -> interupted_func == SQL_API_SQLEXECDIRECT ) { statement -> state = STATE_S1; } else if ( statement -> interupted_func == SQL_API_SQLEXECUTE && statement -> hascols ) { statement -> state = STATE_S3; } else if ( statement -> interupted_func == SQL_API_SQLEXECUTE ) { statement -> state = STATE_S2; } else if ( statement -> interupted_func == SQL_API_SQLBULKOPERATIONS && statement -> interupted_state == STATE_S5 ) { statement -> state = STATE_S5; } else if ( statement -> interupted_func == SQL_API_SQLSETPOS && statement -> interupted_state == STATE_S7 ) { statement -> state = STATE_S7; } else { statement -> state = STATE_S6; statement -> eod = 0; } } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]\ \n\t\t\tValue = %p", __get_return_status( ret, s1 ), *value ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R0 ); } unixODBC-2.3.12/DriverManager/SQLParamOptions.c000066400000000000000000000200511446441710500211040ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLParamOptions.c,v 1.6 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLParamOptions.c,v $ * Revision 1.6 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2005/11/23 08:29:16 lurcher * Add cleanup in postgres driver * * Revision 1.4 2005/07/08 12:11:23 lurcher * * Fix a cursor lib problem (it was broken if you did metadata calls) * Alter the params to SQLParamOptions to use SQLULEN * * Revision 1.3 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.2 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.4 1999/06/03 22:20:25 ngorham * * Finished off the ODBC3-2 mapping * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:20 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLParamOptions.c,v $ $Revision: 1.6 $"; /* * This one is strictly ODBC 2 */ SQLRETURN SQLParamOptions( SQLHSTMT statement_handle, SQLULEN crow, SQLULEN *pirow ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCrow = %d\ \n\t\t\tPirow = %p", statement, (int)crow, (void*)pirow ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( crow == 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1107" ); __post_internal_error( &statement -> error, ERROR_S1107, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1010" ); __post_internal_error( &statement -> error, ERROR_S1010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( CHECK_SQLPARAMOPTIONS( statement -> connection )) { ret = SQLPARAMOPTIONS( statement -> connection, statement -> driver_stmt, crow, pirow ); } else if ( CHECK_SQLSETSTMTATTR( statement -> connection )) { ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)(intptr_t) crow, 0 ); if ( SQL_SUCCEEDED( ret )) { ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, pirow, 0 ); } } else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)(intptr_t) crow, 0 ); if ( SQL_SUCCEEDED( ret )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, pirow, 0 ); } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLPrepare.c000066400000000000000000000252641446441710500201010ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLPrepare.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLPrepare.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2005/03/04 14:38:08 lurcher * Bump version number * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.4 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.3 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.2 2000/10/25 09:23:53 nick * * Fixed incorrect error return when NULL string passed * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:16 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.4 1999/05/03 19:50:43 nick * Another check point * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLPrepare.c,v $ $Revision: 1.7 $"; SQLRETURN SQLPrepareA( SQLHSTMT statement_handle, SQLCHAR *statement_text, SQLINTEGER text_length ) { return SQLPrepare( statement_handle, statement_text, text_length ); } SQLRETURN SQLPrepare( SQLHSTMT statement_handle, SQLCHAR *statement_text, SQLINTEGER text_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR *s1; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { /* * allocate some space for the buffer */ if ( statement_text && text_length == SQL_NTS ) { s1 = malloc( strlen((char*) statement_text ) + 100 ); } else if ( statement_text ) { s1 = malloc( text_length + 100 ); } else { s1 = malloc( 101 ); } sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tSQL = %s", statement, __string_with_length( s1, statement_text, text_length )); free( s1 ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( !statement_text ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( text_length <= 0 && text_length != SQL_NTS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if ( statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLPREPARE ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver ) { int wlen; SQLWCHAR *s1; if ( !CHECK_SQLPREPAREW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( statement_text, text_length, statement -> connection, &wlen ); text_length = wlen; ret = SQLPREPAREW( statement -> connection , statement -> driver_stmt, s1, text_length ); if ( s1 ) free( s1 ); } else { if ( !CHECK_SQLPREPARE( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLPREPARE( statement -> connection , statement -> driver_stmt, statement_text, text_length ); } if ( SQL_SUCCEEDED( ret )) { statement -> hascols = 0; statement -> state = STATE_S3; statement -> prepared = 1; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLPREPARE; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s2 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLPrepareW.c000066400000000000000000000243051446441710500202230ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLPrepareW.c,v 1.8 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLPrepareW.c,v $ * Revision 1.8 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.7 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.6 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLPrepareW.c,v $"; SQLRETURN SQLPrepareW( SQLHSTMT statement_handle, SQLWCHAR *statement_text, SQLINTEGER text_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR *s1; SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLPREPAREW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLPREPAREW( parent_statement -> connection, statement_handle, statement_text, text_length ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { /* * allocate some space for the buffer */ if ( statement_text && text_length == SQL_NTS ) { s1 = malloc( wide_strlen( statement_text ) + 100 ); } else if ( statement_text ) { s1 = malloc( text_length + 100 ); } else { s1 = malloc( 101 ); } sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tSQL = %s", statement, __wstring_with_length( s1, statement_text, text_length )); free( s1 ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( !statement_text ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( text_length <= 0 && text_length != SQL_NTS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLPREPARE ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver || CHECK_SQLPREPAREW( statement -> connection )) { if ( !CHECK_SQLPREPAREW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLPREPAREW( statement -> connection , statement -> driver_stmt, statement_text, text_length ); } else { SQLCHAR *as1; int clen; if ( !CHECK_SQLPREPARE( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } as1 = (SQLCHAR*) unicode_to_ansi_alloc( statement_text, text_length, statement -> connection, &clen ); text_length = clen; ret = SQLPREPARE( statement -> connection , statement -> driver_stmt, as1, text_length ); if ( as1 ) free( as1 ); } if ( SQL_SUCCEEDED( ret )) { statement -> hascols = 0; statement -> state = STATE_S3; statement -> prepared = 1; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLPREPARE; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s2 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLPrimaryKeys.c000066400000000000000000000306341446441710500207570ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLPrimaryKeys.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLPrimaryKeys.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.9 2000/06/20 12:44:01 ngorham * * Fix bug that caused a success with info message from SQLExecute or * SQLExecDirect to be lost if used with a ODBC 3 driver and the application * called SQLGetDiagRec * * Revision 1.8 2000/06/16 16:52:18 ngorham * * Stop info messages being lost when calling SQLExecute etc on ODBC 3 * drivers, the SQLNumResultCols were clearing the error before * function return had a chance to get to them * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/05/03 19:50:43 nick * Another check point * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLPrimaryKeys.c,v $ $Revision: 1.7 $"; SQLRETURN SQLPrimaryKeysA( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_table_name, SQLSMALLINT cb_table_name ) { return SQLPrimaryKeys( statement_handle, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_table_name, cb_table_name ); } SQLRETURN SQLPrimaryKeys( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_table_name, SQLSMALLINT cb_table_name ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Type = %s", statement, __string_with_length( s1, sz_catalog_name, cb_catalog_name ), __string_with_length( s2, sz_schema_name, cb_schema_name ), __string_with_length( s3, sz_table_name, cb_table_name )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( cb_catalog_name < 0 && cb_catalog_name != SQL_NTS ) || ( cb_schema_name < 0 && cb_schema_name != SQL_NTS ) || ( cb_table_name < 0 && cb_table_name != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if ( statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLPRIMARYKEYS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( sz_table_name == NULL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1, *s2, *s3; int wlen; if ( !CHECK_SQLPRIMARYKEYSW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( sz_catalog_name, cb_catalog_name, statement -> connection, &wlen ); s2 = ansi_to_unicode_alloc( sz_schema_name, cb_schema_name, statement -> connection, &wlen ); s3 = ansi_to_unicode_alloc( sz_table_name, cb_table_name, statement -> connection, &wlen ); ret = SQLPRIMARYKEYSW( statement -> connection , statement -> driver_stmt, s1, cb_catalog_name, s2, cb_schema_name, s3, cb_table_name ); if ( s1 ) free( s1 ); if ( s2 ) free( s2 ); if ( s3 ) free( s3 ); } else { if ( !CHECK_SQLPRIMARYKEYS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLPRIMARYKEYS( statement -> connection , statement -> driver_stmt, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_table_name, cb_table_name ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /******** * Added this to get num cols from drivers which can only tell * us after execute - PAH */ /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, statement, ret, TRUE, DEFER_R1 ); } SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); /******/ #endif statement -> hascols = 1; statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLPRIMARYKEYS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLPrimaryKeysW.c000066400000000000000000000275501446441710500211110ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLPrimaryKeysW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLPrimaryKeysW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLPrimaryKeysW.c,v $"; SQLRETURN SQLPrimaryKeysW( SQLHSTMT statement_handle, SQLWCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLWCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLWCHAR *sz_table_name, SQLSMALLINT cb_table_name ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLPRIMARYKEYSW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLPRIMARYKEYSW( parent_statement -> connection, statement_handle, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_table_name, cb_table_name ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Type = %s", statement, __wstring_with_length( s1, sz_catalog_name, cb_catalog_name ), __wstring_with_length( s2, sz_schema_name, cb_schema_name ), __wstring_with_length( s3, sz_table_name, cb_table_name )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( cb_catalog_name < 0 && cb_catalog_name != SQL_NTS ) || ( cb_schema_name < 0 && cb_schema_name != SQL_NTS ) || ( cb_table_name < 0 && cb_table_name != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLPRIMARYKEYS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( sz_table_name == NULL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver || CHECK_SQLPRIMARYKEYSW( statement -> connection )) { if ( !CHECK_SQLPRIMARYKEYSW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLPRIMARYKEYSW( statement -> connection , statement -> driver_stmt, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_table_name, cb_table_name ); } else { SQLCHAR *as1, *as2, *as3; int clen; if ( !CHECK_SQLPRIMARYKEYS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } as1 = (SQLCHAR*) unicode_to_ansi_alloc( sz_catalog_name, cb_catalog_name, statement -> connection, &clen ); cb_catalog_name = clen; as2 = (SQLCHAR*) unicode_to_ansi_alloc( sz_schema_name, cb_schema_name, statement -> connection, &clen ); cb_schema_name = clen; as3 = (SQLCHAR*) unicode_to_ansi_alloc( sz_table_name, cb_table_name, statement -> connection, &clen ); cb_table_name = clen; ret = SQLPRIMARYKEYS( statement -> connection , statement -> driver_stmt, as1, cb_catalog_name, as2, cb_schema_name, as3, cb_table_name ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); if ( as3 ) free( as3 ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /******** * Added this to get num cols from drivers which can only tell * us after execute - PAH */ /* * grab any errors */ if ( ret == SQL_SUCCESS_WITH_INFO ) { function_return_ex( IGNORE_THREAD, statement, ret, TRUE, DEFER_R1 ); } SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); /******/ #endif statement -> hascols = 1; statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLPRIMARYKEYS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLProcedureColumns.c000066400000000000000000000300541446441710500217650ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLProcedureColumns.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLProcedureColumns.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/05/03 19:50:43 nick * Another check point * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLProcedureColumns.c,v $ $Revision: 1.7 $"; SQLRETURN SQLProcedureColumnsA( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_proc_name, SQLSMALLINT cb_proc_name, SQLCHAR *sz_column_name, SQLSMALLINT cb_column_name ) { return SQLProcedureColumns( statement_handle, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_proc_name, cb_proc_name, sz_column_name, cb_column_name ); } SQLRETURN SQLProcedureColumns( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_proc_name, SQLSMALLINT cb_proc_name, SQLCHAR *sz_column_name, SQLSMALLINT cb_column_name ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tProc Name = %s\ \n\t\t\tColumn Type = %s", statement, __string_with_length( s1, sz_catalog_name, cb_catalog_name ), __string_with_length( s2, sz_schema_name, cb_schema_name ), __string_with_length( s3, sz_proc_name, cb_proc_name ), __string_with_length( s4, sz_column_name, cb_column_name )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( sz_catalog_name && cb_catalog_name < 0 && cb_catalog_name != SQL_NTS ) || ( sz_schema_name && cb_schema_name < 0 && cb_schema_name != SQL_NTS ) || ( sz_proc_name && cb_proc_name < 0 && cb_proc_name != SQL_NTS ) || ( sz_column_name && cb_column_name < 0 && cb_column_name != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLPROCEDURECOLUMNS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1, *s2, *s3, *s4; int wlen; if ( !CHECK_SQLPROCEDURECOLUMNSW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( sz_catalog_name, cb_catalog_name, statement -> connection, &wlen ); cb_catalog_name = wlen; s2 = ansi_to_unicode_alloc( sz_schema_name, cb_schema_name, statement -> connection, &wlen ); cb_schema_name = wlen; s3 = ansi_to_unicode_alloc( sz_proc_name, cb_proc_name, statement -> connection, &wlen ); cb_proc_name = wlen; s4 = ansi_to_unicode_alloc( sz_column_name, cb_column_name, statement -> connection, &wlen ); cb_column_name = wlen; ret = SQLPROCEDURECOLUMNSW( statement -> connection , statement -> driver_stmt, s1, cb_catalog_name, s2, cb_schema_name, s3, cb_proc_name, s4, cb_column_name ); if ( s1 ) free( s1 ); if ( s2 ) free( s2 ); if ( s3 ) free( s3 ); if ( s4 ) free( s4 ); } else { if ( !CHECK_SQLPROCEDURECOLUMNS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLPROCEDURECOLUMNS( statement -> connection , statement -> driver_stmt, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_proc_name, cb_proc_name, sz_column_name, cb_column_name ); } if ( SQL_SUCCEEDED( ret )) { statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLPROCEDURECOLUMNS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLProcedureColumnsW.c000066400000000000000000000272601446441710500221210ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLProcedureColumnsW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLProcedureColumnsW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLProcedureColumnsW.c,v $"; SQLRETURN SQLProcedureColumnsW( SQLHSTMT statement_handle, SQLWCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLWCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLWCHAR *sz_proc_name, SQLSMALLINT cb_proc_name, SQLWCHAR *sz_column_name, SQLSMALLINT cb_column_name ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLPROCEDURECOLUMNSW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLPROCEDURECOLUMNSW( parent_statement -> connection, statement_handle, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_proc_name, cb_proc_name, sz_column_name, cb_column_name ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tProc Name = %s\ \n\t\t\tColumn Type = %s", statement, __wstring_with_length( s1, sz_catalog_name, cb_catalog_name ), __wstring_with_length( s2, sz_schema_name, cb_schema_name ), __wstring_with_length( s3, sz_proc_name, cb_proc_name ), __wstring_with_length( s4, sz_column_name, cb_column_name )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( sz_catalog_name && cb_catalog_name < 0 && cb_catalog_name != SQL_NTS ) || ( sz_schema_name && cb_schema_name < 0 && cb_schema_name != SQL_NTS ) || ( sz_proc_name && cb_proc_name < 0 && cb_proc_name != SQL_NTS ) || ( sz_column_name && cb_column_name < 0 && cb_column_name != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLPROCEDURECOLUMNS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver || CHECK_SQLPROCEDURECOLUMNSW( statement -> connection )) { if ( !CHECK_SQLPROCEDURECOLUMNSW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLPROCEDURECOLUMNSW( statement -> connection , statement -> driver_stmt, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_proc_name, cb_proc_name, sz_column_name, cb_column_name ); } else { SQLCHAR *as1, *as2, *as3, *as4; int clen; if ( !CHECK_SQLPROCEDURECOLUMNS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } as1 = (SQLCHAR*) unicode_to_ansi_alloc( sz_catalog_name, cb_catalog_name, statement -> connection, &clen ); cb_catalog_name = clen; as2 = (SQLCHAR*) unicode_to_ansi_alloc( sz_schema_name, cb_schema_name, statement -> connection, &clen ); cb_schema_name = clen; as3 = (SQLCHAR*) unicode_to_ansi_alloc( sz_proc_name, cb_proc_name, statement -> connection, &clen ); cb_proc_name = clen; as4 = (SQLCHAR*) unicode_to_ansi_alloc( sz_column_name, cb_column_name, statement -> connection, &clen ); cb_column_name = clen; ret = SQLPROCEDURECOLUMNS( statement -> connection , statement -> driver_stmt, as1, cb_catalog_name, as2, cb_schema_name, as3, cb_proc_name, as4, cb_column_name ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); if ( as3 ) free( as3 ); if ( as4 ) free( as4 ); } if ( SQL_SUCCEEDED( ret )) { statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLPROCEDURECOLUMNS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLProcedures.c000066400000000000000000000263151446441710500206140ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLProcedures.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLProcedures.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/05/03 19:50:43 nick * Another check point * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLProcedures.c,v $ $Revision: 1.7 $"; SQLRETURN SQLProceduresA( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_proc_name, SQLSMALLINT cb_proc_name ) { return SQLProcedures( statement_handle, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_proc_name, cb_proc_name ); } SQLRETURN SQLProcedures( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_proc_name, SQLSMALLINT cb_proc_name ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tProc Name = %s", statement, __string_with_length( s1, sz_catalog_name, cb_catalog_name ), __string_with_length( s2, sz_schema_name, cb_schema_name ), __string_with_length( s3, sz_proc_name, cb_proc_name )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( cb_catalog_name < 0 && cb_catalog_name != SQL_NTS ) || ( cb_schema_name < 0 && cb_schema_name != SQL_NTS ) || ( cb_proc_name < 0 && cb_proc_name != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLPROCEDURES ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1, *s2, *s3; int wlen; if ( !CHECK_SQLPROCEDURESW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( sz_catalog_name, cb_catalog_name, statement -> connection, &wlen ); cb_catalog_name = wlen; s2 = ansi_to_unicode_alloc( sz_schema_name, cb_schema_name, statement -> connection, &wlen ); cb_schema_name = wlen; s3 = ansi_to_unicode_alloc( sz_proc_name, cb_proc_name, statement -> connection, &wlen ); cb_proc_name = wlen; ret = SQLPROCEDURESW( statement -> connection , statement -> driver_stmt, s1, cb_catalog_name, s2, cb_schema_name, s3, cb_proc_name ); if ( s1 ) free( s1 ); if ( s2 ) free( s2 ); if ( s3 ) free( s3 ); } else { if ( !CHECK_SQLPROCEDURES( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLPROCEDURES( statement -> connection , statement -> driver_stmt, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_proc_name, cb_proc_name ); } if ( SQL_SUCCEEDED( ret )) { statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLPROCEDURES; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLProceduresW.c000066400000000000000000000256641446441710500207510ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLProceduresW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLProceduresW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLProceduresW.c,v $ $Revision: 1.9 $"; SQLRETURN SQLProceduresW( SQLHSTMT statement_handle, SQLWCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLWCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLWCHAR *sz_proc_name, SQLSMALLINT cb_proc_name ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLPROCEDURESW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLPROCEDURESW( parent_statement -> connection, statement_handle, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_proc_name, cb_proc_name ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tProc Name = %s", statement, __wstring_with_length( s1, sz_catalog_name, cb_catalog_name ), __wstring_with_length( s2, sz_schema_name, cb_schema_name ), __wstring_with_length( s3, sz_proc_name, cb_proc_name )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( cb_catalog_name < 0 && cb_catalog_name != SQL_NTS ) || ( cb_schema_name < 0 && cb_schema_name != SQL_NTS ) || ( cb_proc_name < 0 && cb_proc_name != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLPROCEDURES ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver || CHECK_SQLPROCEDURESW( statement -> connection )) { if ( !CHECK_SQLPROCEDURESW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLPROCEDURESW( statement -> connection , statement -> driver_stmt, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_proc_name, cb_proc_name ); } else { SQLCHAR *as1, *as2, *as3; int clen; if ( !CHECK_SQLPROCEDURES( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } as1 = (SQLCHAR*) unicode_to_ansi_alloc( sz_catalog_name, cb_catalog_name, statement -> connection, &clen ); cb_catalog_name = clen; as2 = (SQLCHAR*) unicode_to_ansi_alloc( sz_schema_name, cb_schema_name, statement -> connection, &clen ); cb_schema_name = clen; as3 = (SQLCHAR*) unicode_to_ansi_alloc( sz_proc_name, cb_proc_name, statement -> connection, &clen ); cb_proc_name = clen; ret = SQLPROCEDURES( statement -> connection , statement -> driver_stmt, as1, cb_catalog_name, as2, cb_schema_name, as3, cb_proc_name ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); if ( as3 ) free( as3 ); } if ( SQL_SUCCEEDED( ret )) { statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLPROCEDURES; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLPutData.c000066400000000000000000000223271446441710500200420ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLPutData.c,v 1.5 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLPutData.c,v $ * Revision 1.5 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.4 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLPutData.c,v $ $Revision: 1.5 $"; SQLRETURN SQLPutData( SQLHSTMT statement_handle, SQLPOINTER data, SQLLEN strlen_or_ind ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tData = %p\ \n\t\t\tStrLen = %d", statement, data, (int)strlen_or_ind ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S2 || statement -> state == STATE_S3 || statement -> state == STATE_S4 || statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 || statement -> state == STATE_S8 || statement -> state == STATE_S13 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * not the first put for this paramenter and we * try and set a NULL */ if ( statement -> state == STATE_S10 && strlen_or_ind == SQL_NULL_DATA ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY011" ); __post_internal_error( &statement -> error, ERROR_HY011, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLPUTDATA ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( data == NULL && strlen_or_ind != 0 && strlen_or_ind != SQL_DEFAULT_PARAM && strlen_or_ind != SQL_NULL_DATA ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( !CHECK_SQLPUTDATA( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLPUTDATA( statement -> connection, statement -> driver_stmt, data, strlen_or_ind ); if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLPUTDATA; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else if ( SQL_SUCCEEDED( ret )) { if ( statement -> state == STATE_S13 ) { statement -> state = STATE_S14; } else { statement -> state = STATE_S10; } } else { if ( statement -> interupted_func == SQL_API_SQLEXECDIRECT ) { statement -> state = STATE_S1; } else if ( statement -> interupted_func == SQL_API_SQLEXECUTE && statement -> hascols ) { statement -> state = STATE_S3; } else if ( statement -> interupted_func == SQL_API_SQLEXECUTE ) { statement -> state = STATE_S2; } else if ( statement -> interupted_func == SQL_API_SQLBULKOPERATIONS && statement -> interupted_state == STATE_S5 ) { statement -> state = STATE_S5; } else if ( statement -> interupted_func == SQL_API_SQLSETPOS && statement -> interupted_state == STATE_S7 ) { statement -> state = STATE_S7; } else { statement -> state = STATE_S6; statement -> eod = 0; } } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLRowCount.c000066400000000000000000000163301446441710500202550ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLRowCount.c,v 1.8 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLRowCount.c,v $ * Revision 1.8 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.7 2007/04/02 10:50:19 lurcher * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 ) * * Revision 1.6 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.3 2002/08/12 13:17:52 lurcher * * Replicate the way the MS DM handles loading of driver libs, and allocating * handles in the driver. usage counting in the driver means that dlopen is * only called for the first use, and dlclose for the last. AllocHandle for * the driver environment is only called for the first time per driver * per application environment. * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLRowCount.c,v $ $Revision: 1.8 $"; SQLRETURN SQLRowCount( SQLHSTMT statement_handle, SQLLEN *rowcount ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s0[ 24 ], s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { if ( rowcount ) { *rowcount = -1; } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tRow Count = %p", statement, rowcount ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S2 || statement -> state == STATE_S3 || statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { if ( rowcount ) { *rowcount = -1; } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( !CHECK_SQLROWCOUNT( statement -> connection )) { if ( rowcount ) { *rowcount = -1; } dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = DEF_SQLROWCOUNT( statement -> connection, statement -> driver_stmt, rowcount ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]\ \n\t\t\tRow Count = %s", __get_return_status( ret, s0 ), __ptr_as_string( s1, rowcount )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetConnectAttr.c000066400000000000000000000665561446441710500214140ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetConnectAttr.c,v 1.17 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetConnectAttr.c,v $ * Revision 1.17 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.16 2006/04/11 10:22:56 lurcher * Fix a data type check * * Revision 1.15 2005/03/01 15:50:50 lurcher * Add Eric's SQLSetConnectAttr patch * * Revision 1.14 2004/06/21 10:01:11 lurcher * * Fix a couple of 64 bit issues * * Revision 1.13 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.12 2003/03/05 09:48:44 lurcher * * Add some 64 bit fixes * * Revision 1.11 2003/02/27 12:19:39 lurcher * * Add the A functions as well as the W * * Revision 1.10 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.9 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.8 2002/07/16 13:08:18 lurcher * * Filter attribute values from SQLSetStmtAttr to SQLSetStmtOption to fit * within ODBC 2 * Make DSN's double clickable in ODBCConfig * * Revision 1.7 2002/07/04 17:27:56 lurcher * * Small bug fixes * * Revision 1.5 2002/01/30 12:20:02 lurcher * * Add MyODBC 3 driver source * * Revision 1.4 2002/01/10 11:17:20 lurcher * * Allow SQL_ATTR_LOGIN_TIMEOUT to be set when connected to mirror what the * MS DM does * * Revision 1.3 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.2 2001/11/14 12:33:20 lurcher * * Remove the comments around the tracing code * * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher * * First upload to SourceForge * * Revision 1.12 2001/09/27 17:05:48 nick * * Assorted fixes and tweeks * * Revision 1.11 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * Revision 1.10 2001/08/03 15:19:00 nick * * Add changes to set values before connect * * Revision 1.9 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.8 2001/04/25 14:29:36 nick * * remove comment * * Revision 1.7 2001/04/23 13:58:43 nick * * Assorted tweeks to text driver to get it to work with StarOffice * * Revision 1.6 2001/04/20 13:58:13 nick * * Add txt driver * * Revision 1.5 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.4 2001/02/06 18:43:38 nick * * Fix problem with SQLSetConnectAttr.c looking for UNICODE versions in * ansi side of call * * Revision 1.3 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.2 2000/11/14 10:15:27 nick * * Add test for localtime_r * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.11 2000/06/20 13:30:09 ngorham * * Fix problems when using bookmarks * * Revision 1.10 2000/05/21 21:49:19 ngorham * * Assorted fixes * * Revision 1.9 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.8 1999/11/10 03:51:34 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.7 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.6 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.5 1999/09/19 22:24:34 ngorham * * Added support for the cursor library * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetConnectAttr.c,v $ $Revision: 1.17 $"; SQLRETURN SQLSetConnectAttrA( SQLHDBC connection_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length ) { return SQLSetConnectAttr( connection_handle, attribute, value, string_length ); } SQLRETURN SQLSetConnectAttr( SQLHDBC connection_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length ) { DMHDBC connection = (DMHDBC)connection_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * doesn't require a handle */ if ( attribute == SQL_ATTR_TRACE ) { if ((SQLLEN) value != SQL_OPT_TRACE_OFF && (SQLLEN) value != SQL_OPT_TRACE_ON ) { if ( __validate_dbc( connection )) { thread_protect( SQL_HANDLE_DBC, connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); function_entry( connection ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } } if ((SQLLEN) value == SQL_OPT_TRACE_OFF ) { char force_string[ 30 ]; SQLGetPrivateProfileString( "ODBC", "ForceTrace", "0", force_string, sizeof( force_string ), "ODBCINST.INI" ); if ( force_string[ 0 ] == '1' || toupper( force_string[ 0 ] ) == 'Y' || ( toupper( force_string[ 0 ] ) == 'O' && toupper( force_string[ 1 ] ) == 'N' )) { if ( log_info.log_flag ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Application tried to turn logging off" ); } } else { if ( log_info.log_flag ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Application turning logging off" ); } log_info.log_flag = 0; } } else { log_info.log_flag = 1; } return SQL_SUCCESS; } else if ( attribute == SQL_ATTR_TRACEFILE ) { if ( value ) { if (((SQLCHAR*)value)[ 0 ] == '\0' ) { if ( __validate_dbc( connection )) { thread_protect( SQL_HANDLE_DBC, connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); function_entry( connection ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } } else { if ( log_info.log_file_name ) { free( log_info.log_file_name ); } log_info.log_file_name = strdup( value ); } } else { if ( __validate_dbc( connection )) { thread_protect( SQL_HANDLE_DBC, connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); function_entry( connection ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } } return SQL_SUCCESS; } /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tAttribute = %s\ \n\t\t\tValue = %p\ \n\t\t\tStrLen = %d", connection, __con_attr_as_string( s1, attribute ), value, (int)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( connection -> state == STATE_C2 ) { if ( attribute == SQL_ATTR_TRANSLATE_OPTION || attribute == SQL_ATTR_TRANSLATE_LIB ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else if ( connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else if ( connection -> state == STATE_C4 || connection -> state == STATE_C5 || connection -> state == STATE_C6 ) { if ( attribute == SQL_ATTR_ODBC_CURSORS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08002" ); __post_internal_error( &connection -> error, ERROR_08002, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else if ( attribute == SQL_ATTR_PACKET_SIZE ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY011" ); __post_internal_error( &connection -> error, ERROR_HY011, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } /* * is it a legitimate value */ ret = dm_check_connection_attrs( connection, attribute, value ); if ( ret != SQL_SUCCESS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * is it a connection attribute or statement, check state of any active connections */ switch( attribute ) { /* ODBC 3.x statement attributes are not settable at the connection level */ case SQL_ATTR_APP_PARAM_DESC: case SQL_ATTR_APP_ROW_DESC: case SQL_ATTR_CURSOR_SCROLLABLE: case SQL_ATTR_CURSOR_SENSITIVITY: case SQL_ATTR_ENABLE_AUTO_IPD: case SQL_ATTR_FETCH_BOOKMARK_PTR: case SQL_ATTR_IMP_PARAM_DESC: case SQL_ATTR_IMP_ROW_DESC: case SQL_ATTR_PARAM_BIND_OFFSET_PTR: case SQL_ATTR_PARAM_BIND_TYPE: case SQL_ATTR_PARAM_OPERATION_PTR: case SQL_ATTR_PARAM_STATUS_PTR: case SQL_ATTR_PARAMS_PROCESSED_PTR: case SQL_ATTR_PARAMSET_SIZE: case SQL_ATTR_ROW_ARRAY_SIZE: case SQL_ATTR_ROW_BIND_OFFSET_PTR: case SQL_ATTR_ROW_OPERATION_PTR: case SQL_ATTR_ROW_STATUS_PTR: case SQL_ATTR_ROWS_FETCHED_PTR: __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); case SQL_ATTR_CONCURRENCY: case SQL_BIND_TYPE: case SQL_ATTR_CURSOR_TYPE: case SQL_ATTR_MAX_LENGTH: case SQL_MAX_ROWS: case SQL_ATTR_KEYSET_SIZE: case SQL_ROWSET_SIZE: case SQL_ATTR_NOSCAN: case SQL_ATTR_QUERY_TIMEOUT: case SQL_ATTR_RETRIEVE_DATA: case SQL_ATTR_SIMULATE_CURSOR: case SQL_ATTR_USE_BOOKMARKS: if( __check_stmt_from_dbc_v( connection, 5, STATE_S8, STATE_S9, STATE_S10, STATE_S11, STATE_S12 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &connection -> error, ERROR_24000, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } break; default: if( __check_stmt_from_dbc_v( connection, 5, STATE_S8, STATE_S9, STATE_S10, STATE_S11, STATE_S12 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } break; } /* * is it something overridden */ value = __attr_override( connection, SQL_HANDLE_DBC, attribute, value, &string_length ); /* * we need to save this even if connected so we can use it for the next connect */ if ( attribute == SQL_ATTR_LOGIN_TIMEOUT ) { connection -> login_timeout = ( SQLLEN ) value; connection -> login_timeout_set = 1; } /* * if connected, call the driver * otherwise we need to save the states and set them when we * do connect */ if ( connection -> state == STATE_C2 ) { /* * is it for us */ if ( attribute == SQL_ATTR_ODBC_CURSORS ) { connection -> cursors = ( SQLLEN ) value; } else if ( attribute == SQL_ATTR_ACCESS_MODE ) { connection -> access_mode = ( SQLLEN ) value; connection -> access_mode_set = 1; } else if ( attribute == SQL_ATTR_ASYNC_ENABLE ) { connection -> async_enable = ( SQLLEN ) value; connection -> async_enable_set = 1; } else if ( attribute == SQL_ATTR_AUTO_IPD ) { connection -> auto_ipd = ( SQLLEN ) value; connection -> auto_ipd_set = 1; } else if ( attribute == SQL_ATTR_AUTOCOMMIT ) { connection -> auto_commit = ( SQLLEN ) value; connection -> auto_commit_set = 1; } else if ( attribute == SQL_ATTR_CONNECTION_TIMEOUT ) { connection -> connection_timeout = ( SQLLEN ) value; connection -> connection_timeout_set = 1; } else if ( attribute == SQL_ATTR_METADATA_ID ) { connection -> metadata_id = ( SQLLEN ) value; connection -> metadata_id_set = 1; } else if ( attribute == SQL_ATTR_PACKET_SIZE ) { connection -> packet_size = ( SQLLEN ) value; connection -> packet_size_set = 1; } else if ( attribute == SQL_ATTR_QUIET_MODE ) { connection -> quite_mode = ( SQLLEN ) value; connection -> quite_mode_set = 1; } else if ( attribute == SQL_ATTR_TXN_ISOLATION ) { connection -> txn_isolation = ( SQLLEN ) value; connection -> txn_isolation_set = 1; } else if ( attribute != SQL_ATTR_LOGIN_TIMEOUT ) { /* * save any unknown attributes until connect */ struct save_attr sa, *sap; memset( &sa, 0, sizeof ( sa )); sa.attr_type = attribute; if ( string_length > 0 ) { sa.str_attr = malloc( string_length ); memcpy( sa.str_attr, value, string_length ); sa.str_len = string_length; } else if ( string_length == SQL_NTS ) { if (!value) { __post_internal_error( &connection -> error, ERROR_HY024, "Invalid argument value", connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { sa.str_attr = strdup( value ); sa.str_len = string_length; } } else { sa.intptr_attr = (intptr_t) value; sa.str_len = string_length; } sap = connection -> save_attr; while ( sap ) { if ( sap -> attr_type == attribute ) { free ( sap -> str_attr ); break; } sap = sap -> next; } if ( sap ) /* replace existing attribute */ { *sap = sa; } else { sap = malloc( sizeof( struct save_attr )); *sap = sa; sap -> next = connection -> save_attr; connection -> save_attr = sap; } } sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_SUCCESS ); } else { if ( !connection -> unicode_driver ) { if ( !CHECK_SQLSETCONNECTATTR( connection )) { if ( CHECK_SQLSETCONNECTOPTION( connection )) { /* * Is it in the legal range of values */ if ( attribute < SQL_CONN_DRIVER_MIN && ( attribute > SQL_PACKET_SIZE || attribute < SQL_ACCESS_MODE )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } ret = SQLSETCONNECTOPTION( connection, connection -> driver_dbc, attribute, (SQLULEN) value ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { ret = SQLSETCONNECTATTR( connection, connection -> driver_dbc, attribute, value, string_length ); } } else { if ( !CHECK_SQLSETCONNECTATTRW( connection )) { if ( CHECK_SQLSETCONNECTOPTIONW( connection )) { SQLWCHAR *s1; /* * Is it in the legal range of values */ if ( attribute < SQL_CONN_DRIVER_MIN && ( attribute > SQL_PACKET_SIZE || attribute < SQL_ACCESS_MODE )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } switch( attribute ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: s1 = ansi_to_unicode_alloc( value, SQL_NTS, connection, NULL ); ret = SQLSETCONNECTOPTIONW( connection, connection -> driver_dbc, attribute, (SQLULEN) s1 ); if ( s1 ) free( s1 ); break; default: ret = SQLSETCONNECTOPTIONW( connection, connection -> driver_dbc, attribute, (SQLULEN) value ); break; } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { SQLWCHAR *s1; switch( attribute ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: s1 = ansi_to_unicode_alloc( value, string_length, connection, NULL ); ret = SQLSETCONNECTATTRW( connection, connection -> driver_dbc, attribute, s1, string_length == SQL_NTS ? SQL_NTS : string_length * sizeof( SQLWCHAR )); if ( s1 ) free( s1 ); break; default: ret = SQLSETCONNECTATTRW( connection, connection -> driver_dbc, attribute, value, string_length ); break; } } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } } /* * catch this */ if ( attribute == SQL_ATTR_USE_BOOKMARKS && SQL_SUCCEEDED( ret )) { connection -> bookmarks_on = (SQLLEN) value; } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetConnectAttrW.c000066400000000000000000000651161446441710500215320ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetConnectAttrW.c,v 1.14 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetConnectAttrW.c,v $ * Revision 1.14 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.13 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.12 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.11 2006/04/18 10:24:47 lurcher * Add a couple of changes from Mark Vanderwiel * * Revision 1.10 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.9 2003/03/05 09:48:44 lurcher * * Add some 64 bit fixes * * Revision 1.8 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.7 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.6 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.5 2002/07/16 13:08:18 lurcher * * Filter attribute values from SQLSetStmtAttr to SQLSetStmtOption to fit * within ODBC 2 * Make DSN's double clickable in ODBCConfig * * Revision 1.4 2002/07/04 17:27:56 lurcher * * Small bug fixes * * Revision 1.3 2002/01/30 12:20:02 lurcher * * Add MyODBC 3 driver source * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.7 2001/09/27 17:05:48 nick * * Assorted fixes and tweeks * * Revision 1.6 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * Revision 1.5 2001/08/03 15:19:00 nick * * Add changes to set values before connect * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/05/23 13:48:37 nick * * Remove unwanted include * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetConnectAttrW.c,v $"; SQLRETURN SQLSetConnectAttrW( SQLHDBC connection_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length ) { DMHDBC connection = (DMHDBC)connection_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; SQLWCHAR buffer[ 512 ]; /* * doesn't require a handle */ if ( attribute == SQL_ATTR_TRACE ) { if ((SQLLEN) value != SQL_OPT_TRACE_OFF && (SQLLEN) value != SQL_OPT_TRACE_ON ) { if ( __validate_dbc( connection )) { thread_protect( SQL_HANDLE_DBC, connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); function_entry( connection ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } } if ((SQLLEN) value == SQL_OPT_TRACE_OFF ) { char force_string[ 30 ]; SQLGetPrivateProfileString( "ODBC", "ForceTrace", "0", force_string, sizeof( force_string ), "ODBCINST.INI" ); if ( force_string[ 0 ] == '1' || toupper( force_string[ 0 ] ) == 'Y' || ( toupper( force_string[ 0 ] ) == 'O' && toupper( force_string[ 1 ] ) == 'N' )) { if ( log_info.log_flag ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Application tried to turn logging off" ); } } else { if ( log_info.log_flag ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Application turning logging off" ); } log_info.log_flag = 0; } } else { log_info.log_flag = 1; } return SQL_SUCCESS; } else if ( attribute == SQL_ATTR_TRACEFILE ) { if ( value ) { if (((SQLWCHAR*)value)[ 0 ] == 0 ) { if ( __validate_dbc( connection )) { thread_protect( SQL_HANDLE_DBC, connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); function_entry( connection ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } } else { if ( log_info.log_file_name ) { free( log_info.log_file_name ); } log_info.log_file_name = unicode_to_ansi_alloc((SQLWCHAR *) value, SQL_NTS, connection, NULL ); } } else { if ( __validate_dbc( connection )) { thread_protect( SQL_HANDLE_DBC, connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); function_entry( connection ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } } return SQL_SUCCESS; } /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHDBC parent_connection; parent_connection = find_parent_handle( connection, SQL_HANDLE_DBC ); if ( parent_connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLSETCONNECTATTRW( parent_connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLSETCONNECTATTRW( parent_connection, connection_handle, attribute, value, string_length ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tAttribute = %s\ \n\t\t\tValue = %p\ \n\t\t\tStrLen = %d", connection, __con_attr_as_string( s1, attribute ), value, (int)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( connection -> state == STATE_C2 ) { if ( attribute == SQL_ATTR_TRANSLATE_OPTION || attribute == SQL_ATTR_TRANSLATE_LIB ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else if ( connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else if ( connection -> state == STATE_C4 || connection -> state == STATE_C5 || connection -> state == STATE_C6 ) { if ( attribute == SQL_ATTR_ODBC_CURSORS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08002" ); __post_internal_error( &connection -> error, ERROR_08002, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else if ( attribute == SQL_ATTR_PACKET_SIZE ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY011" ); __post_internal_error( &connection -> error, ERROR_HY011, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } /* * is it a legitimate value */ ret = dm_check_connection_attrs( connection, attribute, value ); if ( ret != SQL_SUCCESS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * is it a connection attribute or statement, check state of any active connections */ switch( attribute ) { /* ODBC 3.x statement attributes are not settable at the connection level */ case SQL_ATTR_APP_PARAM_DESC: case SQL_ATTR_APP_ROW_DESC: case SQL_ATTR_CURSOR_SCROLLABLE: case SQL_ATTR_CURSOR_SENSITIVITY: case SQL_ATTR_ENABLE_AUTO_IPD: case SQL_ATTR_FETCH_BOOKMARK_PTR: case SQL_ATTR_IMP_PARAM_DESC: case SQL_ATTR_IMP_ROW_DESC: case SQL_ATTR_PARAM_BIND_OFFSET_PTR: case SQL_ATTR_PARAM_BIND_TYPE: case SQL_ATTR_PARAM_OPERATION_PTR: case SQL_ATTR_PARAM_STATUS_PTR: case SQL_ATTR_PARAMS_PROCESSED_PTR: case SQL_ATTR_PARAMSET_SIZE: case SQL_ATTR_ROW_ARRAY_SIZE: case SQL_ATTR_ROW_BIND_OFFSET_PTR: case SQL_ATTR_ROW_OPERATION_PTR: case SQL_ATTR_ROW_STATUS_PTR: case SQL_ATTR_ROWS_FETCHED_PTR: __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); case SQL_ATTR_CONCURRENCY: case SQL_BIND_TYPE: case SQL_ATTR_CURSOR_TYPE: case SQL_ATTR_MAX_LENGTH: case SQL_MAX_ROWS: case SQL_ATTR_KEYSET_SIZE: case SQL_ROWSET_SIZE: case SQL_ATTR_NOSCAN: case SQL_ATTR_QUERY_TIMEOUT: case SQL_ATTR_RETRIEVE_DATA: case SQL_ATTR_SIMULATE_CURSOR: case SQL_ATTR_USE_BOOKMARKS: if( __check_stmt_from_dbc_v( connection, 8, STATE_S8, STATE_S9, STATE_S10, STATE_S11, STATE_S12, STATE_S13, STATE_S14, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &connection -> error, ERROR_24000, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } break; default: if( __check_stmt_from_dbc_v( connection, 8, STATE_S8, STATE_S9, STATE_S10, STATE_S11, STATE_S12, STATE_S13, STATE_S14, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } break; } /* * is it something overridden */ value = __attr_override_wide( connection, SQL_HANDLE_DBC, attribute, value, &string_length, buffer ); /* * we need to save this even if connected so we can use it for the next connect */ if ( attribute == SQL_ATTR_LOGIN_TIMEOUT ) { connection -> login_timeout = ( SQLLEN ) value; connection -> login_timeout_set = 1; } /* * if connected, call the driver * otherwise we need to save the states and set them when we * do connect */ if ( connection -> state == STATE_C2 ) { /* * is it for us */ if ( attribute == SQL_ATTR_ODBC_CURSORS ) { connection -> cursors = ( SQLLEN ) value; } else if ( attribute == SQL_ATTR_ACCESS_MODE ) { connection -> access_mode = ( SQLLEN ) value; connection -> access_mode_set = 1; } else if ( attribute == SQL_ATTR_ASYNC_ENABLE ) { connection -> async_enable = ( SQLLEN ) value; connection -> async_enable_set = 1; } else if ( attribute == SQL_ATTR_AUTO_IPD ) { connection -> auto_ipd = ( SQLLEN ) value; connection -> auto_ipd_set = 1; } else if ( attribute == SQL_ATTR_AUTOCOMMIT ) { connection -> auto_commit = ( SQLLEN ) value; connection -> auto_commit_set = 1; } else if ( attribute == SQL_ATTR_CONNECTION_TIMEOUT ) { connection -> connection_timeout = ( SQLLEN ) value; connection -> connection_timeout_set = 1; } else if ( attribute == SQL_ATTR_METADATA_ID ) { connection -> metadata_id = ( SQLLEN ) value; connection -> metadata_id_set = 1; } else if ( attribute == SQL_ATTR_PACKET_SIZE ) { connection -> packet_size = ( SQLLEN ) value; connection -> packet_size_set = 1; } else if ( attribute == SQL_ATTR_QUIET_MODE ) { connection -> quite_mode = ( SQLLEN ) value; connection -> quite_mode_set = 1; } else if ( attribute == SQL_ATTR_TXN_ISOLATION ) { connection -> txn_isolation = ( SQLLEN ) value; connection -> txn_isolation_set = 1; } else if ( attribute != SQL_ATTR_LOGIN_TIMEOUT ) { /* * save any unknown attributes until connect */ struct save_attr sa, *sap; memset( &sa, 0, sizeof ( sa )); sa.attr_type = attribute; if ( string_length > 0 ) { sa.str_attr = malloc( string_length ); memcpy( sa.str_attr, value, string_length ); sa.str_len = string_length; } else if ( string_length == SQL_NTS ) { if (!value) { __post_internal_error( &connection -> error, ERROR_HY024, "Invalid argument value", connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { sa.str_attr = unicode_to_ansi_alloc( value, string_length, connection, NULL ); sa.str_len = string_length; } } else { sa.intptr_attr = (intptr_t) value; sa.str_len = string_length; } sap = connection -> save_attr; while ( sap ) { if ( sap -> attr_type == attribute ) { free ( sap -> str_attr ); break; } sap = sap -> next; } if ( sap ) /* replace existing attribute */ { *sap = sa; } else { sap = malloc( sizeof( struct save_attr )); *sap = sa; sap -> next = connection -> save_attr; connection -> save_attr = sap; } } sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_SUCCESS ); } else { if ( connection -> unicode_driver || CHECK_SQLSETCONNECTATTRW( connection )) { if ( !CHECK_SQLSETCONNECTATTRW( connection )) { if ( CHECK_SQLSETCONNECTOPTIONW( connection )) { /* * Is it in the legal range of values */ if ( attribute < SQL_CONN_DRIVER_MIN && ( attribute > SQL_PACKET_SIZE || attribute < SQL_ACCESS_MODE )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } ret = SQLSETCONNECTOPTIONW( connection, connection -> driver_dbc, attribute, (SQLULEN) value ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { ret = SQLSETCONNECTATTRW( connection, connection -> driver_dbc, attribute, value, string_length ); } } else { if ( !CHECK_SQLSETCONNECTATTR( connection )) { if ( CHECK_SQLSETCONNECTOPTION( connection )) { SQLCHAR *as1 = NULL; /* * Is it in the legal range of values */ if ( attribute < SQL_CONN_DRIVER_MIN && ( attribute > SQL_PACKET_SIZE || attribute < SQL_ACCESS_MODE )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &connection -> error, ERROR_HY092, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } switch( attribute ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( value ) { as1 = (SQLCHAR*) unicode_to_ansi_alloc( value, SQL_NTS, connection, NULL ); } break; } ret = SQLSETCONNECTOPTION( connection, connection -> driver_dbc, attribute, (SQLULEN) (as1 ? as1 : value) ); if ( as1 ) free( as1 ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { SQLCHAR *as1 = NULL; switch( attribute ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if ( value ) { if ( string_length > 0 ) { as1 = (SQLCHAR*) unicode_to_ansi_alloc( value, string_length, connection, NULL ); } else if ( string_length == SQL_NTS ) { as1 = (SQLCHAR*) unicode_to_ansi_alloc( value, SQL_NTS, connection, NULL ); } } ret = SQLSETCONNECTATTR( connection, connection -> driver_dbc, attribute, as1 ? as1 : value, string_length / sizeof( SQLWCHAR )); if ( as1 ) { free( as1 ); } break; default: ret = SQLSETCONNECTATTR( connection, connection -> driver_dbc, attribute, value, string_length ); break; } } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } } /* * catch this */ if ( attribute == SQL_ATTR_USE_BOOKMARKS && SQL_SUCCEEDED( ret )) { connection -> bookmarks_on = (SQLULEN) value; } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetConnectOption.c000066400000000000000000000465501446441710500217420ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetConnectOption.c,v 1.12 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetConnectOption.c,v $ * Revision 1.12 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.11 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.10 2003/03/05 09:48:45 lurcher * * Add some 64 bit fixes * * Revision 1.9 2003/02/27 12:19:40 lurcher * * Add the A functions as well as the W * * Revision 1.8 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.7 2002/07/25 09:30:26 lurcher * * Additional unicode and iconv changes * * Revision 1.6 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.5 2002/07/04 17:27:56 lurcher * * Small bug fixes * * Revision 1.3 2002/01/30 12:20:02 lurcher * * Add MyODBC 3 driver source * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.8 2001/09/27 17:05:48 nick * * Assorted fixes and tweeks * * Revision 1.7 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * Revision 1.6 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.5 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.4 2001/02/07 11:20:23 nick * * Remove some compile warnings * * Revision 1.3 2001/02/06 18:46:55 nick * * More UNICODE ommissions * * Revision 1.2 2000/11/14 10:15:27 nick * * Add test for localtime_r * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.11 2000/06/20 13:30:10 ngorham * * Fix problems when using bookmarks * * Revision 1.10 2000/05/21 21:49:19 ngorham * * Assorted fixes * * Revision 1.9 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.8 1999/11/10 03:51:34 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.7 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.6 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.5 1999/09/19 22:24:34 ngorham * * Added support for the cursor library * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.4 1999/06/03 22:20:25 ngorham * * Finished off the ODBC3-2 mapping * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:21 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetConnectOption.c,v $ $Revision: 1.12 $"; SQLRETURN SQLSetConnectOptionA( SQLHDBC connection_handle, SQLUSMALLINT option, SQLULEN value ) { return SQLSetConnectOption( connection_handle, option, value ); } SQLRETURN SQLSetConnectOption( SQLHDBC connection_handle, SQLUSMALLINT option, SQLULEN value ) { DMHDBC connection = (DMHDBC)connection_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * doesn't require a handle */ if ( option == SQL_ATTR_TRACE ) { if ((SQLLEN) value != SQL_OPT_TRACE_OFF && (SQLLEN) value != SQL_OPT_TRACE_ON ) { if ( __validate_dbc( connection )) { thread_protect( SQL_HANDLE_DBC, connection ); function_entry( connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } } if ( value == SQL_OPT_TRACE_OFF ) { log_info.log_flag = 0; } else { log_info.log_flag = 1; } return SQL_SUCCESS; } else if ( option == SQL_ATTR_TRACEFILE ) { if ( value ) { if (((SQLCHAR*)value)[ 0 ] == '\0' ) { if ( __validate_dbc( connection )) { thread_protect( SQL_HANDLE_DBC, connection ); function_entry( connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } } else { if ( log_info.log_file_name ) { free( log_info.log_file_name ); } log_info.log_file_name = strdup((char*) value ); } } else { if ( __validate_dbc( connection )) { thread_protect( SQL_HANDLE_DBC, connection ); function_entry( connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } } return SQL_SUCCESS; } /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tOption = %s\ \n\t\t\tValue = %d", connection, __con_attr_as_string( s1, option ), (int)value ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( connection -> state == STATE_C2 ) { if ( option == SQL_TRANSLATE_OPTION || option == SQL_TRANSLATE_DLL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else if ( connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else if ( connection -> state == STATE_C4 || connection -> state == STATE_C5 ) { if ( option == SQL_ODBC_CURSORS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08002" ); __post_internal_error( &connection -> error, ERROR_08002, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else if ( connection -> state == STATE_C6 ) { if ( option == SQL_ODBC_CURSORS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08002" ); __post_internal_error( &connection -> error, ERROR_08002, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else if ( option == SQL_TXN_ISOLATION ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1011" ); __post_internal_error( &connection -> error, ERROR_S1011, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } /* * is it a legitimate value */ ret = dm_check_connection_attrs( connection, option, (SQLPOINTER)value ); if ( ret != SQL_SUCCESS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * is it something overridden */ value = (SQLULEN) __attr_override( connection, SQL_HANDLE_DBC, option, (void*) value, NULL ); /* * we need to save this even if connected so we can use it for the next connect */ if ( option == SQL_LOGIN_TIMEOUT ) { connection -> login_timeout_set = 1; connection -> login_timeout = value; } else if ( option == SQL_ATTR_ACCESS_MODE ) { connection -> access_mode = ( SQLLEN ) value; connection -> access_mode_set = 1; } else if ( option == SQL_AUTOCOMMIT ) { connection -> auto_commit = ( SQLINTEGER ) value; connection -> auto_commit_set = 1; } if ( option == SQL_ODBC_CURSORS ) { connection -> cursors = value; ret = SQL_SUCCESS; } else if ( connection -> state == STATE_C2 ) { if ( option == SQL_AUTOCOMMIT ) { connection -> auto_commit = ( SQLINTEGER ) value; connection -> auto_commit_set = 1; } else if ( option == SQL_ATTR_QUIET_MODE ) { connection -> quite_mode = ( SQLLEN ) value; connection -> quite_mode_set = 1; } else if ( option == SQL_ATTR_ACCESS_MODE ) { connection -> access_mode = ( SQLLEN ) value; connection -> access_mode_set = 1; } else { /* * save any unknown attributes until connect */ struct save_attr sa, *sap; memset( &sa, 0, sizeof( sa )); sa.attr_type = option; sa.intptr_attr = value; sap = connection -> save_attr; while ( sap ) { if ( sap -> attr_type == option ) { free( sap -> str_attr ); break; } sap = sap -> next; } if ( sap ) { *sap = sa; } else { sap = malloc( sizeof( struct save_attr )); *sap = sa; sap -> next = connection -> save_attr; connection -> save_attr = sap; } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_SUCCESS ); } else { /* * call the driver */ if ( connection -> unicode_driver ) { if ( CHECK_SQLSETCONNECTOPTIONW( connection )) { ret = SQLSETCONNECTOPTIONW( connection, connection -> driver_dbc, option, value ); } else if ( CHECK_SQLSETCONNECTATTRW( connection )) { SQLINTEGER string_length; void *ptr = (void *) value; switch( option ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: string_length = SQL_NTS; ptr = (void *) ansi_to_unicode_alloc(( SQLCHAR * ) value, SQL_NTS, connection, NULL ); break; default: string_length = 0; break; } ret = SQLSETCONNECTATTRW( connection, connection -> driver_dbc, option, ptr, string_length ); if ( ptr != (void*) value ) { free( ptr ); } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else { if ( CHECK_SQLSETCONNECTOPTION( connection )) { ret = SQLSETCONNECTOPTION( connection, connection -> driver_dbc, option, value ); } else if ( CHECK_SQLSETCONNECTATTR( connection )) { SQLINTEGER string_length; switch( option ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: string_length = SQL_NTS; break; default: string_length = 0; break; } ret = SQLSETCONNECTATTR( connection, connection -> driver_dbc, option, (SQLPOINTER)(intptr_t) value, string_length ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } } /* * catch this */ if ( option == SQL_ATTR_USE_BOOKMARKS && SQL_SUCCEEDED( ret )) { connection -> bookmarks_on = (SQLUINTEGER) value; } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetConnectOptionW.c000066400000000000000000000374431446441710500220720ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetConnectOptionW.c,v 1.10 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetConnectOptionW.c,v $ * Revision 1.10 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.9 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.8 2006/04/18 10:24:47 lurcher * Add a couple of changes from Mark Vanderwiel * * Revision 1.7 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.6 2003/03/05 09:48:45 lurcher * * Add some 64 bit fixes * * Revision 1.5 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.3 2002/01/30 12:20:02 lurcher * * Add MyODBC 3 driver source * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.4 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetConnectOptionW.c,v $"; SQLRETURN SQLSetConnectOptionW( SQLHDBC connection_handle, SQLUSMALLINT option, SQLULEN value ) { DMHDBC connection = (DMHDBC)connection_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; SQLWCHAR buffer[ 512 ]; /* * doesn't require a handle */ if ( option == SQL_ATTR_TRACE ) { if ((SQLLEN) value != SQL_OPT_TRACE_OFF && (SQLLEN) value != SQL_OPT_TRACE_ON ) { if ( __validate_dbc( connection )) { thread_protect( SQL_HANDLE_DBC, connection ); function_entry( connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } } if ( value == SQL_OPT_TRACE_OFF ) { log_info.log_flag = 0; } else { log_info.log_flag = 1; } return SQL_SUCCESS; } else if ( option == SQL_ATTR_TRACEFILE ) { if ( value ) { if (((SQLWCHAR*)value)[ 0 ] == 0 ) { if ( __validate_dbc( connection )) { thread_protect( SQL_HANDLE_DBC, connection ); function_entry( connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } } else { if ( log_info.log_file_name ) { free( log_info.log_file_name ); } log_info.log_file_name = unicode_to_ansi_alloc((SQLWCHAR *) value, SQL_NTS, connection, NULL ); } } else { if ( __validate_dbc( connection )) { thread_protect( SQL_HANDLE_DBC, connection ); function_entry( connection ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else { return SQL_INVALID_HANDLE; } } return SQL_SUCCESS; } /* * check connection */ if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHDBC parent_connection; parent_connection = find_parent_handle( connection, SQL_HANDLE_DBC ); if ( parent_connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLSETCONNECTOPTIONW( parent_connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLSETCONNECTOPTIONW( parent_connection, connection_handle, option, value ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tConnection = %p\ \n\t\t\tOption = %s\ \n\t\t\tValue = %d", connection, __con_attr_as_string( s1, option ), (int)value ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( connection -> state == STATE_C2 ) { if ( option == SQL_TRANSLATE_OPTION || option == SQL_TRANSLATE_DLL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else if ( connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else if ( connection -> state == STATE_C4 || connection -> state == STATE_C5 ) { if ( option == SQL_ODBC_CURSORS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08002" ); __post_internal_error( &connection -> error, ERROR_08002, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } else if ( connection -> state == STATE_C6 ) { if ( option == SQL_ODBC_CURSORS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08002" ); __post_internal_error( &connection -> error, ERROR_08002, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } else if ( option == SQL_TXN_ISOLATION ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1011" ); __post_internal_error( &connection -> error, ERROR_S1011, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } } /* * is it a legitimate value */ ret = dm_check_connection_attrs( connection, option, (SQLPOINTER)value ); if ( ret != SQL_SUCCESS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &connection -> error, ERROR_HY024, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * is it something overridden */ value = (SQLULEN) __attr_override_wide( connection, SQL_HANDLE_DBC, option, (void*) value, NULL, buffer ); if ( option == SQL_LOGIN_TIMEOUT ) { connection -> login_timeout_set = 1; connection -> login_timeout = value; ret = SQL_SUCCESS; } else if ( option == SQL_ATTR_ACCESS_MODE ) { connection -> access_mode = ( SQLLEN ) value; connection -> access_mode_set = 1; } else if ( option == SQL_AUTOCOMMIT ) { connection -> auto_commit = ( SQLINTEGER ) value; connection -> auto_commit_set = 1; } if ( option == SQL_ODBC_CURSORS ) { connection -> cursors = value; ret = SQL_SUCCESS; } else if ( connection -> state == STATE_C2 ) { if ( option == SQL_AUTOCOMMIT ) { connection -> auto_commit = ( SQLINTEGER ) value; connection -> auto_commit_set = 1; } else if ( option == SQL_ATTR_QUIET_MODE ) { connection -> quite_mode = ( SQLLEN ) value; connection -> quite_mode_set = 1; } else if ( option == SQL_ATTR_ACCESS_MODE ) { connection -> access_mode = ( SQLLEN ) value; connection -> access_mode_set = 1; } else { /* * save any unknown attributes untill connect */ struct save_attr sa, *sap; memset( &sa, 0, sizeof( sa )); sa.attr_type = option; sa.intptr_attr = value; sap = connection -> save_attr; while ( sap ) { if ( sap -> attr_type == option ) { free( sap -> str_attr ); break; } sap = sap -> next; } if ( sap ) { *sap = sa; } else { sap = malloc( sizeof( struct save_attr )); *sap = sa; sap -> next = connection -> save_attr; connection -> save_attr = sap; } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_SUCCESS ); } else { /* * call the driver */ if ( CHECK_SQLSETCONNECTOPTIONW( connection )) { ret = SQLSETCONNECTOPTIONW( connection, connection -> driver_dbc, option, value ); } else if ( CHECK_SQLSETCONNECTATTRW( connection )) { SQLINTEGER string_length; switch( option ) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: string_length = SQL_NTS; break; default: string_length = 0; break; } ret = SQLSETCONNECTATTRW( connection, connection -> driver_dbc, option, (SQLPOINTER)(intptr_t) value, string_length ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } } /* * catch this */ if ( option == SQL_ATTR_USE_BOOKMARKS && SQL_SUCCEEDED( ret )) { connection -> bookmarks_on = (SQLUINTEGER) value; } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetCursorName.c000066400000000000000000000210001446441710500212150ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetCursorName.c,v 1.6 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetCursorName.c,v $ * Revision 1.6 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/02/27 12:19:40 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:18 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetCursorName.c,v $ $Revision: 1.6 $"; SQLRETURN SQLSetCursorNameA( SQLHSTMT statement_handle, SQLCHAR *cursor_name, SQLSMALLINT name_length ) { return SQLSetCursorName( statement_handle, cursor_name, name_length ); } SQLRETURN SQLSetCursorName( SQLHSTMT statement_handle, SQLCHAR *cursor_name, SQLSMALLINT name_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCursor name = %s", statement, __string_with_length( s1, cursor_name, name_length )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( !cursor_name || (name_length < 0 && name_length != SQL_NTS ) ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S4 || statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1; int wlen; if ( !CHECK_SQLSETCURSORNAMEW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( cursor_name, name_length, statement -> connection, &wlen ); name_length = wlen; ret = SQLSETCURSORNAMEW( statement -> connection, statement -> driver_stmt, s1, name_length ); if ( s1 ) free( s1 ); } else { if ( !CHECK_SQLSETCURSORNAME( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLSETCURSORNAME( statement -> connection, statement -> driver_stmt, cursor_name, name_length ); } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetCursorNameW.c000066400000000000000000000170251446441710500213600ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetCursorNameW.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetCursorNameW.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetCursorNameW.c,v $"; SQLRETURN SQLSetCursorNameW( SQLHSTMT statement_handle, SQLWCHAR *cursor_name, SQLSMALLINT name_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCursor name = %s", statement, __wstring_with_length( s1, cursor_name, name_length )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( !cursor_name || (name_length < 0 && name_length != SQL_NTS ) ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S4 || statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> connection -> unicode_driver || CHECK_SQLSETCURSORNAMEW( statement -> connection )) { if ( !CHECK_SQLSETCURSORNAMEW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLSETCURSORNAMEW( statement -> connection, statement -> driver_stmt, cursor_name, name_length ); } else { SQLCHAR *as1; int clen; if ( !CHECK_SQLSETCURSORNAME( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } as1 = (SQLCHAR*) unicode_to_ansi_alloc( cursor_name, name_length, statement -> connection, &clen ); name_length = clen; ret = SQLSETCURSORNAME( statement -> connection, statement -> driver_stmt, as1, name_length ); if ( as1 ) free( as1 ); } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetDescField.c000066400000000000000000000274031446441710500207760ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetDescField.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetDescField.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2007/05/25 16:42:32 lurcher * Sync up * * Revision 1.5 2005/11/21 17:25:43 lurcher * A few DM fixes for Oracle's ODBC driver * * Revision 1.4 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2003/02/27 12:19:40 lurcher * * Add the A functions as well as the W * * Revision 1.2 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/17 16:29:39 nick * * More checks and autotest fixes * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:00 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetDescField.c,v $ $Revision: 1.7 $"; SQLRETURN SQLSetDescFieldA( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT field_identifier, SQLPOINTER value, SQLINTEGER buffer_length ) { return SQLSetDescField( descriptor_handle, rec_number, field_identifier, value, buffer_length ); } SQLRETURN SQLSetDescField( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT field_identifier, SQLPOINTER value, SQLINTEGER buffer_length ) { /* * not quite sure how the descriptor can be * allocated to a statement, all the documentation talks * about state transitions on statement states, but the * descriptor may be allocated with more than one statement * at one time. Which one should I check ? */ DMHDESC descriptor = (DMHDESC) descriptor_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; int isStrField = 0; /* * check descriptor */ if ( !__validate_desc( descriptor )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( descriptor ); if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tEntry:\ \n\t\t\tDescriptor = %p\ \n\t\t\tRec Number = %d\ \n\t\t\tField Ident = %s\ \n\t\t\tValue = %p\ \n\t\t\tBuffer Length = %d", descriptor, rec_number, __desc_attr_as_string( s1, field_identifier ), value, (int)buffer_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } thread_protect( SQL_HANDLE_DESC, descriptor ); if ( descriptor -> connection -> state < STATE_C4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } /* * check status of statements associated with this descriptor */ if( __check_stmt_from_desc( descriptor, STATE_S8 ) || __check_stmt_from_desc( descriptor, STATE_S9 ) || __check_stmt_from_desc( descriptor, STATE_S10 ) || __check_stmt_from_desc( descriptor, STATE_S11 ) || __check_stmt_from_desc( descriptor, STATE_S12 ) || __check_stmt_from_desc( descriptor, STATE_S13 ) || __check_stmt_from_desc( descriptor, STATE_S14 ) || __check_stmt_from_desc( descriptor, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( rec_number < 0 ) { __post_internal_error( &descriptor -> error, ERROR_07009, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } switch ( field_identifier ) { /* Fixed-length fields: buffer_length is ignored */ case SQL_DESC_ALLOC_TYPE: case SQL_DESC_ARRAY_SIZE: case SQL_DESC_ARRAY_STATUS_PTR: case SQL_DESC_BIND_OFFSET_PTR: case SQL_DESC_BIND_TYPE: case SQL_DESC_COUNT: case SQL_DESC_ROWS_PROCESSED_PTR: case SQL_DESC_AUTO_UNIQUE_VALUE: case SQL_DESC_CASE_SENSITIVE: case SQL_DESC_CONCISE_TYPE: case SQL_DESC_DATA_PTR: case SQL_DESC_DATETIME_INTERVAL_CODE: case SQL_DESC_DATETIME_INTERVAL_PRECISION: case SQL_DESC_DISPLAY_SIZE: case SQL_DESC_FIXED_PREC_SCALE: case SQL_DESC_INDICATOR_PTR: case SQL_DESC_LENGTH: case SQL_DESC_NULLABLE: case SQL_DESC_NUM_PREC_RADIX: case SQL_DESC_OCTET_LENGTH: case SQL_DESC_OCTET_LENGTH_PTR: case SQL_DESC_PARAMETER_TYPE: case SQL_DESC_PRECISION: case SQL_DESC_ROWVER: case SQL_DESC_SCALE: case SQL_DESC_SEARCHABLE: case SQL_DESC_TYPE: case SQL_DESC_UNNAMED: case SQL_DESC_UNSIGNED: case SQL_DESC_UPDATABLE: isStrField = 0; break; /* Pointer to data: buffer_length must be valid */ case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_CATALOG_NAME: case SQL_DESC_LABEL: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: isStrField = 1; break; default: isStrField = buffer_length != SQL_IS_POINTER && buffer_length != SQL_IS_INTEGER && buffer_length != SQL_IS_UINTEGER && buffer_length != SQL_IS_SMALLINT && buffer_length != SQL_IS_USMALLINT; } if ( isStrField && buffer_length < 0 && buffer_length != SQL_NTS) { __post_internal_error( &descriptor -> error, ERROR_HY090, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( field_identifier == SQL_DESC_COUNT && (intptr_t)value < 0 ) { __post_internal_error( &descriptor -> error, ERROR_07009, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( field_identifier == SQL_DESC_PARAMETER_TYPE && (intptr_t)value != SQL_PARAM_INPUT && (intptr_t)value != SQL_PARAM_OUTPUT && (intptr_t)value != SQL_PARAM_INPUT_OUTPUT && (intptr_t)value != SQL_PARAM_INPUT_OUTPUT_STREAM && (intptr_t)value != SQL_PARAM_OUTPUT_STREAM ) { __post_internal_error( &descriptor -> error, ERROR_HY105, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( CHECK_SQLSETDESCFIELD( descriptor -> connection )) { ret = SQLSETDESCFIELD( descriptor -> connection, descriptor -> driver_desc, rec_number, field_identifier, value, buffer_length ); } else if ( CHECK_SQLSETDESCFIELDW( descriptor -> connection )) { SQLWCHAR *s1 = NULL; if (isStrField) { s1 = ansi_to_unicode_alloc( value, buffer_length, descriptor -> connection, NULL ); if (SQL_NTS != buffer_length) { buffer_length *= sizeof(SQLWCHAR); } } else { s1 = value; } ret = SQLSETDESCFIELDW( descriptor -> connection, descriptor -> driver_desc, rec_number, field_identifier, s1, buffer_length ); if (isStrField) { if (s1) free(s1); } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } return function_return( SQL_HANDLE_DESC, descriptor, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetDescFieldW.c000066400000000000000000000304241446441710500211220ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetDescFieldW.c,v 1.8 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetDescFieldW.c,v $ * Revision 1.8 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.7 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.6 2007/03/05 09:49:24 lurcher * Get it to build on VMS again * * Revision 1.5 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.4 2006/04/18 10:24:47 lurcher * Add a couple of changes from Mark Vanderwiel * * Revision 1.3 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.2 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/17 16:29:39 nick * * More checks and autotest fixes * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetDescFieldW.c,v $"; SQLRETURN SQLSetDescFieldW( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT field_identifier, SQLPOINTER value, SQLINTEGER buffer_length ) { /* * not quite sure how the descriptor can be * allocated to a statement, all the documentation talks * about state transitions on statement states, but the * descriptor may be allocated with more than one statement * at one time. Which one should I check ? */ DMHDESC descriptor = (DMHDESC) descriptor_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; int isStrField = 0; /* * check descriptor */ if ( !__validate_desc( descriptor )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHDESC parent_desc; parent_desc = find_parent_handle( descriptor, SQL_HANDLE_DESC ); if ( parent_desc ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLSETDESCFIELDW( parent_desc -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLSETDESCFIELDW( parent_desc -> connection, descriptor, rec_number, field_identifier, value, buffer_length ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( descriptor ); if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tEntry:\ \n\t\t\tDescriptor = %p\ \n\t\t\tRec Number = %d\ \n\t\t\tField Ident = %s\ \n\t\t\tValue = %p\ \n\t\t\tBuffer Length = %d", descriptor, rec_number, __desc_attr_as_string( s1, field_identifier ), value, (int)buffer_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } thread_protect( SQL_HANDLE_DESC, descriptor ); if ( descriptor -> connection -> state < STATE_C4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } /* * check status of statements associated with this descriptor */ if( __check_stmt_from_desc( descriptor, STATE_S8 ) || __check_stmt_from_desc( descriptor, STATE_S9 ) || __check_stmt_from_desc( descriptor, STATE_S10 ) || __check_stmt_from_desc( descriptor, STATE_S11 ) || __check_stmt_from_desc( descriptor, STATE_S12 ) || __check_stmt_from_desc( descriptor, STATE_S13 ) || __check_stmt_from_desc( descriptor, STATE_S14 ) || __check_stmt_from_desc( descriptor, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( rec_number < 0 ) { __post_internal_error( &descriptor -> error, ERROR_07009, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } switch ( field_identifier ) { /* Fixed-length fields: buffer_length is ignored */ case SQL_DESC_ALLOC_TYPE: case SQL_DESC_ARRAY_SIZE: case SQL_DESC_ARRAY_STATUS_PTR: case SQL_DESC_BIND_OFFSET_PTR: case SQL_DESC_BIND_TYPE: case SQL_DESC_COUNT: case SQL_DESC_ROWS_PROCESSED_PTR: case SQL_DESC_AUTO_UNIQUE_VALUE: case SQL_DESC_CASE_SENSITIVE: case SQL_DESC_CONCISE_TYPE: case SQL_DESC_DATA_PTR: case SQL_DESC_DATETIME_INTERVAL_CODE: case SQL_DESC_DATETIME_INTERVAL_PRECISION: case SQL_DESC_DISPLAY_SIZE: case SQL_DESC_FIXED_PREC_SCALE: case SQL_DESC_INDICATOR_PTR: case SQL_DESC_LENGTH: case SQL_DESC_NULLABLE: case SQL_DESC_NUM_PREC_RADIX: case SQL_DESC_OCTET_LENGTH: case SQL_DESC_OCTET_LENGTH_PTR: case SQL_DESC_PARAMETER_TYPE: case SQL_DESC_PRECISION: case SQL_DESC_ROWVER: case SQL_DESC_SCALE: case SQL_DESC_SEARCHABLE: case SQL_DESC_TYPE: case SQL_DESC_UNNAMED: case SQL_DESC_UNSIGNED: case SQL_DESC_UPDATABLE: isStrField = 0; break; /* Pointer to data: buffer_length must be valid */ case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_CATALOG_NAME: case SQL_DESC_LABEL: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: isStrField = 1; break; default: isStrField = buffer_length != SQL_IS_POINTER && buffer_length != SQL_IS_INTEGER && buffer_length != SQL_IS_UINTEGER && buffer_length != SQL_IS_SMALLINT && buffer_length != SQL_IS_USMALLINT; } if ( isStrField && buffer_length < 0 && buffer_length != SQL_NTS) { __post_internal_error( &descriptor -> error, ERROR_HY090, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( field_identifier == SQL_DESC_COUNT && (intptr_t)value < 0 ) { __post_internal_error( &descriptor -> error, ERROR_07009, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( field_identifier == SQL_DESC_PARAMETER_TYPE && (intptr_t)value != SQL_PARAM_INPUT && (intptr_t)value != SQL_PARAM_OUTPUT && (intptr_t)value != SQL_PARAM_INPUT_OUTPUT && (intptr_t)value != SQL_PARAM_INPUT_OUTPUT_STREAM && (intptr_t)value != SQL_PARAM_OUTPUT_STREAM ) { __post_internal_error( &descriptor -> error, ERROR_HY105, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( descriptor -> connection -> unicode_driver || CHECK_SQLSETDESCFIELDW( descriptor -> connection )) { if ( !CHECK_SQLSETDESCFIELDW( descriptor -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } ret = SQLSETDESCFIELDW( descriptor -> connection, descriptor -> driver_desc, rec_number, field_identifier, value, buffer_length ); if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } } else { SQLCHAR *ascii_str = NULL; if ( !CHECK_SQLSETDESCFIELD( descriptor -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } /* * is it a char arg... */ switch ( field_identifier ) { case SQL_DESC_NAME: /* This is the only R/W SQLCHAR* type */ ascii_str = (SQLCHAR*) unicode_to_ansi_alloc( value, buffer_length, descriptor -> connection, NULL ); value = ascii_str; buffer_length = strlen((char*) ascii_str ); break; default: break; } ret = SQLSETDESCFIELD( descriptor -> connection, descriptor -> driver_desc, rec_number, field_identifier, value, buffer_length ); if ( log_info.log_flag ) { sprintf( descriptor -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, descriptor -> msg ); } if ( ascii_str ) { free( ascii_str ); } } return function_return( SQL_HANDLE_DESC, descriptor, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetDescRec.c000066400000000000000000000142441446441710500204630ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetDescRec.c,v 1.4 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetDescRec.c,v $ * Revision 1.4 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.3 2001/04/17 16:29:39 nick * * More checks and autotest fixes * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.5 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetDescRec.c,v $ $Revision: 1.4 $"; SQLRETURN SQLSetDescRec( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT type, SQLSMALLINT subtype, SQLLEN length, SQLSMALLINT precision, SQLSMALLINT scale, SQLPOINTER data, SQLLEN *string_length, SQLLEN *indicator ) { /* * not quite sure how the descriptor can be * allocated to a statement, all the documentation talks * about state transitions on statement states, but the * descriptor may be allocated with more than one statement * at one time. Which one should I check ? */ DMHDESC descriptor = (DMHDESC) descriptor_handle; SQLRETURN ret; /* * check descriptor */ if ( !__validate_desc( descriptor )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( descriptor ); thread_protect( SQL_HANDLE_DESC, descriptor ); if ( descriptor -> connection -> state < STATE_C4 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } /* * check status of statements associated with this descriptor */ if( __check_stmt_from_desc( descriptor, STATE_S8 ) || __check_stmt_from_desc( descriptor, STATE_S9 ) || __check_stmt_from_desc( descriptor, STATE_S10 ) || __check_stmt_from_desc( descriptor, STATE_S11 ) || __check_stmt_from_desc( descriptor, STATE_S12 ) || __check_stmt_from_desc( descriptor, STATE_S13 ) || __check_stmt_from_desc( descriptor, STATE_S14 ) || __check_stmt_from_desc( descriptor, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &descriptor -> error, ERROR_HY010, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } if ( !CHECK_SQLSETDESCREC( descriptor -> connection )) { __post_internal_error( &descriptor -> error, ERROR_IM001, NULL, descriptor -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DESC, descriptor, SQL_ERROR ); } ret = SQLSETDESCREC( descriptor -> connection, descriptor -> driver_desc, rec_number, type, subtype, length, precision, scale, data, string_length, indicator ); return function_return( SQL_HANDLE_DESC, descriptor, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetEnvAttr.c000066400000000000000000000254741446441710500205450ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetEnvAttr.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetEnvAttr.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.7 2004/06/21 10:01:11 lurcher * * Fix a couple of 64 bit issues * * Revision 1.6 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2003/03/05 09:48:45 lurcher * * Add some 64 bit fixes * * Revision 1.4 2003/01/23 15:33:25 lurcher * * Fix problems with using putenv() * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/02/21 18:44:09 lurcher * * Fix bug on 32 bit platforms without long long support * Add option to set environment variables from the ini file * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.5 2001/09/27 17:05:48 nick * * Assorted fixes and tweeks * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/14 18:10:19 nick * * Add connection pooling * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetEnvAttr.c,v $ $Revision: 1.9 $"; extern int pooling_enabled; SQLRETURN SQLSetEnvAttr( SQLHENV environment_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length ) { DMHENV environment = (DMHENV) environment_handle; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; if ( !environment_handle && ( attribute == SQL_ATTR_CONNECTION_POOLING || attribute == SQL_ATTR_CP_MATCH )) { if ( attribute == SQL_ATTR_CONNECTION_POOLING ) { if ((SQLLEN) value == SQL_CP_ONE_PER_DRIVER || (SQLLEN) value == SQL_CP_ONE_PER_HENV ) { pooling_enabled = 1; } } return SQL_SUCCESS; } /* * check environment */ if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( environment ); if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tEntry:\ \n\t\t\tEnvironment = %p\ \n\t\t\tAttribute = %s\ \n\t\t\tValue = %p\ \n\t\t\tStrLen = %d", environment, __env_attr_as_string( s1, attribute ), value, (int)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } thread_protect( SQL_HANDLE_ENV, environment ); switch ( attribute ) { case SQL_ATTR_CONNECTION_POOLING: { #ifdef HAVE_PTRDIFF_T SQLUINTEGER ptr = (ptrdiff_t) value; #else SQLUINTEGER ptr = (SQLUINTEGER) value; #endif if ( ptr != SQL_CP_OFF && ptr != SQL_CP_ONE_PER_DRIVER && ptr != SQL_CP_ONE_PER_HENV ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &environment -> error, ERROR_HY024, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } environment -> connection_pooling = ptr; } break; case SQL_ATTR_CP_MATCH: { #ifdef HAVE_PTRDIFF_T SQLUINTEGER ptr = (ptrdiff_t) value; #else SQLUINTEGER ptr = (SQLUINTEGER) value; #endif if ( ptr != SQL_CP_STRICT_MATCH && ptr != SQL_CP_RELAXED_MATCH ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &environment -> error, ERROR_HY024, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } environment -> cp_match = ptr; } break; case SQL_ATTR_ODBC_VERSION: { #ifdef HAVE_PTRDIFF_T SQLUINTEGER ptr = (ptrdiff_t) value; #else SQLUINTEGER ptr = (SQLUINTEGER) value; #endif if ( ptr != SQL_OV_ODBC2 && ptr != SQL_OV_ODBC3 && ptr != SQL_OV_ODBC3_80 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &environment -> error, ERROR_HY024, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } else { if ( environment -> connection_count > 0 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1010" ); __post_internal_error( &environment -> error, ERROR_S1010, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } environment -> requested_version = ptr; environment -> version_set = 1; } } break; case SQL_ATTR_OUTPUT_NTS: { #ifdef HAVE_PTRDIFF_T SQLUINTEGER ptr = (ptrdiff_t) value; #else SQLUINTEGER ptr = (SQLUINTEGER) value; #endif /* * this must be one of the most brain dead atribute, * it can be set, but only to TRUE, any other value * (ie FALSE) returns a error. It's almost as if it's not * settable :-) */ if ( ptr == SQL_FALSE ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HYC00" ); __post_internal_error( &environment -> error, ERROR_HYC00, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } } break; /* * unixODBC additions */ case SQL_ATTR_UNIXODBC_ENVATTR: if ( value ) { char *str = (char*) value; /* * its a memory leak, but not much I can do, see "man putenv" */ putenv( strdup( str )); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } break; /* * Third party extensions */ case 1064: /* SQL_ATTR_APP_UNICODE_TYPE */ break; default: dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &environment -> error, ERROR_HY092, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_SUCCESS ); } unixODBC-2.3.12/DriverManager/SQLSetParam.c000066400000000000000000000304531446441710500202130ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetParam.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetParam.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2005/04/26 08:40:35 lurcher * * Add data type mapping for SQLSetPos. * Remove out of date macro in sqlext.h * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/19 09:11:49 lurcher * * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/10/29 21:07:40 ngorham * * Fix some stupid bugs in the DM * Make the postgres driver work via unix sockets * * Revision 1.6 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:25 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.4 1999/06/03 22:20:25 ngorham * * Finished off the ODBC3-2 mapping * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:21 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetParam.c,v $ $Revision: 1.7 $"; int check_value_type( int c_type, int connection_mode) { /* * * driver defined types * */ if ( connection_mode >= SQL_OV_ODBC3_80 && c_type >= 0x4000 && c_type <= 0x7FFF ) { return 1; } switch( c_type ) { case SQL_C_CHAR: case SQL_C_LONG: case SQL_C_SHORT: case SQL_C_FLOAT: case SQL_C_NUMERIC: case SQL_C_DEFAULT: case SQL_C_DATE: case SQL_C_TIME: case SQL_C_TIMESTAMP: case SQL_C_TYPE_DATE: case SQL_C_TYPE_TIME: case SQL_C_TYPE_TIMESTAMP: case SQL_C_INTERVAL_YEAR: case SQL_C_INTERVAL_MONTH: case SQL_C_INTERVAL_DAY: case SQL_C_INTERVAL_HOUR: case SQL_C_INTERVAL_MINUTE: case SQL_C_INTERVAL_SECOND: case SQL_C_INTERVAL_YEAR_TO_MONTH: case SQL_C_INTERVAL_DAY_TO_HOUR: case SQL_C_INTERVAL_DAY_TO_MINUTE: case SQL_C_INTERVAL_DAY_TO_SECOND: case SQL_C_INTERVAL_HOUR_TO_MINUTE: case SQL_C_INTERVAL_HOUR_TO_SECOND: case SQL_C_INTERVAL_MINUTE_TO_SECOND: case SQL_C_BINARY: case SQL_C_BIT: case SQL_C_SBIGINT: case SQL_C_UBIGINT: case SQL_C_TINYINT: case SQL_C_SLONG: case SQL_C_SSHORT: case SQL_C_STINYINT: case SQL_C_ULONG: case SQL_C_USHORT: case SQL_C_UTINYINT: case SQL_C_GUID: case SQL_C_WCHAR: case SQL_ARD_TYPE: case SQL_C_DOUBLE: /* case SQL_C_XML: still trying to find what value this is */ return 1; default: return 0; } } SQLRETURN SQLSetParam( SQLHSTMT statement_handle, SQLUSMALLINT parameter_number, SQLSMALLINT value_type, SQLSMALLINT parameter_type, SQLULEN length_precision, SQLSMALLINT parameter_scale, SQLPOINTER parameter_value, SQLLEN *strlen_or_ind ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tParam Number = %d\ \n\t\t\tValue Type = %d %s\ \n\t\t\tParameter Type = %d %s\ \n\t\t\tLength Precision = %d\ \n\t\t\tParameter Scale = %d\ \n\t\t\tParameter Value = %p\ \n\t\t\tStrLen Or Ind = %p", statement, parameter_number, value_type, __c_as_text( value_type ), parameter_type, __sql_as_text( parameter_type ), (int)length_precision, (int)parameter_scale, (void*)parameter_value, (void*)strlen_or_ind ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( parameter_number < 1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 07009" ); __post_internal_error_api( &statement -> error, ERROR_07009, NULL, statement -> connection -> environment -> requested_version, SQL_API_SQLSETPARAM ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if (!check_value_type( value_type, statement -> connection -> environment -> requested_version )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY003" ); __post_internal_error_api( &statement -> error, ERROR_HY003, NULL, statement -> connection -> environment -> requested_version, SQL_API_SQLSETPARAM ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( parameter_value == NULL && strlen_or_ind == NULL && value_type != SQL_PARAM_OUTPUT ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error_api( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version, SQL_API_SQLSETPARAM ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( CHECK_SQLSETPARAM( statement -> connection )) { ret = SQLSETPARAM( statement -> connection, statement -> driver_stmt, parameter_number, __map_type(MAP_C_DM2D,statement->connection,value_type), __map_type(MAP_SQL_DM2D,statement->connection,parameter_type), length_precision, parameter_scale, parameter_value, strlen_or_ind ); } else if ( CHECK_SQLBINDPARAMETER( statement -> connection )) { ret = SQLBINDPARAMETER( statement -> connection, statement -> driver_stmt, parameter_number, SQL_PARAM_INPUT_OUTPUT, __map_type(MAP_C_DM2D,statement->connection,value_type), __map_type(MAP_SQL_DM2D,statement->connection,parameter_type), length_precision, parameter_scale, parameter_value, SQL_SETPARAM_VALUE_MAX, strlen_or_ind ); } else if ( CHECK_SQLBINDPARAM( statement -> connection )) { ret = SQLBINDPARAM( statement -> connection, statement -> driver_stmt, parameter_number, __map_type(MAP_C_DM2D,statement->connection,value_type), __map_type(MAP_SQL_DM2D,statement->connection,parameter_type), length_precision, parameter_scale, parameter_value, strlen_or_ind ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetPos.c000066400000000000000000000244631446441710500177200ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetPos.c,v 1.6 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetPos.c,v $ * Revision 1.6 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.4 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/10/29 21:07:40 ngorham * * Fix some stupid bugs in the DM * Make the postgres driver work via unix sockets * * Revision 1.6 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:26 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/05/04 22:41:12 nick * and another night ends * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetPos.c,v $ $Revision: 1.6 $"; SQLRETURN SQLSetPos( SQLHSTMT statement_handle, SQLSETPOSIROW irow, SQLUSMALLINT foption, SQLUSMALLINT flock ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tIrow = %ld\ \n\t\t\tFoption = %d\ \n\t\t\tFlock = %d", statement, (long int)irow, foption, flock ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( foption != SQL_POSITION && foption != SQL_REFRESH && foption != SQL_UPDATE && foption != SQL_DELETE && foption != SQL_ADD ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &statement -> error, ERROR_HY092, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( flock != SQL_LOCK_NO_CHANGE && flock != SQL_LOCK_EXCLUSIVE && flock != SQL_LOCK_UNLOCK ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &statement -> error, ERROR_HY092, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ if ( statement -> state == STATE_S1 || statement -> state == STATE_S2 || statement -> state == STATE_S3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S4 || statement -> state == STATE_S5 || (foption != SQL_ADD && statement -> state == STATE_S7 && statement -> eod )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func == SQL_API_SQLEXTENDEDFETCH ) { __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> interupted_func != SQL_API_SQLSETPOS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( !CHECK_SQLSETPOS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLSETPOS( statement -> connection, statement -> driver_stmt, irow, foption, flock ); if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLSETPOS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) { statement -> interupted_state = statement -> state; statement -> state = STATE_S11; } } else if ( SQL_SUCCEEDED( ret ) && (statement -> state == STATE_S11 || statement -> state == STATE_S12)) { statement -> state = statement -> interupted_state; } else if ( ret == SQL_NEED_DATA ) { statement -> interupted_func = SQL_API_SQLSETPOS; statement -> interupted_state = statement -> state; statement -> state = STATE_S8; } else if (statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { statement -> state = statement -> interupted_state; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetScrollOptions.c000066400000000000000000000435111446441710500217640ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetScrollOptions.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetScrollOptions.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2007/01/02 10:27:50 lurcher * Fix descriptor leak with unicode only driver * * Revision 1.7 2005/11/23 08:29:16 lurcher * Add cleanup in postgres driver * * Revision 1.6 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/01/15 10:31:34 lurcher * * Fix invalid diag message * * Revision 1.3 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.2 2001/12/04 10:16:59 lurcher * * Fix SQLSetScrollOption problem * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:26 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb * first go at it * * Revision 1.5 1999/06/03 22:20:25 ngorham * * Finished off the ODBC3-2 mapping * * Revision 1.4 1999/06/02 23:48:45 ngorham * * Added more 3-2 mapping * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:21 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetScrollOptions.c,v $ $Revision: 1.9 $"; SQLRETURN SQLSetScrollOptions( SQLHSTMT statement_handle, SQLUSMALLINT f_concurrency, SQLLEN crow_keyset, SQLUSMALLINT crow_rowset ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tConcurrency = %d\ \n\t\t\tKeyset = %d\ \n\t\t\tRowset = %d", statement, f_concurrency, (int)crow_keyset, crow_rowset ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( statement -> state != STATE_S1 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1010" ); __post_internal_error( &statement -> error, ERROR_S1010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if (( crow_keyset != SQL_SCROLL_FORWARD_ONLY && crow_keyset != SQL_SCROLL_STATIC && crow_keyset != SQL_SCROLL_KEYSET_DRIVEN && crow_keyset != SQL_SCROLL_DYNAMIC ) || !crow_rowset) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1107" ); __post_internal_error( &statement -> error, ERROR_S1107, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( f_concurrency != SQL_CONCUR_READ_ONLY && f_concurrency != SQL_CONCUR_LOCK && f_concurrency != SQL_CONCUR_ROWVER && f_concurrency != SQL_CONCUR_VALUES ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1108" ); __post_internal_error( &statement -> error, ERROR_S1108, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( CHECK_SQLSETSCROLLOPTIONS( statement -> connection )) { ret = SQLSETSCROLLOPTIONS( statement -> connection, statement -> driver_stmt, f_concurrency, crow_keyset, crow_rowset ); } else if ( statement -> connection -> driver_act_ver >= SQL_OV_ODBC3 && (CHECK_SQLGETINFO( statement -> connection ) || CHECK_SQLGETINFOW( statement -> connection )) && (CHECK_SQLSETSTMTATTR( statement -> connection ) || CHECK_SQLSETSTMTATTRW( statement -> connection ))) { SQLINTEGER info_type, ivp; switch( crow_keyset ) { case SQL_SCROLL_FORWARD_ONLY: info_type = SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2; break; case SQL_SCROLL_STATIC: info_type = SQL_STATIC_CURSOR_ATTRIBUTES2; break; case SQL_SCROLL_KEYSET_DRIVEN: info_type = SQL_KEYSET_CURSOR_ATTRIBUTES2; break; case SQL_SCROLL_DYNAMIC: info_type = SQL_DYNAMIC_CURSOR_ATTRIBUTES2; break; default: if ( crow_keyset > crow_rowset ) { info_type = SQL_KEYSET_CURSOR_ATTRIBUTES2; } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1107" ); __post_internal_error( &statement -> error, ERROR_S1107, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } break; } ret = __SQLGetInfo( statement -> connection, info_type, &ivp, sizeof( ivp ), 0 ); if( !SQL_SUCCEEDED( ret )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQLGetInfo fails" ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR, DEFER_R3 ); } if ( f_concurrency == SQL_CONCUR_READ_ONLY && !( ivp & SQL_CA2_READ_ONLY_CONCURRENCY )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1C00" ); __post_internal_error( &statement -> error, ERROR_S1C00, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR, DEFER_R3 ); } else if ( f_concurrency == SQL_CONCUR_LOCK && !( ivp & SQL_CA2_LOCK_CONCURRENCY )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1C00" ); __post_internal_error( &statement -> error, ERROR_S1C00, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR, DEFER_R3 ); } else if ( f_concurrency == SQL_CONCUR_ROWVER && !( ivp & SQL_CA2_OPT_ROWVER_CONCURRENCY )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1C00" ); __post_internal_error( &statement -> error, ERROR_S1C00, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR, DEFER_R3 ); } if ( f_concurrency == SQL_CONCUR_VALUES && !( ivp & SQL_CA2_OPT_VALUES_CONCURRENCY )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1C00" ); __post_internal_error( &statement -> error, ERROR_S1C00, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR, DEFER_R3 ); } if ( f_concurrency != SQL_CONCUR_READ_ONLY && f_concurrency != SQL_CONCUR_LOCK && f_concurrency != SQL_CONCUR_ROWVER && f_concurrency != SQL_CONCUR_VALUES ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1108" ); __post_internal_error( &statement -> error, ERROR_S1108, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR, DEFER_R3 ); } if(CHECK_SQLSETSTMTATTR( statement -> connection )) { ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER)(intptr_t) f_concurrency, 0 ); } else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER)(intptr_t) f_concurrency, 0 ); } if ( !SQL_SUCCEEDED( ret )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQLSetStmtAttr fails" ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR, DEFER_R3 ); } switch( crow_keyset ) { case SQL_SCROLL_FORWARD_ONLY: info_type = SQL_CURSOR_FORWARD_ONLY; break; case SQL_SCROLL_STATIC: info_type = SQL_CURSOR_STATIC; break; case SQL_SCROLL_KEYSET_DRIVEN: info_type = SQL_CURSOR_KEYSET_DRIVEN; break; case SQL_SCROLL_DYNAMIC: info_type = SQL_CURSOR_DYNAMIC; break; default: if ( crow_keyset > crow_rowset ) { info_type = SQL_CURSOR_KEYSET_DRIVEN; } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1107" ); __post_internal_error( &statement -> error, ERROR_S1107, NULL, statement -> connection -> environment -> requested_version ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR, DEFER_R3 ); } break; } if(CHECK_SQLSETSTMTATTR( statement -> connection )) { ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)(intptr_t) info_type, 0 ); } else if(CHECK_SQLSETSTMTATTRW( statement -> connection )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)(intptr_t) info_type, 0 ); } if ( !SQL_SUCCEEDED( ret )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQLSetStmtAttr fails" ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR, DEFER_R3 ); } if ( crow_keyset > 0 ) { if(CHECK_SQLSETSTMTATTR( statement -> connection )) { ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, SQL_ATTR_KEYSET_SIZE, (SQLPOINTER)(intptr_t) crow_keyset, 0 ); } else if(CHECK_SQLSETSTMTATTRW( statement -> connection )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, SQL_ATTR_KEYSET_SIZE, (SQLPOINTER)(intptr_t) crow_keyset, 0 ); } if ( !SQL_SUCCEEDED( ret )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQLSetStmtAttr fails" ); return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR, DEFER_R3 ); } } if(CHECK_SQLSETSTMTATTR( statement -> connection )) { ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, SQL_ROWSET_SIZE, (SQLPOINTER)(intptr_t) crow_rowset, 0 ); } else if(CHECK_SQLSETSTMTATTRW( statement -> connection )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, SQL_ROWSET_SIZE, (SQLPOINTER)(intptr_t) crow_rowset, 0 ); } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetStmtAttr.c000066400000000000000000000666531446441710500207500ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetStmtAttr.c,v 1.16 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetStmtAttr.c,v $ * Revision 1.16 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.15 2009/02/04 09:30:02 lurcher * Fix some SQLINTEGER/SQLLEN conflicts * * Revision 1.14 2007/12/17 13:13:03 lurcher * Fix a couple of descriptor typo's * * Revision 1.13 2007/02/12 11:49:34 lurcher * Add QT4 support to existing GUI parts * * Revision 1.12 2006/04/27 16:39:50 lurcher * fix missing return from SQLSetStmtAttr changes * * Revision 1.11 2006/04/24 08:42:10 lurcher * Handle resetting statement descriptors to implicit values, by passing in NULL or the implicit descrptor to SQLSetStmtAttr with the attribute SQL_ATTR_APP_PARAM_DESC or SQL_ATTR_APP_ROW_DESC. Also catch trying to call SQLGetDescField on a closed connection * * Revision 1.10 2005/11/23 08:29:16 lurcher * Add cleanup in postgres driver * * Revision 1.9 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.8 2003/03/05 09:48:45 lurcher * * Add some 64 bit fixes * * Revision 1.7 2003/02/27 12:19:40 lurcher * * Add the A functions as well as the W * * Revision 1.6 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.5 2002/09/18 14:49:32 lurcher * * DataManagerII additions and some more threading fixes * * Revision 1.3 2002/07/16 13:08:18 lurcher * * Filter attribute values from SQLSetStmtAttr to SQLSetStmtOption to fit * within ODBC 2 * Make DSN's double clickable in ODBCConfig * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.8 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * Revision 1.7 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.6 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.5 2001/03/28 14:57:22 nick * * Fix bugs in corsor lib introduced bu UNCODE and other changes * * Revision 1.4 2001/01/09 22:33:13 nick * * Stop passing NULL into SQLExtendedFetch * Further fixes to unicode to ansi conversions * * Revision 1.3 2000/12/18 12:53:29 nick * * More pooling tweeks * * Revision 1.2 2000/11/22 19:03:40 nick * * Fix problem with error status in SQLSpecialColumns * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.11 2000/06/24 18:45:09 ngorham * * Fix for SQLExtendedFetch on big endian platforms. the row count pointer * was declared as a small not a int. * * Revision 1.10 2000/06/20 13:30:10 ngorham * * Fix problems when using bookmarks * * Revision 1.9 2000/02/11 00:41:46 ngorham * * Added a couple of fixes for drivers without SQLExtendedFetch * * Revision 1.8 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.6 1999/09/21 22:34:26 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.5 1999/09/19 22:24:34 ngorham * * Added support for the cursor library * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb * first go at it * * Revision 1.6 1999/06/04 16:29:00 ngorham * * Added chack that SQLSetStmtAttr exists in the driver before calling it * * Revision 1.5 1999/06/03 22:20:25 ngorham * * Finished off the ODBC3-2 mapping * * Revision 1.4 1999/06/02 23:48:45 ngorham * * Added more 3-2 mapping * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:21 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetStmtAttr.c,v $ $Revision: 1.16 $"; SQLRETURN SQLSetStmtAttrA( SQLHSTMT statement_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length ) { return SQLSetStmtAttr( statement_handle, attribute, value, string_length ); } SQLRETURN SQLSetStmtAttr( SQLHSTMT statement_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tAttribute = %s\ \n\t\t\tValue = %p\ \n\t\t\tStrLen = %d", statement, __stmt_attr_as_string( s1, attribute ), value, (int)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( attribute == SQL_ATTR_CONCURRENCY || attribute == SQL_ATTR_CURSOR_TYPE || attribute == SQL_ATTR_SIMULATE_CURSOR || attribute == SQL_ATTR_USE_BOOKMARKS || attribute == SQL_ATTR_CURSOR_SCROLLABLE || attribute == SQL_ATTR_CURSOR_SENSITIVITY ) { if ( statement -> state == STATE_S2 || statement -> state == STATE_S3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY011" ); __post_internal_error( &statement -> error, ERROR_HY011, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S4 || statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { if ( statement -> prepared ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY011" ); __post_internal_error( &statement -> error, ERROR_HY011, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } } else { if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( (!CHECK_SQLSETSTMTATTR( statement -> connection ) && !CHECK_SQLSETSTMTATTRW( statement -> connection )) && !CHECK_SQLSETSTMTOPTION( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * map descriptors to our copies */ if ( attribute == SQL_ATTR_APP_ROW_DESC ) { DMHDESC desc = ( DMHDESC ) value; /* * needs to reset to implicit descriptor, this is safe * without a validate, as the value is either null, or the * same as a descriptor we know is valid */ if ( desc == NULL || desc == statement -> implicit_ard ) { DRV_SQLHDESC drv_desc = NULL; ret = SQL_SUCCESS; if ( desc == statement -> implicit_ard ) { drv_desc = statement -> implicit_ard -> driver_desc; } if ( CHECK_SQLSETSTMTATTR( statement -> connection )) { ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, attribute, drv_desc, 0 ); } else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, attribute, statement -> implicit_ard -> driver_desc, 0 ); } else { ret = SQLSETSTMTOPTION( statement -> connection, statement -> driver_stmt, attribute, (SQLULEN) statement -> implicit_ard -> driver_desc ); } if ( ret != SQL_SUCCESS ) { if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } /* * copy DM descriptor */ statement -> apd = statement -> implicit_apd; if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } if ( !__validate_desc( desc )) { thread_release( SQL_HANDLE_STMT, statement ); sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_INVALID_HANDLE, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); return SQL_INVALID_HANDLE; } if ( desc -> implicit && desc != statement -> implicit_ard ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY017" ); __post_internal_error( &statement -> error, ERROR_HY017, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( desc -> connection != statement -> connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &statement -> error, ERROR_HY024, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * set the value to the driver descriptor handle */ value = ( SQLPOINTER ) desc -> driver_desc; statement -> ard = desc; desc -> associated_with = statement; } if ( attribute == SQL_ATTR_APP_PARAM_DESC ) { DMHDESC desc = ( DMHDESC ) value; /* * needs to reset to implicit descriptor, this is safe * without a validate, as the value is either null, or the * same as a descriptor we know is valid */ if ( desc == NULL || desc == statement -> implicit_apd ) { DRV_SQLHDESC drv_desc = NULL; ret = SQL_SUCCESS; if ( desc == statement -> implicit_apd ) { drv_desc = statement -> implicit_apd -> driver_desc; } if ( CHECK_SQLSETSTMTATTR( statement -> connection )) { ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, attribute, statement -> implicit_apd -> driver_desc, 0 ); } else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, attribute, statement -> implicit_apd -> driver_desc, 0 ); } else { ret = SQLSETSTMTOPTION( statement -> connection, statement -> driver_stmt, attribute, (SQLULEN) drv_desc ); } if ( ret != SQL_SUCCESS ) { if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } /* * copy DM descriptor */ statement -> apd = statement -> implicit_apd; if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } if ( !__validate_desc( desc )) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_INVALID_HANDLE, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); thread_release( SQL_HANDLE_STMT, statement ); return SQL_INVALID_HANDLE; } if ( desc -> implicit && desc != statement -> implicit_apd ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY017" ); __post_internal_error( &statement -> error, ERROR_HY017, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( desc -> connection != statement -> connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &statement -> error, ERROR_HY024, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * set the value to the driver descriptor handle */ value = ( SQLPOINTER ) desc -> driver_desc; statement -> apd = desc; desc -> associated_with = statement; } /* * save for internal use */ if ( attribute == SQL_ATTR_METADATA_ID ) { statement -> metadata_id = (SQLLEN) value; } if ( attribute == SQL_ATTR_IMP_ROW_DESC || attribute == SQL_ATTR_IMP_PARAM_DESC ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY017" ); __post_internal_error( &statement -> error, ERROR_HY017, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * is it a legitimate value */ ret = dm_check_statement_attrs( statement, attribute, value ); if ( ret != SQL_SUCCESS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &statement -> error, ERROR_HY024, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * is it something overridden */ value = __attr_override( statement, SQL_HANDLE_STMT, attribute, value, &string_length ); /* * does the call need mapping from 3 to 2 */ if ( attribute == SQL_ATTR_FETCH_BOOKMARK_PTR && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && CHECK_SQLEXTENDEDFETCH( statement -> connection ) && !CHECK_SQLFETCHSCROLL( statement -> connection )) { statement -> fetch_bm_ptr = (SQLULEN*) value; /* * pass on if required */ if ( statement -> connection -> cl_handle ) { if ( CHECK_SQLSETSTMTATTR( statement -> connection )) { SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, attribute, value, string_length ); } else { ret = SQLSETSTMTOPTION( statement -> connection, statement -> driver_stmt, attribute, (SQLULEN) value ); } } ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_ROW_STATUS_PTR && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 ) { statement -> row_st_arr = (SQLUSMALLINT*) value; /* * pass on if required */ if ( statement -> connection -> cl_handle ) { if ( CHECK_SQLSETSTMTATTR( statement -> connection )) { SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, attribute, value, string_length ); } else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, attribute, value, string_length ); } else { ret = SQLSETSTMTOPTION( statement -> connection, statement -> driver_stmt, attribute, (SQLULEN) value ); } } ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_ROWS_FETCHED_PTR && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 ) { statement -> row_ct_ptr = (SQLULEN*) value; /* * pass on if required */ if ( statement -> connection -> cl_handle ) { if ( CHECK_SQLSETSTMTATTR( statement -> connection )) { SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, attribute, value, string_length ); } else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, attribute, value, string_length ); } else { ret = SQLSETSTMTOPTION( statement -> connection, statement -> driver_stmt, attribute, (SQLULEN) value ); } } ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_ROW_ARRAY_SIZE && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 ) { /* * save this in case we need it in SQLExtendedFetch */ statement -> row_array_size = (SQLULEN) value; if ( CHECK_SQLSETSTMTATTR( statement -> connection )) { ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, SQL_ROWSET_SIZE, value, string_length ); } else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, SQL_ROWSET_SIZE, value, string_length ); } else { ret = SQLSETSTMTOPTION( statement -> connection, statement -> driver_stmt, SQL_ROWSET_SIZE, (SQLULEN) value ); } } else if ( CHECK_SQLSETSTMTATTR( statement -> connection )) { ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, attribute, value, string_length ); } else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, attribute, value, string_length ); } else { /* * Is it in the legal range of values */ if ( attribute < SQL_STMT_DRIVER_MIN && ( attribute > SQL_ROW_NUMBER || attribute < SQL_QUERY_TIMEOUT )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY092" ); __post_internal_error( &statement -> error, ERROR_HY092, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLSETSTMTOPTION( statement -> connection, statement -> driver_stmt, attribute, (SQLULEN) value ); } /* * take notice of this */ if ( attribute == SQL_ATTR_USE_BOOKMARKS && SQL_SUCCEEDED( ret )) { statement -> bookmarks_on = (SQLULEN) value; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetStmtAttrW.c000066400000000000000000000517321446441710500210670ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetStmtAttrW.c,v 1.10 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetStmtAttrW.c,v $ * Revision 1.10 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.9 2009/02/04 09:30:02 lurcher * Fix some SQLINTEGER/SQLLEN conflicts * * Revision 1.8 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2006/04/18 10:24:47 lurcher * Add a couple of changes from Mark Vanderwiel * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/03/05 09:48:45 lurcher * * Add some 64 bit fixes * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/05/28 13:30:34 lurcher * * Tidy up for AIX * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.4 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetStmtAttrW.c,v $"; SQLRETURN SQLSetStmtAttrW( SQLHSTMT statement_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; SQLWCHAR buffer[ 512 ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLSETSTMTATTRW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLSETSTMTATTRW( parent_statement -> connection, statement_handle, attribute, value, string_length ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tAttribute = %s\ \n\t\t\tValue = %p\ \n\t\t\tStrLen = %d", statement, __stmt_attr_as_string( s1, attribute ), value, (int)string_length ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( attribute == SQL_ATTR_CONCURRENCY || attribute == SQL_ATTR_CURSOR_TYPE || attribute == SQL_ATTR_SIMULATE_CURSOR || attribute == SQL_ATTR_USE_BOOKMARKS || attribute == SQL_ATTR_CURSOR_SCROLLABLE || attribute == SQL_ATTR_CURSOR_SENSITIVITY ) { if ( statement -> state == STATE_S2 || statement -> state == STATE_S3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY011" ); __post_internal_error( &statement -> error, ERROR_HY011, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S4 || statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { if ( statement -> prepared ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY011" ); __post_internal_error( &statement -> error, ERROR_HY011, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } } else { if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver || CHECK_SQLSETSTMTATTRW( statement -> connection )) { if ( !CHECK_SQLSETSTMTATTRW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } else { if ( !CHECK_SQLSETSTMTATTR( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * map descriptors to our copies */ if ( attribute == SQL_ATTR_APP_ROW_DESC ) { DMHDESC desc = ( DMHDESC ) value; /* * needs to reset to implicit descriptor, this is safe * without a validate, as the value is either null, or the * same as a descriptor we know is valid */ if ( desc == NULL || desc == statement -> implicit_ard ) { DRV_SQLHDESC drv_desc = NULL; ret = SQL_SUCCESS; if ( desc == statement -> implicit_ard ) { drv_desc = statement -> implicit_ard -> driver_desc; } if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, attribute, statement -> implicit_ard -> driver_desc, 0 ); } else if ( CHECK_SQLSETSTMTATTR( statement -> connection )) { ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, attribute, drv_desc, 0 ); } else { ret = SQLSETSTMTOPTION( statement -> connection, statement -> driver_stmt, attribute, (SQLULEN) statement -> implicit_ard -> driver_desc ); } if ( ret != SQL_SUCCESS ) { if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } /* * copy DM descriptor */ statement -> apd = statement -> implicit_apd; if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } if ( !__validate_desc( desc )) { thread_release( SQL_HANDLE_STMT, statement ); return SQL_INVALID_HANDLE; } if ( desc -> implicit && desc != statement -> implicit_ard ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY017" ); __post_internal_error( &statement -> error, ERROR_HY017, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( desc -> connection != statement -> connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &statement -> error, ERROR_HY024, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * set the value to the driver descriptor handle */ value = ( SQLPOINTER ) desc -> driver_desc; statement -> ard = desc; desc -> associated_with = statement; } if ( attribute == SQL_ATTR_APP_PARAM_DESC ) { DMHDESC desc = ( DMHDESC ) value; /* * needs to reset to implicit descriptor, this is safe * without a validate, as the value is either null, or the * same as a descriptor we know is valid */ if ( desc == NULL || desc == statement -> implicit_apd ) { DRV_SQLHDESC drv_desc = NULL; ret = SQL_SUCCESS; if ( desc == statement -> implicit_apd ) { drv_desc = statement -> implicit_apd -> driver_desc; } if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, attribute, statement -> implicit_apd -> driver_desc, 0 ); } else if ( CHECK_SQLSETSTMTATTR( statement -> connection )) { ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, attribute, statement -> implicit_apd -> driver_desc, 0 ); } else { ret = SQLSETSTMTOPTION( statement -> connection, statement -> driver_stmt, attribute, (SQLULEN) drv_desc ); } if ( ret != SQL_SUCCESS ) { if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } /* * copy DM descriptor */ statement -> apd = statement -> implicit_apd; if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } if ( !__validate_desc( desc )) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_INVALID_HANDLE, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); thread_release( SQL_HANDLE_STMT, statement ); return SQL_INVALID_HANDLE; } if ( desc -> implicit && desc != statement -> implicit_apd ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY017" ); __post_internal_error( &statement -> error, ERROR_HY017, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( desc -> connection != statement -> connection ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY024" ); __post_internal_error( &statement -> error, ERROR_HY024, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * set the value to the driver descriptor handle */ value = ( SQLPOINTER ) desc -> driver_desc; statement -> apd = desc; desc -> associated_with = statement; } /* * save for internal use */ if ( attribute == SQL_ATTR_METADATA_ID ) { #ifdef HAVE_PTRDIFF_T statement -> metadata_id = (ptrdiff_t) value; #else statement -> metadata_id = (SQLINTEGER) value; #endif } if ( attribute == SQL_ATTR_IMP_ROW_DESC || attribute == SQL_ATTR_IMP_PARAM_DESC ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY017" ); __post_internal_error( &statement -> error, ERROR_HY017, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * is it a legitimate value */ ret = dm_check_statement_attrs( statement, attribute, value ); if ( ret != SQL_SUCCESS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY011" ); __post_internal_error( &statement -> error, ERROR_HY024, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * is it something overridden */ value = __attr_override_wide( statement, SQL_HANDLE_STMT, attribute, value, &string_length, buffer ); /* * does the call need mapping from 3 to 2 */ if ( attribute == SQL_ATTR_FETCH_BOOKMARK_PTR && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 && CHECK_SQLEXTENDEDFETCH( statement -> connection ) && !CHECK_SQLFETCHSCROLL( statement -> connection )) { statement -> fetch_bm_ptr = (SQLULEN*) value; ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_ROW_STATUS_PTR && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 ) { statement -> row_st_arr = (SQLUSMALLINT*) value; ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_ROWS_FETCHED_PTR && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 ) { statement -> row_ct_ptr = (SQLULEN*) value; ret = SQL_SUCCESS; } else if ( attribute == SQL_ATTR_ROW_ARRAY_SIZE && statement -> connection -> driver_act_ver == SQL_OV_ODBC2 ) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, SQL_ROWSET_SIZE, value, string_length ); } else { if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, attribute, value, string_length ); } else { /* * I can't find any string values, so we don't need to translate */ ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, attribute, value, string_length ); } } /* * take notice of this */ if ( attribute == SQL_ATTR_USE_BOOKMARKS && SQL_SUCCEEDED( ret )) { statement -> bookmarks_on = (SQLULEN) value; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetStmtOption.c000066400000000000000000000341261446441710500212740ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetStmtOption.c,v 1.10 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetStmtOption.c,v $ * Revision 1.10 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.9 2009/02/04 09:30:02 lurcher * Fix some SQLINTEGER/SQLLEN conflicts * * Revision 1.8 2007/11/29 12:00:31 lurcher * Add 64 bit type changes to SQLExtendedFetch etc * * Revision 1.7 2005/11/23 08:29:16 lurcher * Add cleanup in postgres driver * * Revision 1.6 2005/04/05 09:11:31 lurcher * The config string being passed into ConfigDsn was wrong, removed semicolon, and added terminating double null * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/03/05 09:48:45 lurcher * * Add some 64 bit fixes * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.4 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 2000/06/20 13:30:12 ngorham * * Fix problems when using bookmarks * * Revision 1.7 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:26 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb * first go at it * * Revision 1.4 1999/06/03 22:20:25 ngorham * * Finished off the ODBC3-2 mapping * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:21 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetStmtOption.c,v $ $Revision: 1.10 $"; SQLRETURN SQLSetStmtOptionA( SQLHSTMT statement_handle, SQLUSMALLINT option, SQLULEN value ) { return SQLSetStmtOption( statement_handle, option, value ); } SQLRETURN SQLSetStmtOption( SQLHSTMT statement_handle, SQLUSMALLINT option, SQLULEN value ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tOption = %s\ \n\t\t\tValue = %d", statement, __stmt_attr_as_string( s1, option ), (int)value ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( option == SQL_CONCURRENCY || option == SQL_CURSOR_TYPE || option == SQL_SIMULATE_CURSOR || option == SQL_USE_BOOKMARKS ) { if ( statement -> state == STATE_S2 || statement -> state == STATE_S3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1011" ); __post_internal_error( &statement -> error, ERROR_S1011, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S4 || statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { if ( statement -> prepared ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1011" ); __post_internal_error( &statement -> error, ERROR_S1011, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1010" ); __post_internal_error( &statement -> error, ERROR_S1010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } } else { if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1010" ); __post_internal_error( &statement -> error, ERROR_S1010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( option == SQL_ATTR_IMP_ROW_DESC || option == SQL_ATTR_IMP_PARAM_DESC ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY017" ); __post_internal_error( &statement -> error, ERROR_HY017, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * is it a legitimate value */ ret = dm_check_statement_attrs( statement, option, (SQLPOINTER)value ); if ( ret != SQL_SUCCESS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY011" ); __post_internal_error( &statement -> error, ERROR_HY024, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * is it something overridden */ value = (SQLULEN) __attr_override( statement, SQL_HANDLE_STMT, option, (void*) value, NULL ); if ( CHECK_SQLSETSTMTOPTION( statement -> connection )) { ret = SQLSETSTMTOPTION( statement -> connection, statement -> driver_stmt, option, value ); } else if ( CHECK_SQLSETSTMTATTR( statement -> connection )) { switch ( option ) { case SQL_ATTR_APP_PARAM_DESC: if ( value ) memcpy( &statement -> apd, (void*)value, sizeof( statement -> apd )); ret = SQL_SUCCESS; break; case SQL_ATTR_APP_ROW_DESC: if ( value ) memcpy( &statement -> ard, (void*)value, sizeof( statement -> ard )); ret = SQL_SUCCESS; break; case SQL_ATTR_IMP_PARAM_DESC: if ( value ) memcpy( &statement -> ipd, (void*)value, sizeof( statement -> ipd )); ret = SQL_SUCCESS; break; case SQL_ATTR_IMP_ROW_DESC: if ( value ) memcpy( &statement -> ird, (void*)value, sizeof( statement -> ird )); ret = SQL_SUCCESS; break; default: ret = SQLSETSTMTATTR( statement -> connection, statement -> driver_stmt, option, (SQLPOINTER)(intptr_t) value, SQL_NTS ); break; } } else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { switch ( option ) { case SQL_ATTR_APP_PARAM_DESC: if ( value ) memcpy( &statement -> apd, (void*)value, sizeof( statement -> apd )); ret = SQL_SUCCESS; break; case SQL_ATTR_APP_ROW_DESC: if ( value ) memcpy( &statement -> ard, (void*)value, sizeof( statement -> ard )); ret = SQL_SUCCESS; break; case SQL_ATTR_IMP_PARAM_DESC: if ( value ) memcpy( &statement -> ipd, (void*)value, sizeof( statement -> ipd )); ret = SQL_SUCCESS; break; case SQL_ATTR_IMP_ROW_DESC: if ( value ) memcpy( &statement -> ird, (void*)value, sizeof( statement -> ird )); ret = SQL_SUCCESS; break; default: ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, option, (SQLPOINTER)(intptr_t) value, SQL_NTS ); break; } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * take notice of this */ if ( option == SQL_USE_BOOKMARKS && SQL_SUCCEEDED( ret )) { statement -> bookmarks_on = (SQLULEN) value; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSetStmtOptionW.c000066400000000000000000000331121446441710500214150ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetStmtOptionW.c,v 1.6 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSetStmtOptionW.c,v $ * Revision 1.6 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2009/02/04 09:30:02 lurcher * Fix some SQLINTEGER/SQLLEN conflicts * * Revision 1.4 2007/11/29 12:00:31 lurcher * Add 64 bit type changes to SQLExtendedFetch etc * * Revision 1.3 2007/02/28 15:37:48 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.2 2006/04/18 10:24:47 lurcher * Add a couple of changes from Mark Vanderwiel * * Revision 1.1 2005/05/02 20:37:31 lurcher * Add missing SQLSetStmtOptionW.c * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/03/05 09:48:45 lurcher * * Add some 64 bit fixes * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.4 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 2000/06/20 13:30:12 ngorham * * Fix problems when using bookmarks * * Revision 1.7 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:26 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:55 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb * first go at it * * Revision 1.4 1999/06/03 22:20:25 ngorham * * Finished off the ODBC3-2 mapping * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:21 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSetStmtOptionW.c,v $ $Revision: 1.6 $"; SQLRETURN SQLSetStmtOptionW( SQLHSTMT statement_handle, SQLUSMALLINT option, SQLULEN value ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; SQLWCHAR buffer[ 512 ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLSETSTMTOPTIONW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLSETSTMTOPTIONW( parent_statement -> connection, statement_handle, option, value ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tOption = %s\ \n\t\t\tValue = %d", statement, __stmt_attr_as_string( s1, option ), (int)value ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * check states */ if ( option == SQL_CONCURRENCY || option == SQL_CURSOR_TYPE || option == SQL_SIMULATE_CURSOR || option == SQL_USE_BOOKMARKS ) { if ( statement -> state == STATE_S2 || statement -> state == STATE_S3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1011" ); __post_internal_error( &statement -> error, ERROR_S1011, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S4 || statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { if ( statement -> prepared ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1011" ); __post_internal_error( &statement -> error, ERROR_S1011, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1010" ); __post_internal_error( &statement -> error, ERROR_S1010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } } else { if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: S1010" ); __post_internal_error( &statement -> error, ERROR_S1010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( option == SQL_ATTR_IMP_ROW_DESC || option == SQL_ATTR_IMP_PARAM_DESC ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY017" ); __post_internal_error( &statement -> error, ERROR_HY017, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * is it a legitimate value */ ret = dm_check_statement_attrs( statement, option, (SQLPOINTER)value ); if ( ret != SQL_SUCCESS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY011" ); __post_internal_error( &statement -> error, ERROR_HY024, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * is it something overridden */ value = (SQLULEN) __attr_override_wide( statement, SQL_HANDLE_STMT, option, (void*) value, NULL, buffer ); if ( CHECK_SQLSETSTMTOPTIONW( statement -> connection )) { ret = SQLSETSTMTOPTIONW( statement -> connection, statement -> driver_stmt, option, value ); } else if ( CHECK_SQLSETSTMTATTRW( statement -> connection )) { switch ( option ) { case SQL_ATTR_APP_PARAM_DESC: if ( value ) memcpy( &statement -> apd, (void*)value, sizeof( statement -> apd )); ret = SQL_SUCCESS; break; case SQL_ATTR_APP_ROW_DESC: if ( value ) memcpy( &statement -> ard, (void*)value, sizeof( statement -> ard )); ret = SQL_SUCCESS; break; case SQL_ATTR_IMP_PARAM_DESC: if ( value ) memcpy( &statement -> ipd, (void*)value, sizeof( statement -> ipd )); ret = SQL_SUCCESS; break; case SQL_ATTR_IMP_ROW_DESC: if ( value ) memcpy( &statement -> ird, (void*)value, sizeof( statement -> ird )); ret = SQL_SUCCESS; break; default: ret = SQLSETSTMTATTRW( statement -> connection, statement -> driver_stmt, option, (SQLPOINTER)(intptr_t) value, SQL_NTS ); break; } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * take notice of this */ if ( option == SQL_USE_BOOKMARKS && SQL_SUCCEEDED( ret )) { statement -> bookmarks_on = (SQLULEN) value; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R3 ); } unixODBC-2.3.12/DriverManager/SQLSpecialColumns.c000066400000000000000000000345721446441710500214260ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSpecialColumns.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSpecialColumns.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/02/27 12:19:40 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.6 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.5 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.4 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.3 2000/12/05 16:49:21 nick * * Add missing identifier_type in SQLSpecialColumns log * * Revision 1.2 2000/11/22 19:03:40 nick * * Fix problem with error status in SQLSpecialColumns * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:26 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:56 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/05/03 19:50:43 nick * Another check point * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSpecialColumns.c,v $ $Revision: 1.7 $"; SQLRETURN SQLSpecialColumnsA( SQLHSTMT statement_handle, SQLUSMALLINT identifier_type, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLUSMALLINT scope, SQLUSMALLINT nullable ) { return SQLSpecialColumns( statement_handle, identifier_type, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, scope, nullable ); } SQLRETURN SQLSpecialColumns( SQLHSTMT statement_handle, SQLUSMALLINT identifier_type, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLUSMALLINT scope, SQLUSMALLINT nullable ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tIdentifier Type = %d\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Name = %s\ \n\t\t\tScope = %d\ \n\t\t\tNullable = %d", statement, identifier_type, __string_with_length( s1, catalog_name, name_length1 ), __string_with_length( s2, schema_name, name_length2 ), __string_with_length( s3, table_name, name_length3 ), scope, nullable ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( identifier_type != SQL_BEST_ROWID && identifier_type != SQL_ROWVER ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY097" ); __post_internal_error( &statement -> error, ERROR_HY097, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if (( name_length1 < 0 && name_length1 != SQL_NTS ) || ( name_length2 < 0 && name_length2 != SQL_NTS )) { __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( table_name == NULL ) { __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( name_length3 < 0 && name_length3 != SQL_NTS ) { __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> metadata_id == SQL_TRUE && schema_name == NULL ) { __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( scope != SQL_SCOPE_CURROW && scope != SQL_SCOPE_TRANSACTION && scope != SQL_SCOPE_SESSION ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY098" ); __post_internal_error( &statement -> error, ERROR_HY098, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( nullable != SQL_NO_NULLS && nullable != SQL_NULLABLE ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY099" ); __post_internal_error( &statement -> error, ERROR_HY099, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if ( statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 2400" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLSPECIALCOLUMNS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1, *s2, *s3; int wlen; if ( !CHECK_SQLSPECIALCOLUMNSW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( catalog_name, name_length1, statement -> connection, &wlen ); name_length1 = wlen; s2 = ansi_to_unicode_alloc( schema_name, name_length2, statement -> connection, &wlen ); name_length2 = wlen; s3 = ansi_to_unicode_alloc( table_name, name_length3, statement -> connection, &wlen ); name_length3 = wlen; ret = SQLSPECIALCOLUMNSW( statement -> connection , statement -> driver_stmt, identifier_type, s1, name_length1, s2, name_length2, s3, name_length3, scope, nullable ); if( s1 ) free( s1 ); if( s2 ) free( s2 ); if( s3 ) free( s3 ); } else { if ( !CHECK_SQLSPECIALCOLUMNS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLSPECIALCOLUMNS( statement -> connection , statement -> driver_stmt, identifier_type, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, scope, nullable ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /******** * Added this to get num cols from drivers which can only tell * us after execute - PAH */ /* ret = SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); */ statement -> numcols = 1; /******/ #endif statement -> hascols = 1; statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLSPECIALCOLUMNS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLSpecialColumnsW.c000066400000000000000000000336251446441710500215530ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSpecialColumnsW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLSpecialColumnsW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:49 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLSpecialColumnsW.c,v $"; SQLRETURN SQLSpecialColumnsW( SQLHSTMT statement_handle, SQLUSMALLINT identifier_type, SQLWCHAR *catalog_name, SQLSMALLINT name_length1, SQLWCHAR *schema_name, SQLSMALLINT name_length2, SQLWCHAR *table_name, SQLSMALLINT name_length3, SQLUSMALLINT scope, SQLUSMALLINT nullable ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLSPECIALCOLUMNSW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLSPECIALCOLUMNSW( parent_statement -> connection, statement_handle, identifier_type, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, scope, nullable ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tIdentifier Type = %d\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Name = %s\ \n\t\t\tScope = %d\ \n\t\t\tNullable = %d", statement, identifier_type, __wstring_with_length( s1, catalog_name, name_length1 ), __wstring_with_length( s2, schema_name, name_length2 ), __wstring_with_length( s3, table_name, name_length3 ), scope, nullable ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if ( identifier_type != SQL_BEST_ROWID && identifier_type != SQL_ROWVER ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY097" ); __post_internal_error( &statement -> error, ERROR_HY097, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if (( name_length1 < 0 && name_length1 != SQL_NTS ) || ( name_length2 < 0 && name_length2 != SQL_NTS )) { __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( table_name == NULL ) { __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( name_length3 < 0 && name_length3 != SQL_NTS ) { __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> metadata_id == SQL_TRUE && schema_name == NULL ) { __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( scope != SQL_SCOPE_CURROW && scope != SQL_SCOPE_TRANSACTION && scope != SQL_SCOPE_SESSION ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY098" ); __post_internal_error( &statement -> error, ERROR_HY098, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( nullable != SQL_NO_NULLS && nullable != SQL_NULLABLE ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY099" ); __post_internal_error( &statement -> error, ERROR_HY099, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if ( statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 2400" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLSPECIALCOLUMNS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver || CHECK_SQLSPECIALCOLUMNSW( statement -> connection )) { if ( !CHECK_SQLSPECIALCOLUMNSW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLSPECIALCOLUMNSW( statement -> connection , statement -> driver_stmt, identifier_type, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, scope, nullable ); } else { SQLCHAR *as1, *as2, *as3; int clen; if ( !CHECK_SQLSPECIALCOLUMNS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } as1 = (SQLCHAR*) unicode_to_ansi_alloc( catalog_name, name_length1, statement -> connection, &clen ); name_length1 = clen; as2 = (SQLCHAR*) unicode_to_ansi_alloc( schema_name, name_length2, statement -> connection, &clen ); name_length2 = clen; as3 = (SQLCHAR*) unicode_to_ansi_alloc( table_name, name_length3, statement -> connection, &clen ); name_length3 = clen; ret = SQLSPECIALCOLUMNS( statement -> connection , statement -> driver_stmt, identifier_type, as1, name_length1, as2, name_length2, as3, name_length3, scope, nullable ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); if ( as3 ) free( as3 ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /******** * Added this to get num cols from drivers which can only tell * us after execute - PAH */ /* ret = SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); */ statement -> numcols = 1; /******/ #endif statement -> hascols = 1; statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLSPECIALCOLUMNS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLStatistics.c000066400000000000000000000333101446441710500206240ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLStatistics.c,v 1.8 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLStatistics.c,v $ * Revision 1.8 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.7 2005/02/07 14:17:07 lurcher * Fix small typo in SQLStatistics * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/02/27 12:19:40 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:26 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:56 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.4 1999/05/03 19:50:43 nick * Another check point * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLStatistics.c,v $ $Revision: 1.8 $"; SQLRETURN SQLStatisticsA( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLUSMALLINT unique, SQLUSMALLINT reserved ) { return SQLStatistics( statement_handle, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, unique, reserved ); } SQLRETURN SQLStatistics( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLUSMALLINT unique, SQLUSMALLINT reserved ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Name = %s\ \n\t\t\tUnique = %d\ \n\t\t\tReserved = %d", statement, __string_with_length( s1, catalog_name, name_length1 ), __string_with_length( s2, schema_name, name_length2 ), __string_with_length( s3, table_name, name_length3 ), unique, reserved ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( name_length1 < 0 && name_length1 != SQL_NTS ) || ( name_length2 < 0 && name_length2 != SQL_NTS ) || ( name_length3 < 0 && name_length3 != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( reserved != SQL_ENSURE && reserved != SQL_QUICK ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY101" ); __post_internal_error( &statement -> error, ERROR_HY101, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( unique != SQL_INDEX_UNIQUE && unique != SQL_INDEX_ALL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY100" ); __post_internal_error( &statement -> error, ERROR_HY100, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if ( statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLSTATISTICS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( table_name == NULL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> metadata_id == SQL_TRUE ) { if ( schema_name == NULL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1, *s2, *s3; int wlen; if ( !CHECK_SQLSTATISTICSW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( catalog_name, name_length1, statement -> connection, &wlen ); name_length1 = wlen; s2 = ansi_to_unicode_alloc( schema_name, name_length2, statement -> connection, &wlen ); name_length2 = wlen; s3 = ansi_to_unicode_alloc( table_name, name_length3, statement -> connection, &wlen ); name_length3 = wlen; ret = SQLSTATISTICSW( statement -> connection, statement -> driver_stmt, s1, name_length1, s2, name_length2, s3, name_length3, unique, reserved ); if( s1 ) free( s1 ); if( s2 ) free( s2 ); if( s3 ) free( s3 ); } else { if ( !CHECK_SQLSTATISTICS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLSTATISTICS( statement -> connection, statement -> driver_stmt, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, unique, reserved ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /******** * Added this to get num cols from drivers which can only tell * us after execute - PAH */ /* ret = SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); */ statement -> numcols = 1; /******/ #endif statement -> hascols = 1; statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLSTATISTICS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLStatisticsW.c000066400000000000000000000325251446441710500207620ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLStatisticsW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLStatisticsW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:49 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLStatisticsW.c,v $"; SQLRETURN SQLStatisticsW( SQLHSTMT statement_handle, SQLWCHAR *catalog_name, SQLSMALLINT name_length1, SQLWCHAR *schema_name, SQLSMALLINT name_length2, SQLWCHAR *table_name, SQLSMALLINT name_length3, SQLUSMALLINT unique, SQLUSMALLINT reserved ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLSTATISTICSW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLSTATISTICSW( parent_statement -> connection, statement_handle, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, unique, reserved ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Name = %s\ \n\t\t\tUnique = %d\ \n\t\t\tReserved = %d", statement, __wstring_with_length( s1, catalog_name, name_length1 ), __wstring_with_length( s2, schema_name, name_length2 ), __wstring_with_length( s3, table_name, name_length3 ), unique, reserved ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( name_length1 < 0 && name_length1 != SQL_NTS ) || ( name_length2 < 0 && name_length2 != SQL_NTS ) || ( name_length3 < 0 && name_length3 != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( reserved != SQL_ENSURE && reserved != SQL_QUICK ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY101" ); __post_internal_error( &statement -> error, ERROR_HY101, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( unique != SQL_INDEX_UNIQUE && unique != SQL_INDEX_ALL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY100" ); __post_internal_error( &statement -> error, ERROR_HY100, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLSTATISTICS ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( table_name == NULL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> metadata_id == SQL_TRUE ) { if ( schema_name == NULL ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY009" ); __post_internal_error( &statement -> error, ERROR_HY009, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } if ( statement -> connection -> unicode_driver || CHECK_SQLSTATISTICSW( statement -> connection )) { if ( !CHECK_SQLSTATISTICSW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLSTATISTICSW( statement -> connection, statement -> driver_stmt, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, unique, reserved ); } else { SQLCHAR *as1, *as2, *as3; int clen; if ( !CHECK_SQLSTATISTICS( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } as1 = (SQLCHAR*) unicode_to_ansi_alloc( catalog_name, name_length1, statement -> connection, &clen ); name_length1 = clen; as2 = (SQLCHAR*) unicode_to_ansi_alloc( schema_name, name_length2, statement -> connection, &clen ); name_length2 = clen; as3 = (SQLCHAR*) unicode_to_ansi_alloc( table_name, name_length3, statement -> connection, &clen ); name_length3 = clen; ret = SQLSTATISTICS( statement -> connection, statement -> driver_stmt, as1, name_length1, as2, name_length2, as3, name_length3, unique, reserved ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); if ( as3 ) free( as3 ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /******** * Added this to get num cols from drivers which can only tell * us after execute - PAH */ /* ret = SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); */ statement -> numcols = 1; /******/ #endif statement -> hascols = 1; statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLSTATISTICS; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLTablePrivileges.c000066400000000000000000000270261446441710500215620ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLTablePrivileges.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLTablePrivileges.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.7 2006/07/26 16:29:48 lurcher * Fix unicode translation for SQLTablePrivileges * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/02/27 12:19:40 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:26 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:56 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/05/03 19:50:43 nick * Another check point * * Revision 1.2 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLTablePrivileges.c,v $ $Revision: 1.9 $"; SQLRETURN SQLTablePrivilegesA( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_table_name, SQLSMALLINT cb_table_name ) { return SQLTablePrivileges( statement_handle, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_table_name, cb_table_name ); } SQLRETURN SQLTablePrivileges( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_table_name, SQLSMALLINT cb_table_name ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Name = %s", statement, __string_with_length( s1, sz_catalog_name, cb_catalog_name ), __string_with_length( s2, sz_schema_name, cb_schema_name ), __string_with_length( s3, sz_table_name, cb_table_name )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( sz_catalog_name && cb_catalog_name < 0 && cb_catalog_name != SQL_NTS ) || ( sz_schema_name && cb_schema_name < 0 && cb_schema_name != SQL_NTS ) || ( sz_table_name && cb_table_name < 0 && cb_table_name != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLTABLEPRIVILEGES ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver ) { SQLWCHAR *s1, *s2, *s3; int wlen; if ( !CHECK_SQLTABLEPRIVILEGESW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( sz_catalog_name, cb_catalog_name, statement -> connection, &wlen ); cb_catalog_name = wlen; s2 = ansi_to_unicode_alloc( sz_schema_name, cb_schema_name, statement -> connection, &wlen ); cb_schema_name = wlen; s3 = ansi_to_unicode_alloc( sz_table_name, cb_table_name, statement -> connection, &wlen ); cb_table_name = wlen; ret = SQLTABLEPRIVILEGESW( statement -> connection , statement -> driver_stmt, s1, cb_catalog_name, s2, cb_schema_name, s3, cb_table_name ); if( s1 ) free( s1 ); if( s2 ) free( s2 ); if( s3 ) free( s3 ); } else { if ( !CHECK_SQLTABLEPRIVILEGES( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLTABLEPRIVILEGES( statement -> connection , statement -> driver_stmt, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_table_name, cb_table_name ); } if ( SQL_SUCCEEDED( ret )) { statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLTABLEPRIVILEGES; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLTablePrivilegesW.c000066400000000000000000000261561446441710500217140ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLTablePrivilegesW.c,v 1.10 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLTablePrivilegesW.c,v $ * Revision 1.10 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.9 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.8 2007/02/28 15:37:49 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.7 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.6 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.5 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.4 2002/11/11 17:10:18 lurcher * * VMS changes * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLTablePrivilegesW.c,v $"; SQLRETURN SQLTablePrivilegesW( SQLHSTMT statement_handle, SQLWCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLWCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLWCHAR *sz_table_name, SQLSMALLINT cb_table_name ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLTABLEPRIVILEGESW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLTABLEPRIVILEGESW( parent_statement -> connection, statement_handle, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_table_name, cb_table_name ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Name = %s", statement, __wstring_with_length( s1, sz_catalog_name, cb_catalog_name ), __wstring_with_length( s2, sz_schema_name, cb_schema_name ), __wstring_with_length( s3, sz_table_name, cb_table_name )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); if (( sz_catalog_name && cb_catalog_name < 0 && cb_catalog_name != SQL_NTS ) || ( sz_schema_name && cb_schema_name < 0 && cb_schema_name != SQL_NTS ) || ( sz_table_name && cb_table_name < 0 && cb_table_name != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLTABLEPRIVILEGES ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver || CHECK_SQLTABLEPRIVILEGESW( statement -> connection )) { if ( !CHECK_SQLTABLEPRIVILEGESW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLTABLEPRIVILEGESW( statement -> connection , statement -> driver_stmt, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_table_name, cb_table_name ); } else { SQLCHAR *as1, *as2, *as3; int clen; if ( !CHECK_SQLTABLEPRIVILEGES( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } as1 = (SQLCHAR*) unicode_to_ansi_alloc( sz_catalog_name, cb_catalog_name, statement -> connection, &clen ); cb_catalog_name = clen; as2 = (SQLCHAR*) unicode_to_ansi_alloc( sz_schema_name, cb_schema_name, statement -> connection, &clen ); cb_schema_name = clen; as3 = (SQLCHAR*) unicode_to_ansi_alloc( sz_table_name, cb_table_name, statement -> connection, &clen ); cb_table_name = clen; ret = SQLTABLEPRIVILEGES( statement -> connection , statement -> driver_stmt, as1, cb_catalog_name, as2, cb_schema_name, as3, cb_table_name ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); if ( as3 ) free( as3 ); } if ( SQL_SUCCEEDED( ret )) { statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLTABLEPRIVILEGES; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLTables.c000066400000000000000000000311101446441710500177000ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLTables.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLTables.c,v $ * Revision 1.7 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2003/02/27 12:19:40 lurcher * * Add the A functions as well as the W * * Revision 1.3 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.4 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.8 2000/08/16 14:31:11 ngorham * * Add fix for broken version of EXCEL * * Revision 1.7 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.6 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.5 1999/09/21 22:34:26 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:56 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb * first go at it * * Revision 1.2 1999/06/07 01:29:31 pharvey * *** empty log message *** * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.4 1999/05/03 19:50:43 nick * Another check point * * Revision 1.3 1999/04/30 16:22:47 nick * Another checkpoint * * Revision 1.2 1999/04/29 20:47:37 nick * Another checkpoint * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLTables.c,v $ $Revision: 1.7 $"; SQLRETURN SQLTablesA( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLCHAR *table_type, SQLSMALLINT name_length4 ) { return SQLTables( statement_handle, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, table_type, name_length4 ); } SQLRETURN SQLTables( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLCHAR *table_type, SQLSMALLINT name_length4 ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Name = %s\ \n\t\t\tTable Type = %s", statement, __string_with_length( s1, catalog_name, name_length1 ), __string_with_length( s2, schema_name, name_length2 ), __string_with_length( s3, table_name, name_length3 ), __string_with_length( s4, table_type, name_length4 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * this is a fix for old version of EXCEL */ if ( !catalog_name ) name_length1 = 0; if ( !schema_name ) name_length2 = 0; if ( !table_name ) name_length3 = 0; if ( !table_type ) name_length4 = 0; if (( name_length1 < 0 && name_length1 != SQL_NTS ) || ( name_length2 < 0 && name_length2 != SQL_NTS ) || ( name_length3 < 0 && name_length3 != SQL_NTS ) || ( name_length4 < 0 && name_length4 != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLTABLES ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver ) { int wlen; SQLWCHAR *s1, *s2, *s3, *s4; if ( !CHECK_SQLTABLESW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } s1 = ansi_to_unicode_alloc( catalog_name, name_length1, statement -> connection, &wlen ); name_length1 = wlen; s2 = ansi_to_unicode_alloc( schema_name, name_length2, statement -> connection, &wlen ); name_length2 = wlen; s3 = ansi_to_unicode_alloc( table_name, name_length3, statement -> connection, &wlen ); name_length3 = wlen; s4 = ansi_to_unicode_alloc( table_type, name_length4, statement -> connection, &wlen ); name_length4 = wlen; ret = SQLTABLESW( statement -> connection , statement -> driver_stmt, s1, name_length1, s2, name_length2, s3, name_length3, s4, name_length4 ); if( s1 ) free( s1 ); if( s2 ) free( s2 ); if( s3 ) free( s3 ); if( s4 ) free( s4 ); } else { if ( !CHECK_SQLTABLES( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLTABLES( statement -> connection , statement -> driver_stmt, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, table_type, name_length4 ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /******** * Added this to get num cols from drivers which can only tell * us after execute - PAH */ /* * There is no point in doing this as we can't trust the value * from SQLPrepare, so we can't perform checks on the column number * ret = SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); */ statement -> numcols = 1; /******/ #endif statement -> hascols = 1; statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLTABLES; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLTablesW.c000066400000000000000000000301461446441710500200370ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLTablesW.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLTablesW.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2008/08/29 08:01:39 lurcher * Alter the way W functions are passed to the driver * * Revision 1.7 2007/02/28 15:37:49 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.6 2004/01/12 09:54:39 lurcher * * Fix problem where STATE_S5 stops metadata calls * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.4 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.3 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.2 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.3 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1 2000/12/31 20:30:54 nick * * Add UNICODE support * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLTablesW.c,v $"; SQLRETURN SQLTablesW( SQLHSTMT statement_handle, SQLWCHAR *catalog_name, SQLSMALLINT name_length1, SQLWCHAR *schema_name, SQLSMALLINT name_length2, SQLWCHAR *table_name, SQLSMALLINT name_length3, SQLWCHAR *table_type, SQLSMALLINT name_length4 ) { DMHSTMT statement = (DMHSTMT) statement_handle; SQLRETURN ret; SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ]; /* * check statement */ if ( !__validate_stmt( statement )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); #ifdef WITH_HANDLE_REDIRECT { DMHSTMT parent_statement; parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); if ( parent_statement ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: found parent handle" ); if ( CHECK_SQLTABLESW( parent_statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Info: calling redirected driver function" ); return SQLTABLESW( parent_statement -> connection, statement_handle, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, table_type, name_length4 ); } } } #endif return SQL_INVALID_HANDLE; } function_entry( statement ); if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tEntry:\ \n\t\t\tStatement = %p\ \n\t\t\tCatalog Name = %s\ \n\t\t\tSchema Name = %s\ \n\t\t\tTable Name = %s\ \n\t\t\tTable Type = %s", statement, __wstring_with_length( s1, catalog_name, name_length1 ), __wstring_with_length( s2, schema_name, name_length2 ), __wstring_with_length( s3, table_name, name_length3 ), __wstring_with_length( s4, table_type, name_length4 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } thread_protect( SQL_HANDLE_STMT, statement ); /* * this is a fix for old version of EXCEL */ if ( !catalog_name ) name_length1 = 0; if ( !schema_name ) name_length2 = 0; if ( !table_name ) name_length3 = 0; if ( !table_type ) name_length4 = 0; if (( name_length1 < 0 && name_length1 != SQL_NTS ) || ( name_length2 < 0 && name_length2 != SQL_NTS ) || ( name_length3 < 0 && name_length3 != SQL_NTS ) || ( name_length4 < 0 && name_length4 != SQL_NTS )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY090" ); __post_internal_error( &statement -> error, ERROR_HY090, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } /* * check states */ #ifdef NR_PROBE if ( statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) #else if (( statement -> state == STATE_S6 && statement -> eod == 0 ) || statement -> state == STATE_S7 ) #endif { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24000" ); __post_internal_error( &statement -> error, ERROR_24000, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } else if ( statement -> state == STATE_S8 || statement -> state == STATE_S9 || statement -> state == STATE_S10 || statement -> state == STATE_S13 || statement -> state == STATE_S14 || statement -> state == STATE_S15 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } if ( statement -> state == STATE_S11 || statement -> state == STATE_S12 ) { if ( statement -> interupted_func != SQL_API_SQLTABLES ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &statement -> error, ERROR_HY010, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } } /* * TO_DO Check the SQL_ATTR_METADATA_ID settings */ if ( statement -> connection -> unicode_driver || CHECK_SQLTABLESW( statement -> connection )) { if ( !CHECK_SQLTABLESW( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } ret = SQLTABLESW( statement -> connection , statement -> driver_stmt, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, table_type, name_length4 ); } else { SQLCHAR *as1, *as2, *as3, *as4; int clen; if ( !CHECK_SQLTABLES( statement -> connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &statement -> error, ERROR_IM001, NULL, statement -> connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR ); } as1 = (SQLCHAR*) unicode_to_ansi_alloc( catalog_name, name_length1, statement -> connection, &clen ); name_length1 = clen; as2 = (SQLCHAR*) unicode_to_ansi_alloc( schema_name, name_length2, statement -> connection, &clen ); name_length2 = clen; as3 = (SQLCHAR*) unicode_to_ansi_alloc( table_name, name_length3, statement -> connection, &clen ); name_length3 = clen; as4 = (SQLCHAR*) unicode_to_ansi_alloc( table_type, name_length4, statement -> connection, &clen ); name_length4 = clen; ret = SQLTABLES( statement -> connection , statement -> driver_stmt, as1, name_length1, as2, name_length2, as3, name_length3, as4, name_length4 ); if ( as1 ) free( as1 ); if ( as2 ) free( as2 ); if ( as3 ) free( as3 ); if ( as4 ) free( as4 ); } if ( SQL_SUCCEEDED( ret )) { #ifdef NR_PROBE /******** * Added this to get num cols from drivers which can only tell * us after execute - PAH */ /* * There is no point in doing this as we can't trust the value * from SQLPrepare, so we can't perform checks on the column number * ret = SQLNUMRESULTCOLS( statement -> connection, statement -> driver_stmt, &statement -> numcols ); */ statement -> numcols = 1; /******/ #endif statement -> hascols = 1; statement -> state = STATE_S5; statement -> prepared = 0; } else if ( ret == SQL_STILL_EXECUTING ) { statement -> interupted_func = SQL_API_SQLTABLES; if ( statement -> state != STATE_S11 && statement -> state != STATE_S12 ) statement -> state = STATE_S11; } else { statement -> state = STATE_S1; } if ( log_info.log_flag ) { sprintf( statement -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, statement -> msg ); } return function_return( SQL_HANDLE_STMT, statement, ret, DEFER_R1 ); } unixODBC-2.3.12/DriverManager/SQLTransact.c000066400000000000000000000411131446441710500202510ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLTransact.c,v 1.11 2009/02/18 17:59:08 lurcher Exp $ * * $Log: SQLTransact.c,v $ * Revision 1.11 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.10 2007/08/30 12:54:17 lurcher * Add -3 option to isql to use ODBC3 calls * * Revision 1.9 2006/05/31 17:35:34 lurcher * Add unicode ODBCINST entry points * * Revision 1.8 2004/06/16 14:42:03 lurcher * * * Fix potential corruption with threaded use and SQLEndTran * * Revision 1.7 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.6 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.5 2002/09/18 14:49:32 lurcher * * DataManagerII additions and some more threading fixes * * Revision 1.3 2002/08/20 12:41:07 lurcher * * Fix incorrect return state from SQLEndTran/SQLTransact * * Revision 1.2 2002/08/12 16:20:44 lurcher * * Make it try and find a working iconv set of encodings * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.10 2000/08/16 15:57:51 ngorham * * Fix bug where it falled if called in state C4 * * Revision 1.9 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.8 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.7 1999/10/20 19:45:15 ngorham * * Added fix to SQLTransact in the DM * * Revision 1.6 1999/09/21 22:34:26 ngorham * * Improve performance by removing unneeded logging calls when logging is * disabled * * Revision 1.5 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.4 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.3 1999/06/30 23:56:56 ngorham * * Add initial thread safety code * * Revision 1.2 1999/06/19 17:51:40 ngorham * * Applied assorted minor bug fixes * * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb * first go at it * * Revision 1.3 1999/06/02 20:12:10 ngorham * * Fixed botched log entry, and removed the dos \r from the sql header files. * * Revision 1.2 1999/06/02 19:57:21 ngorham * * Added code to check if a attempt is being made to compile with a C++ * Compiler, and issue a message. * Start work on the ODBC2-3 conversions. * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.2 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: SQLTransact.c,v $ $Revision: 1.11 $"; SQLRETURN SQLTransact( SQLHENV environment_handle, SQLHDBC connection_handle, SQLUSMALLINT completion_type ) { SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; /* * check either handle first */ if ( connection_handle != SQL_NULL_HDBC ) { DMHDBC connection = (DMHDBC) connection_handle; if ( !__validate_dbc( connection )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } } if ( environment_handle != SQL_NULL_HENV ) { DMHENV environment = (DMHENV) environment_handle; if ( !__validate_env( environment )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } } if ( connection_handle != SQL_NULL_HDBC ) { DMHDBC connection = (DMHDBC) connection_handle; SQLRETURN ret; function_entry( connection ); if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tEntry:\ \n\t\t\tEnvironment = %p\ \n\t\t\tConnection = %p\ \n\t\t\tCompletion Type = %d", (void*)environment_handle, (void*)connection_handle, (int)completion_type ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } thread_protect( SQL_HANDLE_DBC, connection ); if ( connection -> state == STATE_C1 || connection -> state == STATE_C2 || connection -> state == STATE_C3 ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 08003" ); __post_internal_error( &connection -> error, ERROR_08003, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } /* * check status of statements belonging to this connection */ if( __check_stmt_from_dbc_v( connection, 8, STATE_S8, STATE_S9, STATE_S10, STATE_S11, STATE_S12, STATE_S13, STATE_S14, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &connection -> error, ERROR_HY010, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( completion_type != SQL_COMMIT && completion_type != SQL_ROLLBACK ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY012" ); __post_internal_error( &connection -> error, ERROR_HY012, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if ( CHECK_SQLTRANSACT( connection )) { ret = SQLTRANSACT( connection, SQL_NULL_HENV, connection -> driver_dbc, completion_type ); } else if ( CHECK_SQLENDTRAN( connection )) { ret = SQLENDTRAN( connection, SQL_HANDLE_DBC, connection -> driver_dbc, completion_type ); } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &connection -> error, ERROR_IM001, NULL, connection -> environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); } if( SQL_SUCCEEDED(ret) && connection -> auto_commit == SQL_AUTOCOMMIT_OFF ) { SQLSMALLINT cb_value; SQLSMALLINT cb_value_length = sizeof(SQLSMALLINT); SQLRETURN ret1; /* * for each statement belonging to this connection set its state * relative to the commit or rollback behavior */ if ( connection -> cbs_found == 0 ) { /* release thread so we can get the info */ thread_release( SQL_HANDLE_DBC, connection ); ret1 = SQLGetInfo(connection, SQL_CURSOR_COMMIT_BEHAVIOR, &connection -> ccb_value, sizeof( SQLSMALLINT ), &cb_value_length); if ( SQL_SUCCEEDED( ret1 )) { ret1 = SQLGetInfo(connection, SQL_CURSOR_ROLLBACK_BEHAVIOR, &connection -> crb_value, sizeof( SQLSMALLINT ), &cb_value_length); } /* protect thread again */ thread_protect( SQL_HANDLE_DBC, connection ); if ( SQL_SUCCEEDED( ret1 )) { connection -> cbs_found = 1; } } if( completion_type == SQL_COMMIT ) { cb_value = connection -> ccb_value; } else { cb_value = connection -> crb_value; } if( connection -> cbs_found ) { __set_stmt_state( connection, cb_value ); } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\n\t\tExit:[%s]", __get_return_status( ret, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, connection -> msg ); } return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R0 ); } else if ( environment_handle != SQL_NULL_HENV ) { DMHENV environment = (DMHENV) environment_handle; DMHDBC connection; SQLRETURN ret; function_entry( environment ); if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tEntry:\ \n\t\t\tEnvironment = %p\ \n\t\t\tConnection = %p\ \n\t\t\tCompletion Type = %d", (void*)environment_handle, (void*)connection_handle, (int)completion_type ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } thread_protect( SQL_HANDLE_ENV, environment ); if ( completion_type != SQL_COMMIT && completion_type != SQL_ROLLBACK ) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY012" ); __post_internal_error( &environment -> error, ERROR_HY012, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } if ( environment -> state == STATE_E2 ) { /* * check that none of the connections are in a need data state */ connection = __get_dbc_root(); while( connection ) { if ( connection -> environment == environment && connection -> state > STATE_C4 ) { if( __check_stmt_from_dbc_v( connection, 8, STATE_S8, STATE_S9, STATE_S10, STATE_S11, STATE_S12, STATE_S13, STATE_S14, STATE_S15 )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: HY010" ); __post_internal_error( &environment -> error, ERROR_HY010, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } } connection = connection -> next_class_list; } /* * for each connection on this env */ connection = __get_dbc_root(); while( connection ) { if ( connection -> environment == environment && connection -> state > STATE_C4 ) { if ( CHECK_SQLTRANSACT( connection )) { ret = SQLTRANSACT( connection, SQL_NULL_HENV, connection -> driver_dbc, completion_type ); if ( !SQL_SUCCEEDED( ret )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24S01" ); __post_internal_error( &environment -> error, ERROR_25S01, NULL, environment -> requested_version ); thread_release( SQL_HANDLE_ENV, environment ); return function_return( SQL_HANDLE_ENV, environment, SQL_ERROR, DEFER_R0 ); } } else if ( CHECK_SQLENDTRAN( connection )) { ret = SQLENDTRAN( connection, SQL_HANDLE_DBC, connection -> driver_dbc, completion_type ); if ( !SQL_SUCCEEDED( ret )) { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: 24S01" ); __post_internal_error( &environment -> error, ERROR_25S01, NULL, environment -> requested_version ); return function_return( SQL_HANDLE_ENV, environment, SQL_ERROR, DEFER_R0 ); } } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); __post_internal_error( &environment -> error, ERROR_IM001, NULL, environment -> requested_version ); return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR ); } } connection = connection -> next_class_list; } } if ( log_info.log_flag ) { sprintf( environment -> msg, "\n\t\tExit:[%s]", __get_return_status( SQL_SUCCESS, s1 )); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } thread_release( SQL_HANDLE_ENV, environment ); return SQL_SUCCESS; } else { dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } } unixODBC-2.3.12/DriverManager/TODO000066400000000000000000000010441446441710500164350ustar00rootroot00000000000000Add explicit descriptor allocation and release. Keep track of bound columns to check if SQLGetData is valid. (may not be posible). Pass any connect and env attr onto driver when connected. Handle Env attrs (Set/Get EnvAttr). GetDescField needs finishing. Manage file DSN's. Interface to Cursor and Translator libs. Clear errors at the start of each function. Handle SQLCopyDesc where the source and destination is on different connections. SQLBulkoperations needs some conditions testing. SQLBrowseConnect needs some conditions testing. unixODBC-2.3.12/DriverManager/__attribute.c000066400000000000000000001175761446441710500204340ustar00rootroot00000000000000/********************************************************************* * * Written by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: __attribute.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $ * * $Log: __attribute.c,v $ * Revision 1.9 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.8 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.7 2007/07/13 09:01:08 lurcher * Add isql option to quote field data * * Revision 1.6 2006/04/18 10:24:47 lurcher * Add a couple of changes from Mark Vanderwiel * * Revision 1.5 2004/10/27 08:57:57 lurcher * Remove -module from cur Makefile.am, it seems to stop the lib building on HPUX... * * Revision 1.4 2004/06/21 10:01:12 lurcher * * Fix a couple of 64 bit issues * * Revision 1.3 2003/01/23 15:33:25 lurcher * * Fix problems with using putenv() * * Revision 1.2 2002/02/21 18:44:09 lurcher * * Fix bug on 32 bit platforms without long long support * Add option to set environment variables from the ini file * * Revision 1.1.1.1 2001/10/17 16:40:09 lurcher * * First upload to SourceForge * * Revision 1.1 2001/08/08 17:05:17 nick * * Add support for attribute setting in the ini files * * **********************************************************************/ #include #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: __attribute.c,v $"; /* * these are taken directly from odbctest/attr.cpp * so any bugs or additions, should be added there also */ typedef struct attr_value { char *text; int value; char *version; int data_type; } attr_value; typedef struct attr_options { char *text; int attr; attr_value values[ 6 ]; char *version; int data_type; int is_bitmap; int is_pointer; } attr_options; static attr_options stmt_options[] = { { "SQL_ATTR_APP_PARAM_DESC", SQL_ATTR_APP_PARAM_DESC, { { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_APP_ROW_DESC", SQL_ATTR_APP_ROW_DESC, { { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_ASYNC_ENABLE", SQL_ATTR_ASYNC_ENABLE, { { "SQL_ASYNC_ENABLE_OFF", SQL_ASYNC_ENABLE_OFF }, { "SQL_ASYNC_ENABLE_ON", SQL_ASYNC_ENABLE_ON }, { NULL } }, "1.0", SQL_INTEGER }, { "SQL_ATTR_CONCURRENCY", SQL_ATTR_CONCURRENCY, { { "SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY }, { "SQL_CONCUR_LOCK", SQL_CONCUR_LOCK }, { "SQL_CONCUR_ROWVER", SQL_CONCUR_ROWVER }, { "SQL_CONCUR_VALUES", SQL_CONCUR_VALUES }, { NULL } }, "2.0", SQL_INTEGER }, { "SQL_ATTR_CURSOR_SCROLLABLE", SQL_ATTR_CURSOR_SCROLLABLE, { { "SQL_NONSCROLLABLE", SQL_NONSCROLLABLE }, { "SQL_SCROLLABLE", SQL_SCROLLABLE }, { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_CURSOR_SENSITIVITY", SQL_ATTR_CURSOR_SENSITIVITY, { { "SQL_UNSPECIFIED", SQL_UNSPECIFIED }, { "SQL_INSENSITIVE", SQL_INSENSITIVE }, { "SQL_SENSITIVE", SQL_SENSITIVE }, { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_CURSOR_TYPE", SQL_ATTR_CURSOR_TYPE, { { "SQL_CURSOR_FORWARD_ONLY", SQL_CURSOR_FORWARD_ONLY }, { "SQL_CURSOR_STATIC", SQL_CURSOR_STATIC }, { "SQL_CURSOR_KEYSET_DRIVEN", SQL_CURSOR_KEYSET_DRIVEN }, { "SQL_CURSOR_DYNAMIC", SQL_CURSOR_DYNAMIC }, { NULL } }, "2.0", SQL_INTEGER }, { "SQL_ATTR_ENABLE_AUTO_IPD", SQL_ATTR_ENABLE_AUTO_IPD, { { "SQL_FALSE", SQL_FALSE }, { "SQL_TRUE", SQL_TRUE }, { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_FETCH_BOOKMARK_PTR", SQL_ATTR_FETCH_BOOKMARK_PTR, { { NULL } }, "3.0", SQL_INTEGER, FALSE, TRUE }, { "SQL_ATTR_FETCH_IMP_PARAM_DESC", SQL_ATTR_IMP_PARAM_DESC, { { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_FETCH_IMP_ROW_DESC", SQL_ATTR_IMP_ROW_DESC, { { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_KEYSET_SIZE", SQL_ATTR_KEYSET_SIZE, { { NULL } }, "2.0", SQL_INTEGER }, { "SQL_ATTR_MAX_LENGTH", SQL_ATTR_MAX_LENGTH, { { NULL } }, "1.0", SQL_INTEGER }, { "SQL_ATTR_MAX_ROWS", SQL_ATTR_MAX_ROWS, { { NULL } }, "1.0", SQL_INTEGER }, { "SQL_ATTR_METADATA_ID", SQL_ATTR_METADATA_ID, { { "SQL_FALSE", SQL_FALSE }, { "SQL_TRUE", SQL_TRUE }, { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_NOSCAN", SQL_ATTR_NOSCAN, { { "SQL_NOSCAN_OFF", SQL_NOSCAN_OFF }, { "SQL_NOSCAN_ON", SQL_NOSCAN_ON }, { NULL } }, "1.0", SQL_INTEGER }, { "SQL_ATTR_PARAM_BIND_OFFSET_PTR", SQL_ATTR_PARAM_BIND_OFFSET_PTR, { { NULL } }, "3.0", SQL_INTEGER, FALSE, TRUE }, { "SQL_ATTR_PARAM_BIND_TYPE", SQL_ATTR_PARAM_BIND_TYPE, { { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_PARAM_OPERATION_PTR", SQL_ATTR_PARAM_OPERATION_PTR, { { NULL } }, "3.0", SQL_SMALLINT, FALSE, TRUE }, { "SQL_ATTR_PARAM_STATUS_PTR", SQL_ATTR_PARAM_STATUS_PTR, { { NULL } }, "3.0", SQL_SMALLINT, FALSE, TRUE }, { "SQL_ATTR_PARAMS_PROCESSED_PTR", SQL_ATTR_PARAMS_PROCESSED_PTR, { { NULL } }, "3.0", SQL_SMALLINT, FALSE, TRUE }, { "SQL_ATTR_PARAMSET_SIZE", SQL_ATTR_PARAMSET_SIZE, { { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_QUERY_TIMEOUT", SQL_ATTR_QUERY_TIMEOUT, { { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_RETRIEVE_DATA", SQL_ATTR_RETRIEVE_DATA, { { "SQL_RD_ON", SQL_RD_ON }, { "SQL_RD_OFF", SQL_RD_OFF }, { NULL } }, "2.0", SQL_INTEGER }, { "SQL_ATTR_ROW_ARRAY_SIZE", SQL_ATTR_ROW_ARRAY_SIZE, { { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_ROW_BIND_OFFSET_PTR", SQL_ATTR_ROW_BIND_OFFSET_PTR, { { NULL } }, "3.0", SQL_INTEGER, FALSE, TRUE }, { "SQL_ATTR_ROW_BIND_TYPE", SQL_ATTR_ROW_BIND_TYPE, { { "SQL_BIND_BY_COLUMN", SQL_BIND_BY_COLUMN }, { NULL } }, "1.0", SQL_INTEGER }, { "SQL_ATTR_ROW_NUMBER", SQL_ATTR_ROW_NUMBER, { { NULL } }, "2.0", SQL_INTEGER }, { "SQL_ATTR_ROW_OPERATION_PTR", SQL_ATTR_ROW_OPERATION_PTR, { { NULL } }, "3.0", SQL_SMALLINT, FALSE, TRUE }, { "SQL_ATTR_ROW_STATUS_PTR", SQL_ATTR_ROW_STATUS_PTR, { { NULL } }, "3.0", SQL_SMALLINT, FALSE, TRUE }, { "SQL_ATTR_ROWS_FETCHED_PTR", SQL_ATTR_ROWS_FETCHED_PTR, { { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_SIMULATE_CURSOR", SQL_ATTR_SIMULATE_CURSOR, { { NULL } }, "2.0", SQL_INTEGER }, { "SQL_ATTR_USE_BOOKMARKS", SQL_ATTR_USE_BOOKMARKS, { { NULL } }, "2.0", SQL_INTEGER }, { NULL } }; static attr_options stmt_opt_options[] = { { "SQL_ASYNC_ENABLE", SQL_ASYNC_ENABLE, { { "SQL_ASYNC_ENABLE_OFF", SQL_ASYNC_ENABLE_OFF }, { "SQL_ASYNC_ENABLE_ON", SQL_ASYNC_ENABLE_ON }, { NULL } }, "1.0", SQL_INTEGER }, { "SQL_BIND_TYPE", SQL_BIND_TYPE, { { "SQL_BIND_BY_COLUMN", SQL_BIND_BY_COLUMN }, { NULL } }, "1.0", SQL_INTEGER }, { "SQL_CONCURRENCY", SQL_CONCURRENCY, { { "SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY }, { "SQL_CONCUR_LOCK", SQL_CONCUR_LOCK }, { "SQL_CONCUR_ROWVER", SQL_CONCUR_ROWVER }, { "SQL_CONCUR_VALUES", SQL_CONCUR_VALUES }, { "SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY }, { NULL } }, "2.0", SQL_INTEGER }, { "SQL_CURSOR_TYPE", SQL_CURSOR_TYPE, { { "SQL_CURSOR_FORWARD_ONLY", SQL_CURSOR_FORWARD_ONLY }, { "SQL_CURSOR_STATIC", SQL_CURSOR_STATIC }, { "SQL_CURSOR_KEYSET_DRIVEN", SQL_CURSOR_KEYSET_DRIVEN }, { "SQL_CURSOR_DYNAMIC", SQL_CURSOR_DYNAMIC }, { NULL } }, "2.0", SQL_INTEGER }, { "SQL_KEYSET_SIZE", SQL_KEYSET_SIZE, { { NULL } }, "2.0", SQL_INTEGER }, { "SQL_MAX_LENGTH", SQL_MAX_LENGTH, { { NULL } }, "1.0", SQL_INTEGER }, { "SQL_MAX_ROWS", SQL_MAX_ROWS, { { NULL } }, "1.0", SQL_INTEGER }, { "SQL_NOSCAN", SQL_NOSCAN, { { "SQL_NOSCAN_OFF", SQL_NOSCAN_OFF }, { "SQL_NOSCAN_ON", SQL_NOSCAN_ON }, { NULL } }, "1.0", SQL_INTEGER }, { "SQL_QUERY_TIMEOUT", SQL_QUERY_TIMEOUT, { { NULL } }, "1.0", SQL_INTEGER }, { "SQL_RETRIEVE_DATA", SQL_RETRIEVE_DATA, { { "SQL_RD_ON", SQL_RD_ON }, { "SQL_RD_OFF", SQL_RD_OFF }, { NULL } }, "2.0", SQL_INTEGER }, { "SQL_ROWSET_SIZE", SQL_ROWSET_SIZE, { { NULL } }, "2.0", SQL_INTEGER }, { "SQL_SIMULATE_CURSOR", SQL_SIMULATE_CURSOR, { { "SQL_SC_NON_UNIQUE", SQL_SC_NON_UNIQUE }, { "SQL_SC_TRY_UNIQUE", SQL_SC_TRY_UNIQUE }, { "SQL_SC_UNIQUE", SQL_SC_UNIQUE }, { NULL } }, "2.0", SQL_INTEGER }, { "SQL_USE_BOOKMARKS", SQL_USE_BOOKMARKS, { { "SQL_UB_ON", SQL_UB_ON }, { "SQL_UB_OFF", SQL_UB_OFF }, { NULL } }, "2.0", SQL_INTEGER }, { NULL } }; static attr_options conn_options[] = { { "SQL_ATTR_ACCESS_MODE", SQL_ATTR_ACCESS_MODE, { { "SQL_MODE_READ_WRITE", SQL_MODE_READ_WRITE }, { "SQL_MODE_READ_ONLY", SQL_MODE_READ_ONLY }, { NULL } }, "1.0", SQL_INTEGER }, { "SQL_ATTR_ASYNC_ENABLE", SQL_ATTR_ASYNC_ENABLE, { { "SQL_ASYNC_ENABLE_OFF", SQL_ASYNC_ENABLE_OFF }, { "SQL_ASYNC_ENABLE_ON", SQL_ASYNC_ENABLE_ON }, { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_AUTO_IPD", SQL_ATTR_AUTO_IPD, { { "SQL_TRUE", SQL_TRUE }, { "SQL_FALSE", SQL_FALSE }, { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_AUTOCOMMIT", SQL_ATTR_AUTOCOMMIT, { { "SQL_AUTOCOMMIT_ON", SQL_AUTOCOMMIT_ON }, { "SQL_AUTOCOMMIT_OFF", SQL_AUTOCOMMIT_OFF }, { NULL } }, "1.0", SQL_INTEGER }, { "SQL_ATTR_CONNECTION_TIMEOUT", SQL_ATTR_CONNECTION_TIMEOUT, { { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_CURRENT_CATALOG", SQL_ATTR_CURRENT_CATALOG, { { NULL } }, "2.0", SQL_CHAR }, { "SQL_ATTR_LOGIN_TIMEOUT", SQL_ATTR_LOGIN_TIMEOUT, { { NULL } }, "1.0", SQL_INTEGER }, { "SQL_ATTR_METADATA_ID", SQL_ATTR_METADATA_ID, { { "SQL_TRUE", SQL_TRUE }, { "SQL_FALSE", SQL_FALSE }, { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_ODBC_CURSORS", SQL_ATTR_ODBC_CURSORS, { { "SQL_CUR_USE_IF_NEEDED", SQL_CUR_USE_IF_NEEDED }, { "SQL_CUR_USE_ODBC", SQL_CUR_USE_ODBC }, { "SQL_CUR_USE_DRIVER", SQL_CUR_USE_DRIVER }, { NULL } }, "2.0", SQL_INTEGER }, { "SQL_ATTR_PACKET_SIZE", SQL_ATTR_PACKET_SIZE, { { NULL } }, "2.0", SQL_INTEGER }, { "SQL_ATTR_QUIET_MODE", SQL_ATTR_QUIET_MODE, { { NULL } }, "2.0", SQL_INTEGER }, { "SQL_ATTR_TRACE", SQL_ATTR_TRACE, { { "SQL_OPT_TRACE_OFF", SQL_OPT_TRACE_OFF }, { "SQL_OPT_TRACE_ON", SQL_OPT_TRACE_ON }, { NULL } }, "1.0", SQL_INTEGER }, { "SQL_ATTR_TRACEFILE", SQL_ATTR_TRACEFILE, { { NULL } }, "1.0", SQL_CHAR }, { "SQL_ATTR_TRANSLATE_LIB", SQL_ATTR_TRANSLATE_LIB, { { NULL } }, "1.0", SQL_CHAR }, { "SQL_ATTR_TRANSLATE_OPTION", SQL_ATTR_TRANSLATE_OPTION, { { NULL } }, "1.0", SQL_INTEGER }, { "SQL_ATTR_TXN_ISOLATION", SQL_ATTR_TXN_ISOLATION, { { "SQL_TXN_READ_UNCOMMITTED", SQL_TXN_READ_UNCOMMITTED }, { "SQL_TXN_READ_COMMITTED", SQL_TXN_READ_COMMITTED }, { "SQL_TXN_REPEATABLE_READ", SQL_TXN_REPEATABLE_READ }, { "SQL_TXN_SERIALIZABLE", SQL_TXN_SERIALIZABLE }, { NULL } }, "1.0", SQL_INTEGER }, { NULL } }; static attr_options conn_opt_options[] = { { "conn: SQL_ACCESS_MODE", SQL_ACCESS_MODE, { { "SQL_MODE_READ_ONLY", SQL_MODE_READ_ONLY }, { "SQL_MODE_READ_WRITE", SQL_MODE_READ_WRITE }, { NULL } }, "1.0", SQL_INTEGER }, { "conn: SQL_AUTOCOMMIT", SQL_AUTOCOMMIT, { { "SQL_AUTOCOMMIT_ON", SQL_AUTOCOMMIT_ON }, { "SQL_AUTOCOMMIT_OFF", SQL_AUTOCOMMIT_OFF }, { NULL } }, "1.0", SQL_INTEGER }, { "conn: SQL_CURRENT_QUALIFIER", SQL_CURRENT_QUALIFIER, { { NULL } }, "2.0", SQL_CHAR }, { "conn: SQL_LOGIN_TIMEOUT", SQL_LOGIN_TIMEOUT, { { NULL } }, "1.0", SQL_INTEGER }, { "conn: SQL_ODBC_CURSORS", SQL_ODBC_CURSORS, { { "SQL_CUR_USE_IF_NEEDED", SQL_CUR_USE_IF_NEEDED }, { "SQL_CUR_USE_ODBC", SQL_CUR_USE_ODBC }, { "SQL_CUR_USE_DRIVER", SQL_CUR_USE_DRIVER }, { NULL } }, "2.0", SQL_INTEGER }, { "conn: SQL_OPT_TRACE", SQL_OPT_TRACE, { { "SQL_OPT_TRACE_ON", SQL_OPT_TRACE_ON }, { "SQL_OPT_TRACE_OFF", SQL_OPT_TRACE_OFF }, { NULL } }, "1.0", SQL_INTEGER }, { "conn: SQL_OPT_TRACEFILE", SQL_OPT_TRACEFILE, { { NULL } }, "1.0", SQL_CHAR }, { "conn: SQL_PACKET_SIZE", SQL_PACKET_SIZE, { { NULL } }, "2.0", SQL_INTEGER }, { "conn: SQL_QUIET_MODE", SQL_QUIET_MODE, { { NULL } }, "2.0", SQL_INTEGER }, { "conn: SQL_TRANSLATE_DLL", SQL_TRANSLATE_DLL, { { NULL } }, "1.0", SQL_CHAR }, { "conn: SQL_TRANSLATE_OPTION", SQL_TRANSLATE_OPTION, { { NULL } }, "1.0", SQL_INTEGER }, { "conn: SQL_TXN_ISOLATION", SQL_TXN_ISOLATION, { { "SQL_TXN_READ_UNCOMMITED", SQL_TXN_READ_UNCOMMITTED }, { "SQL_TXN_READ_COMMITED", SQL_TXN_READ_COMMITTED }, { "SQL_TXN_REPEATABLE_READ", SQL_TXN_REPEATABLE_READ }, { "SQL_TXN_SERIALIZABLE", SQL_TXN_SERIALIZABLE }, { "SQL_TXN_VERSIONING", 0x00000010L }, { NULL } }, "1.0", SQL_INTEGER }, { "stmt: SQL_ASYNC_ENABLE", SQL_ASYNC_ENABLE, { { "SQL_ASYNC_ENABLE_OFF", SQL_ASYNC_ENABLE_OFF }, { "SQL_ASYNC_ENABLE_ON", SQL_ASYNC_ENABLE_ON }, { NULL } }, "1.0", SQL_INTEGER }, { "stmt: SQL_BIND_TYPE", SQL_BIND_TYPE, { { "SQL_BIND_BY_COLUMN", SQL_BIND_BY_COLUMN }, { NULL } }, "1.0", SQL_INTEGER }, { "stmt: SQL_CONCURRENCY", SQL_CONCURRENCY, { { "SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY }, { "SQL_CONCUR_LOCK", SQL_CONCUR_LOCK }, { "SQL_CONCUR_ROWVER", SQL_CONCUR_ROWVER }, { "SQL_CONCUR_VALUES", SQL_CONCUR_VALUES }, { "SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY }, { NULL } }, "2.0", SQL_INTEGER }, { "stmt: SQL_CURSOR_TYPE", SQL_CURSOR_TYPE, { { "SQL_CURSOR_FORWARD_ONLY", SQL_CURSOR_FORWARD_ONLY }, { "SQL_CURSOR_STATIC", SQL_CURSOR_STATIC }, { "SQL_CURSOR_KEYSET_DRIVEN", SQL_CURSOR_KEYSET_DRIVEN }, { "SQL_CURSOR_DYNAMIC", SQL_CURSOR_DYNAMIC }, { NULL } }, "2.0", SQL_INTEGER }, { "stmt: SQL_KEYSET_SIZE", SQL_KEYSET_SIZE, { { NULL } }, "2.0", SQL_INTEGER }, { "stmt: SQL_MAX_LENGTH", SQL_MAX_LENGTH, { { NULL } }, "1.0", SQL_INTEGER }, { "stmt: SQL_MAX_ROWS", SQL_MAX_ROWS, { { NULL } }, "1.0", SQL_INTEGER }, { "stmt: SQL_NOSCAN", SQL_NOSCAN, { { "SQL_NOSCAN_OFF", SQL_NOSCAN_OFF }, { "SQL_NOSCAN_ON", SQL_NOSCAN_ON }, { NULL } }, "1.0", SQL_INTEGER }, { "stmt: SQL_QUERY_TIMEOUT", SQL_QUERY_TIMEOUT, { { NULL } }, "1.0", SQL_INTEGER }, { "stmt: SQL_RETRIEVE_DATA", SQL_RETRIEVE_DATA, { { "SQL_RD_ON", SQL_RD_ON }, { "SQL_RD_OFF", SQL_RD_OFF }, { NULL } }, "2.0", SQL_INTEGER }, { "stmt: SQL_ROWSET_SIZE", SQL_ROWSET_SIZE, { { NULL } }, "2.0", SQL_INTEGER }, { "stmt: SQL_SIMULATE_CURSOR", SQL_SIMULATE_CURSOR, { { "SQL_SC_NON_UNIQUE", SQL_SC_NON_UNIQUE }, { "SQL_SC_TRY_UNIQUE", SQL_SC_TRY_UNIQUE }, { "SQL_SC_UNIQUE", SQL_SC_UNIQUE }, { NULL } }, "2.0", SQL_INTEGER }, { "stmt: SQL_USE_BOOKMARKS", SQL_USE_BOOKMARKS, { { "SQL_UB_ON", SQL_UB_ON }, { "SQL_UB_OFF", SQL_UB_OFF }, { NULL } }, "2.0", SQL_INTEGER }, { NULL } }; static attr_options env_options[] = { { "SQL_ATTR_ODBC_VERSION", SQL_ATTR_ODBC_VERSION, { { "SQL_OV_ODBC2", SQL_OV_ODBC2 }, { "SQL_OV_ODBC3", SQL_OV_ODBC3 }, { "SQL_OV_ODBC3_80", SQL_OV_ODBC3_80 }, { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_CP_MATCH", SQL_ATTR_CP_MATCH, { { "SQL_CP_STRICT_MATCH", SQL_CP_STRICT_MATCH }, { "SQL_CP_RELAXED_MATCH", SQL_CP_RELAXED_MATCH }, { "SQL_CP_MATCH_DEFAULT", SQL_CP_MATCH_DEFAULT }, { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_CONNECTION_POOLING", SQL_ATTR_CONNECTION_POOLING, { { "SQL_CP_OFF", SQL_OV_ODBC2 }, { "SQL_CP_ONE_PER_DRIVER", SQL_CP_ONE_PER_DRIVER }, { "SQL_CP_ONE_PER_HENV", SQL_CP_ONE_PER_HENV }, { "SQL_CP_DEFAULT", SQL_CP_DEFAULT }, { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_OUTPUT_NTS", SQL_ATTR_OUTPUT_NTS, { { "SQL_TRUE", SQL_TRUE }, { "SQL_FALSE", SQL_FALSE }, { NULL } }, "3.0", SQL_INTEGER }, { "SQL_ATTR_UNIXODBC_ENVATTR", SQL_ATTR_UNIXODBC_ENVATTR, { { NULL } }, "3.0", SQL_CHAR }, { NULL } }; static int find_option( char *kw, struct attr_set *as, struct attr_options *opt ) { struct attr_value *val; int found = 0; while( opt -> text && !found ) { if ( strcasecmp( kw, opt -> text ) == 0 ) { found = 1; val = opt -> values; as -> attribute = opt -> attr; while ( val -> text ) { if ( strcasecmp( as -> value, val -> text ) == 0 ) { break; } val ++; } if ( val -> text ) { as -> is_int_type = 1; as -> int_value = val -> value; } else { if ( opt -> data_type != SQL_CHAR ) { as -> is_int_type = 1; as -> int_value = atoi( as -> value ); } } } opt ++; } /* * Handle non standard attributes by [numeric_value]={char value} or [numeric_value]=\int_value */ if ( !found ) { if ( kw[ 0 ] == '[' ) { as -> attribute = atoi( kw + 1 ); if ( as -> value[ 0 ] == '\\' ) { as -> is_int_type = 1; as -> int_value = atoi( as -> value + 1 ); } found = 1; } } return found; } struct attr_set * __get_set( char ** cp, int *skip ) { char *ptr, *kw; int len; struct attr_set *as; /* * flag to indicate a non valid option */ *skip = 0; ptr = *cp; if ( !**cp ) return NULL; while ( **cp && **cp != '=' ) { (*cp)++; } if ( !**cp ) return NULL; as = malloc( sizeof( struct attr_set )); if ( !as ) { return NULL; } memset( as, 0, sizeof( struct attr_set )); len = *cp - ptr; as -> keyword = malloc( len + 1 ); memcpy( as -> keyword, ptr, len ); as -> keyword[ len ] = '\0'; (*cp)++; ptr = *cp; if ( **cp && **cp == '{' ) { (*cp)++; ptr ++; while ( **cp && **cp != '}' ) (*cp)++; len = *cp - ptr; as -> value = malloc( len + 1 ); memcpy( as -> value, ptr , len ); as -> value[ len ] = '\0'; (*cp)++; } else { while ( **cp && **cp != ';' ) (*cp)++; len = *cp - ptr; as -> value = malloc( len + 1 ); memcpy( as -> value, ptr, len ); as -> value[ len ] = '\0'; } /* * now we translate the keyword and attribute values */ if ( as -> keyword[ 0 ] == '*' ) { kw = as -> keyword + 1; as -> override = 1; } else { kw = as -> keyword; } if ( !find_option( kw, as, env_options ) && !find_option( kw, as, conn_options ) && !find_option( kw, as, conn_opt_options ) && !find_option( kw, as, stmt_options ) && !find_option( kw, as, stmt_opt_options )) { *skip = 1; } if ( **cp ) (*cp)++; return as; } int __append_set( struct attr_struct *attr_str, struct attr_set *ap ) { struct attr_set *ptr, *end, *nap; /* check that the attribute is not already in the list */ end = NULL; if ( attr_str -> count > 0 ) { ptr = attr_str -> list; while( ptr ) { if( ap -> attribute == ptr -> attribute ) { return 0; } end = ptr; ptr = ptr -> next; } } nap = malloc( sizeof( *ptr )); *nap = *ap; nap -> keyword = malloc( strlen( ap -> keyword ) + 1 ); strcpy( nap -> keyword, ap -> keyword ); nap -> value = malloc( strlen( ap -> value ) + 1 ); strcpy( nap -> value, ap -> value ); attr_str -> count ++; if ( attr_str -> list ) { end -> next = nap; nap -> next = NULL; } else { nap -> next = NULL; attr_str -> list = nap; } return 0; } int __parse_attribute_string( struct attr_struct *attr_str, char *str, int str_len ) { struct attr_set *cp; char *local_str, *ptr; int skip; attr_str -> count = 0; attr_str -> list = NULL; if ( str_len != SQL_NTS ) { local_str = malloc( str_len + 1 ); memcpy( local_str, str, str_len ); local_str[ str_len ] = '\0'; } else { local_str = str; } ptr = local_str; while(( cp = __get_set( &ptr, &skip )) != NULL ) { if ( !skip ) { __append_set( attr_str, cp ); } free( cp -> keyword ); free( cp -> value ); free( cp ); } if ( str_len != SQL_NTS ) free( local_str ); return 0; } void __release_attr_str( struct attr_struct *attr_str ) { struct attr_set *set, *ptr; if ( !attr_str ) { return; } set = attr_str -> list; while ( set ) { ptr = set -> next; free( set -> keyword ); free( set -> value ); free( set ); set = ptr; } attr_str -> list = NULL; attr_str -> count = 0; } static void __set_local_attribute( void *handle, int type, struct attr_set *as ) { SQLRETURN ret = SQL_SUCCESS; if ( type == SQL_HANDLE_ENV ) { DMHDBC connection = (DMHDBC) handle; if ( as -> attribute == SQL_ATTR_UNIXODBC_ENVATTR ) { /* * its a memory leak, but not much I can do, see "man putenv" */ putenv( strdup( as -> value )); } else { return; } if ( log_info.log_flag ) { sprintf( connection -> msg, "\t\tENV ATTR [%s=%s] ret = %d", as -> keyword, as -> value, ret ); dm_log_write_diag( connection -> msg ); } } } static void __set_attribute( void *handle, int type, struct attr_set *as ) { SQLRETURN ret = SQL_ERROR; if ( type == SQL_HANDLE_ENV ) { DMHDBC connection = (DMHDBC) handle; if ( as -> attribute == SQL_ATTR_UNIXODBC_ENVATTR ) { return; } if ( connection -> driver_version >= SQL_OV_ODBC3 ) { if ( CHECK_SQLSETENVATTR( connection )) { if ( as -> is_int_type ) { ret = SQLSETENVATTR( connection, connection -> driver_dbc, as -> attribute, (SQLPOINTER)(intptr_t) as -> int_value, 0 ); } else { ret = SQLSETENVATTR( connection, connection -> driver_dbc, as -> attribute, as -> value, strlen( as -> value )); } } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\t\tENV ATTR [%s=%s] ret = %d", as -> keyword, as -> value, ret ); dm_log_write_diag( connection -> msg ); } } else if ( type == SQL_HANDLE_DBC ) { DMHDBC connection = (DMHDBC) handle; if ( connection -> driver_version >= SQL_OV_ODBC3 ) { if ( CHECK_SQLSETCONNECTATTR( connection )) { if ( as -> is_int_type ) { ret = SQLSETCONNECTATTR( connection, connection -> driver_dbc, as -> attribute, (SQLPOINTER)(intptr_t) as -> int_value, 0 ); } else { ret = SQLSETCONNECTATTR( connection, connection -> driver_dbc, as -> attribute, as -> value, strlen( as -> value )); } } else if ( CHECK_SQLSETCONNECTOPTION( connection )) { if ( as -> is_int_type ) { ret = SQLSETCONNECTOPTION( connection, connection -> driver_dbc, as -> attribute, as -> int_value ); } else { ret = SQLSETCONNECTOPTION( connection, connection -> driver_dbc, as -> attribute, (SQLULEN) as -> value ); } } } else { if ( CHECK_SQLSETCONNECTOPTION( connection )) { if ( as -> is_int_type ) { ret = SQLSETCONNECTOPTION( connection, connection -> driver_dbc, as -> attribute, as -> int_value ); } else { ret = SQLSETCONNECTOPTION( connection, connection -> driver_dbc, as -> attribute, (SQLULEN) as -> value ); } } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\t\tCONN ATTR [%s=%s] ret = %d", as -> keyword, as -> value, ret ); dm_log_write_diag( connection -> msg ); } } else if ( type == SQL_HANDLE_STMT ) { DMHSTMT statement = (DMHSTMT) handle; DMHDBC connection = statement -> connection; if ( connection -> driver_version >= SQL_OV_ODBC3 ) { if ( CHECK_SQLSETSTMTATTR( connection )) { if ( as -> is_int_type ) { ret = SQLSETSTMTATTR( connection, statement -> driver_stmt, as -> attribute, (SQLPOINTER)(intptr_t) as -> int_value, 0 ); } else { ret = SQLSETSTMTATTR( connection, statement -> driver_stmt, as -> attribute, as -> value, strlen( as -> value )); } } else if ( CHECK_SQLSETSTMTOPTION( connection )) { if ( as -> is_int_type ) { ret = SQLSETSTMTOPTION( connection, statement -> driver_stmt, as -> attribute, as -> int_value ); } else { ret = SQLSETSTMTOPTION( connection, statement -> driver_stmt, as -> attribute, (SQLULEN) as -> value ); } } } else { if ( CHECK_SQLSETSTMTOPTION( connection )) { if ( as -> is_int_type ) { ret = SQLSETSTMTOPTION( connection, statement -> driver_stmt, as -> attribute, as -> int_value ); } else { ret = SQLSETSTMTOPTION( connection, statement -> driver_stmt, as -> attribute, (SQLULEN) as -> value ); } } /* * Fall back, the attribute may be ODBC 3 only */ if ( ret == SQL_ERROR ) { if ( CHECK_SQLSETSTMTATTR( connection )) { if ( as -> is_int_type ) { ret = SQLSETSTMTATTR( connection, statement -> driver_stmt, as -> attribute, (SQLPOINTER)(intptr_t) as -> int_value, 0 ); } else { ret = SQLSETSTMTATTR( connection, statement -> driver_stmt, as -> attribute, as -> value, strlen( as -> value )); } } } } if ( log_info.log_flag ) { sprintf( connection -> msg, "\t\tSTMT ATTR [%s=%s] ret = %d", as -> keyword, as -> value, ret ); dm_log_write_diag( connection -> msg ); } } } void __set_local_attributes( void * handle, int type ) { struct attr_set *as; switch( type ) { case SQL_HANDLE_ENV: as = ((DMHDBC) handle ) -> env_attribute.list; break; default: as = NULL; break; } while( as ) { __set_local_attribute( handle, type, as ); as = as -> next; } } void __set_attributes( void * handle, int type ) { struct attr_set *as; switch( type ) { case SQL_HANDLE_ENV: as = ((DMHDBC) handle ) -> env_attribute.list; break; case SQL_HANDLE_DBC: as = ((DMHDBC) handle ) -> dbc_attribute.list; break; case SQL_HANDLE_STMT: as = ((DMHSTMT) handle ) -> connection -> stmt_attribute.list; break; default: as = NULL; break; } while( as ) { __set_attribute( handle, type, as ); as = as -> next; } } void *__attr_override( void *handle, int type, int attribute, void *value, SQLINTEGER *string_length ) { struct attr_set *as; char *msg; switch( type ) { case SQL_HANDLE_DBC: as = ((DMHDBC) handle ) -> dbc_attribute.list; msg = ((DMHDBC) handle ) -> msg; break; case SQL_HANDLE_STMT: as = ((DMHSTMT) handle ) -> connection -> stmt_attribute.list; msg = ((DMHSTMT) handle ) -> msg; break; default: as = NULL; msg = NULL; break; } while( as ) { if ( as -> override && as -> attribute == attribute ) { break; } as = as -> next; } if ( as ) { if ( log_info.log_flag ) { sprintf( msg, "\t\tATTR OVERRIDE [%s=%s]", as -> keyword + 1, as -> value ); dm_log_write_diag( msg ); } if ( as -> is_int_type ) { #ifdef HAVE_PTRDIFF_T return (void*)(ptrdiff_t) as -> int_value; #else return (void*)(long) as -> int_value; #endif } else { if ( string_length ) { *string_length = strlen( as -> value ); } return as -> value; } } else { return value; } } void *__attr_override_wide( void *handle, int type, int attribute, void *value, SQLINTEGER *string_length, SQLWCHAR *buffer ) { struct attr_set *as; char *msg; switch( type ) { case SQL_HANDLE_DBC: as = ((DMHDBC) handle ) -> dbc_attribute.list; msg = ((DMHDBC) handle ) -> msg; break; case SQL_HANDLE_STMT: as = ((DMHSTMT) handle ) -> connection -> stmt_attribute.list; msg = ((DMHSTMT) handle ) -> msg; break; default: as = NULL; msg = NULL; break; } while( as ) { if ( as -> override && as -> attribute == attribute ) { break; } as = as -> next; } if ( as ) { if ( log_info.log_flag ) { sprintf( msg, "\t\tATTR OVERRIDE [%s=%s]", as -> keyword + 1, as -> value ); dm_log_write_diag( msg ); } if ( as -> is_int_type ) { #ifdef HAVE_PTRDIFF_T return (void*)(ptrdiff_t) as -> int_value; #else return (void*)(long) as -> int_value; #endif } else { if ( string_length ) { *string_length = strlen( as -> value ) * sizeof( SQLWCHAR ); } switch( type ) { case SQL_HANDLE_DBC: ansi_to_unicode_copy( buffer, as->value, SQL_NTS, (DMHDBC) handle, NULL ); break; case SQL_HANDLE_STMT: ansi_to_unicode_copy( buffer, as->value, SQL_NTS, ((DMHSTMT) handle ) -> connection, NULL ); break; } return buffer; } } else { return value; } } /* * check for valid attributes in the setting functions */ int dm_check_connection_attrs( DMHDBC connection, SQLINTEGER attribute, SQLPOINTER value ) { #ifdef HAVE_PTRDIFF_T ptrdiff_t ival; #else SQLINTEGER ival; #endif #ifdef HAVE_PTRDIFF_T ival = (ptrdiff_t) value; #else ival = (SQLINTEGER) value; #endif switch( attribute ) { case SQL_ACCESS_MODE: if ( ival != SQL_MODE_READ_ONLY && ival != SQL_MODE_READ_WRITE ) { return SQL_ERROR; } break; case SQL_ATTR_ASYNC_ENABLE: if ( ival != SQL_ASYNC_ENABLE_OFF && ival != SQL_ASYNC_ENABLE_ON ) { return SQL_ERROR; } break; case SQL_ATTR_AUTO_IPD: if ( ival != SQL_TRUE && ival != SQL_FALSE ) { return SQL_ERROR; } break; case SQL_ATTR_AUTOCOMMIT: if ( ival != SQL_AUTOCOMMIT_ON && ival != SQL_AUTOCOMMIT_OFF ) { return SQL_ERROR; } break; case SQL_ATTR_METADATA_ID: if ( ival != SQL_TRUE && ival != SQL_FALSE ) { return SQL_ERROR; } break; case SQL_ATTR_ODBC_CURSORS: if ( ival != SQL_CUR_USE_IF_NEEDED && ival != SQL_CUR_USE_ODBC && ival != SQL_CUR_USE_DRIVER ) { return SQL_ERROR; } break; case SQL_ATTR_TRACE: if ( ival != SQL_OPT_TRACE_ON && ival != SQL_OPT_TRACE_OFF ) { return SQL_ERROR; } break; case SQL_ATTR_TXN_ISOLATION: if ( ival != SQL_TXN_READ_UNCOMMITTED && ival != SQL_TXN_READ_COMMITTED && ival != SQL_TXN_REPEATABLE_READ && ival != SQL_TXN_SERIALIZABLE ) { return SQL_ERROR; } break; /* * include statement attributes as well */ case SQL_ATTR_CONCURRENCY: if ( ival != SQL_CONCUR_READ_ONLY && ival != SQL_CONCUR_LOCK && ival != SQL_CONCUR_ROWVER && ival != SQL_CONCUR_VALUES ) { return SQL_ERROR; } break; case SQL_ATTR_CURSOR_SCROLLABLE: if ( ival != SQL_NONSCROLLABLE && ival != SQL_SCROLLABLE ) { return SQL_ERROR; } break; case SQL_ATTR_CURSOR_SENSITIVITY: if ( ival != SQL_UNSPECIFIED && ival != SQL_INSENSITIVE && ival != SQL_SENSITIVE ) { return SQL_ERROR; } break; case SQL_ATTR_CURSOR_TYPE: if ( ival != SQL_CURSOR_FORWARD_ONLY && ival != SQL_CURSOR_STATIC && ival != SQL_CURSOR_KEYSET_DRIVEN && ival != SQL_CURSOR_DYNAMIC ) { return SQL_ERROR; } break; case SQL_ATTR_ENABLE_AUTO_IPD: if ( ival != SQL_TRUE && ival != SQL_FALSE ) { return SQL_ERROR; } break; case SQL_ATTR_NOSCAN: if ( ival != SQL_NOSCAN_ON && ival != SQL_NOSCAN_OFF ) { return SQL_ERROR; } break; case SQL_ATTR_RETRIEVE_DATA: if ( ival != SQL_RD_ON && ival != SQL_RD_OFF ) { return SQL_ERROR; } break; case SQL_ATTR_SIMULATE_CURSOR: if ( ival != SQL_SC_NON_UNIQUE && ival != SQL_SC_TRY_UNIQUE && ival != SQL_SC_UNIQUE ) { return SQL_ERROR; } break; case SQL_ATTR_USE_BOOKMARKS: if ( ival != SQL_UB_OFF && ival != SQL_UB_VARIABLE && ival != SQL_UB_FIXED ) { return SQL_ERROR; } break; default: return SQL_SUCCESS; } return SQL_SUCCESS; } int dm_check_statement_attrs( DMHSTMT statement, SQLINTEGER attribute, SQLPOINTER value ) { #ifdef HAVE_PTRDIFF_T ptrdiff_t ival; #else SQLUINTEGER ival; #endif #ifdef HAVE_PTRDIFF_T ival = (ptrdiff_t) value; #else ival = (SQLUINTEGER) value; #endif switch( attribute ) { case SQL_ATTR_ASYNC_ENABLE: if ( ival != SQL_ASYNC_ENABLE_OFF && ival != SQL_ASYNC_ENABLE_ON ) { return SQL_ERROR; } break; case SQL_ATTR_CONCURRENCY: if ( ival != SQL_CONCUR_READ_ONLY && ival != SQL_CONCUR_LOCK && ival != SQL_CONCUR_ROWVER && ival != SQL_CONCUR_VALUES ) { return SQL_ERROR; } break; case SQL_ATTR_CURSOR_SCROLLABLE: if ( ival != SQL_NONSCROLLABLE && ival != SQL_SCROLLABLE ) { return SQL_ERROR; } break; case SQL_ATTR_CURSOR_SENSITIVITY: if ( ival != SQL_UNSPECIFIED && ival != SQL_INSENSITIVE && ival != SQL_SENSITIVE ) { return SQL_ERROR; } break; case SQL_ATTR_CURSOR_TYPE: if ( ival != SQL_CURSOR_FORWARD_ONLY && ival != SQL_CURSOR_STATIC && ival != SQL_CURSOR_KEYSET_DRIVEN && ival != SQL_CURSOR_DYNAMIC ) { return SQL_ERROR; } break; case SQL_ATTR_ENABLE_AUTO_IPD: if ( ival != SQL_TRUE && ival != SQL_FALSE ) { return SQL_ERROR; } break; case SQL_ATTR_NOSCAN: if ( ival != SQL_NOSCAN_ON && ival != SQL_NOSCAN_OFF ) { return SQL_ERROR; } break; case SQL_ATTR_RETRIEVE_DATA: if ( ival != SQL_RD_ON && ival != SQL_RD_OFF ) { return SQL_ERROR; } break; case SQL_ATTR_SIMULATE_CURSOR: if ( ival != SQL_SC_NON_UNIQUE && ival != SQL_SC_TRY_UNIQUE && ival != SQL_SC_UNIQUE ) { return SQL_ERROR; } break; case SQL_ATTR_USE_BOOKMARKS: if ( ival != SQL_UB_OFF && ival != SQL_UB_VARIABLE && ival != SQL_UB_FIXED ) { return SQL_ERROR; } break; case SQL_ROWSET_SIZE: return ival > 0 ? SQL_SUCCESS : SQL_ERROR; default: return SQL_SUCCESS; } return SQL_SUCCESS; } unixODBC-2.3.12/DriverManager/__connection.c000066400000000000000000000164711446441710500205600ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: __connection.c,v 1.6 2009/02/18 17:59:08 lurcher Exp $ * * $Log: __connection.c,v $ * Revision 1.6 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.4 2004/09/08 16:38:54 lurcher * * Get ready for a 2.2.10 release * * Revision 1.3 2003/04/10 13:45:52 lurcher * * Alter the way that SQLDataSources returns the description field (again) * * Revision 1.2 2003/04/09 08:42:18 lurcher * * Allow setting of odbcinstQ lib from odbcinst.ini and Environment * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.2 2001/05/15 10:57:44 nick * * Add initial support for VMS * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.7 1999/11/28 18:35:50 ngorham * * Add extra ODBC3/2 Date/Time mapping * * Revision 1.6 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.5 1999/10/09 00:56:16 ngorham * * Added Manush's patch to map ODBC 3-2 datetime values * * Revision 1.4 1999/08/03 21:47:39 shandyb * Moving to automake: changed files in DriverManager * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/19 17:51:41 ngorham * * Applied assorted minor bug fixes * * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include "drivermanager.h" /* * list of places to look, a $ at the start indicates * then it following text should be looked in as a env * variable */ static char const rcsid[]= "$RCSfile: __connection.c,v $ $Revision: 1.6 $"; /* * search for the library (.so) that the DSN points to */ char *__find_lib_name( char *dsn, char *lib_name, char *driver_name ) { char driver[ INI_MAX_PROPERTY_VALUE + 1 ]; char driver_lib[ INI_MAX_PROPERTY_VALUE + 1 ]; SQLSetConfigMode( ODBC_USER_DSN ); /* * GET DRIVER FROM ODBC.INI */ SQLGetPrivateProfileString( dsn, "Driver", "", driver_lib, sizeof( driver_lib ), "ODBC.INI" ); if ( driver_lib[ 0 ] == 0 ) { /* * if not found look in system DSN */ SQLSetConfigMode( ODBC_SYSTEM_DSN ); SQLGetPrivateProfileString( dsn, "Driver", "", driver_lib, sizeof( driver_lib ), "ODBC.INI" ); SQLSetConfigMode( ODBC_BOTH_DSN ); if ( driver_lib[ 0 ] == 0 ) return NULL; } /* * GET DRIVER FROM ODBCINST.INI IF ODBC.INI HAD USER FRIENDLY NAME */ strcpy( driver_name, "" ); if ( driver_lib[ 0 ] != '/' ) { strcpy( driver, driver_lib ); /* * allow the use of "User odbcinst files */ #ifdef PLATFORM64 SQLGetPrivateProfileString( driver, "Driver64", "", driver_lib, sizeof( driver_lib ), "ODBCINST.INI" ); if ( driver_lib[ 0 ] == '\0' ) { SQLGetPrivateProfileString( driver, "Driver", "", driver_lib, sizeof( driver_lib ), "ODBCINST.INI" ); } #else SQLGetPrivateProfileString( driver, "Driver", "", driver_lib, sizeof( driver_lib ), "ODBCINST.INI" ); #endif strcpy( driver_name, driver ); if ( driver_lib[ 0 ] == 0 ) { return NULL; } } strcpy( lib_name, driver_lib ); return lib_name; } static SQLSMALLINT sql_old_to_new(SQLSMALLINT type) { switch(type) { case SQL_TIME: type=SQL_TYPE_TIME; break; case SQL_DATE: type=SQL_TYPE_DATE; break; case SQL_TIMESTAMP: type=SQL_TYPE_TIMESTAMP; break; } return type; } static SQLSMALLINT sql_new_to_old(SQLSMALLINT type) { switch(type) { case SQL_TYPE_TIME: type=SQL_TIME; break; case SQL_TYPE_DATE: type=SQL_DATE; break; case SQL_TYPE_TIMESTAMP: type=SQL_TIMESTAMP; break; } return type; } static SQLSMALLINT c_old_to_new(SQLSMALLINT type) { switch(type) { case SQL_C_TIME: type=SQL_C_TYPE_TIME; break; case SQL_C_DATE: type=SQL_C_TYPE_DATE; break; case SQL_C_TIMESTAMP: type=SQL_C_TYPE_TIMESTAMP; break; } return type; } static SQLSMALLINT c_new_to_old(SQLSMALLINT type) { switch(type) { case SQL_C_TYPE_TIME: type=SQL_C_TIME; break; case SQL_C_TYPE_DATE: type=SQL_C_DATE; break; case SQL_C_TYPE_TIMESTAMP: type=SQL_C_TIMESTAMP; break; } return type; } SQLSMALLINT __map_type(int map, DMHDBC connection, SQLSMALLINT type) { int driver_ver=connection->driver_act_ver; int wanted_ver=connection->environment->requested_version; if(driver_ver==SQL_OV_ODBC2 && wanted_ver>=SQL_OV_ODBC3) { switch(map) { case MAP_SQL_DM2D: type=sql_new_to_old(type); break; case MAP_SQL_D2DM: type=sql_old_to_new(type); break; case MAP_C_DM2D: type=c_new_to_old(type); break; case MAP_C_D2DM: type=c_old_to_new(type); break; } } else if(driver_ver>=SQL_OV_ODBC3 && wanted_ver==SQL_OV_ODBC2) { switch(map) { case MAP_SQL_DM2D: type=sql_old_to_new(type); break; case MAP_SQL_D2DM: type=sql_new_to_old(type); break; case MAP_C_DM2D: type=c_old_to_new(type); break; case MAP_C_D2DM: type=c_new_to_old(type); break; } } else if(driver_ver>=SQL_OV_ODBC3 && wanted_ver>=SQL_OV_ODBC3) { switch(map) { case MAP_SQL_DM2D: case MAP_SQL_D2DM: type=sql_old_to_new(type); break; case MAP_C_DM2D: case MAP_C_D2DM: type=c_old_to_new(type); break; } } else if(driver_ver==SQL_OV_ODBC2 && wanted_ver==SQL_OV_ODBC2) { switch(map) { case MAP_SQL_DM2D: case MAP_SQL_D2DM: type=sql_new_to_old(type); break; case MAP_C_DM2D: case MAP_C_D2DM: type=c_new_to_old(type); break; } } return type; } unixODBC-2.3.12/DriverManager/__handles.c000066400000000000000000001311341446441710500200310ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: __handles.c,v 1.13 2009/05/15 15:23:56 lurcher Exp $ * * $Log: __handles.c,v $ * Revision 1.13 2009/05/15 15:23:56 lurcher * Fix pooled connection thread problems * * Revision 1.12 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.11 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.10 2007/02/28 15:37:49 lurcher * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg * * Revision 1.9 2006/05/31 17:35:34 lurcher * Add unicode ODBCINST entry points * * Revision 1.8 2004/09/28 08:44:46 lurcher * Fix memory leak in pthread descriptor code * * Revision 1.7 2004/07/24 17:55:37 lurcher * Sync up CVS * * Revision 1.6 2003/06/04 12:49:45 lurcher * * Further PID logging tweeks * * Revision 1.5 2003/06/02 16:51:36 lurcher * * Add TracePid option * * Revision 1.4 2002/08/12 16:20:44 lurcher * * Make it try and find a working iconv set of encodings * * Revision 1.3 2002/08/12 13:17:52 lurcher * * Replicate the way the MS DM handles loading of driver libs, and allocating * handles in the driver. usage counting in the driver means that dlopen is * only called for the first use, and dlclose for the last. AllocHandle for * the driver environment is only called for the first time per driver * per application environment. * * Revision 1.2 2002/02/22 10:23:22 lurcher * * s/Trace File/TraceFile * * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher * * First upload to SourceForge * * Revision 1.14 2001/06/25 12:55:15 nick * * Fix threading problem with multiple ENV's * * Revision 1.13 2001/06/04 15:24:49 nick * * Add port to MAC OSX and QT3 changes * * Revision 1.12 2001/05/15 13:33:44 jason * * Wrapped calls to stats with COLLECT_STATS * * Revision 1.11 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.10 2001/03/02 14:24:23 nick * * Fix thread detection for Solaris * * Revision 1.9 2001/01/04 13:16:25 nick * * Add support for GNU portable threads and tidy up some UNICODE compile * warnings * * Revision 1.8 2000/12/18 11:51:59 martin * * stats specific mode to uodbc_open_stats. * * Revision 1.7 2000/12/18 11:03:58 martin * * Add support for the collection and retrieval of handle statistics. * * Revision 1.6 2000/12/17 11:17:22 nick * * Remove typo * * Revision 1.5 2000/12/17 11:00:32 nick * * Add thread safe bits to pooling * * Revision 1.4 2000/11/29 17:53:59 nick * * Fix race condition * * Revision 1.3 2000/10/25 09:39:42 nick * * Clear handles out, to avoid reuse * * Revision 1.2 2000/09/08 08:58:17 nick * * Add SQL_DRIVER_HDESC to SQLGetinfo * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.16 2000/06/29 17:27:52 ngorham * * Add fast validate option * * Revision 1.15 2000/06/27 17:34:12 ngorham * * Fix a problem when the second part of the connect failed a seg fault * was generated in the error reporting * * Revision 1.14 2001/03/28 23:09:57 ngorham * * Fix logging * * Revision 1.13 2000/03/11 15:55:47 ngorham * * A few more changes and bug fixes (see NEWS) * * Revision 1.12 2000/02/25 00:02:00 ngorham * * Add a patch to support IBM DB2, and Solaris threads * * Revision 1.11 2000/02/22 22:14:45 ngorham * * Added support for solaris threads * Added check to overcome bug in PHP4 * Fixed bug in descriptors and ODBC 3 drivers * * Revision 1.10 1999/12/11 13:01:57 ngorham * * Add some fixes to the Postgres driver for long types * * Revision 1.9 1999/12/01 09:20:07 ngorham * * Fix some threading problems * * Revision 1.8 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.7 1999/11/10 03:51:34 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.6 1999/08/05 18:59:49 ngorham * * Typo error found by Greg Bentz * * Revision 1.5 1999/08/03 21:47:39 shandyb * Moving to automake: changed files in DriverManager * * Revision 1.4 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/30 23:56:56 ngorham * * Add initial thread safety code * * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb * first go at it * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * Revision 1.3 1999/05/09 23:27:11 nick * All the API done now * * Revision 1.2 1999/05/03 19:50:43 nick * Another check point * * Revision 1.1 1999/04/25 23:06:11 nick * Initial revision * * **********************************************************************/ #include #include #include "drivermanager.h" #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) #include "__stats.h" #include #endif static char const rcsid[]= "$RCSfile: __handles.c,v $ $Revision: 1.13 $"; /* * these are used to enable us to check if a handle is * valid without the danger of a seg-vio. */ static DMHENV environment_root; static DMHDBC connection_root; static DMHSTMT statement_root; static DMHDESC descriptor_root; /* * use just one mutex for all the lists, this avoids any issues * with deadlocks, the performance issue should be minimal, if it * turns out to be a problem, we can readdress this * * We also have a mutex to protect the connection pooling code * * If compiled with thread support the DM allows four different * thread strategies: * * Level 0 - Only the DM internal structures are protected. * The driver is assumed to take care of itself * * Level 1 - The driver is protected down to the statement level. * Each statement will be protected, and the same for the connect * level for connect functions. Note that descriptors are considered * equal to statements when it comes to thread protection. * * Level 2 - The driver is protected at the connection level. Only * one thread can be in a particular driver at one time. * * Level 3 - The driver is protected at the env level, only one thing * at a time. * * By default the driver opens connections with lock level 0; drivers * are expected to be thread safe now. This can be changed by adding * the line * * Threading = N * * to the driver entry in odbcinst.ini, where N is the locking level * (0-3) * */ #ifdef HAVE_LIBPTH #include static pth_mutex_t mutex_lists = PTH_MUTEX_INIT; static pth_mutex_t mutex_env = PTH_MUTEX_INIT; static pth_mutex_t mutex_pool = PTH_MUTEX_INIT; static pth_mutex_t mutex_iconv = PTH_MUTEX_INIT; static int pth_init_called = 0; static pth_cond_t cond_pool = PTH_COND_INIT; static int local_mutex_entry( pth_mutex_t *mutex ) { if ( !pth_init_called ) { pth_init(); pth_init_called = 1; } return pth_mutex_acquire( mutex, 0, NULL ); } static int local_mutex_exit( pth_mutex_t *mutex ) { return pth_mutex_release( mutex ); } static int local_cond_timedwait( pth_cond_t *cond, pth_mutex_t *mutex, struct timespec *until ) { /* NOTE: timedwait is not present in PTH */ return pth_cond_await( cond, mutex, 0 ); } static void local_cond_signal( pth_cond_t *cond ) { pth_cond_notify( cond, 0 ); } #elif HAVE_LIBPTHREAD #include static pthread_mutex_t mutex_lists = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t mutex_env = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t mutex_pool = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t mutex_iconv = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t cond_pool = PTHREAD_COND_INITIALIZER; static int local_mutex_entry( pthread_mutex_t *mutex ) { return pthread_mutex_lock( mutex ); } static int local_mutex_exit( pthread_mutex_t *mutex ) { return pthread_mutex_unlock( mutex ); } static int local_cond_timedwait( pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *until ) { return pthread_cond_timedwait( cond, mutex, until ); } static void local_cond_signal( pthread_cond_t *cond ) { pthread_cond_signal( cond ); } #elif HAVE_LIBTHREAD #include static mutex_t mutex_lists; static mutex_t mutex_env; static mutex_t mutex_pool; static mutex_t mutex_iconv; static cond_t cond_pool; static int local_mutex_entry( mutex_t *mutex ) { return mutex_lock( mutex ); } static int local_mutex_exit( mutex_t *mutex ) { return mutex_unlock( mutex ); } static int local_cond_timedwait( cond_t *cond, mutex_t *mutex, struct timespec *until ) { return cond_timedwait( cond, mutex, until ); } static void local_cond_signal( cond_t *cond ) { cond_signal( cond ); } #else #define local_mutex_entry(x) #define local_mutex_exit(x) #define local_cond_timedwait(x,y,z) 0 #define local_cond_signal(x) #endif /* * protection for connection pooling */ void mutex_pool_entry( void ) { local_mutex_entry( &mutex_pool ); } void mutex_pool_exit( void ) { local_mutex_exit( &mutex_pool ); } /* * protection for iconv */ void mutex_iconv_entry( void ) { local_mutex_entry( &mutex_iconv ); } void mutex_iconv_exit( void ) { local_mutex_exit( &mutex_iconv ); } /* * protection for lib loading and counting, reuse the lists mutex as this * is the lowest level protection the DM uses */ void mutex_lib_entry( void ) { local_mutex_entry( &mutex_lists ); } void mutex_lib_exit( void ) { local_mutex_exit( &mutex_lists ); } static DMHENV __locked_alloc_env() { DMHENV environment; environment = calloc( sizeof( *environment ), 1 ); if ( environment ) { char tracing_string[ 64 ]; char tracing_file[ 64 ]; #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) if (uodbc_open_stats(&environment->sh, UODBC_STATS_WRITE) != 0) { ; } uodbc_update_stats(environment->sh, UODBC_STATS_TYPE_HENV, (void *)1); #endif /* * add to list of env handles */ environment -> next_class_list = environment_root; environment_root = environment; environment -> type = HENV_MAGIC; SQLGetPrivateProfileString( "ODBC", "Trace", "No", tracing_string, sizeof( tracing_string ), "odbcinst.ini" ); if ( tracing_string[ 0 ] == '1' || toupper( tracing_string[ 0 ] ) == 'Y' || ( toupper( tracing_string[ 0 ] ) == 'O' && toupper( tracing_string[ 1 ] ) == 'N' )) { SQLGetPrivateProfileString( "ODBC", "TraceFile", "/tmp/sql.log", tracing_file, sizeof( tracing_file ), "odbcinst.ini" ); /* * start logging */ SQLGetPrivateProfileString( "ODBC", "TracePid", "No", tracing_string, sizeof( tracing_string ), "odbcinst.ini" ); if ( tracing_string[ 0 ] == '1' || toupper( tracing_string[ 0 ] ) == 'Y' || ( toupper( tracing_string[ 0 ] ) == 'O' && toupper( tracing_string[ 1 ] ) == 'N' )) { dm_log_open( "ODBC", tracing_file, 1 ); } else { dm_log_open( "ODBC", tracing_file, 0 ); } sprintf( environment -> msg, "\n\t\tExit:[SQL_SUCCESS]\n\t\t\tEnvironment = %p", environment ); dm_log_write( __FILE__, __LINE__, LOG_INFO, LOG_INFO, environment -> msg ); } setup_error_head( &environment -> error, environment, SQL_HANDLE_ENV ); } return environment; } static DMHENV shared_environment; DMHENV __share_env( int *first ) { DMHENV environment; local_mutex_entry( &mutex_lists ); if ( shared_environment ) { *first = 0; environment = shared_environment; } else { environment = __locked_alloc_env(); *first = 1; shared_environment = environment; } local_mutex_exit( &mutex_lists ); return environment; } /* * allocate and register a environment handle */ DMHENV __alloc_env( void ) { DMHENV environment = NULL; local_mutex_entry( &mutex_lists ); environment = __locked_alloc_env(); local_mutex_exit( &mutex_lists ); return environment; } /* * check that a env is real */ int __validate_env_mark_released( DMHENV env ) { if ( shared_environment && env == shared_environment ) { return 1; } #ifdef FAST_HANDLE_VALIDATE if ( env && *(( int * ) env ) == HENV_MAGIC ) return 1; else return 0; #else DMHENV ptr; int ret = 0; local_mutex_entry( &mutex_lists ); ptr = environment_root; while( ptr ) { if ( ptr == env ) { ret = 1; env -> released = 1; break; } ptr = ptr -> next_class_list; } local_mutex_exit( &mutex_lists ); return ret; #endif } int __validate_env( DMHENV env ) { if ( shared_environment && env == shared_environment ) { return 1; } #ifdef FAST_HANDLE_VALIDATE if ( env && *(( int * ) env ) == HENV_MAGIC ) return 1; else return 0; #else DMHENV ptr; int ret = 0; local_mutex_entry( &mutex_lists ); ptr = environment_root; while( ptr ) { if ( ptr == env ) { if ( env -> released ) { fprintf( stderr, "unixODBC: API Error, env handle used after being free\n" ); ret = 0; } else { ret = 1; } break; } ptr = ptr -> next_class_list; } local_mutex_exit( &mutex_lists ); return ret; #endif } /* * remove from list */ void __release_env( DMHENV environment ) { DMHENV last = NULL; DMHENV ptr; if ( shared_environment && environment == shared_environment ) { return; } local_mutex_entry( &mutex_lists ); ptr = environment_root; while( ptr ) { if ( environment == ptr ) { break; } last = ptr; ptr = ptr -> next_class_list; } if ( ptr ) { if ( last ) { last -> next_class_list = ptr -> next_class_list; } else { environment_root = ptr -> next_class_list; } } clear_error_head( &environment -> error ); /* * free log */ dm_log_close(); #if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H ) if (environment->sh) uodbc_close_stats(environment->sh); #endif /* * clear just to make sure */ memset( environment, 0, sizeof( *environment )); free( environment ); local_mutex_exit( &mutex_lists ); } /* * get the root, for use in SQLEndTran and SQLTransact */ DMHDBC __get_dbc_root( void ) { return connection_root; } /* * allocate and register a connection handle */ DMHDBC __alloc_dbc( void ) { DMHDBC connection = NULL; local_mutex_entry( &mutex_lists ); connection = calloc( sizeof( *connection ), 1 ); if ( connection ) { /* * add to list of connection handles */ connection -> next_class_list = connection_root; connection_root = connection; connection -> type = HDBC_MAGIC; setup_error_head( &connection -> error, connection, SQL_HANDLE_DBC ); #ifdef HAVE_LIBPTH pth_mutex_init( &connection -> mutex ); /* * for the moment protect at the environment level */ connection -> protection_level = TS_LEVEL3; #elif HAVE_LIBPTHREAD pthread_mutex_init( &connection -> mutex, NULL ); /* * for the moment protect at the environment level */ connection -> protection_level = TS_LEVEL3; #elif HAVE_LIBTHREAD mutex_init( &connection -> mutex, USYNC_THREAD, NULL ); connection -> protection_level = TS_LEVEL3; #endif #ifdef HAVE_ICONV connection -> iconv_cd_uc_to_ascii = (iconv_t)(-1); connection -> iconv_cd_ascii_to_uc = (iconv_t)(-1); #endif } local_mutex_exit( &mutex_lists ); return connection; } /* * adjust the threading level */ void dbc_change_thread_support( DMHDBC connection, int level ) { #if defined ( HAVE_LIBPTHREAD ) || defined( HAVE_LIBTHREAD ) || defined( HAVE_LIBPTH ) int old_level; if ( connection -> protection_level == level ) return; old_level = connection -> protection_level; connection -> protection_level = level; if ( level == TS_LEVEL3 ) { /* * if we are moving from level 3 we may have to release the existing * connection lock, and create the env lock */ if(old_level != TS_LEVEL0) local_mutex_exit( &connection -> mutex ); local_mutex_entry( &mutex_env ); } else if ( old_level == TS_LEVEL3 ) { /* * if we are moving from level 3 we may have to create the new * connection lock, and remove the env lock */ if(level != TS_LEVEL0) local_mutex_entry( &connection -> mutex ); local_mutex_exit( &mutex_env ); } #endif } /* * check that a connection is real */ int __validate_dbc( DMHDBC connection ) { #ifdef FAST_HANDLE_VALIDATE if ( connection && *(( int * ) connection ) == HDBC_MAGIC ) return 1; else return 0; #else DMHDBC ptr; int ret = 0; local_mutex_entry( &mutex_lists ); ptr = connection_root; while( ptr ) { if ( ptr == connection ) { ret = 1; break; } ptr = ptr -> next_class_list; } local_mutex_exit( &mutex_lists ); return ret; #endif } /* * remove from list */ void __release_dbc( DMHDBC connection ) { DMHDBC last = NULL; DMHDBC ptr; local_mutex_entry( &mutex_lists ); ptr = connection_root; while( ptr ) { if ( connection == ptr ) { break; } last = ptr; ptr = ptr -> next_class_list; } if ( ptr ) { if ( last ) { last -> next_class_list = ptr -> next_class_list; } else { connection_root = ptr -> next_class_list; } } clear_error_head( &connection -> error ); /* * shutdown unicode */ unicode_shutdown( connection ); #ifdef HAVE_LIBPTH #elif HAVE_LIBPTHREAD pthread_mutex_destroy( &connection -> mutex ); #elif HAVE_LIBTHREAD mutex_destroy( &connection -> mutex ); #endif if ( connection -> save_attr ) { struct save_attr *sa = connection -> save_attr; while ( sa ) { struct save_attr *nsa = sa -> next; free( sa -> str_attr ); free( sa ); sa = nsa; } } if ( connection -> _driver_connect_string ) { free( connection -> _driver_connect_string ); } /* * clear just to make sure */ memset( connection, 0, sizeof( *connection )); free( connection ); local_mutex_exit( &mutex_lists ); } /* * allocate and register a statement handle */ DMHSTMT __alloc_stmt( void ) { DMHSTMT statement = NULL; local_mutex_entry( &mutex_lists ); statement = calloc( sizeof( *statement ), 1 ); if ( statement ) { /* * add to list of statement handles */ statement -> next_class_list = statement_root; #ifdef FAST_HANDLE_VALIDATE if ( statement_root ) { statement_root -> prev_class_list = statement; } #endif statement_root = statement; statement -> type = HSTMT_MAGIC; setup_error_head( &statement -> error, statement, SQL_HANDLE_STMT ); #ifdef HAVE_LIBPTH pth_mutex_init( &statement -> mutex ); #elif HAVE_LIBPTHREAD pthread_mutex_init( &statement -> mutex, NULL ); #elif HAVE_LIBTHREAD mutex_init( &statement -> mutex, USYNC_THREAD, NULL ); #endif } local_mutex_exit( &mutex_lists ); return statement; } /* * assigns a statements to the connection */ void __register_stmt ( DMHDBC connection, DMHSTMT statement ) { local_mutex_entry( &mutex_lists ); connection -> statement_count ++; statement -> connection = connection; #ifdef FAST_HANDLE_VALIDATE statement -> next_conn_list = connection -> statements; connection -> statements = statement; #endif local_mutex_exit( &mutex_lists ); } /* * Sets statement state after commit or rollback transaction */ void __set_stmt_state ( DMHDBC connection, SQLSMALLINT cb_value ) { DMHSTMT statement; SQLINTEGER stmt_remaining; local_mutex_entry( &mutex_lists ); #ifdef FAST_HANDLE_VALIDATE statement = connection -> statements; while ( statement ) { if ( (statement -> state == STATE_S2 || statement -> state == STATE_S3) && cb_value == SQL_CB_DELETE ) { statement -> state = STATE_S1; statement -> prepared = 0; } else if ( statement -> state == STATE_S4 || statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) { if( !statement -> prepared && (cb_value == SQL_CB_DELETE || cb_value == SQL_CB_CLOSE) ) { statement -> state = STATE_S1; } else if( statement -> prepared ) { if( cb_value == SQL_CB_DELETE ) { statement -> state = STATE_S1; statement -> prepared = 0; } else if( cb_value == SQL_CB_CLOSE ) { if ( statement -> state == STATE_S4 ) statement -> state = STATE_S2; else statement -> state = STATE_S3; } } } statement = statement -> next_conn_list; } #else statement = statement_root; stmt_remaining = connection -> statement_count; while ( statement && stmt_remaining > 0 ) { if ( statement -> connection == connection ) { if ( (statement -> state == STATE_S2 || statement -> state == STATE_S3) && cb_value == SQL_CB_DELETE ) { statement -> state = STATE_S1; statement -> prepared = 0; } else if ( statement -> state == STATE_S4 || statement -> state == STATE_S5 || statement -> state == STATE_S6 || statement -> state == STATE_S7 ) { if( !statement -> prepared && (cb_value == SQL_CB_DELETE || cb_value == SQL_CB_CLOSE) ) { statement -> state = STATE_S1; } else if( statement -> prepared ) { if( cb_value == SQL_CB_DELETE ) { statement -> state = STATE_S1; statement -> prepared = 0; } else if( cb_value == SQL_CB_CLOSE ) { if ( statement -> state == STATE_S4 ) statement -> state = STATE_S2; else statement -> state = STATE_S3; } } } stmt_remaining --; } statement = statement -> next_class_list; } #endif local_mutex_exit( &mutex_lists ); } /* * clear all statements on a DBC */ int __clean_stmt_from_dbc( DMHDBC connection ) { DMHSTMT ptr, last; int ret = 0; local_mutex_entry( &mutex_lists ); #ifdef FAST_HANDLE_VALIDATE while ( connection -> statements ) { ptr = connection -> statements; last = connection -> statements -> prev_class_list; connection -> statements = ptr -> next_conn_list; if ( last ) { last -> next_class_list = ptr -> next_class_list; if ( last -> next_class_list ) { last -> next_class_list -> prev_class_list = last; } } else { statement_root = ptr -> next_class_list; if ( statement_root ) { statement_root -> prev_class_list = NULL; } } clear_error_head( &ptr -> error ); #ifdef HAVE_LIBPTH #elif HAVE_LIBPTHREAD pthread_mutex_destroy( &ptr -> mutex ); #elif HAVE_LIBTHREAD mutex_destroy( &ptr -> mutex ); #endif free( ptr ); } #else last = NULL; ptr = statement_root; while( ptr ) { if ( ptr -> connection == connection ) { if ( last ) { last -> next_class_list = ptr -> next_class_list; } else { statement_root = ptr -> next_class_list; } clear_error_head( &ptr -> error ); #ifdef HAVE_LIBPTH #elif HAVE_LIBPTHREAD pthread_mutex_destroy( &ptr -> mutex ); #elif HAVE_LIBTHREAD mutex_destroy( &ptr -> mutex ); #endif free( ptr ); /* * go back to the start */ last = NULL; ptr = statement_root; } else { last = ptr; ptr = ptr -> next_class_list; } } #endif local_mutex_exit( &mutex_lists ); return ret; } int __check_stmt_from_dbc_v( DMHDBC connection, int statecount, ... ) { va_list ap; int states[ MAX_STATE_ARGS ]; DMHSTMT ptr; int found = 0; int i; va_start (ap, statecount); for ( i = 0; i < statecount; i ++ ) { states[ i ] = va_arg (ap, int ); } va_end (ap); local_mutex_entry( &mutex_lists ); #ifdef FAST_HANDLE_VALIDATE ptr = connection -> statements; while( !found && ptr ) { for ( i = 0; i < statecount; i ++ ) { if ( ptr -> state == states[ i ] ) { found = 1; break; } } ptr = ptr -> next_conn_list; } #else ptr = statement_root; while( !found && ptr ) { if ( ptr -> connection == connection ) { for ( i = 0; i < statecount; i ++ ) { if ( ptr -> state == states[ i ] ) { found = 1; break; } } } ptr = ptr -> next_class_list; } #endif local_mutex_exit( &mutex_lists ); return found; } /* * check if any statements on this connection are in a given state */ int __check_stmt_from_dbc( DMHDBC connection, int state ) { DMHSTMT ptr; int found = 0; local_mutex_entry( &mutex_lists ); #ifdef FAST_HANDLE_VALIDATE ptr = connection -> statements; while( ptr ) { if ( ptr -> state == state ) { found = 1; break; } ptr = ptr -> next_conn_list; } #else ptr = statement_root; while( ptr ) { if ( ptr -> connection == connection ) { if ( ptr -> state == state ) { found = 1; break; } } ptr = ptr -> next_class_list; } #endif local_mutex_exit( &mutex_lists ); return found; } int __check_stmt_from_desc( DMHDESC desc, int state ) { DMHDBC connection; DMHSTMT ptr; int found = 0; local_mutex_entry( &mutex_lists ); connection = desc -> connection; #ifdef FAST_HANDLE_VALIDATE ptr = connection -> statements; while( ptr ) { if ( ptr -> ipd == desc || ptr -> ird == desc || ptr -> apd == desc || ptr -> ard == desc ) { if ( ptr -> state == state ) { found = 1; break; } } ptr = ptr -> next_conn_list; } #else ptr = statement_root; while( ptr ) { if ( ptr -> connection == connection ) { if ( ptr -> ipd == desc || ptr -> ird == desc || ptr -> apd == desc || ptr -> ard == desc ) { if ( ptr -> state == state ) { found = 1; break; } } } ptr = ptr -> next_class_list; } #endif local_mutex_exit( &mutex_lists ); return found; } int __check_stmt_from_desc_ird( DMHDESC desc, int state ) { DMHDBC connection; DMHSTMT ptr; int found = 0; local_mutex_entry( &mutex_lists ); connection = desc -> connection; #ifdef FAST_HANDLE_VALIDATE ptr = connection -> statements; while( ptr ) { if ( ptr -> ird == desc ) { if ( ptr -> state == state ) { found = 1; break; } } ptr = ptr -> next_conn_list; } #else ptr = statement_root; while( ptr ) { if ( ptr -> connection == connection ) { if ( ptr -> ird == desc ) { if ( ptr -> state == state ) { found = 1; break; } } } ptr = ptr -> next_class_list; } #endif local_mutex_exit( &mutex_lists ); return found; } /* * check any statements that are associated with a descriptor */ /* * check that a statement is real */ int __validate_stmt( DMHSTMT statement ) { #ifdef FAST_HANDLE_VALIDATE if ( statement && *(( int * ) statement ) == HSTMT_MAGIC ) return 1; else return 0; #else DMHSTMT ptr; int ret = 0; local_mutex_entry( &mutex_lists ); ptr = statement_root; while( ptr ) { if ( ptr == statement ) { ret = 1; break; } ptr = ptr -> next_class_list; } local_mutex_exit( &mutex_lists ); return ret; #endif } /* * remove from list */ void __release_stmt( DMHSTMT statement ) { DMHSTMT last = NULL; DMHSTMT ptr; local_mutex_entry( &mutex_lists ); #ifdef FAST_HANDLE_VALIDATE /* * A check never mind */ if ( statement && ( *(( int * ) statement ) == HSTMT_MAGIC )) { ptr = statement; last = statement->prev_class_list; if ( statement -> connection ) { DMHDBC connection = statement -> connection; DMHSTMT conn_last = NULL; DMHSTMT conn_ptr = connection -> statements; while ( conn_ptr ) { if ( statement == conn_ptr ) { break; } conn_last = conn_ptr; conn_ptr = conn_ptr -> next_conn_list; } if ( conn_ptr ) { if ( conn_last ) { conn_last -> next_conn_list = conn_ptr -> next_conn_list; } else { connection -> statements = conn_ptr -> next_conn_list; } } } } else { ptr = NULL; last = NULL; } #else ptr = statement_root; while( ptr ) { if ( statement == ptr ) { break; } last = ptr; ptr = ptr -> next_class_list; } #endif if ( ptr ) { if ( last ) { last -> next_class_list = ptr -> next_class_list; #ifdef FAST_HANDLE_VALIDATE if ( last -> next_class_list ) { last -> next_class_list -> prev_class_list = last; } #endif } else { statement_root = ptr -> next_class_list; #ifdef FAST_HANDLE_VALIDATE if ( statement_root ) { statement_root -> prev_class_list = NULL; } #endif } } clear_error_head( &statement -> error ); #ifdef HAVE_LIBPTH #elif HAVE_LIBPTHREAD pthread_mutex_destroy( &statement -> mutex ); #elif HAVE_LIBTHREAD mutex_destroy( &statement -> mutex ); #endif /* * clear just to make sure */ memset( statement, 0, sizeof( *statement )); free( statement ); local_mutex_exit( &mutex_lists ); } /* * allocate and register a descriptor handle */ DMHDESC __alloc_desc( void ) { DMHDESC descriptor; local_mutex_entry( &mutex_lists ); descriptor = calloc( sizeof( *descriptor ), 1 ); if ( descriptor ) { /* * add to list of descriptor handles */ descriptor -> next_class_list = descriptor_root; #ifdef FAST_HANDLE_VALIDATE if ( descriptor_root ) { descriptor_root -> prev_class_list = descriptor; } #endif descriptor_root = descriptor; descriptor -> type = HDESC_MAGIC; setup_error_head( &descriptor -> error, descriptor, SQL_HANDLE_DESC ); #ifdef HAVE_LIBPTH pth_mutex_init( &descriptor -> mutex ); #elif HAVE_LIBPTHREAD pthread_mutex_init( &descriptor -> mutex, NULL ); #elif HAVE_LIBTHREAD mutex_init( &descriptor -> mutex, USYNC_THREAD, NULL ); #endif } local_mutex_exit( &mutex_lists ); return descriptor; } /* * check that a descriptor is real */ int __validate_desc( DMHDESC descriptor ) { #ifdef FAST_HANDLE_VALIDATE if ( descriptor && *(( int * ) descriptor ) == HDESC_MAGIC ) return 1; else return 0; #else DMHDESC ptr; int ret = 0; local_mutex_entry( &mutex_lists ); ptr = descriptor_root; while( ptr ) { if ( ptr == descriptor ) { ret = 1; break; } ptr = ptr -> next_class_list; } local_mutex_exit( &mutex_lists ); return ret; #endif } /* * clear all descriptors on a DBC */ int __clean_desc_from_dbc( DMHDBC connection ) { DMHDESC ptr, last; int ret = 0; local_mutex_entry( &mutex_lists ); last = NULL; ptr = descriptor_root; while( ptr ) { if ( ptr -> connection == connection ) { if ( last ) { last -> next_class_list = ptr -> next_class_list; #ifdef FAST_HANDLE_VALIDATE if ( last -> next_class_list ) { last -> next_class_list -> prev_class_list = last; } #endif } else { descriptor_root = ptr -> next_class_list; #ifdef FAST_HANDLE_VALIDATE if ( descriptor_root ) { descriptor_root -> prev_class_list = NULL; } #endif } clear_error_head( &ptr -> error ); #ifdef HAVE_LIBPTH #elif HAVE_LIBPTHREAD pthread_mutex_destroy( &ptr -> mutex ); #elif HAVE_LIBTHREAD mutex_destroy( &ptr -> mutex ); #endif free( ptr ); /* * go back to the start */ last = NULL; ptr = descriptor_root; } else { last = ptr; ptr = ptr -> next_class_list; } } local_mutex_exit( &mutex_lists ); return ret; } /* * remove from list */ void __release_desc( DMHDESC descriptor ) { DMHDESC last = NULL; DMHDESC ptr; DMHSTMT assoc_stmt; local_mutex_entry( &mutex_lists ); #ifdef FAST_HANDLE_VALIDATE /* * A check never mind */ if ( descriptor && ( *(( int * ) descriptor ) == HDESC_MAGIC )) { ptr = descriptor; last = descriptor->prev_class_list; } else { ptr = NULL; last = NULL; } #else ptr = descriptor_root; while( ptr ) { if ( descriptor == ptr ) { break; } last = ptr; ptr = ptr -> next_class_list; } #endif if ( ptr ) { if ( last ) { last -> next_class_list = ptr -> next_class_list; #ifdef FAST_HANDLE_VALIDATE if ( last -> next_class_list ) { last -> next_class_list -> prev_class_list = last; } #endif } else { descriptor_root = ptr -> next_class_list; #ifdef FAST_HANDLE_VALIDATE if ( descriptor_root ) { descriptor_root -> prev_class_list = NULL; } #endif } } clear_error_head( &descriptor -> error ); /* If there are any statements still pointing to this descriptor, revert them to implicit */ assoc_stmt = statement_root; while ( assoc_stmt ) { DMHDESC *pDesc[] = { &assoc_stmt -> ipd, &assoc_stmt -> apd, &assoc_stmt -> ird, &assoc_stmt -> ard }; DMHDESC impDesc[] = { assoc_stmt -> implicit_ipd, assoc_stmt -> implicit_apd, assoc_stmt -> implicit_ird, assoc_stmt -> implicit_ard }; int i; for ( i = 0; i < 4; i++ ) { if ( *pDesc[i] == descriptor ) { *pDesc[i] = impDesc[i]; } } assoc_stmt = assoc_stmt -> next_class_list; } #ifdef HAVE_LIBPTH #elif HAVE_LIBPTHREAD pthread_mutex_destroy( &descriptor -> mutex ); #elif HAVE_LIBTHREAD mutex_destroy( &descriptor -> mutex ); #endif /* * clear just to make sure */ memset( descriptor, 0, sizeof( *descriptor )); free( descriptor ); local_mutex_exit( &mutex_lists ); } #if defined ( HAVE_LIBPTHREAD ) || defined ( HAVE_LIBTHREAD ) || defined( HAVE_LIBPTH ) void thread_protect( int type, void *handle ) { DMHDBC connection; DMHSTMT statement; DMHDESC descriptor; switch( type ) { case SQL_HANDLE_ENV: local_mutex_entry( &mutex_env ); break; case SQL_HANDLE_DBC: connection = handle; if ( connection -> protection_level == TS_LEVEL3 ) { local_mutex_entry( &mutex_env ); } else if ( connection -> protection_level == TS_LEVEL2 || connection -> protection_level == TS_LEVEL1 ) { local_mutex_entry( &connection -> mutex ); } break; case SQL_HANDLE_STMT: statement = handle; if ( statement -> connection -> protection_level == TS_LEVEL3 ) { local_mutex_entry( &mutex_env ); } else if ( statement -> connection -> protection_level == TS_LEVEL2 ) { local_mutex_entry( &statement -> connection -> mutex ); } else if ( statement -> connection -> protection_level == TS_LEVEL1 ) { local_mutex_entry( &statement -> mutex ); } break; case SQL_HANDLE_DESC: descriptor = handle; if ( descriptor -> connection -> protection_level == TS_LEVEL3 ) { local_mutex_entry( &mutex_env ); } if ( descriptor -> connection -> protection_level == TS_LEVEL2 ) { local_mutex_entry( &descriptor -> connection -> mutex ); } if ( descriptor -> connection -> protection_level == TS_LEVEL1 ) { local_mutex_entry( &descriptor -> mutex ); } break; } } void thread_release( int type, void *handle ) { DMHDBC connection; DMHSTMT statement; DMHDESC descriptor; switch( type ) { case SQL_HANDLE_ENV: local_mutex_exit( &mutex_env ); break; case SQL_HANDLE_DBC: connection = handle; if ( connection -> protection_level == TS_LEVEL3 ) { local_mutex_exit( &mutex_env ); } else if ( connection -> protection_level == TS_LEVEL2 || connection -> protection_level == TS_LEVEL1 ) { local_mutex_exit( &connection -> mutex ); } break; case SQL_HANDLE_STMT: statement = handle; if ( statement -> connection -> protection_level == TS_LEVEL3 ) { local_mutex_exit( &mutex_env ); } else if ( statement -> connection -> protection_level == TS_LEVEL2 ) { local_mutex_exit( &statement -> connection -> mutex ); } else if ( statement -> connection -> protection_level == TS_LEVEL1 ) { local_mutex_exit( &statement -> mutex ); } break; case SQL_HANDLE_DESC: descriptor = handle; if ( descriptor -> connection -> protection_level == TS_LEVEL3 ) { local_mutex_exit( &mutex_env ); } else if ( descriptor -> connection -> protection_level == TS_LEVEL2 ) { local_mutex_exit( &descriptor -> connection -> mutex ); } else if ( descriptor -> connection -> protection_level == TS_LEVEL1 ) { local_mutex_exit( &descriptor -> mutex ); } break; } } /* * Waits on pool condition variable until signaled, or 1s timeout elapses. * * Will be called with mutexes locked according to threading level as follows: * * 0 - mutex_pool * 1,2 - connection->mutex mutex_pool * 3 - mutex_env mutex_pool * * Returns * nonzero on timeout * zero when signaled */ int pool_timedwait( DMHDBC connection ) { int ret; struct timespec waituntil; #ifdef HAVE_CLOCK_GETTIME clock_gettime( CLOCK_REALTIME, &waituntil ); waituntil.tv_sec ++; #else waituntil.tv_sec = time( NULL ); waituntil.tv_nsec = 0; waituntil.tv_sec ++; #endif switch ( connection -> protection_level ) { case TS_LEVEL3: mutex_pool_exit(); ret = local_cond_timedwait( &cond_pool, &mutex_env, &waituntil ); mutex_pool_entry(); break; case TS_LEVEL2: case TS_LEVEL1: mutex_pool_exit(); ret = local_cond_timedwait( &cond_pool, &connection -> mutex, &waituntil ); mutex_pool_entry(); break; case TS_LEVEL0: ret = local_cond_timedwait( &cond_pool, &mutex_pool, &waituntil ); break; } return ret; } void pool_signal() { local_cond_signal( &cond_pool ); } #endif #ifdef WITH_HANDLE_REDIRECT /* * try and find a handle that has the suplied handle as the driver handle * there will be threading issues with this, so be carefull. * However it will normally only get used with "broken" drivers. */ void *find_parent_handle( DRV_SQLHANDLE drv_hand, int type ) { void *found_handle = NULL; local_mutex_entry( &mutex_lists ); switch( type ) { case SQL_HANDLE_DBC: { DMHDBC hand = connection_root; while( hand ) { if ( hand -> driver_dbc == drv_hand ) { found_handle = hand; break; } hand = hand -> next_class_list; } } break; case SQL_HANDLE_STMT: { DMHSTMT hand = statement_root; while( hand ) { if ( hand -> driver_stmt == drv_hand ) { found_handle = hand; break; } hand = hand -> next_class_list; } } break; case SQL_HANDLE_DESC: { DMHDESC hand = descriptor_root; while( hand ) { if ( hand -> driver_desc == drv_hand ) { found_handle = hand; break; } hand = hand -> next_class_list; } } break; default: break; } local_mutex_exit( &mutex_lists ); return found_handle; } #endif unixODBC-2.3.12/DriverManager/__info.c000066400000000000000000004521611446441710500173540ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: __info.c,v 1.50 2009/02/18 17:59:08 lurcher Exp $ * * $Log: __info.c,v $ * Revision 1.50 2009/02/18 17:59:08 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.49 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.48 2008/09/29 14:02:45 lurcher * Fix missing dlfcn group option * * Revision 1.47 2008/01/02 15:10:33 lurcher * Fix problems trying to use the cursor lib on a non select statement * * Revision 1.46 2007/11/26 11:37:23 lurcher * Sync up before tag * * Revision 1.45 2007/09/28 13:20:22 lurcher * Add timestamp to logging * * Revision 1.44 2007/04/02 10:50:19 lurcher * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 ) * * Revision 1.43 2007/03/05 09:49:24 lurcher * Get it to build on VMS again * * Revision 1.42 2006/11/27 14:08:34 lurcher * Sync up dirs * * Revision 1.41 2006/03/08 11:22:13 lurcher * Add check for valid C_TYPE * * Revision 1.40 2005/12/19 18:43:26 lurcher * Add new parts to contrib and alter how the errors are returned from the driver * * Revision 1.39 2005/11/08 09:37:10 lurcher * Allow the driver and application to have different length handles * * Revision 1.38 2005/02/07 11:46:45 lurcher * Add missing ODBC2 installer stubs * * Revision 1.37 2004/07/24 17:55:37 lurcher * Sync up CVS * * Revision 1.36 2004/05/17 08:25:00 lurcher * Update the way the libltso is used, and fix a problem with gODBCConfig * not closeing correctly. * * Revision 1.35 2004/03/30 13:20:11 lurcher * * * Fix problem with SQLCopyDesc * Add additional target for iconv * * Revision 1.34 2003/12/01 16:37:17 lurcher * * Fix a bug in SQLWritePrivateProfileString * * Revision 1.33 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.32 2003/09/08 15:34:29 lurcher * * A couple of small but perfectly formed fixes * * Revision 1.31 2003/07/21 11:12:59 lurcher * * Fix corruption in Postgre7.1 driver * Tidy up gODBCconfig * * Revision 1.30 2003/06/24 09:40:58 lurcher * * Extra UNICODE stuff * * Revision 1.29 2003/06/04 12:49:45 lurcher * * Further PID logging tweeks * * Revision 1.28 2003/06/03 13:52:13 lurcher * * Change the mode of PID logfiles to allow the process to change to another * user * * Revision 1.27 2003/06/02 16:51:36 lurcher * * Add TracePid option * * Revision 1.26 2003/02/25 13:28:31 lurcher * * Allow errors on the drivers AllocHandle to be reported * Fix a problem that caused errors to not be reported in the log * Remove a redundant line from the spec file * * Revision 1.25 2003/02/06 12:58:25 lurcher * * Fix a speeling problem :-) * * Revision 1.24 2002/12/05 17:44:31 lurcher * * Display unknown return values in return logging * * Revision 1.23 2002/11/11 17:10:20 lurcher * * VMS changes * * Revision 1.22 2002/11/06 16:08:01 lurcher * * Update missing * * Revision 1.21 2002/08/23 09:42:37 lurcher * * Fix some build warnings with casts, and a AIX linker mod, to include * deplib's on the link line, but not the libtool generated ones * * Revision 1.20 2002/08/20 12:41:07 lurcher * * Fix incorrect return state from SQLEndTran/SQLTransact * * Revision 1.19 2002/08/19 09:11:49 lurcher * * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state * * Revision 1.18 2002/08/15 08:10:33 lurcher * * Couple of small fixes from John L Miller * * Revision 1.17 2002/08/12 16:20:44 lurcher * * Make it try and find a working iconv set of encodings * * Revision 1.16 2002/08/12 13:17:52 lurcher * * Replicate the way the MS DM handles loading of driver libs, and allocating * handles in the driver. usage counting in the driver means that dlopen is * only called for the first use, and dlclose for the last. AllocHandle for * the driver environment is only called for the first time per driver * per application environment. * * Revision 1.15 2002/07/25 09:30:26 lurcher * * Additional unicode and iconv changes * * Revision 1.14 2002/07/24 08:49:52 lurcher * * Alter UNICODE support to use iconv for UNICODE-ANSI conversion * * Revision 1.13 2002/07/10 15:05:57 lurcher * * Alter the return code in the Postgres driver, for a warning, it should be * 01000 it was 00000 * Fix a problem in DriverManagerII with the postgres driver as the driver * doesn't return a propper list of schemas * Allow the delimiter to be set in isql to a hex/octal char not just a * printable one * * Revision 1.12 2002/07/08 16:37:35 lurcher * * Fix bug in unicode_to_ansi_copy * * Revision 1.11 2002/07/04 17:27:56 lurcher * * Small bug fixes * * Revision 1.9 2002/05/28 13:30:34 lurcher * * Tidy up for AIX * * Revision 1.8 2002/05/21 14:19:44 lurcher * * * Update libtool to escape from AIX build problem * * Add fix to avoid file handle limitations * * Add more UNICODE changes, it looks like it is native 16 representation * the old way can be reproduced by defining UCS16BE * * Add iusql, its just the same as isql but uses the wide functions * * Revision 1.7 2002/04/10 11:04:36 lurcher * * Fix endian issue with 4 byte unicode support * * Revision 1.6 2002/02/27 11:27:14 lurcher * * Fix bug in error reporting * * Revision 1.5 2002/01/21 18:00:51 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.4 2001/12/13 13:56:31 lurcher * * init a global for Peter * * Revision 1.3 2001/12/13 13:00:32 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.2 2001/11/15 18:38:21 lurcher * * Make the errors returned from SQLError reset after each API call * if the app is expecting ODBC 3 operation * * Revision 1.1.1.1 2001/10/17 16:40:09 lurcher * * First upload to SourceForge * * Revision 1.23 2001/09/27 17:05:48 nick * * Assorted fixes and tweeks * * Revision 1.22 2001/07/03 09:30:41 nick * * Add ability to alter size of displayed message in the log * * Revision 1.21 2001/07/02 17:09:37 nick * * Add some portability changes * * Revision 1.20 2001/06/20 17:25:32 pat * Correct msg1 length in 4 extract diag functions * * Revision 1.19 2001/06/20 08:19:25 nick * * Fix buffer overflow in error handling * * Revision 1.18 2001/04/23 13:58:43 nick * * Assorted tweeks to text driver to get it to work with StarOffice * * Revision 1.17 2001/04/20 16:57:25 nick * * Add extra mapping of data types * * Revision 1.16 2001/04/18 15:03:37 nick * * Fix problem when going to DB2 unicode driver * * Revision 1.15 2001/04/16 22:35:10 nick * * More tweeks to the AutoTest code * * Revision 1.14 2001/04/14 10:42:03 nick * * Extra work on the autotest feature of odbctest * * Revision 1.13 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.12 2001/04/03 16:34:12 nick * * Add support for strangly broken unicode drivers * * Revision 1.11 2001/01/09 23:15:18 nick * * More unicode error fixes * * Revision 1.10 2001/01/09 22:33:13 nick * * Stop passing NULL into SQLExtendedFetch * Further fixes to unicode to ansi conversions * * Revision 1.9 2001/01/09 11:03:32 nick * * Fixed overrun bug * * Revision 1.8 2001/01/06 15:00:12 nick * * Fix bug in SQLError introduced with UNICODE * * Revision 1.7 2000/12/31 20:30:54 nick * * Add UNICODE support * * Revision 1.6 2000/10/25 12:45:51 nick * * Add mapping for both ODBC 2 - 3 and ODBC 3 - 2 error states * * Revision 1.5 2000/10/25 12:32:41 nick * * The mapping was the wrong way around for errors, ODBC3 error are mapped * to ODBC 2 not the other way around * * Revision 1.4 2000/10/25 09:13:26 nick * * Remove some invalid ODBC2-ODBC3 error mappings * * Revision 1.3 2000/10/13 15:18:49 nick * * Change string length parameter from SQLINTEGER to SQLSMALLINT * * Revision 1.2 2000/09/19 13:13:13 nick * * Add display of returned error text in log file * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.28 2000/07/31 08:46:11 ngorham * * Avoid potential buffer overrun * * Revision 1.27 2000/06/23 16:11:38 ngorham * * Map ODBC 2 SQLSTATE values to ODBC 3 * * Revision 1.25 2000/06/21 11:07:36 ngorham * * Stop Errors from SQLAllocHandle being lost * * Revision 1.24 2000/06/20 12:44:01 ngorham * * Fix bug that caused a success with info message from SQLExecute or * SQLExecDirect to be lost if used with a ODBC 3 driver and the application * called SQLGetDiagRec * * Revision 1.23 2000/06/01 11:00:51 ngorham * * return errors from descriptor functions * * Revision 1.22 2001/05/31 23:24:20 ngorham * * Update timestamps * * Revision 1.21 2000/05/21 21:49:19 ngorham * * Assorted fixes * * Revision 1.20 2001/04/11 09:00:05 ngorham * * remove stray printf * * Revision 1.19 2001/04/01 00:06:50 ngorham * * Dont use stderr, if the log file fails to open. * * Revision 1.18 2000/03/14 07:45:35 ngorham * * Fix bug that discarded connection errors * * Revision 1.17 2000/01/18 17:24:50 ngorham * * Add missing [unixODBC] prefix in front of error messages. * * Revision 1.16 1999/12/14 19:02:25 ngorham * * Mask out the password fields in the logging * * Revision 1.15 1999/12/04 17:01:23 ngorham * * Remove C++ comments from the Postgres code * * Revision 1.14 1999/12/01 09:20:07 ngorham * * Fix some threading problems * * Revision 1.13 1999/11/17 21:08:58 ngorham * * Fix Bug with the ODBC 3 error handling * * Revision 1.12 1999/11/13 23:41:01 ngorham * * Alter the way DM logging works * Upgrade the Postgres driver to 6.4.6 * * Revision 1.11 1999/11/10 22:15:48 ngorham * * Fix some bugs with the DM and error reporting. * * Revision 1.10 1999/11/10 03:51:34 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.9 1999/10/24 23:54:19 ngorham * * First part of the changes to the error reporting * * Revision 1.8 1999/10/03 23:05:16 ngorham * * First public outing of the cursor lib * * Revision 1.7 1999/09/19 22:24:34 ngorham * * Added support for the cursor library * * Revision 1.6 1999/08/03 21:47:39 shandyb * Moving to automake: changed files in DriverManager * * Revision 1.5 1999/07/10 21:10:17 ngorham * * Adjust error sqlstate from driver manager, depending on requested * version (ODBC2/3) * * Revision 1.4 1999/07/05 19:54:05 ngorham * * Fix a problem where a long string could crash the DM * * Revision 1.3 1999/07/04 21:05:08 ngorham * * Add LGPL Headers to code * * Revision 1.2 1999/06/19 17:51:41 ngorham * * Applied assorted minor bug fixes * * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb * first go at it * * Revision 1.2 1999/06/03 22:20:25 ngorham * * Finished off the ODBC3-2 mapping * * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey * Imported sources * * * **********************************************************************/ #include #include #include #include #if defined( HAVE_GETTIMEOFDAY ) && defined( HAVE_SYS_TIME_H ) #include #elif defined( HAVE_FTIME ) && defined( HAVE_SYS_TIMEB_H ) #include #elif defined( DHAVE_TIME ) && defined( HAVE_TIME_H ) #include #endif #ifdef HAVE_LANGINFO_H #include #elif defined(_WIN32) && !defined(__CYGWIN__) #include #include // Can't include here unsigned int __stdcall GetACP (void); typedef struct { char *win_enc; char *canonical_enc; } t_enc; static t_enc lookuptable[] = { { "CP1361", "JOHAB" }, { "CP20127", "ASCII" }, { "CP20866", "KOI8-R" }, { "CP20936", "GB2312" }, { "CP21866", "KOI8-RU" }, { "CP28591", "ISO-8859-1" }, { "CP28592", "ISO-8859-2" }, { "CP28593", "ISO-8859-3" }, { "CP28594", "ISO-8859-4" }, { "CP28595", "ISO-8859-5" }, { "CP28596", "ISO-8859-6" }, { "CP28597", "ISO-8859-7" }, { "CP28598", "ISO-8859-8" }, { "CP28599", "ISO-8859-9" }, { "CP28605", "ISO-8859-15" }, { "CP38598", "ISO-8859-8" }, { "CP51932", "EUC-JP" }, { "CP51936", "GB2312" }, { "CP51949", "EUC-KR" }, { "CP51950", "EUC-TW" }, { "CP54936", "GB18030" }, { "CP65001", "UTF-8" }, { "CP936", "GBK" } }; #endif #include "drivermanager.h" static char const rcsid[]= "$RCSfile: __info.c,v $ $Revision: 1.50 $"; struct log_structure log_info = { NULL, NULL, 0, 0 }; SQLINTEGER ODBCSharedTraceFlag = 0; /* * unicode setup functions, do them on a connection basis. */ int unicode_setup( DMHDBC connection ) { #ifdef HAVE_ICONV char ascii[ 256 ], unicode[ 256 ]; char *be_ucode[] = { "UCS-2-INTERNAL", "UCS-2BE", "UCS-2", "ucs2", NULL }; char *le_ucode[] = { "UCS-2-INTERNAL", "UCS-2LE", NULL }; char *asc[] = { "char", "char", "ISO8859-1", "ISO-8859-1", "8859-1", "iso8859_1", "ASCII", NULL }; union { long l; char c[sizeof (long)]; } u; int be; if ( connection -> iconv_cd_uc_to_ascii != (iconv_t)(-1) && connection -> iconv_cd_ascii_to_uc != (iconv_t)(-1)) { return 1; } /* * is this a bigendian machine ? */ u.l = 1; be = (u.c[sizeof (long) - 1] == 1); mutex_iconv_entry(); #if defined( HAVE_NL_LANGINFO ) && defined(HAVE_LANGINFO_CODESET) /* * Try with current locale settings first */ asc[ 0 ] = nl_langinfo(CODESET); #elif defined(_WIN32) && !defined(__CYGWIN__) static char resultbuf[2 + 10 + 1]; { // Heavily inspired by the localcharset module of gnulib (LGPL-2.1) char buf[2 + 10 + 1]; char *current_locale = setlocale (LC_CTYPE, NULL); char *pdot = strrchr (current_locale, '.'); if (pdot && 2 + strlen (pdot + 1) + 1 <= sizeof (buf)) sprintf (buf, "CP%s", pdot + 1); else sprintf (buf, "CP%u", GetACP ()); if (strcmp (buf + 2, "65001") == 0 || strcmp (buf + 2, "utf8") == 0) asc[ 0 ] = "UTF-8"; else { strcpy (resultbuf, buf); asc[ 0 ] = resultbuf; } int i; for (i = 0; i < sizeof (lookuptable) / sizeof (t_enc); i++) { t_enc sym = lookuptable[i]; if (strcmp(sym.win_enc, asc[ 0 ]) == 0) { strcpy (resultbuf, sym.canonical_enc); asc[ 0 ] = resultbuf; break; } } } #endif /* * if required find a match */ if ( strcmp( ASCII_ENCODING, "auto-search" ) == 0 && strcmp( connection -> unicode_string, "auto-search" ) == 0 ) { /* * look for both */ int i, j, found; iconv_t icvt; ascii[ 0 ] = '\0'; unicode[ 0 ] = '\0'; for ( i = found = 0; ( be ? be_ucode[ i ] : le_ucode[ i ] ) != NULL && !found; i ++ ) { for ( j = 0; asc[ j ] && !found; j ++ ) { if (( icvt = iconv_open( asc[ j ], be ? be_ucode[ i ] : le_ucode[ i ] )) != ((iconv_t) -1 ) ) { strcpy( ascii, asc[ j ] ); strcpy( unicode, be ? be_ucode[ i ] : le_ucode[ i ] ); iconv_close( icvt ); found = 1; } } } } else if ( strcmp( ASCII_ENCODING, "auto-search" ) == 0 ) { /* * look for ascii */ int j; iconv_t icvt; strcpy( unicode, connection -> unicode_string ); for ( j = 0; asc[ j ]; j ++ ) { if (( icvt = iconv_open( asc[ j ], unicode )) != ((iconv_t) -1 ) ) { strcpy( ascii, asc[ j ] ); iconv_close( icvt ); break; } } } else if ( strcmp( connection -> unicode_string, "auto-search" ) == 0 ) { /* * look for unicode */ int i; iconv_t icvt; strcpy( ascii, ASCII_ENCODING ); for ( i = 0; be ? be_ucode[ i ] : le_ucode[ i ]; i ++ ) { if (( icvt = iconv_open( ascii, be ? be_ucode[ i ] : le_ucode[ i ] )) != ((iconv_t) -1 ) ) { strcpy( unicode, be ? be_ucode[ i ] : le_ucode[ i ] ); iconv_close( icvt ); break; } } } else { strcpy( ascii, ASCII_ENCODING ); strcpy( unicode, connection -> unicode_string ); } if ( log_info.log_flag ) { sprintf( connection -> msg, "\t\tUNICODE Using encoding ASCII '%s' and UNICODE '%s'", ascii, unicode ); dm_log_write_diag( connection -> msg ); } connection -> iconv_cd_uc_to_ascii = iconv_open( ascii, unicode ); connection -> iconv_cd_ascii_to_uc = iconv_open( unicode, ascii ); mutex_iconv_exit(); if ( connection -> iconv_cd_uc_to_ascii == (iconv_t)(-1) || connection -> iconv_cd_ascii_to_uc == (iconv_t)(-1)) { return 0; } else { return 1; } #else return 1; #endif } void unicode_shutdown( DMHDBC connection ) { #ifdef HAVE_ICONV mutex_iconv_entry(); if ( connection -> iconv_cd_ascii_to_uc != (iconv_t)(-1) ) { iconv_close( connection -> iconv_cd_ascii_to_uc ); } if ( connection -> iconv_cd_uc_to_ascii != (iconv_t)(-1)) { iconv_close( connection -> iconv_cd_uc_to_ascii ); } connection -> iconv_cd_uc_to_ascii = (iconv_t)(-1); connection -> iconv_cd_ascii_to_uc = (iconv_t)(-1); mutex_iconv_exit(); #endif } /* * returned a malloc'd buffer in unicode converted from the ansi buffer */ SQLWCHAR *ansi_to_unicode_alloc( SQLCHAR *str, SQLINTEGER len, DMHDBC connection, int *wlen ) { SQLWCHAR *ustr; if ( wlen ) { *wlen = len; } if( !str ) { return NULL; } if ( len == SQL_NTS ) { len = strlen((char*) str ); } else if ( len < 0 ) { len = 0; } ustr = malloc( sizeof( SQLWCHAR ) * ( len + 1 )); if ( !ustr ) { return NULL; } return ansi_to_unicode_copy( ustr, (char*) str, len, connection, wlen ); } /* * return a ansi representation of a unicode buffer, according to * the chosen conversion method */ char *unicode_to_ansi_alloc( SQLWCHAR *str, SQLINTEGER len, DMHDBC connection, int *clen ) { char *aptr; if ( clen ) { *clen = len; } if ( !str ) { return NULL; } if ( len == SQL_NTS ) { len = wide_strlen( str ); } aptr = malloc(( len * 4 ) + 1 ); /* There may be UTF8 */ if ( !aptr ) { return NULL; } return unicode_to_ansi_copy( aptr, len * 4, str, len, connection, clen ); } /* * copy from a unicode buffer to a ansi buffer using the chosen conversion */ char *unicode_to_ansi_copy( char * dest, int dest_len, SQLWCHAR *src, SQLINTEGER buffer_len, DMHDBC connection, int *clen ) { int i; if ( !src || !dest ) { return NULL; } if ( buffer_len == SQL_NTS ) { buffer_len = wide_strlen( src ); } #ifdef HAVE_ICONV mutex_iconv_entry(); if ( connection && connection -> iconv_cd_uc_to_ascii != (iconv_t)(-1)) { size_t ret; size_t inbl = buffer_len * sizeof( SQLWCHAR ); size_t obl = dest_len; char *ipt = (char*)src; char *opt = (char*)dest; if (( ret = iconv( connection -> iconv_cd_uc_to_ascii, (ICONV_CONST char**)&ipt, &inbl, &opt, &obl )) != (size_t)(-1)) { mutex_iconv_exit(); if ( clen ) { *clen = opt - dest; } /* Null terminate outside of iconv, so that the length returned does not include the null terminator. */ if ( obl ) { *opt = '\0'; } return dest; } } mutex_iconv_exit(); #endif for ( i = 0; i < buffer_len && i < dest_len && src[ i ] != 0; i ++ ) { #ifdef SQL_WCHART_CONVERT dest[ i ] = (char)(src[ i ] & 0x000000ff); #else dest[ i ] = src[ i ] & 0x00FF; #endif } if ( clen ) { *clen = i; } if (dest_len) { dest[ i < dest_len ? i : i-1 ] = '\0'; } return dest; } /* * copy from a ansi buffer to a unicode buffer using the chosen conversion */ SQLWCHAR *ansi_to_unicode_copy( SQLWCHAR * dest, char *src, SQLINTEGER buffer_len, DMHDBC connection, int *wlen ) { int i; if ( !src || !dest ) { return NULL; } if ( buffer_len == SQL_NTS ) { buffer_len = strlen( src ); } else if ( buffer_len < 0 ) { buffer_len = 0; } #ifdef HAVE_ICONV if ( connection && connection -> iconv_cd_ascii_to_uc != (iconv_t)(-1)) { size_t inbl = buffer_len; size_t obl = buffer_len * sizeof( SQLWCHAR ); char *ipt = (char*)src; char *opt = (char*)dest; mutex_iconv_entry(); if ( iconv( connection -> iconv_cd_ascii_to_uc, (ICONV_CONST char**)&ipt, &inbl, &opt, &obl ) != (size_t)(-1)) { mutex_iconv_exit(); if ( wlen ) { *wlen = ( opt - ((char*)dest)) / sizeof( SQLWCHAR ); } /* Null terminate outside of iconv, so that the length returned does not include the null terminator. */ dest[( opt - ((char*)dest)) / sizeof( SQLWCHAR )] = 0; return dest; } mutex_iconv_exit(); } #endif for ( i = 0; i < buffer_len && src[ i ] != 0; i ++ ) { #ifdef SQL_WCHART_CONVERT dest[ i ] = src[ i ] & 0x000000ff; #else dest[ i ] = src[ i ] & 0x00FF; #endif } if ( wlen ) { *wlen = i; } dest[ i ] = 0; return dest; } /* * display a SQLGetTypeInfo type as a astring */ char * __type_as_string( SQLCHAR *s, SQLSMALLINT type ) { switch( type ) { case SQL_DOUBLE: sprintf((char*) s, "SQL_DOUBLE" ); break; case SQL_FLOAT: sprintf((char*) s, "SQL_FLOAT" ); break; case SQL_REAL: sprintf((char*) s, "SQL_REAL" ); break; case SQL_BIT: sprintf((char*) s, "SQL_BIT" ); break; case SQL_CHAR: sprintf((char*) s, "SQL_CHAR" ); break; case SQL_VARCHAR: sprintf((char*) s, "SQL_VARCHAR" ); break; case SQL_LONGVARCHAR: sprintf((char*) s, "SQL_LONGVARCHAR" ); break; case SQL_BINARY: sprintf((char*) s, "SQL_BINARY" ); break; case SQL_VARBINARY: sprintf((char*) s, "SQL_VARBINARY" ); break; case SQL_LONGVARBINARY: sprintf((char*) s, "SQL_LONGVARBINARY" ); break; case SQL_DECIMAL: sprintf((char*) s, "SQL_DECIMAL" ); break; case SQL_NUMERIC: sprintf((char*) s, "SQL_NUMERIC" ); break; case SQL_BIGINT: sprintf((char*) s, "SQL_BIGINT" ); break; case SQL_INTEGER: sprintf((char*) s, "SQL_INTEGER" ); break; case SQL_SMALLINT: sprintf((char*) s, "SQL_SMALLINT" ); break; case SQL_TINYINT: sprintf((char*) s, "SQL_TINYINT" ); break; case SQL_TYPE_DATE: sprintf((char*) s, "SQL_TYPE_DATE" ); break; case SQL_TYPE_TIME: sprintf((char*) s, "SQL_TYPE_TIME" ); break; case SQL_TYPE_TIMESTAMP: sprintf((char*) s, "SQL_TYPE_TIMESTAMP" ); break; case SQL_DATE: sprintf((char*) s, "SQL_DATE" ); break; case SQL_TIME: sprintf((char*) s, "SQL_TIME" ); break; case SQL_TIMESTAMP: sprintf((char*) s, "SQL_TIMESTAMP" ); break; case SQL_INTERVAL_YEAR: sprintf((char*) s, "SQL_INTERVAL_YEAR" ); break; case SQL_INTERVAL_YEAR_TO_MONTH: sprintf((char*) s, "SQL_INTERVAL_YEAR_TO_MONTH" ); break; case SQL_INTERVAL_MONTH: sprintf((char*) s, "SQL_INTERVAL_MONTH" ); break; case SQL_INTERVAL_DAY_TO_SECOND: sprintf((char*) s, "SQL_INTERVAL_DAY_TO_SECOND" ); break; case SQL_INTERVAL_DAY_TO_MINUTE: sprintf((char*) s, "SQL_INTERVAL_DAY_TO_MINUTE" ); break; case SQL_INTERVAL_DAY: sprintf((char*) s, "SQL_INTERVAL_DAY" ); break; case SQL_INTERVAL_HOUR_TO_SECOND: sprintf((char*) s, "SQL_INTERVAL_HOUR_TO_SECOND" ); break; case SQL_INTERVAL_HOUR_TO_MINUTE: sprintf((char*) s, "SQL_INTERVAL_HOUR_TO_MINUTE" ); break; case SQL_INTERVAL_HOUR: sprintf((char*) s, "SQL_INTERVAL_HOUR" ); break; case SQL_INTERVAL_MINUTE_TO_SECOND: sprintf((char*) s, "SQL_INTERVAL_MINUTE_TO_SECOND" ); break; case SQL_INTERVAL_MINUTE: sprintf((char*) s, "SQL_INTERVAL_MINUTE" ); break; case SQL_INTERVAL_SECOND: sprintf((char*) s, "SQL_INTERVAL_SECOND" ); break; case SQL_ALL_TYPES: sprintf((char*) s, "SQL_ALL_TYPES" ); break; default: sprintf((char*) s, "Unknown(%d)", (int)type ); break; } return (char*) s; } /* * display a data field as a string */ char * __sdata_as_string( SQLCHAR *s, SQLINTEGER type, SQLSMALLINT *ptr, SQLPOINTER buf ) { SQLLEN iptr; if ( ptr ) { iptr = *ptr; return __data_as_string( s, type, &iptr, buf ); } else { return __data_as_string( s, type, NULL, buf ); } return (char*) s; } char * __idata_as_string( SQLCHAR *s, SQLINTEGER type, SQLINTEGER *ptr, SQLPOINTER buf ) { SQLLEN iptr; if ( ptr ) { iptr = *ptr; return __data_as_string( s, type, &iptr, buf ); } else { return __data_as_string( s, type, NULL, buf ); } return (char*) s; } char * __data_as_string( SQLCHAR *s, SQLINTEGER type, SQLLEN *ptr, SQLPOINTER buf ) { if ( ptr && *ptr == SQL_NULL_DATA ) { sprintf((char*) s, "SQL_NULL_DATA" ); } else if ( ptr && *ptr < 0 ) { sprintf((char*) s, "Indicator = %d", (int)*ptr ); } else if ( !buf ) { sprintf((char*) s, "[NULLPTR]" ); } else { switch ( type ) { case SQL_INTEGER: { SQLINTEGER val; memcpy( &val, buf, sizeof( SQLINTEGER )); sprintf((char*) s, "[%d]", (int)val ); } break; case SQL_CHAR: case SQL_VARCHAR: sprintf((char*) s, "[%.*s]", LOG_MESSAGE_LEN, (char*)buf ); break; case SQL_WCHAR: case SQL_WVARCHAR: { int len = LOG_MESSAGE_LEN; signed short *ptr = (signed short*)buf; char *optr; optr = (char*) s; sprintf((char*) s, "[" ); optr ++; while( len > 0 ) { if ( *ptr == 0x0000 ) break; sprintf( optr, "%c", *ptr & 0x00FF ); optr ++; len --; ptr ++; } sprintf( optr, "](unicode)" ); } break; case SQL_DOUBLE: { double val; memcpy( &val, buf, sizeof( double )); sprintf((char*) s, "[%g]", val ); } break; case SQL_FLOAT: case SQL_REAL: { float val; memcpy( &val, buf, sizeof( float )); sprintf((char*) s, "[%g]", val ); } break; case SQL_BIT: { SQLCHAR val; memcpy( &val, buf, sizeof( SQLCHAR )); sprintf((char*) s, "[%d]", (int)val ); } break; case SQL_LONGVARCHAR: sprintf((char*) s, "[LONGVARCHARDATA...]" ); break; case SQL_BINARY: sprintf((char*) s, "[BINARYDATA...]" ); break; case SQL_VARBINARY: sprintf((char*) s, "[VARBINARYDATA...]" ); break; case SQL_LONGVARBINARY: sprintf((char*) s, "[LONGVARBINARYDATA...]" ); break; case SQL_DECIMAL: sprintf((char*) s, "[DECIMAL...]" ); break; case SQL_NUMERIC: sprintf((char*) s, "[NUMERIC...]" ); break; case SQL_BIGINT: sprintf((char*) s, "[BIGINT...]" ); break; case SQL_SMALLINT: { short val; memcpy( &val, buf, sizeof( short )); sprintf((char*) s, "[%d]", (int)val ); } break; case SQL_TINYINT: { char val; memcpy( &val, buf, sizeof( char )); sprintf((char*) s, "[%d]", (int)val ); } break; case SQL_TYPE_DATE: case SQL_DATE: sprintf((char*) s, "[DATE...]" ); break; case SQL_TYPE_TIME: case SQL_TIME: sprintf((char*) s, "[TIME...]" ); break; case SQL_TYPE_TIMESTAMP: case SQL_TIMESTAMP: sprintf((char*) s, "[TIMESTAMP...]" ); break; case SQL_INTERVAL_YEAR: case SQL_INTERVAL_YEAR_TO_MONTH: case SQL_INTERVAL_MONTH: case SQL_INTERVAL_DAY_TO_SECOND: case SQL_INTERVAL_DAY_TO_MINUTE: case SQL_INTERVAL_DAY: case SQL_INTERVAL_HOUR_TO_SECOND: case SQL_INTERVAL_HOUR_TO_MINUTE: case SQL_INTERVAL_HOUR: case SQL_INTERVAL_MINUTE_TO_SECOND: case SQL_INTERVAL_MINUTE: case SQL_INTERVAL_SECOND: sprintf((char*) s, "[INTERVAL...]" ); break; default: sprintf((char*) s, "[Data...]" ); break; } } return (char*) s; } /* * display a pointer to a int */ char * __iptr_as_string( SQLCHAR *s, SQLINTEGER *ptr ) { if ( ptr ) { sprintf((char*) s, "%p -> %ld (%d bits)", (void*)ptr, (long)*ptr, (int)sizeof( SQLINTEGER ) * 8 ); } else { sprintf((char*) s, "NULLPTR" ); } return (char*) s; } char * __ptr_as_string( SQLCHAR *s, SQLLEN *ptr ) { if ( ptr ) { sprintf((char*) s, "%p -> %ld (%d bits)", (void*)ptr, (long)*ptr, (int)sizeof( SQLLEN ) * 8 ); } else { sprintf((char*) s, "NULLPTR" ); } return (char*) s; } /* * display a pointer to a int */ char * __sptr_as_string( SQLCHAR *s, SQLSMALLINT *ptr ) { if ( ptr ) { sprintf((char*) s, "%p -> %d", (void*)ptr, (int)*ptr ); } else { sprintf((char*) s, "NULLPTR" ); } return (char*) s; } /* * convert a function id to a string */ char * __fid_as_string( SQLCHAR *s, SQLINTEGER type ) { switch( type ) { case SQL_API_SQLALLOCCONNECT: sprintf((char*) s, "SQLAllocConnect" ); break; case SQL_API_SQLALLOCENV: sprintf((char*) s, "SQLAllocEnv" ); break; case SQL_API_SQLALLOCHANDLE: sprintf((char*) s, "SQLAllocHandle" ); break; case SQL_API_SQLALLOCSTMT: sprintf((char*) s, "SQLAllocStmt" ); break; case SQL_API_SQLALLOCHANDLESTD: sprintf((char*) s, "SQLAllochandleStd" ); break; case SQL_API_SQLBINDCOL: sprintf((char*) s, "SQLBindCol" ); break; case SQL_API_SQLBINDPARAM: sprintf((char*) s, "SQLBindParam" ); break; case SQL_API_SQLBINDPARAMETER: sprintf((char*) s, "SQLBindParameter" ); break; case SQL_API_SQLBROWSECONNECT: sprintf((char*) s, "SQLBrowseConnect" ); break; case SQL_API_SQLBULKOPERATIONS: sprintf((char*) s, "SQLBulkOperations" ); break; case SQL_API_SQLCANCEL: sprintf((char*) s, "SQLCancel" ); break; case SQL_API_SQLCLOSECURSOR: sprintf((char*) s, "SQLCloseCursor" ); break; case SQL_API_SQLCOLATTRIBUTES: sprintf((char*) s, "SQLColAttribute(s)" ); break; case SQL_API_SQLCOLUMNPRIVILEGES: sprintf((char*) s, "SQLColumnPrivileges" ); break; case SQL_API_SQLCOLUMNS: sprintf((char*) s, "SQLColumns" ); break; case SQL_API_SQLCONNECT: sprintf((char*) s, "SQLConnect" ); break; case SQL_API_SQLCOPYDESC: sprintf((char*) s, "SQLCopyDesc" ); break; case SQL_API_SQLDATASOURCES: sprintf((char*) s, "SQLDataSources" ); break; case SQL_API_SQLDESCRIBECOL: sprintf((char*) s, "SQLDescribeCol" ); break; case SQL_API_SQLDESCRIBEPARAM: sprintf((char*) s, "SQLDescribeParam" ); break; case SQL_API_SQLDISCONNECT: sprintf((char*) s, "SQLDisconnect" ); break; case SQL_API_SQLDRIVERCONNECT: sprintf((char*) s, "SQLDriverConnect" ); break; case SQL_API_SQLDRIVERS: sprintf((char*) s, "SQLDrivers" ); break; case SQL_API_SQLENDTRAN: sprintf((char*) s, "SQLEndTran" ); break; case SQL_API_SQLERROR: sprintf((char*) s, "SQLError" ); break; case SQL_API_SQLEXECDIRECT: sprintf((char*) s, "SQLExecDirect" ); break; case SQL_API_SQLEXECUTE: sprintf((char*) s, "SQLExecute" ); break; case SQL_API_SQLEXTENDEDFETCH: sprintf((char*) s, "SQLExtendedFetch" ); break; case SQL_API_SQLFETCH: sprintf((char*) s, "SQLFetch" ); break; case SQL_API_SQLFETCHSCROLL: sprintf((char*) s, "SQLFetchScroll" ); break; case SQL_API_SQLFOREIGNKEYS: sprintf((char*) s, "SQLForeignKeys" ); break; case SQL_API_SQLFREEENV: sprintf((char*) s, "SQLFreeEnv" ); break; case SQL_API_SQLFREEHANDLE: sprintf((char*) s, "SQLFreeHandle" ); break; case SQL_API_SQLFREESTMT: sprintf((char*) s, "SQLFreeStmt" ); break; case SQL_API_SQLFREECONNECT: sprintf((char*) s, "SQLFreeConnect" ); break; case SQL_API_SQLGETCONNECTATTR: sprintf((char*) s, "SQLGetConnectAttr" ); break; case SQL_API_SQLGETCONNECTOPTION: sprintf((char*) s, "SQLGetConnectOption" ); break; case SQL_API_SQLGETCURSORNAME: sprintf((char*) s, "SQLGetCursorName" ); break; case SQL_API_SQLGETDATA: sprintf((char*) s, "SQLGetData" ); break; case SQL_API_SQLGETDESCFIELD: sprintf((char*) s, "SQLGetDescField" ); break; case SQL_API_SQLGETDESCREC: sprintf((char*) s, "SQLGetDescRec" ); break; case SQL_API_SQLGETDIAGFIELD: sprintf((char*) s, "SQLGetDiagField" ); break; case SQL_API_SQLGETENVATTR: sprintf((char*) s, "SQLGetEnvAttr" ); break; case SQL_API_SQLGETFUNCTIONS: sprintf((char*) s, "SQLGetFunctions" ); break; case SQL_API_SQLGETINFO: sprintf((char*) s, "SQLGetInfo" ); break; case SQL_API_SQLGETSTMTATTR: sprintf((char*) s, "SQLGetStmtAttr" ); break; case SQL_API_SQLGETSTMTOPTION: sprintf((char*) s, "SQLGetStmtOption" ); break; case SQL_API_SQLGETTYPEINFO: sprintf((char*) s, "SQLGetTypeInfo" ); break; case SQL_API_SQLMORERESULTS: sprintf((char*) s, "SQLMoreResults" ); break; case SQL_API_SQLNATIVESQL: sprintf((char*) s, "SQLNativeSql" ); break; case SQL_API_SQLNUMPARAMS: sprintf((char*) s, "SQLNumParams" ); break; case SQL_API_SQLNUMRESULTCOLS: sprintf((char*) s, "SQLNumResultCols" ); break; case SQL_API_SQLPARAMDATA: sprintf((char*) s, "SQLParamData" ); break; case SQL_API_SQLPARAMOPTIONS: sprintf((char*) s, "SQLParamOptions" ); break; case SQL_API_SQLPREPARE: sprintf((char*) s, "SQLPrepare" ); break; case SQL_API_SQLPRIMARYKEYS: sprintf((char*) s, "SQLPrimaryKeys" ); break; case SQL_API_SQLPROCEDURECOLUMNS: sprintf((char*) s, "SQLProcedureColumns" ); break; case SQL_API_SQLPROCEDURES: sprintf((char*) s, "SQLProcedures" ); break; case SQL_API_SQLPUTDATA: sprintf((char*) s, "SQLPutData" ); break; case SQL_API_SQLROWCOUNT: sprintf((char*) s, "SQLRowCount" ); break; case SQL_API_SQLSETCONNECTATTR: sprintf((char*) s, "SQLSetConnectAttr" ); break; case SQL_API_SQLSETCONNECTOPTION: sprintf((char*) s, "SQLSetConnectOption" ); break; case SQL_API_SQLSETCURSORNAME: sprintf((char*) s, "SQLSetCursorName" ); break; case SQL_API_SQLSETDESCFIELD: sprintf((char*) s, "SQLSetDescField" ); break; case SQL_API_SQLSETDESCREC: sprintf((char*) s, "SQLSetDescRec" ); break; case SQL_API_SQLSETENVATTR: sprintf((char*) s, "SQLSetEnvAttr" ); break; case SQL_API_SQLSETPARAM: sprintf((char*) s, "SQLSetParam" ); break; case SQL_API_SQLSETPOS: sprintf((char*) s, "SQLSetPos" ); break; case SQL_API_SQLSETSCROLLOPTIONS: sprintf((char*) s, "SQLSetScrollOptions" ); break; case SQL_API_SQLSETSTMTATTR: sprintf((char*) s, "SQLSetStmtAttr" ); break; case SQL_API_SQLSETSTMTOPTION: sprintf((char*) s, "SQLSetStmtOption" ); break; case SQL_API_SQLSPECIALCOLUMNS: sprintf((char*) s, "SQLSpecialColumns" ); break; case SQL_API_SQLSTATISTICS: sprintf((char*) s, "SQLStatistics" ); break; case SQL_API_SQLTABLEPRIVILEGES: sprintf((char*) s, "SQLTablePrivileges" ); break; case SQL_API_SQLTABLES: sprintf((char*) s, "SQLTables" ); break; case SQL_API_SQLTRANSACT: sprintf((char*) s, "SQLTransact" ); break; case SQL_API_SQLGETDIAGREC: sprintf((char*) s, "SQLGetDiagRec" ); break; default: sprintf((char*) s, "%d", (int)type ); } return (char*) s; } /* * convert a column attribute to a string */ char * __col_attr_as_string( SQLCHAR *s, SQLINTEGER type ) { switch( type ) { case SQL_DESC_AUTO_UNIQUE_VALUE: sprintf((char*) s, "SQL_DESC_AUTO_UNIQUE_VALUE" ); break; case SQL_DESC_BASE_COLUMN_NAME: sprintf((char*) s, "SQL_DESC_BASE_COLUMN_NAME" ); break; case SQL_DESC_BASE_TABLE_NAME: sprintf((char*) s, "SQL_DESC_BASE_TABLE_NAME" ); break; case SQL_DESC_CASE_SENSITIVE: sprintf((char*) s, "SQL_DESC_CASE_SENSITIVE" ); break; case SQL_DESC_CATALOG_NAME: sprintf((char*) s, "SQL_DESC_CATALOG_NAME" ); break; case SQL_DESC_CONCISE_TYPE: sprintf((char*) s, "SQL_DESC_CONCISE_TYPE" ); break; case SQL_DESC_DISPLAY_SIZE: sprintf((char*) s, "SQL_DESC_DISPLAY_SIZE" ); break; case SQL_DESC_FIXED_PREC_SCALE: sprintf((char*) s, "SQL_DESC_FIXED_PREC_SCALE" ); break; case SQL_DESC_LABEL: sprintf((char*) s, "SQL_DESC_LABEL" ); break; case SQL_COLUMN_NAME: sprintf((char*) s, "SQL_COLUMN_NAME" ); break; case SQL_DESC_LENGTH: sprintf((char*) s, "SQL_DESC_LENGTH" ); break; case SQL_COLUMN_LENGTH: sprintf((char*) s, "SQL_COLUMN_LENGTH" ); break; case SQL_DESC_LITERAL_PREFIX: sprintf((char*) s, "SQL_DESC_LITERAL_PREFIX" ); break; case SQL_DESC_LITERAL_SUFFIX: sprintf((char*) s, "SQL_DESC_LITERAL_SUFFIX" ); break; case SQL_DESC_LOCAL_TYPE_NAME: sprintf((char*) s, "SQL_DESC_LOCAL_TYPE_NAME" ); break; case SQL_DESC_NAME: sprintf((char*) s, "SQL_DESC_NAME" ); break; case SQL_DESC_NULLABLE: sprintf((char*) s, "SQL_DESC_NULLABLE" ); break; case SQL_COLUMN_NULLABLE: sprintf((char*) s, "SQL_COLUMN_NULLABLE" ); break; case SQL_DESC_NUM_PREC_RADIX: sprintf((char*) s, "SQL_DESC_NUM_PREC_RADIX" ); break; case SQL_DESC_OCTET_LENGTH: sprintf((char*) s, "SQL_DESC_OCTET_LENGTH" ); break; case SQL_DESC_PRECISION: sprintf((char*) s, "SQL_DESC_PRECISION" ); break; case SQL_COLUMN_PRECISION: sprintf((char*) s, "SQL_COLUMN_PRECISION" ); break; case SQL_DESC_SCALE: sprintf((char*) s, "SQL_DESC_SCALE" ); break; case SQL_COLUMN_SCALE: sprintf((char*) s, "SQL_COLUMN_SCALE" ); break; case SQL_DESC_SCHEMA_NAME: sprintf((char*) s, "SQL_DESC_SCHEMA_NAME" ); break; case SQL_DESC_SEARCHABLE: sprintf((char*) s, "SQL_DESC_SEARCHABLE" ); break; case SQL_DESC_TABLE_NAME: sprintf((char*) s, "SQL_DESC_TABLE_NAME" ); break; case SQL_DESC_TYPE: sprintf((char*) s, "SQL_DESC_TYPE" ); break; case SQL_DESC_TYPE_NAME: sprintf((char*) s, "SQL_DESC_TYPE_NAME" ); break; case SQL_DESC_UNNAMED: sprintf((char*) s, "SQL_DESC_UNNAMED" ); break; case SQL_DESC_UNSIGNED: sprintf((char*) s, "SQL_DESC_UNSIGNED" ); break; case SQL_DESC_UPDATABLE: sprintf((char*) s, "SQL_DESC_UPDATABLE" ); break; default: sprintf((char*) s, "%d", (int)type ); } return (char*) s; } /* * convert a connect attribute to a string */ char * __env_attr_as_string( SQLCHAR *s, SQLINTEGER type ) { switch( type ) { case SQL_ATTR_CONNECTION_POOLING: sprintf((char*) s, "SQL_ATTR_CONNECTION_POOLING" ); break; case SQL_ATTR_CP_MATCH: sprintf((char*) s, "SQL_ATTR_CP_MATCH" ); break; case SQL_ATTR_ODBC_VERSION: sprintf((char*) s, "SQL_ATTR_ODBC_VERSION" ); break; case SQL_ATTR_OUTPUT_NTS: sprintf((char*) s, "SQL_ATTR_OUTPUT_NTS" ); break; default: sprintf((char*) s, "%d", (int)type ); } return (char*) s; } /* * convert a connect attribute to a string */ char * __con_attr_as_string( SQLCHAR *s, SQLINTEGER type ) { switch( type ) { case SQL_ATTR_ACCESS_MODE: sprintf((char*) s, "SQL_ATTR_ACCESS_MODE" ); break; case SQL_ATTR_ASYNC_ENABLE: sprintf((char*) s, "SQL_ATTR_ASYNC_ENABLE" ); break; case SQL_ATTR_AUTO_IPD: sprintf((char*) s, "SQL_ATTR_AUTO_IPD" ); break; case SQL_ATTR_AUTOCOMMIT: sprintf((char*) s, "SQL_ATTR_AUTOCOMMIT" ); break; case SQL_ATTR_CONNECTION_TIMEOUT: sprintf((char*) s, "SQL_ATTR_CONNECTION_TIMEOUT" ); break; case SQL_ATTR_CURRENT_CATALOG: sprintf((char*) s, "SQL_ATTR_CURRENT_CATALOG" ); break; case SQL_ATTR_LOGIN_TIMEOUT: sprintf((char*) s, "SQL_ATTR_LOGIN_TIMEOUT" ); break; case SQL_ATTR_METADATA_ID: sprintf((char*) s, "SQL_ATTR_METADATA_ID" ); break; case SQL_ATTR_ODBC_CURSORS: sprintf((char*) s, "SQL_ATTR_ODBC_CURSORS" ); break; case SQL_ATTR_PACKET_SIZE: sprintf((char*) s, "SQL_ATTR_PACKET_SIZE" ); break; case SQL_ATTR_QUIET_MODE: sprintf((char*) s, "SQL_ATTR_QUIET_MODE" ); break; case SQL_ATTR_TRACE: sprintf((char*) s, "SQL_ATTR_TRACE" ); break; case SQL_ATTR_TRACEFILE: sprintf((char*) s, "SQL_ATTR_TRACEFILE" ); break; case SQL_ATTR_TRANSLATE_LIB: sprintf((char*) s, "SQL_ATTR_TRANSLATE_LIB" ); break; case SQL_ATTR_TRANSLATE_OPTION: sprintf((char*) s, "SQL_ATTR_TRANSLATE_OPTION" ); break; case SQL_ATTR_TXN_ISOLATION: sprintf((char*) s, "SQL_ATTR_TXN_ISOLATION" ); break; default: sprintf((char*) s, "%d", (int)type ); } return (char*) s; } /* * convert a diagnostic attribute to a string */ char * __diag_attr_as_string( SQLCHAR *s, SQLINTEGER type ) { switch( type ) { case SQL_DIAG_CURSOR_ROW_COUNT: sprintf((char*) s, "SQL_DIAG_CURSOR_ROW_COUNT" ); break; case SQL_DIAG_DYNAMIC_FUNCTION: sprintf((char*) s, "SQL_DIAG_DYNAMIC_FUNCTION" ); break; case SQL_DIAG_DYNAMIC_FUNCTION_CODE: sprintf((char*) s, "SQL_DIAG_DYNAMIC_FUNCTION_CODE" ); break; case SQL_DIAG_NUMBER: sprintf((char*) s, "SQL_DIAG_NUMBER" ); break; case SQL_DIAG_RETURNCODE: sprintf((char*) s, "SQL_DIAG_RETURNCODE" ); break; case SQL_DIAG_ROW_COUNT: sprintf((char*) s, "SQL_DIAG_ROW_COUNT" ); break; case SQL_DIAG_CLASS_ORIGIN: sprintf((char*) s, "SQL_DIAG_CLASS_ORIGIN" ); break; case SQL_DIAG_COLUMN_NUMBER: sprintf((char*) s, "SQL_DIAG_COLUMN_NUMBER" ); break; case SQL_DIAG_CONNECTION_NAME: sprintf((char*) s, "SQL_DIAG_CONNECTION_NAME" ); break; case SQL_DIAG_MESSAGE_TEXT: sprintf((char*) s, "SQL_DIAG_MESSAGE_TEXT" ); break; case SQL_DIAG_NATIVE: sprintf((char*) s, "SQL_DIAG_NATIVE" ); break; case SQL_DIAG_ROW_NUMBER: sprintf((char*) s, "SQL_DIAG_ROW_NUMBER" ); break; case SQL_DIAG_SERVER_NAME: sprintf((char*) s, "SQL_DIAG_SERVER_NAME" ); break; case SQL_DIAG_SQLSTATE: sprintf((char*) s, "SQL_DIAG_SQLSTATE" ); break; case SQL_DIAG_SUBCLASS_ORIGIN: sprintf((char*) s, "SQL_DIAG_SUBCLASS_ORIGIN" ); break; default: sprintf((char*) s, "%d", (int)type ); } return (char*) s; } /* * convert a descriptor attribute to a string */ char * __desc_attr_as_string( SQLCHAR *s, SQLINTEGER type ) { switch( type ) { case SQL_DESC_ALLOC_TYPE: sprintf((char*) s, "SQL_DESC_ALLOC_TYPE" ); break; case SQL_DESC_ARRAY_SIZE: sprintf((char*) s, "SQL_DESC_ARRAY_SIZE" ); break; case SQL_DESC_ARRAY_STATUS_PTR: sprintf((char*) s, "SQL_DESC_ARRAY_STATUS_PTR" ); break; case SQL_DESC_BIND_OFFSET_PTR: sprintf((char*) s, "SQL_DESC_BIND_OFFSET_PTR" ); break; case SQL_DESC_BIND_TYPE: sprintf((char*) s, "SQL_DESC_BIND_TYPE" ); break; case SQL_DESC_COUNT: sprintf((char*) s, "SQL_DESC_COUNT" ); break; case SQL_DESC_ROWS_PROCESSED_PTR: sprintf((char*) s, "SQL_DESC_ROWS_PROCESSED_PTR" ); break; case SQL_DESC_AUTO_UNIQUE_VALUE: sprintf((char*) s, "SQL_DESC_AUTO_UNIQUE_VALUE" ); break; case SQL_DESC_BASE_COLUMN_NAME: sprintf((char*) s, "SQL_DESC_BASE_COLUMN_NAME" ); break; case SQL_DESC_BASE_TABLE_NAME: sprintf((char*) s, "SQL_DESC_BASE_TABLE_NAME" ); break; case SQL_DESC_CASE_SENSITIVE: sprintf((char*) s, "SQL_DESC_CASE_SENSITIVE" ); break; case SQL_DESC_CATALOG_NAME: sprintf((char*) s, "SQL_DESC_CATALOG_NAME" ); break; case SQL_DESC_CONCISE_TYPE: sprintf((char*) s, "SQL_DESC_CONCISE_TYPE" ); break; case SQL_DESC_DATA_PTR: sprintf((char*) s, "SQL_DESC_DATA_PTR" ); break; case SQL_DESC_DATETIME_INTERVAL_CODE: sprintf((char*) s, "SQL_DESC_DATETIME_INTERVAL_CODE" ); break; case SQL_DESC_DATETIME_INTERVAL_PRECISION: sprintf((char*) s, "SQL_DESC_DATETIME_INTERVAL_PRECISION" ); break; case SQL_DESC_DISPLAY_SIZE: sprintf((char*) s, "SQL_DESC_DISPLAY_SIZE" ); break; case SQL_DESC_FIXED_PREC_SCALE: sprintf((char*) s, "SQL_DESC_FIXED_PREC_SCALE" ); break; case SQL_DESC_INDICATOR_PTR: sprintf((char*) s, "SQL_DESC_INDICATOR_PTR" ); break; case SQL_DESC_LABEL: sprintf((char*) s, "SQL_DESC_LABEL" ); break; case SQL_DESC_LENGTH: sprintf((char*) s, "SQL_DESC_LENGTH" ); break; case SQL_DESC_LITERAL_PREFIX: sprintf((char*) s, "SQL_DESC_LITERAL_PREFIX" ); break; case SQL_DESC_LITERAL_SUFFIX: sprintf((char*) s, "SQL_DESC_LITERAL_SUFFIX" ); break; case SQL_DESC_LOCAL_TYPE_NAME: sprintf((char*) s, "SQL_DESC_LOCAL_TYPE_NAME" ); break; case SQL_DESC_NAME: sprintf((char*) s, "SQL_DESC_NAME" ); break; case SQL_DESC_NULLABLE: sprintf((char*) s, "SQL_DESC_NULLABLE" ); break; case SQL_DESC_NUM_PREC_RADIX: sprintf((char*) s, "SQL_DESC_NUM_PREC_RADIX" ); break; case SQL_DESC_OCTET_LENGTH: sprintf((char*) s, "SQL_DESC_OCTET_LENGTH" ); break; case SQL_DESC_OCTET_LENGTH_PTR: sprintf((char*) s, "SQL_DESC_OCTET_LENGTH_PTR" ); break; case SQL_DESC_PARAMETER_TYPE: sprintf((char*) s, "SQL_DESC_PARAMETER_TYPE" ); break; case SQL_DESC_PRECISION: sprintf((char*) s, "SQL_DESC_PRECISION" ); break; case SQL_DESC_SCALE: sprintf((char*) s, "SQL_DESC_SCALE" ); break; case SQL_DESC_SCHEMA_NAME: sprintf((char*) s, "SQL_DESC_SCHEMA_NAME" ); break; case SQL_DESC_SEARCHABLE: sprintf((char*) s, "SQL_DESC_SEARCHABLE" ); break; case SQL_DESC_TABLE_NAME: sprintf((char*) s, "SQL_DESC_TABLE_NAME" ); break; case SQL_DESC_TYPE: sprintf((char*) s, "SQL_DESC_TYPE" ); break; case SQL_DESC_TYPE_NAME: sprintf((char*) s, "SQL_DESC_TYPE_NAME" ); break; case SQL_DESC_UNNAMED: sprintf((char*) s, "SQL_DESC_UNNAMED" ); break; case SQL_DESC_UNSIGNED: sprintf((char*) s, "SQL_DESC_UNSIGNED" ); break; case SQL_DESC_UPDATABLE: sprintf((char*) s, "SQL_DESC_UPDATABLE" ); break; default: sprintf((char*) s, "%d", (int)type ); } return (char*) s; } /* * convert a statement attribute to a string */ char * __stmt_attr_as_string( SQLCHAR *s, SQLINTEGER type ) { switch( type ) { case SQL_ATTR_APP_PARAM_DESC: sprintf((char*) s, "SQL_ATTR_APP_PARAM_DESC" ); break; case SQL_ATTR_APP_ROW_DESC: sprintf((char*) s, "SQL_ATTR_APP_ROW_DESC" ); break; case SQL_ATTR_ASYNC_ENABLE: sprintf((char*) s, "SQL_ATTR_ASYNC_ENABLE" ); break; case SQL_ATTR_CONCURRENCY: sprintf((char*) s, "SQL_ATTR_CONCURRENCY" ); break; case SQL_ATTR_CURSOR_SCROLLABLE: sprintf((char*) s, "SQL_ATTR_CURSOR_SCROLLABLE" ); break; case SQL_ATTR_CURSOR_SENSITIVITY: sprintf((char*) s, "SQL_ATTR_CURSOR_SENSITIVITY" ); break; case SQL_ATTR_CURSOR_TYPE: sprintf((char*) s, "SQL_ATTR_CURSOR_TYPE" ); break; case SQL_ATTR_ENABLE_AUTO_IPD: sprintf((char*) s, "SQL_ATTR_ENABLE_AUTO_IPD" ); break; case SQL_ATTR_FETCH_BOOKMARK_PTR: sprintf((char*) s, "SQL_ATTR_FETCH_BOOKMARK_PTR" ); break; case SQL_ATTR_IMP_PARAM_DESC: sprintf((char*) s, "SQL_ATTR_IMP_PARAM_DESC" ); break; case SQL_ATTR_IMP_ROW_DESC: sprintf((char*) s, "SQL_ATTR_IMP_ROW_DESC" ); break; case SQL_ATTR_KEYSET_SIZE: sprintf((char*) s, "SQL_ATTR_KEYSET_SIZE" ); break; case SQL_ATTR_MAX_LENGTH: sprintf((char*) s, "SQL_ATTR_MAX_LENGTH" ); break; case SQL_ATTR_MAX_ROWS: sprintf((char*) s, "SQL_ATTR_MAX_ROWS" ); break; case SQL_ATTR_METADATA_ID: sprintf((char*) s, "SQL_ATTR_METADATA_ID" ); break; case SQL_ATTR_NOSCAN: sprintf((char*) s, "SQL_ATTR_NOSCAN" ); break; case SQL_ATTR_PARAM_BIND_OFFSET_PTR: sprintf((char*) s, "SQL_ATTR_PARAM_BIND_OFFSET_PTR" ); break; case SQL_ATTR_PARAM_BIND_TYPE: sprintf((char*) s, "SQL_ATTR_PARAM_BIND_TYPE" ); break; case SQL_ATTR_PARAM_OPERATION_PTR: sprintf((char*) s, "SQL_ATTR_PARAM_OPERATION_PTR" ); break; case SQL_ATTR_PARAM_STATUS_PTR: sprintf((char*) s, "SQL_ATTR_PARAM_STATUS_PTR" ); break; case SQL_ATTR_PARAMS_PROCESSED_PTR: sprintf((char*) s, "SQL_ATTR_PARAMS_PROCESSED_PTR" ); break; case SQL_ATTR_PARAMSET_SIZE: sprintf((char*) s, "SQL_ATTR_PARAMSET_SIZE" ); break; case SQL_ATTR_QUERY_TIMEOUT: sprintf((char*) s, "SQL_ATTR_QUERY_TIMEOUT" ); break; case SQL_ATTR_RETRIEVE_DATA: sprintf((char*) s, "SQL_ATTR_RETRIEVE_DATA" ); break; case SQL_ROWSET_SIZE: sprintf((char*) s, "SQL_ROWSET_SIZE" ); break; case SQL_ATTR_ROW_ARRAY_SIZE: sprintf((char*) s, "SQL_ATTR_ROW_ARRAY_SIZE" ); break; case SQL_ATTR_ROW_BIND_OFFSET_PTR: sprintf((char*) s, "SQL_ATTR_ROW_BIND_OFFSET_PTR" ); break; case SQL_ATTR_ROW_BIND_TYPE: sprintf((char*) s, "SQL_ATTR_ROW_BIND_TYPE" ); break; case SQL_ATTR_ROW_NUMBER: sprintf((char*) s, "SQL_ATTR_ROW_NUMBER" ); break; case SQL_ATTR_ROW_OPERATION_PTR: sprintf((char*) s, "SQL_ATTR_ROW_OPERATION_PTR" ); break; case SQL_ATTR_ROW_STATUS_PTR: sprintf((char*) s, "SQL_ATTR_ROW_STATUS_PTR" ); break; case SQL_ATTR_ROWS_FETCHED_PTR: sprintf((char*) s, "SQL_ATTR_ROWS_FETCHED_PTR" ); break; case SQL_ATTR_SIMULATE_CURSOR: sprintf((char*) s, "SQL_ATTR_SIMULATE_CURSOR" ); break; case SQL_ATTR_USE_BOOKMARKS: sprintf((char*) s, "SQL_ATTR_USE_BOOKMARKS" ); break; default: sprintf((char*) s, "%d", (int)type ); } return (char*) s; } /* * return a SQLGetInfo type as a string */ char * __info_as_string( SQLCHAR *s, SQLINTEGER type ) { switch( type ) { case SQL_ACCESSIBLE_PROCEDURES: sprintf((char*) s, "SQL_ACCESSIBLE_PROCEDURES" ); break; case SQL_ACCESSIBLE_TABLES: sprintf((char*) s, "SQL_ACCESSIBLE_TABLES" ); break; case SQL_ACTIVE_ENVIRONMENTS: sprintf((char*) s, "SQL_ACTIVE_ENVIRONMENTS" ); break; case SQL_AGGREGATE_FUNCTIONS: sprintf((char*) s, "SQL_AGGREGATE_FUNCTIONS" ); break; case SQL_ALTER_DOMAIN: sprintf((char*) s, "SQL_ALTER_DOMAIN" ); break; case SQL_ALTER_TABLE: sprintf((char*) s, "SQL_ALTER_TABLE" ); break; case SQL_ASYNC_MODE: sprintf((char*) s, "SQL_ASYNC_MODE" ); break; case SQL_BATCH_ROW_COUNT: sprintf((char*) s, "SQL_BATCH_ROW_COUNT" ); break; case SQL_BATCH_SUPPORT: sprintf((char*) s, "SQL_BATCH_SUPPORT" ); break; case SQL_BOOKMARK_PERSISTENCE: sprintf((char*) s, "SQL_BOOKMARK_PERSISTENCE" ); break; case SQL_CATALOG_LOCATION: sprintf((char*) s, "SQL_CATALOG_LOCATION" ); break; case SQL_CATALOG_NAME: sprintf((char*) s, "SQL_CATALOG_NAME" ); break; case SQL_CATALOG_NAME_SEPARATOR: sprintf((char*) s, "SQL_CATALOG_NAME_SEPARATOR" ); break; case SQL_CATALOG_TERM: sprintf((char*) s, "SQL_CATALOG_TERM" ); break; case SQL_CATALOG_USAGE: sprintf((char*) s, "SQL_CATALOG_USAGE" ); break; case SQL_COLLATION_SEQ: sprintf((char*) s, "SQL_COLLATION_SEQ" ); break; case SQL_COLUMN_ALIAS: sprintf((char*) s, "SQL_COLUMN_ALIAS" ); break; case SQL_CONCAT_NULL_BEHAVIOR: sprintf((char*) s, "SQL_CONCAT_NULL_BEHAVIOR" ); break; case SQL_CONVERT_BIGINT: sprintf((char*) s, "SQL_CONVERT_BIGINT" ); break; case SQL_CONVERT_BINARY: sprintf((char*) s, "SQL_CONVERT_BINARY" ); break; case SQL_CONVERT_BIT: sprintf((char*) s, "SQL_CONVERT_BIT" ); break; case SQL_CONVERT_CHAR: sprintf((char*) s, "SQL_CONVERT_CHAR" ); break; case SQL_CONVERT_DATE: sprintf((char*) s, "SQL_CONVERT_DATE" ); break; case SQL_CONVERT_DECIMAL: sprintf((char*) s, "SQL_CONVERT_DECIMAL" ); break; case SQL_CONVERT_DOUBLE: sprintf((char*) s, "SQL_CONVERT_DOUBLE" ); break; case SQL_CONVERT_FLOAT: sprintf((char*) s, "SQL_CONVERT_FLOAT" ); break; case SQL_CONVERT_INTEGER: sprintf((char*) s, "SQL_CONVERT_INTEGER" ); break; case SQL_CONVERT_INTERVAL_YEAR_MONTH: sprintf((char*) s, "SQL_CONVERT_INTERVAL_YEAR_MONTH" ); break; case SQL_CONVERT_INTERVAL_DAY_TIME: sprintf((char*) s, "SQL_CONVERT_INTERVAL_DAY_TIME" ); break; case SQL_CONVERT_LONGVARBINARY: sprintf((char*) s, "SQL_CONVERT_LONGVARBINARY" ); break; case SQL_CONVERT_LONGVARCHAR: sprintf((char*) s, "SQL_CONVERT_LONGVARCHAR" ); break; case SQL_CONVERT_NUMERIC: sprintf((char*) s, "SQL_CONVERT_NUMERIC" ); break; case SQL_CONVERT_REAL: sprintf((char*) s, "SQL_CONVERT_REAL" ); break; case SQL_CONVERT_SMALLINT: sprintf((char*) s, "SQL_CONVERT_SMALLINT" ); break; case SQL_CONVERT_TIME: sprintf((char*) s, "SQL_CONVERT_TIME" ); break; case SQL_CONVERT_TIMESTAMP: sprintf((char*) s, "SQL_CONVERT_TIMESTAMP" ); break; case SQL_CONVERT_TINYINT: sprintf((char*) s, "SQL_CONVERT_TINYINT" ); break; case SQL_CONVERT_VARBINARY: sprintf((char*) s, "SQL_CONVERT_VARBINARY" ); break; case SQL_CONVERT_VARCHAR: sprintf((char*) s, "SQL_CONVERT_VARCHAR" ); break; case SQL_CONVERT_FUNCTIONS: sprintf((char*) s, "SQL_CONVERT_FUNCTIONS" ); break; case SQL_CORRELATION_NAME: sprintf((char*) s, "SQL_CORRELATION_NAME" ); break; case SQL_CREATE_ASSERTION: sprintf((char*) s, "SQL_CREATE_ASSERTION" ); break; case SQL_CREATE_CHARACTER_SET: sprintf((char*) s, "SQL_CREATE_CHARACTER_SET" ); break; case SQL_CREATE_COLLATION: sprintf((char*) s, "SQL_CREATE_COLLATION" ); break; case SQL_CREATE_DOMAIN: sprintf((char*) s, "SQL_CREATE_DOMAIN" ); break; case SQL_CREATE_SCHEMA: sprintf((char*) s, "SQL_CREATE_SCHEMA" ); break; case SQL_CREATE_TABLE: sprintf((char*) s, "SQL_CREATE_TABLE" ); break; case SQL_CREATE_TRANSLATION: sprintf((char*) s, "SQL_CREATE_TRANSLATION" ); break; case SQL_CREATE_VIEW: sprintf((char*) s, "SQL_CREATE_VIEW" ); break; case SQL_CURSOR_COMMIT_BEHAVIOR: sprintf((char*) s, "SQL_CURSOR_COMMIT_BEHAVIOR" ); break; case SQL_CURSOR_ROLLBACK_BEHAVIOR: sprintf((char*) s, "SQL_CURSOR_ROLLBACK_BEHAVIOR" ); break; case SQL_CURSOR_SENSITIVITY: sprintf((char*) s, "SQL_CURSOR_SENSITIVITY" ); break; case SQL_DATA_SOURCE_NAME: sprintf((char*) s, "SQL_DATA_SOURCE_NAME" ); break; case SQL_DATA_SOURCE_READ_ONLY: sprintf((char*) s, "SQL_DATA_SOURCE_READ_ONLY" ); break; case SQL_DATABASE_NAME: sprintf((char*) s, "SQL_DATABASE_NAME" ); break; case SQL_DATETIME_LITERALS: sprintf((char*) s, "SQL_DATETIME_LITERALS" ); break; case SQL_DBMS_NAME: sprintf((char*) s, "SQL_DBMS_NAME" ); break; case SQL_DBMS_VER: sprintf((char*) s, "SQL_DBMS_VER" ); break; case SQL_DDL_INDEX: sprintf((char*) s, "SQL_DDL_INDEX" ); break; case SQL_DEFAULT_TXN_ISOLATION: sprintf((char*) s, "SQL_DEFAULT_TXN_ISOLATION" ); break; case SQL_DESCRIBE_PARAMETER: sprintf((char*) s, "SQL_DESCRIBE_PARAMETER" ); break; case SQL_DRIVER_NAME: sprintf((char*) s, "SQL_DRIVER_NAME" ); break; case SQL_DRIVER_HLIB: sprintf((char*) s, "SQL_DRIVER_HLIB" ); break; case SQL_DRIVER_HSTMT: sprintf((char*) s, "SQL_DRIVER_HSTMT" ); break; case SQL_DRIVER_ODBC_VER: sprintf((char*) s, "SQL_DRIVER_ODBC_VER" ); break; case SQL_DRIVER_VER: sprintf((char*) s, "SQL_DRIVER_VER" ); break; case SQL_ODBC_VER: sprintf((char*) s, "SQL_ODBC_VER" ); break; case SQL_DROP_ASSERTION: sprintf((char*) s, "SQL_DROP_ASSERTION" ); break; case SQL_DROP_CHARACTER_SET: sprintf((char*) s, "SQL_DROP_CHARACTER_SET" ); break; case SQL_DROP_COLLATION: sprintf((char*) s, "SQL_DROP_COLLATION" ); break; case SQL_DROP_DOMAIN: sprintf((char*) s, "SQL_DROP_DOMAIN" ); break; case SQL_DROP_SCHEMA: sprintf((char*) s, "SQL_DROP_SCHEMA" ); break; case SQL_DROP_TABLE: sprintf((char*) s, "SQL_DROP_TABLE" ); break; case SQL_DROP_TRANSLATION: sprintf((char*) s, "SQL_DROP_TRANSLATION" ); break; case SQL_DROP_VIEW: sprintf((char*) s, "SQL_DROP_VIEW" ); break; case SQL_DYNAMIC_CURSOR_ATTRIBUTES1: sprintf((char*) s, "SQL_DYNAMIC_CURSOR_ATTRIBUTES1" ); break; case SQL_DYNAMIC_CURSOR_ATTRIBUTES2: sprintf((char*) s, "SQL_EXPRESSIONS_IN_ORDERBY" ); break; case SQL_EXPRESSIONS_IN_ORDERBY: sprintf((char*) s, "SQL_EXPRESSIONS_IN_ORDERBY" ); break; case SQL_FILE_USAGE: sprintf((char*) s, "SQL_FILE_USAGE" ); break; case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1: sprintf((char*) s, "SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1" ); break; case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2: sprintf((char*) s, "SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2" ); break; case SQL_GETDATA_EXTENSIONS: sprintf((char*) s, "SQL_GETDATA_EXTENSIONS" ); break; case SQL_GROUP_BY: sprintf((char*) s, "SQL_GROUP_BY" ); break; case SQL_IDENTIFIER_CASE: sprintf((char*) s, "SQL_IDENTIFIER_CASE" ); break; case SQL_IDENTIFIER_QUOTE_CHAR: sprintf((char*) s, "SQL_IDENTIFIER_QUOTE_CHAR" ); break; case SQL_INDEX_KEYWORDS: sprintf((char*) s, "SQL_INDEX_KEYWORDS" ); break; case SQL_INFO_SCHEMA_VIEWS: sprintf((char*) s, "SQL_INFO_SCHEMA_VIEWS" ); break; case SQL_INSERT_STATEMENT: sprintf((char*) s, "SQL_INSERT_STATEMENT" ); break; case SQL_INTEGRITY: sprintf((char*) s, "SQL_INTEGRITY" ); break; case SQL_KEYSET_CURSOR_ATTRIBUTES1: sprintf((char*) s, "SQL_KEYSET_CURSOR_ATTRIBUTES1" ); break; case SQL_KEYSET_CURSOR_ATTRIBUTES2: sprintf((char*) s, "SQL_KEYSET_CURSOR_ATTRIBUTES2" ); break; case SQL_KEYWORDS: sprintf((char*) s, "SQL_KEYWORDS" ); break; case SQL_LIKE_ESCAPE_CLAUSE: sprintf((char*) s, "SQL_LIKE_ESCAPE_CLAUSE" ); break; case SQL_MAX_ASYNC_CONCURRENT_STATEMENTS: sprintf((char*) s, "SQL_MAX_ASYNC_CONCURRENT_STATEMENTS" ); break; case SQL_MAX_BINARY_LITERAL_LEN: sprintf((char*) s, "SQL_MAX_BINARY_LITERAL_LEN" ); break; case SQL_MAX_CATALOG_NAME_LEN: sprintf((char*) s, "SQL_MAX_CATALOG_NAME_LEN" ); break; case SQL_MAX_CHAR_LITERAL_LEN: sprintf((char*) s, "SQL_MAX_CHAR_LITERAL_LEN" ); break; case SQL_MAX_COLUMN_NAME_LEN: sprintf((char*) s, "SQL_MAX_COLUMN_NAME_LEN" ); break; case SQL_MAX_COLUMNS_IN_GROUP_BY: sprintf((char*) s, "SQL_MAX_COLUMNS_IN_GROUP_BY" ); break; case SQL_MAX_COLUMNS_IN_INDEX: sprintf((char*) s, "SQL_MAX_COLUMNS_IN_INDEX" ); break; case SQL_MAX_COLUMNS_IN_SELECT: sprintf((char*) s, "SQL_MAX_COLUMNS_IN_SELECT" ); break; case SQL_MAX_COLUMNS_IN_ORDER_BY: sprintf((char*) s, "SQL_MAX_COLUMNS_IN_ORDER_BY" ); break; case SQL_MAX_COLUMNS_IN_TABLE: sprintf((char*) s, "SQL_MAX_COLUMNS_IN_TABLE" ); break; case SQL_MAX_CONCURRENT_ACTIVITIES: sprintf((char*) s, "SQL_MAX_CONCURRENT_ACTIVITIES" ); break; case SQL_MAX_CURSOR_NAME_LEN: sprintf((char*) s, "SQL_MAX_CURSOR_NAME_LEN" ); break; case SQL_MAX_DRIVER_CONNECTIONS: sprintf((char*) s, "SQL_MAX_DRIVER_CONNECTIONS" ); break; case SQL_MAX_IDENTIFIER_LEN: sprintf((char*) s, "SQL_MAX_IDENTIFIER_LEN" ); break; case SQL_MAX_INDEX_SIZE: sprintf((char*) s, "SQL_MAX_INDEX_SIZE" ); break; case SQL_MAX_PROCEDURE_NAME_LEN: sprintf((char*) s, "SQL_MAX_PROCEDURE_NAME_LEN" ); break; case SQL_MAX_ROW_SIZE: sprintf((char*) s, "SQL_MAX_ROW_SIZE" ); break; case SQL_MAX_ROW_SIZE_INCLUDES_LONG: sprintf((char*) s, "SQL_MAX_ROW_SIZE_INCLUDES_LONG" ); break; case SQL_MAX_SCHEMA_NAME_LEN: sprintf((char*) s, "SQL_MAX_SCHEMA_NAME_LEN" ); break; case SQL_MAX_STATEMENT_LEN: sprintf((char*) s, "SQL_MAX_STATEMENT_LEN" ); break; case SQL_MAX_TABLE_NAME_LEN: sprintf((char*) s, "SQL_MAX_TABLE_NAME_LEN" ); break; case SQL_MAX_TABLES_IN_SELECT: sprintf((char*) s, "SQL_MAX_TABLES_IN_SELECT" ); break; case SQL_MAX_USER_NAME_LEN: sprintf((char*) s, "SQL_MAX_USER_NAME_LEN" ); break; case SQL_MULT_RESULT_SETS: sprintf((char*) s, "SQL_MULT_RESULT_SETS" ); break; case SQL_MULTIPLE_ACTIVE_TXN: sprintf((char*) s, "SQL_MULTIPLE_ACTIVE_TXN" ); break; case SQL_NEED_LONG_DATA_LEN: sprintf((char*) s, "SQL_NEED_LONG_DATA_LEN" ); break; case SQL_NON_NULLABLE_COLUMNS: sprintf((char*) s, "SQL_NON_NULLABLE_COLUMNS" ); break; case SQL_NULL_COLLATION: sprintf((char*) s, "SQL_NULL_COLLATION" ); break; case SQL_NUMERIC_FUNCTIONS: sprintf((char*) s, "SQL_NUMERIC_FUNCTIONS" ); break; case SQL_ODBC_INTERFACE_CONFORMANCE: sprintf((char*) s, "SQL_ODBC_INTERFACE_CONFORMANCE" ); break; case SQL_OJ_CAPABILITIES: sprintf((char*) s, "SQL_OJ_CAPABILITIES" ); break; case SQL_ORDER_BY_COLUMNS_IN_SELECT: sprintf((char*) s, "SQL_ORDER_BY_COLUMNS_IN_SELECT" ); break; case SQL_PARAM_ARRAY_ROW_COUNTS: sprintf((char*) s, "SQL_PARAM_ARRAY_ROW_COUNTS" ); break; case SQL_PARAM_ARRAY_SELECTS: sprintf((char*) s, "SQL_PARAM_ARRAY_SELECTS" ); break; case SQL_PROCEDURE_TERM: sprintf((char*) s, "SQL_PROCEDURE_TERM" ); break; case SQL_PROCEDURES: sprintf((char*) s, "SQL_PROCEDURES" ); break; case SQL_QUOTED_IDENTIFIER_CASE: sprintf((char*) s, "SQL_QUOTED_IDENTIFIER_CASE" ); break; case SQL_ROW_UPDATES: sprintf((char*) s, "SQL_ROW_UPDATES" ); break; case SQL_SCHEMA_TERM: sprintf((char*) s, "SQL_SCHEMA_TERM" ); break; case SQL_SCHEMA_USAGE: sprintf((char*) s, "SQL_SCHEMA_USAGE" ); break; case SQL_SCROLL_OPTIONS: sprintf((char*) s, "SQL_SCROLL_OPTIONS" ); break; case SQL_SEARCH_PATTERN_ESCAPE: sprintf((char*) s, "SQL_SEARCH_PATTERN_ESCAPE" ); break; case SQL_SERVER_NAME: sprintf((char*) s, "SQL_SERVER_NAME" ); break; case SQL_SPECIAL_CHARACTERS: sprintf((char*) s, "SQL_SPECIAL_CHARACTERS" ); break; case SQL_SQL_CONFORMANCE: sprintf((char*) s, "SQL_SQL_CONFORMANCE" ); break; case SQL_SQL92_DATETIME_FUNCTIONS: sprintf((char*) s, "SQL_SQL92_DATETIME_FUNCTIONS" ); break; case SQL_SQL92_FOREIGN_KEY_DELETE_RULE: sprintf((char*) s, "SQL_SQL92_FOREIGN_KEY_DELETE_RULE" ); break; case SQL_SQL92_FOREIGN_KEY_UPDATE_RULE: sprintf((char*) s, "SQL_SQL92_FOREIGN_KEY_UPDATE_RULE" ); break; case SQL_SQL92_GRANT: sprintf((char*) s, "SQL_SQL92_GRANT" ); break; case SQL_SQL92_NUMERIC_VALUE_FUNCTIONS: sprintf((char*) s, "SQL_SQL92_NUMERIC_VALUE_FUNCTIONS" ); break; case SQL_SQL92_PREDICATES: sprintf((char*) s, "SQL_SQL92_PREDICATES" ); break; case SQL_SQL92_RELATIONAL_JOIN_OPERATORS: sprintf((char*) s, "SQL_SQL92_RELATIONAL_JOIN_OPERATORS" ); break; case SQL_SQL92_REVOKE: sprintf((char*) s, "SQL_SQL92_REVOKE" ); break; case SQL_SQL92_ROW_VALUE_CONSTRUCTOR: sprintf((char*) s, "SQL_SQL92_ROW_VALUE_CONSTRUCTOR" ); break; case SQL_SQL92_STRING_FUNCTIONS: sprintf((char*) s, "SQL_SQL92_STRING_EXPRESSIONS" ); break; case SQL_SQL92_VALUE_EXPRESSIONS: sprintf((char*) s, "SQL_SQL92_VALUE_EXPRESSIONS" ); break; case SQL_STANDARD_CLI_CONFORMANCE: sprintf((char*) s, "SQL_STANDARD_CLI_CONFORMANCE" ); break; case SQL_STATIC_CURSOR_ATTRIBUTES1: sprintf((char*) s, "SQL_STATIC_CURSOR_ATTRIBUTES1" ); break; case SQL_STATIC_CURSOR_ATTRIBUTES2: sprintf((char*) s, "SQL_STATIC_CURSOR_ATTRIBUTES2" ); break; case SQL_STRING_FUNCTIONS: sprintf((char*) s, "SQL_STRING_FUNCTIONS" ); break; case SQL_SUBQUERIES: sprintf((char*) s, "SQL_SUBQUERIES" ); break; case SQL_SYSTEM_FUNCTIONS: sprintf((char*) s, "SQL_SYSTEM_FUNCTIONS" ); break; case SQL_TABLE_TERM: sprintf((char*) s, "SQL_TABLE_TERM" ); break; case SQL_TIMEDATE_ADD_INTERVALS: sprintf((char*) s, "SQL_TIMEDATE_ADD_INTERVALS" ); break; case SQL_TIMEDATE_DIFF_INTERVALS: sprintf((char*) s, "SQL_TIMEDATE_DIFF_INTERVALS" ); break; case SQL_TIMEDATE_FUNCTIONS: sprintf((char*) s, "SQL_TIMEDATE_FUNCTIONS" ); break; case SQL_TXN_CAPABLE: sprintf((char*) s, "SQL_TXN_CAPABLE" ); break; case SQL_TXN_ISOLATION_OPTION: sprintf((char*) s, "SQL_TXN_ISOLATION_OPTION" ); break; case SQL_UNION: sprintf((char*) s, "SQL_UNION" ); break; case SQL_USER_NAME: sprintf((char*) s, "SQL_USER_NAME" ); break; case SQL_XOPEN_CLI_YEAR: sprintf((char*) s, "SQL_XOPEN_CLI_YEAR" ); break; case SQL_FETCH_DIRECTION: sprintf((char*) s, "SQL_FETCH_DIRECTION" ); break; case SQL_LOCK_TYPES: sprintf((char*) s, "SQL_LOCK_TYPES" ); break; case SQL_ODBC_API_CONFORMANCE: sprintf((char*) s, "SQL_ODBC_API_CONFORMANCE" ); break; case SQL_ODBC_SQL_CONFORMANCE: sprintf((char*) s, "SQL_ODBC_SQL_CONFORMANCE" ); break; case SQL_POS_OPERATIONS: sprintf((char*) s, "SQL_POS_OPERATIONS" ); break; case SQL_POSITIONED_STATEMENTS: sprintf((char*) s, "SQL_POSITIONED_STATEMENTS" ); break; case SQL_SCROLL_CONCURRENCY: sprintf((char*) s, "SQL_SCROLL_CONCURRENCY" ); break; case SQL_STATIC_SENSITIVITY: sprintf((char*) s, "SQL_STATIC_SENSITIVITY" ); break; case SQL_OUTER_JOINS: sprintf((char*) s, "SQL_OUTER_JOINS" ); break; case SQL_DRIVER_AWARE_POOLING_SUPPORTED: sprintf((char*) s, "SQL_DRIVER_AWARE_POOLING_SUPPORTED" ); break; default: sprintf((char*) s, "%d", (int)type ); } return (char*) s; } /* * convert from type 3 error states to type 2 */ struct state_map { char ver2[6]; char ver3[6]; }; static const struct state_map state_mapping_3_2[] = { { "01S03", "01001" }, { "01S04", "01001" }, { "22003", "HY019" }, { "22005", "22018" }, { "22008", "22007" }, { "24000", "07005" }, { "37000", "42000" }, { "70100", "HY018" }, { "S0001", "42S01" }, { "S0002", "42S02" }, { "S0011", "42S11" }, { "S0012", "42S12" }, { "S0021", "42S21" }, { "S0022", "42S22" }, { "S0023", "42S23" }, { "S1000", "HY000" }, { "S1001", "HY001" }, { "S1002", "07009" }, { "S1003", "HY003" }, { "S1004", "HY004" }, { "S1007", "HY007" }, { "S1008", "HY008" }, { "S1009", "HY009" }, { "S1010", "HY010" }, { "S1011", "HY011" }, { "S1012", "HY012" }, { "S1090", "HY090" }, { "S1091", "HY091" }, { "S1092", "HY092" }, { "S1093", "07009" }, { "S1096", "HY096" }, { "S1097", "HY097" }, { "S1098", "HY098" }, { "S1099", "HY099" }, { "S1100", "HY100" }, { "S1101", "HY101" }, { "S1103", "HY103" }, { "S1104", "HY104" }, { "S1105", "HY105" }, { "S1106", "HY106" }, { "S1107", "HY107" }, { "S1108", "HY108" }, { "S1109", "HY109" }, { "S1110", "HY110" }, { "S1111", "HY111" }, { "S1C00", "HYC00" }, { "S1T00", "HYT00" }, { "", "" } }; /* * the book doesn't say that it should map ODBC 2 states to ODBC 3 * but the MS Windows DM can be seen to do just that */ static const struct state_map state_mapping_2_3[] = { { "01S03", "01001" }, { "01S04", "01001" }, { "22005", "22018" }, { "37000", "42000" }, { "70100", "HY018" }, { "S0001", "42S01" }, { "S0002", "42S02" }, { "S0011", "42S11" }, { "S0012", "42S12" }, { "S0021", "42S21" }, { "S0022", "42S22" }, { "S0023", "42S23" }, { "S1000", "HY000" }, { "S1001", "HY001" }, { "S1002", "07009" }, { "S1003", "HY003" }, { "S1004", "HY004" }, { "S1007", "HY007" }, { "S1008", "HY008" }, { "S1009", "HY009" }, { "S1010", "HY010" }, { "S1011", "HY011" }, { "S1012", "HY012" }, { "S1090", "HY090" }, { "S1091", "HY091" }, { "S1092", "HY092" }, { "S1093", "07009" }, { "S1096", "HY096" }, { "S1097", "HY097" }, { "S1098", "HY098" }, { "S1099", "HY099" }, { "S1100", "HY100" }, { "S1101", "HY101" }, { "S1103", "HY103" }, { "S1104", "HY104" }, { "S1105", "HY105" }, { "S1106", "HY106" }, { "S1107", "HY107" }, { "S1108", "HY108" }, { "S1109", "HY109" }, { "S1110", "HY110" }, { "S1111", "HY111" }, { "S1C00", "HYC00" }, { "S1T00", "HYT00" }, { "", "" } }; /* * map ODBC3 states to/from ODBC 2 */ void __map_error_state( char * state, int requested_version ) { const struct state_map *ptr; if ( !state ) return; if ( requested_version == SQL_OV_ODBC2 ) { ptr = state_mapping_3_2; while( ptr -> ver3[0] ) { if ( strcmp( ptr -> ver3, state ) == 0 ) { strcpy( state, ptr -> ver2 ); return; } ptr ++; } } else if ( requested_version >= SQL_OV_ODBC3 ) { ptr = state_mapping_2_3; while( ptr -> ver2[0] ) { if ( strcmp( ptr -> ver2, state ) == 0 ) { strcpy( state, ptr -> ver3 ); return; } ptr ++; } } } void __map_error_state_w( SQLWCHAR * wstate, int requested_version ) { char state[ 6 ]; unicode_to_ansi_copy( state, 6, wstate, SQL_NTS, NULL, NULL ); __map_error_state( state, requested_version ); ansi_to_unicode_copy( wstate, state, SQL_NTS, NULL, NULL ); } /* * return the process id as a string */ char * __get_pid( SQLCHAR * str ) { sprintf((char *) str, "%d", getpid()); return (char*)str; } /* * take a SQL string and its length indicator and format it for * display */ char * __string_with_length( SQLCHAR *ostr, SQLCHAR *instr, SQLINTEGER len ) { if ( instr == NULL ) { sprintf((char*) ostr, "[NULL]" ); } else if ( len == SQL_NTS ) { if ( strlen((char*) instr ) > LOG_MESSAGE_LEN ) { sprintf((char*) ostr, "[%.*s...][length = %ld (SQL_NTS)]", LOG_MESSAGE_LEN, instr, (long int)strlen((char*) instr )); } else { sprintf((char*) ostr, "[%s][length = %ld (SQL_NTS)]", instr, (long int)strlen((char*) instr )); } } else { if ( len < LOG_MESSAGE_LEN ) sprintf((char*) ostr, "[%.*s][length = %d]", (int)len, instr, (int)len ); else sprintf((char*) ostr, "[%.*s...][length = %d]", LOG_MESSAGE_LEN, instr, (int)len ); } return (char*)ostr; } char * __wstring_with_length( SQLCHAR *ostr, SQLWCHAR *instr, SQLINTEGER len ) { int i = 0; char tmp[ LOG_MESSAGE_LEN ]; if ( instr == NULL ) { sprintf((char*) ostr, "[NULL]" ); } else if ( len == SQL_NTS ) { if ( ( i = wide_strlen( instr ) ) < LOG_MESSAGE_LEN ) { strcpy((char*) ostr, "[" ); unicode_to_ansi_copy((char*) ostr + 1, LOG_MESSAGE_LEN, instr, i, NULL, NULL ); strcat((char*) ostr, "]" ); } else { strcpy((char*) ostr, "[" ); unicode_to_ansi_copy((char*) ostr + 1, LOG_MESSAGE_LEN, instr, LOG_MESSAGE_LEN, NULL, NULL ); strcat((char*) ostr, "...]" ); } sprintf( tmp, "[length = %d (SQL_NTS)]", i ); strcat((char*) ostr, tmp ); } else { if ( len < LOG_MESSAGE_LEN ) { strcpy((char*) ostr, "[" ); unicode_to_ansi_copy((char*) ostr + 1, LOG_MESSAGE_LEN, instr, len, NULL, NULL ); strcat((char*) ostr, "]" ); } else { strcpy((char*) ostr, "[" ); unicode_to_ansi_copy((char*) ostr + 1, LOG_MESSAGE_LEN, instr, LOG_MESSAGE_LEN, NULL, NULL ); strcat((char*) ostr, "...]" ); } sprintf( tmp, "[length = %d]", (int)len ); strcat((char*) ostr, tmp ); } return (char*)ostr; } /* * replace password with **** */ char * __string_with_length_pass( SQLCHAR *out, SQLCHAR *str, SQLINTEGER len ) { char *p = __string_with_length( out, str, len ); /* * the string will be of the form [text] */ if ( str ) { char * ptr = p + 1; while ( *ptr && *ptr != ']' ) { *ptr = '*'; ptr ++; } } return p; } char * __wstring_with_length_pass( SQLCHAR *out, SQLWCHAR *str, SQLINTEGER len ) { char *p = __wstring_with_length( out, str, len ); /* * the string will be of the form [text] */ if ( str ) { char * ptr = p + 1; while ( *ptr && *ptr != ']' ) { *ptr = '*'; ptr ++; } } return p; } /* * mask out PWD=str; * wont work on lower case pwd but there you go */ char * __string_with_length_hide_pwd( SQLCHAR *out, SQLCHAR *str, SQLINTEGER len ) { char *p = __string_with_length( out, str, len ); if ( str ) { char *ptr; ptr = strstr( p, "PWD=" ); while ( ptr ) { ptr += 4; while ( *ptr && *ptr != ';' && *ptr != ']' ) { *ptr = '*'; ptr ++; } ptr = strstr( ptr, "PWD=" ); } } return p; } char * __wstring_with_length_hide_pwd( SQLCHAR *out, SQLWCHAR *str, SQLINTEGER len ) { char *p = __wstring_with_length( out, str, len ); if ( str ) { char *ptr; ptr = strstr( p, "PWD=" ); while ( ptr ) { ptr += 4; while ( *ptr && *ptr != ';' && *ptr != ']' ) { *ptr = '*'; ptr ++; } ptr = strstr( ptr, "PWD=" ); } } return p; } /* * display a C type as a string */ char * __c_as_text( SQLINTEGER type ) { switch( type ) { case SQL_C_CHAR: return "SQL_C_CHAR"; case SQL_C_LONG: return "SQL_C_LONG"; case SQL_C_SHORT: return "SQL_C_SHORT"; case SQL_C_FLOAT: return "SQL_C_FLOAT"; case SQL_C_DOUBLE: return "SQL_C_DOUBLE"; case SQL_C_NUMERIC: return "SQL_C_NUMERIC"; case SQL_C_DEFAULT: return "SQL_C_DEFAULT"; case SQL_C_DATE: return "SQL_C_DATE"; case SQL_C_TIME: return "SQL_C_TIME"; case SQL_C_TIMESTAMP: return "SQL_C_TIMESTAMP"; case SQL_C_TYPE_DATE: return "SQL_C_TYPE_DATE"; case SQL_C_TYPE_TIME: return "SQL_C_TYPE_TIME"; case SQL_C_TYPE_TIMESTAMP: return "SQL_C_TYPE_TIMESTAMP "; case SQL_C_INTERVAL_YEAR: return "SQL_C_INTERVAL_YEAR "; case SQL_C_INTERVAL_MONTH: return "SQL_C_INTERVAL_MONTH"; case SQL_C_INTERVAL_DAY: return "SQL_C_INTERVAL_DAY "; case SQL_C_INTERVAL_HOUR: return "SQL_C_INTERVAL_HOUR"; case SQL_C_INTERVAL_MINUTE: return "SQL_C_INTERVAL_MINUTE"; case SQL_C_INTERVAL_SECOND: return "SQL_C_INTERVAL_SECOND"; case SQL_C_INTERVAL_YEAR_TO_MONTH: return "SQL_C_INTERVAL_YEAR_TO_MONTH"; case SQL_C_INTERVAL_DAY_TO_HOUR: return "SQL_C_INTERVAL_DAY_TO_HOUR "; case SQL_C_INTERVAL_DAY_TO_MINUTE: return "SQL_C_INTERVAL_DAY_TO_MINUTE"; case SQL_C_INTERVAL_DAY_TO_SECOND: return "SQL_C_INTERVAL_DAY_TO_SECOND"; case SQL_C_INTERVAL_HOUR_TO_MINUTE: return "SQL_C_INTERVAL_HOUR_TO_MINUTE"; case SQL_C_INTERVAL_HOUR_TO_SECOND: return "SQL_C_INTERVAL_HOUR_TO_SECOND"; case SQL_C_INTERVAL_MINUTE_TO_SECOND: return "SQL_C_INTERVAL_MINUTE_TO_SECOND"; case SQL_C_BINARY: return "SQL_C_BINARY"; case SQL_C_BIT: return "SQL_C_BIT"; case SQL_C_SBIGINT: return "SQL_C_SBIGINT"; case SQL_C_UBIGINT: return "SQL_C_UBIGINT"; case SQL_C_TINYINT: return "SQL_C_TINYINT"; case SQL_C_SLONG: return "SQL_C_SLONG"; case SQL_C_SSHORT: return "SQL_C_SSHORT"; case SQL_C_STINYINT: return "SQL_C_STINYINT"; case SQL_C_ULONG: return "SQL_C_ULONG"; case SQL_C_USHORT: return "SQL_C_USHORT"; case SQL_C_UTINYINT: return "SQL_C_UTINYINT"; case SQL_C_GUID: return "SQL_C_GUID"; case SQL_C_WCHAR: return "SQL_C_WCHAR"; default: return ""; } } /* * display a SQL type as a string */ char * __sql_as_text( SQLINTEGER type ) { switch( type ) { case SQL_DECIMAL: return "SQL_DECIMAL"; case SQL_VARCHAR: return "SQL_VARCHAR"; case SQL_LONGVARCHAR: return "SQL_LONGVARCHAR"; case SQL_LONGVARBINARY: return "SQL_LONGVARBINARY"; case SQL_C_BINARY: return "SQL_C_BINARY"; case SQL_VARBINARY: return "SQL_VARBINARY"; case SQL_CHAR: return "SQL_CHAR"; case SQL_WCHAR: return "SQL_WCHAR"; case SQL_WVARCHAR: return "SQL_WVARCHAR"; case SQL_INTEGER: return "SQL_INTEGER"; case SQL_C_ULONG: return "SQL_C_ULONG"; case SQL_C_SLONG: return "SQL_C_SLONG"; case SQL_BIGINT: return "SQL_BIGINT"; case SQL_C_UBIGINT: return "SQL_C_SBIGINT"; case SQL_C_SBIGINT: return "SQL_C_SBIGINT"; case SQL_SMALLINT: return "SQL_SMALLINT"; case SQL_C_USHORT: return "SQL_C_USHORT"; case SQL_C_SSHORT: return "SQL_C_SSHORT"; case SQL_TINYINT: return "SQL_TINYINT"; case SQL_C_UTINYINT: return "SQL_C_UTINYINT"; case SQL_C_STINYINT: return "SQL_C_STINYINT"; case SQL_BIT: return "SQL_BIT"; case SQL_NUMERIC: return "SQL_NUMERIC"; case SQL_REAL: return "SQL_REAL"; case SQL_DOUBLE: return "SQL_DOUBLE"; case SQL_FLOAT: return "SQL_FLOAT"; case SQL_TYPE_DATE: return "SQL_TYPE_DATE"; case SQL_DATE: return "SQL_DATE"; case SQL_TYPE_TIME: return "SQL_TYPE_TIME"; case SQL_TIME: return "SQL_TIME"; case SQL_TYPE_TIMESTAMP: return "SQL_TYPE_TIMESTAMP"; case SQL_TIMESTAMP: return "SQL_TIMESTAMP"; case SQL_INTERVAL_YEAR: return "SQL_INTERVAL_YEAR "; case SQL_INTERVAL_MONTH: return "SQL_INTERVAL_MONTH"; case SQL_INTERVAL_DAY: return "SQL_INTERVAL_DAY "; case SQL_INTERVAL_HOUR: return "SQL_INTERVAL_HOUR"; case SQL_INTERVAL_MINUTE: return "SQL_INTERVAL_MINUTE"; case SQL_INTERVAL_SECOND: return "SQL_INTERVAL_SECOND"; case SQL_INTERVAL_YEAR_TO_MONTH: return "SQL_INTERVAL_YEAR_TO_MONTH"; case SQL_INTERVAL_DAY_TO_HOUR: return "SQL_INTERVAL_DAY_TO_HOUR "; case SQL_INTERVAL_DAY_TO_MINUTE: return "SQL_INTERVAL_DAY_TO_MINUTE"; case SQL_INTERVAL_DAY_TO_SECOND: return "SQL_INTERVAL_DAY_TO_SECOND"; case SQL_INTERVAL_HOUR_TO_MINUTE: return "SQL_INTERVAL_HOUR_TO_MINUTE"; case SQL_INTERVAL_HOUR_TO_SECOND: return "SQL_INTERVAL_HOUR_TO_SECOND"; case SQL_INTERVAL_MINUTE_TO_SECOND: return "SQL_INTERVAL_MINUTE_TO_SECOND"; default: return ""; } } /* * convert a return type as a string */ char * __get_return_status( SQLRETURN ret, SQLCHAR *buffer ) { switch ( ret ) { case SQL_SUCCESS: return "SQL_SUCCESS"; case SQL_ERROR: return "SQL_ERROR"; case SQL_SUCCESS_WITH_INFO: return "SQL_SUCCESS_WITH_INFO"; case SQL_NO_DATA: return "SQL_NO_DATA"; case SQL_STILL_EXECUTING: return "SQL_STILL_EXECUTING"; case SQL_INVALID_HANDLE: return "SQL_INVALID_HANDLE"; case SQL_NEED_DATA: return "SQL_NEED_DATA"; case SQL_PARAM_DATA_AVAILABLE: return "SQL_PARAM_DATA_AVAILABLE"; default: sprintf((char*) buffer, "UNKNOWN(%d)", ret ); return (char*)buffer; } } int wide_ansi_strncmp( SQLWCHAR *str1, char *str2, int len ) { char c; while( len > 0 ) { if ( *str1 == 0 || *str2 == 0 ) break; c = (char) *str1; if ( c != *str2 ) return *str2 - c; str1 ++; str2 ++; len --; } c = (char) *str1; return *str2 - c; } SQLWCHAR *wide_strcpy( SQLWCHAR *str1, SQLWCHAR *str2 ) { SQLWCHAR *retp = str1; if ( !str1 ) return NULL; while( *str2 ) { *str1 = *str2; str1 ++; str2 ++; } *str1 = 0; return retp; } SQLWCHAR *wide_strncpy( SQLWCHAR *str1, SQLWCHAR *str2, int buffer_length ) { SQLWCHAR *retp = str1; if ( !str1 ) return NULL; while( *str2 && buffer_length > 0 ) { *str1 = *str2; str1 ++; str2 ++; buffer_length --; } *str1 = 0; return retp; } SQLWCHAR *wide_strcat( SQLWCHAR *str1, SQLWCHAR *str2 ) { SQLWCHAR *retp = str1; while( *str1 ) { str1 ++; } while( *str2 ) { *str1 = *str2; str1 ++; str2 ++; } *str1 = 0; return retp; } SQLWCHAR *wide_strdup( SQLWCHAR *str1 ) { SQLWCHAR *ptr; int len = 0; while( str1[ len ] ) len ++; ptr = malloc( sizeof( SQLWCHAR ) * ( len + 1 )); if ( !ptr ) return NULL; return wide_strcpy( ptr, str1 ); } int wide_strlen( SQLWCHAR *str1 ) { int len = 0; while( str1[ len ] ) { len ++; } return len; } static int check_error_order( ERROR *e1, ERROR *e2, EHEAD *head ) { char *s1, *s2; int ret; /* * as far as I can see, a simple strcmp gives the order we need */ s1 = unicode_to_ansi_alloc( e1 -> sqlstate, SQL_NTS, __get_connection( head ), NULL); s2 = unicode_to_ansi_alloc( e2 -> sqlstate, SQL_NTS, __get_connection( head ), NULL ); ret = strcmp( s1, s2 ); free( s1 ); free( s2 ); return ret; } /* * insert the error into the list, making sure its in the correct * order */ static void insert_into_error_list( EHEAD *error_header, ERROR *e1 ) { error_header -> sql_error_head.error_count ++; if ( error_header -> sql_error_head.error_list_head ) { /* * find where in the list it needs to go */ ERROR *curr, *prev; prev = NULL; curr = error_header -> sql_error_head.error_list_head; while ( curr && check_error_order( curr, e1, error_header ) >= 0 ) { prev = curr; curr = curr -> next; } if ( curr ) { if ( prev ) { /* * in the middle */ e1 -> next = curr; e1 -> prev = curr -> prev; curr -> prev -> next = e1; curr -> prev = e1; } else { /* * at the beginning */ e1 -> next = error_header -> sql_error_head.error_list_head; e1 -> prev = NULL; e1 -> next -> prev = e1; error_header -> sql_error_head.error_list_head = e1; } } else { /* * at the end */ e1 -> next = NULL; e1 -> prev = error_header -> sql_error_head.error_list_tail; e1 -> prev -> next = e1; error_header -> sql_error_head.error_list_tail = e1; } } else { e1 -> next = e1 -> prev = NULL; error_header -> sql_error_head.error_list_tail = e1; error_header -> sql_error_head.error_list_head = e1; } } static void insert_into_diag_list( EHEAD *error_header, ERROR *e2 ) { error_header -> sql_diag_head.internal_count ++; if ( error_header -> sql_diag_head.internal_list_head ) { /* * find where in the list it needs to go */ ERROR *curr, *prev; prev = NULL; curr = error_header -> sql_diag_head.internal_list_head; while ( curr && check_error_order( curr, e2, error_header ) >= 0 ) { prev = curr; curr = curr -> next; } if ( curr ) { if ( prev ) { /* * in the middle */ e2 -> next = curr; e2 -> prev = curr -> prev; curr -> prev -> next = e2; curr -> prev = e2; } else { /* * at the beginning */ e2 -> next = error_header -> sql_diag_head.internal_list_head; e2 -> prev = NULL; e2 -> next -> prev = e2; error_header -> sql_diag_head.internal_list_head = e2; } } else { /* * at the end */ e2 -> next = NULL; e2 -> prev = error_header -> sql_diag_head.internal_list_tail; e2 -> prev -> next = e2; error_header -> sql_diag_head.internal_list_tail = e2; } } else { e2 -> next = e2 -> prev = NULL; error_header -> sql_diag_head.internal_list_tail = e2; error_header -> sql_diag_head.internal_list_head = e2; } } void __post_internal_error_ex( EHEAD *error_header, SQLCHAR *sqlstate, SQLINTEGER native_error, SQLCHAR *message_text, int class_origin, int subclass_origin ) { SQLCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ]; /* * add our prefix */ strcpy((char*) msg, ERROR_PREFIX ); strcat((char*) msg, (char*) message_text ); __post_internal_error_ex_noprefix( error_header, sqlstate, native_error, msg, class_origin, subclass_origin ); } void __post_internal_error_ex_noprefix( EHEAD *error_header, SQLCHAR *sqlstate, SQLINTEGER native_error, SQLCHAR *msg, int class_origin, int subclass_origin ) { /* * create a error block and add to the lists, * leave space for the error prefix */ ERROR *e1, *e2; DMHDBC conn = __get_connection( error_header ); e1 = malloc( sizeof( ERROR )); if (e1 == NULL) return; e2 = malloc( sizeof( ERROR )); if (e2 == NULL) { free(e1); return; } memset( e1, 0, sizeof( *e1 )); memset( e2, 0, sizeof( *e2 )); e1 -> native_error = native_error; e2 -> native_error = native_error; ansi_to_unicode_copy(e1 -> sqlstate, (char*)sqlstate, SQL_NTS, conn, NULL ); wide_strcpy( e2 -> sqlstate, e1 -> sqlstate ); e1 -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, conn, NULL ); if ( !e1 -> msg ) { free( e1 ); free( e2 ); return; } e2 -> msg = wide_strdup( e1 -> msg ); if ( !e2 -> msg ) { free( e1 -> msg); free( e1 ); free( e2 ); return; } e1 -> return_val = SQL_ERROR; e2 -> return_val = SQL_ERROR; e1 -> diag_column_number_ret = SQL_NO_COLUMN_NUMBER; e1 -> diag_row_number_ret = SQL_NO_ROW_NUMBER; e1 -> diag_class_origin_ret = SQL_SUCCESS; e1 -> diag_subclass_origin_ret = SQL_SUCCESS; e1 -> diag_connection_name_ret = SQL_SUCCESS; e1 -> diag_server_name_ret = SQL_SUCCESS; e1 -> diag_column_number = 0; e1 -> diag_row_number = 0; e2 -> diag_column_number_ret = SQL_NO_COLUMN_NUMBER; e2 -> diag_row_number_ret = SQL_NO_ROW_NUMBER; e2 -> diag_class_origin_ret = SQL_SUCCESS; e2 -> diag_subclass_origin_ret = SQL_SUCCESS; e2 -> diag_connection_name_ret = SQL_SUCCESS; e2 -> diag_server_name_ret = SQL_SUCCESS; e2 -> diag_column_number = 0; e2 -> diag_row_number = 0; if ( class_origin == SUBCLASS_ODBC ) ansi_to_unicode_copy( e1 -> diag_class_origin, (char*) "ODBC 3.0", SQL_NTS, conn, NULL ); else ansi_to_unicode_copy( e1 -> diag_class_origin, (char*) "ISO 9075", SQL_NTS, conn, NULL ); wide_strcpy( e2 -> diag_class_origin, e1 -> diag_class_origin ); if ( subclass_origin == SUBCLASS_ODBC ) ansi_to_unicode_copy( e1 -> diag_subclass_origin, (char*) "ODBC 3.0", SQL_NTS, conn, NULL ); else ansi_to_unicode_copy( e1 -> diag_subclass_origin, (char*) "ISO 9075", SQL_NTS, conn, NULL ); wide_strcpy( e2 -> diag_subclass_origin, e1 -> diag_subclass_origin ); ansi_to_unicode_copy( e1 -> diag_connection_name, (char*) "", SQL_NTS, conn, NULL ); wide_strcpy( e2 -> diag_connection_name, e1 -> diag_connection_name ); ansi_to_unicode_copy( e1 -> diag_server_name, conn ? conn->dsn : (char*) "", SQL_NTS, conn, NULL ); wide_strcpy( e2 -> diag_server_name, e1 -> diag_server_name ); /* * the list for SQLError puts both local and driver * errors in the same list */ insert_into_error_list( error_header, e1 ); insert_into_diag_list( error_header, e2 ); } void __post_internal_error_ex_w( EHEAD *error_header, SQLWCHAR *sqlstate, SQLINTEGER native_error, SQLWCHAR *message_text, int class_origin, int subclass_origin ) { SQLWCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ]; /* * add our prefix */ ansi_to_unicode_copy(msg, (char*) ERROR_PREFIX, SQL_NTS, __get_connection( error_header ), NULL); wide_strcat( msg, message_text ); __post_internal_error_ex_w_noprefix( error_header, sqlstate, native_error, msg, class_origin, subclass_origin ); } void __post_internal_error_ex_w_noprefix( EHEAD *error_header, SQLWCHAR *sqlstate, SQLINTEGER native_error, SQLWCHAR *msg, int class_origin, int subclass_origin ) { /* * create a error block and add to the lists, * leave space for the error prefix */ ERROR *e1, *e2; e1 = malloc( sizeof( ERROR )); if ( !e1 ) return; e2 = malloc( sizeof( ERROR )); if ( !e2 ) { free(e1); return; } memset( e1, 0, sizeof( *e1 )); memset( e2, 0, sizeof( *e2 )); e1 -> native_error = native_error; e2 -> native_error = native_error; wide_strcpy( e1 -> sqlstate, sqlstate ); wide_strcpy( e2 -> sqlstate, sqlstate ); e1 -> msg = wide_strdup( msg ); e2 -> msg = wide_strdup( msg ); e1 -> return_val = SQL_ERROR; e2 -> return_val = SQL_ERROR; e1 -> diag_column_number_ret = SQL_NO_COLUMN_NUMBER; e1 -> diag_row_number_ret = SQL_NO_ROW_NUMBER; e1 -> diag_class_origin_ret = SQL_SUCCESS; e1 -> diag_subclass_origin_ret = SQL_SUCCESS; e1 -> diag_connection_name_ret = SQL_SUCCESS; e1 -> diag_server_name_ret = SQL_SUCCESS; e1 -> diag_column_number = 0; e1 -> diag_row_number = 0; e2 -> diag_column_number_ret = SQL_NO_COLUMN_NUMBER; e2 -> diag_row_number_ret = SQL_NO_ROW_NUMBER; e2 -> diag_class_origin_ret = SQL_SUCCESS; e2 -> diag_subclass_origin_ret = SQL_SUCCESS; e2 -> diag_connection_name_ret = SQL_SUCCESS; e2 -> diag_server_name_ret = SQL_SUCCESS; e2 -> diag_column_number = 0; e2 -> diag_row_number = 0; if ( class_origin == SUBCLASS_ODBC ) ansi_to_unicode_copy( e1 -> diag_class_origin, (char*) "ODBC 3.0", SQL_NTS, __get_connection( error_header ), NULL ); else ansi_to_unicode_copy( e1 -> diag_class_origin, (char*) "ISO 9075", SQL_NTS, __get_connection( error_header ), NULL ); wide_strcpy( e2 -> diag_class_origin, e1 -> diag_class_origin ); if ( subclass_origin == SUBCLASS_ODBC ) ansi_to_unicode_copy( e1 -> diag_subclass_origin, (char*) "ODBC 3.0", SQL_NTS, __get_connection( error_header ), NULL ); else ansi_to_unicode_copy( e1 ->diag_subclass_origin, (char*) "ISO 9075", SQL_NTS, __get_connection( error_header ), NULL ); wide_strcpy( e2 -> diag_subclass_origin, e1 -> diag_subclass_origin ); e1 -> diag_connection_name[ 0 ] = 0; e2 -> diag_connection_name[ 0 ] = 0; e1 -> diag_server_name[ 0 ] = 0; e2 -> diag_server_name[ 0 ] = 0; error_header -> return_code = SQL_ERROR; /* * the list for SQLError puts both local and driver * errors in the same list */ insert_into_error_list( error_header, e1 ); insert_into_diag_list( error_header, e2 ); } /* * initialise a error header and take note what it belongs to */ void setup_error_head( EHEAD *error_header, void *handle, int type ) { memset( error_header, 0, sizeof( *error_header )); error_header -> owning_handle = handle; error_header -> handle_type = type; } /* * free any resources used but the error headers */ void clear_error_head( EHEAD *error_header ) { ERROR *cur, *prev; prev = NULL; cur = error_header -> sql_error_head.error_list_head; while( cur ) { prev = cur; free( prev -> msg ); cur = prev -> next; free( prev ); } error_header -> sql_error_head.error_list_head = NULL; error_header -> sql_error_head.error_list_tail = NULL; prev = NULL; cur = error_header -> sql_diag_head.error_list_head; while( cur ) { prev = cur; free( prev -> msg ); cur = prev -> next; free( prev ); } error_header -> sql_diag_head.error_list_head = NULL; error_header -> sql_diag_head.error_list_tail = NULL; prev = NULL; cur = error_header -> sql_diag_head.internal_list_head; while( cur ) { prev = cur; free( prev -> msg ); cur = prev -> next; free( prev ); } error_header -> sql_diag_head.internal_list_head = NULL; error_header -> sql_diag_head.internal_list_tail = NULL; } /* * get the error values from the handle */ void extract_diag_error( int htype, DRV_SQLHANDLE handle, DMHDBC connection, EHEAD *head, int return_code, int save_to_diag ) { SQLRETURN ret; SQLCHAR *msg; SQLCHAR *msg1; SQLCHAR sqlstate[ 6 ]; SQLINTEGER native; SQLINTEGER rec_number; SQLSMALLINT len; head -> return_code = return_code; head -> header_set = 0; head -> diag_cursor_row_count_ret = SQL_ERROR; head -> diag_dynamic_function_ret = SQL_ERROR; head -> diag_dynamic_function_code_ret = SQL_ERROR; head -> diag_number_ret = SQL_ERROR; head -> diag_row_count_ret = SQL_ERROR; rec_number = 1; do { len = 0; msg1 = malloc( SQL_MAX_MESSAGE_LENGTH + 1 ); ret = SQLGETDIAGREC( connection, head -> handle_type, handle, rec_number, sqlstate, &native, msg1, SQL_MAX_MESSAGE_LENGTH + 1, &len ); if ( SQL_SUCCEEDED( ret )) { ERROR *e = malloc( sizeof( ERROR )); SQLWCHAR *tmp; /* * make sure we are truncated in the right place */ if ( ret == SQL_SUCCESS_WITH_INFO || len >= SQL_MAX_MESSAGE_LENGTH ) { msg1 = realloc( msg1, len + 1 ); ret = SQLGETDIAGREC( connection, head -> handle_type, handle, rec_number, sqlstate, &native, msg1, len + 1, &len ); } msg = malloc( len + 32 ); #ifdef STRICT_ODBC_ERROR strcpy((char*) msg, (char*)msg1 ); #else strcpy((char*) msg, ERROR_PREFIX ); strcat((char*) msg, (char*)msg1 ); #endif /* * add to the SQLError list */ e -> native_error = native; tmp = ansi_to_unicode_alloc( sqlstate, SQL_NTS, connection, NULL ); wide_strcpy( e -> sqlstate, tmp ); free( tmp ); e -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL ); e -> return_val = return_code; insert_into_error_list( head, e ); /* * we do this if called from a DM function that goes on to call * a further driver function before returning */ if ( save_to_diag ) { SQLWCHAR *tmp; e = malloc( sizeof( ERROR )); e -> native_error = native; tmp = ansi_to_unicode_alloc( sqlstate, SQL_NTS, connection, NULL ); wide_strcpy( e -> sqlstate, tmp ); free( tmp ); e -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL ); e -> return_val = return_code; insert_into_diag_list( head, e ); /* * now we need to do some extra calls to get * extended info */ e -> diag_column_number_ret = SQL_ERROR; e -> diag_row_number_ret = SQL_ERROR; e -> diag_class_origin_ret = SQL_ERROR; e -> diag_subclass_origin_ret = SQL_ERROR; e -> diag_connection_name_ret = SQL_ERROR; e -> diag_server_name_ret= SQL_ERROR; if ( head -> handle_type == SQL_HANDLE_STMT ) { if ( rec_number == 1 ) { head -> header_set = 1; head -> diag_cursor_row_count_ret = SQLGETDIAGFIELD( connection, head -> handle_type, handle, 0, SQL_DIAG_CURSOR_ROW_COUNT, &head->diag_cursor_row_count, 0, NULL ); if ( SQL_SUCCEEDED( head -> diag_dynamic_function_ret = SQLGETDIAGFIELD( connection, head -> handle_type, handle, 0, SQL_DIAG_DYNAMIC_FUNCTION, msg, sizeof( msg ), &len ))) { tmp = ansi_to_unicode_alloc(msg, SQL_NTS, connection, NULL ); wide_strcpy( head->diag_dynamic_function, tmp ); free( tmp ); } head -> diag_dynamic_function_code_ret = SQLGETDIAGFIELD( connection, head -> handle_type, handle, 0, SQL_DIAG_DYNAMIC_FUNCTION_CODE, &head->diag_dynamic_function_code, 0, NULL ); head -> diag_number_ret = SQLGETDIAGFIELD( connection, head -> handle_type, handle, 0, SQL_DIAG_NUMBER, &head->diag_number, 0, NULL ); head -> diag_row_count_ret = SQLGETDIAGFIELD( connection, head -> handle_type, handle, 0, SQL_DIAG_ROW_COUNT, &head->diag_row_count, 0, NULL ); } e -> diag_column_number_ret = SQLGETDIAGFIELD( connection, head -> handle_type, handle, rec_number, SQL_DIAG_COLUMN_NUMBER, &e->diag_column_number, 0, NULL ); e -> diag_row_number_ret = SQLGETDIAGFIELD( connection, head -> handle_type, handle, rec_number, SQL_DIAG_ROW_NUMBER, &e->diag_row_number, 0, NULL ); } else { e -> diag_column_number_ret = SQL_ERROR; e -> diag_row_number_ret = SQL_ERROR; e -> diag_class_origin_ret = SQL_ERROR; e -> diag_subclass_origin_ret = SQL_ERROR; e -> diag_connection_name_ret = SQL_ERROR; e -> diag_server_name_ret= SQL_ERROR; if ( SQL_SUCCEEDED( e -> diag_class_origin_ret = SQLGETDIAGFIELD( connection, head -> handle_type, handle, rec_number, SQL_DIAG_CLASS_ORIGIN, msg, sizeof( msg ), &len ))) { tmp = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL ); wide_strcpy( e->diag_class_origin, tmp ); free( tmp ); } if ( SQL_SUCCEEDED( e -> diag_subclass_origin_ret = SQLGETDIAGFIELD( connection, head -> handle_type, handle, rec_number, SQL_DIAG_SUBCLASS_ORIGIN, msg, sizeof( msg ), &len ))) { tmp = ansi_to_unicode_alloc(msg, SQL_NTS, connection, NULL ); wide_strcpy( e->diag_subclass_origin, tmp ); free( tmp ); } if ( SQL_SUCCEEDED( e -> diag_connection_name_ret = SQLGETDIAGFIELD( connection, head -> handle_type, handle, rec_number, SQL_DIAG_CONNECTION_NAME, msg, sizeof( msg ), &len ))) { tmp = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL ); wide_strcpy( e->diag_connection_name, tmp ); free( tmp ); } if ( SQL_SUCCEEDED( e -> diag_server_name_ret = SQLGETDIAGFIELD( connection, head -> handle_type, handle, rec_number, SQL_DIAG_SERVER_NAME, msg, sizeof( msg ), &len ))) { tmp = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL ); wide_strcpy( e -> diag_server_name, tmp ); free( tmp ); } } } else { head -> sql_diag_head.error_count ++; } rec_number ++; /* * add to logfile */ if ( log_info.log_flag ) { sprintf( connection -> msg, "\t\tDIAG [%s] %s", sqlstate, msg1 ); dm_log_write_diag( connection -> msg ); } free( msg ); free( msg1 ); } else { free( msg1 ); } } while( SQL_SUCCEEDED( ret )); } void extract_sql_error( DRV_SQLHANDLE henv, DRV_SQLHANDLE hdbc, DRV_SQLHANDLE hstmt, DMHDBC connection, EHEAD *head, int return_code ) { SQLRETURN ret; SQLCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ]; SQLCHAR msg1[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLCHAR sqlstate[ 6 ]; SQLINTEGER native; SQLSMALLINT len; head -> return_code = return_code; head -> header_set = 0; head -> diag_cursor_row_count_ret = SQL_ERROR; head -> diag_dynamic_function_ret = SQL_ERROR; head -> diag_dynamic_function_code_ret = SQL_ERROR; head -> diag_number_ret = SQL_ERROR; head -> diag_row_count_ret = SQL_ERROR; do { len = 0; ret = SQLERROR( connection, henv, hdbc, hstmt, sqlstate, &native, msg1, sizeof( msg1 ), &len ); if ( SQL_SUCCEEDED( ret )) { SQLWCHAR *tmp; ERROR *e = malloc( sizeof( ERROR )); /* * add to the lists, SQLError list first */ /* * add our prefix */ /* * make sure we are truncated in the right place */ if ( ret == SQL_SUCCESS_WITH_INFO || len >= SQL_MAX_MESSAGE_LENGTH ) { msg1[ SQL_MAX_MESSAGE_LENGTH ] = '\0'; } #ifdef STRICT_ODBC_ERROR strcpy((char*) msg, (char*)msg1 ); #else strcpy((char*) msg, ERROR_PREFIX ); strcat((char*) msg, (char*)msg1 ); #endif e -> native_error = native; tmp = ansi_to_unicode_alloc( sqlstate, SQL_NTS, connection, NULL ); wide_strcpy( e -> sqlstate, tmp ); free( tmp ); e -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL ); e -> return_val = return_code; insert_into_error_list( head, e ); /* * SQLGetDiagRec list next */ e = malloc( sizeof( ERROR )); e -> diag_column_number_ret = SQL_ERROR; e -> diag_row_number_ret = SQL_ERROR; e -> diag_class_origin_ret = SQL_ERROR; e -> diag_subclass_origin_ret = SQL_ERROR; e -> diag_connection_name_ret = SQL_ERROR; e -> diag_server_name_ret= SQL_ERROR; e -> native_error = native; tmp = ansi_to_unicode_alloc( sqlstate, SQL_NTS, connection, NULL ); wide_strcpy( e -> sqlstate, tmp ); free( tmp ); e -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL ); e -> return_val = return_code; insert_into_diag_list( head, e ); /* * add to logfile */ if ( log_info.log_flag ) { sprintf( connection -> msg, "\t\tDIAG [%s] %s", sqlstate, msg1 ); dm_log_write_diag( connection -> msg ); } } } while( SQL_SUCCEEDED( ret )); } void extract_diag_error_w( int htype, DRV_SQLHANDLE handle, DMHDBC connection, EHEAD *head, int return_code, int save_to_diag ) { SQLRETURN ret; SQLWCHAR *msg; SQLWCHAR *msg1; SQLWCHAR sqlstate[ 6 ]; SQLINTEGER native; SQLINTEGER rec_number; SQLSMALLINT len; head -> return_code = return_code; head -> header_set = 0; head -> diag_cursor_row_count_ret = SQL_ERROR; head -> diag_dynamic_function_ret = SQL_ERROR; head -> diag_dynamic_function_code_ret = SQL_ERROR; head -> diag_number_ret = SQL_ERROR; head -> diag_row_count_ret = SQL_ERROR; rec_number = 1; do { len = 0; msg1 = malloc(( SQL_MAX_MESSAGE_LENGTH + 1 ) * sizeof( SQLWCHAR )); ret = SQLGETDIAGRECW( connection, head -> handle_type, handle, rec_number, sqlstate, &native, msg1, SQL_MAX_MESSAGE_LENGTH + 1, &len ); if ( SQL_SUCCEEDED( ret )) { ERROR *e = malloc( sizeof( ERROR )); #ifndef STRICT_ODBC_ERROR SQLWCHAR *tmp; #endif /* * make sure we are truncated in the right place */ if ( ret == SQL_SUCCESS_WITH_INFO || len >= SQL_MAX_MESSAGE_LENGTH ) { msg1 = realloc( msg1, ( len + 1 ) * sizeof( SQLWCHAR )); ret = SQLGETDIAGRECW( connection, head -> handle_type, handle, rec_number, sqlstate, &native, msg1, len + 1, &len ); } msg = malloc(( len + 32 ) * sizeof( SQLWCHAR )); #ifdef STRICT_ODBC_ERROR wide_strcpy( msg, msg1 ); #else tmp = ansi_to_unicode_alloc((SQLCHAR*) ERROR_PREFIX, SQL_NTS, connection ); wide_strcpy( msg, tmp ); free( tmp ); wide_strcat( msg, msg1 ); #endif /* * add to the SQLError list */ e -> native_error = native; wide_strcpy( e -> sqlstate, sqlstate ); e -> msg = wide_strdup( msg ); e -> return_val = return_code; insert_into_error_list( head, e ); /* * we do this if called from a DM function that goes on to call * a further driver function before returning */ if ( save_to_diag ) { e = malloc( sizeof( ERROR )); e -> native_error = native; wide_strcpy( e -> sqlstate, sqlstate ); e -> msg = wide_strdup( msg ); e -> return_val = return_code; insert_into_diag_list( head, e ); /* * now we need to do some extra calls to get * extended info */ e -> diag_column_number_ret = SQL_ERROR; e -> diag_row_number_ret = SQL_ERROR; e -> diag_class_origin_ret = SQL_ERROR; e -> diag_subclass_origin_ret = SQL_ERROR; e -> diag_connection_name_ret = SQL_ERROR; e -> diag_server_name_ret= SQL_ERROR; if ( head -> handle_type == SQL_HANDLE_STMT ) { if ( rec_number == 1 ) { head -> header_set = 1; head -> diag_cursor_row_count_ret = SQLGETDIAGFIELDW( connection, head -> handle_type, handle, 0, SQL_DIAG_CURSOR_ROW_COUNT, &head->diag_cursor_row_count, 0, NULL ); head -> diag_dynamic_function_ret = SQLGETDIAGFIELDW( connection, head -> handle_type, handle, 0, SQL_DIAG_DYNAMIC_FUNCTION, head->diag_dynamic_function, sizeof( head->diag_dynamic_function ), &len ); head -> diag_dynamic_function_code_ret = SQLGETDIAGFIELDW( connection, head -> handle_type, handle, 0, SQL_DIAG_DYNAMIC_FUNCTION_CODE, &head->diag_dynamic_function_code, 0, NULL ); head -> diag_number_ret = SQLGETDIAGFIELDW( connection, head -> handle_type, handle, 0, SQL_DIAG_NUMBER, &head->diag_number, 0, NULL ); head -> diag_row_count_ret = SQLGETDIAGFIELDW( connection, head -> handle_type, handle, 0, SQL_DIAG_ROW_COUNT, &head->diag_row_count, 0, NULL ); } e -> diag_column_number_ret = SQLGETDIAGFIELDW( connection, head -> handle_type, handle, rec_number, SQL_DIAG_COLUMN_NUMBER, &e->diag_column_number, 0, NULL ); e -> diag_row_number_ret = SQLGETDIAGFIELDW( connection, head -> handle_type, handle, rec_number, SQL_DIAG_ROW_NUMBER, &e->diag_row_number, 0, NULL ); } else { e -> diag_column_number_ret = SQL_ERROR; e -> diag_row_number_ret = SQL_ERROR; e -> diag_class_origin_ret = SQL_ERROR; e -> diag_subclass_origin_ret = SQL_ERROR; e -> diag_connection_name_ret = SQL_ERROR; e -> diag_server_name_ret= SQL_ERROR; e -> diag_class_origin_ret = SQLGETDIAGFIELDW( connection, head -> handle_type, handle, rec_number, SQL_DIAG_CLASS_ORIGIN, e->diag_class_origin, sizeof( e->diag_class_origin ), &len ); e -> diag_subclass_origin_ret = SQLGETDIAGFIELDW( connection, head -> handle_type, handle, rec_number, SQL_DIAG_SUBCLASS_ORIGIN, e->diag_subclass_origin, sizeof( e->diag_subclass_origin ), &len ); e -> diag_connection_name_ret = SQLGETDIAGFIELDW( connection, head -> handle_type, handle, rec_number, SQL_DIAG_CONNECTION_NAME, e->diag_connection_name, sizeof( e->diag_connection_name ), &len ); e -> diag_server_name_ret = SQLGETDIAGFIELDW( connection, head -> handle_type, handle, rec_number, SQL_DIAG_SERVER_NAME, e->diag_server_name, sizeof( e->diag_server_name ), &len ); } } else { head -> sql_diag_head.error_count ++; } rec_number ++; /* * add to logfile */ if ( log_info.log_flag ) { SQLCHAR *as1, *as2; as1 = (SQLCHAR*) unicode_to_ansi_alloc( sqlstate, SQL_NTS, connection, NULL ); as2 = (SQLCHAR*) unicode_to_ansi_alloc( msg1, SQL_NTS, connection, NULL ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", as1, as2 ); if( as1 ) free( as1 ); if( as2 ) free( as2 ); dm_log_write_diag( connection -> msg ); } free( msg ); free( msg1 ); } else { free( msg1 ); } } while( SQL_SUCCEEDED( ret )); } void extract_sql_error_w( DRV_SQLHANDLE henv, DRV_SQLHANDLE hdbc, DRV_SQLHANDLE hstmt, DMHDBC connection, EHEAD *head, int return_code ) { SQLRETURN ret; SQLWCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ]; SQLWCHAR msg1[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLWCHAR sqlstate[ 6 ]; SQLINTEGER native; SQLSMALLINT len; head -> return_code = return_code; do { len = 0; ret = SQLERRORW( connection, henv, hdbc, hstmt, sqlstate, &native, msg1, SQL_MAX_MESSAGE_LENGTH, &len ); if ( SQL_SUCCEEDED( ret )) { #ifndef STRICT_ODBC_ERROR SQLWCHAR *tmp; #endif /* * add to the lists, SQLError list first */ ERROR *e = malloc( sizeof( ERROR )); /* * add our prefix */ /* * make sure we are truncated in the right place */ if ( ret == SQL_SUCCESS_WITH_INFO || len >= SQL_MAX_MESSAGE_LENGTH ) { msg1[ SQL_MAX_MESSAGE_LENGTH ] = 0; } #ifdef STRICT_ODBC_ERROR wide_strcpy( msg, msg1 ); #else tmp = ansi_to_unicode_alloc((SQLCHAR*) ERROR_PREFIX, SQL_NTS, connection, NULL ); wide_strcpy( msg, tmp ); free( tmp ); wide_strcat( msg, msg1 ); #endif e -> native_error = native; wide_strcpy( e -> sqlstate, sqlstate ); e -> msg = wide_strdup( msg ); e -> return_val = return_code; insert_into_error_list( head, e ); /* * SQLGetDiagRec list next */ e = malloc( sizeof( ERROR )); e -> native_error = native; wide_strcpy( e -> sqlstate, sqlstate ); e -> msg = wide_strdup( msg ); e -> return_val = return_code; insert_into_diag_list( head, e ); /* * add to logfile */ if ( log_info.log_flag ) { SQLCHAR *as1, *as2; as1 = (SQLCHAR*) unicode_to_ansi_alloc( sqlstate, SQL_NTS, connection, NULL ); as2 = (SQLCHAR*) unicode_to_ansi_alloc( msg1, SQL_NTS, connection, NULL ); sprintf( connection -> msg, "\t\tDIAG [%s] %s", as1, as2 ); if( as1 ) free( as1 ); if( as2 ) free( as2 ); dm_log_write_diag( connection -> msg ); } } } while( SQL_SUCCEEDED( ret )); } /* * Extract diag information from driver */ void extract_error_from_driver( EHEAD * error_handle, DMHDBC hdbc, int ret_code, int save_to_diag ) { void (*extracterrorfunc)( DRV_SQLHANDLE, DRV_SQLHANDLE, DRV_SQLHANDLE, DMHDBC, EHEAD *, int ) = 0; void (*extractdiagfunc)( int, DRV_SQLHANDLE, DMHDBC, EHEAD*, int, int ) = 0; DRV_SQLHANDLE hdbc_drv = SQL_NULL_HDBC; DRV_SQLHANDLE hstmt_drv = SQL_NULL_HSTMT; DRV_SQLHANDLE handle_diag_extract = __get_driver_handle( error_handle ); if ( error_handle->handle_type == SQL_HANDLE_ENV ) { return; } if ( error_handle->handle_type == SQL_HANDLE_DBC ) { hdbc_drv = handle_diag_extract; } else if ( error_handle->handle_type == SQL_HANDLE_STMT ) { hstmt_drv = handle_diag_extract; } /* If we have the W functions may as well use them */ if ( CHECK_SQLGETDIAGFIELDW( hdbc ) && CHECK_SQLGETDIAGRECW( hdbc )) { extractdiagfunc = extract_diag_error_w; } else if ( CHECK_SQLERRORW( hdbc )) { extracterrorfunc = extract_sql_error_w; } else if ( CHECK_SQLGETDIAGFIELD( hdbc ) && CHECK_SQLGETDIAGREC( hdbc )) { extractdiagfunc = extract_diag_error; } else if ( CHECK_SQLERROR( hdbc )) { extracterrorfunc = extract_sql_error; } if ( extractdiagfunc ) { extractdiagfunc( error_handle->handle_type, handle_diag_extract, hdbc, error_handle, ret_code, save_to_diag ); } else if ( error_handle->handle_type != SQL_HANDLE_DESC && extracterrorfunc ) { extracterrorfunc( SQL_NULL_HENV, hdbc_drv, hstmt_drv, hdbc, error_handle, ret_code ); } else { __post_internal_error( error_handle, ERROR_HY000, "Driver returned SQL_ERROR or SQL_SUCCESS_WITH_INFO but no error reporting API found", hdbc->environment->requested_version ); } } /* Return without collecting diag recs from the handle - to be called if the DM function is returning before calling the driver function. */ int function_return_nodrv( int level, void *handle, int ret_code) { if ( level != IGNORE_THREAD ) { thread_release( level, handle ); } return ret_code; } /* * capture function returns and check error's if necessary */ int function_return_ex( int level, void * handle, int ret_code, int save_to_diag, int defer_type ) { DMHENV henv; DMHDBC hdbc; DMHSTMT hstmt; DMHDESC hdesc; EHEAD *herror = NULL; if ( ret_code == SQL_SUCCESS_WITH_INFO || ret_code == SQL_ERROR || ret_code == SQL_NO_DATA) { /* * find what type of handle it is */ henv = handle; switch ( henv -> type ) { case HENV_MAGIC: { /* * do nothing, it must be local */ } break; case HDBC_MAGIC: { hdbc = handle; /* * are we connected ? */ if ( hdbc -> state >= STATE_C4 ) { herror = &hdbc->error; } } break; case HSTMT_MAGIC: { hstmt = handle; herror = &hstmt->error; hdbc = hstmt->connection; } break; case HDESC_MAGIC: { hdesc = handle; herror = &hdesc->error; hdbc = hdesc->connection; } break; } if ( herror ) { /* * set defer flag */ herror->defer_extract = ( ret_code == SQL_ERROR ? defer_type >> 1 : defer_type ) & 1; if ( herror->defer_extract ) { herror->ret_code_deferred = ret_code; } else { extract_error_from_driver( herror, hdbc, ret_code, save_to_diag ); } } } /* * release any threads */ if ( level != IGNORE_THREAD ) { thread_release( level, handle ); } return ret_code; } /* * clear errors down at the start of a new statement * only clear for the ODBC lists, the rest stay */ void function_entry( void *handle ) { ERROR *cur, *prev; EHEAD *error_header; DMHENV henv; DMHDBC hdbc; DMHSTMT hstmt; DMHDESC hdesc; int version; /* * find what the handle is */ henv = handle; switch( henv -> type ) { case HENV_MAGIC: error_header = &henv -> error; version = henv -> requested_version; break; case HDBC_MAGIC: hdbc = handle; error_header = &hdbc -> error; version = hdbc -> environment -> requested_version; break; case HSTMT_MAGIC: hstmt = handle; error_header = &hstmt -> error; version = hstmt -> connection -> environment -> requested_version; break; case HDESC_MAGIC: hdesc = handle; error_header = &hdesc -> error; version = hdesc -> connection -> environment -> requested_version; break; } error_header->defer_extract = 0; error_header->ret_code_deferred = 0; prev = NULL; cur = error_header -> sql_diag_head.error_list_head; while( cur ) { prev = cur; free( prev -> msg ); cur = prev -> next; free( prev ); } error_header -> sql_diag_head.error_list_head = NULL; error_header -> sql_diag_head.error_list_tail = NULL; error_header -> sql_diag_head.error_count = 0; error_header -> header_set = 0; prev = NULL; cur = error_header -> sql_diag_head.internal_list_head; while( cur ) { prev = cur; free( prev -> msg ); cur = prev -> next; free( prev ); } error_header -> sql_diag_head.internal_list_head = NULL; error_header -> sql_diag_head.internal_list_tail = NULL; error_header -> sql_diag_head.internal_count = 0; /* * if version is SQL_OV_ODBC3 then clear the SQLError list * as well */ #ifdef USE_OLD_ODBC2_ERROR_CLEARING if ( version >= SQL_OV_ODBC3 ) #endif { prev = NULL; cur = error_header -> sql_error_head.error_list_head; while( cur ) { prev = cur; free( prev -> msg ); cur = prev -> next; free( prev ); } error_header -> sql_error_head.error_list_head = NULL; error_header -> sql_error_head.error_list_tail = NULL; error_header -> sql_error_head.error_count = 0; } } void __post_internal_error( EHEAD *error_handle, error_id id, char *txt, int connection_mode ) { __post_internal_error_api( error_handle, id, txt, connection_mode, 0 ); } void __post_internal_error_api( EHEAD *error_handle, error_id id, char *txt, int connection_mode, int calling_api ) { char sqlstate[ 6 ]; char *message; SQLCHAR msg[ SQL_MAX_MESSAGE_LENGTH ]; SQLRETURN ret = SQL_ERROR; int class, subclass; class = SUBCLASS_ISO; subclass = SUBCLASS_ISO; switch( id ) { case ERROR_01000: strcpy( sqlstate, "01000" ); message = "General warning"; break; case ERROR_01004: strcpy( sqlstate, "01004" ); message = "String data, right truncated"; break; case ERROR_01S02: strcpy( sqlstate, "01S02" ); message = "Option value changed"; subclass = SUBCLASS_ODBC; break; case ERROR_01S06: strcpy( sqlstate, "01S06" ); message = "Attempt to fetch before the result set returned the first rowset"; subclass = SUBCLASS_ODBC; break; case ERROR_07005: strcpy( sqlstate, "07005" ); message = "Prepared statement not a cursor-specification"; break; case ERROR_07009: switch( calling_api ) { case SQL_API_SQLDESCRIBEPARAM: case SQL_API_SQLBINDPARAMETER: case SQL_API_SQLSETPARAM: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "07009" ); else strcpy( sqlstate, "S1093" ); message = "Invalid parameter index"; break; default: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "07009" ); else strcpy( sqlstate, "S1002" ); message = "Invalid descriptor index"; break; } break; case ERROR_08002: strcpy( sqlstate, "08002" ); message = "Connection in use"; break; case ERROR_08003: strcpy( sqlstate, "08003" ); message = "Connection not open"; break; case ERROR_24000: strcpy( sqlstate, "24000" ); message = "Invalid cursor state"; break; case ERROR_25000: message = "Invalid transaction state"; strcpy( sqlstate, "25000" ); break; case ERROR_25S01: message = "Transaction state unknown"; strcpy( sqlstate, "25S01" ); subclass = SUBCLASS_ODBC; break; case ERROR_S1000: message = "General error"; strcpy( sqlstate, "S1000" ); break; case ERROR_S1003: message = "Program type out of range"; strcpy( sqlstate, "S1003" ); break; case ERROR_S1010: message = "Function sequence error"; strcpy( sqlstate, "S1010" ); break; case ERROR_S1011: message = "Operation invalid at this time"; strcpy( sqlstate, "S1011" ); break; case ERROR_S1107: message = "Row value out of range"; strcpy( sqlstate, "S1107" ); break; case ERROR_S1108: message = "Concurrency option out of range"; strcpy( sqlstate, "S1108" ); break; case ERROR_S1C00: message = "Driver not capable"; strcpy( sqlstate, "S1C00" ); break; case ERROR_HY001: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY001" ); else strcpy( sqlstate, "S1011" ); message = "Memory allocation error"; break; case ERROR_HY003: if ( connection_mode >= SQL_OV_ODBC3 ) { strcpy( sqlstate, "HY003" ); /* Windows DM returns " Program type out of range" instead of "Invalid application buffer type" */ message = "Program type out of range"; } else { strcpy( sqlstate, "S1003" ); message = "Invalid application buffer type"; } break; case ERROR_HY004: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY004" ); else strcpy( sqlstate, "S1004" ); message = "Invalid SQL data type"; break; case ERROR_HY007: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY007" ); else strcpy( sqlstate, "S1007" ); message = "Associated statement is not prepared"; break; case ERROR_HY009: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY009" ); else strcpy( sqlstate, "S1009" ); message = "Invalid use of null pointer"; break; case ERROR_HY010: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY010" ); else strcpy( sqlstate, "S1010" ); message = "Function sequence error"; break; case ERROR_HY011: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY011" ); else strcpy( sqlstate, "S1011" ); message = "Attribute cannot be set now"; break; case ERROR_HY012: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY012" ); else strcpy( sqlstate, "S1012" ); message = "Invalid transaction operation code"; break; case ERROR_HY013: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY013" ); else strcpy( sqlstate, "S1013" ); message = "Memory management error"; break; case ERROR_HY017: strcpy( sqlstate, "HY017" ); message = "Invalid use of an automatically allocated descriptor handle"; break; case ERROR_HY024: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY024" ); else strcpy( sqlstate, "S1009" ); message = "Invalid attribute value"; break; case ERROR_HY090: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY090" ); else strcpy( sqlstate, "S1090" ); message = "Invalid string or buffer length"; break; case ERROR_HY092: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY092" ); else strcpy( sqlstate, "S1092" ); message = "Invalid attribute/option identifier"; break; case ERROR_HY095: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY095" ); else strcpy( sqlstate, "S1095" ); message = "Function type out of range"; break; case ERROR_HY097: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY097" ); else strcpy( sqlstate, "S1097" ); message = "Column type out of range"; break; case ERROR_HY098: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY098" ); else strcpy( sqlstate, "S1098" ); message = "Scope type out of range"; break; case ERROR_HY099: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY099" ); else strcpy( sqlstate, "S1099" ); message = "Nullable type out of range"; break; case ERROR_HY100: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY100" ); else strcpy( sqlstate, "S1100" ); message = "Uniqueness option type out of range"; break; case ERROR_HY101: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY101" ); else strcpy( sqlstate, "S1101" ); message = "Accuracy option type out of range"; break; case ERROR_HY103: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY103" ); else strcpy( sqlstate, "S1103" ); message = "Invalid retrieval code"; break; case ERROR_HY105: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY105" ); else strcpy( sqlstate, "S1105" ); message = "Invalid parameter type"; break; case ERROR_HY106: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY106" ); else strcpy( sqlstate, "S1106" ); message = "Fetch type out of range"; break; case ERROR_HY110: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY110" ); else strcpy( sqlstate, "S1110" ); message = "Invalid driver completion"; break; case ERROR_HY111: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY111" ); else strcpy( sqlstate, "S1111" ); message = "Invalid bookmark value"; break; case ERROR_HYC00: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HYC00" ); else strcpy( sqlstate, "S1C00" ); message = "Optional feature not implemented"; break; case ERROR_IM001: strcpy( sqlstate, "IM001" ); message = "Driver does not support this function"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; case ERROR_IM002: strcpy( sqlstate, "IM002" ); message = "Data source name not found and no default driver specified"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; case ERROR_IM003: strcpy( sqlstate, "IM003" ); message = "Specified driver could not be loaded"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; case ERROR_IM004: strcpy( sqlstate, "IM004" ); message = "Driver's SQLAllocHandle on SQL_HANDLE_HENV failed"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; case ERROR_IM005: strcpy( sqlstate, "IM005" ); message = "Driver's SQLAllocHandle on SQL_HANDLE_DBC failed"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; case ERROR_IM010: strcpy( sqlstate, "IM010" ); message = "Data source name too long"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; case ERROR_IM011: strcpy( sqlstate, "IM011" ); message = "Driver name too long"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; case ERROR_IM012: strcpy( sqlstate, "IM012" ); message = "DRIVER keyword syntax error"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; case ERROR_SL004: strcpy( sqlstate, "SL004" ); message = "Result set not generated by a SELECT statement"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; case ERROR_SL009: strcpy( sqlstate, "SL009" ); message = "No columns were bound prior to calling SQLFetch or SQLFetchScroll"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; case ERROR_SL010: strcpy( sqlstate, "SL010" ); message = "SQLBindCol returned SQL_ERROR on a attempt to bind a internal buffer"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; case ERROR_SL008: strcpy( sqlstate, "SL008" ); message = "SQLGetData is not allowed on a forward only (non-buffered) cursor"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; case ERROR_HY000: if ( connection_mode >= SQL_OV_ODBC3 ) strcpy( sqlstate, "HY000" ); else strcpy( sqlstate, "S1000" ); message = "General error"; break; case ERROR_HYT02: strcpy( sqlstate, "HYT02"); message = "Connection pool at capacity and the wait has timed out"; subclass = SUBCLASS_ODBC; class = SUBCLASS_ODBC; break; default: strcpy( sqlstate, "?????" ); message = "Unknown"; } if ( txt ) message = txt; strcpy((char*) msg, DM_ERROR_PREFIX ); strncat((char*) msg, message, sizeof(msg) - sizeof(DM_ERROR_PREFIX) ); error_handle -> return_code = ret; __post_internal_error_ex( error_handle, (SQLCHAR*)sqlstate, 0, msg, class, subclass ); } /* * open a log file */ void dm_log_open( char *program_name, char *log_file_name, int pid_logging ) { if ( log_info.program_name ) { free( log_info.program_name ); } if ( log_info.log_file_name ) { free( log_info.log_file_name ); } log_info.program_name = strdup( program_name ); log_info.log_file_name = strdup( log_file_name ); log_info.log_flag = 1; /* * are we doing perprocess logging */ log_info.pid_logging = pid_logging; log_info.ref_count++; } void dm_log_write( char *function_name, int line, int type, int severity, char *message ) { FILE *fp; char tmp[ 24 ]; if ( !log_info.log_flag && !ODBCSharedTraceFlag ) return; if ( log_info.pid_logging ) { char file_name[ 256 ], str[ 20 ]; if ( !log_info.log_file_name ) { strcpy( file_name, "/tmp/sql.log" ); } else { sprintf( file_name, "%s/%s", log_info.log_file_name, __get_pid((SQLCHAR*) str )); } fp = uo_fopen( file_name, "a" ); /* * Change the mode to be rw for all */ chmod( file_name, 0666 ); } else { if ( !log_info.log_file_name ) { fp = uo_fopen( "/tmp/sql.log", "a" ); } else { fp = uo_fopen( log_info.log_file_name, "a" ); } } if ( fp ) { char tstamp_str[ 128 ]; #if defined( HAVE_GETTIMEOFDAY ) && defined( HAVE_SYS_TIME_H ) { struct timeval tv; void* tz = NULL; gettimeofday( &tv, tz ); sprintf( tstamp_str, "[%ld.%06ld]", tv.tv_sec, tv.tv_usec ); } #elif defined( HAVE_FTIME ) && defined( HAVE_SYS_TIMEB_H ) { struct timeb tp; ftime( &tp ); sprintf( tstamp_str, "[%ld.%03d]", tp.time, tp.millitm ); } #elif defined( DHAVE_TIME ) && defined( HAVE_TIME_H ) { time_t tv; time( &tv ); sprintf( tstamp_str, "[%ld]", tv ); } #else tstamp_str[ 0 ] = '\0'; #endif if ( !log_info.program_name ) { uo_fprintf( fp, "[ODBC][%s]%s[%s][%d]%s\n", __get_pid((SQLCHAR*) tmp ), tstamp_str, function_name, line, message ); } else { uo_fprintf( fp, "[%s][%s]%s[%s][%d]%s\n", log_info.program_name, __get_pid((SQLCHAR*) tmp ), tstamp_str, function_name, line, message ); } uo_fclose( fp ); } } void dm_log_write_diag( char *message ) { FILE *fp; if ( !log_info.log_flag && !ODBCSharedTraceFlag ) return; if ( log_info.pid_logging ) { char file_name[ 256 ], str[ 20 ]; if ( !log_info.log_file_name ) { strcpy( file_name, "/tmp/sql.log" ); } else { sprintf( file_name, "%s/%s", log_info.log_file_name, __get_pid((SQLCHAR*) str )); } fp = uo_fopen( file_name, "a" ); /* * Change the mode to be rw for all */ chmod( file_name, 0666 ); } else { if ( !log_info.log_file_name ) { fp = uo_fopen( "/tmp/sql.log", "a" ); } else { fp = uo_fopen( log_info.log_file_name, "a" ); } } if ( fp ) { uo_fprintf( fp, "%s\n\n", message ); uo_fclose( fp ); } } void dm_log_close( void ) { if ( !log_info.ref_count ) return; log_info.ref_count--; if ( !log_info.ref_count ) { free( log_info.program_name ); free( log_info.log_file_name ); log_info.program_name = NULL; log_info.log_file_name = NULL; log_info.log_flag = 0; } } unixODBC-2.3.12/DriverManager/__stats.c000066400000000000000000000550461446441710500175600ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: __stats.c,v 1.4 2009/02/18 17:59:09 lurcher Exp $ * * $Log: __stats.c,v $ * Revision 1.4 2009/02/18 17:59:09 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2009/02/17 09:47:44 lurcher * Clear up a number of bugs * * Revision 1.2 2004/05/07 09:53:13 lurcher * * * Fix potential problrm in stats if creating a semaphore fails * Alter state after SQLParamData from S4 to S5 * * Revision 1.1.1.1 2001/10/17 16:40:09 lurcher * * First upload to SourceForge * * Revision 1.11 2001/09/27 17:05:48 nick * * Assorted fixes and tweeks * * Revision 1.10 2001/06/04 15:24:49 nick * * Add port to MAC OSX and QT3 changes * * Revision 1.9 2001/05/15 13:56:29 jason * * semaphore header file not requires unless COLLECT_STATS is defined * * Revision 1.8 2001/05/15 13:29:07 jason * * * Moved COLLECT_STATS define to allow compilation on OpenVMS. * * Revision 1.7 2001/01/03 10:15:16 martin * * Fix bug in uodbc_update_stats() which attempted to use the shared memory * ID to release the semaphore if the array of process info full. * Fix bug in release_sem_lock() which called semop saying there were 2 ops * when there was really only one. * * Revision 1.6 2000/12/21 16:18:37 martin * * Add the promised support to return a list of process IDs currently attached * to the DM. * * Revision 1.5 2000/12/21 15:58:35 martin * * Fix problems with any app exiting clearing all stats. * * Revision 1.4 2000/12/20 12:00:52 nick * * Add uodbc_update_stats to the non stats build * * Revision 1.3 2000/12/19 10:28:29 martin * * Return "not built with stats" in uodbc_error() if stats function called * when stats not built. * Add uodbc_update_stats() calls to SQLFreeHandle. * * Revision 1.1 2000/12/18 11:53:51 martin * * handle statistic API. * * **********************************************************************/ #include #ifdef HAVE_SYS_SEM_H #include #include #include #include #include #include #include #include #endif /* HAVE_SYS_SEM_H */ #ifdef COLLECT_STATS #include #include #include #endif #include #include "__stats.h" #include #include "drivermanager.h" static char const rcsid[]= "$RCSfile: __stats.c,v $ $Revision: 1.4 $"; #ifdef COLLECT_STATS #ifdef HAVE_LIBPTHREAD #include #endif /* * PROJECT_ID is used in the call to ftok(). * The PROJECT_ID reduces the chance of a class between processes using IPC. * Do not change thisnumber as it will make different versions of unixODBC * incompatible. */ #define PROJECT_ID 121 /* * Permssions on sempahore/shared memory * These needs to be world readable/writeable or different apps running under * different users we not be able to update/read the stats. */ #define IPC_ACCESS_MODE (S_IRUSR | S_IWUSR \ | S_IRGRP | S_IWGRP \ | S_IROTH | S_IWOTH) static char errmsg[512]=""; static int release_sem_lock(int sem_id); static int acquire_sem_lock(int sem_id); int uodbc_open_stats( void **rh, unsigned int mode) { key_t ipc_key; int shm_created = 0; uodbc_stats_handle_t *h = NULL; uodbc_stats_handle_t lh; char odbcini[1024]; unsigned int i; int shmflg; if (!rh) { return -1; } #ifdef STATS_FTOK_NAME if ( strcmp( STATS_FTOK_NAME, "odbc.ini" ) == 0 ) { if (!_odbcinst_SystemINI(odbcini, FALSE)) { snprintf(errmsg, sizeof(errmsg), "Failed to find system odbc.ini"); return -1; } } else { strcpy( odbcini, STATS_FTOK_NAME ); } #else if (!_odbcinst_SystemINI(odbcini, FALSE)) { snprintf(errmsg, sizeof(errmsg), "Failed to find system odbc.ini"); return -1; } #endif memset(&lh, '\0', sizeof(lh)); memcpy(lh.id, UODBC_STATS_ID, 5); lh.shm_id = -1; lh.sem_id = -1; lh.pid = getpid(); /* * Check the odbc.ini file used in ftok() exists. */ if (access(odbcini, F_OK) < 0) { snprintf(errmsg, sizeof(errmsg), "Cannot locate %s", odbcini); return -1; } /* * Get a unique IPC key. */ if ((ipc_key = ftok(odbcini, (char)PROJECT_ID)) < 0) { snprintf(errmsg, sizeof(errmsg), "Failed to obtain IPC key - %s", strerror(errno)); return -1; } /* * See if the semaphore exists and create if it doesn't. */ lh.sem_id = semget(ipc_key, 1, IPC_ACCESS_MODE | IPC_CREAT | IPC_EXCL); if (lh.sem_id < 0) { if (errno != EEXIST) { snprintf(errmsg, sizeof(errmsg), "Failed to get semaphore ID - %s", strerror(errno)); return -1; } lh.sem_id = semget(ipc_key, 1, IPC_ACCESS_MODE | IPC_CREAT); if (lh.sem_id < 0) { snprintf(errmsg, sizeof(errmsg), "Failed to create semaphore - %s", strerror(errno)); return -1; } } /* * Create/map shared memory */ if (mode & UODBC_STATS_WRITE) shmflg = IPC_ACCESS_MODE | IPC_CREAT | IPC_EXCL; else shmflg = IPC_ACCESS_MODE; lh.shm_id = shmget(ipc_key, sizeof(uodbc_stats_t), shmflg); if (lh.shm_id < 0) { if (mode & UODBC_STATS_READ) { snprintf(errmsg, sizeof(errmsg), "No statistics available yet"); return -1; } if (errno == EEXIST) { lh.shm_id = shmget(ipc_key, sizeof(uodbc_stats_t), IPC_ACCESS_MODE); if (lh.shm_id < 0) { snprintf(errmsg, sizeof(errmsg), "Shared memory exists but cannot map it - %s", strerror(errno)); return -1; } } else { snprintf(errmsg, sizeof(errmsg), "Failed to get shared memory ID - %s", strerror(errno)); return -1; } } else { if (mode & UODBC_STATS_WRITE) shm_created = 1; } lh.stats = (uodbc_stats_t *)shmat(lh.shm_id, 0, 0); if (lh.stats == (uodbc_stats_t *)-1) { snprintf(errmsg, sizeof(errmsg), "Failed to attach to shared memory - %s", strerror(errno)); return -1; } else if (shm_created) { unsigned int i; int lk; lk = acquire_sem_lock(lh.sem_id); memset(lh.stats, '\0', sizeof(uodbc_stats_t)); for (i = 0; i < (sizeof(lh.stats->perpid) / sizeof(lh.stats->perpid[0])); i++) { lh.stats->perpid[i].pid = (pid_t)0; } if (lk == 0) release_sem_lock(lh.sem_id); } if ((h = calloc(1, sizeof(uodbc_stats_handle_t))) == NULL) return -1; memcpy(h, &lh, sizeof(uodbc_stats_handle_t)); /* * If caller asked for write access it is assumed it is going to * change the statistics and so it needs an entry in the stats. */ if (mode & UODBC_STATS_WRITE) { int lk; lk = acquire_sem_lock(lh.sem_id); for (i = 0; i < (sizeof(h->stats->perpid) / sizeof(h->stats->perpid[0])); i++) { if (h->stats->perpid[i].pid == (pid_t)0) { h->stats->perpid[i].pid = getpid(); h->stats->perpid[i].n_env = 0; h->stats->perpid[i].n_dbc = 0; h->stats->perpid[i].n_stmt = 0; h->stats->perpid[i].n_desc = 0; break; } } if (lk == 0) release_sem_lock(lh.sem_id); } *(uodbc_stats_handle_t **)rh = h; return 0; } /************************************************************************/ /* */ /* uodbc_close_stats */ /* ================= */ /* */ /************************************************************************/ int uodbc_close_stats( void *h) { uodbc_stats_handle_t *sh; sh = (uodbc_stats_handle_t *)h; if (!sh) { snprintf(errmsg, sizeof(errmsg), "NULL stats handle"); return -1; } if (memcmp(sh->id, UODBC_STATS_ID, sizeof(sh->id)) != 0) { snprintf(errmsg, sizeof(errmsg), "Invalid stats handle %p", sh); return -1; } if ((sh->shm_id != -1) && (sh->stats)) { unsigned int i; for (i = 0; i < (sizeof(sh->stats->perpid) / sizeof(sh->stats->perpid[0])); i++) { if (sh->stats->perpid[i].pid == sh->pid) { sh->stats->perpid[i].pid = (pid_t) 0; break; } } shmdt((char *)sh->stats); sh->stats = NULL; sh->shm_id = -1; } /* * Should we examine attach count and delete shared memory? */ memset(sh->id, '\0', sizeof(sh->id)); free(sh); return 0; } /************************************************************************/ /* */ /* uodbc_update_stats */ /* ================== */ /* */ /************************************************************************/ int uodbc_update_stats(void *h, unsigned int stats_type_mask, void *value) { unsigned long type; unsigned int i; uodbc_stats_handle_t *sh; int lk; sh = (uodbc_stats_handle_t *)h; if (!sh) { snprintf(errmsg, sizeof(errmsg), "NULL stats handle"); return -1; } if (memcmp(sh->id, UODBC_STATS_ID, sizeof(sh->id)) != 0) { snprintf(errmsg, sizeof(errmsg), "Invalid stats handle %p", h); return -1; } if (!sh->stats) { snprintf(errmsg, sizeof(errmsg), "stats memory not mapped"); return -1; } lk = acquire_sem_lock(sh->sem_id); /* * Find this PID in array */ for (i = 0; i < (sizeof(sh->stats->perpid) / sizeof(sh->stats->perpid[0])); i++) { if (sh->stats->perpid[i].pid == sh->pid) break; } /* * Check if array full. */ if ( i >= (sizeof(sh->stats->perpid) / sizeof(sh->stats->perpid[0]))) { /* * array full - process not entered. */ if (lk == 0) release_sem_lock(sh->sem_id); return 0; } type = stats_type_mask & UODBC_STATS_TYPE_TYPE_MASK; switch(type) { case UODBC_STATS_TYPE_HENV: { sh->stats->perpid[i].n_env += (long)value; break; } case UODBC_STATS_TYPE_HDBC: { sh->stats->perpid[i].n_dbc += (long)value; break; } case UODBC_STATS_TYPE_HSTMT: { sh->stats->perpid[i].n_stmt += (long)value; break; } case UODBC_STATS_TYPE_HDESC: { sh->stats->perpid[i].n_desc += (long)value; break; } default: { break; } } if (lk == 0) release_sem_lock(sh->sem_id); return 0; } /************************************************************************/ /* */ /* uodbc_stats_error */ /* ================= */ /* */ /************************************************************************/ char *uodbc_stats_error( char *buf, size_t buflen) { if (!buf) return NULL; if (strlen(errmsg) > buflen) { memcpy(buf, errmsg, buflen - 1); buf[buflen - 1] = '\0'; } else { strcpy(buf, errmsg); } return buf; } /************************************************************************/ /* */ /* uodbc_get_stats */ /* =============== */ /* */ /* This function should be provided with an array of statistic */ /* structures which will be filled with the required statistics */ /* records. */ /* */ /* ret_stats = uodbc_get_stats(h, request_pid, s, n_stats); */ /* */ /* h = a statistics handle returned from uodbc_open_stats(). */ /* request_pid = */ /* -1 = return stats on all attached processes. */ /* n (n > 0) = return stats on specific process request_pid. */ /* 0 = return list of processes attached. */ /* s = ptr to array of statistics structures. */ /* n_stats = number of statistics structures at s. */ /* ret_stats = number of stats structures filled in at s. */ /* */ /************************************************************************/ int uodbc_get_stats( void *h, pid_t request_pid, uodbc_stats_retentry *s, int n_stats) { uodbc_stats_handle_t *sh; unsigned int i; long n_env=0; long n_dbc=0; long n_stmt=0; long n_desc=0; int cur_stat; sh = (uodbc_stats_handle_t *)h; if (!sh) { snprintf(errmsg, sizeof(errmsg), "NULL stats return ptr supplied"); return -1; } if (n_stats < 1) { snprintf(errmsg, sizeof(errmsg), "No stats return structures supplied"); return -1; } if (!sh) { snprintf(errmsg, sizeof(errmsg), "NULL stats handle"); return -1; } if (memcmp(sh->id, UODBC_STATS_ID, sizeof(sh->id)) != 0) { snprintf(errmsg, sizeof(errmsg), "Invalid stats handle %p", sh); return -1; } if (!sh->stats) { snprintf(errmsg, sizeof(errmsg), "stats memory not mapped"); return -1; } cur_stat = 0; for (i = 0; i < (sizeof(sh->stats->perpid) / sizeof(sh->stats->perpid[0])); i++) { if (sh->stats->perpid[i].pid > 0) { int sts; /* * Check this process still exists and if not zero counts. */ sts = kill(sh->stats->perpid[i].pid, 0); if ((sts == 0) || ((sts < 0) && (errno == EPERM))) { ; } else { sh->stats->perpid[i].pid = 0; sh->stats->perpid[i].n_env = 0; sh->stats->perpid[i].n_dbc = 0; sh->stats->perpid[i].n_stmt = 0; sh->stats->perpid[i].n_desc = 0; } } if (((request_pid == (pid_t)-1) && (sh->stats->perpid[i].pid > 0)) || (sh->stats->perpid[i].pid == request_pid)) { n_env += sh->stats->perpid[i].n_env; n_dbc += sh->stats->perpid[i].n_dbc; n_stmt += sh->stats->perpid[i].n_stmt; n_desc += sh->stats->perpid[i].n_desc; } else if (request_pid == (pid_t)0) { s[cur_stat].type = UODBC_STAT_LONG; s[cur_stat].value.l_value = sh->stats->perpid[i].pid; strcpy(s[cur_stat].name, "PID"); if (++cur_stat > n_stats) return cur_stat; } } if (request_pid == (pid_t)0) return cur_stat; s[cur_stat].type = UODBC_STAT_LONG; s[cur_stat].value.l_value = n_env; strcpy(s[cur_stat].name, "Environments"); if (++cur_stat > n_stats) return cur_stat; s[cur_stat].type = UODBC_STAT_LONG; s[cur_stat].value.l_value = n_dbc; strcpy(s[cur_stat].name, "Connections"); if (++cur_stat > n_stats) return cur_stat; s[cur_stat].type = UODBC_STAT_LONG; s[cur_stat].value.l_value = n_stmt; strcpy(s[cur_stat].name, "Statements"); if (++cur_stat > n_stats) return cur_stat; s[cur_stat].type = UODBC_STAT_LONG; s[cur_stat].value.l_value = n_desc; strcpy(s[cur_stat].name, "Descriptors"); if (++cur_stat > n_stats) return cur_stat; return cur_stat; } /************************************************************************/ /* */ /* acquire_sem_lock */ /* ================ */ /* */ /* This function locks other threads/processes out whilst a change to */ /* to the statistics is made. It uses a global semaphore which was */ /* created in uodbc_open_stats(). The semaphore set contains only the */ /* one semaphore which is incremented to 1 when locked. All semops */ /* are performed with SEM_UNDO so if the process unexepctedly exits */ /* sempahore operations are undone. */ /* */ /* NOTE: some older platforms have a kernel limit on the number of */ /* SEM_UNDOs structures that may be used. If you run out, you will */ /* either have to increase the limit or take out the SEM_UNDO in this */ /* function and release_sem_lock() and hope uodbc_update_stats() never */ /* causes a preature exit. */ /* */ /************************************************************************/ static int acquire_sem_lock(int sem_id) { /* * Semaphore operations: */ /* lock the semaphore */ struct sembuf op_lock[2] = { {0, 0, 0}, /* Wait for [0] (lock) to equal 0 */ {0, 1, SEM_UNDO} /* increment [0] to lock */ }; if (semop(sem_id, &op_lock[0], 2) < 0) { return -1; } return 0; } /************************************************************************/ /* */ /* release_sem_lock */ /* ================ */ /* */ /* This function unlocks the semaphore used to lock other */ /* threads/processes out whilst a change to the statistics is made. */ /* It uses a global semaphore which was created in uodbc_open_stats(). */ /* The semaphore set contains only the one semaphore which is */ /* incremented to 1 when locked and decremented when unlocked. */ /* All semops are performed with SEM_UNDO so if the process */ /* unexepctedly exits sempahore operations are undone. */ /* */ /* NOTE: some older platforms have a kernel limit on the number of */ /* SEM_UNDOs structures that may be used. If you run out, you will */ /* either have to increase the limit or take out the SEM_UNDO in this */ /* function and acquire_sem_lock() and hope uodbc_update_stats() never */ /* causes a preature exit. */ /* */ /************************************************************************/ static int release_sem_lock(int sem_id) { /* * Semaphore operations: */ /* unlock the semaphore */ struct sembuf op_unlock[1] = { {0, -1, SEM_UNDO}, /* Decrement [0] lock back to zero */ }; if (semop(sem_id, &op_unlock[0], 1) < 0) { return -1; } return 0; } #else int uodbc_open_stats( void **rh, unsigned int mode) { return -1; } int uodbc_close_stats( void *h) { return -1; } char *uodbc_stats_error( char *buf, size_t buflen) { const char *notbuilt="unixODBC not built with statistics code"; if (!buf) return NULL; if (strlen(notbuilt) > buflen) { memcpy(buf, notbuilt, buflen - 1); buf[buflen - 1] = '\0'; } else { strcpy(buf, notbuilt); } return buf; } int uodbc_get_stats( void *h, pid_t request_pid, uodbc_stats_retentry *s, int n_stats) { return -1; } int uodbc_update_stats(void *h, unsigned int stats_type_mask, void *value) { return -1; } #endif /* COLLECT_STATS */ unixODBC-2.3.12/DriverManager/__stats.h000066400000000000000000000056421446441710500175620ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: __stats.h,v 1.2 2005/02/01 10:24:24 lurcher Exp $ * * $Log: __stats.h,v $ * Revision 1.2 2005/02/01 10:24:24 lurcher * Cope if SHLIBEXT is not set * * Revision 1.1.1.1 2001/10/17 16:40:09 lurcher * * First upload to SourceForge * * Revision 1.1 2000/12/18 11:53:51 martin * * handle statistic API. * * **********************************************************************/ #ifndef UNIXODBC__STATS_H #define UNIXODBC__STATS_H 1 #include #include #ifdef HAVE_SYS_STAT_H #include #endif typedef struct uodbc_stats_proc { pid_t pid; /* process ID */ long n_env; /* # of henvs */ long n_dbc; /* # of hdbcs */ long n_stmt; /* # of hstmts */ long n_desc; /* # of hdescs */ } uodbc_stats_proc_t; typedef struct uodbc_stats { int n_pid; /* # of PIDs attached */ uodbc_stats_proc_t perpid[20]; } uodbc_stats_t; typedef struct uodbc_stats_handle { char id[5]; /* identifier */ # define UODBC_STATS_ID "UODBC" int sem_id; /* sempahore ID */ int shm_id; /* shared memory ID */ uodbc_stats_t *stats; /* ptr to stats in shared mem */ pid_t pid; } uodbc_stats_handle_t; int uodbc_update_stats(void *rh, unsigned int type, void *value); #define UODBC_STATS_TYPE_TYPE_MASK 0xffff #define UODBC_STATS_TYPE_HENV 1 #define UODBC_STATS_TYPE_HDBC 2 #define UODBC_STATS_TYPE_HSTMT 3 #define UODBC_STATS_TYPE_HDESC 4 #endif /* UNIXODBC__STATS_H */ unixODBC-2.3.12/DriverManager/drivermanager.h000066400000000000000000002347211446441710500207560ustar00rootroot00000000000000#ifndef _DRIVERMANAGER_H #define _DRIVERMANAGER_H #define ODBCVER 0x0380 #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_PWD_H #include #endif #include #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_TIME_H #include #endif #ifdef HAVE_SYNCH_H #include #endif #ifdef HAVE_LIBPTH #include #elif HAVE_LIBPTHREAD #include #elif HAVE_LIBTHREAD #include #endif #define SQL_NOUNICODEMAP #define UNICODE #include #include #include #include /* THIS WILL BRING IN sql.h and sqltypes.h AS WELL AS PROVIDE MS EXTENSIONS */ #include #include "__stats.h" /* * iconv support */ #ifdef HAVE_ICONV #include #include #endif #ifdef UNICODE_ENCODING #define DEFAULT_ICONV_ENCODING UNICODE_ENCODING #else #define DEFAULT_ICONV_ENCODING "auto-search" #endif #define ERROR_PREFIX "[unixODBC]" #define DM_ERROR_PREFIX "[Driver Manager]" #define LOG_MESSAGE_LEN 128 /* length of string to display in log */ /* * SQLSetStmt/ConnectionAttr limits */ #define SQL_CONN_DRIVER_MIN 20000 #define SQL_STMT_DRIVER_MIN 20000 /* * its possible that the driver has a different definition of a handle to the driver * manager, DB2 64bit is a example of this */ #define DRV_SQLHANDLE SQLHANDLE #define DRV_SQLHDESC SQLHDESC /* * DEFAULT FILE NAMES * */ /* * magic numbers */ #define HENV_MAGIC 19289 #define HDBC_MAGIC 19290 #define HSTMT_MAGIC 19291 #define HDESC_MAGIC 19292 /* * states */ #define STATE_E0 0 #define STATE_E1 1 #define STATE_E2 2 #define STATE_C0 0 #define STATE_C1 1 #define STATE_C2 2 #define STATE_C3 3 #define STATE_C4 4 #define STATE_C5 5 #define STATE_C6 6 #define STATE_S0 0 #define STATE_S1 1 #define STATE_S2 2 #define STATE_S3 3 #define STATE_S4 4 #define STATE_S5 5 #define STATE_S6 6 #define STATE_S7 7 #define STATE_S8 8 #define STATE_S9 9 #define STATE_S10 10 #define STATE_S11 11 #define STATE_S12 12 #define STATE_S13 13 /* SQLExecute/SQLExecDirect/SQLMoreResult returned SQL_PARAM_DATA_AVAILABLE */ #define STATE_S14 14 /* SQL_PARAM_DATA_AVAILABLE version of S9, Must Get */ #define STATE_S15 15 /* SQL_PARAM_DATA_AVAILABLE version of S10, Can Get */ #define STATE_D0 0 #define STATE_D1i 1 #define STATE_D1e 2 /* * rules to extract diag/error record from driver */ #define DEFER_R0 0 /* Not defer extracting diag/err record from driver. Use this as default */ #define DEFER_R1 1 /* defer extracting diag/err record from driver when SQL_SUCCESS_WITH_INFO is returned */ #define DEFER_R2 2 /* defer extracting diag/err record from driver when SQL_ERROR is returned */ #define DEFER_R3 3 /* defer extracting diag/err record from driver when SQL_SUCCESS_WITH_INFO or SQL_ERROR is returned */ /* * structure to contain the loaded lib entry points */ struct driver_func { int ordinal; char *name; void *dm_func; /* this is to fix what seems a bug in */ /* some dlopen implemnations where dlsym */ /* will return the driver manager func */ /* not the driver one */ void *dm_funcW; SQLRETURN (*func)(); SQLRETURN (*funcW)(); /* function with a unicode W */ SQLRETURN (*funcA)(); /* function with a unicode A */ int can_supply; /* this is used to indicate that */ /* the DM can execute the function */ /* even if the driver does not */ /* supply it */ }; typedef struct error { SQLWCHAR sqlstate[ 6 ]; SQLWCHAR *msg; SQLINTEGER native_error; int return_val; SQLRETURN diag_column_number_ret; SQLRETURN diag_row_number_ret; SQLRETURN diag_class_origin_ret; SQLRETURN diag_subclass_origin_ret; SQLRETURN diag_connection_name_ret; SQLRETURN diag_server_name_ret; SQLINTEGER diag_column_number; SQLLEN diag_row_number; SQLWCHAR diag_class_origin[ 128 ]; SQLWCHAR diag_subclass_origin[ 128 ]; SQLWCHAR diag_connection_name[ 128 ]; SQLWCHAR diag_server_name[ 128 ]; struct error *next; struct error *prev; } ERROR; typedef struct error_header { int error_count; ERROR *error_list_head; ERROR *error_list_tail; int internal_count; ERROR *internal_list_head; ERROR *internal_list_tail; } EHEADER; typedef struct error_head { EHEADER sql_error_head; EHEADER sql_diag_head; void *owning_handle; int handle_type; SQLRETURN return_code; SQLINTEGER header_set; SQLRETURN diag_cursor_row_count_ret; SQLRETURN diag_dynamic_function_ret; SQLRETURN diag_dynamic_function_code_ret; SQLRETURN diag_number_ret; SQLRETURN diag_row_count_ret; SQLLEN diag_cursor_row_count; SQLWCHAR diag_dynamic_function[ 128 ]; SQLINTEGER diag_dynamic_function_code; SQLLEN diag_number; SQLLEN diag_row_count; int defer_extract; /* determine the extraction of driver's message for SQLGetDiagRec or SQLGetDiagField. 0 by default is not deferred */ SQLRETURN ret_code_deferred; /* used for deferring extraction */ } EHEAD; struct log_structure { char *program_name; char *log_file_name; int log_flag; int pid_logging; /* the log path specifies a directory, and a */ /* log file per pid is created */ int ref_count; /* number of times dm_log_open()'d without dm_log_close() */ }; extern struct log_structure log_info; /* * save connection attr untill after the connect, and then pass on */ struct save_attr { int attr_type; char *str_attr; int str_len; intptr_t intptr_attr; struct save_attr *next; }; /* * attribute extension support */ struct attr_set { char *keyword; char *value; int override; int attribute; int is_int_type; int int_value; struct attr_set *next; }; struct attr_struct { int count; struct attr_set *list; }; int __parse_attribute_string( struct attr_struct *attr_str, char *str, int str_len ); void __release_attr_str( struct attr_struct *attr_str ); void __set_attributes( void *handle, int type ); void __set_local_attributes( void *handle, int type ); void *__attr_override( void *handle, int type, int attribute, void * value, SQLINTEGER *string_length ); void *__attr_override_wide( void *handle, int type, int attribute, void * value, SQLINTEGER *string_length, SQLWCHAR *buffer ); /* * use this to maintain a list of the drivers that are loaded under this env, * and to decide if we want to call SQLAllocHandle( SQL_ENV ) om them */ struct env_lib_struct { char *lib_name; DRV_SQLHANDLE env_handle; int count; int driver_act_ver; /* real version of the driver, keep in the list instead of the env, as * we may have both V2 and V3 drivers in use */ struct env_lib_struct *next; }; typedef struct environment { int type; /* magic number */ struct environment *next_class_list;/* static list of all env handles */ char msg[ LOG_MSG_MAX*2 ]; /* buff to format msgs */ int state; /* state of environment */ int version_set; /* whether ODBC version has been set */ SQLINTEGER requested_version; /* SQL_OV_ODBC2 or SQL_OV_ODBC3 */ int connection_count; /* number of hdbc of this env */ int sql_driver_count; /* used for SQLDrivers */ EHEAD error; /* keep track of errors */ SQLINTEGER connection_pooling; /* does connection pooling operate */ SQLINTEGER cp_match; int fetch_mode; /* for SQLDataSources */ int entry; void *sh; /* statistics handle */ int released; /* Catch a race condition in SQLAPI lib */ struct env_lib_struct *env_lib_list;/* use this to avoid multiple AllocEnv in the driver */ } *DMHENV; #ifdef FAST_HANDLE_VALIDATE struct statement; #endif /* * connection pooling attributes */ typedef struct connection { int type; /* magic number */ struct connection *next_class_list; /* static list of all dbc handles */ char msg[ LOG_MSG_MAX*2 ]; /* buff to format msgs */ int state; /* state of connection */ DMHENV environment; /* environment that own's the connection */ #ifdef FAST_HANDLE_VALIDATE struct statement *statements; /* List of statements owned by this connection */ #endif void *dl_handle; /* handle of the loaded lib */ char dl_name[ 256 ]; /* name of loaded lib */ struct driver_func *functions; /* entry points */ struct driver_func ini_func; /* optinal start end functions */ struct driver_func fini_func; int unicode_driver; /* do we use the W functions in the */ /* driver ? */ DRV_SQLHANDLE driver_env; /* environment handle in client */ DRV_SQLHANDLE driver_dbc; /* connection handle in client */ int driver_version; /* required version of the connected */ /* driver */ int driver_act_ver; /* real version of the driver */ int statement_count; /* number of statements on this dbc */ EHEAD error; /* keep track of errors */ char dsn[ SQL_MAX_DSN_LENGTH + 1 ]; /* where we are connected */ int access_mode; /* variables set via SQLSetConnectAttr */ int access_mode_set; int login_timeout; int login_timeout_set; int auto_commit; int auto_commit_set; int async_enable; int async_enable_set; int auto_ipd; int auto_ipd_set; int connection_timeout; int connection_timeout_set; int metadata_id; int metadata_id_set; int packet_size; int packet_size_set; SQLLEN quite_mode; int quite_mode_set; int txn_isolation; int txn_isolation_set; SQLINTEGER cursors; void *cl_handle; /* handle to the cursor lib */ int trace; char tracefile[ INI_MAX_PROPERTY_VALUE + 1 ]; #ifdef HAVE_LIBPTH pth_mutex_t mutex; /* protect the object */ int protection_level; #elif HAVE_LIBPTHREAD pthread_mutex_t mutex; /* protect the object */ int protection_level; #elif HAVE_LIBTHREAD mutex_t mutex; /* protect the object */ int protection_level; #endif int ex_fetch_mapping; /* disable SQLFetch -> SQLExtendedFetch */ int disable_gf; /* dont call SQLGetFunctions in the driver */ int dont_dlclose; /* disable dlclosing of the handle */ int bookmarks_on; /* bookmarks are set on */ void *pooled_connection; /* points to t connection pool structure */ int pooling_timeout; int ttl; char *_driver_connect_string; int dsn_length; char server[ 128 ]; int server_length; char user[ 128 ]; int user_length; char password[ 128 ]; int password_length; char cli_year[ 5 ]; struct attr_struct env_attribute; /* Extended attribute set info */ struct attr_struct dbc_attribute; struct attr_struct stmt_attribute; struct save_attr *save_attr; /* SQLConnectAttr before connect */ #ifdef HAVE_ICONV iconv_t iconv_cd_uc_to_ascii; /* in and out conversion descriptor */ iconv_t iconv_cd_ascii_to_uc; char unicode_string[ 64 ]; /* name of unicode conversion */ #endif struct env_lib_struct *env_list_ent; /* pointer to reference in the env list */ char probe_sql[ 512 ]; /* SQL to use to check a pool is valid */ int threading_level; /* level of thread protection the DM proves */ int cbs_found; /* Have we queried the driver for the effect of a */ SQLSMALLINT ccb_value; /* COMMIT or a ROLLBACK */ SQLSMALLINT crb_value; } *DMHDBC; struct connection_pool_head; typedef struct connection_pool_entry { time_t expiry_time; int ttl; int timeout; int in_use; struct connection_pool_entry *next; struct connection_pool_head *head; struct connection connection; int cursors; } CPOOLENT; typedef struct connection_pool_head { struct connection_pool_head *next; char *_driver_connect_string; int dsn_length; char server[ 128 ]; int server_length; char user[ 128 ]; int user_length; char password[ 128 ]; int password_length; volatile int num_entries; /* always at least 1 */ CPOOLENT *entries; } CPOOLHEAD; void pool_unreserve( CPOOLHEAD *pooh ); typedef struct descriptor { int type; /* magic number */ struct descriptor *next_class_list; /* static list of all desc handles */ char msg[ LOG_MSG_MAX*2 ]; /* buff to format msgs */ int state; /* state of descriptor */ #ifdef FAST_HANDLE_VALIDATE struct descriptor *prev_class_list;/* static list of all desc handles */ #endif EHEAD error; /* keep track of errors */ DRV_SQLHDESC driver_desc; /* driver descriptor */ DMHDBC connection; /* DM connection that owns this */ int implicit; /* created by a AllocStmt */ void *associated_with; /* statement that this is a descriptor of */ #ifdef HAVE_LIBPTH pth_mutex_t mutex; /* protect the object */ #elif HAVE_LIBPTHREAD pthread_mutex_t mutex; /* protect the object */ #elif HAVE_LIBTHREAD mutex_t mutex; /* protect the object */ #endif } *DMHDESC; typedef struct statement { int type; /* magic number */ struct statement *next_class_list; /* static list of all stmt handles */ char msg[ LOG_MSG_MAX*2 ]; /* buff to format msgs */ int state; /* state of statement */ #ifdef FAST_HANDLE_VALIDATE struct statement *prev_class_list; /* static list of all stmt handles */ struct statement *next_conn_list; /* Single linked list storing statements owned by "connection" connection */ #endif DMHDBC connection; /* DM connection that owns this */ DRV_SQLHANDLE driver_stmt; /* statement in the driver */ SQLSMALLINT hascols; /* is there a result set */ int prepared; /* the statement has been prepared */ int interupted_func; /* current function running async */ /* or NEED_DATA */ int interupted_state; /* state we went into need data or */ /* still executing from */ int bookmarks_on; /* bookmarks are set on */ EHEAD error; /* keep track of errors */ SQLINTEGER metadata_id; DMHDESC ipd; /* current descriptors */ DMHDESC apd; DMHDESC ird; DMHDESC ard; DMHDESC implicit_ipd; /* implicit descriptors */ DMHDESC implicit_apd; DMHDESC implicit_ird; DMHDESC implicit_ard; SQLULEN *fetch_bm_ptr; /* Saved for ODBC3 to ODBC2 mapping */ SQLULEN *row_ct_ptr; /* row count ptr */ SQLUSMALLINT *row_st_arr; /* row status array */ SQLULEN row_array_size; SQLPOINTER valueptr; /* Default buffer for SQLParamData() */ #ifdef HAVE_LIBPTH pth_mutex_t mutex; /* protect the object */ #elif HAVE_LIBPTHREAD pthread_mutex_t mutex; /* protect the object */ #elif HAVE_LIBTHREAD mutex_t mutex; /* protect the object */ #endif int eod; /* when in S6 has EOD been returned */ } *DMHSTMT; #if defined ( HAVE_LIBPTHREAD ) || defined ( HAVE_LIBTHREAD ) || defined ( HAVE_LIBPTH ) #define TS_LEVEL0 0 /* no implicit protection, only for */ /* dm internal structures */ #define TS_LEVEL1 1 /* protection on a statement level */ #define TS_LEVEL2 2 /* protection on a connection level */ #define TS_LEVEL3 3 /* protection on a environment level */ #endif void mutex_lib_entry( void ); void mutex_lib_exit( void ); void mutex_pool_entry( void ); void mutex_pool_exit( void ); void mutex_iconv_entry( void ); void mutex_iconv_exit( void ); typedef struct connection_pair { char *name; char *value; struct connection_pair *next; } *connection_attribute; /* * defined down here to get the DMHDBC definition */ void __handle_attr_extensions( DMHDBC connection, char *dsn, char *driver_name ); /* * handle allocation functions */ DMHENV __share_env( int *first ); DMHENV __alloc_env( void ); int __validate_env( DMHENV ); void __release_env( DMHENV environment ); int __validate_env_mark_released( DMHENV env ); DMHDBC __alloc_dbc( void ); int __validate_dbc( DMHDBC ); void __release_dbc( DMHDBC connection ); DMHSTMT __alloc_stmt( void ); void __register_stmt ( DMHDBC connection, DMHSTMT statement ); void __set_stmt_state ( DMHDBC connection, SQLSMALLINT cb_value ); int __validate_stmt( DMHSTMT ); void __release_stmt( DMHSTMT ); DMHDESC __alloc_desc( void ); int __validate_desc( DMHDESC ); void __release_desc( DMHDESC ); /* * generic functions */ SQLRETURN __SQLAllocHandle( SQLSMALLINT handle_type, SQLHANDLE input_handle, SQLHANDLE *output_handle, SQLINTEGER requested_version ); SQLRETURN __SQLFreeHandle( SQLSMALLINT handle_type, SQLHANDLE handle ); SQLRETURN __SQLGetInfo( SQLHDBC connection_handle, SQLUSMALLINT info_type, SQLPOINTER info_value, SQLSMALLINT buffer_length, SQLSMALLINT *string_length ); int __connect_part_one( DMHDBC connection, char *driver_lib, char *driver_name, int *warnings ); void __disconnect_part_one( DMHDBC connection ); int __connect_part_two( DMHDBC connection ); void __disconnect_part_two( DMHDBC connection ); void __disconnect_part_three( DMHDBC connection ); void __disconnect_part_four( DMHDBC connection ); DMHDBC __get_dbc_root( void ); void __check_for_function( DMHDBC connection, SQLUSMALLINT function_id, SQLUSMALLINT *supported ); int __clean_stmt_from_dbc( DMHDBC connection ); int __clean_desc_from_dbc( DMHDBC connection ); void __map_error_state( char * state, int requested_version ); void __map_error_state_w( SQLWCHAR * wstate, int requested_version ); /* * mapping from ODBC 2 <-> 3 datetime types */ #define MAP_SQL_DM2D 0 #define MAP_SQL_D2DM 1 #define MAP_C_DM2D 2 #define MAP_C_D2DM 3 SQLSMALLINT __map_type( int map, DMHDBC connection, SQLSMALLINT type); /* * error functions */ typedef enum error_id { ERROR_01000, ERROR_01004, ERROR_01S02, ERROR_01S06, ERROR_07005, ERROR_07009, ERROR_08002, ERROR_08003, ERROR_24000, ERROR_25000, ERROR_25S01, ERROR_S1000, ERROR_S1003, ERROR_S1010, ERROR_S1011, ERROR_S1107, ERROR_S1108, ERROR_S1C00, ERROR_HY001, ERROR_HY003, ERROR_HY004, ERROR_HY007, ERROR_HY009, ERROR_HY010, ERROR_HY011, ERROR_HY012, ERROR_HY013, ERROR_HY017, ERROR_HY024, ERROR_HY090, ERROR_HY092, ERROR_HY095, ERROR_HY097, ERROR_HY098, ERROR_HY099, ERROR_HY100, ERROR_HY101, ERROR_HY103, ERROR_HY105, ERROR_HY106, ERROR_HY110, ERROR_HY111, ERROR_HYC00, ERROR_IM001, ERROR_IM002, ERROR_IM003, ERROR_IM004, ERROR_IM005, ERROR_IM010, ERROR_IM012, ERROR_SL004, ERROR_SL009, ERROR_SL010, ERROR_SL008, ERROR_HY000, ERROR_IM011, ERROR_HYT02 } error_id; #define IGNORE_THREAD (-1) #define function_return(l,h,r,d) function_return_ex(l,h,r,FALSE,d) #define SUBCLASS_ODBC 0 #define SUBCLASS_ISO 1 void __post_internal_error( EHEAD *error_handle, error_id, char *txt, int connection_mode ); void __post_internal_error_api( EHEAD *error_handle, error_id, char *txt, int connection_mode, int calling_api ); void __post_internal_error_ex( EHEAD *error_handle, SQLCHAR *sqlstate, SQLINTEGER native_error, SQLCHAR *message_text, int class_origin, int subclass_origin ); void __post_internal_error_ex_noprefix( EHEAD *error_handle, SQLCHAR *sqlstate, SQLINTEGER native_error, SQLCHAR *message_text, int class_origin, int subclass_origin ); void __post_internal_error_ex_w( EHEAD *error_handle, SQLWCHAR *sqlstate, SQLINTEGER native_error, SQLWCHAR *message_text, int class_origin, int subclass_origin ); void __post_internal_error_ex_w_noprefix( EHEAD *error_handle, SQLWCHAR *sqlstate, SQLINTEGER native_error, SQLWCHAR *message_text, int class_origin, int subclass_origin ); void extract_error_from_driver( EHEAD * error_handle, DMHDBC hdbc, int ret_code, int save_to_diag ); int function_return_nodrv( int level, void *handle, int ret_code ); int function_return_ex( int level, void * handle, int ret_code, int save_to_diag, int defer_type ); void function_entry( void *handle ); void setup_error_head( EHEAD *error_header, void *handle, int handle_type ); void clear_error_head( EHEAD *error_header ); SQLWCHAR *ansi_to_unicode_copy( SQLWCHAR * dest, char *src, SQLINTEGER buffer_len, DMHDBC connection, int *wlen ); SQLWCHAR *ansi_to_unicode_alloc( SQLCHAR *str, SQLINTEGER len, DMHDBC connection, int *wlen ); char *unicode_to_ansi_copy( char* dest, int dest_len, SQLWCHAR *src, SQLINTEGER len, DMHDBC connection, int *clen ); char *unicode_to_ansi_alloc( SQLWCHAR *str, SQLINTEGER len, DMHDBC connection, int *clen ); int unicode_setup( DMHDBC connection ); void unicode_shutdown( DMHDBC connection ); char * __get_return_status( SQLRETURN ret, SQLCHAR *buffer ); char * __sql_as_text( SQLINTEGER type ); char * __c_as_text( SQLINTEGER type ); char * __string_with_length( SQLCHAR *out, SQLCHAR *str, SQLINTEGER len ); char * __string_with_length_pass( SQLCHAR *out, SQLCHAR *str, SQLINTEGER len ); char * __string_with_length_hide_pwd( SQLCHAR *out, SQLCHAR *str, SQLINTEGER len ); char * __wstring_with_length( SQLCHAR *out, SQLWCHAR *str, SQLINTEGER len ); char * __wstring_with_length_pass( SQLCHAR *out, SQLWCHAR *str, SQLINTEGER len ); char * __wstring_with_length_hide_pwd( SQLCHAR *out, SQLWCHAR *str, SQLINTEGER len ); SQLWCHAR *wide_strcpy( SQLWCHAR *str1, SQLWCHAR *str2 ); SQLWCHAR *wide_strncpy( SQLWCHAR *str1, SQLWCHAR *str2, int buffer_length ); SQLWCHAR *wide_strcat( SQLWCHAR *str1, SQLWCHAR *str2 ); SQLWCHAR *wide_strdup( SQLWCHAR *str1 ); int wide_strlen( SQLWCHAR *str1 ); int wide_ansi_strncmp( SQLWCHAR *str1, char *str2, int len ); char * __get_pid( SQLCHAR *str ); char * __iptr_as_string( SQLCHAR *s, SQLINTEGER *ptr ); char * __ptr_as_string( SQLCHAR *s, SQLLEN *ptr ); char * __sptr_as_string( SQLCHAR *s, SQLSMALLINT *ptr ); char * __info_as_string( SQLCHAR *s, SQLINTEGER typ ); void __clear_internal_error( struct error *error_handle ); char * __data_as_string( SQLCHAR *s, SQLINTEGER type, SQLLEN *ptr, SQLPOINTER buf ); char * __sdata_as_string( SQLCHAR *s, SQLINTEGER type, SQLSMALLINT *ptr, SQLPOINTER buf ); char * __idata_as_string( SQLCHAR *s, SQLINTEGER type, SQLINTEGER *ptr, SQLPOINTER buf ); char * __col_attr_as_string( SQLCHAR *s, SQLINTEGER type ); char * __fid_as_string( SQLCHAR *s, SQLINTEGER fid ); char * __con_attr_as_string( SQLCHAR *s, SQLINTEGER type ); char * __env_attr_as_string( SQLCHAR *s, SQLINTEGER type ); char * __stmt_attr_as_string( SQLCHAR *s, SQLINTEGER type ); char * __desc_attr_as_string( SQLCHAR *s, SQLINTEGER type ); char * __diag_attr_as_string( SQLCHAR *s, SQLINTEGER type ); char * __type_as_string( SQLCHAR *s, SQLSMALLINT type ); DMHDBC __get_connection( EHEAD * head ); DRV_SQLHANDLE __get_driver_handle( EHEAD * head ); int __get_version( EHEAD * head ); int dm_check_connection_attrs( DMHDBC connection, SQLINTEGER attribute, SQLPOINTER value ); int dm_check_statement_attrs( DMHSTMT statement, SQLINTEGER attribute, SQLPOINTER value ); int __check_stmt_from_dbc( DMHDBC connection, int state ); #define MAX_STATE_ARGS 8 int __check_stmt_from_dbc_v( DMHDBC connection, int statecount, ... ); int __check_stmt_from_desc( DMHDESC desc, int state ); int __check_stmt_from_desc_ird( DMHDESC desc, int state ); /* * These are passed to the cursor lib as helper functions */ struct driver_helper_funcs { void (*__post_internal_error_ex)( EHEAD *error_header, SQLCHAR *sqlstate, SQLINTEGER native_error, SQLCHAR *message_text, int class_origin, int subclass_origin ); void (*__post_internal_error)( EHEAD *error_handle, error_id id, char *txt, int connection_mode ); void (*dm_log_write)( char *function_name, int line, int type, int severity, char *message ); }; /* * thread protection funcs */ #if defined ( HAVE_LIBPTHREAD ) || defined ( HAVE_LIBTHREAD ) || defined ( HAVE_LIBPTH ) void thread_protect( int type, void *handle ); void thread_release( int type, void *handle ); int pool_timedwait( DMHDBC ); void pool_signal(); #else #define thread_protect(a,b) #define thread_release(a,b) #define pool_timedwait(a) #define pool_signal() #endif void dbc_change_thread_support( DMHDBC connection, int level ); #ifdef WITH_HANDLE_REDIRECT void *find_parent_handle( DRV_SQLHANDLE hand, int type ); #endif /* * lookup functions */ char *__find_lib_name( char *dsn, char *lib_name, char *driver_name ); /* * setup the cursor library */ SQLRETURN SQL_API CLConnect( DMHDBC connection, struct driver_helper_funcs * ); /* * connection string functions */ struct con_pair { char *keyword; char *attribute; char *identifier; struct con_pair *next; }; struct con_struct { int count; struct con_pair *list; }; void __generate_connection_string( struct con_struct *con_str, char *str, int str_len ); int __parse_connection_string( struct con_struct *con_str, char *str, int str_len ); int __parse_connection_string_w( struct con_struct *con_str, SQLWCHAR *str, int str_len ); char * __get_attribute_value( struct con_struct * con_str, char * keyword ); void __release_conn( struct con_struct *con_str ); void __get_attr( char ** cp, char ** keyword, char ** value ); struct con_pair * __get_pair( char ** cp ); int __append_pair( struct con_struct *con_str, char *kword, char *value ); void __handle_attr_extensions_cs( DMHDBC connection, struct con_struct *con_str ); void __strip_from_pool( DMHENV env ); void extract_diag_error_w( int htype, DRV_SQLHANDLE handle, DMHDBC connection, EHEAD *head, int return_code, int save_to_diag ); void extract_diag_error( int htype, DRV_SQLHANDLE handle, DMHDBC connection, EHEAD *head, int return_code, int save_to_diag ); void extract_sql_error_w( DRV_SQLHANDLE henv, DRV_SQLHANDLE hdbc, DRV_SQLHANDLE hstmt, DMHDBC connection, EHEAD *head, int return_code ); void extract_sql_error( DRV_SQLHANDLE henv, DRV_SQLHANDLE hdbc, DRV_SQLHANDLE hstmt, DMHDBC connection, EHEAD *head, int return_code ); /* * the following two are part of a effort to get a particular unicode driver working */ SQLINTEGER map_ca_odbc3_to_2( SQLINTEGER field_identifier ); SQLINTEGER map_ca_odbc2_to_3( SQLINTEGER field_identifier ); /* * check the type passed to SQLBindCol is a valid C_TYPE */ int check_target_type( int c_type, int connection_mode); /* * entry exit functions in drivers */ #define ODBC_INI_FUNCTION "SQLDriverLoad" #define ODBC_FINI_FUNCTION "SQLDriverUnload" /* * driver manager logging functions */ void dm_log_open( char *program_name, char *log_file, int pid_logging ); void dm_log_write( char *function_name, int line, int type, int severity, char *message ); void dm_log_write_diag( char *message ); void dm_log_close( void ); /* * connection pooling functions */ int search_for_pool( DMHDBC connection, SQLCHAR *server_name, SQLSMALLINT name_length1, SQLCHAR *user_name, SQLSMALLINT name_length2, SQLCHAR *authentication, SQLSMALLINT name_length3, SQLCHAR *connect_string, SQLSMALLINT connect_string_length, CPOOLHEAD **pooh, int retrying ); void return_to_pool( DMHDBC connection ); int add_to_pool( DMHDBC connection, CPOOLHEAD *pooh ); /* * Macros to check and call functions in the driver */ #define DM_SQLALLOCCONNECT 0 #define CHECK_SQLALLOCCONNECT(con) (con->functions[0].func!=NULL) #define SQLALLOCCONNECT(con,env,oh)\ ((SQLRETURN (*)(SQLHENV, SQLHDBC*))\ con->functions[0].func)(env,oh) #define DM_SQLALLOCENV 1 #define CHECK_SQLALLOCENV(con) (con->functions[1].func!=NULL) #define SQLALLOCENV(con,oh)\ ((SQLRETURN (*)(SQLHENV*))\ con->functions[1].func)(oh) #define DM_SQLALLOCHANDLE 2 #define CHECK_SQLALLOCHANDLE(con) (con->functions[2].func!=NULL) /* * if the function is in the cursor lib, pass a additional * arg that allows the cursor lib to get the dm handle */ #define SQLALLOCHANDLE(con,ht,ih,oh,dmh)\ (con->cl_handle?\ ((SQLRETURN (*)(SQLSMALLINT, SQLHANDLE, SQLHANDLE*, SQLHANDLE))\ con->functions[2].func)(ht,ih,oh,dmh):\ ((SQLRETURN (*)(SQLSMALLINT, SQLHANDLE, SQLHANDLE*))\ con->functions[2].func)(ht,ih,oh)) #define DM_SQLALLOCSTMT 3 #define CHECK_SQLALLOCSTMT(con) (con->functions[3].func!=NULL) #define SQLALLOCSTMT(con,dbc,oh,dmh)\ (con->cl_handle?\ ((SQLRETURN (*)(SQLHDBC, SQLHSTMT*, SQLHANDLE))\ con->functions[3].func)(dbc,oh,dmh):\ ((SQLRETURN (*)(SQLHDBC, SQLHSTMT*))\ con->functions[3].func)(dbc,oh)) #define DM_SQLALLOCHANDLESTD 4 #define DM_SQLBINDCOL 5 #define CHECK_SQLBINDCOL(con) (con->functions[5].func!=NULL) #define SQLBINDCOL(con,stmt,cn,tt,tvp,bl,sli)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT,\ SQLSMALLINT, SQLPOINTER, SQLLEN, SQLLEN*))\ con->functions[5].func)\ (stmt,cn,tt,tvp,bl,sli) #define DM_SQLBINDPARAM 6 #define CHECK_SQLBINDPARAM(con) (con->functions[6].func!=NULL) #define SQLBINDPARAM(con,stmt,pn,vt,pt,cs,dd,pvp,ind)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLUSMALLINT, SQLSMALLINT,\ SQLSMALLINT, SQLULEN, SQLSMALLINT,\ SQLPOINTER, SQLLEN*))\ con->functions[6].func)\ (stmt,pn,vt,pt,cs,dd,pvp,ind) #define DM_SQLBINDPARAMETER 7 #define CHECK_SQLBINDPARAMETER(con) (con->functions[7].func!=NULL) #define SQLBINDPARAMETER(con,stmt,pn,typ,vt,pt,cs,dd,pvp,bl,ind)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT,\ SQLSMALLINT, SQLSMALLINT, SQLSMALLINT,\ SQLULEN, SQLSMALLINT, SQLPOINTER,\ SQLLEN, SQLLEN*))\ con->functions[7].func)\ (stmt,pn,typ,vt,pt,cs,dd,pvp,bl,ind) #define DM_SQLBROWSECONNECT 8 #define CHECK_SQLBROWSECONNECT(con) (con->functions[8].func!=NULL) #define SQLBROWSECONNECT(con,dbc,ics,sl1,ocs,bl,sl2)\ ((SQLRETURN (*)(SQLHDBC,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT, SQLSMALLINT*))\ con->functions[8].func)\ (dbc,ics,sl1,ocs,bl,sl2) #define CHECK_SQLBROWSECONNECTW(con) (con->functions[8].funcW!=NULL) #define SQLBROWSECONNECTW(con,dbc,ics,sl1,ocs,bl,sl2)\ ((SQLRETURN (*)(SQLHDBC,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*))\ con->functions[8].funcW)\ (dbc,ics,sl1,ocs,bl,sl2) #define DM_SQLBULKOPERATIONS 9 #define CHECK_SQLBULKOPERATIONS(con) (con->functions[9].func!=NULL) #define SQLBULKOPERATIONS(con,stmt,op)\ ((SQLRETURN (*)(SQLHSTMT, SQLSMALLINT))\ con->functions[9].func)(stmt,op) #define DM_SQLCANCEL 10 #define CHECK_SQLCANCEL(con) (con->functions[10].func!=NULL) #define SQLCANCEL(con,stmt)\ ((SQLRETURN (*)(SQLHSTMT))\ con->functions[10].func)(stmt) #define DM_SQLCLOSECURSOR 11 #define CHECK_SQLCLOSECURSOR(con) (con->functions[11].func!=NULL) #define SQLCLOSECURSOR(con,stmt)\ ((SQLRETURN (*)(SQLHSTMT))\ con->functions[11].func)(stmt) #define DM_SQLCOLATTRIBUTE 12 #define CHECK_SQLCOLATTRIBUTE(con) (con->functions[12].func!=NULL) #define SQLCOLATTRIBUTE(con,stmt,cn,fi,cap,bl,slp,nap)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT,\ SQLUSMALLINT, SQLPOINTER, SQLSMALLINT,\ SQLSMALLINT*, SQLLEN*))\ con->functions[12].func)\ (stmt,cn,fi,cap,bl,slp,nap) #define CHECK_SQLCOLATTRIBUTEW(con) (con->functions[12].funcW!=NULL) #define SQLCOLATTRIBUTEW(con,stmt,cn,fi,cap,bl,slp,nap)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT,\ SQLUSMALLINT, SQLPOINTER, SQLSMALLINT,\ SQLSMALLINT*, SQLLEN*))\ con->functions[12].funcW)\ (stmt,cn,fi,cap,bl,slp,nap) #define DM_SQLCOLATTRIBUTES 13 #define CHECK_SQLCOLATTRIBUTES(con) (con->functions[13].func!=NULL) #define SQLCOLATTRIBUTES(con,stmt,cn,fi,cap,bl,slp,nap)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT,\ SQLUSMALLINT, SQLPOINTER, SQLSMALLINT,\ SQLSMALLINT*, SQLLEN*))\ con->functions[13].func)\ (stmt,cn,fi,cap,bl,slp,nap) #define CHECK_SQLCOLATTRIBUTESW(con) (con->functions[13].funcW!=NULL) #define SQLCOLATTRIBUTESW(con,stmt,cn,fi,cap,bl,slp,nap)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT,\ SQLUSMALLINT, SQLPOINTER, SQLSMALLINT,\ SQLSMALLINT*, SQLLEN*))\ con->functions[13].funcW)\ (stmt,cn,fi,cap,bl,slp,nap) #define DM_SQLCOLUMNPRIVILEGES 14 #define CHECK_SQLCOLUMNPRIVILEGES(con) (con->functions[14].func!=NULL) #define SQLCOLUMNPRIVILEGES(con,stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT))\ con->functions[14].func)\ (stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4) #define CHECK_SQLCOLUMNPRIVILEGESW(con) (con->functions[14].funcW!=NULL) #define SQLCOLUMNPRIVILEGESW(con,stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT))\ con->functions[14].funcW)\ (stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4) #define DM_SQLCOLUMNS 15 #define CHECK_SQLCOLUMNS(con) (con->functions[15].func!=NULL) #define SQLCOLUMNS(con,stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT))\ con->functions[15].func)\ (stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4) #define CHECK_SQLCOLUMNSW(con) (con->functions[15].funcW!=NULL) #define SQLCOLUMNSW(con,stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT))\ con->functions[15].funcW)\ (stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4) #define DM_SQLCONNECT 16 #define CHECK_SQLCONNECT(con) (con->functions[16].func!=NULL) #define SQLCONNECT(con,dbc,dsn,l1,uid,l2,at,l3)\ ((SQLRETURN (*)(SQLHDBC,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT))\ con->functions[16].func)\ (dbc,dsn,l1,uid,l2,at,l3) #define CHECK_SQLCONNECTW(con) (con->functions[16].funcW!=NULL) #define SQLCONNECTW(con,dbc,dsn,l1,uid,l2,at,l3)\ ((SQLRETURN (*)(SQLHDBC,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT))\ con->functions[16].funcW)\ (dbc,dsn,l1,uid,l2,at,l3) #define DM_SQLCOPYDESC 17 #define CHECK_SQLCOPYDESC(con) (con->functions[17].func!=NULL) #define SQLCOPYDESC(con,sd,td)\ ((SQLRETURN (*)(SQLHDESC, SQLHDESC))\ con->functions[17].func)(sd,td) #define DM_SQLDATASOURCES 18 #define DM_SQLDESCRIBECOL 19 #define CHECK_SQLDESCRIBECOL(con) (con->functions[19].func!=NULL) #define SQLDESCRIBECOL(con,stmt,cnum,cn,bli,nl,dt,cs,dd,n)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLUSMALLINT, SQLCHAR*, SQLSMALLINT,\ SQLSMALLINT*, SQLSMALLINT*, SQLULEN*,\ SQLSMALLINT*, SQLSMALLINT*))\ con->functions[19].func)\ (stmt,cnum,cn,bli,nl,dt,cs,dd,n) #define CHECK_SQLDESCRIBECOLW(con) (con->functions[19].funcW!=NULL) #define SQLDESCRIBECOLW(con,stmt,cnum,cn,bli,nl,dt,cs,dd,n)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLUSMALLINT, SQLWCHAR*, SQLSMALLINT,\ SQLSMALLINT*, SQLSMALLINT*, SQLULEN*,\ SQLSMALLINT*, SQLSMALLINT*))\ con->functions[19].funcW)\ (stmt,cnum,cn,bli,nl,dt,cs,dd,n) #define DM_SQLDESCRIBEPARAM 20 #define CHECK_SQLDESCRIBEPARAM(con) (con->functions[20].func!=NULL) #define SQLDESCRIBEPARAM(con,stmt,pn,dtp,psp,ddp,np)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLUSMALLINT, SQLSMALLINT*, SQLULEN*,\ SQLSMALLINT*, SQLSMALLINT*))\ con->functions[20].func)\ (stmt,pn,dtp,psp,ddp,np) #define DM_SQLDISCONNECT 21 #define CHECK_SQLDISCONNECT(con) (con->functions[21].func!=NULL) #define SQLDISCONNECT(con,dbc)\ ((SQLRETURN (*)(SQLHDBC))\ con->functions[21].func)(dbc) #define DM_SQLDRIVERCONNECT 22 #define CHECK_SQLDRIVERCONNECT(con) (con->functions[22].func!=NULL) #define SQLDRIVERCONNECT(con,dbc,wh,ics,sl1,ocs,bl,sl2p,dc)\ ((SQLRETURN (*)(SQLHDBC, SQLHWND,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLSMALLINT*, SQLUSMALLINT))\ con->functions[22].func)\ (dbc,wh,ics,sl1,ocs,bl,sl2p,dc) #define CHECK_SQLDRIVERCONNECTW(con) (con->functions[22].funcW!=NULL) #define SQLDRIVERCONNECTW(con,dbc,wh,ics,sl1,ocs,bl,sl2p,dc)\ ((SQLRETURN (*)(SQLHDBC, SQLHWND,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLSMALLINT*, SQLUSMALLINT))\ con->functions[22].funcW)\ (dbc,wh,ics,sl1,ocs,bl,sl2p,dc) #define DM_SQLDRIVERS 23 #define DM_SQLENDTRAN 24 #define CHECK_SQLENDTRAN(con) (con->functions[24].func!=NULL) #define SQLENDTRAN(con,ht,h,op)\ ((SQLRETURN (*)(SQLSMALLINT, SQLHANDLE, SQLSMALLINT))\ con->functions[24].func)(ht,h,op) #define DM_SQLERROR 25 #define CHECK_SQLERROR(con) (con->functions[25].func!=NULL) #define SQLERROR(con,env,dbc,stmt,st,nat,msg,mm,pcb)\ ((SQLRETURN (*)(SQLHENV, SQLHDBC, SQLHSTMT,\ SQLCHAR*, SQLINTEGER*,\ SQLCHAR*, SQLSMALLINT, SQLSMALLINT*))\ con->functions[25].func)\ (env,dbc,stmt,st,nat,msg,mm,pcb) #define CHECK_SQLERRORW(con) (con->functions[25].funcW!=NULL) #define SQLERRORW(con,env,dbc,stmt,st,nat,msg,mm,pcb)\ ((SQLRETURN (*)(SQLHENV, SQLHDBC, SQLHSTMT,\ SQLWCHAR*, SQLINTEGER*,\ SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*))\ con->functions[25].funcW)\ (env,dbc,stmt,st,nat,msg,mm,pcb) #define DM_SQLEXECDIRECT 26 #define CHECK_SQLEXECDIRECT(con) (con->functions[26].func!=NULL) #define SQLEXECDIRECT(con,stmt,sql,len)\ ((SQLRETURN (*)(SQLHSTMT, SQLCHAR*, SQLINTEGER))\ con->functions[26].func)(stmt,sql,len) #define CHECK_SQLEXECDIRECTW(con) (con->functions[26].funcW!=NULL) #define SQLEXECDIRECTW(con,stmt,sql,len)\ ((SQLRETURN (*)(SQLHSTMT, SQLWCHAR*, SQLINTEGER))\ con->functions[26].funcW)(stmt,sql,len) #define DM_SQLEXECUTE 27 #define CHECK_SQLEXECUTE(con) (con->functions[27].func!=NULL) #define SQLEXECUTE(con,stmt)\ ((SQLRETURN (*)(SQLHSTMT))\ con->functions[27].func)(stmt) #define DM_SQLEXTENDEDFETCH 28 #define CHECK_SQLEXTENDEDFETCH(con) (con->functions[28].func!=NULL) #define SQLEXTENDEDFETCH(con,stmt,fo,of,rcp,ssa)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT,\ SQLLEN, SQLULEN*, SQLUSMALLINT*))\ con->functions[28].func)\ (stmt,fo,of,rcp,ssa) #define DM_FETCH 29 #define CHECK_SQLFETCH(con) (con->functions[29].func!=NULL) #define SQLFETCH(con,stmt)\ ((SQLRETURN (*)(SQLHSTMT))\ con->functions[29].func)(stmt) #define DM_SQLFETCHSCROLL 30 #define CHECK_SQLFETCHSCROLL(con) (con->functions[30].func!=NULL) #define SQLFETCHSCROLL(con,stmt,or,of)\ ((SQLRETURN (*)(SQLHSTMT, SQLSMALLINT, SQLLEN))\ con->functions[30].func)\ (stmt,or,of) #define DM_SQLFOREIGNKEYS 31 #define CHECK_SQLFOREIGNKEYS(con) (con->functions[31].func!=NULL) #define SQLFOREIGNKEYS(con,stmt,cn,nl1,sn,nl2,tn,nl3,fcn,nl4,fsn,nl5,ftn,nl6)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT))\ con->functions[31].func)\ (stmt,cn,nl1,sn,nl2,tn,nl3,fcn,nl4,fsn,nl5,ftn,nl6) #define CHECK_SQLFOREIGNKEYSW(con) (con->functions[31].funcW!=NULL) #define SQLFOREIGNKEYSW(con,stmt,cn,nl1,sn,nl2,tn,nl3,fcn,nl4,fsn,nl5,ftn,nl6)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT))\ con->functions[31].funcW)\ (stmt,cn,nl1,sn,nl2,tn,nl3,fcn,nl4,fsn,nl5,ftn,nl6) #define DM_SQLFREEENV 32 #define CHECK_SQLFREEENV(con) (con->functions[32].func!=NULL) #define SQLFREEENV(con,env)\ ((SQLRETURN (*)(SQLHENV))\ con->functions[32].func)(env) #define DM_SQLFREEHANDLE 33 #define CHECK_SQLFREEHANDLE(con) (con->functions[33].func!=NULL) #define SQLFREEHANDLE(con,typ,env)\ ((SQLRETURN (*)(SQLSMALLINT, SQLHANDLE))\ con->functions[33].func)(typ,env) #define DM_SQLFREESTMT 34 #define CHECK_SQLFREESTMT(con) (con->functions[34].func!=NULL) #define SQLFREESTMT(con,stmt,opt)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT))\ con->functions[34].func)(stmt,opt) #define DM_SQLFREECONNECT 35 #define CHECK_SQLFREECONNECT(con) (con->functions[35].func!=NULL) #define SQLFREECONNECT(con,dbc)\ ((SQLRETURN (*)(SQLHDBC))\ con->functions[35].func)(dbc) #define DM_SQLGETCONNECTATTR 36 #define CHECK_SQLGETCONNECTATTR(con) (con->functions[36].func!=NULL) #define SQLGETCONNECTATTR(con,dbc,at,vp,bl,slp)\ ((SQLRETURN (*)(SQLHDBC, SQLINTEGER,\ SQLPOINTER, SQLINTEGER, SQLINTEGER*))\ con->functions[36].func)\ (dbc,at,vp,bl,slp) #define CHECK_SQLGETCONNECTATTRW(con) (con->functions[36].funcW!=NULL) #define SQLGETCONNECTATTRW(con,dbc,at,vp,bl,slp)\ ((SQLRETURN (*)(SQLHDBC, SQLINTEGER,\ SQLPOINTER, SQLINTEGER, SQLINTEGER*))\ con->functions[36].funcW)\ (dbc,at,vp,bl,slp) #define DM_SQLGETCONNECTOPTION 37 #define CHECK_SQLGETCONNECTOPTION(con) (con->functions[37].func!=NULL) #define SQLGETCONNECTOPTION(con,dbc,at,val)\ ((SQLRETURN (*)(SQLHDBC, SQLUSMALLINT, SQLPOINTER))\ con->functions[37].func)\ (dbc,at,val) #define CHECK_SQLGETCONNECTOPTIONW(con) (con->functions[37].funcW!=NULL) #define SQLGETCONNECTOPTIONW(con,dbc,at,val)\ ((SQLRETURN (*)(SQLHDBC, SQLUSMALLINT, SQLPOINTER))\ con->functions[37].funcW)\ (dbc,at,val) #define DM_SQLGETCURSORNAME 38 #define CHECK_SQLGETCURSORNAME(con) (con->functions[38].func!=NULL) #define SQLGETCURSORNAME(con,stmt,cn,bl,nlp)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLCHAR*, SQLSMALLINT, SQLSMALLINT*))\ con->functions[38].func)\ (stmt,cn,bl,nlp) #define CHECK_SQLGETCURSORNAMEW(con) (con->functions[38].funcW!=NULL) #define SQLGETCURSORNAMEW(con,stmt,cn,bl,nlp)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*))\ con->functions[38].funcW)\ (stmt,cn,bl,nlp) #define DM_SQLGETDATA 39 #define CHECK_SQLGETDATA(con) (con->functions[39].func!=NULL) #define SQLGETDATA(con,stmt,cn,tt,tvp,bl,sli)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT,\ SQLSMALLINT, SQLPOINTER, SQLLEN, SQLLEN*))\ con->functions[39].func)\ (stmt,cn,tt,tvp,bl,sli) #define DM_SQLGETDESCFIELD 40 #define CHECK_SQLGETDESCFIELD(con) (con->functions[40].func!=NULL) #define SQLGETDESCFIELD(con,des,rn,fi,vp,bl,slp)\ ((SQLRETURN (*)(SQLHDESC, SQLSMALLINT,\ SQLSMALLINT, SQLPOINTER, SQLINTEGER, SQLINTEGER*))\ con->functions[40].func)\ (des,rn,fi,vp,bl,slp) #define CHECK_SQLGETDESCFIELDW(con) (con->functions[40].funcW!=NULL) #define SQLGETDESCFIELDW(con,des,rn,fi,vp,bl,slp)\ ((SQLRETURN (*)(SQLHDESC, SQLSMALLINT,\ SQLSMALLINT, SQLPOINTER, SQLINTEGER, SQLINTEGER*))\ con->functions[40].funcW)\ (des,rn,fi,vp,bl,slp) #define DM_SQLGETDESCREC 41 #define CHECK_SQLGETDESCREC(con) (con->functions[41].func!=NULL) #define SQLGETDESCREC(con,des,rn,n,bl,slp,tp,stp,lp,pp,sp,np)\ ((SQLRETURN (*)(SQLHDESC, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT, SQLSMALLINT*,\ SQLSMALLINT*, SQLSMALLINT*, SQLLEN*,\ SQLSMALLINT*, SQLSMALLINT*, SQLSMALLINT*))\ con->functions[41].func)\ (des,rn,n,bl,slp,tp,stp,lp,pp,sp,np) #define CHECK_SQLGETDESCRECW(con) (con->functions[41].funcW!=NULL) #define SQLGETDESCRECW(con,des,rn,n,bl,slp,tp,stp,lp,pp,sp,np)\ ((SQLRETURN (*)(SQLHDESC, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*,\ SQLSMALLINT*, SQLSMALLINT*, SQLLEN*,\ SQLSMALLINT*, SQLSMALLINT*, SQLSMALLINT*))\ con->functions[41].funcW)\ (des,rn,n,bl,slp,tp,stp,lp,pp,sp,np) #define DM_SQLGETDIAGFIELD 42 #define CHECK_SQLGETDIAGFIELD(con) (con->functions[42].func!=NULL) #define SQLGETDIAGFIELD(con,typ,han,rn,di,dip,bl,slp)\ ((SQLRETURN (*)(SQLSMALLINT, SQLHANDLE,\ SQLSMALLINT, SQLSMALLINT, SQLPOINTER,\ SQLSMALLINT, SQLSMALLINT*))\ con->functions[42].func)\ (typ,han,rn,di,dip,bl,slp) #define CHECK_SQLGETDIAGFIELDW(con) (con->functions[42].funcW!=NULL) #define SQLGETDIAGFIELDW(con,typ,han,rn,di,dip,bl,slp)\ ((SQLRETURN (*)(SQLSMALLINT, SQLHANDLE,\ SQLSMALLINT, SQLSMALLINT, SQLPOINTER,\ SQLSMALLINT, SQLSMALLINT*))\ con->functions[42].funcW)\ (typ,han,rn,di,dip,bl,slp) #define DM_SQLGETENVATTR 43 #define CHECK_SQLGETENVATTR(con) (con->functions[43].func!=NULL) #define SQLGETENVATTR(con,env,attr,val,len,ol)\ ((SQLRETURN (*)(SQLHENV, SQLINTEGER,\ SQLPOINTER, SQLINTEGER, SQLINTEGER*))\ con->functions[43].func)\ (env,attr,val,len,ol) #define DM_SQLGETFUNCTIONS 44 #define CHECK_SQLGETFUNCTIONS(con) (con->functions[44].func!=NULL) #define SQLGETFUNCTIONS(con,dbc,id,ptr)\ ((SQLRETURN (*)(SQLHDBC, SQLUSMALLINT, SQLUSMALLINT*))\ con->functions[44].func)\ (dbc,id,ptr) #define DM_SQLGETINFO 45 #define CHECK_SQLGETINFO(con) (con->functions[45].func!=NULL) #define SQLGETINFO(con,dbc,it,ivo,bl,slp)\ ((SQLRETURN (*)(SQLHDBC, SQLUSMALLINT,\ SQLPOINTER, SQLSMALLINT, SQLSMALLINT*))\ con->functions[45].func)\ (dbc,it,ivo,bl,slp) #define CHECK_SQLGETINFOW(con) (con->functions[45].funcW!=NULL) #define SQLGETINFOW(con,dbc,it,ivo,bl,slp)\ ((SQLRETURN (*)(SQLHDBC, SQLUSMALLINT,\ SQLPOINTER, SQLSMALLINT, SQLSMALLINT*))\ con->functions[45].funcW)\ (dbc,it,ivo,bl,slp) #define DM_SQLGETSTMTATTR 46 #define CHECK_SQLGETSTMTATTR(con) (con->functions[46].func!=NULL) #define SQLGETSTMTATTR(con,stmt,at,vp,bl,slp)\ ((SQLRETURN (*)(SQLHSTMT, SQLINTEGER,\ SQLPOINTER, SQLINTEGER, SQLINTEGER*))\ con->functions[46].func)\ (stmt,at,vp,bl,slp) #define CHECK_SQLGETSTMTATTRW(con) (con->functions[46].funcW!=NULL) #define SQLGETSTMTATTRW(con,stmt,at,vp,bl,slp)\ ((SQLRETURN (*)(SQLHSTMT, SQLINTEGER,\ SQLPOINTER, SQLINTEGER, SQLINTEGER*))\ con->functions[46].funcW)\ (stmt,at,vp,bl,slp) #define DM_SQLGETSTMTOPTION 47 #define CHECK_SQLGETSTMTOPTION(con) (con->functions[47].func!=NULL) #define SQLGETSTMTOPTION(con,stmt,op,val)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT, SQLPOINTER))\ con->functions[47].func)\ (stmt,op,val) #define CHECK_SQLGETSTMTOPTIONW(con) (con->functions[47].funcW!=NULL) #define SQLGETSTMTOPTIONW(con,stmt,op,val)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT, SQLPOINTER))\ con->functions[47].funcW)\ (stmt,op,val) #define DM_SQLGETTYPEINFO 48 #define CHECK_SQLGETTYPEINFO(con) (con->functions[48].func!=NULL) #define SQLGETTYPEINFO(con,stmt,typ)\ ((SQLRETURN (*)(SQLHSTMT, SQLSMALLINT))\ con->functions[48].func)(stmt,typ) #define CHECK_SQLGETTYPEINFOW(con) (con->functions[48].funcW!=NULL) #define SQLGETTYPEINFOW(con,stmt,typ)\ ((SQLRETURN (*)(SQLHSTMT, SQLSMALLINT))\ con->functions[48].funcW)(stmt,typ) #define DM_SQLMORERESULTS 49 #define CHECK_SQLMORERESULTS(con) (con->functions[49].func!=NULL) #define SQLMORERESULTS(con,stmt)\ ((SQLRETURN (*)(SQLHSTMT))\ con->functions[49].func)(stmt) #define DM_SQLNATIVESQL 50 #define CHECK_SQLNATIVESQL(con) (con->functions[50].func!=NULL) #define SQLNATIVESQL(con,dbc,ist,tl,ost,bl,tlp)\ ((SQLRETURN (*)(SQLHDBC,\ SQLCHAR*, SQLINTEGER,\ SQLCHAR*, SQLINTEGER, SQLINTEGER*))\ con->functions[50].func)\ (dbc,ist,tl,ost,bl,tlp) #define CHECK_SQLNATIVESQLW(con) (con->functions[50].funcW!=NULL) #define SQLNATIVESQLW(con,dbc,ist,tl,ost,bl,tlp)\ ((SQLRETURN (*)(SQLHDBC,\ SQLWCHAR*, SQLINTEGER,\ SQLWCHAR*, SQLINTEGER, SQLINTEGER*))\ con->functions[50].funcW)\ (dbc,ist,tl,ost,bl,tlp) #define DM_SQLNUMPARAMS 51 #define CHECK_SQLNUMPARAMS(con) (con->functions[51].func!=NULL) #define SQLNUMPARAMS(con,stmt,cnt)\ ((SQLRETURN (*)(SQLHSTMT, SQLSMALLINT*))\ con->functions[51].func)(stmt,cnt) #define DM_SQLNUMRESULTCOLS 52 #define CHECK_SQLNUMRESULTCOLS(con) (con->functions[52].func!=NULL) #define SQLNUMRESULTCOLS(con,stmt,cnt)\ ((SQLRETURN (*)(SQLHSTMT, SQLSMALLINT*))\ con->functions[52].func)(stmt,cnt) #define DM_SQLPARAMDATA 53 #define CHECK_SQLPARAMDATA(con) (con->functions[53].func!=NULL) #define SQLPARAMDATA(con,stmt,val)\ ((SQLRETURN (*)(SQLHSTMT, SQLPOINTER*))\ con->functions[53].func)(stmt,val) #define DM_SQLPARAMOPTIONS 54 #define CHECK_SQLPARAMOPTIONS(con) (con->functions[54].func!=NULL) #define SQLPARAMOPTIONS(con,stmt,cr,pi)\ ((SQLRETURN (*)(SQLHSTMT, SQLULEN, SQLULEN*))\ con->functions[54].func)(stmt,cr,pi) #define DM_SQLPREPARE 55 #define CHECK_SQLPREPARE(con) (con->functions[55].func!=NULL) #define SQLPREPARE(con,stmt,sql,len)\ ((SQLRETURN (*)(SQLHSTMT, SQLCHAR*, SQLINTEGER))\ con->functions[55].func)(stmt,sql,len) #define CHECK_SQLPREPAREW(con) (con->functions[55].funcW!=NULL) #define SQLPREPAREW(con,stmt,sql,len)\ ((SQLRETURN (*)(SQLHSTMT, SQLWCHAR*, SQLINTEGER))\ con->functions[55].funcW)(stmt,sql,len) #define DM_SQLPRIMARYKEYS 56 #define CHECK_SQLPRIMARYKEYS(con) (con->functions[56].func!=NULL) #define SQLPRIMARYKEYS(con,stmt,cn,nl1,sn,nl2,tn,nl3)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT))\ con->functions[56].func)\ (stmt,cn,nl1,sn,nl2,tn,nl3) #define CHECK_SQLPRIMARYKEYSW(con) (con->functions[56].funcW!=NULL) #define SQLPRIMARYKEYSW(con,stmt,cn,nl1,sn,nl2,tn,nl3)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT))\ con->functions[56].funcW)\ (stmt,cn,nl1,sn,nl2,tn,nl3) #define DM_SQLPROCEDURECOLUMNS 57 #define CHECK_SQLPROCEDURECOLUMNS(con) (con->functions[57].func!=NULL) #define SQLPROCEDURECOLUMNS(con,stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT))\ con->functions[57].func)\ (stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4) #define CHECK_SQLPROCEDURECOLUMNSW(con) (con->functions[57].funcW!=NULL) #define SQLPROCEDURECOLUMNSW(con,stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT))\ con->functions[57].funcW)\ (stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4) #define DM_SQLPROCEDURES 58 #define CHECK_SQLPROCEDURES(con) (con->functions[58].func!=NULL) #define SQLPROCEDURES(con,stmt,cn,nl1,sn,nl2,tn,nl3)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT))\ con->functions[58].func)\ (stmt,cn,nl1,sn,nl2,tn,nl3) #define CHECK_SQLPROCEDURESW(con) (con->functions[58].funcW!=NULL) #define SQLPROCEDURESW(con,stmt,cn,nl1,sn,nl2,tn,nl3)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT))\ con->functions[58].funcW)\ (stmt,cn,nl1,sn,nl2,tn,nl3) #define DM_SQLPUTDATA 59 #define CHECK_SQLPUTDATA(con) (con->functions[59].func!=NULL) #define SQLPUTDATA(con,stmt,d,p)\ ((SQLRETURN (*)(SQLHSTMT, SQLPOINTER, SQLLEN))\ con->functions[59].func)(stmt,d,p) #define DM_SQLROWCOUNT 60 #define CHECK_SQLROWCOUNT(con) (con->functions[60].func!=NULL) #define DEF_SQLROWCOUNT(con,stmt,cnt)\ ((SQLRETURN (*)(SQLHSTMT, SQLLEN*))\ con->functions[60].func)(stmt,cnt) #define DM_SQLSETCONNECTATTR 61 #define CHECK_SQLSETCONNECTATTR(con) (con->functions[61].func!=NULL) #define SQLSETCONNECTATTR(con,dbc,at,vp,sl)\ ((SQLRETURN (*)(SQLHDBC, SQLINTEGER,\ SQLPOINTER, SQLINTEGER))\ con->functions[61].func)\ (dbc,at,vp,sl) #define CHECK_SQLSETCONNECTATTRW(con) (con->functions[61].funcW!=NULL) #define SQLSETCONNECTATTRW(con,dbc,at,vp,sl)\ ((SQLRETURN (*)(SQLHDBC, SQLINTEGER,\ SQLPOINTER, SQLINTEGER))\ con->functions[61].funcW)\ (dbc,at,vp,sl) #define DM_SQLSETCONNECTOPTION 62 #define CHECK_SQLSETCONNECTOPTION(con) (con->functions[62].func!=NULL) #define SQLSETCONNECTOPTION(con,dbc,op,p)\ ((SQLRETURN (*)(SQLHDBC, SQLUSMALLINT, SQLULEN))\ con->functions[62].func)\ (dbc,op,p) #define CHECK_SQLSETCONNECTOPTIONW(con) (con->functions[62].funcW!=NULL) #define SQLSETCONNECTOPTIONW(con,dbc,op,p)\ ((SQLRETURN (*)(SQLHDBC, SQLUSMALLINT, SQLULEN))\ con->functions[62].funcW)\ (dbc,op,p) #define DM_SQLSETCURSORNAME 63 #define CHECK_SQLSETCURSORNAME(con) (con->functions[63].func!=NULL) #define SQLSETCURSORNAME(con,stmt,nam,len)\ ((SQLRETURN (*)(SQLHSTMT, SQLCHAR*, SQLSMALLINT))\ con->functions[63].func)(stmt,nam,len) #define CHECK_SQLSETCURSORNAMEW(con) (con->functions[63].funcW!=NULL) #define SQLSETCURSORNAMEW(con,stmt,nam,len)\ ((SQLRETURN (*)(SQLHSTMT, SQLWCHAR*, SQLSMALLINT))\ con->functions[63].funcW)(stmt,nam,len) #define DM_SQLSETDESCFIELD 64 #define CHECK_SQLSETDESCFIELD(con) (con->functions[64].func!=NULL) #define SQLSETDESCFIELD(con,des,rn,fi,vp,bl)\ ((SQLRETURN (*)(SQLHDESC, SQLSMALLINT,\ SQLSMALLINT, SQLPOINTER, SQLINTEGER))\ con->functions[64].func)\ (des,rn,fi,vp,bl) #define CHECK_SQLSETDESCFIELDW(con) (con->functions[64].funcW!=NULL) #define SQLSETDESCFIELDW(con,des,rn,fi,vp,bl)\ ((SQLRETURN (*)(SQLHDESC, SQLSMALLINT,\ SQLSMALLINT, SQLPOINTER, SQLINTEGER))\ con->functions[64].funcW)\ (des,rn,fi,vp,bl) #define DM_SQLSETDESCREC 65 #define CHECK_SQLSETDESCREC(con) (con->functions[65].func!=NULL) #define SQLSETDESCREC(con,des,rn,t,st,l,p,sc,dp,slp,ip)\ ((SQLRETURN (*)(SQLHDESC, SQLSMALLINT,\ SQLSMALLINT, SQLSMALLINT, SQLLEN, SQLSMALLINT,\ SQLSMALLINT, SQLPOINTER, SQLLEN*, SQLLEN*))\ con->functions[65].func)\ (des,rn,t,st,l,p,sc,dp,slp,ip) #define DM_SQLSETENVATTR 66 #define CHECK_SQLSETENVATTR(con) (con->functions[66].func!=NULL) #define SQLSETENVATTR(con,env,attr,val,len)\ ((SQLRETURN (*)(SQLHENV, SQLINTEGER, SQLPOINTER, SQLINTEGER))\ con->functions[66].func)(env,attr,val,len) #define DM_SQLSETPARAM 67 #define CHECK_SQLSETPARAM(con) (con->functions[67].func!=NULL) #define SQLSETPARAM(con,stmt,pn,vt,pt,lp,ps,pv,sli)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT,\ SQLSMALLINT, SQLSMALLINT, SQLULEN,\ SQLSMALLINT, SQLPOINTER, SQLLEN*))\ con->functions[67].func)\ (stmt,pn,vt,pt,lp,ps,pv,sli) #define DM_SQLSETPOS 68 #define CHECK_SQLSETPOS(con) (con->functions[68].func!=NULL) #define SQLSETPOS(con,stmt,rn,op,lt)\ ((SQLRETURN (*)(SQLHSTMT, SQLSETPOSIROW,\ SQLUSMALLINT, SQLUSMALLINT))\ con->functions[68].func)\ (stmt,rn,op,lt) #define DM_SQLSETSCROLLOPTIONS 69 #define CHECK_SQLSETSCROLLOPTIONS(con) (con->functions[69].func!=NULL) #define SQLSETSCROLLOPTIONS(con,stmt,fc,cr,rs)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT,\ SQLLEN, SQLUSMALLINT))\ con->functions[69].func)\ (stmt,fc,cr,rs) #define DM_SQLSETSTMTATTR 70 #define CHECK_SQLSETSTMTATTR(con) (con->functions[70].func!=NULL) #define SQLSETSTMTATTR(con,stmt,attr,vp,sl)\ ((SQLRETURN (*)(SQLHSTMT, SQLINTEGER, SQLPOINTER, SQLINTEGER))\ con->functions[70].func)\ (stmt,attr,vp,sl) #define CHECK_SQLSETSTMTATTRW(con) (con->functions[70].funcW!=NULL) #define SQLSETSTMTATTRW(con,stmt,attr,vp,sl)\ ((SQLRETURN (*)(SQLHSTMT, SQLINTEGER, SQLPOINTER, SQLINTEGER))\ con->functions[70].funcW)\ (stmt,attr,vp,sl) #define DM_SQLSETSTMTOPTION 71 #define CHECK_SQLSETSTMTOPTION(con) (con->functions[71].func!=NULL) #define SQLSETSTMTOPTION(con,stmt,op,val)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT, SQLULEN))\ con->functions[71].func)\ (stmt,op,val) #define CHECK_SQLSETSTMTOPTIONW(con) (con->functions[71].funcW!=NULL) #define SQLSETSTMTOPTIONW(con,stmt,op,val)\ ((SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT, SQLULEN))\ con->functions[71].funcW)\ (stmt,op,val) #define DM_SQLSPECIALCOLUMNS 72 #define CHECK_SQLSPECIALCOLUMNS(con) (con->functions[72].func!=NULL) #define SQLSPECIALCOLUMNS(con,stmt,it,cn,nl1,sn,nl2,tn,nl3,s,n)\ ((SQLRETURN (*) (\ SQLHSTMT, SQLUSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLUSMALLINT, SQLUSMALLINT))\ con->functions[72].func)\ (stmt,it,cn,nl1,sn,nl2,tn,nl3,s,n) #define CHECK_SQLSPECIALCOLUMNSW(con) (con->functions[72].funcW!=NULL) #define SQLSPECIALCOLUMNSW(con,stmt,it,cn,nl1,sn,nl2,tn,nl3,s,n)\ ((SQLRETURN (*) (\ SQLHSTMT, SQLUSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLUSMALLINT, SQLUSMALLINT))\ con->functions[72].funcW)\ (stmt,it,cn,nl1,sn,nl2,tn,nl3,s,n) #define DM_SQLSTATISTICS 73 #define CHECK_SQLSTATISTICS(con) (con->functions[73].func!=NULL) #define SQLSTATISTICS(con,stmt,cn,nl1,sn,nl2,tn,nl3,un,res)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLUSMALLINT, SQLUSMALLINT))\ con->functions[73].func)\ (stmt,cn,nl1,sn,nl2,tn,nl3,un,res) #define CHECK_SQLSTATISTICSW(con) (con->functions[73].funcW!=NULL) #define SQLSTATISTICSW(con,stmt,cn,nl1,sn,nl2,tn,nl3,un,res)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLUSMALLINT, SQLUSMALLINT))\ con->functions[73].funcW)\ (stmt,cn,nl1,sn,nl2,tn,nl3,un,res) #define DM_SQLTABLEPRIVILEGES 74 #define CHECK_SQLTABLEPRIVILEGES(con) (con->functions[74].func!=NULL) #define SQLTABLEPRIVILEGES(con,stmt,cn,nl1,sn,nl2,tn,nl3)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT))\ con->functions[74].func)\ (stmt,cn,nl1,sn,nl2,tn,nl3) #define CHECK_SQLTABLEPRIVILEGESW(con) (con->functions[74].funcW!=NULL) #define SQLTABLEPRIVILEGESW(con,stmt,cn,nl1,sn,nl2,tn,nl3)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT))\ con->functions[74].funcW)\ (stmt,cn,nl1,sn,nl2,tn,nl3) #define DM_SQLTABLES 75 #define CHECK_SQLTABLES(con) (con->functions[75].func!=NULL) #define SQLTABLES(con,stmt,cn,nl1,sn,nl2,tn,nl3,tt,nl4)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT,\ SQLCHAR*, SQLSMALLINT))\ con->functions[75].func)\ (stmt,cn,nl1,sn,nl2,tn,nl3,tt,nl4) #define CHECK_SQLTABLESW(con) (con->functions[75].funcW!=NULL) #define SQLTABLESW(con,stmt,cn,nl1,sn,nl2,tn,nl3,tt,nl4)\ ((SQLRETURN (*)(SQLHSTMT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT,\ SQLWCHAR*, SQLSMALLINT))\ con->functions[75].funcW)\ (stmt,cn,nl1,sn,nl2,tn,nl3,tt,nl4) #define DM_SQLTRANSACT 76 #define CHECK_SQLTRANSACT(con) (con->functions[76].func!=NULL) #define SQLTRANSACT(con,eh,ch,op)\ ((SQLRETURN (*)(SQLHENV, SQLHDBC, SQLUSMALLINT))\ con->functions[76].func)(eh,ch,op) #define DM_SQLGETDIAGREC 77 #define CHECK_SQLGETDIAGREC(con) (con->functions[77].func!=NULL) #define SQLGETDIAGREC(con,typ,han,rn,st,nat,msg,bl,tlp)\ ((SQLRETURN (*)(SQLSMALLINT, SQLHANDLE,\ SQLSMALLINT, SQLCHAR*, SQLINTEGER*,\ SQLCHAR*, SQLSMALLINT, SQLSMALLINT*))\ con->functions[77].func)\ (typ,han,rn,st,nat,msg,bl,tlp) #define CHECK_SQLGETDIAGRECW(con) (con->functions[77].funcW!=NULL) #define SQLGETDIAGRECW(con,typ,han,rn,st,nat,msg,bl,tlp)\ ((SQLRETURN (*)(SQLSMALLINT, SQLHANDLE,\ SQLSMALLINT, SQLWCHAR*, SQLINTEGER*,\ SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*))\ con->functions[77].funcW)\ (typ,han,rn,st,nat,msg,bl,tlp) #define DM_SQLCANCELHANDLE 78 #define CHECK_SQLCANCELHANDLE(con) (con->functions[78].func!=NULL) #define SQLCANCELHANDLE(con,typ,han)\ ((SQLRETURN (*)(SQLSMALLINT, SQLHANDLE))\ con->functions[78].func)\ (typ,han) #endif unixODBC-2.3.12/DriverManager/drivermanager_axp.opt000066400000000000000000000044771446441710500222040ustar00rootroot00000000000000CASE_SENSITIVE=YES SYMBOL_VECTOR = (SQLAllocConnect=PROCEDURE,- SQLAllocEnv=PROCEDURE,- SQLAllocHandle=PROCEDURE,- SQLAllocHandleStd=PROCEDURE,- SQLAllocStmt=PROCEDURE,- SQLBindCol=PROCEDURE,- SQLBindParam=PROCEDURE,- SQLBindParameter=PROCEDURE,- SQLBrowseConnect=PROCEDURE,- SQLBulkOperations=PROCEDURE,- SQLCancel=PROCEDURE,- SQLCancelHandle=PROCEDURE,- SQLCloseCursor=PROCEDURE,- SQLColAttribute=PROCEDURE,- SQLColAttributes=PROCEDURE,- SQLColumnPrivileges=PROCEDURE,- SQLColumns=PROCEDURE,- SQLConnect=PROCEDURE,- SQLCopyDesc=PROCEDURE,- SQLDataSources=PROCEDURE,- SQLDescribeCol=PROCEDURE,- SQLDescribeParam=PROCEDURE,- SQLDisconnect=PROCEDURE,- SQLDriverConnect=PROCEDURE,- SQLDrivers=PROCEDURE,- SQLEndTran=PROCEDURE,- SQLError=PROCEDURE,- SQLExecDirect=PROCEDURE,- SQLExecute=PROCEDURE,- SQLExtendedFetch=PROCEDURE,- SQLFetch=PROCEDURE,- SQLFetchScroll=PROCEDURE,- SQLForeignKeys=PROCEDURE,- SQLFreeConnect=PROCEDURE,- SQLFreeEnv=PROCEDURE,- SQLFreeHandle=PROCEDURE,- SQLFreeStmt=PROCEDURE,- SQLGetConnectAttr=PROCEDURE,- SQLGetConnectOption=PROCEDURE,- SQLGetCursorName=PROCEDURE,- SQLGetData=PROCEDURE,- SQLGetDescField=PROCEDURE,- SQLGetDescRec=PROCEDURE,- SQLGetDiagField=PROCEDURE,- SQLGetDiagRec=PROCEDURE,- SQLGetEnvAttr=PROCEDURE,- SQLGetFunctions=PROCEDURE,- SQLGetInfo=PROCEDURE,- SQLGetStmtAttr=PROCEDURE,- SQLGetStmtOption=PROCEDURE,- SQLGetTypeInfo=PROCEDURE,- SQLMoreResults=PROCEDURE,- SQLNativeSql=PROCEDURE,- SQLNumParams=PROCEDURE,- SQLNumResultCols=PROCEDURE,- SQLParamData=PROCEDURE,- SQLParamOptions=PROCEDURE,- SQLPrepare=PROCEDURE,- SQLPrimaryKeys=PROCEDURE,- SQLProcedureColumns=PROCEDURE,- SQLProcedures=PROCEDURE,- SQLPutData=PROCEDURE,- SQLRowCount=PROCEDURE,- SQLSetConnectAttr=PROCEDURE,- SQLSetConnectOption=PROCEDURE,- SQLSetCursorName=PROCEDURE,- SQLSetDescField=PROCEDURE,- SQLSetDescRec=PROCEDURE,- SQLSetEnvAttr=PROCEDURE,- SQLSetParam=PROCEDURE,- SQLSetPos=PROCEDURE,- SQLSetScrollOptions=PROCEDURE,- SQLSetStmtAttr=PROCEDURE,- SQLSetStmtOption=PROCEDURE,- SQLSpecialColumns=PROCEDURE,- SQLStatistics=PROCEDURE,- SQLTablePrivileges=PROCEDURE,- SQLTables=PROCEDURE,- SQLTransact=PROCEDURE) unixODBC-2.3.12/DriverManager/odbc.pc.in000066400000000000000000000007161446441710500176120ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ sysconfdir=@sysconfdir@ odbcversion=3 longodbcversion=3.52 odbcini=${sysconfdir}/odbc.ini odbcinstini=${sysconfdir}/odbcinst.ini ulen=@ODBC_ULEN@ build_cflags=@ODBC_CFLAGS@ Name: odbc (@PACKAGE_NAME@) Description: unixODBC Driver Manager library URL: http://unixodbc.org Version: @PACKAGE_VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -lodbc Libs.private: @LIBLTDL@ @LIBS@ unixODBC-2.3.12/Drivers/000077500000000000000000000000001446441710500146365ustar00rootroot00000000000000unixODBC-2.3.12/Drivers/Makefile.am000066400000000000000000000001251446441710500166700ustar00rootroot00000000000000if DRIVERS SUBDIRS = \ Postgre7.1 \ template \ MiniSQL \ nn endif unixODBC-2.3.12/Drivers/MiniSQL/000077500000000000000000000000001446441710500161125ustar00rootroot00000000000000unixODBC-2.3.12/Drivers/MiniSQL/ChangeLog000066400000000000000000000006371446441710500176720ustar00rootroot000000000000001999-05-03 Peter Harvey * SQLColAttribute: Returned SQL_ERROR even when all was ok. 1999-04-03 Peter Harvey * SQLSpecialColumns: Mostly implemented. Simply returns _rowid. Quick and dirty. 1999-04-02 Peter Harvey * SQLFetchScroll: Mostly implemented * SQLExecDirect: Created _Execute * SQLPrepare: Created _Prepare unixODBC-2.3.12/Drivers/MiniSQL/Makefile.am000066400000000000000000000073341446441710500201550ustar00rootroot00000000000000if MSQL lib_LTLIBRARIES = libodbcmini.la AM_CPPFLAGS = -I@top_srcdir@/include -I. -I@msql_headers@ -I${LTDLINCL} libodbcmini_la_SOURCES = \ SQLAllocConnect.c \ SQLAllocEnv.c \ SQLAllocHandle.c \ SQLAllocStmt.c \ SQLBindCol.c \ SQLBindParameter.c \ SQLBrowseConnect.c \ SQLBulkOperations.c \ SQLCancel.c \ SQLCloseCursor.c \ SQLColAttribute.c \ SQLColAttributes.c \ SQLColumnPrivileges.c \ SQLColumns.c \ SQLConnect.c \ SQLCopyDesc.c \ SQLDescribeCol.c \ SQLDescribeParam.c \ SQLDisconnect.c \ SQLDriverConnect.c \ SQLEndTran.c \ SQLError.c \ SQLExecDirect.c \ SQLExecute.c \ SQLExtendedFetch.c \ SQLFetch.c \ SQLFetchScroll.c \ SQLForeignKeys.c \ SQLFreeConnect.c \ SQLFreeEnv.c \ SQLFreeHandle.c \ SQLFreeStmt.c \ SQLGetConnectAttr.c \ SQLGetConnectOption.c \ SQLGetCursorName.c \ SQLGetData.c \ SQLGetDescField.c \ SQLGetDescRec.c \ SQLGetDiagField.c \ SQLGetDiagRec.c \ SQLGetEnvAttr.c \ SQLGetInfo.c \ SQLGetStmtAttr.c \ SQLGetStmtOption.c \ SQLGetTypeInfo.c \ SQLMoreResults.c \ SQLNativeSql.c \ SQLNumParams.c \ SQLNumResultCols.c \ SQLParamData.c \ SQLParamOptions.c \ SQLPrepare.c \ SQLPrimaryKeys.c \ SQLProcedureColumns.c \ SQLProcedures.c \ SQLPutData.c \ SQLRowCount.c \ SQLSetConnectOption.c \ SQLSetCursorName.c \ SQLSetDescField.c \ SQLSetDescRec.c \ SQLSetEnvAttr.c \ SQLSetParam.c \ SQLSetPos.c \ SQLSetScrollOptions.c \ SQLSetStmtAttr.c \ SQLSetStmtOption.c \ SQLSpecialColumns.c \ SQLStatistics.c \ SQLTablePrivileges.c \ SQLTables.c \ SQLTransact.c \ _AllocConnect.c \ _AllocEnv.c \ _AllocStmt.c \ _Execute.c \ _FreeDbc.c \ _FreeStmt.c \ _FreeDbcList.c \ _FreeStmtList.c \ _FreeResults.c \ _GetData.c \ _NativeToSQLColumnHeader.c \ _NativeToSQLType.c \ _NativeTypeDesc.c \ _NativeTypeLength.c \ _NativeTypePrecision.c \ _Prepare.c \ _sqlFreeConnect.c \ _sqlFreeEnv.c \ _sqlFreeStmt.c endif EXTRA_DIST = \ SQLAllocConnect.c \ SQLAllocEnv.c \ SQLAllocHandle.c \ SQLAllocStmt.c \ SQLBindCol.c \ SQLBindParameter.c \ SQLBrowseConnect.c \ SQLBulkOperations.c \ SQLCancel.c \ SQLCloseCursor.c \ SQLColAttribute.c \ SQLColAttributes.c \ SQLColumnPrivileges.c \ SQLColumns.c \ SQLConnect.c \ SQLCopyDesc.c \ SQLDescribeCol.c \ SQLDescribeParam.c \ SQLDisconnect.c \ SQLDriverConnect.c \ SQLEndTran.c \ SQLError.c \ SQLExecDirect.c \ SQLExecute.c \ SQLExtendedFetch.c \ SQLFetch.c \ SQLFetchScroll.c \ SQLForeignKeys.c \ SQLFreeConnect.c \ SQLFreeEnv.c \ SQLFreeHandle.c \ SQLFreeStmt.c \ SQLGetConnectAttr.c \ SQLGetConnectOption.c \ SQLGetCursorName.c \ SQLGetData.c \ SQLGetDescField.c \ SQLGetDescRec.c \ SQLGetDiagField.c \ SQLGetDiagRec.c \ SQLGetEnvAttr.c \ SQLGetInfo.c \ SQLGetStmtAttr.c \ SQLGetStmtOption.c \ SQLGetTypeInfo.c \ SQLMoreResults.c \ SQLNativeSql.c \ SQLNumParams.c \ SQLNumResultCols.c \ SQLParamData.c \ SQLParamOptions.c \ SQLPrepare.c \ SQLPrimaryKeys.c \ SQLProcedureColumns.c \ SQLProcedures.c \ SQLPutData.c \ SQLRowCount.c \ SQLSetConnectOption.c \ SQLSetCursorName.c \ SQLSetDescField.c \ SQLSetDescRec.c \ SQLSetEnvAttr.c \ SQLSetParam.c \ SQLSetPos.c \ SQLSetScrollOptions.c \ SQLSetStmtAttr.c \ SQLSetStmtOption.c \ SQLSpecialColumns.c \ SQLStatistics.c \ SQLTablePrivileges.c \ SQLTables.c \ SQLTransact.c \ _AllocConnect.c \ _AllocEnv.c \ _AllocStmt.c \ _Execute.c \ _FreeDbc.c \ _FreeDbcList.c \ _FreeResults.c \ _FreeStmt.c \ _FreeStmtList.c \ _GetData.c \ _NativeToSQLColumnHeader.c \ _NativeToSQLType.c \ _NativeTypeDesc.c \ _NativeTypeLength.c \ _NativeTypePrecision.c \ _Prepare.c \ driver.h \ driverextras.h \ _sqlFreeConnect.c \ _sqlFreeEnv.c \ _sqlFreeStmt.c libodbcmini_la_LDFLAGS = -no-undefined -version-info 1:0:0 \ -L@msql_libraries@ -lmsql -module unixODBC-2.3.12/Drivers/MiniSQL/README000066400000000000000000000026541446441710500170010ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | Driver for MiniSQL | +-------------------------------------------------------------+ This driver is for use with the MiniSQL SQL Server Version 2.x. To build 1. modify Config.mk as required 2. make Compliance This driver is a work in progress which strives to meet 3.51 CLI compliance. This driver currently implements a usefull set of; 1. catalog functions via SQLColumns, SQLTables, SQLDescribeCol, SQLColAttribute 2. alloc and free calls for Environment, Connection, and Statement 3. connect via SQLConnect 4. SQL execution via SQLPrepare, SQLExecute 5. data retreival via SQLFetch, SQLBindCol, SQLGetData If you would like to improve this driver then please send me (Peter Harvey) an email. +-------------------------------------------------------------+ | Please vist; | | www.codebydesign.com/unixODBC | | www.Hughes.com.au | +-------------------------------------------------------------+ unixODBC-2.3.12/Drivers/MiniSQL/SQLAllocConnect.c000066400000000000000000000010641446441710500212030ustar00rootroot00000000000000/************************************************** * SQLAllocConnect * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" SQLRETURN SQLAllocConnect( SQLHENV hDrvEnv, SQLHDBC *phDrvDbc ) { return _AllocConnect( hDrvEnv, phDrvDbc ); } unixODBC-2.3.12/Drivers/MiniSQL/SQLAllocEnv.c000066400000000000000000000011661446441710500203450ustar00rootroot00000000000000/********************************************************************** * SQLAllocEnv * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLAllocEnv( SQLHENV *phDrvEnv ) { return _AllocEnv( phDrvEnv ); } unixODBC-2.3.12/Drivers/MiniSQL/SQLAllocHandle.c000066400000000000000000000020441446441710500210040ustar00rootroot00000000000000/********************************************************************** * SQLAllocHandle * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLAllocHandle( SQLSMALLINT nHandleType, SQLHANDLE nInputHandle, SQLHANDLE *pnOutputHandle ) { switch ( nHandleType ) { case SQL_HANDLE_ENV: return _AllocEnv( (SQLHENV *)pnOutputHandle ); case SQL_HANDLE_DBC: return _AllocConnect( (SQLHENV)nInputHandle, (SQLHDBC *)pnOutputHandle ); case SQL_HANDLE_STMT: return _AllocStmt( (SQLHDBC)nInputHandle, (SQLHSTMT *)pnOutputHandle ); case SQL_HANDLE_DESC: break; default: return SQL_ERROR; break; } return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLAllocStmt.c000066400000000000000000000013061446441710500205400ustar00rootroot00000000000000/********************************************************************** * SQLAllocStmt (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLAllocStmt( SQLHDBC hDrvDbc, SQLHSTMT *phDrvStmt ) { return _AllocStmt( hDrvDbc, phDrvStmt ); } unixODBC-2.3.12/Drivers/MiniSQL/SQLBindCol.c000066400000000000000000000050141446441710500201500ustar00rootroot00000000000000/********************************************************************** * SQLBindCol * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" /* THIS IS THE CORRECT SYNTAX.... SQLRETURN SQLBindCol( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLSMALLINT nTargetType, SQLPOINTER pTargetValue, SQLINTEGER nTargetValueMax, SQLINTEGER *pnLengthOrIndicator ) AND THIS IS WHAT WORKS... */ SQLRETURN SQLBindCol( SQLHSTMT hDrvStmt, UWORD nCol, SWORD nTargetType, PTR pTargetValue, SDWORD nTargetValueMax, SDWORD *pnLengthOrIndicator ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; COLUMNHDR *pColumnHeader; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt=$%08lX nCol=%5d", hStmt, nCol ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); if ( hStmt->hStmtExtras->nRows == 0 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No result set." ); return SQL_ERROR; } if ( nCol < 1 || nCol > hStmt->hStmtExtras->nCols ) { sprintf( hStmt->szSqlMsg, "SQL_ERROR Column %d is out of range. Range is 1 - %s", nCol, hStmt->hStmtExtras->nCols ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } if ( pTargetValue == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Invalid data pointer" ); return SQL_ERROR; } if ( pnLengthOrIndicator != NULL ) *pnLengthOrIndicator = 0; /* SET DEFAULTS */ /* validate length etc */ /* store app col pointer */ pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nCol]; pColumnHeader->nTargetType = nTargetType; pColumnHeader->nTargetValueMax = nTargetValueMax; pColumnHeader->pnLengthOrIndicator = pnLengthOrIndicator; pColumnHeader->pTargetValue = pTargetValue; logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLBindParameter.c000066400000000000000000000033751446441710500213630ustar00rootroot00000000000000/********************************************************************** * SQLBindParameter * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLBindParameter( SQLHSTMT hDrvStmt, SQLUSMALLINT nParameterNumber, SQLSMALLINT nIOType, SQLSMALLINT nBufferType, SQLSMALLINT nParamType, SQLUINTEGER nParamLength, SQLSMALLINT nScale, SQLPOINTER pData, SQLINTEGER nBufferLength, SQLINTEGER *pnLengthOrIndicator ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt=$%08lX nParameterNumber=%d nIOType=%d nBufferType=%d nParamType=%d nParamLength=%d nScale=%d pData=$%08lX nBufferLength=%d *pnLengthOrIndicator=$%08lX",hStmt,nParameterNumber,nIOType,nBufferType,nParamType,nParamLength,nScale,pData,nBufferLength, *pnLengthOrIndicator ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not currently supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLBrowseConnect.c000066400000000000000000000025241446441710500214140ustar00rootroot00000000000000/********************************************************************** * SQLBrowseConnect * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLBrowseConnect( SQLHDBC hDrvDbc, SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; if ( hDbc == NULL ) return SQL_INVALID_HANDLE; sprintf( hDbc->szSqlMsg, "hDbc = $%08lX", hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not currently supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLBulkOperations.c000066400000000000000000000031551446441710500216030ustar00rootroot00000000000000/********************************************************************** * SQLBulkOperations * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLBulkOperations( SQLHSTMT hDrvStmt, SQLSMALLINT nOperation ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /* OK */ switch ( nOperation ) { case SQL_ADD: break; case SQL_UPDATE_BY_BOOKMARK: break; case SQL_DELETE_BY_BOOKMARK: break; case SQL_FETCH_BY_BOOKMARK: break; default: sprintf( hStmt->szSqlMsg, "SQL_ERROR Unknown nOperation=%d", nOperation ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not currently supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLCancel.c000066400000000000000000000021651446441710500200270ustar00rootroot00000000000000/********************************************************************** * SQLCancel * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLCancel( SQLHSTMT hDrvStmt ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLCloseCursor.c000066400000000000000000000021731446441710500211040ustar00rootroot00000000000000/********************************************************************** * SQLCloseCursor * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLCloseCursor( SQLHSTMT hDrvStmt ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLColAttribute.c000066400000000000000000000125051446441710500212420ustar00rootroot00000000000000/********************************************************************** * SQLColAttribute * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLColAttribute( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLUSMALLINT nFieldIdentifier, SQLPOINTER pszValue, SQLSMALLINT nValueLengthMax, SQLSMALLINT *pnValueLength, SQLLEN *pnValue ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; COLUMNHDR *pColumnHeader; int nValue = 0; /* SANITY CHECKS */ if( !hStmt ) return SQL_INVALID_HANDLE; if ( !hStmt->hStmtExtras ) return SQL_INVALID_HANDLE; if ( hStmt->hStmtExtras->nRows < 1 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No result set." ); return SQL_ERROR; } if ( nCol < 1 || nCol > hStmt->hStmtExtras->nCols ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Invalid column" ); return SQL_ERROR; } /* OK */ pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nCol]; switch( nFieldIdentifier ) { case SQL_DESC_AUTO_UNIQUE_VALUE: nValue = pColumnHeader->bSQL_DESC_AUTO_UNIQUE_VALUE; break; case SQL_DESC_BASE_COLUMN_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_BASE_COLUMN_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_BASE_TABLE_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_BASE_TABLE_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_CASE_SENSITIVE: nValue = pColumnHeader->bSQL_DESC_CASE_SENSITIVE; break; case SQL_DESC_CATALOG_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_CATALOG_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_CONCISE_TYPE: nValue = pColumnHeader->nSQL_DESC_CONCISE_TYPE; break; case SQL_DESC_COUNT: nValue = hStmt->hStmtExtras->nCols; break; case SQL_DESC_DISPLAY_SIZE: nValue = pColumnHeader->nSQL_DESC_DISPLAY_SIZE; break; case SQL_DESC_FIXED_PREC_SCALE: nValue = pColumnHeader->bSQL_DESC_FIXED_PREC_SCALE; break; case SQL_DESC_LABEL: strncpy( pszValue, pColumnHeader->pszSQL_DESC_LABEL, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_LENGTH: nValue = pColumnHeader->nSQL_DESC_LENGTH; break; case SQL_DESC_LITERAL_PREFIX: strncpy( pszValue, pColumnHeader->pszSQL_DESC_LITERAL_PREFIX, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_LITERAL_SUFFIX: strncpy( pszValue, pColumnHeader->pszSQL_DESC_LITERAL_SUFFIX, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_LOCAL_TYPE_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_LOCAL_TYPE_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_NULLABLE: nValue = pColumnHeader->nSQL_DESC_NULLABLE; break; case SQL_DESC_NUM_PREC_RADIX: nValue = pColumnHeader->nSQL_DESC_NUM_PREC_RADIX; break; case SQL_DESC_OCTET_LENGTH: nValue = pColumnHeader->nSQL_DESC_OCTET_LENGTH; break; case SQL_DESC_PRECISION: nValue = pColumnHeader->nSQL_DESC_PRECISION; break; case SQL_DESC_SCALE: nValue = pColumnHeader->nSQL_DESC_SCALE; break; case SQL_DESC_SCHEMA_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_SCHEMA_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_SEARCHABLE: nValue = pColumnHeader->nSQL_DESC_SEARCHABLE; break; case SQL_DESC_TABLE_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_TABLE_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_TYPE: nValue = pColumnHeader->nSQL_DESC_TYPE; break; case SQL_DESC_TYPE_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_TYPE_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_UNNAMED: nValue = pColumnHeader->nSQL_DESC_UNNAMED; break; case SQL_DESC_UNSIGNED: nValue = pColumnHeader->bSQL_DESC_UNSIGNED; break; case SQL_DESC_UPDATABLE: nValue = pColumnHeader->nSQL_DESC_UPDATABLE; break; default: sprintf( hStmt->szSqlMsg, "Invalid nFieldIdentifier value of %d", nFieldIdentifier ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } if ( pnValue ) *(int*)pnValue = nValue; logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLColAttributes.c000066400000000000000000000047501446441710500214300ustar00rootroot00000000000000/********************************************************************** * SQLColAttributes (this function has been deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLColAttributes( SQLHSTMT hDrvStmt, UWORD nCol, UWORD nDescType, PTR pszDesc, SWORD nDescMax, SWORD *pcbDesc, SDWORD *pfDesc ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************** * 1. verify we have result set * 2. verify col is within range **************************/ /************************** * 3. process request **************************/ switch( nDescType ) { /* enum these case SQL_COLUMN_AUTO_INCREMENT: case SQL_COLUMN_CASE_SENSITIVE: case SQL_COLUMN_COUNT: case SQL_COLUMN_DISPLAY_SIZE: case SQL_COLUMN_LENGTH: case SQL_COLUMN_MONEY: case SQL_COLUMN_NULLABLE: case SQL_COLUMN_PRECISION: case SQL_COLUMN_SCALE: case SQL_COLUMN_SEARCHABLE: case SQL_COLUMN_TYPE: case SQL_COLUMN_UNSIGNED: case SQL_COLUMN_UPDATABLE: case SQL_COLUMN_CATALOG_NAME: case SQL_COLUMN_QUALIFIER_NAME: case SQL_COLUMN_DISTINCT_TYPE: case SQL_COLUMN_LABEL: case SQL_COLUMN_NAME: case SQL_COLUMN_SCHEMA_NAME: case SQL_COLUMN_OWNER_NAME: case SQL_COLUMN_TABLE_NAME: case SQL_COLUMN_TYPE_NAME: */ default: sprintf( hStmt->szSqlMsg, "SQL_ERROR nDescType=%d", nDescType ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLColumnPrivileges.c000066400000000000000000000027471446441710500221370ustar00rootroot00000000000000/******************************************************************** * SQLColumnPrivileges * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLColumnPrivileges( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength, SQLCHAR *szColumnName, SQLSMALLINT nColumnNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLColumns.c000066400000000000000000000157031446441710500202640ustar00rootroot00000000000000/******************************************************************** * SQLColumns * * This is something of a mess. Part of the problem here is that msqlListFields * are returned as mSQL 'column headers'... we want them to be returned as a * row for each. So we have to turn the results on their side . * * Another problem is that msqlListFields will also return indexs. So we have * to make sure that these are not included here. * * The end result is more code than what would usually be found here. * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" enum nSQLColumns { TABLE_CAT = 1, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, DATA_TYPE, TYPE_NAME, COLUMN_SIZE, BUFFER_LENGTH, DECIMAL_DIGITS, NUM_PREC_RADIX, NULLABLE, REMARKS, COLUMN_DEF, SQL_DATA_TYPE, SQL_DATETIME_SUB, CHAR_OCTET_LENGTH, ORDINAL_POSITION, IS_NULLABLE, COL_MAX }; m_field aSQLColumns[] = { "", "", 0, 0, 0, "TABLE_CAT", "sys", CHAR_TYPE, 50, 0, "TABLE_SCHEM", "sys", CHAR_TYPE, 50, 0, "TABLE_NAME", "sys", CHAR_TYPE, 50, 0, "COLUMN_NAME", "sys", CHAR_TYPE, 50, 0, "DATA_TYPE", "sys", INT_TYPE, 3, 0, "TYPE_NAME", "sys", CHAR_TYPE, 50, 0, "COLUMN_SIZE", "sys", INT_TYPE, 3, 0, "BUFFER_LENGTH", "sys", INT_TYPE, 3, 0, "DECIMAL_DIGITS", "sys", INT_TYPE, 3, 0, "NUM_PREC_RADIX", "sys", INT_TYPE, 3, 0, "NULLABLE", "sys", INT_TYPE, 3, 0, "REMARKS", "sys", CHAR_TYPE, 50, 0, "COLUMN_DEF", "sys", CHAR_TYPE, 50, 0, "SQL_DATA_TYPE", "sys", INT_TYPE, 3, 0, "SQL_DATETIME_SUB", "sys", INT_TYPE, 3, 0, "CHAR_OCTET_LENGTH","sys", INT_TYPE, 3, 0, "ORDINAL_POSITION", "sys", CHAR_TYPE, 50, 0, "IS_NULLABLE", "sys", CHAR_TYPE, 50, 0 }; SQLRETURN SQLColumns( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength, SQLCHAR *szColumnName, SQLSMALLINT nColumnNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; m_result *pResults; /* mSQL DATA */ m_field *pField; /* mSQL field */ COLUMNHDR *pColumnHeader; int nColumn; long nCols; long nRow; long nCurRow; char szBuffer[101]; int nIndexColumns = 0; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); if ( szTableName == NULL || szTableName[0] == '\0' ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Must supply a valid table name" ); return SQL_ERROR; } /************************** * close any existing result **************************/ if ( hStmt->hStmtExtras->aResults ) _FreeResults( hStmt->hStmtExtras ); if ( hStmt->pszQuery != NULL ) free( hStmt->pszQuery ); hStmt->pszQuery = NULL; /************************ * generate a result set listing columns (these will be our rows) ************************/ pResults = msqlListFields( ((HDRVDBC)hStmt->hDbc)->hDbcExtras->hServer, szTableName ); if ( pResults == NULL ) { sprintf( hStmt->szSqlMsg, "SQL_ERROR Query failed. %s", msqlErrMsg ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } /************************ * how many columns are indexs? ************************/ nIndexColumns = 0; while ( pField = msqlFetchField( pResults ) ) { if ( pField->type == IDX_TYPE) nIndexColumns++; } msqlFieldSeek( pResults, 0 ); /************************** * allocate memory for columns headers and result data (row 0 is column header while col 0 is reserved for bookmarks) **************************/ hStmt->hStmtExtras->nCols = COL_MAX-1; hStmt->hStmtExtras->nRows = msqlNumFields( pResults ) - nIndexColumns; hStmt->hStmtExtras->nRow = 0; hStmt->hStmtExtras->aResults = malloc( sizeof(char*) * (hStmt->hStmtExtras->nRows+1) * (hStmt->hStmtExtras->nCols+1) ); memset( hStmt->hStmtExtras->aResults, 0, sizeof(char*) * (hStmt->hStmtExtras->nRows+1) * (hStmt->hStmtExtras->nCols+1) ); if ( hStmt->hStmtExtras->aResults == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "Not enough memory. (malloc failed)" ); hStmt->hStmtExtras->nRows = 0; hStmt->hStmtExtras->nCols = 0; msqlFreeResult( pResults ); return SQL_ERROR; } /************************** * gather column header information (save col 0 for bookmarks) **************************/ for ( nColumn = 1; nColumn < COL_MAX; nColumn++ ) { (hStmt->hStmtExtras->aResults)[nColumn] = malloc( sizeof(COLUMNHDR) ); pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nColumn]; memset( pColumnHeader, 0, sizeof(COLUMNHDR) ); _NativeToSQLColumnHeader( pColumnHeader, &(aSQLColumns[nColumn]) ); } /************************ * gather data (save col 0 for bookmarks and factor out index columns) ************************/ nCols = hStmt->hStmtExtras->nCols; hStmt->hStmtExtras->nRow = 0; for ( nCurRow = 1; nCurRow <= msqlNumFields( pResults ); nCurRow++ ) { pField = msqlFetchField( pResults ); if ( pField->type != IDX_TYPE) { hStmt->hStmtExtras->nRow++; nRow = hStmt->hStmtExtras->nRow; for ( nColumn = 1; nColumn < COL_MAX; nColumn++ ) { switch ( nColumn ) { case TABLE_NAME: (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = (char*)strdup( szTableName ); break; case COLUMN_NAME: (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = (char*)strdup( pField->name ); break; case TYPE_NAME: (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = (char*)strdup( msqlTypeNames[pField->type] ); break; case COLUMN_SIZE: sprintf( szBuffer, "%d", pField->length ); (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = (char*)strdup( szBuffer ); break; case NULLABLE: (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = (char *)strdup( IS_NOT_NULL( pField->flags ) ? "0" : "1" ); break; default: (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = NULL; } /* switch nColumn */ } /* for nColumn */ } /* if */ } /* for nRow */ hStmt->hStmtExtras->nRow = 0; /************************** * free the snapshot **************************/ msqlFreeResult( pResults ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLConnect.c000066400000000000000000000113251446441710500202310ustar00rootroot00000000000000/********************************************************************** * SQLConnect * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLConnect( SQLHDBC hDrvDbc, SQLCHAR *szDataSource, SQLSMALLINT nDataSourceLength, SQLCHAR *szUID, SQLSMALLINT nUIDLength, SQLCHAR *szPWD, SQLSMALLINT nPWDLength ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; char szDATABASE[INI_MAX_PROPERTY_VALUE+1]; char szCONFIGFILE[INI_MAX_PROPERTY_VALUE+1]; char szHOST[INI_MAX_PROPERTY_VALUE+1]; /* SANITY CHECKS */ if( SQL_NULL_HDBC == hDbc ) return SQL_INVALID_HANDLE; sprintf( hDbc->szSqlMsg, "hDbc=$%08lX szDataSource=(%s)", hDbc, szDataSource ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); if( hDbc->bConnected == 1 ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Already connected" ); return SQL_ERROR; } if ( strlen( szDataSource ) > ODBC_FILENAME_MAX+INI_MAX_OBJECT_NAME ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Given Data Source is too long. I consider it suspect." ); return SQL_ERROR; } /******************** * gather and use any required DSN properties * - CONFIGFILE - for msqlLoadConfigFile() (has precedence over other properties) * - DATABASE * - HOST (localhost assumed if not supplied) ********************/ szDATABASE[0] = '\0'; szHOST[0] = '\0'; szCONFIGFILE[0] = '\0'; SQLGetPrivateProfileString( szDataSource, "DATABASE", "", szDATABASE, sizeof(szDATABASE), ".odbc.ini" ); if ( szDATABASE[0] == '\0' ) { sprintf( hDbc->szSqlMsg, "SQL_ERROR Could not find Driver entry for %s in system information", szDataSource ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); return SQL_ERROR; } SQLGetPrivateProfileString( szDataSource, "HOST", "", szHOST, sizeof(szHOST), ".odbc.ini" ); SQLGetPrivateProfileString( szDataSource, "CONFIGFILE", "", szCONFIGFILE, sizeof(szCONFIGFILE), ".odbc.ini" ); /******************** * 1. initialise structures * 2. try connection with database using your native calls * 3. store your server handle in the extras somewhere * 4. set connection state * hDbc->bConnected = TRUE; ********************/ if ( szCONFIGFILE[0] != '\0' ) { if ( msqlLoadConfigFile( szCONFIGFILE ) != 0 ) { sprintf( hDbc->szSqlMsg, "SQL_ERROR %s", msqlErrMsg ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); sprintf( hDbc->szSqlMsg, "SQL_WARNING Failed to use (%s)", szCONFIGFILE ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); return SQL_ERROR; } } if ( szHOST[0] == '\0' ) { hDbc->hDbcExtras->hServer = msqlConnect( NULL ); /* this is faster than using localhost */ strcpy( szHOST, "localhost" ); } else hDbc->hDbcExtras->hServer = msqlConnect( szHOST ); if ( hDbc->hDbcExtras->hServer < 0 ) { sprintf( hDbc->szSqlMsg, "SQL_ERROR %s", msqlErrMsg ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); sprintf( hDbc->szSqlMsg, "SQL_ERROR Failed to connect to (%s)", szHOST ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); return SQL_ERROR; } hDbc->bConnected = 1; /* SET DATABASE */ if ( szDATABASE[0] != '\0' ) { if ( msqlSelectDB( hDbc->hDbcExtras->hServer, szDATABASE ) == -1 ) { sprintf( hDbc->szSqlMsg, "SQL_WARNING %s", msqlErrMsg ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); sprintf( hDbc->szSqlMsg, "SQL_WARNING Connected to server but failed to use database (%s)", szDATABASE ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); } else { sprintf( hDbc->szSqlMsg, "SQL_INFO DATABASE=%s", szDATABASE ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); } } logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLCopyDesc.c000066400000000000000000000013661446441710500203550ustar00rootroot00000000000000/********************************************************************** * SQLCopyDesc * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLCopyDesc( SQLHDESC hSourceDescHandle, SQLHDESC hTargetDescHandle ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLDescribeCol.c000066400000000000000000000044421446441710500210200ustar00rootroot00000000000000/********************************************************************** * SQLDescribeCol * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLDescribeCol( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLCHAR *szColName, SQLSMALLINT nColNameMax, SQLSMALLINT *pnColNameLength, SQLSMALLINT *pnSQLDataType, SQLUINTEGER *pnColSize, SQLSMALLINT *pnDecDigits, SQLSMALLINT *pnNullable ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; COLUMNHDR *pColumnHeader; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); if ( hStmt->hStmtExtras->nRows < 1 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No result set." ); return SQL_ERROR; } if ( nCol < 1 || nCol > hStmt->hStmtExtras->nCols ) { sprintf( hStmt->szSqlMsg, "SQL_ERROR Column %d is out of range. Range is 1 - %s", nCol, hStmt->hStmtExtras->nCols ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } /**************************** * Ok ***************************/ pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nCol]; if ( szColName ) strncpy( szColName, pColumnHeader->pszSQL_DESC_NAME, nColNameMax ); if ( pnColNameLength ) *pnColNameLength = strlen( szColName ); if ( pnSQLDataType ) *pnSQLDataType = pColumnHeader->nSQL_DESC_TYPE; if ( pnColSize ) *pnColSize = pColumnHeader->nSQL_DESC_LENGTH; if ( pnDecDigits ) *pnDecDigits = pColumnHeader->nSQL_DESC_SCALE; if ( pnNullable ) *pnNullable = pColumnHeader->nSQL_DESC_NULLABLE; logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLDescribeParam.c000066400000000000000000000034651446441710500213470ustar00rootroot00000000000000/********************************************************************** * SQLDescribeParam * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" /* HERES THE CORRECT WAY... SQLRETURN SQLDescribeParam( SQLHSTMT hDrvStmt, SQLUSMALLINT nParmNumber, SQLSMALLINT *pnDataType, SQLUINTEGER *pnSize, SQLSMALLINT *pnDecDigits, SQLSMALLINT *pnNullable ) HERES THE WAY THAT WORKS... */ SQLRETURN SQLDescribeParam( SQLHSTMT hDrvStmt, UWORD nParmNumber, SWORD *pnDataType, UDWORD *pnSize, SWORD *pnDecDigits, SWORD *pnNullable ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLDisconnect.c000066400000000000000000000031361446441710500207320ustar00rootroot00000000000000/********************************************************************** * SQLDisconnect * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLDisconnect( SQLHDBC hDrvDbc ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; /* SANITY CHECKS */ if( NULL == hDbc ) return SQL_INVALID_HANDLE; sprintf( hDbc->szSqlMsg, "hDbc = $%08lX", hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); if( hDbc->bConnected == 0 ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_SUCCESS_WITH_INFO Connection not open" ); return SQL_SUCCESS_WITH_INFO; } if ( hDbc->hFirstStmt != SQL_NULL_HSTMT ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Active Statements exist. Can not disconnect." ); return SQL_ERROR; } /**************************** * 1. do driver specific close here ****************************/ msqlClose( hDbc->hDbcExtras->hServer ); hDbc->hDbcExtras->hServer = -1; hDbc->bConnected = 0; logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLDriverConnect.c000066400000000000000000000046411446441710500214100ustar00rootroot00000000000000/********************************************************************** * SQLDriverConnect * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLDriverConnect( SQLHDBC hDrvDbc, SQLHWND hWnd, SQLCHAR *szConnStrIn, SQLSMALLINT nConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pnConnStrOut, SQLUSMALLINT nDriverCompletion ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; /* SANITY CHECKS */ if( NULL == hDbc ) return SQL_INVALID_HANDLE; sprintf( hDbc->szSqlMsg, "hDbc = $%08lX", hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); if( hDbc->bConnected == 1 ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Already connected" ); return SQL_ERROR; } /************************* * 1. parse nConnStrIn for connection options. Format is; * Property=Value;... * 2. we may not have all options so handle as per DM request * 3. fill as required szConnStrOut *************************/ switch( nDriverCompletion ) { case SQL_DRIVER_PROMPT: case SQL_DRIVER_COMPLETE: case SQL_DRIVER_COMPLETE_REQUIRED: case SQL_DRIVER_NOPROMPT: default: sprintf( hDbc->szSqlMsg, "Invalid nDriverCompletion=%d", nDriverCompletion ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); break; } /************************* * 4. try to connect * 5. set gathered options (ie USE Database or whatever) * 6. set connection state * hDbc->bConnected = TRUE; * hDbc->ciActive = 0; *************************/ logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported." ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLEndTran.c000066400000000000000000000014161446441710500201730ustar00rootroot00000000000000/********************************************************************** * SQLEndTran * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLEndTran( SQLSMALLINT nHandleType, SQLHANDLE nHandle, SQLSMALLINT nCompletionType ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLError.c000066400000000000000000000040761446441710500177360ustar00rootroot00000000000000/********************************************************************** * SQLError (deprecated see SQLGetDiagRec) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLError( SQLHENV hDrvEnv, SQLHDBC hDrvDbc, SQLHSTMT hDrvStmt, SQLCHAR *szSqlState, SQLINTEGER *pfNativeError, SQLCHAR *szErrorMsg, SQLSMALLINT nErrorMsgMax, SQLSMALLINT *pcbErrorMsg ) { HDRVENV hEnv = (HDRVENV)hDrvEnv; HDRVDBC hDbc = (HDRVDBC)hDrvDbc; HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; char *pszState = NULL; /* pointer to status code */ char *pszErrMsg = NULL; /* pointer to error message */ char szMsgHdr[1024]; int nCode; /* SANITY CHECKS */ if( hEnv == SQL_NULL_HENV && hDbc == SQL_NULL_HDBC && hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; /* DEFAULTS */ szSqlState[0] = '\0'; *pfNativeError = 0; szErrorMsg[0] = '\0'; *pcbErrorMsg = 0; /* STATEMENT */ if( hStmt != SQL_NULL_HENV ) { if ( logPopMsg( hStmt->hLog ) != LOG_SUCCESS ) return SQL_NO_DATA; strncpy( szErrorMsg, hStmt->szSqlMsg, nErrorMsgMax ); *pcbErrorMsg = strlen( szErrorMsg ); return SQL_SUCCESS; } /* CONNECTION */ if( hDbc != SQL_NULL_HDBC ) { if ( logPopMsg( hDbc->hLog ) != LOG_SUCCESS ) return SQL_NO_DATA; strncpy( szErrorMsg, hDbc->szSqlMsg, nErrorMsgMax ); *pcbErrorMsg = strlen( szErrorMsg ); return SQL_SUCCESS; } /* ENVIRONMENT */ if( hEnv != SQL_NULL_HSTMT ) { if ( logPopMsg( hEnv->hLog ) != LOG_SUCCESS ) return SQL_NO_DATA; strncpy( szErrorMsg, hEnv->szSqlMsg, nErrorMsgMax ); *pcbErrorMsg = strlen( szErrorMsg ); return SQL_SUCCESS; } return SQL_NO_DATA; } unixODBC-2.3.12/Drivers/MiniSQL/SQLExecDirect.c000066400000000000000000000027711446441710500206640ustar00rootroot00000000000000/********************************************************************** * SQLExecDirect * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLExecDirect( SQLHSTMT hDrvStmt, SQLCHAR *szSqlStr, SQLINTEGER nSqlStr ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; RETCODE rc; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /* prepare command */ rc = _Prepare( hDrvStmt, szSqlStr, nSqlStr ); if ( SQL_SUCCESS != rc ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "Could not prepare statement" ); return rc; } /* execute command */ rc = _Execute( hDrvStmt ); if ( SQL_SUCCESS != rc ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "Problem calling SQLEXecute" ); return rc; } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLExecute.c000066400000000000000000000011651446441710500202430ustar00rootroot00000000000000/********************************************************************** * SQLExecute * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLExecute( SQLHSTMT hDrvStmt ) { return _Execute( hDrvStmt ); } unixODBC-2.3.12/Drivers/MiniSQL/SQLExtendedFetch.c000066400000000000000000000026201446441710500213500ustar00rootroot00000000000000/********************************************************************** * SQLExtendedFetch * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLExtendedFetch( SQLHSTMT hDrvStmt, SQLUSMALLINT nOrientation, SQLINTEGER nOffset, SQLUINTEGER *pnRowCount, SQLUSMALLINT *pRowStatusArray ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLFetch.c000066400000000000000000000042461446441710500176750ustar00rootroot00000000000000/********************************************************************** * SQLFetch * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLFetch( SQLHSTMT hDrvStmt) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; int nColumn = -1; COLUMNHDR *pColumnHeader; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); if ( hStmt->hStmtExtras->nRows < 1 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No result set." ); return SQL_ERROR; } /************************ * goto next row ************************/ if ( hStmt->hStmtExtras->nRow < 0 ) return SQL_NO_DATA; if ( hStmt->hStmtExtras->nRow >= hStmt->hStmtExtras->nRows ) return SQL_NO_DATA; hStmt->hStmtExtras->nRow++; /************************ * transfer bound column values to bound storage as required ************************/ for ( nColumn=1; nColumn <= hStmt->hStmtExtras->nCols; nColumn++ ) { pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nColumn]; if ( pColumnHeader->pTargetValue != NULL ) { if ( _GetData( hDrvStmt, nColumn, pColumnHeader->nTargetType, pColumnHeader->pTargetValue, pColumnHeader->nTargetValueMax, pColumnHeader->pnLengthOrIndicator ) != SQL_SUCCESS ) { sprintf( hStmt->szSqlMsg, "SQL_ERROR Failed to get data for column %d", nColumn ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } } } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLFetchScroll.c000066400000000000000000000054741446441710500210600ustar00rootroot00000000000000/***************************************************************************** * SQLFetchScroll * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * *****************************************************************************/ #include #include "driver.h" SQLRETURN SQLFetchScroll( SQLHSTMT hDrvStmt, SQLSMALLINT nOrientation, SQLINTEGER nOffset ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; int nColumn = -1; COLUMNHDR *pColumnHeader; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /* how much do we want to move */ switch ( nOrientation ) { case SQL_FETCH_NEXT: if ( hStmt->hStmtExtras->nRow >= hStmt->hStmtExtras->nRows ) return SQL_NO_DATA; hStmt->hStmtExtras->nRow++; break; case SQL_FETCH_PRIOR: if ( hStmt->hStmtExtras->nRow == 0 ) return SQL_NO_DATA; hStmt->hStmtExtras->nRow--; break; case SQL_FETCH_FIRST: hStmt->hStmtExtras->nRow = 0; break; case SQL_FETCH_LAST: hStmt->hStmtExtras->nRow = hStmt->hStmtExtras->nRows-1; break; case SQL_FETCH_ABSOLUTE: if ( nOffset < 0 || nOffset >= hStmt->hStmtExtras->nRows ) return SQL_NO_DATA; hStmt->hStmtExtras->nRow = nOffset; break; case SQL_FETCH_RELATIVE: if ( hStmt->hStmtExtras->nRow+nOffset < 0 || hStmt->hStmtExtras->nRow+nOffset >= hStmt->hStmtExtras->nRows ) return SQL_NO_DATA; hStmt->hStmtExtras->nRow += nOffset; break; case SQL_FETCH_BOOKMARK: return SQL_ERROR; break; default: return SQL_ERROR; } /************************ * transfer bound column values to bound storage as required ************************/ for ( nColumn=1; nColumn <= hStmt->hStmtExtras->nCols; nColumn++ ) { pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nColumn]; if ( pColumnHeader->pTargetValue != NULL ) { if ( _GetData( hDrvStmt, nColumn, pColumnHeader->nTargetType, pColumnHeader->pTargetValue, pColumnHeader->nTargetValueMax, pColumnHeader->pnLengthOrIndicator ) != SQL_SUCCESS ) { sprintf( hStmt->szSqlMsg, "SQL_ERROR Failed to get data for column %d", nColumn ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } } } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLForeignKeys.c000066400000000000000000000036431446441710500210710ustar00rootroot00000000000000/******************************************************************** * SQLForeignKeys * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLForeignKeys( SQLHSTMT hDrvStmt, SQLCHAR *szPKCatalogName, SQLSMALLINT nPKCatalogNameLength, SQLCHAR *szPKSchemaName, SQLSMALLINT nPKSchemaNameLength, SQLCHAR *szPKTableName, SQLSMALLINT nPKTableNameLength, SQLCHAR *szFKCatalogName, SQLSMALLINT nFKCatalogNameLength, SQLCHAR *szFKSchemaName, SQLSMALLINT nFKSchemaNameLength, SQLCHAR *szFKTableName, SQLSMALLINT nFKTableNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLFreeConnect.c000066400000000000000000000013751446441710500210370ustar00rootroot00000000000000/********************************************************************** * SQLFreeConnect * * Do not try to Free Dbc if there are Stmts... return an error. Let the * Driver Manager do a recursive clean up if it wants. * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLFreeConnect( SQLHDBC hDrvDbc ) { return sqlFreeConnect( hDrvDbc ); } unixODBC-2.3.12/Drivers/MiniSQL/SQLFreeEnv.c000066400000000000000000000013601446441710500201700ustar00rootroot00000000000000/********************************************************************** * SQLFreeEnv * * Do not try to Free Env if there are Dbcs... return an error. Let the * Driver Manager do a recursive clean up if it wants. * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLFreeEnv( SQLHENV hDrvEnv ) { return sqlFreeEnv( hDrvEnv ); } unixODBC-2.3.12/Drivers/MiniSQL/SQLFreeHandle.c000066400000000000000000000020321446441710500206300ustar00rootroot00000000000000/********************************************************************** * SQLFreeHandle * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLFreeHandle( SQLSMALLINT nHandleType, SQLHANDLE nHandle ) { switch( nHandleType ) { case SQL_HANDLE_ENV: return sqlFreeEnv( (SQLHENV)nHandle ); case SQL_HANDLE_DBC: return sqlFreeConnect( (SQLHDBC)nHandle ); case SQL_HANDLE_STMT: return sqlFreeStmt( (SQLHSTMT)nHandle, 0 ); case SQL_HANDLE_DESC: break; default: return SQL_ERROR; } return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLFreeStmt.c000066400000000000000000000012461446441710500203720ustar00rootroot00000000000000/********************************************************************** * SQLFreeStmt * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLFreeStmt( SQLHSTMT hDrvStmt, SQLUSMALLINT nOption ) { return sqlFreeStmt( hDrvStmt, nOption ); } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetConnectAttr.c000066400000000000000000000026511446441710500215260ustar00rootroot00000000000000/********************************************************************** * SQLGetConnectAttr * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetConnectAttr( SQLHDBC hDrvDbc, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; /* SANITY CHECKS */ if( NULL == hDbc ) return SQL_INVALID_HANDLE; sprintf( hDbc->szSqlMsg, "hDbc = $%08lX", hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetConnectOption.c000066400000000000000000000022721446441710500220630ustar00rootroot00000000000000/********************************************************************** * SQLGetConnectOption (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetConnectOption( SQLHDBC hDrvDbc, UWORD fOption, PTR pvParam ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; /* SANITY CHECKS */ if( NULL == hDbc ) return SQL_INVALID_HANDLE; sprintf( hDbc->szSqlMsg, "hDbc = $%08lX", hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetCursorName.c000066400000000000000000000033641446441710500213620ustar00rootroot00000000000000/********************************************************************** * SQLGetCursorName * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetCursorName( SQLHSTMT hDrvStmt, SQLCHAR *szCursor, SQLSMALLINT nCursorMaxLength, SQLSMALLINT *pnCursorLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; int ci; /* counter variable */ /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); if ( NULL == szCursor ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No cursor name." ); return SQL_ERROR; } /* ** copy cursor name */ strncpy( szCursor, hStmt->szCursorName, nCursorMaxLength ); /* ** set length of transfered data */ ci = strlen( hStmt->szCursorName ); /* if ( NULL != pnCursorLength ) *pnCursorLength = MIN( ci, nCursorMaxLength ); */ if ( nCursorMaxLength < ci ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_SUCCESS_WITH_INFO Cursor was truncated" ); return SQL_SUCCESS_WITH_INFO; } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetData.c000066400000000000000000000020261446441710500201470ustar00rootroot00000000000000/********************************************************************** * SQLGetData * * 1. MiniSQL server sends all data as ascii strings so things are * simplified. We always convert from string to nTargetType. * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetData( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLSMALLINT nTargetType, /* C DATA TYPE */ SQLPOINTER pTarget, SQLINTEGER nTargetLength, SQLINTEGER *pnLengthOrIndicator ) { return _GetData( hDrvStmt, nCol, nTargetType, pTarget, nTargetLength, pnLengthOrIndicator ); } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetDescField.c000066400000000000000000000017301446441710500211210ustar00rootroot00000000000000/********************************************************************** * SQLGetDescField * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetDescField( SQLHDESC DescriptorHandle, SQLSMALLINT RecordNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetDescRec.c000066400000000000000000000023521446441710500206100ustar00rootroot00000000000000/********************************************************************** * SQLGetDescRec * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetDescRec( SQLHDESC DescriptorHandle, SQLSMALLINT RecordNumber, SQLCHAR *Name, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, SQLSMALLINT *Type, SQLSMALLINT *SubType, SQLINTEGER *Length, SQLSMALLINT *Precision, SQLSMALLINT *Scale, SQLSMALLINT *Nullable ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetDiagField.c000066400000000000000000000020141446441710500211030ustar00rootroot00000000000000/********************************************************************** * SQLGetDiagField * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetDiagField( SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecordNumber, SQLSMALLINT DiagIdentifier, SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetDiagRec.c000066400000000000000000000021031446441710500205700ustar00rootroot00000000000000/********************************************************************** * SQLGetDiagRec * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetDiagRec( SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecordNumber, SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetEnvAttr.c000066400000000000000000000016201446441710500206600ustar00rootroot00000000000000/********************************************************************** * SQLGetEnvAttr * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetEnvAttr( SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetInfo.c000066400000000000000000000031641446441710500201750ustar00rootroot00000000000000/********************************************************************** * SQLGetInfo * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetInfo( SQLHDBC hDbc, SQLUSMALLINT nInfoType, SQLPOINTER pInfoValue, SQLSMALLINT nInfoValueMax, SQLSMALLINT *pnLength) { SQLRETURN rc=SQL_ERROR; switch (nInfoType) { case SQL_DBMS_NAME: if (nInfoValueMax < 5) break; strcpy( pInfoValue, "mSQL"); *pnLength = 4; rc = SQL_SUCCESS; break; case SQL_DBMS_VER: { SQLPOINTER ver=(SQLPOINTER)msqlGetServerInfo(); SQLSMALLINT len=strlen(ver); if (nInfoValueMax < len+1) break; strcpy( pInfoValue, ver); *pnLength = len; rc = SQL_SUCCESS; break; } case SQL_TXN_CAPABLE: { SQLSMALLINT supp=0; if (nInfoValueMax < sizeof(SQLSMALLINT)) break; pInfoValue = (SQLPOINTER)&supp; *pnLength = sizeof(SQLSMALLINT); rc = SQL_SUCCESS; break; } } return rc; } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetStmtAttr.c000066400000000000000000000026071446441710500210650ustar00rootroot00000000000000/********************************************************************** * SQLGetStmtAttr * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetStmtAttr( SQLHSTMT hDrvStmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetStmtOption.c000066400000000000000000000023541446441710500214220ustar00rootroot00000000000000/********************************************************************** * SQLGetStmtOption (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetStmtOption( SQLHSTMT hDrvStmt, UWORD fOption, PTR pvParam) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLGetTypeInfo.c000066400000000000000000000022611446441710500210340ustar00rootroot00000000000000/********************************************************************** * SQLGetTypeInfo * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetTypeInfo( SQLHSTMT hDrvStmt, SQLSMALLINT nSqlType ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLMoreResults.c000066400000000000000000000021621446441710500211230ustar00rootroot00000000000000/********************************************************************** * SQLMoreResults * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLMoreResults( SQLHSTMT hDrvStmt ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLNativeSql.c000066400000000000000000000026111446441710500205440ustar00rootroot00000000000000/********************************************************************** * SQLNativeSql * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLNativeSql( SQLHSTMT hDrvStmt, SQLCHAR *szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLCHAR *szSqlStr, SQLINTEGER cbSqlStrMax, SQLINTEGER *pcbSqlStr ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLNumParams.c000066400000000000000000000022551446441710500205450ustar00rootroot00000000000000/********************************************************************** * SQLNumParams * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLNumParams( SQLHSTMT hDrvStmt, SQLSMALLINT *pnParamCount ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLNumResultCols.c000066400000000000000000000025531446441710500214220ustar00rootroot00000000000000/********************************************************************** * SQLNumResultCols * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLNumResultCols( SQLHSTMT hDrvStmt, SQLSMALLINT *pnColumnCount ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); if ( hStmt->hStmtExtras->nRows < 0 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No result set." ); return SQL_ERROR; } /******************** * get number of columns in result set ********************/ *pnColumnCount = hStmt->hStmtExtras->nCols; logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLParamData.c000066400000000000000000000022461446441710500204740ustar00rootroot00000000000000/********************************************************************** * SQLParamData * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLParamData( SQLHSTMT hDrvStmt, SQLPOINTER *pValue ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLParamOptions.c000066400000000000000000000022631446441710500212550ustar00rootroot00000000000000/********************************************************************** * SQLParamOptions (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLParamOptions( SQLHSTMT hDrvStmt, SQLULEN nRow, SQLULEN *pnRow ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLPrepare.c000066400000000000000000000013131446441710500202320ustar00rootroot00000000000000/********************************************************************** * SQLPrepare * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLPrepare( SQLHSTMT hDrvStmt, SQLCHAR *szSqlStr, SQLINTEGER nSqlStrLength ) { return _Prepare( hDrvStmt, szSqlStr, nSqlStrLength ); } unixODBC-2.3.12/Drivers/MiniSQL/SQLPrimaryKeys.c000066400000000000000000000025751446441710500211260ustar00rootroot00000000000000/******************************************************************** * SQLPrimaryKeys * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLPrimaryKeys( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLProcedureColumns.c000066400000000000000000000027701446441710500221350ustar00rootroot00000000000000/******************************************************************** * SQLProcedureColumns * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLProcedureColumns( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szProcName, SQLSMALLINT nProcNameLength, SQLCHAR *szColumnName, SQLSMALLINT nColumnNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLProcedures.c000066400000000000000000000025761446441710500207630ustar00rootroot00000000000000/******************************************************************** * SQLProcedures * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLProcedures( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szProcName, SQLSMALLINT nProcNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLPutData.c000066400000000000000000000024421446441710500202020ustar00rootroot00000000000000/********************************************************************** * SQLPutData * * Supplies parameter data at execution time. Used in conjuction with * SQLParamData. ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLPutData( SQLHSTMT hDrvStmt, SQLPOINTER pData, SQLINTEGER nLengthOrIndicator ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLRowCount.c000066400000000000000000000023571446441710500204250ustar00rootroot00000000000000/********************************************************************** * SQLRowCount * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLRowCount( SQLHSTMT hDrvStmt, SQLINTEGER *pnRowCount) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); if ( NULL == pnRowCount ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR pnRowCount can not be NULL" ); return SQL_ERROR; } *pnRowCount = hStmt->hStmtExtras->nRows; logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLSetConnectOption.c000066400000000000000000000024731446441710500221020ustar00rootroot00000000000000/********************************************************************** * SQLSetConnectOption (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetConnectOption( SQLHDBC hDrvDbc, UWORD nOption, UDWORD vParam) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; /* SANITY CHECKS */ if ( hDbc == SQL_NULL_HDBC ) return SQL_INVALID_HANDLE; switch ( nOption ) { case SQL_TRANSLATE_DLL: case SQL_TRANSLATE_OPTION: /* case SQL_CONNECT_OPT_DRVR_START: */ case SQL_ODBC_CURSORS: case SQL_OPT_TRACE: switch ( vParam ) { case SQL_OPT_TRACE_ON: case SQL_OPT_TRACE_OFF: default: ; } break; case SQL_OPT_TRACEFILE: case SQL_ACCESS_MODE: case SQL_AUTOCOMMIT: default: ; } logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_SUCCESS_WITH_INFO Function not fully implemented" ); return SQL_SUCCESS_WITH_INFO; } unixODBC-2.3.12/Drivers/MiniSQL/SQLSetCursorName.c000066400000000000000000000030721446441710500213720ustar00rootroot00000000000000/********************************************************************** * SQLSetCursorName * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetCursorName( SQLHSTMT hDrvStmt, SQLCHAR *szCursor, SQLSMALLINT nCursorLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); if ( NULL == szCursor || 0 == isalpha(*szCursor) ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Invalid cursor name" ); return SQL_ERROR; } /* COPY CURSOR */ if ( SQL_NTS == nCursorLength ) { strncpy( hStmt->szCursorName, szCursor, SQL_MAX_CURSOR_NAME ); } else { /* strncpy( hStmt->szCursorName, szCursor, MIN(SQL_MAX_CURSOR_NAME - 1, nCursorLength) ); hStmt->szCursorName[ MIN( SQL_MAX_CURSOR_NAME - 1, nCursorLength) ] = '\0'; */ } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLSetDescField.c000066400000000000000000000016311446441710500211350ustar00rootroot00000000000000/********************************************************************** * SQLSetDescField * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetDescField( SQLHDESC DescriptorHandle, SQLSMALLINT RecordNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLSetDescRec.c000066400000000000000000000022611446441710500206230ustar00rootroot00000000000000/********************************************************************** * SQLSetDescRec * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetDescRec( SQLHDESC hDescriptorHandle, SQLSMALLINT nRecordNumber, SQLSMALLINT nType, SQLSMALLINT nSubType, SQLINTEGER nLength, SQLSMALLINT nPrecision, SQLSMALLINT nScale, SQLPOINTER pData, SQLINTEGER *pnStringLength, SQLINTEGER *pnIndicator ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLSetEnvAttr.c000066400000000000000000000015211446441710500206740ustar00rootroot00000000000000/********************************************************************** * SQLSetEnvAttr * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetEnvAttr( SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLSetParam.c000066400000000000000000000031741446441710500203570ustar00rootroot00000000000000/******************************************************************** * SQLSetParam (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetParam( SQLHSTMT hDrvStmt, UWORD nPar, SWORD nType, SWORD nSqlType, UDWORD nColDef, SWORD nScale, PTR pValue, SDWORD *pnValue ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); if ( NULL == hStmt->pszQuery ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No prepared statement to work with" ); return SQL_ERROR; } /****************** * 1. Your param storage is in hStmt->hStmtExtras * so you will have to code for it. Do it here. ******************/ /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLSetPos.c000066400000000000000000000036131446441710500200560ustar00rootroot00000000000000/******************************************************************** * SQLSetPos * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetPos( SQLHSTMT hDrvStmt, SQLUSMALLINT nRow, SQLUSMALLINT nOperation, SQLUSMALLINT nLockType ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /* OK */ switch ( nOperation ) { case SQL_POSITION: break; case SQL_REFRESH: break; case SQL_UPDATE: break; case SQL_DELETE: break; default: sprintf( hStmt->szSqlMsg, "SQL_ERROR Invalid nOperation=%d", nOperation ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } switch ( nLockType ) { case SQL_LOCK_NO_CHANGE: break; case SQL_LOCK_EXCLUSIVE: break; case SQL_LOCK_UNLOCK: break; default: sprintf( hStmt->szSqlMsg, "SQL_ERROR Invalid nLockType=%d", nLockType ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLSetScrollOptions.c000066400000000000000000000023731446441710500221310ustar00rootroot00000000000000/******************************************************************** * SQLSetScrollOptions (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetScrollOptions( SQLHSTMT hDrvStmt, UWORD fConcurrency, SDWORD crowKeyset, UWORD crowRowset ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLSetStmtAttr.c000066400000000000000000000025351446441710500211010ustar00rootroot00000000000000/********************************************************************** * SQLSetStmtAttr * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetStmtAttr( SQLHSTMT hDrvStmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLSetStmtOption.c000066400000000000000000000023071446441710500214340ustar00rootroot00000000000000/********************************************************************** * SQLSetStmtOption (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetStmtOption( SQLHSTMT hDrvStmt, UWORD fOption, UDWORD vParam) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLSpecialColumns.c000066400000000000000000000121161446441710500215600ustar00rootroot00000000000000/******************************************************************** * SQLSpecialColumns * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" enum nSQLSpecialColumns { COLUMN_NAME = 1, COL_MAX }; m_field aSQLSpecialColumns[] = { "", "", 0, 0, 0, "COLUMN_NAME", "sys", CHAR_TYPE, 50, 0 }; /* THIS IS CORRECT... SQLRETURN SQLSpecialColumns( SQLHSTMT hDrvStmt, SQLSMALLINT nColumnType, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength, SQLSMALLINT nScope, SQLSMALLINT nNullable ) THIS WORKS... */ SQLRETURN SQLSpecialColumns( SQLHSTMT hDrvStmt, UWORD nColumnType, UCHAR *szCatalogName, SWORD nCatalogNameLength, UCHAR *szSchemaName, SWORD nSchemaNameLength, UCHAR *szTableName, SWORD nTableNameLength, UWORD nScope, UWORD nNullable ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; COLUMNHDR *pColumnHeader; int nColumn; long nCols; long nRow; long nCurRow; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; if ( !szTableName ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /* validate nColumnType */ switch ( nColumnType ) { case SQL_BEST_ROWID: break; case SQL_ROWVER: default: logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } /* validate nScope */ switch ( nScope ) { case SQL_SCOPE_CURROW: case SQL_SCOPE_TRANSACTION: case SQL_SCOPE_SESSION: break; default: logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } /* validate nNullable */ switch ( nNullable ) { case SQL_NO_NULLS: case SQL_NULLABLE: break; default: logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } /* only one scenario supported: nColumnType=SQL_BEST_ROWID and nScope=ignored nNullable=ignored */ /************************** * close any existing result **************************/ if ( hStmt->hStmtExtras->aResults ) _FreeResults( hStmt->hStmtExtras ); if ( hStmt->pszQuery != NULL ) free( hStmt->pszQuery ); hStmt->pszQuery = NULL; /************************** * allocate memory for columns headers and result data (row 0 is column header while col 0 is reserved for bookmarks) **************************/ hStmt->hStmtExtras->nCols = COL_MAX-1; hStmt->hStmtExtras->nRows = 1; hStmt->hStmtExtras->nRow = 0; hStmt->hStmtExtras->aResults = malloc( sizeof(char*) * (hStmt->hStmtExtras->nRows+1) * (hStmt->hStmtExtras->nCols+1) ); memset( hStmt->hStmtExtras->aResults, 0, sizeof(char*) * (hStmt->hStmtExtras->nRows+1) * (hStmt->hStmtExtras->nCols+1) ); if ( hStmt->hStmtExtras->aResults == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "Not enough memory. (malloc failed)" ); hStmt->hStmtExtras->nRows = 0; hStmt->hStmtExtras->nCols = 0; return SQL_ERROR; } /************************** * gather column header information (save col 0 for bookmarks) **************************/ for ( nColumn = 1; nColumn < COL_MAX; nColumn++ ) { (hStmt->hStmtExtras->aResults)[nColumn] = malloc( sizeof(COLUMNHDR) ); pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nColumn]; memset( pColumnHeader, 0, sizeof(COLUMNHDR) ); _NativeToSQLColumnHeader( pColumnHeader, &(aSQLSpecialColumns[nColumn]) ); } /************************ * gather data (save col 0 for bookmarks and factor out index columns) ************************/ nCols = hStmt->hStmtExtras->nCols; hStmt->hStmtExtras->nRow = 0; nCurRow = 1; hStmt->hStmtExtras->nRow++; nRow = hStmt->hStmtExtras->nRow; for ( nColumn = 1; nColumn < COL_MAX; nColumn++ ) { switch ( nColumn ) { case COLUMN_NAME: (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = (char*)strdup( "_rowid" ); break; default: (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = NULL; } /* switch nColumn */ } /* for nColumn */ hStmt->hStmtExtras->nRow = 0; logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLStatistics.c000066400000000000000000000143221446441710500207720ustar00rootroot00000000000000/******************************************************************** * SQLStatistics * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" enum nSQLStatistics { TABLE_CAT = 1, TABLE_SCHEM, TABLE_NAME, NON_UNIQUE, INDEX_QUALIFIER, INDEX_NAME, TYPE, ORDINAL_POSITION, COLUMN_NAME, ASC_OR_DESC, CARDINALITY, PAGES, FILTER_CONDITION, COL_MAX }; m_field aSQLStatistics[] = { "", "", 0, 0, 0, "TABLE_CAT", "sys", CHAR_TYPE, 50, 0, "TABLE_SCHEM", "sys", CHAR_TYPE, 50, 0, "TABLE_NAME", "sys", CHAR_TYPE, 50, 0, "NON_UNIQUE", "sys", INT_TYPE, 3, 0, "INDEX_QUALIFIER", "sys", CHAR_TYPE, 50, 0, "INDEX_NAME", "sys", CHAR_TYPE, 50, 0, "TYPE", "sys", INT_TYPE, 3, 0, "ORDINAL_POSITION", "sys", CHAR_TYPE, 50, 0, "COLUMN_NAME", "sys", CHAR_TYPE, 50, 0, "ASC_OR_DESC", "sys", INT_TYPE, 3, 0, "CARDINALITY", "sys", INT_TYPE, 3, 0, "PAGES", "sys", INT_TYPE, 3, 0, "FILTER_CONDITION", "sys", CHAR_TYPE, 50, 0 }; SQLRETURN SQLStatistics( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, /* MUST BE SUPPLIED */ SQLSMALLINT nTableNameLength, SQLUSMALLINT nTypeOfIndex, SQLUSMALLINT nReserved ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; m_result *pResults; /* mSQL DATA */ m_field *pField; /* mSQL field */ COLUMNHDR *pColumnHeader; int nColumn; long nCols; long nCurRow; long nRow; char szBuffer[101]; int nIndexColumns = 0; int nNormalColumns = 0; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); if ( szTableName == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No table name" ); return SQL_ERROR; } if ( szTableName[0] == '\0' ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No table name" ); return SQL_ERROR; } /************************** * close any existing result **************************/ if ( hStmt->hStmtExtras->aResults ) _FreeResults( hStmt->hStmtExtras ); if ( hStmt->pszQuery != NULL ) free( hStmt->pszQuery ); hStmt->pszQuery = NULL; /************************ * generate a result set listing columns (these will be our rows) ************************/ pResults = msqlListFields( ((HDRVDBC)hStmt->hDbc)->hDbcExtras->hServer, szTableName ); if ( pResults == NULL ) { sprintf( hStmt->szSqlMsg, "SQL_ERROR Query failed. %s", msqlErrMsg ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } /************************ * how many columns are indexs? ************************/ nIndexColumns = 0; while ( pField = msqlFetchField( pResults ) ) { if ( pField->type == IDX_TYPE) nIndexColumns++; } msqlFieldSeek( pResults, 0 ); nNormalColumns = msqlNumFields( pResults ) - nIndexColumns; /************************** * allocate memory for columns headers and result data (row 0 is column header while col 0 is reserved for bookmarks) **************************/ hStmt->hStmtExtras->nCols = COL_MAX-1; hStmt->hStmtExtras->nRows = nIndexColumns; hStmt->hStmtExtras->nRow = 0; hStmt->hStmtExtras->aResults = malloc( sizeof(char*) * (hStmt->hStmtExtras->nRows+1) * (hStmt->hStmtExtras->nCols+1) ); memset( hStmt->hStmtExtras->aResults, 0, sizeof(char*) * (hStmt->hStmtExtras->nRows+1) * (hStmt->hStmtExtras->nCols+1) ); if ( hStmt->hStmtExtras->aResults == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "Not enough memory. (malloc failed)" ); hStmt->hStmtExtras->nRows = 0; hStmt->hStmtExtras->nCols = 0; msqlFreeResult( pResults ); return SQL_ERROR; } /************************** * gather column header information (save col 0 for bookmarks) **************************/ for ( nColumn = 1; nColumn < COL_MAX; nColumn++ ) { (hStmt->hStmtExtras->aResults)[nColumn] = malloc( sizeof(COLUMNHDR) ); pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nColumn]; memset( pColumnHeader, 0, sizeof(COLUMNHDR) ); _NativeToSQLColumnHeader( pColumnHeader, &(aSQLStatistics[nColumn]) ); } /************************ * gather data (save col 0 for bookmarks and factor out normal columns) ************************/ nCols = hStmt->hStmtExtras->nCols; hStmt->hStmtExtras->nRow = 0; for ( nCurRow = 1; nCurRow <= msqlNumFields( pResults ); nCurRow++ ) { pField = msqlFetchField( pResults ); if ( pField->type == IDX_TYPE) { hStmt->hStmtExtras->nRow++; nRow = hStmt->hStmtExtras->nRow; for ( nColumn = 1; nColumn < COL_MAX; nColumn++ ) { switch ( nColumn ) { case TABLE_NAME: (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = (char*)strdup( szTableName ); break; case INDEX_NAME: (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = (char*)strdup( pField->name ); break; case NON_UNIQUE: (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = (char *)strdup( IS_NOT_NULL( pField->flags ) ? "0" : "1" ); break; default: (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = NULL; } /* switch nColumn */ } /* for nColumn */ } /* if */ } /* for nRow */ hStmt->hStmtExtras->nRow = 0; /************************** * free the snapshot **************************/ msqlFreeResult( pResults ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLTablePrivileges.c000066400000000000000000000026111446441710500217170ustar00rootroot00000000000000/******************************************************************** * SQLTablePrivileges * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLTablePrivileges( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/SQLTables.c000066400000000000000000000107731446441710500200600ustar00rootroot00000000000000/********************************************************************** * SQLTables * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" enum nSQLTables { TABLE_CAT = 1, TABLE_SCHEM, TABLE_NAME, TABLE_TYPE, REMARKS, COL_MAX }; m_field aSQLTables[] = { "", "", 0, 0, 0, /* keep things 1 based */ "TABLE_CAT", "sys", CHAR_TYPE, 50, 0, "TABLE_SCHEM", "sys", CHAR_TYPE, 50, 0, "TABLE_NAME", "sys", CHAR_TYPE, 50, 0, "TABLE_TYPE", "sys", CHAR_TYPE, 50, 0, "REMARKS", "sys", CHAR_TYPE, 50, 0 }; SQLRETURN SQLTables( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength, SQLCHAR *szTableType, SQLSMALLINT nTableTypeLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; m_result *pResults; /* mSQL DATA */ m_field *pField; /* mSQL field */ COLUMNHDR *pColumnHeader; m_row rowResult; /* mSQL ROW */ int nColumn; long nResultMemory; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /************************** * close any existing result **************************/ if ( hStmt->hStmtExtras->aResults ) _FreeResults( hStmt->hStmtExtras ); if ( hStmt->pszQuery != NULL ) free( hStmt->pszQuery ); hStmt->pszQuery = NULL; /************************ * generate a result set listing tables ************************/ pResults = msqlListTables( ((HDRVDBC)hStmt->hDbc)->hDbcExtras->hServer ); if ( pResults == NULL ) { sprintf( hStmt->szSqlMsg, "SQL_ERROR Query failed. %s", msqlErrMsg ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } /************************** * allocate memory for columns headers and result data (row 0 is column header while col 0 is reserved for bookmarks) **************************/ hStmt->hStmtExtras->nCols = COL_MAX-1; hStmt->hStmtExtras->nRows = msqlNumRows( pResults ); hStmt->hStmtExtras->nRow = 0; nResultMemory = sizeof(char*) * (hStmt->hStmtExtras->nRows+1) * (hStmt->hStmtExtras->nCols+1); hStmt->hStmtExtras->aResults = malloc( nResultMemory ); if ( hStmt->hStmtExtras->aResults == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "Not enough memory. (malloc failed)" ); hStmt->hStmtExtras->nRows = 0; hStmt->hStmtExtras->nCols = 0; msqlFreeResult( pResults ); return SQL_ERROR; } /************************** * gather column header information (save col 0 for bookmarks) **************************/ for ( nColumn = 1; nColumn < COL_MAX; nColumn++ ) { (hStmt->hStmtExtras->aResults)[nColumn] = malloc( sizeof(COLUMNHDR) ); pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nColumn]; memset( pColumnHeader, 0, sizeof(COLUMNHDR) ); _NativeToSQLColumnHeader( pColumnHeader, &(aSQLTables[nColumn]) ); } /************************ * gather data (save col 0 for bookmarks) ************************/ hStmt->hStmtExtras->nRow = 0; while ( (rowResult = msqlFetchRow( pResults )) != NULL ) { hStmt->hStmtExtras->nRow++; msqlFieldSeek( pResults, 0 ); for ( nColumn = 1; nColumn <= hStmt->hStmtExtras->nCols; nColumn++ ) { switch ( nColumn ) { case TABLE_NAME: (hStmt->hStmtExtras->aResults)[hStmt->hStmtExtras->nRow*hStmt->hStmtExtras->nCols+nColumn] = (char *)strdup( rowResult[0] ); break; default: (hStmt->hStmtExtras->aResults)[hStmt->hStmtExtras->nRow*hStmt->hStmtExtras->nCols+nColumn] = NULL; } } } hStmt->hStmtExtras->nRow = 0; /************************** * free the snapshot **************************/ msqlFreeResult( pResults ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/SQLTransact.c000066400000000000000000000025231446441710500204170ustar00rootroot00000000000000/******************************************************************** * SQLTransact (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLTransact( SQLHENV hDrvEnv, SQLHDBC hDrvDbc, UWORD nType) { HDRVENV hEnv = (HDRVENV)hDrvEnv; HDRVDBC hDbc = (HDRVDBC)hDrvDbc; /* SANITY CHECKS */ if ( hEnv == SQL_NULL_HENV ) return SQL_INVALID_HANDLE; sprintf( hEnv->szSqlMsg, "hEnv = $%08lX", hEnv ); logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hEnv->szSqlMsg ); switch ( nType ) { case SQL_COMMIT: break; case SQL_ROLLBACK: break; default: sprintf( hEnv->szSqlMsg, "SQL_ERROR Invalid nType=%d", nType ); logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hEnv->szSqlMsg ); return SQL_ERROR; } logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/MiniSQL/_AllocConnect.c000066400000000000000000000052041446441710500207620ustar00rootroot00000000000000/************************************************** * _AllocConnect * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" SQLRETURN _AllocConnect( SQLHENV hDrvEnv, SQLHDBC *phDrvDbc ) { HDRVENV hEnv = (HDRVENV)hDrvEnv; HDRVDBC *phDbc = (HDRVDBC*)phDrvDbc; /************************ * SANITY CHECKS ************************/ if( SQL_NULL_HENV == hEnv ) return SQL_INVALID_HANDLE; sprintf( hEnv->szSqlMsg, "hEnv = $%08lX phDbc = $%08lX", hEnv, phDbc ); logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hEnv->szSqlMsg ); if( SQL_NULL_HDBC == phDbc ) { logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR *phDbc is NULL" ); return SQL_ERROR; } /************************ * OK LETS DO IT ************************/ /* allocate database access structure */ *phDbc = (HDRVDBC)malloc( sizeof(DRVDBC) ); if( SQL_NULL_HDBC == *phDbc ) { *phDbc = SQL_NULL_HDBC; logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR malloc error" ); return SQL_ERROR; } /* initialize structure */ memset( *phDbc, 0, sizeof(DRVDBC) ); (*phDbc)->bConnected = 0; (*phDbc)->hDbcExtras = NULL; (*phDbc)->hFirstStmt = NULL; (*phDbc)->hLastStmt = NULL; (*phDbc)->pNext = NULL; (*phDbc)->pPrev = NULL; (*phDbc)->hEnv = (SQLPOINTER)hEnv; /* start logging */ if ( !logOpen( &(*phDbc)->hLog, SQL_DRIVER_NAME, NULL, 50 ) ) (*phDbc)->hLog = NULL; logOn( (*phDbc)->hLog, 1 ); /* ADD TO END OF LIST */ if ( hEnv->hFirstDbc == NULL ) { /* 1st is null so the list is empty right now */ hEnv->hFirstDbc = (*phDbc); hEnv->hLastDbc = (*phDbc); } else { /* at least one node in list */ hEnv->hLastDbc->pNext = (SQLPOINTER)(*phDbc); (*phDbc)->pPrev = (SQLPOINTER)hEnv->hLastDbc; hEnv->hLastDbc = (*phDbc); } /********************************************************/ /* ALLOCATE AND INIT EXTRAS HERE */ (*phDbc)->hDbcExtras = malloc( sizeof(DBCEXTRAS) ); (*phDbc)->hDbcExtras->hServer = -1; /********************************************************/ logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_AllocEnv.c000066400000000000000000000027061446441710500201250ustar00rootroot00000000000000/********************************************************************** * _AllocEnv * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN _AllocEnv( SQLHENV *phDrvEnv ) { HDRVENV *phEnv = (HDRVENV*)phDrvEnv; /* SANITY CHECKS */ if( NULL == phEnv ) return SQL_INVALID_HANDLE; /* OK */ /* allocate environment */ *phEnv = malloc( sizeof(DRVENV) ); if( SQL_NULL_HENV == *phEnv ) { *phEnv = SQL_NULL_HENV; return SQL_ERROR; } /* initialise environment */ memset( *phEnv, 0, sizeof(DRVENV) ); (*phEnv)->hFirstDbc = NULL; (*phEnv)->hLastDbc = NULL; (*phEnv)->hLog = NULL; /* start logging */ if ( !logOpen( &(*phEnv)->hLog, SQL_DRIVER_NAME, NULL, 50 ) ) (*phEnv)->hLog = NULL; logOn( (*phEnv)->hLog, 1 ); /* ALLOCATE AND INIT DRIVER SPECIFIC STORAGE */ (*phEnv)->hEnvExtras = malloc(sizeof(ENVEXTRAS)); (*phEnv)->hEnvExtras->nDummy = -1; logPushMsg( (*phEnv)->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_AllocStmt.c000066400000000000000000000065061446441710500203260ustar00rootroot00000000000000/********************************************************************** * _AllocStmt (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN _AllocStmt( SQLHDBC hDrvDbc, SQLHSTMT *phDrvStmt ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; HDRVSTMT *phStmt = (HDRVSTMT*)phDrvStmt; /* SANITY CHECKS */ if( hDbc == SQL_NULL_HDBC ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } sprintf( hDbc->szSqlMsg, "hDbc = $%08lX", hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); if( NULL == phStmt ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR phStmt=NULL" ); return SQL_ERROR; } /* OK */ /* allocate memory */ *phStmt = malloc( sizeof(DRVSTMT) ); if( SQL_NULL_HSTMT == *phStmt ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR memory allocation failure" ); return SQL_ERROR; } /* initialize memory */ sprintf( hDbc->szSqlMsg, "*phstmt = $%08lX", *phStmt ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); memset( *phStmt, 0, sizeof(DRVSTMT) ); /* SAFETY */ (*phStmt)->hDbc = (SQLPOINTER)hDbc; (*phStmt)->hLog = NULL; (*phStmt)->hStmtExtras = NULL; (*phStmt)->pNext = NULL; (*phStmt)->pPrev = NULL; (*phStmt)->pszQuery = NULL; sprintf( (*phStmt)->szCursorName, "CUR_%08lX", *phStmt ); /* ADD TO DBCs STATEMENT LIST */ /* start logging */ if ( logOpen( &(*phStmt)->hLog, SQL_DRIVER_NAME, NULL, 50 ) ) { logOn( (*phStmt)->hLog, 1 ); logPushMsg( (*phStmt)->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "Statement logging allocated ok" ); } else (*phStmt)->hLog = NULL; /* ADD TO END OF LIST */ if ( hDbc->hFirstStmt == NULL ) { /* 1st is null so the list is empty right now */ hDbc->hFirstStmt = (*phStmt); hDbc->hLastStmt = (*phStmt); } else { /* at least one node in list */ hDbc->hLastStmt->pNext = (SQLPOINTER)(*phStmt); (*phStmt)->pPrev = (SQLPOINTER)hDbc->hLastStmt; hDbc->hLastStmt = (*phStmt); } /****************************************************************************/ /* ALLOCATE AND INIT DRIVER EXTRAS HERE */ (*phStmt)->hStmtExtras = malloc(sizeof(STMTEXTRAS)); memset( (*phStmt)->hStmtExtras, 0, sizeof(STMTEXTRAS) ); /* SAFETY */ (*phStmt)->hStmtExtras->aResults = NULL; (*phStmt)->hStmtExtras->nCols = 0; (*phStmt)->hStmtExtras->nRow = 0; (*phStmt)->hStmtExtras->nRows = 0; /****************************************************************************/ logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_Execute.c000066400000000000000000000102071446441710500200170ustar00rootroot00000000000000/********************************************************************** * SQLExecute * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN _Execute( SQLHSTMT hDrvStmt ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; int nColumn; int nCols; int nRow; m_result *pResults; /* mSQL DATA */ m_row rowResult; /* mSQL ROW */ m_field *pField; /* mSQL COL HDR */ COLUMNHDR *pColumnHeader; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); if( hStmt->pszQuery == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No prepared statement" ); return SQL_ERROR; } /************************** * Free any current results **************************/ if ( hStmt->hStmtExtras->aResults ) _FreeResults( hStmt->hStmtExtras ); /************************** * send prepared query to server **************************/ if ( (hStmt->hStmtExtras->nRows = msqlQuery( ((HDRVDBC)hStmt->hDbc)->hDbcExtras->hServer, hStmt->pszQuery )) == -1 ) { sprintf( hStmt->szSqlMsg, "SQL_ERROR Query failed. %s", msqlErrMsg ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } /************************** * snapshot our results (assume no results means UPDATE, DELETE or INSERT **************************/ pResults = msqlStoreResult(); if ( !pResults ) return SQL_SUCCESS; /************************** * allocate memory for columns headers and result data (row 0 is column header while col 0 is reserved for bookmarks) **************************/ hStmt->hStmtExtras->nRows = msqlNumRows( pResults ); hStmt->hStmtExtras->nCols = msqlNumFields( pResults ); hStmt->hStmtExtras->aResults = malloc( sizeof(char*) * (hStmt->hStmtExtras->nRows+1) * (hStmt->hStmtExtras->nCols+1) ); if ( hStmt->hStmtExtras->aResults == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "Not enough memory. (malloc failed)" ); hStmt->hStmtExtras->nRows = 0; hStmt->hStmtExtras->nCols = 0; msqlFreeResult( pResults ); return SQL_ERROR; } memset( hStmt->hStmtExtras->aResults, 0, sizeof(char*) * (hStmt->hStmtExtras->nRows+1) * (hStmt->hStmtExtras->nCols+1) ); /************************** * gather column header information (save col 0 for bookmarks) **************************/ for ( nColumn = 1; nColumn <= hStmt->hStmtExtras->nCols; nColumn++ ) { pField = msqlFetchField( pResults ); (hStmt->hStmtExtras->aResults)[nColumn] = malloc( sizeof(COLUMNHDR) ); memset( (hStmt->hStmtExtras->aResults)[nColumn], 0, sizeof(COLUMNHDR) ); pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nColumn]; _NativeToSQLColumnHeader( pColumnHeader, pField ); } /************************ * gather data (save col 0 for bookmarks) ************************/ nCols = hStmt->hStmtExtras->nCols; nRow = 0; while ( (rowResult = msqlFetchRow( pResults )) != NULL ) { nRow++; msqlFieldSeek( pResults, 0 ); for ( nColumn=1; nColumn <= nCols; nColumn++ ) { if ( rowResult[nColumn-1] ) (hStmt->hStmtExtras->aResults)[nRow*nCols+nColumn] = (char *)strdup( rowResult[nColumn-1] ); } } hStmt->hStmtExtras->nRow = 0; /************************** * free the snapshot **************************/ msqlFreeResult( pResults ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_FreeDbc.c000066400000000000000000000032241446441710500177100ustar00rootroot00000000000000/************************************************** * _FreeDbc * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" SQLRETURN _FreeDbc( SQLHDBC hDrvDbc ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; HDRVDBC hPrevDbc; SQLRETURN nReturn; if ( hDbc == SQL_NULL_HDBC ) return SQL_ERROR; /* TRY TO FREE STATEMENTS */ /* THIS IS JUST IN CASE; SHOULD NOT BE REQUIRED */ nReturn = _FreeStmtList( hDbc ); if ( nReturn != SQL_SUCCESS ) return nReturn; /* SPECIAL CHECK FOR FIRST IN LIST */ if ( ((HDRVENV)hDbc->hEnv)->hFirstDbc == hDbc ) ((HDRVENV)hDbc->hEnv)->hFirstDbc = hDbc->pNext; /* SPECIAL CHECK FOR LAST IN LIST */ if ( ((HDRVENV)hDbc->hEnv)->hLastDbc == hDbc ) ((HDRVENV)hDbc->hEnv)->hLastDbc = hDbc->pPrev; /* EXTRACT SELF FROM LIST */ if ( hDbc->pPrev != SQL_NULL_HDBC ) hDbc->pPrev->pNext = hDbc->pNext; if ( hDbc->pNext != SQL_NULL_HDBC ) hDbc->pNext->pPrev = hDbc->pPrev; /**********************************************/ /* !!! CODE TO FREE DRIVER SPECIFIC MEMORY (hidden in hStmtExtras) HERE !!! */ if ( hDbc->hDbcExtras->hServer > -1 ) msqlClose( hDbc->hDbcExtras->hServer ); free( hDbc->hDbcExtras ); /**********************************************/ logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); logClose( hDbc->hLog ); free( hDbc ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_FreeDbcList.c000066400000000000000000000012111446441710500205360ustar00rootroot00000000000000/************************************************** * _FreeDbcList * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" SQLRETURN _FreeDbcList( SQLHENV hDrvEnv ) { HDRVENV hEnv = (HDRVENV)hDrvEnv; if ( hEnv == SQL_NULL_HENV ) return SQL_SUCCESS; while ( _FreeDbc( hEnv->hFirstDbc ) == SQL_SUCCESS ) { } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_FreeResults.c000066400000000000000000000034061446441710500206630ustar00rootroot00000000000000/************************************************** * _FreeResults * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" SQLRETURN _FreeResults( HSTMTEXTRAS hStmt ) { COLUMNHDR *pColumnHeader; int nCurColumn; if ( hStmt == NULL ) return SQL_ERROR; if ( hStmt->aResults == NULL ) return SQL_SUCCESS; /* COLUMN HDRS (col=0 is not used) */ for ( nCurColumn = 1; nCurColumn <= hStmt->nCols; nCurColumn++ ) { pColumnHeader = (COLUMNHDR*)(hStmt->aResults)[nCurColumn]; free( pColumnHeader->pszSQL_DESC_BASE_COLUMN_NAME ); free( pColumnHeader->pszSQL_DESC_BASE_TABLE_NAME ); free( pColumnHeader->pszSQL_DESC_CATALOG_NAME ); free( pColumnHeader->pszSQL_DESC_LABEL ); free( pColumnHeader->pszSQL_DESC_LITERAL_PREFIX ); free( pColumnHeader->pszSQL_DESC_LITERAL_SUFFIX ); free( pColumnHeader->pszSQL_DESC_LOCAL_TYPE_NAME ); free( pColumnHeader->pszSQL_DESC_NAME ); free( pColumnHeader->pszSQL_DESC_SCHEMA_NAME ); free( pColumnHeader->pszSQL_DESC_TABLE_NAME ); free( pColumnHeader->pszSQL_DESC_TYPE_NAME ); free( (hStmt->aResults)[nCurColumn] ); } /* RESULT DATA (col=0 is bookmark) */ for ( hStmt->nRow = 1; hStmt->nRow <= hStmt->nRows; hStmt->nRow++ ) { for ( nCurColumn = 1; nCurColumn <= hStmt->nCols; nCurColumn++ ) { free( (hStmt->aResults)[hStmt->nRow*hStmt->nCols+nCurColumn] ); } } free( hStmt->aResults ); hStmt->aResults = NULL; hStmt->nCols = 0; hStmt->nRows = 0; hStmt->nRow = 0; return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_FreeStmt.c000066400000000000000000000031251446441710500201470ustar00rootroot00000000000000/************************************************** * _FreeStmt * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" SQLRETURN _FreeStmt( SQLHSTMT hDrvStmt ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; HDRVSTMT hPrevStmt; SQLRETURN nReturn; if ( hStmt == SQL_NULL_HDBC ) return SQL_ERROR; /* SPECIAL CHECK FOR FIRST IN LIST */ if ( ((HDRVDBC)hStmt->hDbc)->hFirstStmt == hStmt ) ((HDRVDBC)hStmt->hDbc)->hFirstStmt = hStmt->pNext; /* SPECIAL CHECK FOR LAST IN LIST */ if ( ((HDRVDBC)hStmt->hDbc)->hLastStmt == hStmt ) ((HDRVDBC)hStmt->hDbc)->hLastStmt = hStmt->pPrev; /* EXTRACT SELF FROM LIST */ if ( hStmt->pPrev != SQL_NULL_HSTMT ) hStmt->pPrev->pNext = hStmt->pNext; if ( hStmt->pNext != SQL_NULL_HSTMT ) hStmt->pNext->pPrev = hStmt->pPrev; /* FREE STANDARD MEMORY */ if( NULL != hStmt->pszQuery ) free( hStmt->pszQuery ); /*********************************************************************/ /* !!! FREE DRIVER SPECIFIC MEMORY (hidden in hStmtExtras) HERE !!! */ _FreeResults( hStmt->hStmtExtras ); free( hStmt->hStmtExtras ); /*********************************************************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); logClose( hStmt->hLog ); free( hStmt ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_FreeStmtList.c000066400000000000000000000013061446441710500210020ustar00rootroot00000000000000/************************************************** * _FreeStmtList * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" SQLRETURN _FreeStmtList( SQLHDBC hDrvDbc ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; if ( hDbc == SQL_NULL_HDBC ) return SQL_SUCCESS; if ( hDbc->hFirstStmt == NULL ) return SQL_SUCCESS; while ( _FreeStmt( hDbc->hFirstStmt ) == SQL_SUCCESS ) { } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_GetData.c000066400000000000000000000064401446441710500177320ustar00rootroot00000000000000/************************************************** * _GetData * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" SQLRETURN _GetData( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLSMALLINT nTargetType, /* C DATA TYPE */ SQLPOINTER pTarget, SQLINTEGER nTargetLength, SQLINTEGER *pnLengthOrIndicator ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; char *pSourceData = NULL; /* SANITY CHECKS */ if ( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; if ( hStmt->hStmtExtras == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; if ( hStmt->hStmtExtras->nRows == 0 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No result set." ); return SQL_ERROR; } /********************************************************************** * GET pSourceData FOR NORMAL RESULT SETS **********************************************************************/ if ( hStmt->hStmtExtras->nRow > hStmt->hStmtExtras->nRows || hStmt->hStmtExtras->nRow < 1 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No current row" ); return SQL_ERROR; } pSourceData = (hStmt->hStmtExtras->aResults)[hStmt->hStmtExtras->nRow*hStmt->hStmtExtras->nCols+nCol]; /**************************** * ALL cols are stored as SQL_CHAR... bad for storage... good for code * SO no need to determine the source type when translating to destination ***************************/ if ( pSourceData == NULL ) { /********************* * Now get the col if value = NULL *********************/ if ( pnLengthOrIndicator != NULL ) *pnLengthOrIndicator = SQL_NULL_DATA; switch ( nTargetType ) { case SQL_C_LONG: memset( pTarget, 0, sizeof(int) ); break; case SQL_C_FLOAT: memset( pTarget, 0, sizeof(float) ); break; case SQL_C_CHAR: *((char *)pTarget) = '\0'; break; default: sprintf( hStmt->szSqlMsg, "SQL_ERROR Unknown target type %d", nTargetType ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); } } else { /********************* * Now get the col when we have a value *********************/ switch ( nTargetType ) { case SQL_C_LONG: *((int *)pTarget) = atoi(pSourceData); if ( NULL != pnLengthOrIndicator ) *pnLengthOrIndicator = sizeof( int ); break; case SQL_C_FLOAT: sscanf( pSourceData, "%g", pTarget ); if ( NULL != pnLengthOrIndicator ) *pnLengthOrIndicator = sizeof( float ); break; case SQL_C_CHAR: strncpy( pTarget, pSourceData, nTargetLength ); if ( NULL != pnLengthOrIndicator ) *pnLengthOrIndicator = strlen(pTarget); break; default: sprintf( hStmt->szSqlMsg, "SQL_ERROR Unknown target type %d", nTargetType ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); } } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_NativeToSQLColumnHeader.c000066400000000000000000000072541446441710500230250ustar00rootroot00000000000000/************************************************** * _NativeToSQLColumnHeader * * We want to make the driver code as general as possible. This isolates * the translation from the native client to the SQL format for column * header information. ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" SQLRETURN _NativeToSQLColumnHeader( COLUMNHDR *pColumnHeader, void *pNativeColumnHeader ) { m_field *pField = (m_field*)pNativeColumnHeader; char szBuffer[501]; if ( !pNativeColumnHeader ) return SQL_ERROR; if ( !pColumnHeader ) return SQL_ERROR; /* IS AUTO INCREMENT COL? */ pColumnHeader->bSQL_DESC_AUTO_UNIQUE_VALUE = 0; /* empty string if N/A */ pColumnHeader->pszSQL_DESC_BASE_COLUMN_NAME = (char*)strdup( pField->name ); /* empty string if N/A */ pColumnHeader->pszSQL_DESC_BASE_TABLE_NAME = pField->table ? (char*)strdup( pField->table ) : (char*)strdup( "" ); /* IS CASE SENSITIVE COLUMN? */ pColumnHeader->bSQL_DESC_CASE_SENSITIVE = 0; /* empty string if N/A */ pColumnHeader->pszSQL_DESC_CATALOG_NAME = (char*)strdup( "" ); /* ie SQL_CHAR, SQL_TYPE_TIME... */ pColumnHeader->nSQL_DESC_CONCISE_TYPE = _NativeToSQLType( pField ); /* max digits required to display */ pColumnHeader->nSQL_DESC_DISPLAY_SIZE = pField->length; /* has data source specific precision? */ pColumnHeader->bSQL_DESC_FIXED_PREC_SCALE = 0; /* display label, col name or empty string */ pColumnHeader->pszSQL_DESC_LABEL = (char*)strdup( pField->name ); /* strlen or bin size */ pColumnHeader->nSQL_DESC_LENGTH = _NativeTypeLength( pField ); /* empty string if N/A */ pColumnHeader->pszSQL_DESC_LITERAL_PREFIX = (char*)strdup( "" ); /* empty string if N/A */ pColumnHeader->pszSQL_DESC_LITERAL_SUFFIX = (char*)strdup( "" ); /* empty string if N/A */ pColumnHeader->pszSQL_DESC_LOCAL_TYPE_NAME = (char*)strdup( "" ); /* col alias, col name or empty string */ pColumnHeader->pszSQL_DESC_NAME = (char*)strdup( pField->name ); /* SQL_NULLABLE, _NO_NULLS or _UNKNOWN */ pColumnHeader->nSQL_DESC_NULLABLE = IS_NOT_NULL( pField->flags ) ? SQL_NO_NULLS : SQL_NULLABLE; /* 2, 10, or if N/A... 0 */ pColumnHeader->nSQL_DESC_NUM_PREC_RADIX = 0; /* max size */ pColumnHeader->nSQL_DESC_OCTET_LENGTH = pField->length; /* */ pColumnHeader->nSQL_DESC_PRECISION = _NativeTypePrecision( pField ); /* */ pColumnHeader->nSQL_DESC_SCALE = 4; /* empty string if N/A */ pColumnHeader->pszSQL_DESC_SCHEMA_NAME = (char*)strdup( "" ); /* can be in a filter ie SQL_PRED_NONE... */ pColumnHeader->nSQL_DESC_SEARCHABLE = SQL_PRED_SEARCHABLE; /* empty string if N/A */ pColumnHeader->pszSQL_DESC_TABLE_NAME = pField->table ? (char*)strdup( pField->table ) : (char*)strdup( "" ); /* SQL data type ie SQL_CHAR, SQL_INTEGER.. */ pColumnHeader->nSQL_DESC_TYPE = _NativeToSQLType( pField ); /* DBMS data type ie VARCHAR, MONEY... */ pColumnHeader->pszSQL_DESC_TYPE_NAME = (char*)strdup( _NativeTypeDesc( szBuffer, pField->type ) ); /* qualifier for SQL_DESC_NAME ie SQL_NAMED */ pColumnHeader->nSQL_DESC_UNNAMED = SQL_NAMED; /* if signed FALSE else TRUE */ pColumnHeader->bSQL_DESC_UNSIGNED = 0; /* ie SQL_ATTR_READONLY, SQL_ATTR_WRITE... */ pColumnHeader->nSQL_DESC_UPDATABLE = SQL_ATTR_READONLY; return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_NativeToSQLType.c000066400000000000000000000017711446441710500213760ustar00rootroot00000000000000/************************************************** * _NativeToSQLType * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" int _NativeToSQLType( void *pNativeColumnHeader ) { m_field *pField = (m_field*)pNativeColumnHeader; switch ( pField->type ) { case MONEY_TYPE: return SQL_REAL; case INT_TYPE: return SQL_INTEGER; case UINT_TYPE: return SQL_INTEGER; case TIME_TYPE: return SQL_CHAR; case DATE_TYPE: return SQL_CHAR; case REAL_TYPE: return SQL_REAL; case CHAR_TYPE: return SQL_CHAR; case TEXT_TYPE: return SQL_CHAR; case IDENT_TYPE: return SQL_CHAR; default: return SQL_UNKNOWN_TYPE; } return SQL_CHAR; } unixODBC-2.3.12/Drivers/MiniSQL/_NativeTypeDesc.c000066400000000000000000000011111446441710500212760ustar00rootroot00000000000000/************************************************** * _NativeTypeDesc * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" char *_NativeTypeDesc( char *pszTypeName, int nMiniSQLType ) { sprintf( pszTypeName, "%s", msqlTypeNames[nMiniSQLType] ); return pszTypeName; } unixODBC-2.3.12/Drivers/MiniSQL/_NativeTypeLength.c000066400000000000000000000021541446441710500216510ustar00rootroot00000000000000/************************************************** * _NativeTypeLength * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" int _NativeTypeLength( void *pNativeColumnHeader ) { m_field *pField = (m_field*)pNativeColumnHeader; int nLength; /**************************** * DEFAULT ***************************/ nLength = pField->length; /**************************** * NON-DEFAULT ***************************/ switch ( pField->type ) { case MONEY_TYPE: return 16; case INT_TYPE: return 5; case UINT_TYPE: return 5; case TIME_TYPE: return nLength; case DATE_TYPE: return nLength; case REAL_TYPE: return nLength; case CHAR_TYPE: return nLength; case TEXT_TYPE: return nLength; case IDENT_TYPE: return nLength; default: return nLength; } return nLength; } unixODBC-2.3.12/Drivers/MiniSQL/_NativeTypePrecision.c000066400000000000000000000007761446441710500223730ustar00rootroot00000000000000/************************************************** * _NativeTypePrecision * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" int _NativeTypePrecision( void *pNativeColumnHeader ) { return 4; } unixODBC-2.3.12/Drivers/MiniSQL/_Prepare.c000066400000000000000000000032771446441710500200240ustar00rootroot00000000000000/********************************************************************** * SQLPrepare * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN _Prepare( SQLHSTMT hDrvStmt, SQLCHAR *szSqlStr, SQLINTEGER nSqlStrLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); if ( szSqlStr == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No SQL to process" ); return SQL_ERROR; } if ( hStmt->pszQuery != NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Statement already in use." ); return SQL_ERROR; } /* allocate and copy statement to buffer (process escape sequences and parameter tokens as required) */ hStmt->pszQuery = (char *)strdup( szSqlStr ); if ( NULL == hStmt->pszQuery ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Memory allocation error" ); return SQL_ERROR; } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_sqlFreeConnect.c000066400000000000000000000026471446441710500213410ustar00rootroot00000000000000/********************************************************************** * sqlFreeConnect * * Do not try to Free Dbc if there are Stmts... return an error. Let the * Driver Manager do a recursive clean up if it wants. * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN sqlFreeConnect( SQLHDBC hDrvDbc ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; int nReturn; /* SANITY CHECKS */ if( NULL == hDbc ) return SQL_INVALID_HANDLE; sprintf( hDbc->szSqlMsg, "hDbc = $%08lX", hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hDbc->szSqlMsg ); if( hDbc->hDbcExtras->hServer > -1 ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Connection is active" ); return SQL_ERROR; } if ( hDbc->hFirstStmt != NULL ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Connection has allocated statements" ); return SQL_ERROR; } nReturn = _FreeDbc( hDbc ); return nReturn; } unixODBC-2.3.12/Drivers/MiniSQL/_sqlFreeEnv.c000066400000000000000000000027131446441710500204720ustar00rootroot00000000000000/********************************************************************** * sqlFreeEnv * * Do not try to Free Env if there are Dbcs... return an error. Let the * Driver Manager do a recursive clean up if it wants. * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN sqlFreeEnv( SQLHENV hDrvEnv ) { HDRVENV hEnv = (HDRVENV)hDrvEnv; /* SANITY CHECKS */ if( hEnv == SQL_NULL_HENV ) return SQL_INVALID_HANDLE; sprintf( hEnv->szSqlMsg, "hEnv = $%08lX", hEnv ); logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hEnv->szSqlMsg ); if ( hEnv->hFirstDbc != NULL ) { logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR There are allocated Connections" ); return SQL_ERROR; } /************ * !!! ADD CODE TO FREE DRIVER SPECIFIC MEMORY (hidden in hEnvExtras) HERE !!! ************/ free( hEnv->hEnvExtras ); logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); logClose( hEnv->hLog ); free( hEnv ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/_sqlFreeStmt.c000066400000000000000000000025701446441710500206720ustar00rootroot00000000000000/********************************************************************** * sqlFreeStmt * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN sqlFreeStmt( SQLHSTMT hDrvStmt, SQLUSMALLINT nOption ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf( hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); /********* * RESET PARAMS *********/ switch( nOption ) { case SQL_CLOSE: break; case SQL_DROP: return _FreeStmt( hStmt ); case SQL_UNBIND: break; case SQL_RESET_PARAMS: break; default: sprintf( hStmt->szSqlMsg, "SQL_ERROR Invalid nOption=%d", nOption ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, hStmt->szSqlMsg ); return SQL_ERROR; } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/MiniSQL/driver.h000066400000000000000000000061541446441710500175640ustar00rootroot00000000000000/********************************************** * Driver.h * * Description: * * This is all of the stuff that is common among ALL drivers (but not to the DriverManager). * * Make sure that your driver specific driverextras.h exists! * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************/ #ifndef _H_DRIVER #define _H_DRIVER /***************************************************************************** * ODBC VERSION (THAT THIS DRIVER COMPLIES WITH) *****************************************************************************/ #define ODBCVER 0x0351 /* this is optimistic to say the least but we are heading to full 3.51 compliance */ #include #include #include #include #include "driverextras.h" #define SQL_MAX_CURSOR_NAME 100 /***************************************************************************** * STATEMENT *****************************************************************************/ typedef struct tDRVSTMT { struct tDRVSTMT *pPrev; /* prev struct or null */ struct tDRVSTMT *pNext; /* next struct or null */ SQLPOINTER hDbc; /* pointer to DB context */ SQLCHAR szCursorName[SQL_MAX_CURSOR_NAME]; /* name of cursor */ SQLCHAR *pszQuery; /* query string */ SQLCHAR szSqlMsg[LOG_MSG_MAX]; /* buff to format msgs */ HLOG hLog; /* handle to msg logs */ HSTMTEXTRAS hStmtExtras; /* DRIVER SPECIFIC STORAGE */ } DRVSTMT, *HDRVSTMT; /***************************************************************************** * CONNECTION *****************************************************************************/ typedef struct tDRVDBC { struct tDRVDBC *pPrev; /* prev struct or null */ struct tDRVDBC *pNext; /* next struct or null */ SQLPOINTER hEnv; /* pointer to ENV structure */ HDRVSTMT hFirstStmt; /* first in list or null */ HDRVSTMT hLastStmt; /* last in list or null */ SQLCHAR szSqlMsg[LOG_MSG_MAX]; /* buff to format msgs */ HLOG hLog; /* handle to msg logs */ int bConnected; /* TRUE on open connection */ HDBCEXTRAS hDbcExtras; /* DRIVER SPECIFIC DATA */ } DRVDBC, *HDRVDBC; /***************************************************************************** * ENVIRONMENT *****************************************************************************/ typedef struct tDRVENV { HDRVDBC hFirstDbc; /* first in list or null */ HDRVDBC hLastDbc; /* last in list or null */ SQLCHAR szSqlMsg[LOG_MSG_MAX]; /* buff to format msgs */ HLOG hLog; /* handle to msg logs */ HENVEXTRAS hEnvExtras; } DRVENV, *HDRVENV; #endif unixODBC-2.3.12/Drivers/MiniSQL/driverextras.h000066400000000000000000000142041446441710500210060ustar00rootroot00000000000000/********************************************** * driverextras.h * * Purpose: * * To define driver specifc extras such as structs to be included * along side the common ODBC includes. * * Description: * * The short-term storage a driver requires as infrastructure varies somewhat from * DBMS to DBMS. The ODBC DriverManager requires predictable storage and it is defined * in include files such as hstmt.h. The Driver also requires predictable storage and * it is defined in driver.h. Storage *specific to a type of driver* is defined here. * * The three main storage items are the ENV, DBC, and STMT structs. These are defined * as type void * in sql.h. * * So if your driver requires extra storage (and it probably does) then define * the storage within these structs, allocate/initialize as required. Cast them * to and from the standard names as required. * * For example; * * App DM |DRV * (as per hdbc.h) |(as per driver.h) *==================================================================== * hDbc=void* hDbc=SQLHDBC hDbc=HDBCEXTRAS *-------------------------------------------------------------------- * * DO NOT FORGET TO FREE ANY ALLOCATED MEMORY (at some point) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #ifndef DRIVEREXTRAS_H #define DRIVEREXTRAS_H /********************************************** * KEEP IT SIMPLE; PUT ALL DRIVER INCLUDES HERE THEN EACH DRIVER MODULE JUST INCLUDES THIS ONE FILE **********************************************/ #include #include #include #include #include #include /********************************************** * ENVIRONMENT: DRIVER SPECIFIC STUFF THAT NEEDS TO BE STORED IN THE DRIVERS ENVIRONMENT **********************************************/ typedef struct tENVEXTRAS { int nDummy; } ENVEXTRAS, *HENVEXTRAS; /********************************************** * CONNECTION: DRIVER SPECIFIC STUFF THAT NEEDS TO BE STORED IN THE DRIVERS CONNECTIONS **********************************************/ typedef struct tDBCEXTRAS { int hServer; /* HANDLE TO mSQl SERVER (socket) */ } DBCEXTRAS, *HDBCEXTRAS; /********************************************** * STATEMENT: DRIVER SPECIFIC STUFF THAT NEEDS TO BE STORED IN THE DRIVERS STATEMENTS **********************************************/ typedef struct tCOLUMNHDR /* this is how we will store bound columns */ { /* EVERYTHING YOU WOULD EVER WANT TO KNOW ABOUT THE COLUMN. INIT THIS BY CALLING */ /* _NativeToSQLColumnHeader AS SOON AS YOU HAVE COLUMN INFO. THIS MAKES THE COL HDR LARGER */ /* BUT GENERALIZES MORE CODE. see SQLColAttribute() */ int bSQL_DESC_AUTO_UNIQUE_VALUE; /* IS AUTO INCREMENT COL? */ char *pszSQL_DESC_BASE_COLUMN_NAME; /* empty string if N/A */ char *pszSQL_DESC_BASE_TABLE_NAME; /* empty string if N/A */ int bSQL_DESC_CASE_SENSITIVE; /* IS CASE SENSITIVE COLUMN? */ char *pszSQL_DESC_CATALOG_NAME; /* empty string if N/A */ int nSQL_DESC_CONCISE_TYPE; /* ie SQL_CHAR, SQL_TYPE_TIME... */ int nSQL_DESC_DISPLAY_SIZE; /* max digits required to display */ int bSQL_DESC_FIXED_PREC_SCALE; /* has data source specific precision? */ char *pszSQL_DESC_LABEL; /* display label, col name or empty string */ int nSQL_DESC_LENGTH; /* strlen or bin size */ char *pszSQL_DESC_LITERAL_PREFIX; /* empty string if N/A */ char *pszSQL_DESC_LITERAL_SUFFIX; /* empty string if N/A */ char *pszSQL_DESC_LOCAL_TYPE_NAME; /* empty string if N/A */ char *pszSQL_DESC_NAME; /* col alias, col name or empty string */ int nSQL_DESC_NULLABLE; /* SQL_NULLABLE, _NO_NULLS or _UNKNOWN */ int nSQL_DESC_NUM_PREC_RADIX; /* 2, 10, or if N/A... 0 */ int nSQL_DESC_OCTET_LENGTH; /* max size */ int nSQL_DESC_PRECISION; /* */ int nSQL_DESC_SCALE; /* */ char *pszSQL_DESC_SCHEMA_NAME; /* empty string if N/A */ int nSQL_DESC_SEARCHABLE; /* can be in a filter ie SQL_PRED_NONE... */ char *pszSQL_DESC_TABLE_NAME; /* empty string if N/A */ int nSQL_DESC_TYPE; /* SQL data type ie SQL_CHAR, SQL_INTEGER.. */ char *pszSQL_DESC_TYPE_NAME; /* DBMS data type ie VARCHAR, MONEY... */ int nSQL_DESC_UNNAMED; /* qualifier for SQL_DESC_NAME ie SQL_NAMED */ int bSQL_DESC_UNSIGNED; /* if signed FALSE else TRUE */ int nSQL_DESC_UPDATABLE; /* ie SQL_ATTR_READONLY, SQL_ATTR_WRITE... */ /* BINDING INFO */ short nTargetType; /* BIND: C DATA TYPE ie SQL_C_CHAR */ char *pTargetValue; /* BIND: POINTER FROM APPLICATION TO COPY TO*/ long nTargetValueMax; /* BIND: MAX SPACE IN pTargetValue */ long *pnLengthOrIndicator; /* BIND: TO RETURN LENGTH OR NULL INDICATOR */ } COLUMNHDR; typedef struct tSTMTEXTRAS { char **aResults; /* nRows x nCols OF CHAR POINTERS. Row 0= ptrs to COLUMNHDR. Col 0=Bookmarks */ int nCols; /* # OF VALID COLUMNS IN aColumns */ int nRows; /* # OF ROWS IN aResults */ int nRow; /* CURRENT ROW */ } STMTEXTRAS, *HSTMTEXTRAS; /**************************** * ***************************/ SQLRETURN _GetData( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLSMALLINT nTargetType, SQLPOINTER pTarget, SQLINTEGER nTargetLength, SQLINTEGER *pnLengthOrIndicator ); SQLRETURN _NativeToSQLColumnHeader( COLUMNHDR *pColumnHeader, void *pNativeColumnHeader ); int _NativeToSQLType( void *pNativeColumnHeader ); char *_NativeTypeDesc( char *pszTypeName, int nType ); int _NativeTypeLength( void *pNativeColumnHeader ); int _NativeTypePrecision( void *pNativeColumnHeader ); #endif unixODBC-2.3.12/Drivers/Postgre7.1/000077500000000000000000000000001446441710500165075ustar00rootroot00000000000000unixODBC-2.3.12/Drivers/Postgre7.1/Makefile.am000066400000000000000000000023041446441710500205420ustar00rootroot00000000000000lib_LTLIBRARIES = libodbcpsql.la AM_CPPFLAGS = -I@top_srcdir@/include $(LTDLINCL) libodbcpsql_la_LDFLAGS = \ -version-info 2:0:0 \ -no-undefined \ $(LIBSOCKET) $(LIBNSL) \ -export-dynamic \ -export-symbols @srcdir@/driver.exp \ -module EXTRA_DIST = \ bind.h \ columninfo.h \ connection.h \ convert.h \ dlg_specific.h \ environ.h \ isql.h \ isqlext.h \ lobj.h \ md5.h \ misc.h \ pgtypes.h \ psqlodbc.h \ qresult.h \ resource.h \ socket.h \ statement.h \ tuple.h \ tuplelist.h \ notice.txt \ driver.exp libodbcpsql_la_LIBADD = \ ../../lst/liblstlc.la \ ../../log/libloglc.la \ ../../ini/libinilc.la \ ../../odbcinst/libodbcinstlc.la \ $(LIBLTDL) \ $(LIBADD_CRYPT) $(LIBADD_POW) libodbcpsql_la_DEPENDENCIES = \ ../../lst/liblstlc.la \ ../../log/libloglc.la \ ../../ini/libinilc.la \ ../../odbcinst/libodbcinstlc.la \ ../../extras/libodbcextraslc.la \ $(LTDLDEPS) libodbcpsql_la_SOURCES = \ bind.c \ columninfo.c \ connection.c \ convert.c \ dlg_specific.c \ drvconn.c \ environ.c \ execute.c \ info.c \ lobj.c \ md5.c \ misc.c \ options.c \ parse.c \ pgtypes.c \ psqlodbc.c \ qresult.c \ results.c \ socket.c \ statement.c \ tuple.c \ tuplelist.c unixODBC-2.3.12/Drivers/Postgre7.1/bind.c000066400000000000000000000304321446441710500175710ustar00rootroot00000000000000 /* Module: bind.c * * Description: This module contains routines related to binding * columns and parameters. * * Classes: BindInfoClass, ParameterInfoClass * * API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams, * SQLParamOptions(NI) * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "bind.h" #include "environ.h" #include "statement.h" #include "qresult.h" #include "pgtypes.h" #include #include #include "sql.h" #include "sqlext.h" /* Bind parameters on a statement handle */ SQLRETURN SQLBindParameter( SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType, SQLSMALLINT fCType, SQLSMALLINT fSqlType, SQLULEN cbColDef, SQLSMALLINT ibScale, SQLPOINTER rgbValue, SQLLEN cbValueMax, SQLLEN *pcbValue) { StatementClass *stmt = (StatementClass *) hstmt; static char* const func="SQLBindParameter"; mylog( "%s: entering...\n", func); if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } if(stmt->parameters_allocated < ipar) { ParameterInfoClass *old_parameters; int i, old_parameters_allocated; old_parameters = stmt->parameters; old_parameters_allocated = stmt->parameters_allocated; stmt->parameters = (ParameterInfoClass *) malloc(sizeof(ParameterInfoClass)*(ipar)); if ( ! stmt->parameters) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Could not allocate memory for statement parameters"); SC_log_error(func, "", stmt); return SQL_ERROR; } stmt->parameters_allocated = ipar; /* copy the old parameters over */ for(i = 0; i < old_parameters_allocated; i++) { /* a structure copy should work */ stmt->parameters[i] = old_parameters[i]; } /* get rid of the old parameters, if there were any */ if(old_parameters) free(old_parameters); /* zero out the newly allocated parameters (in case they skipped some, */ /* so we don't accidentally try to use them later) */ for(; i < stmt->parameters_allocated; i++) { stmt->parameters[i].buflen = 0; stmt->parameters[i].buffer = 0; stmt->parameters[i].used = 0; stmt->parameters[i].paramType = 0; stmt->parameters[i].CType = 0; stmt->parameters[i].SQLType = 0; stmt->parameters[i].precision = 0; stmt->parameters[i].scale = 0; stmt->parameters[i].data_at_exec = FALSE; stmt->parameters[i].lobj_oid = 0; stmt->parameters[i].EXEC_used = NULL; stmt->parameters[i].EXEC_buffer = NULL; } } ipar--; /* use zero based column numbers for the below part */ /* store the given info */ stmt->parameters[ipar].buflen = cbValueMax; stmt->parameters[ipar].buffer = rgbValue; stmt->parameters[ipar].used = pcbValue; stmt->parameters[ipar].paramType = fParamType; stmt->parameters[ipar].CType = fCType; stmt->parameters[ipar].SQLType = fSqlType; stmt->parameters[ipar].precision = cbColDef; stmt->parameters[ipar].scale = ibScale; /* If rebinding a parameter that had data-at-exec stuff in it, then free that stuff */ if (stmt->parameters[ipar].EXEC_used) { free(stmt->parameters[ipar].EXEC_used); stmt->parameters[ipar].EXEC_used = NULL; } if (stmt->parameters[ipar].EXEC_buffer) { if (stmt->parameters[ipar].SQLType != SQL_LONGVARBINARY) free(stmt->parameters[ipar].EXEC_buffer); stmt->parameters[ipar].EXEC_buffer = NULL; } /* Data at exec macro only valid for C char/binary data */ if ((fSqlType == SQL_LONGVARBINARY || fSqlType == SQL_LONGVARCHAR) && pcbValue && (*pcbValue <= SQL_LEN_DATA_AT_EXEC_OFFSET || *pcbValue == SQL_DATA_AT_EXEC )) stmt->parameters[ipar].data_at_exec = TRUE; else stmt->parameters[ipar].data_at_exec = FALSE; mylog("SQLBindParamater: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d, rgbValue=%d, *pcbValue = %d, data_at_exec = %d\n", ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue ? *pcbValue: -777, stmt->parameters[ipar].data_at_exec); return SQL_SUCCESS; } /* - - - - - - - - - */ /* Associate a user-supplied buffer with a database column. */ RETCODE SQL_API PG_SQLBindCol( HSTMT hstmt, UWORD icol, SWORD fCType, PTR rgbValue, SQLLEN cbValueMax, SQLLEN *pcbValue) { StatementClass *stmt = (StatementClass *) hstmt; static char* const func="SQLBindCol"; mylog( "%s: entering...\n", func); mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol); if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } SC_clear_error(stmt); if( stmt->status == STMT_EXECUTING) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Can't bind columns while statement is still executing."); SC_log_error(func, "", stmt); return SQL_ERROR; } /* If the bookmark column is being bound, then just save it */ if (icol == 0) { if (rgbValue == NULL) { stmt->bookmark.buffer = NULL; stmt->bookmark.used = NULL; } else { /* Make sure it is the bookmark data type */ if ( fCType != SQL_C_BOOKMARK && fCType != SQL_C_BINARY ) { SC_set_error(stmt, STMT_PROGRAM_TYPE_OUT_OF_RANGE, "Column 0 is not of type SQL_C_BOOKMARK"); SC_log_error(func, "", stmt); return SQL_ERROR; } stmt->bookmark.buffer = rgbValue; stmt->bookmark.used = pcbValue; } return SQL_SUCCESS; } /* allocate enough bindings if not already done */ /* Most likely, execution of a statement would have setup the */ /* necessary bindings. But some apps call BindCol before any */ /* statement is executed. */ if ( icol > stmt->bindings_allocated) extend_bindings(stmt, icol); /* check to see if the bindings were allocated */ if ( ! stmt->bindings) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Could not allocate memory for bindings."); SC_log_error(func, "", stmt); return SQL_ERROR; } icol--; /* use zero based col numbers from here out */ /* Reset for SQLGetData */ stmt->bindings[icol].data_left = -1; if (rgbValue == NULL) { /* we have to unbind the column */ stmt->bindings[icol].buflen = 0; stmt->bindings[icol].buffer = NULL; stmt->bindings[icol].used = NULL; stmt->bindings[icol].returntype = SQL_C_CHAR; } else { /* ok, bind that column */ stmt->bindings[icol].buflen = cbValueMax; stmt->bindings[icol].buffer = rgbValue; stmt->bindings[icol].used = pcbValue; stmt->bindings[icol].returntype = fCType; mylog(" bound buffer[%d] = %u\n", icol, stmt->bindings[icol].buffer); } return SQL_SUCCESS; } SQLRETURN SQLBindCol(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgbValue, SQLLEN cbValueMax, SQLLEN *pcbValue) { return PG_SQLBindCol( hstmt, icol, fCType, rgbValue, cbValueMax, pcbValue ); } /* - - - - - - - - - */ /* Returns the description of a parameter marker. */ /* This function is listed as not being supported by SQLGetFunctions() because it is */ /* used to describe "parameter markers" (not bound parameters), in which case, */ /* the dbms should return info on the markers. Since Postgres doesn't support that, */ /* it is best to say this function is not supported and let the application assume a */ /* data type (most likely varchar). */ RETCODE SQL_API SQLDescribeParam( HSTMT hstmt, UWORD ipar, SWORD FAR *pfSqlType, SQLULEN *pcbColDef, SWORD FAR *pibScale, SWORD FAR *pfNullable) { StatementClass *stmt = (StatementClass *) hstmt; static char* const func = "SQLDescribeParam"; mylog( "%s: entering...\n", func); if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } if( (ipar < 1) || (ipar > stmt->parameters_allocated) ) { SC_set_error(stmt, STMT_BAD_PARAMETER_NUMBER_ERROR, "Invalid parameter number for SQLDescribeParam."); SC_log_error(func, "", stmt); return SQL_ERROR; } ipar--; /* This implementation is not very good, since it is supposed to describe */ /* parameter markers, not bound parameters. */ if(pfSqlType) *pfSqlType = stmt->parameters[ipar].SQLType; if(pcbColDef) *pcbColDef = stmt->parameters[ipar].precision; if(pibScale) *pibScale = stmt->parameters[ipar].scale; if(pfNullable) *pfNullable = pgtype_nullable(stmt, stmt->parameters[ipar].paramType); return SQL_SUCCESS; } /* - - - - - - - - - */ /* Sets multiple values (arrays) for the set of parameter markers. */ RETCODE SQL_API SQLParamOptions( HSTMT hstmt, SQLULEN crow, SQLULEN FAR *pirow) { static char* const func = "SQLParamOptions"; mylog( "%s: entering...\n", func); SC_log_error(func, "Function not implemented", (StatementClass *) hstmt); return SQL_ERROR; } /* - - - - - - - - - */ /* This function should really talk to the dbms to determine the number of */ /* "parameter markers" (not bound parameters) in the statement. But, since */ /* Postgres doesn't support that, the driver should just count the number of markers */ /* and return that. The reason the driver just can't say this function is unsupported */ /* like it does for SQLDescribeParam is that some applications don't care and try */ /* to call it anyway. */ /* If the statement does not have parameters, it should just return 0. */ RETCODE SQL_API SQLNumParams( HSTMT hstmt, SWORD FAR *pcpar) { StatementClass *stmt = (StatementClass *) hstmt; char in_quote = FALSE; unsigned int i; static char* const func = "SQLNumParams"; mylog( "%s: entering...\n", func); if(!stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } if (pcpar) *pcpar = 0; else { SC_log_error(func, "pcpar was null", stmt); return SQL_ERROR; } if(!stmt->statement) { /* no statement has been allocated */ SC_set_error(stmt, STMT_SEQUENCE_ERROR, "SQLNumParams called with no statement ready."); SC_log_error(func, "", stmt); return SQL_ERROR; } else { size_t stlen=strlen(stmt->statement); for(i=0; i < stlen; i++) { if(stmt->statement[i] == '?' && !in_quote) (*pcpar)++; else { if (stmt->statement[i] == '\'') in_quote = (in_quote ? FALSE : TRUE); } } return SQL_SUCCESS; } } /******************************************************************** * Bindings Implementation */ BindInfoClass * create_empty_bindings(int num_columns) { BindInfoClass *new_bindings; int i; new_bindings = (BindInfoClass *)malloc(num_columns * sizeof(BindInfoClass)); if(!new_bindings) { return 0; } for(i=0; i < num_columns; i++) { new_bindings[i].buflen = 0; new_bindings[i].buffer = NULL; new_bindings[i].used = NULL; new_bindings[i].data_left = -1; } return new_bindings; } void extend_bindings(StatementClass *stmt, int num_columns) { static char* const func="extend_bindings"; BindInfoClass *new_bindings; int i; mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func, stmt, stmt->bindings_allocated, num_columns); /* if we have too few, allocate room for more, and copy the old */ /* entries into the new structure */ if(stmt->bindings_allocated < num_columns) { new_bindings = create_empty_bindings(num_columns); if ( ! new_bindings) { mylog("%s: unable to create %d new bindings from %d old bindings\n", func, num_columns, stmt->bindings_allocated); if (stmt->bindings) { free(stmt->bindings); stmt->bindings = NULL; } stmt->bindings_allocated = 0; return; } if(stmt->bindings) { for(i=0; ibindings_allocated; i++) new_bindings[i] = stmt->bindings[i]; free(stmt->bindings); } stmt->bindings = new_bindings; stmt->bindings_allocated = num_columns; } /* There is no reason to zero out extra bindings if there are */ /* more than needed. If an app has allocated extra bindings, */ /* let it worry about it by unbinding those columns. */ /* SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings */ /* SQLExecDirect(...) # returns 5 cols */ /* SQLExecDirect(...) # returns 10 cols (now OK) */ mylog("exit extend_bindings\n"); } unixODBC-2.3.12/Drivers/Postgre7.1/bind.h000066400000000000000000000024301446441710500175730ustar00rootroot00000000000000 /* File: bind.h * * Description: See "bind.c" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __BIND_H__ #define __BIND_H__ #include "psqlodbc.h" /* * BindInfoClass -- stores information about a bound column */ struct BindInfoClass_ { Int4 buflen; /* size of buffer */ Int4 data_left; /* amount of data left to read (SQLGetData) */ char *buffer; /* pointer to the buffer */ SQLLEN *used; /* used space in the buffer (for strings not counting the '\0') */ Int2 returntype; /* kind of conversion to be applied when returning (SQL_C_DEFAULT, SQL_C_CHAR...) */ }; /* * ParameterInfoClass -- stores information about a bound parameter */ struct ParameterInfoClass_ { Int4 buflen; char *buffer; SQLLEN *used; Int2 paramType; Int2 CType; Int2 SQLType; UInt4 precision; Int2 scale; Oid lobj_oid; Int4 *EXEC_used; /* amount of data OR the oid of the large object */ char *EXEC_buffer; /* the data or the FD of the large object */ char data_at_exec; }; BindInfoClass *create_empty_bindings(int num_columns); void extend_bindings(StatementClass *stmt, int num_columns); RETCODE SQL_API PG_SQLBindCol(HSTMT hstmt, UWORD icol, SWORD fCType, PTR rgbValue, SQLLEN cbValueMax, SQLLEN *pcbValue); #endif unixODBC-2.3.12/Drivers/Postgre7.1/columninfo.c000066400000000000000000000076501446441710500210340ustar00rootroot00000000000000 /* Module: columninfo.c * * Description: This module contains routines related to * reading and storing the field information from a query. * * Classes: ColumnInfoClass (Functions prefix: "CI_") * * API functions: none * * Comments: See "notice.txt" for copyright and license information. * */ #include #include "columninfo.h" #include "connection.h" #include "socket.h" #include #include ColumnInfoClass * CI_Constructor() { ColumnInfoClass *rv; rv = (ColumnInfoClass *) malloc(sizeof(ColumnInfoClass)); if (rv) { rv->num_fields = 0; rv->name = NULL; rv->adtid = NULL; rv->adtsize = NULL; rv->display_size = NULL; rv->atttypmod = NULL; } return rv; } void CI_Destructor(ColumnInfoClass *self) { if ( self ) { CI_free_memory(self); free(self); } } /* Read in field descriptions. If self is not null, then also store the information. If self is null, then just read, don't store. */ char CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn) { Int2 lf; int new_num_fields; Oid new_adtid; Int2 new_adtsize; Int4 new_atttypmod = -1; char new_field_name[MAX_MESSAGE_LEN+1]; SocketClass *sock; ConnInfo *ci; sock = CC_get_socket(conn); ci = &conn->connInfo; /* at first read in the number of fields that are in the query */ new_num_fields = (Int2) SOCK_get_int(sock, sizeof(Int2)); mylog("num_fields = %d\n", new_num_fields); if (self) { /* according to that allocate memory */ CI_set_num_fields(self, new_num_fields); } /* now read in the descriptions */ for(lf = 0; lf < new_num_fields; lf++) { SOCK_get_string(sock, new_field_name, MAX_MESSAGE_LEN); new_adtid = (Oid) SOCK_get_int(sock, 4); new_adtsize = (Int2) SOCK_get_int(sock, 2); /* If 6.4 protocol, then read the atttypmod field */ if (PG_VERSION_GE(conn, 6.4)) { mylog("READING ATTTYPMOD\n"); new_atttypmod = (Int4) SOCK_get_int(sock, 4); /* Subtract the header length */ new_atttypmod -= 4; if (new_atttypmod < 0) new_atttypmod = -1; } mylog("CI_read_fields: fieldname='%s', adtid=%d, adtsize=%d, atttypmod=%d\n", new_field_name, new_adtid, new_adtsize, new_atttypmod); if (self) CI_set_field_info(self, lf, new_field_name, new_adtid, new_adtsize, new_atttypmod); } return (SOCK_get_errcode(sock) == 0); } void CI_free_memory(ColumnInfoClass *self) { register Int2 lf; int num_fields = self->num_fields; for (lf = 0; lf < num_fields; lf++) { if (self->name[lf]) { free(self->name[lf]); self->name[lf] = NULL; } } /* Safe to call even if null */ self->num_fields = 0; if (self->name) free(self->name); self->name = NULL; if (self->adtid) free(self->adtid); self->adtid = NULL; if (self->adtsize) free(self->adtsize); self->adtsize = NULL; if (self->display_size) free(self->display_size); self->display_size = NULL; if (self->atttypmod) free(self->atttypmod); self->atttypmod = NULL; } void CI_set_num_fields(ColumnInfoClass *self, int new_num_fields) { CI_free_memory(self); /* always safe to call */ self->num_fields = new_num_fields; self->name = (char **) malloc (sizeof(char *) * self->num_fields); self->adtid = (Oid *) malloc (sizeof(Oid) * self->num_fields); self->adtsize = (Int2 *) malloc (sizeof(Int2) * self->num_fields); self->display_size = (Int2 *) malloc(sizeof(Int2) * self->num_fields); self->atttypmod = (Int4 *) malloc(sizeof(Int4) * self->num_fields); } void CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name, Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod) { /* check bounds */ if((field_num < 0) || (field_num >= self->num_fields)) { return; } /* store the info */ self->name[field_num] = strdup(new_name); self->adtid[field_num] = new_adtid; self->adtsize[field_num] = new_adtsize; self->atttypmod[field_num] = new_atttypmod; self->display_size[field_num] = 0; } unixODBC-2.3.12/Drivers/Postgre7.1/columninfo.h000066400000000000000000000025761446441710500210430ustar00rootroot00000000000000 /* File: columninfo.h * * Description: See "columninfo.c" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __COLUMNINFO_H__ #define __COLUMNINFO_H__ #include "psqlodbc.h" struct ColumnInfoClass_ { Int2 num_fields; char **name; /* list of type names */ Oid *adtid; /* list of type ids */ Int2 *adtsize; /* list type sizes */ Int2 *display_size; /* the display size (longest row) */ Int4 *atttypmod; /* the length of bpchar/varchar */ }; #define CI_get_num_fields(self) ((self) ? (self->num_fields) : (-1)) #define CI_get_oid(self, col) (self->adtid[col]) #define CI_get_fieldname(self, col) (self->name[col]) #define CI_get_fieldsize(self, col) (self->adtsize[col]) #define CI_get_display_size(self, col) (self->display_size[col]) #define CI_get_atttypmod(self, col) (self->atttypmod[col]) ColumnInfoClass *CI_Constructor(void); void CI_Destructor(ColumnInfoClass *self); void CI_free_memory(ColumnInfoClass *self); char CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn); /* functions for setting up the fields from within the program, */ /* without reading from a socket */ void CI_set_num_fields(ColumnInfoClass *self, int new_num_fields); void CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name, Oid new_adtid, Int2 new_adtsize, Int4 atttypmod); #endif unixODBC-2.3.12/Drivers/Postgre7.1/connection.c000066400000000000000000001300011446441710500210050ustar00rootroot00000000000000 /* Module: connection.c * * Description: This module contains routines related to * connecting to and disconnecting from the Postgres DBMS. * * Classes: ConnectionClass (Functions prefix: "CC_") * * API functions: SQLAllocConnect, SQLConnect, SQLDisconnect, SQLFreeConnect, * SQLBrowseConnect(NI) * * Comments: See "notice.txt" for copyright and license information. * */ #include #include "environ.h" #include "connection.h" #include "socket.h" #include "statement.h" #include "qresult.h" #include "lobj.h" #include "misc.h" #include "dlg_specific.h" #include #include #include #ifdef WIN32 #include #endif #ifdef UNIXODBC #include #ifdef HAVE_CRYPT_H #include #endif #include "md5.h" #endif #define STMT_INCREMENT 16 /* how many statement holders to allocate at a time */ #define PRN_NULLCHECK extern GLOBAL_VALUES globals; RETCODE SQL_API SQLAllocConnect(HENV henv, HDBC FAR *phdbc) { EnvironmentClass *env = (EnvironmentClass *)henv; ConnectionClass *conn; static char* const func="SQLAllocConnect"; mylog( "%s: entering...\n", func); conn = CC_Constructor(); mylog("**** %s: henv = %u, conn = %u\n", func, henv, conn); if( ! conn) { env->errornumber = ENV_ALLOC_ERROR; env->errormsg = "Couldn't allocate memory for Connection object."; *phdbc = SQL_NULL_HDBC; EN_log_error(func, "", env); return SQL_ERROR; } if ( ! EN_add_connection(env, conn)) { env->errornumber = ENV_ALLOC_ERROR; env->errormsg = "Maximum number of connections exceeded."; CC_Destructor(conn); *phdbc = SQL_NULL_HDBC; EN_log_error(func, "", env); return SQL_ERROR; } *phdbc = (HDBC) conn; return SQL_SUCCESS; } /* - - - - - - - - - */ RETCODE SQL_API SQLConnect( HDBC hdbc, UCHAR FAR *szDSN, SWORD cbDSN, UCHAR FAR *szUID, SWORD cbUID, UCHAR FAR *szAuthStr, SWORD cbAuthStr) { ConnectionClass *conn = (ConnectionClass *) hdbc; ConnInfo *ci; static char* const func = "SQLConnect"; mylog( "%s: entering...\n", func); if ( ! conn) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } ci = &conn->connInfo; make_string((char*)szDSN, cbDSN, ci->dsn); /* get the values for the DSN from the registry */ getDSNinfo(ci, CONN_OVERWRITE); /* initialize pg_version from connInfo.protocol */ CC_initialize_pg_version(conn); /* override values from DSN info with UID and authStr(pwd) This only occurs if the values are actually there. */ make_string((char*)szUID, cbUID, ci->username); make_string((char*)szAuthStr, cbAuthStr, ci->password); /* fill in any defaults */ getDSNdefaults(ci); qlog("conn = %u, %s(DSN='%s', UID='%s', PWD='%s')\n", conn, func, ci->dsn, ci->username, ci->password); if ( CC_connect(conn, AUTH_REQ_OK, NULL) <= 0) { /* Error messages are filled in */ CC_log_error(func, "Error on CC_connect", conn); return SQL_ERROR; } mylog( "%s: returning...\n", func); return SQL_SUCCESS; } /* - - - - - - - - - */ RETCODE SQL_API SQLBrowseConnect( HDBC hdbc, UCHAR FAR *szConnStrIn, SWORD cbConnStrIn, UCHAR FAR *szConnStrOut, SWORD cbConnStrOutMax, SWORD FAR *pcbConnStrOut) { static char* const func="SQLBrowseConnect"; mylog( "%s: entering...\n", func); return SQL_SUCCESS; } /* - - - - - - - - - */ /* Drop any hstmts open on hdbc and disconnect from database */ RETCODE SQL_API SQLDisconnect( HDBC hdbc) { ConnectionClass *conn = (ConnectionClass *) hdbc; static char* const func = "SQLDisconnect"; mylog( "%s: entering...\n", func); if ( ! conn) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } qlog("conn=%u, %s\n", conn, func); if (conn->status == CONN_EXECUTING) { CC_set_error(conn, CONN_IN_USE, "A transaction is currently being executed"); CC_log_error(func, "", conn); return SQL_ERROR; } mylog("%s: about to CC_cleanup\n", func); /* Close the connection and free statements */ CC_cleanup(conn); mylog("%s: done CC_cleanup\n", func); mylog("%s: returning...\n", func); return SQL_SUCCESS; } /* - - - - - - - - - */ RETCODE SQL_API SQLFreeConnect( HDBC hdbc) { ConnectionClass *conn = (ConnectionClass *) hdbc; static char* const func = "SQLFreeConnect"; mylog( "%s: entering...\n", func); mylog("**** in %s: hdbc=%u\n", func, hdbc); if ( ! conn) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } /* Remove the connection from the environment */ if ( ! EN_remove_connection((EnvironmentClass*)conn->henv, conn)) { CC_set_error(conn, CONN_IN_USE, "A transaction is currently being executed"); CC_log_error(func, "", conn); return SQL_ERROR; } CC_Destructor(conn); mylog("%s: returning...\n", func); return SQL_SUCCESS; } /* * * IMPLEMENTATION CONNECTION CLASS * */ ConnectionClass *CC_Constructor() { ConnectionClass *rv; rv = (ConnectionClass *)malloc(sizeof(ConnectionClass)); if (rv != NULL) { rv->henv = (HENV)NULL; /* not yet associated with an environment */ CC_clear_error(rv); rv->status = CONN_NOT_CONNECTED; rv->transact_status = CONN_IN_AUTOCOMMIT; /* autocommit by default */ memset(&rv->connInfo, 0, sizeof(ConnInfo)); rv->sock = SOCK_Constructor(); if ( ! rv->sock) return NULL; rv->stmts = (StatementClass **) malloc( sizeof(StatementClass *) * STMT_INCREMENT); if ( ! rv->stmts) return NULL; memset(rv->stmts, 0, sizeof(StatementClass *) * STMT_INCREMENT); rv->num_stmts = STMT_INCREMENT; rv->lobj_type = PG_TYPE_LO; rv->ntables = 0; rv->col_info = NULL; rv->translation_option = 0; rv->translation_handle = NULL; rv->DataSourceToDriver = NULL; rv->DriverToDataSource = NULL; memset(rv->pg_version, 0, sizeof(rv->pg_version)); rv->pg_version_number = .0; rv->pg_version_major = 0; rv->pg_version_minor = 0; /* Initialize statement options to defaults */ /* Statements under this conn will inherit these options */ InitializeStatementOptions(&rv->stmtOptions); } return rv; } char CC_Destructor(ConnectionClass *self) { mylog("enter CC_Destructor, self=%u\n", self); if (self->status == CONN_EXECUTING) return 0; CC_cleanup(self); /* cleanup socket and statements */ mylog("after CC_Cleanup\n"); /* Free up statement holders */ if (self->stmts) { free(self->stmts); self->stmts = NULL; } mylog("after free statement holders\n"); /* Free cached table info */ if (self->col_info) { int i; for (i = 0; i < self->ntables; i++) { if (self->col_info[i]->result) /* Free the SQLColumns result structure */ QR_Destructor(self->col_info[i]->result); free(self->col_info[i]); } CC_set_errormsg(self, NULL); free(self->col_info); } CC_set_errormsg(self, NULL); free(self); mylog("exit CC_Destructor\n"); return 1; } /* Return how many cursors are opened on this connection */ int CC_cursor_count(ConnectionClass *self) { StatementClass *stmt; int i, count = 0; mylog("CC_cursor_count: self=%u, num_stmts=%d\n", self, self->num_stmts); for (i = 0; i < self->num_stmts; i++) { stmt = self->stmts[i]; if (stmt && stmt->result && stmt->result->cursor) count++; } mylog("CC_cursor_count: returning %d\n", count); return count; } void CC_clear_error(ConnectionClass *self) { self->__error_number = 0; self->__error_message = NULL; self->errormsg_created = FALSE; } /* Used to cancel a transaction */ /* We are almost always in the middle of a transaction. */ char CC_abort(ConnectionClass *self) { QResultClass *res; if ( CC_is_in_trans(self)) { res = NULL; mylog("CC_abort: sending ABORT!\n"); res = CC_send_query(self, "ABORT", NULL); CC_set_no_trans(self); if (res != NULL) QR_Destructor(res); else return FALSE; } return TRUE; } /* This is called by SQLDisconnect also */ char CC_cleanup(ConnectionClass *self) { int i; StatementClass *stmt; if (self->status == CONN_EXECUTING) return FALSE; mylog("in CC_Cleanup, self=%u\n", self); /* Cancel an ongoing transaction */ /* We are always in the middle of a transaction, */ /* even if we are in auto commit. */ if (self->sock) CC_abort(self); /* * mimic closePGconn */ if ( self->sock) { SOCK_put_string( self->sock, "X" ); SOCK_flush_output( self->sock ); } mylog("after CC_abort\n"); /* This actually closes the connection to the dbase */ if (self->sock) { SOCK_Destructor(self->sock); self->sock = NULL; } mylog("after SOCK destructor\n"); /* Free all the stmts on this connection */ for (i = 0; i < self->num_stmts; i++) { if ( self->stmts ) { stmt = self->stmts[i]; if (stmt) { stmt->hdbc = NULL; /* prevent any more dbase interactions */ SC_Destructor(stmt); self->stmts[i] = NULL; } } } /* Check for translation dll */ #ifdef WIN32 if ( self->translation_handle) { FreeLibrary (self->translation_handle); self->translation_handle = NULL; } #endif mylog("exit CC_Cleanup\n"); return TRUE; } int CC_set_translation (ConnectionClass *self) { #ifdef WIN32 if (self->translation_handle != NULL) { FreeLibrary (self->translation_handle); self->translation_handle = NULL; } if (self->connInfo.translation_dll[0] == 0) return TRUE; self->translation_option = atoi (self->connInfo.translation_option); self->translation_handle = LoadLibrary (self->connInfo.translation_dll); if (self->translation_handle == NULL) { CC_set_error(self, CONN_UNABLE_TO_LOAD_DLL, "Could not load the translation DLL."); return FALSE; } self->DataSourceToDriver = (DataSourceToDriverProc) GetProcAddress (self->translation_handle, "SQLDataSourceToDriver"); self->DriverToDataSource = (DriverToDataSourceProc) GetProcAddress (self->translation_handle, "SQLDriverToDataSource"); if (self->DataSourceToDriver == NULL || self->DriverToDataSource == NULL) { CC_set_error(self, CONN_UNABLE_TO_LOAD_DLL, "Could not find translation DLL functions."); return FALSE; } #endif return TRUE; } static int md5_auth_send(ConnectionClass *self, const char *salt) { char *pwd1 = NULL, *pwd2 = NULL; ConnInfo *ci = &(self->connInfo); SocketClass *sock = self->sock; if (!(pwd1 = malloc(MD5_PASSWD_LEN + 1))) return 1; if (!EncryptMD5(ci->password, ci->username, strlen(ci->username), pwd1)) { free(pwd1); return 1; } if (!(pwd2 = malloc(MD5_PASSWD_LEN + 1))) { free(pwd1); return 1; } if (!EncryptMD5(pwd1 + strlen("md5"), salt, 4, pwd2)) { free(pwd2); free(pwd1); return 1; } free(pwd1); SOCK_put_int(sock, 4 + strlen(pwd2) + 1, 4); SOCK_put_n_char(sock, pwd2, strlen(pwd2) + 1); SOCK_flush_output(sock); free(pwd2); return 0; } char CC_connect(ConnectionClass *self, char password_req, char *salt_para) { StartupPacket sp; StartupPacket6_2 sp62; QResultClass *res; SocketClass *sock; ConnInfo *ci = &(self->connInfo); int areq = -1; int beresp; char msgbuffer[ERROR_MSG_LENGTH]; char salt[5], notice[512]; static char* const func="CC_connect"; char *encoding; mylog("%s: entering...\n", func); if (password_req != AUTH_REQ_OK) sock = self->sock; /* already connected, just authenticate */ else { qlog("Global Options: Version='%s', fetch=%d, socket=%d, unknown_sizes=%d, max_varchar_size=%d, max_longvarchar_size=%d\n", POSTGRESDRIVERVERSION, globals.fetch_max, globals.socket_buffersize, globals.unknown_sizes, globals.max_varchar_size, globals.max_longvarchar_size); qlog(" disable_optimizer=%d, ksqo=%d, unique_index=%d, use_declarefetch=%d\n", globals.disable_optimizer, globals.ksqo, globals.unique_index, globals.use_declarefetch); qlog(" text_as_longvarchar=%d, unknowns_as_longvarchar=%d, bools_as_char=%d\n", globals.text_as_longvarchar, globals.unknowns_as_longvarchar, globals.bools_as_char); qlog(" extra_systable_prefixes='%s', conn_settings='%s'\n", globals.extra_systable_prefixes, globals.conn_settings); if (self->status != CONN_NOT_CONNECTED) { CC_set_error(self, CONN_OPENDB_ERROR, "Already connected."); return 0; } if ( ci->server[0] == '\0' || ci->port[0] == '\0' || ci->database[0] == '\0') { CC_set_error(self, CONN_INIREAD_ERROR,"Missing server name, port, or database name in call to CC_connect."); return 0; } mylog("CC_connect(): DSN = '%s', server = '%s', port = '%s', database = '%s', username = '%s', password='%s'\n", ci->dsn, ci->server, ci->port, ci->database, ci->username, ci->password); another_version_retry: /* If the socket was closed for some reason (like a SQLDisconnect, but no SQLFreeConnect * then create a socket now. */ if ( ! self->sock) { self->sock = SOCK_Constructor(); if ( ! self->sock) { CC_set_error(self, CONNECTION_SERVER_NOT_REACHED, "Could not open a socket to the server"); return 0; } } sock = self->sock; mylog("connecting to the server socket...\n"); SOCK_connect_to(sock, (short) atoi(ci->port), ci->server, ci->uds); if (SOCK_get_errcode(sock) != 0) { mylog("connection to the server socket failed.\n"); CC_set_error(self, CONNECTION_SERVER_NOT_REACHED, "Could not connect to the server"); return 0; } mylog("connection to the server socket succeeded.\n"); if ( PROTOCOL_62(ci)) { sock->reverse = TRUE; /* make put_int and get_int work for 6.2 */ memset(&sp62, 0, sizeof(StartupPacket6_2)); SOCK_put_int(sock, htonl(4+sizeof(StartupPacket6_2)), 4); sp62.authtype = htonl(NO_AUTHENTICATION); strncpy(sp62.database, ci->database, PATH_SIZE); strncpy(sp62.user, ci->username, NAMEDATALEN); SOCK_put_n_char(sock, (char *) &sp62, sizeof(StartupPacket6_2)); SOCK_flush_output(sock); } else { memset(&sp, 0, sizeof(StartupPacket)); mylog("sizeof startup packet = %d\n", sizeof(StartupPacket)); /* Send length of Authentication Block */ SOCK_put_int(sock, 4+sizeof(StartupPacket), 4); if ( PROTOCOL_63(ci)) sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_63); else sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LATEST); strncpy(sp.database, ci->database, SM_DATABASE); strncpy(sp.user, ci->username, SM_USER); SOCK_put_n_char(sock, (char *) &sp, sizeof(StartupPacket)); SOCK_flush_output(sock); } mylog("sent the authentication block.\n"); if (sock->errornumber != 0) { mylog("couldn't send the authentication block properly.\n"); CC_set_error(self, CONN_INVALID_AUTHENTICATION, "Sending the authentication packet failed"); return 0; } mylog("sent the authentication block successfully.\n"); } mylog("gonna do authentication\n"); /* *************************************************** */ /* Now get the authentication request from backend */ /* *************************************************** */ if (!PROTOCOL_62(ci)) { BOOL before_64 = PG_VERSION_LT(self, 6.4), ReadyForQuery = FALSE; do { if (password_req != AUTH_REQ_OK) beresp = 'R'; else { beresp = SOCK_get_char(sock); mylog("auth got '%c'\n", beresp); } switch (beresp) { case 'E': SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); CC_set_error(self, CONN_INVALID_AUTHENTICATION, msgbuffer); qlog("ERROR from backend during authentication: '%s'\n", msgbuffer); if (strncmp(msgbuffer, "Unsupported frontend protocol", 29) == 0) { /* retry older version */ if (PROTOCOL_63(ci)) strcpy(ci->protocol, PG62); else strcpy(ci->protocol, PG63); SOCK_Destructor(sock); self->sock = (SocketClass *) 0; CC_initialize_pg_version(self); goto another_version_retry; } return 0; case 'R': if (password_req != AUTH_REQ_OK) { mylog("in 'R' password_req=%s\n", ci->password); areq = password_req; if (salt_para) memcpy(salt, salt_para, sizeof(salt)); password_req = AUTH_REQ_OK; } else { areq = SOCK_get_int(sock, 4); if (areq == AUTH_REQ_MD5) SOCK_get_n_char(sock, salt, 4); else if (areq == AUTH_REQ_CRYPT) SOCK_get_n_char(sock, salt, 2); mylog("areq = %d\n", areq); } switch (areq) { case AUTH_REQ_OK: break; case AUTH_REQ_KRB4: CC_set_error(self, CONN_AUTH_TYPE_UNSUPPORTED, "Kerberos 4 authentication not supported"); return 0; case AUTH_REQ_KRB5: CC_set_error(self, CONN_AUTH_TYPE_UNSUPPORTED, "Kerberos 5 authentication not supported"); return 0; case AUTH_REQ_PASSWORD: mylog("in AUTH_REQ_PASSWORD\n"); if (ci->password[0] == '\0') { CC_set_error(self, CONNECTION_NEED_PASSWORD, "A password is required for this connection."); return -areq; /* need password */ } mylog("past need password\n"); SOCK_put_int(sock, 4 + strlen(ci->password) + 1, 4); SOCK_put_n_char(sock, ci->password, strlen(ci->password) + 1); SOCK_flush_output(sock); mylog("past flush\n"); break; case AUTH_REQ_CRYPT: #ifdef HAVE_LIBCRYPT { char *password; mylog("in AUTH_REQ_CRYPT\n"); if (ci->password[0] == '\0') { CC_set_error(self, CONNECTION_NEED_PASSWORD, "A password is required for this connection."); return -1; /* need password */ } mylog("past need password\n"); password = crypt( ci -> password, salt ); SOCK_put_int(sock, 4+strlen(password)+1, 4); SOCK_put_n_char(sock, password, strlen(password) + 1); SOCK_flush_output(sock); mylog("past flush\n"); break; } #else CC_set_error(self, CONN_AUTH_TYPE_UNSUPPORTED, "Password crypt authentication not supported."); #endif return 0; case AUTH_REQ_MD5: mylog("in AUTH_REQ_MD5\n"); if (ci->password[0] == '\0') { CC_set_error(self, CONNECTION_NEED_PASSWORD, "A password is required for this connection."); if (salt_para) memcpy(salt_para, salt, sizeof(salt)); return -areq; /* need password */ } if (md5_auth_send(self, salt)) { CC_set_error(self, CONN_INVALID_AUTHENTICATION, "md5 hashing failed"); return 0; } break; case AUTH_REQ_SCM_CREDS: CC_set_error(self, CONN_AUTH_TYPE_UNSUPPORTED, "Unix socket credential authentication not supported"); return 0; default: CC_set_error(self, CONN_AUTH_TYPE_UNSUPPORTED, "Unknown authentication type"); return 0; } break; case 'K': /* Secret key (6.4 protocol) */ self->be_pid = SOCK_get_int(sock, 4); /* pid */ self->be_key = SOCK_get_int(sock, 4); /* key */ break; case 'Z': /* Backend is ready for new query (6.4) */ ReadyForQuery = TRUE; break; case 'N': /* Notices may come */ while (SOCK_get_string(sock, notice, sizeof(notice) - 1)) ; break; default: CC_set_error(self, CONN_INVALID_AUTHENTICATION, "Unexpected protocol character during authentication"); return 0; } /* * There were no ReadyForQuery responce before 6.4. */ if (before_64 && areq == AUTH_REQ_OK) ReadyForQuery = TRUE; } while (!ReadyForQuery); } CC_set_errormsg(self, NULL); CC_clear_error(self); /* clear any password error */ /* send an empty query in order to find out whether the specified */ /* database really exists on the server machine */ mylog("sending an empty query...\n"); res = CC_send_query(self, " ", NULL); if ( res == NULL || QR_get_status(res) != PGRES_EMPTY_QUERY) { mylog("got no result from the empty query. (probably database does not exist)\n"); CC_set_error(self, CONNECTION_NO_SUCH_DATABASE, "The database does not exist on the server\nor user authentication failed."); if (res != NULL) QR_Destructor(res); if( self->sock ) { SOCK_Destructor(self->sock); self->sock = NULL; } return 0; } if (res) QR_Destructor(res); mylog("empty query seems to be OK.\n"); CC_set_translation (self); /**********************************************/ /******* Send any initial settings *********/ /**********************************************/ /* Since these functions allocate statements, and since the connection is not established yet, it would violate odbc state transition rules. Therefore, these functions call the corresponding local function instead. */ CC_send_settings(self); CC_lookup_lo(self); /* a hack to get the oid of our large object oid type */ CC_lookup_pg_version(self); /* Get PostgreSQL version for SQLGetInfo use */ CC_set_errormsg(self, NULL); CC_clear_error(self); /* clear any initial command errors */ self->status = CONN_CONNECTED; mylog("%s: returning...\n", func); return 1; } char CC_add_statement(ConnectionClass *self, StatementClass *stmt) { int i; mylog("CC_add_statement: self=%u, stmt=%u\n", self, stmt); for (i = 0; i < self->num_stmts; i++) { if ( !self->stmts[i]) { stmt->hdbc = self; self->stmts[i] = stmt; return TRUE; } } /* no more room -- allocate more memory */ self->stmts = (StatementClass **) realloc( self->stmts, sizeof(StatementClass *) * (STMT_INCREMENT + self->num_stmts)); if ( ! self->stmts) return FALSE; memset(&self->stmts[self->num_stmts], 0, sizeof(StatementClass *) * STMT_INCREMENT); stmt->hdbc = self; self->stmts[self->num_stmts] = stmt; self->num_stmts += STMT_INCREMENT; return TRUE; } char CC_remove_statement(ConnectionClass *self, StatementClass *stmt) { int i; for (i = 0; i < self->num_stmts; i++) { if (self->stmts[i] == stmt && stmt->status != STMT_EXECUTING) { self->stmts[i] = NULL; return TRUE; } } return FALSE; } /* Create a more informative error message by concatenating the connection error message with its socket error message. */ char * CC_create_errormsg(ConnectionClass *self) { SocketClass *sock = self->sock; int pos; static char msg[4096]; mylog("enter CC_create_errormsg\n"); msg[0] = '\0'; if (CC_get_errormsg(self)) strncpy(msg, CC_get_errormsg(self), sizeof(msg)); mylog("msg = '%s'\n", msg); if (sock && sock->errormsg && sock->errormsg[0] != '\0') { pos = strlen(msg); sprintf(&msg[pos], ";\n%s", sock->errormsg); } mylog("exit CC_create_errormsg\n"); return msg ? strdup(msg) : NULL; } void CC_set_error(ConnectionClass *self, int number, const char *message) { if (self->__error_message) free(self->__error_message); self->__error_number = number; self->__error_message = message ? strdup(message) : NULL; } void CC_set_errormsg(ConnectionClass *self, const char *message) { if (self->__error_message) free(self->__error_message); self->__error_message = message ? strdup(message) : NULL; } char CC_get_error(ConnectionClass *self, int *number, char **message) { int rv; char *msgcrt; mylog("enter CC_get_error\n"); /* Create a very informative errormsg if it hasn't been done yet. */ if ( ! self->errormsg_created) { msgcrt = CC_create_errormsg(self); if (self->__error_message) free(self->__error_message); self->__error_message = msgcrt; self->errormsg_created = TRUE; } if (CC_get_errornumber(self)) { *number = CC_get_errornumber(self); *message = CC_get_errormsg(self); } rv = (CC_get_errornumber(self) != 0); self->__error_number = 0; /* clear the error */ mylog("exit CC_get_error\n"); return rv; } /* The "result_in" is only used by QR_next_tuple() to fetch another group of rows into the same existing QResultClass (this occurs when the tuple cache is depleted and needs to be re-filled). The "cursor" is used by SQLExecute to associate a statement handle as the cursor name (i.e., C3326857) for SQL select statements. This cursor is then used in future 'declare cursor C3326857 for ...' and 'fetch 100 in C3326857' statements. */ QResultClass * CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) { QResultClass *result_in, *res = NULL; char swallow; int id; SocketClass *sock = self->sock; static char msgbuffer[MAX_MESSAGE_LEN+1]; char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont need static */ mylog("send_query(): conn=%u, query='%s'\n", self, query); qlog("conn=%u, query='%s'\n", self, query); /* Indicate that we are sending a query to the backend */ if(strlen(query) > MAX_MESSAGE_LEN-2) { CC_set_error(self, CONNECTION_MSG_TOO_LONG, "Query string is too long"); return NULL; } if ((NULL == query) || (query[0] == '\0')) return NULL; if (SOCK_get_errcode(sock) != 0) { CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send Query to backend"); CC_set_no_trans(self); return NULL; } SOCK_put_char(sock, 'Q'); if (SOCK_get_errcode(sock) != 0) { CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send Query to backend"); CC_set_no_trans(self); return NULL; } SOCK_put_string(sock, query); SOCK_flush_output(sock); if (SOCK_get_errcode(sock) != 0) { CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send Query to backend"); CC_set_no_trans(self); return NULL; } mylog("send_query: done sending query\n"); while(1) { /* what type of message is coming now ? */ id = SOCK_get_char(sock); if ((SOCK_get_errcode(sock) != 0) || (id == EOF)) { CC_set_error(self, CONNECTION_NO_RESPONSE, "No response from the backend"); if (res) QR_Destructor(res); mylog("send_query: 'id' - %s\n", CC_get_errormsg(self)); CC_set_no_trans(self); return NULL; } mylog("send_query: got id = '%c'\n", id); switch (id) { case 'A' : /* Asynchronous Messages are ignored */ (void)SOCK_get_int(sock, 4); /* id of notification */ SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN); /* name of the relation the message comes from */ break; case 'C' : /* portal query command, no tuples returned */ /* read in the return message from the backend */ SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN); if (SOCK_get_errcode(sock) != 0) { CC_set_error(self, CONNECTION_NO_RESPONSE, "No response from backend while receiving a portal query command"); mylog("send_query: 'C' - %s\n", CC_get_errormsg(self)); CC_set_no_trans(self); if (res) QR_Destructor(res); return NULL; } else { char clear = 0; mylog("send_query: ok - 'C' - %s\n", cmdbuffer); if (res) { QR_Destructor(res); res = NULL; } if (res == NULL) /* allow for "show" style notices */ res = QR_Constructor(); mylog("send_query: setting cmdbuffer = '%s'\n", cmdbuffer); /* Only save the first command */ QR_set_status(res, PGRES_COMMAND_OK); QR_set_command(res, cmdbuffer); /* (Quotation from the original comments) since backend may produce more than one result for some commands we need to poll until clear so we send an empty query, and keep reading out of the pipe until an 'I' is received */ SOCK_put_string(sock, "Q "); SOCK_flush_output(sock); while( ! clear) { id = SOCK_get_char(sock); if ((SOCK_get_errcode(sock) != 0) || (id == EOF)) { CC_set_error(self, CONNECTION_NO_RESPONSE, "No response from the backend"); if (res) { QR_Destructor(res); } mylog("send_query: id=%d error=%s \n", id, "No response from the backend"); CC_set_no_trans(self); return NULL; } switch(id) { case 'I': (void) SOCK_get_char(sock); clear = TRUE; break; case 'Z': break; case 'C': SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); qlog("Command response: '%s'\n", cmdbuffer); break; case 'N': SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); qlog("NOTICE from backend during clear: '%s'\n", cmdbuffer); break; case 'E': SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); qlog("ERROR from backend during clear: '%s'\n", cmdbuffer); /* We must report this type of error as well (practically for reference integrity violation error reporting, from PostgreSQL 7.0). (Zoltan Kovacs, 04/26/2000) */ CC_set_errormsg(self, cmdbuffer); if ( ! strncmp(cmdbuffer, "FATAL", 5)) { CC_set_errornumber(self, CONNECTION_SERVER_REPORTED_ERROR); CC_set_no_trans(self); } else CC_set_errornumber(self, CONNECTION_SERVER_REPORTED_WARNING); QR_set_status(res, PGRES_NONFATAL_ERROR); QR_set_aborted(res, TRUE); break; } } mylog("send_query: returning res = %u\n", res); return res; } case 'K': /* Secret key (6.4 protocol) */ (void)SOCK_get_int(sock, 4); /* pid */ (void)SOCK_get_int(sock, 4); /* key */ break; case 'Z': /* Backend is ready for new query (6.4) */ break; case 'N' : /* NOTICE: */ SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); if (res) QR_Destructor(res); res = QR_Constructor(); QR_set_status(res, PGRES_NONFATAL_ERROR); QR_set_notice(res, cmdbuffer); /* will dup this string */ mylog("~~~ NOTICE: '%s'\n", cmdbuffer); qlog("NOTICE from backend during send_query: '%s'\n", cmdbuffer); continue; /* dont return a result -- continue reading */ case 'I' : /* The server sends an empty query */ /* There is a closing '\0' following the 'I', so we eat it */ swallow = SOCK_get_char(sock); if ((swallow != '\0') || SOCK_get_errcode(sock) != 0) { CC_set_error(self, CONNECTION_BACKEND_CRAZY, "Unexpected protocol character from backend (send_query - I)"); if (res) QR_Destructor(res); res = QR_Constructor(); QR_set_status(res, PGRES_FATAL_ERROR); return res; } else { /* We return the empty query */ if (res) QR_Destructor(res); res = QR_Constructor(); QR_set_status(res, PGRES_EMPTY_QUERY); return res; } break; case 'E' : SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); /* Remove a newline */ if (msgbuffer[0] != '\0' && msgbuffer[strlen(msgbuffer)-1] == '\n') msgbuffer[strlen(msgbuffer)-1] = '\0'; CC_set_errormsg(self, msgbuffer); mylog("send_query: 'E' - %s\n", msgbuffer); qlog("ERROR from backend during send_query: '%s'\n", msgbuffer); /* We should report that an error occurred. Zoltan */ if (res) QR_Destructor(res); res = QR_Constructor(); if ( ! strncmp(msgbuffer, "FATAL", 5)) { CC_set_errornumber(self, CONNECTION_SERVER_REPORTED_ERROR); CC_set_no_trans(self); QR_set_status(res, PGRES_FATAL_ERROR); } else { CC_set_errornumber(self, CONNECTION_SERVER_REPORTED_WARNING); QR_set_status(res, PGRES_NONFATAL_ERROR); } QR_set_aborted(res, TRUE); return res; /* instead of NULL. Zoltan */ case 'P' : /* get the Portal name */ SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN); break; case 'T': /* Tuple results start here */ result_in = qi ? qi->result_in : NULL; if ( result_in == NULL) { result_in = QR_Constructor(); mylog("send_query: 'T' no result_in: res = %u\n", result_in); if ( ! result_in) { CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, "Could not create result info in send_query."); if (res) QR_Destructor(res); return NULL; } if (qi) QR_set_cache_size(result_in, qi->row_size); if ( ! QR_fetch_tuples(result_in, self, qi ? qi->cursor : NULL)) { CC_set_errornumber(self, CONNECTION_COULD_NOT_RECEIVE); if (res) QR_Destructor(res); CC_set_errormsg(self, QR_get_message(result_in)); return NULL; } } else { /* next fetch, so reuse an existing result */ if ( ! QR_fetch_tuples(result_in, NULL, NULL)) { CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(result_in)); if (res) QR_Destructor(res); return NULL; } } return result_in; case 'D': /* Copy in command began successfully */ if (res) QR_Destructor(res); res = QR_Constructor(); QR_set_status(res, PGRES_COPY_IN); return res; case 'B': /* Copy out command began successfully */ if (res) QR_Destructor(res); res = QR_Constructor(); QR_set_status(res, PGRES_COPY_OUT); return res; default: CC_set_error(self, CONNECTION_BACKEND_CRAZY, "Unexpected protocol character from backend (send_query)"); CC_set_no_trans(self); mylog("send_query: error - %s\n", CC_get_errormsg(self)); if (res) QR_Destructor(res); return NULL; } } } int CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *args, int nargs) { char id, c, done; SocketClass *sock = self->sock; static char msgbuffer[MAX_MESSAGE_LEN+1]; int i; mylog("send_function(): conn=%u, fnid=%d, result_is_int=%d, nargs=%d\n", self, fnid, result_is_int, nargs); if (SOCK_get_errcode(sock) != 0) { CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send function to backend"); CC_set_no_trans(self); return FALSE; } SOCK_put_string(sock, "F "); if (SOCK_get_errcode(sock) != 0) { CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send function to backend"); CC_set_no_trans(self); return FALSE; } SOCK_put_int(sock, fnid, 4); SOCK_put_int(sock, nargs, 4); mylog("send_function: done sending function\n"); for (i = 0; i < nargs; ++i) { mylog(" arg[%d]: len = %d, isint = %d, integer = %d, ptr = %u\n", i, args[i].len, args[i].isint, args[i].u.integer, args[i].u.ptr); SOCK_put_int(sock, args[i].len, 4); if (args[i].isint) SOCK_put_int(sock, args[i].u.integer, 4); else SOCK_put_n_char(sock, (char *) args[i].u.ptr, args[i].len); } mylog(" done sending args\n"); SOCK_flush_output(sock); mylog(" after flush output\n"); done = FALSE; while ( ! done) { id = SOCK_get_char(sock); mylog(" got id = %c\n", id); switch(id) { case 'V': done = TRUE; break; /* ok */ case 'N': SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); mylog("send_function(V): 'N' - %s\n", msgbuffer); /* continue reading */ break; case 'E': SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); CC_set_errormsg(self, msgbuffer); mylog("send_function(V): 'E' - %s\n", msgbuffer); qlog("ERROR from backend during send_function: '%s'\n", msgbuffer); return FALSE; case 'Z': break; default: CC_set_error(self, CONNECTION_BACKEND_CRAZY, "Unexpected protocol character from backend (send_function, args)"); CC_set_no_trans(self); mylog("send_function: error - %s\n", CC_get_errormsg(self)); return FALSE; } } id = SOCK_get_char(sock); for (;;) { switch (id) { case 'G': /* function returned properly */ mylog(" got G!\n"); *actual_result_len = SOCK_get_int(sock, 4); mylog(" actual_result_len = %d\n", *actual_result_len); if (result_is_int) *((int *) result_buf) = SOCK_get_int(sock, 4); else SOCK_get_n_char(sock, (char *) result_buf, *actual_result_len); mylog(" after get result\n"); c = SOCK_get_char(sock); /* get the last '0' */ mylog(" after get 0\n"); return TRUE; case 'E': SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); CC_set_errormsg(self, msgbuffer); mylog("send_function(G): 'E' - %s\n", msgbuffer); qlog("ERROR from backend during send_function: '%s'\n", msgbuffer); return FALSE; case 'N': SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); mylog("send_function(G): 'N' - %s\n", msgbuffer); qlog("NOTICE from backend during send_function: '%s'\n", msgbuffer); continue; /* dont return a result -- continue reading */ case '0': /* empty result */ return TRUE; default: CC_set_error(self, CONNECTION_BACKEND_CRAZY, "Unexpected protocol character from backend (send_function, result)"); CC_set_no_trans(self); mylog("send_function: error - %s\n", CC_get_errormsg(self)); return FALSE; } } } char CC_send_settings(ConnectionClass *self) { /* char ini_query[MAX_MESSAGE_LEN]; */ ConnInfo *ci = &(self->connInfo); /* QResultClass *res; */ HSTMT hstmt; StatementClass *stmt; RETCODE result; char status = TRUE; char *cs, *ptr; static char* const func="CC_send_settings"; mylog("%s: entering...\n", func); /* This function must use the local odbc API functions since the odbc state has not transitioned to "connected" yet. */ result = PG_SQLAllocStmt( self, &hstmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { return FALSE; } stmt = (StatementClass *) hstmt; stmt->internal = TRUE; /* ensure no BEGIN/COMMIT/ABORT stuff */ /* Set the Datestyle to the format the driver expects it to be in */ result = PG_SQLExecDirect(hstmt, "set DateStyle to 'ISO'", SQL_NTS); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; mylog("%s: result %d, status %d from set DateStyle\n", func, result, status); /* Disable genetic optimizer based on global flag */ if (globals.disable_optimizer) { result = PG_SQLExecDirect(hstmt, "set geqo to 'OFF'", SQL_NTS); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; mylog("%s: result %d, status %d from set geqo\n", func, result, status); } /* KSQO */ if (globals.ksqo) { result = PG_SQLExecDirect(hstmt, "set ksqo to 'ON'", SQL_NTS); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; mylog("%s: result %d, status %d from set ksqo\n", func, result, status); } /* Global settings */ if (globals.conn_settings[0] != '\0') { cs = strdup(globals.conn_settings); ptr = strtok(cs, ";"); while (ptr) { result = PG_SQLExecDirect(hstmt, ptr, SQL_NTS); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; mylog("%s: result %d, status %d from '%s'\n", func, result, status, ptr); ptr = strtok(NULL, ";"); } free(cs); } /* Per Datasource settings */ if (ci->conn_settings[0] != '\0') { cs = strdup(ci->conn_settings); ptr = strtok(cs, ";"); while (ptr) { result = PG_SQLExecDirect(hstmt, ptr, SQL_NTS); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; mylog("%s: result %d, status %d from '%s'\n", func, result, status, ptr); ptr = strtok(NULL, ";"); } free(cs); } PG_SQLFreeStmt(hstmt, SQL_DROP); return status; } /* This function is just a hack to get the oid of our Large Object oid type. If a real Large Object oid type is made part of Postgres, this function will go away and the define 'PG_TYPE_LO' will be updated. */ void CC_lookup_lo(ConnectionClass *self) { HSTMT hstmt; StatementClass *stmt; RETCODE result; static char* const func = "CC_lookup_lo"; mylog( "%s: entering...\n", func); /* This function must use the local odbc API functions since the odbc state has not transitioned to "connected" yet. */ result = PG_SQLAllocStmt( self, &hstmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { return; } stmt = (StatementClass *) hstmt; result = PG_SQLExecDirect(hstmt, "select oid from pg_type where typname='" PG_TYPE_LO_NAME "'", SQL_NTS); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { PG_SQLFreeStmt(hstmt, SQL_DROP); return; } result = PG_SQLFetch(hstmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { PG_SQLFreeStmt(hstmt, SQL_DROP); return; } result = PG_SQLGetData(hstmt, 1, SQL_C_SLONG, &self->lobj_type, sizeof(self->lobj_type), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { PG_SQLFreeStmt(hstmt, SQL_DROP); return; } mylog("Got the large object oid: %d\n", self->lobj_type); qlog(" [ Large Object oid = %d ]\n", self->lobj_type); result = PG_SQLFreeStmt(hstmt, SQL_DROP); } /* This function initializes the version of PostgreSQL from connInfo.protocol that we're connected to. h-inoue 01-2-2001 */ void CC_initialize_pg_version(ConnectionClass *self) { strcpy(self->pg_version, self->connInfo.protocol); if (PROTOCOL_62(&self->connInfo)) { self->pg_version_number = (float) 6.2; self->pg_version_major = 6; self->pg_version_minor = 2; } else if (PROTOCOL_63(&self->connInfo)) { self->pg_version_number = (float) 6.3; self->pg_version_major = 6; self->pg_version_minor = 3; } else { self->pg_version_number = (float) 6.4; self->pg_version_major = 6; self->pg_version_minor = 4; } } /* This function gets the version of PostgreSQL that we're connected to. This is used to return the correct info in SQLGetInfo DJP - 25-1-2001 */ void CC_lookup_pg_version(ConnectionClass *self) { HSTMT hstmt; StatementClass *stmt; RETCODE result; char szVersion[32]; int major, minor; static char* const func = "CC_lookup_pg_version"; mylog( "%s: entering...\n", func); /* This function must use the local odbc API functions since the odbc state has not transitioned to "connected" yet. */ result = PG_SQLAllocStmt( self, &hstmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { return; } stmt = (StatementClass *) hstmt; /* get the server's version if possible */ result = PG_SQLExecDirect(hstmt, "select version()", SQL_NTS); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { PG_SQLFreeStmt(hstmt, SQL_DROP); return; } result = PG_SQLFetch(hstmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { PG_SQLFreeStmt(hstmt, SQL_DROP); return; } result = PG_SQLGetData(hstmt, 1, SQL_C_CHAR, self->pg_version, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { PG_SQLFreeStmt(hstmt, SQL_DROP); return; } /* Extract the Major and Minor numbers from the string. */ /* This assumes the string starts 'Postgresql X.X' */ strcpy(szVersion, "0.0"); if (sscanf(self->pg_version, "%*s %d.%d", &major, &minor) >= 2) { sprintf(szVersion, "%d.%d", major, minor); self->pg_version_major = major; self->pg_version_minor = minor; } self->pg_version_number = (float) atof(szVersion); mylog("Got the PostgreSQL version string: '%s'\n", self->pg_version); mylog("Extracted PostgreSQL version number: '%1.1f'\n", self->pg_version_number); qlog(" [ PostgreSQL version string = '%s' ]\n", self->pg_version); qlog(" [ PostgreSQL version number = '%1.1f' ]\n", self->pg_version_number); result = PG_SQLFreeStmt(hstmt, SQL_DROP); } void CC_log_error(char *func, char *desc, ConnectionClass *self) { #ifdef PRN_NULLCHECK #define nullcheck(a) (a ? a : "(NULL)") #endif if (self) { qlog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->__error_number, nullcheck (self->__error_message)); mylog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->__error_number, nullcheck (self->__error_message)); qlog(" ------------------------------------------------------------\n"); qlog(" henv=%u, conn=%u, status=%u, num_stmts=%d\n", self->henv, self, self->status, self->num_stmts); qlog(" sock=%u, stmts=%u, lobj_type=%d\n", self->sock, self->stmts, self->lobj_type); qlog(" ---------------- Socket Info -------------------------------\n"); if (self->sock) { SocketClass *sock = self->sock; qlog(" socket=%d, reverse=%d, errornumber=%d, errormsg='%s'\n", sock->socket, sock->reverse, sock->errornumber, nullcheck(sock->errormsg)); qlog(" buffer_in=%u, buffer_out=%u\n", sock->buffer_in, sock->buffer_out); qlog(" buffer_filled_in=%d, buffer_filled_out=%d, buffer_read_in=%d\n", sock->buffer_filled_in, sock->buffer_filled_out, sock->buffer_read_in); } } else qlog("INVALID CONNECTION HANDLE ERROR: func=%s, desc='%s'\n", func, desc); #undef PRN_NULLCHECK } unixODBC-2.3.12/Drivers/Postgre7.1/connection.h000066400000000000000000000245611446441710500210270ustar00rootroot00000000000000 /* File: connection.h * * Description: See "connection.c" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __CONNECTION_H__ #define __CONNECTION_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "psqlodbc.h" #ifndef WIN32 #include "isql.h" #include "isqlext.h" #else #include #include #include #endif typedef enum { CONN_NOT_CONNECTED, /* Connection has not been established */ CONN_CONNECTED, /* Connection is up and has been established */ CONN_DOWN, /* Connection is broken */ CONN_EXECUTING /* the connection is currently executing a statement */ } CONN_Status; /* These errors have general sql error state */ #define CONNECTION_SERVER_NOT_REACHED 101 #define CONNECTION_MSG_TOO_LONG 103 #define CONNECTION_COULD_NOT_SEND 104 #define CONNECTION_NO_SUCH_DATABASE 105 #define CONNECTION_BACKEND_CRAZY 106 #define CONNECTION_NO_RESPONSE 107 #define CONNECTION_SERVER_REPORTED_ERROR 108 #define CONNECTION_COULD_NOT_RECEIVE 109 #define CONNECTION_SERVER_REPORTED_WARNING 110 #define CONNECTION_NEED_PASSWORD 112 /* These errors correspond to specific SQL states */ #define CONN_INIREAD_ERROR 201 #define CONN_OPENDB_ERROR 202 #define CONN_STMT_ALLOC_ERROR 203 #define CONN_IN_USE 204 #define CONN_UNSUPPORTED_OPTION 205 /* Used by SetConnectoption to indicate unsupported options */ #define CONN_INVALID_ARGUMENT_NO 206 /* SetConnectOption: corresponds to ODBC--"S1009" */ #define CONN_TRANSACT_IN_PROGRES 207 #define CONN_NO_MEMORY_ERROR 208 #define CONN_NOT_IMPLEMENTED_ERROR 209 #define CONN_INVALID_AUTHENTICATION 210 #define CONN_AUTH_TYPE_UNSUPPORTED 211 #define CONN_UNABLE_TO_LOAD_DLL 212 #define CONN_OPTION_VALUE_CHANGED 213 #define CONN_VALUE_OUT_OF_RANGE 214 #define CONN_TRUNCATED 215 /* Conn_status defines */ #define CONN_IN_AUTOCOMMIT 0x01 #define CONN_IN_TRANSACTION 0x02 /* AutoCommit functions */ #define CC_set_autocommit_off(x) (x->transact_status &= ~CONN_IN_AUTOCOMMIT) #define CC_set_autocommit_on(x) (x->transact_status |= CONN_IN_AUTOCOMMIT) #define CC_is_in_autocommit(x) (x->transact_status & CONN_IN_AUTOCOMMIT) /* Transaction in/not functions */ #define CC_set_in_trans(x) (x->transact_status |= CONN_IN_TRANSACTION) #define CC_set_no_trans(x) (x->transact_status &= ~CONN_IN_TRANSACTION) #define CC_is_in_trans(x) (x->transact_status & CONN_IN_TRANSACTION) #define CC_get_errornumber(x) (x->__error_number) #define CC_get_errormsg(x) (x->__error_message) #define CC_set_errornumber(x, n) (x->__error_number = n) /* Authentication types */ #define AUTH_REQ_OK 0 #define AUTH_REQ_KRB4 1 #define AUTH_REQ_KRB5 2 #define AUTH_REQ_PASSWORD 3 #define AUTH_REQ_CRYPT 4 #define AUTH_REQ_MD5 5 #define AUTH_REQ_SCM_CREDS 6 /* Startup Packet sizes */ #define SM_DATABASE 64 #define SM_USER 32 #define SM_OPTIONS 64 #define SM_UNUSED 64 #define SM_TTY 64 /* Old 6.2 protocol defines */ #define NO_AUTHENTICATION 7 #define PATH_SIZE 64 #define ARGV_SIZE 64 #define NAMEDATALEN 16 typedef unsigned int ProtocolVersion; #define PG_PROTOCOL(major, minor) (((major) << 16) | (minor)) #define PG_PROTOCOL_LATEST PG_PROTOCOL(2, 0) #define PG_PROTOCOL_63 PG_PROTOCOL(1, 0) #define PG_PROTOCOL_62 PG_PROTOCOL(0, 0) /* This startup packet is to support latest Postgres protocol (6.4, 6.3) */ typedef struct _StartupPacket { ProtocolVersion protoVersion; char database[SM_DATABASE]; char user[SM_USER]; char options[SM_OPTIONS]; char unused[SM_UNUSED]; char tty[SM_TTY]; } StartupPacket; /* This startup packet is to support pre-Postgres 6.3 protocol */ typedef struct _StartupPacket6_2 { unsigned int authtype; char database[PATH_SIZE]; char user[NAMEDATALEN]; char options[ARGV_SIZE]; char execfile[ARGV_SIZE]; char tty[PATH_SIZE]; } StartupPacket6_2; /* Structure to hold all the connection attributes for a specific connection (used for both registry and file, DSN and DRIVER) */ typedef struct { char dsn[MEDIUM_REGISTRY_LEN]; char desc[MEDIUM_REGISTRY_LEN]; char driver[MEDIUM_REGISTRY_LEN]; char server[MEDIUM_REGISTRY_LEN]; char database[MEDIUM_REGISTRY_LEN]; char username[MEDIUM_REGISTRY_LEN]; char password[MEDIUM_REGISTRY_LEN]; char conn_settings[LARGE_REGISTRY_LEN]; char protocol[SMALL_REGISTRY_LEN]; char port[SMALL_REGISTRY_LEN]; char uds[LARGE_REGISTRY_LEN]; char onlyread[SMALL_REGISTRY_LEN]; char fake_oid_index[SMALL_REGISTRY_LEN]; char show_oid_column[SMALL_REGISTRY_LEN]; char row_versioning[SMALL_REGISTRY_LEN]; char show_system_tables[SMALL_REGISTRY_LEN]; char translation_dll[MEDIUM_REGISTRY_LEN]; char translation_option[SMALL_REGISTRY_LEN]; char focus_password; } ConnInfo; /* Macro to determine is the connection using 6.2 protocol? */ #define PROTOCOL_62(conninfo_) (strncmp((conninfo_)->protocol, PG62, strlen(PG62)) == 0) /* Macro to determine is the connection using 6.3 protocol? */ #define PROTOCOL_63(conninfo_) (strncmp((conninfo_)->protocol, PG63, strlen(PG63)) == 0) /* * Macros to compare the server's version with a specified version * 1st parameter: pointer to a ConnectionClass object * 2nd parameter: major version number * 3rd parameter: minor version number */ #define SERVER_VERSION_GT(conn, major, minor) \ ((conn)->pg_version_major > major || \ ((conn)->pg_version_major == major && (conn)->pg_version_minor > minor)) #define SERVER_VERSION_GE(conn, major, minor) \ ((conn)->pg_version_major > major || \ ((conn)->pg_version_major == major && (conn)->pg_version_minor >= minor)) #define SERVER_VERSION_EQ(conn, major, minor) \ ((conn)->pg_version_major == major && (conn)->pg_version_minor == minor) #define SERVER_VERSION_LE(conn, major, minor) (! SERVER_VERSION_GT(conn, major, minor)) #define SERVER_VERSION_LT(conn, major, minor) (! SERVER_VERSION_GE(conn, major, minor)) /*#if ! defined(HAVE_CONFIG_H) || defined(HAVE_STRINGIZE)*/ #define STRING_AFTER_DOT(string) (strchr(#string, '.') + 1) /*#else #define STRING_AFTER_DOT(str) (strchr("str", '.') + 1) #endif*/ /* * Simplified macros to compare the server's version with a * specified version * Note: Never pass a variable as the second parameter. * It must be a decimal constant of the form %d.%d . */ #define PG_VERSION_GT(conn, ver) \ (SERVER_VERSION_GT(conn, (int) ver, atoi(STRING_AFTER_DOT(ver)))) #define PG_VERSION_GE(conn, ver) \ (SERVER_VERSION_GE(conn, (int) ver, atoi(STRING_AFTER_DOT(ver)))) #define PG_VERSION_EQ(conn, ver) \ (SERVER_VERSION_EQ(conn, (int) ver, atoi(STRING_AFTER_DOT(ver)))) #define PG_VERSION_LE(conn, ver) (! PG_VERSION_GT(conn, ver)) #define PG_VERSION_LT(conn, ver) (! PG_VERSION_GE(conn, ver)) /* This is used to store cached table information in the connection */ struct col_info { QResultClass *result; char name[MAX_TABLE_LEN+1]; }; /* Translation DLL entry points */ #ifdef WIN32 #define DLLHANDLE HINSTANCE #else #define WINAPI CALLBACK #define DLLHANDLE void * #define HINSTANCE void * #endif typedef BOOL (FAR WINAPI *DataSourceToDriverProc) (UDWORD, SWORD, PTR, SDWORD, PTR, SDWORD, SDWORD FAR *, UCHAR FAR *, SWORD, SWORD FAR *); typedef BOOL (FAR WINAPI *DriverToDataSourceProc) (UDWORD, SWORD, PTR, SDWORD, PTR, SDWORD, SDWORD FAR *, UCHAR FAR *, SWORD, SWORD FAR *); /******* The Connection handle ************/ struct ConnectionClass_ { HENV henv; /* environment this connection was created on */ StatementOptions stmtOptions; char *__error_message; int __error_number; CONN_Status status; ConnInfo connInfo; StatementClass **stmts; int num_stmts; SocketClass *sock; int lobj_type; int ntables; COL_INFO **col_info; long translation_option; HINSTANCE translation_handle; DataSourceToDriverProc DataSourceToDriver; DriverToDataSourceProc DriverToDataSource; Int2 driver_version; /* prepared for ODBC3.0 */ char transact_status; /* Is a transaction is currently in progress */ char errormsg_created; /* has an informative error msg been created? */ char pg_version[MAX_INFO_STRING]; /* Version of PostgreSQL we're connected to - DJP 25-1-2001 */ float pg_version_number; Int2 pg_version_major; Int2 pg_version_minor; char ms_jet; char unicode; char result_uncommitted; char schema_support; char *client_encoding; char *server_encoding; int ccsc; int be_pid; /* pid returned by backend */ int be_key; /* auth code needed to send cancel */ UInt4 isolation; char *current_schema; int num_discardp; char **discardp; #if (ODBCVER >= 0x0300) int num_descs; DescriptorClass **descs; #endif /* ODBCVER */ #if defined(WIN_MULTITHREAD_SUPPORT) CRITICAL_SECTION cs; #elif defined(POSIX_THREADMUTEX_SUPPORT) pthread_mutex_t cs; #endif /* WIN_MULTITHREAD_SUPPORT */ }; /* Accessor functions */ #define CC_get_socket(x) (x->sock) #define CC_get_database(x) (x->connInfo.database) #define CC_get_server(x) (x->connInfo.server) #define CC_get_DSN(x) (x->connInfo.dsn) #define CC_get_username(x) (x->connInfo.username) #define CC_is_onlyread(x) (x->connInfo.onlyread[0] == '1') /* for CC_DSN_info */ #define CONN_DONT_OVERWRITE 0 #define CONN_OVERWRITE 1 /* prototypes */ ConnectionClass *CC_Constructor(void); char CC_Destructor(ConnectionClass *self); int CC_cursor_count(ConnectionClass *self); char CC_cleanup(ConnectionClass *self); char CC_abort(ConnectionClass *self); int CC_set_translation (ConnectionClass *self); char CC_connect(ConnectionClass *self, char password_req, char *salt_para); char CC_add_statement(ConnectionClass *self, StatementClass *stmt); char CC_remove_statement(ConnectionClass *self, StatementClass *stmt); void CC_set_error(ConnectionClass *self, int number, const char *message); void CC_set_errormsg(ConnectionClass *self, const char *message); char CC_get_error(ConnectionClass *self, int *number, char **message); QResultClass *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi); void CC_clear_error(ConnectionClass *self); char *CC_create_errormsg(ConnectionClass *self); int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs); char CC_send_settings(ConnectionClass *self); void CC_lookup_lo(ConnectionClass *conn); void CC_lookup_pg_version(ConnectionClass *conn); void CC_initialize_pg_version(ConnectionClass *conn); void CC_log_error(char *func, char *desc, ConnectionClass *self); #endif unixODBC-2.3.12/Drivers/Postgre7.1/convert.c000066400000000000000000001277171446441710500203520ustar00rootroot00000000000000 /* Module: convert.c * * Description: This module contains routines related to * converting parameters and columns into requested data types. * Parameters are converted from their SQL_C data types into * the appropriate postgres type. Columns are converted from * their postgres type (SQL type) into the appropriate SQL_C * data type. * * Classes: n/a * * API functions: none * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "psqlodbc.h" #ifndef WIN32 #include "isql.h" #include "isqlext.h" #else #include #include #include #endif #include #ifdef HAVE_LOCALE_H #include #endif #include #include "convert.h" #include "statement.h" #include "qresult.h" #include "bind.h" #include "pgtypes.h" #include "lobj.h" #include "connection.h" #ifndef WIN32 #ifndef HAVE_STRICMP #define stricmp(s1,s2) strcasecmp(s1,s2) #define strnicmp(s1,s2,n) strncasecmp(s1,s2,n) #endif #endif extern GLOBAL_VALUES globals; /* How to map ODBC scalar functions {fn func(args)} to Postgres * This is just a simple substitution * List augmented from * http://www.merant.com/datadirect/download/docs/odbc16/Odbcref/rappc.htm * - thomas 2000-04-03 */ char* const mapFuncs[][2] = { /* { "ASCII", "ascii" }, */ { "CHAR", "chr" }, { "CONCAT", "textcat" }, /* { "DIFFERENCE", "difference" }, */ /* { "INSERT", "insert" }, */ { "LCASE", "lower" }, { "LEFT", "ltrunc" }, { "LOCATE", "strpos" }, { "LENGTH", "char_length"}, /* { "LTRIM", "ltrim" }, */ { "RIGHT", "rtrunc" }, /* { "REPEAT", "repeat" }, */ /* { "REPLACE", "replace" }, */ /* { "RTRIM", "rtrim" }, */ /* { "SOUNDEX", "soundex" }, */ { "SUBSTRING", "substr" }, { "UCASE", "upper" }, /* { "ABS", "abs" }, */ /* { "ACOS", "acos" }, */ /* { "ASIN", "asin" }, */ /* { "ATAN", "atan" }, */ /* { "ATAN2", "atan2" }, */ { "CEILING", "ceil" }, /* { "COS", "cos" }, */ /* { "COT", "cot" }, */ /* { "DEGREES", "degrees" }, */ /* { "EXP", "exp" }, */ /* { "FLOOR", "floor" }, */ { "LOG", "ln" }, { "LOG10", "log" }, /* { "MOD", "mod" }, */ /* { "PI", "pi" }, */ { "POWER", "pow" }, /* { "RADIANS", "radians" }, */ { "RAND", "random" }, /* { "ROUND", "round" }, */ /* { "SIGN", "sign" }, */ /* { "SIN", "sin" }, */ /* { "SQRT", "sqrt" }, */ /* { "TAN", "tan" }, */ { "TRUNCATE", "trunc" }, /* { "CURDATE", "curdate" }, */ /* { "CURTIME", "curtime" }, */ /* { "DAYNAME", "dayname" }, */ /* { "DAYOFMONTH", "dayofmonth" }, */ /* { "DAYOFWEEK", "dayofweek" }, */ /* { "DAYOFYEAR", "dayofyear" }, */ /* { "HOUR", "hour" }, */ /* { "MINUTE", "minute" }, */ /* { "MONTH", "month" }, */ /* { "MONTHNAME", "monthname" }, */ /* { "NOW", "now" }, */ /* { "QUARTER", "quarter" }, */ /* { "SECOND", "second" }, */ /* { "WEEK", "week" }, */ /* { "YEAR", "year" }, */ /* { "DATABASE", "database" }, */ { "IFNULL", "coalesce" }, { "USER", "odbc_user" }, { 0, 0 } }; char *mapFunction(char *func); unsigned int conv_from_octal(unsigned char *s); unsigned int conv_from_hex(unsigned char *s); char *conv_to_octal(unsigned char val); /******** A Guide for date/time/timestamp conversions ************** field_type fCType Output ---------- ------ ---------- PG_TYPE_DATE SQL_C_DEFAULT SQL_C_DATE PG_TYPE_DATE SQL_C_DATE SQL_C_DATE PG_TYPE_DATE SQL_C_TIMESTAMP SQL_C_TIMESTAMP (time = 0 (midnight)) PG_TYPE_TIME SQL_C_DEFAULT SQL_C_TIME PG_TYPE_TIME SQL_C_TIME SQL_C_TIME PG_TYPE_TIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP (date = current date) PG_TYPE_ABSTIME SQL_C_DEFAULT SQL_C_TIMESTAMP PG_TYPE_ABSTIME SQL_C_DATE SQL_C_DATE (time is truncated) PG_TYPE_ABSTIME SQL_C_TIME SQL_C_TIME (date is truncated) PG_TYPE_ABSTIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP ******************************************************************************/ /* This is called by SQLFetch() */ int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col) { BindInfoClass *bic = &(stmt->bindings[col]); return copy_and_convert_field(stmt, field_type, value, (Int2)bic->returntype, (PTR)bic->buffer, (SDWORD)bic->buflen, (SQLLEN *)bic->used); } static void setup_ts( SIMPLE_TIME st ) { time_t t = time( NULL ); struct tm *tim; #ifdef HAVE_LOCALTIME_R struct tm tp; #endif #ifdef HAVE_LOCALTIME_R tim = localtime_r(&t, &tp); #else tim = localtime(&t); #endif st.m = tim->tm_mon + 1; st.d = tim->tm_mday; st.y = tim->tm_year + 1900; st.hh = tim->tm_hour; st.mm = tim->tm_min; st.ss = tim->tm_sec; } /* This is called by SQLGetData() */ int copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType, PTR rgbValue, SDWORD cbValueMax, SQLLEN *pcbValue) { Int4 len = 0, copy_len = 0; SIMPLE_TIME st; time_t t; struct tm *tim; int pcbValueOffset, rgbValueOffset; char *rgbValueBindRow, *ptr; int bind_row = stmt->bind_row; int bind_size = stmt->options.bind_size; int result = COPY_OK; /* char tempBuf[TEXT_FIELD_SIZE+5]; */ char *tempBuf; #ifdef HAVE_LOCALE_H char saved_locale[256]; #endif #ifdef HAVE_LOCALTIME_R struct tm tp; #endif /* rgbValueOffset is *ONLY* for character and binary data */ /* pcbValueOffset is for computing any pcbValue location */ tempBuf = (char *) malloc(TEXT_FIELD_SIZE+5); if (bind_size > 0) { pcbValueOffset = rgbValueOffset = (bind_size * bind_row); } else { pcbValueOffset = bind_row * sizeof(SDWORD); rgbValueOffset = bind_row * cbValueMax; } memset(&st, 0, sizeof(SIMPLE_TIME)); mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, (value==NULL)?"":value, cbValueMax); if ( ! value) { /* handle a null just by returning SQL_NULL_DATA in pcbValue, */ /* and doing nothing to the buffer. */ if(pcbValue) { *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = SQL_NULL_DATA; } free(tempBuf); return COPY_OK; } if (stmt->hdbc->DataSourceToDriver != NULL) { int length = strlen (value); stmt->hdbc->DataSourceToDriver (stmt->hdbc->translation_option, SQL_CHAR, value, length, value, length, NULL, NULL, 0, NULL); } /******************************************************************** First convert any specific postgres types into more useable data. NOTE: Conversions from PG char/varchar of a date/time/timestamp value to SQL_C_DATE,SQL_C_TIME, SQL_C_TIMESTAMP not supported *********************************************************************/ switch(field_type) { /* $$$ need to add parsing for date/time/timestamp strings in PG_TYPE_CHAR,VARCHAR $$$ */ case PG_TYPE_DATE: setup_ts( st ); sscanf(value, "%4d-%2d-%2d", &st.y, &st.m, &st.d); break; case PG_TYPE_TIME: setup_ts( st ); sscanf(value, "%2d:%2d:%2d", &st.hh, &st.mm, &st.ss); break; case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP: case PG_TYPE_TIMESTAMP_NO_TMZONE: setup_ts( st ); if (strnicmp(value, "invalid", 7) != 0) { sscanf(value, "%4d-%2d-%2d %2d:%2d:%2d", &st.y, &st.m, &st.d, &st.hh, &st.mm, &st.ss); } else { /* The timestamp is invalid so set something conspicuous, like the epoch */ t = 0; #ifdef HAVE_LOCALTIME_R tim = localtime_r(&t, &tp); #else tim = localtime(&t); #endif st.m = tim->tm_mon + 1; st.d = tim->tm_mday; st.y = tim->tm_year + 1900; st.hh = tim->tm_hour; st.mm = tim->tm_min; st.ss = tim->tm_sec; } break; case PG_TYPE_BOOL: { /* change T/F to 1/0 */ char *s = (char *) value; if (s[0] == 'T' || s[0] == 't') s[0] = '1'; else s[0] = '0'; } break; /* This is for internal use by SQLStatistics() */ case PG_TYPE_INT2VECTOR: { int nval, i; char *vp; /* this is an array of eight integers */ short *short_array = (short *) ( (char *) rgbValue + rgbValueOffset); len = 16; vp = value; nval = 0; for (i = 0; i < 8; i++) { if (sscanf(vp, "%hd", &short_array[i]) != 1) break; nval++; /* skip the current token */ while ((*vp != '\0') && (! isspace((unsigned char) *vp))) vp++; /* and skip the space to the next token */ while ((*vp != '\0') && (isspace((unsigned char) *vp))) vp++; if (*vp == '\0') break; } for (i = nval; i < 8; i++) { short_array[i] = 0; } #if 0 sscanf(value, "%hd %hd %hd %hd %hd %hd %hd %hd", &short_array[0], &short_array[1], &short_array[2], &short_array[3], &short_array[4], &short_array[5], &short_array[6], &short_array[7]); #endif /* There is no corresponding fCType for this. */ if(pcbValue) *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = len; free(tempBuf); return COPY_OK; /* dont go any further or the data will be trashed */ } /* This is a large object OID, which is used to store LONGVARBINARY objects. */ case PG_TYPE_LO: free(tempBuf); return convert_lo( stmt, value, fCType, ((char *) rgbValue + rgbValueOffset), cbValueMax, (SDWORD *) ((char *) pcbValue + pcbValueOffset)); default: if (field_type == stmt->hdbc->lobj_type) /* hack until permanent type available */ { free(tempBuf); return convert_lo( stmt, value, fCType, ((char *) rgbValue + rgbValueOffset), cbValueMax, (SDWORD *) ((char *) pcbValue + pcbValueOffset)); } } /* Change default into something useable */ if (fCType == SQL_C_DEFAULT) { fCType = pgtype_to_ctype(stmt, field_type); mylog("copy_and_convert, SQL_C_DEFAULT: fCType = %d\n", fCType); } rgbValueBindRow = (char *) rgbValue + rgbValueOffset; if(fCType == SQL_C_CHAR) { /* Special character formatting as required */ /* These really should return error if cbValueMax is not big enough. */ switch(field_type) { case PG_TYPE_DATE: len = 10; if (cbValueMax > len) sprintf(rgbValueBindRow, "%.4d-%.2d-%.2d", st.y, st.m, st.d); break; case PG_TYPE_TIME: len = 8; if (cbValueMax > len) sprintf(rgbValueBindRow, "%.2d:%.2d:%.2d", st.hh, st.mm, st.ss); break; case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP: case PG_TYPE_TIMESTAMP_NO_TMZONE: len = 19; if (cbValueMax > len) sprintf(rgbValueBindRow, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", st.y, st.m, st.d, st.hh, st.mm, st.ss); break; case PG_TYPE_BOOL: len = 1; if (cbValueMax > len) { strcpy(rgbValueBindRow, value); mylog("PG_TYPE_BOOL: rgbValueBindRow = '%s'\n", rgbValueBindRow); } break; /* Currently, data is SILENTLY TRUNCATED for BYTEA and character data types if there is not enough room in cbValueMax because the driver can't handle multiple calls to SQLGetData for these, yet. Most likely, the buffer passed in will be big enough to handle the maximum limit of postgres, anyway. LongVarBinary types are handled correctly above, observing truncation and all that stuff since there is essentially no limit on the large object used to store those. */ case PG_TYPE_BYTEA: /* convert binary data to hex strings (i.e, 255 = "FF") */ len = convert_pgbinary_to_char(value, rgbValueBindRow, cbValueMax); /***** THIS IS NOT PROPERLY IMPLEMENTED *****/ break; default: /* convert linefeeds to carriage-return/linefeed */ len = convert_linefeeds(value, tempBuf, TEXT_FIELD_SIZE+5); ptr = tempBuf; mylog("DEFAULT: len = %d, ptr = '%s'\n", len, ptr); if (stmt->current_col >= 0) { if (stmt->bindings[stmt->current_col].data_left == 0) { free( tempBuf ); return COPY_NO_DATA_FOUND; } else if (stmt->bindings[stmt->current_col].data_left > 0) { ptr += len - stmt->bindings[stmt->current_col].data_left; len = stmt->bindings[stmt->current_col].data_left; } else stmt->bindings[stmt->current_col].data_left = strlen(ptr); } if (cbValueMax > 0) { copy_len = (len >= cbValueMax) ? cbValueMax -1 : len; #ifdef HAVE_LOCALE_H switch (field_type) { case PG_TYPE_FLOAT4: case PG_TYPE_FLOAT8: case PG_TYPE_NUMERIC: { struct lconv *lc; char *new_string; int i, j, dplen; new_string = malloc( cbValueMax ); lc = localeconv(); dplen = strlen(lc->decimal_point); for (i = 0, j = 0; (j < cbValueMax - 1) && ptr[i]; i++) if (ptr[i] == '.') { if ((j + dplen) <= (cbValueMax - 1)) { strncpy(&new_string[j], lc->decimal_point, dplen); j += dplen; } else break; } else new_string[j++] = ptr[i]; new_string[j] = '\0'; strncpy_null(rgbValueBindRow, new_string, copy_len + 1); free(new_string); break; } default: /* Copy the data */ strncpy_null(rgbValueBindRow, ptr, copy_len + 1); } #else /* Copy the data */ strncpy_null(rgbValueBindRow, ptr, copy_len + 1); #endif /* Adjust data_left for next time */ if (stmt->current_col >= 0) { stmt->bindings[stmt->current_col].data_left -= copy_len; } } /* Finally, check for truncation so that proper status can be returned */ if ( len >= cbValueMax) result = COPY_RESULT_TRUNCATED; mylog(" SQL_C_CHAR, default: len = %d, cbValueMax = %d, rgbValueBindRow = '%s'\n", len, cbValueMax, rgbValueBindRow); break; } } else { /* for SQL_C_CHAR, it's probably ok to leave currency symbols in. But to convert to numeric types, it is necessary to get rid of those. */ if (field_type == PG_TYPE_MONEY) convert_money(value); switch(fCType) { case SQL_C_DATE: len = 6; { DATE_STRUCT *ds; if (bind_size > 0) { ds = (DATE_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); } else { ds = (DATE_STRUCT *) rgbValue + bind_row; } ds->year = st.y; ds->month = st.m; ds->day = st.d; } break; case SQL_C_TIME: len = 6; { TIME_STRUCT *ts; if (bind_size > 0) { ts = (TIME_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); } else { ts = (TIME_STRUCT *) rgbValue + bind_row; } ts->hour = st.hh; ts->minute = st.mm; ts->second = st.ss; } break; case SQL_C_TIMESTAMP: len = 16; { TIMESTAMP_STRUCT *ts; if (bind_size > 0) { ts = (TIMESTAMP_STRUCT *) ((char *) rgbValue + (bind_row * bind_size)); } else { ts = (TIMESTAMP_STRUCT *) rgbValue + bind_row; } ts->year = st.y; ts->month = st.m; ts->day = st.d; ts->hour = st.hh; ts->minute = st.mm; ts->second = st.ss; ts->fraction = 0; } break; case SQL_C_BIT: len = 1; if (bind_size > 0) { *(UCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); } else { *((UCHAR *)rgbValue + bind_row) = atoi(value); } /* mylog("SQL_C_BIT: val = %d, cb = %d, rgb=%d\n", atoi(value), cbValueMax, *((UCHAR *)rgbValue)); */ break; case SQL_C_STINYINT: case SQL_C_TINYINT: len = 1; if (bind_size > 0) { *(SCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); } else { *((SCHAR *) rgbValue + bind_row) = atoi(value); } break; case SQL_C_UTINYINT: len = 1; if (bind_size > 0) { *(UCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); } else { *((UCHAR *) rgbValue + bind_row) = atoi(value); } break; case SQL_C_FLOAT: #ifdef HAVE_LOCALE_H strcpy(saved_locale,setlocale(LC_ALL, NULL)); setlocale(LC_ALL, "C"); #endif len = 4; if (bind_size > 0) { *(SFLOAT *) ((char *) rgbValue + (bind_row * bind_size)) = (float) atof(value); } else { *((SFLOAT *)rgbValue + bind_row) = (float) atof(value); } #ifdef HAVE_LOCALE_H setlocale(LC_ALL, saved_locale); #endif break; case SQL_C_DOUBLE: #ifdef HAVE_LOCALE_H strcpy(saved_locale, setlocale(LC_ALL, NULL)); setlocale(LC_ALL, "C"); #endif len = 8; if (bind_size > 0) { *(SDOUBLE *) ((char *) rgbValue + (bind_row * bind_size)) = atof(value); } else { *((SDOUBLE *)rgbValue + bind_row) = atof(value); } #ifdef HAVE_LOCALE_H setlocale(LC_ALL, saved_locale); #endif break; case SQL_C_SSHORT: case SQL_C_SHORT: len = 2; if (bind_size > 0) { *(SWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); } else { *((SWORD *)rgbValue + bind_row) = atoi(value); } break; case SQL_C_USHORT: len = 2; if (bind_size > 0) { *(UWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value); } else { *((UWORD *)rgbValue + bind_row) = atoi(value); } break; case SQL_C_SLONG: case SQL_C_LONG: len = 4; if (bind_size > 0) { *(SDWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atol(value); } else { *((SDWORD *)rgbValue + bind_row) = atol(value); } break; case SQL_C_ULONG: len = 4; if (bind_size > 0) { *(UDWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atol(value); } else { *((UDWORD *)rgbValue + bind_row) = atol(value); } break; #ifdef HAVE_LONG_LONG case SQL_BIGINT: { long long lv; len = 8; #ifdef HAVE_ATOLL lv = atoll( value ); #elif HAVE_STROLL lv = strtoll( value, NULL, 10 ); #else lv = atol( value ); #endif if (bind_size > 0) { *(long long *) ((char *) rgbValue + (bind_row * bind_size)) = lv; } else { *((long long *)rgbValue + bind_row) = lv; } } break; #endif case SQL_C_BINARY: /* truncate if necessary */ /* convert octal escapes to bytes */ len = convert_from_pgbinary(value, (SQLCHAR*)tempBuf, TEXT_FIELD_SIZE+5); ptr = tempBuf; if (stmt->current_col >= 0) { /* No more data left for this column */ if (stmt->bindings[stmt->current_col].data_left == 0) { free(tempBuf); return COPY_NO_DATA_FOUND; } /* Second (or more) call to SQLGetData so move the pointer */ else if (stmt->bindings[stmt->current_col].data_left > 0) { ptr += len - stmt->bindings[stmt->current_col].data_left; len = stmt->bindings[stmt->current_col].data_left; } /* First call to SQLGetData so initialize data_left */ else stmt->bindings[stmt->current_col].data_left = len; } if (cbValueMax > 0) { copy_len = (len > cbValueMax) ? cbValueMax : len; /* Copy the data */ memcpy(rgbValueBindRow, ptr, copy_len); /* Adjust data_left for next time */ if (stmt->current_col >= 0) { stmt->bindings[stmt->current_col].data_left -= copy_len; } } /* Finally, check for truncation so that proper status can be returned */ if ( len > cbValueMax) result = COPY_RESULT_TRUNCATED; mylog("SQL_C_BINARY: len = %d, copy_len = %d\n", len, copy_len); break; default: free(tempBuf); return COPY_UNSUPPORTED_TYPE; } } /* store the length of what was copied, if there's a place for it */ if(pcbValue) { *(SDWORD *) ((char *)pcbValue + pcbValueOffset) = len; } free(tempBuf); return result; } /* This function inserts parameters into an SQL statements. It will also modify a SELECT statement for use with declare/fetch cursors. This function no longer does any dynamic memory allocation! */ int copy_statement_with_parameters(StatementClass *stmt) { static char* const func="copy_statement_with_parameters"; unsigned int opos, npos, oldstmtlen; char param_string[1024], tmp[256]; char * cbuf; /* [TEXT_FIELD_SIZE+5]; */ int param_number; Int2 param_ctype, param_sqltype; char *old_statement = stmt->statement; char *new_statement = stmt->stmt_with_params; SIMPLE_TIME st; time_t t = time(NULL); struct tm *tim; SDWORD used; char *buffer, *buf; char in_quote = FALSE; Oid lobj_oid; int lobj_fd, retval; stmt -> reexecute = 0; cbuf=(char *)malloc(TEXT_FIELD_SIZE+5); if ( ! old_statement) { SC_log_error(func, "No statement string", stmt); free(cbuf); return SQL_ERROR; } memset(&st, 0, sizeof(SIMPLE_TIME)); /* If the application hasn't set a cursor name, then generate one */ if ( stmt->cursor_name[0] == '\0') sprintf(stmt->cursor_name, "SQL_CUR%p", stmt); /* For selects, prepend a declare cursor to the statement */ if (stmt->statement_type == STMT_TYPE_SELECT && globals.use_declarefetch) { sprintf(new_statement, "declare %s cursor for ", stmt->cursor_name); npos = strlen(new_statement); } else { new_statement[0] = '0'; npos = 0; } param_number = -1; oldstmtlen = strlen(old_statement); for (opos = 0; opos < oldstmtlen; opos++) { /* Squeeze carriage-return/linefeed pairs to linefeed only */ if (old_statement[opos] == '\r' && opos+1 < oldstmtlen && old_statement[opos+1] == '\n') { continue; } /* Handle literals (date, time, timestamp) and ODBC scalar functions */ else if (old_statement[opos] == '{') { char *esc; char *begin = &old_statement[opos + 1]; char *end = strchr(begin, '}'); if ( ! end) continue; *end = '\0'; esc = convert_escape(begin); if (esc) { memcpy(&new_statement[npos], esc, strlen(esc)); npos += strlen(esc); } else { /* it's not a valid literal so just copy */ *end = '}'; new_statement[npos++] = old_statement[opos]; continue; } opos += end - begin + 1; *end = '}'; continue; } /* Can you have parameter markers inside of quotes? I dont think so. All the queries I've seen expect the driver to put quotes if needed. */ else if (old_statement[opos] == '?' && !in_quote) ; /* ok */ else { if (old_statement[opos] == '\'') in_quote = (in_quote ? FALSE : TRUE); new_statement[npos++] = old_statement[opos]; continue; } /****************************************************/ /* Its a '?' parameter alright */ /****************************************************/ param_number++; if (param_number >= stmt->parameters_allocated) { strcpy(&new_statement[npos], "NULL"); npos += strlen("NULL"); stmt -> reexecute = 1; continue; } /* Assign correct buffers based on data at exec param or not */ if ( stmt->parameters[param_number].data_at_exec) { used = stmt->parameters[param_number].EXEC_used ? *stmt->parameters[param_number].EXEC_used : SQL_NTS; buffer = stmt->parameters[param_number].EXEC_buffer; } else { used = stmt->parameters[param_number].used ? *stmt->parameters[param_number].used : SQL_NTS; buffer = stmt->parameters[param_number].buffer; } /* Handle NULL parameter data */ if (used == SQL_NULL_DATA) { strcpy(&new_statement[npos], "NULL"); npos += 4; continue; } /* If no buffer, and it's not null, then what the hell is it? Just leave it alone then. */ if ( ! buffer) { new_statement[npos++] = '?'; continue; } param_ctype = stmt->parameters[param_number].CType; param_sqltype = stmt->parameters[param_number].SQLType; mylog("copy_statement_with_params: from(fcType)=%d, to(fSqlType)=%d\n", param_ctype, param_sqltype); /* replace DEFAULT with something we can use */ if(param_ctype == SQL_C_DEFAULT) param_ctype = sqltype_to_default_ctype(param_sqltype); buf = NULL; param_string[0] = '\0'; cbuf[0] = '\0'; /* Convert input C type to a neutral format */ switch(param_ctype) { case SQL_C_BINARY: buf = buffer; break; #ifdef HAVE_LOCALE_H case SQL_C_CHAR: if (param_sqltype == SQL_NUMERIC || param_sqltype == SQL_DECIMAL || param_sqltype == SQL_FLOAT || param_sqltype == SQL_REAL || param_sqltype == SQL_DOUBLE) { struct lconv *lc; int i, j, dplen; lc = localeconv(); dplen = strlen(lc->decimal_point); for (i = 0, j = 0; j < sizeof(param_string)-1 && buffer[i]; ) if (!strncmp(&buffer[i], lc->decimal_point, dplen)) { param_string[j++] = '.'; i += dplen; } else param_string[j++] = buffer[i++]; param_string[j] = '\0'; break; } else buf = buffer; break; #else case SQL_C_CHAR: buf = buffer; break; #endif case SQL_C_DOUBLE: #ifdef HAVE_LOCALE_H strcpy(tmp, setlocale(LC_ALL, NULL)); setlocale(LC_ALL, "C"); #endif sprintf(param_string, "%g", *((SDOUBLE *) buffer)); #ifdef HAVE_LOCALE_H setlocale(LC_ALL, tmp); #endif break; case SQL_C_FLOAT: #ifdef HAVE_LOCALE_H strcpy(tmp, setlocale(LC_ALL, NULL)); setlocale(LC_ALL, "C"); #endif sprintf(param_string, "%g", *((SFLOAT *) buffer)); #ifdef HAVE_LOCALE_H setlocale(LC_ALL, tmp); #endif break; case SQL_C_SLONG: case SQL_C_LONG: #if (SIZEOF_LONG_INT == 4) sprintf(param_string, "%ld", #else sprintf(param_string, "%d", #endif *((SDWORD *) buffer)); break; case SQL_C_SSHORT: case SQL_C_SHORT: sprintf(param_string, "%d", *((SWORD *) buffer)); break; case SQL_C_STINYINT: case SQL_C_TINYINT: sprintf(param_string, "%d", *((SCHAR *) buffer)); break; case SQL_C_ULONG: #if (SIZEOF_LONG_INT == 4) sprintf(param_string, "%lu", #else sprintf(param_string, "%u", #endif *((UDWORD *) buffer)); break; case SQL_C_USHORT: sprintf(param_string, "%u", *((UWORD *) buffer)); break; case SQL_C_UTINYINT: sprintf(param_string, "%u", *((UCHAR *) buffer)); break; case SQL_C_BIT: { int i = *((UCHAR *) buffer); sprintf(param_string, "%d", i ? 1 : 0); break; } case SQL_C_DATE: { DATE_STRUCT *ds = (DATE_STRUCT *) buffer; setup_ts( st ); st.m = ds->month; st.d = ds->day; st.y = ds->year; break; } case SQL_C_TIME: { TIME_STRUCT *ts = (TIME_STRUCT *) buffer; setup_ts( st ); st.hh = ts->hour; st.mm = ts->minute; st.ss = ts->second; break; } case SQL_C_TIMESTAMP: { TIMESTAMP_STRUCT *tss = (TIMESTAMP_STRUCT *) buffer; setup_ts( st ); st.m = tss->month; st.d = tss->day; st.y = tss->year; st.hh = tss->hour; st.mm = tss->minute; st.ss = tss->second; mylog("m=%d,d=%d,y=%d,hh=%d,mm=%d,ss=%d\n", st.m, st.d, st.y, st.hh, st.mm, st.ss); break; } default: /* error */ SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Unrecognized C_parameter type in copy_statement_with_parameters"); new_statement[npos] = '\0'; /* just in case */ SC_log_error(func, "", stmt); free(cbuf); return SQL_ERROR; } /* Now that the input data is in a neutral format, convert it to the desired output format (sqltype) */ switch(param_sqltype) { case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: new_statement[npos++] = '\''; /* Open Quote */ /* it was a SQL_C_CHAR */ if (buf) { convert_special_chars(buf, &new_statement[npos], used); npos += strlen(&new_statement[npos]); } /* it was a numeric type */ else if (param_string[0] != '\0') { strcpy(&new_statement[npos], param_string); npos += strlen(param_string); } /* it was date,time,timestamp -- use m,d,y,hh,mm,ss */ else { setup_ts( st ); sprintf(tmp, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", st.y, st.m, st.d, st.hh, st.mm, st.ss); strcpy(&new_statement[npos], tmp); npos += strlen(tmp); } new_statement[npos++] = '\''; /* Close Quote */ break; case SQL_DATE: if (buf) { /* copy char data to time */ my_strcpy(cbuf, TEXT_FIELD_SIZE+5, buf, used); parse_datetime(cbuf, &st); } sprintf(tmp, "'%.4d-%.2d-%.2d'", st.y, st.m, st.d); strcpy(&new_statement[npos], tmp); npos += strlen(tmp); break; case SQL_TIME: if (buf) { /* copy char data to time */ my_strcpy(cbuf, TEXT_FIELD_SIZE+5, buf, used); parse_datetime(cbuf, &st); } sprintf(tmp, "'%.2d:%.2d:%.2d'", st.hh, st.mm, st.ss); strcpy(&new_statement[npos], tmp); npos += strlen(tmp); break; case SQL_TIMESTAMP: if (buf) { my_strcpy(cbuf, TEXT_FIELD_SIZE+5, buf, used); parse_datetime(cbuf, &st); } sprintf(tmp, "'%.4d-%.2d-%.2d %.2d:%.2d:%.2d'", st.y, st.m, st.d, st.hh, st.mm, st.ss); strcpy(&new_statement[npos], tmp); npos += strlen(tmp); break; case SQL_BINARY: case SQL_VARBINARY: /* non-ascii characters should be converted to octal */ new_statement[npos++] = '\''; /* Open Quote */ mylog("SQL_VARBINARY: about to call convert_to_pgbinary, used = %d\n", used); npos += convert_to_pgbinary((SQLCHAR*)buf, &new_statement[npos], used); new_statement[npos++] = '\''; /* Close Quote */ break; case SQL_LONGVARBINARY: if ( stmt->parameters[param_number].data_at_exec) { lobj_oid = stmt->parameters[param_number].lobj_oid; } else { /* begin transaction if needed */ if(!CC_is_in_trans(stmt->hdbc)) { QResultClass *res; char ok; res = CC_send_query(stmt->hdbc, "BEGIN", NULL); if (!res) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not begin (in-line) a transaction"); SC_log_error(func, "", stmt); free(cbuf); return SQL_ERROR; } ok = QR_command_successful(res); QR_Destructor(res); if (!ok) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not begin (in-line) a transaction"); SC_log_error(func, "", stmt); free(cbuf); return SQL_ERROR; } CC_set_in_trans(stmt->hdbc); } /* store the oid */ lobj_oid = odbc_lo_creat(stmt->hdbc, INV_READ | INV_WRITE); if (lobj_oid == 0) { SC_set_error(stmt, STMT_EXEC_ERROR, "Couldnt create (in-line) large object."); SC_log_error(func, "", stmt); free(cbuf); return SQL_ERROR; } /* store the fd */ lobj_fd = odbc_lo_open(stmt->hdbc, lobj_oid, INV_WRITE); if ( lobj_fd < 0) { SC_set_error(stmt, STMT_EXEC_ERROR, "Couldnt open (in-line) large object for writing."); SC_log_error(func, "", stmt); free(cbuf); return SQL_ERROR; } retval = odbc_lo_write(stmt->hdbc, lobj_fd, buffer, used); odbc_lo_close(stmt->hdbc, lobj_fd); /* commit transaction if needed */ if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) { QResultClass *res; char ok; res = CC_send_query(stmt->hdbc, "COMMIT", NULL); if (!res) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not commit (in-line) a transaction"); SC_log_error(func, "", stmt); free(cbuf); return SQL_ERROR; } ok = QR_command_successful(res); QR_Destructor(res); if (!ok) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not commit (in-line) a transaction"); SC_log_error(func, "", stmt); free(cbuf); return SQL_ERROR; } CC_set_no_trans(stmt->hdbc); } } /* the oid of the large object -- just put that in for the parameter marker -- the data has already been sent to the large object */ sprintf(param_string, "'%d'", lobj_oid); strcpy(&new_statement[npos], param_string); npos += strlen(param_string); break; /* because of no conversion operator for bool and int4, SQL_BIT */ /* must be quoted (0 or 1 is ok to use inside the quotes) */ case SQL_REAL: if (buf) my_strcpy(param_string, sizeof(param_string), buf, used); sprintf(tmp, "'%s'::float4", param_string); strcpy(&new_statement[npos], tmp); npos += strlen(tmp); break; case SQL_FLOAT: case SQL_DOUBLE: if (buf) my_strcpy(param_string, sizeof(param_string), buf, used); sprintf(tmp, "'%s'::float8", param_string); strcpy(&new_statement[npos], tmp); npos += strlen(tmp); break; case SQL_NUMERIC: if (buf) { cbuf[0] = '\''; my_strcpy(cbuf + 1, TEXT_FIELD_SIZE+5 - 12, buf, used); /* 12 = 1('\'') + strlen("'::numeric") + 1('\0') */ strcat(cbuf, "'::numeric"); } else sprintf(cbuf, "'%s'::numeric", param_string); my_strcpy(&new_statement[npos], sizeof(stmt->stmt_with_params) - npos - 1, cbuf, strlen(cbuf)); npos += strlen(&new_statement[npos]); break; default: /* a numeric type or SQL_BIT */ if (param_sqltype == SQL_BIT) new_statement[npos++] = '\''; /* Open Quote */ if (buf) { my_strcpy(&new_statement[npos], sizeof(stmt->stmt_with_params) - npos, buf, used); npos += strlen(&new_statement[npos]); } else { strcpy(&new_statement[npos], param_string); npos += strlen(param_string); } if (param_sqltype == SQL_BIT) new_statement[npos++] = '\''; /* Close Quote */ break; } } /* end, for */ /* make sure new_statement is always null-terminated */ new_statement[npos] = '\0'; if(stmt->hdbc->DriverToDataSource != NULL) { int length = strlen (new_statement); stmt->hdbc->DriverToDataSource (stmt->hdbc->translation_option, SQL_CHAR, new_statement, length, new_statement, length, NULL, NULL, 0, NULL); } free(cbuf); return SQL_SUCCESS; } char * mapFunction(char *func) { int i; for (i = 0; mapFuncs[i][0]; i++) if ( ! stricmp(mapFuncs[i][0], func)) return mapFuncs[i][1]; return NULL; } /* convert_escape() * This function returns a pointer to static memory! */ char * convert_escape(char *value) { static char escape[1024]; char key[33]; /* Separate off the key, skipping leading and trailing whitespace */ while ((*value != '\0') && isspace((unsigned char) *value)) value++; sscanf(value, "%32s", key); while ((*value != '\0') && (! isspace((unsigned char) *value))) value++; while ((*value != '\0') && isspace((unsigned char) *value)) value++; mylog("convert_escape: key='%s', val='%s'\n", key, value); if ( (strcmp(key, "d") == 0) || (strcmp(key, "t") == 0) || (strcmp(key, "ts") == 0) || (stricmp(key, "oj") == 0)) { /* Literal; return the escape part as-is */ strncpy(escape, value, sizeof(escape)-1); } else if (strcmp(key, "fn") == 0) { /* Function invocation * Separate off the func name, * skipping trailing whitespace. */ char *funcEnd = value; char svchar; char *mapFunc; while ((*funcEnd != '\0') && (*funcEnd != '(') && (! isspace((unsigned char) *funcEnd))) funcEnd++; svchar = *funcEnd; *funcEnd = '\0'; sscanf(value, "%32s", key); *funcEnd = svchar; while ((*funcEnd != '\0') && isspace((unsigned char) *funcEnd)) funcEnd++; /* We expect left parenthesis here, * else return fn body as-is since it is * one of those "function constants". */ if (*funcEnd != '(') { strncpy(escape, value, sizeof(escape)-1); return escape; } mapFunc = mapFunction(key); /* We could have mapFunction() return key if not in table... * - thomas 2000-04-03 */ if (mapFunc == NULL) { /* If unrecognized function name, return fn body as-is */ strncpy(escape, value, sizeof(escape)-1); return escape; } /* copy mapped name and remaining input string */ strcpy(escape, mapFunc); strncat(escape, funcEnd, sizeof(escape)-1-strlen(mapFunc)); } else { /* Bogus key, leave untranslated */ return NULL; } return escape; } char * convert_money(char *s) { size_t i = 0, out = 0, slen=strlen(s); for (i = 0; i < slen; i++) { if (s[i] == '$' || s[i] == ',' || s[i] == ')') ; /* skip these characters */ else if (s[i] == '(') s[out++] = '-'; else s[out++] = s[i]; } s[out] = '\0'; return s; } /* This function parses a character string for date/time info and fills in SIMPLE_TIME */ /* It does not zero out SIMPLE_TIME in case it is desired to initialize it with a value */ char parse_datetime(char *buf, SIMPLE_TIME *st) { int y,m,d,hh,mm,ss; int nf; y = m = d = hh = mm = ss = 0; if (buf[4] == '-') /* year first */ nf = sscanf(buf, "%4d-%2d-%2d %2d:%2d:%2d", &y,&m,&d,&hh,&mm,&ss); else nf = sscanf(buf, "%2d-%2d-%4d %2d:%2d:%2d", &m,&d,&y,&hh,&mm,&ss); if (nf == 5 || nf == 6) { st->y = y; st->m = m; st->d = d; st->hh = hh; st->mm = mm; st->ss = ss; return TRUE; } if (buf[4] == '-') /* year first */ nf = sscanf(buf, "%4d-%2d-%2d", &y, &m, &d); else nf = sscanf(buf, "%2d-%2d-%4d", &m, &d, &y); if (nf == 3) { st->y = y; st->m = m; st->d = d; return TRUE; } nf = sscanf(buf, "%2d:%2d:%2d", &hh, &mm, &ss); if (nf == 2 || nf == 3) { st->hh = hh; st->mm = mm; st->ss = ss; return TRUE; } return FALSE; } /* Change linefeed to carriage-return/linefeed */ int convert_linefeeds(char *si, char *dst, size_t max) { size_t i = 0, out = 0; for (i = 0; si[ i ] && out < max - 1; i++) { if (si[i] == '\n') { /* Only add the carriage-return if needed */ if (i > 0 && si[i-1] == '\r') { dst[out++] = si[i]; continue; } dst[out++] = '\r'; dst[out++] = '\n'; } else dst[out++] = si[i]; } dst[out] = '\0'; return out; } /* Change carriage-return/linefeed to just linefeed Plus, escape any special characters. */ char * convert_special_chars(char *si, char *dst, int used) { size_t i = 0, out = 0, max; /*static char sout[TEXT_FIELD_SIZE+5];*/ char *p; int in_len = strlen( si ); if (dst) p = dst; else /* p = sout; */ { printf("BUG !!! convert_special_chars\n"); exit(0); } p[0] = '\0'; if (used == SQL_NTS) max = strlen(si); else max = used; for (i = 0; i < max; i++) { if (si[i] == '\r' && i+1 < in_len && si[i+1] == '\n') continue; else if (si[i] == '\'' || si[i] == '\\') p[out++] = '\\'; p[out++] = si[i]; } p[out] = '\0'; return p; } /* !!! Need to implement this function !!! */ int convert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax) { mylog("convert_pgbinary_to_char: value = '%s'\n", value); strncpy_null(rgbValue, value, cbValueMax); return 0; } unsigned int conv_from_octal(unsigned char *s) { int i, y=0; for (i = 1; i <= 3; i++) { y += (s[i] - 48) * (int) pow(8, 3-i); } return y; } unsigned int conv_from_hex(unsigned char *s) { int i, y=0, val; for (i = 1; i <= 2; i++) { if (s[i] >= 'a' && s[i] <= 'f') val = s[i] - 'a' + 10; else if (s[i] >= 'A' && s[i] <= 'F') val = s[i] - 'A' + 10; else val = s[i] - '0'; y += val * (int) pow(16, 2-i); } return y; } /* convert octal escapes to bytes */ int convert_from_pgbinary(unsigned char *value, unsigned char *rgbValue, int cbValueMax) { int o=0; size_t i, valen=strlen((char*)value);; for (i = 0; i < valen && o < cbValueMax; ) { if (value[i] == '\\') { rgbValue[o] = conv_from_octal(&value[i]); i += 4; } else { rgbValue[o] = value[i++]; } mylog("convert_from_pgbinary: i=%d, rgbValue[%d] = %d, %c\n", i, o, rgbValue[o], rgbValue[o]); o++; } rgbValue[o] = '\0'; /* extra protection */ return o; } char * conv_to_octal(unsigned char val) { int i; static char x[6]; x[0] = '\\'; x[1] = '\\'; x[5] = '\0'; for (i = 4; i > 1; i--) { x[i] = (val & 7) + 48; val >>= 3; } return x; } /* convert non-ascii bytes to octal escape sequences */ int convert_to_pgbinary(unsigned char *in, char *out, int len) { int i, o=0; for (i = 0; i < len; i++) { mylog("convert_to_pgbinary: in[%d] = %d, %c\n", i, in[i], in[i]); if ( isalnum(in[i]) || in[i] == ' ') { out[o++] = in[i]; } else { strcpy(&out[o], conv_to_octal(in[i])); o += 5; } } mylog("convert_to_pgbinary: returning %d, out='%.*s'\n", o, o, out); return o; } void encode(char *in, char *out) { unsigned int i, o = 0; size_t inlen=strlen(in); for (i = 0; i < inlen; i++) { if ( in[i] == '+') { sprintf(&out[o], "%%2B"); o += 3; } else if ( isspace((unsigned char) in[i])) { out[o++] = '+'; } else if ( ! isalnum((unsigned char) in[i])) { sprintf(&out[o], "%%%02x", (unsigned char) in[i]); o += 3; } else out[o++] = in[i]; } out[o++] = '\0'; } void decode(char *in, char *out) { unsigned int i, o = 0; size_t stlen=strlen(in); for(i=0; i < stlen; i++) { if (in[i] == '+') out[o++] = ' '; else if (in[i] == '%') { sprintf(&out[o++], "%c", conv_from_hex((SQLCHAR*)&in[i])); i+=2; } else out[o++] = in[i]; } out[o++] = '\0'; } /* 1. get oid (from 'value') 2. open the large object 3. read from the large object (handle multiple GetData) 4. close when read less than requested? -OR- lseek/read each time handle case where application receives truncated and decides not to continue reading. CURRENTLY, ONLY LONGVARBINARY is handled, since that is the only data type currently mapped to a PG_TYPE_LO. But, if any other types are desired to map to a large object (PG_TYPE_LO), then that would need to be handled here. For example, LONGVARCHAR could possibly be mapped to PG_TYPE_LO someday, instead of PG_TYPE_TEXT as it is now. */ int convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue) { Oid oid; int retval, result, left = -1; BindInfoClass *bindInfo = NULL; /* If using SQLGetData, then current_col will be set */ if (stmt->current_col >= 0) { bindInfo = &stmt->bindings[stmt->current_col]; left = bindInfo->data_left; } /* if this is the first call for this column, open the large object for reading */ if ( ! bindInfo || bindInfo->data_left == -1) { /* begin transaction if needed */ if(!CC_is_in_trans(stmt->hdbc)) { QResultClass *res; char ok; res = CC_send_query(stmt->hdbc, "BEGIN", NULL); if (!res) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not begin (in-line) a transaction"); return COPY_GENERAL_ERROR; } ok = QR_command_successful(res); QR_Destructor(res); if (!ok) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not begin (in-line) a transaction"); return COPY_GENERAL_ERROR; } CC_set_in_trans(stmt->hdbc); } oid = atoi(value); stmt->lobj_fd = odbc_lo_open(stmt->hdbc, oid, INV_READ); if (stmt->lobj_fd < 0) { SC_set_error(stmt, STMT_EXEC_ERROR, "Couldnt open large object for reading."); return COPY_GENERAL_ERROR; } /* Get the size */ retval = odbc_lo_lseek(stmt->hdbc, stmt->lobj_fd, 0L, SEEK_END); if (retval >= 0) { left = odbc_lo_tell(stmt->hdbc, stmt->lobj_fd); if (bindInfo) bindInfo->data_left = left; /* return to beginning */ odbc_lo_lseek(stmt->hdbc, stmt->lobj_fd, 0L, SEEK_SET); } } if (left == 0) { return COPY_NO_DATA_FOUND; } if (stmt->lobj_fd < 0) { SC_set_error(stmt, STMT_EXEC_ERROR, "Large object FD undefined for multiple read."); return COPY_GENERAL_ERROR; } retval = odbc_lo_read(stmt->hdbc, stmt->lobj_fd, (char *) rgbValue, cbValueMax); if (retval < 0) { odbc_lo_close(stmt->hdbc, stmt->lobj_fd); /* commit transaction if needed */ if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) { QResultClass *res; char ok; res = CC_send_query(stmt->hdbc, "COMMIT", NULL); if (!res) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not commit (in-line) a transaction"); return COPY_GENERAL_ERROR; } ok = QR_command_successful(res); QR_Destructor(res); if (!ok) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not commit (in-line) a transaction"); return COPY_GENERAL_ERROR; } CC_set_no_trans(stmt->hdbc); } stmt->lobj_fd = -1; SC_set_error(stmt, STMT_EXEC_ERROR, "Error reading from large object."); return COPY_GENERAL_ERROR; } if (retval < left) result = COPY_RESULT_TRUNCATED; else result = COPY_OK; if (pcbValue) *pcbValue = left < 0 ? SQL_NO_TOTAL : left; if (bindInfo && bindInfo->data_left > 0) bindInfo->data_left -= retval; if (! bindInfo || bindInfo->data_left == 0) { odbc_lo_close(stmt->hdbc, stmt->lobj_fd); /* commit transaction if needed */ if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) { QResultClass *res; char ok; res = CC_send_query(stmt->hdbc, "COMMIT", NULL); if (!res) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not commit (in-line) a transaction"); return COPY_GENERAL_ERROR; } ok = QR_command_successful(res); QR_Destructor(res); if (!ok) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not commit (in-line) a transaction"); return COPY_GENERAL_ERROR; } CC_set_no_trans(stmt->hdbc); } stmt->lobj_fd = -1; /* prevent further reading */ } return result; } unixODBC-2.3.12/Drivers/Postgre7.1/convert.h000066400000000000000000000030061446441710500203370ustar00rootroot00000000000000 /* File: convert.h * * Description: See "convert.c" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __CONVERT_H__ #define __CONVERT_H__ #include "psqlodbc.h" /* copy_and_convert results */ #define COPY_OK 0 #define COPY_UNSUPPORTED_TYPE 1 #define COPY_UNSUPPORTED_CONVERSION 2 #define COPY_RESULT_TRUNCATED 3 #define COPY_GENERAL_ERROR 4 #define COPY_NO_DATA_FOUND 5 typedef struct { int m; int d; int y; int hh; int mm; int ss; } SIMPLE_TIME; int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col); int copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType, PTR rgbValue, SDWORD cbValueMax, SQLLEN *pcbValue); int copy_statement_with_parameters(StatementClass *stmt); char *convert_escape(char *value); char *convert_money(char *s); char parse_datetime(char *buf, SIMPLE_TIME *st); int convert_linefeeds(char *s, char *dst, size_t max); char *convert_special_chars(char *si, char *dst, int used); int convert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax); int convert_from_pgbinary(unsigned char *value, unsigned char *rgbValue, int cbValueMax); int convert_to_pgbinary(unsigned char *in, char *out, int len); void encode(char *in, char *out); void decode(char *in, char *out); int convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue); #endif unixODBC-2.3.12/Drivers/Postgre7.1/dlg_specific.c000066400000000000000000000653461446441710500213040ustar00rootroot00000000000000 /* Module: dlg_specific.c * * Description: This module contains any specific code for handling * dialog boxes such as driver/datasource options. Both the * ConfigDSN() and the SQLDriverConnect() functions use * functions in this module. If you were to add a new option * to any dialog box, you would most likely only have to change * things in here rather than in 2 separate places as before. * * Classes: none * * API functions: none * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef WIN32 # include # include # ifdef UNIXODBC # include # else # include "gpps.h" # define SQLGetPrivateProfileString(a,b,c,d,e,f) GetPrivateProfileString(a,b,c,d,e,f) # define SQLWritePrivateProfileString(a,b,c,d) WritePrivateProfileString(a,b,c,d) # endif # ifndef HAVE_STRICMP # define stricmp(s1,s2) strcasecmp(s1,s2) # define strnicmp(s1,s2,n) strncasecmp(s1,s2,n) # endif #endif #include "dlg_specific.h" #include "convert.h" #ifndef BOOL #define BOOL int #endif #ifndef FALSE #define FALSE (BOOL)0 #endif #ifndef TRUE #define TRUE (BOOL)1 #endif extern GLOBAL_VALUES globals; #ifdef WIN32 void SetDlgStuff(HWND hdlg, ConnInfo *ci) { /* If driver attribute NOT present, then set the datasource name and description */ if (ci->driver[0] == '\0') { SetDlgItemText(hdlg, IDC_DSNAME, ci->dsn); SetDlgItemText(hdlg, IDC_DESC, ci->desc); } SetDlgItemText(hdlg, IDC_DATABASE, ci->database); SetDlgItemText(hdlg, IDC_SERVER, ci->server); SetDlgItemText(hdlg, IDC_USER, ci->username); SetDlgItemText(hdlg, IDC_PASSWORD, ci->password); SetDlgItemText(hdlg, IDC_PORT, ci->port); } void GetDlgStuff(HWND hdlg, ConnInfo *ci) { GetDlgItemText(hdlg, IDC_DESC, ci->desc, sizeof(ci->desc)); GetDlgItemText(hdlg, IDC_DATABASE, ci->database, sizeof(ci->database)); GetDlgItemText(hdlg, IDC_SERVER, ci->server, sizeof(ci->server)); GetDlgItemText(hdlg, IDC_USER, ci->username, sizeof(ci->username)); GetDlgItemText(hdlg, IDC_PASSWORD, ci->password, sizeof(ci->password)); GetDlgItemText(hdlg, IDC_PORT, ci->port, sizeof(ci->port)); } int CALLBACK driver_optionsProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam) { switch (wMsg) { case WM_INITDIALOG: CheckDlgButton(hdlg, DRV_COMMLOG, globals.commlog); CheckDlgButton(hdlg, DRV_OPTIMIZER, globals.disable_optimizer); CheckDlgButton(hdlg, DRV_KSQO, globals.ksqo); CheckDlgButton(hdlg, DRV_UNIQUEINDEX, globals.unique_index); CheckDlgButton(hdlg, DRV_READONLY, globals.onlyread); CheckDlgButton(hdlg, DRV_USEDECLAREFETCH, globals.use_declarefetch); /* Unknown (Default) Data Type sizes */ switch(globals.unknown_sizes) { case UNKNOWNS_AS_DONTKNOW: CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 1); break; case UNKNOWNS_AS_LONGEST: CheckDlgButton(hdlg, DRV_UNKNOWN_LONGEST, 1); break; case UNKNOWNS_AS_MAX: default: CheckDlgButton(hdlg, DRV_UNKNOWN_MAX, 1); break; } CheckDlgButton(hdlg, DRV_TEXT_LONGVARCHAR, globals.text_as_longvarchar); CheckDlgButton(hdlg, DRV_UNKNOWNS_LONGVARCHAR, globals.unknowns_as_longvarchar); CheckDlgButton(hdlg, DRV_BOOLS_CHAR, globals.bools_as_char); CheckDlgButton(hdlg, DRV_PARSE, globals.parse); CheckDlgButton(hdlg, DRV_CANCELASFREESTMT, globals.cancel_as_freestmt); SetDlgItemInt(hdlg, DRV_CACHE_SIZE, globals.fetch_max, FALSE); SetDlgItemInt(hdlg, DRV_VARCHAR_SIZE, globals.max_varchar_size, FALSE); SetDlgItemInt(hdlg, DRV_LONGVARCHAR_SIZE, globals.max_longvarchar_size, TRUE); SetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, globals.extra_systable_prefixes); /* Driver Connection Settings */ SetDlgItemText(hdlg, DRV_CONNSETTINGS, globals.conn_settings); break; case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: globals.commlog = IsDlgButtonChecked(hdlg, DRV_COMMLOG); globals.disable_optimizer = IsDlgButtonChecked(hdlg, DRV_OPTIMIZER); globals.ksqo = IsDlgButtonChecked(hdlg, DRV_KSQO); globals.unique_index = IsDlgButtonChecked(hdlg, DRV_UNIQUEINDEX); globals.onlyread = IsDlgButtonChecked(hdlg, DRV_READONLY); globals.use_declarefetch = IsDlgButtonChecked(hdlg, DRV_USEDECLAREFETCH); /* Unknown (Default) Data Type sizes */ if (IsDlgButtonChecked(hdlg, DRV_UNKNOWN_MAX)) globals.unknown_sizes = UNKNOWNS_AS_MAX; else if (IsDlgButtonChecked(hdlg, DRV_UNKNOWN_DONTKNOW)) globals.unknown_sizes = UNKNOWNS_AS_DONTKNOW; else if (IsDlgButtonChecked(hdlg, DRV_UNKNOWN_LONGEST)) globals.unknown_sizes = UNKNOWNS_AS_LONGEST; else globals.unknown_sizes = UNKNOWNS_AS_MAX; globals.text_as_longvarchar = IsDlgButtonChecked(hdlg, DRV_TEXT_LONGVARCHAR); globals.unknowns_as_longvarchar = IsDlgButtonChecked(hdlg, DRV_UNKNOWNS_LONGVARCHAR); globals.bools_as_char = IsDlgButtonChecked(hdlg, DRV_BOOLS_CHAR); globals.parse = IsDlgButtonChecked(hdlg, DRV_PARSE); globals.cancel_as_freestmt = IsDlgButtonChecked(hdlg, DRV_CANCELASFREESTMT); globals.fetch_max = GetDlgItemInt(hdlg, DRV_CACHE_SIZE, NULL, FALSE); globals.max_varchar_size = GetDlgItemInt(hdlg, DRV_VARCHAR_SIZE, NULL, FALSE); globals.max_longvarchar_size= GetDlgItemInt(hdlg, DRV_LONGVARCHAR_SIZE, NULL, TRUE); /* allows for SQL_NO_TOTAL */ GetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, globals.extra_systable_prefixes, sizeof(globals.extra_systable_prefixes)); /* Driver Connection Settings */ GetDlgItemText(hdlg, DRV_CONNSETTINGS, globals.conn_settings, sizeof(globals.conn_settings)); updateGlobals(); /* fall through */ case IDCANCEL: EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK); return TRUE; case IDDEFAULTS: CheckDlgButton(hdlg, DRV_COMMLOG, DEFAULT_COMMLOG); CheckDlgButton(hdlg, DRV_OPTIMIZER, DEFAULT_OPTIMIZER); CheckDlgButton(hdlg, DRV_KSQO, DEFAULT_KSQO); CheckDlgButton(hdlg, DRV_UNIQUEINDEX, DEFAULT_UNIQUEINDEX); CheckDlgButton(hdlg, DRV_READONLY, DEFAULT_READONLY); CheckDlgButton(hdlg, DRV_USEDECLAREFETCH, DEFAULT_USEDECLAREFETCH); CheckDlgButton(hdlg, DRV_PARSE, DEFAULT_PARSE); CheckDlgButton(hdlg, DRV_CANCELASFREESTMT, DEFAULT_CANCELASFREESTMT); /* Unknown Sizes */ CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 0); CheckDlgButton(hdlg, DRV_UNKNOWN_LONGEST, 0); CheckDlgButton(hdlg, DRV_UNKNOWN_MAX, 0); switch(DEFAULT_UNKNOWNSIZES) { case UNKNOWNS_AS_DONTKNOW: CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 1); break; case UNKNOWNS_AS_LONGEST: CheckDlgButton(hdlg, DRV_UNKNOWN_LONGEST, 1); break; case UNKNOWNS_AS_MAX: CheckDlgButton(hdlg, DRV_UNKNOWN_MAX, 1); break; } CheckDlgButton(hdlg, DRV_TEXT_LONGVARCHAR, DEFAULT_TEXTASLONGVARCHAR); CheckDlgButton(hdlg, DRV_UNKNOWNS_LONGVARCHAR, DEFAULT_UNKNOWNSASLONGVARCHAR); CheckDlgButton(hdlg, DRV_BOOLS_CHAR, DEFAULT_BOOLSASCHAR); SetDlgItemInt(hdlg, DRV_CACHE_SIZE, FETCH_MAX, FALSE); SetDlgItemInt(hdlg, DRV_VARCHAR_SIZE, MAX_VARCHAR_SIZE, FALSE); SetDlgItemInt(hdlg, DRV_LONGVARCHAR_SIZE, TEXT_FIELD_SIZE, TRUE); SetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, DEFAULT_EXTRASYSTABLEPREFIXES); /* Driver Connection Settings */ SetDlgItemText(hdlg, DRV_CONNSETTINGS, ""); break; } } return FALSE; } int CALLBACK ds_optionsProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam) { ConnInfo *ci; char buf[128]; switch (wMsg) { case WM_INITDIALOG: ci = (ConnInfo *) lParam; SetWindowLong(hdlg, DWL_USER, lParam); /* save for OK */ /* Change window caption */ if (ci->driver[0]) SetWindowText(hdlg, "Advanced Options (Connection)"); else { sprintf(buf, "Advanced Options (%s)", ci->dsn); SetWindowText(hdlg, buf); } /* Readonly */ CheckDlgButton(hdlg, DS_READONLY, atoi(ci->onlyread)); /* Protocol */ if (strncmp(ci->protocol, PG62, strlen(PG62)) == 0) CheckDlgButton(hdlg, DS_PG62, 1); else if (strncmp(ci->protocol, PG63, strlen(PG63)) == 0) CheckDlgButton(hdlg, DS_PG63, 1); else /* latest */ CheckDlgButton(hdlg, DS_PG64, 1); CheckDlgButton(hdlg, DS_SHOWOIDCOLUMN, atoi(ci->show_oid_column)); CheckDlgButton(hdlg, DS_FAKEOIDINDEX, atoi(ci->fake_oid_index)); CheckDlgButton(hdlg, DS_ROWVERSIONING, atoi(ci->row_versioning)); CheckDlgButton(hdlg, DS_SHOWSYSTEMTABLES, atoi(ci->show_system_tables)); EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), atoi(ci->show_oid_column)); /* Datasource Connection Settings */ SetDlgItemText(hdlg, DS_CONNSETTINGS, ci->conn_settings); break; case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case DS_SHOWOIDCOLUMN: mylog("WM_COMMAND: DS_SHOWOIDCOLUMN\n"); EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), IsDlgButtonChecked(hdlg, DS_SHOWOIDCOLUMN)); return TRUE; case IDOK: ci = (ConnInfo *)GetWindowLong(hdlg, DWL_USER); mylog("IDOK: got ci = %u\n", ci); /* Readonly */ sprintf(ci->onlyread, "%d", IsDlgButtonChecked(hdlg, DS_READONLY)); /* Protocol */ if ( IsDlgButtonChecked(hdlg, DS_PG62)) strcpy(ci->protocol, PG62); else if ( IsDlgButtonChecked(hdlg, DS_PG63)) strcpy(ci->protocol, PG63); else /* latest */ strcpy(ci->protocol, PG64); sprintf(ci->show_system_tables, "%d", IsDlgButtonChecked(hdlg, DS_SHOWSYSTEMTABLES)); sprintf(ci->row_versioning, "%d", IsDlgButtonChecked(hdlg, DS_ROWVERSIONING)); /* OID Options*/ sprintf(ci->fake_oid_index, "%d", IsDlgButtonChecked(hdlg, DS_FAKEOIDINDEX)); sprintf(ci->show_oid_column, "%d", IsDlgButtonChecked(hdlg, DS_SHOWOIDCOLUMN)); /* Datasource Connection Settings */ GetDlgItemText(hdlg, DS_CONNSETTINGS, ci->conn_settings, sizeof(ci->conn_settings)); /* fall through */ case IDCANCEL: EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK); return TRUE; } } return FALSE; } #endif /* WIN32 */ void makeConnectString(char *connect_string, ConnInfo *ci) { char got_dsn = (ci->dsn[0] != '\0'); char encoded_conn_settings[LARGE_REGISTRY_LEN]; /* fundamental info */ sprintf(connect_string, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;PWD=%s", got_dsn ? "DSN" : "DRIVER", got_dsn ? ci->dsn : ci->driver, ci->database, ci->server, ci->port, ci->username, ci->password); encode(ci->conn_settings, encoded_conn_settings); /* extra info */ sprintf(&connect_string[strlen(connect_string)], ";READONLY=%s;PROTOCOL=%s;FAKEOIDINDEX=%s;SHOWOIDCOLUMN=%s;ROWVERSIONING=%s;SHOWSYSTEMTABLES=%s;CONNSETTINGS=%s", ci->onlyread, ci->protocol, ci->fake_oid_index, ci->show_oid_column, ci->row_versioning, ci->show_system_tables, encoded_conn_settings); } void copyAttributes(ConnInfo *ci, char *attribute, char *value) { if(stricmp(attribute, "DSN") == 0) strcpy(ci->dsn, value); else if(stricmp(attribute, "driver") == 0) strcpy(ci->driver, value); else if(stricmp(attribute, INI_DATABASE) == 0) strcpy(ci->database, value); else if(stricmp(attribute, INI_SERVER) == 0 || stricmp(attribute, "server") == 0) strcpy(ci->server, value); else if(stricmp(attribute, INI_USER) == 0 || stricmp(attribute, "uid") == 0) strcpy(ci->username, value); else if(stricmp(attribute, INI_PASSWORD) == 0 || stricmp(attribute, "pwd") == 0) strcpy(ci->password, value); else if(stricmp(attribute, INI_PORT) == 0) strcpy(ci->port, value); else if(stricmp(attribute, INI_UDS) == 0) strcpy(ci->uds, value); else if (stricmp(attribute, INI_READONLY) == 0) strcpy(ci->onlyread, value); else if (stricmp(attribute, INI_PROTOCOL) == 0) strcpy(ci->protocol, value); else if (stricmp(attribute, INI_SHOWOIDCOLUMN) == 0) strcpy(ci->show_oid_column, value); else if (stricmp(attribute, INI_FAKEOIDINDEX) == 0) strcpy(ci->fake_oid_index, value); else if (stricmp(attribute, INI_ROWVERSIONING) == 0) strcpy(ci->row_versioning, value); else if (stricmp(attribute, INI_SHOWSYSTEMTABLES) == 0) strcpy(ci->show_system_tables, value); else if (stricmp(attribute, INI_CONNSETTINGS) == 0) { decode(value, ci->conn_settings); /* strcpy(ci->conn_settings, value); */ } mylog("copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s', conn_settings='%s')\n", ci->dsn, ci->server,ci->database,ci->username,ci->password,ci->port,ci->onlyread,ci->protocol,ci->conn_settings); } void getDSNdefaults(ConnInfo *ci) { if (ci->port[0] == '\0') strcpy(ci->port, DEFAULT_PORT); if (ci->onlyread[0] == '\0') sprintf(ci->onlyread, "%d", globals.onlyread); if (ci->protocol[0] == '\0') strcpy(ci->protocol, globals.protocol); if (ci->fake_oid_index[0] == '\0') sprintf(ci->fake_oid_index, "%d", DEFAULT_FAKEOIDINDEX); if (ci->show_oid_column[0] == '\0') sprintf(ci->show_oid_column, "%d", DEFAULT_SHOWOIDCOLUMN); if (ci->show_system_tables[0] == '\0') sprintf(ci->show_system_tables, "%d", DEFAULT_SHOWSYSTEMTABLES); if (ci->row_versioning[0] == '\0') sprintf(ci->row_versioning, "%d", DEFAULT_ROWVERSIONING); } void getDSNinfo(ConnInfo *ci, char overwrite) { char *DSN = ci->dsn; char encoded_conn_settings[LARGE_REGISTRY_LEN]; /* If a driver keyword was present, then dont use a DSN and return. */ /* If DSN is null and no driver, then use the default datasource. */ if ( DSN[0] == '\0') { if ( ci->driver[0] != '\0') return; else strcpy(DSN, INI_DSN); } /* brute-force chop off trailing blanks... */ while (*(DSN+strlen(DSN)-1) == ' ') *(DSN+strlen(DSN)-1) = '\0'; /* Proceed with getting info for the given DSN. */ if ( ci->desc[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_KDESC, "", ci->desc, sizeof(ci->desc), ODBC_INI); if ( ci->server[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_SERVER, "", ci->server, sizeof(ci->server), ODBC_INI); if ( ci->database[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_DATABASE, "", ci->database, sizeof(ci->database), ODBC_INI); if ( ci->username[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_USER, "", ci->username, sizeof(ci->username), ODBC_INI); if ( ci->password[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_PASSWORD, "", ci->password, sizeof(ci->password), ODBC_INI); if ( ci->port[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_PORT, "", ci->port, sizeof(ci->port), ODBC_INI); if ( ci->uds[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_UDS, "", ci->uds, sizeof(ci->uds), ODBC_INI); if ( ci->onlyread[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_READONLY, "", ci->onlyread, sizeof(ci->onlyread), ODBC_INI); if ( toupper(ci->onlyread[0]) == 'Y' ) strcpy( ci->onlyread, "1" ); if ( ci->show_oid_column[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_SHOWOIDCOLUMN, "", ci->show_oid_column, sizeof(ci->show_oid_column), ODBC_INI); if ( toupper(ci->show_oid_column[0]) == 'Y' ) strcpy( ci->show_oid_column, "1" ); if ( ci->fake_oid_index[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_FAKEOIDINDEX, "", ci->fake_oid_index, sizeof(ci->fake_oid_index), ODBC_INI); if ( toupper(ci->fake_oid_index[0]) == 'Y' ) strcpy( ci->fake_oid_index, "1" ); if ( ci->row_versioning[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_ROWVERSIONING, "", ci->row_versioning, sizeof(ci->row_versioning), ODBC_INI); if ( toupper(ci->row_versioning[0]) == 'Y' ) strcpy( ci->row_versioning, "1" ); if ( ci->show_system_tables[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_SHOWSYSTEMTABLES, "", ci->show_system_tables, sizeof(ci->show_system_tables), ODBC_INI); if ( toupper(ci->show_system_tables[0]) == 'Y' ) strcpy( ci->show_system_tables, "1" ); if ( ci->protocol[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_PROTOCOL, "", ci->protocol, sizeof(ci->protocol), ODBC_INI); if ( ci->conn_settings[0] == '\0' || overwrite) { SQLGetPrivateProfileString(DSN, INI_CONNSETTINGS, "", encoded_conn_settings, sizeof(encoded_conn_settings), ODBC_INI); decode(encoded_conn_settings, ci->conn_settings); } if ( ci->translation_dll[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_TRANSLATIONDLL, "", ci->translation_dll, sizeof(ci->translation_dll), ODBC_INI); if ( ci->translation_option[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_TRANSLATIONOPTION, "", ci->translation_option, sizeof(ci->translation_option), ODBC_INI); /* Allow override of odbcinst.ini parameters here */ getGlobalDefaults(DSN, ODBC_INI, TRUE); qlog("DSN info: DSN='%s',server='%s',port='%s',dbase='%s',user='%s',passwd='%s'\n", DSN, ci->server, ci->port, ci->database, ci->username, ci->password); qlog(" onlyread='%s',protocol='%s',showoid='%s',fakeoidindex='%s',showsystable='%s'\n", ci->onlyread, ci->protocol, ci->show_oid_column, ci->fake_oid_index, ci->show_system_tables); qlog(" conn_settings='%s'\n", ci->conn_settings); qlog(" translation_dll='%s',translation_option='%s'\n", ci->translation_dll, ci->translation_option); } /* This is for datasource based options only */ void writeDSNinfo(ConnInfo *ci) { char *DSN = ci->dsn; char encoded_conn_settings[LARGE_REGISTRY_LEN]; encode(ci->conn_settings, encoded_conn_settings); SQLWritePrivateProfileString(DSN, INI_KDESC, ci->desc, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_DATABASE, ci->database, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_SERVER, ci->server, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_PORT, ci->port, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_UDS, ci->uds, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_USER, ci->username, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_PASSWORD, ci->password, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_READONLY, ci->onlyread, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_SHOWOIDCOLUMN, ci->show_oid_column, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_FAKEOIDINDEX, ci->fake_oid_index, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_ROWVERSIONING, ci->row_versioning, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_SHOWSYSTEMTABLES, ci->show_system_tables, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_PROTOCOL, ci->protocol, ODBC_INI); SQLWritePrivateProfileString(DSN, INI_CONNSETTINGS, encoded_conn_settings, ODBC_INI); } /* This function reads the ODBCINST.INI portion of the registry and gets any driver defaults. */ void getGlobalDefaults(char *section, char *filename, char override) { char temp[256]; /* Fetch Count is stored in driver section */ SQLGetPrivateProfileString(section, INI_FETCH, "", temp, sizeof(temp), filename); if ( temp[0] ) { globals.fetch_max = atoi(temp); /* sanity check if using cursors */ if (globals.fetch_max <= 0) globals.fetch_max = FETCH_MAX; } else if ( ! override) globals.fetch_max = FETCH_MAX; /* Socket Buffersize is stored in driver section */ SQLGetPrivateProfileString(section, INI_SOCKET, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.socket_buffersize = atoi(temp); else if ( ! override) globals.socket_buffersize = SOCK_BUFFER_SIZE; /* Debug is stored in the driver section */ SQLGetPrivateProfileString(section, INI_DEBUG, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.debug = atoi(temp); else if ( ! override) globals.debug = DEFAULT_DEBUG; /* CommLog is stored in the driver section */ SQLGetPrivateProfileString(section, INI_COMMLOG, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.commlog = atoi(temp); else if ( ! override) globals.commlog = DEFAULT_COMMLOG; /* Optimizer is stored in the driver section only */ SQLGetPrivateProfileString(section, INI_OPTIMIZER, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.disable_optimizer = atoi(temp); else if ( ! override) globals.disable_optimizer = DEFAULT_OPTIMIZER; /* KSQO is stored in the driver section only */ SQLGetPrivateProfileString(section, INI_KSQO, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.ksqo = atoi(temp); else if ( ! override) globals.ksqo = DEFAULT_KSQO; /* Recognize Unique Index is stored in the driver section only */ SQLGetPrivateProfileString(section, INI_UNIQUEINDEX, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.unique_index = atoi(temp); else if ( ! override) globals.unique_index = DEFAULT_UNIQUEINDEX; /* Unknown Sizes is stored in the driver section only */ SQLGetPrivateProfileString(section, INI_UNKNOWNSIZES, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.unknown_sizes = atoi(temp); else if ( ! override) globals.unknown_sizes = DEFAULT_UNKNOWNSIZES; /* Lie about supported functions? */ SQLGetPrivateProfileString(section, INI_LIE, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.lie = atoi(temp); else if ( ! override) globals.lie = DEFAULT_LIE; /* Parse statements */ SQLGetPrivateProfileString(section, INI_PARSE, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.parse = atoi(temp); else if ( ! override) globals.parse = DEFAULT_PARSE; /* SQLCancel calls SQLFreeStmt in Driver Manager */ SQLGetPrivateProfileString(section, INI_CANCELASFREESTMT, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.cancel_as_freestmt = atoi(temp); else if ( ! override) globals.cancel_as_freestmt = DEFAULT_CANCELASFREESTMT; /* UseDeclareFetch is stored in the driver section only */ SQLGetPrivateProfileString(section, INI_USEDECLAREFETCH, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.use_declarefetch = atoi(temp); else if ( ! override) globals.use_declarefetch = DEFAULT_USEDECLAREFETCH; /* Max Varchar Size */ SQLGetPrivateProfileString(section, INI_MAXVARCHARSIZE, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.max_varchar_size = atoi(temp); else if ( ! override) globals.max_varchar_size = MAX_VARCHAR_SIZE; /* Max TextField Size */ SQLGetPrivateProfileString(section, INI_MAXLONGVARCHARSIZE, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.max_longvarchar_size = atoi(temp); else if ( ! override) globals.max_longvarchar_size = TEXT_FIELD_SIZE; /* Text As LongVarchar */ SQLGetPrivateProfileString(section, INI_TEXTASLONGVARCHAR, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.text_as_longvarchar = atoi(temp); else if ( ! override) globals.text_as_longvarchar = DEFAULT_TEXTASLONGVARCHAR; /* Unknowns As LongVarchar */ SQLGetPrivateProfileString(section, INI_UNKNOWNSASLONGVARCHAR, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.unknowns_as_longvarchar = atoi(temp); else if ( ! override) globals.unknowns_as_longvarchar = DEFAULT_UNKNOWNSASLONGVARCHAR; /* Bools As Char */ SQLGetPrivateProfileString(section, INI_BOOLSASCHAR, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.bools_as_char = atoi(temp); else if ( ! override) globals.bools_as_char = DEFAULT_BOOLSASCHAR; /* Extra Systable prefixes */ /* Use @@@ to distinguish between blank extra prefixes and no key entry */ SQLGetPrivateProfileString(section, INI_EXTRASYSTABLEPREFIXES, "@@@", temp, sizeof(temp), filename); if ( strcmp(temp, "@@@" )) strcpy(globals.extra_systable_prefixes, temp); else if ( ! override) strcpy(globals.extra_systable_prefixes, DEFAULT_EXTRASYSTABLEPREFIXES); mylog("globals.extra_systable_prefixes = '%s'\n", globals.extra_systable_prefixes); /* Dont allow override of an override! */ if ( ! override) { /* ConnSettings is stored in the driver section and per datasource for override */ SQLGetPrivateProfileString(section, INI_CONNSETTINGS, "", globals.conn_settings, sizeof(globals.conn_settings), filename); /* Default state for future DSN's Readonly attribute */ SQLGetPrivateProfileString(section, INI_READONLY, "", temp, sizeof(temp), filename); if ( temp[0] ) globals.onlyread = atoi(temp); else globals.onlyread = DEFAULT_READONLY; /* Default state for future DSN's protocol attribute This isn't a real driver option YET. This is more intended for customization from the install. */ SQLGetPrivateProfileString(section, INI_PROTOCOL, "@@@", temp, sizeof(temp), filename); if ( strcmp(temp, "@@@" )) strcpy(globals.protocol, temp); else strcpy(globals.protocol, DEFAULT_PROTOCOL); } } /* This function writes any global parameters (that can be manipulated) to the ODBCINST.INI portion of the registry */ void updateGlobals(void) { char tmp[128]; sprintf(tmp, "%d", globals.fetch_max); SQLWritePrivateProfileString(DBMS_NAME, INI_FETCH, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.commlog); SQLWritePrivateProfileString(DBMS_NAME, INI_COMMLOG, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.disable_optimizer); SQLWritePrivateProfileString(DBMS_NAME, INI_OPTIMIZER, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.ksqo); SQLWritePrivateProfileString(DBMS_NAME, INI_KSQO, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.unique_index); SQLWritePrivateProfileString(DBMS_NAME, INI_UNIQUEINDEX, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.onlyread); SQLWritePrivateProfileString(DBMS_NAME, INI_READONLY, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.use_declarefetch); SQLWritePrivateProfileString(DBMS_NAME, INI_USEDECLAREFETCH, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.unknown_sizes); SQLWritePrivateProfileString(DBMS_NAME, INI_UNKNOWNSIZES, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.text_as_longvarchar); SQLWritePrivateProfileString(DBMS_NAME, INI_TEXTASLONGVARCHAR, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.unknowns_as_longvarchar); SQLWritePrivateProfileString(DBMS_NAME, INI_UNKNOWNSASLONGVARCHAR, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.bools_as_char); SQLWritePrivateProfileString(DBMS_NAME, INI_BOOLSASCHAR, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.parse); SQLWritePrivateProfileString(DBMS_NAME, INI_PARSE, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.cancel_as_freestmt); SQLWritePrivateProfileString(DBMS_NAME, INI_CANCELASFREESTMT, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.max_varchar_size); SQLWritePrivateProfileString(DBMS_NAME, INI_MAXVARCHARSIZE, tmp, ODBCINST_INI); sprintf(tmp, "%d", globals.max_longvarchar_size); SQLWritePrivateProfileString(DBMS_NAME, INI_MAXLONGVARCHARSIZE, tmp, ODBCINST_INI); SQLWritePrivateProfileString(DBMS_NAME, INI_EXTRASYSTABLEPREFIXES, globals.extra_systable_prefixes, ODBCINST_INI); SQLWritePrivateProfileString(DBMS_NAME, INI_CONNSETTINGS, globals.conn_settings, ODBCINST_INI); } unixODBC-2.3.12/Drivers/Postgre7.1/dlg_specific.h000066400000000000000000000120301446441710500212670ustar00rootroot00000000000000 /* File: dlg_specific.h * * Description: See "dlg_specific.c" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __DLG_SPECIFIC_H__ #define __DLG_SPECIFIC_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "psqlodbc.h" #include "connection.h" #ifdef WIN32 #include #include #include #include "resource.h" #endif /* Unknown data type sizes */ #define UNKNOWNS_AS_MAX 0 #define UNKNOWNS_AS_DONTKNOW 1 #define UNKNOWNS_AS_LONGEST 2 /* INI File Stuff */ #ifndef WIN32 #ifdef UNIXODBC #define ODBC_INI "ODBC.INI" /* ODBC initialization file */ #define ODBCINST_INI "ODBCINST.INI" /* ODBC Installation file */ #else # define ODBC_INI ".odbc.ini" # ifdef ODBCINSTDIR # define ODBCINST_INI ODBCINSTDIR "/odbcinst.ini" # else # define ODBCINST_INI "/etc/odbcinst.ini" # endif #endif #else /* WIN32 */ # define ODBC_INI "ODBC.INI" /* ODBC initialization file */ # define ODBCINST_INI "ODBCINST.INI" /* ODBC Installation file */ #endif /* WIN32 */ #define INI_DSN DBMS_NAME /* Name of default Datasource in ini file (not used?) */ #define INI_KDESC "Description" /* Data source description */ #define INI_SERVER "Servername" /* Name of Server running the Postgres service */ #define INI_PORT "Port" /* Port on which the Postmaster is listening */ #define INI_UDS "Uds" /* Unix Domain socket path */ #define INI_DATABASE "Database" /* Database Name */ #define INI_USER "Username" /* Default User Name */ #define INI_PASSWORD "Password" /* Default Password */ #define INI_DEBUG "Debug" /* Debug flag */ #define INI_FETCH "Fetch" /* Fetch Max Count */ #define INI_SOCKET "Socket" /* Socket buffer size */ #define INI_READONLY "ReadOnly" /* Database is read only */ #define INI_COMMLOG "CommLog" /* Communication to backend logging */ #define INI_PROTOCOL "Protocol" /* What protocol (6.2) */ #define INI_OPTIMIZER "Optimizer" /* Use backend genetic optimizer */ #define INI_KSQO "Ksqo" /* Keyset query optimization */ #define INI_CONNSETTINGS "ConnSettings" /* Anything to send to backend on successful connection */ #define INI_UNIQUEINDEX "UniqueIndex" /* Recognize unique indexes */ #define INI_UNKNOWNSIZES "UnknownSizes" /* How to handle unknown result set sizes */ #define INI_CANCELASFREESTMT "CancelAsFreeStmt" #define INI_USEDECLAREFETCH "UseDeclareFetch" /* Use Declare/Fetch cursors */ /* More ini stuff */ #define INI_TEXTASLONGVARCHAR "TextAsLongVarchar" #define INI_UNKNOWNSASLONGVARCHAR "UnknownsAsLongVarchar" #define INI_BOOLSASCHAR "BoolsAsChar" #define INI_MAXVARCHARSIZE "MaxVarcharSize" #define INI_MAXLONGVARCHARSIZE "MaxLongVarcharSize" #define INI_FAKEOIDINDEX "FakeOidIndex" #define INI_SHOWOIDCOLUMN "ShowOidColumn" #define INI_ROWVERSIONING "RowVersioning" #define INI_SHOWSYSTEMTABLES "ShowSystemTables" #define INI_LIE "Lie" #define INI_PARSE "Parse" #define INI_EXTRASYSTABLEPREFIXES "ExtraSysTablePrefixes" #define INI_TRANSLATIONNAME "TranslationName" #define INI_TRANSLATIONDLL "TranslationDLL" #define INI_TRANSLATIONOPTION "TranslationOption" /* Connection Defaults */ #define DEFAULT_PORT "5432" #define DEFAULT_UDS "" #define DEFAULT_READONLY 1 #define DEFAULT_PROTOCOL "6.4" /* the latest protocol is the default */ #define DEFAULT_USEDECLAREFETCH 0 #define DEFAULT_TEXTASLONGVARCHAR 1 #define DEFAULT_UNKNOWNSASLONGVARCHAR 0 #define DEFAULT_BOOLSASCHAR 1 #define DEFAULT_OPTIMIZER 1 /* disable */ #define DEFAULT_KSQO 1 /* on */ #define DEFAULT_UNIQUEINDEX 0 /* dont recognize */ #define DEFAULT_COMMLOG 0 /* dont log */ #define DEFAULT_DEBUG 0 #define DEFAULT_UNKNOWNSIZES UNKNOWNS_AS_MAX #define DEFAULT_FAKEOIDINDEX 0 #define DEFAULT_SHOWOIDCOLUMN 0 #define DEFAULT_ROWVERSIONING 0 #define DEFAULT_SHOWSYSTEMTABLES 0 /* dont show system tables */ #define DEFAULT_LIE 0 #define DEFAULT_PARSE 0 #define DEFAULT_CANCELASFREESTMT 0 #define DEFAULT_EXTRASYSTABLEPREFIXES "dd_;" /* prototypes */ void getGlobalDefaults(char *section, char *filename, char override); #ifdef WIN32 void SetDlgStuff(HWND hdlg, ConnInfo *ci); void GetDlgStuff(HWND hdlg, ConnInfo *ci); int CALLBACK driver_optionsProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam); int CALLBACK ds_optionsProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam); #endif /* WIN32 */ void updateGlobals(void); void writeDSNinfo(ConnInfo *ci); void getDSNdefaults(ConnInfo *ci); void getDSNinfo(ConnInfo *ci, char overwrite); void makeConnectString(char *connect_string, ConnInfo *ci); void copyAttributes(ConnInfo *ci, char *attribute, char *value); #endif unixODBC-2.3.12/Drivers/Postgre7.1/driver.exp000066400000000000000000000013751446441710500205260ustar00rootroot00000000000000SQLAllocConnect SQLAllocEnv SQLAllocStmt SQLBindCol SQLBindParameter SQLBrowseConnect SQLCancel SQLColAttributes SQLColumnPrivileges SQLColumns SQLConnect SQLDescribeCol SQLDescribeParam SQLDisconnect SQLDriverConnect SQLError SQLExecDirect SQLExecute SQLExtendedFetch SQLFetch SQLForeignKeys SQLFreeConnect SQLFreeEnv SQLFreeStmt SQLGetConnectOption SQLGetCursorName SQLGetData SQLGetFunctions SQLGetInfo SQLGetStmtOption SQLGetTypeInfo SQLMoreResults SQLNativeSql SQLNumParams SQLNumResultCols SQLParamData SQLParamOptions SQLPrepare SQLPrimaryKeys SQLProcedureColumns SQLProcedures SQLPutData SQLRowCount SQLSetConnectOption SQLSetCursorName SQLSetPos SQLSetScrollOptions SQLSetStmtOption SQLSpecialColumns SQLStatistics SQLTablePrivileges SQLTables SQLTransact unixODBC-2.3.12/Drivers/Postgre7.1/drvconn.c000066400000000000000000000217111446441710500203260ustar00rootroot00000000000000 /* Module: drvconn.c * * Description: This module contains only routines related to * implementing SQLDriverConnect. * * Classes: n/a * * API functions: SQLDriverConnect * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "psqlodbc.h" #include "connection.h" #ifndef WIN32 #include #include #define NEAR #else #include #include #endif #include #ifndef WIN32 #define stricmp(s1,s2) strcasecmp(s1,s2) #define strnicmp(s1,s2,n) strncasecmp(s1,s2,n) #else #include #include #include #include "resource.h" #endif #ifndef TRUE #define TRUE (BOOL)1 #endif #ifndef FALSE #define FALSE (BOOL)0 #endif #include "dlg_specific.h" /* prototypes */ void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci); #ifdef WIN32 BOOL FAR PASCAL dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam); RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci); extern HINSTANCE NEAR s_hModule; /* Saved module handle. */ #endif extern GLOBAL_VALUES globals; RETCODE SQL_API SQLDriverConnect( HDBC hdbc, HWND hwnd, UCHAR FAR *szConnStrIn, SWORD cbConnStrIn, UCHAR FAR *szConnStrOut, SWORD cbConnStrOutMax, SWORD FAR *pcbConnStrOut, UWORD fDriverCompletion) { static char* const func = "SQLDriverConnect"; ConnectionClass *conn = (ConnectionClass *) hdbc; ConnInfo *ci; #ifdef WIN32 RETCODE dialog_result; #endif RETCODE result; char connStrIn[MAX_CONNECT_STRING]; char connStrOut[MAX_CONNECT_STRING]; int retval; char salt[5]; char password_required = AUTH_REQ_OK; int len = 0; mylog("%s: entering...\n", func); if ( ! conn) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } make_string((char*)szConnStrIn, cbConnStrIn, connStrIn); mylog("**** SQLDriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn); qlog("conn=%u, SQLDriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion); ci = &(conn->connInfo); /* Parse the connect string and fill in conninfo for this hdbc. */ dconn_get_connect_attributes((SQLCHAR*)connStrIn, ci); /* If the ConnInfo in the hdbc is missing anything, */ /* this function will fill them in from the registry (assuming */ /* of course there is a DSN given -- if not, it does nothing!) */ getDSNinfo(ci, CONN_DONT_OVERWRITE); /* Fill in any default parameters if they are not there. */ getDSNdefaults(ci); /* initialize pg_version */ CC_initialize_pg_version(conn); salt[0] = '\0'; #ifdef WIN32 dialog: #endif ci->focus_password = password_required; switch(fDriverCompletion) { #ifdef WIN32 case SQL_DRIVER_PROMPT: dialog_result = dconn_DoDialog(hwnd, ci); if(dialog_result != SQL_SUCCESS) { return dialog_result; } break; case SQL_DRIVER_COMPLETE_REQUIRED: /* Fall through */ case SQL_DRIVER_COMPLETE: /* Password is not a required parameter. */ if( ci->username[0] == '\0' || ci->server[0] == '\0' || ci->database[0] == '\0' || ci->port[0] == '\0' || password_required) { dialog_result = dconn_DoDialog(hwnd, ci); if(dialog_result != SQL_SUCCESS) { return dialog_result; } } break; #else case SQL_DRIVER_PROMPT: case SQL_DRIVER_COMPLETE: case SQL_DRIVER_COMPLETE_REQUIRED: #endif case SQL_DRIVER_NOPROMPT: break; } /* Password is not a required parameter unless authentication asks for it. For now, I think it's better to just let the application ask over and over until a password is entered (the user can always hit Cancel to get out) */ if( ci->username[0] == '\0' || ci->server[0] == '\0' || ci->database[0] == '\0' || ci->port[0] == '\0') { /* (password_required && ci->password[0] == '\0')) */ return SQL_NO_DATA_FOUND; } /* do the actual connect */ retval = CC_connect(conn, password_required, salt); if (retval < 0) { /* need a password */ if (fDriverCompletion == SQL_DRIVER_NOPROMPT) { CC_log_error(func, "Need password but Driver_NoPrompt", conn); return SQL_ERROR; /* need a password but not allowed to prompt so error */ } else { #ifdef WIN32 password_required = TRUE; goto dialog; #else return SQL_ERROR; /* until a better solution is found. */ #endif } } else if (retval == 0) { /* error msg filled in above */ CC_log_error(func, "Error from CC_Connect", conn); return SQL_ERROR; } /*********************************************/ /* Create the Output Connection String */ /*********************************************/ result = SQL_SUCCESS; makeConnectString(connStrOut, ci); len = strlen(connStrOut); if(szConnStrOut) { /* Return the completed string to the caller. The correct method is to only construct the connect string if a dialog was put up, otherwise, it should just copy the connection input string to the output. However, it seems ok to just always construct an output string. There are possible bad side effects on working applications (Access) by implementing the correct behavior, anyway. */ strncpy_null((char*)szConnStrOut, connStrOut, cbConnStrOutMax); if (len >= cbConnStrOutMax) { result = SQL_SUCCESS_WITH_INFO; CC_set_error(conn, CONN_TRUNCATED, "The buffer was too small for the result."); } } if(pcbConnStrOut) *pcbConnStrOut = len; mylog("szConnStrOut = '%s'\n", szConnStrOut); qlog("conn=%u, SQLDriverConnect(out)='%s'\n", conn, szConnStrOut); mylog("SQLDRiverConnect: returning %d\n", result); return result; } #ifdef WIN32 RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci) { int dialog_result; mylog("dconn_DoDialog: ci = %u\n", ci); if(hwnd) { dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG), hwnd, dconn_FDriverConnectProc, (LPARAM) ci); if(!dialog_result || (dialog_result == -1)) { return SQL_NO_DATA_FOUND; } else { return SQL_SUCCESS; } } return SQL_ERROR; } BOOL FAR PASCAL dconn_FDriverConnectProc( HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam) { ConnInfo *ci; switch (wMsg) { case WM_INITDIALOG: ci = (ConnInfo *) lParam; /* Change the caption for the setup dialog */ SetWindowText(hdlg, "PostgreSQL Connection"); SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), "Connection"); /* Hide the DSN and description fields */ ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE); ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE); ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE); ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE); SetWindowLong(hdlg, DWL_USER, lParam);/* Save the ConnInfo for the "OK" */ SetDlgStuff(hdlg, ci); if (ci->database[0] == '\0') ; /* default focus */ else if (ci->server[0] == '\0') SetFocus(GetDlgItem(hdlg, IDC_SERVER)); else if (ci->port[0] == '\0') SetFocus(GetDlgItem(hdlg, IDC_PORT)); else if (ci->username[0] == '\0') SetFocus(GetDlgItem(hdlg, IDC_USER)); else if (ci->focus_password) SetFocus(GetDlgItem(hdlg, IDC_PASSWORD)); break; case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER); GetDlgStuff(hdlg, ci); case IDCANCEL: EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK); return TRUE; case IDC_DRIVER: DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV), hdlg, driver_optionsProc, (LPARAM) NULL); break; case IDC_DATASOURCE: ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER); DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS), hdlg, ds_optionsProc, (LPARAM) ci); break; } } return FALSE; } #endif /* WIN32 */ void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci) { char *our_connect_string; char *pair, *attribute, *value, *equals; char *strtok_arg; memset(ci, 0, sizeof(ConnInfo)); our_connect_string = strdup((char*)connect_string); strtok_arg = our_connect_string; mylog("our_connect_string = '%s'\n", our_connect_string); while(1) { pair = strtok(strtok_arg, ";"); if(strtok_arg) { strtok_arg = 0; } if(!pair) { break; } equals = strchr(pair, '='); if ( ! equals) continue; *equals = '\0'; attribute = pair; /* ex. DSN */ value = equals + 1; /* ex. 'CEO co1' */ mylog("attribute = '%s', value = '%s'\n", attribute, value); if( !attribute || !value) continue; /* Copy the appropriate value to the conninfo */ copyAttributes(ci, attribute, value); } free(our_connect_string); } unixODBC-2.3.12/Drivers/Postgre7.1/environ.c000066400000000000000000000360171446441710500203420ustar00rootroot00000000000000 /* Module: environ.c * * Description: This module contains routines related to * the environment, such as storing connection handles, * and returning errors. * * Classes: EnvironmentClass (Functions prefix: "EN_") * * API functions: SQLAllocEnv, SQLFreeEnv, SQLError * * Comments: See "notice.txt" for copyright and license information. * */ #include #include #include "environ.h" #include "connection.h" #include "statement.h" #include #include #ifdef UNIXODBC #include #include #include "dlg_specific.h" #else #include "isql.h" #include "isqlext.h" #endif /* The one instance of the handles */ ConnectionClass *conns[MAX_CONNECTIONS]; RETCODE SQL_API SQLAllocEnv(HENV FAR *phenv) { static char* const func = "SQLAllocEnv"; mylog("**** in SQLAllocEnv ** \n"); /* * add this here from _init (NG) */ getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE); *phenv = (HENV) EN_Constructor(); if ( ! *phenv) { *phenv = SQL_NULL_HENV; EN_log_error(func, "Error allocating environment", NULL); return SQL_ERROR; } mylog("** exit SQLAllocEnv: phenv = %u **\n", *phenv); return SQL_SUCCESS; } RETCODE SQL_API SQLFreeEnv(HENV henv) { static char* const func = "SQLFreeEnv"; EnvironmentClass *env = (EnvironmentClass *) henv; mylog("**** in SQLFreeEnv: env = %u ** \n", env); if (env && EN_Destructor(env)) { mylog(" ok\n"); return SQL_SUCCESS; } mylog(" error\n"); EN_log_error(func, "Error freeing environment", env); return SQL_ERROR; } /* Returns the next SQL error information. */ SQLRETURN SQLError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLCHAR *szSqlState, SQLINTEGER *pfNativeError, SQLCHAR *szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT *pcbErrorMsg) { char *msg; int status; mylog("**** SQLError: henv=%u, hdbc=%u, hstmt=%u\n", henv, hdbc, hstmt); if (SQL_NULL_HSTMT != hstmt) { /* CC: return an error of a hstmt */ StatementClass *stmt = (StatementClass *) hstmt; if (SC_get_error(stmt, &status, &msg)) { mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg); if (NULL == msg) { if (NULL != szSqlState) strcpy((char*)szSqlState, "00000"); if (NULL != pcbErrorMsg) *pcbErrorMsg = 0; if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) szErrorMsg[0] = '\0'; return SQL_NO_DATA_FOUND; } if (NULL != pcbErrorMsg) *pcbErrorMsg = (SWORD)strlen(msg); if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) strncpy_null((char*)szErrorMsg, msg, cbErrorMsgMax); if (NULL != pfNativeError) *pfNativeError = status; if (NULL != szSqlState) switch (status) { /* now determine the SQLSTATE to be returned */ case STMT_TRUNCATED: strcpy((char*)szSqlState, "01004"); /* data truncated */ break; case STMT_INFO_ONLY: strcpy((char*)szSqlState, "01000"); /* just information that is returned, no error */ break; case STMT_BAD_ERROR: strcpy((char*)szSqlState, "08S01"); /* communication link failure */ break; case STMT_CREATE_TABLE_ERROR: strcpy((char*)szSqlState, "S0001"); /* table already exists */ break; case STMT_STATUS_ERROR: case STMT_SEQUENCE_ERROR: strcpy((char*)szSqlState, "S1010"); /* Function sequence error */ break; case STMT_NO_MEMORY_ERROR: strcpy((char*)szSqlState, "S1001"); /* memory allocation failure */ break; case STMT_COLNUM_ERROR: strcpy((char*)szSqlState, "S1002"); /* invalid column number */ break; case STMT_NO_STMTSTRING: strcpy((char*)szSqlState, "S1001"); /* having no stmtstring is also a malloc problem */ break; case STMT_ERROR_TAKEN_FROM_BACKEND: strcpy((char*)szSqlState, "S1000"); /* general error */ break; case STMT_INTERNAL_ERROR: strcpy((char*)szSqlState, "S1000"); /* general error */ break; case STMT_ROW_OUT_OF_RANGE: strcpy((char*)szSqlState, "S1107"); break; case STMT_OPERATION_CANCELLED: strcpy((char*)szSqlState, "S1008"); break; case STMT_NOT_IMPLEMENTED_ERROR: strcpy((char*)szSqlState, "S1C00"); /* == 'driver not capable' */ break; case STMT_OPTION_OUT_OF_RANGE_ERROR: strcpy((char*)szSqlState, "S1092"); break; case STMT_BAD_PARAMETER_NUMBER_ERROR: strcpy((char*)szSqlState, "S1093"); break; case STMT_INVALID_COLUMN_NUMBER_ERROR: strcpy((char*)szSqlState, "S1002"); break; case STMT_RESTRICTED_DATA_TYPE_ERROR: strcpy((char*)szSqlState, "07006"); break; case STMT_INVALID_CURSOR_STATE_ERROR: strcpy((char*)szSqlState, "24000"); break; case STMT_OPTION_VALUE_CHANGED: strcpy((char*)szSqlState, "01S02"); break; case STMT_INVALID_CURSOR_NAME: strcpy((char*)szSqlState, "34000"); break; case STMT_NO_CURSOR_NAME: strcpy((char*)szSqlState, "S1015"); break; case STMT_INVALID_ARGUMENT_NO: strcpy((char*)szSqlState, "S1009"); /* invalid argument value */ break; case STMT_INVALID_CURSOR_POSITION: strcpy((char*)szSqlState, "S1109"); break; case STMT_VALUE_OUT_OF_RANGE: strcpy((char*)szSqlState, "22003"); break; case STMT_OPERATION_INVALID: strcpy((char*)szSqlState, "S1011"); break; case STMT_EXEC_ERROR: default: strcpy((char*)szSqlState, "S1000"); /* also a general error */ break; } mylog(" szSqlState = '%s', szError='%s'\n", szSqlState, szErrorMsg); } else { if (NULL != szSqlState) strcpy((char*)szSqlState, "00000"); if (NULL != pcbErrorMsg) *pcbErrorMsg = 0; if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) szErrorMsg[0] = '\0'; mylog(" returning NO_DATA_FOUND\n"); return SQL_NO_DATA_FOUND; } return SQL_SUCCESS; } else if (SQL_NULL_HDBC != hdbc) { ConnectionClass *conn = (ConnectionClass *) hdbc; mylog("calling CC_get_error\n"); if (CC_get_error(conn, &status, &msg)) { mylog("CC_get_error: status = %d, msg = #%s#\n", status, msg); if (NULL == msg) { if (NULL != szSqlState) strcpy((char*)szSqlState, "00000"); if (NULL != pcbErrorMsg) *pcbErrorMsg = 0; if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) szErrorMsg[0] = '\0'; return SQL_NO_DATA_FOUND; } if (NULL != pcbErrorMsg) *pcbErrorMsg = (SWORD)strlen(msg); if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) strncpy_null((char*)szErrorMsg, msg, cbErrorMsgMax); if (NULL != pfNativeError) *pfNativeError = status; if (NULL != szSqlState) switch(status) { case STMT_OPTION_VALUE_CHANGED: case CONN_OPTION_VALUE_CHANGED: strcpy((char*)szSqlState, "01S02"); break; case STMT_TRUNCATED: case CONN_TRUNCATED: strcpy((char*)szSqlState, "01004"); /* data truncated */ break; case CONN_INIREAD_ERROR: strcpy((char*)szSqlState, "IM002"); /* data source not found */ break; case CONN_OPENDB_ERROR: strcpy((char*)szSqlState, "08001"); /* unable to connect to data source */ break; case CONN_INVALID_AUTHENTICATION: case CONN_AUTH_TYPE_UNSUPPORTED: strcpy((char*)szSqlState, "28000"); break; case CONN_STMT_ALLOC_ERROR: strcpy((char*)szSqlState, "S1001"); /* memory allocation failure */ break; case CONN_IN_USE: strcpy((char*)szSqlState, "S1000"); /* general error */ break; case CONN_UNSUPPORTED_OPTION: strcpy((char*)szSqlState, "IM001"); /* driver does not support this function */ case CONN_INVALID_ARGUMENT_NO: strcpy((char*)szSqlState, "S1009"); /* invalid argument value */ break; case CONN_TRANSACT_IN_PROGRES: strcpy((char*)szSqlState, "S1010"); /* when the user tries to switch commit mode in a transaction */ /* -> function sequence error */ break; case CONN_NO_MEMORY_ERROR: strcpy((char*)szSqlState, "S1001"); break; case CONN_NOT_IMPLEMENTED_ERROR: case STMT_NOT_IMPLEMENTED_ERROR: strcpy((char*)szSqlState, "S1C00"); break; case CONN_VALUE_OUT_OF_RANGE: case STMT_VALUE_OUT_OF_RANGE: strcpy((char*)szSqlState, "22003"); break; default: strcpy((char*)szSqlState, "S1000"); /* general error */ break; } } else { mylog("CC_Get_error returned nothing.\n"); if (NULL != szSqlState) strcpy((char*)szSqlState, "00000"); if (NULL != pcbErrorMsg) *pcbErrorMsg = 0; if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) szErrorMsg[0] = '\0'; return SQL_NO_DATA_FOUND; } return SQL_SUCCESS; } else if (SQL_NULL_HENV != henv) { EnvironmentClass *env = (EnvironmentClass *)henv; if(EN_get_error(env, &status, &msg)) { mylog("EN_get_error: status = %d, msg = #%s#\n", status, msg); if (NULL == msg) { if (NULL != szSqlState) strcpy((char*)szSqlState, "00000"); if (NULL != pcbErrorMsg) *pcbErrorMsg = 0; if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) szErrorMsg[0] = '\0'; return SQL_NO_DATA_FOUND; } if (NULL != pcbErrorMsg) *pcbErrorMsg = (SWORD)strlen(msg); if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) strncpy_null((char*)szErrorMsg, msg, cbErrorMsgMax); if (NULL != pfNativeError) *pfNativeError = status; if(szSqlState) { switch(status) { case ENV_ALLOC_ERROR: /* memory allocation failure */ strcpy((char*)szSqlState, "S1001"); break; default: strcpy((char*)szSqlState, "S1000"); /* general error */ break; } } } else { if (NULL != szSqlState) strcpy((char*)szSqlState, "00000"); if (NULL != pcbErrorMsg) *pcbErrorMsg = 0; if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) szErrorMsg[0] = '\0'; return SQL_NO_DATA_FOUND; } return SQL_SUCCESS; } if (NULL != szSqlState) strcpy((char*)szSqlState, "00000"); if (NULL != pcbErrorMsg) *pcbErrorMsg = 0; if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) szErrorMsg[0] = '\0'; return SQL_NO_DATA_FOUND; } /*********************************************************************/ /* * EnvironmentClass implementation */ EnvironmentClass *EN_Constructor(void) { EnvironmentClass *rv; rv = (EnvironmentClass *) malloc(sizeof(EnvironmentClass)); if( rv) { rv->errormsg = 0; rv->errornumber = 0; } return rv; } char EN_Destructor(EnvironmentClass *self) { int lf; char rv = 1; mylog("in EN_Destructor, self=%u\n", self); /* the error messages are static strings distributed throughout */ /* the source--they should not be freed */ /* Free any connections belonging to this environment */ for (lf = 0; lf < MAX_CONNECTIONS; lf++) { if (conns[lf] && conns[lf]->henv == (HENV) self) rv = rv && CC_Destructor(conns[lf]); } free( self ); mylog("exit EN_Destructor: rv = %d\n", rv); return rv; } char EN_get_error(EnvironmentClass *self, int *number, char **message) { if(self && self->errormsg && self->errornumber) { *message = self->errormsg; *number = self->errornumber; self->errormsg = 0; self->errornumber = 0; return 1; } else { return 0; } } char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn) { int i; mylog("EN_add_connection: self = %u, conn = %u\n", self, conn); for (i = 0; i < MAX_CONNECTIONS; i++) { if ( ! conns[i]) { conn->henv = (HENV)self; conns[i] = conn; mylog(" added at i =%d, conn->henv = %u, conns[i]->henv = %u\n", i, conn->henv, conns[i]->henv); return TRUE; } } return FALSE; } char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn) { int i; for (i = 0; i < MAX_CONNECTIONS; i++) if (conns[i] == conn && conns[i]->status != CONN_EXECUTING) { conns[i] = NULL; return TRUE; } return FALSE; } void EN_log_error(char *func, char *desc, EnvironmentClass *self) { if (self) { qlog("ENVIRON ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg); } else qlog("INVALID ENVIRON HANDLE ERROR: func=%s, desc='%s'\n", func, desc); } unixODBC-2.3.12/Drivers/Postgre7.1/environ.h000066400000000000000000000016601446441710500203430ustar00rootroot00000000000000 /* File: environ.h * * Description: See "environ.c" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __ENVIRON_H__ #define __ENVIRON_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "psqlodbc.h" #ifndef WIN32 #include "isql.h" #include "isqlext.h" #else #include #include #include #endif #define ENV_ALLOC_ERROR 1 /********** Environment Handle *************/ struct EnvironmentClass_ { char *errormsg; int errornumber; }; /* Environment prototypes */ EnvironmentClass *EN_Constructor(void); char EN_Destructor(EnvironmentClass *self); char EN_get_error(EnvironmentClass *self, int *number, char **message); char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn); char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn); void EN_log_error(char *func, char *desc, EnvironmentClass *self); #endif unixODBC-2.3.12/Drivers/Postgre7.1/execute.c000066400000000000000000000526311446441710500203240ustar00rootroot00000000000000 /* Module: execute.c * * Description: This module contains routines related to * preparing and executing an SQL statement. * * Classes: n/a * * API functions: SQLPrepare, SQLExecute, SQLExecDirect, SQLTransact, * SQLCancel, SQLNativeSql, SQLParamData, SQLPutData * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "psqlodbc.h" #include #include #ifndef WIN32 #include "isqlext.h" #else #include #include #endif #include "connection.h" #include "statement.h" #include "qresult.h" #include "convert.h" #include "bind.h" #include "lobj.h" #include "misc.h" extern GLOBAL_VALUES globals; SQLRETURN PG_SQLPrepare(SQLHSTMT hstmt, SQLCHAR *szSqlStr , SQLINTEGER cbSqlStr); SQLRETURN SQLPrepare(SQLHSTMT hstmt, SQLCHAR *szSqlStr , SQLINTEGER cbSqlStr) { return PG_SQLPrepare( hstmt, szSqlStr, cbSqlStr ); } /* Perform a Prepare on the SQL statement */ SQLRETURN PG_SQLPrepare(SQLHSTMT hstmt, SQLCHAR *szSqlStr, SQLINTEGER cbSqlStr) { static char* const func = "SQLPrepare"; StatementClass *self = (StatementClass *) hstmt; int sqllen = 0; /* used for MAX_ROWS if specified */ int limlen = 0; char buffer[32]; mylog( "%s: entering...\n", func); if ( ! self) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } /* According to the ODBC specs it is valid to call SQLPrepare mulitple times. In that case, the bound SQL statement is replaced by the new one */ switch(self->status) { case STMT_PREMATURE: mylog("**** SQLPrepare: STMT_PREMATURE, recycle\n"); SC_recycle_statement(self); /* recycle the statement, but do not remove parameter bindings */ break; case STMT_FINISHED: mylog("**** SQLPrepare: STMT_FINISHED, recycle\n"); SC_recycle_statement(self); /* recycle the statement, but do not remove parameter bindings */ break; case STMT_ALLOCATED: mylog("**** SQLPrepare: STMT_ALLOCATED, copy\n"); self->status = STMT_READY; break; case STMT_READY: mylog("**** SQLPrepare: STMT_READY, change SQL\n"); break; case STMT_EXECUTING: mylog("**** SQLPrepare: STMT_EXECUTING, error!\n"); SC_set_error(self, STMT_SEQUENCE_ERROR, "SQLPrepare(): The handle does not point to a statement that is ready to be executed"); SC_log_error(func, "", self); return SQL_ERROR; default: SC_set_error(self, STMT_INTERNAL_ERROR, "An Internal Error has occurred -- Unknown statement status."); SC_log_error(func, "", self); return SQL_ERROR; } if (self->statement) free(self->statement); self->statement_type = statement_type((char*)szSqlStr); if (self->statement_type == STMT_TYPE_SELECT && 0 != self->options.maxRows) { limlen = sprintf(buffer," LIMIT %d", self->options.maxRows); } sqllen = my_strlen((char*)szSqlStr, cbSqlStr) + limlen; self->statement = make_string((char*)szSqlStr, sqllen, NULL); if ( ! self->statement) { SC_set_error(self, STMT_NO_MEMORY_ERROR, "No memory available to store statement"); SC_log_error(func, "", self); return SQL_ERROR; } if (self->statement_type == STMT_TYPE_SELECT && 0 != self->options.maxRows) { strcat(self->statement, buffer); } self->prepare = TRUE; /* Check if connection is onlyread (only selects are allowed) */ if ( CC_is_onlyread(self->hdbc) && STMT_UPDATE(self)) { SC_set_error(self, STMT_EXEC_ERROR, "Connection is readonly, only select statements are allowed."); SC_log_error(func, "", self); return SQL_ERROR; } return SQL_SUCCESS; } /* - - - - - - - - - */ /* Performs the equivalent of SQLPrepare, followed by SQLExecute. */ RETCODE SQL_API PG_SQLExecDirect( HSTMT hstmt, UCHAR FAR *szSqlStr, SDWORD cbSqlStr) { StatementClass *stmt = (StatementClass *) hstmt; RETCODE result; static char* const func = "SQLExecDirect"; mylog( "%s: entering...\n", func); if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } if (stmt->statement) free(stmt->statement); /* keep a copy of the un-parametrized statement, in case */ /* they try to execute this statement again */ stmt->statement = make_string((char*)szSqlStr, cbSqlStr, NULL); if ( ! stmt->statement) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "No memory available to store statement"); SC_log_error(func, "", stmt); return SQL_ERROR; } mylog("**** %s: hstmt=%u, statement='%s'\n", func, hstmt, stmt->statement); stmt->prepare = FALSE; /* If an SQLPrepare was performed prior to this, but was left in */ /* the premature state because an error occurred prior to SQLExecute */ /* then set the statement to finished so it can be recycled. */ if ( stmt->status == STMT_PREMATURE ) stmt->status = STMT_FINISHED; stmt->statement_type = statement_type(stmt->statement); /* Check if connection is onlyread (only selects are allowed) */ if ( CC_is_onlyread(stmt->hdbc) && STMT_UPDATE(stmt)) { SC_set_error(stmt, STMT_EXEC_ERROR, "Connection is readonly, only select statements are allowed."); SC_log_error(func, "", stmt); return SQL_ERROR; } mylog("%s: calling SQLExecute...\n", func); result = PG_SQLExecute(hstmt); mylog("%s: returned %hd from SQLExecute\n", func, result); return result; } SQLRETURN SQLExecDirect(SQLHSTMT hstmt, SQLCHAR *szSqlStr, SQLINTEGER cbSqlStr) { return PG_SQLExecDirect( hstmt, szSqlStr, cbSqlStr ); } /* Execute a prepared SQL statement */ RETCODE SQL_API PG_SQLExecute( HSTMT hstmt) { static char* const func="SQLExecute"; StatementClass *stmt = (StatementClass *) hstmt; ConnectionClass *conn; int i, retval; mylog("%s: entering...\n", func); if ( ! stmt) { SC_log_error(func, "", NULL); mylog("%s: NULL statement so return SQL_INVALID_HANDLE\n", func); return SQL_INVALID_HANDLE; } /* If the statement is premature, it means we already executed it from an SQLPrepare/SQLDescribeCol type of scenario. So just return success. */ if ( stmt->prepare && stmt->status == STMT_PREMATURE && !stmt->reexecute ) { stmt->status = STMT_FINISHED; if (NULL == SC_get_errormsg(stmt)) { mylog("%s: premature statement but return SQL_SUCCESS\n", func); return SQL_SUCCESS; } else { SC_log_error(func, "", stmt); mylog("%s: premature statement so return SQL_ERROR\n", func); return SQL_ERROR; } } else if ( stmt->prepare && stmt->status == STMT_PREMATURE && stmt->reexecute ) { /* * cause it to be reexecuted */ char *str; str = strdup( stmt->statement ); stmt->status = STMT_FINISHED; PG_SQLPrepare( hstmt, (SQLCHAR*) str, SQL_NTS ); free( str ); } mylog("%s: clear errors...\n", func); SC_clear_error(stmt); conn = SC_get_conn(stmt); if (conn->status == CONN_EXECUTING) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Connection is already in use."); SC_log_error(func, "", stmt); mylog("%s: problem with connection\n", func); return SQL_ERROR; } if ( ! stmt->statement) { SC_set_error(stmt, STMT_NO_STMTSTRING, "This handle does not have a SQL statement stored in it"); SC_log_error(func, "", stmt); mylog("%s: problem with handle\n", func); return SQL_ERROR; } /* If SQLExecute is being called again, recycle the statement. Note this should have been done by the application in a call to SQLFreeStmt(SQL_CLOSE) or SQLCancel. */ if (stmt->status == STMT_FINISHED) { mylog("%s: recycling statement (should have been done by app)...\n", func); SC_recycle_statement(stmt); } /* Check if the statement is in the correct state */ if ((stmt->prepare && stmt->status != STMT_READY) || (stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY)) { SC_set_error(stmt, STMT_STATUS_ERROR, "The handle does not point to a statement that is ready to be executed"); SC_log_error(func, "", stmt); mylog("%s: problem with statement\n", func); return SQL_ERROR; } /* The bound parameters could have possibly changed since the last execute of this statement? Therefore check for params and re-copy. */ stmt->data_at_exec = -1; for (i = 0; i < stmt->parameters_allocated; i++) { /* Check for data at execution parameters */ if ( stmt->parameters[i].data_at_exec == TRUE) { if (stmt->data_at_exec < 0) stmt->data_at_exec = 1; else stmt->data_at_exec++; } } /* If there are some data at execution parameters, return need data */ /* SQLParamData and SQLPutData will be used to send params and execute the statement. */ if (stmt->data_at_exec > 0) return SQL_NEED_DATA; mylog("%s: copying statement params: trans_status=%d, len=%d, stmt='%s'\n", func, conn->transact_status, strlen(stmt->statement), stmt->statement); /* Create the statement with parameters substituted. */ retval = copy_statement_with_parameters(stmt); if( retval != SQL_SUCCESS) /* error msg passed from above */ return retval; mylog(" stmt_with_params = '%s'\n", stmt->stmt_with_params); return SC_execute(stmt); } RETCODE SQL_API SQLExecute( HSTMT hstmt) { return PG_SQLExecute( hstmt ); } /* - - - - - - - - - */ RETCODE SQL_API SQLTransact( HENV henv, HDBC hdbc, UWORD fType) { static char* const func = "SQLTransact"; extern ConnectionClass *conns[]; ConnectionClass *conn; QResultClass *res; char ok, *stmt_string; int lf; mylog("entering %s: hdbc=%u, henv=%u\n", func, hdbc, henv); if (hdbc == SQL_NULL_HDBC && henv == SQL_NULL_HENV) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } /* If hdbc is null and henv is valid, it means transact all connections on that henv. */ if (hdbc == SQL_NULL_HDBC && henv != SQL_NULL_HENV) { for (lf=0; lf henv == henv) if ( SQLTransact(henv, (HDBC) conn, fType) != SQL_SUCCESS) return SQL_ERROR; } return SQL_SUCCESS; } conn = (ConnectionClass *) hdbc; if (fType == SQL_COMMIT) { stmt_string = "COMMIT"; } else if (fType == SQL_ROLLBACK) { stmt_string = "ROLLBACK"; } else { CC_set_error(conn, CONN_INVALID_ARGUMENT_NO, "SQLTransact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter"); CC_log_error(func, "", conn); return SQL_ERROR; } /* If manual commit and in transaction, then proceed. */ if ( ! CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) { mylog("SQLTransact: sending on conn %d '%s'\n", conn, stmt_string); res = CC_send_query(conn, stmt_string, NULL); CC_set_no_trans(conn); if ( ! res) { /* error msg will be in the connection */ CC_log_error(func, "", conn); return SQL_ERROR; } ok = QR_command_successful(res); QR_Destructor(res); if (!ok) { CC_log_error(func, "", conn); return SQL_ERROR; } } return SQL_SUCCESS; } /* - - - - - - - - - */ RETCODE SQL_API SQLCancel( HSTMT hstmt) /* Statement to cancel. */ { static char* const func="SQLCancel"; StatementClass *stmt = (StatementClass *) hstmt; RETCODE result; #ifdef WIN32 HMODULE hmodule; FARPROC addr; #endif mylog( "%s: entering...\n", func); /* Check if this can handle canceling in the middle of a SQLPutData? */ if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } /* Not in the middle of SQLParamData/SQLPutData so cancel like a close. */ if (stmt->data_at_exec < 0) { /* MAJOR HACK for Windows to reset the driver manager's cursor state: Because of what seems like a bug in the Odbc driver manager, SQLCancel does not act like a SQLFreeStmt(CLOSE), as many applications depend on this behavior. So, this brute force method calls the driver manager's function on behalf of the application. */ #ifdef WIN32 if (globals.cancel_as_freestmt) { hmodule = GetModuleHandle("ODBC32"); addr = GetProcAddress(hmodule, "SQLFreeStmt"); result = addr( (char *) (stmt->phstmt) - 96, SQL_CLOSE); } else { result = PG_SQLFreeStmt( hstmt, SQL_CLOSE); } #else result = PG_SQLFreeStmt( hstmt, SQL_CLOSE); #endif mylog("SQLCancel: SQLFreeStmt returned %d\n", result); SC_clear_error(hstmt); return SQL_SUCCESS; } /* In the middle of SQLParamData/SQLPutData, so cancel that. */ /* Note, any previous data-at-exec buffers will be freed in the recycle */ /* if they call SQLExecDirect or SQLExecute again. */ stmt->data_at_exec = -1; stmt->current_exec_param = -1; stmt->put_data = FALSE; return SQL_SUCCESS; } /* - - - - - - - - - */ /* Returns the SQL string as modified by the driver. */ /* Currently, just copy the input string without modification */ /* observing buffer limits and truncation. */ SQLRETURN SQLNativeSql( SQLHDBC hdbc, SQLCHAR *szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLCHAR *szSqlStr, SQLINTEGER cbSqlStrMax, SQLINTEGER *pcbSqlStr) { static char* const func="SQLNativeSql"; int len = 0; char *ptr; ConnectionClass *conn = (ConnectionClass *) hdbc; RETCODE result; mylog( "%s: entering...cbSqlStrIn=%d\n", func, cbSqlStrIn); ptr = (cbSqlStrIn == 0) ? "" : make_string((char*)szSqlStrIn, cbSqlStrIn, NULL); if ( ! ptr) { CC_set_error(conn, CONN_NO_MEMORY_ERROR, "No memory available to store native sql string"); CC_log_error(func, "", conn); return SQL_ERROR; } result = SQL_SUCCESS; len = strlen(ptr); if (szSqlStr) { strncpy_null((char*)szSqlStr, ptr, cbSqlStrMax); if (len >= cbSqlStrMax) { result = SQL_SUCCESS_WITH_INFO; CC_set_error(conn, STMT_TRUNCATED, "The buffer was too small for the result."); } } if (pcbSqlStr) *pcbSqlStr = len; free(ptr); return result; } /* - - - - - - - - - */ /* Supplies parameter data at execution time. Used in conjuction with */ /* SQLPutData. */ RETCODE SQL_API SQLParamData( HSTMT hstmt, PTR FAR *prgbValue) { static char* const func = "SQLParamData"; StatementClass *stmt = (StatementClass *) hstmt; int i, retval; mylog( "%s: entering...\n", func); if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } mylog("%s: data_at_exec=%d, params_alloc=%d\n", func, stmt->data_at_exec, stmt->parameters_allocated); if (stmt->data_at_exec < 0) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "No execution-time parameters for this statement"); SC_log_error(func, "", stmt); return SQL_ERROR; } if (stmt->data_at_exec > stmt->parameters_allocated) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Too many execution-time parameters were present"); SC_log_error(func, "", stmt); return SQL_ERROR; } /* close the large object */ if ( stmt->lobj_fd >= 0) { odbc_lo_close(stmt->hdbc, stmt->lobj_fd); /* commit transaction if needed */ if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) { QResultClass *res; char ok; res = CC_send_query(stmt->hdbc, "COMMIT", NULL); if (!res) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not commit (in-line) a transaction"); SC_log_error(func, "", stmt); return SQL_ERROR; } ok = QR_command_successful(res); QR_Destructor(res); if (!ok) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not commit (in-line) a transaction"); SC_log_error(func, "", stmt); return SQL_ERROR; } CC_set_no_trans(stmt->hdbc); } stmt->lobj_fd = -1; } /* Done, now copy the params and then execute the statement */ if (stmt->data_at_exec == 0) { retval = copy_statement_with_parameters(stmt); if (retval != SQL_SUCCESS) return retval; stmt->current_exec_param = -1; return SC_execute(stmt); } /* Set beginning param; if first time SQLParamData is called , start at 0. Otherwise, start at the last parameter + 1. */ i = stmt->current_exec_param >= 0 ? stmt->current_exec_param+1 : 0; /* At least 1 data at execution parameter, so Fill in the token value */ for ( ; i < stmt->parameters_allocated; i++) { if (stmt->parameters[i].data_at_exec == TRUE) { stmt->data_at_exec--; stmt->current_exec_param = i; stmt->put_data = FALSE; *prgbValue = stmt->parameters[i].buffer; /* token */ break; } } return SQL_NEED_DATA; } /* - - - - - - - - - */ /* Supplies parameter data at execution time. Used in conjunction with */ /* SQLParamData. */ SQLRETURN SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue) { static char* const func = "SQLPutData"; StatementClass *stmt = (StatementClass *) hstmt; int old_pos, retval; ParameterInfoClass *current_param; char *buffer; mylog( "%s: entering...\n", func); if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } if (stmt->current_exec_param < 0) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Previous call was not SQLPutData or SQLParamData"); SC_log_error(func, "", stmt); return SQL_ERROR; } current_param = &(stmt->parameters[stmt->current_exec_param]); if ( ! stmt->put_data) { /* first call */ mylog("SQLPutData: (1) cbValue = %d\n", cbValue); stmt->put_data = TRUE; current_param->EXEC_used = malloc(sizeof(SDWORD)); if ( ! current_param->EXEC_used) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Out of memory in SQLPutData (1)"); SC_log_error(func, "", stmt); return SQL_ERROR; } *current_param->EXEC_used = cbValue; if (cbValue == SQL_NULL_DATA) return SQL_SUCCESS; /* Handle Long Var Binary with Large Objects */ if ( current_param->SQLType == SQL_LONGVARBINARY) { /* begin transaction if needed */ if(!CC_is_in_trans(stmt->hdbc)) { QResultClass *res; char ok; res = CC_send_query(stmt->hdbc, "BEGIN", NULL); if (!res) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not begin (in-line) a transaction"); SC_log_error(func, "", stmt); return SQL_ERROR; } ok = QR_command_successful(res); QR_Destructor(res); if (!ok) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not begin (in-line) a transaction"); SC_log_error(func, "", stmt); return SQL_ERROR; } CC_set_in_trans(stmt->hdbc); } /* store the oid */ current_param->lobj_oid = odbc_lo_creat(stmt->hdbc, INV_READ | INV_WRITE); if (current_param->lobj_oid == 0) { SC_set_error(stmt, STMT_EXEC_ERROR, "Couldnt create large object."); SC_log_error(func, "", stmt); return SQL_ERROR; } /* major hack -- to allow convert to see somethings there */ /* have to modify convert to handle this better */ current_param->EXEC_buffer = (char *) ¤t_param->lobj_oid; /* store the fd */ stmt->lobj_fd = odbc_lo_open(stmt->hdbc, current_param->lobj_oid, INV_WRITE); if ( stmt->lobj_fd < 0) { SC_set_error(stmt, STMT_EXEC_ERROR, "Couldnt open large object for writing."); SC_log_error(func, "", stmt); return SQL_ERROR; } retval = odbc_lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue); mylog("odbc_lo_write: cbValue=%d, wrote %d bytes\n", cbValue, retval); } else { /* for handling text fields and small binaries */ if (cbValue == SQL_NTS) { current_param->EXEC_buffer = strdup(rgbValue); if ( ! current_param->EXEC_buffer) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Out of memory in SQLPutData (2)"); SC_log_error(func, "", stmt); return SQL_ERROR; } } else { current_param->EXEC_buffer = malloc(cbValue + 1); if ( ! current_param->EXEC_buffer) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Out of memory in SQLPutData (2)"); SC_log_error(func, "", stmt); return SQL_ERROR; } memcpy(current_param->EXEC_buffer, rgbValue, cbValue); current_param->EXEC_buffer[cbValue] = '\0'; } } } else { /* calling SQLPutData more than once */ mylog("SQLPutData: (>1) cbValue = %d\n", cbValue); if (current_param->SQLType == SQL_LONGVARBINARY) { /* the large object fd is in EXEC_buffer */ retval = odbc_lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue); mylog("odbc_lo_write(2): cbValue = %d, wrote %d bytes\n", cbValue, retval); *current_param->EXEC_used += cbValue; } else { buffer = current_param->EXEC_buffer; if (cbValue == SQL_NTS) { buffer = realloc(buffer, strlen(buffer) + strlen(rgbValue) + 1); if ( ! buffer) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Out of memory in SQLPutData (3)"); SC_log_error(func, "", stmt); return SQL_ERROR; } strcat(buffer, rgbValue); mylog(" cbValue = SQL_NTS: strlen(buffer) = %d\n", strlen(buffer)); *current_param->EXEC_used = cbValue; /* reassign buffer incase realloc moved it */ current_param->EXEC_buffer = buffer; } else if (cbValue > 0) { old_pos = *current_param->EXEC_used; *current_param->EXEC_used += cbValue; mylog(" cbValue = %d, old_pos = %d, *used = %d\n", cbValue, old_pos, *current_param->EXEC_used); /* dont lose the old pointer in case out of memory */ buffer = realloc(current_param->EXEC_buffer, *current_param->EXEC_used + 1); if ( ! buffer) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Out of memory in SQLPutData (3)"); SC_log_error(func, "", stmt); return SQL_ERROR; } memcpy(&buffer[old_pos], rgbValue, cbValue); buffer[*current_param->EXEC_used] = '\0'; /* reassign buffer incase realloc moved it */ current_param->EXEC_buffer = buffer; } else { SC_log_error(func, "bad cbValue", stmt); return SQL_ERROR; } } } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/Postgre7.1/info.c000066400000000000000000003073261446441710500176210ustar00rootroot00000000000000 /* Module: info.c * * Description: This module contains routines related to * ODBC informational functions. * * Classes: n/a * * API functions: SQLGetInfo, SQLGetTypeInfo, SQLGetFunctions, * SQLTables, SQLColumns, SQLStatistics, SQLSpecialColumns, * SQLPrimaryKeys, SQLForeignKeys, * SQLProcedureColumns(NI), SQLProcedures(NI), * SQLTablePrivileges(NI), SQLColumnPrivileges(NI) * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "psqlodbc.h" #ifndef WIN32 #include "isql.h" #include "isqlext.h" #include #else #include #include #include #endif #include "tuple.h" #include "pgtypes.h" #include "environ.h" #include "connection.h" #include "statement.h" #include "qresult.h" #include "bind.h" #include "misc.h" #include "pgtypes.h" /* Trigger related stuff for SQLForeign Keys */ #define TRIGGER_SHIFT 3 #define TRIGGER_MASK 0x03 #define TRIGGER_DELETE 0x01 #define TRIGGER_UPDATE 0x02 extern GLOBAL_VALUES globals; /* - - - - - - - - - */ RETCODE SQL_API SQLGetInfo( HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue, SWORD cbInfoValueMax, SWORD FAR *pcbInfoValue) { static char* const func = "SQLGetInfo"; ConnectionClass *conn = (ConnectionClass *) hdbc; ConnInfo *ci; char *p = NULL, tmp[MAX_INFO_STRING]; int len = 0, value = 0; RETCODE result; mylog( "%s: entering...fInfoType=%d\n", func, fInfoType); if ( ! conn) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } ci = &conn->connInfo; switch (fInfoType) { case SQL_ACCESSIBLE_PROCEDURES: /* ODBC 1.0 */ p = "N"; break; case SQL_ACCESSIBLE_TABLES: /* ODBC 1.0 */ p = "N"; break; case SQL_ACTIVE_CONNECTIONS: /* ODBC 1.0 */ len = 2; value = MAX_CONNECTIONS; break; case SQL_ACTIVE_STATEMENTS: /* ODBC 1.0 */ len = 2; value = 0; break; case SQL_ALTER_TABLE: /* ODBC 2.0 */ len = 4; value = SQL_AT_ADD_COLUMN; break; case SQL_BOOKMARK_PERSISTENCE: /* ODBC 2.0 */ /* very simple bookmark support */ len = 4; value = globals.use_declarefetch ? 0 : (SQL_BP_SCROLL); break; case SQL_COLUMN_ALIAS: /* ODBC 2.0 */ p = "N"; break; case SQL_CONCAT_NULL_BEHAVIOR: /* ODBC 1.0 */ len = 2; value = SQL_CB_NON_NULL; break; case SQL_CONVERT_BIGINT: case SQL_CONVERT_BINARY: case SQL_CONVERT_BIT: case SQL_CONVERT_CHAR: case SQL_CONVERT_DATE: case SQL_CONVERT_DECIMAL: case SQL_CONVERT_DOUBLE: case SQL_CONVERT_FLOAT: case SQL_CONVERT_INTEGER: case SQL_CONVERT_LONGVARBINARY: case SQL_CONVERT_LONGVARCHAR: case SQL_CONVERT_NUMERIC: case SQL_CONVERT_REAL: case SQL_CONVERT_SMALLINT: case SQL_CONVERT_TIME: case SQL_CONVERT_TIMESTAMP: case SQL_CONVERT_TINYINT: case SQL_CONVERT_VARBINARY: case SQL_CONVERT_VARCHAR: /* ODBC 1.0 */ len = 4; value = fInfoType; break; case SQL_CONVERT_FUNCTIONS: /* ODBC 1.0 */ len = 4; value = 0; break; case SQL_CORRELATION_NAME: /* ODBC 1.0 */ /* Saying no correlation name makes Query not work right. value = SQL_CN_NONE; */ len = 2; value = SQL_CN_ANY; break; case SQL_CURSOR_COMMIT_BEHAVIOR: /* ODBC 1.0 */ len = 2; value = SQL_CB_CLOSE; break; case SQL_CURSOR_ROLLBACK_BEHAVIOR: /* ODBC 1.0 */ len = 2; value = SQL_CB_CLOSE; break; case SQL_DATA_SOURCE_NAME: /* ODBC 1.0 */ p = CC_get_DSN(conn); break; case SQL_DATA_SOURCE_READ_ONLY: /* ODBC 1.0 */ p = CC_is_onlyread(conn) ? "Y" : "N"; break; case SQL_DATABASE_NAME: /* Support for old ODBC 1.0 Apps */ /* Returning the database name causes problems in MS Query. It generates query like: "SELECT DISTINCT a FROM byronncrap3 crap3" p = CC_get_database(conn); */ p = ""; break; case SQL_DBMS_NAME: /* ODBC 1.0 */ p = DBMS_NAME; break; case SQL_DBMS_VER: /* ODBC 1.0 */ /* The ODBC spec wants ##.##.#### ...whatever... so prepend the driver */ /* version number to the dbms version string */ #ifdef HAVE_SNPRINTF snprintf(tmp, sizeof( tmp ), "%s %s", POSTGRESDRIVERVERSION, conn->pg_version); #else sprintf(tmp, "%s %s", POSTGRESDRIVERVERSION, conn->pg_version); #endif p = tmp; break; case SQL_DEFAULT_TXN_ISOLATION: /* ODBC 1.0 */ len = 4; value = SQL_TXN_READ_COMMITTED; /*SQL_TXN_SERIALIZABLE; */ break; case SQL_DRIVER_NAME: /* ODBC 1.0 */ p = DRIVER_FILE_NAME; break; case SQL_DRIVER_ODBC_VER: p = DRIVER_ODBC_VER; break; case SQL_DRIVER_VER: /* ODBC 1.0 */ p = POSTGRESDRIVERVERSION; break; case SQL_EXPRESSIONS_IN_ORDERBY: /* ODBC 1.0 */ p = "N"; break; case SQL_FETCH_DIRECTION: /* ODBC 1.0 */ len = 4; value = globals.use_declarefetch ? (SQL_FD_FETCH_NEXT) : (SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST | SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE | SQL_FD_FETCH_RELATIVE | SQL_FD_FETCH_BOOKMARK); break; case SQL_FILE_USAGE: /* ODBC 2.0 */ len = 2; value = SQL_FILE_NOT_SUPPORTED; break; case SQL_GETDATA_EXTENSIONS: /* ODBC 2.0 */ len = 4; value = (SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND | SQL_GD_BLOCK); break; case SQL_GROUP_BY: /* ODBC 2.0 */ len = 2; value = SQL_GB_GROUP_BY_EQUALS_SELECT; break; case SQL_IDENTIFIER_CASE: /* ODBC 1.0 */ /* are identifiers case-sensitive (yes, but only when quoted. If not quoted, they default to lowercase) */ len = 2; value = SQL_IC_LOWER; break; case SQL_IDENTIFIER_QUOTE_CHAR: /* ODBC 1.0 */ /* the character used to quote "identifiers" */ p = PG_VERSION_LE(conn, 6.2) ? " " : "\""; break; case SQL_KEYWORDS: /* ODBC 2.0 */ p = ""; break; case SQL_LIKE_ESCAPE_CLAUSE: /* ODBC 2.0 */ /* is there a character that escapes '%' and '_' in a LIKE clause? not as far as I can tell */ p = "N"; break; case SQL_LOCK_TYPES: /* ODBC 2.0 */ len = 4; value = globals.lie ? (SQL_LCK_NO_CHANGE | SQL_LCK_EXCLUSIVE | SQL_LCK_UNLOCK) : SQL_LCK_NO_CHANGE; break; case SQL_MAX_BINARY_LITERAL_LEN: /* ODBC 2.0 */ len = 4; value = 0; break; case SQL_MAX_CHAR_LITERAL_LEN: /* ODBC 2.0 */ len = 4; value = 0; break; case SQL_MAX_COLUMN_NAME_LEN: /* ODBC 1.0 */ len = 2; value = MAX_COLUMN_LEN; break; case SQL_MAX_COLUMNS_IN_GROUP_BY: /* ODBC 2.0 */ len = 2; value = 0; break; case SQL_MAX_COLUMNS_IN_INDEX: /* ODBC 2.0 */ len = 2; value = 0; break; case SQL_MAX_COLUMNS_IN_ORDER_BY: /* ODBC 2.0 */ len = 2; value = 0; break; case SQL_MAX_COLUMNS_IN_SELECT: /* ODBC 2.0 */ len = 2; value = 0; break; case SQL_MAX_COLUMNS_IN_TABLE: /* ODBC 2.0 */ len = 2; value = 0; break; case SQL_MAX_CURSOR_NAME_LEN: /* ODBC 1.0 */ len = 2; value = MAX_CURSOR_LEN; break; case SQL_MAX_INDEX_SIZE: /* ODBC 2.0 */ len = 4; value = 0; break; case SQL_MAX_OWNER_NAME_LEN: /* ODBC 1.0 */ len = 2; value = 0; break; case SQL_MAX_PROCEDURE_NAME_LEN: /* ODBC 1.0 */ len = 2; value = 0; break; case SQL_MAX_QUALIFIER_NAME_LEN: /* ODBC 1.0 */ len = 2; value = 0; break; case SQL_MAX_ROW_SIZE: /* ODBC 2.0 */ len = 4; if (PG_VERSION_GE(conn, 7.1)) { /* Large Rowa in 7.1+ */ value = MAX_ROW_SIZE; } else { /* Without the Toaster we're limited to the blocksize */ value = BLCKSZ; } break; case SQL_MAX_ROW_SIZE_INCLUDES_LONG: /* ODBC 2.0 */ /* does the preceding value include LONGVARCHAR and LONGVARBINARY fields? Well, it does include longvarchar, but not longvarbinary. */ p = "Y"; break; case SQL_MAX_STATEMENT_LEN: /* ODBC 2.0 */ /* maybe this should be 0? */ len = 4; if (PG_VERSION_GE(conn, 7.0)) { /* Long Queries in 7.0+ */ value = MAX_STATEMENT_LEN; } else if (PG_VERSION_GE(conn, 6.5)) /* Prior to 7.0 we used 2*BLCKSZ */ value = (2*BLCKSZ); else /* Prior to 6.5 we used BLCKSZ */ value = BLCKSZ; break; case SQL_MAX_TABLE_NAME_LEN: /* ODBC 1.0 */ len = 2; value = MAX_TABLE_LEN; break; case SQL_MAX_TABLES_IN_SELECT: /* ODBC 2.0 */ len = 2; value = 0; break; case SQL_MAX_USER_NAME_LEN: len = 2; value = 0; break; case SQL_MULT_RESULT_SETS: /* ODBC 1.0 */ /* Don't support multiple result sets but say yes anyway? */ p = "Y"; break; case SQL_MULTIPLE_ACTIVE_TXN: /* ODBC 1.0 */ p = "Y"; break; case SQL_NEED_LONG_DATA_LEN: /* ODBC 2.0 */ /* Dont need the length, SQLPutData can handle any size and multiple calls */ p = "N"; break; case SQL_NON_NULLABLE_COLUMNS: /* ODBC 1.0 */ len = 2; value = SQL_NNC_NON_NULL; break; case SQL_NULL_COLLATION: /* ODBC 2.0 */ /* where are nulls sorted? */ len = 2; value = SQL_NC_END; break; case SQL_NUMERIC_FUNCTIONS: /* ODBC 1.0 */ len = 4; value = 0; break; case SQL_ODBC_API_CONFORMANCE: /* ODBC 1.0 */ len = 2; value = SQL_OAC_LEVEL1; break; case SQL_ODBC_SAG_CLI_CONFORMANCE: /* ODBC 1.0 */ len = 2; value = SQL_OSCC_NOT_COMPLIANT; break; case SQL_ODBC_SQL_CONFORMANCE: /* ODBC 1.0 */ len = 2; value = SQL_OSC_CORE; break; case SQL_ODBC_SQL_OPT_IEF: /* ODBC 1.0 */ p = "N"; break; case SQL_OJ_CAPABILITIES: /* ODBC 2.01 */ case 115: len = 4; if (PG_VERSION_GE(conn, 7.1)) { /* OJs in 7.1+ */ value = (SQL_OJ_LEFT | SQL_OJ_RIGHT | SQL_OJ_FULL | SQL_OJ_NESTED | SQL_OJ_NOT_ORDERED | SQL_OJ_INNER | SQL_OJ_ALL_COMPARISON_OPS); } else { /* OJs not in <7.1 */ value = 0; } break; case SQL_ORDER_BY_COLUMNS_IN_SELECT: /* ODBC 2.0 */ p = (PG_VERSION_LE(conn, 6.3)) ? "Y" : "N"; break; case SQL_OUTER_JOINS: /* ODBC 1.0 */ if (PG_VERSION_GE(conn, 7.1)) { /* OJs in 7.1+ */ p = "Y"; } else { /* OJs not in <7.1 */ p = "N"; } break; case SQL_OWNER_TERM: /* ODBC 1.0 */ p = "owner"; break; case SQL_OWNER_USAGE: /* ODBC 2.0 */ len = 4; value = 0; break; case SQL_POS_OPERATIONS: /* ODBC 2.0 */ len = 4; value = globals.lie ? (SQL_POS_POSITION | SQL_POS_REFRESH | SQL_POS_UPDATE | SQL_POS_DELETE | SQL_POS_ADD) : (SQL_POS_POSITION | SQL_POS_REFRESH); break; case SQL_POSITIONED_STATEMENTS: /* ODBC 2.0 */ len = 4; value = globals.lie ? (SQL_PS_POSITIONED_DELETE | SQL_PS_POSITIONED_UPDATE | SQL_PS_SELECT_FOR_UPDATE) : 0; break; case SQL_PROCEDURE_TERM: /* ODBC 1.0 */ p = "procedure"; break; case SQL_PROCEDURES: /* ODBC 1.0 */ p = "Y"; break; case SQL_QUALIFIER_LOCATION: /* ODBC 2.0 */ len = 2; value = SQL_QL_START; break; case SQL_QUALIFIER_NAME_SEPARATOR: /* ODBC 1.0 */ p = ""; break; case SQL_QUALIFIER_TERM: /* ODBC 1.0 */ p = ""; break; case SQL_QUALIFIER_USAGE: /* ODBC 2.0 */ len = 4; value = 0; break; case SQL_QUOTED_IDENTIFIER_CASE: /* ODBC 2.0 */ /* are "quoted" identifiers case-sensitive? YES! */ len = 2; value = SQL_IC_SENSITIVE; break; case SQL_ROW_UPDATES: /* ODBC 1.0 */ /* Driver doesn't support keyset-driven or mixed cursors, so not much point in saying row updates are supported */ p = globals.lie ? "Y" : "N"; break; case SQL_SCROLL_CONCURRENCY: /* ODBC 1.0 */ len = 4; value = globals.lie ? (SQL_SCCO_READ_ONLY | SQL_SCCO_LOCK | SQL_SCCO_OPT_ROWVER | SQL_SCCO_OPT_VALUES) : (SQL_SCCO_READ_ONLY); break; case SQL_SCROLL_OPTIONS: /* ODBC 1.0 */ len = 4; value = globals.lie ? (SQL_SO_FORWARD_ONLY | SQL_SO_STATIC | SQL_SO_KEYSET_DRIVEN | SQL_SO_DYNAMIC | SQL_SO_MIXED) : (globals.use_declarefetch ? SQL_SO_FORWARD_ONLY : (SQL_SO_FORWARD_ONLY | SQL_SO_STATIC)); break; case SQL_SEARCH_PATTERN_ESCAPE: /* ODBC 1.0 */ p = ""; break; case SQL_SERVER_NAME: /* ODBC 1.0 */ p = CC_get_server(conn); break; case SQL_SPECIAL_CHARACTERS: /* ODBC 2.0 */ p = "_"; break; case SQL_STATIC_SENSITIVITY: /* ODBC 2.0 */ len = 4; value = globals.lie ? (SQL_SS_ADDITIONS | SQL_SS_DELETIONS | SQL_SS_UPDATES) : 0; break; case SQL_STRING_FUNCTIONS: /* ODBC 1.0 */ len = 4; value = (SQL_FN_STR_CONCAT | SQL_FN_STR_LCASE | SQL_FN_STR_LENGTH | SQL_FN_STR_LOCATE | SQL_FN_STR_LTRIM | SQL_FN_STR_RTRIM | SQL_FN_STR_SUBSTRING | SQL_FN_STR_UCASE); break; case SQL_SUBQUERIES: /* ODBC 2.0 */ /* postgres 6.3 supports subqueries */ len = 4; value = (SQL_SQ_QUANTIFIED | SQL_SQ_IN | SQL_SQ_EXISTS | SQL_SQ_COMPARISON); break; case SQL_SYSTEM_FUNCTIONS: /* ODBC 1.0 */ len = 4; value = 0; break; case SQL_TABLE_TERM: /* ODBC 1.0 */ p = "table"; break; case SQL_TIMEDATE_ADD_INTERVALS: /* ODBC 2.0 */ len = 4; value = 0; break; case SQL_TIMEDATE_DIFF_INTERVALS: /* ODBC 2.0 */ len = 4; value = 0; break; case SQL_TIMEDATE_FUNCTIONS: /* ODBC 1.0 */ len = 4; value = (SQL_FN_TD_NOW); break; case SQL_TXN_CAPABLE: /* ODBC 1.0 */ /* Postgres can deal with create or drop table statements in a transaction */ len = 2; value = SQL_TC_ALL; break; case SQL_TXN_ISOLATION_OPTION: /* ODBC 1.0 */ len = 4; value = SQL_TXN_READ_COMMITTED; /* SQL_TXN_SERIALIZABLE; */ break; case SQL_UNION: /* ODBC 2.0 */ /* unions with all supported in postgres 6.3 */ len = 4; value = (SQL_U_UNION | SQL_U_UNION_ALL); break; case SQL_USER_NAME: /* ODBC 1.0 */ p = CC_get_username(conn); break; /* * These have been added even though they are ODBC 3 attributes to enable * StarOffice 6.0 and OpenOffice to work, its a problem in the app, but * we do what we can... */ case /*SQL_CREATE_VIEW*/ 134: len = 4; value = SQL_CV_CREATE_VIEW; break; case /*SQL_STATIC_CURSOR_ATTRIBUTES1*/ 167: len = 4; /*value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE | SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK;*/ value = 0x00000001L | 0x00000002L | 0x00000004L | 0x00000008L; break; default: /* unrecognized key */ CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR, "Unrecognized key passed to SQLGetInfo."); CC_log_error(func, "", conn); return SQL_ERROR; } result = SQL_SUCCESS; mylog("SQLGetInfo: p='%s', len=%d, value=%d, cbMax=%d\n", p?p:"", len, value, cbInfoValueMax); /* NOTE, that if rgbInfoValue is NULL, then no warnings or errors should result and just pcbInfoValue is returned, which indicates what length would be required if a real buffer had been passed in. */ if (p) { /* char/binary data */ len = strlen(p); if (rgbInfoValue) { strncpy_null((char *)rgbInfoValue, p, (size_t)cbInfoValueMax); if (len >= cbInfoValueMax) { result = SQL_SUCCESS_WITH_INFO; CC_set_error(conn, STMT_TRUNCATED, "The buffer was too small for the result."); } } } else { /* numeric data */ if (rgbInfoValue) { if (len == 2 ) *((WORD *)rgbInfoValue) = (WORD) value; else if (len == 4) *((DWORD *)rgbInfoValue) = (DWORD) value; } } if (pcbInfoValue) *pcbInfoValue = len; return result; } /* - - - - - - - - - */ RETCODE SQL_API SQLGetTypeInfo( HSTMT hstmt, SWORD fSqlType) { static char* const func = "SQLGetTypeInfo"; StatementClass *stmt = (StatementClass *) hstmt; TupleNode *row; int i; /* Int4 type; */ Int4 pgType; Int2 sqlType; mylog("%s: entering...fSqlType = %d\n", func, fSqlType); if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } stmt->manual_result = TRUE; stmt->result = QR_Constructor(); if( ! stmt->result) { SC_log_error(func, "Error creating result.", stmt); return SQL_ERROR; } extend_bindings(stmt, 15); QR_set_num_fields(stmt->result, 15); QR_set_field_info(stmt->result, 0, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 1, "DATA_TYPE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 2, "PRECISION", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 3, "LITERAL_PREFIX", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 4, "LITERAL_SUFFIX", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 5, "CREATE_PARAMS", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 6, "NULLABLE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 7, "CASE_SENSITIVE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 8, "SEARCHABLE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 9, "UNSIGNED_ATTRIBUTE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 10, "MONEY", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 11, "AUTO_INCREMENT", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 12, "LOCAL_TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 13, "MINIMUM_SCALE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 14, "MAXIMUM_SCALE", PG_TYPE_INT2, 2); for(i=0, sqlType = sqlTypes[0]; sqlType; sqlType = sqlTypes[++i]) { pgType = sqltype_to_pgtype(sqlType); if (fSqlType == SQL_ALL_TYPES || fSqlType == sqlType) { row = (TupleNode *)malloc(sizeof(TupleNode) + (15 - 1)*sizeof(TupleField)); /* These values can't be NULL */ set_tuplefield_string(&row->tuple[0], pgtype_to_name(stmt, pgType)); set_tuplefield_int2(&row->tuple[1], (Int2) sqlType); set_tuplefield_int2(&row->tuple[6], pgtype_nullable(stmt, pgType)); set_tuplefield_int2(&row->tuple[7], pgtype_case_sensitive(stmt, pgType)); set_tuplefield_int2(&row->tuple[8], pgtype_searchable(stmt, pgType)); set_tuplefield_int2(&row->tuple[10], pgtype_money(stmt, pgType)); /* Localized data-source dependent data type name (always NULL) */ set_tuplefield_null(&row->tuple[12]); /* These values can be NULL */ set_nullfield_int4(&row->tuple[2], pgtype_precision(stmt, pgType, PG_STATIC, PG_STATIC)); set_nullfield_string(&row->tuple[3], pgtype_literal_prefix(stmt, pgType)); set_nullfield_string(&row->tuple[4], pgtype_literal_suffix(stmt, pgType)); set_nullfield_string(&row->tuple[5], pgtype_create_params(stmt, pgType)); set_nullfield_int2(&row->tuple[9], pgtype_unsigned(stmt, pgType)); set_nullfield_int2(&row->tuple[11], pgtype_auto_increment(stmt, pgType)); set_nullfield_int2(&row->tuple[13], pgtype_scale(stmt, pgType, PG_STATIC)); set_nullfield_int2(&row->tuple[14], pgtype_scale(stmt, pgType, PG_STATIC)); QR_add_tuple(stmt->result, row); } } stmt->status = STMT_FINISHED; stmt->currTuple = -1; stmt->rowset_start = -1; stmt->current_col = -1; return SQL_SUCCESS; } /* - - - - - - - - - */ RETCODE SQL_API SQLGetFunctions( HDBC hdbc, UWORD fFunction, UWORD FAR *pfExists) { static char* const func="SQLGetFunctions"; mylog( "%s: entering...\n", func); if (fFunction == SQL_API_ALL_FUNCTIONS) { if (globals.lie) { int i; memset(pfExists, 0, sizeof(UWORD)*100); pfExists[SQL_API_SQLALLOCENV] = TRUE; pfExists[SQL_API_SQLFREEENV] = TRUE; for (i = SQL_API_SQLALLOCCONNECT; i <= SQL_NUM_FUNCTIONS; i++) pfExists[i] = TRUE; for (i = SQL_EXT_API_START; i <= SQL_EXT_API_LAST; i++) pfExists[i] = TRUE; } else { memset(pfExists, 0, sizeof(UWORD)*100); /* ODBC core functions */ pfExists[SQL_API_SQLALLOCCONNECT] = TRUE; pfExists[SQL_API_SQLALLOCENV] = TRUE; pfExists[SQL_API_SQLALLOCSTMT] = TRUE; pfExists[SQL_API_SQLBINDCOL] = TRUE; pfExists[SQL_API_SQLCANCEL] = TRUE; pfExists[SQL_API_SQLCOLATTRIBUTES] = TRUE; pfExists[SQL_API_SQLCONNECT] = TRUE; pfExists[SQL_API_SQLDESCRIBECOL] = TRUE; /* partial */ pfExists[SQL_API_SQLDISCONNECT] = TRUE; pfExists[SQL_API_SQLERROR] = TRUE; pfExists[SQL_API_SQLEXECDIRECT] = TRUE; pfExists[SQL_API_SQLEXECUTE] = TRUE; pfExists[SQL_API_SQLFETCH] = TRUE; pfExists[SQL_API_SQLFREECONNECT] = TRUE; pfExists[SQL_API_SQLFREEENV] = TRUE; pfExists[SQL_API_SQLFREESTMT] = TRUE; pfExists[SQL_API_SQLGETCURSORNAME] = TRUE; pfExists[SQL_API_SQLNUMRESULTCOLS] = TRUE; pfExists[SQL_API_SQLPREPARE] = TRUE; /* complete? */ pfExists[SQL_API_SQLROWCOUNT] = TRUE; pfExists[SQL_API_SQLSETCURSORNAME] = TRUE; pfExists[SQL_API_SQLSETPARAM] = FALSE; /* odbc 1.0 */ pfExists[SQL_API_SQLTRANSACT] = TRUE; /* ODBC level 1 functions */ pfExists[SQL_API_SQLBINDPARAMETER] = TRUE; pfExists[SQL_API_SQLCOLUMNS] = TRUE; pfExists[SQL_API_SQLDRIVERCONNECT] = TRUE; pfExists[SQL_API_SQLGETCONNECTOPTION] = TRUE; /* partial */ pfExists[SQL_API_SQLGETDATA] = TRUE; pfExists[SQL_API_SQLGETFUNCTIONS] = TRUE; pfExists[SQL_API_SQLGETINFO] = TRUE; pfExists[SQL_API_SQLGETSTMTOPTION] = TRUE; /* partial */ pfExists[SQL_API_SQLGETTYPEINFO] = TRUE; pfExists[SQL_API_SQLPARAMDATA] = TRUE; pfExists[SQL_API_SQLPUTDATA] = TRUE; pfExists[SQL_API_SQLSETCONNECTOPTION] = TRUE; /* partial */ pfExists[SQL_API_SQLSETSTMTOPTION] = TRUE; pfExists[SQL_API_SQLSPECIALCOLUMNS] = TRUE; pfExists[SQL_API_SQLSTATISTICS] = TRUE; pfExists[SQL_API_SQLTABLES] = TRUE; /* ODBC level 2 functions */ pfExists[SQL_API_SQLBROWSECONNECT] = FALSE; pfExists[SQL_API_SQLCOLUMNPRIVILEGES] = FALSE; pfExists[SQL_API_SQLDATASOURCES] = FALSE; /* only implemented by DM */ pfExists[SQL_API_SQLDESCRIBEPARAM] = FALSE; /* not properly implemented */ pfExists[SQL_API_SQLDRIVERS] = FALSE; /* only implemented by DM */ pfExists[SQL_API_SQLEXTENDEDFETCH] = TRUE; pfExists[SQL_API_SQLFOREIGNKEYS] = TRUE; pfExists[SQL_API_SQLMORERESULTS] = TRUE; pfExists[SQL_API_SQLNATIVESQL] = TRUE; pfExists[SQL_API_SQLNUMPARAMS] = TRUE; pfExists[SQL_API_SQLPARAMOPTIONS] = FALSE; pfExists[SQL_API_SQLPRIMARYKEYS] = TRUE; pfExists[SQL_API_SQLPROCEDURECOLUMNS] = FALSE; pfExists[SQL_API_SQLPROCEDURES] = FALSE; pfExists[SQL_API_SQLSETPOS] = TRUE; pfExists[SQL_API_SQLSETSCROLLOPTIONS] = TRUE; /* odbc 1.0 */ pfExists[SQL_API_SQLTABLEPRIVILEGES] = FALSE; } } else { if (globals.lie) *pfExists = TRUE; else { switch(fFunction) { case SQL_API_SQLALLOCCONNECT: *pfExists = TRUE; break; case SQL_API_SQLALLOCENV: *pfExists = TRUE; break; case SQL_API_SQLALLOCSTMT: *pfExists = TRUE; break; case SQL_API_SQLBINDCOL: *pfExists = TRUE; break; case SQL_API_SQLCANCEL: *pfExists = TRUE; break; case SQL_API_SQLCOLATTRIBUTES: *pfExists = TRUE; break; case SQL_API_SQLCONNECT: *pfExists = TRUE; break; case SQL_API_SQLDESCRIBECOL: *pfExists = TRUE; break; /* partial */ case SQL_API_SQLDISCONNECT: *pfExists = TRUE; break; case SQL_API_SQLERROR: *pfExists = TRUE; break; case SQL_API_SQLEXECDIRECT: *pfExists = TRUE; break; case SQL_API_SQLEXECUTE: *pfExists = TRUE; break; case SQL_API_SQLFETCH: *pfExists = TRUE; break; case SQL_API_SQLFREECONNECT: *pfExists = TRUE; break; case SQL_API_SQLFREEENV: *pfExists = TRUE; break; case SQL_API_SQLFREESTMT: *pfExists = TRUE; break; case SQL_API_SQLGETCURSORNAME: *pfExists = TRUE; break; case SQL_API_SQLNUMRESULTCOLS: *pfExists = TRUE; break; case SQL_API_SQLPREPARE: *pfExists = TRUE; break; case SQL_API_SQLROWCOUNT: *pfExists = TRUE; break; case SQL_API_SQLSETCURSORNAME: *pfExists = TRUE; break; case SQL_API_SQLSETPARAM: *pfExists = FALSE; break; /* odbc 1.0 */ case SQL_API_SQLTRANSACT: *pfExists = TRUE; break; /* ODBC level 1 functions */ case SQL_API_SQLBINDPARAMETER: *pfExists = TRUE; break; case SQL_API_SQLCOLUMNS: *pfExists = TRUE; break; case SQL_API_SQLDRIVERCONNECT: *pfExists = TRUE; break; case SQL_API_SQLGETCONNECTOPTION: *pfExists = TRUE; break; /* partial */ case SQL_API_SQLGETDATA: *pfExists = TRUE; break; case SQL_API_SQLGETFUNCTIONS: *pfExists = TRUE; break; case SQL_API_SQLGETINFO: *pfExists = TRUE; break; case SQL_API_SQLGETSTMTOPTION: *pfExists = TRUE; break; /* partial */ case SQL_API_SQLGETTYPEINFO: *pfExists = TRUE; break; case SQL_API_SQLPARAMDATA: *pfExists = TRUE; break; case SQL_API_SQLPUTDATA: *pfExists = TRUE; break; case SQL_API_SQLSETCONNECTOPTION: *pfExists = TRUE; break; /* partial */ case SQL_API_SQLSETSTMTOPTION: *pfExists = TRUE; break; case SQL_API_SQLSPECIALCOLUMNS: *pfExists = TRUE; break; case SQL_API_SQLSTATISTICS: *pfExists = TRUE; break; case SQL_API_SQLTABLES: *pfExists = TRUE; break; /* ODBC level 2 functions */ case SQL_API_SQLBROWSECONNECT: *pfExists = FALSE; break; case SQL_API_SQLCOLUMNPRIVILEGES: *pfExists = FALSE; break; case SQL_API_SQLDATASOURCES: *pfExists = FALSE; break; /* only implemented by DM */ case SQL_API_SQLDESCRIBEPARAM: *pfExists = FALSE; break; /* not properly implemented */ case SQL_API_SQLDRIVERS: *pfExists = FALSE; break; /* only implemented by DM */ case SQL_API_SQLEXTENDEDFETCH: *pfExists = TRUE; break; case SQL_API_SQLFOREIGNKEYS: *pfExists = TRUE; break; case SQL_API_SQLMORERESULTS: *pfExists = TRUE; break; case SQL_API_SQLNATIVESQL: *pfExists = TRUE; break; case SQL_API_SQLNUMPARAMS: *pfExists = TRUE; break; case SQL_API_SQLPARAMOPTIONS: *pfExists = FALSE; break; case SQL_API_SQLPRIMARYKEYS: *pfExists = TRUE; break; case SQL_API_SQLPROCEDURECOLUMNS: *pfExists = FALSE; break; case SQL_API_SQLPROCEDURES: *pfExists = FALSE; break; case SQL_API_SQLSETPOS: *pfExists = TRUE; break; case SQL_API_SQLSETSCROLLOPTIONS: *pfExists = TRUE; break; /* odbc 1.0 */ case SQL_API_SQLTABLEPRIVILEGES: *pfExists = FALSE; break; } } } return SQL_SUCCESS; } RETCODE SQL_API SQLTables( HSTMT hstmt, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName, UCHAR FAR * szTableType, SWORD cbTableType) { static char* const func = "SQLTables"; StatementClass *stmt = (StatementClass *) hstmt; StatementClass *tbl_stmt; TupleNode *row; HSTMT htbl_stmt; RETCODE result; char *tableType; char tables_query[STD_STATEMENT_LEN]; char table_name[MAX_INFO_STRING], table_owner[MAX_INFO_STRING], relkind_or_hasrules[MAX_INFO_STRING]; ConnectionClass *conn; ConnInfo *ci; char *prefix[32], prefixes[MEDIUM_REGISTRY_LEN]; char *table_type[32], table_types[MAX_INFO_STRING]; char show_system_tables, show_regular_tables, show_views; char regular_table, view, systable; int i; mylog("%s: entering...stmt=%u\n", func, stmt); if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } stmt->manual_result = TRUE; stmt->errormsg_created = TRUE; conn = (ConnectionClass *) (stmt->hdbc); ci = &stmt->hdbc->connInfo; result = PG_SQLAllocStmt( stmt->hdbc, &htbl_stmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for SQLTables result."); SC_log_error(func, "", stmt); return SQL_ERROR; } tbl_stmt = (StatementClass *) htbl_stmt; /* ********************************************************************** */ /* Create the query to find out the tables */ /* ********************************************************************** */ if (PG_VERSION_GE(conn, 7.1)) { /* view is represented by its relkind since 7.1 */ strcpy(tables_query, "select relname, usename, relkind from pg_class, pg_user"); strcat(tables_query, " where relkind in ('r', 'v')"); } else { strcpy(tables_query, "select relname, usename, relhasrules from pg_class, pg_user"); strcat(tables_query, " where relkind = 'r'"); } my_strcat(tables_query, " and usename like '%.*s'", (char*)szTableOwner, cbTableOwner); my_strcat(tables_query, " and relname like '%.*s'", (char*)szTableName, cbTableName); /* Parse the extra systable prefix */ strcpy(prefixes, globals.extra_systable_prefixes); i = 0; prefix[i] = strtok(prefixes, ";"); while (prefix[i] && ishow_system_tables) && ! show_system_tables) { strcat(tables_query, " and relname !~ '^" POSTGRES_SYS_PREFIX); /* Also filter out user-defined system table types */ i = 0; while(prefix[i]) { strcat(tables_query, "|^"); strcat(tables_query, prefix[i]); i++; } strcat(tables_query, "'"); } /* match users */ if (PG_VERSION_LT(conn, 7.1)) /* filter out large objects in older versions */ strcat(tables_query, " and relname !~ '^xinv[0-9]+'"); strcat(tables_query, " and usesysid = relowner"); strcat(tables_query, " order by relname"); /* ********************************************************************** */ result = PG_SQLExecDirect(htbl_stmt, tables_query, strlen(tables_query)); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_create_errormsg((StatementClass *)htbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 1, SQL_C_CHAR, table_name, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 2, SQL_C_CHAR, table_owner, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 3, SQL_C_CHAR, relkind_or_hasrules, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } stmt->result = QR_Constructor(); if(!stmt->result) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for SQLTables result."); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } /* the binding structure for a statement is not set up until */ /* a statement is actually executed, so we'll have to do this ourselves. */ extend_bindings(stmt, 5); /* set the field names */ QR_set_num_fields(stmt->result, 5); QR_set_field_info(stmt->result, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 3, "TABLE_TYPE", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 4, "REMARKS", PG_TYPE_TEXT, 254); /* add the tuples */ result = PG_SQLFetch(htbl_stmt); while((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) { /* Determine if this table name is a system table. If treating system tables as regular tables, then no need to do this test. */ systable = FALSE; if( ! atoi(ci->show_system_tables)) { if ( strncmp(table_name, POSTGRES_SYS_PREFIX, strlen(POSTGRES_SYS_PREFIX)) == 0) systable = TRUE; else { /* Check extra system table prefixes */ i = 0; while (prefix[i]) { mylog("table_name='%s', prefix[%d]='%s'\n", table_name, i, prefix[i]); if (strncmp(table_name, prefix[i], strlen(prefix[i])) == 0) { systable = TRUE; break; } i++; } } } /* Determine if the table name is a view */ if (PG_VERSION_GE(conn, 7.1)) /* view is represented by its relkind since 7.1 */ view = (relkind_or_hasrules[0] == 'v'); else view = (relkind_or_hasrules[0] == '1'); /* It must be a regular table */ regular_table = ( ! systable && ! view); /* Include the row in the result set if meets all criteria */ /* NOTE: Unsupported table types (i.e., LOCAL TEMPORARY, ALIAS, etc) will return nothing */ if ( (systable && show_system_tables) || (view && show_views) || (regular_table && show_regular_tables)) { row = (TupleNode *)malloc(sizeof(TupleNode) + (5 - 1) * sizeof(TupleField)); set_tuplefield_string(&row->tuple[0], ""); /* I have to hide the table owner from Access, otherwise it */ /* insists on referring to the table as 'owner.table'. */ /* (this is valid according to the ODBC SQL grammar, but */ /* Postgres won't support it.) */ /* set_tuplefield_string(&row->tuple[1], table_owner); */ mylog("SQLTables: table_name = '%s'\n", table_name); set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[2], table_name); set_tuplefield_string(&row->tuple[3], systable ? "SYSTEM TABLE" : (view ? "VIEW" : "TABLE")); set_tuplefield_string(&row->tuple[4], ""); QR_add_tuple(stmt->result, row); } result = PG_SQLFetch(htbl_stmt); } if(result != SQL_NO_DATA_FOUND) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_create_errormsg((StatementClass *)htbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } /* also, things need to think that this statement is finished so */ /* the results can be retrieved. */ stmt->status = STMT_FINISHED; /* set up the current tuple pointer for SQLFetch */ stmt->currTuple = -1; stmt->rowset_start = -1; stmt->current_col = -1; PG_SQLFreeStmt(htbl_stmt, SQL_DROP); mylog("SQLTables(): EXIT, stmt=%u\n", stmt); return SQL_SUCCESS; } RETCODE SQL_API PG_SQLColumns( HSTMT hstmt, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName, UCHAR FAR * szColumnName, SWORD cbColumnName) { static char* const func = "SQLColumns"; StatementClass *stmt = (StatementClass *) hstmt; TupleNode *row; HSTMT hcol_stmt; StatementClass *col_stmt; char columns_query[STD_STATEMENT_LEN]; RETCODE result; char table_owner[MAX_INFO_STRING], table_name[MAX_INFO_STRING], field_name[MAX_INFO_STRING], field_type_name[MAX_INFO_STRING]; Int2 field_number, result_cols, scale; Int4 field_type, the_type, field_length, mod_length, precision; char useStaticPrecision; char not_null[MAX_INFO_STRING], relhasrules[MAX_INFO_STRING]; ConnInfo *ci; ConnectionClass *conn; mylog("%s: entering...stmt=%u\n", func, stmt); if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } stmt->manual_result = TRUE; stmt->errormsg_created = TRUE; conn = (ConnectionClass *) (stmt->hdbc); ci = &stmt->hdbc->connInfo; /* ********************************************************************** */ /* Create the query to find out the columns (Note: pre 6.3 did not have the atttypmod field) */ /* ********************************************************************** */ sprintf(columns_query, "select u.usename, c.relname, a.attname, a.atttypid" ", t.typname, a.attnum, a.attlen, %s, a.attnotnull, c.relhasrules" " from pg_user u, pg_class c, pg_attribute a, pg_type t" " where u.usesysid = c.relowner" " and c.oid= a.attrelid and a.atttypid = t.oid and (a.attnum > 0)", PG_VERSION_LE(conn, 6.2) ? "a.attlen" : "a.atttypmod"); my_strcat(columns_query, " and c.relname like '%.*s'", (char*)szTableName, cbTableName); my_strcat(columns_query, " and u.usename like '%.*s'", (char*)szTableOwner, cbTableOwner); my_strcat(columns_query, " and a.attname like '%.*s'", (char*)szColumnName, cbColumnName); /* give the output in the order the columns were defined */ /* when the table was created */ strcat(columns_query, " order by attnum"); /* ********************************************************************** */ result = PG_SQLAllocStmt( stmt->hdbc, &hcol_stmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for SQLColumns result."); SC_log_error(func, "", stmt); return SQL_ERROR; } col_stmt = (StatementClass *) hcol_stmt; mylog("SQLColumns: hcol_stmt = %u, col_stmt = %u\n", hcol_stmt, col_stmt); result = PG_SQLExecDirect(hcol_stmt, columns_query, strlen(columns_query)); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_create_errormsg((StatementClass *)hcol_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(hcol_stmt, 1, SQL_C_CHAR, table_owner, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(hcol_stmt, 2, SQL_C_CHAR, table_name, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(hcol_stmt, 3, SQL_C_CHAR, field_name, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(hcol_stmt, 4, SQL_C_LONG, &field_type, 4, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(hcol_stmt, 5, SQL_C_CHAR, field_type_name, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(hcol_stmt, 6, SQL_C_SHORT, &field_number, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(hcol_stmt, 7, SQL_C_LONG, &field_length, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(hcol_stmt, 8, SQL_C_LONG, &mod_length, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(hcol_stmt, 9, SQL_C_CHAR, not_null, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(hcol_stmt, 10, SQL_C_CHAR, relhasrules, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } stmt->result = QR_Constructor(); if(!stmt->result) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for SQLColumns result."); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } /* the binding structure for a statement is not set up until */ /* a statement is actually executed, so we'll have to do this ourselves. */ result_cols = 14; extend_bindings(stmt, result_cols); /* set the field names */ QR_set_num_fields(stmt->result, result_cols); QR_set_field_info(stmt->result, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 3, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 4, "DATA_TYPE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 5, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 6, "PRECISION", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 7, "LENGTH", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 8, "SCALE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 9, "RADIX", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 10, "NULLABLE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 11, "REMARKS", PG_TYPE_TEXT, 254); /* User defined fields */ QR_set_field_info(stmt->result, 12, "DISPLAY_SIZE", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 13, "FIELD_TYPE", PG_TYPE_INT4, 4); result = PG_SQLFetch(hcol_stmt); /* Only show oid if option AND there are other columns AND it's not being called by SQLStatistics . Always show OID if it's a system table */ if (result != SQL_ERROR && ! stmt->internal) { if (relhasrules[0] != '1' && (atoi(ci->show_oid_column) || strncmp(table_name, POSTGRES_SYS_PREFIX, strlen(POSTGRES_SYS_PREFIX)) == 0)) { /* For OID fields */ the_type = PG_TYPE_OID; row = (TupleNode *)malloc(sizeof(TupleNode) + (result_cols - 1) * sizeof(TupleField)); set_tuplefield_string(&row->tuple[0], ""); /* see note in SQLTables() */ /* set_tuplefield_string(&row->tuple[1], table_owner); */ set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[2], table_name); set_tuplefield_string(&row->tuple[3], "oid"); set_tuplefield_int2(&row->tuple[4], pgtype_to_sqltype(stmt, the_type)); set_tuplefield_string(&row->tuple[5], "OID"); set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC)); set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, the_type, PG_STATIC, PG_STATIC)); set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, the_type, PG_STATIC)); set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, the_type)); set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS); set_tuplefield_string(&row->tuple[11], ""); set_tuplefield_int4(&row->tuple[12], pgtype_display_size(stmt, the_type, PG_STATIC, PG_STATIC)); set_tuplefield_int4(&row->tuple[13], the_type); QR_add_tuple(stmt->result, row); } } while((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) { row = (TupleNode *)malloc(sizeof(TupleNode) + (result_cols - 1) * sizeof(TupleField)); set_tuplefield_string(&row->tuple[0], ""); /* see note in SQLTables() */ /* set_tuplefield_string(&row->tuple[1], table_owner); */ set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[2], table_name); set_tuplefield_string(&row->tuple[3], field_name); set_tuplefield_int2(&row->tuple[4], pgtype_to_sqltype(stmt, field_type)); set_tuplefield_string(&row->tuple[5], field_type_name); /* Some Notes about Postgres Data Types: VARCHAR - the length is stored in the pg_attribute.atttypmod field BPCHAR - the length is also stored as varchar is NUMERIC - the scale is stored in atttypmod as follows: precision = ((atttypmod - VARHDRSZ) >> 16) & 0xffff scale = (atttypmod - VARHDRSZ) & 0xffff */ qlog("SQLColumns: table='%s',field_name='%s',type=%d,sqltype=%d,name='%s'\n", table_name,field_name,field_type,pgtype_to_sqltype,field_type_name); useStaticPrecision = TRUE; if (field_type == PG_TYPE_NUMERIC) { if (mod_length >= 4) mod_length -= 4; /* the length is in atttypmod - 4 */ if (mod_length >= 0) { useStaticPrecision = FALSE; precision = (mod_length >> 16) & 0xffff; scale = mod_length & 0xffff; mylog("SQLColumns: field type is NUMERIC: field_type = %d, mod_length=%d, precision=%d, scale=%d\n", field_type, mod_length, precision, scale ); set_tuplefield_int4(&row->tuple[7], precision + 2); /* sign+dec.point */ set_tuplefield_int4(&row->tuple[6], precision); set_tuplefield_int4(&row->tuple[12], precision + 2); /* sign+dec.point */ set_nullfield_int2(&row->tuple[8], scale); } } if((field_type == PG_TYPE_VARCHAR) || (field_type == PG_TYPE_BPCHAR)) { useStaticPrecision = FALSE; if (mod_length >= 4) mod_length -= 4; /* the length is in atttypmod - 4 */ if (mod_length > globals.max_varchar_size || mod_length <= 0) mod_length = globals.max_varchar_size; mylog("SQLColumns: field type is VARCHAR,BPCHAR: field_type = %d, mod_length = %d\n", field_type, mod_length); set_tuplefield_int4(&row->tuple[7], mod_length); set_tuplefield_int4(&row->tuple[6], mod_length); set_tuplefield_int4(&row->tuple[12], mod_length); set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, field_type, PG_STATIC)); } if (useStaticPrecision) { mylog("SQLColumns: field type is OTHER: field_type = %d, pgtype_length = %d\n", field_type, pgtype_length(stmt, field_type, PG_STATIC, PG_STATIC)); set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, field_type, PG_STATIC, PG_STATIC)); set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, field_type, PG_STATIC, PG_STATIC)); set_tuplefield_int4(&row->tuple[12], pgtype_display_size(stmt, field_type, PG_STATIC, PG_STATIC)); set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, field_type, PG_STATIC)); } set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, field_type)); set_tuplefield_int2(&row->tuple[10], (Int2) (not_null[0] == '1' ? SQL_NO_NULLS : pgtype_nullable(stmt, field_type))); set_tuplefield_string(&row->tuple[11], ""); set_tuplefield_int4(&row->tuple[13], field_type); QR_add_tuple(stmt->result, row); result = PG_SQLFetch(hcol_stmt); } if(result != SQL_NO_DATA_FOUND) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_create_errormsg((StatementClass *)hcol_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } /* Put the row version column at the end so it might not be */ /* mistaken for a key field. */ if ( relhasrules[0] != '1' && ! stmt->internal && atoi(ci->row_versioning)) { /* For Row Versioning fields */ the_type = PG_TYPE_INT4; row = (TupleNode *)malloc(sizeof(TupleNode) + (result_cols - 1) * sizeof(TupleField)); set_tuplefield_string(&row->tuple[0], ""); set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[2], table_name); set_tuplefield_string(&row->tuple[3], "xmin"); set_tuplefield_int2(&row->tuple[4], pgtype_to_sqltype(stmt, the_type)); set_tuplefield_string(&row->tuple[5], pgtype_to_name(stmt, the_type)); set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, the_type, PG_STATIC, PG_STATIC)); set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC)); set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, the_type, PG_STATIC)); set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, the_type)); set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS); set_tuplefield_string(&row->tuple[11], ""); set_tuplefield_int4(&row->tuple[12], pgtype_display_size(stmt, the_type, PG_STATIC, PG_STATIC)); set_tuplefield_int4(&row->tuple[13], the_type); QR_add_tuple(stmt->result, row); } /* also, things need to think that this statement is finished so */ /* the results can be retrieved. */ stmt->status = STMT_FINISHED; /* set up the current tuple pointer for SQLFetch */ stmt->currTuple = -1; stmt->rowset_start = -1; stmt->current_col = -1; PG_SQLFreeStmt(hcol_stmt, SQL_DROP); mylog("SQLColumns(): EXIT, stmt=%u\n", stmt); return SQL_SUCCESS; } RETCODE SQL_API SQLColumns( HSTMT hstmt, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName, UCHAR FAR * szColumnName, SWORD cbColumnName) { return PG_SQLColumns( hstmt, szTableQualifier, cbTableQualifier, szTableOwner, cbTableOwner, szTableName, cbTableName, szColumnName, cbColumnName ); } RETCODE SQL_API SQLSpecialColumns( HSTMT hstmt, UWORD fColType, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName, UWORD fScope, UWORD fNullable) { static char* const func = "SQLSpecialColumns"; TupleNode *row; StatementClass *stmt = (StatementClass *) hstmt; ConnInfo *ci; HSTMT hcol_stmt; StatementClass *col_stmt; char columns_query[STD_STATEMENT_LEN]; RETCODE result; char relhasrules[MAX_INFO_STRING]; mylog("%s: entering...stmt=%u\n", func, stmt); if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } ci = &stmt->hdbc->connInfo; stmt->manual_result = TRUE; /* ********************************************************************** */ /* Create the query to find out if this is a view or not... */ /* ********************************************************************** */ sprintf(columns_query, "select c.relhasrules " "from pg_user u, pg_class c where " "u.usesysid = c.relowner"); my_strcat(columns_query, " and c.relname like '%.*s'", (char*)szTableName, cbTableName); my_strcat(columns_query, " and u.usename like '%.*s'", (char*)szTableOwner, cbTableOwner); result = PG_SQLAllocStmt( stmt->hdbc, &hcol_stmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for SQLSpecialColumns result."); SC_log_error(func, "", stmt); return SQL_ERROR; } col_stmt = (StatementClass *) hcol_stmt; mylog("SQLSpecialColumns: hcol_stmt = %u, col_stmt = %u\n", hcol_stmt, col_stmt); result = PG_SQLExecDirect(hcol_stmt, columns_query, strlen(columns_query)); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_create_errormsg((StatementClass *)hcol_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(hcol_stmt, 1, SQL_C_CHAR, relhasrules, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLFetch(hcol_stmt); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); stmt->result = QR_Constructor(); extend_bindings(stmt, 8); QR_set_num_fields(stmt->result, 8); QR_set_field_info(stmt->result, 0, "SCOPE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 1, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 2, "DATA_TYPE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 3, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 4, "PRECISION", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 5, "LENGTH", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 6, "SCALE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 7, "PSEUDO_COLUMN", PG_TYPE_INT2, 2); if ( relhasrules[0] != '1' ) { /* use the oid value for the rowid */ if(fColType == SQL_BEST_ROWID) { row = (TupleNode *)malloc(sizeof(TupleNode) + (8 - 1) * sizeof(TupleField)); set_tuplefield_int2(&row->tuple[0], SQL_SCOPE_SESSION); set_tuplefield_string(&row->tuple[1], "oid"); set_tuplefield_int2(&row->tuple[2], pgtype_to_sqltype(stmt, PG_TYPE_OID)); set_tuplefield_string(&row->tuple[3], "OID"); set_tuplefield_int4(&row->tuple[4], pgtype_precision(stmt, PG_TYPE_OID, PG_STATIC, PG_STATIC)); set_tuplefield_int4(&row->tuple[5], pgtype_length(stmt, PG_TYPE_OID, PG_STATIC, PG_STATIC)); set_tuplefield_int2(&row->tuple[6], pgtype_scale(stmt, PG_TYPE_OID, PG_STATIC)); set_tuplefield_int2(&row->tuple[7], SQL_PC_PSEUDO); QR_add_tuple(stmt->result, row); } else if(fColType == SQL_ROWVER) { Int2 the_type = PG_TYPE_INT4; if (atoi(ci->row_versioning)) { row = (TupleNode *)malloc(sizeof(TupleNode) + (8 - 1) * sizeof(TupleField)); set_tuplefield_null(&row->tuple[0]); set_tuplefield_string(&row->tuple[1], "xmin"); set_tuplefield_int2(&row->tuple[2], pgtype_to_sqltype(stmt, the_type)); set_tuplefield_string(&row->tuple[3], pgtype_to_name(stmt, the_type)); set_tuplefield_int4(&row->tuple[4], pgtype_precision(stmt, the_type, PG_STATIC, PG_STATIC)); set_tuplefield_int4(&row->tuple[5], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC)); set_tuplefield_int2(&row->tuple[6], pgtype_scale(stmt, the_type, PG_STATIC)); set_tuplefield_int2(&row->tuple[7], SQL_PC_PSEUDO); QR_add_tuple(stmt->result, row); } } } stmt->status = STMT_FINISHED; stmt->currTuple = -1; stmt->rowset_start = -1; stmt->current_col = -1; mylog("SQLSpecialColumns(): EXIT, stmt=%u\n", stmt); return SQL_SUCCESS; } RETCODE SQL_API SQLStatistics( HSTMT hstmt, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName, UWORD fUnique, UWORD fAccuracy) { static char* const func="SQLStatistics"; StatementClass *stmt = (StatementClass *) hstmt; char index_query[STD_STATEMENT_LEN]; HSTMT hindx_stmt; RETCODE result; char *table_name; char index_name[MAX_INFO_STRING]; short fields_vector[8]; char isunique[10], isclustered[10]; SDWORD index_name_len, fields_vector_len; TupleNode *row; int i; HSTMT hcol_stmt; StatementClass *col_stmt, *indx_stmt; char column_name[MAX_INFO_STRING], relhasrules[MAX_INFO_STRING]; char **column_names = 0; Int4 column_name_len; int total_columns = 0; char error = TRUE; ConnInfo *ci; char buf[256]; mylog("%s: entering...stmt=%u\n", func, stmt); if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } stmt->manual_result = TRUE; stmt->errormsg_created = TRUE; ci = &stmt->hdbc->connInfo; stmt->result = QR_Constructor(); if(!stmt->result) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for SQLStatistics result."); SC_log_error(func, "", stmt); return SQL_ERROR; } /* the binding structure for a statement is not set up until */ /* a statement is actually executed, so we'll have to do this ourselves. */ extend_bindings(stmt, 13); /* set the field names */ QR_set_num_fields(stmt->result, 13); QR_set_field_info(stmt->result, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 3, "NON_UNIQUE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 4, "INDEX_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 5, "INDEX_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 6, "TYPE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 7, "SEQ_IN_INDEX", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 8, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 9, "COLLATION", PG_TYPE_CHAR, 1); QR_set_field_info(stmt->result, 10, "CARDINALITY", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 11, "PAGES", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 12, "FILTER_CONDITION", PG_TYPE_TEXT, MAX_INFO_STRING); /* only use the table name... the owner should be redundant, and */ /* we never use qualifiers. */ table_name = make_string((char*)szTableName, cbTableName, NULL); if ( ! table_name) { SC_set_error(stmt, STMT_INTERNAL_ERROR, "No table name passed to SQLStatistics."); SC_log_error(func, "", stmt); return SQL_ERROR; } /* we need to get a list of the field names first, */ /* so we can return them later. */ result = PG_SQLAllocStmt( stmt->hdbc, &hcol_stmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "SQLAllocStmt failed in SQLStatistics for columns."); goto SEEYA; } col_stmt = (StatementClass *) hcol_stmt; /* "internal" prevents SQLColumns from returning the oid if it is being shown. This would throw everything off. */ col_stmt->internal = TRUE; result = PG_SQLColumns(hcol_stmt, (SQLCHAR*)"", 0, (SQLCHAR*)"", 0, (SQLCHAR*)table_name, (SWORD) strlen(table_name), (SQLCHAR*)"", 0); col_stmt->internal = FALSE; if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); goto SEEYA; } result = PG_SQLBindCol(hcol_stmt, 4, SQL_C_CHAR, column_name, MAX_INFO_STRING, &column_name_len); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_get_errormsg(col_stmt)); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); goto SEEYA; } result = PG_SQLFetch(hcol_stmt); while((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) { total_columns++; column_names = (char **)realloc(column_names, total_columns * sizeof(char *)); column_names[total_columns-1] = (char *)malloc(strlen(column_name)+1); strcpy(column_names[total_columns-1], column_name); mylog("SQLStatistics: column_name = '%s'\n", column_name); result = PG_SQLFetch(hcol_stmt); } if(result != SQL_NO_DATA_FOUND || total_columns == 0) { SC_set_error(stmt, SC_get_errornumber(col_stmt), SC_create_errormsg((StatementClass *)hcol_stmt)); PG_SQLFreeStmt(hcol_stmt, SQL_DROP); goto SEEYA; } PG_SQLFreeStmt(hcol_stmt, SQL_DROP); /* get a list of indexes on this table */ result = PG_SQLAllocStmt( stmt->hdbc, &hindx_stmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "SQLAllocStmt failed in SQLStatistics for indices."); goto SEEYA; } indx_stmt = (StatementClass *) hindx_stmt; sprintf(index_query, "select c.relname, i.indkey, i.indisunique" ", i.indisclustered, c.relhasrules" " from pg_index i, pg_class c, pg_class d" " where c.oid = i.indexrelid and d.relname = '%s'" " and d.oid = i.indrelid", table_name); result = PG_SQLExecDirect(hindx_stmt, index_query, strlen(index_query)); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(indx_stmt), SC_create_errormsg((StatementClass *)hindx_stmt)); PG_SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } /* bind the index name column */ result = PG_SQLBindCol(hindx_stmt, 1, SQL_C_CHAR, index_name, MAX_INFO_STRING, &index_name_len); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(indx_stmt), SC_get_errormsg(indx_stmt)); PG_SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } /* bind the vector column */ result = PG_SQLBindCol(hindx_stmt, 2, SQL_C_DEFAULT, fields_vector, 16, &fields_vector_len); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(indx_stmt), SC_get_errormsg(indx_stmt)); PG_SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } /* bind the "is unique" column */ result = PG_SQLBindCol(hindx_stmt, 3, SQL_C_CHAR, isunique, sizeof(isunique), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(indx_stmt), SC_get_errormsg(indx_stmt)); PG_SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } /* bind the "is clustered" column */ result = PG_SQLBindCol(hindx_stmt, 4, SQL_C_CHAR, isclustered, sizeof(isclustered), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(indx_stmt), SC_get_errormsg(indx_stmt)); PG_SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } result = PG_SQLBindCol(hindx_stmt, 5, SQL_C_CHAR, relhasrules, MAX_INFO_STRING, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(indx_stmt), SC_get_errormsg(indx_stmt)); PG_SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } /* fake index of OID */ if ( relhasrules[0] != '1' && atoi(ci->show_oid_column) && atoi(ci->fake_oid_index)) { row = (TupleNode *)malloc(sizeof(TupleNode) + (13 - 1) * sizeof(TupleField)); /* no table qualifier */ set_tuplefield_string(&row->tuple[0], ""); /* don't set the table owner, else Access tries to use it */ set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[2], table_name); /* non-unique index? */ set_tuplefield_int2(&row->tuple[3], (Int2) (globals.unique_index ? FALSE : TRUE)); /* no index qualifier */ set_tuplefield_string(&row->tuple[4], ""); sprintf(buf, "%s_idx_fake_oid", table_name); set_tuplefield_string(&row->tuple[5], buf); /* Clustered index? I think non-clustered should be type OTHER not HASHED */ set_tuplefield_int2(&row->tuple[6], (Int2) SQL_INDEX_OTHER); set_tuplefield_int2(&row->tuple[7], (Int2) 1); set_tuplefield_string(&row->tuple[8], "oid"); set_tuplefield_string(&row->tuple[9], "A"); set_tuplefield_null(&row->tuple[10]); set_tuplefield_null(&row->tuple[11]); set_tuplefield_null(&row->tuple[12]); QR_add_tuple(stmt->result, row); } result = PG_SQLFetch(hindx_stmt); while((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) { /* If only requesting unique indexs, then just return those. */ if (fUnique == SQL_INDEX_ALL || (fUnique == SQL_INDEX_UNIQUE && atoi(isunique))) { i = 0; /* add a row in this table for each field in the index */ while(i < 8 && fields_vector[i] != 0) { row = (TupleNode *)malloc(sizeof(TupleNode) + (13 - 1) * sizeof(TupleField)); /* no table qualifier */ set_tuplefield_string(&row->tuple[0], ""); /* don't set the table owner, else Access tries to use it */ set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[2], table_name); /* non-unique index? */ if (globals.unique_index) set_tuplefield_int2(&row->tuple[3], (Int2) (atoi(isunique) ? FALSE : TRUE)); else set_tuplefield_int2(&row->tuple[3], TRUE); /* no index qualifier */ set_tuplefield_string(&row->tuple[4], ""); set_tuplefield_string(&row->tuple[5], index_name); /* Clustered index? I think non-clustered should be type OTHER not HASHED */ set_tuplefield_int2(&row->tuple[6], (Int2) (atoi(isclustered) ? SQL_INDEX_CLUSTERED : SQL_INDEX_OTHER)); set_tuplefield_int2(&row->tuple[7], (Int2) (i+1)); if(fields_vector[i] == OID_ATTNUM) { set_tuplefield_string(&row->tuple[8], "oid"); mylog("SQLStatistics: column name = oid\n"); } else if(fields_vector[i] < 0 || fields_vector[i] > total_columns) { set_tuplefield_string(&row->tuple[8], "UNKNOWN"); mylog("SQLStatistics: column name = UNKNOWN\n"); } else { set_tuplefield_string(&row->tuple[8], column_names[fields_vector[i]-1]); mylog("SQLStatistics: column name = '%s'\n", column_names[fields_vector[i]-1]); } set_tuplefield_string(&row->tuple[9], "A"); set_tuplefield_null(&row->tuple[10]); set_tuplefield_null(&row->tuple[11]); set_tuplefield_null(&row->tuple[12]); QR_add_tuple(stmt->result, row); i++; } } result = PG_SQLFetch(hindx_stmt); } if(result != SQL_NO_DATA_FOUND) { SC_set_error(stmt, SC_get_errornumber(indx_stmt), SC_create_errormsg((StatementClass *)hindx_stmt)); PG_SQLFreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } PG_SQLFreeStmt(hindx_stmt, SQL_DROP); /* also, things need to think that this statement is finished so */ /* the results can be retrieved. */ stmt->status = STMT_FINISHED; /* set up the current tuple pointer for SQLFetch */ stmt->currTuple = -1; stmt->rowset_start = -1; stmt->current_col = -1; error = FALSE; SEEYA: /* These things should be freed on any error ALSO! */ free(table_name); for(i = 0; i < total_columns; i++) { free(column_names[i]); } free(column_names); mylog("SQLStatistics(): EXIT, %s, stmt=%u\n", error ? "error" : "success", stmt); if (error) { SC_log_error(func, "", stmt); return SQL_ERROR; } else return SQL_SUCCESS; } RETCODE SQL_API SQLColumnPrivileges( HSTMT hstmt, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName, UCHAR FAR * szColumnName, SWORD cbColumnName) { static char* const func="SQLColumnPrivileges"; mylog("%s: entering...\n", func); /* Neither Access or Borland care about this. */ SC_log_error(func, "Function not implemented", (StatementClass *) hstmt); return SQL_ERROR; } /* SQLPrimaryKeys() * Retrieve the primary key columns for the specified table. */ RETCODE SQL_API PG_SQLPrimaryKeys( HSTMT hstmt, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName) { static char* const func = "SQLPrimaryKeys"; StatementClass *stmt = (StatementClass *) hstmt; TupleNode *row; RETCODE result; int seq = 0; HSTMT htbl_stmt; StatementClass *tbl_stmt; char tables_query[STD_STATEMENT_LEN]; char attname[MAX_INFO_STRING]; SDWORD attname_len; char pktab[MAX_TABLE_LEN + 1]; Int2 result_cols; mylog("%s: entering...stmt=%u\n", func, stmt); if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } stmt->manual_result = TRUE; stmt->errormsg_created = TRUE; stmt->result = QR_Constructor(); if(!stmt->result) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for SQLPrimaryKeys result."); SC_log_error(func, "", stmt); return SQL_ERROR; } /* the binding structure for a statement is not set up until */ /* a statement is actually executed, so we'll have to do this ourselves. */ result_cols = 6; extend_bindings(stmt, result_cols); /* set the field names */ QR_set_num_fields(stmt->result, result_cols); QR_set_field_info(stmt->result, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 3, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 4, "KEY_SEQ", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 5, "PK_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); result = PG_SQLAllocStmt( stmt->hdbc, &htbl_stmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for Primary Key result."); SC_log_error(func, "", stmt); return SQL_ERROR; } tbl_stmt = (StatementClass *) htbl_stmt; pktab[0] = '\0'; make_string((char*)szTableName, cbTableName, pktab); if ( pktab[0] == '\0') { SC_set_error(stmt, STMT_INTERNAL_ERROR, "No Table specified to SQLPrimaryKeys."); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } #if 0 sprintf(tables_query, "select distinct on (attnum) a2.attname, a2.attnum from pg_attribute a1, pg_attribute a2, pg_class c, pg_index i where c.relname = '%s_pkey' AND c.oid = i.indexrelid AND a1.attrelid = c.oid AND a2.attrelid = c.oid AND (i.indkey[0] = a1.attnum OR i.indkey[1] = a1.attnum OR i.indkey[2] = a1.attnum OR i.indkey[3] = a1.attnum OR i.indkey[4] = a1.attnum OR i.indkey[5] = a1.attnum OR i.indkey[6] = a1.attnum OR i.indkey[7] = a1.attnum) order by a2.attnum", pktab); #else /* Simplified query to remove assumptions about * number of possible index columns. * Courtesy of Tom Lane - thomas 2000-03-21 */ sprintf(tables_query, "select ta.attname, ia.attnum" " from pg_attribute ta, pg_attribute ia, pg_class c, pg_index i" " where c.relname = '%s_pkey'" " AND c.oid = i.indexrelid" " AND ia.attrelid = i.indexrelid" " AND ta.attrelid = i.indrelid" " AND ta.attnum = i.indkey[ia.attnum-1]" " order by ia.attnum", pktab); #endif mylog("SQLPrimaryKeys: tables_query='%s'\n", tables_query); result = PG_SQLExecDirect(htbl_stmt, tables_query, strlen(tables_query)); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_create_errormsg((StatementClass *)htbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 1, SQL_C_CHAR, attname, MAX_INFO_STRING, &attname_len); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLFetch(htbl_stmt); while((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) { row = (TupleNode *)malloc(sizeof(TupleNode) + (result_cols - 1) * sizeof(TupleField)); set_tuplefield_null(&row->tuple[0]); /* I have to hide the table owner from Access, otherwise it * insists on referring to the table as 'owner.table'. * (this is valid according to the ODBC SQL grammar, but * Postgres won't support it.) */ set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[2], pktab); set_tuplefield_string(&row->tuple[3], attname); set_tuplefield_int2(&row->tuple[4], (Int2) (++seq)); set_tuplefield_null(&row->tuple[5]); QR_add_tuple(stmt->result, row); mylog(">> primaryKeys: pktab = '%s', attname = '%s', seq = %d\n", pktab, attname, seq); result = PG_SQLFetch(htbl_stmt); } if(result != SQL_NO_DATA_FOUND) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_create_errormsg((StatementClass *)htbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } PG_SQLFreeStmt(htbl_stmt, SQL_DROP); /* also, things need to think that this statement is finished so */ /* the results can be retrieved. */ stmt->status = STMT_FINISHED; /* set up the current tuple pointer for SQLFetch */ stmt->currTuple = -1; stmt->rowset_start = -1; stmt->current_col = -1; mylog("SQLPrimaryKeys(): EXIT, stmt=%u\n", stmt); return SQL_SUCCESS; } RETCODE SQL_API SQLPrimaryKeys( HSTMT hstmt, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName) { return PG_SQLPrimaryKeys( hstmt, szTableQualifier, cbTableQualifier, szTableOwner, cbTableOwner, szTableName, cbTableName ); } RETCODE SQL_API SQLForeignKeys( HSTMT hstmt, UCHAR FAR * szPkTableQualifier, SWORD cbPkTableQualifier, UCHAR FAR * szPkTableOwner, SWORD cbPkTableOwner, UCHAR FAR * szPkTableName, SWORD cbPkTableName, UCHAR FAR * szFkTableQualifier, SWORD cbFkTableQualifier, UCHAR FAR * szFkTableOwner, SWORD cbFkTableOwner, UCHAR FAR * szFkTableName, SWORD cbFkTableName) { static char* const func = "SQLForeignKeys"; StatementClass *stmt = (StatementClass *) hstmt; TupleNode *row; HSTMT htbl_stmt, hpkey_stmt; StatementClass *tbl_stmt; RETCODE result, keyresult; char tables_query[STD_STATEMENT_LEN]; char trig_deferrable[2]; char trig_initdeferred[2]; char trig_args[1024]; char upd_rule[MAX_TABLE_LEN], del_rule[MAX_TABLE_LEN]; char pk_table_needed[MAX_TABLE_LEN + 1]; char fk_table_needed[MAX_TABLE_LEN + 1]; char *pkey_ptr, *fkey_ptr, *pk_table, *fk_table; int i, j, k, num_keys; SWORD trig_nargs, upd_rule_type=0, del_rule_type=0; #if (ODBCVER >= 0x0300) SWORD defer_type; #endif char pkey[MAX_INFO_STRING]; Int2 result_cols; mylog("%s: entering...stmt=%u\n", func, stmt); if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } stmt->manual_result = TRUE; stmt->errormsg_created = TRUE; stmt->result = QR_Constructor(); if(!stmt->result) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for SQLForeignKeys result."); SC_log_error(func, "", stmt); return SQL_ERROR; } /* the binding structure for a statement is not set up until */ /* a statement is actually executed, so we'll have to do this ourselves. */ result_cols = 14; extend_bindings(stmt, result_cols); /* set the field names */ QR_set_num_fields(stmt->result, result_cols); QR_set_field_info(stmt->result, 0, "PKTABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 1, "PKTABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 2, "PKTABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 3, "PKCOLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 4, "FKTABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 5, "FKTABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 6, "FKTABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 7, "FKCOLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 8, "KEY_SEQ", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 9, "UPDATE_RULE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 10, "DELETE_RULE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 11, "FK_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 12, "PK_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 13, "TRIGGER_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); #if (ODBCVER >= 0x0300) QR_set_field_info(stmt->result, 14, "DEFERRABILITY", PG_TYPE_INT2, 2); #endif /* ODBCVER >= 0x0300 */ /* also, things need to think that this statement is finished so */ /* the results can be retrieved. */ stmt->status = STMT_FINISHED; /* set up the current tuple pointer for SQLFetch */ stmt->currTuple = -1; stmt->rowset_start = -1; stmt->current_col = -1; result = PG_SQLAllocStmt( stmt->hdbc, &htbl_stmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for SQLForeignKeys result."); SC_log_error(func, "", stmt); return SQL_ERROR; } tbl_stmt = (StatementClass *) htbl_stmt; pk_table_needed[0] = '\0'; fk_table_needed[0] = '\0'; make_string((char*)szPkTableName, cbPkTableName, pk_table_needed); make_string((char*)szFkTableName, cbFkTableName, fk_table_needed); /* Case #2 -- Get the foreign keys in the specified table (fktab) that refer to the primary keys of other table(s). */ if (fk_table_needed[0] != '\0') { mylog("%s: entering Foreign Key Case #2", func); sprintf(tables_query, "SELECT pt.tgargs, " " pt.tgnargs, " " pt.tgdeferrable, " " pt.tginitdeferred, " " pg_proc.proname, " " pg_proc_1.proname " "FROM pg_class pc, " " pg_proc pg_proc, " " pg_proc pg_proc_1, " " pg_trigger pg_trigger, " " pg_trigger pg_trigger_1, " " pg_proc pp, " " pg_trigger pt " "WHERE pt.tgrelid = pc.oid " "AND pp.oid = pt.tgfoid " "AND pg_trigger.tgconstrrelid = pc.oid " "AND pg_proc.oid = pg_trigger.tgfoid " "AND pg_trigger_1.tgfoid = pg_proc_1.oid " "AND pg_trigger_1.tgconstrrelid = pc.oid " "AND ((pc.relname='%s') " "AND (pp.proname LIKE '%%ins') " "AND (pg_proc.proname LIKE '%%upd') " "AND (pg_proc_1.proname LIKE '%%del') " "AND (pg_trigger.tgrelid=pt.tgconstrrelid) " "AND (pg_trigger.tgconstrname=pt.tgconstrname) " "AND (pg_trigger_1.tgrelid=pt.tgconstrrelid) " "AND (pg_trigger_1.tgconstrname=pt.tgconstrname))", fk_table_needed); result = PG_SQLExecDirect(htbl_stmt, tables_query, strlen(tables_query)); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_create_errormsg((StatementClass *)htbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 1, SQL_C_BINARY, trig_args, sizeof(trig_args), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 2, SQL_C_SHORT, &trig_nargs, 0, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 3, SQL_C_CHAR, trig_deferrable, sizeof(trig_deferrable), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 4, SQL_C_CHAR, trig_initdeferred, sizeof(trig_initdeferred), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 5, SQL_C_CHAR, upd_rule, sizeof(upd_rule), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 6, SQL_C_CHAR, del_rule, sizeof(del_rule), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLFetch(htbl_stmt); if (result == SQL_NO_DATA_FOUND) return SQL_SUCCESS; if(result != SQL_SUCCESS) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_create_errormsg((StatementClass *)htbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } keyresult = PG_SQLAllocStmt( stmt->hdbc, &hpkey_stmt); if((keyresult != SQL_SUCCESS) && (keyresult != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for SQLForeignKeys (pkeys) result."); SC_log_error(func, "", stmt); return SQL_ERROR; } keyresult = PG_SQLBindCol(hpkey_stmt, 4, SQL_C_CHAR, pkey, sizeof(pkey), NULL); if (keyresult != SQL_SUCCESS) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't bindcol for primary keys for SQLForeignKeys result."); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hpkey_stmt, SQL_DROP); return SQL_ERROR; } while (result == SQL_SUCCESS) { /* Compute the number of keyparts. */ num_keys = (trig_nargs - 4) / 2; mylog("Foreign Key Case#2: trig_nargs = %d, num_keys = %d\n", trig_nargs, num_keys); pk_table = trig_args; /* Get to the PK Table Name */ for (k = 0; k < 2; k++) pk_table += strlen(pk_table) + 1; /* If there is a pk table specified, then check it. */ if (pk_table_needed[0] != '\0') { /* If it doesn't match, then continue */ if ( strcmp(pk_table, pk_table_needed)) { result = PG_SQLFetch(htbl_stmt); continue; } } keyresult = PG_SQLPrimaryKeys(hpkey_stmt, NULL, 0, NULL, 0, (SQLCHAR*)pk_table, SQL_NTS); if (keyresult != SQL_SUCCESS) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't get primary keys for SQLForeignKeys result."); SC_log_error(func, "", stmt); PG_SQLFreeStmt(hpkey_stmt, SQL_DROP); return SQL_ERROR; } /* Check that the key listed is the primary key */ keyresult = PG_SQLFetch(hpkey_stmt); /* Get to first primary key */ pkey_ptr = trig_args; for (i = 0; i < 5; i++) pkey_ptr += strlen(pkey_ptr) + 1; for (k = 0; k < num_keys; k++) { mylog("%s: pkey_ptr='%s', pkey='%s'\n", func, pkey_ptr, pkey); if ( keyresult != SQL_SUCCESS || strcmp(pkey_ptr, pkey)) { num_keys = 0; break; } /* Get to next primary key */ for (k = 0; k < 2; k++) pkey_ptr += strlen(pkey_ptr) + 1; keyresult = PG_SQLFetch(hpkey_stmt); } /* Set to first fk column */ fkey_ptr = trig_args; for (k = 0; k < 4; k++) fkey_ptr += strlen(fkey_ptr) + 1; /* Set update and delete actions for foreign keys */ if (!strcmp(upd_rule, "RI_FKey_cascade_upd")) { upd_rule_type = SQL_CASCADE; } else if (!strcmp(upd_rule, "RI_FKey_noaction_upd")) { upd_rule_type = SQL_NO_ACTION; } else if (!strcmp(upd_rule, "RI_FKey_restrict_upd")) { upd_rule_type = SQL_NO_ACTION; } else if (!strcmp(upd_rule, "RI_FKey_setdefault_upd")) { upd_rule_type = SQL_SET_DEFAULT; } else if (!strcmp(upd_rule, "RI_FKey_setnull_upd")) { upd_rule_type = SQL_SET_NULL; } if (!strcmp(upd_rule, "RI_FKey_cascade_del")) { del_rule_type = SQL_CASCADE; } else if (!strcmp(upd_rule, "RI_FKey_noaction_del")) { del_rule_type = SQL_NO_ACTION; } else if (!strcmp(upd_rule, "RI_FKey_restrict_del")) { del_rule_type = SQL_NO_ACTION; } else if (!strcmp(upd_rule, "RI_FKey_setdefault_del")) { del_rule_type = SQL_SET_DEFAULT; } else if (!strcmp(upd_rule, "RI_FKey_setnull_del")) { del_rule_type = SQL_SET_NULL; } #if (ODBCVER >= 0x0300) /* Set deferrability type */ if (!strcmp(trig_initdeferred, "y")) { defer_type = SQL_INITIALLY_DEFERRED; } else if (!strcmp(trig_deferrable, "y")) { defer_type = SQL_INITIALLY_IMMEDIATE; } else { defer_type = SQL_NOT_DEFERRABLE; } #endif /* ODBCVER >= 0x0300 */ /* Get to first primary key */ pkey_ptr = trig_args; for (i = 0; i < 5; i++) pkey_ptr += strlen(pkey_ptr) + 1; for (k = 0; k < num_keys; k++) { row = (TupleNode *)malloc(sizeof(TupleNode) + (result_cols - 1) * sizeof(TupleField)); mylog("%s: pk_table = '%s', pkey_ptr = '%s'\n", func, pk_table, pkey_ptr); set_tuplefield_null(&row->tuple[0]); set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[2], pk_table); set_tuplefield_string(&row->tuple[3], pkey_ptr); mylog("%s: fk_table_needed = '%s', fkey_ptr = '%s'\n", func, fk_table_needed, fkey_ptr); set_tuplefield_null(&row->tuple[4]); set_tuplefield_string(&row->tuple[5], ""); set_tuplefield_string(&row->tuple[6], fk_table_needed); set_tuplefield_string(&row->tuple[7], fkey_ptr); mylog("%s: upd_rule_type = '%i', del_rule_type = '%i'\n, trig_name = '%s'", func, upd_rule_type, del_rule_type, trig_args); set_tuplefield_int2(&row->tuple[8], (Int2) (k + 1)); set_tuplefield_int2(&row->tuple[9], (Int2) upd_rule_type); set_tuplefield_int2(&row->tuple[10], (Int2) del_rule_type); set_tuplefield_null(&row->tuple[11]); set_tuplefield_null(&row->tuple[12]); set_tuplefield_string(&row->tuple[13], trig_args); #if (ODBCVER >= 0x0300) set_tuplefield_int2(&row->tuple[14], defer_type); #endif /* ODBCVER >= 0x0300 */ QR_add_tuple(stmt->result, row); /* next primary/foreign key */ for (i = 0; i < 2; i++) { fkey_ptr += strlen(fkey_ptr) + 1; pkey_ptr += strlen(pkey_ptr) + 1; } } result = PG_SQLFetch(htbl_stmt); } PG_SQLFreeStmt(hpkey_stmt, SQL_DROP); } /* Case #1 -- Get the foreign keys in other tables that refer to the primary key in the specified table (pktab). i.e., Who points to me? */ else if (pk_table_needed[0] != '\0') { sprintf(tables_query, "SELECT pg_trigger.tgargs, " " pg_trigger.tgnargs, " " pg_trigger.tgdeferrable, " " pg_trigger.tginitdeferred, " " pg_proc.proname, " " pg_proc_1.proname " "FROM pg_class pg_class, " " pg_class pg_class_1, " " pg_class pg_class_2, " " pg_proc pg_proc, " " pg_proc pg_proc_1, " " pg_trigger pg_trigger, " " pg_trigger pg_trigger_1, " " pg_trigger pg_trigger_2 " "WHERE pg_trigger.tgconstrrelid = pg_class.oid " " AND pg_trigger.tgrelid = pg_class_1.oid " " AND pg_trigger_1.tgfoid = pg_proc_1.oid " " AND pg_trigger_1.tgconstrrelid = pg_class_1.oid " " AND pg_trigger_2.tgconstrrelid = pg_class_2.oid " " AND pg_trigger_2.tgfoid = pg_proc.oid " " AND pg_class_2.oid = pg_trigger.tgrelid " " AND (" " (pg_class.relname='%s') " " AND (pg_proc.proname Like '%%upd') " " AND (pg_proc_1.proname Like '%%del')" " AND (pg_trigger_1.tgrelid = pg_trigger.tgconstrrelid) " " AND (pg_trigger_2.tgrelid = pg_trigger.tgconstrrelid) " " )", pk_table_needed); result = PG_SQLExecDirect(htbl_stmt, tables_query, strlen(tables_query)); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_create_errormsg((StatementClass *)htbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 1, SQL_C_BINARY, trig_args, sizeof(trig_args), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 2, SQL_C_SHORT, &trig_nargs, 0, NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 3, SQL_C_CHAR, trig_deferrable, sizeof(trig_deferrable), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 4, SQL_C_CHAR, trig_initdeferred, sizeof(trig_initdeferred), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 5, SQL_C_CHAR, upd_rule, sizeof(upd_rule), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLBindCol(htbl_stmt, 6, SQL_C_CHAR, del_rule, sizeof(del_rule), NULL); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_get_errormsg(tbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } result = PG_SQLFetch(htbl_stmt); if (result == SQL_NO_DATA_FOUND) return SQL_SUCCESS; if(result != SQL_SUCCESS) { SC_set_error(stmt, SC_get_errornumber(tbl_stmt), SC_create_errormsg((StatementClass *)htbl_stmt)); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } while (result == SQL_SUCCESS) { /* Calculate the number of key parts */ num_keys = (trig_nargs - 4) / 2;; /* Handle action (i.e., 'cascade', 'restrict', 'setnull') */ if (!strcmp(upd_rule, "RI_FKey_cascade_upd")) { upd_rule_type = SQL_CASCADE; } else if (!strcmp(upd_rule, "RI_FKey_noaction_upd")) { upd_rule_type = SQL_NO_ACTION; } else if (!strcmp(upd_rule, "RI_FKey_restrict_upd")) { upd_rule_type = SQL_NO_ACTION; } else if (!strcmp(upd_rule, "RI_FKey_setdefault_upd")) { upd_rule_type = SQL_SET_DEFAULT; } else if (!strcmp(upd_rule, "RI_FKey_setnull_upd")) { upd_rule_type = SQL_SET_NULL; } if (!strcmp(upd_rule, "RI_FKey_cascade_del")) { del_rule_type = SQL_CASCADE; } else if (!strcmp(upd_rule, "RI_FKey_noaction_del")) { del_rule_type = SQL_NO_ACTION; } else if (!strcmp(upd_rule, "RI_FKey_restrict_del")) { del_rule_type = SQL_NO_ACTION; } else if (!strcmp(upd_rule, "RI_FKey_setdefault_del")) { del_rule_type = SQL_SET_DEFAULT; } else if (!strcmp(upd_rule, "RI_FKey_setnull_del")) { del_rule_type = SQL_SET_NULL; } #if (ODBCVER >= 0x0300) /* Set deferrability type */ if (!strcmp(trig_initdeferred, "y")) { defer_type = SQL_INITIALLY_DEFERRED; } else if (!strcmp(trig_deferrable, "y")) { defer_type = SQL_INITIALLY_IMMEDIATE; } else { defer_type = SQL_NOT_DEFERRABLE; } #endif /* ODBCVER >= 0x0300 */ mylog("Foreign Key Case#1: trig_nargs = %d, num_keys = %d\n", trig_nargs, num_keys); /* Get to first primary key */ pkey_ptr = trig_args; for (i = 0; i < 5; i++) pkey_ptr += strlen(pkey_ptr) + 1; /* Get to first foreign table */ fk_table = trig_args; fk_table += strlen(fk_table) + 1; /* Get to first foreign key */ fkey_ptr = trig_args; for (k = 0; k < 4; k++) fkey_ptr += strlen(fkey_ptr) + 1; for (k = 0; k < num_keys; k++) { mylog("pkey_ptr = '%s', fk_table = '%s', fkey_ptr = '%s'\n", pkey_ptr, fk_table, fkey_ptr); row = (TupleNode *)malloc(sizeof(TupleNode) + (result_cols - 1) * sizeof(TupleField)); mylog("pk_table_needed = '%s', pkey_ptr = '%s'\n", pk_table_needed, pkey_ptr); set_tuplefield_null(&row->tuple[0]); set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[2], pk_table_needed); set_tuplefield_string(&row->tuple[3], pkey_ptr); mylog("fk_table = '%s', fkey_ptr = '%s'\n", fk_table, fkey_ptr); set_tuplefield_null(&row->tuple[4]); set_tuplefield_string(&row->tuple[5], ""); set_tuplefield_string(&row->tuple[6], fk_table); set_tuplefield_string(&row->tuple[7], fkey_ptr); set_tuplefield_int2(&row->tuple[8], (Int2) (k + 1)); mylog("upd_rule = %d, del_rule= %d", upd_rule_type, del_rule_type); set_nullfield_int2(&row->tuple[9], (Int2) upd_rule_type); set_nullfield_int2(&row->tuple[10], (Int2) del_rule_type); set_tuplefield_null(&row->tuple[11]); set_tuplefield_null(&row->tuple[12]); set_tuplefield_string(&row->tuple[13], trig_args); #if (ODBCVER >= 0x0300) mylog("defer_type = '%s'", defer_type); set_tuplefield_int2(&row->tuple[14], defer_type); #endif /* ODBCVER >= 0x0300 */ QR_add_tuple(stmt->result, row); /* next primary/foreign key */ for (j = 0; j < 2; j++) { pkey_ptr += strlen(pkey_ptr) + 1; fkey_ptr += strlen(fkey_ptr) + 1; } } result = PG_SQLFetch(htbl_stmt); } } else { SC_set_error(stmt, STMT_INTERNAL_ERROR, "No tables specified to SQLForeignKeys."); SC_log_error(func, "", stmt); PG_SQLFreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } PG_SQLFreeStmt(htbl_stmt, SQL_DROP); mylog("SQLForeignKeys(): EXIT, stmt=%u\n", stmt); return SQL_SUCCESS; } RETCODE SQL_API SQLProcedureColumns( HSTMT hstmt, UCHAR FAR * szProcQualifier, SWORD cbProcQualifier, UCHAR FAR * szProcOwner, SWORD cbProcOwner, UCHAR FAR * szProcName, SWORD cbProcName, UCHAR FAR * szColumnName, SWORD cbColumnName) { static char* const func="SQLProcedureColumns"; mylog("%s: entering...\n", func); SC_log_error(func, "Function not implemented", (StatementClass *) hstmt); return SQL_ERROR; } RETCODE SQL_API SQLProcedures( HSTMT hstmt, UCHAR FAR * szProcQualifier, SWORD cbProcQualifier, UCHAR FAR * szProcOwner, SWORD cbProcOwner, UCHAR FAR * szProcName, SWORD cbProcName) { static char* const func="SQLProcedures"; mylog("%s: entering...\n", func); SC_log_error(func, "Function not implemented", (StatementClass *) hstmt); return SQL_ERROR; } RETCODE SQL_API SQLTablePrivileges( HSTMT hstmt, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName) { static char* const func="SQLTablePrivileges"; mylog("%s: entering...\n", func); SC_log_error(func, "Function not implemented", (StatementClass *) hstmt); return SQL_ERROR; } unixODBC-2.3.12/Drivers/Postgre7.1/isql.h000066400000000000000000000000211446441710500176210ustar00rootroot00000000000000#include unixODBC-2.3.12/Drivers/Postgre7.1/isqlext.h000066400000000000000000000000241446441710500203450ustar00rootroot00000000000000#include unixODBC-2.3.12/Drivers/Postgre7.1/lobj.c000066400000000000000000000060641446441710500176070ustar00rootroot00000000000000 /* Module: lobj.c * * Description: This module contains routines related to manipulating * large objects. * * Classes: none * * API functions: none * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "lobj.h" #include "psqlodbc.h" #include "connection.h" Oid odbc_lo_creat(ConnectionClass *conn, int mode) { LO_ARG argv[1]; int retval, result_len; argv[0].isint = 1; argv[0].len = 4; argv[0].u.integer = mode; if ( ! CC_send_function(conn, LO_CREAT, &retval, &result_len, 1, argv, 1)) return 0; /* invalid oid */ else return retval; } int odbc_lo_open(ConnectionClass *conn, int lobjId, int mode) { int fd; int result_len; LO_ARG argv[2]; argv[0].isint = 1; argv[0].len = 4; argv[0].u.integer = lobjId; argv[1].isint = 1; argv[1].len = 4; argv[1].u.integer = mode; if ( ! CC_send_function(conn, LO_OPEN, &fd, &result_len, 1, argv, 2)) return -1; if (fd >= 0 && odbc_lo_lseek(conn, fd, 0L, SEEK_SET) < 0) return -1; return fd; } int odbc_lo_close(ConnectionClass *conn, int fd) { LO_ARG argv[1]; int retval, result_len; argv[0].isint = 1; argv[0].len = 4; argv[0].u.integer = fd; if ( ! CC_send_function(conn, LO_CLOSE, &retval, &result_len, 1, argv, 1)) return -1; else return retval; } int odbc_lo_read(ConnectionClass *conn, int fd, char *buf, int len) { LO_ARG argv[2]; int result_len; argv[0].isint = 1; argv[0].len = 4; argv[0].u.integer = fd; argv[1].isint = 1; argv[1].len = 4; argv[1].u.integer = len; if ( ! CC_send_function(conn, LO_READ, (int *) buf, &result_len, 0, argv, 2)) return -1; else return result_len; } int odbc_lo_write(ConnectionClass *conn, int fd, char *buf, int len) { LO_ARG argv[2]; int retval, result_len; if (len <= 0) return 0; argv[0].isint = 1; argv[0].len = 4; argv[0].u.integer = fd; argv[1].isint = 0; argv[1].len = len; argv[1].u.ptr = (char *) buf; if ( ! CC_send_function(conn, LO_WRITE, &retval, &result_len, 1, argv, 2)) return -1; else return retval; } int odbc_lo_lseek(ConnectionClass *conn, int fd, int offset, int whence) { LO_ARG argv[3]; int retval, result_len; argv[0].isint = 1; argv[0].len = 4; argv[0].u.integer = fd; argv[1].isint = 1; argv[1].len = 4; argv[1].u.integer = offset; argv[2].isint = 1; argv[2].len = 4; argv[2].u.integer = whence; if ( ! CC_send_function(conn, LO_LSEEK, &retval, &result_len, 1, argv, 3)) return -1; else return retval; } int odbc_lo_tell(ConnectionClass *conn, int fd) { LO_ARG argv[1]; int retval, result_len; argv[0].isint = 1; argv[0].len = 4; argv[0].u.integer = fd; if ( ! CC_send_function(conn, LO_TELL, &retval, &result_len, 1, argv, 1)) return -1; else return retval; } int odbc_lo_unlink(ConnectionClass *conn, Oid lobjId) { LO_ARG argv[1]; int retval, result_len; argv[0].isint = 1; argv[0].len = 4; argv[0].u.integer = lobjId; if ( ! CC_send_function(conn, LO_UNLINK, &retval, &result_len, 1, argv, 1)) return -1; else return retval; } unixODBC-2.3.12/Drivers/Postgre7.1/lobj.h000066400000000000000000000020051446441710500176030ustar00rootroot00000000000000 /* File: lobj.h * * Description: See "lobj.c" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __LOBJ_H__ #define __LOBJ_H__ #include "psqlodbc.h" struct lo_arg { int isint; int len; union { int integer; char *ptr; } u; }; #define LO_CREAT 957 #define LO_OPEN 952 #define LO_CLOSE 953 #define LO_READ 954 #define LO_WRITE 955 #define LO_LSEEK 956 #define LO_TELL 958 #define LO_UNLINK 964 #define INV_WRITE 0x00020000 #define INV_READ 0x00040000 Oid odbc_lo_creat(ConnectionClass *conn, int mode); int odbc_lo_open(ConnectionClass *conn, int lobjId, int mode); int odbc_lo_close(ConnectionClass *conn, int fd); int odbc_lo_read(ConnectionClass *conn, int fd, char *buf, int len); int odbc_lo_write(ConnectionClass *conn, int fd, char *buf, int len); int odbc_lo_lseek(ConnectionClass *conn, int fd, int offset, int len); int odbc_lo_tell(ConnectionClass *conn, int fd); int odbc_lo_unlink(ConnectionClass *conn, Oid lobjId); #endif unixODBC-2.3.12/Drivers/Postgre7.1/md5.c000066400000000000000000000241201446441710500173370ustar00rootroot00000000000000/* * md5.c * * Implements the MD5 Message-Digest Algorithm as specified in * RFC 1321. This implementation is a simple one, in that it * needs every input byte to be buffered before doing any * calculations. I do not expect this file to be used for * general purpose MD5'ing of large amounts of data, only for * generating hashed passwords from limited input. * * Sverre H. Huseby * * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION * $Header: /cvsroot/unixodbc/unixODBC/Drivers/Postgre7.1/md5.c,v 1.2 2009/02/18 17:59:16 lurcher Exp $ */ /* * NOTE: * * There are two copies of this file, one in backend/libpq and another * in interfaces/odbc. They should be identical. This is done so ODBC * can be compiled stand-alone. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "md5.h" #undef palloc #define palloc malloc #undef pfree #define pfree free /* * PRIVATE FUNCTIONS */ /* * The returned array is allocated using malloc. the caller should free it * when it is no longer needed. */ static uint8 * createPaddedCopyWithLength(uint8 *b, uint32 *l) { uint8 *ret; uint32 q; uint32 len, newLen448; uint32 len_high, len_low; /* 64-bit value split into 32-bit sections */ len = ((b == NULL) ? 0 : *l); newLen448 = len + 64 - (len % 64) - 8; if (newLen448 <= len) newLen448 += 64; *l = newLen448 + 8; if ((ret = (uint8 *) malloc(sizeof(uint8) * *l)) == NULL) return NULL; if (b != NULL) memcpy(ret, b, sizeof(uint8) * len); /* pad */ ret[len] = 0x80; for (q = len + 1; q < newLen448; q++) ret[q] = 0x00; /* append length as a 64 bit bitcount */ len_low = len; /* split into two 32-bit values */ /* we only look at the bottom 32-bits */ len_high = len >> 29; len_low <<= 3; q = newLen448; ret[q++] = (len_low & 0xff); len_low >>= 8; ret[q++] = (len_low & 0xff); len_low >>= 8; ret[q++] = (len_low & 0xff); len_low >>= 8; ret[q++] = (len_low & 0xff); ret[q++] = (len_high & 0xff); len_high >>= 8; ret[q++] = (len_high & 0xff); len_high >>= 8; ret[q++] = (len_high & 0xff); len_high >>= 8; ret[q] = (len_high & 0xff); return ret; } #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | ~(z))) #define ROT_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) static void doTheRounds(uint32 X[16], uint32 state[4]) { uint32 a, b, c, d; a = state[0]; b = state[1]; c = state[2]; d = state[3]; /* round 1 */ a = b + ROT_LEFT((a + F(b, c, d) + X[0] + 0xd76aa478), 7); /* 1 */ d = a + ROT_LEFT((d + F(a, b, c) + X[1] + 0xe8c7b756), 12); /* 2 */ c = d + ROT_LEFT((c + F(d, a, b) + X[2] + 0x242070db), 17); /* 3 */ b = c + ROT_LEFT((b + F(c, d, a) + X[3] + 0xc1bdceee), 22); /* 4 */ a = b + ROT_LEFT((a + F(b, c, d) + X[4] + 0xf57c0faf), 7); /* 5 */ d = a + ROT_LEFT((d + F(a, b, c) + X[5] + 0x4787c62a), 12); /* 6 */ c = d + ROT_LEFT((c + F(d, a, b) + X[6] + 0xa8304613), 17); /* 7 */ b = c + ROT_LEFT((b + F(c, d, a) + X[7] + 0xfd469501), 22); /* 8 */ a = b + ROT_LEFT((a + F(b, c, d) + X[8] + 0x698098d8), 7); /* 9 */ d = a + ROT_LEFT((d + F(a, b, c) + X[9] + 0x8b44f7af), 12); /* 10 */ c = d + ROT_LEFT((c + F(d, a, b) + X[10] + 0xffff5bb1), 17); /* 11 */ b = c + ROT_LEFT((b + F(c, d, a) + X[11] + 0x895cd7be), 22); /* 12 */ a = b + ROT_LEFT((a + F(b, c, d) + X[12] + 0x6b901122), 7); /* 13 */ d = a + ROT_LEFT((d + F(a, b, c) + X[13] + 0xfd987193), 12); /* 14 */ c = d + ROT_LEFT((c + F(d, a, b) + X[14] + 0xa679438e), 17); /* 15 */ b = c + ROT_LEFT((b + F(c, d, a) + X[15] + 0x49b40821), 22); /* 16 */ /* round 2 */ a = b + ROT_LEFT((a + G(b, c, d) + X[1] + 0xf61e2562), 5); /* 17 */ d = a + ROT_LEFT((d + G(a, b, c) + X[6] + 0xc040b340), 9); /* 18 */ c = d + ROT_LEFT((c + G(d, a, b) + X[11] + 0x265e5a51), 14); /* 19 */ b = c + ROT_LEFT((b + G(c, d, a) + X[0] + 0xe9b6c7aa), 20); /* 20 */ a = b + ROT_LEFT((a + G(b, c, d) + X[5] + 0xd62f105d), 5); /* 21 */ d = a + ROT_LEFT((d + G(a, b, c) + X[10] + 0x02441453), 9); /* 22 */ c = d + ROT_LEFT((c + G(d, a, b) + X[15] + 0xd8a1e681), 14); /* 23 */ b = c + ROT_LEFT((b + G(c, d, a) + X[4] + 0xe7d3fbc8), 20); /* 24 */ a = b + ROT_LEFT((a + G(b, c, d) + X[9] + 0x21e1cde6), 5); /* 25 */ d = a + ROT_LEFT((d + G(a, b, c) + X[14] + 0xc33707d6), 9); /* 26 */ c = d + ROT_LEFT((c + G(d, a, b) + X[3] + 0xf4d50d87), 14); /* 27 */ b = c + ROT_LEFT((b + G(c, d, a) + X[8] + 0x455a14ed), 20); /* 28 */ a = b + ROT_LEFT((a + G(b, c, d) + X[13] + 0xa9e3e905), 5); /* 29 */ d = a + ROT_LEFT((d + G(a, b, c) + X[2] + 0xfcefa3f8), 9); /* 30 */ c = d + ROT_LEFT((c + G(d, a, b) + X[7] + 0x676f02d9), 14); /* 31 */ b = c + ROT_LEFT((b + G(c, d, a) + X[12] + 0x8d2a4c8a), 20); /* 32 */ /* round 3 */ a = b + ROT_LEFT((a + H(b, c, d) + X[5] + 0xfffa3942), 4); /* 33 */ d = a + ROT_LEFT((d + H(a, b, c) + X[8] + 0x8771f681), 11); /* 34 */ c = d + ROT_LEFT((c + H(d, a, b) + X[11] + 0x6d9d6122), 16); /* 35 */ b = c + ROT_LEFT((b + H(c, d, a) + X[14] + 0xfde5380c), 23); /* 36 */ a = b + ROT_LEFT((a + H(b, c, d) + X[1] + 0xa4beea44), 4); /* 37 */ d = a + ROT_LEFT((d + H(a, b, c) + X[4] + 0x4bdecfa9), 11); /* 38 */ c = d + ROT_LEFT((c + H(d, a, b) + X[7] + 0xf6bb4b60), 16); /* 39 */ b = c + ROT_LEFT((b + H(c, d, a) + X[10] + 0xbebfbc70), 23); /* 40 */ a = b + ROT_LEFT((a + H(b, c, d) + X[13] + 0x289b7ec6), 4); /* 41 */ d = a + ROT_LEFT((d + H(a, b, c) + X[0] + 0xeaa127fa), 11); /* 42 */ c = d + ROT_LEFT((c + H(d, a, b) + X[3] + 0xd4ef3085), 16); /* 43 */ b = c + ROT_LEFT((b + H(c, d, a) + X[6] + 0x04881d05), 23); /* 44 */ a = b + ROT_LEFT((a + H(b, c, d) + X[9] + 0xd9d4d039), 4); /* 45 */ d = a + ROT_LEFT((d + H(a, b, c) + X[12] + 0xe6db99e5), 11); /* 46 */ c = d + ROT_LEFT((c + H(d, a, b) + X[15] + 0x1fa27cf8), 16); /* 47 */ b = c + ROT_LEFT((b + H(c, d, a) + X[2] + 0xc4ac5665), 23); /* 48 */ /* round 4 */ a = b + ROT_LEFT((a + I(b, c, d) + X[0] + 0xf4292244), 6); /* 49 */ d = a + ROT_LEFT((d + I(a, b, c) + X[7] + 0x432aff97), 10); /* 50 */ c = d + ROT_LEFT((c + I(d, a, b) + X[14] + 0xab9423a7), 15); /* 51 */ b = c + ROT_LEFT((b + I(c, d, a) + X[5] + 0xfc93a039), 21); /* 52 */ a = b + ROT_LEFT((a + I(b, c, d) + X[12] + 0x655b59c3), 6); /* 53 */ d = a + ROT_LEFT((d + I(a, b, c) + X[3] + 0x8f0ccc92), 10); /* 54 */ c = d + ROT_LEFT((c + I(d, a, b) + X[10] + 0xffeff47d), 15); /* 55 */ b = c + ROT_LEFT((b + I(c, d, a) + X[1] + 0x85845dd1), 21); /* 56 */ a = b + ROT_LEFT((a + I(b, c, d) + X[8] + 0x6fa87e4f), 6); /* 57 */ d = a + ROT_LEFT((d + I(a, b, c) + X[15] + 0xfe2ce6e0), 10); /* 58 */ c = d + ROT_LEFT((c + I(d, a, b) + X[6] + 0xa3014314), 15); /* 59 */ b = c + ROT_LEFT((b + I(c, d, a) + X[13] + 0x4e0811a1), 21); /* 60 */ a = b + ROT_LEFT((a + I(b, c, d) + X[4] + 0xf7537e82), 6); /* 61 */ d = a + ROT_LEFT((d + I(a, b, c) + X[11] + 0xbd3af235), 10); /* 62 */ c = d + ROT_LEFT((c + I(d, a, b) + X[2] + 0x2ad7d2bb), 15); /* 63 */ b = c + ROT_LEFT((b + I(c, d, a) + X[9] + 0xeb86d391), 21); /* 64 */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; } static int calculateDigestFromBuffer(uint8 *b, uint32 len, uint8 sum[16]) { register uint32 i, j, k, newI; uint32 l; uint8 *input; register uint32 *wbp; uint32 workBuff[16], state[4]; l = len; state[0] = 0x67452301; state[1] = 0xEFCDAB89; state[2] = 0x98BADCFE; state[3] = 0x10325476; if ((input = createPaddedCopyWithLength(b, &l)) == NULL) return 0; for (i = 0;;) { if ((newI = i + 16 * 4) > l) break; k = i + 3; for (j = 0; j < 16; j++) { wbp = (workBuff + j); *wbp = input[k--]; *wbp <<= 8; *wbp |= input[k--]; *wbp <<= 8; *wbp |= input[k--]; *wbp <<= 8; *wbp |= input[k]; k += 7; } doTheRounds(workBuff, state); i = newI; } free(input); j = 0; for (i = 0; i < 4; i++) { k = state[i]; sum[j++] = (k & 0xff); k >>= 8; sum[j++] = (k & 0xff); k >>= 8; sum[j++] = (k & 0xff); k >>= 8; sum[j++] = (k & 0xff); } return 1; } static void bytesToHex(uint8 b[16], char *s) { static char *hex = "0123456789abcdef"; int q, w; for (q = 0, w = 0; q < 16; q++) { s[w++] = hex[(b[q] >> 4) & 0x0F]; s[w++] = hex[b[q] & 0x0F]; } s[w] = '\0'; } /* * PUBLIC FUNCTIONS */ /* * md5_hash * * Calculates the MD5 sum of the bytes in a buffer. * * SYNOPSIS #include "crypt.h" * int md5_hash(const void *buff, size_t len, char *hexsum) * * INPUT buff the buffer containing the bytes that you want * the MD5 sum of. * len number of bytes in the buffer. * * OUTPUT hexsum the MD5 sum as a '\0'-terminated string of * hexadecimal digits. an MD5 sum is 16 bytes long. * each byte is represented by two heaxadecimal * characters. you thus need to provide an array * of 33 characters, including the trailing '\0'. * * RETURNS 0 on failure (out of memory for internal buffers) or * non-zero on success. * * STANDARDS MD5 is described in RFC 1321. * * AUTHOR Sverre H. Huseby * */ bool md5_hash(const void *buff, size_t len, char *hexsum) { uint8 sum[16]; if (!calculateDigestFromBuffer((uint8 *) buff, len, sum)) return false; bytesToHex(sum, hexsum); return true; } /* * Computes MD5 checksum of "passwd" (a null-terminated string) followed * by "salt" (which need not be null-terminated). * * Output format is "md5" followed by a 32-hex-digit MD5 checksum. * Hence, the output buffer "buf" must be at least 36 bytes long. * * Returns TRUE if okay, FALSE on error (out of memory). */ bool EncryptMD5(const char *passwd, const char *salt, size_t salt_len, char *buf) { size_t passwd_len = strlen(passwd); char *crypt_buf = palloc(passwd_len + salt_len); bool ret; /* * Place salt at the end because it may be known by users trying to * crack the MD5 output. */ strcpy(crypt_buf, passwd); memcpy(crypt_buf + passwd_len, salt, salt_len); strcpy(buf, "md5"); ret = md5_hash(crypt_buf, passwd_len + salt_len, buf + 3); pfree(crypt_buf); return ret; } unixODBC-2.3.12/Drivers/Postgre7.1/md5.h000066400000000000000000000016251446441710500173510ustar00rootroot00000000000000/* File: md5.h * * Description: See "md5.h" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __MD5_H__ #define __MD5_H__ #include "psqlodbc.h" #include #include #define MD5_PASSWD_LEN 35 /* From c.h */ #ifndef __BEOS__ #ifndef __cplusplus #if !defined(bool) || defined(__APPLE_ALTIVEC__) typedef char bool; #endif #ifndef true #define true ((bool) 1) #endif #ifndef false #define false ((bool) 0) #endif #endif /* not C++ */ #endif /* __BEOS__ */ /* Also defined in include/c.h */ #ifndef HAVE_UINT8 typedef unsigned char uint8; /* == 8 bits */ typedef unsigned short uint16; /* == 16 bits */ typedef unsigned int uint32; /* == 32 bits */ #endif /* not HAVE_UINT8 */ extern bool md5_hash(const void *buff, size_t len, char *hexsum); extern bool EncryptMD5(const char *passwd, const char *salt, size_t salt_len, char *buf); #endif unixODBC-2.3.12/Drivers/Postgre7.1/misc.c000066400000000000000000000121111446441710500176020ustar00rootroot00000000000000 /* Module: misc.c * * Description: This module contains miscellaneous routines * such as for debugging/logging and string functions. * * Classes: n/a * * API functions: none * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "psqlodbc.h" #ifndef WIN32 #if HAVE_PWD_H #include #endif #include #include #else #include /* Byron: is this where Windows keeps def. of getpid ? */ #endif extern GLOBAL_VALUES globals; void generate_filename(char*,char*,char*); void generate_filename(char* dirname,char* prefix,char* filename) { int pid = 0; #ifndef WIN32 struct passwd *ptr = 0; ptr = getpwuid(getuid()); #endif pid = getpid(); if(dirname == 0 || filename == 0) return; strcpy(filename,dirname); strcat(filename,DIRSEPARATOR); if(prefix != 0) strcat(filename,prefix); #ifndef WIN32 strcat(filename,ptr->pw_name); #endif sprintf(filename,"%s%u%s",filename,pid,".log"); return; } #ifdef MY_LOG void mylog(char * fmt, ...) { va_list args; char filebuf[80]; FILE* LOGFP = globals.mylogFP; if ( globals.debug) { va_start(args, fmt); if (! LOGFP) { generate_filename(MYLOGDIR,MYLOGFILE,filebuf); LOGFP = fopen(filebuf, PG_BINARY_W); globals.mylogFP = LOGFP; setbuf(LOGFP, NULL); } if (LOGFP) vfprintf(LOGFP, fmt, args); va_end(args); } } #endif #ifdef Q_LOG void qlog(char * fmt, ...) { va_list args; char filebuf[80]; FILE* LOGFP = globals.qlogFP; if ( globals.commlog) { va_start(args, fmt); if (! LOGFP) { generate_filename(QLOGDIR,QLOGFILE,filebuf); LOGFP = fopen(filebuf, PG_BINARY_W); globals.qlogFP = LOGFP; setbuf(LOGFP, NULL); } if (LOGFP) vfprintf(LOGFP, fmt, args); va_end(args); } } #endif /* Undefine these because windows.h will redefine and cause a warning */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef WIN32 #undef va_start #undef va_end #endif #ifndef WIN32 #include "isql.h" #else #include #include #endif /* returns STRCPY_FAIL, STRCPY_TRUNCATED, or #bytes copied (not including null term) */ int my_strcpy(char *dst, int dst_len, char *src, int src_len) { if (dst_len <= 0) return STRCPY_FAIL; if (src_len == SQL_NULL_DATA) { dst[0] = '\0'; return STRCPY_NULL; } else if (src_len == SQL_NTS) src_len = strlen(src); if (src_len <= 0) return STRCPY_FAIL; else { if (src_len < dst_len) { memcpy(dst, src, src_len); dst[src_len] = '\0'; } else { memcpy(dst, src, dst_len-1); dst[dst_len-1] = '\0'; /* truncated */ return STRCPY_TRUNCATED; } } return strlen(dst); } /* strncpy copies up to len characters, and doesn't terminate */ /* the destination string if src has len characters or more. */ /* instead, I want it to copy up to len-1 characters and always */ /* terminate the destination string. */ char *strncpy_null(char *dst, const char *src, int len) { int i; if (NULL != dst) { /* Just in case, check for special lengths */ if (len == SQL_NULL_DATA) { dst[0] = '\0'; return NULL; } else if (len == SQL_NTS) len = strlen(src) + 1; for(i = 0; src[i] && i < len - 1; i++) { dst[i] = src[i]; } if(len > 0) { dst[i] = '\0'; } } return dst; } /* Create a null terminated string (handling the SQL_NTS thing): */ /* 1. If buf is supplied, place the string in there (assumes enough space) and return buf. */ /* 2. If buf is not supplied, malloc space and return this string */ char * make_string(char *s, int len, char *buf) { int length; char *str; if(s && (len > 0 || (len == SQL_NTS && strlen(s) > 0))) { length = (len > 0) ? len : strlen(s); if (buf) { strncpy_null(buf, s, length+1); return buf; } str = malloc(length + 1); if ( ! str) return NULL; strncpy_null(str, s, length+1); return str; } return NULL; } /* Return the length of a string (handling the SQL_NTS thing): */ int my_strlen(char *s, int len) { int length = 0; if(s && (len > 0 || (len == SQL_NTS && strlen(s) > 0))) { length = (len > 0) ? len : strlen(s); } return length; } /* Concatenate a single formatted argument to a given buffer handling the SQL_NTS thing. */ /* "fmt" must contain somewhere in it the single form '%.*s' */ /* This is heavily used in creating queries for info routines (SQLTables, SQLColumns). */ /* This routine could be modified to use vsprintf() to handle multiple arguments. */ char * my_strcat(char *buf, char *fmt, char *s, int len) { if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0))) { int length = (len > 0) ? len : strlen(s); int pos = strlen(buf); sprintf(&buf[pos], fmt, length, s); return buf; } return NULL; } void remove_newlines(char *string) { unsigned int i; size_t stlen=strlen(string); for(i=0; i < stlen; i++) { if((string[i] == '\n') || (string[i] == '\r')) { string[i] = ' '; } } } char * trim(char *s) { int i; for (i = strlen(s) - 1; i >= 0; i--) { if (s[i] == ' ') s[i] = '\0'; else break; } return s; } unixODBC-2.3.12/Drivers/Postgre7.1/misc.h000066400000000000000000000062321446441710500176160ustar00rootroot00000000000000 /* File: misc.h * * Description: See "misc.c" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __MISC_H__ #define __MISC_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef WIN32 #ifdef UNIXODBC # include #else # include "gpps.h" # define SQLGetPrivateProfileString(a,b,c,d,e,f) GetPrivateProfileString(a,b,c,d,e,f) # endif #endif #include /* Uncomment MY_LOG define to compile in the mylog() statements. Then, debug logging will occur if 'Debug' is set to 1 in the ODBCINST.INI portion of the registry. You may have to manually add this key. This logfile is intended for development use, not for an end user! */ #define MY_LOG /* Uncomment Q_LOG to compile in the qlog() statements (Communications log, i.e. CommLog). This logfile contains serious log statements that are intended for an end user to be able to read and understand. It is controlled by the 'CommLog' flag in the ODBCINST.INI portion of the registry (see above), which is manipulated on the setup/connection dialog boxes. */ #define Q_LOG #ifdef MY_LOG #define MYLOGFILE "mylog_" #ifndef WIN32 #define MYLOGDIR "/tmp" #else #define MYLOGDIR "c:" #endif extern void mylog(char * fmt, ...); #else #ifndef WIN32 #define mylog(args...) /* GNU convention for variable arguments */ #else #define mylog /* mylog */ #endif #endif #ifdef Q_LOG #define QLOGFILE "psqlodbc_" #ifndef WIN32 #define QLOGDIR "/tmp" #else #define QLOGDIR "c:" #endif extern void qlog(char * fmt, ...); #else #ifndef WIN32 #define qlog(args...) /* GNU convention for variable arguments */ #else #define qlog /* qlog */ #endif #endif #ifndef WIN32 #define DIRSEPARATOR "/" #else #define DIRSEPARATOR "\\" #endif #ifdef WIN32 #define PG_BINARY O_BINARY #define PG_BINARY_R "rb" #define PG_BINARY_W "wb" #else #define PG_BINARY 0 #define PG_BINARY_R "r" #define PG_BINARY_W "w" #endif void remove_newlines(char *string); char *strncpy_null(char *dst, const char *src, int len); char *trim(char *string); char *make_string(char *s, int len, char *buf); char *my_strcat(char *buf, char *fmt, char *s, int len); int my_strlen(char *s, int len); /* defines for return value of my_strcpy */ #define STRCPY_SUCCESS 1 #define STRCPY_FAIL 0 #define STRCPY_TRUNCATED -1 #define STRCPY_NULL -2 int my_strcpy(char *dst, int dst_len, char *src, int src_len); RETCODE SQL_API PG_SQLExecDirect(HSTMT hstmt, UCHAR FAR *szSqlStr, SDWORD cbSqlStr); RETCODE SQL_API PG_SQLExecute(HSTMT hstmt); RETCODE SQL_API PG_SQLGetData(HSTMT hstmt, UWORD icol, SWORD fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD FAR *pcbValue); RETCODE SQL_API PG_SQLFetch(HSTMT hstmt); RETCODE SQL_API PG_SQLColumns(HSTMT hstmt, UCHAR FAR * szTableQualifier, SWORD cbTableQualifier, UCHAR FAR * szTableOwner, SWORD cbTableOwner, UCHAR FAR * szTableName, SWORD cbTableName, UCHAR FAR * szColumnName, SWORD cbColumnName); #endif unixODBC-2.3.12/Drivers/Postgre7.1/notice.txt000066400000000000000000000022621446441710500205330ustar00rootroot00000000000000 /******************************************************************** PSQLODBC.DLL - A library to talk to the PostgreSQL DBMS using ODBC. Copyright (C) 1998; Insight Distribution Systems The code contained in this library is based on code written by Christian Czezatke and Dan McGuirk, (C) 1996. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library (see "license.txt"); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. How to contact the author: email: byronn@insightdist.com (Byron Nikolaidis) ***********************************************************************/ unixODBC-2.3.12/Drivers/Postgre7.1/options.c000066400000000000000000000360751446441710500203610ustar00rootroot00000000000000 /* Module: options.c * * Description: This module contains routines for getting/setting * connection and statement options. * * Classes: n/a * * API functions: SQLSetConnectOption, SQLSetStmtOption, SQLGetConnectOption, * SQLGetStmtOption * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "psqlodbc.h" #include #ifndef WIN32 #include "isql.h" #include "isqlext.h" #else #include #include #include #endif #include "environ.h" #include "connection.h" #include "statement.h" #include "qresult.h" extern GLOBAL_VALUES globals; RETCODE set_statement_option(ConnectionClass *conn, StatementClass *stmt, UWORD fOption, UDWORD vParam); RETCODE set_statement_option(ConnectionClass *conn, StatementClass *stmt, UWORD fOption, UDWORD vParam) { static char* const func="set_statement_option"; char changed = FALSE; switch(fOption) { case SQL_ASYNC_ENABLE:/* ignored */ break; case SQL_BIND_TYPE: /* now support multi-column and multi-row binding */ if (conn) conn->stmtOptions.bind_size = vParam; if (stmt) stmt->options.bind_size = vParam; break; case SQL_CONCURRENCY: /* positioned update isn't supported so cursor concurrency is read-only */ if (conn) conn->stmtOptions.scroll_concurrency = vParam; if (stmt) stmt->options.scroll_concurrency = vParam; break; /* if (globals.lie) { if (conn) conn->stmtOptions.scroll_concurrency = vParam; if (stmt) stmt->options.scroll_concurrency = vParam; } else { if (conn) conn->stmtOptions.scroll_concurrency = SQL_CONCUR_READ_ONLY; if (stmt) stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; if (vParam != SQL_CONCUR_READ_ONLY) changed = TRUE; } break; */ case SQL_CURSOR_TYPE: /* if declare/fetch, then type can only be forward. otherwise, it can only be forward or static. */ mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d\n", vParam); if (globals.lie) { if (conn) conn->stmtOptions.cursor_type = vParam; if (stmt) stmt->options.cursor_type = vParam; } else { if (globals.use_declarefetch) { if (conn) conn->stmtOptions.cursor_type = SQL_CURSOR_FORWARD_ONLY; if (stmt) stmt->options.cursor_type = SQL_CURSOR_FORWARD_ONLY; if (vParam != SQL_CURSOR_FORWARD_ONLY) changed = TRUE; } else { if (vParam == SQL_CURSOR_FORWARD_ONLY || vParam == SQL_CURSOR_STATIC) { if (conn) conn->stmtOptions.cursor_type = vParam; /* valid type */ if (stmt) stmt->options.cursor_type = vParam; /* valid type */ } else { if (conn) conn->stmtOptions.cursor_type = SQL_CURSOR_STATIC; if (stmt) stmt->options.cursor_type = SQL_CURSOR_STATIC; changed = TRUE; } } } break; case SQL_KEYSET_SIZE: /* ignored, but saved and returned */ mylog("SetStmtOption(): SQL_KEYSET_SIZE, vParam = %d\n", vParam); if (conn) conn->stmtOptions.keyset_size = vParam; if (stmt) stmt->options.keyset_size = vParam; break; /* if (globals.lie) stmt->keyset_size = vParam; else { SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Driver does not support keyset size option"); SC_log_error(func, "", stmt); return SQL_ERROR; } */ case SQL_MAX_LENGTH:/* ignored, but saved */ mylog("SetStmtOption(): SQL_MAX_LENGTH, vParam = %d\n", vParam); if (conn) conn->stmtOptions.maxLength = vParam; if (stmt) stmt->options.maxLength = vParam; break; case SQL_MAX_ROWS: /* ignored, but saved */ mylog("SetStmtOption(): SQL_MAX_ROWS, vParam = %d\n", vParam); if (conn) conn->stmtOptions.maxRows = vParam; if (stmt) stmt->options.maxRows = vParam; break; case SQL_NOSCAN: /* ignored */ mylog("SetStmtOption: SQL_NOSCAN, vParam = %d\n", vParam); break; case SQL_QUERY_TIMEOUT: /* ignored */ mylog("SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d\n", vParam); /* "0" returned in SQLGetStmtOption */ break; case SQL_RETRIEVE_DATA: /* ignored, but saved */ mylog("SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d\n", vParam); if (conn) conn->stmtOptions.retrieve_data = vParam; if (stmt) stmt->options.retrieve_data = vParam; break; case SQL_ROWSET_SIZE: mylog("SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d\n", vParam); /* Save old rowset size for SQLExtendedFetch purposes If the rowset_size is being changed since the last call to fetch rows. */ if (stmt && stmt->save_rowset_size <= 0 && stmt->last_fetch_count > 0 ) stmt->save_rowset_size = stmt->options.rowset_size; if (vParam < 1) { vParam = 1; changed = TRUE; } if (conn) conn->stmtOptions.rowset_size = vParam; if (stmt) stmt->options.rowset_size = vParam; break; case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */ if (stmt) { SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Simulated positioned update/delete not supported. Use the cursor library."); SC_log_error(func, "", stmt); } if (conn) { CC_set_error(conn, STMT_NOT_IMPLEMENTED_ERROR, "Simulated positioned update/delete not supported. Use the cursor library."); CC_log_error(func, "", conn); } return SQL_ERROR; case SQL_USE_BOOKMARKS: if (stmt) stmt->options.use_bookmarks = vParam; if (conn) conn->stmtOptions.use_bookmarks = vParam; break; /* * added to be nice to OpenOffice */ case /*SQL_ATTR_CURSOR_SENSITIVITY*/ 65534: break; default: { char option[64]; if (stmt) { SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Set)"); sprintf(option, "fOption=%d, vParam=%ld", fOption, (long)vParam); SC_log_error(func, option, stmt); } if (conn) { CC_set_error(conn, STMT_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Set)"); sprintf(option, "fOption=%d, vParam=%ld", fOption, (long)vParam); CC_log_error(func, option, conn); } return SQL_ERROR; } } if (changed) { if (stmt) { SC_set_error(stmt, STMT_OPTION_VALUE_CHANGED, "Requested value changed."); } if (conn) { CC_set_error(conn, STMT_OPTION_VALUE_CHANGED, "Requested value changed."); } return SQL_SUCCESS_WITH_INFO; } else return SQL_SUCCESS; } /* Implements only SQL_AUTOCOMMIT */ RETCODE SQL_API SQLSetConnectOption( HDBC hdbc, UWORD fOption, SQLULEN vParam) { static char* const func="SQLSetConnectOption"; ConnectionClass *conn = (ConnectionClass *) hdbc; char changed = FALSE; RETCODE retval; int i; mylog("%s: entering...\n", func); if ( ! conn) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } switch (fOption) { /* Statement Options (apply to all stmts on the connection and become defaults for new stmts) */ case SQL_ASYNC_ENABLE: case SQL_BIND_TYPE: case SQL_CONCURRENCY: case SQL_CURSOR_TYPE: case SQL_KEYSET_SIZE: case SQL_MAX_LENGTH: case SQL_MAX_ROWS: case SQL_NOSCAN: case SQL_QUERY_TIMEOUT: case SQL_RETRIEVE_DATA: case SQL_ROWSET_SIZE: case SQL_SIMULATE_CURSOR: case SQL_USE_BOOKMARKS: /* Affect all current Statements */ for (i = 0; i < conn->num_stmts; i++) { if ( conn->stmts[i]) { set_statement_option(NULL, conn->stmts[i], fOption, vParam); } } /* Become the default for all future statements on this connection */ retval = set_statement_option(conn, NULL, fOption, vParam); if (retval == SQL_SUCCESS_WITH_INFO) changed = TRUE; else if (retval == SQL_ERROR) return SQL_ERROR; break; /**********************************/ /***** Connection Options *******/ /**********************************/ case SQL_ACCESS_MODE: /* ignored */ break; case SQL_AUTOCOMMIT: if (CC_is_in_trans(conn)) { CC_set_error(conn, CONN_TRANSACT_IN_PROGRES, "Cannot switch commit mode while a transaction is in progress"); CC_log_error(func, "", conn); return SQL_ERROR; } mylog("SQLSetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam); switch(vParam) { case SQL_AUTOCOMMIT_OFF: CC_set_autocommit_off(conn); break; case SQL_AUTOCOMMIT_ON: CC_set_autocommit_on(conn); break; default: CC_set_error(conn, CONN_INVALID_ARGUMENT_NO, "Illegal parameter value for SQL_AUTOCOMMIT"); CC_log_error(func, "", conn); return SQL_ERROR; } break; case SQL_CURRENT_QUALIFIER: /* ignored */ break; case SQL_LOGIN_TIMEOUT: /* ignored */ break; case SQL_PACKET_SIZE: /* ignored */ break; case SQL_QUIET_MODE: /* ignored */ break; case SQL_TXN_ISOLATION: /* ignored */ break; /* These options should be handled by driver manager */ case SQL_ODBC_CURSORS: case SQL_OPT_TRACE: case SQL_OPT_TRACEFILE: case SQL_TRANSLATE_DLL: case SQL_TRANSLATE_OPTION: CC_log_error(func, "This connect option (Set) is only used by the Driver Manager", conn); break; default: { char option[64]; CC_set_error(conn, CONN_UNSUPPORTED_OPTION, "Unknown connect option (Set)"); sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam); CC_log_error(func, option, conn); return SQL_ERROR; } } if (changed) { CC_set_error(conn, CONN_OPTION_VALUE_CHANGED, "Requested value changed."); return SQL_SUCCESS_WITH_INFO; } else return SQL_SUCCESS; } /* - - - - - - - - - */ /* This function just can tell you whether you are in Autcommit mode or not */ RETCODE SQL_API SQLGetConnectOption( HDBC hdbc, UWORD fOption, PTR pvParam) { static char* const func="SQLGetConnectOption"; ConnectionClass *conn = (ConnectionClass *) hdbc; mylog("%s: entering...\n", func); if (! conn) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } switch (fOption) { case SQL_ACCESS_MODE:/* NOT SUPPORTED */ *((UDWORD *) pvParam) = SQL_MODE_READ_WRITE; break; case SQL_AUTOCOMMIT: *((UDWORD *)pvParam) = (UDWORD)( CC_is_in_autocommit(conn) ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF); break; case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */ if(pvParam) { ((char*)pvParam)[0]='\0'; } break; case SQL_LOGIN_TIMEOUT: /* NOT SUPPORTED */ *((UDWORD *) pvParam) = 0; break; case SQL_PACKET_SIZE: /* NOT SUPPORTED */ *((UDWORD *) pvParam) = globals.socket_buffersize; break; case SQL_QUIET_MODE:/* NOT SUPPORTED */ *((UDWORD *) pvParam) = (UDWORD) NULL; break; case SQL_TXN_ISOLATION:/* NOT SUPPORTED */ *((UDWORD *) pvParam) = SQL_TXN_SERIALIZABLE; break; /* These options should be handled by driver manager */ case SQL_ODBC_CURSORS: case SQL_OPT_TRACE: case SQL_OPT_TRACEFILE: case SQL_TRANSLATE_DLL: case SQL_TRANSLATE_OPTION: CC_log_error(func, "This connect option (Get) is only used by the Driver Manager", conn); break; default: { char option[64]; CC_set_error(conn, CONN_UNSUPPORTED_OPTION, "Unknown connect option (Get)"); sprintf(option, "fOption=%d", fOption); CC_log_error(func, option, conn); return SQL_ERROR; break; } } return SQL_SUCCESS; } /* - - - - - - - - - */ RETCODE SQL_API SQLSetStmtOption( HSTMT hstmt, UWORD fOption, SQLULEN vParam) { static char* const func="SQLSetStmtOption"; StatementClass *stmt = (StatementClass *) hstmt; mylog("%s: entering...\n", func); /* thought we could fake Access out by just returning SQL_SUCCESS */ /* all the time, but it tries to set a huge value for SQL_MAX_LENGTH */ /* and expects the driver to reduce it to the real value */ if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } return set_statement_option(NULL, stmt, fOption, vParam); } /* - - - - - - - - - */ RETCODE SQL_API SQLGetStmtOption( HSTMT hstmt, UWORD fOption, PTR pvParam) { static char* const func="SQLGetStmtOption"; StatementClass *stmt = (StatementClass *) hstmt; QResultClass *res; mylog("%s: entering...\n", func); /* thought we could fake Access out by just returning SQL_SUCCESS */ /* all the time, but it tries to set a huge value for SQL_MAX_LENGTH */ /* and expects the driver to reduce it to the real value */ if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } switch(fOption) { case SQL_GET_BOOKMARK: case SQL_ROW_NUMBER: res = stmt->result; if ( stmt->manual_result || ! globals.use_declarefetch) { /* make sure we're positioned on a valid row */ if((stmt->currTuple < 0) || (stmt->currTuple >= QR_get_num_tuples(res))) { SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row."); SC_log_error(func, "", stmt); return SQL_ERROR; } } else { if (stmt->currTuple == -1 || ! res || ! res->tupleField) { SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row."); SC_log_error(func, "", stmt); return SQL_ERROR; } } if (fOption == SQL_GET_BOOKMARK && stmt->options.use_bookmarks == SQL_UB_OFF) { SC_set_error(stmt, STMT_OPERATION_INVALID, "Operation invalid because use bookmarks not enabled."); SC_log_error(func, "", stmt); return SQL_ERROR; } *((UDWORD *) pvParam) = SC_get_bookmark(stmt); break; case SQL_ASYNC_ENABLE: /* NOT SUPPORTED */ *((SDWORD *) pvParam) = SQL_ASYNC_ENABLE_OFF; break; case SQL_BIND_TYPE: *((SDWORD *) pvParam) = stmt->options.bind_size; break; case SQL_CONCURRENCY: /* NOT REALLY SUPPORTED */ mylog("GetStmtOption(): SQL_CONCURRENCY\n"); *((SDWORD *)pvParam) = stmt->options.scroll_concurrency; break; case SQL_CURSOR_TYPE: /* PARTIAL SUPPORT */ mylog("GetStmtOption(): SQL_CURSOR_TYPE\n"); *((SDWORD *)pvParam) = stmt->options.cursor_type; break; case SQL_KEYSET_SIZE: /* NOT SUPPORTED, but saved */ mylog("GetStmtOption(): SQL_KEYSET_SIZE\n"); *((SDWORD *)pvParam) = stmt->options.keyset_size; break; case SQL_MAX_LENGTH: /* NOT SUPPORTED, but saved */ *((SDWORD *)pvParam) = stmt->options.maxLength; break; case SQL_MAX_ROWS: /* NOT SUPPORTED, but saved */ *((SDWORD *)pvParam) = stmt->options.maxRows; mylog("GetSmtOption: MAX_ROWS, returning %d\n", stmt->options.maxRows); break; case SQL_NOSCAN:/* NOT SUPPORTED */ *((SDWORD *) pvParam) = SQL_NOSCAN_ON; break; case SQL_QUERY_TIMEOUT: /* NOT SUPPORTED */ *((SDWORD *) pvParam) = 0; break; case SQL_RETRIEVE_DATA: /* NOT SUPPORTED, but saved */ *((SDWORD *) pvParam) = stmt->options.retrieve_data; break; case SQL_ROWSET_SIZE: *((SDWORD *) pvParam) = stmt->options.rowset_size; break; case SQL_SIMULATE_CURSOR:/* NOT SUPPORTED */ *((SDWORD *) pvParam) = SQL_SC_NON_UNIQUE; break; case SQL_USE_BOOKMARKS: *((SDWORD *) pvParam) = stmt->options.use_bookmarks; break; /* * added to be nice to StarOffice and OpenOffice */ case /*SQL_ATTR_CURSOR_SENSITIVITY*/ 65534: *((SDWORD *) pvParam) = /*SQL_UNSPECIFIED*/ 0; break; default: { char option[64]; SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Get)"); sprintf(option, "fOption=%d", fOption); SC_log_error(func, option, stmt); return SQL_ERROR; } } return SQL_SUCCESS; } /* - - - - - - - - - */ unixODBC-2.3.12/Drivers/Postgre7.1/parse.c000066400000000000000000000464671446441710500200060ustar00rootroot00000000000000 /* Module: parse.c * * Description: This module contains routines related to parsing SQL statements. * This can be useful for two reasons: * * 1. So the query does not actually have to be executed to return data about it * * 2. To be able to return information about precision, nullability, aliases, etc. * in the functions SQLDescribeCol and SQLColAttributes. Currently, Postgres * doesn't return any information about these things in a query. * * Classes: none * * API functions: none * * Comments: See "notice.txt" for copyright and license information. * */ #include #include #include #include #include #include "statement.h" #include "connection.h" #include "qresult.h" #include "pgtypes.h" #include "misc.h" #ifndef WIN32 #ifndef HAVE_STRICMP #define stricmp(s1,s2) strcasecmp(s1,s2) #define strnicmp(s1,s2,n) strncasecmp(s1,s2,n) #endif #endif #define FLD_INCR 32 #define TAB_INCR 8 #define COL_INCR 16 char *getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric); void getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k); char searchColInfo(COL_INFO *col_info, FIELD_INFO *fi); char * getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric) { int i = 0; int out = 0; char qc, in_escape = FALSE; if (smax <= 1) return NULL; smax--; /* skip leading delimiters */ while (isspace((unsigned char) s[i]) || s[i] == ',') { /* mylog("skipping '%c'\n", s[i]); */ i++; } if (s[0] == '\0') { token[0] = '\0'; return NULL; } if (quote) *quote = FALSE; if (dquote) *dquote = FALSE; if (numeric) *numeric = FALSE; /* get the next token */ while ( ! isspace((unsigned char) s[i]) && s[i] != ',' && s[i] != '\0' && out != smax) { /* Handle quoted stuff */ if ( out == 0 && (s[i] == '\"' || s[i] == '\'')) { qc = s[i]; if (qc == '\"') { if (dquote) *dquote = TRUE; } if (qc == '\'') { if (quote) *quote = TRUE; } i++; /* dont return the quote */ while (s[i] != '\0' && out != smax) { if (s[i] == qc && ! in_escape) { break; } if (s[i] == '\\' && ! in_escape) { in_escape = TRUE; } else { in_escape = FALSE; token[out++] = s[i]; } i++; } if (s[i] == qc) i++; break; } /* Check for numeric literals */ if ( out == 0 && isdigit((unsigned char) s[i])) { if (numeric) *numeric = TRUE; token[out++] = s[i++]; while ( isalnum((unsigned char) s[i]) || s[i] == '.') token[out++] = s[i++]; break; } if ( ispunct((unsigned char) s[i]) && s[i] != '_') { mylog("got ispunct: s[%d] = '%c'\n", i, s[i]); if (out == 0) { token[out++] = s[i++]; break; } else break; } if (out != smax) token[out++] = s[i]; i++; } /* mylog("done -- s[%d] = '%c'\n", i, s[i]); */ token[out] = '\0'; /* find the delimiter */ while ( isspace((unsigned char) s[i])) i++; /* return the most priority delimiter */ if (s[i] == ',') { if (delim) *delim = s[i]; } else if (s[i] == '\0') { if (delim) *delim = '\0'; } else { if (delim) *delim = ' '; } /* skip trailing blanks */ while ( isspace((unsigned char) s[i])) { i++; } return &s[i]; } #if 0 QR_set_num_fields(stmt->result, 14); QR_set_field_info(stmt->result, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 3, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 4, "DATA_TYPE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 5, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); QR_set_field_info(stmt->result, 6, "PRECISION", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 7, "LENGTH", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 8, "SCALE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 9, "RADIX", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 10, "NULLABLE", PG_TYPE_INT2, 2); QR_set_field_info(stmt->result, 11, "REMARKS", PG_TYPE_TEXT, 254); /* User defined fields */ QR_set_field_info(stmt->result, 12, "DISPLAY_SIZE", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 13, "FIELD_TYPE", PG_TYPE_INT4, 4); #endif void getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k) { if (fi->name[0] == '\0') strcpy(fi->name, QR_get_value_manual(col_info->result, k, 3)); fi->type = atoi( QR_get_value_manual(col_info->result, k, 13)); fi->precision = atoi( QR_get_value_manual(col_info->result, k, 6)); fi->length = atoi( QR_get_value_manual(col_info->result, k, 7)); fi->nullable = atoi( QR_get_value_manual(col_info->result, k, 10)); fi->display_size = atoi( QR_get_value_manual(col_info->result, k, 12)); } char searchColInfo(COL_INFO *col_info, FIELD_INFO *fi) { int k; char *col; for (k = 0; k < QR_get_num_tuples(col_info->result); k++) { col = QR_get_value_manual(col_info->result, k, 3); if ( ! strcmp(col, fi->name)) { getColInfo(col_info, fi, k); mylog("PARSE: searchColInfo: \n"); return TRUE; } } return FALSE; } char parse_statement(StatementClass *stmt) { static char* const func="parse_statement"; char token[256]; char delim, quote, dquote, numeric, unquoted; char *ptr; char in_select = FALSE, in_distinct = FALSE, in_on = FALSE, in_from = FALSE, in_where = FALSE, in_table = FALSE; char in_field = FALSE, in_expr = FALSE, in_func = FALSE, in_dot = FALSE, in_as = FALSE; int j, i, k = 0, n, blevel = 0; FIELD_INFO **fi; TABLE_INFO **ti; char parse; ConnectionClass *conn = stmt->hdbc; HSTMT hcol_stmt; StatementClass *col_stmt; RETCODE result; mylog("%s: entering...\n", func); ptr = stmt->statement; fi = stmt->fi; ti = stmt->ti; stmt->nfld = 0; stmt->ntab = 0; while ((ptr = getNextToken(ptr, token, sizeof(token), &delim, "e, &dquote, &numeric)) != NULL) { unquoted = ! ( quote || dquote ); mylog("unquoted=%d, quote=%d, dquote=%d, numeric=%d, delim='%c', token='%s', ptr='%s'\n", unquoted, quote, dquote, numeric, delim, token, ptr); if ( unquoted && ! stricmp(token, "select")) { in_select = TRUE; mylog("SELECT\n"); continue; } if ( unquoted && in_select && ! stricmp(token, "distinct")) { in_distinct = TRUE; mylog("DISTINCT\n"); continue; } if ( unquoted && ! stricmp(token, "into")) { in_select = FALSE; mylog("INTO\n"); continue; } if ( unquoted && ! stricmp(token, "from")) { in_select = FALSE; in_from = TRUE; mylog("FROM\n"); continue; } if ( unquoted && (! stricmp(token, "where") || ! stricmp(token, "union") || ! stricmp(token, "order") || ! stricmp(token, "group") || ! stricmp(token, "having"))) { in_select = FALSE; in_from = FALSE; in_where = TRUE; mylog("WHERE...\n"); break; } if (in_select) { if ( in_distinct) { mylog("in distinct\n"); if (unquoted && ! stricmp(token, "on")) { in_on = TRUE; mylog("got on\n"); continue; } if (in_on) { in_distinct = FALSE; in_on = FALSE; continue; /* just skip the unique on field */ } mylog("done distinct\n"); in_distinct = FALSE; } if ( in_expr || in_func) { /* just eat the expression */ mylog("in_expr=%d or func=%d\n", in_expr, in_func); if (quote || dquote) continue; if (in_expr && blevel == 0 && delim == ',') { mylog("**** in_expr and Got comma\n"); in_expr = FALSE; in_field = FALSE; } else if (token[0] == '(') { blevel++; mylog("blevel++ = %d\n", blevel); } else if (token[0] == ')') { blevel--; mylog("blevel-- = %d\n", blevel); if (delim==',') { in_func = FALSE; in_expr = FALSE; in_field = FALSE; } } continue; } if ( ! in_field) { if ( ! token[0]) continue; if ( ! (stmt->nfld % FLD_INCR)) { mylog("reallocing at nfld=%d\n", stmt->nfld); fi = (FIELD_INFO **) realloc(fi, (stmt->nfld + FLD_INCR) * sizeof(FIELD_INFO *)); if ( ! fi) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } stmt->fi = fi; } fi[stmt->nfld] = (FIELD_INFO *) malloc( sizeof(FIELD_INFO)); if (fi[stmt->nfld] == NULL) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } /* Initialize the field info */ memset(fi[stmt->nfld], 0, sizeof(FIELD_INFO)); /* double quotes are for qualifiers */ if (dquote) fi[stmt->nfld]->dquote = TRUE; if (quote) { fi[stmt->nfld++]->quote = TRUE; continue; } else if (numeric) { mylog("**** got numeric: nfld = %d\n", stmt->nfld); fi[stmt->nfld]->numeric = TRUE; } else if (token[0] == '(') { /* expression */ mylog("got EXPRESSION\n"); fi[stmt->nfld++]->expr = TRUE; in_expr = TRUE; blevel = 1; continue; } else { strcpy(fi[stmt->nfld]->name, token); fi[stmt->nfld]->dot[0] = '\0'; } mylog("got field='%s', dot='%s'\n", fi[stmt->nfld]->name, fi[stmt->nfld]->dot); if (delim == ',') { mylog("comma (1)\n"); } else { in_field = TRUE; } stmt->nfld++; continue; } /**************************/ /* We are in a field now */ /**************************/ if (in_dot) { stmt->nfld--; strcpy(fi[stmt->nfld]->dot, fi[stmt->nfld]->name); strcpy(fi[stmt->nfld]->name, token); stmt->nfld++; in_dot = FALSE; if (delim == ',') { mylog("in_dot: got comma\n"); in_field = FALSE; } continue; } if (in_as) { stmt->nfld--; strcpy(fi[stmt->nfld]->alias, token); mylog("alias for field '%s' is '%s'\n", fi[stmt->nfld]->name, fi[stmt->nfld]->alias); in_as = FALSE; in_field = FALSE; stmt->nfld++; if (delim == ',') { mylog("comma(2)\n"); } continue; } /* Function */ if (token[0] == '(') { in_func = TRUE; blevel = 1; fi[stmt->nfld-1]->func = TRUE; /* name will have the function name -- maybe useful some day */ mylog("**** got function = '%s'\n", fi[stmt->nfld-1]->name); continue; } if (token[0] == '.') { in_dot = TRUE; mylog("got dot\n"); continue; } if ( ! stricmp(token, "as")) { in_as = TRUE; mylog("got AS\n"); continue; } /* otherwise, it's probably an expression */ in_expr = TRUE; fi[stmt->nfld-1]->expr = TRUE; fi[stmt->nfld-1]->name[0] = '\0'; mylog("*** setting expression\n"); } if (in_from) { if ( ! in_table) { if ( ! token[0]) continue; if ( ! (stmt->ntab % TAB_INCR)) { ti = (TABLE_INFO **) realloc(ti, (stmt->ntab + TAB_INCR) * sizeof(TABLE_INFO *)); if ( ! ti) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } stmt->ti = ti; } ti[stmt->ntab] = (TABLE_INFO *) malloc(sizeof(TABLE_INFO)); if (ti[stmt->ntab] == NULL) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } ti[stmt->ntab]->alias[0] = '\0'; strcpy(ti[stmt->ntab]->name, token); mylog("got table = '%s'\n", ti[stmt->ntab]->name); if (delim == ',') { mylog("more than 1 tables\n"); } else { in_table = TRUE; } stmt->ntab++; continue; } strcpy(ti[stmt->ntab-1]->alias, token); mylog("alias for table '%s' is '%s'\n", ti[stmt->ntab-1]->name, ti[stmt->ntab-1]->alias); in_table = FALSE; if (delim == ',') { mylog("more than 1 tables\n"); } } } /*************************************************/ /* Resolve any possible field names with tables */ /*************************************************/ parse = TRUE; /* Resolve field names with tables */ for (i = 0; i < stmt->nfld; i++) { if (fi[i]->func || fi[i]->expr || fi[i]->numeric) { fi[i]->ti = NULL; fi[i]->type = -1; parse = FALSE; continue; } else if (fi[i]->quote) { /* handle as text */ fi[i]->ti = NULL; fi[i]->type = PG_TYPE_TEXT; fi[i]->precision = 0; continue; } /* it's a dot, resolve to table or alias */ else if (fi[i]->dot[0]) { for (k = 0; k < stmt->ntab; k++) { if ( ! stricmp(ti[k]->name, fi[i]->dot)) { fi[i]->ti = ti[k]; break; } else if ( ! stricmp(ti[k]->alias, fi[i]->dot)) { fi[i]->ti = ti[k]; break; } } } else if (stmt->ntab == 1) fi[i]->ti = ti[0]; } mylog("--------------------------------------------\n"); mylog("nfld=%d, ntab=%d\n", stmt->nfld, stmt->ntab); for (i=0; i < stmt->nfld; i++) { mylog("Field %d: expr=%d, func=%d, quote=%d, dquote=%d, numeric=%d, name='%s', alias='%s', dot='%s'\n", i, fi[i]->expr, fi[i]->func, fi[i]->quote, fi[i]->dquote, fi[i]->numeric, fi[i]->name, fi[i]->alias, fi[i]->dot); if (fi[i]->ti) mylog(" ----> table_name='%s', table_alias='%s'\n", fi[i]->ti->name, fi[i]->ti->alias); } for (i=0; i < stmt->ntab; i++) { mylog("Table %d: name='%s', alias='%s'\n", i, ti[i]->name, ti[i]->alias); } /******************************************************/ /* Now save the SQLColumns Info for the parse tables */ /******************************************************/ /* Call SQLColumns for each table and store the result */ for (i = 0; i < stmt->ntab; i++) { /* See if already got it */ char found = FALSE; for (k = 0; k < conn->ntables; k++) { if ( ! stricmp(conn->col_info[k]->name, ti[i]->name)) { mylog("FOUND col_info table='%s'\n", ti[i]->name); found = TRUE; break; } } if ( ! found) { mylog("PARSE: Getting SQLColumns for table[%d]='%s'\n", i, ti[i]->name); result = PG_SQLAllocStmt( stmt->hdbc, &hcol_stmt); if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "SQLAllocStmt failed in parse_statement for columns."); stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } col_stmt = (StatementClass *) hcol_stmt; col_stmt->internal = TRUE; result = PG_SQLColumns(hcol_stmt, "", 0, "", 0, ti[i]->name, (SWORD) strlen(ti[i]->name), "", 0); mylog(" Past SQLColumns\n"); if (result == SQL_SUCCESS) { mylog(" Success\n"); if ( ! (conn->ntables % COL_INCR)) { mylog("PARSE: Allocing col_info at ntables=%d\n", conn->ntables); conn->col_info = (COL_INFO **) realloc(conn->col_info, (conn->ntables + COL_INCR) * sizeof(COL_INFO *)); if ( ! conn->col_info) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } } mylog("PARSE: malloc at conn->col_info[%d]\n", conn->ntables); conn->col_info[conn->ntables] = (COL_INFO *) malloc(sizeof(COL_INFO)); if ( ! conn->col_info[conn->ntables]) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } /* Store the table name and the SQLColumns result structure */ strcpy(conn->col_info[conn->ntables]->name, ti[i]->name); conn->col_info[conn->ntables]->result = col_stmt->result; /* The connection will now free the result structures, so make sure that the statement doesn't free it */ col_stmt->result = NULL; conn->ntables++; PG_SQLFreeStmt(hcol_stmt, SQL_DROP); mylog("Created col_info table='%s', ntables=%d\n", ti[i]->name, conn->ntables); } else { PG_SQLFreeStmt(hcol_stmt, SQL_DROP); break; } } /* Associate a table from the statement with a SQLColumn info */ ti[i]->col_info = conn->col_info[k]; mylog("associate col_info: i=%d, k=%d\n", i, k); } mylog("Done SQLColumns\n"); /******************************************************/ /* Now resolve the fields to point to column info */ /******************************************************/ for (i = 0; i < stmt->nfld;) { /* Dont worry about functions or quotes */ if (fi[i]->func || fi[i]->quote || fi[i]->numeric) { i++; continue; } /* Stars get expanded to all fields in the table */ else if (fi[i]->name[0] == '*') { char do_all_tables; int total_cols, old_alloc, new_size, cols; int increased_cols; mylog("expanding field %d\n", i); total_cols = 0; if (fi[i]->ti) /* The star represents only the qualified table */ total_cols = QR_get_num_tuples(fi[i]->ti->col_info->result); else { /* The star represents all tables */ /* Calculate the total number of columns after expansion */ for (k = 0; k < stmt->ntab; k++) { total_cols += QR_get_num_tuples(ti[k]->col_info->result); } } increased_cols = total_cols - 1; /* Allocate some more field pointers if necessary */ /*------------------------------------------------------------- */ old_alloc = ((stmt->nfld - 1) / FLD_INCR + 1) * FLD_INCR; new_size = stmt->nfld + increased_cols; mylog("k=%d, increased_cols=%d, old_alloc=%d, new_size=%d\n", k,increased_cols,old_alloc,new_size); if (new_size > old_alloc) { int new_alloc = ((new_size / FLD_INCR) + 1) * FLD_INCR; mylog("need more cols: new_alloc = %d\n", new_alloc); fi = (FIELD_INFO **) realloc(fi, new_alloc * sizeof(FIELD_INFO *)); if ( ! fi) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } stmt->fi = fi; } /*------------------------------------------------------------- */ /* copy any other fields (if there are any) up past the expansion */ for (j = stmt->nfld - 1; j > i; j--) { mylog("copying field %d to %d\n", j, increased_cols + j); fi[increased_cols + j] = fi[j]; } mylog("done copying fields\n"); /*------------------------------------------------------------- */ /* Set the new number of fields */ stmt->nfld += increased_cols; mylog("stmt->nfld now at %d\n", stmt->nfld); /*------------------------------------------------------------- */ /* copy the new field info */ do_all_tables = (fi[i]->ti ? FALSE : TRUE); for (k = 0; k < (do_all_tables ? stmt->ntab : 1); k++) { TABLE_INFO *the_ti = do_all_tables ? ti[k] : fi[i]->ti; cols = QR_get_num_tuples(the_ti->col_info->result); for (n = 0; n < cols; n++) { mylog("creating field info: n=%d\n", n); /* skip malloc (already did it for the Star) */ if (k > 0 || n > 0) { mylog("allocating field info at %d\n", n + i); fi[n + i] = (FIELD_INFO *) malloc( sizeof(FIELD_INFO)); if (fi[n + i] == NULL) { stmt->parse_status = STMT_PARSE_FATAL; return FALSE; } } /* Initialize the new space (or the * field) */ memset(fi[n + i], 0, sizeof(FIELD_INFO)); fi[n + i]->ti = the_ti; mylog("about to copy at %d\n", n + i); getColInfo(the_ti->col_info, fi[n + i], n); mylog("done copying\n"); } i += cols; mylog("i now at %d\n", i); } /*------------------------------------------------------------- */ } /* We either know which table the field was in because it was qualified with a table name or alias -OR- there was only 1 table. */ else if (fi[i]->ti) { if ( ! searchColInfo(fi[i]->ti->col_info, fi[i])) parse = FALSE; i++; } /* Don't know the table -- search all tables in "from" list */ else { parse = FALSE; for (k = 0; k < stmt->ntab; k++) { if ( searchColInfo(ti[k]->col_info, fi[i])) { fi[i]->ti = ti[k]; /* now know the table */ parse = TRUE; break; } } i++; } } if ( ! parse) stmt->parse_status = STMT_PARSE_INCOMPLETE; else stmt->parse_status = STMT_PARSE_COMPLETE; mylog("done parse_statement: parse=%d, parse_status=%d\n", parse, stmt->parse_status); return parse; } unixODBC-2.3.12/Drivers/Postgre7.1/pgtypes.c000066400000000000000000000440461446441710500203560ustar00rootroot00000000000000 /* Module: pgtypes.c * * Description: This module contains routines for getting information * about the supported Postgres data types. Only the function * pgtype_to_sqltype() returns an unknown condition. All other * functions return a suitable default so that even data types that * are not directly supported can be used (it is handled as char data). * * Classes: n/a * * API functions: none * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "psqlodbc.h" #include "dlg_specific.h" #include "pgtypes.h" #include "statement.h" #include "connection.h" #include "qresult.h" #ifndef WIN32 #include "isql.h" #include "isqlext.h" #else #include #include #include #endif extern GLOBAL_VALUES globals; Int4 getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as); /* these are the types we support. all of the pgtype_ functions should */ /* return values for each one of these. */ /* Even types not directly supported are handled as character types so all types should work (points, etc.) */ /* ALL THESE TYPES ARE NO LONGER REPORTED in SQLGetTypeInfo. Instead, all the SQL TYPES are reported and mapped to a corresponding Postgres Type */ /* Int4 pgtypes_defined[] = { PG_TYPE_CHAR, PG_TYPE_CHAR2, PG_TYPE_CHAR4, PG_TYPE_CHAR8, PG_TYPE_CHAR16, PG_TYPE_NAME, PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, PG_TYPE_DATE, PG_TYPE_TIME, PG_TYPE_DATETIME, PG_TYPE_ABSTIME, PG_TYPE_TIMESTAMP, PG_TYPE_TEXT, PG_TYPE_INT2, PG_TYPE_INT4, PG_TYPE_FLOAT4, PG_TYPE_FLOAT8, PG_TYPE_OID, PG_TYPE_MONEY, PG_TYPE_BOOL, PG_TYPE_BYTEA, PG_TYPE_LO, 0 }; */ /* These are NOW the SQL Types reported in SQLGetTypeInfo. */ Int2 sqlTypes [] = { SQL_BIGINT, /* SQL_BINARY, -- Commented out because VarBinary is more correct. */ SQL_BIT, SQL_CHAR, SQL_DATE, SQL_DECIMAL, SQL_DOUBLE, SQL_FLOAT, SQL_INTEGER, SQL_LONGVARBINARY, SQL_LONGVARCHAR, SQL_NUMERIC, SQL_REAL, SQL_SMALLINT, SQL_TIME, SQL_TIMESTAMP, SQL_TINYINT, SQL_VARBINARY, SQL_VARCHAR, 0 }; Int4 sqltype_to_pgtype(SWORD fSqlType) { Int4 pgType; switch(fSqlType) { case SQL_BINARY: pgType = PG_TYPE_BYTEA; break; case SQL_CHAR: pgType = PG_TYPE_BPCHAR; break; case SQL_BIT: pgType = globals.bools_as_char ? PG_TYPE_CHAR : PG_TYPE_BOOL; break; case SQL_DATE: pgType = PG_TYPE_DATE; break; case SQL_DOUBLE: case SQL_FLOAT: pgType = PG_TYPE_FLOAT8; break; case SQL_DECIMAL: case SQL_NUMERIC: pgType = PG_TYPE_NUMERIC; break; case SQL_BIGINT: pgType = PG_TYPE_INT8; break; case SQL_INTEGER: pgType = PG_TYPE_INT4; break; case SQL_LONGVARBINARY: pgType = PG_TYPE_LO; break; case SQL_LONGVARCHAR: pgType = globals.text_as_longvarchar ? PG_TYPE_TEXT : PG_TYPE_VARCHAR; break; case SQL_REAL: pgType = PG_TYPE_FLOAT4; break; case SQL_SMALLINT: case SQL_TINYINT: pgType = PG_TYPE_INT2; break; case SQL_TIME: pgType = PG_TYPE_TIME; break; case SQL_TIMESTAMP: pgType = PG_TYPE_DATETIME; break; case SQL_VARBINARY: pgType = PG_TYPE_BYTEA; break; case SQL_VARCHAR: pgType = PG_TYPE_VARCHAR; break; default: pgType = 0; /* ??? */ break; } return pgType; } /* There are two ways of calling this function: 1. When going through the supported PG types (SQLGetTypeInfo) 2. When taking any type id (SQLColumns, SQLGetData) The first type will always work because all the types defined are returned here. The second type will return a default based on global parameter when it does not know. This allows for supporting types that are unknown. All other pg routines in here return a suitable default. */ Int2 pgtype_to_sqltype(StatementClass *stmt, Int4 type) { switch(type) { case PG_TYPE_CHAR: case PG_TYPE_CHAR2: case PG_TYPE_CHAR4: case PG_TYPE_CHAR8: case PG_TYPE_NAME: return SQL_CHAR; case PG_TYPE_BPCHAR: return SQL_CHAR; case PG_TYPE_VARCHAR: return SQL_VARCHAR; case PG_TYPE_TEXT: return globals.text_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR; case PG_TYPE_BYTEA: return SQL_VARBINARY; case PG_TYPE_LO: return SQL_LONGVARBINARY; case PG_TYPE_INT2: return SQL_SMALLINT; case PG_TYPE_OID: case PG_TYPE_XID: case PG_TYPE_INT4: return SQL_INTEGER; /* Change this to SQL_BIGINT for ODBC v3 bjm 2001-01-23 */ #ifdef HAVE_LONG_LONG case PG_TYPE_INT8: return SQL_BIGINT; #else case PG_TYPE_INT8: return SQL_INTEGER; #endif case PG_TYPE_NUMERIC: return SQL_NUMERIC; case PG_TYPE_FLOAT4: return SQL_REAL; case PG_TYPE_FLOAT8: return SQL_FLOAT; case PG_TYPE_DATE: return SQL_DATE; case PG_TYPE_TIME: return SQL_TIME; case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP_NO_TMZONE: case PG_TYPE_TIMESTAMP: return SQL_TIMESTAMP; case PG_TYPE_MONEY: return SQL_FLOAT; case PG_TYPE_BOOL: return globals.bools_as_char ? SQL_CHAR : SQL_BIT; default: /* first, check to see if 'type' is in list. If not, look up with query. Add oid, name to list. If it's already in list, just return. */ if (type == stmt->hdbc->lobj_type) /* hack until permanent type is available */ return SQL_LONGVARBINARY; return globals.unknowns_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR; } } Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type) { switch(type) { #ifdef HAVE_LONG_LONG case PG_TYPE_INT8: return SQL_BIGINT; #else case PG_TYPE_INT8: return SQL_INTEGER; #endif case PG_TYPE_NUMERIC: return SQL_C_CHAR; case PG_TYPE_INT2: return SQL_C_SSHORT; case PG_TYPE_OID: case PG_TYPE_XID: case PG_TYPE_INT4: return SQL_C_SLONG; case PG_TYPE_FLOAT4: return SQL_C_FLOAT; case PG_TYPE_FLOAT8: return SQL_C_DOUBLE; case PG_TYPE_DATE: return SQL_C_DATE; case PG_TYPE_TIME: return SQL_C_TIME; case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP_NO_TMZONE: case PG_TYPE_TIMESTAMP: return SQL_C_TIMESTAMP; case PG_TYPE_MONEY: return SQL_C_FLOAT; case PG_TYPE_BOOL: return globals.bools_as_char ? SQL_C_CHAR : SQL_C_BIT; case PG_TYPE_BYTEA: return SQL_C_BINARY; case PG_TYPE_LO: return SQL_C_BINARY; default: if (type == stmt->hdbc->lobj_type) /* hack until permanent type is available */ return SQL_C_BINARY; return SQL_C_CHAR; } } char *pgtype_to_name(StatementClass *stmt, Int4 type) { switch(type) { case PG_TYPE_CHAR: return "char"; case PG_TYPE_CHAR2: return "char2"; case PG_TYPE_CHAR4: return "char4"; case PG_TYPE_CHAR8: return "char8"; case PG_TYPE_INT8: return "int8"; case PG_TYPE_NUMERIC: return "numeric"; case PG_TYPE_VARCHAR: return "varchar"; case PG_TYPE_BPCHAR: return "char"; case PG_TYPE_TEXT: return "text"; case PG_TYPE_NAME: return "name"; case PG_TYPE_INT2: return "int2"; case PG_TYPE_OID: return "oid"; case PG_TYPE_INT4: return "int4"; case PG_TYPE_FLOAT4: return "float4"; case PG_TYPE_FLOAT8: return "float8"; case PG_TYPE_DATE: return "date"; case PG_TYPE_TIME: return "time"; case PG_TYPE_ABSTIME: return "abstime"; case PG_TYPE_DATETIME: return "datetime"; case PG_TYPE_TIMESTAMP: return "timestamp"; case PG_TYPE_MONEY: return "money"; case PG_TYPE_BOOL: return "bool"; case PG_TYPE_BYTEA: return "bytea"; case PG_TYPE_LO: return PG_TYPE_LO_NAME; default: if (type == stmt->hdbc->lobj_type) /* hack until permanent type is available */ return PG_TYPE_LO_NAME; /* "unknown" can actually be used in alter table because it is a real PG type! */ return "unknown"; } } static Int2 getNumericScale(StatementClass *stmt, Int4 type, int col) { Int4 atttypmod; QResultClass *result; ColumnInfoClass *flds; mylog("getNumericScale: type=%d, col=%d, unknown = %d\n", type,col); if (col < 0) return PG_NUMERIC_MAX_SCALE; result = SC_get_Result(stmt); /* Manual Result Sets -- use assigned column width (i.e., from set_tuplefield_string) */ if (stmt->manual_result) { flds = result->fields; if (flds) return flds->adtsize[col]; else return PG_NUMERIC_MAX_SCALE; } atttypmod = QR_get_atttypmod(result, col); if ( atttypmod > -1 ) return (atttypmod & 0xffff); else return ( QR_get_display_size(result, col) ? QR_get_display_size(result, col) : PG_NUMERIC_MAX_SCALE); } static Int4 getNumericPrecision(StatementClass *stmt, Int4 type, int col) { Int4 atttypmod; QResultClass *result; ColumnInfoClass *flds; mylog("getNumericPrecision: type=%d, col=%d, unknown = %d\n", type,col); if (col < 0) return PG_NUMERIC_MAX_PRECISION; result = SC_get_Result(stmt); /* Manual Result Sets -- use assigned column width (i.e., from set_tuplefield_string) */ if (stmt->manual_result) { flds = result->fields; if (flds) return flds->adtsize[col]; else return PG_NUMERIC_MAX_PRECISION; } atttypmod = QR_get_atttypmod(result, col); if ( atttypmod > -1 ) return (atttypmod >> 16) & 0xffff; else return ( QR_get_display_size(result, col) >= 0 ? QR_get_display_size(result, col) : PG_NUMERIC_MAX_PRECISION ); } Int4 getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as) { int p = -1, maxsize; QResultClass *result; ColumnInfoClass *flds; mylog("getCharPrecision: type=%d, col=%d, unknown = %d\n", type,col,handle_unknown_size_as); /* Assign Maximum size based on parameters */ switch(type) { case PG_TYPE_TEXT: if (globals.text_as_longvarchar) maxsize = globals.max_longvarchar_size; else maxsize = globals.max_varchar_size; break; case PG_TYPE_VARCHAR: case PG_TYPE_BPCHAR: maxsize = globals.max_varchar_size; break; default: if (globals.unknowns_as_longvarchar) maxsize = globals.max_longvarchar_size; else maxsize = globals.max_varchar_size; break; } /* Static Precision (i.e., the Maximum Precision of the datatype) This has nothing to do with a result set. */ if (col < 0) return maxsize; result = SC_get_Result(stmt); /* Manual Result Sets -- use assigned column width (i.e., from set_tuplefield_string) */ if (stmt->manual_result) { flds = result->fields; if (flds) return flds->adtsize[col]; else return maxsize; } /* Size is unknown -- handle according to parameter */ if (QR_get_atttypmod(result, col) > -1) return QR_get_atttypmod(result, col); if (type == PG_TYPE_BPCHAR || handle_unknown_size_as == UNKNOWNS_AS_LONGEST) { p = QR_get_display_size(result, col); mylog("getCharPrecision: LONGEST: p = %d\n", p); } if (p < 0 && handle_unknown_size_as == UNKNOWNS_AS_MAX) return maxsize; else return p; } /* For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, PG_TYPE_NUMERIC, SQLColumns will override this length with the atttypmod length from pg_attribute . If col >= 0, then will attempt to get the info from the result set. This is used for functions SQLDescribeCol and SQLColAttributes. */ Int4 pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as) { switch(type) { case PG_TYPE_CHAR: return 1; case PG_TYPE_CHAR2: return 2; case PG_TYPE_CHAR4: return 4; case PG_TYPE_CHAR8: return 8; case PG_TYPE_NAME: return NAME_FIELD_SIZE; case PG_TYPE_INT2: return 5; case PG_TYPE_OID: case PG_TYPE_XID: case PG_TYPE_INT4: return 10; case PG_TYPE_INT8: return 19; /* signed */ case PG_TYPE_NUMERIC: return getNumericPrecision(stmt,type,col); case PG_TYPE_FLOAT4: case PG_TYPE_MONEY: return 7; case PG_TYPE_FLOAT8: return 15; case PG_TYPE_DATE: return 10; case PG_TYPE_TIME: return 8; case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP: return 19; case PG_TYPE_BOOL: return 1; case PG_TYPE_LO: return SQL_NO_TOTAL; default: if (type == stmt->hdbc->lobj_type) /* hack until permanent type is available */ return SQL_NO_TOTAL; /* Handle Character types and unknown types */ return getCharPrecision(stmt, type, col, handle_unknown_size_as); } } Int4 pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as) { switch(type) { case PG_TYPE_INT2: return 6; case PG_TYPE_OID: case PG_TYPE_XID: return 10; case PG_TYPE_INT4: return 11; case PG_TYPE_INT8: return 20; /* signed: 19 digits + sign */ case PG_TYPE_NUMERIC: return getNumericPrecision(stmt,type,col) + 2; case PG_TYPE_MONEY: return 15; /* ($9,999,999.99) */ case PG_TYPE_FLOAT4: return 13; case PG_TYPE_FLOAT8: return 22; /* Character types use regular precision */ default: return pgtype_precision(stmt, type, col, handle_unknown_size_as); } } /* For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, SQLColumns will override this length with the atttypmod length from pg_attribute */ Int4 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as) { switch(type) { case PG_TYPE_INT2: return 2; case PG_TYPE_OID: case PG_TYPE_XID: case PG_TYPE_INT4: return 4; case PG_TYPE_INT8: return 20; /* signed: 19 digits + sign */ case PG_TYPE_NUMERIC: return getNumericPrecision(stmt,type,col) + 2; case PG_TYPE_FLOAT4: case PG_TYPE_MONEY: return 4; case PG_TYPE_FLOAT8: return 8; case PG_TYPE_DATE: case PG_TYPE_TIME: return 6; case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP: return 16; /* Character types (and NUMERIC) use the default precision */ default: return pgtype_precision(stmt, type, col, handle_unknown_size_as); } } Int2 pgtype_scale(StatementClass *stmt, Int4 type, int col) { switch(type) { case PG_TYPE_INT2: case PG_TYPE_OID: case PG_TYPE_XID: case PG_TYPE_INT4: case PG_TYPE_INT8: case PG_TYPE_FLOAT4: case PG_TYPE_FLOAT8: case PG_TYPE_MONEY: case PG_TYPE_BOOL: /* Number of digits to the right of the decimal point in "yyyy-mm=dd hh:mm:ss[.f...]" */ case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP: return 0; case PG_TYPE_NUMERIC: return getNumericScale(stmt,type,col); default: return -1; } } Int2 pgtype_radix(StatementClass *stmt, Int4 type) { switch(type) { case PG_TYPE_INT2: case PG_TYPE_OID: case PG_TYPE_INT4: case PG_TYPE_INT8: case PG_TYPE_NUMERIC: case PG_TYPE_FLOAT4: case PG_TYPE_MONEY: case PG_TYPE_FLOAT8: return 10; default: return -1; } } Int2 pgtype_nullable(StatementClass *stmt, Int4 type) { return SQL_NULLABLE; /* everything should be nullable */ } Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type) { switch(type) { case PG_TYPE_INT2: case PG_TYPE_OID: case PG_TYPE_XID: case PG_TYPE_INT4: case PG_TYPE_FLOAT4: case PG_TYPE_MONEY: case PG_TYPE_BOOL: case PG_TYPE_FLOAT8: case PG_TYPE_INT8: case PG_TYPE_NUMERIC: case PG_TYPE_DATE: case PG_TYPE_TIME: case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP: return FALSE; default: return -1; } } Int2 pgtype_case_sensitive(StatementClass *stmt, Int4 type) { switch(type) { case PG_TYPE_CHAR: case PG_TYPE_CHAR2: case PG_TYPE_CHAR4: case PG_TYPE_CHAR8: case PG_TYPE_VARCHAR: case PG_TYPE_BPCHAR: case PG_TYPE_TEXT: case PG_TYPE_NAME: return TRUE; default: return FALSE; } } Int2 pgtype_money(StatementClass *stmt, Int4 type) { switch(type) { case PG_TYPE_MONEY: return TRUE; default: return FALSE; } } Int2 pgtype_searchable(StatementClass *stmt, Int4 type) { switch(type) { case PG_TYPE_CHAR: case PG_TYPE_CHAR2: case PG_TYPE_CHAR4: case PG_TYPE_CHAR8: case PG_TYPE_VARCHAR: case PG_TYPE_BPCHAR: case PG_TYPE_TEXT: case PG_TYPE_NAME: return SQL_SEARCHABLE; default: return SQL_ALL_EXCEPT_LIKE; } } Int2 pgtype_unsigned(StatementClass *stmt, Int4 type) { switch(type) { case PG_TYPE_OID: case PG_TYPE_XID: return TRUE; case PG_TYPE_INT2: case PG_TYPE_INT4: case PG_TYPE_INT8: case PG_TYPE_NUMERIC: case PG_TYPE_FLOAT4: case PG_TYPE_FLOAT8: case PG_TYPE_MONEY: return FALSE; default: return -1; } } char *pgtype_literal_prefix(StatementClass *stmt, Int4 type) { switch(type) { case PG_TYPE_INT2: case PG_TYPE_OID: case PG_TYPE_XID: case PG_TYPE_INT4: case PG_TYPE_INT8: case PG_TYPE_NUMERIC: case PG_TYPE_FLOAT4: case PG_TYPE_FLOAT8: case PG_TYPE_MONEY: return NULL; default: return "'"; } } char *pgtype_literal_suffix(StatementClass *stmt, Int4 type) { switch(type) { case PG_TYPE_INT2: case PG_TYPE_OID: case PG_TYPE_XID: case PG_TYPE_INT4: case PG_TYPE_INT8: case PG_TYPE_NUMERIC: case PG_TYPE_FLOAT4: case PG_TYPE_FLOAT8: case PG_TYPE_MONEY: return NULL; default: return "'"; } } char *pgtype_create_params(StatementClass *stmt, Int4 type) { switch(type) { case PG_TYPE_BPCHAR: case PG_TYPE_CHAR: case PG_TYPE_VARCHAR: return "max. length"; case PG_TYPE_NUMERIC: return "precision, scale"; default: return NULL; } } Int2 sqltype_to_default_ctype(Int2 sqltype) { /* from the table on page 623 of ODBC 2.0 Programmer's Reference */ /* (Appendix D) */ switch(sqltype) { case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: case SQL_DECIMAL: case SQL_NUMERIC: #ifndef HAVE_LONG_LONG case SQL_BIGINT: #endif return SQL_C_CHAR; #ifdef HAVE_LONG_LONG case SQL_BIGINT: return SQL_BIGINT; #endif case SQL_BIT: return SQL_C_BIT; case SQL_TINYINT: return SQL_C_STINYINT; case SQL_SMALLINT: return SQL_C_SSHORT; case SQL_INTEGER: return SQL_C_SLONG; case SQL_REAL: return SQL_C_FLOAT; case SQL_FLOAT: case SQL_DOUBLE: return SQL_C_DOUBLE; case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: return SQL_C_BINARY; case SQL_DATE: return SQL_C_DATE; case SQL_TIME: return SQL_C_TIME; case SQL_TIMESTAMP: return SQL_C_TIMESTAMP; default: /* should never happen */ return SQL_C_CHAR; } } unixODBC-2.3.12/Drivers/Postgre7.1/pgtypes.h000066400000000000000000000061201446441710500203520ustar00rootroot00000000000000 /* File: pgtypes.h * * Description: See "pgtypes.c" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __PGTYPES_H__ #define __PGTYPES_H__ #include "psqlodbc.h" /* the type numbers are defined by the OID's of the types' rows */ /* in table pg_type */ #if 0 #define PG_TYPE_LO ???? /* waiting for permanent type */ #endif #define PG_TYPE_BOOL 16 #define PG_TYPE_BYTEA 17 #define PG_TYPE_CHAR 18 #define PG_TYPE_NAME 19 #define PG_TYPE_INT8 20 #define PG_TYPE_INT2 21 #define PG_TYPE_INT2VECTOR 22 #define PG_TYPE_INT4 23 #define PG_TYPE_REGPROC 24 #define PG_TYPE_TEXT 25 #define PG_TYPE_OID 26 #define PG_TYPE_TID 27 #define PG_TYPE_XID 28 #define PG_TYPE_CID 29 #define PG_TYPE_OIDVECTOR 30 #define PG_TYPE_SET 32 #define PG_TYPE_CHAR2 409 #define PG_TYPE_CHAR4 410 #define PG_TYPE_CHAR8 411 #define PG_TYPE_POINT 600 #define PG_TYPE_LSEG 601 #define PG_TYPE_PATH 602 #define PG_TYPE_BOX 603 #define PG_TYPE_POLYGON 604 #define PG_TYPE_FILENAME 605 #define PG_TYPE_FLOAT4 700 #define PG_TYPE_FLOAT8 701 #define PG_TYPE_ABSTIME 702 #define PG_TYPE_RELTIME 703 #define PG_TYPE_TINTERVAL 704 #define PG_TYPE_UNKNOWN 705 #define PG_TYPE_MONEY 790 #define PG_TYPE_OIDINT2 810 #define PG_TYPE_OIDINT4 910 #define PG_TYPE_OIDNAME 911 #define PG_TYPE_BPCHAR 1042 #define PG_TYPE_VARCHAR 1043 #define PG_TYPE_DATE 1082 #define PG_TYPE_TIME 1083 #define PG_TYPE_DATETIME 1184 #define PG_TYPE_TIMESTAMP 1296 #define PG_TYPE_NUMERIC 1700 #define PG_TYPE_TIMESTAMP_NO_TMZONE 1114 /* extern Int4 pgtypes_defined[]; */ extern Int2 sqlTypes[]; /* Defines for pgtype_precision */ #define PG_STATIC -1 Int4 sqltype_to_pgtype(Int2 fSqlType); Int2 pgtype_to_sqltype(StatementClass *stmt, Int4 type); Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type); char *pgtype_to_name(StatementClass *stmt, Int4 type); /* These functions can use static numbers or result sets(col parameter) */ Int4 pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as); Int4 pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as); Int4 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as); Int2 pgtype_scale(StatementClass *stmt, Int4 type, int col); Int2 pgtype_radix(StatementClass *stmt, Int4 type); Int2 pgtype_nullable(StatementClass *stmt, Int4 type); Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type); Int2 pgtype_case_sensitive(StatementClass *stmt, Int4 type); Int2 pgtype_money(StatementClass *stmt, Int4 type); Int2 pgtype_searchable(StatementClass *stmt, Int4 type); Int2 pgtype_unsigned(StatementClass *stmt, Int4 type); char *pgtype_literal_prefix(StatementClass *stmt, Int4 type); char *pgtype_literal_suffix(StatementClass *stmt, Int4 type); char *pgtype_create_params(StatementClass *stmt, Int4 type); Int2 sqltype_to_default_ctype(Int2 sqltype); #endif unixODBC-2.3.12/Drivers/Postgre7.1/psqlodbc.c000066400000000000000000000055271446441710500204730ustar00rootroot00000000000000 /* Module: psqlodbc.c * * Description: This module contains the main entry point (DllMain) for the library. * It also contains functions to get and set global variables for the * driver in the registry. * * Classes: n/a * * API functions: none * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "psqlodbc.h" #include "dlg_specific.h" #ifndef WIN32 #include "isql.h" #include "isqlext.h" #else #include #include #include #include #endif GLOBAL_VALUES globals; RETCODE SQL_API SQLDummyOrdinal(void); #ifdef WIN32 HINSTANCE NEAR s_hModule; /* Saved module handle. */ /* This is where the Driver Manager attaches to this Driver */ BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) { WORD wVersionRequested; WSADATA wsaData; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: s_hModule = hInst; /* Save for dialog boxes */ /* Load the WinSock Library */ wVersionRequested = MAKEWORD(1, 1); if ( WSAStartup(wVersionRequested, &wsaData)) return FALSE; /* Verify that this is the minimum version of WinSock */ if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) { WSACleanup(); return FALSE; } getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE); break; case DLL_THREAD_ATTACH: break; case DLL_PROCESS_DETACH: WSACleanup(); return TRUE; case DLL_THREAD_DETACH: break; default: break; } return TRUE; UNREFERENCED_PARAMETER(lpReserved); } #else /* not WIN32 */ #ifndef TRUE #define TRUE (BOOL)1 #endif #ifndef FALSE #define FALSE (BOOL)0 #endif #ifdef __GNUC__ /* This function is called at library initialization time. */ static BOOL __attribute__((constructor)) init(void) { getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE); return TRUE; } #else /* not __GNUC__ */ #ifdef DONT_DO_IT /* These two functions do shared library initialziation on UNIX, well at least * on Linux. I don't know about other systems. */ BOOL _init(void) { getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE); return TRUE; } BOOL _fini(void) { return TRUE; } #endif /* not __GNUC__ */ #endif #endif /* not WIN32 */ /* This function is used to cause the Driver Manager to call functions by number rather than name, which is faster. The ordinal value of this function must be 199 to have the Driver Manager do this. Also, the ordinal values of the functions must match the value of fFunction in SQLGetFunctions() */ RETCODE SQL_API SQLDummyOrdinal(void) { return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/Postgre7.1/psqlodbc.h000066400000000000000000000116541446441710500204760ustar00rootroot00000000000000 /* File: psqlodbc.h * * Description: This file contains defines and declarations that are related to * the entire driver. * * Comments: See "notice.txt" for copyright and license information. * * $Id: psqlodbc.h,v 1.4 2003/02/18 18:46:48 lurcher Exp $ */ #ifndef __PSQLODBC_H__ #define __PSQLODBC_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include /* for FILE* pointers: see GLOBAL_VALUES */ #ifndef WIN32 #include /* for prototype of atof() etc */ #define Int4 int #define UInt4 unsigned int #define Int2 short #define UInt2 unsigned short #else #define Int4 int #define UInt4 unsigned int #define Int2 short #define UInt2 unsigned short #endif typedef UInt4 Oid; #undef ODBCVER /* Driver stuff */ #define ODBCVER 0x0250 #define DRIVER_ODBC_VER "02.50" #define DRIVERNAME "PostgreSQL ODBC" #define DBMS_NAME "PostgreSQL" #define POSTGRESDRIVERVERSION "07.01.0003" #ifdef WIN32 #define DRIVER_FILE_NAME "PSQLODBC.DLL" #else #define DRIVER_FILE_NAME "libpsqlodbc.so" #endif /* Limits */ #define BLCKSZ 4096 #define MAX_MESSAGE_LEN 65536 /* This puts a limit on query size but I don't */ /* see an easy way round this - DJP 24-1-2001 */ #define MAX_CONNECT_STRING 4096 #define ERROR_MSG_LENGTH 4096 #define FETCH_MAX 100 /* default number of rows to cache for declare/fetch */ #define TUPLE_MALLOC_INC 100 #define SOCK_BUFFER_SIZE 4096 /* default socket buffer size */ #define MAX_CONNECTIONS 128 /* conns per environment (arbitrary) */ #define MAX_FIELDS 512 #define BYTELEN 8 #define VARHDRSZ sizeof(Int4) #define MAX_TABLE_LEN 32 #define MAX_COLUMN_LEN 32 #define MAX_CURSOR_LEN 32 /* Registry length limits */ #define LARGE_REGISTRY_LEN 4096 /* used for special cases */ #define MEDIUM_REGISTRY_LEN 256 /* normal size for user,database,etc. */ #define SMALL_REGISTRY_LEN 10 /* for 1/0 settings */ /* These prefixes denote system tables */ #define POSTGRES_SYS_PREFIX "pg_" #define KEYS_TABLE "dd_fkey" /* Info limits */ #define MAX_INFO_STRING 128 #define MAX_KEYPARTS 20 #define MAX_KEYLEN 512 /* max key of the form "date+outlet+invoice" */ #define MAX_ROW_SIZE 0 /* Unlimited rowsize with the Tuple Toaster */ #define MAX_STATEMENT_LEN 0 /* Unlimited statement size with 7.0 */ /* Previously, numerous query strings were defined of length MAX_STATEMENT_LEN */ /* Now that's 0, lets use this instead. DJP 24-1-2001 */ #define STD_STATEMENT_LEN MAX_MESSAGE_LEN #define PG62 "6.2" /* "Protocol" key setting to force Postgres 6.2 */ #define PG63 "6.3" /* "Protocol" key setting to force postgres 6.3 */ #define PG64 "6.4" typedef struct ConnectionClass_ ConnectionClass; typedef struct StatementClass_ StatementClass; typedef struct QResultClass_ QResultClass; typedef struct SocketClass_ SocketClass; typedef struct BindInfoClass_ BindInfoClass; typedef struct ParameterInfoClass_ ParameterInfoClass; typedef struct ColumnInfoClass_ ColumnInfoClass; typedef struct TupleListClass_ TupleListClass; typedef struct EnvironmentClass_ EnvironmentClass; typedef struct TupleNode_ TupleNode; typedef struct TupleField_ TupleField; typedef struct col_info COL_INFO; typedef struct lo_arg LO_ARG; typedef struct GlobalValues_ { int fetch_max; int socket_buffersize; int unknown_sizes; int max_varchar_size; int max_longvarchar_size; char debug; char commlog; char disable_optimizer; char ksqo; char unique_index; char onlyread; /* readonly is reserved on Digital C++ compiler */ char use_declarefetch; char text_as_longvarchar; char unknowns_as_longvarchar; char bools_as_char; char lie; char parse; char cancel_as_freestmt; char extra_systable_prefixes[MEDIUM_REGISTRY_LEN]; char conn_settings[LARGE_REGISTRY_LEN]; char protocol[SMALL_REGISTRY_LEN]; FILE* mylogFP; FILE* qlogFP; } GLOBAL_VALUES; /* * rename to avoid colision */ #define global pg_global typedef struct StatementOptions_ { int maxRows; int maxLength; int rowset_size; int keyset_size; int cursor_type; int scroll_concurrency; int retrieve_data; int bind_size; /* size of each structure if using Row Binding */ int use_bookmarks; } StatementOptions; /* Used to pass extra query info to send_query */ typedef struct QueryInfo_ { int row_size; QResultClass *result_in; char *cursor; } QueryInfo; #define PG_TYPE_LO -999 /* hack until permanent type available */ #define PG_TYPE_LO_NAME "lo" #define OID_ATTNUM -2 /* the attnum in pg_index of the oid */ /* sizes */ #define TEXT_FIELD_SIZE 65536 /* size of text fields (not including null term) */ #define NAME_FIELD_SIZE 32 /* size of name fields */ #define MAX_VARCHAR_SIZE 254 /* maximum size of a varchar (not including null term) */ #define PG_NUMERIC_MAX_PRECISION 1000 #define PG_NUMERIC_MAX_SCALE 1000 #include "misc.h" #endif unixODBC-2.3.12/Drivers/Postgre7.1/qresult.c000066400000000000000000000403011446441710500203500ustar00rootroot00000000000000 /* Module: qresult.c * * Description: This module contains functions related to * managing result information (i.e, fetching rows from the backend, * managing the tuple cache, etc.) and retrieving it. * Depending on the situation, a QResultClass will hold either data * from the backend or a manually built result (see "qresult.h" to * see which functions/macros are for manual or backend results. * For manually built results, the QResultClass simply points to * TupleList and ColumnInfo structures, which actually hold the data. * * Classes: QResultClass (Functions prefix: "QR_") * * API functions: none * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "qresult.h" #include "misc.h" #include #include #ifndef TRUE #define TRUE (BOOL)1 #endif #ifndef FALSE #define FALSE (BOOL)0 #endif extern GLOBAL_VALUES globals; /* Used for building a Manual Result only */ /* All info functions call this function to create the manual result set. */ void QR_set_num_fields(QResultClass *self, int new_num_fields) { mylog("in QR_set_num_fields\n"); CI_set_num_fields(self->fields, new_num_fields); if(self->manual_tuples) TL_Destructor(self->manual_tuples); self->manual_tuples = TL_Constructor(new_num_fields); mylog("exit QR_set_num_fields\n"); } void QR_set_position(QResultClass *self, int pos) { self->tupleField = self->backend_tuples + ((self->base + pos) * self->num_fields); } void QR_set_cache_size(QResultClass *self, int cache_size) { self->cache_size = cache_size; } void QR_set_rowset_size(QResultClass *self, int rowset_size) { self->rowset_size = rowset_size; } void QR_inc_base(QResultClass *self, int base_inc) { self->base += base_inc; } /************************************/ /* CLASS QResult */ /************************************/ QResultClass * QR_Constructor(void) { QResultClass *rv; mylog("in QR_Constructor\n"); rv = (QResultClass *) malloc(sizeof(QResultClass)); if (rv != NULL) { rv->status = PGRES_EMPTY_QUERY; /* construct the column info */ if ( ! (rv->fields = CI_Constructor())) { free(rv); return NULL; } rv->manual_tuples = NULL; rv->backend_tuples = NULL; rv->message = NULL; rv->command = NULL; rv->notice = NULL; rv->conn = NULL; rv->inTuples = FALSE; rv->fcount = 0; rv->fetch_count = 0; rv->base = 0; rv->currTuple = -1; rv->num_fields = 0; rv->tupleField = NULL; rv->cursor = NULL; rv->aborted = FALSE; rv->cache_size = globals.fetch_max; rv->rowset_size = 1; } mylog("exit QR_Constructor\n"); return rv; } void QR_Destructor(QResultClass *self) { mylog("QResult: in DESTRUCTOR\n"); /* manual result set tuples */ if (self->manual_tuples) TL_Destructor(self->manual_tuples); /* If conn is defined, then we may have used "backend_tuples", */ /* so in case we need to, free it up. Also, close the cursor. */ if (self->conn && self->conn->sock && CC_is_in_trans(self->conn)) QR_close(self); /* close the cursor if there is one */ QR_free_memory(self); /* safe to call anyway */ /* Should have been freed in the close() but just in case... */ if (self->cursor) free(self->cursor); /* Free up column info */ if (self->fields) CI_Destructor(self->fields); /* Free command info (this is from strdup()) */ if (self->command) free(self->command); /* Free notice info (this is from strdup()) */ if (self->notice) free(self->notice); free(self); mylog("QResult: exit DESTRUCTOR\n"); } void QR_set_command(QResultClass *self, char *msg) { if (self->command) free(self->command); self->command = msg ? strdup(msg) : NULL; } void QR_set_notice(QResultClass *self, char *msg) { if (self->notice) free(self->notice); self->notice = msg ? strdup(msg) : NULL; } void QR_free_memory(QResultClass *self) { register int lf, row; register TupleField *tuple = self->backend_tuples; int fcount = self->fcount; int num_fields = self->num_fields; mylog("QResult: free memory in, fcount=%d\n", fcount); if ( self->backend_tuples) { for (row = 0; row < fcount; row++) { mylog("row = %d, num_fields = %d\n", row, num_fields); for (lf=0; lf < num_fields; lf++) { if (tuple[lf].value != NULL) { mylog("free [lf=%d] %u\n", lf, tuple[lf].value); free(tuple[lf].value); } } tuple += num_fields; /* next row */ } free(self->backend_tuples); self->backend_tuples = NULL; } self->fcount = 0; mylog("QResult: free memory out\n"); } /* This function is called by send_query() */ char QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor) { int tuple_size; /* If called from send_query the first time (conn != NULL), */ /* then set the inTuples state, */ /* and read the tuples. If conn is NULL, */ /* it implies that we are being called from next_tuple(), */ /* like to get more rows so don't call next_tuple again! */ if (conn != NULL) { self->conn = conn; mylog("QR_fetch_tuples: cursor = '%s', self->cursor=%u\n", (cursor==NULL)?"":cursor, self->cursor); if (self->cursor) free(self->cursor); if ( globals.use_declarefetch) { if (! cursor || cursor[0] == '\0') { self->status = PGRES_INTERNAL_ERROR; QR_set_message(self, "Internal Error -- no cursor for fetch"); return FALSE; } self->cursor = strdup(cursor); } /* Read the field attributes. */ /* $$$$ Should do some error control HERE! $$$$ */ if ( CI_read_fields(self->fields, self->conn)) { self->status = PGRES_FIELDS_OK; self->num_fields = CI_get_num_fields(self->fields); } else { self->status = PGRES_BAD_RESPONSE; QR_set_message(self, "Error reading field information"); return FALSE; } mylog("QR_fetch_tuples: past CI_read_fields: num_fields = %d\n", self->num_fields); if (globals.use_declarefetch) tuple_size = self->cache_size; else tuple_size = TUPLE_MALLOC_INC; /* allocate memory for the tuple cache */ mylog("MALLOC: tuple_size = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size); self->backend_tuples = (TupleField *) malloc(self->num_fields * sizeof(TupleField) * tuple_size); if ( ! self->backend_tuples) { self->status = PGRES_FATAL_ERROR; QR_set_message(self, "Could not get memory for tuple cache."); return FALSE; } self->inTuples = TRUE; /* Force a read to occur in next_tuple */ self->fcount = tuple_size+1; self->fetch_count = tuple_size+1; self->base = 0; return QR_next_tuple(self); } else { /* Always have to read the field attributes. */ /* But we dont have to reallocate memory for them! */ if ( ! CI_read_fields(NULL, self->conn)) { self->status = PGRES_BAD_RESPONSE; QR_set_message(self, "Error reading field information"); return FALSE; } return TRUE; } } /* Close the cursor and end the transaction (if no cursors left) */ /* We only close cursor/end the transaction if a cursor was used. */ int QR_close(QResultClass *self) { QResultClass *res; if (globals.use_declarefetch && self->conn && self->cursor) { char buf[64]; sprintf(buf, "close %s", self->cursor); mylog("QResult: closing cursor: '%s'\n", buf); res = CC_send_query(self->conn, buf, NULL); self->inTuples = FALSE; self->currTuple = -1; free(self->cursor); self->cursor = NULL; if (res == NULL) { self->status = PGRES_FATAL_ERROR; QR_set_message(self, "Error closing cursor."); return FALSE; } /* End the transaction if there are no cursors left on this conn */ if (CC_cursor_count(self->conn) == 0) { mylog("QResult: END transaction on conn=%u\n", self->conn); res = CC_send_query(self->conn, "END", NULL); CC_set_no_trans(self->conn); if (res == NULL) { self->status = PGRES_FATAL_ERROR; QR_set_message(self, "Error ending transaction."); return FALSE; } } } return TRUE; } /* This function is called by fetch_tuples() AND SQLFetch() */ int QR_next_tuple(QResultClass *self) { int id; QResultClass *res; SocketClass *sock; /* Speed up access */ int fetch_count = self->fetch_count; int fcount = self->fcount; int fetch_size, offset= 0; int end_tuple = self->rowset_size + self->base; char corrected = FALSE; TupleField *the_tuples = self->backend_tuples; static char msgbuffer[MAX_MESSAGE_LEN+1]; char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont need static */ char fetch[128]; QueryInfo qi; if (fetch_count < fcount) { /* return a row from cache */ mylog("next_tuple: fetch_count < fcount: returning tuple %d, fcount = %d\n", fetch_count, fcount); self->tupleField = the_tuples + (fetch_count * self->num_fields); /* next row */ self->fetch_count++; return TRUE; } else if (self->fcount < self->cache_size) { /* last row from cache */ /* We are done because we didn't even get CACHE_SIZE tuples */ mylog("next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d\n", fcount, fetch_count); self->tupleField = NULL; self->status = PGRES_END_TUPLES; return -1; /* end of tuples */ } else { /* See if we need to fetch another group of rows. We may be being called from send_query(), and if so, don't send another fetch, just fall through and read the tuples. */ self->tupleField = NULL; if ( ! self->inTuples) { if ( ! globals.use_declarefetch) { mylog("next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d\n", fcount, fetch_count); self->tupleField = NULL; self->status = PGRES_END_TUPLES; return -1; /* end of tuples */ } if (self->base == fcount) { /* not a correction */ /* Determine the optimum cache size. */ if (globals.fetch_max % self->rowset_size == 0) fetch_size = globals.fetch_max; else if (self->rowset_size < globals.fetch_max) fetch_size = (globals.fetch_max / self->rowset_size) * self->rowset_size; else fetch_size = self->rowset_size; self->cache_size = fetch_size; self->fetch_count = 1; } else { /* need to correct */ corrected = TRUE; fetch_size = end_tuple - fcount; self->cache_size += fetch_size; offset = self->fetch_count; self->fetch_count++; } self->backend_tuples = (TupleField *) realloc(self->backend_tuples, self->num_fields * sizeof(TupleField) * self->cache_size); if ( ! self->backend_tuples) { self->status = PGRES_FATAL_ERROR; QR_set_message(self, "Out of memory while reading tuples."); return FALSE; } sprintf(fetch, "fetch %d in %s", fetch_size, self->cursor); mylog("next_tuple: sending actual fetch (%d) query '%s'\n", fetch_size, fetch); /* don't read ahead for the next tuple (self) ! */ qi.row_size = self->cache_size; qi.result_in = self; qi.cursor = NULL; res = CC_send_query(self->conn, fetch, &qi); if (res == NULL) { self->status = PGRES_FATAL_ERROR; QR_set_message(self, "Error fetching next group."); return FALSE; } self->inTuples = TRUE; } else { mylog("next_tuple: inTuples = true, falling through: fcount = %d, fetch_count = %d\n", self->fcount, self->fetch_count); /* This is a pre-fetch (fetching rows right after query but before any real SQLFetch() calls. This is done so the field attributes are available. */ self->fetch_count = 0; } } if ( ! corrected) { self->base = 0; self->fcount = 0; } sock = CC_get_socket(self->conn); self->tupleField = NULL; for ( ; ;) { id = SOCK_get_char(sock); switch (id) { case 'T': /* Tuples within tuples cannot be handled */ self->status = PGRES_BAD_RESPONSE; QR_set_message(self, "Tuples within tuples cannot be handled"); return FALSE; case 'B': /* Tuples in binary format */ case 'D': /* Tuples in ASCII format */ if ( ! globals.use_declarefetch && self->fcount > 0 && ! (self->fcount % TUPLE_MALLOC_INC)) { size_t old_size = self->fcount * self->num_fields * sizeof(TupleField); mylog("REALLOC: old_size = %d\n", old_size); self->backend_tuples = (TupleField *) realloc(self->backend_tuples, old_size + (self->num_fields * sizeof(TupleField) * TUPLE_MALLOC_INC)); if ( ! self->backend_tuples) { self->status = PGRES_FATAL_ERROR; QR_set_message(self, "Out of memory while reading tuples."); return FALSE; } } if ( ! QR_read_tuple(self, (char) (id == 0))) { self->status = PGRES_BAD_RESPONSE; QR_set_message(self, "Error reading the tuple"); return FALSE; } self->fcount++; break; /* continue reading */ case 'C': /* End of tuple list */ SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN); QR_set_command(self, cmdbuffer); mylog("end of tuple list -- setting inUse to false: this = %u\n", self); self->inTuples = FALSE; if (self->fcount > 0) { qlog(" [ fetched %d rows ]\n", self->fcount); mylog("_next_tuple: 'C' fetch_max && fcount = %d\n", self->fcount); /* set to first row */ self->tupleField = self->backend_tuples + (offset * self->num_fields); return TRUE; } else { /* We are surely done here (we read 0 tuples) */ qlog(" [ fetched 0 rows ]\n"); mylog("_next_tuple: 'C': DONE (fcount == 0)\n"); return -1; /* end of tuples */ } case 'E': /* Error */ SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); QR_set_message(self, msgbuffer); self->status = PGRES_FATAL_ERROR; if ( ! strncmp(msgbuffer, "FATAL", 5)) CC_set_no_trans(self->conn); qlog("ERROR from backend in next_tuple: '%s'\n", msgbuffer); return FALSE; case 'N': /* Notice */ SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); QR_set_message(self, msgbuffer); self->status = PGRES_NONFATAL_ERROR; qlog("NOTICE from backend in next_tuple: '%s'\n", msgbuffer); continue; default: /* this should only happen if the backend dumped core */ mylog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id); qlog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id); QR_set_message(self, "Unexpected result from backend. It probably crashed"); self->status = PGRES_FATAL_ERROR; CC_set_no_trans(self->conn); return FALSE; } } return TRUE; } char QR_read_tuple(QResultClass *self, char binary) { Int2 field_lf; TupleField *this_tuplefield; char bmp, bitmap[MAX_FIELDS]; /* Max. len of the bitmap */ Int2 bitmaplen; /* len of the bitmap in bytes */ Int2 bitmap_pos; Int2 bitcnt; Int4 len; char *buffer; int num_fields = self->num_fields; /* speed up access */ SocketClass *sock = CC_get_socket(self->conn); ColumnInfoClass *flds; /* set the current row to read the fields into */ this_tuplefield = self->backend_tuples + (self->fcount * num_fields); bitmaplen = (Int2) num_fields / BYTELEN; if ((num_fields % BYTELEN) > 0) bitmaplen++; /* At first the server sends a bitmap that indicates which database fields are null */ SOCK_get_n_char(sock, bitmap, bitmaplen); bitmap_pos = 0; bitcnt = 0; bmp = bitmap[bitmap_pos]; for(field_lf = 0; field_lf < num_fields; field_lf++) { /* Check if the current field is NULL */ if(!(bmp & 0200)) { /* YES, it is NULL ! */ this_tuplefield[field_lf].len = 0; this_tuplefield[field_lf].value = 0; } else { /* NO, the field is not null. so get at first the length of the field (four bytes) */ len = SOCK_get_int(sock, VARHDRSZ); if (!binary) len -= VARHDRSZ; buffer = (char *)malloc(len+1); SOCK_get_n_char(sock, buffer, len); buffer[len] = '\0'; mylog("qresult: len=%d, buffer='%s'\n", len, buffer); this_tuplefield[field_lf].len = len; this_tuplefield[field_lf].value = buffer; /* This can be used to set the longest length of the column for any row in the tuple cache. It would not be accurate for varchar and text fields to use this since a tuple cache is only 100 rows. Bpchar can be handled since the strlen of all rows is fixed, assuming there are not 100 nulls in a row! */ flds = self->fields; if (flds->display_size[field_lf] < len) flds->display_size[field_lf] = len; } /* Now adjust for the next bit to be scanned in the next loop. */ bitcnt++; if (BYTELEN == bitcnt) { bitmap_pos++; bmp = bitmap[bitmap_pos]; bitcnt = 0; } else bmp <<= 1; } self->currTuple++; return TRUE; } unixODBC-2.3.12/Drivers/Postgre7.1/qresult.h000066400000000000000000000114701446441710500203620ustar00rootroot00000000000000 /* File: qresult.h * * Description: See "qresult.c" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __QRESULT_H__ #define __QRESULT_H__ #include "connection.h" #include "socket.h" #include "columninfo.h" #include "tuplelist.h" #include "psqlodbc.h" #include "tuple.h" enum QueryResultCode_ { PGRES_EMPTY_QUERY = 0, PGRES_COMMAND_OK, /* a query command that doesn't return */ /* anything was executed properly by the backend */ PGRES_TUPLES_OK, /* a query command that returns tuples */ /* was executed properly by the backend, PGresult */ /* contains the resulttuples */ PGRES_COPY_OUT, PGRES_COPY_IN, PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the backend */ PGRES_NONFATAL_ERROR, PGRES_FATAL_ERROR, PGRES_FIELDS_OK, /* field information from a query was successful */ PGRES_END_TUPLES, PGRES_INTERNAL_ERROR }; typedef enum QueryResultCode_ QueryResultCode; struct QResultClass_ { ColumnInfoClass *fields; /* the Column information */ TupleListClass *manual_tuples; /* manual result tuple list */ ConnectionClass *conn; /* the connection this result is using (backend) */ /* Stuff for declare/fetch tuples */ int fetch_count; /* logical rows read so far */ int fcount; /* actual rows read in the fetch */ int currTuple; int base; int num_fields; /* number of fields in the result */ int cache_size; int rowset_size; QueryResultCode status; char *message; char *cursor; /* The name of the cursor for select statements */ char *command; char *notice; TupleField *backend_tuples; /* data from the backend (the tuple cache) */ TupleField *tupleField; /* current backend tuple being retrieved */ char inTuples; /* is a fetch of rows from the backend in progress? */ char aborted; /* was aborted?*/ }; #define QR_get_fields(self) (self->fields) /* These functions are for retrieving data from the qresult */ #define QR_get_value_manual(self, tupleno, fieldno) (TL_get_fieldval(self->manual_tuples, tupleno, fieldno)) #define QR_get_value_backend(self, fieldno) (self->tupleField[fieldno].value) #define QR_get_value_backend_row(self, tupleno, fieldno) ((self->backend_tuples + (tupleno * self->num_fields))[fieldno].value) /* These functions are used by both manual and backend results */ #define QR_NumResultCols(self) (CI_get_num_fields(self->fields)) #define QR_get_fieldname(self, fieldno_) (CI_get_fieldname(self->fields, fieldno_)) #define QR_get_fieldsize(self, fieldno_) (CI_get_fieldsize(self->fields, fieldno_)) #define QR_get_display_size(self, fieldno_) (CI_get_display_size(self->fields, fieldno_)) #define QR_get_atttypmod(self, fieldno_) (CI_get_atttypmod(self->fields, fieldno_)) #define QR_get_field_type(self, fieldno_) (CI_get_oid(self->fields, fieldno_)) /* These functions are used only for manual result sets */ #define QR_get_num_tuples(self) (self->manual_tuples ? TL_get_num_tuples(self->manual_tuples) : self->fcount) #define QR_add_tuple(self, new_tuple) (TL_add_tuple(self->manual_tuples, new_tuple)) #define QR_set_field_info(self, field_num, name, adtid, adtsize) (CI_set_field_info(self->fields, field_num, name, adtid, adtsize, -1)) /* status macros */ #define QR_command_successful(self) ( !(self->status == PGRES_BAD_RESPONSE || self->status == PGRES_NONFATAL_ERROR || self->status == PGRES_FATAL_ERROR)) #define QR_command_nonfatal(self) ( self->status == PGRES_NONFATAL_ERROR) #define QR_end_tuples(self) ( self->status == PGRES_END_TUPLES) #define QR_set_status(self, condition) ( self->status = condition ) #define QR_set_message(self, message_) ( self->message = message_) #define QR_set_aborted(self, aborted_) ( self->aborted = aborted_) #define QR_get_message(self) (self->message) #define QR_get_command(self) (self->command) #define QR_get_notice(self) (self->notice) #define QR_get_status(self) (self->status) #define QR_get_aborted(self) (self->aborted) #define QR_aborted(self) (!self || self->aborted) /* Core Functions */ QResultClass *QR_Constructor(void); void QR_Destructor(QResultClass *self); char QR_read_tuple(QResultClass *self, char binary); int QR_next_tuple(QResultClass *self); int QR_close(QResultClass *self); char QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor); void QR_free_memory(QResultClass *self); void QR_set_command(QResultClass *self, char *msg); void QR_set_notice(QResultClass *self, char *msg); void QR_set_num_fields(QResultClass *self, int new_num_fields); /* manual result only */ void QR_inc_base(QResultClass *self, int base_inc); void QR_set_cache_size(QResultClass *self, int cache_size); void QR_set_rowset_size(QResultClass *self, int rowset_size); void QR_set_position(QResultClass *self, int pos); #endif unixODBC-2.3.12/Drivers/Postgre7.1/resource.h000066400000000000000000000047131446441710500205140ustar00rootroot00000000000000/* {{NO_DEPENDENCIES}} */ /* Microsoft Developer Studio generated include file. */ /* Used by psqlodbc.rc */ #define IDS_BADDSN 1 #define IDS_MSGTITLE 2 #define DLG_OPTIONS_DRV 102 #define DLG_OPTIONS_DS 103 #define IDC_DSNAME 400 #define IDC_DSNAMETEXT 401 #define IDC_DESC 404 #define IDC_SERVER 407 #define IDC_DATABASE 408 #define DLG_CONFIG 1001 #define IDC_PORT 1002 #define IDC_USER 1006 #define IDC_PASSWORD 1009 #define DS_READONLY 1011 #define DS_SHOWOIDCOLUMN 1012 #define DS_FAKEOIDINDEX 1013 #define DRV_COMMLOG 1014 #define DS_PG62 1016 #define IDC_DATASOURCE 1018 #define DRV_OPTIMIZER 1019 #define DS_CONNSETTINGS 1020 #define IDC_DRIVER 1021 #define DRV_CONNSETTINGS 1031 #define DRV_UNIQUEINDEX 1032 #define DRV_UNKNOWN_MAX 1035 #define DRV_UNKNOWN_DONTKNOW 1036 #define DRV_READONLY 1037 #define IDC_DESCTEXT 1039 #define DRV_MSG_LABEL 1040 #define DRV_UNKNOWN_LONGEST 1041 #define DRV_TEXT_LONGVARCHAR 1043 #define DRV_UNKNOWNS_LONGVARCHAR 1044 #define DRV_CACHE_SIZE 1045 #define DRV_VARCHAR_SIZE 1046 #define DRV_LONGVARCHAR_SIZE 1047 #define IDDEFAULTS 1048 #define DRV_USEDECLAREFETCH 1049 #define DRV_BOOLS_CHAR 1050 #define DS_SHOWSYSTEMTABLES 1051 #define DRV_EXTRASYSTABLEPREFIXES 1051 #define DS_ROWVERSIONING 1052 #define DRV_PARSE 1052 #define DRV_CANCELASFREESTMT 1053 #define IDC_OPTIONS 1054 #define DRV_KSQO 1055 #define DS_PG64 1057 #define DS_PG63 1058 /* Next default values for new objects */ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 104 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1060 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif unixODBC-2.3.12/Drivers/Postgre7.1/results.c000066400000000000000000000765131446441710500203700ustar00rootroot00000000000000 /* Module: results.c * * Description: This module contains functions related to * retrieving result information through the ODBC API. * * Classes: n/a * * API functions: SQLRowCount, SQLNumResultCols, SQLDescribeCol, SQLColAttributes, * SQLGetData, SQLFetch, SQLExtendedFetch, * SQLMoreResults(NI), SQLSetPos, SQLSetScrollOptions(NI), * SQLSetCursorName, SQLGetCursorName * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "psqlodbc.h" #include "dlg_specific.h" #include "environ.h" #include "connection.h" #include "statement.h" #include "bind.h" #include "qresult.h" #include "convert.h" #include "pgtypes.h" #include "misc.h" #include #ifndef WIN32 #include "isqlext.h" #else #include #include #endif extern GLOBAL_VALUES globals; SQLRETURN SQLRowCount(SQLHSTMT hstmt, SQLLEN *pcrow) { static char* const func="SQLRowCount"; StatementClass *stmt = (StatementClass *) hstmt; QResultClass *res; char *msg, *ptr; if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } if (stmt->manual_result) { if (pcrow) *pcrow = -1; return SQL_SUCCESS; } if(stmt->statement_type == STMT_TYPE_SELECT) { if (stmt->status == STMT_FINISHED) { res = SC_get_Result(stmt); if(res && pcrow) { *pcrow = globals.use_declarefetch ? -1 : QR_get_num_tuples(res); return SQL_SUCCESS; } } } else { res = SC_get_Result(stmt); if (res && pcrow) { msg = QR_get_command(res); mylog("*** msg = '%s'\n", msg); trim(msg); /* get rid of trailing spaces */ ptr = strrchr(msg, ' '); if (ptr) { *pcrow = atoi(ptr+1); mylog("**** SQLRowCount(): THE ROWS: *pcrow = %d\n", *pcrow); } else { *pcrow = -1; mylog("**** SQLRowCount(): NO ROWS: *pcrow = %d\n", *pcrow); } return SQL_SUCCESS; } } SC_log_error(func, "Bad return value", stmt); return SQL_ERROR; } /* This returns the number of columns associated with the database */ /* attached to "hstmt". */ RETCODE SQL_API SQLNumResultCols( HSTMT hstmt, SWORD FAR *pccol) { static char* const func="SQLNumResultCols"; StatementClass *stmt = (StatementClass *) hstmt; QResultClass *result; char parse_ok; if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } SC_clear_error(stmt); parse_ok = FALSE; if (globals.parse && stmt->statement_type == STMT_TYPE_SELECT) { if (stmt->parse_status == STMT_PARSE_NONE) { mylog("SQLNumResultCols: calling parse_statement on stmt=%u\n", stmt); parse_statement(stmt); } if (stmt->parse_status != STMT_PARSE_FATAL) { parse_ok = TRUE; *pccol = stmt->nfld; mylog("PARSE: SQLNumResultCols: *pccol = %d\n", *pccol); } } if ( ! parse_ok) { SC_pre_execute(stmt); result = SC_get_Result(stmt); mylog("SQLNumResultCols: result = %u, status = %d, numcols = %d\n", result, stmt->status, result != NULL ? QR_NumResultCols(result) : -1); if (( ! result) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE)) ) { /* no query has been executed on this statement */ SC_set_error(stmt, STMT_SEQUENCE_ERROR, "No query has been executed with that handle"); SC_log_error(func, "", stmt); return SQL_ERROR; } *pccol = QR_NumResultCols(result); } return SQL_SUCCESS; } /* - - - - - - - - - */ /* Return information about the database column the user wants */ /* information about. */ RETCODE SQL_API SQLDescribeCol( HSTMT hstmt, UWORD icol, UCHAR FAR *szColName, SWORD cbColNameMax, SWORD FAR *pcbColName, SWORD FAR *pfSqlType, SQLULEN FAR *pcbColDef, SWORD FAR *pibScale, SWORD FAR *pfNullable) { static char* const func="SQLDescribeCol"; /* gets all the information about a specific column */ StatementClass *stmt = (StatementClass *) hstmt; QResultClass *res; char *col_name = NULL; Int4 fieldtype = 0; int precision = 0; ConnInfo *ci; char parse_ok; char buf[255]; int len = 0; RETCODE result; mylog("%s: entering...\n", func); if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } ci = &(stmt->hdbc->connInfo); SC_clear_error(stmt); /* Dont check for bookmark column. This is the responsibility of the driver manager. */ icol--; /* use zero based column numbers */ parse_ok = FALSE; if (globals.parse && stmt->statement_type == STMT_TYPE_SELECT) { if (stmt->parse_status == STMT_PARSE_NONE) { mylog("SQLDescribeCol: calling parse_statement on stmt=%u\n", stmt); parse_statement(stmt); } mylog("PARSE: DescribeCol: icol=%d, stmt=%u, stmt->nfld=%d, stmt->fi=%u\n", icol, stmt, stmt->nfld, stmt->fi); if (stmt->parse_status != STMT_PARSE_FATAL && stmt->fi && stmt->fi[icol]) { if (icol >= stmt->nfld) { SC_set_error(stmt, STMT_INVALID_COLUMN_NUMBER_ERROR, "Invalid column number in DescribeCol."); SC_log_error(func, "", stmt); return SQL_ERROR; } mylog("DescribeCol: getting info for icol=%d\n", icol); fieldtype = stmt->fi[icol]->type; col_name = stmt->fi[icol]->name; precision = stmt->fi[icol]->precision; mylog("PARSE: fieldtype=%d, col_name='%s', precision=%d\n", fieldtype, col_name, precision); if (fieldtype > 0) parse_ok = TRUE; } } /* If couldn't parse it OR the field being described was not parsed (i.e., because it was a function or expression, etc, then do it the old fashioned way. */ if ( ! parse_ok) { SC_pre_execute(stmt); res = SC_get_Result(stmt); mylog("**** SQLDescribeCol: res = %u, stmt->status = %d, !finished=%d, !premature=%d\n", res, stmt->status, stmt->status != STMT_FINISHED, stmt->status != STMT_PREMATURE); if ( (NULL == res) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE))) { /* no query has been executed on this statement */ SC_set_error(stmt, STMT_SEQUENCE_ERROR, "No query has been assigned to this statement."); SC_log_error(func, "", stmt); return SQL_ERROR; } if (icol >= QR_NumResultCols(res)) { SC_set_error(stmt, STMT_INVALID_COLUMN_NUMBER_ERROR, "Invalid column number in DescribeCol."); sprintf(buf, "Col#=%d, #Cols=%d", icol, QR_NumResultCols(res)); SC_log_error(func, buf, stmt); return SQL_ERROR; } col_name = QR_get_fieldname(res, icol); fieldtype = QR_get_field_type(res, icol); precision = pgtype_precision(stmt, fieldtype, icol, globals.unknown_sizes); /* atoi(ci->unknown_sizes) */ } mylog("describeCol: col %d fieldname = '%s'\n", icol, col_name); mylog("describeCol: col %d fieldtype = %d\n", icol, fieldtype); mylog("describeCol: col %d precision = %d\n", icol, precision); result = SQL_SUCCESS; /************************/ /* COLUMN NAME */ /************************/ len = strlen(col_name); if (pcbColName) *pcbColName = len; if (szColName) { strncpy_null((char*)szColName, col_name, cbColNameMax); if (len >= cbColNameMax) { result = SQL_SUCCESS_WITH_INFO; SC_set_error(stmt, STMT_TRUNCATED, "The buffer was too small for the result."); } } /************************/ /* SQL TYPE */ /************************/ if (pfSqlType) { *pfSqlType = pgtype_to_sqltype(stmt, fieldtype); mylog("describeCol: col %d *pfSqlType = %d\n", icol, *pfSqlType); } /************************/ /* PRECISION */ /************************/ if (pcbColDef) { if ( precision < 0) precision = 0; /* "I dont know" */ *pcbColDef = precision; mylog("describeCol: col %d *pcbColDef = %d\n", icol, *pcbColDef); } /************************/ /* SCALE */ /************************/ if (pibScale) { Int2 scale; scale = pgtype_scale(stmt, fieldtype, icol); if(scale == -1) { scale = 0; } *pibScale = scale; mylog("describeCol: col %d *pibScale = %d\n", icol, *pibScale); } /************************/ /* NULLABILITY */ /************************/ if (pfNullable) { *pfNullable = (parse_ok) ? stmt->fi[icol]->nullable : pgtype_nullable(stmt, fieldtype); mylog("describeCol: col %d *pfNullable = %d\n", icol, *pfNullable); } return result; } /* Returns result column descriptor information for a result set. */ SQLRETURN SQLColAttributes( SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLPOINTER rgbDesc, SQLSMALLINT cbDescMax, SQLSMALLINT *pcbDesc, SQLLEN *pfDesc) { static char* const func = "SQLColAttributes"; StatementClass *stmt = (StatementClass *) hstmt; Int4 field_type = 0; ConnInfo *ci; int unknown_sizes; int cols = 0; char parse_ok; RETCODE result; char *p = NULL; int len = 0, value = 0; mylog("%s: entering...\n", func); if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } ci = &(stmt->hdbc->connInfo); /* Dont check for bookmark column. This is the responsibility of the driver manager. For certain types of arguments, the column number is ignored anyway, so it may be 0. */ icol--; unknown_sizes = globals.unknown_sizes; /* atoi(ci->unknown_sizes); */ if (unknown_sizes == UNKNOWNS_AS_DONTKNOW) /* not appropriate for SQLColAttributes() */ unknown_sizes = UNKNOWNS_AS_MAX; parse_ok = FALSE; if (globals.parse && stmt->statement_type == STMT_TYPE_SELECT) { if (stmt->parse_status == STMT_PARSE_NONE) { mylog("SQLColAttributes: calling parse_statement\n"); parse_statement(stmt); } cols = stmt->nfld; /* Column Count is a special case. The Column number is ignored in this case. */ if (fDescType == SQL_COLUMN_COUNT) { if (pfDesc) *pfDesc = cols; return SQL_SUCCESS; } if (stmt->parse_status != STMT_PARSE_FATAL && stmt->fi && stmt->fi[icol]) { if (icol >= cols) { SC_set_error(stmt, STMT_INVALID_COLUMN_NUMBER_ERROR, "Invalid column number in DescribeCol."); SC_log_error(func, "", stmt); return SQL_ERROR; } field_type = stmt->fi[icol]->type; if (field_type > 0) parse_ok = TRUE; } } if ( ! parse_ok) { SC_pre_execute(stmt); mylog("**** SQLColAtt: result = %u, status = %d, numcols = %d\n", stmt->result, stmt->status, stmt->result != NULL ? QR_NumResultCols(stmt->result) : -1); if ( (NULL == stmt->result) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE)) ) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Can't get column attributes: no result found."); SC_log_error(func, "", stmt); return SQL_ERROR; } cols = QR_NumResultCols(stmt->result); /* Column Count is a special case. The Column number is ignored in this case. */ if (fDescType == SQL_COLUMN_COUNT) { if (pfDesc) *pfDesc = cols; return SQL_SUCCESS; } if (icol >= cols) { SC_set_error(stmt, STMT_INVALID_COLUMN_NUMBER_ERROR, "Invalid column number in DescribeCol."); SC_log_error(func, "", stmt); return SQL_ERROR; } field_type = QR_get_field_type(stmt->result, icol); } mylog("colAttr: col %d field_type = %d\n", icol, field_type); switch(fDescType) { case SQL_COLUMN_AUTO_INCREMENT: value = pgtype_auto_increment(stmt, field_type); if (value == -1) /* non-numeric becomes FALSE (ODBC Doc) */ value = FALSE; break; case SQL_COLUMN_CASE_SENSITIVE: value = pgtype_case_sensitive(stmt, field_type); break; /* This special case is handled above. case SQL_COLUMN_COUNT: */ case SQL_COLUMN_DISPLAY_SIZE: value = (parse_ok) ? stmt->fi[icol]->display_size : pgtype_display_size(stmt, field_type, icol, unknown_sizes); mylog("SQLColAttributes: col %d, display_size= %d\n", icol, value); break; case SQL_COLUMN_LABEL: if (parse_ok && stmt->fi[icol]->alias[0] != '\0') { p = stmt->fi[icol]->alias; mylog("SQLColAttr: COLUMN_LABEL = '%s'\n", p); break; } /* otherwise same as column name -- FALL THROUGH!!! */ case SQL_COLUMN_NAME: p = (parse_ok) ? stmt->fi[icol]->name : QR_get_fieldname(stmt->result, icol); mylog("SQLColAttr: COLUMN_NAME = '%s'\n", p); break; case SQL_COLUMN_LENGTH: value = (parse_ok) ? stmt->fi[icol]->length : pgtype_length(stmt, field_type, icol, unknown_sizes); mylog("SQLColAttributes: col %d, length = %d\n", icol, value); break; case SQL_COLUMN_MONEY: value = pgtype_money(stmt, field_type); break; case SQL_COLUMN_NULLABLE: value = (parse_ok) ? stmt->fi[icol]->nullable : pgtype_nullable(stmt, field_type); break; case SQL_COLUMN_OWNER_NAME: p = ""; break; case SQL_COLUMN_PRECISION: value = (parse_ok) ? stmt->fi[icol]->precision : pgtype_precision(stmt, field_type, icol, unknown_sizes); mylog("SQLColAttributes: col %d, precision = %d\n", icol, value); break; case SQL_COLUMN_QUALIFIER_NAME: p = ""; break; case SQL_COLUMN_SCALE: value = pgtype_scale(stmt, field_type, icol); break; case SQL_COLUMN_SEARCHABLE: value = pgtype_searchable(stmt, field_type); break; case SQL_COLUMN_TABLE_NAME: p = (parse_ok && stmt->fi[icol]->ti) ? stmt->fi[icol]->ti->name : ""; mylog("SQLColAttr: TABLE_NAME = '%s'\n", p); break; case SQL_COLUMN_TYPE: value = pgtype_to_sqltype(stmt, field_type); break; case SQL_COLUMN_TYPE_NAME: p = pgtype_to_name(stmt, field_type); break; case SQL_COLUMN_UNSIGNED: value = pgtype_unsigned(stmt, field_type); if(value == -1) /* non-numeric becomes TRUE (ODBC Doc) */ value = TRUE; break; case SQL_COLUMN_UPDATABLE: /* Neither Access or Borland care about this. if (field_type == PG_TYPE_OID) *pfDesc = SQL_ATTR_READONLY; else */ value = SQL_ATTR_WRITE; mylog("SQLColAttr: UPDATEABLE = %d\n", value); break; } result = SQL_SUCCESS; if (p) { /* char/binary data */ len = strlen(p); if (rgbDesc) { strncpy_null((char *)rgbDesc, p, (size_t)cbDescMax); if (len >= cbDescMax) { result = SQL_SUCCESS_WITH_INFO; SC_set_error(stmt, STMT_TRUNCATED, "The buffer was too small for the result."); } } if (pcbDesc) *pcbDesc = len; } else { /* numeric data */ if (pfDesc) *pfDesc = value; } return result; } /* Returns result data for a single column in the current row. */ RETCODE SQL_API PG_SQLGetData( HSTMT hstmt, UWORD icol, SWORD fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD FAR *pcbValue) { static char* const func="SQLGetData"; QResultClass *res; StatementClass *stmt = (StatementClass *) hstmt; int num_cols, num_rows; Int4 field_type; void *value = NULL; int result; char get_bookmark = FALSE; mylog("SQLGetData: enter, stmt=%u\n", stmt); if( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } res = stmt->result; if (STMT_EXECUTING == stmt->status) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Can't get data while statement is still executing."); SC_log_error(func, "", stmt); return SQL_ERROR; } if (stmt->status != STMT_FINISHED) { SC_set_error(stmt, STMT_STATUS_ERROR, "GetData can only be called after the successful execution on a SQL statement"); SC_log_error(func, "", stmt); return SQL_ERROR; } if (icol == 0) { if (stmt->options.use_bookmarks == SQL_UB_OFF) { SC_set_error(stmt, STMT_COLNUM_ERROR, "Attempt to retrieve bookmark with bookmark usage disabled"); SC_log_error(func, "", stmt); return SQL_ERROR; } /* Make sure it is the bookmark data type */ if (fCType != SQL_C_BOOKMARK && fCType != SQL_C_BINARY ) { SC_set_error(stmt, STMT_PROGRAM_TYPE_OUT_OF_RANGE, "Column 0 is not of type SQL_C_BOOKMARK"); SC_log_error(func, "", stmt); return SQL_ERROR; } get_bookmark = TRUE; } else { /* use zero-based column numbers */ icol--; /* make sure the column number is valid */ num_cols = QR_NumResultCols(res); if (icol >= num_cols) { SC_set_error(stmt, STMT_INVALID_COLUMN_NUMBER_ERROR, "Invalid column number."); SC_log_error(func, "", stmt); return SQL_ERROR; } } if ( stmt->manual_result || ! globals.use_declarefetch) { /* make sure we're positioned on a valid row */ num_rows = QR_get_num_tuples(res); if((stmt->currTuple < 0) || (stmt->currTuple >= num_rows)) { SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row for GetData."); SC_log_error(func, "", stmt); return SQL_ERROR; } mylog(" num_rows = %d\n", num_rows); if ( ! get_bookmark) { if ( stmt->manual_result) { value = QR_get_value_manual(res, stmt->currTuple, icol); } else { value = QR_get_value_backend_row(res, stmt->currTuple, icol); } mylog(" value = '%s'\n", value); } } else { /* it's a SOCKET result (backend data) */ if (stmt->currTuple == -1 || ! res || ! res->tupleField) { SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row for GetData."); SC_log_error(func, "", stmt); return SQL_ERROR; } if ( ! get_bookmark) value = QR_get_value_backend(res, icol); mylog(" socket: value = '%s'\n", value); } if ( get_bookmark) { *((UDWORD *) rgbValue) = SC_get_bookmark(stmt); if (pcbValue) *pcbValue = 4; return SQL_SUCCESS; } field_type = QR_get_field_type(res, icol); mylog("**** SQLGetData: icol = %d, fCType = %d, field_type = %d, value = '%s'\n", icol, fCType, field_type, value); stmt->current_col = icol; result = copy_and_convert_field(stmt, field_type, value, fCType, rgbValue, cbValueMax, (SQLLEN*)pcbValue); stmt->current_col = -1; switch(result) { case COPY_OK: return SQL_SUCCESS; case COPY_UNSUPPORTED_TYPE: SC_set_error(stmt, STMT_RESTRICTED_DATA_TYPE_ERROR, "Received an unsupported type from Postgres."); SC_log_error(func, "", stmt); return SQL_ERROR; case COPY_UNSUPPORTED_CONVERSION: SC_set_error(stmt, STMT_RESTRICTED_DATA_TYPE_ERROR, "Couldn't handle the necessary data type conversion."); SC_log_error(func, "", stmt); return SQL_ERROR; case COPY_RESULT_TRUNCATED: SC_set_error(stmt, STMT_TRUNCATED, "The buffer was too small for the result."); return SQL_SUCCESS_WITH_INFO; case COPY_GENERAL_ERROR: /* error msg already filled in */ SC_log_error(func, "", stmt); return SQL_ERROR; case COPY_NO_DATA_FOUND: /* SC_log_error(func, "no data found", stmt); */ return SQL_NO_DATA_FOUND; default: SC_set_error(stmt, STMT_INTERNAL_ERROR, "Unrecognized return value from copy_and_convert_field."); SC_log_error(func, "", stmt); return SQL_ERROR; } } SQLRETURN SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgbValue, SQLLEN cbValueMax, SQLLEN *pcbValue) { return PG_SQLGetData( hstmt, icol, fCType, rgbValue, cbValueMax, (SDWORD FAR *)pcbValue ); } /* Returns data for bound columns in the current row ("hstmt->iCursor"), */ /* advances the cursor. */ RETCODE SQL_API PG_SQLFetch( HSTMT hstmt) { static char* const func = "SQLFetch"; StatementClass *stmt = (StatementClass *) hstmt; QResultClass *res; mylog("SQLFetch: stmt = %u, stmt->result= %u\n", stmt, stmt->result); if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } SC_clear_error(stmt); if ( ! (res = stmt->result)) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Null statement result in SQLFetch."); SC_log_error(func, "", stmt); return SQL_ERROR; } /* Not allowed to bind a bookmark column when using SQLFetch. */ if ( stmt->bookmark.buffer) { SC_set_error(stmt, STMT_COLNUM_ERROR, "Not allowed to bind a bookmark column when using SQLFetch"); SC_log_error(func, "", stmt); return SQL_ERROR; } if (stmt->status == STMT_EXECUTING) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Can't fetch while statement is still executing."); SC_log_error(func, "", stmt); return SQL_ERROR; } if (stmt->status != STMT_FINISHED) { SC_set_error(stmt, STMT_STATUS_ERROR, "Fetch can only be called after the successful execution on a SQL statement"); SC_log_error(func, "", stmt); return SQL_ERROR; } if (stmt->bindings == NULL) { /* just to avoid a crash if the user insists on calling this */ /* function even if SQL_ExecDirect has reported an Error */ SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Bindings were not allocated properly."); SC_log_error(func, "", stmt); return SQL_ERROR; } QR_set_rowset_size(res, 1); QR_inc_base(res, stmt->last_fetch_count); return SC_fetch(stmt); } RETCODE SQL_API SQLFetch( HSTMT hstmt) { return PG_SQLFetch( hstmt ); } /* This fetchs a block of data (rowset). */ SQLRETURN SQLExtendedFetch( SQLHSTMT hstmt, SQLUSMALLINT fFetchType, SQLLEN irow, SQLULEN *pcrow, SQLUSMALLINT *rgfRowStatus) { static char* const func = "SQLExtendedFetch"; StatementClass *stmt = (StatementClass *) hstmt; QResultClass *res; int num_tuples, i, save_rowset_size; RETCODE result; char truncated, error; mylog("SQLExtendedFetch: stmt=%u\n", stmt); if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } if ( globals.use_declarefetch && ! stmt->manual_result) { if ( fFetchType != SQL_FETCH_NEXT) { SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Unsupported fetch type for SQLExtendedFetch with UseDeclareFetch option."); return SQL_ERROR; } } SC_clear_error(stmt); if ( ! (res = stmt->result)) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Null statement result in SQLExtendedFetch."); SC_log_error(func, "", stmt); return SQL_ERROR; } /* If a bookmark colunmn is bound but bookmark usage is off, then error */ if (stmt->bookmark.buffer && stmt->options.use_bookmarks == SQL_UB_OFF) { SC_set_error(stmt, STMT_COLNUM_ERROR, "Attempt to retrieve bookmark with bookmark usage disabled"); SC_log_error(func, "", stmt); return SQL_ERROR; } if (stmt->status == STMT_EXECUTING) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Can't fetch while statement is still executing."); SC_log_error(func, "", stmt); return SQL_ERROR; } if (stmt->status != STMT_FINISHED) { SC_set_error(stmt, STMT_STATUS_ERROR, "ExtendedFetch can only be called after the successful execution on a SQL statement"); SC_log_error(func, "", stmt); return SQL_ERROR; } if (stmt->bindings == NULL) { /* just to avoid a crash if the user insists on calling this */ /* function even if SQL_ExecDirect has reported an Error */ SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Bindings were not allocated properly."); SC_log_error(func, "", stmt); return SQL_ERROR; } /* Initialize to no rows fetched */ if (rgfRowStatus) for (i = 0; i < stmt->options.rowset_size; i++) *(rgfRowStatus + i) = SQL_ROW_NOROW; if (pcrow) *pcrow = 0; num_tuples = QR_get_num_tuples(res); /* Save and discard the saved rowset size */ save_rowset_size = stmt->save_rowset_size; stmt->save_rowset_size = -1; switch (fFetchType) { case SQL_FETCH_NEXT: /* From the odbc spec... If positioned before the start of the RESULT SET, then this should be equivalent to SQL_FETCH_FIRST. */ if (stmt->rowset_start < 0) stmt->rowset_start = 0; else { stmt->rowset_start += (save_rowset_size > 0 ? save_rowset_size : stmt->options.rowset_size); } mylog("SQL_FETCH_NEXT: num_tuples=%d, currtuple=%d\n", num_tuples, stmt->currTuple); break; case SQL_FETCH_PRIOR: mylog("SQL_FETCH_PRIOR: num_tuples=%d, currtuple=%d\n", num_tuples, stmt->currTuple); /* From the odbc spec... If positioned after the end of the RESULT SET, then this should be equivalent to SQL_FETCH_LAST. */ if (stmt->rowset_start >= num_tuples) { stmt->rowset_start = num_tuples <= 0 ? 0 : (num_tuples - stmt->options.rowset_size); } else { stmt->rowset_start -= stmt->options.rowset_size; } break; case SQL_FETCH_FIRST: mylog("SQL_FETCH_FIRST: num_tuples=%d, currtuple=%d\n", num_tuples, stmt->currTuple); stmt->rowset_start = 0; break; case SQL_FETCH_LAST: mylog("SQL_FETCH_LAST: num_tuples=%d, currtuple=%d\n", num_tuples, stmt->currTuple); stmt->rowset_start = num_tuples <= 0 ? 0 : (num_tuples - stmt->options.rowset_size) ; break; case SQL_FETCH_ABSOLUTE: mylog("SQL_FETCH_ABSOLUTE: num_tuples=%d, currtuple=%d, irow=%d\n", num_tuples, stmt->currTuple, irow); /* Position before result set, but dont fetch anything */ if (irow == 0) { stmt->rowset_start = -1; stmt->currTuple = -1; return SQL_NO_DATA_FOUND; } /* Position before the desired row */ else if (irow > 0) { stmt->rowset_start = irow - 1; } /* Position with respect to the end of the result set */ else { stmt->rowset_start = num_tuples + irow; } break; case SQL_FETCH_RELATIVE: /* Refresh the current rowset -- not currently implemented, but lie anyway */ if (irow == 0) { break; } stmt->rowset_start += irow; break; case SQL_FETCH_BOOKMARK: stmt->rowset_start = irow - 1; break; default: SC_log_error(func, "Unsupported SQLExtendedFetch Direction", stmt); return SQL_ERROR; } /***********************************/ /* CHECK FOR PROPER CURSOR STATE */ /***********************************/ /* Handle Declare Fetch style specially because the end is not really the end... */ if ( globals.use_declarefetch && ! stmt->manual_result) { if (QR_end_tuples(res)) { return SQL_NO_DATA_FOUND; } } else { /* If *new* rowset is after the result_set, return no data found */ if (stmt->rowset_start >= num_tuples) { stmt->rowset_start = num_tuples; return SQL_NO_DATA_FOUND; } } /* If *new* rowset is prior to result_set, return no data found */ if (stmt->rowset_start < 0) { if (stmt->rowset_start + stmt->options.rowset_size <= 0) { stmt->rowset_start = -1; return SQL_NO_DATA_FOUND; } else { /* overlap with beginning of result set, so get first rowset */ stmt->rowset_start = 0; } } /* currTuple is always 1 row prior to the rowset */ stmt->currTuple = stmt->rowset_start - 1; /* increment the base row in the tuple cache */ QR_set_rowset_size(res, stmt->options.rowset_size); QR_inc_base(res, stmt->last_fetch_count); /* Physical Row advancement occurs for each row fetched below */ mylog("SQLExtendedFetch: new currTuple = %d\n", stmt->currTuple); truncated = error = FALSE; for (i = 0; i < stmt->options.rowset_size; i++) { stmt->bind_row = i; /* set the binding location */ result = SC_fetch(stmt); /* Determine Function status */ if (result == SQL_NO_DATA_FOUND) break; else if (result == SQL_SUCCESS_WITH_INFO) truncated = TRUE; else if (result == SQL_ERROR) error = TRUE; /* Determine Row Status */ if (rgfRowStatus) { if (result == SQL_ERROR) *(rgfRowStatus + i) = SQL_ROW_ERROR; else *(rgfRowStatus + i)= SQL_ROW_SUCCESS; } } /* Save the fetch count for SQLSetPos */ stmt->last_fetch_count= i; /* Reset next binding row */ stmt->bind_row = 0; /* Move the cursor position to the first row in the result set. */ stmt->currTuple = stmt->rowset_start; /* For declare/fetch, need to reset cursor to beginning of rowset */ if (globals.use_declarefetch && ! stmt->manual_result) { QR_set_position(res, 0); } /* Set the number of rows retrieved */ if (pcrow) *pcrow = i; if (i == 0) return SQL_NO_DATA_FOUND; /* Only DeclareFetch should wind up here */ else if (error) return SQL_ERROR; else if (truncated) return SQL_SUCCESS_WITH_INFO; else return SQL_SUCCESS; } /* This determines whether there are more results sets available for */ /* the "hstmt". */ /* CC: return SQL_NO_DATA_FOUND since we do not support multiple result sets */ RETCODE SQL_API SQLMoreResults( HSTMT hstmt) { return SQL_NO_DATA_FOUND; } /* This positions the cursor within a rowset, that was positioned using SQLExtendedFetch. */ /* This will be useful (so far) only when using SQLGetData after SQLExtendedFetch. */ RETCODE SQL_API SQLSetPos( HSTMT hstmt, SQLSETPOSIROW irow, UWORD fOption, UWORD fLock) { static char* const func = "SQLSetPos"; StatementClass *stmt = (StatementClass *) hstmt; QResultClass *res; int num_cols, i; BindInfoClass *bindings = stmt->bindings; if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } if (fOption != SQL_POSITION && fOption != SQL_REFRESH) { SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Only SQL_POSITION/REFRESH is supported for SQLSetPos"); SC_log_error(func, "", stmt); return SQL_ERROR; } if ( ! (res = stmt->result)) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Null statement result in SQLSetPos."); SC_log_error(func, "", stmt); return SQL_ERROR; } num_cols = QR_NumResultCols(res); if (irow == 0) { SC_set_error(stmt, STMT_ROW_OUT_OF_RANGE, "Driver does not support Bulk operations."); SC_log_error(func, "", stmt); return SQL_ERROR; } if (irow > stmt->last_fetch_count) { SC_set_error(stmt, STMT_ROW_OUT_OF_RANGE, "Row value out of range"); SC_log_error(func, "", stmt); return SQL_ERROR; } irow--; /* Reset for SQLGetData */ for (i = 0; i < num_cols; i++) bindings[i].data_left = -1; QR_set_position(res, irow); stmt->currTuple = stmt->rowset_start + irow; return SQL_SUCCESS; } /* Sets options that control the behavior of cursors. */ SQLRETURN SQLSetScrollOptions( /* Use SQLSetStmtOptions */ SQLHSTMT hstmt, SQLUSMALLINT fConcurrency, SQLLEN crowKeyset, SQLUSMALLINT crowRowset) { static char* const func = "SQLSetScrollOptions"; SC_log_error(func, "Function not implemented", (StatementClass *) hstmt); return SQL_ERROR; } /* Set the cursor name on a statement handle */ RETCODE SQL_API SQLSetCursorName( HSTMT hstmt, UCHAR FAR *szCursor, SWORD cbCursor) { static char* const func="SQLSetCursorName"; StatementClass *stmt = (StatementClass *) hstmt; int len; mylog("SQLSetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d\n", hstmt, szCursor, cbCursor); if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } len = (cbCursor == SQL_NTS) ? strlen((char*)szCursor) : cbCursor; if (len <= 0 || len > sizeof(stmt->cursor_name) - 1) { SC_set_error(stmt, STMT_INVALID_CURSOR_NAME, "Invalid Cursor Name"); SC_log_error(func, "", stmt); return SQL_ERROR; } strncpy_null((char*)stmt->cursor_name, (char*)szCursor, len+1); return SQL_SUCCESS; } /* Return the cursor name for a statement handle */ RETCODE SQL_API SQLGetCursorName( HSTMT hstmt, UCHAR FAR *szCursor, SWORD cbCursorMax, SWORD FAR *pcbCursor) { static char* const func="SQLGetCursorName"; StatementClass *stmt = (StatementClass *) hstmt; int len = 0; RETCODE result; mylog("SQLGetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d, pcbCursor=%u\n", hstmt, szCursor, cbCursorMax, pcbCursor); if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } if ( stmt->cursor_name[0] == '\0') { SC_set_error(stmt, STMT_NO_CURSOR_NAME, "No Cursor name available"); SC_log_error(func, "", stmt); return SQL_ERROR; } result = SQL_SUCCESS; len = strlen(stmt->cursor_name); if (szCursor) { strncpy_null((char*)szCursor, (char*)stmt->cursor_name, cbCursorMax); if (len >= cbCursorMax) { result = SQL_SUCCESS_WITH_INFO; SC_set_error(stmt, STMT_TRUNCATED, "The buffer was too small for the result."); } } if (pcbCursor) *pcbCursor = len; return result; } unixODBC-2.3.12/Drivers/Postgre7.1/socket.c000066400000000000000000000207341446441710500201510ustar00rootroot00000000000000 /* Module: socket.c * * Description: This module contains functions for low level socket * operations (connecting/reading/writing to the backend) * * Classes: SocketClass (Functions prefix: "SOCK_") * * API functions: none * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "socket.h" #ifndef WIN32 #ifndef VMS #include "sys/un.h" #endif #include #include /* for memset */ #endif extern GLOBAL_VALUES globals; #ifndef BOOL #define BOOL int #endif #ifndef TRUE #define TRUE (BOOL)1 #endif #ifndef FALSE #define FALSE (BOOL)0 #endif void SOCK_clear_error(SocketClass *self) { self->errornumber = 0; self->errormsg = NULL; } SocketClass * SOCK_Constructor() { SocketClass *rv; rv = (SocketClass *) malloc(sizeof(SocketClass)); if (rv != NULL) { rv->socket = (SOCKETFD) -1; rv->buffer_filled_in = 0; rv->buffer_filled_out = 0; rv->buffer_read_in = 0; rv->buffer_in = (unsigned char *) malloc(globals.socket_buffersize); if ( ! rv->buffer_in) return NULL; rv->buffer_out = (unsigned char *) malloc(globals.socket_buffersize); if ( ! rv->buffer_out) return NULL; rv->errormsg = NULL; rv->errornumber = 0; rv->reverse = FALSE; } return rv; } void SOCK_Destructor(SocketClass *self) { if (self->socket != -1) { SOCK_put_char(self, 'X'); SOCK_flush_output(self); closesocket(self->socket); } if (self->buffer_in) free(self->buffer_in); if (self->buffer_out) free(self->buffer_out); free(self); } static char SOCK_connect_to_ip(SocketClass *self, unsigned short port, char *hostname) { struct hostent *host; struct sockaddr_in sadr; struct in_addr iaddr; if (self->socket != -1) { self->errornumber = SOCKET_ALREADY_CONNECTED; self->errormsg = "Socket is already connected"; return 0; } memset((char *)&sadr, 0, sizeof(sadr)); /* If it is a valid IP address, use it. Otherwise use hostname lookup. */ iaddr.s_addr = inet_addr(hostname); if (iaddr.s_addr == INADDR_NONE) { host = gethostbyname(hostname); if (host == NULL) { self->errornumber = SOCKET_HOST_NOT_FOUND; self->errormsg = "Could not resolve hostname."; return 0; } memcpy(&(sadr.sin_addr), host->h_addr, host->h_length); } else memcpy(&(sadr.sin_addr), (struct in_addr *) &iaddr, sizeof(iaddr)); sadr.sin_family = AF_INET; sadr.sin_port = htons(port); self->socket = socket(AF_INET, SOCK_STREAM, 0); if (self->socket == -1) { self->errornumber = SOCKET_COULD_NOT_CREATE_SOCKET; self->errormsg = "Could not create Socket."; return 0; } if ( connect(self->socket, (struct sockaddr *)&(sadr), sizeof(sadr)) < 0) { self->errornumber = SOCKET_COULD_NOT_CONNECT; self->errormsg = "Could not connect to remote socket."; closesocket(self->socket); self->socket = (SOCKETFD) -1; return 0; } return 1; } #ifndef VMS char SOCK_connect_to_unix_port(SocketClass *self, unsigned short port, char *path ) { struct sockaddr_un sadr; if (self->socket != -1) { self->errornumber = SOCKET_ALREADY_CONNECTED; self->errormsg = "Socket is already connected"; return 0; } memset((char *)&sadr, 0, sizeof(sadr)); sadr.sun_family = AF_UNIX; sprintf( sadr.sun_path, "%s.%d", path, port ); self->socket = socket(AF_UNIX, SOCK_STREAM, 0); if (self->socket == -1) { self->errornumber = SOCKET_COULD_NOT_CREATE_SOCKET; self->errormsg = "Could not create Socket."; return 0; } if ( connect(self->socket, (struct sockaddr *)&(sadr), sizeof(sadr)) < 0) { self->errornumber = SOCKET_COULD_NOT_CONNECT; self->errormsg = "Could not connect to remote socket."; closesocket(self->socket); self->socket = (SOCKETFD) -1; return 0; } return 1; } /* * cope with different path for debian distrib */ int SOCK_connect_to_unix(SocketClass *self, unsigned short port, char *path ) { if ( strlen( path ) > 0 ) { return !SOCK_connect_to_unix_port( self, port, path ); } if ( !SOCK_connect_to_unix_port( self, port, "/tmp/.s.PGSQL" )) { if ( SOCK_connect_to_unix_port( self, port, "/var/run/postgresql/.s.PGSQL" )) { SOCK_clear_error(self); return 1; } else { return 0; } } else { return 1; } } #endif char SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname, char *uds) { #ifndef VMS if ( strcmp( hostname, "localhost" ) == 0 ) return SOCK_connect_to_unix( self, port, uds ); else #endif return SOCK_connect_to_ip( self, port, hostname ); } void SOCK_get_n_char(SocketClass *self, char *buffer, int len) { int lf; if ( ! buffer) { self->errornumber = SOCKET_NULLPOINTER_PARAMETER; self->errormsg = "get_n_char was called with NULL-Pointer"; return; } for(lf=0; lf < len; lf++) buffer[lf] = SOCK_get_next_byte(self); } void SOCK_put_n_char(SocketClass *self, char *buffer, int len) { int lf; if ( ! buffer) { self->errornumber = SOCKET_NULLPOINTER_PARAMETER; self->errormsg = "put_n_char was called with NULL-Pointer"; return; } for(lf=0; lf < len; lf++) SOCK_put_next_byte(self, (unsigned char)buffer[lf]); } /* bufsize must include room for the null terminator will read at most bufsize-1 characters + null. */ BOOL SOCK_get_string(SocketClass *self, char *buffer, int bufsize) { register int lf = 0; for (lf = 0; lf < bufsize - 1; lf++) if (!(buffer[lf] = SOCK_get_next_byte(self))) return FALSE; buffer[bufsize - 1] = '\0'; return TRUE; } void SOCK_put_string(SocketClass *self, char *string) { register int lf; int len; len = strlen(string)+1; for(lf = 0; lf < len; lf++) SOCK_put_next_byte(self, (unsigned char)string[lf]); } int SOCK_get_int(SocketClass *self, short len) { char buf[4]; switch (len) { case 2: SOCK_get_n_char(self, buf, len); if (self->reverse) return *((unsigned short *) buf); else return ntohs( *((unsigned short *) buf) ); case 4: SOCK_get_n_char(self, buf, len); if (self->reverse) return *((unsigned int *) buf); else return ntohl( *((unsigned int *) buf) ); default: self->errornumber = SOCKET_GET_INT_WRONG_LENGTH; self->errormsg = "Cannot read ints of that length"; return 0; } } void SOCK_put_int(SocketClass *self, int value, short len) { unsigned int rv; switch (len) { case 2: rv = self->reverse ? value : htons( (unsigned short) value); SOCK_put_n_char(self, (char *) &rv, 2); return; case 4: rv = self->reverse ? value : htonl( (unsigned int) value); SOCK_put_n_char(self, (char *) &rv, 4); return; default: self->errornumber = SOCKET_PUT_INT_WRONG_LENGTH; self->errormsg = "Cannot write ints of that length"; return; } } void SOCK_flush_output(SocketClass *self) { int written; #ifdef MSG_NOSIGNAL written = send(self->socket, (char *)self->buffer_out, self->buffer_filled_out, MSG_NOSIGNAL); #else written = send(self->socket, (char *)self->buffer_out, self->buffer_filled_out, 0); #endif if (written != self->buffer_filled_out) { self->errornumber = SOCKET_WRITE_ERROR; self->errormsg = "Could not flush socket buffer."; } self->buffer_filled_out = 0; } UCHAR SOCK_get_next_byte(SocketClass *self) { if (self->buffer_read_in >= self->buffer_filled_in) { /* there are no more bytes left in the buffer so */ /* reload the buffer */ self->buffer_read_in = 0; self->buffer_filled_in = recv(self->socket, (char *)self->buffer_in, globals.socket_buffersize, 0); mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, globals.socket_buffersize); if (self->buffer_filled_in < 0) { self->errornumber = SOCKET_READ_ERROR; self->errormsg = "Error while reading from the socket."; self->buffer_filled_in = 0; return 0; } if (self->buffer_filled_in == 0) { self->errornumber = SOCKET_CLOSED; self->errormsg = "Socket has been closed."; self->buffer_filled_in = 0; return 0; } } return self->buffer_in[self->buffer_read_in++]; } void SOCK_put_next_byte(SocketClass *self, unsigned char next_byte) { int bytes_sent; self->buffer_out[self->buffer_filled_out++] = next_byte; if (self->buffer_filled_out == globals.socket_buffersize) { /* buffer is full, so write it out */ bytes_sent = send(self->socket, (char *)self->buffer_out, globals.socket_buffersize, 0); if (bytes_sent != globals.socket_buffersize) { self->errornumber = SOCKET_WRITE_ERROR; self->errormsg = "Error while writing to the socket."; } self->buffer_filled_out = 0; } } unixODBC-2.3.12/Drivers/Postgre7.1/socket.h000066400000000000000000000044101446441710500201470ustar00rootroot00000000000000 /* File: socket.h * * Description: See "socket.c" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __SOCKET_H__ #define __SOCKET_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef WIN32 #include #include #include #include #include #include #define closesocket(xxx) close(xxx) #define SOCKETFD int #ifndef INADDR_NONE #ifndef _IN_ADDR_T #define _IN_ADDR_T typedef unsigned int in_addr_t; #endif #define INADDR_NONE ((in_addr_t)-1) #endif #else #include #define SOCKETFD SOCKET #endif #include "psqlodbc.h" #define SOCKET_ALREADY_CONNECTED 1 #define SOCKET_HOST_NOT_FOUND 2 #define SOCKET_COULD_NOT_CREATE_SOCKET 3 #define SOCKET_COULD_NOT_CONNECT 4 #define SOCKET_READ_ERROR 5 #define SOCKET_WRITE_ERROR 6 #define SOCKET_NULLPOINTER_PARAMETER 7 #define SOCKET_PUT_INT_WRONG_LENGTH 8 #define SOCKET_GET_INT_WRONG_LENGTH 9 #define SOCKET_CLOSED 10 struct SocketClass_ { int buffer_filled_in; int buffer_filled_out; int buffer_read_in; unsigned char *buffer_in; unsigned char *buffer_out; SOCKETFD socket; char *errormsg; int errornumber; char reverse; /* used to handle Postgres 6.2 protocol (reverse byte order) */ }; #define SOCK_get_char(self) (SOCK_get_next_byte(self)) #define SOCK_put_char(self, c) (SOCK_put_next_byte(self, c)) /* error functions */ #define SOCK_get_errcode(self) (self->errornumber) #define SOCK_get_errmsg(self) (self->errormsg) /* Socket prototypes */ SocketClass *SOCK_Constructor(void); void SOCK_Destructor(SocketClass *self); char SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname, char*uds); void SOCK_get_n_char(SocketClass *self, char *buffer, int len); void SOCK_put_n_char(SocketClass *self, char *buffer, int len); BOOL SOCK_get_string(SocketClass *self, char *buffer, int bufsize); void SOCK_put_string(SocketClass *self, char *string); int SOCK_get_int(SocketClass *self, short len); void SOCK_put_int(SocketClass *self, int value, short len); void SOCK_flush_output(SocketClass *self); UCHAR SOCK_get_next_byte(SocketClass *self); void SOCK_put_next_byte(SocketClass *self, unsigned char next_byte); void SOCK_clear_error(SocketClass *self); #endif unixODBC-2.3.12/Drivers/Postgre7.1/statement.c000066400000000000000000000626351446441710500206730ustar00rootroot00000000000000 /* Module: statement.c * * Description: This module contains functions related to creating * and manipulating a statement. * * Classes: StatementClass (Functions prefix: "SC_") * * API functions: SQLAllocStmt, SQLFreeStmt * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "statement.h" #include "bind.h" #include "connection.h" #include "qresult.h" #include "convert.h" #include "environ.h" #include "misc.h" #include #include #include #ifndef WIN32 #include "isql.h" #else #include #include #endif extern GLOBAL_VALUES globals; #ifndef WIN32 #ifndef HAVE_STRICMP #define stricmp(s1,s2) strcasecmp(s1,s2) #define strnicmp(s1,s2,n) strncasecmp(s1,s2,n) #endif #endif #define PRN_NULLCHECK /* Map sql commands to statement types */ static struct { int type; char *s; } Statement_Type[] = { { STMT_TYPE_SELECT, "SELECT" }, { STMT_TYPE_INSERT, "INSERT" }, { STMT_TYPE_UPDATE, "UPDATE" }, { STMT_TYPE_DELETE, "DELETE" }, { STMT_TYPE_CREATE, "CREATE" }, { STMT_TYPE_ALTER, "ALTER" }, { STMT_TYPE_DROP, "DROP" }, { STMT_TYPE_GRANT, "GRANT" }, { STMT_TYPE_REVOKE, "REVOKE" }, { 0, NULL } }; RETCODE SQL_API PG_SQLAllocStmt(HDBC hdbc, HSTMT FAR *phstmt) { static char* const func="SQLAllocStmt"; ConnectionClass *conn = (ConnectionClass *) hdbc; StatementClass *stmt; mylog("%s: entering...\n", func); if( ! conn) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } stmt = SC_Constructor(); mylog("**** SQLAllocStmt: hdbc = %u, stmt = %u\n", hdbc, stmt); if ( ! stmt) { CC_set_error(conn, CONN_STMT_ALLOC_ERROR, "No more memory to allocate a further SQL-statement"); *phstmt = SQL_NULL_HSTMT; CC_log_error(func, "", conn); return SQL_ERROR; } if ( ! CC_add_statement(conn, stmt)) { CC_set_error(conn, CONN_STMT_ALLOC_ERROR, "Maximum number of connections exceeded."); CC_log_error(func, "", conn); SC_Destructor(stmt); *phstmt = SQL_NULL_HSTMT; return SQL_ERROR; } *phstmt = (HSTMT) stmt; /* Copy default statement options based from Connection options */ stmt->options = conn->stmtOptions; /* Save the handle for later */ stmt->phstmt = phstmt; return SQL_SUCCESS; } RETCODE SQL_API SQLAllocStmt(HDBC hdbc, HSTMT FAR *phstmt) { return PG_SQLAllocStmt( hdbc, phstmt ); } RETCODE SQL_API PG_SQLFreeStmt(HSTMT hstmt, UWORD fOption) { static char* const func="SQLFreeStmt"; StatementClass *stmt = (StatementClass *) hstmt; mylog("%s: entering...hstmt=%u, fOption=%d\n", func, hstmt, fOption); if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } if (fOption == SQL_DROP) { ConnectionClass *conn = stmt->hdbc; /* Remove the statement from the connection's statement list */ if ( conn) { if ( ! CC_remove_statement(conn, stmt)) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Statement is currently executing a transaction."); SC_log_error(func, "", stmt); return SQL_ERROR; /* stmt may be executing a transaction */ } /* Free any cursors and discard any result info */ if (stmt->result) { QR_Destructor(stmt->result); stmt->result = NULL; } } /* Destroy the statement and free any results, cursors, etc. */ SC_Destructor(stmt); } else if (fOption == SQL_UNBIND) { SC_unbind_cols(stmt); } else if (fOption == SQL_CLOSE) { /* this should discard all the results, but leave the statement */ /* itself in place (it can be executed again) */ if (!SC_recycle_statement(stmt)) { /* errormsg passed in above */ SC_log_error(func, "", stmt); return SQL_ERROR; } } else if(fOption == SQL_RESET_PARAMS) { SC_free_params(stmt, STMT_FREE_PARAMS_ALL); } else { SC_set_error(stmt, STMT_OPTION_OUT_OF_RANGE_ERROR, "Invalid option passed to SQLFreeStmt."); SC_log_error(func, "", stmt); return SQL_ERROR; } return SQL_SUCCESS; } RETCODE SQL_API SQLFreeStmt(HSTMT hstmt, UWORD fOption) { return PG_SQLFreeStmt( hstmt, fOption ); } /********************************************************************** * StatementClass implementation */ void InitializeStatementOptions(StatementOptions *opt) { opt->maxRows = 0; /* driver returns all rows */ opt->maxLength = 0; /* driver returns all data for char/binary */ opt->rowset_size = 1; opt->keyset_size = 0; /* fully keyset driven is the default */ opt->scroll_concurrency = SQL_CONCUR_READ_ONLY; opt->cursor_type = SQL_CURSOR_FORWARD_ONLY; opt->bind_size = 0; /* default is to bind by column */ opt->retrieve_data = SQL_RD_ON; opt->use_bookmarks = SQL_UB_OFF; } StatementClass * SC_Constructor(void) { StatementClass *rv; rv = (StatementClass *) malloc(sizeof(StatementClass)); if (rv) { rv->hdbc = NULL; /* no connection associated yet */ rv->phstmt = NULL; rv->result = NULL; rv->manual_result = FALSE; rv->prepare = FALSE; rv->status = STMT_ALLOCATED; rv->internal = FALSE; SC_clear_error(rv); rv->statement = NULL; rv->stmt_with_params[0] = '\0'; rv->statement_type = STMT_TYPE_UNKNOWN; rv->bindings = NULL; rv->bindings_allocated = 0; rv->bookmark.buffer = NULL; rv->bookmark.used = NULL; rv->parameters_allocated = 0; rv->parameters = 0; rv->currTuple = -1; rv->rowset_start = -1; rv->current_col = -1; rv->bind_row = 0; rv->last_fetch_count = 0; rv->save_rowset_size = -1; rv->data_at_exec = -1; rv->current_exec_param = -1; rv->put_data = FALSE; rv->lobj_fd = -1; rv->cursor_name[0] = '\0'; /* Parse Stuff */ rv->ti = NULL; rv->fi = NULL; rv->ntab = 0; rv->nfld = 0; rv->parse_status = STMT_PARSE_NONE; /* Clear Statement Options -- defaults will be set in AllocStmt */ memset(&rv->options, 0, sizeof(StatementOptions)); } return rv; } char SC_Destructor(StatementClass *self) { mylog("SC_Destructor: self=%u, self->result=%u, self->hdbc=%u\n", self, self->result, self->hdbc); if (STMT_EXECUTING == self->status) { SC_set_error(self, STMT_SEQUENCE_ERROR, "Statement is currently executing a transaction."); return FALSE; } if (self->result) { if ( ! self->hdbc) self->result->conn = NULL; /* prevent any dbase activity */ QR_Destructor(self->result); } if (self->statement) free(self->statement); SC_free_params(self, STMT_FREE_PARAMS_ALL); /* the memory pointed to by the bindings is not deallocated by the driver */ /* by by the application that uses that driver, so we don't have to care */ /* about that here. */ if (self->bindings) free(self->bindings); /* Free the parsed table information */ if (self->ti) { int i; for (i = 0; i < self->ntab; i++) { free(self->ti[i]); } free(self->ti); } /* Free the parsed field information */ if (self->fi) { int i; for (i = 0; i < self->nfld; i++) { free(self->fi[i]); } free(self->fi); } SC_set_errormsg(self, NULL); free(self); mylog("SC_Destructor: EXIT\n"); return TRUE; } /* Free parameters and free the memory from the data-at-execution parameters that was allocated in SQLPutData. */ void SC_free_params(StatementClass *self, char option) { int i; mylog("SC_free_params: ENTER, self=%d\n", self); if( ! self->parameters) return; for (i = 0; i < self->parameters_allocated; i++) { if (self->parameters[i].data_at_exec == TRUE) { if (self->parameters[i].EXEC_used) { free(self->parameters[i].EXEC_used); self->parameters[i].EXEC_used = NULL; } if (self->parameters[i].EXEC_buffer) { if (self->parameters[i].SQLType != SQL_LONGVARBINARY) free(self->parameters[i].EXEC_buffer); self->parameters[i].EXEC_buffer = NULL; } } } self->data_at_exec = -1; self->current_exec_param = -1; self->put_data = FALSE; if (option == STMT_FREE_PARAMS_ALL) { free(self->parameters); self->parameters = NULL; self->parameters_allocated = 0; } mylog("SC_free_params: EXIT\n"); } int statement_type(char *statement) { int i; /* ignore leading whitespace in query string */ while (*statement && isspace((unsigned char) *statement)) statement++; for (i = 0; Statement_Type[i].s; i++) if ( ! strnicmp(statement, Statement_Type[i].s, strlen(Statement_Type[i].s))) return Statement_Type[i].type; return STMT_TYPE_OTHER; } /* Called from SQLPrepare if STMT_PREMATURE, or from SQLExecute if STMT_FINISHED, or from SQLFreeStmt(SQL_CLOSE) */ char SC_recycle_statement(StatementClass *self) { ConnectionClass *conn; mylog("recycle statement: self= %u\n", self); /* This would not happen */ if (self->status == STMT_EXECUTING) { SC_set_error(self, STMT_SEQUENCE_ERROR, "Statement is currently executing a transaction."); return FALSE; } SC_set_errormsg(self, NULL); SC_clear_error(self); switch (self->status) { case STMT_ALLOCATED: /* this statement does not need to be recycled */ return TRUE; case STMT_READY: break; case STMT_PREMATURE: /* Premature execution of the statement might have caused the start of a transaction. If so, we have to rollback that transaction. */ conn = SC_get_conn(self); if ( ! CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) { CC_send_query(conn, "ABORT", NULL); CC_set_no_trans(conn); } break; case STMT_FINISHED: break; default: SC_set_error(self, STMT_INTERNAL_ERROR, "An internal error occurred while recycling statements"); return FALSE; } /* Free the parsed table information */ if (self->ti) { int i; for (i = 0; i < self->ntab; i++) { free(self->ti[i]); } free(self->ti); self->ti = NULL; self->ntab = 0; } /* Free the parsed field information */ if (self->fi) { int i; for (i = 0; i < self->nfld; i++) { free(self->fi[i]); } free(self->fi); self->fi = NULL; self->nfld = 0; } self->parse_status = STMT_PARSE_NONE; /* Free any cursors */ if (self->result) { QR_Destructor(self->result); self->result = NULL; } /****************************************************************/ /* Reset only parameters that have anything to do with results */ /****************************************************************/ self->status = STMT_READY; self->manual_result = FALSE; /* very important */ self->currTuple = -1; self->rowset_start = -1; self->current_col = -1; self->bind_row = 0; self->last_fetch_count = 0; SC_set_errormsg(self, NULL); SC_clear_error(self); self->lobj_fd = -1; /* Free any data at exec params before the statement is executed */ /* again. If not, then there will be a memory leak when */ /* the next SQLParamData/SQLPutData is called. */ SC_free_params(self, STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY); return TRUE; } /* Pre-execute a statement (SQLPrepare/SQLDescribeCol) */ void SC_pre_execute(StatementClass *self) { mylog("SC_pre_execute: status = %d\n", self->status); if (self->status == STMT_READY) { mylog(" preprocess: status = READY\n"); PG_SQLExecute(self); if (self->status == STMT_FINISHED) { mylog(" preprocess: after status = FINISHED, so set PREMATURE\n"); self->status = STMT_PREMATURE; } } } /* This is only called from SQLFreeStmt(SQL_UNBIND) */ char SC_unbind_cols(StatementClass *self) { Int2 lf; for(lf = 0; lf < self->bindings_allocated; lf++) { self->bindings[lf].data_left = -1; self->bindings[lf].buflen = 0; self->bindings[lf].buffer = NULL; self->bindings[lf].used = NULL; self->bindings[lf].returntype = SQL_C_CHAR; } self->bookmark.buffer = NULL; self->bookmark.used = NULL; return 1; } void SC_clear_error(StatementClass *self) { self->__error_number = 0; self->__error_message = NULL; self->errormsg_created = FALSE; } /* This function creates an error msg which is the concatenation */ /* of the result, statement, connection, and socket messages. */ char * SC_create_errormsg(StatementClass *self) { QResultClass *res = self->result; ConnectionClass *conn = self->hdbc; int pos; BOOL detailmsg = FALSE; char msg[4096]; msg[0] = '\0'; if (res && res->message) { strncpy(msg, res->message, sizeof(msg)); detailmsg = TRUE; } else if (SC_get_errormsg(self)) strncpy(msg, SC_get_errormsg(self), sizeof(msg)); if (!msg[0] && res && QR_get_notice(res)) { char *notice = QR_get_notice(res); int len = strlen(notice); if (len < sizeof(msg)) { memcpy(msg, notice, len); msg[len] = '\0'; } else return strdup(notice); } if (conn) { SocketClass *sock = conn->sock; if (!detailmsg && CC_get_errormsg(conn) && (CC_get_errormsg(conn))[0] != '\0') { pos = strlen(msg); sprintf(&msg[pos], ";\n%s", CC_get_errormsg(conn)); } if (sock && sock->errormsg && sock->errormsg[0] != '\0') { pos = strlen(msg); sprintf(&msg[pos], ";\n%s", sock->errormsg); } } return msg[0] ? strdup(msg) : NULL; } void SC_set_error(StatementClass *self, int number, const char *message) { if (self->__error_message) free(self->__error_message); self->__error_number = number; self->__error_message = message ? strdup(message) : NULL; } void SC_set_errormsg(StatementClass *self, const char *message) { if (self->__error_message) free(self->__error_message); self->__error_message = message ? strdup(message) : NULL; } char SC_get_error(StatementClass *self, int *number, char **message) { char rv; /* Create a very informative errormsg if it hasn't been done yet. */ if ( ! self->errormsg_created) { self->__error_message = SC_create_errormsg(self); self->errormsg_created = TRUE; } if (self->__error_number) { *number = self->__error_number; *message = self->__error_message; self->__error_message = NULL; } rv = (self->__error_number != 0); self->__error_number = 0; return rv; } /* Currently, the driver offers very simple bookmark support -- it is just the current row number. But it could be more sophisticated someday, such as mapping a key to a 32 bit value */ unsigned long SC_get_bookmark(StatementClass *self) { return (self->currTuple + 1); } RETCODE SC_fetch(StatementClass *self) { static char* const func = "SC_fetch"; QResultClass *res = self->result; int retval, result; Int2 num_cols, lf; Oid type; char *value; ColumnInfoClass *ci; /* TupleField *tupleField; */ self->last_fetch_count = 0; ci = QR_get_fields(res); /* the column info */ mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, globals.use_declarefetch); if ( self->manual_result || ! globals.use_declarefetch) { if (self->currTuple >= QR_get_num_tuples(res) -1 || (self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1)) { /* if at the end of the tuples, return "no data found" and set the cursor past the end of the result set */ self->currTuple = QR_get_num_tuples(res); return SQL_NO_DATA_FOUND; } mylog("**** SQLFetch: manual_result\n"); (self->currTuple)++; } else { /* read from the cache or the physical next tuple */ retval = QR_next_tuple(res); if (retval < 0) { mylog("**** SQLFetch: end_tuples\n"); return SQL_NO_DATA_FOUND; } else if (retval > 0) (self->currTuple)++; /* all is well */ else { mylog("SQLFetch: error\n"); SC_set_error(self, STMT_EXEC_ERROR, "Error fetching next row"); SC_log_error(func, "", self); return SQL_ERROR; } } num_cols = QR_NumResultCols(res); result = SQL_SUCCESS; self->last_fetch_count = 1; /* If the bookmark column was bound then return a bookmark. Since this is used with SQLExtendedFetch, and the rowset size may be greater than 1, and an application can use row or column wise binding, use the code in copy_and_convert_field() to handle that. */ if (self->bookmark.buffer) { char buf[32]; sprintf(buf, "%ld", SC_get_bookmark(self)); result = copy_and_convert_field(self, 0, buf, SQL_C_ULONG, self->bookmark.buffer, 0, self->bookmark.used); } for (lf=0; lf < num_cols; lf++) { mylog("fetch: cols=%d, lf=%d, self = %u, self->bindings = %u, buffer[] = %u\n", num_cols, lf, self, self->bindings, self->bindings[lf].buffer); /* reset for SQLGetData */ self->bindings[lf].data_left = -1; if (self->bindings[lf].buffer != NULL) { /* this column has a binding */ /* type = QR_get_field_type(res, lf); */ type = CI_get_oid(ci, lf); /* speed things up */ mylog("type = %d\n", type); if (self->manual_result) { value = QR_get_value_manual(res, self->currTuple, lf); mylog("manual_result\n"); } else if (globals.use_declarefetch) value = QR_get_value_backend(res, lf); else { value = QR_get_value_backend_row(res, self->currTuple, lf); } mylog("value = '%s'\n", (value==NULL)?"":value); retval = copy_and_convert_field_bindinfo(self, type, value, lf); mylog("copy_and_convert: retval = %d\n", retval); switch(retval) { case COPY_OK: break; /* OK, do next bound column */ case COPY_UNSUPPORTED_TYPE: SC_set_error(self, STMT_RESTRICTED_DATA_TYPE_ERROR, "Received an unsupported type from Postgres."); SC_log_error(func, "", self); result = SQL_ERROR; break; case COPY_UNSUPPORTED_CONVERSION: SC_set_error(self, STMT_RESTRICTED_DATA_TYPE_ERROR, "Couldn't handle the necessary data type conversion."); SC_log_error(func, "", self); result = SQL_ERROR; break; case COPY_RESULT_TRUNCATED: SC_set_error(self, STMT_TRUNCATED, "The buffer was too small for the result."); result = SQL_SUCCESS_WITH_INFO; break; case COPY_GENERAL_ERROR: /* error msg already filled in */ SC_log_error(func, "", self); result = SQL_ERROR; break; /* This would not be meaningful in SQLFetch. */ case COPY_NO_DATA_FOUND: break; default: SC_set_error(self, STMT_INTERNAL_ERROR, "Unrecognized return value from copy_and_convert_field."); SC_log_error(func, "", self); result = SQL_ERROR; break; } } } return result; } RETCODE SC_execute(StatementClass *self) { static char* const func="SC_execute"; ConnectionClass *conn; QResultClass *res; char ok, was_ok, was_nonfatal; Int2 oldstatus, numcols; QueryInfo qi; conn = SC_get_conn(self); /* Begin a transaction if one is not already in progress */ /* * Basically we don't have to begin a transaction in autocommit mode * because Postgres backend runs in autocomit mode. We issue "BEGIN" * in the following cases. 1) we use declare/fetch and the statement * is SELECT (because declare/fetch must be called in a transaction). * 2) we are in autocommit off state and the statement isn't of type * OTHER. */ if (!self->internal && !CC_is_in_trans(conn) && ((globals.use_declarefetch && self->statement_type == STMT_TYPE_SELECT) || (!CC_is_in_autocommit(conn) && self->statement_type != STMT_TYPE_OTHER))) { mylog(" about to begin a transaction on statement = %u\n", self); res = CC_send_query(conn, "BEGIN", NULL); if (QR_aborted(res)) { SC_set_error(self, STMT_EXEC_ERROR, "Could not begin a transaction"); SC_log_error(func, "", self); return SQL_ERROR; } ok = QR_command_successful(res); mylog("SQLExecute: ok = %d, status = %d\n", ok, QR_get_status(res)); QR_Destructor(res); if (!ok) { SC_set_error(self, STMT_EXEC_ERROR, "Could not begin a transaction"); SC_log_error(func, "", self); return SQL_ERROR; } else CC_set_in_trans(conn); } oldstatus = conn->status; conn->status = CONN_EXECUTING; self->status = STMT_EXECUTING; /* If it's a SELECT statement, use a cursor. */ /* Note that the declare cursor has already been prepended to the statement */ /* in copy_statement... */ if (self->statement_type == STMT_TYPE_SELECT) { char fetch[128]; mylog(" Sending SELECT statement on stmt=%u, cursor_name='%s'\n", self, self->cursor_name); /* send the declare/select */ self->result = CC_send_query(conn, self->stmt_with_params, NULL); if (globals.use_declarefetch && self->result != NULL && QR_command_successful(self->result)) { QR_Destructor(self->result); /* That worked, so now send the fetch to start getting data back */ qi.result_in = NULL; qi.cursor = self->cursor_name; qi.row_size = globals.fetch_max; /* Most likely the rowset size will not be set by the application until after the statement is executed, so might as well use the cache size. The qr_next_tuple() function will correct for any discrepancies in sizes and adjust the cache accordingly. */ sprintf(fetch, "fetch %d in %s", qi.row_size, self->cursor_name); self->result = CC_send_query( conn, fetch, &qi); } mylog(" done sending the query:\n"); } else { /* not a SELECT statement so don't use a cursor */ mylog(" it's NOT a select statement: stmt=%u\n", self); self->result = CC_send_query(conn, self->stmt_with_params, NULL); /* We shouldn't send COMMIT. Postgres backend does the autocommit if neccessary. (Zoltan, 04/26/2000) */ /* Above seems wrong. Even in case of autocommit, started transactions must be committed. (Hiroshi, 02/11/2001) */ if ( ! self->internal && CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) { res = CC_send_query(conn, "COMMIT", NULL); QR_Destructor(res); CC_set_no_trans(conn); } } conn->status = oldstatus; self->status = STMT_FINISHED; /* Check the status of the result */ if (self->result) { was_ok = QR_command_successful(self->result); was_nonfatal = QR_command_nonfatal(self->result); if ( was_ok) SC_set_errornumber(self, STMT_OK); else SC_set_errornumber(self, was_nonfatal ? STMT_INFO_ONLY : STMT_ERROR_TAKEN_FROM_BACKEND); self->currTuple = -1; /* set cursor before the first tuple in the list */ self->current_col = -1; self->rowset_start = -1; /* see if the query did return any result columns */ numcols = QR_NumResultCols(self->result); /* now allocate the array to hold the binding info */ if (numcols > 0) { extend_bindings(self, numcols); if (self->bindings == NULL) { SC_set_error(self, STMT_NO_MEMORY_ERROR, "Could not get enough free memory to store the binding information"); SC_log_error(func, "", self); return SQL_ERROR; } } /* issue "ABORT" when query aborted */ if (QR_get_aborted(self->result) && ! self->internal ) CC_abort(conn); } else { /* Bad Error -- The error message will be in the Connection */ if (self->statement_type == STMT_TYPE_CREATE) { SC_set_error(self, STMT_CREATE_TABLE_ERROR, "Error creating the table"); /* This would allow the table to already exists, thus appending rows to it. BUT, if the table didn't have the same attributes, it would fail. return SQL_SUCCESS_WITH_INFO; */ } else { SC_set_error(self, STMT_EXEC_ERROR, "Error while executing the query"); } if ( ! self->internal) CC_abort(conn); } if (SC_get_errornumber(self) == STMT_OK) return SQL_SUCCESS; else { /* Modified, 2000-04-29, Zoltan */ if (SC_get_errornumber(self) == STMT_INFO_ONLY) SC_set_errormsg(self, "Error while executing the query (non-fatal)"); else SC_set_errormsg(self, "Unknown error"); SC_log_error(func, "", self); return SQL_ERROR; } } void SC_log_error(char *func, char *desc, StatementClass *self) { #ifdef PRN_NULLCHECK #define nullcheck(a) (a ? a : "(NULL)") #endif if (self) { qlog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->__error_number, nullcheck(self->__error_message)); mylog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->__error_number, nullcheck(self->__error_message)); qlog(" ------------------------------------------------------------\n"); qlog(" hdbc=%u, stmt=%u, result=%u\n", self->hdbc, self, self->result); qlog(" manual_result=%d, prepare=%d, internal=%d\n", self->manual_result, self->prepare, self->internal); qlog(" bindings=%u, bindings_allocated=%d\n", self->bindings, self->bindings_allocated); qlog(" parameters=%u, parameters_allocated=%d\n", self->parameters, self->parameters_allocated); qlog(" statement_type=%d, statement='%s'\n", self->statement_type, nullcheck(self->statement)); qlog(" stmt_with_params='%s'\n", nullcheck(self->stmt_with_params)); qlog(" data_at_exec=%d, current_exec_param=%d, put_data=%d\n", self->data_at_exec, self->current_exec_param, self->put_data); qlog(" currTuple=%d, current_col=%d, lobj_fd=%d\n", self->currTuple, self->current_col, self->lobj_fd); qlog(" maxRows=%d, rowset_size=%d, keyset_size=%d, cursor_type=%d, scroll_concurrency=%d\n", self->options.maxRows, self->options.rowset_size, self->options.keyset_size, self->options.cursor_type, self->options.scroll_concurrency); qlog(" cursor_name='%s'\n", nullcheck(self->cursor_name)); qlog(" ----------------QResult Info -------------------------------\n"); if (self->result) { QResultClass *res = self->result; qlog(" fields=%u, manual_tuples=%u, backend_tuples=%u, tupleField=%d, conn=%u\n", res->fields, res->manual_tuples, res->backend_tuples, res->tupleField, res->conn); qlog(" fetch_count=%d, fcount=%d, num_fields=%d, cursor='%s'\n", res->fetch_count, res->fcount, res->num_fields, nullcheck(res->cursor)); qlog(" message='%s', command='%s', notice='%s'\n", nullcheck(res->message), nullcheck(res->command), nullcheck(res->notice)); qlog(" status=%d, inTuples=%d\n", res->status, res->inTuples); } /* Log the connection error if there is one */ CC_log_error(func, desc, self->hdbc); } else qlog("INVALID STATEMENT HANDLE ERROR: func=%s, desc='%s'\n", func, desc); #undef PRN_NULLCHECK } unixODBC-2.3.12/Drivers/Postgre7.1/statement.h000066400000000000000000000152661446441710500206760ustar00rootroot00000000000000 /* File: statement.h * * Description: See "statement.c" * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __STATEMENT_H__ #define __STATEMENT_H__ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "psqlodbc.h" #include "bind.h" #ifndef WIN32 #include "isql.h" #else #include #include #endif #ifndef FALSE #define FALSE (BOOL)0 #endif #ifndef TRUE #define TRUE (BOOL)1 #endif typedef enum { STMT_ALLOCATED, /* The statement handle is allocated, but not used so far */ STMT_READY, /* the statement is waiting to be executed */ STMT_PREMATURE, /* ODBC states that it is legal to call e.g. SQLDescribeCol before a call to SQLExecute, but after SQLPrepare. To get all the necessary information in such a case, we simply execute the query _before_ the actual call to SQLExecute, so that statement is considered to be "premature". */ STMT_FINISHED, /* statement execution has finished */ STMT_EXECUTING /* statement execution is still going on */ } STMT_Status; #define STMT_TRUNCATED -2 #define STMT_INFO_ONLY -1 /* not an error message, just a notification to be returned by SQLError */ #define STMT_OK 0 /* will be interpreted as "no error pending" */ #define STMT_EXEC_ERROR 1 #define STMT_STATUS_ERROR 2 #define STMT_SEQUENCE_ERROR 3 #define STMT_NO_MEMORY_ERROR 4 #define STMT_COLNUM_ERROR 5 #define STMT_NO_STMTSTRING 6 #define STMT_ERROR_TAKEN_FROM_BACKEND 7 #define STMT_INTERNAL_ERROR 8 #define STMT_STILL_EXECUTING 9 #define STMT_NOT_IMPLEMENTED_ERROR 10 #define STMT_BAD_PARAMETER_NUMBER_ERROR 11 #define STMT_OPTION_OUT_OF_RANGE_ERROR 12 #define STMT_INVALID_COLUMN_NUMBER_ERROR 13 #define STMT_RESTRICTED_DATA_TYPE_ERROR 14 #define STMT_INVALID_CURSOR_STATE_ERROR 15 #define STMT_OPTION_VALUE_CHANGED 16 #define STMT_CREATE_TABLE_ERROR 17 #define STMT_NO_CURSOR_NAME 18 #define STMT_INVALID_CURSOR_NAME 19 #define STMT_INVALID_ARGUMENT_NO 20 #define STMT_ROW_OUT_OF_RANGE 21 #define STMT_OPERATION_CANCELLED 22 #define STMT_INVALID_CURSOR_POSITION 23 #define STMT_VALUE_OUT_OF_RANGE 24 #define STMT_OPERATION_INVALID 25 #define STMT_PROGRAM_TYPE_OUT_OF_RANGE 26 #define STMT_BAD_ERROR 27 /* statement types */ enum { STMT_TYPE_UNKNOWN = -2, STMT_TYPE_OTHER = -1, STMT_TYPE_SELECT = 0, STMT_TYPE_INSERT, STMT_TYPE_UPDATE, STMT_TYPE_DELETE, STMT_TYPE_CREATE, STMT_TYPE_ALTER, STMT_TYPE_DROP, STMT_TYPE_GRANT, STMT_TYPE_REVOKE }; #define STMT_UPDATE(stmt) (stmt->statement_type > STMT_TYPE_SELECT) /* Parsing status */ enum { STMT_PARSE_NONE = 0, STMT_PARSE_COMPLETE, STMT_PARSE_INCOMPLETE, STMT_PARSE_FATAL }; /* Result style */ enum { STMT_FETCH_NONE = 0, STMT_FETCH_NORMAL, STMT_FETCH_EXTENDED }; typedef struct { COL_INFO *col_info; /* cached SQLColumns info for this table */ char name[MAX_TABLE_LEN+1]; char alias[MAX_TABLE_LEN+1]; } TABLE_INFO; typedef struct { TABLE_INFO *ti; /* resolve to explicit table names */ int precision; int display_size; int length; int type; char nullable; char func; char expr; char quote; char dquote; char numeric; char dot[MAX_TABLE_LEN+1]; char name[MAX_COLUMN_LEN+1]; char alias[MAX_COLUMN_LEN+1]; } FIELD_INFO; /******** Statement Handle ***********/ struct StatementClass_ { ConnectionClass *hdbc; /* pointer to ConnectionClass this statement belongs to */ QResultClass *result; /* result of the current statement */ HSTMT FAR *phstmt; StatementOptions options; STMT_Status status; char *__error_message; int __error_number; /* information on bindings */ BindInfoClass *bindings; /* array to store the binding information */ BindInfoClass bookmark; int bindings_allocated; /* information on statement parameters */ int parameters_allocated; ParameterInfoClass *parameters; Int4 currTuple; /* current absolute row number (GetData, SetPos, SQLFetch) */ int save_rowset_size; /* saved rowset size in case of change/FETCH_NEXT */ int rowset_start; /* start of rowset (an absolute row number) */ int bind_row; /* current offset for Multiple row/column binding */ int last_fetch_count; /* number of rows retrieved in last fetch/extended fetch */ int current_col; /* current column for GetData -- used to handle multiple calls */ int lobj_fd; /* fd of the current large object */ char *statement; /* if non--null pointer to the SQL statement that has been executed */ TABLE_INFO **ti; FIELD_INFO **fi; int nfld; int ntab; int parse_status; int statement_type; /* According to the defines above */ int data_at_exec; /* Number of params needing SQLPutData */ int current_exec_param; /* The current parameter for SQLPutData */ char put_data; /* Has SQLPutData been called yet? */ char errormsg_created; /* has an informative error msg been created? */ char manual_result; /* Is the statement result manually built? */ char prepare; /* is this statement a prepared statement or direct */ char internal; /* Is this statement being called internally? */ char cursor_name[MAX_CURSOR_LEN+1]; char stmt_with_params[STD_STATEMENT_LEN]; /* statement after parameter substitution */ int reexecute; }; #define SC_get_conn(a) (a->hdbc) #define SC_get_Result(a) (a->result); #define SC_get_errornumber(a) (a->__error_number) #define SC_set_errornumber(a, n) (a->__error_number = n) #define SC_get_errormsg(a) (a->__error_message) /* options for SC_free_params() */ #define STMT_FREE_PARAMS_ALL 0 #define STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY 1 /* Statement prototypes */ StatementClass *SC_Constructor(void); void InitializeStatementOptions(StatementOptions *opt); char SC_Destructor(StatementClass *self); int statement_type(char *statement); char parse_statement(StatementClass *stmt); void SC_pre_execute(StatementClass *self); char SC_unbind_cols(StatementClass *self); char SC_recycle_statement(StatementClass *self); void SC_clear_error(StatementClass *self); void SC_set_error(StatementClass *self, int errnum, const char *msg); void SC_set_errormsg(StatementClass *self, const char *msg); char SC_get_error(StatementClass *self, int *number, char **message); char *SC_create_errormsg(StatementClass *self); RETCODE SC_execute(StatementClass *self); RETCODE SC_fetch(StatementClass *self); void SC_free_params(StatementClass *self, char option); void SC_log_error(char *func, char *desc, StatementClass *self); unsigned long SC_get_bookmark(StatementClass *self); RETCODE SQL_API PG_SQLAllocStmt(HDBC hdbc, HSTMT FAR *phstmt); RETCODE SQL_API PG_SQLFreeStmt(HSTMT hstmt, UWORD fOption); #endif unixODBC-2.3.12/Drivers/Postgre7.1/tuple.c000066400000000000000000000026311446441710500200060ustar00rootroot00000000000000 /* Module: tuple.c * * Description: This module contains functions for setting the data for individual * fields (TupleField structure) of a manual result set. * * Important Note: These functions are ONLY used in building manual result sets for * info functions (SQLTables, SQLColumns, etc.) * * Classes: n/a * * API functions: none * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "tuple.h" #include #include void set_tuplefield_null(TupleField *tuple_field) { tuple_field->len = 0; tuple_field->value = NULL; /* strdup(""); */ } void set_tuplefield_string(TupleField *tuple_field, char *string) { tuple_field->len = strlen(string); tuple_field->value = malloc(strlen(string)+1); strcpy(tuple_field->value, string); } void set_tuplefield_int2(TupleField *tuple_field, Int2 value) { char buffer[10]; sprintf(buffer,"%d", value); tuple_field->len = strlen(buffer)+1; /* +1 ... is this correct (better be on the save side-...) */ tuple_field->value = strdup(buffer); } void set_tuplefield_int4(TupleField *tuple_field, Int4 value) { char buffer[15]; sprintf(buffer,"%ld", (long)value); tuple_field->len = strlen(buffer)+1; /* +1 ... is this correct (better be on the save side-...) */ tuple_field->value = strdup(buffer); } unixODBC-2.3.12/Drivers/Postgre7.1/tuple.h000066400000000000000000000030631446441710500200130ustar00rootroot00000000000000 /* File: tuple.h * * Description: See "tuple.c" * * Important NOTE: The TupleField structure is used both to hold backend data and * manual result set data. The "set_" functions and the TupleNode * structure are only used for manual result sets by info routines. * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __TUPLE_H__ #define __TUPLE_H__ #include "psqlodbc.h" /* Used by backend data AND manual result sets */ struct TupleField_ { Int4 len; /* length of the current Tuple */ void *value; /* an array representing the value */ }; /* Used ONLY for manual result sets */ struct TupleNode_ { struct TupleNode_ *prev, *next; TupleField tuple[1]; }; /* These macros are wrappers for the corresponding set_tuplefield functions but these handle automatic NULL determination and call set_tuplefield_null() if appropriate for the datatype (used by SQLGetTypeInfo). */ #define set_nullfield_string(FLD, VAL) ((VAL) ? set_tuplefield_string(FLD, (VAL)) : set_tuplefield_null(FLD)) #define set_nullfield_int2(FLD, VAL) ((VAL) != -1 ? set_tuplefield_int2(FLD, (VAL)) : set_tuplefield_null(FLD)) #define set_nullfield_int4(FLD, VAL) ((VAL) != -1 ? set_tuplefield_int4(FLD, (VAL)) : set_tuplefield_null(FLD)) void set_tuplefield_null(TupleField *tuple_field); void set_tuplefield_string(TupleField *tuple_field, char *string); void set_tuplefield_int2(TupleField *tuple_field, Int2 value); void set_tuplefield_int4(TupleField *tuple_field, Int4 value); #endif unixODBC-2.3.12/Drivers/Postgre7.1/tuplelist.c000066400000000000000000000107441446441710500207060ustar00rootroot00000000000000 /* Module: tuplelist.c * * Description: This module contains functions for creating a manual result set * (the TupleList) and retrieving data from it for a specific row/column. * * Classes: TupleListClass (Functions prefix: "TL_") * * API functions: none * * Comments: See "notice.txt" for copyright and license information. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "tuplelist.h" #include "tuple.h" TupleListClass * TL_Constructor(UInt4 fieldcnt) { TupleListClass *rv; mylog("in TL_Constructor\n"); rv = (TupleListClass *) malloc(sizeof(TupleListClass)); if (rv) { rv->num_fields = fieldcnt; rv->num_tuples = 0; rv->list_start = NULL; rv->list_end = NULL; rv->lastref = NULL; rv->last_indexed = -1; } mylog("exit TL_Constructor\n"); return rv; } void TL_Destructor(TupleListClass *self) { int lf; TupleNode *node, *tp; mylog("TupleList: in DESTRUCTOR\n"); node = self->list_start; while(node != NULL) { for (lf=0; lf < self->num_fields; lf++) if (node->tuple[lf].value != NULL) { free(node->tuple[lf].value); } tp = node->next; free(node); node = tp; } free(self); mylog("TupleList: exit DESTRUCTOR\n"); } void * TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno) { Int4 lf; Int4 delta, from_end; char end_is_closer, start_is_closer; TupleNode *rv; if (self->last_indexed == -1) /* we have an empty tuple list */ return NULL; /* some more sanity checks */ if ((tupleno >= self->num_tuples) || (tupleno < 0)) /* illegal tuple number range */ return NULL; if ((fieldno >= self->num_fields) || (fieldno < 0)) /* illegel field number range */ return NULL; /* check if we are accessing the same tuple that was used in the last fetch (e.g: for fetching all the fields one after another. Do this to speed things up */ if (tupleno == self->last_indexed) return self->lastref->tuple[fieldno].value; /* now for the tricky part... */ /* Since random access is quite inefficient for linked lists we use the lastref pointer that points to the last element referenced by a get_fieldval() call in conjunction with the its index number that is stored in last_indexed. (So we use some locality of reference principle to speed things up) */ delta = tupleno - self->last_indexed; /* if delta is positive, we have to go forward */ /* now check if we are closer to the start or the end of the list than to our last_indexed pointer */ from_end = (self->num_tuples - 1) - tupleno; start_is_closer = labs(delta) > tupleno; /* true if we are closer to the start of the list than to the last_indexed pointer */ end_is_closer = labs(delta) > from_end; /* true if we are closer at the end of the list */ if (end_is_closer) { /* scanning from the end is the shortest way. so we do that... */ rv = self->list_end; for (lf=0; lf < from_end; lf++) rv = rv->prev; } else if (start_is_closer) { /* the shortest way is to start the search from the head of the list */ rv = self->list_start; for (lf=0; lf < tupleno; lf++) rv = rv->next; } else { /* the closest way is starting from our lastref - pointer */ rv = self->lastref; /* at first determine whether we have to search forward or backwards */ if (delta < 0) { /* we have to search backwards */ for(lf=0; lf < (-1)*delta; lf++) rv = rv->prev; } else { /* ok, we have to search forward... */ for (lf=0; lf < delta; lf++) rv = rv->next; } } /* now we have got our return pointer, so update the lastref and the last_indexed values */ self->lastref = rv; self->last_indexed = tupleno; return rv->tuple[fieldno].value; } char TL_add_tuple(TupleListClass *self, TupleNode *new_field) { /* we append the tuple at the end of the doubly linked list of the tuples we have already read in */ new_field->prev = NULL; new_field->next = NULL; if (self->list_start == NULL) { /* the list is empty, we have to add the first tuple */ self->list_start = new_field; self->list_end = new_field; self->lastref = new_field; self->last_indexed = 0; } else { /* there is already an element in the list, so add the new one at the end of the list */ self->list_end->next = new_field; new_field->prev = self->list_end; self->list_end = new_field; } self->num_tuples++; /* this method of building a list cannot fail, so we return 1 */ return 1; } unixODBC-2.3.12/Drivers/Postgre7.1/tuplelist.h000066400000000000000000000015621446441710500207110ustar00rootroot00000000000000 /* File: tuplelist.h * * Description: See "tuplelist.c" * * Important Note: This structure and its functions are ONLY used in building manual result * sets for info functions (SQLTables, SQLColumns, etc.) * * Comments: See "notice.txt" for copyright and license information. * */ #ifndef __TUPLELIST_H__ #define __TUPLELIST_H__ #include "psqlodbc.h" struct TupleListClass_ { Int4 num_fields; Int4 num_tuples; TupleNode *list_start, *list_end, *lastref; Int4 last_indexed; }; #define TL_get_num_tuples(x) (x->num_tuples) /* Create a TupleList. Each tuple consits of fieldcnt columns */ TupleListClass *TL_Constructor(UInt4 fieldcnt); void TL_Destructor(TupleListClass *self); void *TL_get_fieldval(TupleListClass *self, Int4 tupleno, Int2 fieldno); char TL_add_tuple(TupleListClass *self, TupleNode *new_field); #endif unixODBC-2.3.12/Drivers/README000066400000000000000000000041251446441710500155200ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | Drivers | +-------------------------------------------------------------+ The drivers in here are historical ones or example drivers. They are not supported anymore. But can be used as a starting point to write your own. A list of some third party drivers can be found at: http://www.unixodbc.org/drivers.html Some unixODBC drivers have been coded from scratch while others have been integerated (tweeked to compile and tested) into unixODBC. It is unlikely that you have all of the required libs to build all of these drivers so edit the Makefile in this dir... comment out any unwanted drivers. Getting all drivers up to the latest ODBC Level (ie 3.51) is an ongoing effort. You will find that each driver will implement a different level of compliance but, hopefully, enough to be quite usefull. If you develop a new driver than please let us know. We have created a Template to help you (see template dir). Drivers which are under development or are currently being tested with unixODBC may not be included in this distribution and some others may have to be downloaded from the DBMS vendor. The txt and nn drivers are good candidates for testing when you do not want to install a full DBMS. The txt driver will use a text file based database which may take a bit of time to understand in terms of setting it up. The nn driver uses internet News Servers as a data server so it is, perhaps, the easiest to get started with. +-------------------------------------------------------------+ | Peter Harvey pharvey@codebydesign.com | | www.genix.net/unixODBC | +-------------------------------------------------------------+ unixODBC-2.3.12/Drivers/nn/000077500000000000000000000000001446441710500152515ustar00rootroot00000000000000unixODBC-2.3.12/Drivers/nn/ChangeLog000066400000000000000000000004551446441710500170270ustar00rootroot000000000000001999-05-15 Peter Harvey * All: Started code resconstruction to unixODBC framework. 1999-05-13 Peter Harvey * All: adapted Ke Jin's NN ODBC driver for unixODBC (1st clean compile and successfull query) * ChangeLog: Started ChangeLog unixODBC-2.3.12/Drivers/nn/Makefile.am000066400000000000000000000021321446441710500173030ustar00rootroot00000000000000lib_LTLIBRARIES = libnn.la AM_CPPFLAGS = -I@top_srcdir@/include -I. libnn_la_LDFLAGS = -no-undefined -version-info 1:0:0 -module EXTRA_DIST = \ nnconfig.h \ connect.h \ convert.h \ driver.h \ herr.h \ hstmt.h \ isql.h \ isqlext.h \ nncol.h \ nndate.h \ nnsql.h \ nntp.h \ stmt.h \ yyenv.h \ yyerr.h \ yylex.h \ yyparse.tab.h \ yystmt.h \ herr.ci \ nncol.ci \ nntp.ci \ yyerr.ci \ yylex.ci \ README libnn_la_SOURCES = \ SQLAllocConnect.c \ SQLAllocEnv.c \ SQLAllocStmt.c \ SQLBindCol.c \ SQLBindParameter.c \ SQLCancel.c \ SQLConnect.c \ SQLDescribeCol.c \ SQLDisconnect.c \ SQLDriverConnect.c \ SQLError.c \ SQLExecDirect.c \ SQLExecute.c \ SQLFetch.c \ SQLFreeConnect.c \ SQLFreeEnv.c \ SQLFreeStmt.c \ SQLGetConnectOption.c \ SQLGetData.c \ SQLNumParams.c \ SQLNumResultCols.c \ SQLParamData.c \ SQLPrepare.c \ SQLPutData.c \ SQLRowCount.c \ SQLSetConnectOption.c \ SQLSetParam.c \ misc.c \ connect.c \ convert.c \ execute.c \ herr.c \ prepare.c \ yyparse.y \ yylex.c \ yystmt.c \ yyerr.c \ yyevl.c \ yytchk.c \ nncol.c \ nndate.c \ nntp.c unixODBC-2.3.12/Drivers/nn/README000066400000000000000000000026321446441710500161340ustar00rootroot00000000000000*************************************************************** * This code is GPL. * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | Driver for internet News Servers | +-------------------------------------------------------------+ This is Ke Jin's NN ODBC driver, adapted for unixODBC. Ke Jin's original README is in README.orig. This is a first pass at the effort to integrate it into unixODBC. It works, in its current state, but much more needs to be done (see the TODO). THIS CODE IS FUNCTIONAL BUT IS IN MID-HACK; ONLY THE MOST ADVENTUROUS SHOULD EVEN TRY TO FIGURE THIS OUT IN ITS CURRENT STATE. - PAH The basic concept is that a news server is like a SERVER/DATABASE, a news group is like a TABLE, and data such as Subject is a COLUMN. A useful subset of SQL is supported in the driver. Check out Ke Jins original README (README.orig). This driver can be quite usefull so I hope someone volunteers to tackle some of the items in the TODO list. +-------------------------------------------------------------+ | Peter Harvey pharvey@codebydesign.com | | http://www.unixodbc.org | +-------------------------------------------------------------+ unixODBC-2.3.12/Drivers/nn/SQLAllocConnect.c000066400000000000000000000021601446441710500203400ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLAllocConnect( HENV henv, HDBC * phdbc) { env_t* penv = henv; dbc_t* pdbc; int i; UNSET_ERROR( penv->herr ); pdbc = *phdbc = (void*)MEM_ALLOC( sizeof(dbc_t) ); if (! pdbc ) { PUSHSQLERR( penv->herr, en_S1001 ); return SQL_ERROR; } pdbc->next = penv->hdbc; penv->hdbc = pdbc; pdbc->henv = henv; pdbc->stmt= 0; pdbc->herr = 0; pdbc->hcndes = 0; return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLAllocEnv.c000066400000000000000000000016161446441710500175040ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLAllocEnv( HENV* phenv) { env_t* penv; *phenv = penv = (env_t*)MEM_ALLOC(sizeof(env_t)); if ( ! penv ) return SQL_ERROR; penv->herr = 0; penv->hdbc = 0; return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLAllocStmt.c000066400000000000000000000030321446441710500176750ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLAllocStmt( HDBC hdbc, HSTMT* phstmt ) { void* hcndes; void* yystmt; stmt_t* pstmt; *phstmt = 0; hcndes = nnodbc_getnntpcndes(hdbc); if ( ! (yystmt = nnsql_allocyystmt(hcndes)) ) { int code = nnsql_errcode(hcndes); if ( code == -1 ) code = errno; nnodbc_pushdbcerr( hdbc, code, nnsql_errmsg(hcndes)); return SQL_ERROR; } pstmt = (stmt_t*)MEM_ALLOC(sizeof(stmt_t)); if ( !pstmt ) { nnsql_dropyystmt(yystmt); nnodbc_pushdbcerr(hdbc, en_S1001, 0); return SQL_ERROR; } if ( nnodbc_attach_stmt( hdbc, pstmt ) ) { nnsql_dropyystmt(yystmt); MEM_FREE( pstmt ); return SQL_ERROR; } pstmt->yystmt = yystmt; pstmt->herr = 0; pstmt->pcol = 0; pstmt->ppar = 0; pstmt->ndelay = 0; pstmt->hdbc = hdbc; pstmt->refetch = 0; pstmt->putipar = 0; *phstmt = pstmt; return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLBindCol.c000066400000000000000000000036641446441710500173200ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLBindCol( HSTMT hstmt, UWORD icol, SWORD fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD* pcbValue ) { stmt_t* pstmt = hstmt; column_t* pcol; int i, max; UNSET_ERROR( pstmt->herr ); if ( fCType == SQL_C_BOOKMARK ) fCType = SQL_C_ULONG; switch (fCType) { case SQL_C_DEFAULT: case SQL_C_CHAR: case SQL_C_TINYINT: case SQL_C_STINYINT: case SQL_C_UTINYINT: case SQL_C_SHORT: case SQL_C_SSHORT: case SQL_C_USHORT: case SQL_C_LONG: case SQL_C_SLONG: case SQL_C_ULONG: case SQL_C_DATE: break; default: PUSHSQLERR( pstmt->herr, en_S1C00 ); return SQL_ERROR; } max = nnsql_max_column(); if ( icol > (UWORD)max ) { PUSHSQLERR( pstmt->herr, en_S1002 ); return SQL_ERROR; } if ( ! pstmt->pcol ) { if ( ! rgbValue ) return SQL_SUCCESS; pstmt->pcol = (column_t*)MEM_ALLOC( sizeof(column_t)*(max+1) ); if ( ! pstmt->pcol ) { PUSHSQLERR( pstmt->herr, en_S1001 ); return SQL_ERROR; } MEM_SET(pstmt->pcol, 0, sizeof(column_t)*(max+1) ); } pcol = pstmt->pcol + icol; pcol->ctype = fCType; pcol->userbuf = rgbValue; pcol->userbufsize = cbValueMax; pcol->pdatalen = (long*) pcbValue; pcol->offset = 0; return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLBindParameter.c000066400000000000000000000056521446441710500205220ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLBindParameter( HSTMT hstmt, UWORD ipar, SWORD fParamType, SWORD fCType, SWORD fSqlType, UDWORD cbColDef, SWORD ibScale, PTR rgbValue, SDWORD cbValueMax, SDWORD* pcbValue) { param_t* ppar; int i, max; stmt_t* pstmt = hstmt; fptr_t cvt; UNSET_ERROR( pstmt->herr ); max = nnsql_max_param(); if ( ipar > (UWORD)max ) { PUSHSQLERR( pstmt->herr, en_S1093); return SQL_ERROR; } if ( fCType == SQL_C_DEFAULT ) { switch ( fSqlType ) { case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: fCType = SQL_C_CHAR; break; case SQL_TINYINT: fCType = SQL_C_STINYINT; break; case SQL_SMALLINT: fCType = SQL_C_SSHORT; break; case SQL_INTEGER: fCType = SQL_C_SLONG; break; case SQL_DATE: fCType = SQL_C_DATE; break; default: PUSHSQLERR( pstmt->herr, en_S1C00 ); return SQL_ERROR; } } cvt = nnodbc_get_c2sql_cvt( fCType, fSqlType); if ( ! cvt ) { PUSHSQLERR( pstmt->herr, en_07006 ); return SQL_ERROR; } if ( ! pstmt->ppar ) { int i; pstmt->ppar = (param_t*)MEM_ALLOC( sizeof(param_t)*max ); if ( ! pstmt->ppar ) { PUSHSQLERR( pstmt->herr, en_S1001 ); return SQL_ERROR; } ppar = pstmt->ppar; MEM_SET( ppar, 0, sizeof(param_t)*max ); for (i=0; i< max; i++ ) { ppar->bind = 0; ppar ++; } } ppar = pstmt->ppar + ipar - 1; ppar->bind = 1; ppar->type = fParamType; ppar->coldef = cbColDef; ppar->scale = ibScale; ppar->userbuf = rgbValue; ppar->userbufsize = cbValueMax; ppar->pdatalen = (long*) pcbValue; ppar->ctype = fCType; ppar->sqltype = fSqlType; ppar->cvt = cvt; return SQL_SUCCESS; } RETCODE SQL_API SQLSetParam ( HSTMT hstmt, UWORD ipar, SWORD fCType, SWORD fSqlType, UDWORD cbColDef, SWORD ibScale, PTR rgbValue, SDWORD FAR *pcbValue) { return SQLBindParameter(hstmt, ipar, (SWORD)SQL_PARAM_INPUT_OUTPUT, fCType, fSqlType, cbColDef, ibScale, rgbValue, SQL_SETPARAM_VALUE_MAX, pcbValue ); } unixODBC-2.3.12/Drivers/nn/SQLCancel.c000066400000000000000000000021671446441710500171700ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLCancel( HSTMT hstmt) { stmt_t* pstmt = hstmt; param_t* ppar; int i, npar; UNSET_ERROR( pstmt->herr ); npar = nnsql_getparnum(pstmt->yystmt); for (i=1, ppar = pstmt->ppar; ppar && i < npar + 1; i++, ppar++ ) { nnsql_yyunbindpar( pstmt->yystmt, i); MEM_FREE(ppar->putdtbuf); ppar->putdtbuf = 0; ppar->putdtlen = 0; ppar->need = 0; } pstmt->ndelay = 0; pstmt->putipar= 0; return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLConnect.c000066400000000000000000000025111446441710500173650ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLConnect( HDBC hdbc, UCHAR* szDSN, SWORD cbDSN, UCHAR* szUID, SWORD cbUID, UCHAR* szAuthStr, SWORD cbAuthStr) { dbc_t* pdbc = hdbc; char* ptr; char buf[64]; UNSET_ERROR( pdbc->herr ); ptr = (char*)getkeyvalbydsn( (char*)szDSN, cbDSN, "Server", buf, sizeof(buf)); if ( ! ptr ) { PUSHSQLERR( pdbc->herr, en_IM002 ); return SQL_ERROR; } pdbc->hcndes = nntp_connect(ptr); if ( ! pdbc->hcndes ) { PUSHSQLERR( pdbc->herr, en_08001 ); PUSHSYSERR( pdbc->herr, errno, nntp_errmsg(0)); return SQL_ERROR; } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLDescribeCol.c000066400000000000000000000043051446441710500201550ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLDescribeCol( HSTMT hstmt, UWORD icol, UCHAR* szColName, SWORD cbColNameMax, SWORD* pcbColName, SWORD* pfSqlType, UDWORD* pcbColDef, SWORD* pibScale, SWORD* pfNullable ) { stmt_t* pstmt = hstmt; char* colname; int colnamelen, sqltype, precision, ncol; RETCODE retcode = SQL_SUCCESS; UNSET_ERROR( pstmt->herr ); ncol = nnsql_getcolnum(pstmt->yystmt); if ( icol > (UWORD)(ncol - 1) ) { PUSHSQLERR( pstmt->herr, en_S1002 ); return SQL_ERROR; } colname = nnsql_getcolnamebyidx( nnsql_column_descid(pstmt->yystmt, icol) ); colnamelen = STRLEN(colname); if ( szColName ) { if ( cbColNameMax < colnamelen + 1 ) { colnamelen = cbColNameMax - 1; PUSHSQLERR( pstmt->herr, en_01004 ); retcode = SQL_SUCCESS_WITH_INFO; } STRNCPY( szColName, colname, colnamelen); szColName[colnamelen] = 0; if ( pcbColName ) *pcbColName = colnamelen; } if ( nnsql_isstrcol(pstmt->yystmt, icol) ) { sqltype = SQL_LONGVARCHAR; precision = SQL_NO_TOTAL; } else if ( nnsql_isnumcol(pstmt->yystmt, icol) ) { sqltype = SQL_INTEGER; precision = 10; } else if ( nnsql_isdatecol(pstmt->yystmt, icol) ) { sqltype = SQL_DATE; precision = 10; } else { sqltype= 0; precision = SQL_NO_TOTAL; } if ( pfSqlType ) *pfSqlType = sqltype; if ( pcbColDef ) *pcbColDef = precision; if ( pfNullable ) *pfNullable = nnsql_isnullablecol(pstmt->yystmt, icol); return retcode; } unixODBC-2.3.12/Drivers/nn/SQLDisconnect.c000066400000000000000000000016641446441710500200750ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLDisconnect( HDBC hdbc) { dbc_t* pdbc = hdbc; UNSET_ERROR( pdbc->herr ); for (;pdbc->stmt;) nnodbc_sqlfreestmt(pdbc->stmt->hstmt, SQL_DROP); nntp_close( pdbc->hcndes ); pdbc->hcndes = 0; return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLDriverConnect.c000066400000000000000000000042161446441710500205450ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLDriverConnect( HDBC hdbc, HWND hwnd, UCHAR* szConnStrIn, SWORD cbConnStrIn, UCHAR* szConnStrOut, SWORD cbConnStrOutMax, SWORD* pcbConnStrOut, UWORD fDriverCompletion) { dbc_t* pdbc = hdbc; char *dsn, *server; char buf[64]; int sqlstat = en_00000; UNSET_ERROR( pdbc->herr ); server = getkeyvalinstr((char*)szConnStrIn, cbConnStrIn, "Server", buf, sizeof(buf)); if ( ! server ) { dsn = getkeyvalinstr((char*)szConnStrIn, cbConnStrIn, "DSN", buf, sizeof(buf)); if ( !dsn ) dsn = "default"; server = getkeyvalbydsn((char*)dsn, SQL_NTS, "Server", buf, sizeof(buf)); } if ( ! server ) buf[0] = 0; switch ( fDriverCompletion ) { case SQL_DRIVER_NOPROMPT: break; case SQL_DRIVER_COMPLETE: case SQL_DRIVER_COMPLETE_REQUIRED: if ( ! server ) break; /* to next case */ case SQL_DRIVER_PROMPT: sqlstat = en_IM008; break; default: sqlstat = en_S1110; break; } if ( sqlstat != en_00000 ) { PUSHSQLERR( pdbc->herr, sqlstat ); return SQL_ERROR; } if ( !server ) { PUSHSYSERR( pdbc->herr, en_S1000, NNODBC_ERRHEAD "server name or address not specified" ); return SQL_ERROR; } pdbc->hcndes = nntp_connect(server); if ( ! pdbc->hcndes ) { PUSHSQLERR( pdbc->herr, en_08001 ); PUSHSYSERR( pdbc->herr, errno, nntp_errmsg(0)); return SQL_ERROR; } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLError.c000066400000000000000000000033351446441710500170720ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLError( HENV henv, HDBC hdbc, HSTMT hstmt, UCHAR* szSqlStat, SDWORD* pNativeCode, UCHAR* szMsg, SWORD cbMsgMax, SWORD* pcbMsg ) { void* herr; char* ststr; if ( hstmt ) herr = nnodbc_getstmterrstack(hstmt); else if ( hdbc ) herr = nnodbc_getdbcerrstack(hdbc); else if ( henv ) herr = nnodbc_getenverrstack(henv); if ( nnodbc_errstkempty(herr) ) return SQL_NO_DATA_FOUND; ststr = nnodbc_getsqlstatstr(herr); if (!ststr) ststr = "S1000"; if ( szSqlStat ) STRCPY( szSqlStat, ststr ); if ( pNativeCode ) *pNativeCode = nnodbc_getnativcode(herr); if ( szMsg ) { char buf[128]; char* msg; msg = nnodbc_getsqlstatmsg(herr); if ( !msg ) msg = nnodbc_getnativemsg( herr ); if ( !msg ) msg = "(null)"; sprintf(buf, NNODBC_ERRHEAD "%s", msg); STRNCPY( szMsg, buf, cbMsgMax ); szMsg[cbMsgMax-1]=0; if ( pcbMsg ) *pcbMsg = STRLEN(szMsg); } else if (pcbMsg) *pcbMsg = 0; nnodbc_poperr(herr); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLExecDirect.c000066400000000000000000000021011446441710500200060ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLExecDirect( HSTMT hstmt, UCHAR* szSqlStr, SDWORD cbSqlStr ) { stmt_t* pstmt = hstmt; int sqlcode; UNSET_ERROR( pstmt->herr ); sqlcode = nnodbc_sqlprepare( hstmt, (char*)szSqlStr, cbSqlStr); if ( sqlcode != SQL_SUCCESS && sqlcode != SQL_SUCCESS_WITH_INFO ) return sqlcode; sqlcode |= sqlexecute(hstmt); return sqlcode; } unixODBC-2.3.12/Drivers/nn/SQLExecute.c000066400000000000000000000015021446441710500173750ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLExecute ( HSTMT hstmt ) { stmt_t* pstmt = hstmt; UNSET_ERROR( pstmt->herr ); return sqlexecute(hstmt); } unixODBC-2.3.12/Drivers/nn/SQLFetch.c000066400000000000000000000060441446441710500170320ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLFetch( HSTMT hstmt ) { stmt_t* pstmt = hstmt; column_t* pcol = pstmt->pcol; int ncol, i; long len, clen; char* ptr; int sqltype, sqlstat, dft_ctype, flag = 0, err; fptr_t cvt; char* ret; UNSET_ERROR( pstmt->herr ); ncol = nnsql_getcolnum(pstmt->yystmt); if ( !pstmt->refetch && (err = nnsql_fetch(pstmt->yystmt)) ) { int code; if ( err == 100 ) return SQL_NO_DATA_FOUND; code = nnsql_errcode(pstmt->yystmt); if ( code == -1 ) code = errno; PUSHSYSERR( pstmt->herr, code, nnsql_errmsg(pstmt->yystmt)); return SQL_ERROR; } if ( !pcol ) { int max; max = nnsql_max_column(); pcol = pstmt->pcol = (column_t*)MEM_ALLOC( sizeof(column_t)*(max+1) ); if ( ! pcol ) { PUSHSQLERR( pstmt->herr, en_S1001 ); return SQL_ERROR; } MEM_SET(pcol, 0, sizeof(column_t)*(max+1) ); return SQL_SUCCESS; } for (i=0;ioffset = 0; if ( ! pcol->userbuf ) continue; if ( nnsql_isnullcol(pstmt->yystmt, i) ) { if ( pcol->pdatalen ) *(pcol->pdatalen) = SQL_NULL_DATA; continue; } if ( pcol->pdatalen ) *(pcol->pdatalen ) = 0L; if ( nnsql_isstrcol(pstmt->yystmt, i) ) { ptr = nnsql_getstr(pstmt->yystmt, i); len = STRLEN(ptr) + 1; sqltype = SQL_CHAR; dft_ctype = SQL_C_CHAR; } else if ( nnsql_isnumcol(pstmt->yystmt, i) ) { ptr = (char*)nnsql_getnum(pstmt->yystmt, i); sqltype = SQL_INTEGER; dft_ctype = SQL_C_LONG; } else if ( nnsql_isdatecol(pstmt->yystmt, i) ) { ptr = (char*)nnsql_getdate(pstmt->yystmt, i); sqltype = SQL_DATE; dft_ctype = SQL_C_DATE; } else abort(); if ( pcol->ctype == SQL_C_DEFAULT ) pcol->ctype = dft_ctype; cvt = nnodbc_get_sql2c_cvt(sqltype, pcol->ctype); if ( ! cvt ) { pstmt->refetch = 1; PUSHSQLERR(pstmt->herr, en_07006); return SQL_ERROR; } ret = cvt( ptr, pcol->userbuf, pcol->userbufsize, &clen); if ( ret ) { pstmt->refetch = 1; if ( clen ) sqlstat = en_22003; else sqlstat = en_22005; PUSHSQLERR( pstmt->herr, sqlstat ); return SQL_ERROR; } if ( len && clen == len ) flag = 1; if ( len && pcol->pdatalen ) *(pcol->pdatalen) = clen; /* not 'len' but 'clen' */ } if ( flag ) { PUSHSQLERR( pstmt->herr, en_01004 ); return SQL_SUCCESS_WITH_INFO; } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLFreeConnect.c000066400000000000000000000021611446441710500201700ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLFreeConnect( HDBC hdbc) { dbc_t* tpdbc; dbc_t* pdbc = hdbc; env_t* penv = pdbc->henv; UNSET_ERROR( pdbc->herr ); for ( tpdbc = penv->hdbc; tpdbc; tpdbc = tpdbc->next ) { if ( pdbc == tpdbc ) { penv->hdbc = pdbc->next; break; } if ( pdbc == tpdbc->next ) { tpdbc->next = pdbc->next; break; } } CLEAR_ERROR( pdbc->herr ); MEM_FREE( pdbc ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLFreeEnv.c000066400000000000000000000014741446441710500173350ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLFreeEnv( HENV henv) { CLEAR_ERROR( ((env_t*)henv)->herr ); MEM_FREE( henv ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLFreeStmt.c000066400000000000000000000014621446441710500175310ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLFreeStmt( HSTMT hstmt, UWORD fOption ) { return nnodbc_sqlfreestmt(hstmt, fOption); } unixODBC-2.3.12/Drivers/nn/SQLGetConnectOption.c000066400000000000000000000024271446441710500212240ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLGetConnectOption(HDBC hdbc, UWORD fOption, PTR pvParam) { dbc_t* pdbc = hdbc; UDWORD opt; UNSET_ERROR( pdbc->herr ); if ( fOption == SQL_ACCESS_MODE ) { switch (nntp_getaccmode(pdbc->hcndes)) { case ACCESS_MODE_SELECT: opt = SQL_MODE_READ_ONLY; break; case ACCESS_MODE_INSERT: case ACCESS_MODE_DELETE_TEST: case ACCESS_MODE_DELETE_ANY: opt = SQL_MODE_READ_WRITE; break; default: opt = SQL_MODE_DEFAULT; break; } if (pvParam) *((UDWORD*)pvParam) = opt; return SQL_SUCCESS; } PUSHSQLERR( pdbc->herr, en_S1C00 ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/nn/SQLGetData.c000066400000000000000000000057421446441710500173160ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLGetData( HSTMT hstmt, UWORD icol, SWORD fCType, PTR rgbValue, SDWORD cbValueMax, SDWORD* pcbValue ) { stmt_t* pstmt = hstmt; column_t* pcol; int ncol, flag = 0, clen = 0, len = 0; int sqltype, dft_ctype, sqlstat; char* ptr; char* ret; fptr_t cvt; UNSET_ERROR( pstmt->herr ); ncol = nnsql_getcolnum(pstmt->yystmt); if ( icol >= (UWORD)ncol ) { PUSHSQLERR( pstmt->herr, en_S1002 ); return SQL_ERROR; } pcol = pstmt->pcol + icol; if ( pcol->offset == -1 ) return SQL_NO_DATA_FOUND; if ( fCType == SQL_C_BOOKMARK ) fCType = SQL_C_ULONG; switch (fCType) { case SQL_C_DEFAULT: case SQL_C_CHAR: case SQL_C_TINYINT: case SQL_C_STINYINT: case SQL_C_UTINYINT: case SQL_C_SHORT: case SQL_C_SSHORT: case SQL_C_USHORT: case SQL_C_LONG: case SQL_C_SLONG: case SQL_C_ULONG: case SQL_C_DATE: break; default: PUSHSQLERR( pstmt->herr, en_S1C00 ); return SQL_ERROR; } if ( nnsql_isnullcol(pstmt->yystmt, icol) ) { if ( pcbValue ) *pcbValue = SQL_NULL_DATA; return SQL_SUCCESS; } if ( pcbValue ) *pcbValue = 0L; if ( nnsql_isstrcol(pstmt->yystmt, icol) ) { ptr = nnsql_getstr(pstmt->yystmt, icol) + pcol->offset; len = STRLEN(ptr) + 1; sqltype = SQL_CHAR; dft_ctype = SQL_C_CHAR; } else if ( nnsql_isnumcol(pstmt->yystmt, icol) ) { ptr = (char*)nnsql_getnum(pstmt->yystmt, icol); sqltype = SQL_INTEGER; dft_ctype = SQL_C_LONG; } else if ( nnsql_isdatecol(pstmt->yystmt, icol) ) { ptr = (char*)nnsql_getdate(pstmt->yystmt, icol); sqltype = SQL_DATE; dft_ctype = SQL_C_DATE; } else abort(); if ( fCType == SQL_C_DEFAULT ) fCType = dft_ctype; cvt = nnodbc_get_sql2c_cvt(sqltype, fCType); if ( ! cvt ) { PUSHSQLERR(pstmt->herr, en_07006); return SQL_ERROR; } ret = cvt(ptr, rgbValue, cbValueMax, &clen); if ( ret ) { if ( clen ) sqlstat = en_22003; else sqlstat = en_22005; PUSHSQLERR( pstmt->herr, sqlstat ); return SQL_ERROR; } if ( len && clen == cbValueMax ) { flag = 1; pcol->offset += (clen - 1); } else pcol->offset = -1; if ( len && pcbValue ) *pcbValue = len; /* not 'clen' but 'len' */ if ( flag ) { PUSHSQLERR(pstmt->herr, en_01004 ); return SQL_SUCCESS_WITH_INFO; } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLNumParams.c000066400000000000000000000016321446441710500177020ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLNumParams( HSTMT hstmt, SWORD *pcpar ) { stmt_t* pstmt = hstmt; UNSET_ERROR( pstmt->herr ); if ( pcpar ) *pcpar = nnsql_getparnum( ((stmt_t*)hstmt)->yystmt ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLNumResultCols.c000066400000000000000000000017221446441710500205560ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLNumResultCols( HSTMT hstmt, SWORD* pccol ) { stmt_t* pstmt = hstmt; UNSET_ERROR( pstmt->herr ); if ( pccol ) { int ncol; ncol = nnsql_getcolnum(((stmt_t*)hstmt)->yystmt); *pccol = (ncol)? ncol-1:0; } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLParamData.c000066400000000000000000000037701446441710500176360ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLParamData( HSTMT hstmt, PTR* prgbValue) { stmt_t* pstmt = hstmt; int ipar; param_t* ppar; fptr_t cvt; char* data; date_t dt; UNSET_ERROR( pstmt->herr ); ipar = pstmt->putipar; ppar = pstmt->ppar + ipar - 1; if ( ipar ) { ppar->need = 0; pstmt->ndelay --; if ( ppar->ctype == SQL_C_CHAR ) { if ( ! ppar->putdtbuf && ! ppar->putdtlen ) data = 0; else { cvt = ppar->cvt; data= cvt(ppar->putdtbuf, ppar->putdtlen, &dt); } MEM_FREE( ppar->putdtbuf ); ppar->putdtbuf = 0; ppar->putdtlen = 0; if ( data == (char*)(-1) ) { PUSHSQLERR( pstmt->herr, en_S1000 ); return SQL_ERROR; } sqlputdata( pstmt, ipar, data ); } } if ( pstmt->ndelay ) { for (ipar++, ppar++;;) { if ( ppar->need ) { *prgbValue = (PTR)(ppar->userbuf); pstmt->putipar = ipar; return SQL_NEED_DATA; } } } if ( nnsql_execute(pstmt->yystmt) ) { int code; code = nnsql_errcode( pstmt->yystmt ); if ( code == -1 ) code = errno; PUSHSYSERR( pstmt->herr, code, nnsql_errmsg(pstmt->yystmt)); return SQL_ERROR; } if ( ! nnsql_getcolnum(pstmt->yystmt) && nnsql_getrowcount(pstmt->yystmt) > 1 ) { PUSHSQLERR( pstmt->herr, en_01S04); return SQL_SUCCESS_WITH_INFO; } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLPrepare.c000066400000000000000000000016341446441710500173770ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLPrepare( HSTMT hstmt, UCHAR* szSqlStr, SDWORD cbSqlStr ) { stmt_t* pstmt = hstmt; UNSET_ERROR( pstmt->herr ); return nnodbc_sqlprepare(hstmt, (char*)szSqlStr, cbSqlStr); } unixODBC-2.3.12/Drivers/nn/SQLPutData.c000066400000000000000000000034721446441710500173450ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLPutData( HSTMT hstmt, PTR rgbValue, SDWORD cbValue) { stmt_t* pstmt = hstmt; param_t* ppar; char* ptr; fptr_t cvt; char* data; date_t dt; UNSET_ERROR( pstmt->herr ); ppar = pstmt->ppar + pstmt->putipar - 1; if ( ppar->ctype == SQL_C_CHAR ) { if ( cbValue == SQL_NULL_DATA ) return SQL_SUCCESS; if ( cbValue == SQL_NTS ) cbValue = STRLEN(rgbValue); if ( ! ppar->putdtbuf ) { ppar->putdtbuf = (char*)MEM_ALLOC(cbValue + 1); } else if ( cbValue ) { ppar->putdtbuf = (char*)MEM_REALLOC( ppar->putdtbuf, ppar->putdtlen + cbValue + 1); } if ( ! ppar->putdtbuf ) { PUSHSQLERR(pstmt->herr, en_S1001); return SQL_ERROR; } ptr = ppar->putdtbuf + ppar->putdtlen; STRNCPY(ptr, rgbValue, cbValue); ptr[cbValue] = 0; ppar->putdtlen += cbValue; return SQL_SUCCESS; } cvt = ppar->cvt; data= cvt(ppar->putdtbuf, ppar->putdtlen, &dt); if ( data == (char*)(-1) ) { PUSHSQLERR( pstmt->herr, en_S1000 ); return SQL_ERROR; } sqlputdata( pstmt, pstmt->putipar, data ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLRowCount.c000066400000000000000000000016331446441710500175600ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLRowCount( HSTMT hstmt, SDWORD* pcrow ) { stmt_t* pstmt = hstmt; UNSET_ERROR( pstmt->herr ); if ( pcrow ) *pcrow = nnsql_getrowcount( ((stmt_t*)hstmt)->yystmt ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/SQLSetConnectOption.c000066400000000000000000000023521446441710500212350ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" RETCODE SQL_API SQLSetConnectOption(HDBC hdbc, UWORD fOption, UDWORD vParam) { dbc_t* pdbc = hdbc; UNSET_ERROR( pdbc->herr ); if ( fOption == SQL_ACCESS_MODE ) { switch (vParam) { case SQL_MODE_READ_ONLY: nntp_setaccmode( pdbc->hcndes, ACCESS_MODE_SELECT ); break; case SQL_MODE_READ_WRITE: nntp_setaccmode( pdbc->hcndes, ACCESS_MODE_DELETE_TEST ); break; default: PUSHSQLERR(pdbc->herr, en_S1009 ); return SQL_ERROR; } return SQL_SUCCESS; } PUSHSQLERR(pdbc->herr, en_S1C00 ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/nn/SQLSetParam.c000066400000000000000000000000431446441710500175060ustar00rootroot00000000000000/* Moved to SQLBindParameter.c. */ unixODBC-2.3.12/Drivers/nn/TODO000066400000000000000000000004631446441710500157440ustar00rootroot00000000000000TODO ---- 0. standardize makefile(s) 1. modularize to the function level 2. get all sources to reside in one dir 3. replace redundent code with unixODBC libs such as odbcinst 4. update function declares to ODBC 3.5.1 standard 5. implement catalog functions ( SQLTables, SQLColumns... ) - Peter Harvey unixODBC-2.3.12/Drivers/nn/connect.c000066400000000000000000000136721446441710500170570ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" void* nnodbc_getenverrstack(void* henv) { return ((env_t*)henv)->herr; } void* nnodbc_getdbcerrstack(void* hdbc) { return ((dbc_t*)hdbc)->herr; } void nnodbc_pushdbcerr( void* hdbc, int code, char* msg ) { PUSHSYSERR( ((dbc_t*)hdbc)->herr, code, msg ); } void* nnodbc_getnntpcndes( void* hdbc ) { return ((dbc_t*)hdbc)->hcndes; } int nnodbc_attach_stmt(void* hdbc, void* hstmt) { dbc_t* pdbc = hdbc; gstmt_t* pstmt; pstmt = (gstmt_t*)MEM_ALLOC(sizeof(gstmt_t)); if( ! pstmt ) { PUSHSQLERR( pdbc->herr, en_S1001 ); return SQL_ERROR; } pstmt->next = pdbc->stmt; pdbc->stmt = pstmt; pstmt->hstmt= hstmt; pstmt->hdbc = pdbc; return SQL_SUCCESS; } int nnodbc_detach_stmt(void* hdbc, void* hstmt) { dbc_t* pdbc = hdbc; gstmt_t* pstmt; gstmt_t* ptr; for(pstmt=pdbc->stmt;pstmt;pstmt = pstmt->next) { if(pstmt->hstmt == hstmt) { pdbc->stmt = pstmt->next; MEM_FREE(pstmt); return 0; } if(pstmt->next->hstmt == hstmt ) { ptr = pstmt->next; pstmt->next = ptr->next; MEM_FREE(ptr); return 0; } } return -1; } char* /* return new position in input str */ readtoken( char* istr, /* old position in input buf */ char* obuf ) /* token string ( if "\0", then finished ) */ { for(; *istr && *istr != '\n' ; istr ++ ) { char c, nx; c = *(istr); if( c == ' ' || c == '\t' ) { continue; } nx = *(istr + 1); *obuf = c; obuf ++; if( c == ';' || c == '=' ) { istr ++; break; } if( nx == ' ' || nx == '\t' || nx == ';' || nx == '=' ) { istr ++; break; } } *obuf = '\0'; return istr; } #if !defined(WINDOWS) && !defined(WIN32) && !defined(OS2) # include # include # define UNIX_PWD #endif char* getinitfile(char* buf, int size) { int i, j; char* ptr; j = STRLEN("/odbc.ini") + 1; if( size < j ) { return NULL; } #if !defined(UNIX_PWD) i = GetWindowsDirectory((LPSTR)buf, size ); if( i == 0 || i > size - j ) { return NULL; } sprintf( buf + i, "/odbc.ini"); return buf; #else ptr = (char*)getpwuid(getuid()); if( ptr == NULL ) { return NULL; } ptr = ((struct passwd*)ptr)->pw_dir; if( ptr == NULL || *ptr == '\0' ) { ptr = "/home"; } if( size < STRLEN(ptr) + j ) { return NULL; } sprintf( buf, "%s%s", ptr, "/.odbc.ini"); /* i.e. searching ~/.odbc.ini */ #endif return buf; } char* getkeyvalbydsn( char* dsn, int dsnlen, char* keywd, char* value, int size ) /* read odbc init file to resolve the value of specified * key from named or defaulted dsn section */ { char buf[1024]; char dsntk[SQL_MAX_DSN_LENGTH + 3] = { '[', '\0' }; char token[1024]; /* large enough */ FILE* file; char pathbuf[1024]; char* path; #define DSN_NOMATCH 0 #define DSN_NAMED 1 #define DSN_DEFAULT 2 int dsnid = DSN_NOMATCH; int defaultdsn = DSN_NOMATCH; if( dsn == NULL || *dsn == 0 ) { dsn = "default"; dsnlen = STRLEN(dsn); } if( dsnlen == SQL_NTS ) { dsnlen = STRLEN(dsn); } if( dsnlen <= 0 || keywd == NULL || buf == 0 || size <= 0 ) { return NULL; } if( dsnlen > sizeof(dsntk) - 2 ) { return NULL; } STRNCAT( dsntk, dsn, dsnlen ); STRCAT( dsntk, "]" ); value[0] = 0; dsnlen = dsnlen + 2; path = getinitfile(pathbuf, sizeof(pathbuf)); if( path == NULL ) { return NULL; } file = (FILE*)fopen(path, "r"); if( file == NULL ) { return NULL; } for(;;) { char* str; str = fgets(buf, sizeof(buf), file); if( str == NULL ) { break; } if( *str == '[' ) { if( upper_strneq(str, "[default]", STRLEN("[default]")) ) { /* we only read first dsn default dsn * section (as well as named dsn). */ if( defaultdsn == DSN_NOMATCH ) { dsnid = DSN_DEFAULT; defaultdsn = DSN_DEFAULT; } else { dsnid = DSN_NOMATCH; } continue; } else if( upper_strneq( str, dsntk, dsnlen ) ) { dsnid = DSN_NAMED; } else { dsnid = DSN_NOMATCH; } continue; } else if( dsnid == DSN_NOMATCH ) { continue; } str = readtoken(str, token); if( upper_strneq( keywd, token, STRLEN(keywd)) ) { str = readtoken(str, token); if( ! STREQ( token, "=") ) /* something other than = */ { continue; } str = readtoken(str, token); if( STRLEN(token) > size - 1) { break; } STRNCPY(value, token, size); /* copy the value(i.e. next token) to buf */ if( dsnid != DSN_DEFAULT ) { break; } } } fclose(file); return (*value)? value:NULL; } char* getkeyvalinstr( char* cnstr, int cnlen, char* keywd, char* value, int size ) { char token[1024] = { '\0' }; int flag = 0; if( cnstr == NULL || value == NULL || keywd == NULL || size < 1 ) { return NULL; } if( cnlen == SQL_NTS ) { cnlen = STRLEN (cnstr); } if( cnlen <= 0 ) { return NULL; } for(;;) { cnstr = readtoken(cnstr, token); if( *token == '\0' ) { break; } if( STREQ( token, ";" ) ) { flag = 0; continue; } switch(flag) { case 0: if( upper_strneq(token, keywd, strlen(keywd)) ) { flag = 1; } break; case 1: if( STREQ( token, "=" ) ) { flag = 2; } break; case 2: if( size < strlen(token) + 1 ) { return NULL; } STRNCPY( value, token, size ); return value; default: break; } } return NULL; } unixODBC-2.3.12/Drivers/nn/connect.h000066400000000000000000000017711446441710500170610ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _CONNECT_H # define _CONNECT_H extern int nnodbc_attach_stmt(void* hdbc, void* hstmt); extern int nnodbc_detach_stmt(void* hdbc, void* hstmt); extern void* nnodbc_getenverrstack(void* henv); extern void* nnodbc_getdbcerrstack(void* hdbc); extern void nnodbc_pushdbcerr(void* hdbc, int code, char* msg); extern void* nnodbc_getnntpcndes(void* hdbc); #endif unixODBC-2.3.12/Drivers/nn/convert.c000066400000000000000000000170421446441710500171010ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" /* It looks silly to use a MEM_ALLOC() in function char2str(), etc, * for converting C data type into STRING SQL data type. Esspecially * for char2str(), simply return the C data buffer address seems can * do the same thing. However, all these 'to STRING' functions are * assumed to be invoked in SQLExecute(), etc. According to ODBC, after * that, user buffers are detached from the statement been executed. * For example, for a statement: * * "SELECT FROM comp.databases WHERE subject LIKE ?" * * You may bind a SQL_C_CHAR data to it as the pattern for the * LIKE condition. After SQLExecute(), the user buffer should be * detached from the statement. You can change the data in that * buffer without worry about the SQLFetch() results will be * affected. If we don't use a separate buffer to keep the user * data at SQLExecute() time but only keep a pointer of user buffer, * then when user changes data in user buffer after SQLExecute() * but before or during SQLFetch()s, the SQLFetch()'s result will * be affected as a result of the change of LIKE condition. * * These allocated memory will be released by SQL layer. */ typedef DATE_STRUCT odbc_date_t; char* char2str( char* buf, int size ) { char* ptr; int len; if( size < 0 ) size = STRLEN(buf); ptr = (char*)MEM_ALLOC(size + 1); if( ! ptr ) return (char*)(-1); STRNCPY(ptr, buf, size+1); ptr[size] = 0; return ptr; } char* char2num( char* buf, int size) { char tbuf[16]; if( size < 0 ) size = strlen(buf); if( size>15 ) size = 15; STRNCPY(tbuf, buf, size); tbuf[15] = 0; return (char*)atol(tbuf); } char* char2date( char* buf, int size, date_t* dt) { char tbuf[16]; if( size < 0 ) size = strlen(buf); if( size > 15 ) size = 15; STRNCPY( tbuf, buf, size); tbuf[15] = 0; if( nnsql_odbcdatestr2date(tbuf, dt) ) return (char*)(-1); return (char*)dt; } char* date2str( odbc_date_t* dt ) { char* ptr; if( dt->year < 0 || dt->year > 9999 || dt->month< 1 || dt->month> 12 || dt->day < 1 || dt->day > 31 || !( ptr = (char*)MEM_ALLOC(12)) ) return (char*)(-1); sprintf(ptr, "%04d-%02d-%02d", dt->year, dt->month, dt->day); return ptr; } char* odate2date( odbc_date_t* odt, int size, date_t* dt ) { if( dt->year < 0 || dt->year > 9999 || dt->month< 1 || dt->month> 12 || dt->day < 1 || dt->day > 31 ) return (char*)(-1); dt->year = odt->year; dt->month= odt->month; dt->day = odt->day; return (char*)dt; } char* tint2num( char* d ) { long num = *d; return (char*)num; } char* short2num( short* d ) { long num = *d; return (char*)num; } char* long2num( long* d ) { return (char*)*d; } char* tint2str( char* d ) { int c = *d; char* ptr; if( ! (ptr = MEM_ALLOC(5)) ) return (char*)(-1); sprintf(ptr, "%d", c); return ptr; } char* short2str( short* d ) { int c = *d; char* ptr; if( ! (ptr = MEM_ALLOC(32)) ) return (char*)(-1); sprintf(ptr, "%d", c); return ptr; } char* long2str( long* d ) { long l = *d; char* ptr; if( ! (ptr = MEM_ALLOC(64)) ) return (char*)(-1); sprintf(ptr, "%ld", l); return ptr; } static fptr_t c2sql_cvt_tab[5][3] = { char2str, char2num, char2date, tint2str, tint2num, 0, short2str, short2num,0, long2str, long2num, 0, date2str, 0, odate2date }; static struct { int ctype; int idx; } ctype_idx_tab[] = { SQL_C_CHAR, 0, SQL_C_TINYINT, 1, SQL_C_STINYINT, 1, SQL_C_UTINYINT, 1, SQL_C_SHORT, 2, SQL_C_SSHORT, 2, SQL_C_USHORT, 2, SQL_C_LONG, 3, SQL_C_SLONG, 3, SQL_C_ULONG, 3, SQL_C_DATE, 4 }; static struct { int sqltype; int idx; } sqltype_idx_tab[] = { SQL_CHAR, 0, SQL_VARCHAR, 0, SQL_LONGVARCHAR,0, SQL_TINYINT, 1, SQL_SMALLINT, 1, SQL_INTEGER, 1, SQL_DATE, 2 }; fptr_t nnodbc_get_c2sql_cvt(int ctype, int sqltype) { int i, cidx = -1, sqlidx = -1; for(i=0; i< sizeof(ctype_idx_tab) / sizeof(ctype_idx_tab[ 0 ]); i++ ) { if( ctype_idx_tab[i].ctype == ctype ) { cidx = ctype_idx_tab[i].idx; break; } } if( cidx == -1 ) return 0; for(i=0; i< sizeof(sqltype_idx_tab) / sizeof(sqltype_idx_tab[ 0 ]); i++ ) { if( sqltype_idx_tab[i].sqltype == sqltype ) { sqlidx = sqltype_idx_tab[i].idx; break; } } if( sqlidx == -1 ) return 0; return c2sql_cvt_tab[cidx][sqlidx]; } static char* str2char( char* ptr, char* buf, long size, long* psize) { long len; len = STRLEN(ptr) + 1; if( len > size ) len = size; if( len ) { STRNCPY( buf, ptr, len ); buf[len - 1] = 0; } *psize = len; return 0; } static char* str2tint( char* ptr, char* buf, long size, long* psize ) { unsigned long a, b = (unsigned char)(-1); a = (unsigned long)atol(ptr); if( a > b ) { *psize = a; return (char*)(-1); } *buf = (char)a; return 0; } static char* str2short( char* ptr, short* buf, long size, long* psize) { unsigned long a, b = (unsigned short)(-1); a = atoi(ptr); if( a > b ) { *psize = a; return (char*)(-1); } *buf = (short)a; return 0; } static char* str2long( char* ptr, long* buf) { *buf = atol(ptr); return 0; } static char* str2date( char* ptr, odbc_date_t* buf ) { date_t dt; if( nnsql_nndatestr2date(ptr, &dt) ) return (char*)(-1); buf->year = dt.year; buf->month= dt.month; buf->day = dt.day; return 0; } static char* num2char( long x, char* buf, long size, long* psize) { char tbuf[48]; sprintf(tbuf, "%ld", x); *psize = STRLEN(buf) + 1; if(*psize > size ) return (char*)(-1); STRCPY(buf, tbuf); return 0; } static char* num2tint(long x, char* buf, long size, long* psize) { unsigned long a = x, b = (unsigned char)(-1); if( a > b ) { *psize = x; return (char*)(-1); } *buf = (char)x; return 0; } static char* num2short(long x, short* buf, long size, long* psize) { unsigned long a = x, b = (unsigned short)(-1); if( a > b) { *psize = x; return (char*)(-1); } *buf = (short)x; return 0; } static char* num2long(long x, long* buf ) { *buf = x; return 0; } static char* date2char(date_t* dt, char* buf, long size, long* psize) { *psize = 11; if(size < 11) return (char*)(-1); sprintf(buf, "%04d-%02d-%02d", dt->year, dt->month, dt->day); return 0; } static char* date2odate(date_t* dt, odbc_date_t* buf) { buf->year = dt->year; buf->month= dt->month; buf->day = dt->day; return 0; } static fptr_t sql2c_cvt_tab[3][5] = { str2char, str2tint, str2short, str2long, str2date, num2char, num2tint, num2short, num2long, 0, date2char, 0, 0, 0, date2odate }; fptr_t nnodbc_get_sql2c_cvt(int sqltype, int ctype) { int i, cidx = -1, sqlidx = -1; for(i=0; i< sizeof(ctype_idx_tab) / sizeof(ctype_idx_tab[ 0 ]); i++ ) { if( ctype_idx_tab[i].ctype == ctype ) { cidx = ctype_idx_tab[i].idx; break; } } if( cidx == -1 ) return 0; for(i=0; i< sizeof(sqltype_idx_tab) / sizeof(sqltype_idx_tab[ 0 ]); i++ ) { if( sqltype_idx_tab[i].sqltype == sqltype ) { sqlidx = sqltype_idx_tab[i].idx; break; } } if( sqlidx == -1 ) return 0; return sql2c_cvt_tab[sqlidx][cidx]; } unixODBC-2.3.12/Drivers/nn/convert.h000066400000000000000000000015171446441710500171060ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _CONVERT_H # define _CONVERT_H typedef char* (*fptr_t)(); extern fptr_t nnodbc_get_c2sql_cvt(int ctype, int sqltype); extern fptr_t nnodbc_get_sql2c_cvt(int sqltype, int ctype); #endif unixODBC-2.3.12/Drivers/nn/driver.h000066400000000000000000000043331446441710500167200ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _H_DRIVER #define _H_DRIVER #include "nnconfig.h" #include "isql.h" #include "isqlext.h" #include "convert.h" #include "yystmt.h" #include "yyerr.h" #include "yyenv.h" #include "hstmt.h" #include "herr.h" typedef struct GSTMT { void* hdbc; void* hstmt; struct GSTMT* next; } gstmt_t; typedef struct DBC { void* hcndes; void* henv; gstmt_t* stmt; void* herr; struct DBC* next; } dbc_t; typedef struct { void* hdbc; void* herr; } env_t; typedef struct { int bind; short type; unsigned long coldef; short scale; char* userbuf; long userbufsize; long* pdatalen; int ctype; int sqltype; fptr_t cvt; /* c to sql type convert function */ /* for SQLPutData() on SQL_CHAR, SQL_VARCHAR, SQL_LONGVARCHAR */ char* putdtbuf; int putdtlen; int need; } param_t; typedef struct { short ctype; char* userbuf; long userbufsize; long* pdatalen; long offset; /* getdata offset */ } column_t; typedef struct { void* herr; void* hdbc; column_t* pcol; /* user bound columns */ param_t* ppar; /* user bound parameters */ int ndelay; /* number of delay parameters */ void* yystmt; /* sql layer object handle */ int refetch; /* need refetch */ int putipar; } stmt_t; #include "connect.h" #include "nnsql.h" #include "nntp.h" char* getkeyvalbydsn( char* dsn, int dsnlen, char* keywd, char* value, int size ); char* getkeyvalinstr( char* cnstr, int cnlen, char* keywd, char* value, int size ); int sqlputdata (stmt_t* pstmt, int ipar, char* data); int sqlexecute (stmt_t* pstmt); int upper_strneq (char* s1, char* s2, int n); #endif unixODBC-2.3.12/Drivers/nn/execute.c000066400000000000000000000062421446441710500170630ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" int sqlputdata ( stmt_t* pstmt, int ipar, char* data ) { param_t* ppar; ppar = pstmt->ppar + ipar - 1; switch( ppar->sqltype ) { case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: if( ! data ) nnsql_putnull(pstmt->yystmt, ipar ); else nnsql_putstr(pstmt->yystmt, ipar, (char*)data); break; case SQL_TINYINT: case SQL_SMALLINT: case SQL_INTEGER: nnsql_putnum(pstmt->yystmt, ipar, (long)data); break; case SQL_DATE: if(!data ) nnsql_putnull(pstmt->yystmt, ipar ); else nnsql_putdate(pstmt->yystmt, ipar, (date_t*)data); break; default: return -1; } return 0; } int sqlexecute ( stmt_t* pstmt) { param_t* ppar = pstmt->ppar; int i, npar, flag = 0; long csize; pstmt->refetch = 0; pstmt->ndelay = 0; npar = nnsql_getparnum(pstmt->yystmt); for( i = 0; ppar && i< npar; i++ ) /* general check */ { ppar = pstmt->ppar + i; if( ! ppar->bind ) { PUSHSQLERR( pstmt->herr, en_07001 ); return SQL_ERROR; } if( ( ! ppar->userbuf && ppar->pdatalen ) || ( ppar->userbuf && ppar->pdatalen && *ppar->pdatalen < 0 && *ppar->pdatalen != SQL_NTS ) ) { if( *ppar->pdatalen || *ppar->pdatalen == (long)SQL_NULL_DATA || *ppar->pdatalen == (long)SQL_DATA_AT_EXEC || *ppar->pdatalen <= (long)SQL_LEN_DATA_AT_EXEC(0) ) continue; PUSHSQLERR( pstmt->herr, en_S1090 ); return SQL_ERROR; } } for( i = 0; ppar && i< npar; i++ ) { char* (*cvt)(); date_t date; char* data; ppar = pstmt->ppar + i; if( ! ppar->pdatalen ) csize = 0; else csize = *(ppar->pdatalen); if( csize == (long)SQL_NULL_DATA ) { nnsql_putnull(pstmt->yystmt, i+1); continue; } if( csize == (long)SQL_DATA_AT_EXEC || csize <= (long)SQL_LEN_DATA_AT_EXEC(0) ) /* delated parameter */ { pstmt->ndelay ++; ppar->need = 1; continue; } cvt = ppar->cvt; data= cvt(ppar->userbuf, csize, &date ); if( data == (char*)(-1) ) { PUSHSQLERR(pstmt->herr, en_S1000 ); return SQL_ERROR; } sqlputdata(pstmt, i+1, data); } if( pstmt->ndelay ) return SQL_NEED_DATA; if( nnsql_execute(pstmt->yystmt) ) { int code; code = nnsql_errcode( pstmt->yystmt ); if( code == -1 ) code = errno; PUSHSYSERR( pstmt->herr, code, nnsql_errmsg(pstmt->yystmt)); return SQL_ERROR; } if( ! nnsql_getcolnum(pstmt->yystmt) && nnsql_getrowcount(pstmt->yystmt) > 1 ) { PUSHSQLERR( pstmt->herr, en_01S04); return SQL_SUCCESS_WITH_INFO; } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/herr.c000066400000000000000000000057531446441710500163670ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include #include #include "herr.ci" typedef struct { int code; /* sqlstat(if msg == null) or native code */ char* msg; } err_t; # define ERRSTACK_DEPTH 3 typedef struct { err_t stack[ERRSTACK_DEPTH]; int top; /* top free slot */ } err_stack_t; void* nnodbc_pusherr(void* stack, int code, char* msg) { err_stack_t* err_stack = stack; if( ! err_stack ) { err_stack = (err_stack_t*)MEM_ALLOC( sizeof(err_stack_t)); if( ! err_stack ) return 0; err_stack->top = 0; } if( err_stack->top < ERRSTACK_DEPTH - 1) err_stack->top ++; (err_stack->stack)[err_stack->top - 1].code = code; (err_stack->stack)[err_stack->top - 1].msg = msg; return err_stack; } int nnodbc_errstkempty(void* stack) { err_stack_t* err_stack = stack; if( ! err_stack || ! err_stack->top ) return 1; return 0; } void nnodbc_errstkunset(void* stack) { if( stack ) ((err_stack_t*)stack)->top = 0; } void nnodbc_poperr(void* stack ) { err_stack_t* err_stack = stack; if( ! nnodbc_errstkempty( err_stack ) ) err_stack->top --; return; } static int is_sqlerr(err_t* err) { return !(err->msg); } int nnodbc_getsqlstatcode(void* stack) { err_stack_t* err_stack = stack; err_t* err; err = err_stack->stack + err_stack->top - 1; if( ! is_sqlerr(err) ) return 0; return err->code; } char* nnodbc_getsqlstatstr(void* stack) { err_stack_t* err_stack = stack; err_t* err; int i; err = err_stack->stack + err_stack->top - 1; if( ! is_sqlerr(err) ) return 0; for(i=0;sqlerrmsg_tab[i].stat;i++) { if( sqlerrmsg_tab[i].code == err->code ) return sqlerrmsg_tab[i].stat; } return 0; } char* nnodbc_getsqlstatmsg(void* stack) { err_stack_t* err_stack = stack; err_t* err; int i; err = err_stack->stack + err_stack->top - 1; if( ! is_sqlerr(err) ) return 0; for(i=0;sqlerrmsg_tab[i].stat;i++) { if( sqlerrmsg_tab[i].code == err->code ) return sqlerrmsg_tab[i].msg; } return 0; } int nnodbc_getnativcode(void* stack) { err_stack_t* err_stack = stack; err_t* err; err = err_stack->stack + err_stack->top - 1; if( is_sqlerr(err) ) return 0; return err->code; } char* nnodbc_getnativemsg(void* stack) { err_stack_t* err_stack = stack; err_t* err; err = err_stack->stack + err_stack->top - 1; return err->msg; } void* nnodbc_clearerr(void* stack) { MEM_FREE(stack); return 0; } unixODBC-2.3.12/Drivers/nn/herr.ci000066400000000000000000000111511446441710500165250ustar00rootroot00000000000000static struct { int code; char* stat; char* msg; } sqlerrmsg_tab[] = { en_00000, "00000", "", en_01000, "01000", "General warning", en_01002, "01002", "Disconnect error", en_01004, "01004", "Data truncated", en_01006, "01006", "Privilege not revoked", en_01S00, "01S00", "Invalid connection string attribute", en_01S01, "01S01", "Error in row", en_01S02, "01S02", "Optional value changed", en_01S03, "01S03", "No rows updated or deleted", en_01S04, "01S04", "More than one row updated or deleted", en_07001, "07001", "Wrong number of parameters", en_07006, "07006", "Restricted data type attribute violation", en_08001, "08001", "Unable to connect to data source", en_08002, "08002", "Connection in use", en_08003, "08003", "Connect not open", en_08004, "08004", "Data source rejected establishment of connection", en_08007, "08007", "Connection failure during transaction", en_08S01, "08S01", "Communication link failure", en_0A000, "0A000", "Feature not supported", en_21S01, "21S01", "Insert value list does not match", en_21S02, "21S02", "Degree of derived table does not match column list", en_22001, "22001", "String data right truncation", en_22003, "22003", "Numeric value out of range", en_22005, "22005", "Error in assignment", en_22008, "22008", "Datetime field overflow", en_22012, "22012", "Division by zero", en_22026, "22026", "String data, length mismatch", en_23000, "23000", "Integrity constraint violation", en_24000, "24000", "Invalid cursor state", en_25000, "25000", "Invalid transaction state", en_28000, "28000", "Invalid authorization specification", en_34000, "34000", "Invalid cursor name", en_37000, "37000", "Syntex error or access violation", en_3C000, "3C000", "Duplicate cursor name", en_40001, "40001", "Serialization failure", en_42000, "42000", "Syntax error or access violation", en_70100, "70100", "Operation aborted", en_IM001, "IM001", "Driver does not support this function", en_IM002, "IM002", "Data source name not found and no default " "driver specified. Driver could not be loaded", en_IM003, "IM003", "Specified driver could not be loaded", en_IM004, "IM004", "Driver's SQLAllocEnv() failed", en_IM005, "IM005", "Driver's SQLAllocConnect() failed", en_IM006, "IM006", "Driver's SQLSetConnectOption failed", en_IM007, "IM007", "No data source or driver specified, dialog prohibited", en_IM008, "IM008", "Dialog failed", en_IM009, "IM009", "Unable to load translation DLL", en_IM010, "IM010", "Data source name too long", en_IM011, "IM011", "Driver name too long", en_IM012, "IM012", "DRIVER keyword syntax error", en_IM013, "IM013", "Trace file error", en_IM014, "IM014", "Try to change tracing file while tracing is on", en_S0001, "S0001", "Base table or view already exists", en_S0002, "S0002", "Base table not found", en_S0011, "S0011", "Index already exists", en_S0012, "S0012", "Index not found", en_S0021, "S0021", "Column already exists", en_S0022, "S0022", "Column not found", en_S0023, "S0023", "No default for column", en_S1000, "S1000", "General error", en_S1001, "S1001", "Memory allocation failure", en_S1002, "S1002", "Invalid column number", en_S1003, "S1003", "Program type out of range", en_S1004, "S1004", "SQL data type out of range", en_S1008, "S1008", "Operation canceled", en_S1009, "S1009", "Invalid argument value", en_S1010, "S1010", "Function sequence error", en_S1011, "S1011", "Operation invalid at this time", en_S1012, "S1012", "Invalid transaction operation code specified", en_S1015, "S1015", "No cursor name available", en_S1090, "S1090", "Invalid string or buffer length", en_S1091, "S1091", "Descriptor type out of range", en_S1092, "S1092", "Option type out of range", en_S1093, "S1093", "Invalid parameter", en_S1094, "S1094", "Invalid scale value", en_S1095, "S1095", "Function type out of range", en_S1096, "S1096", "Information type out of range", en_S1097, "S1097", "Column type out of range", en_S1098, "S1098", "Scope type out of range", en_S1099, "S1099", "Nullable type out of range", en_S1100, "S1100", "Uniquenss option type out of range", en_S1101, "S1101", "Accuracy option type out of range", en_S1103, "S1103", "Direction option out of range", en_S1104, "S1104", "Invalid precision value", en_S1105, "S1105", "Invalid parameter type", en_S1106, "S1106", "Fetch type out of range", en_S1107, "S1107", "Row value out of range", en_S1108, "S1108", "Concurrency option out of range", en_S1109, "S1109", "Invalid cursor position", en_S1110, "S1110", "Invalid driver completion", en_S1111, "S1111", "Invalid bookmark value", en_S1C00, "S1C00", "Driver not capable", en_S1T00, "S1T00", "Timeout expired", -1, 0, 0 }; unixODBC-2.3.12/Drivers/nn/herr.h000066400000000000000000000050021446441710500163570ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _HERR_H # define _HERR_H enum { en_00000 = 0, en_01000, en_01002, en_01004, en_01006, en_01S00, en_01S01, en_01S02, en_01S03, en_01S04, en_07001, en_07006, en_08001, en_08002, en_08003, en_08004, en_08007, en_08S01, en_0A000, en_21S01, en_21S02, en_22001, en_22003, en_22005, en_22008, en_22012, en_22026, en_23000, en_24000, en_25000, en_28000, en_34000, en_37000, en_3C000, en_40001, en_42000, en_70100, en_IM001, en_IM002, en_IM003, en_IM004, en_IM005, en_IM006, en_IM007, en_IM008, en_IM009, en_IM010, en_IM011, en_IM012, en_IM013, en_IM014, en_S0001, en_S0002, en_S0011, en_S0012, en_S0021, en_S0022, en_S0023, en_S1000, en_S1001, en_S1002, en_S1003, en_S1004, en_S1008, en_S1009, en_S1010, en_S1011, en_S1012, en_S1015, en_S1090, en_S1091, en_S1092, en_S1093, en_S1094, en_S1095, en_S1096, en_S1097, en_S1098, en_S1099, en_S1100, en_S1101, en_S1103, en_S1104, en_S1105, en_S1106, en_S1107, en_S1108, en_S1109, en_S1110, en_S1111, en_S1C00, en_S1T00 }; extern void* nnodbc_pusherr (void* stack, int code, char* msg); extern void nnodbc_poperr (void* stack); extern int nnodbc_errstkempty (void* stack); extern void nnodbc_errstkunset (void* stack); extern int nnodbc_getsqlstatcode (void* stack); extern char* nnodbc_getsqlstatstr (void* stack); extern char* nnodbc_getsqlstatmsg (void* stack); extern int nnodbc_getnativcode (void* stack); extern char* nnodbc_getnativemsg (void* stack); extern void* nnodbc_clearerr (void* stack); # define PUSHSQLERR(stack, stat) \ stack = nnodbc_pusherr(stack, stat, 0) # define PUSHSYSERR(stack, code, msg) \ stack = nnodbc_pusherr(stack, code, msg) # define UNSET_ERROR(stack) \ nnodbc_errstkunset(stack) # define CLEAR_ERROR(stack) \ stack = nnodbc_clearerr(stack) # define NNODBC_ERRHEAD "[NetNews ODBC][NNODBC driver]" #endif /* _HERR_H */ unixODBC-2.3.12/Drivers/nn/hstmt.h000066400000000000000000000015361446441710500165660ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _HSTMT_H # define _HSTMT_H extern int nnodbc_sqlfreestmt(void* hstmt, int flag); extern int nnodbc_sqlprepare(void* hstmt, char* str, int len); extern void* nnodbc_getstmterrstack(void* hstmt); #endif unixODBC-2.3.12/Drivers/nn/isql.h000066400000000000000000000042711446441710500163760ustar00rootroot00000000000000#ifndef _INTRINSIC_SQL_H #define _INTRINSIC_SQL_H typedef unsigned char UCHAR; #if (SIZEOF_LONG_INT == 4) typedef long int SDWORD; typedef unsigned long int UDWORD; #else typedef int SDWORD; typedef unsigned int UDWORD; #endif typedef short int SWORD; typedef unsigned short int UWORD; typedef void FAR* PTR; typedef void FAR* HENV; typedef void FAR* HDBC; typedef void FAR* HSTMT; typedef signed short RETCODE; #ifdef WIN32 #define SQL_API __stdcall #else #define SQL_API EXPORT CALLBACK #endif #define ODBCVER 0x0200 #define SQL_MAX_MESSAGE_LENGTH 512 #define SQL_MAX_DSN_LENGTH 32 /* return code */ #define SQL_INVALID_HANDLE (-2) #define SQL_ERROR (-1) #define SQL_SUCCESS 0 #define SQL_SUCCESS_WITH_INFO 1 #define SQL_NO_DATA_FOUND 100 /* standard SQL datatypes (agree with ANSI type numbering) */ #define SQL_CHAR 1 #define SQL_NUMERIC 2 #define SQL_DECIMAL 3 #define SQL_INTEGER 4 #define SQL_SMALLINT 5 #define SQL_FLOAT 6 #define SQL_REAL 7 #define SQL_DOUBLE 8 #define SQL_VARCHAR 12 #define SQL_TYPE_MIN SQL_CHAR #define SQL_TYPE_NULL 0 #define SQL_TYPE_MAX SQL_VARCHAR /* C to SQL datatype mapping */ #define SQL_C_CHAR SQL_CHAR #define SQL_C_LONG SQL_INTEGER #define SQL_C_SHORT SQL_SMALLINT #define SQL_C_FLOAT SQL_REAL #define SQL_C_DOUBLE SQL_DOUBLE #define SQL_C_DEFAULT 99 #define SQL_NO_NULLS 0 #define SQL_NULLABLE 1 #define SQL_NULLABLE_UNKNOWN 2 /* some special length values */ #define SQL_NULL_DATA (-1) #define SQL_DATA_AT_EXEC (-2) #define SQL_NTS (-3) /* SQLFreeStmt flag values */ #define SQL_CLOSE 0 #define SQL_DROP 1 #define SQL_UNBIND 2 #define SQL_RESET_PARAMS 3 /* SQLTransact flag values */ #define SQL_COMMIT 0 #define SQL_ROLLBACK 1 /* SQLColAttributes flag values */ #define SQL_COLUMN_COUNT 0 #define SQL_COLUMN_LABEL 18 #define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL #define SQL_COLUMN_DRIVER_START 1000 #define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT /* Null handles */ #define SQL_NULL_HENV 0 #define SQL_NULL_HDBC 0 #define SQL_NULL_HSTMT 0 #endif unixODBC-2.3.12/Drivers/nn/isqlext.h000066400000000000000000000207661446441710500171260ustar00rootroot00000000000000#ifndef _INTRINSIC_SQLEXT_H # define _INTRINSIC_SQLEXT_H # include # define SQL_STILL_EXECUTING 2 # define SQL_NEED_DATA 99 /* extend SQL datatypes */ # define SQL_DATE 9 # define SQL_TIME 10 # define SQL_TIMESTAMP 11 # define SQL_LONGVARCHAR (-1) # define SQL_BINARY (-2) # define SQL_VARBINARY (-3) # define SQL_LONGVARBINARY (-4) # define SQL_BIGINT (-5) # define SQL_TINYINT (-6) # define SQL_BIT (-7) /* conflict with SQL3 ??? */ # define SQL_TYPE_DRIVER_START (-80) /* C to SQL datatype mapping */ # define SQL_C_DATE SQL_DATE # define SQL_C_TIME SQL_TIME # define SQL_C_TIMESTAMP SQL_TIMESTAMP # define SQL_C_BINARY SQL_BINARY # define SQL_C_BIT SQL_BIT # define SQL_C_TINYINT SQL_TINYINT # define SQL_SIGNED_OFFSET (-20) # define SQL_UNSIGNED_OFFSET (-22) # define SQL_C_SLONG (SQL_C_LONG + SQL_SIGNED_OFFSET) # define SQL_C_SSHORT (SQL_C_SHORT + SQL_SIGNED_OFFSET) # define SQL_C_STINYINT (SQL_TINYINT + SQL_SIGNED_OFFSET) # define SQL_C_ULONG (SQL_C_LONG + SQL_UNSIGNED_OFFSET) # define SQL_C_USHORT (SQL_C_SHORT + SQL_UNSIGNED_OFFSET) # define SQL_C_UTINYINT (SQL_TINYINT + SQL_UNSIGNED_OFFSET) # define SQL_C_BOOKMARK SQL_C_ULONG # if defined(SQL_TYPE_MIN) # undef SQL_TYPE_MIN # define SQL_TYPE_MIN SQL_BIT /* Note:If SQL_BIT uses SQL3 value (i.e. 14) then, * SQL_TYPE_MIN need to be defined as SQL_TINYINT * (i.e. -6). */ # endif # define SQL_ALL_TYPES 0 /* SQLDriverConnect flag values */ # define SQL_DRIVER_NOPROMPT 0 # define SQL_DRIVER_COMPLETE 1 # define SQL_DRIVER_PROMPT 2 # define SQL_DRIVER_COMPLETE_REQUIRED 3 # define SQL_NO_TOTAL (-4) /* SQLSetParam extensions */ # define SQL_DEFAULT_PARAM (-5) # define SQL_IGNORE (-6) # define SQL_LEN_DATA_AT_EXEC_OFFSET (-100) # define SQL_LEN_DATA_AT_EXEC(length) ( SQL_LEN_DATA_AT_EXEC_OFFSET - length ) /* function number for SQLGetFunctions */ # define SQL_API_SQLALLOCCONNECT 1 # define SQL_API_SQLALLOCENV 2 # define SQL_API_SQLALLOCSTMT 3 # define SQL_API_SQLBINDCOL 4 # define SQL_API_SQLCANCEL 5 # define SQL_API_SQLCOLATTRIBUTES 6 # define SQL_API_SQLCONNECT 7 # define SQL_API_SQLDESCRIBECOL 8 # define SQL_API_SQLDISCONNECT 9 # define SQL_API_SQLERROR 10 # define SQL_API_SQLEXECDIRECT 11 # define SQL_API_SQLEXECUTE 12 # define SQL_API_SQLFETCH 13 # define SQL_API_SQLFREECONNECT 14 # define SQL_API_SQLFREEENV 15 # define SQL_API_SQLFREESTMT 16 # define SQL_API_SQLGETCURSORNAME 17 # define SQL_API_SQLNUMRESULTCOLS 18 # define SQL_API_SQLPREPARE 19 # define SQL_API_SQLROWCOUNT 20 # define SQL_API_SQLSETCURSORNAME 21 # define SQL_API_SQLSETPARAM 22 # define SQL_API_SQLTRANSACT 23 # define SQL_NUM_FUNCTIONS 23 # define SQL_EXT_API_START 40 # define SQL_API_SQLCOLUMNS 40 # define SQL_API_SQLDRIVERCONNECT 41 # define SQL_API_SQLGETCONNECTOPTION 42 # define SQL_API_SQLGETDATA 43 # define SQL_API_SQLGETFUNCTIONS 44 # define SQL_API_SQLGETINFO 45 # define SQL_API_SQLGETSTMTOPTION 46 # define SQL_API_SQLGETTYPEINFO 47 # define SQL_API_SQLPARAMDATA 48 # define SQL_API_SQLPUTDATA 49 # define SQL_API_SQLSETCONNECTOPTION 50 # define SQL_API_SQLSETSTMTOPTION 51 # define SQL_API_SQLSPECIALCOLUMNS 52 # define SQL_API_SQLSTATISTICS 53 # define SQL_API_SQLTABLES 54 # define SQL_API_SQLBROWSECONNECT 55 # define SQL_API_SQLCOLUMNPRIVILEGES 56 # define SQL_API_SQLDATASOURCES 57 # define SQL_API_SQLDESCRIBEPARAM 58 # define SQL_API_SQLEXTENDEDFETCH 59 # define SQL_API_SQLFOREIGNKEYS 60 # define SQL_API_SQLMORERESULTS 61 # define SQL_API_SQLNATIVESQL 62 # define SQL_API_SQLNUMPARAMS 63 # define SQL_API_SQLPARAMOPTIONS 64 # define SQL_API_SQLPRIMARYKEYS 65 # define SQL_API_SQLPROCEDURECOLUMNS 66 # define SQL_API_SQLPROCEDURES 67 # define SQL_API_SQLSETPOS 68 # define SQL_API_SQLSETSCROLLOPTIONS 69 # define SQL_API_SQLTABLEPRIVILEGES 70 # define SQL_API_SQLDRIVERS 71 # define SQL_API_SQLBINDPARAMETER 72 # define SQL_EXT_API_LAST SQL_API_SQLBINDPARAMETER # define SQL_API_ALL_FUNCTIONS 0 /* SQLGetInfo infor number */ # define SQL_INFO_FIRST 0 # define SQL_DRIVER_HDBC 3 # define SQL_DRIVER_HENV 4 # define SQL_DRIVER_HSTMT 5 # define SQL_DRIVER_NAME 6 # define SQL_ODBC_VER 10 # define SQL_CURSOR_COMMIT_BEHAVIOR 23 # define SQL_CURSOR_ROLLBACK_BEHAVIOR 24 # define SQL_DEFAULT_TXN_ISOLATION 26 # define SQL_TXN_ISOLATION_OPTION 72 # define SQL_NON_NULLABLE_COLUMNS 75 # define SQL_DRIVER_HLIB 76 # define SQL_DRIVER_ODBC_VER 77 # define SQL_QUALIFIER_LOCATION 114 # define SQL_INFO_LAST SQL_QUALIFIER_LOCATION # define SQL_INFO_DRIVER_START 1000 /* SQL_TXN_ISOLATION_OPTION masks */ # define SQL_TXN_READ_UNCOMMITTED 0x00000001L # define SQL_TXN_READ_COMMITTED 0x00000002L # define SQL_TXN_REPEATABLE_READ 0x00000004L # define SQL_TXN_SERIALIZABLE 0x00000008L # define SQL_TXN_VERSIONING 0x00000010L /* SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR values */ # define SQL_CB_DELETE 0x0000 # define SQL_CB_CLOSE 0x0001 # define SQL_CB_PRESERVE 0x0002 /* options for SQLGetStmtOption/SQLSetStmtOption */ # define SQL_QUERY_TIMEOUT 0 # define SQL_MAX_ROWS 1 # define SQL_NOSCAN 2 # define SQL_MAX_LENGTH 3 # define SQL_ASYNC_ENABLE 4 # define SQL_BIND_TYPE 5 # define SQL_CURSOR_TYPE 6 # define SQL_CONCURRENCY 7 # define SQL_KEYSET_SIZE 8 # define SQL_ROWSET_SIZE 9 # define SQL_SIMULATE_CURSOR 10 # define SQL_RETRIEVE_DATA 11 # define SQL_USE_BOOKMARKS 12 # define SQL_GET_BOOKMARK 13 /* GetStmtOption Only */ # define SQL_ROW_NUMBER 14 /* GetStmtOption Only */ # define SQL_STMT_OPT_MAX SQL_ROW_NUMBER # define SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT /* SQL_QUERY_TIMEOUT options */ # define SQL_QUERY_TIMEOUT_DEFAULT 0UL /* SQL_MAX_ROWS options */ # define SQL_MAX_ROWS_DEFAULT 0UL /* SQL_MAX_LENGTH options */ # define SQL_MAX_LENGTH_DEFAULT 0UL /* SQL_CONCURRENCY options */ # define SQL_CONCUR_READ_ONLY 1 # define SQL_CONCUR_LOCK 2 # define SQL_CONCUR_ROWVER 3 # define SQL_CONCUR_VALUES 4 /* options for SQLSetConnectOption/SQLGetConnectOption */ # define SQL_ACCESS_MODE 101 # define SQL_AUTOCOMMIT 102 # define SQL_LOGIN_TIMEOUT 103 # define SQL_OPT_TRACE 104 # define SQL_OPT_TRACEFILE 105 # define SQL_TRANSLATE_DLL 106 # define SQL_TRANSLATE_OPTION 107 # define SQL_TXN_ISOLATION 108 # define SQL_CURRENT_QUALIFIER 109 # define SQL_ODBC_CURSORS 110 # define SQL_QUIET_MODE 111 # define SQL_PACKET_SIZE 112 # define SQL_CONN_OPT_MAX SQL_PACKET_SIZE # define SQL_CONNECT_OPT_DRVR_START 1000 # define SQL_CONN_OPT_MIN SQL_ACCESS_MODE /* SQL_ACCESS_MODE options */ # define SQL_MODE_READ_WRITE 0UL # define SQL_MODE_READ_ONLY 1UL # define SQL_MODE_DEFAULT SQL_MODE_READ_WRITE /* SQL_AUTOCOMMIT options */ # define SQL_AUTOCOMMIT_OFF 0UL # define SQL_AUTOCOMMIT_ON 1UL # define SQL_AUTOCOMMIT_DEFAULT SQL_AUTOCOMMIT_ON /* SQL_LOGIN_TIMEOUT options */ # define SQL_LOGIN_TIMEOUT_DEFAULT 15UL /* SQL_OPT_TRACE options */ # define SQL_OPT_TRACE_OFF 0UL # define SQL_OPT_TRACE_ON 1UL # define SQL_OPT_TRACE_DEFAULT SQL_OPT_TRACE_OFF # define SQL_OPT_TRACE_FILE_DEFAULT "odbc.log" /* SQL_ODBC_CURSORS options */ # define SQL_CUR_USE_IF_NEEDED 0UL # define SQL_CUR_USE_ODBC 1UL # define SQL_CUR_USE_DRIVER 2UL # define SQL_CUR_DEFAULT SQL_CUR_USE_DRIVER /* Column types and scopes in SQLSpecialColumns. */ # define SQL_BEST_ROWID 1 # define SQL_ROWVER 2 # define SQL_SCOPE_CURROW 0 # define SQL_SCOPE_TRANSACTION 1 # define SQL_SCOPE_SESSION 2 /* Operations in SQLSetPos */ # define SQL_ADD 4 /* Lock options in SQLSetPos */ # define SQL_LOCK_NO_CHANGE 0 # define SQL_LOCK_EXCLUSIVE 1 # define SQL_LOCK_UNLOCK 2 /* SQLExtendedFetch flag values */ # define SQL_FETCH_NEXT 1 # define SQL_FETCH_FIRST 2 # define SQL_FETCH_LAST 3 # define SQL_FETCH_PRIOR 4 # define SQL_FETCH_ABSOLUTE 5 # define SQL_FETCH_RELATIVE 6 # define SQL_FETCH_BOOKMARK 8 /* Defines for SQLBindParameter/SQLProcedureColumns */ # define SQL_PARAM_TYPE_UNKNOWN 0 # define SQL_PARAM_INPUT 1 # define SQL_PARAM_INPUT_OUTPUT 2 # define SQL_RESULT_COL 3 # define SQL_PARAM_OUTPUT 4 /* Defines used by Driver Manager for mapping SQLSetParam to SQLBindParameter */ # define SQL_PARAM_TYPE_DEFAULT SQL_PARAM_INPUT_OUTPUT # define SQL_SETPARAM_VALUE_MAX (-1L) /* SQLStatistics flag values */ # define SQL_INDEX_UNIQUE 0 # define SQL_INDEX_ALL 1 # define SQL_QUICK 0 # define SQL_ENSURE 1 /* SQLSetScrollOption flag values */ # define SQL_SCROLL_FORWARD_ONLY 0L # define SQL_SCROLL_KEYSET_DRIVEN (-1L) # define SQL_SCROLL_DYNAMIC (-2L) # define SQL_SCROLL_STATIC (-3L) typedef struct { SWORD year; UWORD month; UWORD day; } DATE_STRUCT; #endif unixODBC-2.3.12/Drivers/nn/misc.c000066400000000000000000000021611446441710500163500ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include #include "driver.h" int upper_strneq( char* s1, char* s2, int n ) { int i; char c1, c2; for(i=0;i= 'a' && c1 <= 'z' ) c1 += ('A' - 'a'); else if( c1 == '\n' ) c1 = '\0'; if( c2 >= 'a' && c2 <= 'z' ) c2 += ('A' - 'a'); else if( c2 == '\n' ) c2 = '\0'; if( (c1 - c2) || !c1 || !c2 ) break; } return (int)!(c1 - c2); } int nnodbc_conndialog() { return -1; } unixODBC-2.3.12/Drivers/nn/nncol.c000066400000000000000000000034471446441710500165360ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include #include #include "nncol.ci" #include "driver.h" int nnsql_getcolidxbyname( char* col_name ) { int i; for( i= 0; nncol_info_tab[i].idx != en_sql_count; i++ ) { if(upper_strneq( col_name, nncol_info_tab[i].name, 16)) return nncol_info_tab[i].idx; } return -1; } char* nnsql_getcolnamebyidx( int idx ) { int i; if( nncol_info_tab[idx].idx == idx ) return nncol_info_tab[idx].name; for(i=0; nncol_info_tab[i].idx != en_sql_count;i++) { if( nncol_info_tab[i].idx == idx ) return nncol_info_tab[i].name; } return 0; } void* nnsql_getcoldescbyidx( int idx ) { int i; if( nncol_info_tab[idx].idx == idx ) return &(nncol_info_tab[idx]); for(i=0; iname; } int nnsql_getcoldatatypebydesc( void* hdesc ) { col_desc_t* desc = hdesc; return desc->datatype; } int nnsql_getcolnullablebydesc( void* hdesc ) { col_desc_t* desc = hdesc; return desc->nullable; } unixODBC-2.3.12/Drivers/nn/nncol.ci000066400000000000000000000027701446441710500167050ustar00rootroot00000000000000typedef struct { int idx; char* name; int datatype; int nullable; int writable; } col_desc_t; static col_desc_t nncol_info_tab[] = { en_article_num, "Article-Num", en_t_num, 0, 0, en_article_num, "Article", en_t_num, 0, 0, /* alias name */ en_newsgroups, "Newsgroups", en_t_str, 1, 0, en_newsgroups, "Groups", en_t_str, 1, 0, /* alias name */ en_subject, "Subject", en_t_str, 0, 1, en_from, "From", en_t_str, 0, 1, en_sender, "Sender", en_t_str, 1, 1, en_organization,"Organization", en_t_str, 1, 1, en_summary, "Summary", en_t_str, 1, 1, en_keywords, "Keywords", en_t_str, 1, 1, en_expires, "Expires", en_t_str, 1, 1, en_msgid, "Message-ID", en_t_str, 1, 1, en_msgid, "Msgid", en_t_str, 1, 1, /* alias name */ en_references, "References", en_t_str, 1, 1, en_followup_to, "Followup-To", en_t_str, 1, 1, en_reply_to, "Reply-To", en_t_str, 1, 1, en_distribution,"Distribution", en_t_str, 1, 1, en_xref, "Xref", en_t_str, 1, 0, en_host, "NNTP-Posting-Host", en_t_str, 1, 0, en_host, "Host", en_t_str, 1, 0, /* alias name */ en_date, "Date", en_t_date,1, 0, en_path, "Path", en_t_str, 1, 0, en_lines, "Lines", en_t_num, 1, 0, en_x_newsreader,"X-Newsreader", en_t_str, 1, 0, en_x_newsreader,"Agent", en_t_str, 1, 0, /* alias name */ en_body, "Body", en_t_text,0, 1, en_body, "Text", en_t_text,0, 1, /* alias name */ en_sql_count, "count()", en_t_num, 1, 0, en_sql_qstr, "qstring", en_t_str, 1, 0, en_sql_num, "number", en_t_num, 1, 0, en_sql_date, "const. date", en_t_date,1, 0 }; unixODBC-2.3.12/Drivers/nn/nncol.h000066400000000000000000000027061446441710500165400ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _NNCOL_H # define _NNCOL_H # define PRIV_NONE 0 # define PRIV_REFER 1 # define PRIV_SELECT 2 # define PRIV_INSERT 3 # define PRIV_UPDATE 4 enum { en_article_num = 0, en_newsgroups, en_subject, en_from, en_sender, en_organization, en_summary, en_keywords, en_expires, en_msgid, en_references, en_followup_to, en_reply_to, en_distribution, en_xref, en_host, en_date, en_path, en_x_newsreader, en_lines, en_body, en_sql_count, en_sql_qstr, en_sql_num, en_sql_date }; enum { en_t_null, en_t_num, en_t_str, en_t_date, en_t_text }; char* nnsql_getcolnamebyidx(int idx); int nnsql_getcolidxbyname(char* name); void* nnsql_getcoldescbyidx(int idx); char* nnsql_getcolnamebydesc(void* desc); int nnsql_getcoldatetypebydesc(void* desc); int nnsql_getcolnullablebydesc(void* desc); #endif unixODBC-2.3.12/Drivers/nn/nnconfig.h000066400000000000000000000070501446441710500172250ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _NNCONFIG_H #define _NNCONFIG_H # if !defined(WINDOWS) && !defined(WIN32_SYSTEM) # define _UNIX_ # include # include # include # include # define MEM_ALLOC(size) (malloc((size_t)(size))) # define MEM_FREE(ptr) {if(ptr) free(ptr);} # define MEM_REALLOC(ptr, size) (ptr? realloc(ptr, size):malloc(size)) # define STRCPY(t, s) (strcpy((char*)(t), (char*)(s))) # define STRNCPY(t,s,n) (strncpy((char*)(t), (char*)(s), (size_t)(n))) # define STRCAT(t, s) (strcat((char*)(t), (char*)(s))) # define STRNCAT(t,s,n) (strncat((char*)(t), (char*)(s), (size_t)(n))) # define STRCMP(a, b) strcmp((char*)(a), (char*)(b)) # define STRNCMP(a,b,n) strncmp((char*)(a), (char*)(b), n) # define STREQ(a, b) (strcmp((char*)(a), (char*)(b)) == 0) # define STRNEQ(a,b,n) (strncmp((char*)(a), (char*)(b), n)==0) # define STRLEN(str) ((str)? strlen((char*)(str)):0) # define MEM_SET(p,c,n) (memset((char*)p, (int)c, (int)n)) # define EXPORT # define CALLBACK # define FAR typedef signed short SSHORT; typedef short WORD; typedef long DWORD; typedef WORD WPARAM; typedef DWORD LPARAM; typedef void* HWND; typedef int BOOL; # endif /* _UNIX_ */ /* for nntp driver */ # ifdef WINSOCK # define SOCK_CLOSE(sd) closesocket(sock) # define SOCK_FDOPEN(fd, mode) wsa_fdopen(fd, mode) # define SOCK_FCLOSE(stream) wsa_fclose(stream) # define SOCK_FGETS(buf, size, stream) wsa_fgets(buf, size, stream) # define SOCK_FPUTS(str, stream) wsa_fputs(str, stream) # define SOCK_FPRINTF wsa_fprintf # define SOCK_FFLUSH(stream) wsa_fflush(stream) # else # include # define SOCK_CLOSE(sd) close(sd) # define SOCK_FDOPEN(fd, mode) fdopen(fd, mode) # define SOCK_FCLOSE(stream) fclose(stream) # define SOCK_FGETS(buf, size, stream) fgets(buf, size, stream) # define SOCK_FPUTS(str, stream) fputs(str, stream) # define SOCK_FPRINTF fprintf # define SOCK_FFLUSH(stream) fflush(stream) # endif # if defined(WINDOWS) || defined(WIN32_SYSTEM) # include # include # ifdef _MSVC_ # define MEM_ALLOC(size) (fmalloc((size_t)(size))) # define MEM_FREE(ptr) ((ptr)? ffree((PTR)(ptr)):0)) # define STRCPY(t, s) (fstrcpy((char FAR*)(t), (char FAR*)(s))) # define STRNCPY(t,s,n) (fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n))) # define STRLEN(str) ((str)? fstrlen((char FAR*)(str)):0) # define STREQ(a, b) (fstrcmp((char FAR*)(a), (char FAR*)(b) == 0) # endif # ifdef _BORLAND_ # define MEM_ALLOC(size) (farmalloc((unsigned long)(size)) # define MEM_FREE(ptr) ((ptr)? farfree((void far*)(ptr)):0) # define STRCPY(t, s) (_fstrcpy((char FAR*)(t), (char FAR*)(s))) # define STRNCPY(t,s,n) (_fstrncpy((char FAR*)(t), (char FAR*)(s), (size_t)(n))) # define STRLEN(str) ((str)? _fstrlen((char FAR*)(str)):0) # define STREQ(a, b) (_fstrcmp((char FAR*)(a), (char FAR*)(b) == 0) # endif # endif /* WINDOWS */ #endif unixODBC-2.3.12/Drivers/nn/nndate.c000066400000000000000000000056611446441710500166760ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include #include #include "driver.h" static char* month_name[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static int nndate2date(char* str, date_t* date) { int i; char buf[4]; date_t dt; if( STRLEN(str) < STRLEN("yyyy m d") ) return -1; sscanf(str, "%d %s %d", &(dt.day), buf, &(dt.year)); if( dt.year < 100 && dt.year > 0 ) dt.year += 1900; if( dt.day <= 0 || dt.day > 31 ) return -1; if(i = atoi(buf)) { dt.month = i; if( i <= 0 || i > 12 ) return -1; *date = dt; date->month = i; return 0; } for(i=0;i<12;i++) { if( upper_strneq(buf, month_name[i], 3) ) { *date = dt; date->month = i+1; return 0; } } return -1; } int nnsql_nndatestr2date(char* str, date_t* date) /* convert 'dd mm year' or 'week, dd mm year' to date struct */ { int r; date_t dt; if( !str ) { if(date) date->day = 0; return 0; } if(atoi(str)) r = nndate2date(str, &dt); /* a 'dd mm year' string */ else r = nndate2date(str+5, &dt); /* a 'week, dd mm year' string */ if( r ) dt.day = 0; if( date ) *date = dt; return r; } int nnsql_datecmp(date_t* a, date_t* b) { int r; if( (r = a->year - b->year) ) return r; if( (r = a->month- b->month) ) return r; return (a->day - b->day); } int nnsql_odbcdatestr2date(char* str, date_t* date) /* convert 'yyyy-m-d', 'yyyy-mm-dd' or 'yyyy-mmm-dd' or even 'yyyy/mm/dd' * string to date struct */ { date_t dt; int i; if( ! str ) { if( date ) date->day = 0; return 0; } if( STRLEN(str) < STRLEN("yyyy-m-d") ) { if( date ) date->day = 0; return -1; } dt.day = 0; dt.year = atoi(str); str += 5; dt.month = atoi(str); if( dt.month < 0 || dt.month > 12 ) { if(date) date->day = 0; return -1; } if(! dt.month) /* jan to dec */ { for(i=0;i<12;i++) { if( upper_strneq(str, month_name[i], 3) ) { dt.month = i+1; break; } } if( ! dt.month ) { if(date) date->day = 0; return -1; } str += 4; } else { if( *str == '0' || dt.month > 9 ) /* 01 to 12 */ str += 3; else /* 1 to 9 */ str += 2; } dt.day = atoi(str); if( dt.day <= 0 || dt.day > 31 ) { if(date) date->day = 0; return -1; } if(date) *date = dt; return 0; } unixODBC-2.3.12/Drivers/nn/nndate.h000066400000000000000000000016101446441710500166710ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _NN_DATE_H # define _NN_DATE_H typedef struct { int year; int month; int day; } date_t; extern int nnsql_odbcdatestr2date(char*, date_t*); extern int nnsql_nndatestr2date(char*, date_t*); extern int nnsql_datecmp(date_t*, date_t*); #endif unixODBC-2.3.12/Drivers/nn/nnsql.h000066400000000000000000000214411446441710500165570ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _NN_SQL_H # define _NN_SQL_H # include "nndate.h" # include "nncol.h" /* interface of nnsql layer */ /* basic statement handle object */ extern void* nnsql_allocyystmt(void* hcndes); /* Allocating and initiating a statement * handle on a given connection. On success, * a statement handle is returned or null on * failure */ extern void nnsql_dropyystmt(void* hstmt); /* Drop(i.e free and detach from the * connection) it */ extern void nnsql_close_cursor(void* hstmt); /* Close a result set, terminate the * fetching process. */ /* open table(i.e. group) */ extern int nnsql_opentable(void* hstmt, char* table); /* Set the active table(i.e. netnews group). * It returns 0 on success, -1 on failure.*/ /* prepare (i.e. parsing and accessing mode check) */ extern int nnsql_prepare(void* hstmt, char* sqlstmt, int len); /* Parsing the SQL statement and check the * accessing mode for INSERT and DELETE * statement. It returns 0 on success, * -1 on failure. */ /* open table(i.e. group), type check, do insert, search delete */ extern int nnsql_execute(void* hstmt); /* Execute a prepared statement(i.e. commit * the INSERT or DELETE, type check, * set active table or open a result set. * It returns 0 on success, -1 on failure.*/ /* fetch result */ extern int nnsql_fetch(void* hstmt); /* Fetching result from a opened result set. * It returns 0 on success, -1 on failure, 100 * on hitting the end of the result set. * The fetched result at the 'th column * in the current row can be gotten with * nnsql_getxxx(hstmt, icol) calls. The * properties(i.e. null, datatype, etc.) of * the 'th column in the result set can * be gotten with nnsql_isxxxcol(hstmt,icol) * calls. */ /* get column describor id */ extern int nnsql_column_descid(void* hstmt, int icol); /* Getting column describator id(i.e en_subject, * en_from, en_msgid, en_body, etc.) for the * the 'th column of a prepared or * executed statement if a result set will or * already been opened. It returns the * describator id or -1 on failure. Note, the * user column index starts from 1 and * column index 0 is always used as a hidden * internal column, the article number. */ /* max number of parameters/columns */ extern int nnsql_max_param(); /* Return the up limit of parameter number(32)*/ extern int nnsql_max_column(); /* Return the up limit of column number (32)*/ /* get value from column */ extern long nnsql_getnum(void* hstmt, int icol); /* Return a long integer from the 'th * column of the current row of the result set. * If the datatype of this column is not INTEGER * (i.e. NUMBER), this function will return 0. * Using nnsql_isnumcol() to check this before * getting the long integer. */ extern char* nnsql_getstr(void* hstmt, int icol); /* Return an null terminated string at the * 'th column of current row of the result * set. If datatype of this column is STRING, * this function will return an null pointer. * Using nnsql_isstrcol() to check this before * getting a string. The string itself is placed * in an internal buffer. It may be overwritten * by the result of later(if not next) * nnsql_fetch() call. Thus, it is your duty to * keep a copy of it when necessary. */ extern date_t* nnsql_getdate(void* hstmt, int icol); /* Return a pointer point to an internal date * datatype structure from the 'th column * of the current row of the result set. If the * datatype of this column is not DATE, this * function will return a null pointer. Using * nnsql_isdatecol() to check this before * getting a date pointer. The date structure * is place in an internal buffer. It may be * overwritten by the result of later(if not * next) nnsql_fetch() call. It is your job to * keep a copy of it when necessary. */ /* get total number of columns and parameters */ extern int nnsql_getcolnum(void* hstmt); /* Return total column number of a prepared or * executed statement, if a result set has been * opened or will be opened after the prepared * statement been executed. It return 0 if there * is no result set will or already been opened. * Unlike ODBC, the column number returned from * this function will be, if it is not 0, equal * or large than 2 to include the hidden internal * column -- the article-num column(it is always * the 0'th column). */ extern int nnsql_getparnum(void* hstmt); /* return total parameter number(i.e. number of * outstanding ? marks) of a prepared SQL * statement.*/ extern int nnsql_getrowcount(void* hstmt); /* For a DELETE statement, this function returns * the total deleted rows(i.e. articles). * For an INSERT statement, this function * returns 0(i.e. insert unsuccess) or 1(i.e. * successed inserted or posted). * For a SELECT statement, this function returns * the current cursor location(i.e. current row * number) which equals to the total number of * successful nnsql_fetch(). */ /* get type of column */ extern int nnsql_isnullcol(void* hstmt, int icol); /* Return TRUE if the 'th column at current * row is null or return FAIL if not */ extern int nnsql_isstrcol(void* hstmt, int icol); /* Return TRUE if datatype of the 'th column * is STRING or return FAIL if not */ extern int nnsql_isnumcol(void* hstmt, int icol); /* Return TRUE if datatype of the 'th column * is INTEGER(i.e NUMBER) or return FAIL if not */ extern int nnsql_isdatecol(void* hstmt, int icol); /* Return TRUE if datatype of the 'th column * is DATE or return FAIL if not */ extern int nnsql_iscountcol(void* hstmt, int icol);/* Return TRUE if the 'th column is a count * column or return FAIL if not */ extern int nnsql_isnullablecol(void* hstmt, int icol); /* Return TRUE if the 'th column is an * nullable one(i.e. not necessary specified in * INSERT statement. return FAIL if not */ /* unbind dummy variable(s) */ extern int nnsql_yyunbindpar(void* hstmt, int ipar); /* Unbinding the 'th parameter * (corrosponding to the value previouse bound * for the 'th outstanding ? mark. This * will free the *user* buffer(if an user string * was previously bound) from the statement * handle.*/ /* put data for dummy variable(s) */ extern int nnsql_putnum(void* hstmt, int ipar, long num); /* Binding an integer as the 'th parameter * (i.e. its value and type will be used in * place of the 'th outstanding ? mark in * the prepared SQL statement. Same as ODBC, here * the index start from 1. */ extern int nnsql_putstr(void* hstmt, int ipar, char* str); /* Binding a string(keep a pointer of the user * string location) as the 'th parameter.*/ extern int nnsql_putdate(void* hstmt, int ipar, date_t* date); /* Binding a date(copy the date struct to an * internal recyclable buffer) as the 'th * parameter */ extern int nnsql_putnull(void* hstmt, int ipar); /* Binding a null as the 'th parameter */ /* error report function */ extern int nnsql_errcode(void* hstmt); /* Return the current errcode or 0 */ extern char* nnsql_errmsg(void* hstmt); /* Return the current errmsg(null terminate * string) or null */ extern int nnsql_errpos(void* hstmt); /* Return parsing position of error in the sql * statement */ /* nntp connection access mode flag. used in nntp_accmode() */ # define ACCESS_MODE_SELECT 0 /* Allow SELECT only */ # define ACCESS_MODE_INSERT 1 /* Allow INSERT and SELECT */ # define ACCESS_MODE_DELETE_TEST 2 /* Allow SELECT, INSERT, DELETE(from *.test * groups) */ # define ACCESS_MODE_DELETE_ANY 3 /* Allow SELECT, INSERT, DELETE(from all groups)*/ #endif unixODBC-2.3.12/Drivers/nn/nntp.c000066400000000000000000000342161446441710500164020ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include #include #include #include #include "driver.h" # include "nntp.ci" #ifndef WINSOCK # include # include # include # include # include # include #else # include #endif #include typedef struct { long article_num; long data; } nntp_xhdridx_t; typedef struct { char* header; long start; long end; int count; nntp_xhdridx_t* idxs; char* buf; } nntp_xhdrinfo_t; typedef struct { void* sin; void* sout; int postok; int code; /* group info */ long start; long end; int count; /* access mode */ int mode; } nntp_cndes_t; void* nntp_connect( char* server ) { int sock, err; char msgbuf[128]; struct sockaddr_in srvaddr; nntp_cndes_t* cndes; #ifdef WINSOCK WSADATA winsock_data; # ifndef WINSOCKVERSION # define WINSOCKVERSION ( 0x0101 ) /* default version 1.1 */ # endif if( WSAStartup((WORD)WINSOCKVERSION, &winsock_data) ) return 0; /* fail to init winsock */ #endif if( atoi(server) > 0 ) /* an IP address */ { srvaddr.sin_family = AF_INET; srvaddr.sin_addr.s_addr = inet_addr(server); } else /* a domain name */ { struct hostent* ph; if( ! (ph = gethostbyname( server )) ) return 0; srvaddr.sin_family = ph->h_addrtype; memcpy( (char*)&srvaddr.sin_addr, (char*)ph->h_addr, ph->h_length); } cndes = (nntp_cndes_t*)MEM_ALLOC(sizeof(nntp_cndes_t)); if( ! cndes ) return 0; srvaddr.sin_port = htons(119); if( (sock = socket( AF_INET, SOCK_STREAM, 0)) == -1 ) { MEM_FREE(cndes); return 0; } if( connect( sock, (struct sockaddr*)&srvaddr, sizeof(srvaddr) ) == -1 ) { SOCK_CLOSE( sock ); MEM_FREE(cndes); return 0; } if( ! (cndes->sin = SOCK_FDOPEN( sock, "r")) ) { SOCK_CLOSE( sock ); MEM_FREE(cndes); return 0; } if( ! (cndes->sout = SOCK_FDOPEN( sock, "w")) ) { SOCK_FCLOSE( cndes->sin ); MEM_FREE(cndes); return 0; } if( ! SOCK_FGETS(msgbuf, sizeof(msgbuf), cndes->sin ) ) { SOCK_FCLOSE( cndes->sin ); SOCK_FCLOSE( cndes->sout ); MEM_FREE(cndes); return 0; } /* a patch from Julia Anne Case */ SOCK_FPUTS("MODE READER\r\n", cndes->sout); if( SOCK_FFLUSH(cndes->sout) == EOF ) return 0; if( ! SOCK_FGETS(msgbuf, sizeof(msgbuf), cndes->sin ) ) { SOCK_FCLOSE( cndes->sin ); SOCK_FCLOSE( cndes->sout ); MEM_FREE(cndes); return 0; } switch( atoi( msgbuf ) ) { case NNTP_POST_CONN_OK: cndes->postok = 1; break; case NNTP_READ_CONN_OK: cndes->postok = 0; break; default: SOCK_FCLOSE( cndes->sin ); SOCK_FCLOSE( cndes->sout ); MEM_FREE(cndes); return 0; } cndes->code = 0; /* group info */ cndes->start= 0L; cndes->end = 0L; cndes->count= 0; cndes->mode = 0; return (void*)cndes; } void nntp_close(void* hcndes) { nntp_cndes_t* pcndes = (nntp_cndes_t*)hcndes; char msgbuf[128]; SOCK_FPUTS( "QUIT\r\n", pcndes->sout ); SOCK_FFLUSH( pcndes->sout ); SOCK_FGETS(msgbuf, sizeof(msgbuf), pcndes->sin ); SOCK_FCLOSE( pcndes->sin ); SOCK_FCLOSE( pcndes->sout ); MEM_FREE( hcndes ); #ifdef WINSOCK WSACleanup(); #endif } int nntp_errcode( void* hcndes ) { if( ! hcndes ) return -1; return ((nntp_cndes_t*)hcndes)->code; } char* nntp_errmsg( void* hcndes ) { int i, errcode; errcode = nntp_errcode( hcndes ); switch( errcode ) { case 0: return 0; case -1: return strerror( errno ); default: break; } for(i=0;ipostok; } int nntp_group( void* hcndes, char* grpnam ) { nntp_cndes_t* pcndes = hcndes; char response[64]; int code; pcndes->code = -1; /* system error */ SOCK_FPRINTF( pcndes->sout, "GROUP %s\r\n", grpnam); if( SOCK_FFLUSH( pcndes->sout ) == EOF ) return -1; if( ! SOCK_FGETS( response, sizeof( response ), pcndes->sin ) ) return -1; code = atoi(response); if( code != NNTP_GROUP_OK ) { pcndes->code = code; return -1; } sscanf( response, "%d%d%ld%ld", &code, &(pcndes->count), &(pcndes->start), &(pcndes->end)); pcndes->code = 0; return 0; } char* nntp_body( void* hcndes, long msgnum, char* msgid) { nntp_cndes_t* pcndes = hcndes; char tmsgbuf[128]; int code; char* body; int totsize, freesize, offset; pcndes->code = -1; if( msgnum > 0 ) SOCK_FPRINTF(pcndes->sout, "BODY %ld\r\n", msgnum ); else if( msgid ) SOCK_FPRINTF(pcndes->sout, "BODY %s\r\n", msgid ); else { SOCK_FPUTS("BODY\r\n", pcndes->sout); } if( SOCK_FFLUSH( pcndes->sout ) == EOF ) return 0; if( ! SOCK_FGETS(tmsgbuf, sizeof(tmsgbuf), pcndes->sin ) ) return 0; code = atoi(tmsgbuf); if( code != NNTP_BODY_OK ) { pcndes->code = code; return 0; } body = MEM_ALLOC(BODY_CHUNK_SIZE); if( !body ) abort(); totsize = freesize = BODY_CHUNK_SIZE; offset = 0; for(;;) { if( freesize <= BODY_CHUNK_SIZE/2 ) { totsize += BODY_CHUNK_SIZE; freesize += BODY_CHUNK_SIZE; body = MEM_REALLOC(body, totsize); if( ! body ) abort(); } if( ! SOCK_FGETS( body + offset, freesize, pcndes->sin ) ) return 0; if( STREQ( body+offset, ".\r\n") ) { *(body+offset) = 0; break; } /* strip off CR i.e '\r' */ offset += STRLEN(body+offset) - 1; freesize = totsize - offset; body[offset-1] = '\n'; } return body; } int nntp_next( void* hcndes ) { nntp_cndes_t* pcndes = hcndes; char tmsgbuf[128]; int code; pcndes->code = -1; SOCK_FPUTS("NEXT\r\n", pcndes->sout); if( SOCK_FFLUSH( pcndes->sout ) == EOF ) return -1; if( ! SOCK_FGETS( tmsgbuf, sizeof(tmsgbuf), pcndes->sin) ) return -1; pcndes->code = atoi(tmsgbuf); switch( pcndes->code ) { case NNTP_END_OF_GROUP: return 100; case NNTP_NEXT_OK: return 0; default: break; } return -1; } int nntp_last( void* hcndes ) { nntp_cndes_t* pcndes = hcndes; char tmsgbuf[128]; int code, sock; char* body; int size; pcndes->code = -1; SOCK_FPUTS("LAST\r\n", pcndes->sout); if( SOCK_FFLUSH( pcndes->sout ) == EOF ) return -1; if( ! SOCK_FGETS( tmsgbuf, sizeof(tmsgbuf), pcndes->sin) ) return -1; pcndes->code = atoi(tmsgbuf); switch( pcndes->code ) { case NNTP_TOP_OF_GROUP: return 100; case NNTP_LAST_OK: return 0; default: break; } return -1; } static int nntp_xhdr( void* hcndes, nntp_xhdrinfo_t* xhdr_data) { nntp_cndes_t* pcndes = hcndes; char tbuf[128]; int totsize, freesize; int flag; char* ptr; pcndes->code = -1; xhdr_data->count = 0; SOCK_FPRINTF( pcndes->sout, "XHDR %s %ld-%ld\r\n", xhdr_data->header, xhdr_data->start, xhdr_data->end ); if( SOCK_FFLUSH( pcndes->sout ) == EOF ) return -1; if( ! SOCK_FGETS( tbuf, sizeof(tbuf), pcndes->sin ) ) return -1; pcndes->code = atoi(tbuf); if( pcndes->code != NNTP_XHDR_OK ) return -1; flag = upper_strneq(xhdr_data->header, "lines", 6); if( flag ) { xhdr_data->buf = 0; } else { totsize = freesize = XHDR_CHUNK_SIZE; xhdr_data->buf = MEM_ALLOC(totsize); if( ! xhdr_data->buf ) return -1; ptr = xhdr_data->buf; } for(xhdr_data->count=0;;xhdr_data->count++) { int num; if( flag ) { if( ! SOCK_FGETS(tbuf, sizeof(tbuf), pcndes->sin) ) return -1; if( STRNEQ(tbuf, ".\r\n", 3) ) break; sscanf(tbuf, "%ld%ld", &(xhdr_data->idxs[xhdr_data->count].article_num), &(xhdr_data->idxs[xhdr_data->count].data) ); } else { if( freesize < XHDR_CHUNK_SIZE/2 ) { int offset; totsize += XHDR_CHUNK_SIZE; freesize += XHDR_CHUNK_SIZE; offset = (int)(ptr - xhdr_data->buf); xhdr_data->buf = MEM_REALLOC( xhdr_data->buf, totsize ); if( ! xhdr_data->buf ) return -1; ptr = xhdr_data->buf + offset; } if( ! SOCK_FGETS(ptr, freesize, pcndes->sin ) ) return -1; if( STRNEQ(ptr, ".\r\n", 3) ) break; sscanf( ptr, "%ld%n", &(xhdr_data->idxs[xhdr_data->count].article_num), &num); if( STREQ( ptr + num + 1, "(none)\r\n") ) { xhdr_data->idxs[xhdr_data->count].data = 0; ptr += (num + 1); } else { xhdr_data->idxs[xhdr_data->count].data = ptr - xhdr_data->buf + num + 1; ptr += (STRLEN(ptr) - 1); } ptr[-1] = 0; freesize = totsize - (int)(ptr - xhdr_data->buf); } } return 0; } typedef struct { void* hcndes; char header[20]; nntp_xhdrinfo_t* hdrinfo; long position; long last; } nntp_header_t; void* nntp_openheader(void* hcndes, char* header, long* tmin, long* tmax) { nntp_cndes_t* pcndes = hcndes; nntp_header_t* hd; long start; pcndes->code = -1; hd = (nntp_header_t*)MEM_ALLOC(sizeof(nntp_header_t)); if( !hd ) return 0; hd->hcndes = hcndes; STRCPY(hd->header, header); hd->last = pcndes->end; hd->hdrinfo = (nntp_xhdrinfo_t*)MEM_ALLOC(sizeof(nntp_xhdrinfo_t)); if( !hd->hdrinfo ) { MEM_FREE( hd ); return 0; } start = pcndes->start; if( *tmax < *tmin ) { #ifndef MAX_SIGNED_LONG # define MAX_SIGNED_LONG ( (-1UL) >> 1 ) #endif if( start < *tmax || start > *tmin ) *tmin = start; *tmax = MAX_SIGNED_LONG; } if( *tmin < start ) *tmin = start; if( *tmin == MAX_SIGNED_LONG ) *tmin = *tmax = 0L; hd->hdrinfo->header = hd->header; hd->hdrinfo->start = 0L; hd->hdrinfo->end = *tmin - 1L; hd->hdrinfo->count = 0; hd->hdrinfo->idxs = (nntp_xhdridx_t*)MEM_ALLOC( sizeof(nntp_xhdridx_t)*NNTP_HEADER_CHUNK); if( ! hd->hdrinfo->idxs ) { MEM_FREE( hd->hdrinfo ); MEM_FREE( hd ); return 0; } hd->hdrinfo->buf = 0; hd->position = 0; return hd; } void nntp_closeheader(void* hh) { nntp_header_t* ph = hh; if( !hh ) return; if( ph->hdrinfo ) { MEM_FREE( ph->hdrinfo->idxs ); MEM_FREE( ph->hdrinfo->buf ); MEM_FREE( ph->hdrinfo ); } MEM_FREE( hh ); } int nntp_fetchheader( void* hh, long* artnum, long* data, void* hrh) { nntp_header_t* ph = hh; nntp_header_t* prh= hrh; /* reference header */ nntp_cndes_t* pcndes; long position; long ldata; if(! hh ) return -1; pcndes = ph->hcndes; position = ph->position; pcndes->code = -1; if( ph->hdrinfo->start >= ph->last ) return 100; if( prh ) { if( ph->hdrinfo->end != prh->hdrinfo->end ) { MEM_FREE(ph->hdrinfo->buf); ph->hdrinfo->buf = 0; ph->hdrinfo->start = prh->hdrinfo->start; ph->hdrinfo->end = prh->hdrinfo->end; if( nntp_xhdr( pcndes, ph->hdrinfo ) ) return -1; } position = ph->position = prh->position-1; } else if( ph->hdrinfo->count == position ) { MEM_FREE(ph->hdrinfo->buf); ph->hdrinfo->buf = 0; for(;;) { ph->hdrinfo->start = ph->hdrinfo->end + 1; ph->hdrinfo->end = ph->hdrinfo->end + NNTP_HEADER_CHUNK; ph->hdrinfo->count = 0; position = ph->position = 0; if( ph->hdrinfo->start > ph->last ) return 100; if( nntp_xhdr( pcndes, ph->hdrinfo ) ) return -1; if( ph->hdrinfo->count ) break; } } if( artnum ) *artnum = (ph->hdrinfo->idxs)[position].article_num; ldata = (ph->hdrinfo->idxs)[position].data; if( ldata ) ldata = (long)(ph->hdrinfo->buf) + ldata; if( data ) *data = ldata; ph->position ++; return 0; } int nntp_start_post(void* hcndes) { nntp_cndes_t* pcndes = hcndes; char msgbuf[128]; int i; pcndes->code = -1; if( ! nntp_postok(hcndes) ) { pcndes->code = NNTP_CANNOT_POST; return -1; } SOCK_FPUTS( "POST\r\n", pcndes->sout ); if( SOCK_FFLUSH( pcndes->sout ) == EOF ) return -1; if( ! SOCK_FGETS(msgbuf, sizeof(msgbuf), pcndes->sin) ) return -1; pcndes->code = atoi(msgbuf); if(pcndes->code != NNTP_POSTING ) return -1; return 0; } int nntp_send_head(void* hcndes, char* head_name, char* head) { nntp_cndes_t* pcndes = hcndes; int i; for(i=0;head[i];i++) /* to make sure there is no new line char in a head string * here, head must be pointed to a writeable area and don't * care whether it will be overwritten after posting */ { if( head[i] == '\n' ) { head[i] = 0; break; } } SOCK_FPRINTF( pcndes->sout, "%s: %s\n", head_name, head); return 0; } int nntp_end_head(void* hcndes) { nntp_cndes_t* pcndes = hcndes; SOCK_FPUTS("\n", pcndes->sout); return 0; } int nntp_send_body(void* hcndes, char* body) { nntp_cndes_t* pcndes = hcndes; char* ptr; for(ptr=body;*ptr;ptr++) /* we require the article body buffer is located in a * writeable area and can be overwritten during the * post action. */ { if( *ptr == '\n' ) { if( STRNEQ( ptr, "\n.\n", 3) || STRNEQ( ptr, "\n.\r\n", 4 ) ) { *ptr = 0; break; } } } SOCK_FPUTS(body, pcndes->sout); return 0; } int nntp_end_post(void* hcndes) { nntp_cndes_t* pcndes = hcndes; char msgbuf[128]; pcndes->code = -1; SOCK_FPUTS("\r\n.\r\n", pcndes->sout); if( SOCK_FFLUSH(pcndes->sout) == EOF ) return -1; if( ! SOCK_FGETS(msgbuf, sizeof(msgbuf), pcndes->sin) ) return -1; pcndes->code = atoi(msgbuf); if( pcndes->code != NNTP_POST_OK ) return -1; return 0; } int nntp_cancel( void* hcndes, char* group, char* sender, char* from, char* msgid ) { char msgbuf[128]; if( ! from ) from = "(none)"; sprintf( msgbuf, "cancel %s", msgid); if( nntp_start_post(hcndes) || nntp_send_head(hcndes, "Newsgroups", group) || ( sender && nntp_send_head(hcndes, "Sender", sender) ) || nntp_send_head(hcndes, "From", from) || nntp_send_head(hcndes, "Control", msgbuf) || nntp_end_head(hcndes) || nntp_end_post(hcndes) ) return -1; return 0; } void nntp_setaccmode(void* hcndes, int mode) { nntp_cndes_t* pcndes = hcndes; pcndes->mode = mode; } int nntp_getaccmode(void* hcndes ) { nntp_cndes_t* pcndes = hcndes; return pcndes->mode; } unixODBC-2.3.12/Drivers/nn/nntp.ci000066400000000000000000000014051446441710500165450ustar00rootroot00000000000000#include # define MSGHEAD "[INN][NNRP server]" static struct { int code; char* msg; } nntp_msg[] = { NNTP_POSTING, MSGHEAD "Article in posting", NNTP_SERVICE_DOWN, MSGHEAD "NNTP Server down", NNTP_INVALID_GROUP, MSGHEAD "No such news group on this server", NNTP_NOT_IN_GROUP, MSGHEAD "Not in a news group", NNTP_NOT_IN_ARTICLE, MSGHEAD "Not in a article", NNTP_END_OF_GROUP, MSGHEAD "End of news group", NNTP_TOP_OF_GROUP, MSGHEAD "Top of news group", NNTP_INVALID_MSGNUM, MSGHEAD "Invalid article number", NNTP_INVALID_MSGID, MSGHEAD "Invalid article ID", NNTP_UNWANTED_MSG, MSGHEAD "Unwanted article", NNTP_REJECTED_MSG, MSGHEAD "Article rejected", NNTP_CANNOT_POST, MSGHEAD "Can't post", NNTP_POSTING_FAILED, MSGHEAD "NNTP Posting failed" }; unixODBC-2.3.12/Drivers/nn/nntp.h000066400000000000000000000053211446441710500164020ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _NNTP_H # define _NNTP_H /* part of useful nntp response code */ # define NNTP_POST_CONN_OK 200 # define NNTP_READ_CONN_OK 201 # define NNTP_SLAVE_CONN_OK 202 # define NNTP_QUIT_OK 205 # define NNTP_GROUP_OK 211 # define NNTP_LIST_OK 215 # define NNTP_ARTICLE_OK 220 # define NNTP_HEAD_OK 221 # define NNTP_XHDR_OK NNTP_HEAD_OK # define NNTP_BODY_OK 222 # define NNTP_NEXT_OK 223 # define NNTP_LAST_OK NNTP_NEXT_OK # define NNTP_NEWMSG_OK 230 # define NNTP_NEWGRP_OK 231 # define NNTP_POST_OK 240 # define NNTP_POSTING 340 # define NNTP_SERVICE_DOWN 400 # define NNTP_INVALID_GROUP 411 # define NNTP_NOT_IN_GROUP 412 # define NNTP_NOT_IN_ARTICLE 420 # define NNTP_END_OF_GROUP 421 # define NNTP_TOP_OF_GROUP 422 # define NNTP_INVALID_MSGNUM 423 # define NNTP_INVALID_MSGID 430 # define NNTP_UNWANTED_MSG 435 # define NNTP_REJECTED_MSG 437 # define NNTP_CANNOT_POST 440 # define NNTP_POSTING_FAILED 441 # define BODY_CHUNK_SIZE 4096 # define XHDR_CHUNK_SIZE 4096 # define NNTP_HEADER_CHUNK 128 extern void* nntp_connect ( char* server ); extern void nntp_close ( void* hcndes ); extern int nntp_group ( void* hcndes, char* grp); extern int nntp_next ( void* hcndes ); extern int nntp_last ( void* hcndes ); extern int nntp_errcode ( void* hcndes ); extern char* nntp_errmsg ( void* hcndes ); extern void* nntp_openheader ( void* hcndes, char* header, long* tmin, long* tmax ); extern int nntp_fetchheader( void* hhead, long* article_num, long* data, void* hrh ); extern void nntp_closeheader( void* hhead ); extern char* nntp_body ( void* hcndes, long artnum, char* artid); extern int nntp_start_post ( void* hcndes ); extern int nntp_send_head ( void* hcndes, char* header_name, char* header ); extern int nntp_end_head ( void* hcndes ); extern int nntp_send_body ( void* hcndes, char* body); extern int nntp_end_post ( void* hcndes ); extern int nntp_cancel ( void* hcndes, char* group, char* sender, char* from, char* msgid); extern int nntp_postok ( void* hcndes ); extern int nntp_getaccmode( void* hcndes ); extern void nntp_setaccmode( void* hcndes, int mode ); #endif unixODBC-2.3.12/Drivers/nn/prepare.c000066400000000000000000000040101446441710500170460ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" void* nnodbc_getstmterrstack(void* hstmt) { return ((stmt_t*)hstmt)->herr; } int nnodbc_sqlfreestmt( void* hstmt, int fOption) { stmt_t* pstmt = hstmt; int i, max; switch( fOption ) { case SQL_DROP: nnodbc_detach_stmt(pstmt->hdbc, hstmt); /* free all resources */ MEM_FREE(pstmt->pcol); MEM_FREE(pstmt->ppar); CLEAR_ERROR(pstmt->herr); MEM_FREE(hstmt); break; case SQL_CLOSE: nnsql_close_cursor(hstmt); break; case SQL_UNBIND: max = nnsql_max_column(); for(i=0; pstmt->pcol && i < max + 1; i++ ) (pstmt->pcol)[i].userbuf = 0; break; case SQL_RESET_PARAMS: max = nnsql_max_param(); for(i=1;pstmt->ppar && i < max + 1; i++ ) { nnsql_yyunbindpar( pstmt->yystmt, i); (pstmt->ppar)[i-1].bind = 0; } break; default: /* this error will be caught by driver manager */ return SQL_ERROR; } return SQL_SUCCESS; } int nnodbc_sqlprepare ( void* hstmt, char* szSqlStr, int cbSqlStr ) { stmt_t* pstmt = hstmt; int len; len = (cbSqlStr == SQL_NTS )? STRLEN(szSqlStr):cbSqlStr; if ( nnsql_prepare(pstmt->yystmt, szSqlStr, len ) ) { int code; code = nnsql_errcode(pstmt->yystmt); if ( code == -1 ) code = errno; PUSHSYSERR( pstmt->herr, code, nnsql_errmsg(pstmt->yystmt) ); return SQL_ERROR; } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/nn/stmt.h000066400000000000000000000013401446441710500164070ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _STMT_H # define _STMT_H # include # include #endif unixODBC-2.3.12/Drivers/nn/yyenv.h000066400000000000000000000026041446441710500165760ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _YYENV_H # define _YYENV_H # include typedef struct { int extlevel; /* {} block nest level */ int errpos; /* error position */ int scanpos; /* current position */ char* texts_bufptr; int dummy_npar; /* total number of dummy parameters */ yystmt_t* pstmt; } yyenv_t; /* it is unlikely we will exceed bison's default init stack depth YYINITDEPTH, * i.e. 200. Thus, for system/compiler which not support alloca(), we simply * set it to null and make a bit larger init stack depth for more safty. */ # if defined(__hpux) && !defined (alloca) && !defined(__GNUC__) # define alloca(size) (0) # define YYINITDEPTH (512) # endif void nnsql_yyinit(yyenv_t* penv, yystmt_t* yystmt); int nnsql_yyparse(yyenv_t* pyyenv); #endif unixODBC-2.3.12/Drivers/nn/yyerr.c000066400000000000000000000026611446441710500165740ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include #include "driver.h" #include "yyerr.ci" int nnsql_errcode(void* yystmt) { if( ! yystmt ) return -1; return ((yystmt_t*)yystmt)->errcode; } char* nnsql_errmsg(void* yystmt) { yystmt_t* pstmt = yystmt; int i, errcode; errcode = nnsql_errcode( yystmt ); switch( errcode ) { case 0: return nntp_errmsg(pstmt->hcndes); case -1: if( nntp_errcode(pstmt->hcndes) ) return nntp_errmsg(pstmt->hcndes); else return strerror( errno ); case PARSER_ERROR: return ((yystmt_t*)yystmt)->msgbuf; default: break; } for(i=0; ierrpos; } unixODBC-2.3.12/Drivers/nn/yyerr.ci000066400000000000000000000035731446441710500167500ustar00rootroot00000000000000#include static struct { int errcode; char* msg; } yy_errmsg[] = { PARSER_ERROR, 0, INVALID_COLUMN_NAME, NNSQL_ERRHEAD "Invalid column name", NOT_SUPPORT_UPDATEABLE_CURSOR, NNSQL_ERRHEAD "Don't support update cursor", NOT_SUPPORT_DISTINCT_SELECT, NNSQL_ERRHEAD "Don't support distinct select", NOT_SUPPORT_MULTITABLE_QUERY, NNSQL_ERRHEAD "Don't support multi-table query", NOT_SUPPORT_GROUP_CLAUSE, NNSQL_ERRHEAD "Don't support GROUP clause", NOT_SUPPORT_HAVING_CLAUSE, NNSQL_ERRHEAD "Don't support HAVING condition", NOT_SUPPORT_ORDER_CLAUSE, NNSQL_ERRHEAD "Don't support ORDER clause", NOT_SUPPORT_DDL_DCL, NNSQL_ERRHEAD "Don't support DDL and DCL", NOT_SUPPORT_UPDATE, NNSQL_ERRHEAD "Don't support UPDATE", NOT_SUPPORT_POSITION_DELETE, NNSQL_ERRHEAD "Don't support position DELETE", TOO_MANY_COLUMNS, NNSQL_ERRHEAD "Too many columns in select list", NOT_SUPPORT_SPROC, NNSQL_ERRHEAD "Don't support stored procedure feature", VARIABLE_IN_SELECT_LIST, NNSQL_ERRHEAD "A variable was used in select list", VARIABLE_IN_TABLE_LIST, NNSQL_ERRHEAD "A variable was used in table list", UNSEARCHABLE_ATTR, NNSQL_ERRHEAD "Unsearchable column was used in " "searching condition", INSERT_VALUE_LESS, NNSQL_ERRHEAD "Number of values less than number of " "columns in insert statement", INSERT_VALUE_MORE, NNSQL_ERRHEAD "Number of values more than number of " "columns in insert statement", POST_WITHOUT_BODY, NNSQL_ERRHEAD "Try to post a article without body", NO_POST_PRIVILEGE, NNSQL_ERRHEAD "No INSERT and DELETE privilege as " "server not accept POST", NO_INSERT_PRIVILEGE, NNSQL_ERRHEAD "No INSERT privilege", NO_DELETE_PRIVILEGE, NNSQL_ERRHEAD "No DELETE privilege on any groups", NO_DELETE_ANY_PRIVILEGE, NNSQL_ERRHEAD "No DELETE privilege on non-test groups", TYPE_VIOLATION, NNSQL_ERRHEAD "Restricted data type attribute violation" }; unixODBC-2.3.12/Drivers/nn/yyerr.h000066400000000000000000000031551446441710500166000ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _YYERR_H # define _YYERR_H # include # define NNSQL_ERRHEAD "[NetNewSQL][Dynamic SQL parser]" # define INVALID_COLUMN_NAME 200 # define NOT_SUPPORT_UPDATEABLE_CURSOR 201 # define NOT_SUPPORT_DISTINCT_SELECT 202 # define NOT_SUPPORT_MULTITABLE_QUERY 203 # define NOT_SUPPORT_GROUP_CLAUSE 204 # define NOT_SUPPORT_HAVING_CLAUSE 205 # define NOT_SUPPORT_ORDER_CLAUSE 206 # define NOT_SUPPORT_DDL_DCL 207 # define NOT_SUPPORT_UPDATE 208 # define NOT_SUPPORT_POSITION_DELETE 209 # define NOT_SUPPORT_SPROC 210 # define TOO_MANY_COLUMNS 211 # define VARIABLE_IN_SELECT_LIST 212 # define VARIABLE_IN_TABLE_LIST 213 # define UNSEARCHABLE_ATTR 214 # define INSERT_VALUE_LESS 215 # define INSERT_VALUE_MORE 216 # define POST_WITHOUT_BODY 217 # define NO_POST_PRIVILEGE 218 # define NO_INSERT_PRIVILEGE 219 # define NO_DELETE_PRIVILEGE 220 # define NO_DELETE_ANY_PRIVILEGE 221 # define TYPE_VIOLATION 222 # define PARSER_ERROR 256 #endif unixODBC-2.3.12/Drivers/nn/yyevl.c000066400000000000000000000264361446441710500166000ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include #include #include #include #include typedef struct { int type; /* can only be en_nt_qstr, en_nt_num and en_nt_null */ union { char* qstr; long num; date_t date; } value; } leaf_t; static int getleaf(yystmt_t* yystmt, node_t* nd, leaf_t* lf) { yypar_t* par; yyattr_t* attr; switch( nd->type ) { case en_nt_attr: attr = yystmt->pattr + (nd->value).iattr; if( (nd->value).iattr == en_lines || (nd->value).iattr == en_article_num ) { lf->type = en_nt_num; (lf->value).num = (attr->value).number; break; } if( (nd->value).iattr == en_date ) { if( (attr->value).date.day ) { lf->type = en_nt_date; (lf->value).date = (attr->value).date; } else lf->type = en_nt_null; break; } if( (attr->value).location ) { lf->type = en_nt_qstr; (lf->value).qstr = (attr->value).location; } else lf->type = en_nt_null; break; case en_nt_param: par = yystmt->ppar + (nd->value).ipar - 1; if( par->type == en_nt_null ) { lf->type = en_nt_null; break; } if( par->type == en_nt_num ) { lf->type = en_nt_num; (lf->value).num = (par->value).number; break; } if( par->type == en_nt_qstr) { if( (par->value).location ) { lf->type = en_nt_qstr; (lf->value).qstr = (par->value).location; break; } lf->type = en_nt_null; break; } if( par->type == en_nt_date) { if( (par->value).date.day ) { lf->type = en_nt_date; (lf->value).date = (par->value).date; break; } lf->type = en_nt_null; } return -1; case en_nt_num: lf->type = en_nt_num; (lf->value).num = (nd->value).num; break; case en_nt_qstr: lf->type = en_nt_qstr; if( (nd->value).qstr ) { lf->type = en_nt_qstr; (lf->value).qstr = (nd->value).qstr; break; } lf->type = en_nt_null; break; case en_nt_date: lf->type = en_nt_date; (lf->value).date = (nd->value).date; break; case en_nt_null: lf->type = en_nt_null; break; default: return -1; } return 0; } #ifndef MAX_SIGNED_LONG # define MAX_SIGNED_LONG ((-1UL) >> 1) #endif # define AREA ( MAX_SIGNED_LONG + 1UL ) # define RANGE_ALL { 0, 1UL, MAX_SIGNED_LONG } # define RANGE_EMPTY { 1, 0UL, 0UL } # define ALL_RANGE(r) { r.flag = 0; \ r.min = 1UL; \ r.max = MAX_SIGNED_LONG; } # define EMPTY_RANGE(r) { r.flag = 1;\ r.min = r.max = 0UL; } # define IS_EMPTY_RANGE(r) \ (((r.min == 0UL) && (r.max==0UL))? 1:0) # define RANGE_MIN(a, b) ((((unsigned long)(a)) < ((unsigned long)(b)))? a:b) # define RANGE_MAX(a, b) ((((unsigned long)(a)) > ((unsigned long)(b)))? a:b) typedef struct { int flag; unsigned long min; unsigned long max; } range_t; static range_t range_and(range_t r1, range_t r2) { range_t r = RANGE_EMPTY; if( !(r.flag = r1.flag || r2.flag) ) return r; if( r1.min > r2.max || r1.max < r2.min ) return r; r.min = (RANGE_MAX(r1.min, r2.min))%AREA; r.max = (RANGE_MIN(r1.max, r2.max))%AREA; return r; } static range_t range_or(range_t r1, range_t r2) { range_t r = RANGE_ALL; if( !(r.flag = r1.flag || r2.flag) ) return r; if( !(r1.max/AREA) || !(r2.max/AREA) ) /* at least one of the rangion does not cross cell */ { unsigned long c1, c2; c1 = (r1.max/2) + (r1.min/2); /* central of rangion 1 */ c2 = (r2.max/2) + (r2.min/2); /* central of rangion 2 */ if( c1 > c2 && (c1 - c2) > (AREA/2) ) { /* shift it to the second cell */ r2.min += AREA; r2.max += AREA; } else if( c2 > c1 && (c2 - c1) > (AREA/2) ) { /* shift it to the second cell */ r1.min += AREA; r1.max += AREA; } } r.min = (RANGE_MIN(r1.min, r2.min))%AREA; r.max = (RANGE_MAX(r1.max, r2.max))%AREA; return r; } static range_t getrange(yystmt_t* yystmt, node_t* pnd) { range_t r = RANGE_ALL, r1, r2; node_t* tpnd = 0; leaf_t a, b; int flag = 0; if( !pnd ) return r; if( pnd->left && pnd->left->type == en_nt_attr && (pnd->left->value).iattr == en_article_num ) { r.flag = 1; switch( pnd->type ) { case en_nt_between: getleaf(yystmt, pnd->right->left, &a); getleaf(yystmt, pnd->right->right, &b); if( a.type == en_nt_null || b.type == en_nt_null ) break; r.min = RANGE_MIN(a.value.num, b.value.num); r.max = RANGE_MAX(a.value.num, b.value.num); break; case en_nt_in: EMPTY_RANGE(r); for(tpnd = pnd->right; tpnd; tpnd=tpnd->right) { getleaf(yystmt, tpnd, &a); if( a.type == en_nt_null ) continue; if( IS_EMPTY_RANGE(r) ) r.min = r.max = a.value.num; else { r.min = RANGE_MIN(r.min, a.value.num); r.max = RANGE_MAX(r.max, a.value.num); } } break; case en_nt_cmpop: getleaf(yystmt, pnd->right, &a); if( a.type == en_nt_null ) break; switch((pnd->value).cmpop) { case en_cmpop_eq: r.min = r.max = a.value.num; break; case en_cmpop_ne: r.min = (a.value.num + 1UL )%AREA; r.max = (a.value.num - 1UL + AREA)%AREA; break; case en_cmpop_gt: r.min = (a.value.num + 1UL)%AREA; break; case en_cmpop_lt: r.max = (a.value.num - 1UL + AREA)%AREA; r.min = (r.max)? 1UL:0UL; break; case en_cmpop_ge: r.min = a.value.num; break; case en_cmpop_le: r.max = a.value.num; r.min = (r.max)? 1UL:0UL; break; default: EMPTY_RANGE(r); break; } break; default: break; } return r; } if( pnd->type != en_nt_logop ) return r; switch( (pnd->value).logop ) { case en_logop_not: r1 = getrange(yystmt, pnd->right); if( r1.flag ) { r.min = (r1.max + 1UL)%AREA; r.max = (r1.min - 1UL + AREA)%AREA; } break; case en_logop_or: flag = 1; case en_logop_and: r1 = getrange(yystmt, pnd->left); r2 = getrange(yystmt, pnd->right); if( !(r1.flag || r2.flag ) ) break; if( r1.min > r1.max ) r1.max = r1.max + AREA; if( r2.min > r2.max ) r2.max = r2.max + AREA; if( flag ) r = range_or ( r1, r2 ); else r = range_and( r1, r2 ); break; default: EMPTY_RANGE(r); break; } return r; } void nnsql_getrange(void* hstmt, long* pmin, long* pmax) { yystmt_t* yystmt = hstmt; range_t r; r = getrange(hstmt, yystmt->srchtree); if( !r.flag ) { *pmin = 1UL; *pmax = MAX_SIGNED_LONG; } else { *pmin = r.min; *pmax = r.max; } } static int is_sql_null(yystmt_t* yystmt, node_t* a) { leaf_t lf; if( getleaf(yystmt, a, &lf) ) return -1; return (lf.type == en_nt_null); } static int compare(yystmt_t* yystmt, node_t* a, node_t* b, int op) { leaf_t la, lb; int diff, r; if( getleaf( yystmt, a, &la ) || getleaf( yystmt, b, &lb ) ) return -1; if( la.type == en_nt_date && lb.type == en_nt_qstr ) { lb.type = en_nt_date; if( nnsql_odbcdatestr2date(lb.value.qstr, &(lb.value.date)) ) return -1; } if( la.type != lb.type || la.type == en_nt_null || lb.type == en_nt_null ) return 0; switch( la.type ) { case en_nt_qstr: diff = STRCMP(la.value.qstr, lb.value.qstr); break; case en_nt_num: diff = la.value.num - lb.value.num; break; case en_nt_date: diff = nnsql_datecmp(&(la.value.date), &(lb.value.date)); break; default: abort(); return -1; } switch(op) { case en_cmpop_eq: r = !diff; break; case en_cmpop_ne: r = !!diff; break; case en_cmpop_gt: r = (diff>0)? 1:0; break; case en_cmpop_ge: r = (diff>=0)? 1:0; break; case en_cmpop_lt: r = (diff<0)? 1:0; break; case en_cmpop_le: r = (diff<=0)? 1:0; break; default: r = -1; break; } return r; } static int ch_case_cmp(char a, char b) { if( a >= 'a' && a <= 'z' ) a += ('A' - 'a'); if( b >= 'a' && b <= 'z' ) b += ('A' - 'a'); return (a - b); } static int strlike( char* str, char* pattern, char esc, int flag ) /* flag = 0: case sensitive */ { char c, cp; for(;;str++, pattern++) { c = *str; cp= *pattern; if( esc && cp == esc ) { cp = *pattern++; if( (!flag && (c - cp) ) || ( flag && ch_case_cmp(c, cp) ) ) return 0; if( !c ) return 1; continue; } switch(cp) { case 0: return !c; case '_': if(!c) return 0; break; case '%': if(! *(pattern + 1) ) return 1; for(;*str;str++) { if(strlike(str, pattern + 1, esc, flag)) return 1; } return 0; default: if( (!flag && (c - cp) ) || ( flag && ch_case_cmp(c, cp) ) ) return 0; break; } } } int nnsql_strlike(char* str, char* pattern, char esc, int flag) { return strlike(str, pattern, esc, flag); } static int evl_like(yystmt_t* yystmt, node_t* a, node_t* b, char esc, int flag) { leaf_t la, lb; if( getleaf(yystmt, a, &la ) || getleaf(yystmt, b, &lb ) ) return -1; if( la.type != en_nt_qstr || lb.type != en_nt_qstr ) return 0; return strlike(la.value.qstr, lb.value.qstr, esc, flag); } static int srchtree_evl(yystmt_t* yystmt, node_t* node) /* return -1: syserr, 0: fail, 1: true */ { int r, s, flag = 0; node_t* ptr; if( ! node ) return 1; switch( node->type ) { case en_nt_cmpop: return compare(yystmt, node->left, node->right, (node->value).cmpop); case en_nt_logop: switch( (node->value).logop ) { case en_logop_not: r = srchtree_evl(yystmt, node->right); if( r == -1 ) return -1; return ( ! r ); case en_logop_and: flag = 1; case en_logop_or: r = srchtree_evl(yystmt, node->left); s = srchtree_evl(yystmt, node->right); if( r == -1 || s == -1 ) return -1; if( flag ) return ( r && s ); else return ( r || s ); default: abort(); break; /* just for turn off the warning */ } break; /* just for turn off the warning */ case en_nt_isnull: return is_sql_null(yystmt, node->left); case en_nt_between: r = compare(yystmt, node->left, node->right->left, en_cmpop_ge); s = compare(yystmt, node->left, node->right->right, en_cmpop_le); if( r == -1 || s == -1 ) return -1; return ( r && s ); case en_nt_in: for(ptr=node->right; ptr; ptr=ptr->right) { r = compare(yystmt, node->left, ptr, en_cmpop_eq); if( r ) /* -1 or 1 */ return r; } return 0; case en_nt_caselike: flag = 1; case en_nt_like: return evl_like( yystmt, node->left, node->right, (node->value).esc, flag ); default: abort(); break; /* turn off the warning */ } return -1; /* just for turn off the warning */ } int nnsql_srchtree_evl(void* hstmt) { yystmt_t* yystmt = hstmt; return srchtree_evl(yystmt, yystmt->srchtree); } unixODBC-2.3.12/Drivers/nn/yylex.c000066400000000000000000000125241446441710500165730ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include #include #include #include #include #include "yylex.ci" # define YYERRCODE 256 #include #include #include "driver.h" static int getcmpopidxbyname(char* name) { int i, size; size = sizeof(cmpop_tab)/sizeof(cmpop_tab[0]); for(i=0; ipstmt->sqlexpr)[(penv->scanpos)]; (penv->errpos) = (penv->scanpos); (penv->scanpos) ++; return c; } static void unputc(char c, yyenv_t* penv) { (penv->errpos) = (--(penv->scanpos)); if( (penv->pstmt->sqlexpr)[(penv->scanpos)] != c ) (penv->pstmt->sqlexpr)[(penv->scanpos)] = c; } static long getnum(yyenv_t* penv) { long a; char c; int i, errpos = (penv->scanpos); a = atol((penv->pstmt->sqlexpr) + (penv->scanpos)); for(i=0;;i++) { c = popc(penv); if( ! isdigit(c) ) { unputc(c, penv); break; } } (penv->errpos) = errpos; return a; } static int getqstring(char* buf, int len, yyenv_t* penv, char term) { char c, c1; int i, errpos = (penv->scanpos); for(i=0; len == -1 || ierrpos) = errpos; return i; } static int getname(char* buf, int len, yyenv_t* penv) { int i = 0; char c; int errpos = (penv->scanpos); for(i=0; len == -1 || ierrpos) = errpos; return i; } static int getcmpop(yyenv_t* penv) { char opname[3]; char c, c1; int errpos = (penv->scanpos); opname[0] = c = popc(penv); opname[1] = c1= popc(penv); opname[2] = 0; if( c1 != '=' && c1 != '>' && c1 != '<' ) { opname[1] = 0; unputc(c1, penv); } (penv->errpos) = errpos; return getcmpopidxbyname(opname); } int nnsql_yylex(YYSTYPE* pyylval, yyenv_t* penv) { int len, cmpop; char c; do { c = popc(penv); } while( c == ' ' || c == '\t' || c == '\n' ); if( isalpha(c) ) { int keywdidx; unputc(c, penv); len = getname(penv->texts_bufptr, -1, penv); if( len == YYERRCODE ) return len; if( penv->extlevel ) keywdidx = getxkeywdidxbyname( penv->texts_bufptr ); else keywdidx = YYERRCODE; if( keywdidx == YYERRCODE ) keywdidx = getkeywdidxbyname( penv->texts_bufptr); if( keywdidx != YYERRCODE ) return keywdidx; pyylval->name = penv->texts_bufptr; (penv->texts_bufptr) += (len + 1); return NAME; } if( isdigit(c) ) { unputc(c, penv); pyylval->number = getnum(penv); return NUM; } switch( c ) { case ';': case '\0': return ';'; case '\'': case '"': len = getqstring(penv->texts_bufptr, -1, penv, c); if( len == YYERRCODE ) return len; if( c == '\'' ) { pyylval->qstring = penv->texts_bufptr; penv->texts_bufptr += (len + 1); return QSTRING; } pyylval->name = penv->texts_bufptr; (penv->texts_bufptr) += (len + 1); return NAME; case '=': case '<': case '>': case '!': unputc(c, penv); cmpop = getcmpop( penv ); if(cmpop == YYERRCODE ) return cmpop; pyylval->cmpop = cmpop; return CMPOP; case '?': pyylval->ipar = (++(penv->dummy_npar)); return PARAM; case '{': penv->extlevel ++; break; case '}': penv->extlevel --; break; default: break; } return c; } void nnsql_yyinit(yyenv_t* penv, yystmt_t* yystmt) { penv->extlevel = 0; penv->dummy_npar = penv->errpos = penv->scanpos = 0; penv->pstmt = yystmt; penv->texts_bufptr = yystmt->texts_buf; } unixODBC-2.3.12/Drivers/nn/yylex.ci000066400000000000000000000022641446441710500167440ustar00rootroot00000000000000static keywd_ent_t keywd_tab[] = { kwd_select, "select", kwd_all, "all", kwd_news, "news", kwd_xnews, "xnews", kwd_distinct, "distinct", kwd_count, "count", kwd_from, "from", kwd_where, "where", kwd_group, "group", kwd_by, "by", kwd_having, "having", kwd_order, "order", kwd_insert, "insert", kwd_into, "into", kwd_values, "values", kwd_delete, "delete", kwd_is, "is", kwd_null, "null", kwd_update, "update", kwd_create, "create", kwd_alter, "alter", kwd_drop, "drop", kwd_for, "for", kwd_of, "of", kwd_current, "current", kwd_grant, "grant", kwd_revoke, "revoke", kwd_in, "in", kwd_like, "like", kwd_escape, "escape", kwd_between, "between", kwd_call, "call", kwd_or, "or", kwd_and, "and", kwd_not, "not", kwd_index, "index", kwd_view, "view", kwd_table, "table", kwd_column, "column", kwd_case, "case", kwd_uncase, "uncase" }; static keywd_ent_t xkeywd_tab[] = /* keyword which scope in an extersion block -- { extension } */ { kwd_fn, "fn", kwd_d, "d" }; static keywd_ent_t cmpop_tab[] = { en_cmpop_eq, "=", en_cmpop_eq, "==", en_cmpop_ne, "<>", en_cmpop_ne, "!=", en_cmpop_gt, ">", en_cmpop_ge, ">=", en_cmpop_lt, "<", en_cmpop_le, "<=" }; unixODBC-2.3.12/Drivers/nn/yylex.h000066400000000000000000000015711446441710500166000ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _YYLEX_H # define _YYLEX_H typedef struct { int idx; char* name; } keywd_ent_t; enum { en_cmpop_eq, en_cmpop_ne, en_cmpop_gt, en_cmpop_lt, en_cmpop_ge, en_cmpop_le, en_logop_and, en_logop_or, en_logop_not }; #endif unixODBC-2.3.12/Drivers/nn/yyparse.c000066400000000000000000002503721446441710500171220ustar00rootroot00000000000000/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "3.0.4" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Copy the first part of user declarations. */ #line 1 "yyparse.y" /* yacc.c:339 */ /** source of nntp odbc sql parser -- yyparse.y Copyright (C) 1995, 1996 by Ke Jin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ static char sccsid[] = "@(#)SQL parser for NNSQL(NetNews SQL), Copyright(c) 1995, 1996 by Ke Jin"; #include #include #include #include #include #include #include #include #include #include # ifdef YYLSP_NEEDED # undef YYLSP_NEEDED # endif #if defined(YYBISON) || defined(__YY_BISON__) # define yylex(pyylval) nnsql_yylex(pyylval, pyyenv) #else # define yylex() nnsql_yylex(&yylval, pyyenv) #endif #define yyparse(x) nnsql_yyparse (yyenv_t* pyyenv) #define yyerror(msg) nnsql_yyerror (pyyenv, msg) #define SETYYERROR(env, code) { env->pstmt->errcode = code; \ env->pstmt->errpos = env->errpos;} typedef struct { char* schema_tab_name; char* column_name; } column_name_t; static void unpack_col_name(char* schema_tab_column_name, column_name_t* ptr); static void* add_node(yystmt_t* pstmt, node_t* node); static void srchtree_reloc(node_t* srchtree, int num); static int add_attr(yystmt_t* pstmt, int idx, int wstat); static void* add_all_attr(yystmt_t* pstmt); static void* add_news_attr(yystmt_t* pstmt); static void* add_xnews_attr(yystmt_t* pstmt); static void* add_column(yystmt_t* pstmt, yycol_t* pcol); static void nnsql_yyerror(yyenv_t* pyyenv, char* msg); static int table_check(yystmt_t* pstmt); static int column_name(yystmt_t* pstmt, char* name); static void* attr_name(yystmt_t* pstmt, char* name); static int add_ins_head(yystmt_t* pstmt, char* head, int idx); static int add_ins_value(yystmt_t* pstmt, node_t node, int idx); static char* get_unpacked_attrname(yystmt_t* pstmt, char* name); #define ERROR_PTR ((void*)(-1L)) #define EMPTY_PTR ERROR_PTR #line 140 "yyparse.c" /* yacc.c:339 */ # ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { kwd_select = 258, kwd_all = 259, kwd_news = 260, kwd_xnews = 261, kwd_distinct = 262, kwd_count = 263, kwd_from = 264, kwd_where = 265, kwd_in = 266, kwd_between = 267, kwd_like = 268, kwd_escape = 269, kwd_group = 270, kwd_by = 271, kwd_having = 272, kwd_order = 273, kwd_for = 274, kwd_insert = 275, kwd_into = 276, kwd_values = 277, kwd_delete = 278, kwd_update = 279, kwd_create = 280, kwd_alter = 281, kwd_drop = 282, kwd_table = 283, kwd_column = 284, kwd_view = 285, kwd_index = 286, kwd_of = 287, kwd_current = 288, kwd_grant = 289, kwd_revoke = 290, kwd_is = 291, kwd_null = 292, kwd_call = 293, kwd_uncase = 294, kwd_case = 295, kwd_fn = 296, kwd_d = 297, QSTRING = 298, NUM = 299, NAME = 300, PARAM = 301, kwd_or = 302, kwd_and = 303, kwd_not = 304, CMPOP = 305 }; #endif /* Tokens. */ #define kwd_select 258 #define kwd_all 259 #define kwd_news 260 #define kwd_xnews 261 #define kwd_distinct 262 #define kwd_count 263 #define kwd_from 264 #define kwd_where 265 #define kwd_in 266 #define kwd_between 267 #define kwd_like 268 #define kwd_escape 269 #define kwd_group 270 #define kwd_by 271 #define kwd_having 272 #define kwd_order 273 #define kwd_for 274 #define kwd_insert 275 #define kwd_into 276 #define kwd_values 277 #define kwd_delete 278 #define kwd_update 279 #define kwd_create 280 #define kwd_alter 281 #define kwd_drop 282 #define kwd_table 283 #define kwd_column 284 #define kwd_view 285 #define kwd_index 286 #define kwd_of 287 #define kwd_current 288 #define kwd_grant 289 #define kwd_revoke 290 #define kwd_is 291 #define kwd_null 292 #define kwd_call 293 #define kwd_uncase 294 #define kwd_case 295 #define kwd_fn 296 #define kwd_d 297 #define QSTRING 298 #define NUM 299 #define NAME 300 #define PARAM 301 #define kwd_or 302 #define kwd_and 303 #define kwd_not 304 #define CMPOP 305 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 78 "yyparse.y" /* yacc.c:355 */ char* qstring; char* name; long number; int ipar; /* parameter index */ int cmpop; /* for comparsion operators */ char esc; int flag; /* for not_opt and case_opt */ int idx; void* offset; /* actually, it is used as a 'int' offset */ node_t node; /* a node haven't add to tree */ #line 293 "yyparse.c" /* yacc.c:355 */ }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif int yyparse (void); /* Copy the second part of user declarations. */ #line 309 "yyparse.c" /* yacc.c:358 */ #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE # if (defined __GNUC__ \ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C # define YY_ATTRIBUTE(Spec) __attribute__(Spec) # else # define YY_ATTRIBUTE(Spec) /* empty */ # endif #endif #ifndef YY_ATTRIBUTE_PURE # define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) #endif #ifndef YY_ATTRIBUTE_UNUSED # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) #endif #if !defined _Noreturn \ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) # if defined _MSC_VER && 1200 <= _MSC_VER # define _Noreturn __declspec (noreturn) # else # define _Noreturn YY_ATTRIBUTE ((__noreturn__)) # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) #else # define YYUSE(E) /* empty */ #endif #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 24 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 220 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 59 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 34 /* YYNRULES -- Number of rules. */ #define YYNRULES 106 /* YYNSTATES -- Number of states. */ #define YYNSTATES 219 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 305 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex, without out-of-bounds checking. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 53, 54, 52, 2, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 2, 58, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 55, 2, 56, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 166, 166, 169, 171, 181, 185, 189, 190, 198, 201, 203, 210, 212, 213, 221, 222, 223, 224, 225, 229, 230, 231, 235, 236, 237, 241, 242, 246, 257, 259, 261, 263, 274, 285, 298, 302, 304, 305, 306, 307, 308, 312, 313, 326, 328, 330, 332, 341, 344, 358, 359, 371, 384, 396, 421, 451, 480, 505, 521, 522, 524, 526, 531, 533, 535, 540, 545, 559, 569, 582, 593, 604, 620, 621, 622, 626, 640, 655, 656, 659, 661, 668, 670, 677, 679, 687, 737, 742, 750, 752, 754, 759, 764, 772, 776, 781, 789, 801, 809, 810, 811, 812, 813, 814, 816, 817 }; #endif #if YYDEBUG || YYERROR_VERBOSE || 0 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "kwd_select", "kwd_all", "kwd_news", "kwd_xnews", "kwd_distinct", "kwd_count", "kwd_from", "kwd_where", "kwd_in", "kwd_between", "kwd_like", "kwd_escape", "kwd_group", "kwd_by", "kwd_having", "kwd_order", "kwd_for", "kwd_insert", "kwd_into", "kwd_values", "kwd_delete", "kwd_update", "kwd_create", "kwd_alter", "kwd_drop", "kwd_table", "kwd_column", "kwd_view", "kwd_index", "kwd_of", "kwd_current", "kwd_grant", "kwd_revoke", "kwd_is", "kwd_null", "kwd_call", "kwd_uncase", "kwd_case", "kwd_fn", "kwd_d", "QSTRING", "NUM", "NAME", "PARAM", "kwd_or", "kwd_and", "kwd_not", "CMPOP", "';'", "'*'", "'('", "')'", "'{'", "'}'", "','", "'='", "$accept", "sql_stmt", "stmt_body", "select_clauses", "for_stmt", "distinct_opt", "select_list", "news_hotlist", "news_xhotlist", "col_name_list", "col_name", "count_sub_opt", "tab_list", "tab_name", "where_clause", "search_condition", "case_opt", "attr_name", "value_list", "value", "escape_desc", "pattern", "not_opt", "group_clause", "having_clause", "order_clause", "insert_stmt", "ins_head_list", "ins_head", "ins_value_list", "ins_value", "srch_delete_stmt", "posi_delete_stmt", "other_stmt", YY_NULLPTR }; #endif # ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 59, 42, 40, 41, 123, 125, 44, 61 }; # endif #define YYPACT_NINF -156 #define yypact_value_is_default(Yystate) \ (!!((Yystate) == (-156))) #define YYTABLE_NINF -1 #define yytable_value_is_error(Yytable_value) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int16 yypact[] = { 1, 86, -12, 5, -156, -156, -156, -156, -156, -156, 8, 19, -6, -156, -156, -156, -156, -156, -156, 34, 21, 21, -156, -28, -156, -156, -3, 2, 17, 47, -156, -156, -156, -156, -156, 27, 48, -156, -156, 58, -156, 51, -156, -156, 50, 69, 113, 87, 70, 73, -32, -156, 83, 12, 85, 21, 29, 88, 101, -22, 52, -156, -156, -156, -156, 78, 79, 80, 81, -156, 82, 77, 84, 89, 90, -5, -156, 76, -156, 91, 94, 95, -156, 97, 38, -156, 96, 107, -156, 53, 53, 99, 72, 15, -156, -156, -156, -156, -156, 98, 100, 108, -156, 53, 21, -156, 126, 114, -156, 110, 112, 115, 128, -22, 116, 111, -156, 40, 129, 53, 53, 117, -156, 66, 4, 104, 105, 103, -156, 146, 147, 109, 118, 120, 121, -156, 122, -156, -156, 124, 119, -156, 131, -156, -156, -156, -156, 123, -156, 130, 125, 66, -156, -156, 156, -156, -156, 127, 29, 53, 153, 132, -156, 136, 16, -156, 137, -156, 138, -156, 66, 134, 68, -156, 58, 72, 159, 165, -156, 133, -156, -156, -156, 42, -156, 135, 139, 59, -156, 66, -156, -156, -8, 29, 161, -156, 140, -156, 16, 141, -156, -156, 66, -156, 143, 176, -156, 58, 160, -156, -156, -156, -156, -156, 148, 29, 142, 58, -156 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 3, 12, 0, 0, 102, 99, 100, 101, 105, 106, 0, 0, 0, 5, 6, 7, 8, 13, 14, 15, 0, 0, 103, 0, 1, 2, 20, 23, 36, 0, 32, 33, 29, 35, 16, 0, 0, 17, 18, 19, 26, 0, 44, 47, 0, 0, 48, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 104, 21, 24, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 48, 42, 0, 27, 0, 0, 0, 89, 0, 0, 87, 0, 0, 63, 0, 0, 0, 49, 78, 40, 41, 39, 38, 30, 0, 0, 0, 34, 0, 0, 4, 80, 0, 45, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 78, 79, 0, 59, 0, 0, 0, 43, 0, 82, 0, 0, 0, 0, 88, 0, 98, 50, 0, 52, 53, 0, 68, 70, 71, 69, 0, 58, 0, 0, 0, 61, 60, 0, 22, 25, 0, 0, 0, 84, 0, 90, 0, 0, 64, 0, 57, 0, 62, 0, 0, 0, 31, 81, 83, 0, 10, 46, 0, 94, 95, 96, 0, 92, 0, 0, 0, 66, 0, 77, 76, 73, 0, 0, 9, 0, 86, 0, 0, 72, 54, 0, 55, 0, 0, 56, 85, 0, 91, 93, 65, 67, 74, 0, 0, 0, 11, 75 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -156, -156, -156, -156, -156, -156, -156, -156, -156, -155, 144, -156, -156, -21, 145, -88, -156, -156, -156, -141, -156, -156, 92, -156, -156, -156, -156, -156, 93, -156, -4, -156, -156, -156 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 11, 12, 105, 195, 19, 36, 37, 38, 39, 40, 51, 75, 45, 61, 92, 154, 93, 187, 148, 206, 192, 124, 130, 160, 177, 13, 84, 85, 183, 184, 14, 15, 16 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_uint8 yytable[] = { 46, 116, 117, 174, 1, 103, 204, 81, 149, 20, 171, 65, 66, 67, 21, 150, 151, 71, 72, 24, 68, 2, 69, 82, 3, 4, 5, 6, 7, 188, 47, 140, 141, 83, 76, 8, 9, 28, 207, 26, 27, 73, 28, 152, 153, 25, 22, 205, 203, 41, 48, 121, 104, 180, 23, 49, 10, 55, 29, 181, 217, 212, 182, 29, 122, 123, 42, 43, 53, 54, 50, 175, 30, 31, 32, 33, 44, 30, 31, 32, 33, 86, 86, 128, 77, 87, 34, 119, 120, 35, 17, 58, 112, 18, 138, 113, 197, 88, 88, 198, 52, 89, 89, 143, 57, 90, 90, 91, 91, 144, 145, 190, 146, 201, 191, 56, 202, 107, 54, 119, 120, 147, 59, 60, 63, 62, 70, 64, 74, 80, 99, 79, 94, 95, 96, 97, 98, 100, 111, 115, 118, 129, 101, 73, 133, 108, 102, 109, 110, 114, 134, 127, 125, 131, 126, 132, 137, 157, 139, 136, 155, 156, 158, 161, 159, 168, 122, 120, 167, 172, 169, 176, 162, 163, 164, 193, 165, 166, 170, 179, 185, 186, 189, 173, 194, 208, 213, 196, 178, 199, 214, 216, 215, 0, 210, 200, 209, 211, 218, 0, 78, 0, 0, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 142, 0, 0, 0, 0, 0, 0, 106 }; static const yytype_int16 yycheck[] = { 21, 89, 90, 158, 3, 10, 14, 29, 4, 21, 151, 43, 44, 45, 9, 11, 12, 5, 6, 0, 52, 20, 54, 45, 23, 24, 25, 26, 27, 170, 58, 119, 120, 55, 55, 34, 35, 8, 193, 5, 6, 29, 8, 39, 40, 51, 38, 55, 189, 28, 53, 36, 57, 37, 46, 53, 55, 9, 29, 43, 215, 202, 46, 29, 49, 50, 45, 46, 41, 42, 53, 159, 43, 44, 45, 46, 55, 43, 44, 45, 46, 29, 29, 104, 55, 33, 52, 47, 48, 55, 4, 41, 54, 7, 54, 57, 54, 45, 45, 57, 53, 49, 49, 37, 53, 53, 53, 55, 55, 43, 44, 43, 46, 54, 46, 57, 57, 41, 42, 47, 48, 55, 53, 10, 54, 38, 43, 54, 43, 28, 53, 43, 54, 54, 54, 54, 54, 53, 41, 32, 41, 15, 53, 29, 29, 54, 56, 53, 53, 53, 22, 43, 54, 43, 54, 43, 45, 54, 29, 43, 56, 56, 16, 54, 17, 42, 49, 48, 37, 13, 40, 18, 54, 53, 53, 16, 54, 53, 53, 43, 43, 43, 48, 56, 19, 24, 43, 54, 56, 54, 14, 43, 32, -1, 198, 56, 56, 56, 56, -1, 56, -1, -1, -1, -1, -1, 113, -1, -1, -1, -1, -1, -1, 121, -1, -1, -1, -1, -1, -1, 75 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 3, 20, 23, 24, 25, 26, 27, 34, 35, 55, 60, 61, 85, 90, 91, 92, 4, 7, 64, 21, 9, 38, 46, 0, 51, 5, 6, 8, 29, 43, 44, 45, 46, 52, 55, 65, 66, 67, 68, 69, 28, 45, 46, 55, 72, 72, 58, 53, 53, 53, 70, 53, 41, 42, 9, 57, 53, 41, 53, 10, 73, 38, 54, 54, 43, 44, 45, 52, 54, 43, 5, 6, 29, 43, 71, 72, 55, 69, 43, 28, 29, 45, 55, 86, 87, 29, 33, 45, 49, 53, 55, 74, 76, 54, 54, 54, 54, 54, 53, 53, 53, 56, 10, 57, 62, 73, 41, 54, 53, 53, 41, 54, 57, 53, 32, 74, 74, 41, 47, 48, 36, 49, 50, 81, 54, 54, 43, 72, 15, 82, 43, 43, 29, 22, 87, 43, 45, 54, 29, 74, 74, 81, 37, 43, 44, 46, 55, 78, 4, 11, 12, 39, 40, 75, 56, 56, 54, 16, 17, 83, 54, 54, 53, 53, 54, 53, 37, 42, 40, 53, 78, 13, 56, 68, 74, 18, 84, 56, 43, 37, 43, 46, 88, 89, 43, 43, 77, 78, 48, 43, 46, 80, 16, 19, 63, 54, 54, 57, 54, 56, 54, 57, 78, 14, 55, 79, 68, 24, 56, 89, 56, 78, 43, 14, 32, 43, 68, 56 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 59, 60, 61, 61, 61, 61, 61, 61, 62, 63, 63, 64, 64, 64, 65, 65, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 70, 70, 70, 70, 70, 70, 71, 71, 72, 72, 72, 72, 73, 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 76, 76, 76, 77, 77, 78, 78, 78, 78, 78, 79, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 86, 86, 87, 87, 87, 88, 88, 89, 89, 89, 90, 91, 92, 92, 92, 92, 92, 92, 92, 92 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 2, 0, 6, 1, 1, 1, 1, 5, 0, 4, 0, 1, 1, 0, 1, 1, 1, 1, 1, 3, 6, 1, 3, 6, 1, 3, 2, 1, 4, 7, 1, 1, 4, 1, 0, 2, 3, 3, 3, 3, 1, 3, 1, 4, 7, 1, 0, 2, 3, 2, 3, 3, 6, 6, 6, 4, 3, 0, 1, 1, 2, 1, 4, 7, 1, 3, 1, 1, 1, 1, 4, 0, 2, 4, 1, 1, 0, 1, 0, 3, 0, 2, 0, 3, 10, 1, 3, 1, 4, 7, 1, 3, 1, 1, 1, 4, 7, 1, 1, 1, 1, 2, 4, 1, 1 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Error token number */ #define YYTERROR 1 #define YYERRCODE 256 /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*----------------------------------------. | Print this symbol's value on YYOUTPUT. | `----------------------------------------*/ static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) { FILE *yyo = yyoutput; YYUSE (yyo); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) { YYFPRINTF (yyoutput, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) { unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[yyssp[yyi + 1 - yynrhs]], &(yyvsp[(yyi + 1) - (yynrhs)]) ); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ static YYSIZE_T yystrlen (const char *yystr) { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize = yysize0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per "expected"). */ int yycount = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yytoken != YYEMPTY) { int yyn = yypact[*yyssp]; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; { YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } } } } switch (yycount) { # define YYCASE_(N, S) \ case N: \ yyformat = S; \ break YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); # undef YYCASE_ } { YYSIZE_T yysize1 = yysize + yystrlen (yyformat); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return 1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyformat += 2; } else { yyp++; yyformat++; } } return 0; } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) { YYUSE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*----------. | yyparse. | `----------*/ int yyparse (void) { /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ /* Default value used for initialization, for pacifying older GCCs or non-GCC compilers. */ YY_INITIAL_VALUE (static YYSTYPE yyval_default;) YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Number of syntax errors so far. */ int yynerrs; int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: 'yyss': related to states. 'yyvs': related to semantic values. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYSIZE_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yyssp = yyss = yyssa; yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = yylex (&yylval); } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token. */ yychar = YYEMPTY; yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: #line 166 "yyparse.y" /* yacc.c:1646 */ { YYACCEPT; } #line 1547 "yyparse.c" /* yacc.c:1646 */ break; case 4: #line 172 "yyparse.y" /* yacc.c:1646 */ { if( ! table_check( pyyenv->pstmt ) ) { SETYYERROR(pyyenv, NOT_SUPPORT_MULTITABLE_QUERY); YYABORT; } pyyenv->pstmt->type = en_stmt_select; } #line 1561 "yyparse.c" /* yacc.c:1646 */ break; case 5: #line 182 "yyparse.y" /* yacc.c:1646 */ { pyyenv->pstmt->type = en_stmt_insert; } #line 1569 "yyparse.c" /* yacc.c:1646 */ break; case 6: #line 186 "yyparse.y" /* yacc.c:1646 */ { pyyenv->pstmt->type = en_stmt_srch_delete; } #line 1577 "yyparse.c" /* yacc.c:1646 */ break; case 8: #line 191 "yyparse.y" /* yacc.c:1646 */ { pyyenv->pstmt->type = en_stmt_alloc; YYABORT; } #line 1586 "yyparse.c" /* yacc.c:1646 */ break; case 11: #line 204 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_UPDATEABLE_CURSOR) ; YYABORT; } #line 1595 "yyparse.c" /* yacc.c:1646 */ break; case 14: #line 214 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_DISTINCT_SELECT); YYABORT; } #line 1604 "yyparse.c" /* yacc.c:1646 */ break; case 15: #line 221 "yyparse.y" /* yacc.c:1646 */ { if(add_all_attr(pyyenv->pstmt)) YYABORT; } #line 1610 "yyparse.c" /* yacc.c:1646 */ break; case 16: #line 222 "yyparse.y" /* yacc.c:1646 */ { if(add_all_attr(pyyenv->pstmt)) YYABORT; } #line 1616 "yyparse.c" /* yacc.c:1646 */ break; case 17: #line 223 "yyparse.y" /* yacc.c:1646 */ { if(add_news_attr(pyyenv->pstmt)) YYABORT; } #line 1622 "yyparse.c" /* yacc.c:1646 */ break; case 18: #line 224 "yyparse.y" /* yacc.c:1646 */ { if(add_xnews_attr(pyyenv->pstmt)) YYABORT; } #line 1628 "yyparse.c" /* yacc.c:1646 */ break; case 19: #line 225 "yyparse.y" /* yacc.c:1646 */ { if(add_attr(pyyenv->pstmt, 0, 0)) YYABORT; } #line 1634 "yyparse.c" /* yacc.c:1646 */ break; case 28: #line 247 "yyparse.y" /* yacc.c:1646 */ { yycol_t col; col.iattr = en_sql_count; col.table = 0; if( add_column(pyyenv->pstmt, &col) ) YYABORT; } #line 1649 "yyparse.c" /* yacc.c:1646 */ break; case 29: #line 258 "yyparse.y" /* yacc.c:1646 */ { if( column_name( pyyenv->pstmt, (yyvsp[0].name) ) ) YYABORT; } #line 1655 "yyparse.c" /* yacc.c:1646 */ break; case 30: #line 260 "yyparse.y" /* yacc.c:1646 */ { if( column_name( pyyenv->pstmt, (yyvsp[-1].qstring) ) ) YYABORT; } #line 1661 "yyparse.c" /* yacc.c:1646 */ break; case 31: #line 262 "yyparse.y" /* yacc.c:1646 */ { if( column_name( pyyenv->pstmt, (yyvsp[-2].qstring) ) ) YYABORT; } #line 1667 "yyparse.c" /* yacc.c:1646 */ break; case 32: #line 264 "yyparse.y" /* yacc.c:1646 */ { yycol_t col; col.iattr = en_sql_qstr; col.value.qstr = (yyvsp[0].qstring); col.table = 0; if( add_column(pyyenv->pstmt, &col) ) YYABORT; } #line 1682 "yyparse.c" /* yacc.c:1646 */ break; case 33: #line 275 "yyparse.y" /* yacc.c:1646 */ { yycol_t col; col.iattr = en_sql_num; col.value.num = (yyvsp[0].number); col.table = 0; if( add_column(pyyenv->pstmt, &col) ) YYABORT; } #line 1697 "yyparse.c" /* yacc.c:1646 */ break; case 34: #line 286 "yyparse.y" /* yacc.c:1646 */ { yycol_t col; col.iattr = en_sql_date; if( nnsql_odbcdatestr2date((yyvsp[-1].qstring), &(col.value.date)) ) YYABORT; col.table = 0; if( add_column(pyyenv->pstmt, &col) ) YYABORT; } #line 1714 "yyparse.c" /* yacc.c:1646 */ break; case 35: #line 299 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, VARIABLE_IN_SELECT_LIST); YYABORT; } #line 1720 "yyparse.c" /* yacc.c:1646 */ break; case 42: #line 312 "yyparse.y" /* yacc.c:1646 */ { pyyenv->pstmt->table = (yyvsp[0].name); } #line 1726 "yyparse.c" /* yacc.c:1646 */ break; case 43: #line 314 "yyparse.y" /* yacc.c:1646 */ { if( ! pyyenv->pstmt->table ) pyyenv->pstmt->table = (yyvsp[0].name); else if( !STREQ(pyyenv->pstmt->table, (yyvsp[0].name)) ) { SETYYERROR(pyyenv, NOT_SUPPORT_MULTITABLE_QUERY); YYABORT; } } #line 1740 "yyparse.c" /* yacc.c:1646 */ break; case 44: #line 327 "yyparse.y" /* yacc.c:1646 */ { (yyval.name) = (yyvsp[0].name); } #line 1746 "yyparse.c" /* yacc.c:1646 */ break; case 45: #line 329 "yyparse.y" /* yacc.c:1646 */ { (yyval.name) = (yyvsp[-1].qstring); } #line 1752 "yyparse.c" /* yacc.c:1646 */ break; case 46: #line 331 "yyparse.y" /* yacc.c:1646 */ { (yyval.name) = (yyvsp[-2].qstring); } #line 1758 "yyparse.c" /* yacc.c:1646 */ break; case 47: #line 333 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, VARIABLE_IN_TABLE_LIST); YYABORT; } #line 1767 "yyparse.c" /* yacc.c:1646 */ break; case 48: #line 341 "yyparse.y" /* yacc.c:1646 */ { pyyenv->pstmt->srchtree = 0; } #line 1775 "yyparse.c" /* yacc.c:1646 */ break; case 49: #line 345 "yyparse.y" /* yacc.c:1646 */ { yystmt_t* pstmt; uintptr_t offset; pstmt = pyyenv->pstmt; offset = (uintptr_t)((yyvsp[0].offset)); pstmt->srchtree = pstmt->node_buf + offset; srchtree_reloc ( pstmt->node_buf, pstmt->srchtreenum); } #line 1790 "yyparse.c" /* yacc.c:1646 */ break; case 50: #line 358 "yyparse.y" /* yacc.c:1646 */ { (yyval.offset) = (yyvsp[-1].offset); } #line 1796 "yyparse.c" /* yacc.c:1646 */ break; case 51: #line 360 "yyparse.y" /* yacc.c:1646 */ { node_t node; node.type = en_nt_logop; node.value.logop = en_logop_not; node.left = EMPTY_PTR; node.right= (yyvsp[0].offset); if(((yyval.offset) = add_node(pyyenv->pstmt, &node)) == ERROR_PTR ) YYABORT; } #line 1812 "yyparse.c" /* yacc.c:1646 */ break; case 52: #line 372 "yyparse.y" /* yacc.c:1646 */ { node_t node; void* p; node.type = en_nt_logop; node.value.logop = en_logop_or; node.left = (yyvsp[-2].offset); node.right= (yyvsp[0].offset); if(((yyval.offset) = add_node(pyyenv->pstmt, &node)) == ERROR_PTR ) YYABORT; } #line 1829 "yyparse.c" /* yacc.c:1646 */ break; case 53: #line 385 "yyparse.y" /* yacc.c:1646 */ { node_t node; node.type = en_nt_logop; node.value.logop = en_logop_and; node.left = (yyvsp[-2].offset); node.right= (yyvsp[0].offset); if(((yyval.offset) = add_node(pyyenv->pstmt, &node)) == ERROR_PTR ) YYABORT; } #line 1845 "yyparse.c" /* yacc.c:1646 */ break; case 54: #line 397 "yyparse.y" /* yacc.c:1646 */ { node_t node; void* ptr; node.type = en_nt_in; node.left = (yyvsp[-5].offset); node.right= (yyvsp[-1].offset); if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; if( (yyvsp[-4].flag) ) { node.type = en_nt_logop; node.value.logop = en_logop_not; node.left = EMPTY_PTR; node.right = ptr; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; } (yyval.offset) = ptr; } #line 1874 "yyparse.c" /* yacc.c:1646 */ break; case 55: #line 422 "yyparse.y" /* yacc.c:1646 */ { node_t node; void* ptr; if( ((node.left = add_node(pyyenv->pstmt, &((yyvsp[-2].node)))) == ERROR_PTR) || ((node.right= add_node(pyyenv->pstmt, &((yyvsp[0].node)))) == ERROR_PTR) || ((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) ) YYABORT; node.type = en_nt_between; node.left = (yyvsp[-5].offset); node.right = ptr; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; if( (yyvsp[-4].flag) ) { node.type = en_nt_logop; node.value.logop = en_logop_not; node.left = EMPTY_PTR; node.right= ptr; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; } (yyval.offset) = ptr; } #line 1908 "yyparse.c" /* yacc.c:1646 */ break; case 56: #line 452 "yyparse.y" /* yacc.c:1646 */ { node_t node; void* ptr; if( (yyvsp[-3].flag) ) node.type = en_nt_caselike; else node.type = en_nt_like; node.value.esc = (yyvsp[0].esc); node.left = (yyvsp[-5].offset); node.right= (yyvsp[-1].offset); if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; if( (yyvsp[-4].flag) ) { node.type = en_nt_logop; node.value.logop = en_logop_not; node.left = EMPTY_PTR; node.right= ptr; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; } (yyval.offset) = ptr; } #line 1941 "yyparse.c" /* yacc.c:1646 */ break; case 57: #line 481 "yyparse.y" /* yacc.c:1646 */ { node_t node; void* ptr; node.type = en_nt_isnull; node.left = (yyvsp[-3].offset); node.right= EMPTY_PTR; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; if( (yyvsp[-1].flag) ) { node.type = en_nt_logop; node.value.logop = en_logop_not; node.left = EMPTY_PTR; node.right= ptr; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; } (yyval.offset) = ptr; } #line 1970 "yyparse.c" /* yacc.c:1646 */ break; case 58: #line 506 "yyparse.y" /* yacc.c:1646 */ { node_t node; node.type = en_nt_cmpop; node.value.cmpop = (yyvsp[-1].cmpop); node.left = (yyvsp[-2].offset); if( ((node.right= add_node(pyyenv->pstmt, &((yyvsp[0].node)))) == ERROR_PTR) || (((yyval.offset) = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) ) YYABORT; } #line 1986 "yyparse.c" /* yacc.c:1646 */ break; case 59: #line 521 "yyparse.y" /* yacc.c:1646 */ { (yyval.flag) = 0; } #line 1992 "yyparse.c" /* yacc.c:1646 */ break; case 60: #line 523 "yyparse.y" /* yacc.c:1646 */ { (yyval.flag) = 0; } #line 1998 "yyparse.c" /* yacc.c:1646 */ break; case 61: #line 525 "yyparse.y" /* yacc.c:1646 */ { (yyval.flag) = 1; } #line 2004 "yyparse.c" /* yacc.c:1646 */ break; case 62: #line 527 "yyparse.y" /* yacc.c:1646 */ { (yyval.flag) = 1; } #line 2010 "yyparse.c" /* yacc.c:1646 */ break; case 63: #line 532 "yyparse.y" /* yacc.c:1646 */ { (yyval.offset) = attr_name( pyyenv->pstmt, (yyvsp[0].name) ); if( (yyval.offset) == ERROR_PTR ) YYABORT; } #line 2016 "yyparse.c" /* yacc.c:1646 */ break; case 64: #line 534 "yyparse.y" /* yacc.c:1646 */ { (yyval.offset) = attr_name( pyyenv->pstmt, (yyvsp[-1].qstring) ); if( (yyval.offset) == ERROR_PTR ) YYABORT; } #line 2022 "yyparse.c" /* yacc.c:1646 */ break; case 65: #line 536 "yyparse.y" /* yacc.c:1646 */ { (yyval.offset) = attr_name( pyyenv->pstmt, (yyvsp[-2].qstring) ); if( (yyval.offset) == ERROR_PTR ) YYABORT; } #line 2028 "yyparse.c" /* yacc.c:1646 */ break; case 66: #line 541 "yyparse.y" /* yacc.c:1646 */ { if( ((yyval.offset) = add_node( pyyenv->pstmt, &((yyvsp[0].node)))) == ERROR_PTR ) YYABORT; } #line 2037 "yyparse.c" /* yacc.c:1646 */ break; case 67: #line 546 "yyparse.y" /* yacc.c:1646 */ { node_t node; node = (yyvsp[0].node); node.left = EMPTY_PTR; node.right= (yyvsp[-2].offset); if( ((yyval.offset) = add_node(pyyenv->pstmt, &node)) == ERROR_PTR ) YYABORT; } #line 2052 "yyparse.c" /* yacc.c:1646 */ break; case 68: #line 560 "yyparse.y" /* yacc.c:1646 */ { node_t node; node.type = en_nt_null; node.left = EMPTY_PTR; node.right= EMPTY_PTR; (yyval.node) = node; } #line 2066 "yyparse.c" /* yacc.c:1646 */ break; case 69: #line 570 "yyparse.y" /* yacc.c:1646 */ { node_t node; node.type = en_nt_param, node.value.ipar = (yyvsp[0].ipar); node.left = EMPTY_PTR; node.right= EMPTY_PTR; pyyenv->pstmt->npar ++; (yyval.node) = node; } #line 2083 "yyparse.c" /* yacc.c:1646 */ break; case 70: #line 583 "yyparse.y" /* yacc.c:1646 */ { node_t node; node.type = en_nt_qstr; node.value.qstr = (yyvsp[0].qstring); node.left = EMPTY_PTR; node.right= EMPTY_PTR; (yyval.node) = node; } #line 2098 "yyparse.c" /* yacc.c:1646 */ break; case 71: #line 594 "yyparse.y" /* yacc.c:1646 */ { node_t node; node.type = en_nt_num; node.value.num = (yyvsp[0].number); node.left = EMPTY_PTR; node.right= EMPTY_PTR; (yyval.node) = node; } #line 2113 "yyparse.c" /* yacc.c:1646 */ break; case 72: #line 605 "yyparse.y" /* yacc.c:1646 */ { node_t node; node.type = en_nt_date; if( nnsql_odbcdatestr2date((yyvsp[-1].qstring), &(node.value.date)) ) YYABORT; node.left = EMPTY_PTR; node.right= EMPTY_PTR; (yyval.node) = node; } #line 2130 "yyparse.c" /* yacc.c:1646 */ break; case 73: #line 620 "yyparse.y" /* yacc.c:1646 */ { (yyval.esc) = 0; } #line 2136 "yyparse.c" /* yacc.c:1646 */ break; case 74: #line 621 "yyparse.y" /* yacc.c:1646 */ { (yyval.esc) = (yyvsp[0].qstring)[0]; } #line 2142 "yyparse.c" /* yacc.c:1646 */ break; case 75: #line 622 "yyparse.y" /* yacc.c:1646 */ { (yyval.esc) = (yyvsp[-1].qstring)[0]; } #line 2148 "yyparse.c" /* yacc.c:1646 */ break; case 76: #line 627 "yyparse.y" /* yacc.c:1646 */ { node_t node; node.type = en_nt_param; node.value.ipar = (yyvsp[0].ipar); node.left = EMPTY_PTR; node.right= EMPTY_PTR; pyyenv->pstmt->npar ++; if(((yyval.offset) = add_node(pyyenv->pstmt, &node)) == EMPTY_PTR) YYABORT; } #line 2166 "yyparse.c" /* yacc.c:1646 */ break; case 77: #line 641 "yyparse.y" /* yacc.c:1646 */ { node_t node; node.type = en_nt_qstr; node.value.qstr = (yyvsp[0].qstring); node.left = EMPTY_PTR; node.right= EMPTY_PTR; if(((yyval.offset) = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; } #line 2182 "yyparse.c" /* yacc.c:1646 */ break; case 78: #line 655 "yyparse.y" /* yacc.c:1646 */ { (yyval.flag) = 0; } #line 2188 "yyparse.c" /* yacc.c:1646 */ break; case 79: #line 656 "yyparse.y" /* yacc.c:1646 */ { (yyval.flag) = 1; } #line 2194 "yyparse.c" /* yacc.c:1646 */ break; case 81: #line 662 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_GROUP_CLAUSE); YYABORT; } #line 2203 "yyparse.c" /* yacc.c:1646 */ break; case 83: #line 671 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_HAVING_CLAUSE); YYABORT; } #line 2212 "yyparse.c" /* yacc.c:1646 */ break; case 85: #line 680 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_ORDER_CLAUSE); YYABORT; } #line 2221 "yyparse.c" /* yacc.c:1646 */ break; case 86: #line 688 "yyparse.y" /* yacc.c:1646 */ { int i; char* head = 0; if( (yyvsp[-5].idx) > (yyvsp[-1].idx) ) { SETYYERROR(pyyenv, INSERT_VALUE_LESS); YYABORT; } if( (yyvsp[-5].idx) < (yyvsp[-1].idx) ) { SETYYERROR(pyyenv, INSERT_VALUE_MORE); YYABORT; } for(i=0;;i++) { head = (pyyenv->pstmt->ins_heads)[i]; if( ! head ) { SETYYERROR(pyyenv, POST_WITHOUT_BODY); YYABORT; } if( nnsql_getcolidxbyname(head) == en_body ) break; } if( add_ins_head(pyyenv->pstmt, 0, (yyvsp[-5].idx)) == -1 ) YYABORT; pyyenv->pstmt->table = (yyvsp[-7].name); /* we will not check table(i.e. group)name here. * According to RFC1036, it is totally legal to * post an articl to a group which is not access * able locally. * table name here is actually newsgroups name. * it should look like: * ,,... * Be aware, there are must no space between the * ',' and the two s. Also, group * names are case sensitive. */ } #line 2272 "yyparse.c" /* yacc.c:1646 */ break; case 87: #line 738 "yyparse.y" /* yacc.c:1646 */ { if( ((yyval.idx) = add_ins_head(pyyenv->pstmt, (yyvsp[0].qstring), 0)) == -1) YYABORT; } #line 2281 "yyparse.c" /* yacc.c:1646 */ break; case 88: #line 743 "yyparse.y" /* yacc.c:1646 */ { if( ((yyval.idx) = add_ins_head(pyyenv->pstmt, (yyvsp[0].qstring), (yyvsp[-2].idx)))== -1) YYABORT; } #line 2290 "yyparse.c" /* yacc.c:1646 */ break; case 89: #line 751 "yyparse.y" /* yacc.c:1646 */ { (yyval.qstring) = get_unpacked_attrname(pyyenv->pstmt, (yyvsp[0].name)); } #line 2296 "yyparse.c" /* yacc.c:1646 */ break; case 90: #line 753 "yyparse.y" /* yacc.c:1646 */ { (yyval.qstring) = get_unpacked_attrname(pyyenv->pstmt, (yyvsp[-1].qstring)); } #line 2302 "yyparse.c" /* yacc.c:1646 */ break; case 91: #line 755 "yyparse.y" /* yacc.c:1646 */ { (yyval.qstring) = (yyvsp[-2].qstring); } #line 2308 "yyparse.c" /* yacc.c:1646 */ break; case 92: #line 760 "yyparse.y" /* yacc.c:1646 */ { if( ((yyval.idx) = add_ins_value(pyyenv->pstmt, (yyvsp[0].node), 0))== -1) YYABORT; } #line 2317 "yyparse.c" /* yacc.c:1646 */ break; case 93: #line 765 "yyparse.y" /* yacc.c:1646 */ { if( ((yyval.idx) = add_ins_value(pyyenv->pstmt, (yyvsp[0].node), (yyvsp[-2].idx)))==-1) YYABORT; } #line 2326 "yyparse.c" /* yacc.c:1646 */ break; case 94: #line 773 "yyparse.y" /* yacc.c:1646 */ { (yyval.node).type = en_nt_null; } #line 2334 "yyparse.c" /* yacc.c:1646 */ break; case 95: #line 777 "yyparse.y" /* yacc.c:1646 */ { (yyval.node).type = en_nt_qstr; (yyval.node).value.qstr = (yyvsp[0].qstring); } #line 2343 "yyparse.c" /* yacc.c:1646 */ break; case 96: #line 782 "yyparse.y" /* yacc.c:1646 */ { (yyval.node).type = en_nt_param; (yyval.node).value.ipar= (yyvsp[0].ipar); } #line 2352 "yyparse.c" /* yacc.c:1646 */ break; case 97: #line 790 "yyparse.y" /* yacc.c:1646 */ { pyyenv->pstmt->table = (yyvsp[-1].name); if( add_attr( pyyenv->pstmt, en_sender, 1 ) || add_attr( pyyenv->pstmt, en_from, 1 ) || add_attr( pyyenv->pstmt, en_msgid, 1 ) ) YYABORT; } #line 2365 "yyparse.c" /* yacc.c:1646 */ break; case 98: #line 802 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR( pyyenv, NOT_SUPPORT_POSITION_DELETE ); YYABORT; } #line 2374 "yyparse.c" /* yacc.c:1646 */ break; case 99: #line 809 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_DDL_DCL); } #line 2380 "yyparse.c" /* yacc.c:1646 */ break; case 100: #line 810 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_DDL_DCL); } #line 2386 "yyparse.c" /* yacc.c:1646 */ break; case 101: #line 811 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_DDL_DCL); } #line 2392 "yyparse.c" /* yacc.c:1646 */ break; case 102: #line 812 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_UPDATE); } #line 2398 "yyparse.c" /* yacc.c:1646 */ break; case 103: #line 813 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_SPROC); } #line 2404 "yyparse.c" /* yacc.c:1646 */ break; case 104: #line 815 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_SPROC); } #line 2410 "yyparse.c" /* yacc.c:1646 */ break; case 105: #line 816 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_DDL_DCL); } #line 2416 "yyparse.c" /* yacc.c:1646 */ break; case 106: #line 817 "yyparse.y" /* yacc.c:1646 */ { SETYYERROR(pyyenv, NOT_SUPPORT_DDL_DCL); } #line 2422 "yyparse.c" /* yacc.c:1646 */ break; #line 2426 "yyparse.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif return yyresult; } #line 819 "yyparse.y" /* yacc.c:1906 */ static void unpack_col_name(char* schema_tab_column_name, column_name_t* ptr) { int len, i; char c; len = STRLEN(schema_tab_column_name); for(i=len; i; i--) { if( schema_tab_column_name[i-1] == '.' ) { schema_tab_column_name[i-1] = 0; break; } } ptr->column_name = ( schema_tab_column_name + i ); if( i ) ptr->schema_tab_name = schema_tab_column_name; else ptr->schema_tab_name = schema_tab_column_name + len; } static char* get_unpacked_attrname(yystmt_t* pstmt, char* name) { column_name_t attrname; unpack_col_name( name, &attrname ); return attrname.column_name; } #define FILTER_CHUNK_SIZE 16 static void* add_node(yystmt_t* pstmt, node_t* node) { int i; node_t* srchtree; if (!pstmt->node_buf) { pstmt->node_buf = (node_t*)MEM_ALLOC( sizeof(node_t)*FILTER_CHUNK_SIZE); if( ! pstmt->node_buf ) { pstmt->errcode = -1; return ERROR_PTR; } pstmt->srchtreesize = FILTER_CHUNK_SIZE; pstmt->srchtreenum = 0; } if( pstmt->srchtreenum == pstmt->srchtreesize ) { pstmt->node_buf = (node_t*)MEM_REALLOC( pstmt->node_buf, sizeof(node_t)*(pstmt->srchtreesize + FILTER_CHUNK_SIZE)); if( ! pstmt->node_buf ) { pstmt->errcode = -1; return ERROR_PTR; } pstmt->srchtreesize += FILTER_CHUNK_SIZE; } srchtree = pstmt->node_buf; srchtree[pstmt->srchtreenum] = *node; pstmt->srchtreenum ++; for(i=pstmt->srchtreenum;isrchtreesize;i++) { srchtree[i].left = EMPTY_PTR; srchtree[i].right= EMPTY_PTR; } return (void*)((uintptr_t)(pstmt->srchtreenum - 1)); } static void srchtree_reloc(node_t* buf, int num) /* The 'where' srchtree is build on a re-allocateable array with addnode(). The purpose * of using an array rather than a link list is to easy the job of freeing it. Thus, * the left and right pointer of a node point is an offset to the array address not * the virtual address of the subtree. However, an evaluate function would be easy to * work by using virtual address of subtree rather than an offset. Because, in the first * case, a recrusive evaluate function only need to pass virtual address of (sub)tree * without worry about the offset of subtree. The purpose of this function, srchtree_reloc(), * is to convert all subnodes' offset into virtual address. It will called only once * after the whole tree has been built. */ { int i; uintptr_t offset; node_t* ptr = buf; for(i=0; ptr && ileft == EMPTY_PTR ) ptr->left = 0; else { offset = (uintptr_t)(ptr->left); ptr->left = buf + offset; } if( ptr->right== EMPTY_PTR ) ptr->right= 0; else { offset = (uintptr_t)(ptr->right); ptr->right= buf+ offset; } } } static int add_attr(yystmt_t* pstmt, int idx, int wstat) { if( ! pstmt->pattr ) { pstmt->pattr = (yyattr_t*)MEM_ALLOC((en_body+1)*sizeof(yyattr_t)); if( ! pstmt->pattr ) { pstmt->errcode = -1; return -1; } MEM_SET(pstmt->pattr, 0, (en_body+1)*sizeof(yyattr_t)); } (pstmt->pattr)[0].stat = 1; (pstmt->pattr)[0].wstat = 1; (pstmt->pattr)[0].article = 0; (pstmt->pattr)[0].nntp_hand = 0; (pstmt->pattr)[idx].stat = 1; (pstmt->pattr)[idx].wstat |= wstat; return 0; } static void* add_all_attr(yystmt_t* pstmt) { int i; yycol_t col; for(i=en_article_num + 1; i < en_body + 1; i++) { col.iattr = i; col.table = 0; if( add_column(pstmt, &col) || add_attr (pstmt, i, 0) ) return ERROR_PTR; } return 0; } static const int news_attr[] = { en_subject, en_date, en_from, en_organization, en_msgid, en_body }; static void* add_news_attr(yystmt_t* pstmt) { int i, n; yycol_t col; n = sizeof(news_attr)/sizeof(news_attr[0]); for(i=0; ipcol ) { pstmt->pcol = (yycol_t*)MEM_ALLOC((MAX_COLUMN_NUMBER + 1)*sizeof(yycol_t)); if( ! pstmt->pcol ) { pstmt->errcode = -1; return ERROR_PTR; } MEM_SET( pstmt->pcol, 0, (MAX_COLUMN_NUMBER + 1)*sizeof(yycol_t)); } if( ! pstmt->ncol ) { pstmt->ncol = 1; pstmt->pcol->iattr = en_article_num; pstmt->pcol->table = 0; } if( pstmt->ncol > MAX_COLUMN_NUMBER + 1) { pstmt->errcode = TOO_MANY_COLUMNS; return ERROR_PTR; } pcol = pstmt->pcol + pstmt->ncol; pstmt->ncol++; *pcol = *column; return 0; } static void nnsql_yyerror(yyenv_t* pyyenv, char* msg) { yystmt_t* pstmt = pyyenv->pstmt; pstmt->errcode = PARSER_ERROR; pstmt->errpos = pyyenv->errpos; sprintf(pstmt->msgbuf, NNSQL_ERRHEAD "%s", msg); } static int table_check(yystmt_t* pstmt) { int i; char *table, *table1; table = pstmt->table; if( ! (table && *table) ) return 0; for(i=1;pstmt->pcol && incol;i++) { table1 = (pstmt->pcol)[i].table; if( table1 && *table1 && !STREQ( table, table1 ) ) return 0; } return 1; } static void* attr_name(yystmt_t* pstmt, char* name) { node_t node; column_name_t attrname; int attridx; void* offset; unpack_col_name( name, &attrname ); attridx = nnsql_getcolidxbyname( attrname.column_name ); if( attridx == -1 ) { pstmt->errcode = INVALID_COLUMN_NAME; return ERROR_PTR; } if( attridx == en_body ) { pstmt->errcode = UNSEARCHABLE_ATTR; return ERROR_PTR; } node.type = en_nt_attr; node.value.iattr = attridx; node.left = EMPTY_PTR; node.right= EMPTY_PTR; if( (offset = add_node(pstmt, &node)) == ERROR_PTR ) return ERROR_PTR; if( add_attr(pstmt, attridx, 1) ) return ERROR_PTR; return offset; } static int column_name(yystmt_t* pstmt, char* name) { column_name_t colname; int colidx; yycol_t col; unpack_col_name( name, &colname ); colidx = nnsql_getcolidxbyname( colname.column_name ); if( colidx == -1 ) { pstmt->errcode = INVALID_COLUMN_NAME; return -1; } col.iattr = colidx; col.table = colname.schema_tab_name; if( add_column(pstmt, &col) || add_attr(pstmt, colidx, 0) ) return -1; return 0; } static int add_ins_head( yystmt_t* pstmt, char* head, int idx) { if( !idx ) { MEM_FREE(pstmt->ins_heads); pstmt->ins_heads = (char**)MEM_ALLOC( FILTER_CHUNK_SIZE * sizeof(char*)); } else if( ! idx%FILTER_CHUNK_SIZE ) { pstmt->ins_heads = (char**)MEM_REALLOC( pstmt->ins_heads, (idx+FILTER_CHUNK_SIZE)*sizeof(char*)); } if( ! pstmt->ins_heads ) return -1; (pstmt->ins_heads)[idx] = head; return idx + 1; } static int add_ins_value( yystmt_t* pstmt, node_t node, int idx) { if( !idx ) { MEM_FREE(pstmt->ins_values); pstmt->ins_values = (node_t*)MEM_ALLOC( FILTER_CHUNK_SIZE * sizeof(node_t)); } else if( ! idx%FILTER_CHUNK_SIZE ) { pstmt->ins_values = (node_t*)MEM_REALLOC( pstmt->ins_values, (idx+FILTER_CHUNK_SIZE)*sizeof(node_t)); } if( ! pstmt->ins_values ) return -1; (pstmt->ins_values)[idx] = node; return idx + 1; } unixODBC-2.3.12/Drivers/nn/yyparse.tab.h000066400000000000000000000024731446441710500176710ustar00rootroot00000000000000typedef union { char* qstring; char* name; long number; int ipar; /* parameter index */ int cmpop; /* for comparsion operators */ char esc; int flag; /* for not_opt and case_opt */ int idx; void* offset; /* actually, it is used as a 'int' offset */ node_t node; /* a node haven't add to tree */ } YYSTYPE; #define kwd_select 258 #define kwd_all 259 #define kwd_news 260 #define kwd_xnews 261 #define kwd_distinct 262 #define kwd_count 263 #define kwd_from 264 #define kwd_where 265 #define kwd_in 266 #define kwd_between 267 #define kwd_like 268 #define kwd_escape 269 #define kwd_group 270 #define kwd_by 271 #define kwd_having 272 #define kwd_order 273 #define kwd_for 274 #define kwd_insert 275 #define kwd_into 276 #define kwd_values 277 #define kwd_delete 278 #define kwd_update 279 #define kwd_create 280 #define kwd_alter 281 #define kwd_drop 282 #define kwd_table 283 #define kwd_column 284 #define kwd_view 285 #define kwd_index 286 #define kwd_of 287 #define kwd_current 288 #define kwd_grant 289 #define kwd_revoke 290 #define kwd_is 291 #define kwd_null 292 #define kwd_call 293 #define kwd_uncase 294 #define kwd_case 295 #define kwd_fn 296 #define kwd_d 297 #define QSTRING 298 #define NUM 299 #define NAME 300 #define PARAM 301 #define kwd_or 302 #define kwd_and 303 #define kwd_not 304 #define CMPOP 305 unixODBC-2.3.12/Drivers/nn/yyparse.y000066400000000000000000000550761446441710500171540ustar00rootroot00000000000000%{ /** source of nntp odbc sql parser -- yyparse.y Copyright (C) 1995, 1996 by Ke Jin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ static char sccsid[] = "@(#)SQL parser for NNSQL(NetNews SQL), Copyright(c) 1995, 1996 by Ke Jin"; #include #include #include #include #include #include #include #include #include #include # ifdef YYLSP_NEEDED # undef YYLSP_NEEDED # endif #if defined(YYBISON) || defined(__YY_BISON__) # define yylex(pyylval) nnsql_yylex(pyylval, pyyenv) #else # define yylex() nnsql_yylex(&yylval, pyyenv) #endif union YYSTYPE; int nnsql_yylex(union YYSTYPE* pyylval, yyenv_t* penv); #define yyparse(x) nnsql_yyparse (yyenv_t* pyyenv) #define yyerror(msg) nnsql_yyerror (pyyenv, msg) #define SETYYERROR(env, code) { env->pstmt->errcode = code; \ env->pstmt->errpos = env->errpos;} typedef struct { char* schema_tab_name; char* column_name; } column_name_t; static void unpack_col_name(char* schema_tab_column_name, column_name_t* ptr); static void* add_node(yystmt_t* pstmt, node_t* node); static void srchtree_reloc(node_t* srchtree, int num); static int add_attr(yystmt_t* pstmt, int idx, int wstat); static void* add_all_attr(yystmt_t* pstmt); static void* add_news_attr(yystmt_t* pstmt); static void* add_xnews_attr(yystmt_t* pstmt); static void* add_column(yystmt_t* pstmt, yycol_t* pcol); static void nnsql_yyerror(yyenv_t* pyyenv, char* msg); static int table_check(yystmt_t* pstmt); static int column_name(yystmt_t* pstmt, char* name); static void* attr_name(yystmt_t* pstmt, char* name); static int add_ins_head(yystmt_t* pstmt, char* head, int idx); static int add_ins_value(yystmt_t* pstmt, node_t node, int idx); static char* get_unpacked_attrname(yystmt_t* pstmt, char* name); #define ERROR_PTR ((void*)(-1L)) #define EMPTY_PTR ERROR_PTR %} %pure_parser /* forcing to generate reentrant parser */ %start sql_stmt %union { char* qstring; char* name; long number; int ipar; /* parameter index */ int cmpop; /* for comparsion operators */ char esc; int flag; /* for not_opt and case_opt */ int idx; void* offset; /* actually, it is used as a 'int' offset */ node_t node; /* a node haven't add to tree */ } %token kwd_select %token kwd_all %token kwd_news %token kwd_xnews %token kwd_distinct %token kwd_count %token kwd_from %token kwd_where %token kwd_in %token kwd_between %token kwd_like %token kwd_escape %token kwd_group %token kwd_by %token kwd_having %token kwd_order %token kwd_for %token kwd_insert %token kwd_into %token kwd_values %token kwd_delete %token kwd_update %token kwd_create %token kwd_alter %token kwd_drop %token kwd_table %token kwd_column %token kwd_view %token kwd_index %token kwd_of %token kwd_current %token kwd_grant %token kwd_revoke %token kwd_is %token kwd_null %token kwd_call %token kwd_uncase %token kwd_case %token kwd_fn %token kwd_d %token QSTRING %token NUM %token NAME %token PARAM %type escape_desc %type not_opt %type case_opt %type tab_name %type search_condition %type pattern %type attr_name %type value_list %type ins_head_list %type ins_value_list %type value %type ins_value %type ins_head %left kwd_or %left kwd_and %nonassoc kwd_not %nonassoc CMPOP %% sql_stmt : stmt_body ';' { YYACCEPT; } ; stmt_body : | kwd_select distinct_opt select_list kwd_from tab_list select_clauses { if( ! table_check( pyyenv->pstmt ) ) { SETYYERROR(pyyenv, NOT_SUPPORT_MULTITABLE_QUERY); YYABORT; } pyyenv->pstmt->type = en_stmt_select; } | insert_stmt { pyyenv->pstmt->type = en_stmt_insert; } | srch_delete_stmt { pyyenv->pstmt->type = en_stmt_srch_delete; } | posi_delete_stmt | other_stmt { pyyenv->pstmt->type = en_stmt_alloc; YYABORT; } ; select_clauses : where_clause group_clause having_clause order_clause for_stmt ; for_stmt : | kwd_for kwd_update kwd_of col_name_list { SETYYERROR(pyyenv, NOT_SUPPORT_UPDATEABLE_CURSOR) ; YYABORT; } ; distinct_opt : | kwd_all | kwd_distinct { SETYYERROR(pyyenv, NOT_SUPPORT_DISTINCT_SELECT); YYABORT; } ; select_list : { if(add_all_attr(pyyenv->pstmt)) YYABORT; } | '*' { if(add_all_attr(pyyenv->pstmt)) YYABORT; } | news_hotlist { if(add_news_attr(pyyenv->pstmt)) YYABORT; } | news_xhotlist { if(add_xnews_attr(pyyenv->pstmt)) YYABORT; } | col_name_list { if(add_attr(pyyenv->pstmt, 0, 0)) YYABORT; } ; news_hotlist : kwd_news | kwd_news '(' ')' | '{' kwd_fn kwd_news '(' ')' '}' ; news_xhotlist : kwd_xnews | kwd_xnews '(' ')' | '{' kwd_fn kwd_xnews '(' ')' '}' ; col_name_list : col_name | col_name_list ',' col_name ; col_name : kwd_count count_sub_opt { yycol_t col; col.iattr = en_sql_count; col.table = 0; if( add_column(pyyenv->pstmt, &col) ) YYABORT; } | NAME { if( column_name( pyyenv->pstmt, $1 ) ) YYABORT; } | kwd_column '(' QSTRING ')' { if( column_name( pyyenv->pstmt, $3 ) ) YYABORT; } | '{' kwd_fn kwd_column '(' QSTRING ')' '}' { if( column_name( pyyenv->pstmt, $5 ) ) YYABORT; } | QSTRING { yycol_t col; col.iattr = en_sql_qstr; col.value.qstr = $1; col.table = 0; if( add_column(pyyenv->pstmt, &col) ) YYABORT; } | NUM { yycol_t col; col.iattr = en_sql_num; col.value.num = $1; col.table = 0; if( add_column(pyyenv->pstmt, &col) ) YYABORT; } | '{' kwd_d QSTRING '}' { yycol_t col; col.iattr = en_sql_date; if( nnsql_odbcdatestr2date($3, &(col.value.date)) ) YYABORT; col.table = 0; if( add_column(pyyenv->pstmt, &col) ) YYABORT; } | PARAM { SETYYERROR(pyyenv, VARIABLE_IN_SELECT_LIST); YYABORT; } ; count_sub_opt : | '(' ')' | '(' '*' ')' | '(' NAME ')' | '(' QSTRING ')' | '(' NUM ')' ; tab_list : tab_name { pyyenv->pstmt->table = $1; } | tab_list ',' tab_name { if( ! pyyenv->pstmt->table ) pyyenv->pstmt->table = $3; else if( !STREQ(pyyenv->pstmt->table, $3) ) { SETYYERROR(pyyenv, NOT_SUPPORT_MULTITABLE_QUERY); YYABORT; } } ; tab_name : NAME { $$ = $1; } | kwd_table '(' QSTRING ')' { $$ = $3; } | '{' kwd_fn kwd_table '(' QSTRING ')' '}' { $$ = $5; } | PARAM { SETYYERROR(pyyenv, VARIABLE_IN_TABLE_LIST); YYABORT; } ; where_clause : { pyyenv->pstmt->srchtree = 0; } | kwd_where search_condition { yystmt_t* pstmt; uintptr_t offset; pstmt = pyyenv->pstmt; offset = (uintptr_t)($2); pstmt->srchtree = pstmt->node_buf + offset; srchtree_reloc ( pstmt->node_buf, pstmt->srchtreenum); } ; search_condition : '(' search_condition ')' { $$ = $2; } | kwd_not search_condition { node_t node; node.type = en_nt_logop; node.value.logop = en_logop_not; node.left = EMPTY_PTR; node.right= $2; if(($$ = add_node(pyyenv->pstmt, &node)) == ERROR_PTR ) YYABORT; } | search_condition kwd_or search_condition { node_t node; void* p; node.type = en_nt_logop; node.value.logop = en_logop_or; node.left = $1; node.right= $3; if(($$ = add_node(pyyenv->pstmt, &node)) == ERROR_PTR ) YYABORT; } | search_condition kwd_and search_condition { node_t node; node.type = en_nt_logop; node.value.logop = en_logop_and; node.left = $1; node.right= $3; if(($$ = add_node(pyyenv->pstmt, &node)) == ERROR_PTR ) YYABORT; } | attr_name not_opt kwd_in '(' value_list ')' { node_t node; void* ptr; node.type = en_nt_in; node.left = $1; node.right= $5; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; if( $2 ) { node.type = en_nt_logop; node.value.logop = en_logop_not; node.left = EMPTY_PTR; node.right = ptr; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; } $$ = ptr; } | attr_name not_opt kwd_between value kwd_and value { node_t node; void* ptr; if( ((node.left = add_node(pyyenv->pstmt, &($4))) == ERROR_PTR) || ((node.right= add_node(pyyenv->pstmt, &($6))) == ERROR_PTR) || ((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) ) YYABORT; node.type = en_nt_between; node.left = $1; node.right = ptr; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; if( $2 ) { node.type = en_nt_logop; node.value.logop = en_logop_not; node.left = EMPTY_PTR; node.right= ptr; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; } $$ = ptr; } | attr_name not_opt case_opt kwd_like pattern escape_desc { node_t node; void* ptr; if( $3 ) node.type = en_nt_caselike; else node.type = en_nt_like; node.value.esc = $6; node.left = $1; node.right= $5; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; if( $2 ) { node.type = en_nt_logop; node.value.logop = en_logop_not; node.left = EMPTY_PTR; node.right= ptr; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; } $$ = ptr; } | attr_name kwd_is not_opt kwd_null { node_t node; void* ptr; node.type = en_nt_isnull; node.left = $1; node.right= EMPTY_PTR; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; if( $3 ) { node.type = en_nt_logop; node.value.logop = en_logop_not; node.left = EMPTY_PTR; node.right= ptr; if((ptr = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; } $$ = ptr; } | attr_name CMPOP value { node_t node; node.type = en_nt_cmpop; node.value.cmpop = $2; node.left = $1; if( ((node.right= add_node(pyyenv->pstmt, &($3))) == ERROR_PTR) || (($$ = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) ) YYABORT; } ; case_opt : { $$ = 0; } | kwd_case { $$ = 0; } | kwd_uncase { $$ = 1; } | kwd_all kwd_case { $$ = 1; } ; attr_name : NAME { $$ = attr_name( pyyenv->pstmt, $1 ); if( $$ == ERROR_PTR ) YYABORT; } | kwd_column '(' QSTRING ')' { $$ = attr_name( pyyenv->pstmt, $3 ); if( $$ == ERROR_PTR ) YYABORT; } | '{' kwd_fn kwd_column '(' QSTRING ')' '}' { $$ = attr_name( pyyenv->pstmt, $5 ); if( $$ == ERROR_PTR ) YYABORT; } ; value_list : value { if( ($$ = add_node( pyyenv->pstmt, &($1))) == ERROR_PTR ) YYABORT; } | value_list ',' value { node_t node; node = $3; node.left = EMPTY_PTR; node.right= $1; if( ($$ = add_node(pyyenv->pstmt, &node)) == ERROR_PTR ) YYABORT; } ; value : kwd_null { node_t node; node.type = en_nt_null; node.left = EMPTY_PTR; node.right= EMPTY_PTR; $$ = node; } | PARAM { node_t node; node.type = en_nt_param, node.value.ipar = $1; node.left = EMPTY_PTR; node.right= EMPTY_PTR; pyyenv->pstmt->npar ++; $$ = node; } | QSTRING { node_t node; node.type = en_nt_qstr; node.value.qstr = $1; node.left = EMPTY_PTR; node.right= EMPTY_PTR; $$ = node; } | NUM { node_t node; node.type = en_nt_num; node.value.num = $1; node.left = EMPTY_PTR; node.right= EMPTY_PTR; $$ = node; } | '{' kwd_d QSTRING '}' { node_t node; node.type = en_nt_date; if( nnsql_odbcdatestr2date($3, &(node.value.date)) ) YYABORT; node.left = EMPTY_PTR; node.right= EMPTY_PTR; $$ = node; } ; escape_desc : { $$ = 0; } | kwd_escape QSTRING { $$ = $2[0]; } | '{' kwd_escape QSTRING '}' { $$ = $3[0]; } ; pattern : PARAM { node_t node; node.type = en_nt_param; node.value.ipar = $1; node.left = EMPTY_PTR; node.right= EMPTY_PTR; pyyenv->pstmt->npar ++; if(($$ = add_node(pyyenv->pstmt, &node)) == EMPTY_PTR) YYABORT; } | QSTRING { node_t node; node.type = en_nt_qstr; node.value.qstr = $1; node.left = EMPTY_PTR; node.right= EMPTY_PTR; if(($$ = add_node(pyyenv->pstmt, &node)) == ERROR_PTR) YYABORT; } ; not_opt : { $$ = 0; } | kwd_not { $$ = 1; } ; group_clause : | kwd_group kwd_by col_name_list { SETYYERROR(pyyenv, NOT_SUPPORT_GROUP_CLAUSE); YYABORT; } ; having_clause : | kwd_having search_condition { SETYYERROR(pyyenv, NOT_SUPPORT_HAVING_CLAUSE); YYABORT; } ; order_clause : | kwd_order kwd_by col_name_list { SETYYERROR(pyyenv, NOT_SUPPORT_ORDER_CLAUSE); YYABORT; } ; insert_stmt : kwd_insert kwd_into tab_name '(' ins_head_list ')' kwd_values '(' ins_value_list ')' { int i; char* head = 0; if( $5 > $9 ) { SETYYERROR(pyyenv, INSERT_VALUE_LESS); YYABORT; } if( $5 < $9 ) { SETYYERROR(pyyenv, INSERT_VALUE_MORE); YYABORT; } for(i=0;;i++) { head = (pyyenv->pstmt->ins_heads)[i]; if( ! head ) { SETYYERROR(pyyenv, POST_WITHOUT_BODY); YYABORT; } if( nnsql_getcolidxbyname(head) == en_body ) break; } if( add_ins_head(pyyenv->pstmt, 0, $5) == -1 ) YYABORT; pyyenv->pstmt->table = $3; /* we will not check table(i.e. group)name here. * According to RFC1036, it is totally legal to * post an articl to a group which is not access * able locally. * table name here is actually newsgroups name. * it should look like: * ,,... * Be aware, there are must no space between the * ',' and the two s. Also, group * names are case sensitive. */ } ; ins_head_list : ins_head { if( ($$ = add_ins_head(pyyenv->pstmt, $1, 0)) == -1) YYABORT; } | ins_head_list ',' ins_head { if( ($$ = add_ins_head(pyyenv->pstmt, $3, $1))== -1) YYABORT; } ; ins_head : NAME { $$ = get_unpacked_attrname(pyyenv->pstmt, $1); } | kwd_column '(' QSTRING ')' { $$ = get_unpacked_attrname(pyyenv->pstmt, $3); } | '{' kwd_fn kwd_column '(' QSTRING ')' '}' { $$ = $5; } ; ins_value_list : ins_value { if( ($$ = add_ins_value(pyyenv->pstmt, $1, 0))== -1) YYABORT; } | ins_value_list ',' ins_value { if( ($$ = add_ins_value(pyyenv->pstmt, $3, $1))==-1) YYABORT; } ; ins_value : kwd_null { $$.type = en_nt_null; } | QSTRING { $$.type = en_nt_qstr; $$.value.qstr = $1; } | PARAM { $$.type = en_nt_param; $$.value.ipar= $1; } ; srch_delete_stmt : kwd_delete kwd_from tab_name where_clause { pyyenv->pstmt->table = $3; if( add_attr( pyyenv->pstmt, en_sender, 1 ) || add_attr( pyyenv->pstmt, en_from, 1 ) || add_attr( pyyenv->pstmt, en_msgid, 1 ) ) YYABORT; } ; posi_delete_stmt : kwd_delete kwd_from tab_name kwd_where kwd_current kwd_of NAME { SETYYERROR( pyyenv, NOT_SUPPORT_POSITION_DELETE ); YYABORT; } ; other_stmt : kwd_create { SETYYERROR(pyyenv, NOT_SUPPORT_DDL_DCL); } | kwd_alter { SETYYERROR(pyyenv, NOT_SUPPORT_DDL_DCL); } | kwd_drop { SETYYERROR(pyyenv, NOT_SUPPORT_DDL_DCL); } | kwd_update { SETYYERROR(pyyenv, NOT_SUPPORT_UPDATE); } | '{' kwd_call { SETYYERROR(pyyenv, NOT_SUPPORT_SPROC); } | '{' PARAM '=' kwd_call { SETYYERROR(pyyenv, NOT_SUPPORT_SPROC); } | kwd_grant { SETYYERROR(pyyenv, NOT_SUPPORT_DDL_DCL); } | kwd_revoke { SETYYERROR(pyyenv, NOT_SUPPORT_DDL_DCL); } ; %% static void unpack_col_name(char* schema_tab_column_name, column_name_t* ptr) { int len, i; char c; len = STRLEN(schema_tab_column_name); for(i=len; i; i--) { if( schema_tab_column_name[i-1] == '.' ) { schema_tab_column_name[i-1] = 0; break; } } ptr->column_name = ( schema_tab_column_name + i ); if( i ) ptr->schema_tab_name = schema_tab_column_name; else ptr->schema_tab_name = schema_tab_column_name + len; } static char* get_unpacked_attrname(yystmt_t* pstmt, char* name) { column_name_t attrname; unpack_col_name( name, &attrname ); return attrname.column_name; } #define FILTER_CHUNK_SIZE 16 static void* add_node(yystmt_t* pstmt, node_t* node) { int i; node_t* srchtree; if (!pstmt->node_buf) { pstmt->node_buf = (node_t*)MEM_ALLOC( sizeof(node_t)*FILTER_CHUNK_SIZE); if( ! pstmt->node_buf ) { pstmt->errcode = -1; return ERROR_PTR; } pstmt->srchtreesize = FILTER_CHUNK_SIZE; pstmt->srchtreenum = 0; } if( pstmt->srchtreenum == pstmt->srchtreesize ) { pstmt->node_buf = (node_t*)MEM_REALLOC( pstmt->node_buf, sizeof(node_t)*(pstmt->srchtreesize + FILTER_CHUNK_SIZE)); if( ! pstmt->node_buf ) { pstmt->errcode = -1; return ERROR_PTR; } pstmt->srchtreesize += FILTER_CHUNK_SIZE; } srchtree = pstmt->node_buf; srchtree[pstmt->srchtreenum] = *node; pstmt->srchtreenum ++; for(i=pstmt->srchtreenum;isrchtreesize;i++) { srchtree[i].left = EMPTY_PTR; srchtree[i].right= EMPTY_PTR; } return (void*)((uintptr_t)(pstmt->srchtreenum - 1)); } static void srchtree_reloc(node_t* buf, int num) /* The 'where' srchtree is build on a re-allocateable array with addnode(). The purpose * of using an array rather than a link list is to easy the job of freeing it. Thus, * the left and right pointer of a node point is an offset to the array address not * the virtual address of the subtree. However, an evaluate function would be easy to * work by using virtual address of subtree rather than an offset. Because, in the first * case, a recrusive evaluate function only need to pass virtual address of (sub)tree * without worry about the offset of subtree. The purpose of this function, srchtree_reloc(), * is to convert all subnodes' offset into virtual address. It will called only once * after the whole tree has been built. */ { int i; uintptr_t offset; node_t* ptr = buf; for(i=0; ptr && ileft == EMPTY_PTR ) ptr->left = 0; else { offset = (uintptr_t)(ptr->left); ptr->left = buf + offset; } if( ptr->right== EMPTY_PTR ) ptr->right= 0; else { offset = (uintptr_t)(ptr->right); ptr->right= buf+ offset; } } } static int add_attr(yystmt_t* pstmt, int idx, int wstat) { if( ! pstmt->pattr ) { pstmt->pattr = (yyattr_t*)MEM_ALLOC((en_body+1)*sizeof(yyattr_t)); if( ! pstmt->pattr ) { pstmt->errcode = -1; return -1; } MEM_SET(pstmt->pattr, 0, (en_body+1)*sizeof(yyattr_t)); } (pstmt->pattr)[0].stat = 1; (pstmt->pattr)[0].wstat = 1; (pstmt->pattr)[0].article = 0; (pstmt->pattr)[0].nntp_hand = 0; (pstmt->pattr)[idx].stat = 1; (pstmt->pattr)[idx].wstat |= wstat; return 0; } static void* add_all_attr(yystmt_t* pstmt) { int i; yycol_t col; for(i=en_article_num + 1; i < en_body + 1; i++) { col.iattr = i; col.table = 0; if( add_column(pstmt, &col) || add_attr (pstmt, i, 0) ) return ERROR_PTR; } return 0; } static const int news_attr[] = { en_subject, en_date, en_from, en_organization, en_msgid, en_body }; static void* add_news_attr(yystmt_t* pstmt) { int i, n; yycol_t col; n = sizeof(news_attr)/sizeof(news_attr[0]); for(i=0; ipcol ) { pstmt->pcol = (yycol_t*)MEM_ALLOC((MAX_COLUMN_NUMBER + 1)*sizeof(yycol_t)); if( ! pstmt->pcol ) { pstmt->errcode = -1; return ERROR_PTR; } MEM_SET( pstmt->pcol, 0, (MAX_COLUMN_NUMBER + 1)*sizeof(yycol_t)); } if( ! pstmt->ncol ) { pstmt->ncol = 1; pstmt->pcol->iattr = en_article_num; pstmt->pcol->table = 0; } if( pstmt->ncol > MAX_COLUMN_NUMBER + 1) { pstmt->errcode = TOO_MANY_COLUMNS; return ERROR_PTR; } pcol = pstmt->pcol + pstmt->ncol; pstmt->ncol++; *pcol = *column; return 0; } static void nnsql_yyerror(yyenv_t* pyyenv, char* msg) { yystmt_t* pstmt = pyyenv->pstmt; pstmt->errcode = PARSER_ERROR; pstmt->errpos = pyyenv->errpos; sprintf(pstmt->msgbuf, NNSQL_ERRHEAD "%s", msg); } static int table_check(yystmt_t* pstmt) { int i; char *table, *table1; table = pstmt->table; if( ! (table && *table) ) return 0; for(i=1;pstmt->pcol && incol;i++) { table1 = (pstmt->pcol)[i].table; if( table1 && *table1 && !STREQ( table, table1 ) ) return 0; } return 1; } static void* attr_name(yystmt_t* pstmt, char* name) { node_t node; column_name_t attrname; int attridx; void* offset; unpack_col_name( name, &attrname ); attridx = nnsql_getcolidxbyname( attrname.column_name ); if( attridx == -1 ) { pstmt->errcode = INVALID_COLUMN_NAME; return ERROR_PTR; } if( attridx == en_body ) { pstmt->errcode = UNSEARCHABLE_ATTR; return ERROR_PTR; } node.type = en_nt_attr; node.value.iattr = attridx; node.left = EMPTY_PTR; node.right= EMPTY_PTR; if( (offset = add_node(pstmt, &node)) == ERROR_PTR ) return ERROR_PTR; if( add_attr(pstmt, attridx, 1) ) return ERROR_PTR; return offset; } static int column_name(yystmt_t* pstmt, char* name) { column_name_t colname; int colidx; yycol_t col; unpack_col_name( name, &colname ); colidx = nnsql_getcolidxbyname( colname.column_name ); if( colidx == -1 ) { pstmt->errcode = INVALID_COLUMN_NAME; return -1; } col.iattr = colidx; col.table = colname.schema_tab_name; if( add_column(pstmt, &col) || add_attr(pstmt, colidx, 0) ) return -1; return 0; } static int add_ins_head( yystmt_t* pstmt, char* head, int idx) { if( !idx ) { MEM_FREE(pstmt->ins_heads); pstmt->ins_heads = (char**)MEM_ALLOC( FILTER_CHUNK_SIZE * sizeof(char*)); } else if( ! idx%FILTER_CHUNK_SIZE ) { pstmt->ins_heads = (char**)MEM_REALLOC( pstmt->ins_heads, (idx+FILTER_CHUNK_SIZE)*sizeof(char*)); } if( ! pstmt->ins_heads ) return -1; (pstmt->ins_heads)[idx] = head; return idx + 1; } static int add_ins_value( yystmt_t* pstmt, node_t node, int idx) { if( !idx ) { MEM_FREE(pstmt->ins_values); pstmt->ins_values = (node_t*)MEM_ALLOC( FILTER_CHUNK_SIZE * sizeof(node_t)); } else if( ! idx%FILTER_CHUNK_SIZE ) { pstmt->ins_values = (node_t*)MEM_REALLOC( pstmt->ins_values, (idx+FILTER_CHUNK_SIZE)*sizeof(node_t)); } if( ! pstmt->ins_values ) return -1; (pstmt->ins_values)[idx] = node; return idx + 1; } unixODBC-2.3.12/Drivers/nn/yystmt.c000066400000000000000000000403261446441710500167730ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include "driver.h" #if !defined(WINDOWS) && !defined(WIN32) && !defined(OS2) #include #endif static char sccsid[] = "@(#)NNSQL(NetNews SQL) v0.5, Copyright(c) 1995, 1996 by Ke Jin"; static int yyunbindpar(yystmt_t* yystmt, int ipar); void* nnsql_allocyystmt(void* hcndes) { yystmt_t* yystmt; yystmt = (yystmt_t*)MEM_ALLOC(sizeof(yystmt_t)); if( ! yystmt ) return 0; MEM_SET(yystmt, 0, sizeof(yystmt_t)); yystmt->hcndes = hcndes; return yystmt; } void nnsql_close_cursor(void* hstmt) { yystmt_t* yystmt = hstmt; yyattr_t* pattr; int i; if( !hstmt ) return; for(pattr = yystmt->pattr, i=0; pattr && i<=en_body; pattr++, i++) { pattr->stat = 0; /* not needed */ pattr->wstat= 0; nntp_closeheader(pattr->nntp_hand); pattr->nntp_hand = 0; } } void nnsql_dropyystmt(void* hstmt) { yystmt_t* yystmt = hstmt; int i; if(! hstmt ) return; /* allocated for any statement */ MEM_FREE( yystmt->texts_buf ); MEM_FREE( yystmt->sqlexpr ); /* allocated for SELECT statement */ MEM_FREE( yystmt->node_buf ); MEM_FREE( yystmt->pcol ); nnsql_close_cursor(hstmt); if( yystmt->pattr ) { MEM_FREE( (yystmt->pattr)[en_body].value.location ); MEM_FREE( yystmt->pattr ); } /* allocated for yybindpar(). i.e. nnsql_put{date, str, num}() */ for(i=1;;i++) { if( yyunbindpar(yystmt, i) ) break; } MEM_FREE( yystmt->ppar ); /* allocated for INSERT statement */ MEM_FREE( yystmt->ins_heads ); MEM_FREE( yystmt->ins_values); /* the statement object itself */ MEM_FREE( hstmt ); } static void nnsql_resetyystmt(void* hstmt) { yystmt_t* yystmt = hstmt; int i; if( ! hstmt ) return; yystmt->type = en_stmt_alloc; /* clear result from any statement */ MEM_FREE( yystmt->sqlexpr ); MEM_FREE( yystmt->texts_buf ); yystmt->sqlexpr = 0; yystmt->texts_buf = 0; yystmt->table = 0; yystmt->ncol = 0; yystmt->npar = 0; yystmt->count = 0; /* reset the search tree (but not free the buffer of it) */ yystmt->srchtree = 0; yystmt->srchtreenum = 0; /* clear fetched result */ nnsql_close_cursor(hstmt); /* clear result of bindpar() */ for(i=1; ;i++ ) { if( yyunbindpar(yystmt, i) ) break; } /* clear result of insert statement */ MEM_FREE( yystmt->ins_heads ); MEM_FREE( yystmt->ins_values ); yystmt->ins_heads = 0; yystmt->ins_values= 0; } static int yyfetch(void* hstmt, int wstat) { int i, j, nattr; yystmt_t* yystmt = hstmt; if( ! hstmt || ! yystmt->pattr ) return -1; for(i=en_article_num + 1, nattr=0; i<= en_body; i++) { yyattr_t* pattr; yyattr_t* tpattr; void* hrh = 0; pattr = yystmt->pattr + i; if(i == en_body ) { if( nattr ) break; i = en_lines; /* use lines to retrive article number */ pattr = yystmt->pattr; nattr --; } if( pattr->stat && pattr->wstat == wstat ) { char* header; long data; int r; nattr++; if( ! (header = nnsql_getcolnamebyidx(i)) ) return -1; if( !wstat && !hrh ) { for(j = 0, tpattr = yystmt->pattr; j < en_body; j++) { tpattr++; if( tpattr->wstat ) { hrh = tpattr->nntp_hand; break; } } if( !hrh && yystmt->pattr->wstat ) hrh = yystmt->pattr->nntp_hand; } if( ! pattr->nntp_hand ) { nnsql_getrange(yystmt, &(yystmt->artnum_min), &(yystmt->artnum_max)); pattr->nntp_hand = nntp_openheader( yystmt->hcndes, header, &(yystmt->artnum_min), &(yystmt->artnum_max) ); if( ! pattr->nntp_hand ) return -1; } if( yystmt->artnum_max ) r = nntp_fetchheader( pattr->nntp_hand, &((yystmt->pattr->value).number), &data, hrh ); else r = 100; if( !r && !i ) { data = (yystmt->pattr->value).number; if(data > yystmt->artnum_max) r = 100; } switch(r) { case 100: (yystmt->pattr->value).number = 0; case -1: nntp_closeheader(pattr->nntp_hand); pattr->nntp_hand = 0; return r; case 0: break; default: abort(); break; } switch(i) { case en_lines: if( nattr ) (pattr->value).number = (long)(data); else return 0; break; case en_date: nnsql_nndatestr2date((char*)data, &((pattr->value).date) ); break; default: (pattr->value).location = (char*)(data); break; } } } return 0; } #include int nnsql_fetch(void* hstmt) { int r, i; yystmt_t* pstmt = hstmt; yyattr_t* pattr = pstmt->pattr + en_body; for(;;) { switch( pstmt->type ) { case en_stmt_fetch_count: pstmt->type = en_stmt_alloc; return 100; case en_stmt_select: break; default: return -1; } r = yyfetch(hstmt, 1); switch(r) { case 100: for(i=1; incol; i++) { if( (pstmt->pcol + i)->iattr == en_sql_count ) { pstmt->type = en_stmt_fetch_count; return 0; } } pstmt->type = en_stmt_alloc; return 100; case -1: pstmt->type = en_stmt_alloc; return -1; case 0: r = nnsql_srchtree_evl(hstmt); switch(r) { case -1: pstmt->type = en_stmt_alloc; return r; case 1: pstmt->count++; if( pstmt->ncol == 2 && (pstmt->pcol + 1)->iattr == en_sql_count ) continue; if( (r = yyfetch(hstmt, 0)) == -1 ) { pstmt->type = en_stmt_alloc; return -1; } if( pattr->stat ) /* pattr has already init to point * to the en_body attr */ { MEM_FREE( (pattr->value).location ); (pattr->value).location = nntp_body( pstmt->hcndes, (pstmt->pattr->value).number, 0); } return 0; case 0: continue; default: abort(); break; } break; default: abort(); break; } break; } abort(); return -1; } int nnsql_opentable(void* hstmt, char* table) { yystmt_t* yystmt = hstmt; if(! hstmt ) return -1; if( !table ) table = yystmt->table; return nntp_group( yystmt->hcndes, table ); } int nnsql_yyunbindpar(void* yystmt, int ipar) { return yyunbindpar(yystmt, ipar); } static int yyunbindpar(yystmt_t* yystmt, int ipar) { int i; yypar_t* par; if( yystmt || ipar <= 0 || ipar > MAX_PARAM_NUMBER || yystmt->ppar ) return -1; par = yystmt->ppar + ipar - 1; switch( par->type ) { case -1: case en_nt_num: case en_nt_null: break; case en_nt_qstr: MEM_FREE( par->value.location ); break; default: abort(); break; } yystmt->ppar->type = -1; return 0; } static int yybindpar(yystmt_t* yystmt, int ipar, long data, int type) { int i; ipar --; if( ! yystmt->ppar ) { yystmt->ppar = (yypar_t*)MEM_ALLOC( sizeof(yypar_t)*MAX_PARAM_NUMBER); if( ! yystmt->ppar ) { yystmt->errcode = -1; return -1; } for(i=0; ippar)[i].type = -1; /* unbind */ } yyunbindpar( yystmt, ipar + 1); (yystmt->ppar)[ipar].type = type; switch(type) { case en_nt_null: return 0; case en_nt_qstr: (yystmt->ppar)[ipar].value.location = (char*)data; break; case en_nt_num: (yystmt->ppar)[ipar].value.number = (long)data; break; case en_nt_date: (yystmt->ppar)[ipar].value.date = *((date_t*)data); break; default: abort(); break; } return 0; } int nnsql_putnull(void* hstmt, int ipar ) { return yybindpar((yystmt_t*)hstmt, ipar, 0, en_nt_null); } int nnsql_putstr(void* hstmt, int ipar, char* str) { return yybindpar((yystmt_t*)hstmt, ipar, (long)str, en_nt_qstr); } int nnsql_putnum(void* hstmt, int ipar, long num) { return yybindpar((yystmt_t*)hstmt, ipar, num, en_nt_num); } int nnsql_putdate(void* hstmt, int ipar, date_t* date) { return yybindpar((yystmt_t*)hstmt, ipar, (long)(date), en_nt_date); } int nnsql_max_param() { return MAX_PARAM_NUMBER; } int nnsql_max_column() { return MAX_COLUMN_NUMBER; } static int access_mode_chk( yystmt_t* pstmt ) { int mode; pstmt->errcode = 0; mode = nntp_getaccmode(pstmt->hcndes); switch( pstmt->type ) { case en_stmt_insert: if( mode < ACCESS_MODE_INSERT ) pstmt->errcode = NO_INSERT_PRIVILEGE; break; case en_stmt_srch_delete: if( nnsql_strlike( pstmt->table, "%.test", 0, 0) ) { if( mode < ACCESS_MODE_DELETE_TEST ) pstmt->errcode = NO_DELETE_PRIVILEGE; } else { if( mode < ACCESS_MODE_DELETE_ANY ) pstmt->errcode = NO_DELETE_ANY_PRIVILEGE; } if( nnsql_opentable(pstmt, 0) ) return -1; break; case en_stmt_select: if( nnsql_opentable(pstmt, 0) ) return -1; return 0; default: pstmt->errcode = -1; break; } if( ! pstmt->errcode && ! nntp_postok( pstmt->hcndes ) ) pstmt->errcode = NO_POST_PRIVILEGE; if( pstmt->errcode ) { nnsql_resetyystmt(pstmt); return -1; } return 0; } int nnsql_prepare(void* hstmt, char* expr, int len) { yyenv_t yyenv; yystmt_t* pstmt = hstmt; int r; if( ! hstmt || ! expr || len < 0 ) return -1; nnsql_resetyystmt(hstmt); pstmt->errcode = -1; pstmt->sqlexpr = MEM_ALLOC(len + 1); if( ! pstmt->sqlexpr ) return -1; pstmt->texts_buf = MEM_ALLOC( len + 1 ); if( ! pstmt->texts_buf ) { MEM_FREE( pstmt->sqlexpr ); pstmt->sqlexpr = 0; return -1; } STRNCPY(pstmt->sqlexpr, expr, len); (pstmt->sqlexpr)[len] = 0; nnsql_yyinit(&yyenv, pstmt); if( nnsql_yyparse(&yyenv) || access_mode_chk( pstmt ) ) { nnsql_resetyystmt(pstmt); return -1; } return 0; } int nnsql_column_descid(void* hstmt, int icol) { if( icol < 0 || icol > MAX_COLUMN_NUMBER ) return -1; return (((yystmt_t*)hstmt)->pcol)[icol].iattr; } static int do_insert(void* hstmt) { yystmt_t* pstmt = hstmt; char *body, *head, *value; node_t* node; int i, attridx; yypar_t* par; int subj_set = 0, from_set = 0; pstmt->count = 0; if( nntp_start_post( pstmt->hcndes) || nntp_send_head( pstmt->hcndes, "X-Newsreader", "NetNews SQL Agent v0.5") || nntp_send_head( pstmt->hcndes, "Newsgroups", pstmt->table ) ) return -1; for(i=0; ;i++) { head = (pstmt->ins_heads)[i]; if( ! head ) break; if( ! *head ) continue; attridx = nnsql_getcolidxbyname( head ); switch( attridx ) { case en_article_num: case en_x_newsreader: case en_newsgroups: case en_xref: case en_host: case en_date: case en_path: case en_lines: case en_msgid: /* better to let srv set id */ continue; case en_subject: subj_set = 1; break; case en_from: from_set = 1; break; case -1: /* an extended header */ break; default: /* any normal header */ head = nnsql_getcolnamebyidx(attridx); /* use stand representation */ break; } node = pstmt->ins_values + i; switch(node->type) { case en_nt_qstr: value = node->value.qstr; break; case en_nt_null: continue; case en_nt_param: par = pstmt->ppar + (node->value).ipar - 1; if(par->type != en_nt_qstr ) continue; value = (par->value).location; break; default: continue; } if( attridx == en_body ) { body = value; continue; } nntp_send_head(pstmt->hcndes, head, value); } if( !subj_set ) nntp_send_head(pstmt->hcndes, "Subject", "(none)"); if( !from_set ) nntp_send_head(pstmt->hcndes, "From", "(none)"); if( nntp_end_head (pstmt->hcndes) || nntp_send_body(pstmt->hcndes, body) || nntp_end_post (pstmt->hcndes) ) return -1; pstmt->count = 1; return 0; } int do_srch_delete(void* hstmt) { int r, i, rcnt; yystmt_t* pstmt = hstmt; yyattr_t* pattr = pstmt->pattr; pstmt->count = 0; for(;;) { r = yyfetch(hstmt, 1); switch(r) { case 100: pstmt->type = en_stmt_alloc; return 0; case -1: pstmt->type = en_stmt_alloc; return -1; case 0: r = nnsql_srchtree_evl(hstmt); switch(r) { case -1: pstmt->type = en_stmt_alloc; return -1; case 1: for(rcnt=0; r && rcnt<6; rcnt++) /* retry 6 times */ { if(rcnt && pstmt->count ) sleep(1 + rcnt); /* give server time to * finish previous DELETE */ r = nntp_cancel( pstmt->hcndes, pstmt->table, pattr[en_sender].value.location, pattr[en_from].value.location, pattr[en_msgid].value.location); } if( r ) return -1; pstmt->count++; continue; case 0: continue; default: abort(); break; } break; default: abort(); break; } break; } abort(); return -1; } int nnsql_execute(void* hstmt) { yystmt_t* pstmt = hstmt; yypar_t* par; int i; par = pstmt->ppar; if( !par && pstmt->npar ) return 99; for(i=0;inpar;i++) { par = pstmt->ppar + i; if(par->type == -1) return 99; } switch(pstmt->type) { case en_stmt_insert: return do_insert(hstmt); case en_stmt_srch_delete: case en_stmt_select: if( nnsql_srchtree_tchk(hstmt) || nnsql_opentable(hstmt, 0) ) break; if( pstmt->type == en_stmt_srch_delete ) return do_srch_delete(hstmt); return 0; default: break; } return -1; } int nnsql_isnullablecol( void* hstmt, int icol ) { switch( (((yystmt_t*)hstmt)->pcol + icol)->iattr ) { case en_subject: case en_from: case en_body: return 0; default: break; } return 1; } int nnsql_isnumcol(void* hstmt, int icol ) { switch( (((yystmt_t*)hstmt)->pcol + icol)->iattr ) { case en_lines: case en_article_num: case en_sql_count: case en_sql_num: return 1; default: break; } return 0; } int nnsql_isdatecol(void* hstmt, int icol) { switch( (((yystmt_t*)hstmt)->pcol + icol)->iattr ) { case en_date: case en_sql_date: return 1; default: break; } return 0; } long nnsql_getnum(void* hstmt, int icol ) { yystmt_t* pstmt = hstmt; yycol_t* pcol; pcol = ((yystmt_t*)hstmt)->pcol + icol; switch( pcol->iattr ) { case en_lines: case en_article_num: return ((pstmt->pattr + pcol->iattr)->value).number; case en_sql_num: return (pcol->value).num; case en_sql_count: return (pstmt->count); default: break; } return 0; } int nnsql_isstrcol(void* hstmt, int icol ) { return ! nnsql_isnumcol(hstmt, icol) && ! nnsql_isdatecol(hstmt, icol); } char* nnsql_getstr(void* hstmt, int icol ) { yystmt_t* pstmt = hstmt; yycol_t* pcol; pcol = ((yystmt_t*)hstmt)->pcol + icol; switch( pcol->iattr ) { case en_lines: case en_article_num: case en_sql_count: case en_sql_num: return 0; case en_sql_qstr: return (pcol->value).qstr; default: break; } return ((pstmt->pattr + pcol->iattr)->value).location; } date_t* nnsql_getdate(void* hstmt, int icol ) { yystmt_t* pstmt = hstmt; yycol_t* pcol; pcol = ((yystmt_t*)hstmt)->pcol + icol; switch( pcol->iattr ) { case en_date: return &(((pstmt->pattr + pcol->iattr)->value).date); case en_sql_date: return &((pcol->value).date); default: break; } return 0; } int nnsql_iscountcol(void* hstmt, int icol ) { return ( (((yystmt_t*)hstmt)->pcol + icol)->iattr == en_sql_count ); } int nnsql_isnullcol(void* hstmt, int icol ) { yystmt_t* pstmt = hstmt; yycol_t* pcol; long artnum; date_t* date; artnum = (pstmt->pattr->value).number; pcol = ((yystmt_t*)hstmt)->pcol + icol; switch( pcol->iattr ) { case en_sql_count: return !!artnum; case en_sql_num: case en_sql_qstr: case en_sql_date: case en_lines: case en_article_num: return !artnum; case en_date: date = nnsql_getdate(hstmt, icol); return !artnum || !date || !date->day; default: break; } return !artnum || !nnsql_getstr(hstmt, icol); } int nnsql_getcolnum(void* hstmt) { return ((yystmt_t*)hstmt)->ncol; } int nnsql_getparnum(void* hstmt) { return ((yystmt_t*)hstmt)->npar; } int nnsql_getrowcount(void* hstmt) { return ((yystmt_t*)hstmt)->count; } unixODBC-2.3.12/Drivers/nn/yystmt.h000066400000000000000000000066441446441710500170050ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #ifndef _YYSTMT_H # define _YYSTMT_H # define MAX_COLUMN_NUMBER 32 # define MAX_PARAM_NUMBER 32 # include # include # include typedef enum { en_nt_cmpop, /* en_cmpop_eq, */ en_nt_logop, /* kwd_and, kwd_or, kwd_not */ en_nt_attr, en_nt_qstr, en_nt_num, en_nt_date, en_nt_param, en_nt_null, en_nt_like, en_nt_between, en_nt_in, en_nt_caselike, en_nt_isnull } node_type; typedef struct tnode { int type; /* compare operator, * logical operator, * column value, * literal value, * dummy parameter */ union { int cmpop; /* en_cmpop_eq, en_cmpop_ne, ... */ int logop; /* kwd_or, kwd_and, kwd_not */ int iattr; /* attribute index */ int ipar; /* parameter idx */ char* qstr; long num; date_t date; char esc; /* escape for like pattern match */ } value; struct tnode* left; struct tnode* right; } node_t; typedef struct { int iattr; char* table; /* table name from yyparse */ union { long num; char* qstr; date_t date; } value; } yycol_t; typedef struct { int stat; /* 0 don't needed(either by select list or by where tree) 1 needed */ int wstat; /* 0 if don't need by where tree, 1 if need */ int article;/* article number */ union { char* location; long number; date_t date; } value; void* nntp_hand; /* create with nntp_openheader() * freed with nntp_closeheader() * fetch with nntp_fetchheader() */ } yyattr_t; typedef struct { int type; /* can only be en_nt_qstr, en_nt_num and en_nt_null */ union { char* location; long number; date_t date; } value; } yypar_t; enum { en_stmt_alloc = 0, /* only in allocated stat */ en_stmt_select, en_stmt_insert, en_stmt_srch_delete, en_stmt_fetch_count = 100 }; typedef struct { void* hcndes; /* nntp cndes */ int type; int errcode; int errpos; yycol_t* pcol; /* column descriptor */ yyattr_t* pattr; /* fetched required column */ yypar_t* ppar; /* user parameter area */ char* table; /* table name from yyparse */ int ncol; int npar; int count; /* num. of record has been fetched. */ char* sqlexpr; /* point to sqlexpr in hstmt_t */ char* texts_buf; char msgbuf[64]; /* buf to hold message string passed to * nnsql_yyerror() */ /* search tree */ node_t* srchtree; /* root of search tree */ node_t* node_buf; /* address of array */ int srchtreesize; /* search tree array size */ int srchtreenum; /* number of nodes in tree */ /* insert headers and values */ char** ins_heads; node_t* ins_values; /* article-num range */ long artnum_min; long artnum_max; } yystmt_t; void nnsql_getrange(void* hstmt, long* pmin, long* pmax); int nnsql_strlike(char* str, char* pattern, char esc, int flag); int nnsql_srchtree_evl(void* hstmt); int nnsql_srchtree_tchk(void* hstmt); #endif unixODBC-2.3.12/Drivers/nn/yytchk.c000066400000000000000000000071771446441710500167440ustar00rootroot00000000000000/** Copyright (C) 1995, 1996 by Ke Jin Enhanced for unixODBC (1999) by Peter Harvey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. **/ #include #include #include #include #include #include #include static int getleaftype(yystmt_t* yystmt, node_t* nd) { yypar_t* par; yyattr_t* attr; switch( nd->type ) { case en_nt_attr: attr = yystmt->pattr + (nd->value).iattr; switch((nd->value).iattr) { case en_lines: case en_article_num: case en_sql_num: case en_sql_count: return en_nt_num; case en_date: case en_sql_date: return en_nt_date; default: break; } return en_nt_qstr; case en_nt_param: par = yystmt->ppar + (nd->value).ipar - 1; switch(par->type) { case en_nt_null: case en_nt_num: case en_nt_qstr: case en_nt_date: break; default: return -1; } return par->type; case en_nt_num: case en_nt_qstr: case en_nt_date: case en_nt_null: return nd->type; default: return -1; } } static int cmp_tchk(yystmt_t* yystmt, node_t* a, node_t* b) { int ta, tb; ta = getleaftype( yystmt, a ); tb = getleaftype( yystmt, b ); if( ta == -1 || tb == -1 ) return -1; if( ta == en_nt_date && tb == en_nt_qstr ) return 0; if( ta != tb && ta != en_nt_null && tb != en_nt_null ) return -1; return 0; } static int evl_like_tchk(yystmt_t* yystmt, node_t* a, node_t* b) { int ta, tb; ta = getleaftype(yystmt, a); tb = getleaftype(yystmt, b); if( tb == en_nt_null || tb == en_nt_null ) return 0; if( ta != en_nt_qstr || tb != en_nt_qstr ) return -1; return 0; } static int srchtree_tchk(yystmt_t* yystmt, node_t* node) /* return -1: err or syserr, 0: ok */ { int r, s, flag = 0; node_t* ptr; if( ! node ) return 0; switch( node->type ) { case en_nt_cmpop: return cmp_tchk(yystmt, node->left, node->right); case en_nt_logop: switch( (node->value).logop ) { case en_logop_not: return srchtree_tchk(yystmt, node->right); case en_logop_and: case en_logop_or: r = srchtree_tchk(yystmt, node->left); s = srchtree_tchk(yystmt, node->right); if( r == -1 || s == -1 ) return -1; return 0; default: abort(); break; /* just for turn off the warning */ } break; /* just for turn off the warning */ case en_nt_isnull: return 0; case en_nt_between: r = cmp_tchk(yystmt, node->left, node->right->left); s = cmp_tchk(yystmt, node->left, node->right->right); if( r == -1 || s == -1 ) return -1; return 0; case en_nt_in: for(ptr=node->right; ptr; ptr=ptr->right) { r = cmp_tchk(yystmt, node->left, ptr); if( r == -1 ) return -1; } return 0; case en_nt_caselike: case en_nt_like: return evl_like_tchk( yystmt, node->left, node->right); default: abort(); break; /* turn off the warning */ } return -1; /* just for turn off the warning */ } int nnsql_srchtree_tchk(void* hstmt) { yystmt_t* yystmt = hstmt; int r; r = srchtree_tchk(yystmt, yystmt->srchtree); if( r ) yystmt->errcode = TYPE_VIOLATION; return r; } unixODBC-2.3.12/Drivers/template/000077500000000000000000000000001446441710500164515ustar00rootroot00000000000000unixODBC-2.3.12/Drivers/template/Makefile.am000066400000000000000000000037311446441710500205110ustar00rootroot00000000000000lib_LTLIBRARIES = libtemplate.la AM_CPPFLAGS = -I@top_srcdir@/include -I. $(LTDLINCL) libtemplate_la_LDFLAGS = -no-undefined -version-info 1:0:0 EXTRA_DIST = \ driver.h \ prototypes.h \ driverextras.h libtemplate_la_LIBADD = \ ../../lst/liblstlc.la \ ../../log/libloglc.la \ ../../ini/libinilc.la \ ../../odbcinst/libodbcinstlc.la \ $(LIBLTDL) libtemplate_la_SOURCES = \ SQLAllocConnect.c \ SQLAllocEnv.c \ SQLAllocHandle.c \ SQLAllocStmt.c \ SQLBindCol.c \ SQLBindParameter.c \ SQLBrowseConnect.c \ SQLBulkOperations.c \ SQLCancel.c \ SQLCloseCursor.c \ SQLColAttribute.c \ SQLColAttributes.c \ SQLColumnPrivileges.c \ SQLColumns.c \ SQLConnect.c \ SQLCopyDesc.c \ SQLDescribeCol.c \ SQLDescribeParam.c \ SQLDisconnect.c \ SQLDriverConnect.c \ SQLEndTran.c \ SQLError.c \ SQLExecDirect.c \ SQLExecute.c \ SQLExtendedFetch.c \ SQLFetch.c \ SQLFetchScroll.c \ SQLForeignKeys.c \ SQLFreeConnect.c \ SQLFreeEnv.c \ SQLFreeHandle.c \ SQLFreeStmt.c \ SQLGetConnectAttr.c \ SQLGetConnectOption.c \ SQLGetCursorName.c \ SQLGetData.c \ SQLGetDescField.c \ SQLGetDescRec.c \ SQLGetDiagField.c \ SQLGetDiagRec.c \ SQLGetEnvAttr.c \ SQLGetInfo.c \ SQLGetStmtAttr.c \ SQLGetStmtOption.c \ SQLGetTypeInfo.c \ SQLMoreResults.c \ SQLNativeSql.c \ SQLNumParams.c \ SQLNumResultCols.c \ SQLParamData.c \ SQLParamOptions.c \ SQLPrepare.c \ SQLPrimaryKeys.c \ SQLProcedureColumns.c \ SQLProcedures.c \ SQLPutData.c \ SQLRowCount.c \ SQLSetConnectOption.c \ SQLSetCursorName.c \ SQLSetDescField.c \ SQLSetDescRec.c \ SQLSetEnvAttr.c \ SQLSetParam.c \ SQLSetPos.c \ SQLSetScrollOptions.c \ SQLSetStmtAttr.c \ SQLSetStmtOption.c \ SQLSpecialColumns.c \ SQLStatistics.c \ SQLTablePrivileges.c \ SQLTables.c \ SQLTransact.c \ _FreeDbc.c \ _FreeStmt.c \ _FreeDbcList.c \ _FreeStmtList.c \ _FreeResults.c \ _GetData.c \ _NativeToSQLColumnHeader.c \ _NativeToSQLType.c \ _NativeTypeDesc.c \ _NativeTypeLength.c \ _NativeTypePrecision.c unixODBC-2.3.12/Drivers/template/README000066400000000000000000000025651446441710500173410ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * * * * Peter Harvey 21.FEB.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | Driver Template | +-------------------------------------------------------------+ Use this template as a starting point when creating a new driver. You can also reference existing unixODBC drivers. This template provides the infrastructure for a 3.51 compliant ODBC driver. A driver created from this template, and in the unixODBC framework should be easy to port to other platforms. In fact, the Drivers are the only component which one may want to ensure portability ... the remaining components (including the DriverManager) strive for interoperability but not portability. +-------------------------------------------------------------+ | Please visit; | | www.genix.net/unixODBC | +-------------------------------------------------------------+ unixODBC-2.3.12/Drivers/template/SQLAllocConnect.c000066400000000000000000000056621446441710500215520ustar00rootroot00000000000000/********************************************************************** * SQLAllocConnect * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN _AllocConnect( SQLHENV hDrvEnv, SQLHDBC *phDrvDbc ) { HDRVENV hEnv = (HDRVENV)hDrvEnv; HDRVDBC *phDbc = (HDRVDBC*)phDrvDbc; /************************ * SANITY CHECKS ************************/ if( SQL_NULL_HENV == hEnv ) return SQL_INVALID_HANDLE; sprintf((char*) hEnv->szSqlMsg, "hEnv = $%08lX phDbc = $%08lX", (long)hEnv, (long)phDbc ); logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hEnv->szSqlMsg ); if( SQL_NULL_HDBC == phDbc ) { logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR *phDbc is NULL" ); return SQL_ERROR; } /************************ * OK LETS DO IT ************************/ /* allocate database access structure */ *phDbc = (HDRVDBC)malloc( sizeof(DRVDBC) ); if( SQL_NULL_HDBC == *phDbc ) { *phDbc = SQL_NULL_HDBC; logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR malloc error" ); return SQL_ERROR; } /* initialize structure */ memset( *phDbc, 0, sizeof(DRVDBC) ); (*phDbc)->bConnected = 0; (*phDbc)->hDbcExtras = NULL; (*phDbc)->hFirstStmt = NULL; (*phDbc)->hLastStmt = NULL; (*phDbc)->pNext = NULL; (*phDbc)->pPrev = NULL; (*phDbc)->hEnv = (SQLPOINTER)hEnv; /* start logging */ if ( !logOpen( &(*phDbc)->hLog, "[template]", NULL, 50 ) ) (*phDbc)->hLog = NULL; logOn( (*phDbc)->hLog, 1 ); /* ADD TO END OF LIST */ if ( hEnv->hFirstDbc == NULL ) { /* 1st is null so the list is empty right now */ hEnv->hFirstDbc = (*phDbc); hEnv->hLastDbc = (*phDbc); } else { /* at least one node in list */ hEnv->hLastDbc->pNext = (SQLPOINTER)(*phDbc); (*phDbc)->pPrev = (SQLPOINTER)hEnv->hLastDbc; hEnv->hLastDbc = (*phDbc); } /********************************************************/ /* ALLOCATE AND INIT EXTRAS HERE */ (*phDbc)->hDbcExtras = (HDBCEXTRAS)malloc( sizeof(DBCEXTRAS) ); memset( (*phDbc)->hDbcExtras, 0, sizeof(DBCEXTRAS) ); /********************************************************/ logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } SQLRETURN SQLAllocConnect( SQLHENV hDrvEnv, SQLHDBC *phDrvDbc ) { return _AllocConnect( hDrvEnv, phDrvDbc ); } unixODBC-2.3.12/Drivers/template/SQLAllocEnv.c000066400000000000000000000030351446441710500207010ustar00rootroot00000000000000/********************************************************************** * SQLAllocEnv * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN _AllocEnv( SQLHENV *phDrvEnv ) { HDRVENV *phEnv = (HDRVENV*)phDrvEnv; /* SANITY CHECKS */ if( NULL == phEnv ) return SQL_INVALID_HANDLE; /* OK */ /* allocate environment */ *phEnv = malloc( sizeof(DRVENV) ); if( SQL_NULL_HENV == *phEnv ) { *phEnv = SQL_NULL_HENV; return SQL_ERROR; } /* initialise environment */ memset( *phEnv, 0, sizeof(DRVENV) ); (*phEnv)->hFirstDbc = NULL; (*phEnv)->hLastDbc = NULL; (*phEnv)->hLog = NULL; /* start logging */ if ( !logOpen( &(*phEnv)->hLog, "[template]", NULL, 50 ) ) (*phEnv)->hLog = NULL; logOn( (*phEnv)->hLog, 1 ); /* ALLOCATE AND INIT DRIVER SPECIFIC STORAGE */ (*phEnv)->hEnvExtras = malloc(sizeof(ENVEXTRAS)); (*phEnv)->hEnvExtras->nDummy = -1; logPushMsg( (*phEnv)->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } SQLRETURN SQLAllocEnv( SQLHENV *phDrvEnv ) { return _AllocEnv( phDrvEnv ); } unixODBC-2.3.12/Drivers/template/SQLAllocHandle.c000066400000000000000000000020441446441710500213430ustar00rootroot00000000000000/********************************************************************** * SQLAllocHandle * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLAllocHandle( SQLSMALLINT nHandleType, SQLHANDLE nInputHandle, SQLHANDLE *pnOutputHandle ) { switch ( nHandleType ) { case SQL_HANDLE_ENV: return _AllocEnv( (SQLHENV *)pnOutputHandle ); case SQL_HANDLE_DBC: return _AllocConnect( (SQLHENV)nInputHandle, (SQLHDBC *)pnOutputHandle ); case SQL_HANDLE_STMT: return _AllocStmt( (SQLHDBC)nInputHandle, (SQLHSTMT *)pnOutputHandle ); case SQL_HANDLE_DESC: break; default: return SQL_ERROR; break; } return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLAllocStmt.c000066400000000000000000000067521446441710500211110ustar00rootroot00000000000000/********************************************************************** * SQLAllocStmt (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN _AllocStmt( SQLHDBC hDrvDbc, SQLHSTMT *phDrvStmt ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; HDRVSTMT *phStmt = (HDRVSTMT*)phDrvStmt; /* SANITY CHECKS */ if( hDbc == SQL_NULL_HDBC ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_INVALID_HANDLE" ); return SQL_INVALID_HANDLE; } sprintf((char*) hDbc->szSqlMsg, "hDbc = $%08lX", (long)hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hDbc->szSqlMsg ); if( NULL == phStmt ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR phStmt=NULL" ); return SQL_ERROR; } /* OK */ /* allocate memory */ *phStmt = malloc( sizeof(DRVSTMT) ); if( SQL_NULL_HSTMT == *phStmt ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR memory allocation failure" ); return SQL_ERROR; } /* initialize memory */ sprintf((char*) hDbc->szSqlMsg, "*phstmt = $%08lX", (long)*phStmt ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hDbc->szSqlMsg ); memset( *phStmt, 0, sizeof(DRVSTMT) ); /* SAFETY */ (*phStmt)->hDbc = (SQLPOINTER)hDbc; (*phStmt)->hLog = NULL; (*phStmt)->hStmtExtras = NULL; (*phStmt)->pNext = NULL; (*phStmt)->pPrev = NULL; (*phStmt)->pszQuery = NULL; sprintf((char*)(*phStmt)->szCursorName, "CUR_%08lX", *phStmt ); /* ADD TO DBCs STATEMENT LIST */ /* start logging */ if ( logOpen( &(*phStmt)->hLog, "[template]", NULL, 50 ) ) { logOn( (*phStmt)->hLog, 1 ); logPushMsg( (*phStmt)->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "Statement logging allocated ok" ); } else (*phStmt)->hLog = NULL; /* ADD TO END OF LIST */ if ( hDbc->hFirstStmt == NULL ) { /* 1st is null so the list is empty right now */ hDbc->hFirstStmt = (*phStmt); hDbc->hLastStmt = (*phStmt); } else { /* at least one node in list */ hDbc->hLastStmt->pNext = (SQLPOINTER)(*phStmt); (*phStmt)->pPrev = (SQLPOINTER)hDbc->hLastStmt; hDbc->hLastStmt = (*phStmt); } /****************************************************************************/ /* ALLOCATE AND INIT DRIVER EXTRAS HERE */ (*phStmt)->hStmtExtras = malloc(sizeof(STMTEXTRAS)); memset( (*phStmt)->hStmtExtras, 0, sizeof(STMTEXTRAS) ); /* SAFETY */ (*phStmt)->hStmtExtras->aResults = NULL; (*phStmt)->hStmtExtras->nCols = 0; (*phStmt)->hStmtExtras->nRow = 0; (*phStmt)->hStmtExtras->nRows = 0; /****************************************************************************/ logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } SQLRETURN SQLAllocStmt( SQLHDBC hDrvDbc, SQLHSTMT *phDrvStmt ) { return _AllocStmt( hDrvDbc, phDrvStmt ); } unixODBC-2.3.12/Drivers/template/SQLBindCol.c000066400000000000000000000043751446441710500205200ustar00rootroot00000000000000/********************************************************************** * SQLBindCol * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLBindCol( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLSMALLINT nTargetType, SQLPOINTER pTargetValue, SQLLEN nTargetValueMax, SQLLEN *pnLengthOrIndicator ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; COLUMNHDR *pColumnHeader; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt=$%08lX nCol=%5d", (long) hStmt, nCol ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO,(char*) hStmt->szSqlMsg ); if ( hStmt->hStmtExtras->nRows == 0 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No result set." ); return SQL_ERROR; } if ( nCol < 1 || nCol > hStmt->hStmtExtras->nCols ) { sprintf((char*) hStmt->szSqlMsg, "SQL_ERROR Column %d is out of range. Range is 1 - %d", nCol, hStmt->hStmtExtras->nCols ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); return SQL_ERROR; } if ( pTargetValue == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Invalid data pointer" ); return SQL_ERROR; } if ( pnLengthOrIndicator != NULL ) *pnLengthOrIndicator = 0; /* SET DEFAULTS */ /* store app col pointer */ pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nCol]; pColumnHeader->nTargetType = nTargetType; pColumnHeader->nTargetValueMax = nTargetValueMax; pColumnHeader->pnLengthOrIndicator = pnLengthOrIndicator; pColumnHeader->pTargetValue = pTargetValue; logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLBindParameter.c000066400000000000000000000034521446441710500217160ustar00rootroot00000000000000/********************************************************************** * SQLBindParameter * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLBindParameter( SQLHSTMT hDrvStmt, SQLUSMALLINT nParameterNumber, SQLSMALLINT nIOType, SQLSMALLINT nBufferType, SQLSMALLINT nParamType, SQLULEN nParamLength, SQLSMALLINT nScale, SQLPOINTER pData, SQLLEN nBufferLength, SQLLEN *pnLengthOrIndicator ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt=$%08lX nParameterNumber=%d nIOType=%d nBufferType=%d nParamType=%d nParamLength=%ld nScale=%d pData=$%08lX nBufferLength=%ld *pnLengthOrIndicator=$%08lX",(long) hStmt,nParameterNumber,nIOType,nBufferType,nParamType,(long) nParamLength,nScale,(long) pData,(long) nBufferLength, *pnLengthOrIndicator ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not currently supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLBrowseConnect.c000066400000000000000000000025501446441710500217520ustar00rootroot00000000000000/********************************************************************** * SQLBrowseConnect * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLBrowseConnect( SQLHDBC hDrvDbc, SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; if ( hDbc == NULL ) return SQL_INVALID_HANDLE; sprintf((char*) hDbc->szSqlMsg, "hDbc = $%08lX", (long)hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hDbc->szSqlMsg ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not currently supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLBulkOperations.c000066400000000000000000000032111446441710500221330ustar00rootroot00000000000000/********************************************************************** * SQLBulkOperations * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLBulkOperations( SQLHSTMT hDrvStmt, SQLSMALLINT nOperation ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /* OK */ switch ( nOperation ) { case SQL_ADD: break; case SQL_UPDATE_BY_BOOKMARK: break; case SQL_DELETE_BY_BOOKMARK: break; case SQL_FETCH_BY_BOOKMARK: break; default: sprintf((char*) hStmt->szSqlMsg, "SQL_ERROR Unknown nOperation=%d", nOperation ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); return SQL_ERROR; } /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not currently supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLCancel.c000066400000000000000000000022111446441710500203560ustar00rootroot00000000000000/********************************************************************** * SQLCancel * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLCancel( SQLHSTMT hDrvStmt ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLCloseCursor.c000066400000000000000000000022171446441710500214420ustar00rootroot00000000000000/********************************************************************** * SQLCloseCursor * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLCloseCursor( SQLHSTMT hDrvStmt ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLColAttribute.c000066400000000000000000000127421446441710500216040ustar00rootroot00000000000000/********************************************************************** * SQLColAttribute * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLColAttribute( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLUSMALLINT nFieldIdentifier, SQLPOINTER pszValue, SQLSMALLINT nValueLengthMax, SQLSMALLINT *pnValueLength, SQLLEN *pnValue ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; COLUMNHDR *pColumnHeader; int nValue = 0; /* SANITY CHECKS */ if( !hStmt ) return SQL_INVALID_HANDLE; if ( !hStmt->hStmtExtras ) return SQL_INVALID_HANDLE; if ( hStmt->hStmtExtras->nRows < 1 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No result set." ); return SQL_ERROR; } if ( nCol < 1 || nCol > hStmt->hStmtExtras->nCols ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Invalid column" ); return SQL_ERROR; } /* OK */ pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nCol]; switch( nFieldIdentifier ) { case SQL_DESC_AUTO_UNIQUE_VALUE: nValue = pColumnHeader->bSQL_DESC_AUTO_UNIQUE_VALUE; break; case SQL_DESC_BASE_COLUMN_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_BASE_COLUMN_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_BASE_TABLE_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_BASE_TABLE_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_CASE_SENSITIVE: nValue = pColumnHeader->bSQL_DESC_CASE_SENSITIVE; break; case SQL_DESC_CATALOG_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_CATALOG_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_CONCISE_TYPE: nValue = pColumnHeader->nSQL_DESC_CONCISE_TYPE; break; case SQL_DESC_COUNT: nValue = hStmt->hStmtExtras->nCols; break; case SQL_DESC_DISPLAY_SIZE: nValue = pColumnHeader->nSQL_DESC_DISPLAY_SIZE; break; case SQL_DESC_FIXED_PREC_SCALE: nValue = pColumnHeader->bSQL_DESC_FIXED_PREC_SCALE; break; case SQL_DESC_LABEL: strncpy( pszValue, pColumnHeader->pszSQL_DESC_LABEL, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_LENGTH: nValue = pColumnHeader->nSQL_DESC_LENGTH; break; case SQL_DESC_LITERAL_PREFIX: strncpy( pszValue, pColumnHeader->pszSQL_DESC_LITERAL_PREFIX, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_LITERAL_SUFFIX: strncpy( pszValue, pColumnHeader->pszSQL_DESC_LITERAL_SUFFIX, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_LOCAL_TYPE_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_LOCAL_TYPE_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_NULLABLE: nValue = pColumnHeader->nSQL_DESC_NULLABLE; break; case SQL_DESC_NUM_PREC_RADIX: nValue = pColumnHeader->nSQL_DESC_NUM_PREC_RADIX; break; case SQL_DESC_OCTET_LENGTH: nValue = pColumnHeader->nSQL_DESC_OCTET_LENGTH; break; case SQL_DESC_PRECISION: nValue = pColumnHeader->nSQL_DESC_PRECISION; break; case SQL_DESC_SCALE: nValue = pColumnHeader->nSQL_DESC_SCALE; break; case SQL_DESC_SCHEMA_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_SCHEMA_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_SEARCHABLE: nValue = pColumnHeader->nSQL_DESC_SEARCHABLE; break; case SQL_DESC_TABLE_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_TABLE_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_TYPE: nValue = pColumnHeader->nSQL_DESC_TYPE; break; case SQL_DESC_TYPE_NAME: strncpy( pszValue, pColumnHeader->pszSQL_DESC_TYPE_NAME, nValueLengthMax ); if ( pnValueLength ) *pnValueLength = strlen( pszValue ); break; case SQL_DESC_UNNAMED: nValue = pColumnHeader->nSQL_DESC_UNNAMED; break; case SQL_DESC_UNSIGNED: nValue = pColumnHeader->bSQL_DESC_UNSIGNED; break; case SQL_DESC_UPDATABLE: nValue = pColumnHeader->nSQL_DESC_UPDATABLE; break; default: sprintf((char*) hStmt->szSqlMsg, "Invalid nFieldIdentifier value of %d", nFieldIdentifier ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); return SQL_ERROR; } if ( pnValue ) *(int*)pnValue = nValue; /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLColAttributes.c000066400000000000000000000050441446441710500217640ustar00rootroot00000000000000/********************************************************************** * SQLColAttributes (this function has been deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLColAttributes( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLUSMALLINT nDescType, SQLPOINTER pszDesc, SQLSMALLINT nDescMax, SQLSMALLINT *pcbDesc, SQLLEN *pfDesc) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************** * 1. verify we have result set * 2. verify col is within range **************************/ /************************** * 3. process request **************************/ switch( nDescType ) { /* enum these case SQL_COLUMN_AUTO_INCREMENT: case SQL_COLUMN_CASE_SENSITIVE: case SQL_COLUMN_COUNT: case SQL_COLUMN_DISPLAY_SIZE: case SQL_COLUMN_LENGTH: case SQL_COLUMN_MONEY: case SQL_COLUMN_NULLABLE: case SQL_COLUMN_PRECISION: case SQL_COLUMN_SCALE: case SQL_COLUMN_SEARCHABLE: case SQL_COLUMN_TYPE: case SQL_COLUMN_UNSIGNED: case SQL_COLUMN_UPDATABLE: case SQL_COLUMN_CATALOG_NAME: case SQL_COLUMN_QUALIFIER_NAME: case SQL_COLUMN_DISTINCT_TYPE: case SQL_COLUMN_LABEL: case SQL_COLUMN_NAME: case SQL_COLUMN_SCHEMA_NAME: case SQL_COLUMN_OWNER_NAME: case SQL_COLUMN_TABLE_NAME: case SQL_COLUMN_TYPE_NAME: */ default: sprintf((char*) hStmt->szSqlMsg, "SQL_ERROR nDescType=%d", nDescType ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); return SQL_ERROR; } /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLColumnPrivileges.c000066400000000000000000000027731446441710500224750ustar00rootroot00000000000000/******************************************************************** * SQLColumnPrivileges * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLColumnPrivileges( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength, SQLCHAR *szColumnName, SQLSMALLINT nColumnNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLColumns.c000066400000000000000000000065051446441710500206230ustar00rootroot00000000000000/******************************************************************** * SQLColumns * * This is something of a mess. Part of the problem here is that msqlListFields * are returned as mSQL 'column headers'... we want them to be returned as a * row for each. So we have to turn the results on their side . * * Another problem is that msqlListFields will also return indexs. So we have * to make sure that these are not included here. * * The end result is more code than what would usually be found here. * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" enum nSQLColumns { TABLE_CAT = 1, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, DATA_TYPE, TYPE_NAME, COLUMN_SIZE, BUFFER_LENGTH, DECIMAL_DIGITS, NUM_PREC_RADIX, NULLABLE, REMARKS, COLUMN_DEF, SQL_DATA_TYPE, SQL_DATETIME_SUB, CHAR_OCTET_LENGTH, ORDINAL_POSITION, IS_NULLABLE, COL_MAX }; /**************************** * replace this with init of some struct (see same func for MiniSQL driver) */ char *aSQLColumns[] = { "one", "two" }; /***************************/ SQLRETURN SQLColumns( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength, SQLCHAR *szColumnName, SQLSMALLINT nColumnNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; COLUMNHDR *pColumnHeader; int nColumn; long nCols; long nRow; char szBuffer[101]; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); if ( szTableName == NULL || szTableName[0] == '\0' ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Must supply a valid table name" ); return SQL_ERROR; } /************************** * close any existing result **************************/ if ( hStmt->hStmtExtras->aResults ) _FreeResults( hStmt->hStmtExtras ); if ( hStmt->pszQuery != NULL ) free( hStmt->pszQuery ); /************************ * generate a result set listing columns ************************/ /************************** * allocate memory for columns headers and result data (row 0 is column header while col 0 is reserved for bookmarks) **************************/ /************************** * gather column header information (save col 0 for bookmarks) **************************/ /************************ * gather data (save col 0 for bookmarks and factor out index columns) ************************/ /************************** * free the snapshot **************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLConnect.c000066400000000000000000000067371446441710500206030ustar00rootroot00000000000000/********************************************************************** * SQLConnect * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLConnect( SQLHDBC hDrvDbc, SQLCHAR *szDataSource, SQLSMALLINT nDataSourceLength, SQLCHAR *szUID, SQLSMALLINT nUIDLength, SQLCHAR *szPWD, SQLSMALLINT nPWDLength ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; char szDATABASE[INI_MAX_PROPERTY_VALUE+1]; char szHOST[INI_MAX_PROPERTY_VALUE+1]; char szPORT[INI_MAX_PROPERTY_VALUE+1]; char szFLAG[INI_MAX_PROPERTY_VALUE+1]; /* SANITY CHECKS */ if( SQL_NULL_HDBC == hDbc ) return SQL_INVALID_HANDLE; sprintf((char*) hDbc->szSqlMsg, "hDbc=$%08lX 3zDataSource=(%s)", (long)hDbc, szDataSource ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hDbc->szSqlMsg ); if( hDbc->bConnected == 1 ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Already connected" ); return SQL_ERROR; } if ( nDataSourceLength == SQL_NTS ) { if ( strlen((char*) szDataSource ) > ODBC_FILENAME_MAX+INI_MAX_OBJECT_NAME ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Given Data Source is too long. I consider it suspect." ); return SQL_ERROR; } } else { if ( nDataSourceLength > ODBC_FILENAME_MAX+INI_MAX_OBJECT_NAME ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Given Data Source is too long. I consider it suspect." ); return SQL_ERROR; } } /******************** * gather and use any required DSN properties * - DATABASE * - HOST (localhost assumed if not supplied) ********************/ szDATABASE[0] = '\0'; szHOST[0] = '\0'; szPORT[0] = '\0'; szFLAG[0] = '\0'; SQLGetPrivateProfileString((char*) szDataSource, "DATABASE", "", szDATABASE, sizeof(szDATABASE), "odbc.ini" ); if ( szDATABASE[0] == '\0' ) { sprintf((char*) hDbc->szSqlMsg, "SQL_ERROR Could not find Driver entry for %s in system information", szDataSource ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hDbc->szSqlMsg ); return SQL_ERROR; } SQLGetPrivateProfileString((char*) szDataSource, "HOST", "localhost", szHOST, sizeof(szHOST), "odbc.ini" ); SQLGetPrivateProfileString((char*) szDataSource, "PORT", "0", szPORT, sizeof(szPORT), "odbc.ini" ); SQLGetPrivateProfileString((char*) szDataSource, "FLAG", "0", szFLAG, sizeof(szFLAG), "odbc.ini" ); /******************** * 1. initialise structures * 2. try connection with database using your native calls * 3. store your server handle in the extras somewhere * 4. set connection state * hDbc->bConnected = TRUE; ********************/ logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLCopyDesc.c000066400000000000000000000013661446441710500207140ustar00rootroot00000000000000/********************************************************************** * SQLCopyDesc * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLCopyDesc( SQLHDESC hSourceDescHandle, SQLHDESC hTargetDescHandle ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLDescribeCol.c000066400000000000000000000042461446441710500213610ustar00rootroot00000000000000/********************************************************************** * SQLDescribeCol * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLDescribeCol( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLCHAR *szColName, SQLSMALLINT nColNameMax, SQLSMALLINT *pnColNameLength, SQLSMALLINT *pnSQLDataType, SQLULEN *pnColSize, SQLSMALLINT *pnDecDigits, SQLSMALLINT *pnNullable ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; COLUMNHDR *pColumnHeader; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; if ( NULL == hStmt->hStmtExtras ) return SQL_INVALID_HANDLE; if ( hStmt->hStmtExtras->nRows < 1 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No result set." ); return SQL_ERROR; } if ( nCol < 1 || nCol > hStmt->hStmtExtras->nCols ) { sprintf((char*) hStmt->szSqlMsg, "SQL_ERROR Column %d is out of range. Range is 1 - %d", nCol, hStmt->hStmtExtras->nCols ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); return SQL_ERROR; } /* OK */ pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nCol]; if ( szColName ) strncpy((char*) szColName, pColumnHeader->pszSQL_DESC_NAME, nColNameMax ); if ( pnColNameLength ) *pnColNameLength = strlen((char*) szColName ); if ( pnSQLDataType ) *pnSQLDataType = pColumnHeader->nSQL_DESC_TYPE; if ( pnColSize ) *pnColSize = pColumnHeader->nSQL_DESC_LENGTH; if ( pnDecDigits ) *pnDecDigits = pColumnHeader->nSQL_DESC_SCALE; if ( pnNullable ) *pnNullable = pColumnHeader->nSQL_DESC_NULLABLE; logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLDescribeParam.c000066400000000000000000000027051446441710500217020ustar00rootroot00000000000000/********************************************************************** * SQLDescribeParam * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLDescribeParam( SQLHSTMT hDrvStmt, SQLUSMALLINT nParmNumber, SQLSMALLINT *pnDataType, SQLULEN *pnSize, SQLSMALLINT *pnDecDigits, SQLSMALLINT *pnNullable ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLDisconnect.c000066400000000000000000000030511446441710500212650ustar00rootroot00000000000000/********************************************************************** * SQLDisconnect * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLDisconnect( SQLHDBC hDrvDbc ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; /* SANITY CHECKS */ if( NULL == hDbc ) return SQL_INVALID_HANDLE; sprintf((char*) hDbc->szSqlMsg, "hDbc = $%08lX", (long)hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, (char*)hDbc->szSqlMsg ); if( hDbc->bConnected == 0 ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_SUCCESS_WITH_INFO Connection not open" ); return SQL_SUCCESS_WITH_INFO; } if ( hDbc->hFirstStmt != SQL_NULL_HSTMT ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Active Statements exist. Can not disconnect." ); return SQL_ERROR; } /**************************** * 1. do driver specific close here ****************************/ hDbc->bConnected = 0; logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLDriverConnect.c000066400000000000000000000106451446441710500217500ustar00rootroot00000000000000/********************************************************************** * SQLDriverConnect * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLDriverConnect( SQLHDBC hDrvDbc, SQLHWND hWnd, SQLCHAR *szConnStrIn, SQLSMALLINT nConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pnConnStrOut, SQLUSMALLINT nDriverCompletion ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; char szDSN[INI_MAX_PROPERTY_VALUE+1] = ""; char szDRIVER[INI_MAX_PROPERTY_VALUE+1] = ""; char szUID[INI_MAX_PROPERTY_VALUE+1] = ""; char szPWD[INI_MAX_PROPERTY_VALUE+1] = ""; char szDATABASE[INI_MAX_PROPERTY_VALUE+1] = ""; char szHOST[INI_MAX_PROPERTY_VALUE+1] = ""; char szPORT[INI_MAX_PROPERTY_VALUE+1] = ""; char szSOCKET[INI_MAX_PROPERTY_VALUE+1] = ""; char szFLAG[INI_MAX_PROPERTY_VALUE+1] = ""; char szNameValue[INI_MAX_PROPERTY_VALUE+1] = ""; char szName[INI_MAX_PROPERTY_VALUE+1] = ""; char szValue[INI_MAX_PROPERTY_VALUE+1] = ""; int nOption = 0; /* SANITY CHECKS */ if( NULL == hDbc ) return SQL_INVALID_HANDLE; sprintf((char*) hDbc->szSqlMsg, "hDbc = $%08lX", (long)hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hDbc->szSqlMsg ); if( hDbc->bConnected == 1 ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Already connected" ); return SQL_ERROR; } if( !szConnStrIn ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Bad argument" ); return SQL_ERROR; } switch( nDriverCompletion ) { case SQL_DRIVER_PROMPT: case SQL_DRIVER_COMPLETE: case SQL_DRIVER_COMPLETE_REQUIRED: case SQL_DRIVER_NOPROMPT: default: sprintf((char*) hDbc->szSqlMsg, "Invalid nDriverCompletion=%d", nDriverCompletion ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hDbc->szSqlMsg ); break; } /************************* * 1. parse nConnStrIn for connection options. Format is; * Property=Value;... * 2. we may not have all options so handle as per DM request * 3. fill as required szConnStrOut *************************/ for ( nOption = 1; iniElement((char*) szConnStrIn, ';', '\0', nOption, szNameValue, sizeof(szNameValue) ) == INI_SUCCESS ; nOption++ ) { szName[0] = '\0'; szValue[0] = '\0'; iniElement( szNameValue, '=', '\0', 0, szName, sizeof(szName) ); iniElement( szNameValue, '=', '\0', 1, szValue, sizeof(szValue) ); if ( strcasecmp( szName, "DSN" ) == 0 ) strcpy( szDSN, szValue ); else if ( strcasecmp( szName, "DRIVER" ) == 0 ) strcpy( szDRIVER, szValue ); else if ( strcasecmp( szName, "UID" ) == 0 ) strcpy( szUID, szValue ); else if ( strcasecmp( szName, "PWD" ) == 0 ) strcpy( szPWD, szValue ); else if ( strcasecmp( szName, "SERVER" ) == 0 ) strcpy( szHOST, szValue ); else if ( strcasecmp( szName, "DB" ) == 0 ) strcpy( szDATABASE, szValue ); else if ( strcasecmp( szName, "SOCKET" ) == 0 ) strcpy( szSOCKET, szValue ); else if ( strcasecmp( szName, "PORT" ) == 0 ) strcpy( szPORT, szValue ); else if ( strcasecmp( szName, "OPTION" ) == 0 ) strcpy( szFLAG, szValue ); } /**************************** * return the connect string we are using ***************************/ if( !szConnStrOut ) { } /************************* * 4. try to connect * 5. set gathered options (ie USE Database or whatever) * 6. set connection state * hDbc->bConnected = TRUE; *************************/ hDbc->bConnected = 1; logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported." ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLEndTran.c000066400000000000000000000014161446441710500205320ustar00rootroot00000000000000/********************************************************************** * SQLEndTran * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLEndTran( SQLSMALLINT nHandleType, SQLHANDLE nHandle, SQLSMALLINT nCompletionType ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLError.c000066400000000000000000000046301446441710500202710ustar00rootroot00000000000000/********************************************************************** * SQLError (deprecated see SQLGetDiagRec) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" /*! * \brief Get oldest error for the given handle. * * This is deprecated - use SQLGetDiagRec instead. This is mapped * to SQLGetDiagRec. The main difference between this and * SQLGetDiagRec is that this call will delete the error message to * allow multiple calls here to work their way through all of the * errors even with the lack of an ability to pass a specific message * number to be returned. * * \param hDrvEnv * \param hDrvDbc * \param hDrvStmt * \param szSqlState * \param pfNativeError * \param szErrorMsg * \param nErrorMsgMax * \param pcbErrorMsg * * \return SQLRETURN * * \sa SQLGetDiagRec */ SQLRETURN SQLError( SQLHENV hDrvEnv, SQLHDBC hDrvDbc, SQLHSTMT hDrvStmt, SQLCHAR *szSqlState, SQLINTEGER *pfNativeError, SQLCHAR *szErrorMsg, SQLSMALLINT nErrorMsgMax, SQLSMALLINT *pcbErrorMsg ) { SQLSMALLINT nHandleType; SQLHANDLE hHandle; SQLRETURN nReturn; HLOG hLog; /* map call to SQLGetDiagRec */ if ( hDrvEnv ) { nHandleType = SQL_HANDLE_ENV; hHandle = hDrvEnv; hLog = ((HDRVENV)hDrvEnv)->hLog; } else if ( hDrvDbc ) { nHandleType = SQL_HANDLE_DBC; hHandle = hDrvDbc; hLog = ((HDRVDBC)hDrvDbc)->hLog; } else if ( hDrvStmt ) { nHandleType = SQL_HANDLE_STMT; hHandle = hDrvStmt; hLog = ((HDRVSTMT)hDrvStmt)->hLog; } else return SQL_INVALID_HANDLE; nReturn = SQLGetDiagRec_( nHandleType, hHandle, 1, szSqlState, pfNativeError, szErrorMsg, nErrorMsgMax, pcbErrorMsg ); /* unlike SQLGetDiagRec - we delete the message returned */ if ( SQL_SUCCEEDED( nReturn ) ) logPopMsg( hLog ); return nReturn; } unixODBC-2.3.12/Drivers/template/SQLExecDirect.c000066400000000000000000000031071446441710500212150ustar00rootroot00000000000000/********************************************************************** * SQLExecDirect * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLExecDirect( SQLHSTMT hDrvStmt, SQLCHAR *szSqlStr, SQLINTEGER nSqlStr ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; RETCODE rc; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /* prepare command, avoid finding the driver manager SQLPrepare */ rc = template_SQLPrepare( hDrvStmt, szSqlStr, nSqlStr ); if ( SQL_SUCCESS != rc ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "Could not prepare statement" ); return rc; } /* execute command */ rc = SQLExecute( hDrvStmt ); if ( SQL_SUCCESS != rc ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "Problem calling SQLEXecute" ); return rc; } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLExecute.c000066400000000000000000000040111446441710500205730ustar00rootroot00000000000000/********************************************************************** * SQLExecute * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLExecute( SQLHSTMT hDrvStmt ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; int nColumn; int nCols; int nRow; COLUMNHDR *pColumnHeader; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); if( hStmt->pszQuery == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No prepared statement" ); return SQL_ERROR; } /************************** * Free any current results **************************/ if ( hStmt->hStmtExtras->aResults ) _FreeResults( hStmt->hStmtExtras ); /************************** * send prepared query to server **************************/ /************************** * allocate memory for columns headers and result data (row 0 is column header while col 0 is reserved for bookmarks) **************************/ /************************** * gather column header information (save col 0 for bookmarks) **************************/ /************************ * gather data (save col 0 for bookmarks) ************************/ /************************** * free the snapshot **************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLExtendedFetch.c000066400000000000000000000026441446441710500217150ustar00rootroot00000000000000/********************************************************************** * SQLExtendedFetch * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLExtendedFetch( SQLHSTMT hDrvStmt, SQLUSMALLINT nOrientation, SQLLEN nOffset, SQLULEN *pnRowCount, SQLUSMALLINT *pRowStatusArray ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLFetch.c000066400000000000000000000043151446441710500202310ustar00rootroot00000000000000/********************************************************************** * SQLFetch * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLFetch( SQLHSTMT hDrvStmt) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; int nColumn = -1; COLUMNHDR *pColumnHeader; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); if ( hStmt->hStmtExtras->nRows < 1 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No result set." ); return SQL_ERROR; } /************************ * goto next row ************************/ if ( hStmt->hStmtExtras->nRow < 0 ) return SQL_NO_DATA; if ( hStmt->hStmtExtras->nRow >= hStmt->hStmtExtras->nRows ) return SQL_NO_DATA; hStmt->hStmtExtras->nRow++; /************************ * transfer bound column values to bound storage as required ************************/ for ( nColumn=1; nColumn <= hStmt->hStmtExtras->nCols; nColumn++ ) { pColumnHeader = (COLUMNHDR*)(hStmt->hStmtExtras->aResults)[nColumn]; if ( pColumnHeader->pTargetValue != NULL ) { if ( _GetData( hDrvStmt, nColumn, pColumnHeader->nTargetType, pColumnHeader->pTargetValue, pColumnHeader->nTargetValueMax, pColumnHeader->pnLengthOrIndicator ) != SQL_SUCCESS ) { sprintf((char*) hStmt->szSqlMsg, "SQL_ERROR Failed to get data for column %d", nColumn ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); return SQL_ERROR; } } } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLFetchScroll.c000066400000000000000000000024131446441710500214050ustar00rootroot00000000000000/***************************************************************************** * SQLFetchScroll * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * *****************************************************************************/ #include #include "driver.h" SQLRETURN SQLFetchScroll( SQLHSTMT hDrvStmt, SQLSMALLINT nOrientation, SQLLEN nOffset ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLForeignKeys.c000066400000000000000000000036671446441710500214360ustar00rootroot00000000000000/******************************************************************** * SQLForeignKeys * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLForeignKeys( SQLHSTMT hDrvStmt, SQLCHAR *szPKCatalogName, SQLSMALLINT nPKCatalogNameLength, SQLCHAR *szPKSchemaName, SQLSMALLINT nPKSchemaNameLength, SQLCHAR *szPKTableName, SQLSMALLINT nPKTableNameLength, SQLCHAR *szFKCatalogName, SQLSMALLINT nFKCatalogNameLength, SQLCHAR *szFKSchemaName, SQLSMALLINT nFKSchemaNameLength, SQLCHAR *szFKTableName, SQLSMALLINT nFKTableNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLFreeConnect.c000066400000000000000000000027771446441710500214050ustar00rootroot00000000000000/********************************************************************** * SQLFreeConnect * * Do not try to Free Dbc if there are Stmts... return an error. Let the * Driver Manager do a recursive clean up if it wants. * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN _FreeConnect( SQLHDBC hDrvDbc ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; int nReturn; /* SANITY CHECKS */ if( NULL == hDbc ) return SQL_INVALID_HANDLE; sprintf((char*) hDbc->szSqlMsg, "hDbc = $%08lX", (long)hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, (char*)hDbc->szSqlMsg ); if( hDbc->bConnected ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Connection is active" ); return SQL_ERROR; } if ( hDbc->hFirstStmt != NULL ) { logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Connection has allocated statements" ); return SQL_ERROR; } nReturn = _FreeDbc( hDbc ); return nReturn; } SQLRETURN SQLFreeConnect( SQLHDBC hDrvDbc ) { return _FreeConnect( hDrvDbc ); } unixODBC-2.3.12/Drivers/template/SQLFreeEnv.c000066400000000000000000000030501446441710500205250ustar00rootroot00000000000000/********************************************************************** * SQLFreeEnv * * Do not try to Free Env if there are Dbcs... return an error. Let the * Driver Manager do a recursive clean up if it wants. * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN _FreeEnv( SQLHENV hDrvEnv ) { HDRVENV hEnv = (HDRVENV)hDrvEnv; /* SANITY CHECKS */ if( hEnv == SQL_NULL_HENV ) return SQL_INVALID_HANDLE; sprintf((char*) hEnv->szSqlMsg, "hEnv = $%08lX", (long)hEnv ); logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hEnv->szSqlMsg ); if ( hEnv->hFirstDbc != NULL ) { logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR There are allocated Connections" ); return SQL_ERROR; } /************ * !!! ADD CODE TO FREE DRIVER SPECIFIC MEMORY (hidden in hEnvExtras) HERE !!! ************/ free( hEnv->hEnvExtras ); logPushMsg( hEnv->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); logClose( hEnv->hLog ); free( hEnv ); return SQL_SUCCESS; } SQLRETURN SQLFreeEnv( SQLHENV hDrvEnv ) { return _FreeEnv( hDrvEnv ); } unixODBC-2.3.12/Drivers/template/SQLFreeHandle.c000066400000000000000000000020211446441710500211650ustar00rootroot00000000000000/********************************************************************** * SQLFreeHandle * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLFreeHandle( SQLSMALLINT nHandleType, SQLHANDLE nHandle ) { switch( nHandleType ) { case SQL_HANDLE_ENV: return _FreeEnv( (SQLHENV)nHandle ); case SQL_HANDLE_DBC: return _FreeConnect( (SQLHDBC)nHandle ); case SQL_HANDLE_STMT: return _FreeStmt( (SQLHSTMT)nHandle ); case SQL_HANDLE_DESC: break; default: return SQL_ERROR; } return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLFreeStmt.c000066400000000000000000000026321446441710500207310ustar00rootroot00000000000000/********************************************************************** * SQLFreeStmt * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLFreeStmt( SQLHSTMT hDrvStmt, SQLUSMALLINT nOption ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /********* * RESET PARAMS *********/ switch( nOption ) { case SQL_CLOSE: break; case SQL_DROP: return _FreeStmt( hStmt ); case SQL_UNBIND: break; case SQL_RESET_PARAMS: break; default: sprintf((char*) hStmt->szSqlMsg, "SQL_ERROR Invalid nOption=%d", nOption ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); return SQL_ERROR; } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLGetConnectAttr.c000066400000000000000000000026751446441710500220730ustar00rootroot00000000000000/********************************************************************** * SQLGetConnectAttr * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetConnectAttr( SQLHDBC hDrvDbc, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; /* SANITY CHECKS */ if( NULL == hDbc ) return SQL_INVALID_HANDLE; sprintf((char*) hDbc->szSqlMsg, "hDbc = $%08lX", (long)hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hDbc->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLGetConnectOption.c000066400000000000000000000023161446441710500224210ustar00rootroot00000000000000/********************************************************************** * SQLGetConnectOption (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetConnectOption( SQLHDBC hDrvDbc, UWORD fOption, PTR pvParam ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; /* SANITY CHECKS */ if( NULL == hDbc ) return SQL_INVALID_HANDLE; sprintf((char*) hDbc->szSqlMsg, "hDbc = $%08lX", (long)hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hDbc->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLGetCursorName.c000066400000000000000000000034351446441710500217200ustar00rootroot00000000000000/********************************************************************** * SQLGetCursorName * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetCursorName( SQLHSTMT hDrvStmt, SQLCHAR *szCursor, SQLSMALLINT nCursorMaxLength, SQLSMALLINT *pnCursorLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; int ci; /* counter variable */ /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); if ( NULL == szCursor ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No cursor name." ); return SQL_ERROR; } /* ** copy cursor name */ strncpy((char*) szCursor, (char*)hStmt->szCursorName, nCursorMaxLength ); /* ** set length of transfered data */ ci = strlen((char*) hStmt->szCursorName ); /* if ( NULL != pnCursorLength ) *pnCursorLength = MIN( ci, nCursorMaxLength ); */ if ( nCursorMaxLength < ci ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_SUCCESS_WITH_INFO Cursor was truncated" ); return SQL_SUCCESS_WITH_INFO; } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLGetData.c000066400000000000000000000020231446441710500205030ustar00rootroot00000000000000/********************************************************************** * SQLGetData * * 1. mSQL server sends all data as ascii strings so things are * simplified. We always convert from string to nTargetType. * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetData( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLSMALLINT nTargetType, /* C DATA TYPE */ SQLPOINTER pTarget, SQLLEN nTargetLength, SQLLEN *pnLengthOrIndicator ) { return _GetData( hDrvStmt, nCol, nTargetType, pTarget, nTargetLength, pnLengthOrIndicator ); } unixODBC-2.3.12/Drivers/template/SQLGetDescField.c000066400000000000000000000017301446441710500214600ustar00rootroot00000000000000/********************************************************************** * SQLGetDescField * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetDescField( SQLHDESC DescriptorHandle, SQLSMALLINT RecordNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLGetDescRec.c000066400000000000000000000023521446441710500211470ustar00rootroot00000000000000/********************************************************************** * SQLGetDescRec * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetDescRec( SQLHDESC DescriptorHandle, SQLSMALLINT RecordNumber, SQLCHAR *Name, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, SQLSMALLINT *Type, SQLSMALLINT *SubType, SQLLEN *Length, SQLSMALLINT *Precision, SQLSMALLINT *Scale, SQLSMALLINT *Nullable ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLGetDiagField.c000066400000000000000000000020141446441710500214420ustar00rootroot00000000000000/********************************************************************** * SQLGetDiagField * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetDiagField( SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecordNumber, SQLSMALLINT DiagIdentifier, SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLGetDiagRec.c000066400000000000000000000055071446441710500211420ustar00rootroot00000000000000/********************************************************************** * SQLGetDiagRec * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetDiagRec_( SQLSMALLINT nHandleType, SQLHANDLE hHandle, SQLSMALLINT nRecordNumber, SQLCHAR * pszState, SQLINTEGER * pnNativeError, SQLCHAR * pszMessageText, SQLSMALLINT nBufferLength, SQLSMALLINT * pnStringLength ) { HLOG hLog = NULL; HLOGMSG hMsg = NULL; /* sanity checks */ if ( !hHandle ) return SQL_INVALID_HANDLE; /* clear return values */ if ( pszState ) strcpy((char*) pszState, "-----" ); if ( pnNativeError ) *pnNativeError = 0; if ( pszMessageText ) memset( pszMessageText, 0, nBufferLength ); if ( pnStringLength ) *pnStringLength = 0; /* get hLog */ switch ( nHandleType ) { case SQL_HANDLE_ENV: hLog = ((HDRVENV)hHandle)->hLog; break; case SQL_HANDLE_DBC: hLog = ((HDRVDBC)hHandle)->hLog; break; case SQL_HANDLE_STMT: hLog = ((HDRVSTMT)hHandle)->hLog; break; case SQL_HANDLE_DESC: default: return SQL_ERROR; } /* get message */ if ( logPeekMsg( hLog, 1, &hMsg ) != LOG_SUCCESS ) return SQL_NO_DATA; if ( pnNativeError ) *pnNativeError = hMsg->nCode; if ( pszMessageText ) strncpy( (char*)pszMessageText, hMsg->pszMessage, nBufferLength-1 ); if ( pnStringLength ) *pnStringLength = strlen( (char*)hMsg->pszMessage ); return SQL_SUCCESS; } SQLRETURN SQLGetDiagRec( SQLSMALLINT nHandleType, SQLHANDLE hHandle, SQLSMALLINT nRecordNumber, SQLCHAR * pszState, SQLINTEGER * pnNativeError, SQLCHAR * pszMessageText, SQLSMALLINT nBufferLength, SQLSMALLINT * pnStringLength ) { return SQLGetDiagRec_( nHandleType, hHandle, nRecordNumber, pszState, pnNativeError, pszMessageText, nBufferLength, pnStringLength ); } unixODBC-2.3.12/Drivers/template/SQLGetEnvAttr.c000066400000000000000000000016201446441710500212170ustar00rootroot00000000000000/********************************************************************** * SQLGetEnvAttr * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetEnvAttr( SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLGetInfo.c000066400000000000000000000014031446441710500205260ustar00rootroot00000000000000/********************************************************************** * SQLGetInfo * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetInfo( SQLHDBC hDbc, SQLUSMALLINT nInfoType, SQLPOINTER pInfoValue, SQLSMALLINT nInfoValueMax, SQLSMALLINT *pnLength) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLGetStmtAttr.c000066400000000000000000000026331446441710500214230ustar00rootroot00000000000000/********************************************************************** * SQLGetStmtAttr * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetStmtAttr( SQLHSTMT hDrvStmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLGetStmtOption.c000066400000000000000000000024001446441710500217510ustar00rootroot00000000000000/********************************************************************** * SQLGetStmtOption (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetStmtOption( SQLHSTMT hDrvStmt, UWORD fOption, PTR pvParam) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLGetTypeInfo.c000066400000000000000000000023051446441710500213720ustar00rootroot00000000000000/********************************************************************** * SQLGetTypeInfo * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLGetTypeInfo( SQLHSTMT hDrvStmt, SQLSMALLINT nSqlType ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLMoreResults.c000066400000000000000000000022061446441710500214610ustar00rootroot00000000000000/********************************************************************** * SQLMoreResults * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLMoreResults( SQLHSTMT hDrvStmt ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLNativeSql.c000066400000000000000000000026351446441710500211110ustar00rootroot00000000000000/********************************************************************** * SQLNativeSql * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLNativeSql( SQLHSTMT hDrvStmt, SQLCHAR *szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLCHAR *szSqlStr, SQLINTEGER cbSqlStrMax, SQLINTEGER *pcbSqlStr ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLNumParams.c000066400000000000000000000023011446441710500210740ustar00rootroot00000000000000/********************************************************************** * SQLNumParams * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLNumParams( SQLHSTMT hDrvStmt, SQLSMALLINT *pnParamCount ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLNumResultCols.c000066400000000000000000000025771446441710500217670ustar00rootroot00000000000000/********************************************************************** * SQLNumResultCols * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLNumResultCols( SQLHSTMT hDrvStmt, SQLSMALLINT *pnColumnCount ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); if ( hStmt->hStmtExtras->nRows < 1 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No result set." ); return SQL_ERROR; } /******************** * get number of columns in result set ********************/ *pnColumnCount = hStmt->hStmtExtras->nCols; logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLParamData.c000066400000000000000000000022721446441710500210320ustar00rootroot00000000000000/********************************************************************** * SQLParamData * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLParamData( SQLHSTMT hDrvStmt, SQLPOINTER *pValue ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLParamOptions.c000066400000000000000000000023071446441710500216130ustar00rootroot00000000000000/********************************************************************** * SQLParamOptions (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLParamOptions( SQLHSTMT hDrvStmt, SQLULEN nRow, SQLULEN *pnRow ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLPrepare.c000066400000000000000000000036351446441710500206020ustar00rootroot00000000000000/********************************************************************** * SQLPrepare * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLPrepare( SQLHSTMT hDrvStmt, SQLCHAR *szSqlStr, SQLINTEGER nSqlStrLength ) { return template_SQLPrepare( hDrvStmt, szSqlStr, nSqlStrLength ); } SQLRETURN template_SQLPrepare( SQLHSTMT hDrvStmt, SQLCHAR *szSqlStr, SQLINTEGER nSqlStrLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if ( NULL == hStmt ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); if ( szSqlStr == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No SQL to process" ); return SQL_ERROR; } if ( hStmt->pszQuery != NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Statement already in use." ); return SQL_ERROR; } /* allocate and copy statement to buffer (process escape sequences and parameter tokens as required) */ hStmt->pszQuery = (SQLCHAR*)strdup((char*) szSqlStr ); if ( NULL == hStmt->pszQuery ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Memory allocation error" ); return SQL_ERROR; } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLPrimaryKeys.c000066400000000000000000000026211446441710500214550ustar00rootroot00000000000000/******************************************************************** * SQLPrimaryKeys * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLPrimaryKeys( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLProcedureColumns.c000066400000000000000000000030141446441710500224640ustar00rootroot00000000000000/******************************************************************** * SQLProcedureColumns * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLProcedureColumns( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szProcName, SQLSMALLINT nProcNameLength, SQLCHAR *szColumnName, SQLSMALLINT nColumnNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLProcedures.c000066400000000000000000000026221446441710500213120ustar00rootroot00000000000000/******************************************************************** * SQLProcedures * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLProcedures( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szProcName, SQLSMALLINT nProcNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLPutData.c000066400000000000000000000024661446441710500205470ustar00rootroot00000000000000/********************************************************************** * SQLPutData * * Supplies parameter data at execution time. Used in conjuction with * SQLParamData. ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLPutData( SQLHSTMT hDrvStmt, SQLPOINTER pData, SQLLEN nLengthOrIndicator ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLRowCount.c000066400000000000000000000023771446441710500207660ustar00rootroot00000000000000/********************************************************************** * SQLRowCount * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLRowCount( SQLHSTMT hDrvStmt, SQLLEN *pnRowCount) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); if ( NULL == pnRowCount ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR pnRowCount can not be NULL" ); return SQL_ERROR; } *pnRowCount = hStmt->hStmtExtras->nRows; logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLSetConnectOption.c000066400000000000000000000024411446441710500224340ustar00rootroot00000000000000/********************************************************************** * SQLSetConnectOption (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetConnectOption( SQLHDBC hDrvDbc, UWORD nOption, SQLULEN vParam) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; /* SANITY CHECKS */ if ( hDbc == SQL_NULL_HDBC ) return SQL_INVALID_HANDLE; switch ( nOption ) { case SQL_TRANSLATE_DLL: case SQL_TRANSLATE_OPTION: /* case SQL_CONNECT_OPT_DRVR_START: */ case SQL_ODBC_CURSORS: case SQL_OPT_TRACE: switch ( vParam ) { case SQL_OPT_TRACE_ON: case SQL_OPT_TRACE_OFF: default: ; } break; case SQL_OPT_TRACEFILE: case SQL_ACCESS_MODE: case SQL_AUTOCOMMIT: default: ; } logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_SUCCESS_WITH_INFO Function not fully implemented" ); return SQL_SUCCESS_WITH_INFO; } unixODBC-2.3.12/Drivers/template/SQLSetCursorName.c000066400000000000000000000031341446441710500217300ustar00rootroot00000000000000/********************************************************************** * SQLSetCursorName * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetCursorName( SQLHSTMT hDrvStmt, SQLCHAR *szCursor, SQLSMALLINT nCursorLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); if ( NULL == szCursor || 0 == isalpha(*szCursor) ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Invalid cursor name" ); return SQL_ERROR; } /* COPY CURSOR */ if ( SQL_NTS == nCursorLength ) { strncpy((char*) hStmt->szCursorName,(char*) szCursor, SQL_MAX_CURSOR_NAME ); } else { /* strncpy( hStmt->szCursorName, szCursor, MIN(SQL_MAX_CURSOR_NAME - 1, nCursorLength) ); hStmt->szCursorName[ MIN( SQL_MAX_CURSOR_NAME - 1, nCursorLength) ] = '\0'; */ } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLSetDescField.c000066400000000000000000000016311446441710500214740ustar00rootroot00000000000000/********************************************************************** * SQLSetDescField * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetDescField( SQLHDESC DescriptorHandle, SQLSMALLINT RecordNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLSetDescRec.c000066400000000000000000000022611446441710500211620ustar00rootroot00000000000000/********************************************************************** * SQLSetDescRec * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetDescRec( SQLHDESC hDescriptorHandle, SQLSMALLINT nRecordNumber, SQLSMALLINT nType, SQLSMALLINT nSubType, SQLLEN nLength, SQLSMALLINT nPrecision, SQLSMALLINT nScale, SQLPOINTER pData, SQLLEN *pnStringLength, SQLLEN *pnIndicator ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLSetEnvAttr.c000066400000000000000000000015211446441710500212330ustar00rootroot00000000000000/********************************************************************** * SQLSetEnvAttr * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetEnvAttr( SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength ) { return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLSetParam.c000066400000000000000000000032371446441710500207160ustar00rootroot00000000000000/******************************************************************** * SQLSetParam (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetParam(SQLHSTMT hDrvStmt, SQLUSMALLINT nPar, SQLSMALLINT nType, SQLSMALLINT nSqlType, SQLULEN nColDef, SQLSMALLINT nScale, SQLPOINTER pValue, SQLLEN *pnValue) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); if ( NULL == hStmt->pszQuery ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No prepared statement to work with" ); return SQL_ERROR; } /****************** * 1. Your param storage is in hStmt->hStmtExtras * so you will have to code for it. Do it here. ******************/ /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLSetPos.c000066400000000000000000000036741446441710500204240ustar00rootroot00000000000000/******************************************************************** * SQLSetPos * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetPos( SQLHSTMT hDrvStmt, SQLSETPOSIROW nRow, SQLUSMALLINT nOperation, SQLUSMALLINT nLockType ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /* OK */ switch ( nOperation ) { case SQL_POSITION: break; case SQL_REFRESH: break; case SQL_UPDATE: break; case SQL_DELETE: break; default: sprintf((char*) hStmt->szSqlMsg, "SQL_ERROR Invalid nOperation=%d", nOperation ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); return SQL_ERROR; } switch ( nLockType ) { case SQL_LOCK_NO_CHANGE: break; case SQL_LOCK_EXCLUSIVE: break; case SQL_LOCK_UNLOCK: break; default: sprintf((char*) hStmt->szSqlMsg, "SQL_ERROR Invalid nLockType=%d", nLockType ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); return SQL_ERROR; } /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLSetScrollOptions.c000066400000000000000000000025111446441710500224620ustar00rootroot00000000000000/******************************************************************** * SQLSetScrollOptions (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetScrollOptions( /* Use SQLSetStmtOptions */ SQLHSTMT hDrvStmt, SQLUSMALLINT fConcurrency, SQLLEN crowKeyset, SQLUSMALLINT crowRowset) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long) hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLSetStmtAttr.c000066400000000000000000000025611446441710500214370ustar00rootroot00000000000000/********************************************************************** * SQLSetStmtAttr * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetStmtAttr( SQLHSTMT hDrvStmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLSetStmtOption.c000066400000000000000000000023341446441710500217730ustar00rootroot00000000000000/********************************************************************** * SQLSetStmtOption (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN SQLSetStmtOption( SQLHSTMT hDrvStmt, UWORD fOption, SQLULEN vParam) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLSpecialColumns.c000066400000000000000000000036461446441710500221270ustar00rootroot00000000000000/******************************************************************** * SQLSpecialColumns * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" /* THIS IS CORRECT... SQLRETURN SQLSpecialColumns( SQLHSTMT hDrvStmt, SQLSMALLINT nColumnType, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength, SQLSMALLINT nScope, SQLSMALLINT nNullable ) THIS WORKS... */ SQLRETURN SQLSpecialColumns( SQLHSTMT hDrvStmt, UWORD nColumnType, UCHAR *szCatalogName, SWORD nCatalogNameLength, UCHAR *szSchemaName, SWORD nSchemaNameLength, UCHAR *szTableName, SWORD nTableNameLength, UWORD nScope, UWORD nNullable ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLStatistics.c000066400000000000000000000060301446441710500213260ustar00rootroot00000000000000/******************************************************************** * SQLStatistics * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" enum nSQLStatistics { TABLE_CAT = 1, TABLE_SCHEM, TABLE_NAME, NON_UNIQUE, INDEX_QUALIFIER, INDEX_NAME, TYPE, ORDINAL_POSITION, COLUMN_NAME, ASC_OR_DESC, CARDINALITY, PAGES, FILTER_CONDITION, COL_MAX }; /**************************** * replace this with init of some struct (see same func for MiniSQL driver) */ char *aSQLStatistics[] = { "one", "two" }; /****************************/ SQLRETURN SQLStatistics( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, /* MUST BE SUPPLIED */ SQLSMALLINT nTableNameLength, SQLUSMALLINT nTypeOfIndex, SQLUSMALLINT nReserved ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; int nColumn; int nCols; int nRow; COLUMNHDR *pColumnHeader; char szSQL[200]; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long) hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); if ( szTableName == NULL ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No table name" ); return SQL_ERROR; } if ( szTableName[0] == '\0' ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No table name" ); return SQL_ERROR; } /************************** * close any existing result **************************/ if ( hStmt->hStmtExtras->aResults ) _FreeResults( hStmt->hStmtExtras ); if ( hStmt->pszQuery != NULL ) free( hStmt->pszQuery ); hStmt->pszQuery = NULL; /************************** * EXEC QUERY TO GET KEYS **************************/ /************************** * allocate memory for columns headers and result data (row 0 is column header while col 0 is reserved for bookmarks) **************************/ /************************** * gather column header information (save col 0 for bookmarks) **************************/ /************************ * gather data (save col 0 for bookmarks and factor out index columns) ************************/ /************************** * free the snapshot **************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLTablePrivileges.c000066400000000000000000000026351446441710500222640ustar00rootroot00000000000000/******************************************************************** * SQLTablePrivileges * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLTablePrivileges( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************ * REPLACE THIS COMMENT WITH SOMETHING USEFULL ************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR This function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/SQLTables.c000066400000000000000000000052461446441710500204160ustar00rootroot00000000000000/********************************************************************** * SQLTables * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" /**************************** * STANDARD COLUMNS RETURNED BY SQLTables ***************************/ enum nSQLTables { TABLE_CAT = 1, TABLE_SCHEM, TABLE_NAME, TABLE_TYPE, REMARKS, COL_MAX }; /**************************** * COLUMN HEADERS (1st row of result set) ***************************/ /**************************** * replace this with init of some struct (see same func for MiniSQL driver) */ char *aSQLTables[] = { "one", "two" }; /****************************/ SQLRETURN SQLTables( SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength, SQLCHAR *szTableType, SQLSMALLINT nTableTypeLength ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; COLUMNHDR *pColumnHeader; int nColumn; long nResultMemory; /* SANITY CHECKS */ if( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; sprintf((char*) hStmt->szSqlMsg, "hStmt = $%08lX", (long)hStmt ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); /************************** * close any existing result **************************/ if ( hStmt->hStmtExtras->aResults ) _FreeResults( hStmt->hStmtExtras ); if ( hStmt->pszQuery != NULL ) free( hStmt->pszQuery ); hStmt->pszQuery = NULL; /************************ * generate a result set listing tables ************************/ /************************** * allocate memory for columns headers and result data (row 0 is column header while col 0 is reserved for bookmarks) **************************/ /************************** * gather column header information (save col 0 for bookmarks) **************************/ /************************ * gather data (save col 0 for bookmarks) ************************/ /************************** * free the snapshot **************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/SQLTransact.c000066400000000000000000000025651446441710500207640ustar00rootroot00000000000000/******************************************************************** * SQLTransact (deprecated) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * ********************************************************************/ #include #include "driver.h" SQLRETURN SQLTransact( SQLHENV hDrvEnv, SQLHDBC hDrvDbc, UWORD nType) { HDRVENV hEnv = (HDRVENV)hDrvEnv; HDRVDBC hDbc = (HDRVDBC)hDrvDbc; /* SANITY CHECKS */ if ( hDbc == SQL_NULL_HDBC ) return SQL_INVALID_HANDLE; sprintf((char*) hDbc->szSqlMsg, "hDbc = $%08lX", (long)hDbc ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hDbc->szSqlMsg ); switch ( nType ) { case SQL_COMMIT: break; case SQL_ROLLBACK: break; default: sprintf((char*) hDbc->szSqlMsg, "SQL_ERROR Invalid nType=%d", nType ); logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hDbc->szSqlMsg ); return SQL_ERROR; } logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR Function not supported" ); return SQL_ERROR; } unixODBC-2.3.12/Drivers/template/_FreeDbc.c000066400000000000000000000025771446441710500202610ustar00rootroot00000000000000/********************************************************************** * _FreeDbc * **********************************************************************/ #include #include "driver.h" SQLRETURN _FreeDbc( SQLHDBC hDrvDbc ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; HDRVDBC hPrevDbc; SQLRETURN nReturn; if ( hDbc == SQL_NULL_HDBC ) return SQL_ERROR; /* TRY TO FREE STATEMENTS */ /* THIS IS JUST IN CASE; SHOULD NOT BE REQUIRED */ nReturn = _FreeStmtList( hDbc ); if ( nReturn != SQL_SUCCESS ) return nReturn; /* SPECIAL CHECK FOR FIRST IN LIST */ if ( ((HDRVENV)hDbc->hEnv)->hFirstDbc == hDbc ) ((HDRVENV)hDbc->hEnv)->hFirstDbc = hDbc->pNext; /* SPECIAL CHECK FOR LAST IN LIST */ if ( ((HDRVENV)hDbc->hEnv)->hLastDbc == hDbc ) ((HDRVENV)hDbc->hEnv)->hLastDbc = hDbc->pPrev; /* EXTRACT SELF FROM LIST */ if ( hDbc->pPrev != SQL_NULL_HDBC ) hDbc->pPrev->pNext = hDbc->pNext; if ( hDbc->pNext != SQL_NULL_HDBC ) hDbc->pNext->pPrev = hDbc->pPrev; /**********************************************/ /* !!! CODE TO FREE DRIVER SPECIFIC MEMORY (hidden in hStmtExtras) HERE !!! */ if ( hDbc->hDbcExtras ) { free( hDbc->hDbcExtras ); } /**********************************************/ logPushMsg( hDbc->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); logClose( hDbc->hLog ); free( hDbc ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/_FreeDbcList.c000066400000000000000000000013761446441710500211110ustar00rootroot00000000000000/********************************************************************** * _FreeDbcList * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN _FreeDbcList( SQLHENV hDrvEnv ) { HDRVENV hEnv = (HDRVENV)hDrvEnv; if ( hEnv == SQL_NULL_HENV ) return SQL_SUCCESS; while ( _FreeDbc( hEnv->hFirstDbc ) == SQL_SUCCESS ) { } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/_FreeResults.c000066400000000000000000000030461446441710500212220ustar00rootroot00000000000000/********************************************************************** * _FreeResults * **********************************************************************/ #include #include "driver.h" SQLRETURN _FreeResults( HSTMTEXTRAS hStmt ) { COLUMNHDR *pColumnHeader; int nCurColumn; if ( hStmt == NULL ) return SQL_ERROR; if ( hStmt->aResults == NULL ) return SQL_SUCCESS; /* COLUMN HDRS (col=0 is not used) */ for ( nCurColumn = 1; nCurColumn <= hStmt->nCols; nCurColumn++ ) { pColumnHeader = (COLUMNHDR*)(hStmt->aResults)[nCurColumn]; free( pColumnHeader->pszSQL_DESC_BASE_COLUMN_NAME ); free( pColumnHeader->pszSQL_DESC_BASE_TABLE_NAME ); free( pColumnHeader->pszSQL_DESC_CATALOG_NAME ); free( pColumnHeader->pszSQL_DESC_LABEL ); free( pColumnHeader->pszSQL_DESC_LITERAL_PREFIX ); free( pColumnHeader->pszSQL_DESC_LITERAL_SUFFIX ); free( pColumnHeader->pszSQL_DESC_LOCAL_TYPE_NAME ); free( pColumnHeader->pszSQL_DESC_NAME ); free( pColumnHeader->pszSQL_DESC_SCHEMA_NAME ); free( pColumnHeader->pszSQL_DESC_TABLE_NAME ); free( pColumnHeader->pszSQL_DESC_TYPE_NAME ); free( (hStmt->aResults)[nCurColumn] ); } /* RESULT DATA (col=0 is bookmark) */ for ( hStmt->nRow = 1; hStmt->nRow <= hStmt->nRows; hStmt->nRow++ ) { for ( nCurColumn = 1; nCurColumn <= hStmt->nCols; nCurColumn++ ) { free( (hStmt->aResults)[hStmt->nRow*hStmt->nCols+nCurColumn] ); } } free( hStmt->aResults ); hStmt->aResults = NULL; hStmt->nCols = 0; hStmt->nRows = 0; hStmt->nRow = 0; return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/_FreeStmt.c000066400000000000000000000025651446441710500205150ustar00rootroot00000000000000/********************************************************************** * _FreeStmt * **********************************************************************/ #include #include "driver.h" SQLRETURN _FreeStmt( SQLHSTMT hDrvStmt ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; HDRVSTMT hPrevStmt; SQLRETURN nReturn; if ( hStmt == SQL_NULL_HDBC ) return SQL_ERROR; /* SPECIAL CHECK FOR FIRST IN LIST */ if ( ((HDRVDBC)hStmt->hDbc)->hFirstStmt == hStmt ) ((HDRVDBC)hStmt->hDbc)->hFirstStmt = hStmt->pNext; /* SPECIAL CHECK FOR LAST IN LIST */ if ( ((HDRVDBC)hStmt->hDbc)->hLastStmt == hStmt ) ((HDRVDBC)hStmt->hDbc)->hLastStmt = hStmt->pPrev; /* EXTRACT SELF FROM LIST */ if ( hStmt->pPrev != SQL_NULL_HSTMT ) hStmt->pPrev->pNext = hStmt->pNext; if ( hStmt->pNext != SQL_NULL_HSTMT ) hStmt->pNext->pPrev = hStmt->pPrev; /* FREE STANDARD MEMORY */ if( NULL != hStmt->pszQuery ) free( hStmt->pszQuery ); /*********************************************************************/ /* !!! FREE DRIVER SPECIFIC MEMORY (hidden in hStmtExtras) HERE !!! */ _FreeResults( hStmt->hStmtExtras ); free( hStmt->hStmtExtras ); /*********************************************************************/ logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); logClose( hStmt->hLog ); free( hStmt ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/_FreeStmtList.c000066400000000000000000000014731446441710500213460ustar00rootroot00000000000000/********************************************************************** * _FreeStmtList * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "driver.h" SQLRETURN _FreeStmtList( SQLHDBC hDrvDbc ) { HDRVDBC hDbc = (HDRVDBC)hDrvDbc; if ( hDbc == SQL_NULL_HDBC ) return SQL_SUCCESS; if ( hDbc->hFirstStmt == NULL ) return SQL_SUCCESS; while ( _FreeStmt( hDbc->hFirstStmt ) == SQL_SUCCESS ) { } return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/_GetData.c000066400000000000000000000064721446441710500202760ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" SQLRETURN _GetData( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLSMALLINT nTargetType, /* C DATA TYPE */ SQLPOINTER pTarget, SQLLEN nTargetLength, SQLLEN *pnLengthOrIndicator ) { HDRVSTMT hStmt = (HDRVSTMT)hDrvStmt; char *pSourceData = NULL; /* SANITY CHECKS */ if ( hStmt == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; if ( hStmt->hStmtExtras == SQL_NULL_HSTMT ) return SQL_INVALID_HANDLE; if ( hStmt->hStmtExtras->nRows == 0 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No result set." ); return SQL_ERROR; } /********************************************************************** * GET pSourceData FOR NORMAL RESULT SETS **********************************************************************/ if ( hStmt->hStmtExtras->nRow > hStmt->hStmtExtras->nRows || hStmt->hStmtExtras->nRow < 1 ) { logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING, "SQL_ERROR No current row" ); return SQL_ERROR; } pSourceData = (hStmt->hStmtExtras->aResults)[hStmt->hStmtExtras->nRow*hStmt->hStmtExtras->nCols+nCol]; /**************************** * ALL cols are stored as SQL_CHAR... bad for storage... good for code * SO no need to determine the source type when translating to destination ***************************/ if ( pSourceData == NULL ) { /********************* * Now get the col if value = NULL *********************/ if ( pnLengthOrIndicator != NULL ) *pnLengthOrIndicator = SQL_NULL_DATA; switch ( nTargetType ) { case SQL_C_LONG: memset( pTarget, 0, sizeof(int) ); break; case SQL_C_FLOAT: memset( pTarget, 0, sizeof(float) ); break; case SQL_C_CHAR: *((char *)pTarget) = '\0'; break; default: sprintf((char*) hStmt->szSqlMsg, "SQL_ERROR Unknown target type %d", nTargetType ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); } } else { /********************* * Now get the col when we have a value *********************/ switch ( nTargetType ) { case SQL_C_LONG: *((int *)pTarget) = atoi(pSourceData); if ( NULL != pnLengthOrIndicator ) *pnLengthOrIndicator = sizeof( int ); break; case SQL_C_FLOAT: sscanf( pSourceData, "%g", (float*)pTarget ); if ( NULL != pnLengthOrIndicator ) *pnLengthOrIndicator = sizeof( float ); break; case SQL_C_CHAR: strncpy( pTarget, pSourceData, nTargetLength ); if ( NULL != pnLengthOrIndicator ) *pnLengthOrIndicator = strlen(pTarget); break; default: sprintf((char*) hStmt->szSqlMsg, "SQL_ERROR Unknown target type %d", nTargetType ); logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_WARNING, LOG_WARNING,(char*) hStmt->szSqlMsg ); } } logPushMsg( hStmt->hLog, __FILE__, __FILE__, __LINE__, LOG_INFO, LOG_INFO, "SQL_SUCCESS" ); return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/_NativeToSQLColumnHeader.c000066400000000000000000000010301446441710500233460ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" SQLRETURN _NativeToSQLColumnHeader( COLUMNHDR *pColumnHeader, void *pNativeColumnHeader ) { return SQL_SUCCESS; } unixODBC-2.3.12/Drivers/template/_NativeToSQLType.c000066400000000000000000000007551446441710500217360ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" int _NativeToSQLType( void *pNativeColumnHeader ) { return SQL_CHAR; } unixODBC-2.3.12/Drivers/template/_NativeTypeDesc.c000066400000000000000000000007711446441710500216500ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" char *_NativeTypeDesc( char *pszTypeName, int nMySQLType ) { return pszTypeName; } unixODBC-2.3.12/Drivers/template/_NativeTypeLength.c000066400000000000000000000007471446441710500222160ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" int _NativeTypeLength( void *pNativeColumnHeader ) { return 0; } unixODBC-2.3.12/Drivers/template/_NativeTypePrecision.c000066400000000000000000000007521446441710500227240ustar00rootroot00000000000000/************************************************** * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "driver.h" int _NativeTypePrecision( void *pNativeColumnHeader ) { return 0; } unixODBC-2.3.12/Drivers/template/driver.h000066400000000000000000000062411446441710500201200ustar00rootroot00000000000000/********************************************** * Driver.h * * Description: * * This is all of the stuff that is common among ALL drivers (but not to the DriverManager). * * Make sure that your driver specific driverextras.h exists! * * Creating a new driver? It is unlikely that you will need to change this * but take a look at driverextras.h * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************/ #ifndef _H_DRIVER #define _H_DRIVER /***************************************************************************** * ODBC VERSION (THAT THIS DRIVER COMPLIES WITH) *****************************************************************************/ #define ODBCVER 0x0351 #include #include #include #include #include "driverextras.h" #include "prototypes.h" #define SQL_MAX_CURSOR_NAME 100 /***************************************************************************** * STATEMENT *****************************************************************************/ typedef struct tDRVSTMT { struct tDRVSTMT *pPrev; /* prev struct or null */ struct tDRVSTMT *pNext; /* next struct or null */ SQLPOINTER hDbc; /* pointer to DB context */ SQLCHAR szCursorName[SQL_MAX_CURSOR_NAME]; /* name of cursor */ SQLCHAR *pszQuery; /* query string */ SQLCHAR szSqlMsg[LOG_MSG_MAX]; /* buff to format msgs */ HLOG hLog; /* handle to msg logs */ HSTMTEXTRAS hStmtExtras; /* DRIVER SPECIFIC STORAGE */ } DRVSTMT, *HDRVSTMT; /***************************************************************************** * CONNECTION *****************************************************************************/ typedef struct tDRVDBC { struct tDRVDBC *pPrev; /* prev struct or null */ struct tDRVDBC *pNext; /* next struct or null */ SQLPOINTER hEnv; /* pointer to ENV structure */ HDRVSTMT hFirstStmt; /* first in list or null */ HDRVSTMT hLastStmt; /* last in list or null */ SQLCHAR szSqlMsg[LOG_MSG_MAX]; /* buff to format msgs */ HLOG hLog; /* handle to msg logs */ int bConnected; /* TRUE on open connection */ HDBCEXTRAS hDbcExtras; /* DRIVER SPECIFIC DATA */ } DRVDBC, *HDRVDBC; /***************************************************************************** * ENVIRONMENT *****************************************************************************/ typedef struct tDRVENV { HDRVDBC hFirstDbc; /* first in list or null */ HDRVDBC hLastDbc; /* last in list or null */ SQLCHAR szSqlMsg[LOG_MSG_MAX]; /* buff to format msgs */ HLOG hLog; /* handle to msg logs */ HENVEXTRAS hEnvExtras; } DRVENV, *HDRVENV; #endif unixODBC-2.3.12/Drivers/template/driverextras.h000066400000000000000000000171531446441710500213530ustar00rootroot00000000000000/********************************************** * driverextras.h * * Purpose: * * To define driver specifc extras such as structs to be included * along side the common ODBC includes. * * Description: * * The short-term storage a driver requires as infrastructure varies somewhat from * DBMS to DBMS. The ODBC DriverManager requires predictable storage and it is defined * in drivermanager.h. The Driver also requires predictable storage and * it is defined in driver.h. Storage *specific to a type of driver* is defined here. * * The three main storage items are the ENV, DBC, and STMT structs. These are defined * as type void * in isql.h. * * So if your driver requires extra storage (and it probably does) then define * the storage within these structs, allocate/initialize as required. Cast them * to and from the standard names as required. * * For example; * * App DM |DRV * (as per hdbc.h) |(as per driver.h) *==================================================================== * hDbc=void* hDbc=SQLHDBC hDbc=HDBCEXTRAS *-------------------------------------------------------------------- * * DO NOT FORGET TO FREE ANY ALLOCATED MEMORY (at some point) * ********************************************************************** * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #ifndef DRIVEREXTRAS_H #define DRIVEREXTRAS_H /********************************************** * KEEP IT SIMPLE; PUT ALL DRIVER INCLUDES HERE THEN EACH DRIVER MODULE JUST INCLUDES THIS ONE FILE **********************************************/ #include #include #include #include #include /**************************** * include DBMS specific includes here and make any required defines here as well */ /***************************/ /********************************************** * ENVIRONMENT: DRIVER SPECIFIC STUFF THAT NEEDS TO BE STORED IN THE DRIVERS ENVIRONMENT **********************************************/ typedef struct tENVEXTRAS { /**************************** * this is usually left empty ***************************/ int nDummy; } ENVEXTRAS, *HENVEXTRAS; /********************************************** * CONNECTION: DRIVER SPECIFIC STUFF THAT NEEDS TO BE STORED IN THE DRIVERS CONNECTIONS **********************************************/ typedef struct tDBCEXTRAS { /**************************** * replace dummy with your DBMS specific stuff. This often means such things as a socket handle. ***************************/ int nDummy; } DBCEXTRAS, *HDBCEXTRAS; /********************************************** * STATEMENT: DRIVER SPECIFIC STUFF THAT NEEDS TO BE STORED IN THE DRIVERS STATEMENTS **********************************************/ typedef struct tCOLUMNHDR /* each element of the 1st row of results is one of these (except col 0) */ { /* EVERYTHING YOU WOULD EVER WANT TO KNOW ABOUT THE COLUMN. INIT THIS BY CALLING */ /* _NativeToSQLColumnHeader AS SOON AS YOU HAVE COLUMN INFO. THIS MAKES THE COL HDR LARGER */ /* BUT GENERALIZES MORE CODE. see SQLColAttribute() */ int bSQL_DESC_AUTO_UNIQUE_VALUE; /* IS AUTO INCREMENT COL? */ char *pszSQL_DESC_BASE_COLUMN_NAME; /* empty string if N/A */ char *pszSQL_DESC_BASE_TABLE_NAME; /* empty string if N/A */ int bSQL_DESC_CASE_SENSITIVE; /* IS CASE SENSITIVE COLUMN? */ char *pszSQL_DESC_CATALOG_NAME; /* empty string if N/A */ int nSQL_DESC_CONCISE_TYPE; /* ie SQL_CHAR, SQL_TYPE_TIME... */ int nSQL_DESC_DISPLAY_SIZE; /* max digits required to display */ int bSQL_DESC_FIXED_PREC_SCALE; /* has data source specific precision? */ char *pszSQL_DESC_LABEL; /* display label, col name or empty string */ int nSQL_DESC_LENGTH; /* strlen or bin size */ char *pszSQL_DESC_LITERAL_PREFIX; /* empty string if N/A */ char *pszSQL_DESC_LITERAL_SUFFIX; /* empty string if N/A */ char *pszSQL_DESC_LOCAL_TYPE_NAME; /* empty string if N/A */ char *pszSQL_DESC_NAME; /* col alias, col name or empty string */ int nSQL_DESC_NULLABLE; /* SQL_NULLABLE, _NO_NULLS or _UNKNOWN */ int nSQL_DESC_NUM_PREC_RADIX; /* 2, 10, or if N/A... 0 */ int nSQL_DESC_OCTET_LENGTH; /* max size */ int nSQL_DESC_PRECISION; /* */ int nSQL_DESC_SCALE; /* */ char *pszSQL_DESC_SCHEMA_NAME; /* empty string if N/A */ int nSQL_DESC_SEARCHABLE; /* can be in a filter ie SQL_PRED_NONE... */ char *pszSQL_DESC_TABLE_NAME; /* empty string if N/A */ int nSQL_DESC_TYPE; /* SQL data type ie SQL_CHAR, SQL_INTEGER.. */ char *pszSQL_DESC_TYPE_NAME; /* DBMS data type ie VARCHAR, MONEY... */ int nSQL_DESC_UNNAMED; /* qualifier for SQL_DESC_NAME ie SQL_NAMED */ int bSQL_DESC_UNSIGNED; /* if signed FALSE else TRUE */ int nSQL_DESC_UPDATABLE; /* ie SQL_ATTR_READONLY, SQL_ATTR_WRITE... */ /* BINDING INFO */ short nTargetType; /* BIND: C DATA TYPE ie SQL_C_CHAR */ char *pTargetValue; /* BIND: POINTER FROM APPLICATION TO COPY TO*/ long nTargetValueMax; /* BIND: MAX SPACE IN pTargetValue */ long *pnLengthOrIndicator; /* BIND: TO RETURN LENGTH OR NULL INDICATOR */ } COLUMNHDR; typedef struct tSTMTEXTRAS { char **aResults; /* nRows x nCols OF CHAR POINTERS. Row 0= ptrs to COLUMNHDR. Col 0=Bookmarks */ int nCols; /* # OF VALID COLUMNS IN aColumns */ int nRows; /* # OF ROWS IN aResults */ int nRow; /* CURRENT ROW */ } STMTEXTRAS, *HSTMTEXTRAS; /* * Shadow functions * * There are times when a function needs to call another function to use common functionality. When the * called function is part of the ODBC API (an entry point to the driver) bad things can happen. The * linker will get confused and call the same-named function elsewhere in the namespace (ie the Driver * Manager). To get around this you create a shadow function - a function with a slightly different name * that will not be confused with others - and then put most if not all of the functionality in there for * common use. * */ SQLRETURN SQLGetDiagRec_( SQLSMALLINT nHandleType, SQLHANDLE hHandle, SQLSMALLINT nRecordNumber, SQLCHAR * pszState, SQLINTEGER * pnNativeError, SQLCHAR * pszMessageText, SQLSMALLINT nBufferLength, SQLSMALLINT * pnStringLength ); SQLRETURN _GetData( SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLSMALLINT nTargetType, SQLPOINTER pTarget, SQLLEN nTargetLength, SQLLEN *pnLengthOrIndicator ); /* * Internal Support Functions */ SQLRETURN _NativeToSQLColumnHeader( COLUMNHDR *pColumnHeader, void *pNativeColumnHeader ); int _NativeToSQLType( void *pNativeColumnHeader ); char *_NativeTypeDesc( char *pszTypeName, int nType ); int _NativeTypeLength( void *pNativeColumnHeader ); int _NativeTypePrecision( void *pNativeColumnHeader ); SQLRETURN template_SQLPrepare( SQLHSTMT hDrvStmt, SQLCHAR *szSqlStr, SQLINTEGER nSqlStrLength ); #endif unixODBC-2.3.12/Drivers/template/prototypes.h000066400000000000000000000310061446441710500210520ustar00rootroot00000000000000/* _FreeDbc.c */ SQLRETURN _FreeDbc(SQLHDBC hDrvDbc); /* _FreeDbcList.c */ SQLRETURN _FreeDbcList(SQLHENV hDrvEnv); /* _FreeResults.c */ SQLRETURN _FreeResults(HSTMTEXTRAS hStmt); /* _FreeStmt.c */ SQLRETURN _FreeStmt(SQLHSTMT hDrvStmt); /* _FreeStmtList.c */ SQLRETURN _FreeStmtList(SQLHDBC hDrvDbc); /* _GetData.c */ SQLRETURN _GetData(SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLSMALLINT nTargetType, SQLPOINTER pTarget, SQLLEN nTargetLength, SQLLEN *pnLengthOrIndicator); /* _NativeToSQLColumnHeader.c */ SQLRETURN _NativeToSQLColumnHeader(COLUMNHDR *pColumnHeader, void *pNativeColumnHeader); /* _NativeToSQLType.c */ int _NativeToSQLType(void *pNativeColumnHeader); /* _NativeTypeDesc.c */ char *_NativeTypeDesc(char *pszTypeName, int nMySQLType); /* _NativeTypeLength.c */ int _NativeTypeLength(void *pNativeColumnHeader); /* _NativeTypePrecision.c */ int _NativeTypePrecision(void *pNativeColumnHeader); /* SQLAllocConnect.c */ SQLRETURN _AllocConnect(SQLHENV hDrvEnv, SQLHDBC *phDrvDbc); SQLRETURN SQLAllocConnect(SQLHENV hDrvEnv, SQLHDBC *phDrvDbc); /* SQLAllocEnv.c */ SQLRETURN _AllocEnv(SQLHENV *phDrvEnv); SQLRETURN SQLAllocEnv(SQLHENV *phDrvEnv); /* SQLAllocHandle.c */ SQLRETURN SQLAllocHandle(SQLSMALLINT nHandleType, SQLHANDLE nInputHandle, SQLHANDLE *pnOutputHandle); /* SQLAllocStmt.c */ SQLRETURN _AllocStmt(SQLHDBC hDrvDbc, SQLHSTMT *phDrvStmt); SQLRETURN SQLAllocStmt(SQLHDBC hDrvDbc, SQLHSTMT *phDrvStmt); /* SQLBindCol.c */ SQLRETURN SQLBindCol(SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLSMALLINT nTargetType, SQLPOINTER pTargetValue, SQLLEN nTargetValueMax, SQLLEN *pnLengthOrIndicator); /* SQLBindParameter.c */ SQLRETURN SQLBindParameter(SQLHSTMT hDrvStmt, SQLUSMALLINT nParameterNumber, SQLSMALLINT nIOType, SQLSMALLINT nBufferType, SQLSMALLINT nParamType, SQLULEN nParamLength, SQLSMALLINT nScale, SQLPOINTER pData, SQLLEN nBufferLength, SQLLEN *pnLengthOrIndicator); /* SQLBrowseConnect.c */ SQLRETURN SQLBrowseConnect(SQLHDBC hDrvDbc, SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut); /* SQLBulkOperations.c */ SQLRETURN SQLBulkOperations(SQLHSTMT hDrvStmt, SQLSMALLINT nOperation); /* SQLCancel.c */ SQLRETURN SQLCancel(SQLHSTMT hDrvStmt); /* SQLCloseCursor.c */ SQLRETURN SQLCloseCursor(SQLHSTMT hDrvStmt); /* SQLColAttribute.c */ SQLRETURN SQLColAttribute(SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLUSMALLINT nFieldIdentifier, SQLPOINTER pszValue, SQLSMALLINT nValueLengthMax, SQLSMALLINT *pnValueLength, SQLLEN *pnValue); /* SQLColAttributes.c */ SQLRETURN SQLColAttributes(SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLUSMALLINT nDescType, SQLPOINTER pszDesc, SQLSMALLINT nDescMax, SQLSMALLINT *pcbDesc, SQLLEN *pfDesc); /* SQLColumnPrivileges.c */ SQLRETURN SQLColumnPrivileges(SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength, SQLCHAR *szColumnName, SQLSMALLINT nColumnNameLength); /* SQLColumns.c */ SQLRETURN SQLColumns(SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength, SQLCHAR *szColumnName, SQLSMALLINT nColumnNameLength); /* SQLConnect.c */ SQLRETURN SQLConnect(SQLHDBC hDrvDbc, SQLCHAR *szDataSource, SQLSMALLINT nDataSourceLength, SQLCHAR *szUID, SQLSMALLINT nUIDLength, SQLCHAR *szPWD, SQLSMALLINT nPWDLength); /* SQLCopyDesc.c */ SQLRETURN SQLCopyDesc(SQLHDESC hSourceDescHandle, SQLHDESC hTargetDescHandle); /* SQLDescribeCol.c */ SQLRETURN SQLDescribeCol(SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLCHAR *szColName, SQLSMALLINT nColNameMax, SQLSMALLINT *pnColNameLength, SQLSMALLINT *pnSQLDataType, SQLULEN *pnColSize, SQLSMALLINT *pnDecDigits, SQLSMALLINT *pnNullable); /* SQLDescribeParam.c */ SQLRETURN SQLDescribeParam(SQLHSTMT hDrvStmt, SQLUSMALLINT nParmNumber, SQLSMALLINT *pnDataType, SQLULEN *pnSize, SQLSMALLINT *pnDecDigits, SQLSMALLINT *pnNullable); /* SQLDisconnect.c */ SQLRETURN SQLDisconnect(SQLHDBC hDrvDbc); /* SQLDriverConnect.c */ SQLRETURN SQLDriverConnect(SQLHDBC hDrvDbc, SQLHWND hWnd, SQLCHAR *szConnStrIn, SQLSMALLINT nConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pnConnStrOut, SQLUSMALLINT nDriverCompletion); /* SQLEndTran.c */ SQLRETURN SQLEndTran(SQLSMALLINT nHandleType, SQLHANDLE nHandle, SQLSMALLINT nCompletionType); /* SQLError.c */ SQLRETURN SQLError(SQLHENV hDrvEnv, SQLHDBC hDrvDbc, SQLHSTMT hDrvStmt, SQLCHAR *szSqlState, SQLINTEGER *pfNativeError, SQLCHAR *szErrorMsg, SQLSMALLINT nErrorMsgMax, SQLSMALLINT *pcbErrorMsg); /* SQLExecDirect.c */ SQLRETURN SQLExecDirect(SQLHSTMT hDrvStmt, SQLCHAR *szSqlStr, SQLINTEGER nSqlStr); /* SQLExecute.c */ SQLRETURN SQLExecute(SQLHSTMT hDrvStmt); /* SQLExtendedFetch.c */ SQLRETURN SQLExtendedFetch(SQLHSTMT hDrvStmt, SQLUSMALLINT nOrientation, SQLLEN nOffset, SQLULEN *pnRowCount, SQLUSMALLINT *pRowStatusArray); /* SQLFetch.c */ SQLRETURN SQLFetch(SQLHSTMT hDrvStmt); /* SQLFetchScroll.c */ SQLRETURN SQLFetchScroll(SQLHSTMT hDrvStmt, SQLSMALLINT nOrientation, SQLLEN nOffset); /* SQLForeignKeys.c */ SQLRETURN SQLForeignKeys(SQLHSTMT hDrvStmt, SQLCHAR *szPKCatalogName, SQLSMALLINT nPKCatalogNameLength, SQLCHAR *szPKSchemaName, SQLSMALLINT nPKSchemaNameLength, SQLCHAR *szPKTableName, SQLSMALLINT nPKTableNameLength, SQLCHAR *szFKCatalogName, SQLSMALLINT nFKCatalogNameLength, SQLCHAR *szFKSchemaName, SQLSMALLINT nFKSchemaNameLength, SQLCHAR *szFKTableName, SQLSMALLINT nFKTableNameLength); /* SQLFreeConnect.c */ SQLRETURN _FreeConnect(SQLHDBC hDrvDbc); SQLRETURN SQLFreeConnect(SQLHDBC hDrvDbc); /* SQLFreeEnv.c */ SQLRETURN _FreeEnv(SQLHENV hDrvEnv); SQLRETURN SQLFreeEnv(SQLHENV hDrvEnv); /* SQLFreeHandle.c */ SQLRETURN SQLFreeHandle(SQLSMALLINT nHandleType, SQLHANDLE nHandle); /* SQLFreeStmt.c */ SQLRETURN SQLFreeStmt(SQLHSTMT hDrvStmt, SQLUSMALLINT nOption); /* SQLGetConnectAttr.c */ SQLRETURN SQLGetConnectAttr(SQLHDBC hDrvDbc, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength); /* SQLGetConnectOption.c */ SQLRETURN SQLGetConnectOption(SQLHDBC hDrvDbc, UWORD fOption, PTR pvParam); /* SQLGetCursorName.c */ SQLRETURN SQLGetCursorName(SQLHSTMT hDrvStmt, SQLCHAR *szCursor, SQLSMALLINT nCursorMaxLength, SQLSMALLINT *pnCursorLength); /* SQLGetData.c */ SQLRETURN SQLGetData(SQLHSTMT hDrvStmt, SQLUSMALLINT nCol, SQLSMALLINT nTargetType, SQLPOINTER pTarget, SQLLEN nTargetLength, SQLLEN *pnLengthOrIndicator); /* SQLGetDescField.c */ SQLRETURN SQLGetDescField(SQLHDESC DescriptorHandle, SQLSMALLINT RecordNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength); /* SQLGetDescRec.c */ SQLRETURN SQLGetDescRec(SQLHDESC DescriptorHandle, SQLSMALLINT RecordNumber, SQLCHAR *Name, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, SQLSMALLINT *Type, SQLSMALLINT *SubType, SQLLEN *Length, SQLSMALLINT *Precision, SQLSMALLINT *Scale, SQLSMALLINT *Nullable); /* SQLGetDiagField.c */ SQLRETURN SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecordNumber, SQLSMALLINT DiagIdentifier, SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength); /* SQLGetDiagRec.c */ SQLRETURN SQLGetDiagRec_(SQLSMALLINT nHandleType, SQLHANDLE hHandle, SQLSMALLINT nRecordNumber, SQLCHAR *pszState, SQLINTEGER *pnNativeError, SQLCHAR *pszMessageText, SQLSMALLINT nBufferLength, SQLSMALLINT *pnStringLength); SQLRETURN SQLGetDiagRec(SQLSMALLINT nHandleType, SQLHANDLE hHandle, SQLSMALLINT nRecordNumber, SQLCHAR *pszState, SQLINTEGER *pnNativeError, SQLCHAR *pszMessageText, SQLSMALLINT nBufferLength, SQLSMALLINT *pnStringLength); /* SQLGetEnvAttr.c */ SQLRETURN SQLGetEnvAttr(SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength); /* SQLGetInfo.c */ SQLRETURN SQLGetInfo(SQLHDBC hDbc, SQLUSMALLINT nInfoType, SQLPOINTER pInfoValue, SQLSMALLINT nInfoValueMax, SQLSMALLINT *pnLength); /* SQLGetStmtAttr.c */ SQLRETURN SQLGetStmtAttr(SQLHSTMT hDrvStmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength); /* SQLGetStmtOption.c */ SQLRETURN SQLGetStmtOption(SQLHSTMT hDrvStmt, UWORD fOption, PTR pvParam); /* SQLGetTypeInfo.c */ SQLRETURN SQLGetTypeInfo(SQLHSTMT hDrvStmt, SQLSMALLINT nSqlType); /* SQLMoreResults.c */ SQLRETURN SQLMoreResults(SQLHSTMT hDrvStmt); /* SQLNativeSql.c */ SQLRETURN SQLNativeSql(SQLHSTMT hDrvStmt, SQLCHAR *szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLCHAR *szSqlStr, SQLINTEGER cbSqlStrMax, SQLINTEGER *pcbSqlStr); /* SQLNumParams.c */ SQLRETURN SQLNumParams(SQLHSTMT hDrvStmt, SQLSMALLINT *pnParamCount); /* SQLNumResultCols.c */ SQLRETURN SQLNumResultCols(SQLHSTMT hDrvStmt, SQLSMALLINT *pnColumnCount); /* SQLParamData.c */ SQLRETURN SQLParamData(SQLHSTMT hDrvStmt, SQLPOINTER *pValue); /* SQLParamOptions.c */ SQLRETURN SQLParamOptions(SQLHSTMT hDrvStmt, SQLULEN nRow, SQLULEN *pnRow); /* SQLPrepare.c */ SQLRETURN SQLPrepare(SQLHSTMT hDrvStmt, SQLCHAR *szSqlStr, SQLINTEGER nSqlStrLength); SQLRETURN template_SQLPrepare(SQLHSTMT hDrvStmt, SQLCHAR *szSqlStr, SQLINTEGER nSqlStrLength); /* SQLPrimaryKeys.c */ SQLRETURN SQLPrimaryKeys(SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength); /* SQLProcedureColumns.c */ SQLRETURN SQLProcedureColumns(SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szProcName, SQLSMALLINT nProcNameLength, SQLCHAR *szColumnName, SQLSMALLINT nColumnNameLength); /* SQLProcedures.c */ SQLRETURN SQLProcedures(SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szProcName, SQLSMALLINT nProcNameLength); /* SQLPutData.c */ SQLRETURN SQLPutData(SQLHSTMT hDrvStmt, SQLPOINTER pData, SQLLEN nLengthOrIndicator); /* SQLRowCount.c */ SQLRETURN SQLRowCount(SQLHSTMT hDrvStmt, SQLLEN *pnRowCount); /* SQLSetConnectOption.c */ SQLRETURN SQLSetConnectOption(SQLHDBC hDrvDbc, UWORD nOption, SQLULEN vParam); /* SQLSetCursorName.c */ SQLRETURN SQLSetCursorName(SQLHSTMT hDrvStmt, SQLCHAR *szCursor, SQLSMALLINT nCursorLength); /* SQLSetDescField.c */ SQLRETURN SQLSetDescField(SQLHDESC DescriptorHandle, SQLSMALLINT RecordNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength); /* SQLSetDescRec.c */ SQLRETURN SQLSetDescRec(SQLHDESC hDescriptorHandle, SQLSMALLINT nRecordNumber, SQLSMALLINT nType, SQLSMALLINT nSubType, SQLLEN nLength, SQLSMALLINT nPrecision, SQLSMALLINT nScale, SQLPOINTER pData, SQLLEN *pnStringLength, SQLLEN *pnIndicator); /* SQLSetEnvAttr.c */ SQLRETURN SQLSetEnvAttr(SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength); /* SQLSetParam.c */ SQLRETURN SQLSetParam(SQLHSTMT hDrvStmt, SQLUSMALLINT nPar, SQLSMALLINT nType, SQLSMALLINT nSqlType, SQLULEN nColDef, SQLSMALLINT nScale, SQLPOINTER pValue, SQLLEN *pnValue); /* SQLSetPos.c */ SQLRETURN SQLSetPos(SQLHSTMT hDrvStmt, SQLSETPOSIROW nRow, SQLUSMALLINT nOperation, SQLUSMALLINT nLockType); /* SQLSetScrollOptions.c */ SQLRETURN SQLSetScrollOptions(SQLHSTMT hDrvStmt, SQLUSMALLINT fConcurrency, SQLLEN crowKeyset, SQLUSMALLINT crowRowset); /* SQLSetStmtAttr.c */ SQLRETURN SQLSetStmtAttr(SQLHSTMT hDrvStmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength); /* SQLSetStmtOption.c */ SQLRETURN SQLSetStmtOption(SQLHSTMT hDrvStmt, UWORD fOption, SQLULEN vParam); /* SQLSpecialColumns.c */ SQLRETURN SQLSpecialColumns(SQLHSTMT hDrvStmt, UWORD nColumnType, UCHAR *szCatalogName, SWORD nCatalogNameLength, UCHAR *szSchemaName, SWORD nSchemaNameLength, UCHAR *szTableName, SWORD nTableNameLength, UWORD nScope, UWORD nNullable); /* SQLStatistics.c */ SQLRETURN SQLStatistics(SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength, SQLUSMALLINT nTypeOfIndex, SQLUSMALLINT nReserved); /* SQLTablePrivileges.c */ SQLRETURN SQLTablePrivileges(SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength); /* SQLTables.c */ SQLRETURN SQLTables(SQLHSTMT hDrvStmt, SQLCHAR *szCatalogName, SQLSMALLINT nCatalogNameLength, SQLCHAR *szSchemaName, SQLSMALLINT nSchemaNameLength, SQLCHAR *szTableName, SQLSMALLINT nTableNameLength, SQLCHAR *szTableType, SQLSMALLINT nTableTypeLength); /* SQLTransact.c */ SQLRETURN SQLTransact(SQLHENV hDrvEnv, SQLHDBC hDrvDbc, UWORD nType); unixODBC-2.3.12/Interix/000077500000000000000000000000001446441710500146425ustar00rootroot00000000000000unixODBC-2.3.12/Interix/config.guess000066400000000000000000001135501446441710500171640ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 # Free Software Foundation, Inc. timestamp='2001-09-04' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Written by Per Bothner . # Please send patches to . # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi dummy=dummy-$$ trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int dummy(){}" > $dummy.c ; for c in cc gcc c89 ; do ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; if test $? = 0 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; rm -f $dummy.c $dummy.o $dummy.rel ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # Netbsd (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # Determine the machine/vendor (is the vendor relevant). case "${UNAME_MACHINE}" in amiga) machine=m68k-unknown ;; arm32) machine=arm-unknown ;; atari*) machine=m68k-atari ;; sun3*) machine=m68k-sun ;; mac68k) machine=m68k-apple ;; macppc) machine=powerpc-apple ;; hp3[0-9][05]) machine=m68k-hp ;; ibmrt|romp-ibm) machine=romp-ibm ;; *) machine=${UNAME_MACHINE}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE}" in i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit 0 ;; alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` fi # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. cat <$dummy.s .data \$Lformat: .byte 37,100,45,37,120,10,0 # "%d-%x\n" .text .globl main .align 4 .ent main main: .frame \$30,16,\$26,0 ldgp \$29,0(\$27) .prologue 1 .long 0x47e03d80 # implver \$0 lda \$2,-1 .long 0x47e20c21 # amask \$2,\$1 lda \$16,\$Lformat mov \$0,\$17 not \$1,\$18 jsr \$26,printf ldgp \$29,0(\$26) mov 0,\$16 jsr \$26,exit .end main EOF eval $set_cc_for_build $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null if test "$?" = 0 ; then case `./$dummy` in 0-0) UNAME_MACHINE="alpha" ;; 1-0) UNAME_MACHINE="alphaev5" ;; 1-1) UNAME_MACHINE="alphaev56" ;; 1-101) UNAME_MACHINE="alphapca56" ;; 2-303) UNAME_MACHINE="alphaev6" ;; 2-307) UNAME_MACHINE="alphaev67" ;; 2-1307) UNAME_MACHINE="alphaev68" ;; esac fi rm -f $dummy.s $dummy echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit 0;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; arc64:OpenBSD:*:*) echo mips64el-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hkmips:OpenBSD:*:*) echo mips-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pmax:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mips-unknown-openbsd${UNAME_RELEASE} exit 0 ;; wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:OS/390:*:*) echo i370-ibm-openedition exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; sparc*:NetBSD:*) echo `uname -p`-unknown-netbsd${UNAME_RELEASE} exit 0 ;; atari*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit 0 ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit 0 ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; sun3*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD $dummy.c -o $dummy \ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && rm -f $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit 0 ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) case "${HPUX_REV}" in 11.[0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; esac ;; esac fi ;; esac if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi rm -f $dummy.c $dummy fi ;; esac echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; hppa*:OpenBSD:*:*) echo hppa-unknown-openbsd exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*X-MP:*:*:*) echo xmp-cray-unicos exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3D:*:*:*) echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos exit 0 ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit 0 ;; x*:Interix*:*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i386-pc-interix exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i386-pc-interix exit 0 ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit 0 ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux exit 0 ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; mips:Linux:*:*) case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in big) echo mips-unknown-linux-gnu && exit 0 ;; little) echo mipsel-unknown-linux-gnu && exit 0 ;; esac ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit 0 ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit 0 ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit 0 ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit 0 ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit 0 ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit 0 ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit 0 ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. ld_supported_targets=`cd /; ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit 0 ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit 0 ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit 0 ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build cat >$dummy.c < #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 printf ("%s-pc-linux-gnu\n", argv[1]); # else printf ("%s-pc-linux-gnulibc1\n", argv[1]); # endif # else printf ("%s-pc-linux-gnulibc1\n", argv[1]); # endif #else printf ("%s-pc-linux-gnuaout\n", argv[1]); #endif return 0; } EOF $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit 0 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit 0 ;; i*86:*:5:[78]*) case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit 0 ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit 0 ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) echo `uname -p`-apple-darwin${UNAME_RELEASE} exit 0 ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) if test "${UNAME_MACHINE}" = "x86pc"; then UNAME_MACHINE=pc fi echo `uname -p`-${UNAME_MACHINE}-nto-qnx exit 0 ;; *:QNX:*:4*) echo i386-pc-qnx exit 0 ;; NSR-[KW]:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit 0 ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit 0 ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit 0 ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit 0 ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit 0 ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit 0 ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit 0 ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit 0 ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit 0 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit 0 ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit 0 ;; *:ITS:*:*) echo pdp10-unknown-its exit 0 ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit 0 ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 rm -f $dummy.c $dummy # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: unixODBC-2.3.12/LICENSE000066400000000000000000000635351446441710500142410ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 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. (This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.) Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, 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 and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, 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 library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library. 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 Library or any portion of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, 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 Library, 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 Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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. If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be 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. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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. 9. 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 Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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 with this License. 11. 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 Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library. 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. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser 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 Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. {description} Copyright (C) {year} {fullname} This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. {signature of Ty Coon}, 1 April 1990 Ty Coon, President of Vice That's all there is to it! unixODBC-2.3.12/Makefile.am000066400000000000000000000016121446441710500152540ustar00rootroot00000000000000ACLOCAL_AMFLAGS=-I m4 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = \ cur/odbccr.pc \ DriverManager/odbc.pc \ odbcinst/odbcinst.pc SUBDIRS = \ extras \ log \ lst \ ini \ libltdl \ odbcinst \ DriverManager \ exe \ cur \ DRVConfig \ Drivers \ include \ doc \ man \ samples EXTRA_DIST = \ README.OSX \ README.VMS \ README.QNX \ README.CYGWIN \ README.AIX \ README.SOLARIS \ README.INTERIX \ vms/install_image.com \ vms/odbc2_axp.opt \ vms/odbc_axp.opt \ vms/odbcinst_axp.opt \ vms/odbc_setup.com \ vms/drivermanager_axp.opt \ vmsbuild.com \ Interix/configure \ Interix/config.guess \ Interix/libtool \ m4 \ configure.ac \ Makefile.svn include_HEADERS = unixodbc.h pkginclude_HEADERS = unixodbc_conf.h install-data-hook: -$(MKDIR_P) $(DESTDIR)$(sysconfdir)/ODBCDataSources -touch $(DESTDIR)$(sysconfdir)/odbcinst.ini -touch $(DESTDIR)$(sysconfdir)/odbc.ini unixODBC-2.3.12/Makefile.svn000066400000000000000000000010671446441710500154710ustar00rootroot00000000000000svn: @echo "*** Retrieving configure tests needed by configure.in" @libtoolize --copy --ltdl --force @aclocal -I m4 @echo "*** Building Makefile templates (step one)" @automake --add-missing @automake @echo "*** Building config.h" @autoheader @sed -i '/UNIXODBC_SOURCE/d' unixodbc_conf.h.in @sed -i '/ VERSION/d' unixodbc_conf.h.in @sed -i '/ PACKAGE/d' unixodbc_conf.h.in @echo "*** Building configure" @autoconf @echo "*** Finished" @echo " Don't forget to run ./configure" @echo " If you haven't done so in a while, run ./configure --help" unixODBC-2.3.12/NEWS000066400000000000000000000020651446441710500137220ustar00rootroot00000000000000Release History =============== NOTE: I have moved what was here into ChangeLog, it seemed to make more sense that way (NG). Release 2.2.10 29-Sep-2004 Release 2.2.9 24-Jan-2004 Release 2.2.8 17-Feb-2004 Release 2.2.7 02-Dec-2003 Release 2.2.6 21-July-2003 Release 2.2.5 26-Feb-2003 Release 2.2.4 24-January-2003 Release 2.2.3 23-August-2002 Release 2.2.2 8-July-2002 Release 2.2.1 23-Mar-2002 Release 2.2.0 30-Jan-2002 Release 2.1.1 2001-12-21 Release 2.1.0 2001-11-27 Release 2.0.10 2001-10-14 Release 2.0.9 2001-08-14 Release 2.0.8 2001-06-25 Release 2.0.7 2001-06-06 Release 2.0.6 2001-04-18 Release 2.0.5 2001-03-21 Release 2.0.4 2001-02-02 Release 2.0.3 2001-01-13 Release 2.0.2 2001-01-08 Release 2.0.1 2001-01-06 Release 2.0.0 2001-01-04 Release 1.8.13 2000-11-14 Release 1.8.12 2000-08-18 Release 1.8.11 2000-08-16 Release 1.8.10 2000-06-15 Release 1.8.9 2000-06-13 Release 1.8.8 2000-05-03 Release 1.8.6 2000-02-21 Release 1.8.4 2000-02-12 Release 1.8.3 1999-12-28 Release 1.8.2 1999-12-11 Release 1.8.1 1999-11-17 Release 1.8 1999-11-13 Release 1.7 1999-07-26 unixODBC-2.3.12/README000066400000000000000000000026221446441710500141020ustar00rootroot00000000000000+-------------------------------------------------------------+ | unixODBC | +-------------------------------------------------------------+ README --------------------------------------------------------------- Description: unixODBC is an Open Source ODBC sub-system and an ODBC SDK for Linux, Mac OSX, and UNIX. License: All libraries are LGPL Version 2.1 All programs are GPL Version 2.0. Parts: unixODBC includes the following; - Driver Manager - Installer Library and command line tool - Command Line Tools to help install a driver and work with SQL How To Start: Look for and read README files with extensions of interest. Then read the INSTALL file. You can also jump into the doc directory and browse information there. And do not forget the online stuff. Some documentation may be a bit out of date the vast majority of it should be ok. Config Files: The ODBC Installer Library is responsible for reading and writing the unixODBC config files. The savvy can look at; _odbcinst_SystemINI.c _odbcinst_UserINI.c In any case; you can override where unixODBC looks for its system config files by setting the ODBCSYSINI environment variable during the use of unixODBC. Resources: http://sourceforge.net/projects/unixodbc/ https://github.com/lurcher/unixODBC/ http://www.unixodbc.org/ unixODBC-2.3.12/README.AIX000066400000000000000000000052021446441710500145170ustar00rootroot00000000000000Building on AIX =============== Install ======= AIX seems to ship with a install tool /usr/bin/bsdinstall, unfortunately the version of autoconf that unixODBC uses doesn't seem to like this, so make sure it doesn't find this. It may be best to define INSTALL as a empty string before building, forcing it to use the builtin install-sh. Threads ======= You need to decide to build with or without threads, if you want threads I would do this export CC=xlc_r export CXX=xlC_r ./configure If you don't want threads, do this export CC=xlc export CXX=xlC ./configure --enable-threads=no Shared Libs =========== Because of the way that AIX builds its shared libs there are a couple of points to remember 1. All drivers need changing into .so The drivers will be build as a .a, containing a .so, BUT dlopen only is able to open a .so, so to fix this, for each driver that is needed, do the following (in this case the postgres driver). Go to the target lib directory cd /usr/local/lib extract the .so from the .a ar -x libodbcpsql.a This will create libodbcpsql.so.2 The same will need doing for the seyup libs ar -x libodbcpsqlS.a 2. Shared libs containing C++ are special This is only a issue with the libodbcinstQ.a lib that is opened by ODBCConfig. There are two things, first because libtool decides that shared libs ar lib*.a the code tries to load libodbcinstQ.a, and also we maye have to rebuild the lib using the IBM util makeC++SharedLib (the name gives its away :-) I have tried this with a current AIX, and it seems that all is needed is to extract the .so from the .a by running ar -x libodbcinstQ.a to get the .so If that doesn't help, or on older AIX's the following may need doing. After the make install is done, go into the odbcinstQ dir on thE build tree, and do the following makeC++SharedLib -p 0 -o libodbcinstQ.so.1.0 -L$QTDIR/lib -lqt -L$PREFIX/lib -lodbc -lodbcinst .libs/libodbcinstQ.lax/libodbcextraslc.al/strcasecmp.o *.o ../ini/*.lo where QTDIR is set to the top of the qt tree, so $QTDIR/lib will contain libqt.a and PREFIX is set to the unixODBC install tree, so $PREFIX/lib contains libodbc.a. Ignore any duplicate symbol warnings they are due to the same things being in libodbc.a and libodbcinst.a this will then build a libodbcinstQ.so.1.0, we can copy that to the target lib dir, and delete the existing lib, and link it (again replace $PREFIX with the correct path cp libodbcinstQ.so.1.0 $PREFIX/lib cd $PREFIX/lib rm libodbcinstQ.a ln -s libodbcinstQ.so.1.0 libodbcinstQ.a Then all should be OK with ODBCConfig Nick Gorham unixODBC-2.3.12/README.CYGWIN000066400000000000000000000010411446441710500150730ustar00rootroot00000000000000To build unixODBC on cygwin, all you need to do is to rerun the autoconf tools to create versions that seem to play on windows, then build as normal. Of course to do this you need to have installed the Cygwin development packages. So: aclocal automake --add-missing automake autoconf libtoolize --copy --ltdl --force Then you can run configure as normal ./configure --enable-gui=no make make install At least that seems to work when I tried it... If you find problems just let me know. -- Nick Gorham (nick.gorham@easysoft.com) unixODBC-2.3.12/README.INTERIX000066400000000000000000000010001446441710500152100ustar00rootroot00000000000000Some notes on building UnixODBC on Microsoft Interix First use the modified configure and config.guess included in the Interix directory, copy them up into the main directory. Then build with the following line CFLAGS="-D_ALL_SOURCE -I/usr/local/include" CPPFLAGS="-D_ALL_SOURCE -I/usr/local/include" LDFLAGS="-L/usr/local/lib" ./configure After running configure, copy libtool from the Interix directory into the build directory Thanks to the MS group for supplying this info. Thats all for now. Nick. unixODBC-2.3.12/README.OSX000066400000000000000000000105601446441710500145520ustar00rootroot00000000000000+-------------------------------------------------------------+ | unixODBC | | Mac OSX | +-------------------------------------------------------------+ README --------------------------------------------------------------- It seems at least with 10.5 of OSX, that we can just configure as normal (--enable-gui=no) and build, no special instructions are needed. --------------------------------------------------------------- Building With GNU Auto Tools (by Nick): It looks as if Darwin (Mac OSX) doesn't support the normal dlopen type process that unixODBC requires. However help is at hand in the form of dlcompat-20010831.tar.gz. This file contains wrappers to emulate the calls. I have put this in ftp://ftp.unixodbc.org/pub/beta/unixODBC/dlcompat-20010831.tar.gz It should be downloaded, unpacked then run make install This should be done before configuring unixODBC This file was created by Christoph Pfisterer and the original copy can be found at http://fink.sourceforge.net If you get a "ld: multiple definitions of symbol " error, then you should edit the file libtool in the unixODBC base directory and find the line whole_archive_flag_spec="-all_load \$convenience" and replace it with whole_archive_flag_spec= As at the time of writing, Qt is not available on OSX, its best to disable the search for X libs that may fail, by configuring with ./configure --enable-gui=no Problems: There is a problem it seems with libtool on OSX that incorrectly sets the SHLIBEXT. The Driver Manager code will now report this if its used in this condition. There are two solutions. Either after running configure check config.h, and search for the string SHLIBEXT. It should look like this: #define SHLIBEXT ".dylib" But may look like this: #define SHLIBEXT "test .$module = .yes && echo .so || echo .dylib" If it does, then change it to the first definition. The other fix is to change the configure script to find the correct value, search for the line: shrext_cmds='test .$module = .yes && echo .so || echo .dylib' And change to shrext_cmds=`test .$module = .yes && echo .so || echo .dylib` Then rerun configure It also seems that Makefile.,svn needs some help, this thread seems to cover it and solutions. https://stackoverflow.com/questions/15448582/installed-libtool-but-libtoolize-not-found/15448876 Building With Qt qmake (by Peter): Qt is now available for OSX but unixODBC may not detect your Qt libs... worse yet you may not be able sort out the GNU auto-tools required to build on OSX. If you want to build using qmake then read README.qmake. Creating Install Packages: unixODBC contains a number of directories and files to help create OSX Packages. The process of doing so is not nearly as automated as creating RPM files using the GNU auto tools. Look for the mac-install and mac-package directories. Cursor LIB The cursor lilb needs a manual stage build to create it as a OSX bundle it needs to be like that so the DM can load it at run time. To do this, after the "make" and "make install" have finished, go to the cur directory in the build tree. Then there issue these commands cc -bundle -flat_namespace -undefined suppress -o libodbccr.1.0.0.so *.lo cp libodbccr.1.0.0.so /usr/local/lib/libodbccr.1 Replace /usr/local/lib/ in the above with whatever your actual unixODBC lib path is. You may also have to do the same with any driver you build. You can check this by testing the type of the lib, for example. file /usr/local/lib/libodbcpsql.2.0.0.so /usr/local/lib/libodbcpsql.2.0.0.so: Mach-O dynamically linked shared library ppc This is not the correct type. So to get it as you need :- cd Drivers/Postgre7.1 cc -bundle -flat_namespace -undefined suppress -o libodbcpsql.2.0.0.so *.lo cp libodbcpsql.2.0.0.so /usr/local/lib/libodbcpsql.2.0.0.so Now to check file /usr/local/lib/libodbcpsql.2.0.0.so /usr/local/lib/libodbcpsql.2.0.0.so: Mach-O bundle ppc Thats how it should be to work under the driver manager +-------------------------------------------------------------+ | Peter Harvey | | Added to by Nick Gorham | +-------------------------------------------------------------+ unixODBC-2.3.12/README.QNX000066400000000000000000000022351446441710500145470ustar00rootroot00000000000000Building unixODBC on QNX ======================== This has been tested on the QNX 6.1 x86 release. 1. unpack the distribution, and cd into the distribution dir 2. Add any missing files automake --add-missing 3. Configure unixODBC ./configure --sysconfdir=/etc --enable-gui=no --prefix=/opt 4. run libtooloze using the QNX version of libtool, then update aclocal.m4 libtoolize --force aclocal 5. We now need to alter the flags dlopen uses cd libltdl sed "s/RTLD_GLOBAL/RTLD_GROUP/" ltdl.c > ltdl.c.new sed "s/RTLD_LAZY/RTLD_NOW/" ltdl.c.new > ltdl.c cd .. 6. Force a reconfigure rm config.cache 7. Make, then install make make install And with luck and a trailing wind, that should be that. EXTRA STUFF for QNX 6.2, if the wind is head on... If you find that it segfaults, its worth going into the libltdl directory, editing the Makefile, and changing the line CFLAGS = -g -O2 to CFLAGS = -g -O2 -DPIC -fPIC then touch ltdl.c to force a rebuild You may also get a error when building in the exe directory, to fix this, go to the exe directory, edit Makefile, and change OBJEXT = @OBJEXT@ to OBJEXT = o And EXEEXT = @EXEEXT@ to EXEEXT = unixODBC-2.3.12/README.SOLARIS000066400000000000000000000026641446441710500152230ustar00rootroot00000000000000Building unixODBC on Solaris ---------------------------- This should just work, however I have had the following helpful hints sent to me by David Brown of Starquest. The suggested change has been made to the code in __info.c "Last fall, I had problems running on Solaris 7, because my system did have an iconv conversion between ISO8859-1 and UCS-2. I discovered two things: * the missing iconv tables are available by a patch for Solaris 7 (there is also a corresponding patch for Solaris 8, that fixes a lot in this area - seems recommended to use that as well) * Solaris uses the name 8859-1 in its tables rather than ISO8859-1 or ISO-8859-1. So what I've done is: 1) make the following change to DriverManager/__info.c: diff __info.c __info.c.orig 385c385 < char *asc[] = { "char", "ISO8859-1", "ISO-8859-1", "8859-1", "ASCII", NULL }; --- >> char *asc[] = { "char", "ISO8859-1", "ISO-8859-1", "ASCII", NULL }; 2) tell customers to apply the following Solaris patches: Solaris 7: Patch-ID# 112689-02 Keywords: UTF-8 ICONV Synopsis: SunOS 5.7: UTF-8 locale ICONV patch Date: Aug/28/2002 Solaris 8: Patch-ID# 113261-01 Keywords: UTF-8 ICONV Synopsis: SunOS 5.8: UTF-8 locale ICONV patch Date: Oct/11/2002 this has since been superseded by 11326-02, but I think unixODBC should function fine with 113261-01 Patch-ID# 113261-02 Keywords: UTF-8 ICONV Synopsis: SunOS 5.8: UTF-8 locale ICONV patch Date: Feb/21/2003" unixODBC-2.3.12/README.VMS000066400000000000000000000121761446441710500145530ustar00rootroot00000000000000Building unixODBC on OpenVMS (non-VAX only) ========================================= Here's an initial go at building unixODBC on OpenVMS, at present this will only run on alpha and itanium, but if anyone requires use of this on VAX drop me an email (suypport@easysoft.com) and I'll do the necessary transfer vector macro's to export the required symbols from the two shared objects (ODBC.EXE and ODBCINST.EXE). Current components which have been built on OpenVMS LIBODBC.OLB Driver manager as an OpenVMS static object library LIBODBCINST.OLB ODBC installer / setup static object library LIBODBCPSQL.OLB Postgres 6.5 driver static object library LIBODBC.EXE Driver manager shareable image LIBODBCINST.EXE ODBC installer / setup shareable image LIBODBCPSQL.EXE Postgres 6.5 driver shareable image ISQL.EXE Command line SQL tool DLTEST.EXE Program to test loading shared libraries Additional components included to perform building on OpenVMS VMSBUILD.COM - DCL script which compiles, links and installs unixODBC [.EXTRAS]VMS.C - Contains OpenVMS specific wrappers (dlopen, etc..) [.VMS]INSTALL_IMAGE.COM - DCL script to install shareable images [.VMS]ODBCINST_AXP.OPT - Linker options file for ODBC installer shared image [.VMS]ODBC_AXP.OPT - Linker options file for Driver manager shared image [.VMS]ODBC2_AXP.OPT - Linker options file for ODBC 2 drivers [.VMS]ODBC_SETUP.COM - DCL script to set up logicals and commands Building unixODBC on OpenVMS ============================ After unpacking the archive, change into the unixodbc directory and perform the following functions. COMPILING $ @vmsbuild COMPILE LINKING $ @vmsbuild LINK COPYING SHARED LIBRARIES TO THEIR INSTALLED LOCATION Define the logical name ODBC_LIBDIR to point to wherever you would like the libraries to reside and run the build procedure again with the "install" option as in the following example: $ define ODBC_LIBDIR DISK$DBSTUFF:[ODBCLIB] ! will be created if it doesn't exist $ @vmsbuild install If the ODBC_LIBDIR logical is not defined, it will be defined for you and a [.odbclib] directory will be created under the top level of the source directory. Note that the build procedure can be run in batch if you prefer. It is also possible to specify ALL as the parameter and do the compile, link, and install in one fell swoop. For example: $ submit/noprint/param=all vmsbuild.com Post-installation tasks ====================================== To use the installed software, you need to run the command procedure ODBC_SETUP.COM, which will have been installed in the same directory as the libraries. This procedure defines the ODBC_LIBDIR logical name and additional logical names that are needed for the image activator to locate the libraries. It also defines the ISQL command. Put a line similar to the following (with your own disk and directory specification) in your LOGIN.COM, or (to make the software available system-wide) in SYS$MANAGER:SYLOGIN.COM: $ @disk$dbstuff:[odbclib]odbc_setup N.B. It may be tempting to simply dump the libraries into SYS$SHARE and depend on the image activator's default behavior to locate the images. That works, but it's the surest way to what is known on another popular platform as DLL hell. If you'll be programming with ODBC rather than just using ISQL, be sure to hang on to the contents of the [.include] and [.doc] directories. Look at the compiler flags and link commands in vmsbuild.com for examples of what you need to do to build programs using the libraries. For performance reasons it may be desirable to install the libraries as known images (which has nothing to do with "install" in the sense of copying software to its target location). See the documentation to the INSTALL command or use the command procedure [.vms]install_image.com provided with this kit. Installing the images with privileges is not recommended unless there is a compelling reason (Hint: failure to set up file permissions properly on your .ini files is not a compelling reason). Locations of ODBC.INI and ODBCINST.INI ====================================== After running the @VMSBUILD INSTALL command a blank odbc.ini and odbcinst.ini will be created in ODBC_LIBDIR. To override the default locations of the user odbc.ini or the directory where the system odbc.ini and odbcinst.ini reside define the following logicals. $ define/log ODBCINI "DKA100:[MYDIR.ODBC]ODBC.INI" $ define/log ODBCSYSINI "DKA100:[MYDIR.SYS]" Example Setup With Postgres 6.5 =============================== ODBC_LIBDIR:ODBCINST.INI [PostgreSQL] Description = Postgres SQL Driver Driver = LIBODBCPSQL Setup = FileUsage = 1 ODBC_LIBDIR:ODBC.INI [Postgres] Description = Test to Postgres Driver = PostgreSQL Trace = No Database = sample Servername = myserver.mydomain.com UserName = postgres Password = password Port = 5432 Protocol = 6.4 ReadOnly = No RowVersioning = No ShowSystemTables = No ShowOidColumn = No FakeOidIndex = No ConnSettings = Jason last updated 12-Jul-2013 by Craig A. Berry -- craigberry@mac.com unixODBC-2.3.12/SECURITY.md000066400000000000000000000003561446441710500150150ustar00rootroot00000000000000# Security Policy ## Supported Versions | Version | Supported | | ------- | ------------------ | | 2.3.11 | :white_check_mark: | | < 2.3.x | :x: | ## Reporting a Vulnerability Contact nick.gorham@easysoft.com unixODBC-2.3.12/acinclude.m4000066400000000000000000000617221446441710500154210ustar00rootroot00000000000000## -*- autoconf -*- dnl unixODBC dnl dnl This file has been customized for unixODBC. dnl dnl AC_CHECK_LIBPT_NOC(LIBRARY, FUNCTION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND dnl [, OTHER-LIBRARIES]]]) AC_DEFUN([AC_CHECK_LIBPT_NOC], [AC_MSG_CHECKING([for $2 in -l$1]) dnl Use a cache variable name containing both the library and function name, dnl because the test really is for library $1 defining function $2, not dnl just for library $1. Separate tests with the same $1 and different $2s dnl may have different results. ac_save_LIBS="$LIBS" LIBS="-l$1 $5 $LIBS" AC_TRY_LINK(dnl [ #ifdef __cplusplus extern "C" #endif #include ], [$2(0)], eval "ac_cv_lib_$ac_lib_var=yes", eval "ac_cv_lib_$ac_lib_var=no") LIBS="$ac_save_LIBS" dnl if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then AC_MSG_RESULT(yes) ifelse([$3], , [changequote(, )dnl ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` changequote([, ])dnl AC_DEFINE_UNQUOTED($ac_tr_lib) LIBS="-l$1 $LIBS" ], [$3]) else AC_MSG_RESULT(no) ifelse([$4], , , [$4 ])dnl fi ]) dnl Check if the compiler works with a given command line option dnl AC_CHECK_COMP_OPT(OPTION) AC_DEFUN([AC_CHECK_COMP_OPT], [AC_MSG_CHECKING([if compiler accepts -$1]) echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -$1 -c conftest.c 2>&1`"; then AC_MSG_RESULT(yes) CFLAGS="$CFLAGS -$1" else AC_MSG_RESULT(no) fi rm -f conftest* ]) dnl Check for a lib, without checking the cache first dnl AC_CHECK_LIB_NOC(LIBRARY, FUNCTION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND dnl [, OTHER-LIBRARIES]]]) AC_DEFUN([AC_CHECK_LIB_NOC], [AC_MSG_CHECKING([for $2 in -l$1 $5]) ac_save_LIBS="$LIBS" LIBS="-l$1 $5 $LIBS" AC_TRY_LINK(dnl [/* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $2(); ], [$2()], eval "ac_cv_lib_$ac_lib_var=yes", eval "ac_cv_lib_$ac_lib_var=no") LIBS="$ac_save_LIBS" if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then AC_MSG_RESULT(yes) ifelse([$3], , [changequote(, )dnl ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` changequote([, ])dnl AC_DEFINE_UNQUOTED($ac_tr_lib) LIBS="-l$1 $LIBS" ], [$3]) else AC_MSG_RESULT(no) ifelse([$4], , , [$4 ])dnl fi ]) dnl ## dnl ## GNU Pth - The GNU Portable Threads dnl ## Copyright (c) 1999-2000 Ralf S. Engelschall dnl ## dnl ## This file is part of GNU Pth, a non-preemptive thread scheduling dnl ## library which can be found at http://www.gnu.org/software/pth/. dnl ## dnl ## This library is free software; you can redistribute it and/or dnl ## modify it under the terms of the GNU Lesser General Public dnl ## License as published by the Free Software Foundation; either dnl ## version 2.1 of the License, or (at your option) any later version. dnl ## dnl ## This library is distributed in the hope that it will be useful, dnl ## but WITHOUT ANY WARRANTY; without even the implied warranty of dnl ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl ## Lesser General Public License for more details. dnl ## dnl ## You should have received a copy of the GNU Lesser General Public dnl ## License along with this library; if not, write to the Free Software dnl ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 dnl ## USA, or contact Ralf S. Engelschall . dnl ## dnl ## pth.m4: Autoconf macro for locating GNU Pth from within dnl ## configure.in of third-party software packages dnl ## dnl ## dnl ## Synopsis: dnl ## AC_CHECK_PTH([MIN-VERSION [, # minimum Pth version, e.g. 1.2b3 dnl ## DEFAULT-WITH-PTH [, # default value for --with-pth option dnl ## DEFAULT-WITH-PTH-TEST [,# default value for --with-pth-test option dnl ## EXTEND-VARS [, # whether CFLAGS/LDFLAGS/etc are extended dnl ## ACTION-IF-FOUND [, # action to perform if Pth was found dnl ## ACTION-IF-NOT-FOUND # action to perform if Pth was not found dnl ## ]]]]]]) dnl ## Examples: dnl ## AC_CHECK_PTH(1.2.0) dnl ## AC_CHECK_PTH(1.2.0,,,no,CFLAGS="$CFLAGS -DHAVE_PTH $PTH_CFLAGS") dnl ## AC_CHECK_PTH(1.2.0,yes,yes,yes,CFLAGS="$CFLAGS -DHAVE_PTH") dnl ## dnl dnl # auxilliary macros AC_DEFUN([_AC_PTH_ERROR], [dnl AC_MSG_RESULT([*FAILED*]) echo " +------------------------------------------------------------------------+" 1>&2 cat <>/ /' 1>&2 $1 EOT echo " +------------------------------------------------------------------------+" 1>&2 exit 1 ]) AC_DEFUN([_AC_PTH_VERBOSE], [dnl if test ".$verbose" = .yes; then AC_MSG_RESULT([ $1]) fi ]) dnl # the user macro AC_DEFUN([AC_CHECK_PTH], [dnl dnl dnl # prerequisites AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_CPP])dnl dnl PTH_CPPFLAGS='' PTH_CFLAGS='' PTH_LDFLAGS='' PTH_LIBS='' AC_SUBST(PTH_CPPFLAGS) AC_SUBST(PTH_CFLAGS) AC_SUBST(PTH_LDFLAGS) AC_SUBST(PTH_LIBS) dnl # command line options AC_MSG_CHECKING(for GNU Pth) _AC_PTH_VERBOSE([]) AC_ARG_WITH(pth,dnl [AS_HELP_STRING([--with-pth[=ARG]], [Build with GNU Pth Library (default=]ifelse([$2],,yes,$2)[)])],dnl ,dnl with_pth="ifelse([$2],,yes,$2)" )dnl AC_ARG_WITH(pth-test,dnl [AS_HELP_STRING([--with-pth-test], [Perform GNU Pth Sanity Test (default=]ifelse([$3],,yes,$3)[)])],dnl ,dnl with_pth_test="ifelse([$3],,yes,$3)" )dnl _AC_PTH_VERBOSE([+ Command Line Options:]) _AC_PTH_VERBOSE([ o --with-pth=$with_pth]) _AC_PTH_VERBOSE([ o --with-pth-test=$with_pth_test]) dnl dnl # configuration if test ".$with_pth" != .no; then _pth_subdir=no _pth_subdir_opts='' case "$with_pth" in subdir:* ) _pth_subdir=yes changequote(, )dnl _pth_subdir_opts=`echo $with_pth | sed -e 's/^subdir:[^ ]*[ ]*//'` with_pth=`echo $with_pth | sed -e 's/^subdir:\([^ ]*\).*$/\1/'` changequote([, ])dnl ;; esac _pth_version="" _pth_location="" _pth_type="" _pth_cppflags="" _pth_cflags="" _pth_ldflags="" _pth_libs="" if test ".$with_pth" = .yes; then # via config script in $PATH changequote(, )dnl _pth_version=`(pth-config --version) 2>/dev/null |\ sed -e 's/^.*\([0-9]\.[0-9]*[ab.][0-9]*\).*$/\1/'` changequote([, ])dnl if test ".$_pth_version" != .; then _pth_location=`pth-config --prefix` _pth_type='installed' _pth_cppflags=`pth-config --cflags` _pth_cflags=`pth-config --cflags` _pth_ldflags=`pth-config --ldflags` _pth_libs=`pth-config --libs` fi elif test -d "$with_pth"; then with_pth=`echo $with_pth | sed -e 's;/*$;;'` _pth_found=no # via locally included source tree if test ".$_pth_subdir" = .yes; then _pth_location="$with_pth" _pth_type='local' _pth_cppflags="-I$with_pth" _pth_cflags="-I$with_pth" if test -f "$with_pth/ltconfig"; then _pth_ldflags="-L$with_pth/.libs" else _pth_ldflags="-L$with_pth" fi _pth_libs="-lpth" changequote(, )dnl _pth_version=`grep '^const char PTH_Hello' $with_pth/pth_vers.c |\ sed -e 's;^.*Version[ ]*\([0-9]*\.[0-9]*[.ab][0-9]*\)[ ].*$;\1;'` changequote([, ])dnl _pth_found=yes ac_configure_args="$ac_configure_args --enable-subdir $_pth_subdir_opts" with_pth_test=no fi # via config script under a specified directory # (a standard installation, but not a source tree) if test ".$_pth_found" = .no; then for _dir in $with_pth/bin $with_pth; do if test -f "$_dir/pth-config"; then test -f "$_dir/pth-config.in" && continue # pth-config in source tree! changequote(, )dnl _pth_version=`($_dir/pth-config --version) 2>/dev/null |\ sed -e 's/^.*\([0-9]\.[0-9]*[ab.][0-9]*\).*$/\1/'` changequote([, ])dnl if test ".$_pth_version" != .; then _pth_location=`$_dir/pth-config --prefix` _pth_type="installed" _pth_cppflags=`$_dir/pth-config --cflags` _pth_cflags=`$_dir/pth-config --cflags` _pth_ldflags=`$_dir/pth-config --ldflags` _pth_libs=`$_dir/pth-config --libs` _pth_found=yes break fi fi done fi # in any subarea under a specified directory # (either a special installation or a Pth source tree) if test ".$_pth_found" = .no; then changequote(, )dnl _pth_found=0 for _file in x `find $with_pth -name "pth.h" -type f -print`; do test .$_file = .x && continue _dir=`echo $_file | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;'` _pth_version=`($_dir/pth-config --version) 2>/dev/null |\ sed -e 's/^.*\([0-9]\.[0-9]*[ab.][0-9]*\).*$/\1/'` if test ".$_pth_version" = .; then _pth_version=`grep '^#define PTH_VERSION_STR' $_file |\ sed -e 's;^#define[ ]*PTH_VERSION_STR[ ]*"\([0-9]*\.[0-9]*[.ab][0-9]*\)[ ].*$;\1;'` fi _pth_cppflags="-I$_dir" _pth_cflags="-I$_dir" _pth_found=`expr $_pth_found + 1` done for _file in x `find $with_pth -name "libpth.[aso]" -type f -print`; do test .$_file = .x && continue _dir=`echo $_file | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;'` _pth_ldflags="-L$_dir" _pth_libs="-lpth" _pth_found=`expr $_pth_found + 1` done changequote([, ])dnl if test ".$_pth_found" = .2; then _pth_location="$with_pth" _pth_type="uninstalled" else _pth_version='' fi fi fi _AC_PTH_VERBOSE([+ Determined Location:]) _AC_PTH_VERBOSE([ o path: $_pth_location]) _AC_PTH_VERBOSE([ o type: $_pth_type]) if test ".$_pth_version" = .; then if test ".$with_pth" != .yes; then _AC_PTH_ERROR([dnl Unable to locate GNU Pth under $with_pth. Please specify the correct path to either a GNU Pth installation tree (use --with-pth=DIR if you used --prefix=DIR for installing GNU Pth in the past) or to a GNU Pth source tree (use --with-pth=DIR if DIR is a path to a pth-X.Y.Z/ directory; but make sure the package is already built, i.e., the "configure; make" step was already performed there).]) else _AC_PTH_ERROR([dnl Unable to locate GNU Pth in any system-wide location (see \$PATH). Please specify the correct path to either a GNU Pth installation tree (use --with-pth=DIR if you used --prefix=DIR for installing GNU Pth in the past) or to a GNU Pth source tree (use --with-pth=DIR if DIR is a path to a pth-X.Y.Z/ directory; but make sure the package is already built, i.e., the "configure; make" step was already performed there).]) fi fi dnl # dnl # Check whether the found version is sufficiently new dnl # _req_version="ifelse([$1],,1.0.0,$1)" for _var in _pth_version _req_version; do eval "_val=\"\$${_var}\"" _major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\1/'` _minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\2/'` _rtype=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\3/'` _micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\4/'` case $_rtype in "a" ) _rtype=0 ;; "b" ) _rtype=1 ;; "." ) _rtype=2 ;; esac _hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \ "major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"` eval "${_var}_hex=\"\$_hex\"" done _AC_PTH_VERBOSE([+ Determined Versions:]) _AC_PTH_VERBOSE([ o existing: $_pth_version -> 0x$_pth_version_hex]) _AC_PTH_VERBOSE([ o required: $_req_version -> 0x$_req_version_hex]) _ok=0 if test ".$_pth_version_hex" != .; then if test ".$_req_version_hex" != .; then if test $_pth_version_hex -ge $_req_version_hex; then _ok=1 fi fi fi if test ".$_ok" = .0; then _AC_PTH_ERROR([dnl Found Pth version $_pth_version, but required at least version $_req_version. Upgrade Pth under $_pth_location to $_req_version or higher first, please.]) fi dnl # dnl # Perform Pth Sanity Compile Check dnl # if test ".$with_pth_test" = .yes; then _ac_save_CPPFLAGS="$CPPFLAGS" _ac_save_CFLAGS="$CFLAGS" _ac_save_LDFLAGS="$LDFLAGS" _ac_save_LIBS="$LIBS" CPPFLAGS="$CPPFLAGS $_pth_cppflags" CFLAGS="$CFLAGS $_pth_cflags" LDFLAGS="$LDFLAGS $_pth_ldflags" LIBS="$LIBS $_pth_libs" _AC_PTH_VERBOSE([+ Test Build Environment:]) _AC_PTH_VERBOSE([ o CPPFLAGS=\"$CPPFLAGS\"]) _AC_PTH_VERBOSE([ o CFLAGS=\"$CFLAGS\"]) _AC_PTH_VERBOSE([ o LDFLAGS=\"$LDFLAGS\"]) _AC_PTH_VERBOSE([ o LIBS=\"$LIBS\"]) cross_compile=no define(_code1, [dnl #include #include ]) define(_code2, [dnl int main(int argc, char *argv[]) { FILE *fp; if (!(fp = fopen("conftestval", "w"))) exit(1); fprintf(fp, "hmm"); fclose(fp); pth_init(); pth_kill(); if (!(fp = fopen("conftestval", "w"))) exit(1); fprintf(fp, "yes"); fclose(fp); exit(0); } ]) _AC_PTH_VERBOSE([+ Performing Sanity Checks:]) _AC_PTH_VERBOSE([ o pre-processor test]) AC_TRY_CPP(_code1, _ok=yes, _ok=no) if test ".$_ok" != .yes; then _AC_PTH_ERROR([dnl Found GNU Pth $_pth_version under $_pth_location, but was unable to perform a sanity pre-processor check. This means the GNU Pth header pth.h was not found. We used the following build environment: >> CPP="$CPP" >> CPPFLAGS="$CPPFLAGS" See config.log for possibly more details.]) fi _AC_PTH_VERBOSE([ o link check]) AC_TRY_LINK(_code1, _code2, _ok=yes, _ok=no) if test ".$_ok" != .yes; then _AC_PTH_ERROR([dnl Found GNU Pth $_pth_version under $_pth_location, but was unable to perform a sanity linker check. This means the GNU Pth library libpth.a was not found. We used the following build environment: >> CC="$CC" >> CFLAGS="$CFLAGS" >> LDFLAGS="$LDFLAGS" >> LIBS="$LIBS" See config.log for possibly more details.]) fi _AC_PTH_VERBOSE([ o run-time check]) AC_TRY_RUN(_code1 _code2, _ok=`cat conftestval`, _ok=no, _ok=no) if test ".$_ok" != .yes; then if test ".$_ok" = .no; then _AC_PTH_ERROR([dnl Found GNU Pth $_pth_version under $_pth_location, but was unable to perform a sanity execution check. This usually means that the GNU Pth shared library libpth.so is present but \$LD_LIBRARY_PATH is incomplete to execute a Pth test. In this case either disable this test via --without-pth-test, or extend \$LD_LIBRARY_PATH, or build GNU Pth as a static library only via its --disable-shared Autoconf option. We used the following build environment: >> CC="$CC" >> CFLAGS="$CFLAGS" >> LDFLAGS="$LDFLAGS" >> LIBS="$LIBS" See config.log for possibly more details.]) else _AC_PTH_ERROR([dnl Found GNU Pth $_pth_version under $_pth_location, but was unable to perform a sanity run-time check. This usually means that the GNU Pth library failed to work and possibly caused a core dump in the test program. In this case it is strongly recommended that you re-install GNU Pth and this time make sure that it really passes its "make test" procedure. We used the following build environment: >> CC="$CC" >> CFLAGS="$CFLAGS" >> LDFLAGS="$LDFLAGS" >> LIBS="$LIBS" See config.log for possibly more details.]) fi fi _extendvars="ifelse([$4],,yes,$4)" if test ".$_extendvars" != .yes; then CPPFLAGS="$_ac_save_CPPFLAGS" CFLAGS="$_ac_save_CFLAGS" LDFLAGS="$_ac_save_LDFLAGS" LIBS="$_ac_save_LIBS" fi else _extendvars="ifelse([$4],,yes,$4)" if test ".$_extendvars" = .yes; then if test ".$_pth_subdir" = .yes; then CPPFLAGS="$CPPFLAGS $_pth_cppflags" CFLAGS="$CFLAGS $_pth_cflags" LDFLAGS="$LDFLAGS $_pth_ldflags" LIBS="$LIBS $_pth_libs" fi fi fi PTH_CPPFLAGS="$_pth_cppflags" PTH_CFLAGS="$_pth_cflags" PTH_LDFLAGS="$_pth_ldflags" PTH_LIBS="$_pth_libs" AC_SUBST(PTH_CPPFLAGS) AC_SUBST(PTH_CFLAGS) AC_SUBST(PTH_LDFLAGS) AC_SUBST(PTH_LIBS) _AC_PTH_VERBOSE([+ Final Results:]) _AC_PTH_VERBOSE([ o PTH_CPPFLAGS=\"$PTH_CPPFLAGS\"]) _AC_PTH_VERBOSE([ o PTH_CFLAGS=\"$PTH_CFLAGS\"]) _AC_PTH_VERBOSE([ o PTH_LDFLAGS=\"$PTH_LDFLAGS\"]) _AC_PTH_VERBOSE([ o PTH_LIBS=\"$PTH_LIBS\"]) fi if test ".$with_pth" != .no; then AC_MSG_RESULT([version $_pth_version, $_pth_type under $_pth_location]) ifelse([$5], , :, [$5]) else AC_MSG_RESULT([no]) ifelse([$6], , :, [$6]) fi ]) # AC_CHECK_LONG_LONG #------------------- AC_DEFUN([AC_CHECK_LONG_LONG], [ AC_MSG_CHECKING(for long long) AC_CACHE_VAL(ac_cv_type_long_long, [ AC_TRY_COMPILE([ #include ], [ long long x; ], ac_cv_type_long_long=yes, ac_cv_type_long_long=no) ]) AC_MSG_RESULT($ac_cv_type_long_long) if eval "test \"`echo $ac_cv_type_long_long`\" = yes"; then AC_DEFINE(HAVE_LONG_LONG, 1, [Define if you have long long]) fi ])# AC_CHECK_LONG_LONG dnl From Bruno Haible. AC_DEFUN([AM_ICONV], [ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and dnl those with the standalone portable GNU libiconv installed). AC_ARG_WITH([libiconv-prefix], [AS_HELP_STRING([--with-libiconv-prefix=DIR], [search for libiconv in DIR/include and DIR/lib])], [ for dir in `echo "$withval" | tr : ' '`; do if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi done ]) AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_func_iconv=yes) if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS -liconv" AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_lib_iconv=yes am_cv_func_iconv=yes) LIBS="$am_save_LIBS" fi ]) if test "$am_cv_func_iconv" = yes; then AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) AC_MSG_CHECKING([for iconv declaration]) AC_CACHE_VAL(am_cv_proto_iconv, [ AC_TRY_COMPILE([ #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif ], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` AC_MSG_RESULT([$]{ac_t:- }[$]am_cv_proto_iconv) AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, [Define as const if the declaration of iconv() needs const.]) fi LIBICONV= if test "$am_cv_lib_iconv" = yes; then LIBICONV="-liconv" fi AC_SUBST(LIBICONV) ]) # AC_LIBLTDL_CONVENIENCE_G([DIRECTORY]) # ----------------------------------- # sets LIBLTDL to the link flags for the libltdl convenience library and # LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-convenience to the configure arguments. Note that # AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, # it is assumed to be `libltdl'. LIBLTDL will be prefixed with # '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' # (note the single quotes!). If your package is not flat and you're not # using automake, define top_builddir and top_srcdir appropriately in # the Makefiles. AC_DEFUN([AC_LIBLTDL_CONVENIENCE_G], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl case $enable_ltdl_convenience in no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; "") enable_ltdl_convenience=yes ac_configure_args="$ac_configure_args --enable-ltdl-convenience CFLAGS=-DWITHOUT_RTLD_GROUP" ;; esac LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) # For backwards non-gettext consistent compatibility... INCLTDL="$LTDLINCL" ])# AC_LIBLTDL_CONVENIENCE AC_DEFUN([AC_CHECK_SEMUNDOO], [ AC_LANG_C AC_MSG_CHECKING([for semundo union]) AC_CACHE_VAL(ac_cv_semundo_union, [ AC_TRY_LINK([ #include #include #include ], [ union semun semctl_arg; ], ac_cv_semundo_union=no, ac_cv_semundo_union=yes) ]) AC_MSG_RESULT($ac_cv_semundo_union) if eval "test \"`echo $ac_cv_semundo_union`\" = yes"; then AC_DEFINE(NEED_SEMUNDO_UNION, 1, [Define if you need semundo union]) fi ]) # =========================================================================== # http://autoconf-archive.cryp.to/ac_define_dir.html # =========================================================================== # # SYNOPSIS # # AC_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION]) # # DESCRIPTION # # This macro sets VARNAME to the expansion of the DIR variable, taking # care of fixing up ${prefix} and such. # # VARNAME is then offered as both an output variable and a C preprocessor # symbol. # # Example: # # AC_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.]) # # LAST MODIFICATION # # 2008-04-12 # # COPYLEFT # # Copyright (c) 2008 Stepan Kasal # Copyright (c) 2008 Andreas Schwab # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2008 Alexandre Oliva # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. AC_DEFUN([AC_DEFINE_DIR], [ prefix_NONE= exec_prefix_NONE= test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn dnl refers to ${prefix}. Thus we have to use `eval' twice. eval ac_define_dir="\"[$]$2\"" eval ac_define_dir="\"$ac_define_dir\"" AC_SUBST($1, "$ac_define_dir") AC_DEFINE_UNQUOTED($1, "$ac_define_dir", [$3]) test "$prefix_NONE" && prefix=NONE test "$exec_prefix_NONE" && exec_prefix=NONE ]) dnl From Bruno Haible. AC_DEFUN([AM_LANGINFO_CODESET], [ AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, [AC_TRY_LINK([#include ], [char* cs = nl_langinfo(CODESET);], am_cv_langinfo_codeset=yes, am_cv_langinfo_codeset=no) ]) if test $am_cv_langinfo_codeset = yes; then AC_DEFINE(HAVE_LANGINFO_CODESET, 1, [Define if you have and nl_langinfo(CODESET).]) fi ]) unixODBC-2.3.12/configure.ac000066400000000000000000000464561446441710500155250ustar00rootroot00000000000000dnl Process this file with autoconf to produce a configure script. AC_INIT([unixODBC], [2.3.12], nick@unixodbc.org, [unixODBC]) AM_INIT_AUTOMAKE dnl Checks for programs. AC_PROG_AWK AC_PROG_YACC AC_PROG_CPP AC_PROG_CC AM_PROG_LEX AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET AC_CONFIG_MACRO_DIR([m4]) AC_DISABLE_STATIC dnl Check if we want to worry about threads AC_ARG_ENABLE( threads, [AS_HELP_STRING([--enable-threads], [build with thread support [default=yes]])], [ case "${enableval}" in yes) thread=true ;; no) thread=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-thread) ;; esac],[thread=true]) AC_ARG_ENABLE( gnuthreads, [AS_HELP_STRING([--enable-gnuthreads], [build with GNU threads support [default=no]])], [ case "${enableval}" in yes) gnuthread=true ;; no) gnuthread=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-gnuthread) ;; esac],[gnuthread=false]) AC_ARG_ENABLE( readline, [AS_HELP_STRING([--enable-readline], [build with readline support [default=yes]])], [ case "${enableval}" in yes) readline=true ;; no) readline=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-readline) ;; esac],[readline=true]) AC_ARG_ENABLE( editline, [AS_HELP_STRING([--enable-editline], [build with editline support [default=no]])], [ case "${enableval}" in yes) editline=true ;; no) editline=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-editline) ;; esac],[editline=false]) AC_ARG_ENABLE( inicaching, [AS_HELP_STRING([--enable-inicaching], [build with ini file caching support [default=yes]])], [ case "${enableval}" in yes) inicaching=true ;; no) inicaching=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-inicaching) ;; esac],[inicaching=true]) dnl Check if we want to build the drivers AC_ARG_ENABLE( drivers, [AS_HELP_STRING([--enable-drivers], [build included drivers [default=no]])], [ case "${enableval}" in yes) drivers=true ;; no) drivers=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-drivers) ;; esac],[drivers=false]) dnl Check if we want to build the driver config AC_ARG_ENABLE( driver-config, [AS_HELP_STRING([--enable-driver-config], [build included driver config libs [default=no]])], [ case "${enableval}" in yes) driverc=true ;; no) driverc=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-driver-conf) ;; esac],[driverc=false]) AC_ARG_ENABLE( fastvalidate, [AS_HELP_STRING([--enable-fastvalidate], [use relaxed handle checking in the DM [default=no]])], [ case "${enableval}" in yes) fastvalidate=true ;; no) fastvalidate=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-fastvalidate) ;; esac],[fastvalidate=false]) AC_ARG_ENABLE( iconv, [AS_HELP_STRING([--enable-iconv], [build with iconv support [default=yes]])], [ case "${enableval}" in yes) iconv=true ;; no) iconv=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-iconv) ;; esac],[iconv=true]) AC_ARG_ENABLE( utf8ini, [AS_HELP_STRING([--enable-utf8ini], [build with basic support for utf8 encoding in ini file support [default=no]])], [ case "${enableval}" in yes) utf8ini=true ;; no) utf8ini=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-utf8ini) ;; esac],[utf8ini=false]) AC_ARG_ENABLE( singleenv, [AS_HELP_STRING([--enable-singleenv], [When using connection pooling, use a shared envorionment handle [default=no]])], [ case "${enableval}" in yes) singleenv=true ;; no) singleenv=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-singleenv) ;; esac],[singleenv=false]) dnl Check for sys/sem.h AC_CHECK_HEADERS(sys/sem.h, semh=true, semh=false) AC_ARG_ENABLE( stats, [AS_HELP_STRING([--enable-stats], [build with statistic-gathering support [default=no]])], [ case "${enableval}" in yes) if test "x$semh" = "xfalse"; then AC_MSG_ERROR(stats enabled but required header was not found) fi stats=true ;; no) stats=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-stats) ;; esac],[stats=false]) stats_ftok_name="odbc.ini" AC_ARG_WITH(stats_ftok_name, [AS_HELP_STRING([--with-stats-ftok-name=filename], [Filename to get IPC ID for stats gathering [default=odbc.ini]])], [stats_ftok_name="$withval"]) STATS_FTOK_NAME="$stats_ftok_name" AC_SUBST(STATS_FTOK_NAME) AC_DEFINE_UNQUOTED([STATS_FTOK_NAME],"$STATS_FTOK_NAME",[Filename to use for ftok]) AC_ARG_ENABLE( setlibversion, [AS_HELP_STRING([--enable-setlibversion], [build with VERS set in libraries [default=no]])], [ case "${enableval}" in yes) setlibversion=true ;; no) setlibversion=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-setlibversion) ;; esac],[setlibversion=false]) AC_ARG_ENABLE( handlemap, [AS_HELP_STRING([--enable-handlemap], [driver manager can map driver handles called back from broken drivers [default=no]])], [ case "${enableval}" in yes) handlemap=true ;; no) handlemap=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-handlemap) ;; esac],[handlemap=false]) AC_ARG_ENABLE( stricterror, [AS_HELP_STRING([--enable-stricterror], [error conform to the MS spec, the unixODBC prefix is removed for driver errors [default=yes]])], [ case "${enableval}" in yes) stricterror=true ;; no) stricterror=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-stricterror) ;; esac],[stricterror=true]) AC_ARG_ENABLE( gui, [AS_HELP_STRING([--enable-gui], [only included for backwards compatibility, gui now in its own project, see ChangeLog])], [ case "${enableval}" in *) ;; esac]) dnl Enable building of the convenience library dnl and set LIBLTDL accordingly INCLTDL="" LIBLTDL="" AC_LIBTOOL_WIN32_DLL dnl AC_PROG_LIBTOOL dnl AC_CONFIG_MACRO_DIR([libltdl/m4]) dnl LT_CONFIG_LTDL_DIR([libltdl]) dnl LTDL_INIT LT_CONFIG_LTDL_DIR([libltdl]) LT_INIT([dlopen]) LTDL_INIT([convenience]) dnl Substitute INCLTDL and LIBLTDL in the Makefiles AC_SUBST(LTDLINCL) AC_SUBST(LIBLTDL) #dnl Find shared lib extension #AC_MSG_CHECKING(for shared lib extension) #SHLIBEXT="$shrext_cmds" #AC_MSG_RESULT($shrext_cmds) #AC_SUBST(SHLIBEXT) dnl Find shared lib extension AC_MSG_CHECKING(for shared lib extension) eval "SHLIBEXT=$shrext_cmds" AC_MSG_RESULT($SHLIBEXT) AC_SUBST(SHLIBEXT,$SHLIBEXT) dnl Check whether the user specified a path in which libltdl should search for dnl ODBC drivers. This search occurs before libltdl tries other paths, such as dnl its own default search path or the system library search path. dnl dnl This option is useful for multi-arch systems such as Debian, which can have dnl multiple arch-specific library search paths present on a given system. AC_ARG_WITH([odbc-driver-path], [AS_HELP_STRING([--with-odbc-driver-path=DIR], [search for ODBC drivers in DIR at run-time before trying the libltdl and system library search paths])], [AC_DEFINE_UNQUOTED([MODULEDIR], ["`eval echo ${withval}`"], [ODBC driver search path])] ) AC_DEFINE_UNQUOTED([SHLIBEXT], "$shrext_cmds", [Shared lib extension]) AC_DEFINE_DIR([DEFLIB_PATH], [libdir], [Lib directory]) AC_DEFINE_DIR([LIB_PREFIX], [libdir], [Lib directory]) AC_DEFINE_DIR([SYSTEM_FILE_PATH], [sysconfdir], [System file path]) AC_DEFINE_DIR([SYSTEM_LIB_PATH], [libdir], [Lib path]) AC_DEFINE_DIR([PREFIX], [prefix], [Install prefix]) AC_DEFINE_DIR([EXEC_PREFIX], [exec_prefix], [Install exec_prefix]) AC_DEFINE_DIR([BIN_PREFIX], [bindir], [Install bindir]) AC_DEFINE_DIR([INCLUDE_PREFIX], [includedir], [Install includedir]) AC_DEFINE([UNIXODBC], [], [Flag that we are not using another DM]) if test "x$iconv" = "xtrue"; then AM_ICONV iconv_char_enc="auto-search" AC_ARG_WITH(iconv_char_enc, [AS_HELP_STRING([--with-iconv-char-enc=enc], [Encoding to use as ASCII [default=auto-search]])], [iconv_char_enc="$withval"]) ICONV_CHAR_ENCODING="$iconv_char_enc" iconv_ucode_enc="auto-search" AC_ARG_WITH(iconv_ucode_enc, [AS_HELP_STRING([--with-iconv-ucode-enc=enc], [Encoding to use as UNICODE [default=auto-search]])], [iconv_ucode_enc="$withval"]) ICONV_CHAR_ENCODING="" ICONV_UNICODE_ENCODING="" if test "$am_cv_func_iconv" = yes; then AC_MSG_CHECKING( for encoding to use for CHAR representations ); ICONV_CHAR_ENCODING="$iconv_char_enc" AC_MSG_RESULT( $iconv_char_enc ); AC_MSG_CHECKING( for encoding to use for UNICODE representations ); ICONV_UNICODE_ENCODING="$iconv_ucode_enc" AC_MSG_RESULT( $iconv_ucode_enc ); fi AC_SUBST(ICONV_CHAR_ENCODING) AC_SUBST(ICONV_UNICODE_ENCODING) AC_DEFINE_UNQUOTED([UNICODE_ENCODING],"$ICONV_UNICODE_ENCODING",[Encoding to use for UNICODE]) AC_DEFINE_UNQUOTED([ASCII_ENCODING],"$ICONV_CHAR_ENCODING",[Encoding to use for CHAR]) AC_ARG_ENABLE( iconvperdriver, [ --enable-iconvperdriver build with iconv support per driver [default=no]], [ case "${enableval}" in yes) iconvperdriver=true ;; no) iconvperdriver=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-iconvperdriver) ;; esac],[iconvperdriver=false]) AC_MSG_CHECKING( Are we using per driver iconv ) if test "x$iconvperdriver" = "xtrue"; then AC_DEFINE([ENABLE_DRIVER_ICONV],[],[Using perdriver iconv]) AC_MSG_RESULT( yes ); else AC_MSG_RESULT( no ); fi fi dnl Checks for libraries. AC_CHECK_LIB(crypt, crypt, [ AC_DEFINE([HAVE_LIBCRYPT], [], [Add -lcrypt to lib list]) LIBADD_CRYPT="-lcrypt" ]) AC_SUBST(LIBADD_CRYPT) AC_CHECK_LIB(m, pow, [ LIBADD_POW="-lm" ], ) AC_SUBST(LIBADD_POW) have_editline="no" if test "x$editline" = "xtrue"; then AC_CHECK_LIB_NOC(edit, readline, [ READLINE=-ledit have_editline="yes" ], [ dnl try with -lcurses AC_CHECK_LIB_NOC(edit, readline, [ READLINE="-ledit -lcurses" have_editline="yes" ], [ ], -lcurses ) ]) if test "x$have_editline" = "xyes"; then AC_CHECK_HEADERS(editline/readline.h, [AC_DEFINE([HAVE_EDITLINE], [1], [Add editline support])]) readline=false fi fi have_readline="no" if test "x$readline" = "xtrue"; then AC_CHECK_LIB_NOC(readline, readline, [ READLINE=-lreadline have_readline="yes" ], [ dnl try with -lcurses AC_CHECK_LIB_NOC(readline, readline, [ READLINE="-lreadline -lcurses" have_readline="yes" ], [ ], -lcurses ) ]) if test "x$have_readline" = "xyes"; then AC_CHECK_HEADERS(readline/history.h, [AC_DEFINE([HAVE_READLINE], [1], [Add readline support])]) fi fi AC_SUBST(READLINE) AC_MSG_CHECKING( Are we using ini caching ) if test "x$inicaching" = "xtrue"; then AC_DEFINE([ENABLE_INI_CACHING],[],[Using ini cacheing]) AC_MSG_RESULT( yes ); else AC_MSG_RESULT( no ); fi AC_MSG_CHECKING( Are we using utf8 ini encoding ) if test "x$utf8ini" = "xtrue"; then AC_DEFINE([WITH_UTF8_INI],[],[Using utf8 ini encoding]) AC_MSG_RESULT( yes ); else AC_MSG_RESULT( no ); fi AC_MSG_CHECKING( Are we using single shared env handle ) if test "x$singleenv" = "xtrue"; then AC_DEFINE([WITH_SHARDENV],[],[Using shared env handle]) AC_MSG_RESULT( yes ); else AC_MSG_RESULT( no ); fi dnl Are we using flex if test "x$drivers" = "xtrue"; then AC_MSG_CHECKING( Are we using flex ) if test "x$LEX" = "xflex"; then LFLAGS="$LFLAGS -i" AC_MSG_RESULT( yes ); AC_CHECK_LIB(c, scandir, [AC_DEFINE([HAVE_SCANDIR], [1], [Use the scandir lib])] ) else AC_MSG_RESULT( no - text driver disabled ); fi AM_CONDITIONAL(HAVE_FLEX, test "x$LEX" = "xflex" ) AC_SUBST(LFLAGS) else AM_CONDITIONAL(HAVE_FLEX, test "xabc" = "xdef" ) fi case $host_os in *qnx* ) qnx="true" AC_DEFINE([QNX_LIBLTDL],[],[Using QNX]) ;; esac dnl intptr_t is used in places now AC_TYPE_INTPTR_T dnl check how time() can be used AC_HEADER_TIME AC_CHECK_HEADERS(sys/time.h) AC_CHECK_SIZEOF(long, 4) AC_MSG_CHECKING([if platform is 64 bit]) if test "$ac_cv_sizeof_long" = "8"; then AC_MSG_RESULT( Yes ); AC_DEFINE([PLATFORM64],[],[Platform is 64 bit]) else AC_MSG_RESULT( No ); fi AC_CHECK_LONG_LONG AC_CHECK_SIZEOF([long int]) AC_CHECK_TYPES([ptrdiff_t]) AC_SYS_LARGEFILE AC_FUNC_FSEEKO AC_CHECK_FUNCS( strcasecmp strncasecmp snprintf vsnprintf strtol atoll strtoll endpwent gettimeofday ftime time stricmp strnicmp getuid getpwuid getpwuid_r nl_langinfo fseeko setvbuf clock_gettime ) AM_LANGINFO_CODESET LIBADD_DL= AC_SUBST(LIBADD_DL) THREADLIB="" if test "x$thread" = "xtrue"; then if test "x$gnuthread" = "xtrue"; then AC_CHECK_PTH( 1.3.0 ) CPPFLAGS="$CPPFLAGS $PTH_CPPFLAGS" CFLAGS="$CFLAGS $PTH_CFLAGS" LDFLAGS="$LDFLAGS $PTH_LDFLAGS" THREADLIB="$PTH_LIBS" AC_DEFINE([HAVE_LIBPTH], [1], [Use the -lpth thread library]) else gotthread="no"; AC_MSG_CHECKING( if os is AIX ) case $host_os in "aix"*) raw_threads="no"; AC_MSG_RESULT( yes - disable check for libthread ); ;; *) raw_threads="yes"; AC_MSG_RESULT( no - enable check for libthread ); ;; esac if test "x$raw_threads" = "xyes"; then AC_CHECK_LIB_NOC(thread, mutex_lock, [ AC_DEFINE([HAVE_LIBTHREAD], [1], [Use the -lthread threading lib]) dnl Check if the compiler will build with -mt as a option, this is a solaris thing AC_CHECK_COMP_OPT(mt) gotthread="yes"; THREADLIB="-lthread" ]) fi if test "x$gotthread" = "xno"; then AC_CHECK_LIBPT_NOC(pthread, pthread_mutex_lock, [ AC_DEFINE([HAVE_LIBPTHREAD], [1], [Use -lpthread threading lib]) gotthread="yes"; THREADLIB="-lpthread" if test "x$ac_cv_prog_gcc" = "xyes"; then dnl Check if the compiler will build with -pthread as a option AC_CHECK_COMP_OPT(pthread) else dnl Check if the compiler will build with -mt as a option AC_CHECK_COMP_OPT(mt) fi ]) fi if test "x$gotthread" = "xno"; then AC_CHECK_LIBPT_NOC(c, pthread_mutex_lock, [ AC_DEFINE(HAVE_LIBPTHREAD,1) gotthread="yes"; THREADLIB="" if test "x$ac_cv_prog_gcc" = "xyes"; then dnl Check if the compiler will build with -pthread as a option AC_CHECK_COMP_OPT(pthread) else dnl Check if the compiler will build with -mt as a option AC_CHECK_COMP_OPT(mt) fi ]) fi if test "x$gotthread" = "xno"; then if test "x$ac_cv_prog_gcc" = "xyes"; then dnl This is for freebsd that needs -lpthread before it finds the lib AC_CHECK_COMP_OPT(pthread) AC_CHECK_LIBPT_NOC(c, pthread_mutex_lock, [ AC_DEFINE(HAVE_LIBPTHREAD,1) THREADLIB="-pthread -lc_r" gotthread="yes"; ]) fi fi dnl Check for AIX if test "x$gotthread" = "xno"; then SAVECFLAGS="$CFLAGS" CFLAGS="$CFLAGS -D_THREAD_SAFE -D_ALL_SOURCE -D_LONG_LONG" AC_CHECK_LIBPT_NOC(pthread, pthread_mutex_lock, [ AC_DEFINE(HAVE_LIBPTHREAD,1) gotthread="yes"; THREADLIB="-lpthread" ]) CFLAGS="$SAVECFLAGS" AC_DEFINE([_THREAD_SAFE],[],[Build flag for AIX]) AC_DEFINE([_ALL_SOURCE],[],[Build flag for AIX]) AC_DEFINE([_LONG_LONG],[],[Build flag for AIX]) fi if test "x$gotthread" = "xyes"; then dnl do not add a -lc because of this save_LIBS=$LIBS AC_CHECK_LIB(c, localtime_r, [AC_DEFINE([HAVE_LOCALTIME_R], [1], [Use rentrant version of localtime] )]) LIBS=$save_LIBS fi fi fi case $host_os in "darwin"*) stats="false" macosx="yes" AC_DEFINE([OSXHEADER],[],[Using OSX]) ;; sysv5Open*) if test "x$THREADLIB" = "x"; then LIBS="$LIBS $THREADLIB" else LIBS="$LIBS -Kthread" fi ;; *) LIBS="$LIBS $THREADLIB" ;; esac if test "x$stats" = "xtrue"; then AC_CHECK_FUNCS( ftok semget shmget semop,[],[stats=false]) fi if test "x$stats" = "xtrue"; then AC_CHECK_SEMUNDOO AC_DEFINE([COLLECT_STATS], [], [Use a semaphore to allow ODBCConfig to display running counts]) fi AC_ARG_WITH(msql-lib, [AS_HELP_STRING([--with-msql-lib=DIR], [where the root of MiniSQL libs are installed])], [msql_libraries="$withval"]) AC_ARG_WITH(msql-include, [AS_HELP_STRING([--with-msql-include=DIR where the MiniSQL headers are installed])], [msql_headers="$withval"]) AC_SUBST(msql_libraries) AC_SUBST(msql_headers) dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(malloc.h unistd.h pwd.h crypt.h limits.h synch.h strings.h string.h locale.h sys/malloc.h sys/types.h sys/sem.h stdarg.h varargs.h sys/time.h sys/timeb.h time.h langinfo.h stddef.h ) INCLUDES="$INCLUDES $USER_INCLUDES"; dnl only build the mSQL code if the headers are in place AC_CHECK_HEADERS(msql.h,[msql=true], [ msql=false; for ac_dir in $kde_extra_includes $msql_headers; do AC_CHECK_HEADERS( $ac_dir/msql.h, [ msql=true; INCLUDES="$INCLUDES $USER_INCLUDES -I$ac_dir"; ]) done ]) dnl AC_SUBST(all_includes) dnl AC_SUBST(all_libraries) AM_CONDITIONAL(MSQL, test "x$msql" = "xtrue" ) AM_CONDITIONAL(DRIVERS, test "x$drivers" = "xtrue" ) AM_CONDITIONAL(DRIVERC, test "x$driverc" = "xtrue" ) AM_CONDITIONAL(QNX, test "x$qnx" = "xtrue" ) AM_CONDITIONAL(WITHLT, test "x$use_builtin_libtool" = "xyes" ) dnl This blows up due to what I think is a bug in automake 1.6.3 dnl AC_SUBST(INCLUDES) if test "x$fastvalidate" = "xtrue"; then AC_DEFINE([FAST_HANDLE_VALIDATE], [], [Disable the precise but slow checking of the validity of handles]) fi if test "x$handlemap" = "xtrue"; then AC_DEFINE([WITH_HANDLE_REDIRECT],[],[Work with IBM drivers that use 32 bit handles on 64 bit platforms]) fi if test "x$stricterror" = "xtrue"; then AC_DEFINE([STRICT_ODBC_ERROR],[],[don't include unixODBC prefix in driver error messages]) fi dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T AC_STRUCT_TM AC_TYPE_UID_T AC_HEADER_DIRENT dnl Checks for library functions. AC_FUNC_ALLOCA AC_FUNC_VPRINTF AC_CHECK_FUNCS( putenv socket strdup strstr setenv setlocale strchr ) dnl This is the unixODBC source tree AC_DEFINE([UNIXODBC_SOURCE],[],[We are building inside the unixODBC source tree]) LIB_VERSION="2:0:0" AC_SUBST(LIB_VERSION) AC_CONFIG_HEADERS(config.h) AC_CONFIG_HEADERS(unixodbc.h) AC_CONFIG_HEADERS(unixodbc_conf.h) AC_CONFIG_FILES([ Makefile extras/Makefile log/Makefile lst/Makefile ini/Makefile odbcinst/Makefile odbcinst/odbcinst.pc cur/Makefile cur/odbccr.pc DriverManager/Makefile DriverManager/odbc.pc exe/Makefile DRVConfig/Makefile DRVConfig/drvcfg1/Makefile DRVConfig/drvcfg2/Makefile DRVConfig/PostgreSQL/Makefile DRVConfig/MiniSQL/Makefile DRVConfig/MySQL/Makefile DRVConfig/nn/Makefile DRVConfig/esoob/Makefile DRVConfig/oplodbc/Makefile DRVConfig/template/Makefile DRVConfig/tds/Makefile DRVConfig/txt/Makefile DRVConfig/Oracle/Makefile DRVConfig/sapdb/Makefile DRVConfig/Mimer/Makefile Drivers/Makefile Drivers/Postgre7.1/Makefile Drivers/nn/Makefile Drivers/template/Makefile Drivers/MiniSQL/Makefile include/Makefile man/Makefile doc/Makefile doc/AdministratorManual/Makefile doc/ProgrammerManual/Makefile doc/ProgrammerManual/Tutorial/Makefile doc/UserManual/Makefile doc/lst/Makefile samples/Makefile ]) AC_OUTPUT dnl Attempt to add version information to libraries generated by libtool AC_MSG_CHECKING( are we setting library version ) if test "x$setlibversion" = "xtrue"; then AC_MSG_RESULT( yes ); sed '/archive_expsym_cmds=/s/{ global/VERS_3.52 {global/' < libtool > libtool.tmp; mv libtool.tmp libtool else AC_MSG_RESULT( no ); fi unixODBC-2.3.12/cur/000077500000000000000000000000001446441710500140115ustar00rootroot00000000000000unixODBC-2.3.12/cur/Makefile.am000066400000000000000000000034201446441710500160440ustar00rootroot00000000000000lib_LTLIBRARIES = libodbccr.la AM_CPPFLAGS = -I@top_srcdir@/include \ -I@top_srcdir@/DriverManager $(LTDLINCL) EXTRA_DIST = \ cursorlibrary.h \ cur.exp libodbccr_la_LDFLAGS = \ -no-undefined \ -version-info @LIB_VERSION@ \ -export-symbols @srcdir@/cur.exp -export-dynamic ../DriverManager/libodbc.la libodbccr_la_SOURCES = \ SQLAllocHandle.c \ SQLAllocHandleStd.c \ SQLAllocStmt.c \ SQLBindCol.c \ SQLBindParam.c \ SQLBindParameter.c \ SQLCancel.c \ SQLCloseCursor.c \ SQLColAttribute.c \ SQLColAttributes.c \ SQLColumnPrivileges.c \ SQLColumns.c \ SQLConnect.c \ SQLCopyDesc.c \ SQLDescribeCol.c \ SQLDescribeParam.c \ SQLEndTran.c \ SQLError.c \ SQLExecDirect.c \ SQLExecute.c \ SQLExtendedFetch.c \ SQLFetch.c \ SQLFetchScroll.c \ SQLForeignKeys.c \ SQLFreeHandle.c \ SQLFreeStmt.c \ SQLGetConnectAttr.c \ SQLGetConnectOption.c \ SQLGetCursorName.c \ SQLGetData.c \ SQLGetDescField.c \ SQLGetDescRec.c \ SQLGetDiagRec.c \ SQLGetDiagField.c \ SQLGetInfo.c \ SQLGetStmtAttr.c \ SQLGetStmtOption.c \ SQLGetTypeInfo.c \ SQLMoreResults.c \ SQLNativeSql.c \ SQLNumParams.c \ SQLNumResultCols.c \ SQLParamData.c \ SQLParamOptions.c \ SQLPrepare.c \ SQLPrimaryKeys.c \ SQLProcedureColumns.c \ SQLProcedures.c \ SQLPutData.c \ SQLRowCount.c \ SQLSetConnectAttr.c \ SQLSetConnectOption.c \ SQLSetCursorName.c \ SQLSetDescRec.c \ SQLSetDescField.c \ SQLSetParam.c \ SQLSetPos.c \ SQLSetScrollOptions.c \ SQLSetStmtAttr.c \ SQLSetStmtOption.c \ SQLSpecialColumns.c \ SQLStatistics.c \ SQLTablePrivileges.c \ SQLTables.c \ SQLTransact.c unixODBC-2.3.12/cur/README000066400000000000000000000002441446441710500146710ustar00rootroot00000000000000A ODBC cursor lib provides cursor functionality ( client-side data caching and navigation ) in a generic manner so that drivers of any type can rely on it. unixODBC-2.3.12/cur/SQLAllocHandle.c000066400000000000000000000112051446441710500167020ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLAllocHandle.c,v 1.6 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLAllocHandle.c,v $ * Revision 1.6 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2009/02/17 09:47:45 lurcher * Clear up a number of bugs * * Revision 1.4 2005/07/08 12:11:23 lurcher * * Fix a cursor lib problem (it was broken if you did metadata calls) * Alter the params to SQLParamOptions to use SQLULEN * * Revision 1.3 2004/07/24 17:55:38 lurcher * Sync up CVS * * Revision 1.2 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/03/28 14:57:22 nick * * Fix bugs in corsor lib introduced bu UNCODE and other changes * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/11/20 20:54:00 ngorham * * Asorted portability fixes * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLAllocHandle( SQLSMALLINT handle_type, SQLHANDLE input_handle, SQLHANDLE *output_handle, SQLHANDLE dm_handle ) { switch ( handle_type ) { case SQL_HANDLE_ENV: case SQL_HANDLE_DBC: /* * shouldn't be here */ return SQL_ERROR; break; case SQL_HANDLE_STMT: { CLHDBC cl_connection = (CLHDBC) input_handle; CLHSTMT cl_statement; DMHDBC connection = cl_connection -> dm_connection; SQLRETURN ret; /* * allocate a cursor lib statement */ cl_statement = malloc( sizeof( *cl_statement )); if ( !cl_statement ) { cl_connection -> dh.dm_log_write( "CL " __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); cl_connection -> dh.__post_internal_error( &connection -> error, ERROR_HY001, NULL, connection -> environment -> requested_version ); return SQL_ERROR; } memset( cl_statement, 0, sizeof( *cl_statement )); cl_statement -> cl_connection = cl_connection; cl_statement -> dm_statement = ( DMHSTMT ) dm_handle; cl_statement -> error_count = 0; cl_statement -> fetch_statement = SQL_NULL_HSTMT; ret = SQLALLOCHANDLE( cl_connection, handle_type, cl_connection -> driver_dbc, &cl_statement -> driver_stmt, NULL ); if ( SQL_SUCCEEDED( ret )) { *output_handle = ( SQLHSTMT ) cl_statement; } else { free( cl_statement ); } return ret; } break; case SQL_HANDLE_DESC: { CLHDBC cl_connection = (CLHDBC) input_handle; return SQLALLOCHANDLE( cl_connection, handle_type, input_handle, output_handle, NULL ); } break; } return SQL_ERROR; } unixODBC-2.3.12/cur/SQLAllocHandleStd.c000066400000000000000000000037031446441710500173610ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLAllocHandleStd.c,v 1.2 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLAllocHandleStd.c,v $ * Revision 1.2 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLAllocHandleStd( SQLSMALLINT handle_type, SQLHANDLE input_handle, SQLHANDLE *output_handle, SQLHANDLE dm_handle ) { return CLAllocHandle( handle_type, input_handle, output_handle, dm_handle ); } unixODBC-2.3.12/cur/SQLAllocStmt.c000066400000000000000000000062741446441710500164500ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLAllocStmt.c,v 1.3 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLAllocStmt.c,v $ * Revision 1.3 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.2 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/11/20 20:54:00 ngorham * * Asorted portability fixes * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLAllocStmt( SQLHDBC connection_handle, SQLHSTMT *statement_handle, SQLHANDLE dm_handle ) { CLHDBC cl_connection = (CLHDBC) connection_handle; CLHSTMT cl_statement; DMHDBC connection = cl_connection -> dm_connection; SQLRETURN ret; /* * allocate a cursor lib statement */ cl_statement = malloc( sizeof( *cl_statement )); if ( !cl_statement ) { cl_connection -> dh.dm_log_write( "CL " __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); cl_connection -> dh.__post_internal_error( &connection -> error, ERROR_HY001, NULL, connection -> environment -> requested_version ); return SQL_ERROR; } memset( cl_statement, 0, sizeof( *cl_statement )); cl_statement -> cl_connection = cl_connection; cl_statement -> dm_statement = ( DMHSTMT ) dm_handle; ret = SQLALLOCSTMT( cl_connection, cl_connection -> driver_dbc, &cl_statement -> driver_stmt, NULL ); if ( SQL_SUCCEEDED( ret )) { *statement_handle = ( SQLHSTMT ) cl_statement; } else { free( cl_statement ); } return ret; } unixODBC-2.3.12/cur/SQLBindCol.c000066400000000000000000000206321446441710500160520ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLBindCol.c,v 1.6 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLBindCol.c,v $ * Revision 1.6 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.4 2005/10/21 16:49:53 lurcher * Fix a problem with the cursor lib and rowsets * * Revision 1.3 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.2 2001/12/13 13:00:33 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.2 2001/05/31 16:05:55 nick * * Fix problems with postgres closing local sockets * Make odbctest build with QT 3 (it doesn't work due to what I think are bugs * in QT 3) * Fix a couple of problems in the cursor lib * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/10/03 23:05:17 ngorham * * First public outing of the cursor lib * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" /* * release all the bound columns */ int free_bound_columns( CLHSTMT cl_statement ) { CLBCOL *bcol; bcol = cl_statement -> bound_columns; while( bcol ) { CLBCOL *next; if ( bcol -> local_buffer ) { free( bcol -> local_buffer ); } next = bcol -> next; free( bcol ); bcol = next; } cl_statement -> bound_columns = NULL; return 0; } static int get_bound_length( int target_type, int len ) { switch( target_type ) { case SQL_C_STINYINT: case SQL_C_UTINYINT: case SQL_C_TINYINT: return 1; case SQL_C_SBIGINT: case SQL_C_UBIGINT: return 8; case SQL_C_SSHORT: case SQL_C_USHORT: case SQL_C_SHORT: return 2; case SQL_C_SLONG: case SQL_C_ULONG: case SQL_C_LONG: return 4; case SQL_C_DOUBLE: return 8; case SQL_C_FLOAT: return 4; case SQL_C_NUMERIC: return sizeof( SQL_NUMERIC_STRUCT ); case SQL_C_TYPE_DATE: case SQL_C_DATE: return sizeof( SQL_DATE_STRUCT ); case SQL_C_TYPE_TIME: case SQL_C_TIME: return sizeof( SQL_TIME_STRUCT ); case SQL_C_TYPE_TIMESTAMP: case SQL_C_TIMESTAMP: return sizeof( SQL_TIMESTAMP_STRUCT ); case SQL_C_INTERVAL_YEAR: case SQL_C_INTERVAL_MONTH: case SQL_C_INTERVAL_DAY: case SQL_C_INTERVAL_HOUR: case SQL_C_INTERVAL_MINUTE: case SQL_C_INTERVAL_SECOND: case SQL_C_INTERVAL_YEAR_TO_MONTH: case SQL_C_INTERVAL_DAY_TO_HOUR: case SQL_C_INTERVAL_DAY_TO_MINUTE: case SQL_C_INTERVAL_DAY_TO_SECOND: case SQL_C_INTERVAL_HOUR_TO_MINUTE: case SQL_C_INTERVAL_HOUR_TO_SECOND: case SQL_C_INTERVAL_MINUTE_TO_SECOND: return sizeof( SQL_INTERVAL_STRUCT ); default: return len; } } SQLRETURN CLBindCol( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLSMALLINT target_type, SQLPOINTER target_value, SQLLEN buffer_length, SQLLEN *strlen_or_ind ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; CLBCOL *bcol; int b_len; SQLRETURN ret; if ( cl_statement -> not_from_select ) { return SQLBINDCOL( cl_statement -> cl_connection, cl_statement -> driver_stmt, column_number, target_type, target_value, buffer_length, strlen_or_ind ); } /* * check in the list of bound columns for a entry */ bcol = cl_statement -> bound_columns; while ( bcol ) { if ( bcol -> column_number == column_number ) break; bcol = bcol -> next; } if ( !bcol ) { /* * do we want to bind anything */ bcol = malloc( sizeof( CLBCOL )); if ( !bcol ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_HY001, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } memset( bcol, 0, sizeof( CLBCOL )); bcol -> column_number = column_number; /* * insert into to list */ if ( cl_statement -> bound_columns ) { CLBCOL *ptr, *prev; ptr = cl_statement -> bound_columns; prev = NULL; while( ptr && ptr -> column_number < column_number ) { prev = ptr; ptr = ptr -> next; } if ( prev ) { bcol -> next = ptr; prev -> next = bcol; } else { bcol -> next = cl_statement -> bound_columns; cl_statement -> bound_columns = bcol; } } else { bcol -> next = NULL; cl_statement -> bound_columns = bcol; } } /* * setup bound info */ /* * find length */ b_len = get_bound_length( target_type, buffer_length ); if ( bcol -> local_buffer ) { free( bcol -> local_buffer ); } bcol -> local_buffer = NULL; if ( target_value && b_len > 0 ) { bcol -> local_buffer = malloc( b_len ); if ( !bcol -> local_buffer ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_HY001, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } } bcol -> bound_buffer = target_value; bcol -> bound_length = b_len; bcol -> bound_type = target_type; if ( strlen_or_ind ) { bcol -> bound_ind = strlen_or_ind; } else { bcol -> bound_ind = NULL; } /* * call the driver to bind a column, but not bookmarks */ if ( column_number > 0 ) { ret = SQLBINDCOL( cl_statement -> cl_connection, cl_statement -> driver_stmt, column_number, target_type, bcol -> local_buffer, bcol -> bound_length, &bcol -> len_ind ); } else { ret = SQL_SUCCESS; } /* * are we unbinding ? */ if ( !target_value && !strlen_or_ind ) { CLBCOL *ptr, *prev; /* * remove from the list */ ptr = cl_statement -> bound_columns; prev = NULL; while( ptr && ptr != bcol ) { prev = ptr; ptr = ptr -> next; } if ( prev ) { prev -> next = bcol -> next; } else { cl_statement -> bound_columns = bcol -> next; } free( bcol ); } return ret; } unixODBC-2.3.12/cur/SQLBindParam.c000066400000000000000000000045741446441710500164040ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLBindParam.c,v 1.3 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLBindParam.c,v $ * Revision 1.3 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLBindParam( SQLHSTMT statement_handle, SQLUSMALLINT parameter_number, SQLSMALLINT value_type, SQLSMALLINT parameter_type, SQLULEN length_precision, SQLSMALLINT parameter_scale, SQLPOINTER parameter_value, SQLLEN *strlen_or_ind ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; return SQLBINDPARAM( cl_statement -> cl_connection, cl_statement -> driver_stmt, parameter_number, value_type, parameter_type, length_precision, parameter_scale, parameter_value, strlen_or_ind ); } unixODBC-2.3.12/cur/SQLBindParameter.c000066400000000000000000000047261446441710500172630ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLBindParameter.c,v 1.3 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLBindParameter.c,v $ * Revision 1.3 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLBindParameter( SQLHSTMT statement_handle, SQLUSMALLINT ipar, SQLSMALLINT f_param_type, SQLSMALLINT f_c_type, SQLSMALLINT f_sql_type, SQLULEN cb_col_def, SQLSMALLINT ib_scale, SQLPOINTER rgb_value, SQLLEN cb_value_max, SQLLEN *pcb_value ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; return SQLBINDPARAMETER( cl_statement -> cl_connection, cl_statement -> driver_stmt, ipar, f_param_type, f_c_type, f_sql_type, cb_col_def, ib_scale, rgb_value, cb_value_max, pcb_value ); } unixODBC-2.3.12/cur/SQLCancel.c000066400000000000000000000035271446441710500157310ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLCancel.c,v 1.2 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLCancel.c,v $ * Revision 1.2 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLCancel( SQLHSTMT statement_handle ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; return SQLCANCEL( cl_statement -> cl_connection, cl_statement -> driver_stmt ); } unixODBC-2.3.12/cur/SQLCloseCursor.c000066400000000000000000000036661446441710500170130ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLCloseCursor.c,v 1.2 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLCloseCursor.c,v $ * Revision 1.2 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLCloseCursor( SQLHSTMT statement_handle ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; /* * free up any rowset */ free_rowset( cl_statement ); return SQLCLOSECURSOR( cl_statement -> cl_connection, cl_statement -> driver_stmt ); } unixODBC-2.3.12/cur/SQLColAttribute.c000066400000000000000000000137561446441710500171520ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLColAttribute.c,v 1.5 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLColAttribute.c,v $ * Revision 1.5 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.4 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.3 2004/06/21 10:01:14 lurcher * * Fix a couple of 64 bit issues * * Revision 1.2 2003/12/01 16:37:17 lurcher * * Fix a bug in SQLWritePrivateProfileString * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLColAttribute ( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLUSMALLINT field_identifier, SQLPOINTER character_attribute, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLLEN *numeric_attribute ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; /* * Catch any requests for bookmark info */ if ( field_identifier != SQL_DESC_COUNT && field_identifier != SQL_COLUMN_COUNT ) { if ( column_number == 0 ) { if ( cl_statement -> use_bookmarks ) { SQLLEN ival; switch( field_identifier ) { case SQL_DESC_AUTO_UNIQUE_VALUE: case SQL_DESC_CASE_SENSITIVE: case SQL_DESC_NULLABLE: case SQL_DESC_UPDATABLE: case SQL_COLUMN_NULLABLE: case SQL_DESC_UNSIGNED: ival = SQL_FALSE; break; case SQL_DESC_CONCISE_TYPE: ival = SQL_C_SLONG; break; case SQL_DESC_DISPLAY_SIZE: ival = 4; break; case SQL_DESC_FIXED_PREC_SCALE: case SQL_DESC_SEARCHABLE: ival = SQL_TRUE; break; case SQL_DESC_NUM_PREC_RADIX: ival = 0; break; case SQL_DESC_LENGTH: case SQL_COLUMN_LENGTH: case SQL_DESC_OCTET_LENGTH: ival = 4; break; case SQL_DESC_PRECISION: case SQL_DESC_SCALE: case SQL_COLUMN_PRECISION: case SQL_COLUMN_SCALE: ival = 0; break; case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_CATALOG_NAME: case SQL_DESC_LABEL: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: case SQL_COLUMN_NAME: if ( string_length ) { *string_length = 0; } if ( character_attribute ) { *((SQLCHAR*)character_attribute) = '\0'; } return SQL_SUCCESS; default: return SQLCOLATTRIBUTE( cl_statement -> cl_connection, cl_statement -> driver_stmt, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } if ( numeric_attribute ) { *((SQLLEN*)numeric_attribute) = ival; } return SQL_SUCCESS; } else { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_07009, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } } } return SQLCOLATTRIBUTE( cl_statement -> cl_connection, cl_statement -> driver_stmt, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } unixODBC-2.3.12/cur/SQLColAttributes.c000066400000000000000000000045411446441710500173250ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLColAttributes.c,v 1.3 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLColAttributes.c,v $ * Revision 1.3 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLColAttributes( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLUSMALLINT field_identifier, SQLPOINTER character_attribute, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLLEN *numeric_attribute ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; return SQLCOLATTRIBUTES( cl_statement -> cl_connection, cl_statement -> driver_stmt, column_number, field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); } unixODBC-2.3.12/cur/SQLColumnPrivileges.c000066400000000000000000000057331446441710500200340ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLColumnPrivileges.c,v 1.2 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLColumnPrivileges.c,v $ * Revision 1.2 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/09/23 21:46:37 ngorham * * Added cursor support for metadata functions * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLColumnPrivileges( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLCHAR *column_name, SQLSMALLINT name_length4 ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLCOLUMNPRIVILEGES( cl_statement -> cl_connection, cl_statement -> driver_stmt, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, column_name, name_length4 ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; cl_statement -> not_from_select = 1; if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLColumns.c000066400000000000000000000056071446441710500161650ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLColumns.c,v 1.2 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLColumns.c,v $ * Revision 1.2 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/09/23 21:46:37 ngorham * * Added cursor support for metadata functions * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLColumns( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLCHAR *column_name, SQLSMALLINT name_length4 ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLCOLUMNS( cl_statement -> cl_connection, cl_statement -> driver_stmt, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, column_name, name_length4 ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; cl_statement -> not_from_select = 1; if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLConnect.c000066400000000000000000000437621446441710500161420ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLConnect.c,v 1.7 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLConnect.c,v $ * Revision 1.7 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2007/02/12 11:49:35 lurcher * Add QT4 support to existing GUI parts * * Revision 1.5 2005/07/08 12:11:23 lurcher * * Fix a cursor lib problem (it was broken if you did metadata calls) * Alter the params to SQLParamOptions to use SQLULEN * * Revision 1.4 2005/05/03 17:16:49 lurcher * Backport a couple of changes from the Debian build * * Revision 1.3 2002/11/25 15:37:54 lurcher * * Fix problems in the cursor lib * * Revision 1.2 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.3 2001/04/12 17:43:36 nick * * Change logging and added autotest to odbctest * * Revision 1.2 2001/03/28 14:57:22 nick * * Fix bugs in corsor lib introduced bu UNCODE and other changes * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.3 1999/11/20 20:54:00 ngorham * * Asorted portability fixes * * Revision 1.2 1999/11/10 03:51:35 ngorham * * Update the error reporting in the DM to enable ODBC 3 and 2 calls to * work at the same time * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" static struct driver_func cl_template_func[] = { /* 00 */ { SQL_API_SQLALLOCCONNECT, "SQLAllocConnect", NULL, NULL, NULL }, /* 01 */ { SQL_API_SQLALLOCENV, "SQLAllocEnv", NULL, NULL, NULL }, /* 02 */ { SQL_API_SQLALLOCHANDLE, "SQLAllocHandle", NULL, NULL, (SQLRETURN (*)())CLAllocHandle }, /* 03 */ { SQL_API_SQLALLOCSTMT, "SQLAllocStmt", NULL, NULL, (SQLRETURN (*)())CLAllocStmt }, /* 04 */ { SQL_API_SQLALLOCHANDLESTD, "SQLAllocHandleStd", NULL, NULL, (SQLRETURN (*)())CLAllocHandleStd }, /* 05 */ { SQL_API_SQLBINDCOL, "SQLBindCol", NULL, NULL, (SQLRETURN (*)())CLBindCol }, /* 06 */ { SQL_API_SQLBINDPARAM, "SQLBindParam", NULL, NULL, (SQLRETURN (*)())CLBindParam }, /* 07 */ { SQL_API_SQLBINDPARAMETER, "SQLBindParameter", NULL, NULL, (SQLRETURN (*)())CLBindParameter }, /* 08 */ { SQL_API_SQLBROWSECONNECT, "SQLBrowseConnect", NULL, NULL, NULL }, /* 09 */ { SQL_API_SQLBULKOPERATIONS, "SQLBulkOperations", NULL, NULL, NULL }, /* 10 */ { SQL_API_SQLCANCEL, "SQLCancel", NULL, NULL, (SQLRETURN (*)())CLCancel }, /* 11 */ { SQL_API_SQLCLOSECURSOR, "SQLCloseCursor", NULL, NULL, (SQLRETURN (*)())CLCloseCursor }, /* 12 */ { SQL_API_SQLCOLATTRIBUTE, "SQLColAttribute", NULL, NULL, (SQLRETURN (*)())CLColAttribute }, /* 13 */ { SQL_API_SQLCOLATTRIBUTES, "SQLColAttributes", NULL, NULL, (SQLRETURN (*)())CLColAttributes }, /* 14 */ { SQL_API_SQLCOLUMNPRIVILEGES, "SQLColumnPrivileges", NULL, NULL, (SQLRETURN (*)())CLColumnPrivileges }, /* 15 */ { SQL_API_SQLCOLUMNS, "SQLColumns", NULL, NULL, (SQLRETURN (*)())CLColumns }, /* 16 */ { SQL_API_SQLCONNECT, "SQLConnect", NULL, NULL, NULL }, /* 17 */ { SQL_API_SQLCOPYDESC, "SQLCopyDesc", NULL, NULL, (SQLRETURN (*)())CLCopyDesc }, /* 18 */ { SQL_API_SQLDATASOURCES, "SQLDataSources", NULL, NULL, NULL }, /* 19 */ { SQL_API_SQLDESCRIBECOL, "SQLDescribeCol", NULL, NULL, (SQLRETURN (*)())CLDescribeCol }, /* 20 */ { SQL_API_SQLDESCRIBEPARAM, "SQLDescribeParam", NULL, NULL, (SQLRETURN (*)())CLDescribeParam }, /* 21 */ { SQL_API_SQLDISCONNECT, "SQLDisconnect", NULL, NULL, (SQLRETURN (*)())CLDisconnect }, /* 22 */ { SQL_API_SQLDRIVERCONNECT, "SQLDriverConnect", NULL, NULL, NULL }, /* 23 */ { SQL_API_SQLDRIVERS, "SQLDrivers", NULL, NULL, NULL }, /* 24 */ { SQL_API_SQLENDTRAN, "SQLEndTran", NULL, NULL, (SQLRETURN (*)())CLEndTran }, /* 25 */ { SQL_API_SQLERROR, "SQLError", NULL, NULL, (SQLRETURN (*)())CLError }, /* 26 */ { SQL_API_SQLEXECDIRECT, "SQLExecDirect", NULL, NULL, (SQLRETURN (*)())CLExecDirect }, /* 27 */ { SQL_API_SQLEXECUTE, "SQLExecute", NULL, NULL, (SQLRETURN (*)())CLExecute }, /* 28 */ { SQL_API_SQLEXTENDEDFETCH, "SQLExtendedFetch", NULL, NULL, (SQLRETURN (*)())CLExtendedFetch }, /* 29 */ { SQL_API_SQLFETCH, "SQLFetch", NULL, NULL, (SQLRETURN (*)())CLFetch }, /* 30 */ { SQL_API_SQLFETCHSCROLL, "SQLFetchScroll", NULL, NULL, (SQLRETURN (*)())CLFetchScroll }, /* 31 */ { SQL_API_SQLFOREIGNKEYS, "SQLForeignKeys", NULL, NULL, (SQLRETURN (*)())CLForeignKeys }, /* 32 */ { SQL_API_SQLFREEENV, "SQLFreeEnv", NULL, NULL, NULL }, /* 33 */ { SQL_API_SQLFREEHANDLE, "SQLFreeHandle", NULL, NULL, (SQLRETURN (*)())CLFreeHandle }, /* 34 */ { SQL_API_SQLFREESTMT, "SQLFreeStmt", NULL, NULL, (SQLRETURN (*)())CLFreeStmt }, /* 35 */ { SQL_API_SQLFREECONNECT, "SQLFreeConnect", NULL, NULL, NULL }, /* 36 */ { SQL_API_SQLGETCONNECTATTR, "SQLGetConnectAttr", NULL, NULL, (SQLRETURN (*)())CLGetConnectAttr }, /* 37 */ { SQL_API_SQLGETCONNECTOPTION, "SQLGetConnectOption", NULL, NULL, (SQLRETURN (*)())CLGetConnectOption }, /* 38 */ { SQL_API_SQLGETCURSORNAME, "SQLGetCursorName", NULL, NULL, (SQLRETURN (*)())CLGetCursorName }, /* 39 */ { SQL_API_SQLGETDATA, "SQLGetData", NULL, NULL, (SQLRETURN (*)())CLGetData }, /* 40 */ { SQL_API_SQLGETDESCFIELD, "SQLGetDescField", NULL, NULL, (SQLRETURN (*)())CLGetDescField }, /* 41 */ { SQL_API_SQLGETDESCREC, "SQLGetDescRec", NULL, NULL, (SQLRETURN (*)())CLGetDescRec }, /* 42 */ { SQL_API_SQLGETDIAGFIELD, "SQLGetDiagField", NULL, NULL, (SQLRETURN (*)())CLGetDiagField }, /* 43 */ { SQL_API_SQLGETENVATTR, "SQLGetEnvAttr", NULL, NULL, NULL }, /* 44 */ { SQL_API_SQLGETFUNCTIONS, "SQLGetFunctions", NULL, NULL, NULL }, /* 45 */ { SQL_API_SQLGETINFO, "SQLGetInfo", NULL, NULL, (SQLRETURN (*)())CLGetInfo }, /* 46 */ { SQL_API_SQLGETSTMTATTR, "SQLGetStmtAttr", NULL, NULL, (SQLRETURN (*)())CLGetStmtAttr }, /* 47 */ { SQL_API_SQLGETSTMTOPTION, "SQLGetStmtOption", NULL, NULL, (SQLRETURN (*)())CLGetStmtOption }, /* 48 */ { SQL_API_SQLGETTYPEINFO, "SQLGetTypeInfo", NULL, NULL, (SQLRETURN (*)())CLGetTypeInfo }, /* 49 */ { SQL_API_SQLMORERESULTS, "SQLMoreResults", NULL, NULL, (SQLRETURN (*)())CLMoreResults }, /* 50 */ { SQL_API_SQLNATIVESQL, "SQLNativeSql", NULL, NULL, (SQLRETURN (*)())CLNativeSql }, /* 51 */ { SQL_API_SQLNUMPARAMS, "SQLNumParams", NULL, NULL, (SQLRETURN (*)())CLNumParams }, /* 52 */ { SQL_API_SQLNUMRESULTCOLS, "SQLNumResultCols", NULL, NULL, (SQLRETURN (*)())CLNumResultCols }, /* 53 */ { SQL_API_SQLPARAMDATA, "SQLParamData", NULL, NULL, (SQLRETURN (*)())CLParamData }, /* 54 */ { SQL_API_SQLPARAMOPTIONS, "SQLParamOptions", NULL, NULL, (SQLRETURN (*)())CLParamOptions }, /* 55 */ { SQL_API_SQLPREPARE, "SQLPrepare", NULL, NULL, (SQLRETURN (*)())CLPrepare }, /* 56 */ { SQL_API_SQLPRIMARYKEYS, "SQLPrimaryKeys", NULL, NULL, (SQLRETURN (*)())CLPrimaryKeys }, /* 57 */ { SQL_API_SQLPROCEDURECOLUMNS, "SQLProcedureColumns", NULL, NULL, (SQLRETURN (*)())CLProcedureColumns }, /* 58 */ { SQL_API_SQLPROCEDURES, "SQLProcedures", NULL, NULL, (SQLRETURN (*)())CLProcedures }, /* 59 */ { SQL_API_SQLPUTDATA, "SQLPutData", NULL, NULL, (SQLRETURN (*)())CLPutData }, /* 60 */ { SQL_API_SQLROWCOUNT, "SQLRowCount", NULL, NULL, (SQLRETURN (*)())CLRowCount }, /* 61 */ { SQL_API_SQLSETCONNECTATTR, "SQLSetConnectAttr", NULL, NULL, (SQLRETURN (*)())CLSetConnectAttr }, /* 62 */ { SQL_API_SQLSETCONNECTOPTION, "SQLSetConnectOption", NULL, NULL, (SQLRETURN (*)())CLSetConnectOption }, /* 63 */ { SQL_API_SQLSETCURSORNAME, "SQLSetCursorName", NULL, NULL, (SQLRETURN (*)())CLSetCursorName }, /* 64 */ { SQL_API_SQLSETDESCFIELD, "SQLSetDescField", NULL, NULL, (SQLRETURN (*)())CLSetDescField }, /* 65 */ { SQL_API_SQLSETDESCREC, "SQLSetDescRec", NULL, NULL, (SQLRETURN (*)())CLSetDescRec }, /* 66 */ { SQL_API_SQLSETENVATTR, "SQLSetEnvAttr", NULL, NULL, NULL }, /* 67 */ { SQL_API_SQLSETPARAM, "SQLSetParam", NULL, NULL, (SQLRETURN (*)())CLSetParam }, /* 68 */ { SQL_API_SQLSETPOS, "SQLSetPos", NULL, NULL, (SQLRETURN (*)())CLSetPos }, /* 69 */ { SQL_API_SQLSETSCROLLOPTIONS, "SQLSetScrollOptions", NULL, NULL, (SQLRETURN (*)())CLSetScrollOptions }, /* 70 */ { SQL_API_SQLSETSTMTATTR, "SQLSetStmtAttr", NULL, NULL, (SQLRETURN (*)())CLSetStmtAttr }, /* 71 */ { SQL_API_SQLSETSTMTOPTION, "SQLSetStmtOption", NULL, NULL, (SQLRETURN (*)())CLSetStmtOption }, /* 72 */ { SQL_API_SQLSPECIALCOLUMNS, "SQLSpecialColumns", NULL, NULL, (SQLRETURN (*)())CLSpecialColumns }, /* 73 */ { SQL_API_SQLSTATISTICS, "SQLStatistics", NULL, NULL, (SQLRETURN (*)())CLStatistics }, /* 74 */ { SQL_API_SQLTABLEPRIVILEGES, "SQLTablePrivileges", NULL, NULL, (SQLRETURN (*)())CLTablePrivileges }, /* 75 */ { SQL_API_SQLTABLES, "SQLTables", NULL, NULL, (SQLRETURN (*)())CLTables }, /* 76 */ { SQL_API_SQLTRANSACT, "SQLTransact", NULL, NULL, (SQLRETURN (*)())CLTransact }, /* 77 */ { SQL_API_SQLGETDIAGREC, "SQLGetDiagRec", NULL, NULL, (SQLRETURN (*)())CLGetDiagRec }, }; /* * connect is done by the driver manager, the is called to put the * cursor lib in the call chain */ SQLRETURN CLConnect( DMHDBC connection, struct driver_helper_funcs *dh ) { int i; CLHDBC cl_connection; SQLRETURN ret; /* * Allocated a cursor connection structure */ cl_connection = malloc( sizeof( struct cl_connection )); if ( !cl_connection ) { dh ->dm_log_write( "CL " __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); dh ->__post_internal_error( &connection -> error, ERROR_HY001, NULL, connection -> environment -> requested_version ); return SQL_ERROR; } memset( cl_connection, 0, sizeof( struct cl_connection )); cl_connection -> functions = connection -> functions; cl_connection -> dm_connection = connection; cl_connection -> dh.__post_internal_error_ex = dh -> __post_internal_error_ex; cl_connection -> dh.__post_internal_error = dh -> __post_internal_error; cl_connection -> dh.dm_log_write = dh -> dm_log_write; /* * allocated a copy of the functions */ if ( !( cl_connection -> functions = malloc( sizeof( cl_template_func )))) { dh ->dm_log_write( "CL " __FILE__, __LINE__, LOG_INFO, LOG_INFO, "Error: IM001" ); cl_connection -> dh.__post_internal_error( &connection -> error, ERROR_HY001, NULL, connection -> environment -> requested_version ); free( cl_connection ); return SQL_ERROR; } /* * replace the function pointers with the ones in the * cursor lib */ for ( i = 0; i < sizeof( cl_template_func ) / sizeof( cl_template_func[ 0 ] ); i ++ ) { cl_connection -> functions[ i ] = connection -> functions[ i ]; /* * if set replace the driver function with the function in * the template */ if ( cl_template_func[ i ].func && connection -> functions[ i ].func ) { connection -> functions[ i ] = cl_template_func[ i ]; /* * copy the can_supply from the drivers list */ connection -> functions[ i ].can_supply = cl_connection -> functions[ i ].can_supply; } } /* * add some functions the cursor lib will supply */ connection -> functions[ DM_SQLSETPOS ].can_supply = 1; connection -> functions[ DM_SQLSETPOS ].func = cl_template_func[ DM_SQLSETPOS ].func; connection -> functions[ DM_SQLSETSCROLLOPTIONS ].can_supply = 1; connection -> functions[ DM_SQLSETSCROLLOPTIONS ].func = cl_template_func[ DM_SQLSETSCROLLOPTIONS ].func; connection -> functions[ DM_SQLFETCHSCROLL ].can_supply = 1; connection -> functions[ DM_SQLFETCHSCROLL ].func = cl_template_func[ DM_SQLFETCHSCROLL ].func; connection -> functions[ DM_SQLEXTENDEDFETCH ].can_supply = 1; connection -> functions[ DM_SQLEXTENDEDFETCH ].func = cl_template_func[ DM_SQLEXTENDEDFETCH ].func; /* * blank off what we don't do */ connection -> functions[ DM_SQLBULKOPERATIONS ].can_supply = 0; connection -> functions[ DM_SQLBULKOPERATIONS ].func = NULL; /* * intercept the driver dbc */ cl_connection -> driver_dbc = connection -> driver_dbc; connection -> driver_dbc = ( DRV_SQLHANDLE ) cl_connection; /* * check the number of alowed active statements */ if ( CHECK_SQLGETINFO( cl_connection )) { ret = SQLGETINFO( cl_connection, cl_connection -> driver_dbc, SQL_MAX_CONCURRENT_ACTIVITIES, &cl_connection -> active_statement_allowed, sizeof( cl_connection -> active_statement_allowed ), NULL ); /* * assume the worst */ if ( !SQL_SUCCEEDED( ret )) { cl_connection -> active_statement_allowed = 1; } } else { cl_connection -> active_statement_allowed = 1; } return SQL_SUCCESS; } SQLRETURN CLDisconnect( SQLHDBC connection_handle ) { SQLRETURN ret; int i; CLHDBC cl_connection = (CLHDBC)connection_handle; DMHDBC connection = cl_connection -> dm_connection; /* * disconnect from the driver */ ret = SQLDISCONNECT( cl_connection, cl_connection -> driver_dbc ); if ( SQL_SUCCEEDED( ret )) { /* * replace the function pointers with the ones from the * cursor lib */ for ( i = 0; i < sizeof( cl_template_func ) / sizeof( cl_template_func[ 0 ] ); i ++ ) { connection -> functions[ i ] = cl_connection -> functions[ i ]; } /* * replace the driver dbc */ connection -> driver_dbc = cl_connection -> driver_dbc; /* * release the allocated memory */ if ( cl_connection -> functions ) { free( cl_connection -> functions ); } free( cl_connection ); } return ret; } unixODBC-2.3.12/cur/SQLCopyDesc.c000066400000000000000000000034401446441710500162470ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLCopyDesc.c,v 1.2 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLCopyDesc.c,v $ * Revision 1.2 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLCopyDesc( SQLHDESC source_desc_handle, SQLHDESC target_desc_handle ) { /* * todo */ return SQL_ERROR; } unixODBC-2.3.12/cur/SQLDescribeCol.c000066400000000000000000000046361446441710500167240ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLDescribeCol.c,v 1.3 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLDescribeCol.c,v $ * Revision 1.3 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLDescribeCol( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLCHAR *column_name, SQLSMALLINT buffer_length, SQLSMALLINT *name_length, SQLSMALLINT *data_type, SQLULEN *column_size, SQLSMALLINT *decimal_digits, SQLSMALLINT *nullable ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; return SQLDESCRIBECOL( cl_statement -> cl_connection, cl_statement -> driver_stmt, column_number, column_name, buffer_length, name_length, data_type, column_size, decimal_digits, nullable ); } unixODBC-2.3.12/cur/SQLDescribeParam.c000066400000000000000000000043711446441710500172430ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLDescribeParam.c,v 1.3 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLDescribeParam.c,v $ * Revision 1.3 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLDescribeParam( SQLHSTMT statement_handle, SQLUSMALLINT ipar, SQLSMALLINT *pf_sql_type, SQLULEN *pcb_param_def, SQLSMALLINT *pib_scale, SQLSMALLINT *pf_nullable ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; return SQLDESCRIBEPARAM( cl_statement -> cl_connection, cl_statement -> driver_stmt, ipar, pf_sql_type, pcb_param_def, pib_scale, pf_nullable ); } unixODBC-2.3.12/cur/SQLEndTran.c000066400000000000000000000044701446441710500160750ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLEndTran.c,v 1.3 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLEndTran.c,v $ * Revision 1.3 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2009/02/17 09:47:45 lurcher * Clear up a number of bugs * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLEndTran( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT completion_type ) { switch ( handle_type ) { case SQL_HANDLE_ENV: /* * the driver manager will not call this */ return SQL_ERROR; break; case SQL_HANDLE_DBC: { CLHDBC cl_connection = (CLHDBC) handle; return SQLENDTRAN( cl_connection, SQL_HANDLE_DBC, cl_connection -> driver_dbc, completion_type ); } break; default: return SQL_ERROR; } } unixODBC-2.3.12/cur/SQLError.c000066400000000000000000000112601446441710500156260ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLError.c,v 1.5 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLError.c,v $ * Revision 1.5 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.4 2009/02/17 09:47:45 lurcher * Clear up a number of bugs * * Revision 1.3 2008/01/02 15:10:33 lurcher * Fix problems trying to use the cursor lib on a non select statement * * Revision 1.2 2005/09/05 09:49:48 lurcher * New QT detection macros added * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.2 2001/03/28 14:57:22 nick * * Fix bugs in corsor lib introduced bu UNCODE and other changes * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLError( SQLHENV environment_handle, SQLHDBC connection_handle, SQLHSTMT statement_handle, SQLCHAR *sqlstate, SQLINTEGER *native_error, SQLCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length ) { if ( statement_handle ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; if ( cl_statement -> driver_stmt_closed ) { return SQL_NO_DATA; } if ( CHECK_SQLERROR( cl_statement -> cl_connection )) { return SQLERROR( cl_statement -> cl_connection, SQL_NULL_HENV, SQL_NULL_HDBC, cl_statement -> driver_stmt, sqlstate, native_error, message_text, buffer_length, text_length ); } else { SQLRETURN ret; ret = SQLGETDIAGREC( cl_statement -> cl_connection, SQL_HANDLE_STMT, cl_statement -> driver_stmt, cl_statement -> error_count, sqlstate, native_error, message_text, buffer_length, text_length ); if ( SQL_SUCCEEDED( ret )) { cl_statement -> error_count ++; } else { cl_statement -> error_count = 0; } return ret; } } else if ( connection_handle ) { CLHDBC cl_connection = (CLHDBC) connection_handle; if ( CHECK_SQLERROR( cl_connection )) { return SQLERROR( cl_connection, SQL_NULL_HENV, cl_connection -> driver_dbc, SQL_NULL_HSTMT, sqlstate, native_error, message_text, buffer_length, text_length ); } else { SQLRETURN ret; ret = SQLGETDIAGREC( cl_connection, SQL_HANDLE_DBC, cl_connection -> driver_dbc, cl_connection -> error_count, sqlstate, native_error, message_text, buffer_length, text_length ); if ( SQL_SUCCEEDED( ret )) { cl_connection -> error_count ++; } else { cl_connection -> error_count = 0; } return ret; } } else if ( environment_handle ) { /* * shouldn't get here */ return SQL_NO_DATA; } return SQL_NO_DATA; } unixODBC-2.3.12/cur/SQLExecDirect.c000066400000000000000000000207761446441710500165700ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLExecDirect.c,v 1.6 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLExecDirect.c,v $ * Revision 1.6 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.4 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.3 2002/01/21 18:00:51 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.2 2001/12/13 13:00:33 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" /* * free the rowset info */ void free_rowset( CLHSTMT cl_statement ) { if ( cl_statement -> rowset_buffer ) { free( cl_statement -> rowset_buffer ); cl_statement -> rowset_buffer = NULL; } if ( cl_statement -> rowset_file ) { fclose( cl_statement -> rowset_file ); cl_statement -> rowset_file = NULL; } if ( cl_statement -> sql_text ) { free( cl_statement -> sql_text ); cl_statement -> sql_text = NULL; } if ( cl_statement -> column_names ) { int i; for ( i = 0; i < cl_statement -> column_count; i ++ ) { free( cl_statement -> column_names[ i ] ); } free( cl_statement -> column_names ); cl_statement -> column_names = NULL; } if ( cl_statement -> data_type ) { free( cl_statement -> data_type ); cl_statement -> data_type = NULL; } if ( cl_statement -> column_size ) { free( cl_statement -> column_size ); cl_statement -> column_size = NULL; } if ( cl_statement -> decimal_digits ) { free( cl_statement -> decimal_digits ); cl_statement -> decimal_digits = NULL; } } /* * run through the bound columns, calculating the offsets */ int calculate_buffers( CLHSTMT cl_statement, int column_count ) { CLBCOL *bcol; cl_statement -> rowset_position = CL_BEFORE_START; cl_statement -> rowset_count = 0; cl_statement -> rowset_complete = 0; cl_statement -> column_count = column_count; /* * row status value */ cl_statement -> buffer_length = sizeof( SQLUSMALLINT ); bcol = cl_statement -> bound_columns; while ( bcol ) { if ( bcol -> column_number <= column_count ) { bcol -> rs_buffer_offset = cl_statement -> buffer_length; cl_statement -> buffer_length += bcol -> bound_length; bcol -> rs_ind_offset = cl_statement -> buffer_length; cl_statement -> buffer_length += sizeof( SQLULEN ); } bcol = bcol -> next; } /* * allocate buffer */ cl_statement -> rowset_buffer = malloc( cl_statement -> buffer_length ); if ( !cl_statement -> rowset_buffer ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_HY001, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } /* * open temp file */ cl_statement -> rowset_file = tmpfile(); if ( !cl_statement -> rowset_file ) { cl_statement -> cl_connection -> dh.__post_internal_error_ex( &cl_statement -> dm_statement -> error, (SQLCHAR*)"S1000", 0, (SQLCHAR*)"General Error, Unable to create file buffer", SUBCLASS_ODBC, SUBCLASS_ODBC ); return SQL_ERROR; } return SQL_SUCCESS; } SQLRETURN get_column_names( CLHSTMT cl_statement ) { int i; char cname[ 256 ]; /* * already done ? */ if ( cl_statement -> column_names ) { return SQL_SUCCESS; } /* * get the names of all the columns */ cl_statement -> column_names = malloc( sizeof(char *) * cl_statement -> column_count ); cl_statement -> data_type = malloc( sizeof( SQLSMALLINT ) * cl_statement -> column_count ); cl_statement -> column_size = malloc( sizeof( SQLULEN ) * cl_statement -> column_count ); cl_statement -> decimal_digits = malloc( sizeof( SQLSMALLINT ) * cl_statement -> column_count ); for ( i = 1; i <= cl_statement -> column_count; i ++ ) { SQLRETURN ret; if ( !CHECK_SQLDESCRIBECOL( cl_statement -> cl_connection )) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_01000, "Driver does not support SQLDescribeCol", cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } ret = SQLDESCRIBECOL( cl_statement -> cl_connection, cl_statement -> driver_stmt, i, (SQLCHAR*) cname, sizeof( cname ), NULL, &cl_statement -> data_type[ i - 1 ], &cl_statement -> column_size[ i - 1 ], &cl_statement -> decimal_digits[ i - 1 ], NULL ); if ( !SQL_SUCCEEDED( ret )) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_01000, "SQLDescribeCol failed in driver", cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } cl_statement -> column_names[ i - 1 ] = strdup( cname ); } return SQL_SUCCESS; } SQLRETURN CLExecDirect( SQLHSTMT statement_handle, SQLCHAR *statement_text, SQLINTEGER text_length ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; /* * save the statement for later use */ if ( cl_statement -> sql_text ) { free( cl_statement -> sql_text ); } if ( text_length < 0 ) { cl_statement -> sql_text = strdup((char*) statement_text ); } else { cl_statement -> sql_text = malloc( text_length + 1 ); memcpy( cl_statement -> sql_text, statement_text, text_length ); cl_statement -> sql_text[ text_length ] = '\0'; } ret = SQLEXECDIRECT( cl_statement -> cl_connection, cl_statement -> driver_stmt, statement_text, text_length ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLExecute.c000066400000000000000000000051751446441710500161470ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLExecute.c,v 1.2 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLExecute.c,v $ * Revision 1.2 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.2 2001/03/28 14:57:22 nick * * Fix bugs in corsor lib introduced bu UNCODE and other changes * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLExecute( SQLHSTMT statement_handle ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLEXECUTE( cl_statement -> cl_connection, cl_statement -> driver_stmt ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; /* * if it's a SELECT statement it will generate columns * WARNING a stored procedure could get here as well */ if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } else { /* TODO Do DELETE/UPDATE WHERE CURRENT OF */ } } return ret; } unixODBC-2.3.12/cur/SQLExtendedFetch.c000066400000000000000000000702731446441710500172600ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLExtendedFetch.c,v 1.14 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLExtendedFetch.c,v $ * Revision 1.14 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.13 2009/02/17 09:47:45 lurcher * Clear up a number of bugs * * Revision 1.12 2008/01/22 17:51:54 lurcher * Another SQLULEN mismatch * * Revision 1.11 2007/11/29 12:00:36 lurcher * Add 64 bit type changes to SQLExtendedFetch etc * * Revision 1.10 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.9 2005/10/27 17:54:49 lurcher * fix what I suspect is a typo in qt.m4 * * Revision 1.8 2005/10/21 16:49:53 lurcher * Fix a problem with the cursor lib and rowsets * * Revision 1.7 2004/07/24 17:55:38 lurcher * Sync up CVS * * Revision 1.6 2003/12/01 16:37:17 lurcher * * Fix a bug in SQLWritePrivateProfileString * * Revision 1.5 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2002/11/25 15:37:54 lurcher * * Fix problems in the cursor lib * * Revision 1.2 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.2 2001/05/31 16:05:55 nick * * Fix problems with postgres closing local sockets * Make odbctest build with QT 3 (it doesn't work due to what I think are bugs * in QT 3) * Fix a couple of problems in the cursor lib * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.3 1999/11/20 20:54:00 ngorham * * Asorted portability fixes * * Revision 1.2 1999/10/03 23:05:17 ngorham * * First public outing of the cursor lib * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" #define ABS(x) (((x)>=0)?(x):(-(x))) #define SQL_FETCH_PART_ROWSET SQL_NO_DATA + 1 SQLRETURN fetch_row( CLHSTMT cl_statement, int row_number, int offset ) { SQLSMALLINT ret; /* * is the row in the cache ? */ if ( row_number < cl_statement -> rowset_count ) { CLBCOL *cbuf; /* * read the file buffer */ #ifdef HAVE_FSEEKO if ( fseeko( cl_statement -> rowset_file, cl_statement -> buffer_length * row_number, SEEK_SET )) #else if ( fseek( cl_statement -> rowset_file, cl_statement -> buffer_length * row_number, SEEK_SET )) #endif { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1000, "General error: fseek fails", cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } if ( fread( cl_statement -> rowset_buffer, cl_statement -> buffer_length, 1, cl_statement -> rowset_file ) != 1 ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1000, "General error: Unable to read from file buffer", cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } /* * extract the data * * status ptr */ memcpy( &ret, cl_statement -> rowset_buffer, sizeof( SQLUSMALLINT )); /* * columninfo */ cbuf = cl_statement -> bound_columns; while ( cbuf ) { char *buffer = NULL; char *ind_ptr = NULL; /* * copy from the file buffer */ memcpy( cbuf -> local_buffer, cl_statement -> rowset_buffer + cbuf -> rs_buffer_offset, cbuf -> bound_length ); memcpy( &cbuf -> len_ind, cl_statement -> rowset_buffer + cbuf -> rs_ind_offset, sizeof( cbuf -> len_ind )); if ( offset >= 0 ) { /* * copy to the application buffer */ if ( cl_statement -> row_bind_type ) { if ( cbuf -> bound_buffer ) { buffer = ((char*)cbuf -> bound_buffer) + cl_statement -> row_bind_type * offset; } if ( cbuf -> bound_ind ) { ind_ptr = ( char * ) cbuf -> bound_ind; ind_ptr += cl_statement -> row_bind_type * offset; } } else { if ( cbuf -> bound_buffer ) { buffer = ((char*)cbuf -> bound_buffer) + cbuf -> bound_length * offset; } if ( cbuf -> bound_ind ) { ind_ptr = ( char * ) cbuf -> bound_ind; ind_ptr += offset * sizeof( SQLULEN ); } } if ( buffer && cbuf -> len_ind >= 0 ) { if ( cbuf -> bound_type == SQL_C_CHAR ) { strcpy( buffer, cbuf -> local_buffer ); } else { memcpy( buffer, cbuf -> local_buffer, cbuf -> bound_length ); } } if ( ind_ptr ) { memcpy( ind_ptr, &cbuf -> len_ind, sizeof( cbuf -> len_ind )); } } cbuf = cbuf -> next; } return SQL_SUCCESS; } else { if ( cl_statement -> rowset_complete ) { return SQL_NO_DATA; } ret = SQLFETCH( cl_statement -> cl_connection, cl_statement -> driver_stmt ); if ( ret == SQL_NO_DATA ) { /* * at the end */ cl_statement -> rowset_complete = 1; cl_statement -> rowset_position = CL_AFTER_END; } else { CLBCOL *cbuf; /* * insert into the cache */ /* * status ptr */ memcpy( cl_statement -> rowset_buffer, &ret, sizeof( SQLUSMALLINT )); /* * columninfo */ cbuf = cl_statement -> bound_columns; while ( cbuf ) { char *buffer = NULL; char *ind_ptr = NULL; /* * copy to the file buffer */ memcpy( cl_statement -> rowset_buffer + cbuf -> rs_buffer_offset, cbuf -> local_buffer, cbuf -> bound_length ); memcpy( cl_statement -> rowset_buffer + cbuf -> rs_ind_offset, &cbuf -> len_ind, sizeof( cbuf -> len_ind )); if ( offset >= 0 ) { /* * copy to the application buffer */ if ( cl_statement -> row_bind_type ) { if ( cbuf -> bound_buffer ) { buffer = ((char*)cbuf -> bound_buffer) + cl_statement -> row_bind_type * offset; } if ( cbuf -> bound_ind ) { ind_ptr = ( char * ) cbuf -> bound_ind; ind_ptr += cl_statement -> row_bind_type * offset; } } else { if ( cbuf -> bound_buffer ) { buffer = ((char*)cbuf -> bound_buffer) + cbuf -> bound_length * offset; } if ( cbuf -> bound_ind ) { ind_ptr = ( char * ) cbuf -> bound_ind; ind_ptr += offset * sizeof( SQLULEN ); } } /* * Not quite sure if the check is valid, I think I can see where * I got it from, but not sure if it's correct * if ( buffer && cbuf -> bound_ind && *cbuf -> bound_ind >= 0 ) */ if ( buffer && cbuf -> bound_ind ) { if ( cbuf -> bound_type == SQL_C_CHAR ) { strcpy( buffer, cbuf -> local_buffer ); } else { memcpy( buffer, cbuf -> local_buffer, cbuf -> bound_length ); } } if ( ind_ptr ) { memcpy( ind_ptr, &cbuf -> len_ind, sizeof( cbuf -> len_ind )); } } cbuf = cbuf -> next; } /* * write the file buffer */ #ifdef HAVE_FSEEKO if ( fseeko( cl_statement -> rowset_file, cl_statement -> buffer_length * row_number, SEEK_SET )) #else if ( fseek( cl_statement -> rowset_file, cl_statement -> buffer_length * row_number, SEEK_SET )) #endif { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1000, "General error: fseek fails", cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } if ( fwrite( cl_statement -> rowset_buffer, cl_statement -> buffer_length, 1, cl_statement -> rowset_file ) != 1 ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1000, "General error: Unable to write to file buffer", cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } cl_statement -> rowset_count ++; } return ret; } } /* * read the rowset until the specied row, or the end if 0 supplied */ SQLRETURN complete_rowset( CLHSTMT cl_statement, int complete_to ) { int row; SQLRETURN ret; if ( complete_to == 0 ) { row = cl_statement -> rowset_count; do { ret = fetch_row( cl_statement, row, -1 ); if ( SQL_SUCCEEDED( ret )) { row ++; } else if ( ret == SQL_NO_DATA ) { cl_statement -> rowset_complete = 1; ret = SQL_SUCCESS; break; } } while ( SQL_SUCCEEDED( ret )); } else { row = cl_statement -> rowset_count; do { ret = fetch_row( cl_statement, row, -1 ); if ( SQL_SUCCEEDED( ret )) { row ++; } else if ( ret == SQL_NO_DATA ) { cl_statement -> rowset_complete = 1; ret = SQL_SUCCESS; break; } } while ( SQL_SUCCEEDED( ret ) && row < complete_to ); } return ret; } /* * rows_in_set is the sizeof the rowset * row_offset is the row number of the first row */ static SQLRETURN fetch_rowset( CLHSTMT cl_statement, int rows_in_set, int row_offset, int *fetched_rows, SQLUSMALLINT *row_status_array, SQLULEN *rows_fetched_ptr ) { SQLRETURN ret; int row_count = 0; int row; for ( row = 0; row < rows_in_set; row ++ ) { ret = fetch_row( cl_statement, row + row_offset, row ); if ( row_status_array ) { row_status_array[ row ] = ret; } if ( SQL_SUCCEEDED( ret )) { row_count ++; } else { break; } ret = SQL_SUCCESS; } if ( ret == SQL_NO_DATA && row > 0 ) { *fetched_rows = row; if ( rows_fetched_ptr ) { *rows_fetched_ptr = row_count; } ret = SQL_FETCH_PART_ROWSET; } if ( SQL_SUCCEEDED( ret )) { *fetched_rows = row; } if ( rows_fetched_ptr ) { *rows_fetched_ptr = row_count; } return ret; } SQLRETURN do_fetch_scroll( CLHSTMT cl_statement, int fetch_orientation, SQLLEN fetch_offset, SQLUSMALLINT *row_status_ptr, SQLULEN *rows_fetched_ptr, int ext_fetch ) { SQLRETURN ret; int rows_in_set, row_offset, fetched_rows, info = 0; cl_statement -> fetch_done = 1; if ( !cl_statement -> first_fetch_done ) { if ( cl_statement -> column_count > 0 && calculate_buffers( cl_statement, cl_statement -> column_count ) == SQL_ERROR ) { /* * tidy up after a failure */ SQLFREESTMT( cl_statement -> cl_connection, cl_statement -> driver_stmt, SQL_CLOSE ); return SQL_ERROR; } cl_statement -> first_fetch_done = 1; } if ( ext_fetch ) { if ( cl_statement -> rowset_size < 1 ) rows_in_set = 1; else rows_in_set = cl_statement -> rowset_size; } else { if ( cl_statement -> rowset_array_size < 1 ) rows_in_set = 1; else rows_in_set = cl_statement -> rowset_array_size; } /* * I refuse to document all these conditions, you have to * look in the book, its just a copy of that */ switch( fetch_orientation ) { case SQL_FETCH_FIRST: cl_statement -> rowset_position = 0; row_offset = 0; cl_statement -> curr_rowset_start = cl_statement -> rowset_position; ret = fetch_rowset( cl_statement, rows_in_set, row_offset, &fetched_rows, row_status_ptr, rows_fetched_ptr ); if ( SQL_SUCCEEDED( ret )) { cl_statement -> curr_rowset_start = cl_statement -> rowset_position; cl_statement -> rowset_position += fetched_rows; } else if ( ret == SQL_FETCH_PART_ROWSET ) { ret = SQL_SUCCESS; } break; case SQL_FETCH_NEXT: if ( cl_statement -> rowset_position == CL_BEFORE_START ) { cl_statement -> rowset_position = 0; row_offset = 0; } else if ( cl_statement -> rowset_position == CL_AFTER_END ) { ret = SQL_NO_DATA; break; } else { row_offset = cl_statement -> rowset_position; } cl_statement -> cursor_pos = 1; ret = fetch_rowset( cl_statement, rows_in_set, row_offset, &fetched_rows, row_status_ptr, rows_fetched_ptr ); if ( SQL_SUCCEEDED( ret )) { cl_statement -> curr_rowset_start = cl_statement -> rowset_position; cl_statement -> rowset_position += fetched_rows; } else if ( ret == SQL_FETCH_PART_ROWSET ) { cl_statement -> rowset_position = CL_AFTER_END; ret = SQL_SUCCESS; } break; case SQL_FETCH_PRIOR: if ( cl_statement -> rowset_position == CL_BEFORE_START ) { ret = SQL_NO_DATA; break; } else if ( cl_statement -> rowset_position == CL_AFTER_END ) { if ( cl_statement -> rowset_count < rows_in_set ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_01S06, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); info = 1; } else { row_offset = cl_statement -> rowset_count - rows_in_set; cl_statement -> rowset_position = row_offset; } } else if ( cl_statement -> rowset_position <= rows_in_set ) { ret = SQL_NO_DATA; cl_statement -> rowset_position = CL_BEFORE_START; break; } else if ( cl_statement -> rowset_position - rows_in_set < rows_in_set ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_01S06, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); ret = SQL_SUCCESS_WITH_INFO; break; } else { row_offset = cl_statement -> rowset_position -= rows_in_set * 2; } cl_statement -> cursor_pos = 1; ret = fetch_rowset( cl_statement, rows_in_set, row_offset, &fetched_rows, row_status_ptr, rows_fetched_ptr ); if ( SQL_SUCCEEDED( ret )) { cl_statement -> curr_rowset_start = cl_statement -> rowset_position; cl_statement -> rowset_position += fetched_rows; } else if ( ret == SQL_FETCH_PART_ROWSET ) { ret = SQL_SUCCESS; } break; case SQL_FETCH_RELATIVE: if (( cl_statement -> rowset_position == CL_BEFORE_START && fetch_offset > 0 ) || ( cl_statement -> rowset_position == CL_AFTER_END && fetch_offset < 0 )) { return do_fetch_scroll( cl_statement, SQL_FETCH_ABSOLUTE, fetch_offset, row_status_ptr, rows_fetched_ptr, ext_fetch ); } else if ( cl_statement -> rowset_position == CL_BEFORE_START && fetch_offset <= 0 ) { ret = SQL_NO_DATA; cl_statement -> rowset_position = CL_BEFORE_START; break; } else if ( cl_statement -> curr_rowset_start == 0 && fetch_offset <= 0 ) { ret = SQL_NO_DATA; cl_statement -> rowset_position = CL_BEFORE_START; break; } else if ( cl_statement -> curr_rowset_start > 0 && cl_statement -> curr_rowset_start + fetch_offset < 1 && ABS( fetch_offset ) > rows_in_set ) { ret = SQL_NO_DATA; cl_statement -> rowset_position = CL_BEFORE_START; break; } else if ( cl_statement -> curr_rowset_start > 0 && cl_statement -> curr_rowset_start + fetch_offset < 1 && ABS( fetch_offset ) > rows_in_set ) { cl_statement -> rowset_position = 0; } else { /* * these conditions requires completing the rowset */ if ( !cl_statement -> rowset_complete ) { ret = complete_rowset( cl_statement, 0 ); if ( !SQL_SUCCEEDED( ret )) break; } if ( 1 <= cl_statement -> curr_rowset_start + fetch_offset && cl_statement -> curr_rowset_start + fetch_offset <= cl_statement -> rowset_count ) { cl_statement -> curr_rowset_start = cl_statement -> rowset_position = cl_statement -> curr_rowset_start + fetch_offset; } else if ( cl_statement -> curr_rowset_start + fetch_offset > cl_statement -> rowset_count ) { ret = SQL_NO_DATA; cl_statement -> rowset_position = CL_AFTER_END; break; } else if ( cl_statement -> rowset_position == CL_AFTER_END && fetch_offset >= 0 ) { ret = SQL_NO_DATA; cl_statement -> rowset_position = CL_AFTER_END; break; } } row_offset = cl_statement -> rowset_position; cl_statement -> cursor_pos = 1; ret = fetch_rowset( cl_statement, rows_in_set, row_offset, &fetched_rows, row_status_ptr, rows_fetched_ptr ); if ( SQL_SUCCEEDED( ret )) { cl_statement -> curr_rowset_start = cl_statement -> rowset_position; cl_statement -> rowset_position += fetched_rows; } else if ( ret == SQL_FETCH_PART_ROWSET ) { ret = SQL_SUCCESS; } break; /* * The code before this turns the bookmark into a absolute */ case SQL_FETCH_BOOKMARK: case SQL_FETCH_ABSOLUTE: /* * close the rowset if needed */ if ( fetch_offset < 0 && !cl_statement -> rowset_complete ) { ret = complete_rowset( cl_statement, 0 ); if ( !SQL_SUCCEEDED( ret )) break; } if ( fetch_offset < 0 && ABS( fetch_offset ) <= cl_statement -> rowset_count ) { cl_statement -> curr_rowset_start = cl_statement -> rowset_count + fetch_offset; cl_statement -> rowset_position = cl_statement -> curr_rowset_start; } else if ( fetch_offset < 0 && ABS( fetch_offset ) > cl_statement -> rowset_count && ABS( fetch_offset ) > rows_in_set ) { cl_statement -> rowset_position = CL_BEFORE_START; ret = SQL_NO_DATA; break; } else if ( fetch_offset < 0 && ABS( fetch_offset ) > cl_statement -> rowset_count && ABS( fetch_offset ) <= rows_in_set ) { cl_statement -> curr_rowset_start = 0; cl_statement -> rowset_position = cl_statement -> curr_rowset_start; cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_01S06, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); info = 1; } else if ( fetch_offset == 0 ) { cl_statement -> rowset_position = CL_BEFORE_START; ret = SQL_NO_DATA; break; } else if ( fetch_offset > cl_statement -> rowset_count ) { ret = complete_rowset( cl_statement, fetch_offset ); if ( ret == SQL_NO_DATA ) { cl_statement -> rowset_position = CL_AFTER_END; break; } else if ( !SQL_SUCCEEDED( ret )) { break; } else { cl_statement -> curr_rowset_start = fetch_offset; cl_statement -> rowset_position = cl_statement -> curr_rowset_start; } } else { cl_statement -> curr_rowset_start = fetch_offset; cl_statement -> rowset_position = cl_statement -> curr_rowset_start; } row_offset = cl_statement -> rowset_position - 1; cl_statement -> cursor_pos = 1; ret = fetch_rowset( cl_statement, rows_in_set, row_offset, &fetched_rows, row_status_ptr, rows_fetched_ptr ); if ( SQL_SUCCEEDED( ret )) { cl_statement -> curr_rowset_start = cl_statement -> rowset_position; cl_statement -> rowset_position += fetched_rows; } else if ( ret == SQL_FETCH_PART_ROWSET ) { ret = SQL_SUCCESS; } break; case SQL_FETCH_LAST: /* * close the rowset if needed */ if ( !cl_statement -> rowset_complete ) { ret = complete_rowset( cl_statement, 0 ); if ( !SQL_SUCCEEDED( ret )) break; } if ( cl_statement -> rowset_count <= rows_in_set ) { cl_statement -> curr_rowset_start = cl_statement -> rowset_position = 0; } else { cl_statement -> curr_rowset_start = cl_statement -> rowset_position = cl_statement -> rowset_count - rows_in_set; } row_offset = cl_statement -> rowset_position; cl_statement -> cursor_pos = 1; ret = fetch_rowset( cl_statement, rows_in_set, row_offset, &fetched_rows, row_status_ptr, rows_fetched_ptr ); if ( SQL_SUCCEEDED( ret )) { cl_statement -> curr_rowset_start = cl_statement -> rowset_position = CL_AFTER_END; } else if ( ret == SQL_FETCH_PART_ROWSET ) { ret = SQL_SUCCESS; } break; } if ( ret == SQL_SUCCESS && info ) ret = SQL_SUCCESS_WITH_INFO; return ret; } SQLRETURN CLExtendedFetch( SQLHSTMT statement_handle, SQLUSMALLINT f_fetch_type, SQLLEN irow, SQLULEN *pcrow, SQLUSMALLINT *rgf_row_status ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; if ( !cl_statement -> bound_columns ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_SL009, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } return do_fetch_scroll( cl_statement, f_fetch_type, irow, rgf_row_status, pcrow, 1 ); } unixODBC-2.3.12/cur/SQLFetch.c000066400000000000000000000060441446441710500155720ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLFetch.c,v 1.6 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLFetch.c,v $ * Revision 1.6 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2005/10/27 17:54:49 lurcher * fix what I suspect is a typo in qt.m4 * * Revision 1.4 2005/07/08 12:11:24 lurcher * * Fix a cursor lib problem (it was broken if you did metadata calls) * Alter the params to SQLParamOptions to use SQLULEN * * Revision 1.3 2003/10/06 15:43:47 lurcher * * Fix cursor lib to work with SQLFetch as well as the other fetch calls * Update README.OSX to detail building the cursor lib * * Revision 1.2 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/10/03 23:05:17 ngorham * * First public outing of the cursor lib * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLFetch( SQLHSTMT statement_handle ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; if ( cl_statement -> not_from_select ) { return SQLFETCH( cl_statement -> cl_connection, cl_statement -> driver_stmt ); } if ( !cl_statement -> bound_columns ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_SL009, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } return do_fetch_scroll( cl_statement, SQL_FETCH_NEXT, 0, cl_statement -> row_status_ptr, cl_statement -> rows_fetched_ptr, 0 ); } unixODBC-2.3.12/cur/SQLFetchScroll.c000066400000000000000000000070761446441710500167570ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLFetchScroll.c,v 1.7 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLFetchScroll.c,v $ * Revision 1.7 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2007/11/29 12:00:36 lurcher * Add 64 bit type changes to SQLExtendedFetch etc * * Revision 1.5 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.4 2005/10/27 17:54:49 lurcher * fix what I suspect is a typo in qt.m4 * * Revision 1.3 2003/12/01 16:37:17 lurcher * * Fix a bug in SQLWritePrivateProfileString * * Revision 1.2 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/10/03 23:05:17 ngorham * * First public outing of the cursor lib * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLFetchScroll( SQLHSTMT statement_handle, SQLSMALLINT fetch_orientation, SQLLEN fetch_offset ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; if ( !cl_statement -> bound_columns ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_SL009, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } /* * get the value from the bookmark pointer and add the offset */ if ( fetch_orientation == SQL_FETCH_BOOKMARK ) { if ( cl_statement -> fetch_bookmark_ptr ) { SQLINTEGER bm_offset = *((SQLINTEGER*)cl_statement -> fetch_bookmark_ptr); fetch_offset += bm_offset; } else { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_HY111, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); } } return do_fetch_scroll( cl_statement, fetch_orientation, fetch_offset, cl_statement -> row_status_ptr, cl_statement -> rows_fetched_ptr, 0 ); } unixODBC-2.3.12/cur/SQLForeignKeys.c000066400000000000000000000064441446441710500167720ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLForeignKeys.c,v 1.2 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLForeignKeys.c,v $ * Revision 1.2 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/09/23 21:46:37 ngorham * * Added cursor support for metadata functions * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLForeignKeys( SQLHSTMT statement_handle, SQLCHAR *szpk_catalog_name, SQLSMALLINT cbpk_catalog_name, SQLCHAR *szpk_schema_name, SQLSMALLINT cbpk_schema_name, SQLCHAR *szpk_table_name, SQLSMALLINT cbpk_table_name, SQLCHAR *szfk_catalog_name, SQLSMALLINT cbfk_catalog_name, SQLCHAR *szfk_schema_name, SQLSMALLINT cbfk_schema_name, SQLCHAR *szfk_table_name, SQLSMALLINT cbfk_table_name ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLFOREIGNKEYS( cl_statement -> cl_connection, cl_statement -> driver_stmt, szpk_catalog_name, cbpk_catalog_name, szpk_schema_name, cbpk_schema_name, szpk_table_name, cbpk_table_name, szfk_catalog_name, cbfk_catalog_name, szfk_schema_name, cbfk_schema_name, szfk_table_name, cbfk_table_name ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; cl_statement -> not_from_select = 1; if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLFreeHandle.c000066400000000000000000000077201446441710500165400ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLFreeHandle.c,v 1.4 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLFreeHandle.c,v $ * Revision 1.4 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2009/02/17 09:47:45 lurcher * Clear up a number of bugs * * Revision 1.2 2004/07/24 17:55:38 lurcher * Sync up CVS * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLFreeHandle( SQLSMALLINT handle_type, SQLHANDLE handle ) { switch ( handle_type ) { case SQL_HANDLE_ENV: case SQL_HANDLE_DBC: return SQL_ERROR; case SQL_HANDLE_STMT: { CLHSTMT cl_statement = (CLHSTMT) handle; SQLRETURN ret = SQL_SUCCESS; /* * call the driver */ if ( !cl_statement -> driver_stmt_closed ) { if ( CHECK_SQLFREEHANDLE( cl_statement -> cl_connection )) { ret = SQLFREEHANDLE( cl_statement -> cl_connection, handle_type, cl_statement -> driver_stmt ); } else { ret = SQLFREESTMT( cl_statement -> cl_connection, cl_statement -> driver_stmt, SQL_DROP ); } if ( cl_statement -> fetch_statement != SQL_NULL_HSTMT ) { if ( CHECK_SQLFREEHANDLE( cl_statement -> cl_connection )) { ret = SQLFREEHANDLE( cl_statement -> cl_connection, handle_type, cl_statement -> fetch_statement ); } else { ret = SQLFREESTMT( cl_statement -> cl_connection, cl_statement -> fetch_statement, SQL_DROP ); } cl_statement -> fetch_statement = SQL_NULL_HSTMT; } } if ( SQL_SUCCEEDED( ret )) { /* * free any bound columns */ free_bound_columns( cl_statement ); /* * free up any rowset */ free_rowset( cl_statement ); free( cl_statement ); } return ret; } case SQL_HANDLE_DESC: /* * worry about this later, we need to get the connection */ return SQL_ERROR; } return SQL_ERROR; } unixODBC-2.3.12/cur/SQLFreeStmt.c000066400000000000000000000062201446441710500162660ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLFreeStmt.c,v 1.3 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLFreeStmt.c,v $ * Revision 1.3 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2004/07/24 17:55:38 lurcher * Sync up CVS * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/10/03 23:05:17 ngorham * * First public outing of the cursor lib * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLFreeStmt( SQLHSTMT statement_handle, SQLUSMALLINT option ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret = SQL_SUCCESS; /* * call the driver */ if ( !cl_statement -> driver_stmt_closed ) { ret = SQLFREESTMT( cl_statement -> cl_connection, cl_statement -> driver_stmt, option ); } if ( SQL_SUCCEEDED( ret )) { if ( option == SQL_DROP ) { if ( cl_statement -> fetch_statement != SQL_NULL_HSTMT ) { ret = SQLFREESTMT( cl_statement -> cl_connection, cl_statement -> fetch_statement, SQL_DROP ); cl_statement -> fetch_statement = SQL_NULL_HSTMT; } /* * free all bound columns */ free_bound_columns( cl_statement ); /* * free up any rowset */ free_rowset( cl_statement ); free( cl_statement ); } else if ( option == SQL_CLOSE ) { /* * free up any rowset */ free_rowset( cl_statement ); } else if ( option == SQL_UNBIND ) { /* * free all bound columns */ free_bound_columns( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLGetConnectAttr.c000066400000000000000000000041131446441710500174200ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetConnectAttr.c,v 1.2 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLGetConnectAttr.c,v $ * Revision 1.2 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLGetConnectAttr( SQLHDBC connection_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { CLHDBC cl_connection = (CLHDBC) connection_handle; return SQLGETCONNECTATTR( cl_connection, cl_connection -> driver_dbc, attribute, value, buffer_length, string_length ); } unixODBC-2.3.12/cur/SQLGetConnectOption.c000066400000000000000000000037201446441710500177610ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetConnectOption.c,v 1.2 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLGetConnectOption.c,v $ * Revision 1.2 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLGetConnectOption( SQLHDBC connection_handle, SQLUSMALLINT option, SQLPOINTER value ) { CLHDBC cl_connection = (CLHDBC) connection_handle; return SQLGETCONNECTOPTION( cl_connection, cl_connection -> driver_dbc, option, value ); } unixODBC-2.3.12/cur/SQLGetCursorName.c000066400000000000000000000061161446441710500172570ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetCursorName.c,v 1.4 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLGetCursorName.c,v $ * Revision 1.4 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.2 2001/12/13 13:00:33 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLGetCursorName( SQLHSTMT statement_handle, SQLCHAR *cursor_name, SQLSMALLINT buffer_length, SQLSMALLINT *name_length ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret = SQL_SUCCESS; if ( cursor_name ) { if ( buffer_length < strlen((char*) cl_statement -> cursor_name ) + 1 ) { memcpy( cursor_name, cl_statement -> cursor_name, buffer_length ); cursor_name[ buffer_length ] = '\0'; ret = SQL_SUCCESS_WITH_INFO; cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_01004, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); } else { strcpy((char*) cursor_name, (char*) cl_statement -> cursor_name ); } } if ( name_length ) { *name_length = strlen((char*) cl_statement -> cursor_name ); } return ret; } unixODBC-2.3.12/cur/SQLGetData.c000066400000000000000000000544131446441710500160550ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetData.c,v 1.12 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLGetData.c,v $ * Revision 1.12 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.11 2008/01/02 15:10:33 lurcher * Fix problems trying to use the cursor lib on a non select statement * * Revision 1.10 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.9 2005/07/08 12:11:24 lurcher * * Fix a cursor lib problem (it was broken if you did metadata calls) * Alter the params to SQLParamOptions to use SQLULEN * * Revision 1.8 2004/12/23 14:51:04 lurcher * Fix problem in the cursor lib with blobs * * Revision 1.7 2004/08/17 17:17:38 lurcher * * Fix problem in the cursor lib when rereading records with NULLs in * * Revision 1.6 2004/07/24 17:55:38 lurcher * Sync up CVS * * Revision 1.5 2003/12/01 16:37:17 lurcher * * Fix a bug in SQLWritePrivateProfileString * * Revision 1.4 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.3 2002/01/21 18:00:51 lurcher * * Assorted fixed and changes, mainly UNICODE/bug fixes * * Revision 1.2 2001/12/13 13:00:33 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.2 2001/03/28 14:57:22 nick * * Fix bugs in corsor lib introduced bu UNCODE and other changes * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLGetData( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLSMALLINT target_type, SQLPOINTER target_value, SQLLEN buffer_length, SQLLEN *strlen_or_ind ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; CLHDBC cl_connection = cl_statement -> cl_connection; SQLRETURN ret; SQLCHAR sql[ 4095 ]; CLBCOL *bound_columns; int next_bind, first; if ( cl_statement -> cursor_type == SQL_CURSOR_FORWARD_ONLY ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_SL008, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } if ( cl_statement -> not_from_select ) { return SQLGETDATA( cl_connection, cl_statement -> driver_stmt, column_number, target_type, target_value, buffer_length, strlen_or_ind ); } /* * check we have what we need */ if ( !CHECK_SQLBINDPARAM( cl_connection ) && !CHECK_SQLBINDPARAMETER( cl_connection )) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1000, "Driver can not bind parameters", cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } if ( !CHECK_SQLEXECDIRECT( cl_connection ) && !( CHECK_SQLPREPARE( cl_connection ) && CHECK_SQLEXECUTE( cl_connection ))) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1000, "Driver can not prepare or execute", cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } if ( !CHECK_SQLFETCH( cl_connection )) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1000, "Driver can not fetch", cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } if ( !CHECK_SQLGETDATA( cl_connection )) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1000, "Driver can not getdata", cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } /* * if it's not and closed resultset, and the driver * can only support one active statement, then close * the result set first */ if ( !cl_statement -> rowset_complete && cl_statement -> cl_connection -> active_statement_allowed == 1 ) { int sav_start, sav_pos; sav_start = cl_statement -> curr_rowset_start; sav_pos = cl_statement -> rowset_position; complete_rowset( cl_statement, 0 ); SQLFREESTMT( cl_connection, cl_statement -> driver_stmt, SQL_DROP ); cl_statement -> driver_stmt_closed = 1; /* * restore the position */ cl_statement -> curr_rowset_start = sav_start; cl_statement -> rowset_position = sav_pos; } /* * Are we looking for the bookmark... */ if ( column_number == 0 ) { if ( cl_statement -> use_bookmarks ) { switch( target_type ) { case SQL_C_LONG: case SQL_C_SLONG: case SQL_C_ULONG: if ( target_value ) { *((SQLINTEGER*)target_value) = cl_statement -> curr_rowset_start; } if ( strlen_or_ind ) { *strlen_or_ind = sizeof( SQLINTEGER ); } return SQL_SUCCESS; case SQL_C_NUMERIC: case SQL_C_CHAR: case SQL_C_WCHAR: case SQL_C_SSHORT: case SQL_C_SHORT: case SQL_C_USHORT: case SQL_C_FLOAT: case SQL_C_DOUBLE: case SQL_C_BIT: case SQL_C_STINYINT: case SQL_C_TINYINT: case SQL_C_UTINYINT: case SQL_C_SBIGINT: case SQL_C_UBIGINT: case SQL_C_BINARY: case SQL_C_TYPE_DATE: case SQL_C_DATE: case SQL_C_TYPE_TIME: case SQL_C_TIME: case SQL_C_TYPE_TIMESTAMP: case SQL_C_TIMESTAMP: cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1003, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } } else { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_07009, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } } /* * refresh the data */ if ( !cl_statement -> fetch_done ) { ret = SQLGETDATA( cl_connection, cl_statement -> fetch_statement, column_number, target_type, target_value, buffer_length, strlen_or_ind ); if ( !SQL_SUCCEEDED( ret ) && ret != SQL_NO_DATA ) { SQLCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; int rec = 1; /* * get the error from the driver before * loseing the connection */ do { if ( CHECK_SQLERROR( cl_connection )) { ret = SQLERROR( cl_connection, SQL_NULL_HENV, SQL_NULL_HSTMT, cl_statement -> fetch_statement, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); } else if ( CHECK_SQLGETDIAGREC( cl_connection )) { ret = SQLGETDIAGREC( cl_connection, SQL_HANDLE_STMT, cl_statement -> fetch_statement, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); } else { ret = SQL_NO_DATA; } if ( ret != SQL_NO_DATA ) { cl_statement -> cl_connection -> dh.__post_internal_error_ex( &cl_statement -> dm_statement -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } } while ( SQL_SUCCEEDED( ret )); } if ( !SQL_SUCCEEDED( ret ) && ret != SQL_NO_DATA ) { SQLFREESTMT( cl_connection, cl_statement -> fetch_statement, SQL_DROP ); cl_statement -> fetch_statement = SQL_NULL_HSTMT; } return ret; } cl_statement -> fetch_done = 0; ret = fetch_row( cl_statement, cl_statement -> curr_rowset_start + cl_statement -> cursor_pos - 1, -1 ); if ( cl_statement -> fetch_statement != SQL_NULL_HSTMT ) { SQLFREESTMT( cl_connection, cl_statement -> fetch_statement, SQL_DROP ); cl_statement -> fetch_statement = SQL_NULL_HSTMT; } ret = SQLALLOCSTMT( cl_connection, cl_connection -> driver_dbc, (SQLHSTMT) &cl_statement -> fetch_statement, NULL ); if ( !SQL_SUCCEEDED( ret )) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1000, "SQLAllocStmt failed in driver", cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } /* * append the cryterior to the end of the statement, binding * the comumns while we are at it */ strcpy((char*) sql, cl_statement -> sql_text ); /* * This is somewhat simplistic, but workable */ if ( strstr( (char*) sql, "WHERE" )) { strcat((char*) sql, " AND" ); } else { strcat((char*) sql, " WHERE" ); } /* * this works because the bound list is in column order */ bound_columns = cl_statement -> bound_columns; first = 1; next_bind = 0; while( bound_columns ) { char addon[ 256 ]; int col = bound_columns -> column_number; /* * Don't bind long types */ if ( cl_statement -> data_type[ col ] == SQL_LONGVARCHAR || cl_statement -> data_type[ col ] == SQL_LONGVARBINARY ) { } else { if ( bound_columns -> len_ind == -1 ) { sprintf( addon, " %s IS NULL", cl_statement -> column_names[ col - 1 ] ); if ( !first ) { strcat((char*) sql, " AND" ); } strcat((char*) sql, addon ); first = 0; } else { sprintf( addon, " %s = ?", cl_statement -> column_names[ col - 1 ] ); if ( !first ) { strcat((char*) sql, " AND" ); } strcat((char*) sql, addon ); first = 0; if ( CHECK_SQLBINDPARAMETER( cl_connection )) { ret = SQLBINDPARAMETER( cl_connection, cl_statement -> fetch_statement, next_bind + 1, SQL_PARAM_INPUT, bound_columns -> bound_type, cl_statement -> data_type[ col - 1 ], cl_statement -> column_size[ col - 1 ], cl_statement -> decimal_digits[ col - 1 ], bound_columns -> local_buffer, bound_columns -> bound_length, &bound_columns -> len_ind ); } else { ret = SQLBINDPARAM( cl_connection, cl_statement -> fetch_statement, next_bind + 1, bound_columns -> bound_type, cl_statement -> data_type[ col - 1 ], cl_statement -> column_size[ col - 1 ], cl_statement -> decimal_digits[ col - 1 ], bound_columns -> local_buffer, &bound_columns -> len_ind ); } if ( !SQL_SUCCEEDED( ret )) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_SL010, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); if ( !SQL_SUCCEEDED( ret ) && ret != SQL_NO_DATA ) { SQLCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; int rec = 1; /* * get the error from the driver before * loseing the stmt */ do { if ( CHECK_SQLERROR( cl_connection )) { ret = SQLERROR( cl_connection, SQL_NULL_HENV, SQL_NULL_HSTMT, cl_statement -> fetch_statement, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); } else if ( CHECK_SQLGETDIAGREC( cl_connection )) { ret = SQLGETDIAGREC( cl_connection, SQL_HANDLE_STMT, cl_statement -> fetch_statement, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); } else { ret = SQL_NO_DATA; } if ( ret != SQL_NO_DATA ) { cl_statement -> cl_connection -> dh.__post_internal_error_ex( &cl_statement -> dm_statement -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } } while ( SQL_SUCCEEDED( ret )); } SQLFREESTMT( cl_connection, cl_statement -> fetch_statement, SQL_DROP ); cl_statement -> fetch_statement = SQL_NULL_HSTMT; return SQL_ERROR; } next_bind ++; } } bound_columns = bound_columns -> next; } if ( CHECK_SQLEXECDIRECT( cl_connection )) { ret = SQLEXECDIRECT( cl_connection, cl_statement -> fetch_statement, sql, strlen((char*) sql )); } else { ret = SQLPREPARE( cl_connection, cl_statement -> fetch_statement, sql, strlen((char*) sql )); if ( SQL_SUCCEEDED( ret )) { ret = SQLEXECUTE( cl_connection, cl_statement -> fetch_statement ); } } if ( !SQL_SUCCEEDED( ret )) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_SL004, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); if ( !SQL_SUCCEEDED( ret ) && ret != SQL_NO_DATA ) { SQLCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; int rec = 1; /* * get the error from the driver before * loseing the stmt */ do { if ( CHECK_SQLERROR( cl_connection )) { ret = SQLERROR( cl_connection, SQL_NULL_HENV, SQL_NULL_HSTMT, cl_statement -> fetch_statement, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); } else if ( CHECK_SQLGETDIAGREC( cl_connection )) { ret = SQLGETDIAGREC( cl_connection, SQL_HANDLE_STMT, cl_statement -> fetch_statement, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); } else { ret = SQL_NO_DATA; } if ( ret != SQL_NO_DATA ) { cl_statement -> cl_connection -> dh.__post_internal_error_ex( &cl_statement -> dm_statement -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } } while ( SQL_SUCCEEDED( ret )); } SQLFREESTMT( cl_connection, cl_statement -> fetch_statement, SQL_DROP ); cl_statement -> fetch_statement = SQL_NULL_HSTMT; return SQL_ERROR; } ret = SQLFETCH( cl_connection, cl_statement -> fetch_statement ); if ( !SQL_SUCCEEDED( ret )) { if ( ret == SQL_NO_DATA ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_SL004, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); } else { SQLCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; int rec = 1; /* * get the error from the driver before * loseing the connection */ do { if ( CHECK_SQLERROR( cl_connection )) { ret = SQLERROR( cl_connection, SQL_NULL_HENV, SQL_NULL_HSTMT, cl_statement -> fetch_statement, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); } else if ( CHECK_SQLGETDIAGREC( cl_connection )) { ret = SQLGETDIAGREC( cl_connection, SQL_HANDLE_STMT, cl_statement -> fetch_statement, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); } else { ret = SQL_NO_DATA; } if ( ret != SQL_NO_DATA ) { cl_statement -> cl_connection -> dh.__post_internal_error_ex( &cl_statement -> dm_statement -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } } while ( SQL_SUCCEEDED( ret )); } SQLFREESTMT( cl_connection, cl_statement -> fetch_statement, SQL_DROP ); cl_statement -> fetch_statement = SQL_NULL_HSTMT; return SQL_ERROR; } ret = SQLGETDATA( cl_connection, cl_statement -> fetch_statement, column_number, target_type, target_value, buffer_length, strlen_or_ind ); if ( !SQL_SUCCEEDED( ret )) { SQLCHAR sqlstate[ 6 ]; SQLINTEGER native_error; SQLSMALLINT ind; SQLCHAR message_text[ SQL_MAX_MESSAGE_LENGTH + 1 ]; SQLRETURN ret; int rec = 1; /* * get the error from the driver before * loseing the connection */ do { if ( CHECK_SQLERROR( cl_connection )) { ret = SQLERROR( cl_connection, SQL_NULL_HENV, SQL_NULL_HSTMT, cl_statement -> fetch_statement, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); } else if ( CHECK_SQLGETDIAGREC( cl_connection )) { ret = SQLGETDIAGREC( cl_connection, SQL_HANDLE_STMT, cl_statement -> fetch_statement, rec ++, sqlstate, &native_error, message_text, sizeof( message_text ), &ind ); } else { ret = SQL_NO_DATA; } if ( ret != SQL_NO_DATA ) { cl_statement -> cl_connection -> dh.__post_internal_error_ex( &cl_statement -> dm_statement -> error, sqlstate, native_error, message_text, SUBCLASS_ODBC, SUBCLASS_ODBC ); } } while ( SQL_SUCCEEDED( ret )); } if ( !SQL_SUCCEEDED( ret )) { SQLFREESTMT( cl_connection, cl_statement -> fetch_statement, SQL_DROP ); cl_statement -> fetch_statement = SQL_NULL_HSTMT; } return ret; } unixODBC-2.3.12/cur/SQLGetDescField.c000066400000000000000000000037571446441710500170330ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetDescField.c,v 1.3 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLGetDescField.c,v $ * Revision 1.3 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2005/09/05 09:49:48 lurcher * New QT detection macros added * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLGetDescField( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT field_identifier, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { return SQL_ERROR; } unixODBC-2.3.12/cur/SQLGetDescRec.c000066400000000000000000000042071446441710500165100ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetDescRec.c,v 1.3 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLGetDescRec.c,v $ * Revision 1.3 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2005/09/05 09:49:48 lurcher * New QT detection macros added * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLGetDescRec( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLCHAR *name, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLSMALLINT *type, SQLSMALLINT *sub_type, SQLINTEGER *length, SQLSMALLINT *precision, SQLSMALLINT *scale, SQLSMALLINT *nullable ) { return SQL_ERROR; } unixODBC-2.3.12/cur/SQLGetDiagField.c000066400000000000000000000037141446441710500170120ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetDiagField.c,v 1.2 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLGetDiagField.c,v $ * Revision 1.2 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLGetDiagField( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT rec_number, SQLSMALLINT diag_identifier, SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length, SQLSMALLINT *string_length_ptr ) { /* * todo */ return SQL_ERROR; } unixODBC-2.3.12/cur/SQLGetDiagRec.c000066400000000000000000000061751446441710500165040ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetDiagRec.c,v 1.7 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLGetDiagRec.c,v $ * Revision 1.7 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.6 2009/02/17 09:47:45 lurcher * Clear up a number of bugs * * Revision 1.5 2008/01/02 15:10:33 lurcher * Fix problems trying to use the cursor lib on a non select statement * * Revision 1.4 2007/02/12 11:49:35 lurcher * Add QT4 support to existing GUI parts * * Revision 1.3 2005/08/26 09:31:39 lurcher * Add call to allow the cursor lib to call SQLGetDiagRec * * Revision 1.2 2004/07/24 20:00:39 peteralexharvey * for OS2 port * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLGetDiagRec( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT rec_number, SQLCHAR *sqlstate, SQLINTEGER *native, SQLCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length_ptr ) { CLHDBC cl_connection = (CLHDBC) handle; DRV_SQLHANDLE dhandle; switch(handle_type) { case SQL_HANDLE_ENV: { return SQL_NO_DATA; } case SQL_HANDLE_DBC: { dhandle = cl_connection->driver_dbc; break; } case SQL_HANDLE_STMT: { CLHSTMT cl_statement = (CLHSTMT)handle; cl_connection = cl_statement->cl_connection; if ( cl_statement -> driver_stmt_closed ) { return SQL_NO_DATA; } dhandle = cl_statement->driver_stmt; break; } } return SQLGETDIAGREC(cl_connection, handle_type, dhandle, rec_number, sqlstate, native, message_text, buffer_length, text_length_ptr); } unixODBC-2.3.12/cur/SQLGetInfo.c000066400000000000000000000133201446441710500160670ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetInfo.c,v 1.2 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLGetInfo.c,v $ * Revision 1.2 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLGetInfo( SQLHDBC connection_handle, SQLUSMALLINT info_type, SQLPOINTER info_value, SQLSMALLINT buffer_length, SQLSMALLINT *string_length ) { CLHDBC cl_connection = (CLHDBC) connection_handle; int do_it_here = 1; SQLUINTEGER value; SQLRETURN ret; char *cval = NULL; switch( info_type ) { case SQL_BOOKMARK_PERSISTENCE: value = 0; break; case SQL_DYNAMIC_CURSOR_ATTRIBUTES1: value = 0; break; case SQL_DYNAMIC_CURSOR_ATTRIBUTES2: value = 0; break; case SQL_FETCH_DIRECTION: value = SQL_FD_FETCH_ABSOLUTE | SQL_FD_FETCH_FIRST | SQL_FD_FETCH_LAST | SQL_FD_FETCH_NEXT | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_RELATIVE | SQL_FD_FETCH_BOOKMARK; break; case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1: value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE | SQL_CA1_RELATIVE | SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION | SQL_CA1_POSITIONED_DELETE | SQL_CA1_POSITIONED_UPDATE | SQL_CA1_SELECT_FOR_UPDATE; break; case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2: value = SQL_CA2_READ_ONLY_CONCURRENCY | SQL_CA2_OPT_VALUES_CONCURRENCY | SQL_CA2_SENSITIVITY_UPDATES; break; case SQL_KEYSET_CURSOR_ATTRIBUTES1: value = 0; break; case SQL_KEYSET_CURSOR_ATTRIBUTES2: value = 0; break; case SQL_LOCK_TYPES: value = SQL_LCK_NO_CHANGE; break; case SQL_STATIC_CURSOR_ATTRIBUTES1: value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE | SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION | SQL_CA1_POSITIONED_DELETE | SQL_CA1_POSITIONED_UPDATE | SQL_CA1_SELECT_FOR_UPDATE; break; case SQL_STATIC_CURSOR_ATTRIBUTES2: value = SQL_CA2_READ_ONLY_CONCURRENCY | SQL_CA2_OPT_VALUES_CONCURRENCY | SQL_CA2_SENSITIVITY_UPDATES; break; case SQL_POS_OPERATIONS: value = SQL_POS_POSITION; break; case SQL_POSITIONED_STATEMENTS: value = SQL_PS_POSITIONED_DELETE | SQL_PS_POSITIONED_UPDATE | SQL_PS_SELECT_FOR_UPDATE; break; case SQL_ROW_UPDATES: cval = "Y"; break; case SQL_SCROLL_CONCURRENCY: value = SQL_SCCO_READ_ONLY | SQL_SCCO_OPT_VALUES; break; case SQL_SCROLL_OPTIONS: value = SQL_SO_FORWARD_ONLY | SQL_SO_STATIC; break; case SQL_STATIC_SENSITIVITY: value = SQL_SS_UPDATES; break; default: do_it_here = 0; break; } if ( do_it_here ) { if ( cval ) { if ( buffer_length > 2 && info_value ) { strcpy( info_value, cval ); ret = SQL_SUCCESS; } else { ret = SQL_SUCCESS_WITH_INFO; } if ( string_length ) { *string_length = 1; } } else { *((SQLINTEGER*)info_value) = value; ret = SQL_SUCCESS; } } else { ret = SQLGETINFO( cl_connection, cl_connection -> driver_dbc, info_type, info_value, buffer_length, string_length ); if ( SQL_SUCCEEDED( ret )) { if ( info_type == SQL_GETDATA_EXTENSIONS && info_value ) { *((SQLINTEGER*)info_value) |= SQL_GD_BLOCK; } } } return ret; } unixODBC-2.3.12/cur/SQLGetStmtAttr.c000066400000000000000000000101541446441710500167600ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetStmtAttr.c,v 1.5 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLGetStmtAttr.c,v $ * Revision 1.5 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.4 2009/02/17 09:47:45 lurcher * Clear up a number of bugs * * Revision 1.3 2005/10/27 17:54:49 lurcher * fix what I suspect is a typo in qt.m4 * * Revision 1.2 2003/12/01 16:37:17 lurcher * * Fix a bug in SQLWritePrivateProfileString * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/12/04 17:01:26 ngorham * * Remove C++ comments from the Postgres code * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLGetStmtAttr( SQLHSTMT statement_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; switch( attribute ) { case SQL_ATTR_CONCURRENCY: *(( SQLUINTEGER * ) value ) = cl_statement -> concurrency; break; case SQL_ATTR_CURSOR_TYPE: *(( SQLUINTEGER * ) value ) = cl_statement -> cursor_type; break; case SQL_ATTR_PARAM_BIND_OFFSET_PTR: *(( SQLPOINTER * ) value ) = cl_statement -> param_bind_offset_ptr; break; case SQL_ATTR_PARAM_BIND_TYPE: *(( SQLUINTEGER * ) value ) = cl_statement -> param_bind_type; break; case SQL_ATTR_ROW_BIND_OFFSET_PTR: *(( SQLPOINTER * ) value ) = cl_statement -> row_bind_offset_ptr; break; case SQL_ATTR_ROW_BIND_TYPE: *(( SQLUINTEGER * ) value ) = cl_statement -> row_bind_type; break; case SQL_ATTR_ROW_ARRAY_SIZE: *(( SQLUINTEGER * ) value ) = cl_statement -> rowset_array_size; break; case SQL_ROWSET_SIZE: *(( SQLUINTEGER * ) value ) = cl_statement -> rowset_size; break; case SQL_ATTR_SIMULATE_CURSOR: *(( SQLUINTEGER * ) value ) = cl_statement -> simulate_cursor; break; case SQL_ATTR_USE_BOOKMARKS: *(( SQLULEN * ) value ) = cl_statement -> use_bookmarks; break; case SQL_ATTR_ROW_STATUS_PTR: *(( SQLUSMALLINT ** ) value ) = cl_statement -> row_status_ptr; break; case SQL_ATTR_ROWS_FETCHED_PTR: *(( SQLULEN ** ) value ) = cl_statement -> rows_fetched_ptr; break; case SQL_ATTR_FETCH_BOOKMARK_PTR: *(( SQLPOINTER * ) value ) = cl_statement -> fetch_bookmark_ptr; break; default: return SQLGETSTMTATTR( cl_statement -> cl_connection, cl_statement -> driver_stmt, attribute, value, buffer_length, string_length ); } return SQL_SUCCESS; } unixODBC-2.3.12/cur/SQLGetStmtOption.c000066400000000000000000000073741446441710500173300ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetStmtOption.c,v 1.4 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLGetStmtOption.c,v $ * Revision 1.4 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2009/02/17 09:47:45 lurcher * Clear up a number of bugs * * Revision 1.2 2005/10/27 17:54:49 lurcher * fix what I suspect is a typo in qt.m4 * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLGetStmtOption( SQLHSTMT statement_handle, SQLUSMALLINT option, SQLPOINTER value ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; switch( option ) { case SQL_CONCURRENCY: *(( SQLUINTEGER * ) value ) = cl_statement -> concurrency; break; case SQL_CURSOR_TYPE: *(( SQLUINTEGER * ) value ) = cl_statement -> cursor_type; break; case SQL_BIND_TYPE: *(( SQLUINTEGER * ) value ) = cl_statement -> row_bind_type; break; case SQL_GET_BOOKMARK: *(( SQLUINTEGER * ) value ) = cl_statement -> use_bookmarks; break; case SQL_ROWSET_SIZE: *(( SQLUINTEGER * ) value ) = cl_statement -> rowset_size; break; case SQL_SIMULATE_CURSOR: *(( SQLUINTEGER * ) value ) = cl_statement -> simulate_cursor; break; case SQL_ATTR_PARAM_BIND_OFFSET_PTR: *(( SQLPOINTER * ) value ) = cl_statement -> param_bind_offset_ptr; break; case SQL_ATTR_PARAM_BIND_TYPE: *(( SQLUINTEGER * ) value ) = cl_statement -> concurrency; break; case SQL_ATTR_ROW_BIND_OFFSET_PTR: *(( SQLPOINTER * ) value ) = cl_statement -> row_bind_offset_ptr; break; case SQL_ATTR_ROW_ARRAY_SIZE: *(( SQLUINTEGER * ) value ) = cl_statement -> rowset_array_size; break; case SQL_ATTR_ROW_STATUS_PTR: *(( SQLUSMALLINT ** ) value ) = cl_statement -> row_status_ptr; break; case SQL_ATTR_ROWS_FETCHED_PTR: *(( SQLULEN ** ) value ) = cl_statement -> rows_fetched_ptr; break; case SQL_ATTR_USE_BOOKMARKS: *(( SQLUINTEGER * ) value ) = cl_statement -> use_bookmarks; break; default: return SQLGETSTMTOPTION( cl_statement -> cl_connection, cl_statement -> driver_stmt, option, value ); } return SQL_SUCCESS; } unixODBC-2.3.12/cur/SQLGetTypeInfo.c000066400000000000000000000044021446441710500167320ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLGetTypeInfo.c,v 1.3 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLGetTypeInfo.c,v $ * Revision 1.3 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2005/07/08 12:11:24 lurcher * * Fix a cursor lib problem (it was broken if you did metadata calls) * Alter the params to SQLParamOptions to use SQLULEN * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/09/23 21:46:37 ngorham * * Added cursor support for metadata functions * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLGetTypeInfo( SQLHSTMT statement_handle, SQLSMALLINT data_type ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLGETTYPEINFO( cl_statement -> cl_connection, cl_statement -> driver_stmt, data_type ); cl_statement -> not_from_select = 1; return ret; } unixODBC-2.3.12/cur/SQLMoreResults.c000066400000000000000000000046131446441710500170250ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLMoreResults.c,v 1.3 2009/02/18 17:59:17 lurcher Exp $ * * $Log: SQLMoreResults.c,v $ * Revision 1.3 2009/02/18 17:59:17 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2008/11/03 14:53:29 lurcher * Allow cursor lib to handle multiple result sets * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLMoreResults( SQLHSTMT statement_handle ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLMORERESULTS( cl_statement -> cl_connection, cl_statement -> driver_stmt ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLNativeSql.c000066400000000000000000000043331446441710500164460ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLNativeSql.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLNativeSql.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLNativeSql( SQLHDBC connection_handle, SQLCHAR *sz_sql_str_in, SQLINTEGER cb_sql_str_in, SQLCHAR *sz_sql_str, SQLINTEGER cb_sql_str_max, SQLINTEGER *pcb_sql_str ) { CLHDBC cl_connection = (CLHDBC) connection_handle; /* * the cursor lib will take a part in this */ return SQLNATIVESQL( cl_connection, cl_connection -> driver_dbc, sz_sql_str_in, cb_sql_str_in, sz_sql_str, cb_sql_str_max, pcb_sql_str ); } unixODBC-2.3.12/cur/SQLNumParams.c000066400000000000000000000036431446441710500164460ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLNumParams.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLNumParams.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLNumParams( SQLHSTMT statement_handle, SQLSMALLINT *pcpar ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; return SQLNUMPARAMS( cl_statement -> cl_connection, cl_statement -> driver_stmt, pcpar ); } unixODBC-2.3.12/cur/SQLNumResultCols.c000066400000000000000000000036611446441710500173220ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLNumResultCols.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLNumResultCols.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLNumResultCols( SQLHSTMT statement_handle, SQLSMALLINT *column_count ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; return SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, column_count ); } unixODBC-2.3.12/cur/SQLParamData.c000066400000000000000000000037331446441710500163750ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLParamData.c,v 1.3 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLParamData.c,v $ * Revision 1.3 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2004/03/15 09:23:59 lurcher * * Add SQL_NULL_DESC * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLParamData( SQLHSTMT statement_handle, SQLPOINTER *value ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; return SQLPARAMDATA( cl_statement -> cl_connection, cl_statement -> driver_stmt, value ); } unixODBC-2.3.12/cur/SQLParamOptions.c000066400000000000000000000040541446441710500171540ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLParamOptions.c,v 1.3 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLParamOptions.c,v $ * Revision 1.3 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2007/02/12 11:49:35 lurcher * Add QT4 support to existing GUI parts * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLParamOptions( SQLHSTMT statement_handle, SQLULEN crow, SQLULEN *pirow ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; return SQLPARAMOPTIONS( cl_statement -> cl_connection, cl_statement -> driver_stmt, crow, pirow ); } unixODBC-2.3.12/cur/SQLPrepare.c000066400000000000000000000052401446441710500161340ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLPrepare.c,v 1.3 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLPrepare.c,v $ * Revision 1.3 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2001/12/13 13:00:33 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLPrepare( SQLHSTMT statement_handle, SQLCHAR *statement_text, SQLINTEGER text_length ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; /* * save the statement for later use */ if ( cl_statement -> sql_text ) { free( cl_statement -> sql_text ); } if ( text_length < 0 ) { cl_statement -> sql_text = strdup((char*) statement_text ); } else { cl_statement -> sql_text = malloc( text_length + 1 ); memcpy( cl_statement -> sql_text, statement_text, text_length ); cl_statement -> sql_text[ text_length ] = '\0'; } return SQLPREPARE( cl_statement -> cl_connection, cl_statement -> driver_stmt, statement_text, text_length ); } unixODBC-2.3.12/cur/SQLPrimaryKeys.c000066400000000000000000000055371446441710500170260ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLPrimaryKeys.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLPrimaryKeys.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/09/23 21:46:37 ngorham * * Added cursor support for metadata functions * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLPrimaryKeys( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_table_name, SQLSMALLINT cb_table_name ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLPRIMARYKEYS( cl_statement -> cl_connection, cl_statement -> driver_stmt, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_table_name, cb_table_name ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; cl_statement -> not_from_select = 1; if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLProcedureColumns.c000066400000000000000000000057661446441710500200440ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLProcedureColumns.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLProcedureColumns.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/09/23 21:46:37 ngorham * * Added cursor support for metadata functions * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLProcedureColumns( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_proc_name, SQLSMALLINT cb_proc_name, SQLCHAR *sz_column_name, SQLSMALLINT cb_column_name ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLPROCEDURECOLUMNS( cl_statement -> cl_connection, cl_statement -> driver_stmt, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_proc_name, cb_proc_name, sz_column_name, cb_column_name ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; cl_statement -> not_from_select = 1; if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLProcedures.c000066400000000000000000000055271446441710500166610ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLProcedures.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLProcedures.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/09/23 21:46:37 ngorham * * Added cursor support for metadata functions * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLProcedures( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_proc_name, SQLSMALLINT cb_proc_name ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLPROCEDURES( cl_statement -> cl_connection, cl_statement -> driver_stmt, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_proc_name, cb_proc_name ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; cl_statement -> not_from_select = 1; if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLPutData.c000066400000000000000000000037061446441710500161050ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLPutData.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLPutData.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLPutData( SQLHSTMT statement_handle, SQLPOINTER data, SQLINTEGER strlen_or_ind ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; return SQLPUTDATA( cl_statement -> cl_connection, cl_statement -> driver_stmt, data, strlen_or_ind ); } unixODBC-2.3.12/cur/SQLRowCount.c000066400000000000000000000046621446441710500163250ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLRowCount.c,v 1.4 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLRowCount.c,v $ * Revision 1.4 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2007/02/12 11:49:35 lurcher * Add QT4 support to existing GUI parts * * Revision 1.2 2001/12/13 13:00:33 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLRowCount( SQLHSTMT statement_handle, SQLLEN *rowcount ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; if ( cl_statement -> first_fetch_done ) { if ( rowcount ) { *rowcount = cl_statement -> rowset_count; } return SQL_SUCCESS; } else { return DEF_SQLROWCOUNT( cl_statement -> cl_connection, cl_statement -> driver_stmt, rowcount ); } } unixODBC-2.3.12/cur/SQLSetConnectAttr.c000066400000000000000000000040131446441710500174330ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetConnectAttr.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLSetConnectAttr.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLSetConnectAttr( SQLHDBC connection_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length ) { CLHDBC cl_connection = (CLHDBC) connection_handle; return SQLSETCONNECTATTR( cl_connection, cl_connection -> driver_dbc, attribute, value, string_length ); } unixODBC-2.3.12/cur/SQLSetConnectOption.c000066400000000000000000000040321446441710500177720ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetConnectOption.c,v 1.3 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLSetConnectOption.c,v $ * Revision 1.3 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2003/03/05 09:48:45 lurcher * * Add some 64 bit fixes * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLSetConnectOption( SQLHDBC connection_handle, SQLUSMALLINT option, SQLULEN value ) { CLHDBC cl_connection = (CLHDBC) connection_handle; return SQLSETCONNECTOPTION( cl_connection, cl_connection -> driver_dbc, option, value ); } unixODBC-2.3.12/cur/SQLSetCursorName.c000066400000000000000000000067461446441710500173040ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetCursorName.c,v 1.4 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLSetCursorName.c,v $ * Revision 1.4 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.2 2001/12/13 13:00:33 lurcher * * Remove most if not all warnings on 64 bit platforms * Add support for new MS 3.52 64 bit changes * Add override to disable the stopping of tracing * Add MAX_ROWS support in postgres driver * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLSetCursorName( SQLHSTMT statement_handle, SQLCHAR *cursor_name, SQLSMALLINT name_length ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret = SQL_SUCCESS; if ( name_length == SQL_NTS ) { if ( strlen((char*) cursor_name ) > MAX_CURSOR_NAME ) { memcpy( cl_statement -> cursor_name, cursor_name, MAX_CURSOR_NAME ); cl_statement -> cursor_name[ MAX_CURSOR_NAME ] = '\0'; ret = SQL_SUCCESS_WITH_INFO; } else { strcpy((char*) cl_statement -> cursor_name, (char*) cursor_name ); } } else { if ( name_length > MAX_CURSOR_NAME ) { memcpy( cl_statement -> cursor_name, cursor_name, MAX_CURSOR_NAME ); cl_statement -> cursor_name[ MAX_CURSOR_NAME ] = '\0'; ret = SQL_SUCCESS_WITH_INFO; } else { memcpy( cl_statement -> cursor_name, cursor_name, name_length ); cl_statement -> cursor_name[ name_length ] = '\0'; } } if ( ret == SQL_SUCCESS_WITH_INFO ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_01004, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); } return ret; } unixODBC-2.3.12/cur/SQLSetDescField.c000066400000000000000000000036231446441710500170370ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetDescField.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLSetDescField.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLSetDescField( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT field_identifier, SQLPOINTER value, SQLINTEGER buffer_length ) { /* * todo */ return SQL_ERROR; } unixODBC-2.3.12/cur/SQLSetDescRec.c000066400000000000000000000041501446441710500165210ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetDescRec.c,v 1.3 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLSetDescRec.c,v $ * Revision 1.3 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:50 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLSetDescRec( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT type, SQLSMALLINT subtype, SQLLEN length, SQLSMALLINT precision, SQLSMALLINT scale, SQLPOINTER data, SQLLEN *string_length, SQLLEN *indicator ) { /* * todo */ return SQL_ERROR; } unixODBC-2.3.12/cur/SQLSetParam.c000066400000000000000000000045771446441710500162660ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetParam.c,v 1.3 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLSetParam.c,v $ * Revision 1.3 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:51 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLSetParam( SQLHSTMT statement_handle, SQLUSMALLINT parameter_number, SQLSMALLINT value_type, SQLSMALLINT parameter_type, SQLULEN length_precision, SQLSMALLINT parameter_scale, SQLPOINTER parameter_value, SQLLEN *strlen_or_ind ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; return SQLSETPARAM( cl_statement -> cl_connection, cl_statement -> driver_stmt, parameter_number, value_type, parameter_type, length_precision, parameter_scale, parameter_value, strlen_or_ind ); } unixODBC-2.3.12/cur/SQLSetPos.c000066400000000000000000000063051446441710500157560ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetPos.c,v 1.4 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLSetPos.c,v $ * Revision 1.4 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.3 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.2 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:51 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLSetPos( SQLHSTMT statement_handle, SQLSETPOSIROW irow, SQLUSMALLINT foption, SQLUSMALLINT flock ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; /* * this is implemented by the cursor lib */ if ( irow == 0 ) { /* * one day maybe, but what do you want, blood ? */ cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_HYC00, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); } else if ( irow > cl_statement -> rowset_array_size ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1107, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); } else if ( foption != SQL_POSITION || flock != SQL_LOCK_NO_CHANGE ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_HYC00, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); } cl_statement -> cursor_pos = irow; return SQL_SUCCESS; } unixODBC-2.3.12/cur/SQLSetScrollOptions.c000066400000000000000000000064171446441710500200330ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetScrollOptions.c,v 1.5 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLSetScrollOptions.c,v $ * Revision 1.5 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.4 2007/11/13 15:04:57 lurcher * Fix 64 bit cursor lib issues * * Revision 1.3 2005/10/27 17:54:49 lurcher * fix what I suspect is a typo in qt.m4 * * Revision 1.2 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/10/03 23:05:17 ngorham * * First public outing of the cursor lib * * Revision 1.1 1999/09/19 22:22:51 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLSetScrollOptions( SQLHSTMT statement_handle, SQLUSMALLINT f_concurrency, SQLLEN crow_keyset, SQLUSMALLINT crow_rowset ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; if ( crow_keyset != SQL_SCROLL_FORWARD_ONLY && crow_keyset != SQL_SCROLL_STATIC ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1107, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } if ( f_concurrency != SQL_CONCUR_READ_ONLY && f_concurrency != SQL_CONCUR_VALUES ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_S1108, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); return SQL_ERROR; } cl_statement -> cursor_type = crow_keyset; cl_statement -> concurrency = f_concurrency; cl_statement -> rowset_array_size = crow_rowset; cl_statement -> rowset_size = crow_rowset; return SQL_SUCCESS; } unixODBC-2.3.12/cur/SQLSetStmtAttr.c000066400000000000000000000127631446441710500170040ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetStmtAttr.c,v 1.8 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLSetStmtAttr.c,v $ * Revision 1.8 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.7 2009/02/17 09:47:45 lurcher * Clear up a number of bugs * * Revision 1.6 2005/10/27 17:54:49 lurcher * fix what I suspect is a typo in qt.m4 * * Revision 1.5 2003/12/01 16:37:17 lurcher * * Fix a bug in SQLWritePrivateProfileString * * Revision 1.4 2003/10/30 18:20:46 lurcher * * Fix broken thread protection * Remove SQLNumResultCols after execute, lease S4/S% to driver * Fix string overrun in SQLDriverConnect * Add initial support for Interix * * Revision 1.3 2003/03/05 09:48:45 lurcher * * Add some 64 bit fixes * * Revision 1.2 2002/11/19 18:52:28 lurcher * * Alter the cursor lib to not require linking to the driver manager. * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:51 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLSetStmtAttr( SQLHSTMT statement_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLUINTEGER val; SQLRETURN ret = SQL_SUCCESS; switch( attribute ) { case SQL_ATTR_CONCURRENCY: val = ( SQLULEN ) value; if ( cl_statement -> concurrency == SQL_CURSOR_FORWARD_ONLY ) { if ( val != SQL_CONCUR_READ_ONLY ) { ret = SQL_SUCCESS_WITH_INFO; } } else { if ( val != SQL_CONCUR_READ_ONLY && val != SQL_CONCUR_VALUES ) { ret = SQL_SUCCESS_WITH_INFO; } } if ( ret == SQL_SUCCESS ) { cl_statement -> concurrency = ( SQLULEN ) value; } break; case SQL_ATTR_CURSOR_TYPE: val = ( SQLULEN ) value; if ( val != SQL_CURSOR_FORWARD_ONLY && val != SQL_CURSOR_STATIC ) { ret = SQL_SUCCESS_WITH_INFO; } else { cl_statement -> cursor_type = ( SQLULEN ) value; } break; case SQL_ATTR_PARAM_BIND_OFFSET_PTR: cl_statement -> param_bind_offset_ptr = ( SQLPOINTER ) value; break; case SQL_ATTR_PARAM_BIND_TYPE: cl_statement -> concurrency = ( SQLULEN ) value; break; case SQL_ATTR_ROW_BIND_OFFSET_PTR: cl_statement -> row_bind_offset_ptr = ( SQLPOINTER ) value; break; case SQL_ATTR_ROW_BIND_TYPE: cl_statement -> row_bind_type = ( SQLULEN ) value; break; case SQL_ATTR_ROW_ARRAY_SIZE: cl_statement -> rowset_array_size = ( SQLULEN ) value; break; case SQL_ROWSET_SIZE: cl_statement -> rowset_size = ( SQLULEN ) value; break; case SQL_ATTR_ROW_STATUS_PTR: cl_statement -> row_status_ptr = ( SQLUSMALLINT * ) value; break; case SQL_ATTR_ROWS_FETCHED_PTR: cl_statement -> rows_fetched_ptr = ( SQLULEN * ) value; break; case SQL_ATTR_SIMULATE_CURSOR: val = ( SQLULEN ) value; if ( val != SQL_SC_NON_UNIQUE ) { ret = SQL_SUCCESS_WITH_INFO; } else { cl_statement -> simulate_cursor = ( SQLULEN ) value; } break; case SQL_ATTR_USE_BOOKMARKS: cl_statement -> use_bookmarks = ( SQLULEN ) value; break; case SQL_ATTR_FETCH_BOOKMARK_PTR: cl_statement -> fetch_bookmark_ptr = ( SQLPOINTER ) value; break; default: return SQLSETSTMTATTR( cl_statement -> cl_connection, cl_statement -> driver_stmt, attribute, value, string_length ); } if ( ret == SQL_SUCCESS_WITH_INFO ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_01S02, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); } return ret; } unixODBC-2.3.12/cur/SQLSetStmtOption.c000066400000000000000000000121261446441710500173330ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSetStmtOption.c,v 1.6 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLSetStmtOption.c,v $ * Revision 1.6 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.5 2009/02/17 09:47:45 lurcher * Clear up a number of bugs * * Revision 1.4 2005/10/27 17:54:49 lurcher * fix what I suspect is a typo in qt.m4 * * Revision 1.3 2005/05/03 17:16:50 lurcher * Backport a couple of changes from the Debian build * * Revision 1.2 2003/03/05 09:48:45 lurcher * * Add some 64 bit fixes * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:51 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLSetStmtOption( SQLHSTMT statement_handle, SQLUSMALLINT option, SQLULEN value ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLUINTEGER val; SQLRETURN ret = SQL_SUCCESS; switch( option ) { case SQL_CONCURRENCY: val = ( SQLUINTEGER ) value; if ( cl_statement -> concurrency == SQL_CURSOR_FORWARD_ONLY ) { if ( val != SQL_CONCUR_READ_ONLY ) { ret = SQL_SUCCESS_WITH_INFO; } } else { if ( val != SQL_CONCUR_READ_ONLY && val != SQL_CONCUR_VALUES ) { ret = SQL_SUCCESS_WITH_INFO; } } if ( ret == SQL_SUCCESS ) { cl_statement -> concurrency = ( SQLUINTEGER ) value; } break; case SQL_CURSOR_TYPE: val = ( SQLUINTEGER ) value; if ( val != SQL_CURSOR_FORWARD_ONLY && val != SQL_CURSOR_TYPE ) { ret = SQL_SUCCESS_WITH_INFO; } else { cl_statement -> cursor_type = ( SQLUINTEGER ) value; } break; case SQL_BIND_TYPE: cl_statement -> row_bind_type = ( SQLUINTEGER ) value; break; case SQL_GET_BOOKMARK: cl_statement -> use_bookmarks = ( SQLUINTEGER ) value; break; case SQL_ROWSET_SIZE: cl_statement -> rowset_size = ( SQLUINTEGER ) value; break; case SQL_SIMULATE_CURSOR: val = ( SQLUINTEGER ) value; if ( val != SQL_SC_NON_UNIQUE ) { ret = SQL_SUCCESS_WITH_INFO; } else { cl_statement -> simulate_cursor = ( SQLUINTEGER ) value; } break; case SQL_ATTR_PARAM_BIND_OFFSET_PTR: cl_statement -> param_bind_offset_ptr = ( SQLPOINTER ) value; break; case SQL_ATTR_PARAM_BIND_TYPE: cl_statement -> concurrency = ( SQLUINTEGER ) value; break; case SQL_ATTR_ROW_BIND_OFFSET_PTR: cl_statement -> row_bind_offset_ptr = ( SQLPOINTER ) value; break; case SQL_ATTR_ROW_ARRAY_SIZE: cl_statement -> rowset_array_size = ( SQLUINTEGER ) value; break; case SQL_ATTR_ROW_STATUS_PTR: cl_statement -> row_status_ptr = ( SQLUSMALLINT * ) value; break; case SQL_ATTR_ROWS_FETCHED_PTR: cl_statement -> rows_fetched_ptr = ( SQLULEN * ) value; break; case SQL_ATTR_USE_BOOKMARKS: cl_statement -> use_bookmarks = ( SQLUINTEGER ) value; break; default: return SQLSETSTMTOPTION( cl_statement -> cl_connection, cl_statement -> driver_stmt, option, value ); } if ( ret == SQL_SUCCESS_WITH_INFO ) { cl_statement -> cl_connection -> dh.__post_internal_error( &cl_statement -> dm_statement -> error, ERROR_01S02, NULL, cl_statement -> dm_statement -> connection -> environment -> requested_version ); } return ret; } unixODBC-2.3.12/cur/SQLSpecialColumns.c000066400000000000000000000057311446441710500174640ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLSpecialColumns.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLSpecialColumns.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/09/23 21:46:37 ngorham * * Added cursor support for metadata functions * * Revision 1.1 1999/09/19 22:22:51 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLSpecialColumns( SQLHSTMT statement_handle, SQLUSMALLINT identifier_type, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLUSMALLINT scope, SQLUSMALLINT nullable ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLSPECIALCOLUMNS( cl_statement -> cl_connection, cl_statement -> driver_stmt, identifier_type, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, scope, nullable ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; cl_statement -> not_from_select = 1; if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLStatistics.c000066400000000000000000000056061446441710500166760ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLStatistics.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLStatistics.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/09/23 21:46:37 ngorham * * Added cursor support for metadata functions * * Revision 1.1 1999/09/19 22:22:51 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLStatistics( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLUSMALLINT unique, SQLUSMALLINT reserved ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLSTATISTICS( cl_statement -> cl_connection, cl_statement -> driver_stmt, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, unique, reserved ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; cl_statement -> not_from_select = 1; if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLTablePrivileges.c000066400000000000000000000055571446441710500176320ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLTablePrivileges.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLTablePrivileges.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/09/23 21:46:37 ngorham * * Added cursor support for metadata functions * * Revision 1.1 1999/09/19 22:22:51 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLTablePrivileges( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_table_name, SQLSMALLINT cb_table_name ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLTABLEPRIVILEGES( cl_statement -> cl_connection, cl_statement -> driver_stmt, sz_catalog_name, cb_catalog_name, sz_schema_name, cb_schema_name, sz_table_name, cb_table_name ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; cl_statement -> not_from_select = 1; if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLTables.c000066400000000000000000000056011446441710500157510ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLTables.c,v 1.2 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLTables.c,v $ * Revision 1.2 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.2 1999/09/23 21:46:37 ngorham * * Added cursor support for metadata functions * * Revision 1.1 1999/09/19 22:22:51 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLTables( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLCHAR *table_type, SQLSMALLINT name_length4 ) { CLHSTMT cl_statement = (CLHSTMT) statement_handle; SQLRETURN ret; ret = SQLTABLES( cl_statement -> cl_connection, cl_statement -> driver_stmt, catalog_name, name_length1, schema_name, name_length2, table_name, name_length3, table_type, name_length4 ); if ( SQL_SUCCEEDED( ret )) { SQLSMALLINT column_count; ret = SQLNUMRESULTCOLS( cl_statement -> cl_connection, cl_statement -> driver_stmt, &column_count ); cl_statement -> column_count = column_count; cl_statement -> first_fetch_done = 0; cl_statement -> not_from_select = 1; if ( column_count > 0 ) { ret = get_column_names( cl_statement ); } } return ret; } unixODBC-2.3.12/cur/SQLTransact.c000066400000000000000000000044651446441710500163250ustar00rootroot00000000000000/********************************************************************* * * unixODBC Cursor Library * * Created by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: SQLTransact.c,v 1.3 2009/02/18 17:59:18 lurcher Exp $ * * $Log: SQLTransact.c,v $ * Revision 1.3 2009/02/18 17:59:18 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.2 2005/07/25 16:11:22 lurcher * Fix swapped about args in the cursor lib * * Revision 1.1.1.1 2001/10/17 16:40:15 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:52 nick * Imported Sources * * Revision 1.1 1999/09/19 22:22:51 ngorham * * * Added first cursor library work, read only at the moment and only works * with selects with no where clause * * **********************************************************************/ #include #include "cursorlibrary.h" SQLRETURN CLTransact( SQLHENV environment_handle, SQLHDBC connection_handle, SQLUSMALLINT completion_type ) { if ( environment_handle ) { /* * the driver manager will not call this */ return SQL_ERROR; } else if ( connection_handle ) { CLHDBC cl_connection = (CLHDBC) connection_handle; return SQLTRANSACT( cl_connection, SQL_NULL_HENV, cl_connection -> driver_dbc, completion_type ); } else { return SQL_ERROR; } } unixODBC-2.3.12/cur/cur.exp000066400000000000000000000000121446441710500153110ustar00rootroot00000000000000CLConnect unixODBC-2.3.12/cur/cursorlibrary.h000066400000000000000000000453731446441710500171000ustar00rootroot00000000000000#ifndef _CURSORLIBRARY_H #define _CURSORLIBRARY_H #ifndef ODBCVER #define ODBCVER 0x0380 #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_PWD_H #include #endif #include #ifdef HAVE_STRING_H #include #endif #include /* THIS WILL BRING IN sql.h and sqltypes.h AS WELL AS PROVIDE MS EXTENSIONS */ #define MAX_CURSOR_NAME 18 /* * cursor positions */ #define CL_BEFORE_START -1 #define CL_AFTER_END -2 #include "drivermanager.h" typedef struct bound_column { struct bound_column *next; int column_number; SQLLEN len_ind; SQLPOINTER local_buffer; /* buffer that the CL binds in */ /* the driver (malloc'd) */ SQLPOINTER bound_buffer; /* buffer that the app binds */ SQLINTEGER bound_type; /* data type of binding */ SQLLEN bound_length; /* length of binding */ SQLLEN *bound_ind; /* ind ptr bound */ int rs_buffer_offset; int rs_ind_offset; /* offset onto the current rowset */ /* buffer */ } CLBCOL; typedef struct cl_connection { struct driver_func *functions; /* entry points, from the original */ /* driver */ DRV_SQLHANDLE driver_dbc; /* HDBC of the driver */ DMHDBC dm_connection; /* driver manager connection str */ DMHSTMT cl_handle; /* dummy to make the macro valid */ SQLUSMALLINT active_statement_allowed; /* can we have more than one active */ /* statement */ int error_count; /* used to call SQLGetDiagRec */ /* * Use these as entry points back to the driver manager */ struct driver_helper_funcs dh; } *CLHDBC; typedef struct cl_statement { DRV_SQLHANDLE driver_stmt; /* driver statement handle */ CLHDBC cl_connection; /* parent cursor lib connection */ DMHSTMT dm_statement; /* Driver manager statement */ DMHSTMT fetch_statement; /* Driver manager statement */ SQLUINTEGER cursor_type; /* statment attr's */ SQLUINTEGER concurrency; SQLPOINTER *fetch_bookmark_ptr; SQLUINTEGER *param_bind_offset_ptr; SQLUINTEGER param_bind_type; SQLPOINTER row_bind_offset_ptr; SQLUINTEGER row_bind_type; SQLUINTEGER rowset_array_size; SQLUINTEGER rowset_size; SQLUINTEGER simulate_cursor; SQLUINTEGER use_bookmarks; SQLULEN *rows_fetched_ptr; SQLUSMALLINT *row_status_ptr; SQLCHAR cursor_name[ MAX_CURSOR_NAME + 1 ]; CLBCOL *bound_columns; int first_fetch_done; char *sql_text; /* text of current statement */ char **column_names; /* names of each column */ SQLSMALLINT *data_type; SQLULEN *column_size; SQLSMALLINT *decimal_digits; int driver_stmt_closed; int not_from_select; int read_only; int fetch_done; /* * rowset info */ int rowset_position; int rowset_count; int rowset_complete; FILE *rowset_file; char *rowset_buffer; #ifdef HAVE_FSEEKO off_t buffer_length; #else long buffer_length; #endif int column_count; int curr_rowset_start; int cursor_pos; int error_count; /* used to call SQLGetDiagRec */ } *CLHSTMT; /* * cursor lib function defs */ SQLRETURN SQL_API CLAllocHandle( SQLSMALLINT handle_type, SQLHANDLE input_handle, SQLHANDLE *output_handle, SQLHANDLE dm_handle ); SQLRETURN SQL_API CLAllocHandleStd( SQLSMALLINT handle_type, SQLHANDLE input_handle, SQLHANDLE *output_handle, SQLHANDLE dm_handle ); SQLRETURN SQL_API CLAllocStmt( SQLHDBC connection_handle, SQLHSTMT *statement_handle, SQLHANDLE dm_handle ); SQLRETURN SQL_API CLBindCol( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLSMALLINT target_type, SQLPOINTER target_value, SQLLEN buffer_length, SQLLEN *strlen_or_ind ); SQLRETURN SQL_API CLBindParam( SQLHSTMT statement_handle, SQLUSMALLINT parameter_number, SQLSMALLINT value_type, SQLSMALLINT parameter_type, SQLULEN length_precision, SQLSMALLINT parameter_scale, SQLPOINTER parameter_value, SQLLEN *strlen_or_ind ); SQLRETURN SQL_API CLBindParameter( SQLHSTMT statement_handle, SQLUSMALLINT ipar, SQLSMALLINT f_param_type, SQLSMALLINT f_c_type, SQLSMALLINT f_sql_type, SQLULEN cb_col_def, SQLSMALLINT ib_scale, SQLPOINTER rgb_value, SQLLEN cb_value_max, SQLLEN *pcb_value ); SQLRETURN SQL_API CLBulkOperations( SQLHSTMT statement_handle, SQLSMALLINT operation ); SQLRETURN SQL_API CLCancel( SQLHSTMT statement_handle ); SQLRETURN SQL_API CLCloseCursor( SQLHSTMT statement_handle ); SQLRETURN SQL_API CLColAttribute ( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLUSMALLINT field_identifier, SQLPOINTER character_attribute, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLLEN *numeric_attribute ); SQLRETURN SQL_API CLColAttributes( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLUSMALLINT field_identifier, SQLPOINTER character_attribute, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLLEN *numeric_attribute ); SQLRETURN SQL_API CLColumnPrivileges( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLCHAR *column_name, SQLSMALLINT name_length4 ); SQLRETURN SQL_API CLColumns( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLCHAR *column_name, SQLSMALLINT name_length4 ); SQLRETURN SQL_API CLCopyDesc( SQLHDESC source_desc_handle, SQLHDESC target_desc_handle ); SQLRETURN SQL_API CLDescribeCol( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLCHAR *column_name, SQLSMALLINT buffer_length, SQLSMALLINT *name_length, SQLSMALLINT *data_type, SQLULEN *column_size, SQLSMALLINT *decimal_digits, SQLSMALLINT *nullable ); SQLRETURN SQL_API CLDescribeParam( SQLHSTMT statement_handle, SQLUSMALLINT ipar, SQLSMALLINT *pf_sql_type, SQLULEN *pcb_param_def, SQLSMALLINT *pib_scale, SQLSMALLINT *pf_nullable ); SQLRETURN SQL_API CLDisconnect( SQLHDBC connection_handle ); SQLRETURN SQL_API CLEndTran( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT completion_type ); SQLRETURN SQL_API CLError( SQLHENV environment_handle, SQLHDBC connection_handle, SQLHSTMT statement_handle, SQLCHAR *sqlstate, SQLINTEGER *native_error, SQLCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length ); SQLRETURN SQL_API CLExecDirect( SQLHSTMT statement_handle, SQLCHAR *statement_text, SQLINTEGER text_length ); SQLRETURN SQL_API CLExecute( SQLHSTMT statement_handle ); SQLRETURN SQL_API CLExtendedFetch( SQLHSTMT statement_handle, SQLUSMALLINT f_fetch_type, SQLLEN irow, SQLULEN *pcrow, SQLUSMALLINT *rgf_row_status ); SQLRETURN SQL_API CLFetch( SQLHSTMT statement_handle ); SQLRETURN SQL_API CLFetchScroll( SQLHSTMT statement_handle, SQLSMALLINT fetch_orientation, SQLLEN fetch_offset ); SQLRETURN SQL_API CLForeignKeys( SQLHSTMT statement_handle, SQLCHAR *szpk_catalog_name, SQLSMALLINT cbpk_catalog_name, SQLCHAR *szpk_schema_name, SQLSMALLINT cbpk_schema_name, SQLCHAR *szpk_table_name, SQLSMALLINT cbpk_table_name, SQLCHAR *szfk_catalog_name, SQLSMALLINT cbfk_catalog_name, SQLCHAR *szfk_schema_name, SQLSMALLINT cbfk_schema_name, SQLCHAR *szfk_table_name, SQLSMALLINT cbfk_table_name ); SQLRETURN SQL_API CLFreeHandle( SQLSMALLINT handle_type, SQLHANDLE handle ); SQLRETURN SQL_API CLFreeStmt( SQLHSTMT statement_handle, SQLUSMALLINT option ); SQLRETURN SQL_API CLGetConnectOption( SQLHDBC connection_handle, SQLUSMALLINT option, SQLPOINTER value ); SQLRETURN SQL_API CLGetConnectAttr( SQLHDBC connection_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ); SQLRETURN SQL_API CLGetCursorName( SQLHSTMT statement_handle, SQLCHAR *cursor_name, SQLSMALLINT buffer_length, SQLSMALLINT *name_length ); SQLRETURN SQL_API CLGetData( SQLHSTMT statement_handle, SQLUSMALLINT column_number, SQLSMALLINT target_type, SQLPOINTER target_value, SQLLEN buffer_length, SQLLEN *strlen_or_ind ); SQLRETURN SQL_API CLGetDescField( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT field_identifier, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ); SQLRETURN SQL_API CLGetDescRec( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLCHAR *name, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLSMALLINT *type, SQLSMALLINT *sub_type, SQLINTEGER *length, SQLSMALLINT *precision, SQLSMALLINT *scale, SQLSMALLINT *nullable ); SQLRETURN SQL_API CLGetDiagField( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT rec_number, SQLSMALLINT diag_identifier, SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length, SQLSMALLINT *string_length_ptr ); SQLRETURN SQL_API CLGetDiagRec( SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT rec_number, SQLCHAR *sqlstate, SQLINTEGER *native, SQLCHAR *message_text, SQLSMALLINT buffer_length, SQLSMALLINT *text_length_ptr ); SQLRETURN SQL_API CLGetInfo( SQLHDBC connection_handle, SQLUSMALLINT info_type, SQLPOINTER info_value, SQLSMALLINT buffer_length, SQLSMALLINT *string_length ); SQLRETURN SQL_API CLGetStmtAttr( SQLHSTMT statement_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER *string_length ); SQLRETURN SQL_API CLGetStmtOption( SQLHSTMT statement_handle, SQLUSMALLINT option, SQLPOINTER value ); SQLRETURN SQL_API CLGetTypeInfo( SQLHSTMT statement_handle, SQLSMALLINT data_type ); SQLRETURN SQL_API CLMoreResults( SQLHSTMT statement_handle ); SQLRETURN SQL_API CLNativeSql( SQLHDBC hdbc, SQLCHAR *sz_sql_str_in, SQLINTEGER cb_sql_str_in, SQLCHAR *sz_sql_str, SQLINTEGER cb_sql_str_max, SQLINTEGER *pcb_sql_str ); SQLRETURN SQL_API CLNumParams( SQLHSTMT statement_handle, SQLSMALLINT *pcpar ); SQLRETURN SQL_API CLNumResultCols( SQLHSTMT statement_handle, SQLSMALLINT *column_count ); SQLRETURN SQL_API CLParamData( SQLHSTMT statement_handle, SQLPOINTER *value ); SQLRETURN SQL_API CLParamOptions( SQLHSTMT statement_handle, SQLULEN crow, SQLULEN *pirow ); SQLRETURN SQL_API CLPrepare( SQLHSTMT statement_handle, SQLCHAR *statement_text, SQLINTEGER text_length ); SQLRETURN SQL_API CLPrimaryKeys( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_table_name, SQLSMALLINT cb_table_name ); SQLRETURN SQL_API CLProcedureColumns( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_proc_name, SQLSMALLINT cb_proc_name, SQLCHAR *sz_column_name, SQLSMALLINT cb_column_name ); SQLRETURN SQL_API CLProcedures( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_proc_name, SQLSMALLINT cb_proc_name ); SQLRETURN SQL_API CLPutData( SQLHSTMT statement_handle, SQLPOINTER data, SQLINTEGER strlen_or_ind ); SQLRETURN SQL_API CLRowCount( SQLHSTMT statement_handle, SQLLEN *rowcount ); SQLRETURN SQL_API CLSetConnectAttr( SQLHDBC connection_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length ); SQLRETURN SQL_API CLSetConnectOption( SQLHDBC connection_handle, SQLUSMALLINT option, SQLULEN value ); SQLRETURN SQL_API CLSetCursorName( SQLHSTMT statement_handle, SQLCHAR *cursor_name, SQLSMALLINT name_length ); SQLRETURN SQL_API CLSetDescField( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT field_identifier, SQLPOINTER value, SQLINTEGER buffer_length ); SQLRETURN SQL_API CLSetDescRec( SQLHDESC descriptor_handle, SQLSMALLINT rec_number, SQLSMALLINT type, SQLSMALLINT subtype, SQLLEN length, SQLSMALLINT precision, SQLSMALLINT scale, SQLPOINTER data, SQLLEN *string_length, SQLLEN *indicator ); SQLRETURN SQL_API CLSetParam( SQLHSTMT statement_handle, SQLUSMALLINT parameter_number, SQLSMALLINT value_type, SQLSMALLINT parameter_type, SQLULEN length_precision, SQLSMALLINT parameter_scale, SQLPOINTER parameter_value, SQLLEN *strlen_or_ind ); SQLRETURN SQL_API CLSetPos( SQLHSTMT statement_handle, SQLSETPOSIROW irow, SQLUSMALLINT foption, SQLUSMALLINT flock ); SQLRETURN SQL_API CLSetScrollOptions( SQLHSTMT statement_handle, SQLUSMALLINT f_concurrency, SQLLEN crow_keyset, SQLUSMALLINT crow_rowset ); SQLRETURN SQL_API CLSetStmtAttr( SQLHSTMT statement_handle, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length ); SQLRETURN SQL_API CLSetStmtOption( SQLHSTMT statement_handle, SQLUSMALLINT option, SQLULEN value ); SQLRETURN SQL_API CLSpecialColumns( SQLHSTMT statement_handle, SQLUSMALLINT identifier_type, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLUSMALLINT scope, SQLUSMALLINT nullable ); SQLRETURN SQL_API CLStatistics( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLUSMALLINT unique, SQLUSMALLINT reserved ); SQLRETURN SQL_API CLTablePrivileges( SQLHSTMT statement_handle, SQLCHAR *sz_catalog_name, SQLSMALLINT cb_catalog_name, SQLCHAR *sz_schema_name, SQLSMALLINT cb_schema_name, SQLCHAR *sz_table_name, SQLSMALLINT cb_table_name ); SQLRETURN SQL_API CLTables( SQLHSTMT statement_handle, SQLCHAR *catalog_name, SQLSMALLINT name_length1, SQLCHAR *schema_name, SQLSMALLINT name_length2, SQLCHAR *table_name, SQLSMALLINT name_length3, SQLCHAR *table_type, SQLSMALLINT name_length4 ); SQLRETURN SQL_API CLTransact( SQLHENV environment_handle, SQLHDBC connection_handle, SQLUSMALLINT completion_type ); /* * internal prototypes */ void free_rowset( CLHSTMT cl_statement ); int calculate_buffers( CLHSTMT cl_statement, int column_count ); int free_bound_columns( CLHSTMT cl_statement ); SQLRETURN do_fetch_scroll( CLHSTMT cl_statement, int fetch_orientation, SQLLEN fetch_offset, SQLUSMALLINT *row_status_ptr, SQLULEN *rows_fetched_ptr, int ext_fetch ); SQLRETURN get_column_names( CLHSTMT cl_statement ); SQLRETURN complete_rowset( CLHSTMT cl_statement, int complete_to ); SQLRETURN fetch_row( CLHSTMT cl_statement, int row_number, int offset ); #endif unixODBC-2.3.12/cur/odbccr.pc.in000066400000000000000000000004141446441710500161750ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ Name: odbccr (@PACKAGE_NAME@) Description: unixODBC Cursor Library URL: http://unixodbc.org Version: @PACKAGE_VERSION@ Requires: odbc Cflags: -I${includedir} Libs: -L${libdir} -lodbccr unixODBC-2.3.12/doc/000077500000000000000000000000001446441710500137655ustar00rootroot00000000000000unixODBC-2.3.12/doc/AdministratorManual/000077500000000000000000000000001446441710500177435ustar00rootroot00000000000000unixODBC-2.3.12/doc/AdministratorManual/Makefile.am000066400000000000000000000001371446441710500220000ustar00rootroot00000000000000EXTRA_DIST = \ index.html \ unixODBC.gif \ odbcinst.html \ php3.html \ unixODBCsetup.html unixODBC-2.3.12/doc/AdministratorManual/index.html000066400000000000000000000300311446441710500217350ustar00rootroot00000000000000 unixODBC - Administrator Manual unixODBC

ADMINISTRATOR MANUAL

Introduction

Welcome to the unixODBC Administrator Manual. This manual has been created to help system administrators install and manage the ODBC sub-system.

Getting Started

At this point you know what ODBC is and what it can offer the Users of your system(s) - now you want to get it on your system(s).

Platforms

unixODBC implements ODBC on the following platforms;

  • Linux
  • Mac OSX
  • VMS
  • and various flavours of UNIX
This manual covers all platforms and will give special indication of differences for any particular platform.

Do You Have It?
 
It is possible that your system already has unixODBC installed. The best way to check for this is to drop to a terminal and execute 'odbcinst --version'.
 
[root@p12 qt]# odbcinst --version
unixODBC 2.1.1
[root@p12 qt]#

Downloading

You can get the source from Source Forge.

You can get binary distributions from various places. One place to look is with the vendor of your operating system. You can also go to Source Forge and take a look at the Home Page to see the availability and location of binary distributions.

Whether you choose a binary distribution or source code depends largely upon your site policy and which operating system you are working with. I recommend the following;

  • Mac OSX - use a binary distribution
  • Others - use a source distribution (tar-ball NOT CVS)


Installing From Source

There are two options when installing from source. You can install from a source distribution (a gzipped tar-ball) or from CVS. In either case you will find README files in the main directory which should help you build and install unixODBC.

The unixODBC build process uses the GNU auto-tools. This will be a concern to you if you choose to build from CVS because you must start the build process with 'make -f Makefile.cvs' - this, in turn, uses the GNU auto-tools (i.e. automake, autoconf) to build a 'configure' script. Unfortunately; the GNU auto-tools can be very version sensitive. See the README file(s) for more on this if you plan to build from CVS source.
 
[root@p12 unixODBC]# make -f Makefile.cvs 

You do not have to 'make -f Makefile.cvs' when using a source distribution. Regardless of whether you choose to use CVS or a source distribution you will want to execute the 'configure' script with options appropriate for your needs.
 
[root@p12 unixODBC]# ./configure --help

The 'configure' script will check your system for features of interest and build some make files as well as create some include file(s) which will ensure that unixODBC will build without errors and only with features supported by your operating system.

At this point it is important to think about whether or not GUI tools are important to you (and your Users). The 'configure' script will try to detect support for the GUI applications in unixODBC and will build them if such support exists. unixODBC includes GUI tools based upon the Qt class library and GTK. The Qt based tools will be built if libqt*so can be found. Linux systems will probably have this. You can get this from Troll Tech.

Now you are ready to build the sources. Do this with the usual build sequence of commands.
 
[root@p12 unixODBC]# make
[root@p12 unixODBC]# make install

Mac OSX: The Apple folks seem to be grappling with their support for the GNU auto-tools at the time of this writing. I recommend installing from a binary distribution of unixODBC. If you must install from source, and you are having problems with the GNU auto-tools, then you may want to try the qmake build. The qmake build process is not well documented at this time. People familiar with qmake should be able to build unixODBC with the included qmake project files.

Installing From Binary

RPM

Various RPMs exist for unixODBC. The best idea is to use any RPM files you can from your O/S vendor. Typically RPM distributions break unixODBC into more than one RPM distribution such as; core, and GUI.

Mac OSX Disk Images

A binary distribution for OSX has recently become available in the downloads section at CodeByDesign. This includes proper Mac installs. The install should be done in the following order;

  1. Qt Runtime
  2. unixODBC
  3. drivers in any order
Others

Proper install packages are also available for other platforms such as the Debian package format for Debian Linux. Check with the O/S vendor.

Where Are Installed Files

The location for files vary somewhat depending upon how you installed unixODBC (source or binary) and which platform you installed on. Furthermore; the location can be changed during a source install by './configure --prefix='.

Typically;

  • library files will go in /usr/lib or /usr/local/lib
  • binaries will go in /usr/bin or /usr/local/bin
  • system config files will go in /etc or /usr/local/etc
The system config files are;
  • odbcinst.ini - list of registered drivers
  • odbc.ini - system data source names
The location of the system config files can be changed by setting the ODBCSYSINI environment variable at run-time. The system config files can be edited using a simple text editor but it is recommended that you use the ODBCConfig GUI tool or the odcinst command-line tool because they will validate the reading and writing of these files while ensuring that the current location is used.

Mac OSX: The OSX binary install will use; /usr/lib, /usr/bin, /Applications/Utilities and /etc.

Post Install

You now have an ODBC sub-system installed on your system(s). What is the system administrators role from here? The system administrator is the only person who can install and register ODBC drivers and create/edit/delete system Data Source Names (DSN).

Drivers

Drivers should be installed and configured based upon the driver vendors instructions. Many drivers do not include a full install process - lacking the driver registration step. These drivers can be registered using the ODBCConfig GUI tool or the odbcinst command-line tool.

System DSN

These can be created using the ODBCConfig GUI tool or the odbcinst command-line tool. ODBCConfig is the preferred method but not all drivers have a User Interface (U.I.) part.

Mac OSX: In some cases the ODBCConfig icon will not open. In such a case you should drop to a terminal window and use the open command.
 
# open /Applications/Utilities/ODBCConfig.app

Summary

unixODBC implements an ODBC sub-system for a wide variety of platforms. unixODBC can be installed using; binary, source and source from CVS. Drivers can be installed using installation methods created by the driver vendor with unixODBC tools available to fill any gaps. ODBC system information can be managed using; ODBCConfig, odbcinst, or a text editor.
 



 
  unixODBC-2.3.12/doc/AdministratorManual/odbcinst.html000066400000000000000000000226741446441710500224510ustar00rootroot00000000000000 unixODBC without the GUI

unixODBC without the GUI

Or
everything you wanted to know about odbcinst but were afraid to ask

Purpose

A lot of people are using unixODBC but for a number of reasons are not building the GUI configuration and testing tools (ODBCConfig and DataManager). This document is aimed at these people and hopes to explain what you need to do and when to do it.

What's a ini file ?

ODBC first appeared within Windows 3.0. At this time Windows used .ini files to contain configuration information. These are text files containing the following layout
[section1]
entry1 = value
entry2 = value

[section2]
entry1 = value
entry2 = value
...
With the advent of Windows NT these ini files have been replaced by the registry, but the API to access them in ODBC has remained the same. Windows has two function in odbcinst.dll that allow applications and drivers to query and modify these files, SQLGetPrivateProfileString and SQLPutPrivateProfileString.

As part of unixODBC's aim of reproducing the ODBC environment on non Windows platform's the ini files and libodbcinst provide the same format and functionality.

System versus User

ODBC distinguishes between two types of ini files. System ini files are designed to be accessible but not modifiable by any user, and user files are private to a particular user, and may be modified by that user.

The system files are odbcinst.ini and odbc.ini (note no leading dot), and the user file is ~/.odbc.ini in each user's home directory (note leading dot).

The system file odbcinst.ini contains information about ODBC drivers available to all users, and the odbc.ini file contains information about DSN's available to all users. These "System DSN's" are useful for application such as web servers that may not be running as a real user and so will not have a home directory to contain a .odbc.ini file.

A good example of this is Apache and PHP with ODBC support. When the http server is first started it calls SQLAllocEnv as root. it then at a later time changes to the specified user (in my case nobody) and calls SQLConnect. If the DSN's was not a system DSN then this fails.

FILEDSN's

ODBC 3 also has a third sort of DSN, a file DSN. These store the connection information in a file that may be accessible to anyone. unixODBC does not at this time support FILEDSN's but it will when I get around to it. They are useful things but of less use to UNIX's than NT. Because of the MS view that everyone should have Windows on there desk, each workstation will have it's own registry with it's own set of system and user DSN's that can not be used by other workstations. File DSN's are a fix to allow the information to be stored in a central server that is accessible to all the workstations.

Why not vi ?

All the configuration files needed by unixODBC are plain text files, so there is no reason that you can not use your favorite text editor to setup the files.

However since beta 1.6 the location of the system files odbcinst.ini and odbc.ini are determined by the configure script. The default location is /usr/local/etc, and if a prefix is specified the location is {prefix}/etc. The location of the etc path can be broken out of the normal prefix tree by specifying --sysconfdir=DIR, so the following will expect the system files to be in the same location as pre 1.6 builds.

./configure --sysconfdir=/etc
The upshot of all this is that if you use odbcinst to configure the files you can be sure that the same path to the files will be used as are used by the driver manager, so the modifications will take effect.

What goes into them ?

Ok now we know a bit of the history of ini files and ODBC so now we need to get to the bit that is actually of use. What you put in them.

odbcinst.ini

This contains a section heading that provides a name for the driver, so for the example below PostgreSQL to indicate a Postgres driver. The following lines contain a description and then the important bits. The Driver and Setup paths point to the ODBC driver and setup libs. The setup lib is used when you click on Add in ODBCConfig to add a new DSN, but as this document is about not using the GUI tools, this is not that important for us. Far more important is the Driver entry (vital in fact) This is the library that the driver manager will dynamically load when SQLConnect or SQLDriverConnect is called for that DSN. If this points to the wrong place the DSN will not work. If the dlopen() fails the DSN will not work. The fileusage entry is added by the odbcinst program, so if you are using a text editor, you will need to add it yourself.
[PostgreSQL]
Description     = PostgreSQL driver for Linux & Win32
Driver          = /usr/local/lib/libodbcpsql.so
Setup           = /usr/local/lib/libodbcpsqlS.so
FileUsage       = 1

templates

odbcinst expects to be supplied with a template file. If you are adding a driver for the above entry the template file would contain the following
[PostgreSQL]
Description     = PostgreSQL driver for Linux & Win32
Driver          = /usr/local/lib/libodbcpsql.so
Setup           = /usr/local/lib/libodbcpsqlS.so
and you would invoke odbcinst with the following arguments, assuming that you have created a file template_file with the above entries in.
odbcinst -i -d -f template_file
The args to odbcinst are as follows

-i install
-d driver
-f name of template file

Threads

Since 1.6 if the driver manager was built with thread support you may add another entry to each driver entry. For example
[PostgreSQL]
Description     = PostgreSQL driver for Linux & Win32
Driver          = /usr/local/lib/libodbcpsql.so
Setup           = /usr/local/lib/libodbcpsqlS.so
Threading       = 2
This entry alters the default thread serialization level. More details can be found in the file DriverManager/__handles.c in the source tree.

[.]odbc.ini

The contents of the odbc.ini files are a bit more complicated, but they follow just the same format as the odbcinst.ini entries. These are complicated by each driver requiring different entries. The entries for all the drivers supplied with the distribution are included below for reference. The entries may be added in the same way using odbcinst, or a text editor. A sample entry to match the above driver could be
[PostgreSQL]
Description         = Test to Postgres
Driver              = PostgreSQL
Trace               = Yes
TraceFile           = sql.log
Database            = nick
Servername          = localhost
UserName            =
Password            =
Port                = 5432
Protocol            = 6.4
ReadOnly            = No
RowVersioning       = No
ShowSystemTables    = No
ShowOidColumn       = No
FakeOidIndex        = No
ConnSettings        =
And this may be written to a template file, and inserted in the ini file for the current user by
odbcinst -i -s -f template_file
The individual entries of course may vary.

The Driver line is used to match the [section] entry in the odbcinst.ini file and the Driver line in the odbcinst file is used to find the path for the driver library, and this loaded and the connection is then established. It's possible to replace the driver entry with a path to the driver itself. This can be used, for example if the user can't get root access to setup anything in /etc (less important now because of the movable etc path). For example

[PostgreSQL]
Description         = Test to Postgres
Driver              = /usr/local/lib/libodbcpsql.so
Trace               = Yes
TraceFile           = sql.log
Database            = nick
Servername          = localhost
UserName            =
Password            =
Port                = 5432
Protocol            = 6.4
ReadOnly            = No
RowVersioning       = No
ShowSystemTables    = No
ShowOidColumn       = No
FakeOidIndex        = No
ConnSettings        =

Templates

The templates for the included drivers are...

Postgress

[PostgreSQL]
Description         = Test to Postgres
Driver              = PostgreSQL
Trace               = Yes
TraceFile           = sql.log
Database            = nick
Servername          = localhost
UserName            =
Password            =
Port                = 5432
Protocol            = 6.4
ReadOnly            = No
RowVersioning       = No
ShowSystemTables    = No
ShowOidColumn       = No
FakeOidIndex        = No
ConnSettings        =

Mini SQL

[Mini SQL]
Description     = MiniSQL
Driver          = MiniSQL
Trace           = No
TraceFile       =
Host            = localhost
Database        =
ConfigFile      =

MySQL

[MySQL]
Description     = MySQL
Driver          = MySQL
Trace           = No
TraceFile       =
Host            = localhost
Port            =
Socket          =
Database        =

NNTP driver

[nntp Data Source]
Description     = nntp Driver
Driver          = nntp Driver
Trace           = No
TraceFile       =
Host            = localhost
Database        =
Port            =

Sybase SQL Anywhere 5.0

Thanks Greg.
[Sybase SQL Anywhere 5.0]
Driver=Sybase SQL Anywhere 5.0
Description=Sybase SQL Anywhere 5.0 ODBC Driver
Userid=dba
Password=sql
DatabaseFile=sademo.db
Hopefully this will be of some use to someone... Nick Gorham unixODBC-2.3.12/doc/AdministratorManual/php3.html000066400000000000000000000037101446441710500215040ustar00rootroot00000000000000 Installing PHP with unixODBC

Installing PHP with unixODBC

This install procedure is based on apache 1.3.6 and PHP 3.0.9. The PHP4 from beta 3 will have a configure option to use unixODBC so most of the following will be redundant.

This document assumes that unixODBC has been built and installed, in this case in the default location /usr/local, and that both Apache and PHP have been untarred in the users home directory.

  1. In the Apache directory run the following command
       ./configure --prefix=/www
    
    plus any other local config you need

  2. Create a file in /usr/local/include called odbc.h containing the following three lines
       #include <sql.h>
       #include <sqlext.h>
       #include <odbcinst.h>
    
    replacing /www with your desired apache install path

  3. Move to the PHP directory Define the following environment variables
       CFLAGS="-I/usr/local/include"
       LDFLAGS=
       CUSTOM_ODBC_LIBS="-L/usr/local/lib -lodbc"
    
    remember to export these variables
       export CFLAGS LDFLAGS CUSTOM_ODBC_LIBS 
    

  4. Configure PHP with
       ./configure --with-apache=../apache_1.3.6 --with-custom-odbc=/usr/local  --enable-track-vars
    
    plus any other local config you need then...
       make
       make install
    

  5. Go back to your apache directory, and do
       ./configure --prefix=/www --activate-module=src/modules/php3/libphp3.a
       make
       make install
    

  6. Back to the PHP directory Then to quote from the PHP INSTALL
       cp php3.ini-dist /usr/local/lib/php3.ini
       You can edit /usr/local/lib/php3.ini file to set PHP options.
       Edit your httpd.conf or srm.conf file and add:
         AddType application/x-httpd-php3 .php3
    
    
    
And that should be that.

If this is of any help to someone, good, any problems let me know.

Nick Gorham unixODBC-2.3.12/doc/AdministratorManual/unixODBC.gif000066400000000000000000000015321446441710500220460ustar00rootroot00000000000000GIF89a l! NETSCAPE2.0!Made with GIMP! , Igͷԍ$Y}R/Lw[JBCŒ]CF5O.ϫ"13{cJyゼ>ov[{z}!vJ{[|fDbr+;WZ=p`uan1& gä ! , 0I8Z/ J\}dyBQ` OoNjoܜ1T{}ux s~8"dz{|pD^p[]^yMwIŗȬƜ2#md2l#;unixODBC-2.3.12/doc/AdministratorManual/unixODBCsetup.html000066400000000000000000000311341446441710500233270ustar00rootroot00000000000000

A neophyte's guide
to getting unixODBC and Mysql/MyODBC working


Introduction

UnixODBC is an idea whose time has come. It holds many promises for those of us who use databases in our daily work and would like to do more of that work on Linux or one of the UNIX variants. Those coming from a windows background will rapidly discover that it can be much more involved setting up a working Unix based database than they are used to. They will also discover a world of great advantages too; stability, scalability and freely available source code are values not easily dismissed.

This document is designed to help people set up and use unixODBC. My database of choice is MySQL, which I have used with great success for several years, and it is the database I will discuss setting up

ODBC is an interface by which programs and programmers can communicate with any database which has an ODBC driver. While most databases have one or more APIs in various programming languages, ODBC allows the same programming code to talk with numerous types of databases. (ODBC is not the only interface to do this, but it is very widely used and supported)

Getting Started

UnixODBC is available in source code only. This means that you download a tar file from http://www.unixODBC.org , extract it, compile it, and install it. Before you do so though you need some other things.

Prerequisets:

  1. The Qt toolkit version 2.x sources from http://www.troll.no . Make sure it is version 2 or higher !

    1. Download the Qt v2 sources.

    2. Extract the sources to somewhere, usually this is done by placing the tar file in a directory like /usr/local or /opt and using the command.
      tar zxvf qt-2.0.1.tar.gz
      to extract the files. This will create a subdirectory qt-2.0.1 . Remember that only root can normally write to /usr/local or /opt. This is an example, use the name of the file you have.

    3. Compile the sources. Assuming you have a relatively recent version of Linux with all the appropriate stuff (libg++, gcc or egcs etc) You issue 3 commands from the qt-2.0.1 directory.
      ./configure
      make
      make install

    4. This last command is scary since it will install the new libqt into places where any old v1.4x libqt may exist. Rest assured that the full name of the library is different and it will not overwrite your existing libqt. It should choke on rewriting the symlink to libqt.so and thus not mess up your existing Qt / KDE apps. If it does rewrite this link, you will need to set it back to its original link.

    5. For more information, see http://www.troll.no . Please don't bother the unixODBC people for instructions on setting up Qt.

  1. A Database - in this case MySQL from http://www.mysql.com

    1. Again, I strongly suggest you get the sources and compile them yourself. The process is similar if not identical to that for Qt described above. By default MySQL installs it's executable files in /usr/local/bin, it's include files (source headers) in /usr/local/include/mysql and it's libraries in /usr/local/lib/mysql. The actual database files are in /usr/local/var.

    2. Before you can use MySQL, you need to run
      /usr/local/bin/mysql_install_db
      as root to set up the system tables. To actually start the database, run
      /usr/local/bin/safe_mysqld &

    3. MySQL comes with very extensive documentation. Refer to it for questions on compiling, installing and using MySQL. This is especially true for permissions. If the permissions aren't correct, no interface will work.

Installing unixODBC

  1. As mentioned before, get the source tar file from http://www.unixodbc.org . As root, move the tar file to /op or /usr/local or where ever you want the source to reside. Untar the file and run the following commands from the command line in the unixODBC source directories:
    ./configure
    ./make
    ./make install

  2. Assuming that you have all the libraries and tools that it needs, you should be breezing through this compile. Certainly after all that practice with Qt and MySQL this should be old hat. UnixODBC takes quite a while to compile, actually all of these packages do. Relax and enjoy it.

Installing a Driver

UnixODBC by itself isn't a whole lot of good without a driver. MySQL has an ODBC driver named MyODBC but it isn't included with the current edition of unixODBC, so you have to get it and compile it yourself. I'll be referring to version 2.50.24, the latest as of this writing. The installation is much the same as the other packages, but you need to give configure some options. It will prompt you for the path to the MySQL sources if you don't specify the path, but you also have to supply the --with-unixODBC=<your unixODBC directory here> flag. The following is from the MyODBC INSTALL file:

To make configure look for unixODBC instead of iODBC, use

--with-unixODBC=DIR

Where DIR is where unixODBC is installed.

And (as usual), if the unixODBC headers and libraries aren't located

in DIR/include and DIR/lib, use

--with-unixODBC-libs=LIBDIR --with-unixODBC-includes=INCDIR

You might want to specify a prefix other than /usr/local for installation,
I, for example keep my ODBC drivers in /usr/local/odbc/lib, so I add

--prefix=/usr/local/odbc

So here is my configure line:

./configure --with-unixodbc=/usr/local --with-mysql-sources=/usr/local/mysql

Running make and then make install puts the resulting library: libmyodbc-2.50.23.so into /usr/local/lib. WAIT A MINUTE ! Didn't I say it was version 2.50.24 ? Yes, I did. However, unless you want to go in and change the version info in the source code, it will create the library with that name. I don't consider this a big deal and so I didn't mess with it.

If you omit the --with-mysql-sources flag, configure will fail. If you omit the --with-unixodbc flag, configure will complete and MyODBC will compile. However, it will not work correctly when using it with unixODBC. The problems described below occurred when I omitted this flag:

1) If the DSN (Data Source Name) you create is also the name of a database, the driver points to that database no matter what you specify the database to be.
2) If the DSN is not the name of an existing database, it will fail, not allowing you to login to the database. The trace log file will tell you that it couldn't find a database with the name of the DSN. This is confusing if you specified a valid database name in the .odbc.ini file .

When using the --with-unixodbc flag, These problems disappear and it works the way it should.

A note: MyODBC does not support ODBC version 3 as of version 2.50.24 . When writing programs that utilize this driver, I have had success with specifying V_OD_ODBC2 when calling SQLSetEnvAttr(...) .

Setting up unixODBC

At long last we come to actually setting up unixODBC and using it. While most of this information exists on the unixODBC web pages and user's guide, I found it difficult to find and follow, so I repeat it here in hopes that it will be made clearer.

UnixODBC consists of a lot of libraries, installed in /usr/local/lib, and a few executable files (binaries) installed into /usr/local/bin. These executable files are ODBCConfig, DataManager, and odbcinst.

In order to get unixODBC running, do these things in this order:

Do this as root...

In an xterm, type ODBCConfig . This is a GUI program and must be run in an X session. At the very least you need to set up a driver to use. The drivers will be specific to one database application, like MyODBC is specific to MySQL. In addition to this, you need to specify a setup file to use for this drive. The setup files are the /usr/local/lib/libodbc*S.so libraries where * signifies the database application, so /usr/local/lib/libodbcmyS.so is the "setup file" for MyODBC. The driver (not the setup file) is /usr/local/lib/libmyodbc-2.50.23.so.

To set up the driver, run ODBCConfig as root, go to the drivers tab and click on "New". The following are the settings I use...

Name: myodbc
Description: MySQL driver.
Driver: /usr/local/lib/libmyodbc-2.50.23.so
Setup: /usr/local/lib/libodbcmyS.so

FileUsage: 1

You should have a driver set up before setting up a DSN. After having done so, you may want to set up a system DSN. You do this by selecting the "System DSN" tab, clicking on 'New', specifying the driver to use and filling in the required information. You will want to select the driver name you just defined as the Driver in the first screen that displays, and click OK.

Doing this as root will create and edit the /usr/local/etc/odbcinst.ini (for the driver info) and /usr/local/etc/odbc.ini (for the system DSN) files. Early versions of unixODBC would put these files in /etc, and you can still use a configure option : --sysconfdir=/etc to put those files in that location.

Do this as a normal user:

The process for setting up a user DSN is identical to setting up a system DSN. You simply select the "User DSN" tab in ODBCConfig and fill out the required fields. The following is how I filled out a User DSN.

Name: mysqltest
Description: myodbc
Driver: myodbc
Trace: Yes
TraceFile: mysql.log
Host: localhost
Port: 3306
Socket:
Database: test

This will create and edit a file named ~/.odbc.ini . Since the test database comes without any tables, you may want to specify mysql as the database instead, so you can see the tables when running DataManager.

Run DataManager

Now you should be able to run DataManager and see your drivers, DSNs and tables for each DSN. See the unixODBC web site for screen shots of what it should look like.

OK, Now What ?

UnixODBC is not so much an end user program, but rather an intermediary between a program and one or more databases. There is information in the unixODBC documentation for example, about setting up StarOffice to use an ODBC connection. I am in the process of writing a program that makes use of unixODBC and numerous others are as well. It may well be that in time unixODBC will be included in numerous Linux distributions and installed by default. Until that time I hope that this document helps you get this software up and running.

Charles Morrison
cmorrison@info2000.net

unixODBC-2.3.12/doc/Makefile.am000066400000000000000000000002101446441710500160120ustar00rootroot00000000000000SUBDIRS = \ AdministratorManual \ ProgrammerManual \ UserManual \ lst EXTRA_DIST = \ index.html \ smallbook.gif \ unixODBC.gif unixODBC-2.3.12/doc/ProgrammerManual/000077500000000000000000000000001446441710500172365ustar00rootroot00000000000000unixODBC-2.3.12/doc/ProgrammerManual/Makefile.am000066400000000000000000000000771446441710500212760ustar00rootroot00000000000000SUBDIRS = Tutorial EXTRA_DIST = \ index.html \ unixODBC.gif unixODBC-2.3.12/doc/ProgrammerManual/Tutorial/000077500000000000000000000000001446441710500210415ustar00rootroot00000000000000unixODBC-2.3.12/doc/ProgrammerManual/Tutorial/Makefile.am000066400000000000000000000002251446441710500230740ustar00rootroot00000000000000EXTRA_DIST = \ close.html \ conne.html \ dsn.html \ gloss.html \ index.html \ intro.html \ navi.html \ odbc.css \ query.html \ resul.html unixODBC-2.3.12/doc/ProgrammerManual/Tutorial/close.html000066400000000000000000000027031446441710500230360ustar00rootroot00000000000000 Closing a connection
Closing a connection

Before your program terminates you need to free all resources you have allocated. If you checked the source on the previous page, you certainly spotted SQLFreeHandle. This function must be used to free each allocated handle. It expects a parameter which states the type of the handle to be freed and the handle itself. So if you want to free an environment handle you should call (in our example program):

SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);

Before you free any handle make sure that it is no longer needed, wouldn't be funny, if you released to connection handle but forgot to close the connection ;)

And if you want to close a connection you need SQLDisconnect. This closes the connection associated with the connection handle offered as argument to SQLDisconnect. In our program we need to call:

SQLDisconnect(V_OD_hdbc);

If you need source code, please have a look here.

unixODBC-2.3.12/doc/ProgrammerManual/Tutorial/conne.html000066400000000000000000000116521446441710500230360ustar00rootroot00000000000000 Connecting
Connecting to a Datasource

First thing you will need is a variable of type SQLHENV. This is a handle (pointer) to an internal ODBC structure which holds all informationen about the ODBC environment. Without a handle of that kind you won't be able do to very much. To get this handle you call SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &V_OD_Env). V_OD_Erg is a variable of type SQLHENV which holds the allocated environment handle.

If you have allocated the handle you need to define which version of ODBC to use. Therefore you should call SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0). The constant SQL_ATTR_ODBC_VERSION defines that the needed version of ODBC will be defined and SQL_OV_ODBC3 says that the program will need ODBC 3.0.

Next thing to do is to create a handle for the database connection which is of the type SQLHDBC. Once again you call SQLAllocHandle this time with SQL_HANDLE_DBC and the variable to the environment returned by the first call to SQLAllocHandle.

Then you may choose to modify the connection attributes, mainly the timeout for any given action on the connection. You do this by calling SQLSetConnectAttr with the connection handle, attribute and value pointer and the string length (if available).

Finally we are able to connect to the database via SQLConnect, which needs the name of the data source, the username and password as parameters. For each parameter you need to specify how long the string is or just gib SQL_NTS which says that it is a string which length has to be determined by SQLConnect

That's it, we are connected to the database. Please note, that all functions mentioned on this page return either SQL_SUCCESS, SQL_SUCCESS_WITH_INFO if all went smoothly or SQL_ERROR or SQL_INVALID_HANDLE in case of an error. We will have a look on how to get diagnostic messages a little later.

So let's have a look at the code:


  
/* odbc.c

    testing unixODBC
*/
#include <stdlib.h>
#include <stdio.h>
#include <odbc/sql.h>
#include <odbc/sqlext.h>
#include <odbc/sqltypes.h>

SQLHENV			 V_OD_Env;     // Handle ODBC environment
long			 V_OD_erg;     // result of functions
SQLHDBC			 V_OD_hdbc;    // Handle connection

char			 V_OD_stat[10]; // Status SQL
SQLINTEGER		 V_OD_err,V_OD_rowanz,V_OD_id;
SQLSMALLINT		 V_OD_mlen;
char             V_OD_msg[200],V_OD_buffer[200];


int main(int argc,char *argv[])
{
	// 1. allocate Environment handle and register version 
	V_OD_erg=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Error AllocHandle\n");
		exit(0);
	}
	V_OD_erg=SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, 
                               (void*)SQL_OV_ODBC3, 0); 
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Error SetEnv\n");
		SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
		exit(0);
	}
	// 2. allocate connection handle, set timeout
	V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc); 
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Error AllocHDB %d\n",V_OD_erg);
		SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
		exit(0);
	}
	SQLSetConnectAttr(V_OD_hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5, 0);
	// 3. Connect to the datasource "web" 
	V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "web", SQL_NTS,
                                     (SQLCHAR*) "christa", SQL_NTS,
                                     (SQLCHAR*) "", SQL_NTS);
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Error SQLConnect %d\n",V_OD_erg);
		SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, 
		              V_OD_stat, &V_OD_err,V_OD_msg,100,&V_OD_mlen);
		printf("%s (%d)\n",V_OD_msg,V_OD_err);
		SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
		exit(0);
	}
	printf("Connected !\n");
	/* continued on next page */
  
  
unixODBC-2.3.12/doc/ProgrammerManual/Tutorial/dsn.html000066400000000000000000000051331446441710500225150ustar00rootroot00000000000000 Obtainign Datasources
Obtaining a Datasourcename

A simple query should be a nobrainer right now. But what if your program runs on a system where you can't be sure which datasource names are configured?

Then you should use SQLDataSources(). After allocating a environment handle you may use this to find out about the DSN and the supplied description for the datasource.

As ODBC knows systemwide and userwide datasources, you need to give a direction which datasource types you are looking for. There you may specify either of the following values:

SQL_FETCH_FIRST Sets up SQLDataSources() to lookup the first of all available datasources (either user or systemwide).
SQL_FETCH_FIRST_USER Sets up SQLDataSources() to lookup the first of the available user datasources.
SQL_FETCH_FIRST_SYSTEM Sets up SQLDataSources() to lookup the first of the available system datasources.
SQL_FETCH_NEXT Fetches the next datasource. Depending on SQL_FETCH_FIRST_USER, SQL_FETCH_FIRST_SYSTEM or SQL_FETCH_FIRST this may only be a user datasource, only a system datasource or one of either.

So let's have a look on a small function, which will return all available datasource names. You may insert this code into the program which you built before and call it somewhere after you've obtained an environment handle.

void OD_ListDSN(void)
{
 char       l_dsn[100],l_desc[100];
 short int  l_len1,l_len2,l_next;

 l_next=SQL_FETCH_FIRST;
 while( SQLDataSources(V_OD_Env,l_next,l_dsn, sizeof(l_dsn),
        &l_len1, l_desc, sizeof(l_desc), &l_len2) == SQL_SUCCESS)
     {
      printf("Server=(%s) Beschreibung=(%s)\n",l_dsn,l_desc);
      l_next=SQL_FETCH_NEXT;
     }
}
unixODBC-2.3.12/doc/ProgrammerManual/Tutorial/gloss.html000066400000000000000000000472241446441710500230670ustar00rootroot00000000000000 Glossary
Index / Glossary
A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z
C   Column
 

A column is another name for field in a SQL table. It has a data type (Integer, Char, Money etc) and a name by which it is addressed.

You specify the name of a column in a query (either DELETE, UPDATE, SELECT or INSERT)

D   data source
  A data source defines all informationen needed by ODBC to connect to a database. This includes the name of the driver to use (Postgres, mySQL etc.), the name of the user, his password, the server name on which the database resides and of course the name of the database. There are a lot more options available.
  Data Types
 

The following table show some ODBC data types and how the relate to standard C data types:

Type identifier ODBC typedef C typedef
SQL_C_CHAR SQLCHAR * unsigned char *
SQL_C_SSHORT SQLSMALLINT short int
SQL_C_USHORT SQLUSMALLINT unsigned short int
SQL_C_SLONG SQLINTEGER long int
SQL_C_FLOAT SQLREAL float
SQL_C_DOUBLE SQLDOUBLE, SQLFLOAT double
SQL_C_BINARY SQLCHAR * unsigned char
SQL_C_TYPE_DATE SQL_DATE_STRUCT struct
tagDATE_STRUCT {
SQLSMALLINT year;
SQLUSMALLINT month;
SQLUSMALLINT day;
} DATE_STRUCT;
SQL_C_TYPE_TIME SQL_TIME_STRUCT struct
tagTIME_STRUCT {
SQLUSMALLINT hour;
SQLUSMALLINT minute;
SQLUSMALLINT second;
} TIME_STRUCT;

You will need the type identifier in calls to SQLBindCol.

 
O   odbc.ini
  /etc/odbc.ini is the configuration file for system data sources. It contains information which will be needed when connecting to a database. It is modified by a graphical utility ODBCConfig.
R   Row
  A row is a set of columns in a query. For example in our table there are two users. Each user makes up a row in the table or in the result of our query.
S   SQLAllocHandle
  allocates needed handles.
SQLRETURN 
SQLAllocHandle(SQLSMALLINT  HandleType,     
               SQLHANDLE    InputHandle, 
               SQLHANDLE   *OutputHandlePtr); 

	  

Arguments

HandleType

Defines the type of handle to be allocated by SQLAllocHandle. There are four possible values:

SQL_HANDLE_ENV
SQL_HANDLE_DBC
SQL_HANDLE_STMT
SQL_HANDLE_DESC
InputHandle
This is the input handle in whose context the new handle will be allocated. If HandleType is SQL_HANDLE_ENV, this is SQL_NULL_HANDLE. For a handle of type SQL_HANDLE_DBC, this has to be an environment handle, and if it is SQL_HANDLE_STMT or SQL_HANDLE_DESC, it must be a connection handle.
OutputHandlePtr
Pointer to a buffer in which to return the allocated handle.

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_INVALID_HANDLE, or SQL_ERROR.
  SQLBindCol
  binds a variable to a column in the result.
SQLRETURN 
SQLBindCol(SQLHSTMT      StatementHandle, 
           SQLUSMALLINT  ColumnNumber, 
           SQLSMALLINT   TargetType,  
           SQLPOINTER    TargetValuePtr, 
           SQLINTEGER    BufferLength, 
           SQLINTEGER   *StrLen_or_IndPtr); 

Arguments

StatementHandle
StatementHandle must have been allocated by SQLAllocHandle and will hold all information and the result set of the statement.
ColumnNumber
Number of the column in the result set. Starts with 1.
TargetType
Type identifier of the data type
TargetValuePtr
The pointer to the variable in which the data will be stored.
BufferLength
The size of the buffer TargetValuePtr points at in bytes.
StrLen_or_IndPtr
When data is fetched, returns either
  • The length of the data available to return
  • SQL_NO_TOTAL
  • SQL_NULL_DATA

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR or SQL_INVALID_HANDLE.
  SQLConnect
  connects to a datasource
SQLRETURN SQLConnect(SQLHDBC     ConnectionHandle, 
                     SQLCHAR    *ServerName, 
                     SQLSMALLINT NameLength1, 
                     SQLCHAR    *UserName, 
                     SQLSMALLINT NameLength2, 
                     SQLCHAR    *Authentication, 
                     SQLSMALLINT NameLength3); 

Arguments

ConnectionHandle
ConnectionHandle must have been allocated by SQLAllocHandle and will hold all information about the connection.
ServerName
Name of the database server
NameLength1
The length of ServerName or SQL_NTS
UserName
The name of the user who connects to the database.
NameLength2
The length of UserName or SQL_NTS
Authentication
Password of the user
NameLength3
The length of Authentication or SQL_NTS

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR or SQL_INVALID_HANDLE.
  SQLDataSources
  fetches available datasource names either user, system or both.
SQLRETURN 
SQLDataSources(SQLHENV      EnvironmentHandle, 
               SQLUSMALLINT Direction, 
               SQLCHAR     *ServerName, 
               SQLSMALLINT  BufferLength1, 
               SQLSMALLINT *NameLength1Ptr, 
               SQLCHAR     *Description, 
               SQLSMALLINT  BufferLength2, 
               SQLSMALLINT *NameLength2Ptr); 

Arguments

EnvironmentHandle
EnvironmentHandle must have been allocated by SQLAllocHandle.
Direction
Which DSN we are looking for. May be on of:
SQL_FETCH_FIRST Sets up SQLDataSources() to lookup the first of all available datasources (either user or systemwide).
SQL_FETCH_FIRST_USER Sets up SQLDataSources() to lookup the first of the available user datasources.
SQL_FETCH_FIRST_SYSTEM Sets up SQLDataSources() to lookup the first of the available system datasources.
SQL_FETCH_NEXT Fetches the next datasource. Depending on SQL_FETCH_FIRST_USER, SQL_FETCH_FIRST_SYSTEM or SQL_FETCH_FIRST this may only be a user datasource, only a system datasource or one of either.
ServerName
The name of the datasource is returned herein.
BufferLength1
Defines how many chars Servername may contain at most.
NameLength1Ptr
The pointer to the variable in which the actual length of the datasource name is stored. If NameLength1Ptr is greater than BufferLength1, then the DSN in ServerName is truncated to fit.
BufferLength
The size of the buffer TargetValuePtr points at in bytes.
Description
The description supplied with the datasource, giving more information on the datasource in human readable form.
BufferLength2
Defines how many chars Description may contain at most.
NameLength2Ptr
The pointer to the variable in which the actual length of the description is stored. If NameLength2Ptr is greater than BufferLength2, then the description in Description is truncated to fit.

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_NO_DATA> or SQL_INVALID_HANDLE.
  SQLExecDirect
  Executes a SQL statement
SQLRETURN SQLExecDirect(SQLHSTMT    StatementHandle, 
                        SQLCHAR    *StatementText, 
                        SQLINTEGER  TextLength); 

Arguments

StatementHandle
StatementHandle must have been allocated by SQLAllocHandle and will hold all information and the result set of the statement.
StatementText
The SQL statement to be executed
TextLength
The length of StatementText or SQL_NTS

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR or SQL_INVALID_HANDLE.
  SQLDisconnect
  disconnects the specified connection
SQLRETURN SQLDisconnect(SQLHDBC     ConnectionHandle);

	  

Arguments

ConnectionHandle
The handle of the connection to be closed.

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_INVALID_HANDLE, or SQL_ERROR.
  SQLFetch
  Fetches the next row of the result set.
SQLRETURN SQLFetch(SQLHDBC     StatementHandle);

	  

Arguments

StatementHandle
The handle of the statement to be closed fromwhich the data should be fetched.

Returns

SQL_SUCCESS, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_SUCCESS_WITH_INFO, SQL_INVALID_HANDLE, or SQL_ERROR.


  SQLFreeHandle
  frees allocated handles.
SQLRETURN SQLFreeHandle(SQLSMALLINT  HandleType,     
                        SQLHANDLE    InputHandle);

	  

Arguments

HandleType

Defines the type of handle to be freed. There are four possible values:

SQL_HANDLE_ENV
SQL_HANDLE_DBC
SQL_HANDLE_STMT
SQL_HANDLE_DESC
InputHandle
The handle to be freed. Should match the type stated by HandleType

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_INVALID_HANDLE, or SQL_ERROR.
  SQLNumResultCols
  returns the number of columns in the result set.
SQLRETURN SQLNumResultCols(SQLHSTMT     StatementHandle, 
                           SQLSMALLINT *ColumnCountPtr); 
	  

Arguments

StatementHandle
StatementHandle must have been allocated by SQLAllocHandle and holds all information and the result set of the statement.
ColumnCountPtr
A pointer to a variable to hold the result value.

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_INVALID_HANDLE, or SQL_ERROR.


  SQLRowCount
  returns the number of rows affected by INSERT, UPDATE or DELETE. Many drivers (but not all) return the number of rows returned by the last executed SELECT statement too.
SQLRETURN SQLSQLRowCount(SQLHSTMT     StatementHandle, 
                         SQLSMALLINT *RowCountPtr); 
	  

Arguments

StatementHandle
StatementHandle must have been allocated by SQLAllocHandle and holds all information and the result set of the statement.
RowCountPtr
A pointer to a variable to hold the result value.

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_INVALID_HANDLE, or SQL_ERROR.


  SQLSetConnectAttr
  modifies attributes of connections.
SQLRETURN SQLSetConnectAttr(SQLHDBC    ConnectionHandle, 
                            SQLINTEGER Attribute, 
                            SQLPOINTER ValuePtr, 
                            SQLINTEGER StringLength); 

Arguments

ConnectionHandle
ConnectionHandle must have been allocated by SQLAllocHandle and defines the connection which will be modified.
Attribute
which attribute to set
ValuePtr
Pointer to the value for Attribute. Depending on Attribute, ValuePtr will be a 32-bit integer value or a pointer to a null-terminated string.
StringLength
If ValuePtr points to a character string or a binary buffer, this argument should be the length of *ValuePtr. Otherwise, for ValuePtr of type integer StringLength is ignored.

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR or SQL_INVALID_HANDLE.


  SQLSetEnvAttr
  sets attributes of environments.
SQLRETURN  SQLSetEnvAttr(SQLHENV    EnvironmentHandle, 
                         SQLINTEGER Attribute, 
                         SQLPOINTER ValuePtr, 
                         SQLINTEGER StringLength); 

Arguments

EnvironmentHandle
EnvironmentHandle must have been allocated by SQLAllocHandle
Attribute
which attribute to set
ValuePtr
Pointer to the value for Attribute. Depending on Attribute, ValuePtr will be a 32-bit integer value or a pointer to a null-terminated string.
StringLength
If ValuePtr points to a character string or a binary buffer, this argument should be the length of *ValuePtr. Otherwise, for ValuePtr of type integer StringLength is ignored.

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR or SQL_INVALID_HANDLE.
unixODBC-2.3.12/doc/ProgrammerManual/Tutorial/index.html000066400000000000000000000004251446441710500230370ustar00rootroot00000000000000 Dokumenttitel unixODBC-2.3.12/doc/ProgrammerManual/Tutorial/intro.html000066400000000000000000000045061446441710500230670ustar00rootroot00000000000000 Introduction
Introduction
Welcome to a short tutorial on ODBC programming. The goal of this tutorial is to introduce a C-Programmer to ODBC programming. During this tutorial we will code a simple program which connects to a database via ODBC and reads some data. There won't be any information on how to program ODBC Drivers or about unixODBC internals. Configuration won't be covered too. The program developed throughout this tutorial was originally coded under WinNT and later ported without any adjustments to Linux and unixODBC. This is how compatibility should work :)

The information given within this tutorial are brief at best. Please take it as a pointer where and how to start.


Requirements   I assume that you have
 
  • a system with unixODBC installed and with at least one working datasource configured.
  • the include files installed under /usr/include/odbc
  • a compiler installed and that you know how to use it ;)
Compiling   If gcc is installed type:
  gcc odbc.c -o odbc -lodbc
which will result in an executable named "odbc".
Database   Our database will have a single table:
 
tkeyuser
iduser sequence
dtname char(40)
dtmaxSize Integer

Our datasource will be named "web" and access is granted to the user "christa" with no password.
unixODBC-2.3.12/doc/ProgrammerManual/Tutorial/navi.html000066400000000000000000000017771446441710500227000ustar00rootroot00000000000000 Navigation
ODBC Programming Tutorial
 
Introduction
Connection
Closing
Queries
Results
Obtaining DSN
Index / Glossary
unixODBC Home
unixODBC-2.3.12/doc/ProgrammerManual/Tutorial/odbc.css000066400000000000000000000152211446441710500224630ustar00rootroot00000000000000/* Style Sheet for odbc documentation =20 M.Rathmann */ BODY {background-color: white; color: black; font-family: Arial; font-style: normal; font-size: medium; background-attachment: fixed; } /*=20 2. Die Verweise: Standard: Text unterstrichen link: #008080=20 vlink=3D"#800000" alink=3D"#008080" */ a:link {color: #2222ff; text-decoration: none; } a:visited {color: #3333ee; text-decoration: none; } a:active {color: #4444dd; text-decoration: none; } TH {border-style: none; background-color: #dddddd; font-family: Arial; font-size: normal; color: white; vertical-align: top; text-align: center; } TD {border-style: none; background-color: white; font-family: Arial; font-size: normal; color: black; border-width: 3px; border-color: white; vertical-align: top; text-align: justify; } TD.center {border-style: none; background-color: #ddddff; text-align: center; font-family: Arial; font-size: medium; color: black; border-width: 3px; border-color: white; vertical-align: top; } TD.head {border-style: none; background-color: #ddddff; text-align: left; font-family: Arial; font-size: medium; color: black; font-weight: bold; vertical-align: top; } Th.head {border-style: none; background-color: #dddddd;=09 text-align: center; font-family: Arial; font-size: medium; color: black; font-weight: bold; vertical-align: top; } TD.big { font-family: Arial; font-size: x-large; } TD.small { font-family: Arial; font-size: x-small; } /* 5. =DCberschriften immer in Rot, Zeichensatz Arial */ H4 { color: black; font-family: Arial; font-size: small; font-weight: bold; } H5 { color: black; font-size: x-small; font-family: courier; } /* 6. Blockquote St=E4rkere Einr=FCckung=20 */ Blockquote {margin-left: 10pt; } CODE.list {margin-left: 10 pt; font-size: xx-small; } } /* 7. Listen */ UL {color: black; font-family: Arial } OL {color: black; list-style-type: decimal} LI {color: black} P {font-family: Arial; font-size: normal; } TD P {font-family: Arial; font-size: normal; } small {font-family: Arial; font-size: x-small } From - Sun Jun 6 14:11:04 1999 Return-path: Envelope-to: pharvey@interlog.com Delivery-date: Sun, 6 Jun 1999 03:55:51 -0400 Received: from plus.interlog.com ([207.34.202.21] ident=root) by mailhub4.interlog.com with esmtp (Exim 2.05 #1) id 10qXmY-0002kw-00 for pharvey@interlog.com; Sun, 6 Jun 1999 03:55:50 -0400 Received: from lilly.ping.de (qmailr@lilly.ping.de [195.37.120.2]) by plus.interlog.com (8.9.3/8.9.3) with SMTP id DAA23367 for ; Sun, 6 Jun 1999 03:55:48 -0400 (EDT) Received: (qmail 26070 invoked by alias); 6 Jun 1999 07:55:45 -0000 Received: (qmail 26063 invoked from network); 6 Jun 1999 07:55:37 -0000 Received: from suprimo-54.ping.de (HELO koala) (195.37.122.54) by lilly.ping.de with SMTP; 6 Jun 1999 07:55:37 -0000 Message-ID: <001a01beaff2$66b90320$030aa8c0@koala> From: "Markus Rathmann" To: "Peter Harvey" Subject: The newest docu, to be sure :) Date: Sun, 6 Jun 1999 09:58:43 +0200 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0017_01BEB003.29819060" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 4.72.3110.1 X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 X-Mozilla-Status: 8001 X-Mozilla-Status2: 00000000 X-UIDL: ea3859ca9b1d73dac919ee5e69391b0b This is a multi-part message in MIME format. ------=_NextPart_000_0017_01BEB003.29819060 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Hi Peter, I'm sorry, but I think that you haven't got the newest version. Therefore I'm sending it to you again. It has one more page (Obtaining Datasource names) and a few display glitches (mainly Netscape) solved. Furthermore I've added a link to the unixODBC Homepage, so that you may use the complete browser window (if you like). Bye Markus ------=_NextPart_000_0017_01BEB003.29819060 Content-Type: text/css; name="ODBC.CSS" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="ODBC.CSS" /* Style Sheet for odbc documentation =20 M.Rathmann */ BODY {background-color: white; color: black; font-family: Arial; font-style: normal; font-size: medium; background-attachment: fixed; } /*=20 2. Die Verweise: Standard: Text unterstrichen link: #008080=20 vlink=3D"#800000" alink=3D"#008080" */ a:link {color: #2222ff; text-decoration: none; } a:visited {color: #3333ee; text-decoration: none; } a:active {color: #4444dd; text-decoration: none; } TH {border-style: none; background-color: #dddddd; font-family: Arial; font-size: normal; color: white; vertical-align: top; text-align: center; } TD {border-style: none; background-color: white; font-family: Arial; font-size: normal; color: black; border-width: 3px; border-color: white; vertical-align: top; text-align: justify; } TD.center {border-style: none; background-color: #ddddff; text-align: center; font-family: Arial; font-size: medium; color: black; border-width: 3px; border-color: white; vertical-align: top; } TD.head {border-style: none; background-color: #ddddff; text-align: left; font-family: Arial; font-size: medium; color: black; font-weight: bold; vertical-align: top; } Th.head {border-style: none; background-color: #dddddd;=09 text-align: center; font-family: Arial; font-size: medium; color: black; font-weight: bold; vertical-align: top; } TD.big { font-family: Arial; font-size: x-large; } TD.small { font-family: Arial; font-size: x-small; } /* 5. =DCberschriften immer in Rot, Zeichensatz Arial */ H4 { color: black; font-family: Arial; font-size: small; font-weight: bold; } H5 { color: black; font-size: x-small; font-family: courier; } /* 6. Blockquote St=E4rkere Einr=FCckung=20 */ Blockquote {margin-left: 10pt; } CODE.list {margin-left: 10 pt; font-size: xx-small; } } /* 7. Listen */ UL {color: black; font-family: Arial } OL {color: black; list-style-type: decimal} LI {color: black} P {font-family: Arial; font-size: normal; } TD P {font-family: Arial; font-size: normal; } small {font-family: Arial; font-size: x-small } unixODBC-2.3.12/doc/ProgrammerManual/Tutorial/query.html000066400000000000000000000070171446441710500231010ustar00rootroot00000000000000 executing a query
Executing a query

If you want to execute a query you will need to specify a handle (SQL_HANDLE_STMT) for a SQL-statement. In order to get one you have to allocate one with SQLAllocHandle.

Then you have to think about the SQL statement you want to execute. As I mentioned in the introduction I assume that we have a table tkeyuser which contains the following data:

iduser dtname dtmaxSize
1 Christa 10000
2 Nicole 9000

In this example, we want to execute a query which returns all the rows for the fields iduser and dtname in this table ordered by iduser. So the SQL statement would be:

SELECT iduser,dtname FROM tkeydata ORDER BY iduser

If you execute this statement you would get two rows each with two columns of data. This data has to be stored somewhere so that your program can actually use it, so you need to define a variable for each of the columns. So you need to bind a column to variable in your program. Binding a variable automatically stores the data of the column in the variable when you retrieve a result row from the connection. It is important that your variables match the type of the column in the table within the database.

So we need to bin column #1 to a variable of type SQLINTEGER and the second column to a variable of type char. This is done by SQLBindCol. Therefore we add the variables:

SQLHSTMT V_OD_hstmt;   // Handle for a statement
SQLINTEGER V_OD_err,V_OD_id;
char V_OD_buffer[200];

Now we can bind the variables:

SQLBindCol(V_OD_hstmt,1,SQL_C_CHAR, &V_OD_buffer,200,&V_OD_err);
SQLBindCol(V_OD_hstmt,2,SQL_C_ULONG,&V_OD_id,sizeof(V_OD_id),&V_OD_err);

Yes you should check for the return code of the function call. I'm to lazy to code it here once again :(

Now we can execute the query by calling SQLExecDirect:

 V_OD_erg=SQLExecDirect(V_OD_hstmt,
             "SELECT dtname,iduser FROM tkeyuser order by iduser",SQL_NTS);
 if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
     printf("Error Select %d\n",V_OD_erg);
     SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, V_OD_stat, &V_OD_err,
	               V_OD_msg,100,&V_OD_mlen);
     printf("%s (%d)\n",V_OD_msg,V_OD_err);
     SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
     SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
     SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
     exit(0);
    }
  
unixODBC-2.3.12/doc/ProgrammerManual/Tutorial/resul.html000066400000000000000000000154541446441710500230720ustar00rootroot00000000000000 Fetching Data
Fetching data from a result set

If the execution of the statement went fine you are now able to fetch the data column by column. May be you would first like to know how many columns there are in the result set (if you use a SELECT * FROM tkeyuser you wouldn't know in your program). A call to SQLNumResultCols. This function takes the statement handle and a pointer to an integer variable which will yield the number of columns after the call.

Knowing that much we can add this to our program:
// At the beginning add:
SQLSMALLINT      V_OD_colanz;    // Num of columns

// At the end add:
   V_OD_erg=SQLNumResultCols(V_OD_hstmt,&V_OD_colanz);
   if ((V_OD_erg != SQL_SUCCESS) && 
       (V_OD_erg != SQL_SUCCESS_WITH_INFO))
      {
       printf("Fehler im ResultCols %d\n",V_OD_erg);
       SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
       SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
       SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
       exit(0);
      }
   printf("Number of Columns %d\n",V_OD_colanz);

  

The next thing you need to know is how many rows have been returned by the query. A call to SQLRowCount should quench your thirst for knowledge.

The last thing to do is to fetch the data itself from the result set. You should call SQLFetch with a statement handle (which has been allocated and SQLBind has been called for all columns). SQLFetch returns SQL_NO_DATA if there is no more data in the result set.

So here is the complete source code. Real C-programmers will moan in disgust how inefficient the program is coded, but I prefer it that way (doesn't it look a little bit like PASCAL?). Take it as a starting point for your own endeavors with ODBC.

/* odbc.c

    testing unixODBC
*/
#include <stdlib.h>
#include <stdio.h>
#include <odbc/sql.h>
#include <odbc/sqlext.h>
#include <odbc/sqltypes.h>

SQLHENV			 V_OD_Env;			// Handle ODBC environment
long			 V_OD_erg;			// result of functions
SQLHDBC			 V_OD_hdbc;			// Handle connection

char			 V_OD_stat[10];		// Status SQL
SQLINTEGER		 V_OD_err,V_OD_rowanz,V_OD_id;
SQLSMALLINT		 V_OD_mlen,V_OD_colanz;
char             V_OD_msg[200],V_OD_buffer[200];


int main(int argc,char *argv[])
{
	// 1. allocate Environment handle and register version 
	V_OD_erg=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Error AllocHandle\n");
		exit(0);
	}
	V_OD_erg=SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); 
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Error SetEnv\n");
		SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
		exit(0);
	}
	// 2. allocate connection handle, set timeout
	V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc); 
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Error AllocHDB %d\n",V_OD_erg);
		SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
		exit(0);
	}
	SQLSetConnectAttr(V_OD_hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5, 0);
	// 3. Connect to the datasource "web" 
	V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "web", SQL_NTS,
                                     (SQLCHAR*) "christa", SQL_NTS,
                                     (SQLCHAR*) "", SQL_NTS);
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Error SQLConnect %d\n",V_OD_erg);
		SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, 
		              V_OD_stat, &V_OD_err,V_OD_msg,100,&V_OD_mlen);
		printf("%s (%d)\n",V_OD_msg,V_OD_err);
		SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
		exit(0);
	}
	printf("Connected !\n");
	V_OD_erg=SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Fehler im AllocStatement %d\n",V_OD_erg);
		SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, V_OD_stat,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
		printf("%s (%d)\n",V_OD_msg,V_OD_err);
		SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
		exit(0);
	}
    SQLBindCol(V_OD_hstmt,1,SQL_C_CHAR, &V_OD_buffer,150,&V_OD_err);
    SQLBindCol(V_OD_hstmt,2,SQL_C_ULONG,&V_OD_id,150,&V_OD_err);
	
    V_OD_erg=SQLExecDirect(V_OD_hstmt,"SELECT dtname,iduser FROM tkeyuser order by iduser",SQL_NTS);   
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
       printf("Error in Select %d\n",V_OD_erg);
       SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, V_OD_stat,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
       printf("%s (%d)\n",V_OD_msg,V_OD_err);
       SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
       SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
       SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
       exit(0);
    }
    V_OD_erg=SQLNumResultCols(V_OD_hstmt,&V_OD_colanz);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
        SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
        SQLDisconnect(V_OD_hdbc);
        SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
        SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
        exit(0);
    }
    printf("Number of Columns %d\n",V_OD_colanz);
    V_OD_erg=SQLRowCount(V_OD_hstmt,&V_OD_rowanz);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
      printf("Number ofRowCount %d\n",V_OD_erg);
      SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
      SQLDisconnect(V_OD_hdbc);
      SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
      SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
      exit(0);
    }
    printf("Number of Rows %d\n",V_OD_rowanz);
    V_OD_erg=SQLFetch(V_OD_hstmt);  
    while(V_OD_erg != SQL_NO_DATA)
    {
     printf("Result: %d %s\n",V_OD_id,V_OD_buffer);
     V_OD_erg=SQLFetch(V_OD_hstmt);  
    }  ;
    SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
    SQLDisconnect(V_OD_hdbc);
    SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
    SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
    return(0);
}
  
If I find some more time I will add something about diagnostics, cursor positioning updating and and and...
unixODBC-2.3.12/doc/ProgrammerManual/index.html000066400000000000000000000113571446441710500212420ustar00rootroot00000000000000 unixODBC

PROGRAMMER MANUAL
Peter Harvey
19.DEC.01

Introduction

Welcome to the unixODBC Programmer Manual. This manual is a starting point for a programmer who is interested in developing an application which *uses* ODBC. This manual does not address Driver development or any other development which is internal to the ODBC sub-system.

Why Use ODBC?

ODBC provides a portable Application Programmers Interface (API) with which to access data. This means that your data access code will recompile without changes on all popular platforms. In practice; portability is sometimes hampered by incomplete drivers. However; the core ODBC functionality (the most used functionality) is always supported any working driver. Other advantages to developing with ODBC include;

  • most popular API of its kind
  • most mature API of its kind
  • skills more reusable/easily found
  • hundreds, if not thousands, of applications use it
  • available on all majour platforms
  • easy to change data storage solution/vendor (ah; freedom)
  • easy to upscale data storage (developer and end-user)
  • arguably the most complete API of its kind
  • many books on the subject
  • greater support base
Languages Supported

ODBC is based upon a C API. C++ programmers will find a number of C++ class libraries for using the ODBC API. These are wrappers - using the C API internally but can provide a much nicer way to use ODBC for C++ programmers.

Any language which can call a C API should be able to use the ODBC API and most languages, such as PHP and Perl, provide an interface to work with ODBC but these are not covered in this manual.

Architecture

Client Libraries

These are client libraries which are specific to the particular database being used. These, often, provide a C API of their own which is used by Driver developers. In some cases these exist inside of the Driver itself or are statically linked into the Driver. Any Client Libraries required by a Driver will be a part of the installation of your Driver or will simply be a requirement for the installation of your Driver. Sometimes Client Libraries must be configured before any ODBC configuration.

Driver

Driver Manager

The Driver Manager acts as a gateway to the ODBC drivers. The main advantage to having a Driver Manager is that the end-user can configure the Driver Manager to use a different Driver than the one original conceived of by the programmer.

It as virtually identical functions declarations as a Driver which means that one *could* create an application
 



 
  unixODBC-2.3.12/doc/ProgrammerManual/unixODBC.gif000066400000000000000000000002341446441710500213370ustar00rootroot00000000000000GIF89a l! NETSCAPE2.0!Made with GIMP! , Igͷԍ$Y}R/Lw[JBCŒ]CF5unixODBC-2.3.12/doc/UserManual/000077500000000000000000000000001446441710500160415ustar00rootroot00000000000000unixODBC-2.3.12/doc/UserManual/Figure1.gif000066400000000000000000000173571446441710500200470ustar00rootroot00000000000000GIF87a}2b666LLLmgure`1.gi)f'*?*^xZ[*~[R R*R؈*W**0 Y\c* X*0Y)c**XY*0 0YY\8z***04YRD*R*z R@X0(*Y*\RT`a@[) *,nZ T| *غ@[**R R T*@2*IJί**ڪ@*M} *OverwJri*tpe exist*ing fi\l e '/hodme/pharveyunixOnDBC/,}H*\ȰÇ#JHŋ3jȱǏ ,`@ɓ(S\ɲ˗0cʜI͛8sɳϟ@, H*]ʴӧPJJիXjʵׯ`ÊKv)ёeX˶۷pʝKݻx˷߿ LѴeFǐ#KL˘3k̹ϠCMӨ//fV1Ʃc˞M۸s6WN$ ȓ+_μs}sسo=;@f2}p=Q O?(&WVT}gvRQ*_d"Y!JVd(bf-"&^6#bȢفWmNAʗu g} G}؋3Ycc6jFm㚞I"80xeHZQ2$QJwpgPJiHyyzYf )jvBylv'ʺj>xk@ꩬA)H7U(~G]f;ib坱 Ƃz븿K"hk;*ko{*m +Ь6EQ*Eq ,NY+oqkpk;xZ/ۦ1+pȮ<^7,U 6VP @mSo "grc熝_+⛳.+:5XLZJ?lNXQD-u~?5=˟|onv4inw搇A H7pR*%ӄO+PO { &NjGv+= w\C՞zdήh5q_j@S(8PH*Zq'J .z` Hƨ0hL61H:x >Ndy I4bqH(6y$$O"I>LoD6|(3Pr#qzReV;EtOVE(S0M~"T EV@Bt.8ИlAٔB}iMҖ8GJx.էAe8JԎzV=jLmϙԥ\KXIՑU:w*ա?5S WSr=kPERw“C=DJ V)UձUK^'W.ͫ==lDTFUE)hղ*\Eȵ.U}kl9vIg[Vv hթVqE,n\+g-Ulr׷R5kgQ骵m\%Ww~q%XjWpFV.akږ.o{ռhmmZ9 [Z\ھw;_zm/;,ѭC- ԉ3+}:@qsbJ!\L%ݫ~ֹ0~*ilWխB}qE,3#, Xp^)xe2vSmkF3eF0=嬞iC|0<.y3~!5L'2w\M'&MEQnm|}8znsl>5.:4,=Cr\$hZ oϓz#V}{s3`{^s6wmR 8~p}2_xA'npZLo8mQvUmtxrsz|5$q.q(|$$Ѓ>$F?zPtT茥ԧN[Xӓ8{`/N:=ݙ\Nw/xϻu>gO>1?x 񐏼>[Al7{>8()wxd}aq x^WrmGzg~|uրh}u7Ww􀼄[5g!wSqk]I3pfc&O(DV,XRm~#hmK3;a=il֖"XLa5^.bfEdHhaXW5Kbv_)vO 5}S~Uegە\<]HtXiYr8;Pid%ehd\q{Hg#{h6QXi&UffeЄddLY腉cFek8&XQ$eHH(FHˆFs8dHaXxUC^HLo&dq0erHFgxx}V(VƆ8bsx`9Zd޸_V]ZRƌGV@iz6T*oYx8xՒ%$%gԐ%oȉ>yw(F9IIKYH@iqBh||}WFYO[ w1lٖnpr9tYvyxrYLI YPy٘9YyٙY(9\xٚI(vGٛYnwYyșʩvĹ9ԙvYٝi׹vYyڷg9r99Ys9Zؔf}ڠv\z)Eji":ɡĤ$,&K(Z|-:4ڟ/jK1ʠ5X/UmXYR(f[{6V^u`Ng;*w]8vMFJ+i^󨷾{FoqS];8{{I[Yzh(N[+<[LZ&JoXZkYVٺO뻘 w{;nʻYۼeK cI u;Kv;G[:Oɾ˼; ;f wۿQ&{FK3w ̲ Y<-h |"l\!I* 's)& 4L6<3>,8< 'zH J L8RLTpV|\\^LqBS\ f̭csF vp\r,H\z|Wz,hܯjyDŽ\\ȹǎȁ<<ɱ *ɘ|LNʢȕl|ʗJʬL˥:*[˶ ˳K\̣|ʬ{=;֌L؜|\<μ\|Ȫ|EǹH(.%,␩t24v6~㽙<Θ>o@9!FnEҬPR~T^寉/ZJUv*PN fKZWn湥FnI5tzx|XΙ~h~h茮x䉾O㗮H~I.~K⣾g 8i>^̾ػxy^~Ȟ1Ǘ^ݱ>λ~^پތg^~NʾN7|y[#֮moW y?|]8* $YiS1be?TU(pXYqԗ0Wao50TMhU!M4ľ mV:No`J?eb^@f3֊%MXcPel\ՖXV`{WmU`n(d2$f eZ߹xnۋ}hokڶ%_e &/z?k &|HUW؍kjof({[i,h{iOfUʍ-jlFH&hg_?CYo^/W zOFnώ/\xgg6gA $hp`… >DA)ZPŋ '>G#ir]Bؒȕ1Q)!ˑ8o<ѥN@{ɠ0HT5m|ӠJ!^kP/gz(lYX~5 ДtvͼaT`i۲k՞J: 1cT(sۭ<9f͋/ 1iĞ]= ڳv:nmZoنmzf̺65%WC^MF^x͟^zۿv|7'O1|o>@o&B /İB7d7?JA9qTBɤR C 8g M1GwGCQXtqB1I dI'2,]D2K%-K/3LnŅLRKM<+ڴ+qN< <=2ێ dTK653B@B䬽I9eoS2CEMU!ͫ8m>j.޸,&54YI.PT(Њ%eˌ65]5XjcEzjoUެ;.Wn w=R͔SLRU),V>k -B _}W|:ٴX͢lخ|5wՃo5b-KOZw3EI.cFz}׷WMㅵ8;u.*i&:srᢏn5_yߧNd*ٽBx׼ GYe:ez`Mfv+-jcm^Efi b"qTI XT!ox̣HF6*q&;"ґd&A1Iv59JRI\)YIҕP?kBd"cK^2>l`ԿɗDf2k% 2 @bHf6 @~@\RDg)yp @;ؖNzSNwFr |nqďN|z-\psڮ]w7}̶\ps׷\ѷH:wx&V{%]r! qjGu F[M(@Z(!s>!|^^(V\d9o7Afu+#!89܇6#>Id< U"i#:idi`M)dSv8HJdq:yJ)%hYJ&!F禝$xWtbdzJ*j[Wm3$fck>Z'B*+iWi蟞ii)(O!? Q*꧆,F*Zxw`"kӪEXd}J{ *b) +)K&ˢ^el egŚN,g wlˁeƯyrGLW[G8<)<L@-D-ҌL7PsTWmX#\w5c-vK|m`+3CpKM PwR]Mv?wOnn8a^'{ Ndwθ㤹U.z] MyT;.N$<۔|Mɼ޼Ot|`5-oχY5<ۤܣNӋ/c~췯6.~w9'ضx[P?\/} G8*Nz=@ NH>ł36yPB GHЅ{KkP 'B0V'CEqED~a|[[sF0Ⰺh[#H4Nt =<:tTa];ЉoF:2ZIJZ̤X4䃠 (GIRL*WTGpIfIZ̥.w^ 0I{e1f:Ќ,9)Ș6[Rsmof7Ir3ߴpX fu Vհޭpg=IW^W5{aMbh¶&oqUsvv= h+;ى;dj{6=),q fn'&7̭O~3Ϋ#gv>jJ-g{_zz#)<ƲƓ<*O\x.w$.dy"o]dij昏|Yn0qScY*yѓ,Ǹ5zUФ+lݶ췯oq?#>szўvm5$j.xxO'OPqdH[S 6c̃~SS/ӗBh~{ טcǷhj _k?V:]i|2[9}y }g=Or~p Oo ?qˉZCqRg~~ ׇf|}z s(5uVdMVuw6%F5|vł \3(4XW7^3JKVFxHC6ׄNxlWxhGzRoThqZwhyTy`by,x_e8j?*yH%|~N$7h~XXVX=Yǔutq;eT`'M\)P5TȈۘXoamM^IOaKeeƉprea=~Tfff(UU}{a\tӸpx9W]F,~٘,ƖN_9G9t獙qx eIٚeĉH 'Eah6dw8raٛbaǙmYmT`y rx_ٛ_ljɟIVC)gXAיxm&99g e5XIOqΙT8aDFUǎ 8٩a*͇Qqyϧ ||kX)9rKYLLG dz甤eӤVORJLYYTzIُR)tBzaJVJ٦nj1 h#tZw2C&z:k|ڧ[`:TGtzFQFyZEZGr¥I:zzڨڪ::w7٫;unixODBC-2.3.12/doc/UserManual/Figure3.gif000066400000000000000000000134511446441710500200400ustar00rootroot00000000000000GIF87aYPHPTPPX`PlP`d`pppl9P@@|d5@|'`@/xHl> @\6@! 7|H`5>{6` @D/| @|A`/8l7 aBj@66/@\D l/ @,A@7@@57@t6j\/ll @@@H/>D/\5>@B6!f@/\G 6q@|<7_#@l @=/e@x/\|\(>#@0c |f/#((L/n@#(6|,'@49l @ '0 @@l/H>Dva~*iTfh9^qPV@TG~)X:`"kM%We雎\&iЍyrhG^Tj妜?>։碌" (VYY6駙Gvju5Yg*zo'뭸ު盹ꫩ*찟K~)6lա4@SVkfE1kSM&*R[fkmQ[PoֹRŋ 7<ֻWտ;wmnCn"3,ϵ߆-,mgW}rg03߂2VxeZNݡGl?GM׽'KL4c-Vқf^K-] seqjkc]׿Q)|oYs-m8[&;sEۃ;N79nW57p4 y_n:Y}3Y9X~[unv{}XAj//}Ygx;#{ս~k >'?? H:? X̠7z GH(L W0 %P8̡w@|a H"HLC2PH*PT d@(>f]`]8F 15iL!pTъ-Ģ(;1~ a G q#x5r!!HJx<hbeEY=^R9>d$$FRЕj\e'92 Y9F^Rrc( Iie,{I23 Mb2Lcns(eis7?(gD;yMkBs&9~ɢ?)Nlf?Nmҡ ->MNzҔ(AЊӛu:cGRf (;:͐ӣ0(jјԥ(h(ӆvt $M1JTTl>EN.ՒuQ:SiK+RvTm-wzNV0HbTgf[7ԫ,a >if_ ֺo:B=e1.g<؊7Fccg.)a6'1nL.@ˮ *sǬ峠-d?oY̆&DC9˞'xJ>il7MNk'uCRԣN5W]OSըfaYҸ洓 |v]dDYN6=d8ZЎv -ZζWhmm7iq&v[vgxηk_y7Mc~_=r.sxNxc2~8.g癟/>xSG*BTz5Unn㹍yy )f{yFzh)cIJ׶ϫx\({h v7:UʷMm^}j#ۙLJ]ŀy! g;R s[-<7j}?xћt&Oi̪oz3w{AO6,=}۱e&/A+/%#|{i{o>ǯlœ<׿h|d_e_Η}78_%`HFL`M O{DD h[3WxvQeTQsXqrZ}0(Uwg]bXwXEFxq4xDD8d-x}1>wN(CG6eGhb)uUQzsVVR?xl}Wa"ȅvutZaSe{qx<4-*|s~Ah}hAuX(EbntcW%`DUxKX_Xur؈xDX{d.?67FT%&xCw^fr,5YLhHe`PXDHw@`P[MJ%sWx]MU8HD pZIXjńe5aih[\Twv-#fa(?TAx[艨,8[H>duHv95^Y8vņ%'9f'(C6Vw*K)39QȔP9RKd8sYt[I)v=aɇݷifhiCeibr9xԕ؁ux)kt` |<ٓ y@ٙ6?锠)o)CYxVyxYEv14 m Cɶ/ԛ)lB9VG nBٜ:iY0yوڹ؝Yzؘ(tYIEǙt+Ԟ)gBk&kjkFk:柵YIz ʠ)gu+8V)tpS ơ(&:*'آ.j074~6z-qƑz"jBDX7AqvU艔HmIFU:CQtF֥mhNpZ*FQX/O?j8/8dڣX$wH%M5ԋxt]XtǥjX|:nʤVy5[ozvȐ7etrPP :qzYnhZ:slz39$foi楀Ƀ󥪬=hux*Ě(våRƎ\Q^븩XfW[ͺnJCz*v[j cht ׮sڕd4v 8`;ê2 H"V*gtVY[qs`n7o'aOj?UyHI[Ue옔r*tikaxr=˨#mh" Jo>jzeȧ:Gl3D[;d9:oSv&wyUg:$,r ~t['x}n{8x  {;{˹˖]+6Ym׺g a(K{~{ۻ{FƶRHe{X4`[fͫ5cVNh_bj5wnɽx:TkXCK{D۰hƛ8׿b%NW"UIjF(lK>d]e 䁬4.8)(JmIfPhR>VV.hX{\^g^s]ED.h\Tv!>h9!,uGb[ZHKk M~rwܫ"}]h@F~M26J\ .;vʨ*ڨ$V5 뿛q^l.ۊα܍;w:d]TW9r->bf^~화TcլhUF.~ kBn~OR=, >jhҶ) 6 _"D޾lTLt*A,e:4K6x;unixODBC-2.3.12/doc/UserManual/Figure4.gif000066400000000000000000000064511446441710500200430ustar00rootroot00000000000000GIF87a[PX`pppH>@686XP@|d@|'`l @@//xH/>\\>6@̘!7|H`>{6`/ @1| @|.`/8l7 @a@@Bj@66/@\1 l/ @,.@7@@57@t6j\/ll @@@H1/\5>@/6!4@/\G 6q@|<7_@l @=/ex/\|\(>c/|H4>8(l @(RL)n9H>#8(|0 @@898 H>l`Da'/,[H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜISb8sɳϟ@ JѣH*]ʴӧPJJիXJׯ`ÊKٳhӪu۷pʝKݻxs ߿ LÈ{ǐ#˘3kޜqB=ӨS^ͺgЀ*( T}˔P߭ Nx8pl?(]P_ν=+<鶧_oMߴ @HO_l'|N^fnGm9 "h₺GY}+_}#4hT!'dVgۏ`X:haGjPF)Mfeh=4$(_2`c.9hٟg$O?d]PaIe8|gkl0RsYJm埐F*ial*7饘fiP榠*jl⨨*Ƹ*\j뭜ъ뮼+rP5%6F+-LT,fVfmۆ+@גM+Nҫᄆ[-+ӽK Cj/7,S-g1ËoG~U18(9)lnV*l3R:S= |?ݧ7'=p |O>LRA3yrRw\3;RMNXG6Xw9MTjlm_ޮ7L#2xg-Ue|_;M'd}F8?yqKl#"".z^n;A.ġ']s[GoC?8wW:他{-_[>G>/|[ HL:'H Z̠7(Aq GH(L W /0 gH8̡w@ H"HL&:P)ZX̢.z` *hL6pH:x̣G0: FAАHDdE4@H(:a&xI!ƆEu ^>04pzA4qmp͚4ݼ آiygB6+)}k;oϾvEv,E/O4/i.)^O76}EgEV8qNLo|gtχNHO(;=}ԧNu9*t<}>F$ͪh]s܉^ϯٙaiϻĵ7/okOu]3;~k/,Z.XX5E[F=z4ޥ^d ֻi}eS+Fq%UQ6R] j3>d|Q{ۼn[߿'uS?:C qH>=V D~8x|g؈Dž8X4;unixODBC-2.3.12/doc/UserManual/Figure6.gif000066400000000000000000000272441446441710500200500ustar00rootroot00000000000000GIF87a@@PX`pppptlȨXܨ@@//xH/>\\>6@̘!7|H`>{6`/ @D| @|A`/8l7 @a@@Bj@66/@\D l/ @,A@7@@57@t6j\/ll @@@HD/\5>@B6!f@/\G 6q@|<7_0%@l @=/ex/\|\(>0%@c/|Hf>08%(l @(RL)n49H>#8(|0 @@*97 H>l`Da'/,+H*\ȰÇ#JHŋ3jȱ CIɓ(S<0cʜI͛8sɳϟ@ JѣHӧPJJի/ʵׯ`ÊKS+ٳhӪ]ٚ4ݻxVfܹrKd= xf_m`MqZ[7f;<34Ө*^,s~%ϥLY4M˟K=,ݿ{Cȝqa&hSΦ_~]{ۡc'-pw_~ha Yzˢs?݀ 蟀m;_|LGg5؟m pv zLVc`e߇y wi 8$ƠL1܍6zyx䑙ȥ'$"jJU8&uZbe`昞'Bޚ37FW(vYgyyhuev|f袌8q,8Zjsڥ*jª45+Yf*&)쳮2 *mfvi~+w覫+`AL,l' 7|LFlg p@ ,R\K,pn54lxtsCYYoTl%UO!# ͘1,T> IBO@tݑ(3$'IJZD$sYG4>+>,pFRr`'fOv%)gIKb']7p@-IL2+l%/K1*4yё\fU)0Y24Yjq&3}Y8`@8QȞX>9Ns&3 7)1xSЅLDYL^SF7юzTNevO>D%Ї0(E- 4"8ͩNw:Ȑ &)}iLzT4f9.u# wxLNm>*T>uQETgnX-(RMꁢ 0+]X*ֳs2_IWiEC:W`x5^TME{=gAP;:ӱT+"fmk/kʴv_9@;ѦHJW]H߉F.,+YO֓-6q JޞEtBZF̸x!&]f% v{夻;x۰rmYX|k$ ) 3bĥnv.R0`x*5zWef7?zz5'DawJE 0opY%v?^VM&|b kn9tb)7~pDs WD9eHv`(@.Vei (% naC\k+NN{d5e>3WFzX| :$MBZT|ca )NS@e eɽvunlx9blIV?M0{ 5F}?[9` UK:-4ӌѕ=iU,#6ގ"Z^<-\6/}12&3=_UJK۞i嚝\+.r\)פֶPym pd.t?Jo4\7ڽ8, Xh#bGw;>ف|9 XO6}攝h-Vޥzջa:oc=wϰO+=a;l7ջD~_KS;/S__O~OOJߘ޿f˔d3m*Y z}7\BuWVWJv0u{wND7 HJVbp(~b8%~)Ӏ1~7Huy淂'H*0Ȃ.8>xA&32Xm|t81#hQx0J؁/X~Oo$kWghJS}4|چY1[⇂C(DdhfȆBdžJGxos1gL}WyIxLd1~X4W"xJohkwZ'ss'p!HwF{2[huȇP򷆫Ԋr['w7 ODžG惿}Syzh(fxrHSndf\x.t(z7Y! vmtyMqȃwp}%/9CP6"is9ǍVv!|xwd)U,cqrY|rtOs;Ivx&z*u-ux[ő)r6P7`f7wo4J MZ{teTM5j\{^ do˸Ug ~yx'8vW$yjhXfZYuiZgO@RwqhLb9DșWy?8]=H癕ygPryǚ_i5yfapI[)G}ǩOٜD|piE雓銟I؉ɛI_ 153߉9^0&ɇe::9`I591V sm l V6aK StBu֠yw\P砀ل ~bg*Z(թ( ZɓNYy(h=I{35`A\U 'ʓ LwIyKM7ht-)#*jY8i^ÇD8YyRFI% ~\zyZYI *z`ysxWȨ=ɖzآJ|isy.z&% }ّc09&W:_j|YfhZ㴬vج\*M*ںԭ2ZD}犮(҄d~ $گ :2~ ;2UUh 00+l6x) 0Hgi8S ıjZ"k Kq:'O.òYï033K*eG˳&EfC zwNV)Kdׅ/;*[*OkȤf[}VX{0Vz. vZwKDyK{}{JA5Kt7YQe۸IJ Z0q˵H{[aKP{Y+$iiKymHL;Ufk0"K- 겝RhԞټ1Л0{캹廱۽껾4si[۳ b0 S+hۿ C Ȋ5ʈ0]I 9+2 \[+Fk |釨+R;7r% E[ pK9y.:ĤZ(41%+0Z"۵,̂p9pFK^JsLr+6x #ƢĢ. ɸk mtl1vw@+[X~iYpW2<[k63̵HƩ[(GvHȘl\3+׊)z(wJq<\k0L0KJs2pN,3_6ƭ3+ĊYL{ͬ,0 L{||wl+{L0w;v̿<'<,k#Ô%yd (,9> 1Ҙ<Ӹ;lI-=]2ESܯ7m;ί[` ɶr 0]4 z,l;=?28]Njǝ<֢$+"~0MȡQ)6̀MI]F> ~Jlyy⋭Ky4 N0N}͸^/i>o>0q>g.w~m@\ڛM=Y8\eл]^Bnm׭4x8[!MQ+\:3-jeߧ|\>u>{ϕN@Tm8N؋^TVȍs.n`>?:{H.>p}㴼ޑ+̜ꬭG}=V<^ޱe|S=y^#.{ mA /?қ.SK=放.c')ߚ|n.9}w9nؽu?zʧWO9gKJێI%ߋr(x?/ӝl_n_o}{m?ۇ]{ ,˱~u_3#ݝ޵j.?~ -__/?ӝJf/_3oxO /@T@ >Qć&XFbRH%MDR Y@cSN=}TPh4P!Q/fdȀT,\UV]仏P돬@O@,ێALj{A2} QD2ITO|"I:1HDjD#KTL3b2A'!!)*PC:N/ӵʚLA)ݴ{FC 1K;LO-g.G%OBB$͠Ik*Ҫg*п픦_NX=TpqugEmJ(Sn-b\4M4;S-TU`M*UR| 2"<_4LZZ4iEZUsEie-ؒE3Ju\ IKm%<%gX擵$s-^z_> mKJEeZ7i\J+5n]d]IIMg[~ӻݽm6IW\bc_o `YdsQ{_~ۣAPyR19\ήp]p[;0ogĘ sbX-v1~;֜2'1Z^<]o 2'6Ճ4VW/02l*A3떹3~Ys do3qYќva"i7C2{Ĉ(1#[mOZSpB7cL.DYWY5}HSyZ)c챒CE^\Q Nmo3(v+îC`,&uMIzT'v>re_t:^y֛n *;+^ 8m;Ov[ȼ#i kZ۟?LywȈ CmBuIqD䒱G=gw6q7q-f/'4PtC?xsޫ%z?}'7At- 'ž,n 1=@$ Ħ@7d?v'D ̝/;'lc;z۷vS {5:lt눢|};o^ܩo&{?.=QN2Rww}.`Az|/)wJD/~i_th|zG j'Mcn-,mtOqӎ? p @?$+@9@pI{ڈ@3@X: \j@{: @ Aٸ['@5ýԉdt/t#zzt>|񃈆 P8B,?s܃BB`+D3DBbaCNÊ.,/l0&2+=C57<5ˆCƠ;,C>T؋+4DzC̸A,D8ꃈ;KB,kC.A|Ll0L/DP$<7RܾSD L:>EY|,xz[\>;I԰W10,{4D!PT14TF ̎bEUd$rDEs\ t3ћƮ9vT w8NV#bbePrML/Mx]zP: 9&V!֍٤ ;mMCg<^O!VQREd_mP(´⍵b LѰ>eau/4M5mcp_ߒ}R./Kl%-(K>6TM@ٻ@`tSfUe)@AQ0h[f&fDby>f$7մrbWhd,}r(f gKg0g4u9g=)㦴fNl%bHgZW-`˭u,hC rkgeSb9bcPX83;ԁQ#u3jjK'cLsZ^hn;%s̬%j8rúh?KQĞjIץaΘVٱJm\]?@3Vϔ -GQAIJKtB8NhӢ:Q'R7S/ MoHeOP)TYZsUG^u[`vKu4 _egfb掘dWvgkvhJi julpumjvqWutr?'{nbzw@wyn_oԺ[gm*7^BpV~?o|kvD3Qr,'yt zg*wy Rw/>yGzkfY$Gnpzfvnf7w>!;unixODBC-2.3.12/doc/UserManual/Makefile.am000066400000000000000000000002321446441710500200720ustar00rootroot00000000000000EXTRA_DIST = \ Figure1.gif \ Figure2.gif \ Figure3.gif \ Figure4.gif \ Figure6.gif \ My.sql \ StarOfficeDataGrid.gif \ index.html \ unixODBC.gif unixODBC-2.3.12/doc/UserManual/My.sql000066400000000000000000000000311446441710500171410ustar00rootroot00000000000000select * from tbSysInfo unixODBC-2.3.12/doc/UserManual/StarOfficeDataGrid.gif000066400000000000000000000127101446441710500221560ustar00rootroot00000000000000GIF87ax4 4x<(PP\\8d ||x H4 8X\8hphhHpppx|xp(,8\l>6@̘,7|H`>{6`/ @| @|`/@|7 @a@@Bj@66/@\ |/ @,H7@@57@t6j\/|| @@H/> /\5>@6!f@/\G 6q@|<7_!@| @= /ex/\|\(>!@c|| |FDa'/,GH*\ȰÇ#JHŋ3jȱǏ CIɓ(3~Xɲ˗0cʜI͛8sɳϟ@ J(F*]ʴӧPJ )իXjʵף-JٳhbR,Kݻ_~p҂x LM|WZ8q⯄*Le,1 啜; 3ТjnsgͰSEMu֖u؛oxŌ8Y+:Gg-zMoin𙅏izI۳WO[Kfs9']zfib'oeR`ץ'_!h!eL ^y  jx61#w"(}4  @. XdAH!ʷWr"yX!eMVb#Yg9i"; *xGc0d.u L:ii$x&v{^YayqN)bF(ۧki"}JnnG諮q'j (goI|dǀxpBvELV[ު7*mn8fe /u "'}ګ+G ׁekb 0k/6iv:1 o8Ӊn뱯i0z,XhXb E fR٪N?q)WnּʱL&IOknvfg EO6_~Yk襁1{c'ά2^2, ׽rv>n߲n! >`X ȝ ',> |7zG_`@ XK Wo>^㟯o~/QV` HL: `"H Z̠7zGH(L!C@υd@p1 Id!8""04u8D#R6a{DJM.ONLbC1;h#рl< G/`LcF011"[F%chC"2Stbq>VґT#/YJx\ vXI/ ) E2Y, 8Z°t*7V 8CH-4&2_Eτ#)KD2хd/KnZ˔0)BbR$^Ә&-)O>2t';9x'9Asӛ&2aLsa'?w|* hB*Pg4h"sъe#}ЄNԛ+dLىRg2MAT2hʠjqlȆfmTnRVH̭z.X(Dfg mIK(fpI-!\a9ֺ vͫ^W ,A**$,b^*d'KZͬf7z hGKҚMjWY(鵰lgKͭnw pKWMrK@2ЅsZͮvz xK^@!k|Ep~C%{ c̸;%Lbegqf/lGLJ//;bCz1-ZyieCry`!Frlw +ٸOm};e߶,pX (c_x8?2qV`# ʯE *ٿoVp<ۢ&Qqhv;V-ܿ,Ña(sYӠ2g.=6/s󳊬h Yի3Ok>Yq2kMk2b }?ɮҗs 3<:~&W[ֻ5d37εo n=z6\hk#ۀvr|k[s=6 J7̙l8LM-k'5znU~tә ocjy>ō\wse#׼ җ>l/'_X\ԟκ]x;vS=t]`ڃ^\o'َfO{>wU3:n!әƈ☕(p_\/=⍧5vW{u{G2|M7yD/7=ģ_-*:+ڋ]|}yCp|<؟w>}Wp* ,_ Q'}!}ԧ~yBw~xwsxy?yxvrF׆t~ihYG|7Jgqi'|qo} 8{F &h6p6Ho}&phoFng;8JnN( v:Dlb`fifF)'yAy1\ `dž6boj?_aiXeą_Kcւei~uixayVW(d_1Ftd.|98X)YwEf|yXj8X]xCu@Y3](XV]cȘXb%XX[5֘(L%_8X(Y긎؎[([϶X\f?7u[%X_US iE+ 9 xt{@e9F@^7ْit?#i?JA%poBZhl"eiIZ?5v 9SϢAecB)gscWCٜ 4>IF?9D1F [ɘffՉ8^i ')v?ypفqbdtag9i)NU(37yO#>YLcנqMu䚔{[h:Xy^<*ZjfTF٠i@,FV)i4xɟ%9S2iiy :E-Z^zWƕWJNjViLp zyACz|؞,_&sEY%H])xx A@qYʨ;b/bI@rԨW.^t\u*CaZ4ګ@DXhCzj{HbV^zؚںڭʧXz蚮꺮fua8hfhz(hc*JN0- KEWK { yZXhڱ@[ kX);ė K'TTIDMtIDeM9v췲XR4U$U)E%U-K/+W(KR$S$d|%KӴMF[WH1ɧbpu@DJXH8N[&+Xy;RkS%Xqt˱w ;EQ[U5mP%X+| ˸):MX{Bj{[UX l2@CLM<;۸CkM5uXY K[;P[Kژzʴ鼟Z[]=f[ +} ھ;kKƥ0kzԋep0[|Z˫Ry8z@f6wdCeU&cs.l[̽HGjvwwb>s)v>D\[11[ihwv9g6oS8C]  &"q~,^)b+2N/.=8^57>;kDANcZJ>bGK;unixODBC-2.3.12/doc/UserManual/index.html000066400000000000000000000445521446441710500200500ustar00rootroot00000000000000

unixODBC


USER MANUAL



Welcome to the unixODBC User Manual.  This manual is targeted toward people who will be using unixODBC to access data sources from tools and applications which have been developed by others. This manual compliments the Administrator Manual and the Programmer Manual, each of which is geared for a more technical audience.

Getting Started

At this point unixODBC has been installed by your System Administrator. Your System Administrator should have installed and registered at least one ODBC Driver (we will assume that the ODBC Text File Driver has been installed). Your System Administrator accomplished this by following the directions laid out in the Administrator Manual.

You will need an account on the UNIX/Linux machine; this is also provided by your System Administrator. In fact, if you run into problems at any point in this manual then you should refer to your System Administrator to ensure that all required software is installed, accounts given and privileges granted. You may also want to talk to your Database Administrator (DBA) to ensure that you have access to your database and to resolve any questions about which driver to use and what options to set.

UNIX users can be given a wide variety of methods to access their account resources and these access methods usually fall into one of two categories.

1. shell account (telnet and terminal sessions)
2. graphical desktop

If you are limited to a shell account then you will not be able to use the ODBCConfig and the DataManager tools.

We are now ready to start using the unixODBC tools. The first thing you should do is verify that you have a working System DSN. If you do not; then you should create a User DSN. These tasks can be accomplished using the ODBCConfig tool.

Using ODBCConfig

The ODBCConfig tool is designed to allow you to easily setup a Data Source (DSN). DSN's act as an access point for getting to your data. In many cases; creating a DSN is as simple as picking a Driver to use, selecting a Server, and entering a Name for the DSN. In fact; DSN stands for Data Source Name.

You should find using the ODBCConfig tool to be quite intuitive because of the simple Graphical User Interface (see Figure 1) but you must understand a few terms before getting started.
 


Figure 1

User DSN

These are your personal Data Sources. You are able to; Add new ones, Remove existing ones, and Configure existing ones. User DSN information is stored in a secret location where only you can access them. Keeping your User DSN's separate from other User DSN's allows you a great deal of flexibility and control over creating and working with Data Sources which are only important to you.

System DSN

These are created by the System Administrator. They act very much like the User DSN's but with three important differences.

1. ONLY the System Administrator can; Add, Remove and Configure System DSN's.
2. System DSN's will be used only if the DSN does not exist as a User DSN. In other words; your User DSN has precedence over the System DSN.
3. Everyone, logged into the ODBC enabled computer, shares the same list of System DSN's.

Drivers

Drivers contain the special code required to talk to the specific type of database you will work with. The Drivers often come from the vendor of the database but may also be found in the unixODBC package. Your System Administrator is the only user who can install and register a Driver. You will select a Driver to use when adding a new DSN.

Add a DSN

You will want to ensure that you have at least one working DSN. Here is a quick step-by-step guide to creating your first User DSN. We will not actually use it yet because that will involve using other tools and we have not talked about them yet.

1. Execute ODBCConfig

This can be done in a variety of ways. If you know that you have an icon or menu item for ODBCConfig on your desktop then execute it using one of these methods. If you do not; then start a shell and enter the command ODBCConfig. You should see a window popup (see Figure 1).

2. Add

Click on the User DSN tab to ensure that you are working with User DSNs. Click on the Add button. Select a Driver from the list. If the list is empty then contact your System Administrator; only the System Administrator can add Drivers. For this example we will try to use the Text File Driver. Select the Text File Driver if you have it available.

3. Edit Options

You should be presented with a list of DSN options which you can edit.  Figure 2 shows the options for the Text File Driver but you may have a different set of options if you selected a different driver. Common options are; Name (a unique name must be entered). Description, Trace and TraceFile.
 
 


Figure 2

Enter a unique name, enter a comment, turn Trace off and click Ok to save it. You may click on Configure, at the main window, to come back to these options at any time in the future. Notice that the Database in Figure-2 is /home/pharvey/test.db. You should ensure that this points to something like; /home/YourLoginID/test.db where you replace YourLoginID with your ID. The test.db file should not already exist (for the purposes of this exercise); it will be created for you. This is how to create a new database using the ODBC Text File Driver.

4. Your Done

Notice that you now have your new DSN listed in the main form. This means that you can try to use it in any tool or application which uses ODBC DSNs for data access. This includes many applications such as Word Processors and Spread Sheets. You may want to test your DSN using the DataManager.

Summary

ODBCConfig is a useful tool for PowerUsers but it is simple enough for almost any user to use. ODBCConfig exposes the most important reason for using ODBC to access your data; the ability for you or your System Administrator to change the Data Source for your tools and applications. Please take some time to get familiar with ODBCConfig and your Driver options, perhaps sit with someone who is a bit more technical and talk about it for one or two minutes. You will be rewarded.

Using DataManager

The DataManager is a great, graphical, tool for exploring your Data Sources. It allows you to explore you Data Sources in a similar manner to exploring your file system. The DataManager ( see Figure 6 ) is split into two views. On the left hand side you have a Tree View'. The Tree View is where you can drill down to the information that interests you. On the right hand side you have a Detail View. The Detail View shows any details that may be available for the selected item in the Tree View.

Just like ODBCConfig, you can execute the DataManager in a variety of ways. One way is to go to a shell and enter the command DataManager. This should bring up a window that looks similar to Figure 6.
 


Figure 6

Next; expand the nodes to drill down to the information that interests you. You will be asked to login if you try to drill past a Data Source. If this happens, enter the login ID and Password provided by your Database Administrator or System Administrator. You will know that you are logged in when the little computer screen changes from Red to Green.

One of the interesting Detail Views occurs when you select a Data Source item in the Tree View when you are logged into it (the little computer screen is Green). The Detail View is an SQL editor. This is only useful if you know the SQL command language but for those that do... it can be very handy.

Summary

The DataManager tool is a good way to test a DSN and then to see what resources are available inside the Data Source. It is also very easy to use.
 

Using isql

This is a command line tool. This means that you can use it even if you are not working on a Graphical Desktop (for example; in a telnet session). This tool is designed for more advanced uses of unixODBC. You can use isql to test a connection but it is designed to be used by those experienced with the Structured Query Language (SQL). You probably will not want to use this tool if you are unfamiliar with SQL.

isql allows you to;

1. connect to your Data Source (using a DSN)
2. send SQL commands to the Data Source
3. receive results from the Data Source

This tool can act in batch mode or interactive mode. Figure 3 shows a simple, interactive, session.
 
 


Figure 3

Figure 4 shows an example of isql being used in batch mode. Notice that it is being told to run a similar query as above but this time it is coming from a file ( My.sql ).
 
 


Figure 4

The example, in Figure 4, is also formatting the results into an HTML table and is sending them to a new file ( My.html ). Figure 5 shows the resulting html table.
 

vcCompanyName

vcCompanyStreet

vcCompanyCity

vcCompanyProvince

vcCompanyPostalCode

XYZ Company

XYZ Street




Another Company





CodeByDesign





Figure 5

Summary

isql is a powerful tool for working SQL to access your Data Source but it is more for the advanced user.

StarOffice 5

StarOffice is an application similar in goals to MS Office. A free version, for non-commercial use, can be downloaded from StarDivisions web site. Figure 7 shows a PostgreSQL table being browsed in StarOffice. StarOffice can use ODBC data but it can be tricky to get going. Here are some things to note about using StarOffice with unixODBC. Make sure that unixODBC is installed on your machine before trying to use StarOffice ODBC on UNIX.
 


Figure 7

Q. StarOffice disappears when I try to load a list of ODBC DSNs and I get an error in my terminal window about some library file missing?

A. If you have StarOffice 5.0 you may want to try adding this to your soffice start script export LD_PRELOAD=/usr/lib/libodbc.so  Your soffice start script can be found in Office50/bin/sofficeand can be edited with any text editor. If you are not sure of where libodbc.so is or where soffice is then you may want to use the UNIX find command.

However with the release of StarOffice 5.1 and beyond all you need to do is to add the path to the libodbc.so to either /etc/ld.so.conf or to your LD_LIBRARY_PATH environment variable.

Q. Do all ODBC drivers work with StarOffice?

A. No. StarOffice is very demanding upon an ODBC driver. StarOffice needs many ODBC features in order to accept a driver. Two drivers which are known to work are; 1. PostgreSQL and 2. MySQL. People are actively working on other drivers.

Summary

StarOffice is a rising 'star' in the UNIX world. You can combine StarOffice with unixODBC to get at your data. With StarOffice and unixODBC you can pull your data into a Spreadsheet, Word Processor or even create Web forms based upon your data.

Conclusion

unixODBC comes with a variety of useful and powerful tools to allow you to configure you ODBC access and to work with your ODBC data. Familiarity with these tools is a great start to using your ODBC in applications such as word processors, spreadsheets and even applications developed at your company of employ. I hope you enjoy them! Please email comments and/or suggestions to me, Peter Harvey.



 
 

unixODBC-2.3.12/doc/UserManual/unixODBC.gif000066400000000000000000000015321446441710500201440ustar00rootroot00000000000000GIF89a l! NETSCAPE2.0!Made with GIMP! , Igͷԍ$Y}R/Lw[JBCŒ]CF5O.ϫ"13{cJyゼ>ov[{z}!vJ{[|fDbr+;WZ=p`uan1& gä ! , 0I8Z/ J\}dyBQ` OoNjoܜ1T{}ux s~8"dz{|pD^p[]^yMwIŗȬƜ2#md2l#;unixODBC-2.3.12/doc/index.html000066400000000000000000000202471446441710500157670ustar00rootroot00000000000000 unixODBC

unixODBC is...

News


unixODBC is an implementation of the ODBC standard which is;
  • open source
  • licensed under LGPL/GPL
  • community developed and community supported
  • proven with over a decade of active use/development

March 15th 2007
New look for unixodbc.org
The old web site was serving the project fine but it seemed like it was about time to make it all 'fresh'. We hope you find it more pleasing to use.
October 13th 2006
2.2.12 Released
More...

Key features...

Architecture


Software Development Kit (SDK) - Develop ODBC applications and drivers using the C language and the unixODBC SDK.

Driver Manager (DM)  - The unixODBC DM allows the end-User to switch data sources without recompiling/linking application source code. The application does not have to be linked to a specific vendors product.

Tools - unixODBC includes CrossPlatform command-line and GUI tools to make working with ODBC easy.

Applications typically link with the unixODBC Driver Manager (DM) which then uses the appropriate Driver to communicate with the data source. The DM understands ODBC but relies on the Driver to understand specifics of the data source.

The Driver is typically provided by the data source Vendor. The Driver understands ODBC and the specifics of the data source.


CrossPlatform

Applications built using unixODBC are compatible with the Microsoft implementation of ODBC. unixODBC is provided with all majour Linux distributions. unixODBC has been ported to all majour UNIX and UNIX-like platforms;
- Linux, Solaris, SGI, etc
- VMS, OS/2, etc
CrossDatabase

unixODBC supports drivers from all majour database vendors including;
- Oracle
- DB2
- Interbase
- Mimer
- MySQL
- others
License

unixODBC was developed by the open source community and is provided under the LGPL and GPL licenses. Commercial applications can be developed using unixODBC without paying for a license or royalty. Free support is provided by the community.
More... More... More...

unixODBC-2.3.12/doc/lst/000077500000000000000000000000001446441710500145675ustar00rootroot00000000000000unixODBC-2.3.12/doc/lst/InternalStructure.gif000066400000000000000000000044501446441710500207560ustar00rootroot00000000000000GIF89a@ @ @@@@@``@``@@@@ @ @ @ @@ @ @ ` `@ ` ` @ @ @ @ @@@@@@ @ @@ @ @@@@@@@@@@`@`@@`@`@@@@@@@@@@@@@@@@@@@@``@``` ` @` ` `@`@@`@`@````@``````@````@````@````@``@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@!,@ H*\ȰÇ#JHQ 3j8" Cqɓ$?\ǖ03I̚U,xsO% tQ=W\)͙*ujͪDZukˮ ,ٓf#M{[kʝݻlՎ5ݿ#o Ugݔo˸q^ŐʍL2O3{}=74NШX#fĨcstL{0'-5e>4|5bBvNz밣kOY/O^vF=g IS7޾eB߀'!Z*A8o\18GxIׅ؇bxȝV7"{HaM_h"∤ft-iNfbF"#CgI]TIFReXymjhfRTXi¹і>ڹuidfFVihZvCF iiE*ީIhbޖ_֪]!ꖭLOz'OB_W"+~SMMgQjnXʙmt.2 VU*o+TY(0o:)^`fm}n _ezq"1L|*r. SZ\>jU Z0"Ck9I#G)$|zt&DVu0n-^n3_Mv4{v>flsA94D4Jui 8iw}8No/܎#^sCMNoڗ=گ e~w8yTޢ*$mzOuo;O3"62θBR7j/l/ޯ<~Z~ݷ\c8_^gR@XnCz݋(rMѾ .f|9*q.z,͛^(>>J1M46P)X>x:ibA&^BC)'^2s2q]鐲45z.> u5Αk#w8UGHa$5l>tƸ] ɾB t01Jv] ;1x LST - Doubly Linked List
LST
Doubly Linked List

LST - Doubly Linked List

Description

This diagram depicts a single, doubly linked, list with 4 items. The actual data being stored in each item is pointed to by pData. Doubly Linked lists are great for storing  things in memory. LST makes working with a linked list very easy. The following pages will describe more advanced features of LST such as cursors.

Related Functions

lstOpen, lstClose, lstAppend, lstFirst, lstEOL, lstNext, lstGet


[Next]

Page 1 of 9

unixODBC-2.3.12/doc/lst/InternalStructure.vsd000066400000000000000000000000061446441710500207760ustar00rootroot00000000000000ࡱunixODBC-2.3.12/doc/lst/InternalStructure2.gif000066400000000000000000000072721446441710500210450ustar00rootroot00000000000000GIF89a@ @ @@@@@``@``@@@@ @ @ @ @@ @ @ ` `@ ` ` @ @ @ @ @@@@@@ @ @@ @ @@@@@@@@@@`@`@@`@`@@@@@@@@@@@@@@@@@@@@``@``` ` @` ` `@`@@`@`@````@``````@````@````@````@``@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@!,@ H*\ȰÇ#JHŋ3jȱ? = ȓ(E6Hʖ0=I̚8s|N@ s(ѣy"tQNYBJbӪ'b-Rj׏KN%PņD Vͷlɪ-Uٰjaj,_]o/a 8"[&!MVd~]TǗ-[nҳgZ\ЫGpvA۴fׂyc- '/ܧqnN=Wguǵ*3lї7W+mXD-`X|*^D`1!oq(bZihS#awfC(_+6^Bw7\lx\V6aawߐ$}(-I~1^e_nٙ`feI)GEֆ曱GڑsV䙗ddi&⤦pNY tg7(6*锏b餘 \O]駙>n ꩨ 塎秂:eQ:6V,V(7,.lsFӞ,C/tɶW-wԥT^y?[FJJYu+m}&*r7~kٯM#2ZLUsǺɕSu089j*fS2=I L! ,a-on7(!%sXN$MV2ɖ8I7&T0}8 tYaTڐ]IN.\Zߦmэ#ꑈou0F{AH1!$E6AlɅ2I+X-NzWS1#Bb*gIK_I[^2[X4x}:0BB]n}sMieQoxW/6d 'QGd'S@cH59gvhZ45:&eI'7Sff f:o/>b늄*^Cwσ&lہheZ=}JƙsEJ?c0#B)“Y#ga[L>[BlZu@Ih оXM$ NbJlpΞDG zVL{lȁ^a'v!Uv5b6BnimlNruVlTUx5X"fH)x}߼qy֜xVW 9#"󏫰9ʲxÛdɛJfh/w˜ڜO49>ԘD3jp[b`._fj/́osVYi>Y_/B+>L"zϸȞ-ɡjɍS|-&-WZ"pE`@G,Zw*Wη`3RW!o~2|FUYuQo7dS0rGz'H5=Քj4evtgu|nc/l3r"Xw5OwGe_=Tv')'cx~HsCg2zGx@hy7+ (%G#zKeBh=+Mb|e^ZwWOD(↣{_+H$sӀU7pCmzgL[wRzh:8q8OH7D[O8a*Hq}VHd7c}T7f]h8ËAIŁ:( U"8C 8?b~}rȷC](J(:L_G8(|[d'NQARhJƏ҃4Yp8QY UHs8b֐@1  (,&)(U 3FԒ:ȓ9=@Y4: KX|c-Jr#t)bh|kg6Nɕ7&."m'Ki%Uل9hdKBH_ZXo~?ɖzAw:'H_2X93Z8XjmW{r(;unixODBC-2.3.12/doc/lst/InternalStructure2.html000066400000000000000000000034001446441710500212310ustar00rootroot00000000000000 LST - Cursor - Add B
LST
Cursor
Add B

LST - Cursor - Add B


Description

This diagram depicts a cursor (B) which is based upon the root list (A). The cursor was created with a call to lstOpenCursor(). This cursor contains a subset of items from the base list because a filter function was provided. Cursors can be manipulated using the same functions as a normal list and they are closed with a simple call to lstClose().

The pData in cursor items refer directly to the corresponding item in the root list. Reference counters are increased in the base list (A) and in each item. This prevents underlying data from being deleted while a derived cursor is still in use.

Related Functions

lstOpenCursor


[Back][Next]

Page 2 of 9

unixODBC-2.3.12/doc/lst/InternalStructure3.gif000066400000000000000000000107631446441710500210450ustar00rootroot00000000000000GIF89a@ @ @@@@@``@``@@@@ @ @ @ @@ @ @ ` `@ ` ` @ @ @ @ @@@@@@ @ @@ @ @@@@@@@@@@`@`@@`@`@@@@@@@@@@@@@@@@@@@@``@``` ` @` ` `@`@@`@`@````@``````@````@````@````@``@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@!,@ H*\ȰÇ#JHŋ3jȱǏ CiI() ^dsM5osω+ *(ĞF["MҦ#BeJtȪVJq+ן^f +vəXe-+,ȕ,uerǸʴKڏU{߾o c[`Jl@9'x,n]4ƥMWL ֆ g,empaH{zu#+.kNGǽC{G{]uy%'}~}_ ^X|7?~1Uv߀C`Bsu |Fx_ahᇮHcvQ bbF݋}V}+W"bUa"޸cu8$l3&,x$burQiK^YSjI`R$ae=蝏?vcnGVq &LjF5 && ՏvєlzQXmgzgDcu>XhC ꩨΖ%h Je*pkY6)lĦtN 쳭bP1iagB/I.:$ ~uinvX %[Wle|,GZ{։-^Khԙ ( p2gFܚEL+|>>KF409SuҨo2=YV_}X(<)d9FHQ5ToTq\_QaᝡlvhF}{sy$kDxC+a)9@ݗ[Zw8Iy6:2~;ʐ?ObRe{ 츦~ߵ#=AJ6 `@1[WfEc g85ZYB! wE}!&F] DPpQH'lQbX M&HI0TZaH'rcdD!~qxclՀ IH zU تgB:}S|$'1Y̤&y (G L* &uƕ5N%Y-{5PUD zI9]҉40wLPC qEiz)i˄&-wbMݲI677mif `R闂8zg|)3!1y q-؞vM:CU<̨F7іT4m =WD+U/:+۟)ЅJbIVm(>%T|,ɧ-YP0E$3 j,(?qJ4aW8T Z QSPCaem/|[ɩזZYɜ"TU⪰aXpE'' f7YqvthG;)Mjw"6B Rhi5~,<:W4IBh?B\v6ESwuȗI~[Dَ{-9mdA$Dh wB7|"5F9WtςeHbs{pŚxt,ę7Ʃ,&MĘ; 8kGɩ,\&~kh{ћY).EAZ!&sמq(蹂0UpH/o9Eh;ّ (mA򓜀d^JzI' DiK]ACZ&碶c% dgng<ڣH嗹C[jq{U\:5@o)h&9u.ꥬ}E_(X$;|քNxsfɠvhY}wL3rJjY\ʨ2.fk c#z+;)ʜUKC8X0 YzS/驽:1*m :tkn:zB91:yՊ*7y٭ s6 iњG̳ҮcA@jrnꥦ#ڨ / 4$Nhc8*5_:K/qʱd Gy9$aYJ-`&뮵3kd59kiئ쁟?[i iEj䆴[+mNP+s6SGWeXZK3iD0+dn$D LST - Cursor On Cursor - Add C
LST
Cursor On Cursor
Add C

LST - Cursor On Cursor - Add C

Description

This diagram depicts a cursor (C) which is based upon another cursor (B). It shows how a list can be incrementally reduced using calls to lstOpenCursor() with a filter function.

Notice that the item (C1) is a direct reference to the root list (A) even though the cursor is based upon (B).

Semantics

(B) and (C) are cursors.

(C) is based upon (B).

(B) is the base list for (C).

(A) is the root list for (B) and (C).

(A) is the base list for (B).

Related Functions

lstOpenCursor()


[Back][Next]

Page 3 of 9

unixODBC-2.3.12/doc/lst/InternalStructure4.gif000066400000000000000000000120741446441710500210430ustar00rootroot00000000000000GIF89a&@ @ @@@@@``@``@@@@ @ @ @ @@ @ @ ` `@ ` ` @ @ @ @ @@@@@@ @ @@ @ @@@@@@@@@@`@`@@`@`@@@@@@@@@@@@@@@@@@@@``@``` ` @` ` `@`@@`@`@````@``````@````@````@````@``@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@!,&@ H*\ȰÇ#JHŋ3jȱǏ CyɓM\ʖ0I̚8oܙQ'ϖ> mt(ɢFD#ӦP] iԪSRi*ϮӫY`NLh[lߢ+!ݺsrTyW/:]*P` >,b%9nHTR\ySG>J3͖;s,_#\Z+f֢ν[b\ٌ׽+\o}N-M*5QW-oM2eT]5_zcsxuZ:)-.vx)4sIMg^Tk+[&۴xŽkhbyiV{,:Y]R6߆]=>;8~^滞G4\*<)<5OK:pk6xfZi|OtgCI?Lxv@p%9Z'aM8|潄M T:"ePwS4xf !;Ѩb)TPv9 g+_͠+]2\mk2e]/E+brE/%dVsB3v NXn<&Q kv "N\hcu+nT!'DF)i=*!'GOU$JIRX`VKD\p'l-y&0~~A"!7If3Ahz%&% Aij1h"Oa :0z>MLi~BlK*РChZإ u$zP2ϢcF ГtBnIxQ.&I :ФhDaӣ̔%;D0PT]/[87pC-gQTکP Iotj$ +JZZ8Ư}dUVrP6}cդMC~XzWU2#b>JZz`RҍrR#F԰ ~eWtyƚ)}VzegZL?] [V/=S^V1%q%1s463tK꒒fthZrw۵u[9^Nb"S* j,ygc?}s)(9=Yt4c{IF_ qrZ.{0 6#kIAf(0' +׹(NqE#`X0dqxEόOfĎ'̕ Yݺs<1/]o{Swwo%[B8V4ۂ[se½zNGwLh6v?}.D=km׺;I<nM6_qqOvwnŞS95'9(saq^zT]Rw8=l';`/֏I*3+=07du|x[X;6,pAhx޳=v˙9 >xb]>Ӄ_͏s^D{^cЛ,wOz#I;n5zP~7PÒ>cȲH8m2i+3]=m[xXX`OYOKnmS[?3>M*e8(tX7T_ XRQSQ5V@(G:"U'(#XV%V8enŁ)p5P3XY=d;H7Yh2ł"qR-Be8pHSLh'FHHqŶ~%Z:(R[XQDYY؁&ah(kioȆ8(]xUYcW*5_Vg؇y8Q`q|GvTrgh/炄޷wVT>x7ĉ)x&?Cdhe>3%w[k~CCzg5~Q hj9GhfеBBYW68HZGtxE9#8dx*#TW(r$/>IAEuШY8Vɏh~Hّw?g ^8 َevXw*(&O )-Hm6yqf-I?9;; !nؓtؔ:IeJ)LAy=SiēE9#T[j8G\G)PWeY\Y-P68\q%!ImP(y`u)g%fxǗf٘\F96xHz6Iٙ6&y )w՚%陰)IIyn9~1]$_y9Li9^I^"b9Y1f,}&3}yN|}iy+.44@9/y9`ypR/i_VbI[uas4=C "fpYm)_Z4U#*9J)mنb&'*7*0$ᣭ42I=eT{4xg@Zd{2.($NS &%OG[bz ?\FJ;j8ɤitC*Ɍtjru:sdg1|Rk }R.F~vza8y_~ꨙʟl utȢFD#ӦMS*ԡV=R5f֫;v@lM`s=v-ڶE)w.úvI{P^%u<`q Fr13;+We/,٦BǏ:d̜th#Uolw_]rǿ 8\&Ox9TW]C:<'5@;LXg˻wOoY y7:툂u߀ iԝ~d`A%_ڂ2xfH݆xׂ Wۑ +V⋞x"2h#<cՌhH(zRޒ)y\CNe[$*Ceіە.n!)}D%&AGP` dIéxZħ1xfoI9 ޟvY)^7)_v(Rhd '|j꩙")MjaڪR)|j4Q~GeV*}:jkVk{o)'ؾ^TA2ldhҶ,ڸkK#𫦽:+ DOLTg #:QV$*Z,/ sc48Bp2;a,EQq[ q.L7'ƇKC rAT=5qg 4QG6~=QtqX#-"X/jbY{R.5#c Ev1-``4/͈u|GH2iSk)#В+(`c&=$JJ-E`(GYL4#cJ{(CPs >_*kY_bAf2Lh_"W1uD!#b C253fdyZ3QD'Y.-$<zƭ>',oςJ"ԖbO*ҠB O9,'5]b͈z'8Ms~pcg5Ot(!0[Қmnr@mSX!CKӢ<[H4 Xr4T) =RT4n\ +ڪZ$+Dֶ2ά2!ֺp9eSzծU:͸JcE Y|[,AaQXlfYNֳC7fIۮ&j&͖VKkP.Ҳ4m[JV #q7cas0bv*G^҉=9"q䜬 EK-QYJKIDF3ջn#CFucL&ﵶ+ KBMV[]WtT^|!|@ =mu\Is$3cߧ@*%(03)d۩.I.=&>#CB5q 5>7i^z/Uj(,nBm`9{u6!" id^у}N͢ <勫7s ԃ51DMGs/?X,'j{rkX 0ӻIJ2>=Uh8 Vg63(kT>ܣu:Do~[Kں6}D-XѾ1)sc3]T_Vt뛃޵ҿ_Ayje 9ux/4$v9*7Mܓ,=+WƼ3Z1S/kZI*7I_s@ߣu|^ߦ׾c,T))wm~BWg>-)BAgv;$#%cAgp h3 b q(fw6S*rz!(?1H:G*2}-8u(VT7{8؃e%0$>8(V3GJ{ݷKx~@L-CQVM w`-S^Ń$]gU؆6g&5(ņztJvw[[h;X`ч.|2ǂb8㈒xeɤ؉7E{z剤\ȄWWX8%W/֊Ȅlw 7]XV* r~ʼnX%7S(h8׌xL9ؘڨT/؍8TeducƎ눎EeqGh%2dEcXd%E i ɐ )d)I)]ϸc4E6Z !YE>V*x33Y1x%9y!])CّEɓCiHOɔ!\u_%%(6>n,9q.,E13vђw$&HT嘗zeZu{j1:NIajBurb%.}9zC7y>Xe׏9c⏨7u9ZX_ɖ`"Fa$j1uu*$pN V:qAVp}^EQ)Z-7ZhSCyaYu(Xejr$Z)ЉYj gr֫27J[9tD%D(ڎ[G~r@BM3FZm+. }ʯG|4#c +Rņ&{㯷HÚE {R)&k;^';O1Lٲ5PJdo TkN365J`1G{ɮV*rWN{qhĪsz|G@^Ȧ?k~^KX++`4O8#\#!y7Q4K癏*mtvcQz00 {Q>CWu*óYtCZ9k*YwyˠskY6nJ m\M虺zǘD#G!át(*VAeap `$ܪCKC۴1HLDEBkkQ9Cs[W@de[EgptCt >7LL:4fAÙ\!w#%L+U5)\vPw HT~tlY^W\]}ax\1yC斬LʌypJKtw}K}悓̸X8NbnPX[3/>n$d rn錎,Ŏ.@SqA'i~9.VLU鷮ݼ.h~^Q;unixODBC-2.3.12/doc/lst/InternalStructure5.html000066400000000000000000000031101446441710500212320ustar00rootroot00000000000000 LST - Cursor On Cursor - Add B3
LST
Cursor On Cursor
Add B3


LST - Cursor On Cursor - Add B3

Description

This diagram depicts what happens when a new item (B3) is added to cursor list (B) which is also a base list (for C).

Notice that the addition of a new item in a base list has no immediate affect on the derived list (C).

Related Functions

lstAppend, lstInsert


[Back][Next]

Page 5 of 9

unixODBC-2.3.12/doc/lst/InternalStructure6.gif000066400000000000000000000125351446441710500210470ustar00rootroot00000000000000GIF89aQ@ @ @@@@@``@``@@@@ @ @ @ @@ @ @ ` `@ ` ` @ @ @ @ @@@@@@ @ @@ @ @@@@@@@@@@`@`@@`@`@@@@@@@@@@@@@@@@@@@@``@``` ` @` ` `@`@@`@`@````@``````@````@````@````@``@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@!,Q@ H*\ȰÇ#JHŋ3jȱǏ C9ɓM\Rʖ0I̚8oiQ'O> utȢFD#ӦJS*ԡV=R5f֫;v@lM`Ϧ=v-ڶE)w.úvޔ:%W`k|iXqJ]̕+ղNlSacw!\Y]I|Sol]-oſ [)oy9XiyC7:UK\Zz_9>E_yazv reZs"4g(SwHhC9Wp1h!y`^$z!% XbRea߇+:="цcnx; HD$L?6'&iT'%QK&䕎hR X%\v ciPe*"C[YRCi6g\~矺H佹 ʼn(>*)FNjdUj?n)8]~(jjjZ8Z(}ʥ먄(҉fIxS嬍2kX*l~29msVXHlF+@ҫ&zp&Kv v*č.l̉~o1 W(&: *,@m879<ۧ-@ڪc=m4|.+B{PWKQWm5X]Rڜ"\-vVlvc= k-GJ |Lut1-\ ~\8"W5Jާm;M7CIFf䄢=]F|Vz>zy.RԚ݆$m^@Y|Jsӛ6l#;#SXy"|||uvD+4{76>ozpf7 !zA5;h(@Tw=_8hu02ӕ}a-X$pS\b*R};La^2[{Jx=$Er;ZN Y8cу'D`eDч <ӨF8JKG4툘,[xVu r~䏘ȫz$TD;&22sȨ0 HRy嫙 >p_'aHEs >yQq\%i: 4 FgӢ"͌%\=t'ΪW}*T?9.]ժ ԩrjymdUڒZ| B2+\6T^,w#,cm׻nkX#M;: ςmC-'Jf Z&V#5Hnk؎e#gK?dWVV\WAy~ rO'G`Ml dxEV!ƻny!E:sW|"Ga+> EyK`alm wj*`Oکa&|6#^6q\͓QX-r- nHՉc?,ޖX`pyGޥ$̕C>e])ò~ٱZ/kCbl(v6wts’fԁ\ HlM;Ao 6g)/z.}dQ iTz0f֦׵+:zGVبX0r9L'S(ı):l?[=Sʚz]_+pn:%/^2"}*ՇXR_-٨&Aafv>lrn][b{CFe(N[ʶPho< NDo[G<oӽ+~1c+q^5\+k(⫆NUC5.6c./qnif<_OJ|md{hYUey0IǍa ؤVȳ~il9֑KOQtK "]{=%o#nEWՠ{"!|DEmcPCH]pUΗ蝵:a_j,2Q8o$yz6F(ҀsDxkU75iP8\e(t\ HQgb838?dxhfl؆Z=XfgE>bXi5V Uuȇ}UyHhf(Ȉ;{V&k(](a艑ȉ(vel^"DfuՄ芪RH:7t8L~rHckhdWxX8茻2zȌh^YhǸfX\^nĊ4Ȏ䎲f$ep4We^v*n)(R! )oHZX[%4qR~OxtَؐiK¸m39\u;,ْUB_4Yyx&K8/  %_5IcB ꥔Gi< D]e)9<:TFHe1M9;w%X9eW4Rg FsUٕD1=a s\(_~c%xx I4}E(vvv wiCיC I șs蘒&Cuh\~'ۦa;I/`xe>NٚYI)avyT 95ni䙞gsLPVb4vbbr +bM+|cɘz;D,.fNl +W%nɠtɃ\ydIJ& iB~'ʡ:R#f@e4l%4~=S7ل<:bAB3jr%RTnՖeJ4D0$֪{FfNkAdVLJi ]} )'ȊZʒVz-*<*$R'P=M4u5ZdJנEkHZ4*@t;jj14技6簍CXHӡQ&@z!?S Kqړ}! cSF!QQ/#[6AP7BE,yCOz3K5iR,ܙŒ)LŰw 6dI̶9i)Eoӡgu28{~tȁl:l#d}/\v[WzU{|\Dx^zj|~x0\ʠ̽2A" z "C0 zM@fA*(.:$ o{<L(نbϜ(dY&gF|4I(ͥ4L^7RIaL#(!{H!m{м* -6Ѷ&iёѫ:ѣ'C"O'yt¼*Ub4]GMʯ9i2?o'31>]:&aieDT UC,_1(-zړڜx:C˱OKׂZhµ|nZun ‚=؋؊؈/7s-]-kٓٛM]ڢ Mըsw,֫uǯMvo6wLm۬Җ0*Jt LST - Cursor On Cursor - Del B2
LST
Cursor On Cursor
Del B2


LST - Cursor On Cursor - Del B2

Description

This diagram depicts what happens when an item (B2) is deleted.

Notice that the reference item (B2) is removed immediately. This causes the reference counter in (A4) to be reduced. A delete flag is set in (A4) because there are still references to it and deletion is delayed until all references are removed. (C) and (C1) are oblivious to the delete.

Navigation is affected by (A4) being flagged for delete. Navigation functions such as; lstFirst and lstNext will skip (hide) any items which are flagged for delete. This prevents deleted items from getting more references.

Related Functions

lstDelete


[Back][Next]

Page 6 of 9

unixODBC-2.3.12/doc/lst/InternalStructure7.gif000066400000000000000000000170731446441710500210520ustar00rootroot00000000000000GIF89a@ @ @@@@@``@``@@@@ @ @ @ @@ @ @ ` `@ ` ` @ @ @ @ @@@@@@ @ @@ @ @@@@@@@@@@`@`@@`@`@@@@@@@@@@@@@@@@@@@@``@``` ` @` ` `@`@@`@`@````@``````@````@````@````@``@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@!,@ H*\ȰÇ#JHŋ3jȱǏ C9ɓM\Rʖ0I̚8oiQ'O> utȢFD#ӦJS*ԡV=R5f֫;v@lM`Ϧ=v-ڶE)w.úv^7bY XqJ]̕+ղN Xc n,殣A>maQol[-oǿ 0M.\7EFO{:I Kw󒻻Q{%/or;<~_{>u!dImtހb%ZA&(נ[f`}mx_Fᇁ Hw"D /#s(c#_5cv/(L6yԒN.eQQW!1Xe yxH^VyeNb2&%CT xwBH_PU曊bIY{)G"ihO:iIz-BjiUv6棙.*+uzOzգ2(]~ZٓFi~*\뛹]]Jj6VyFKPfS:kƂfҖqњS m}h6nXb&F{gE˞+{zp Fq` 쩤F-Ft {@$plddMTŐZJKA9lκ|@[1xVσ+ \e!*-2.B>uj4n7m]-mhfGT+K7k-t  oZ X;jᔲ9as?A9^bѥwa{:J_4sn λZM»ى65+L[).I˃?_ӂ;|Qse'ps;GЀ $*N̠V]0qԠGx*'$L }\ gHWC*ߌrX.\>$=hFd ;3D&G̓DЊъͩi?dE0~PBvʈPUG:ⶰؾ-ULLֵo E=b۠id3>Pt:XDV{֖ ippw(I@G^ttS[eiBybvQ#-M*:rk&giKH OVK%Mϋ"ei7j!r$k0 ab$y󚂊6yҜ(Dzs]y'84>OH
9çPR{(S)T0 O:[_39"hSPKgΉf M jMA 4XbtTVMw44vDGT]H5tU5NeTښv 9$WUVTyꢑT%&izԵOiK]XGs66 bcjef7YΞ+)bcY}O[@'uVU*mx0{2ԚU1aX qF/dCC[[Ni,^*bq/2ݓ6-ȣz)sn|hK"VYGurML:8.d9̪э/#ۦЗ~L +)u w;8u,2P묈GLAjx&v  T؅mS]g%AӄDޘҐ|SW!r-C(ݔe/evufzgR=^:4[7|`3W,g2 B7#d+[Jь{Qa@ZҘ~4[0ӠojP7_5:$7XƵ^ X:V%Cykb+E屑l]D?6 -.L̺b^3ɟ6[@/-rv\#πrn-6PN^tG7o )IȲWJ6׹TBe8).FTM 7,ь^_EdLϷa'1NzX*i}\=aT7:;yuc2_vyLeǛlIB"w6e<\xI+4|w~PUw[6c&DLL[7BwӒݎ6]ol'E!*okkgW%IC|Ca}|ߗDn>+g~9oJJ:$p%i=c~JhWWx$E|̒h7 "AG8uyQ-w KT(g)ǀYy zCDB7F=$vgzWo&L-YGdg7H= }bd$sn~@GwD0AX3: [w|N|tӗ_]|b,W TTE7Jy78ƅcj3sBmh;*LJRey㇝Si|d aB3(9x'XXf)hm1$UwUzx(5m2e8G(:(\'XȊ.8pGsmOb&x"8t/d؄8^瑍W{U)sWRNXC`}|eDxHW+XU2tI獲Wq6>X) 6㖑[^vZv(Su5"$ymAIqZ$rĉsC<{ [B69W/952Cxxz%sXutk1Ђv)^7\僉ǕȒ0K;bUփ|Ӕ^{xfQ Es2w|8d^rCO%>uI%HØ2FoS1)@rI"$sMp.9f?ࠖXued{QCgFo)p&jω_Ʉl"ǓIY3ٔٙ8]GIYyXy@<e+yyKRZ#.YBY c Tn )ɞ;H"2 )y(Z)jBY)Ɲ؃Xcőf@ڋIEz8I:*ؤ{H¤Pr9F}4f(W/td*ErؠjHm:28j]FxZ7lڧ-֝? +hqӗԸǙږ7e426 dZefX2j ڦ6xx`ꪠiJ*c:tzXԫ4Tjcz?y ʑڑٶ +F>G/~**71ꊭ:% |Jj\ꥱip(9{W ԰C['v঱v5vv!+#{K ;q+)/˲3K51 7nfv%k?'-+;kI9m} PG 3ǪCoUkW;c:Dju5س)lNDrkKMgY@Buky+s[wD{˷/G#XnqQSi7d$HnNeX'o7XFGPN{t^(M (Qץ&lCTXĸ{uq(hqisjw{<|rKW$LWֻ1ckYwsgS87'Gu (<{]R;!nKrX򧿔F4s { kJEzZ'\mkiaZL;xzwm7 āvV=i>Ӣ尚Y?mkw=%-蓳USDItN"ruLCDV6>Yl~7Iwie^"3ɂ:J xN(}mݢli2yL2^tV߼.m[Ǽa)2`37S3F~ ^  e*b>"g-F[/|oC:ֻ1.Om5N ә+QN.m՘,^/5%8]n_ [_*wOrOu6x}wh~Gn=e/psƾZ SPAJC-֍ ]t_3Z š0/ހ:DhPi_R`iY%CH^˟2i:oOx9ALiWA .dC%XQĉ 4b,G!E. "8\y2H1eLHfĖrބh'GAw$ZtЋF̨S;zD NІUAT׫I8 ױHњeTm[Rʅ[dɍZyU)6ߋ6k`"a[Fvt.es|yfЖ[.2)AgM!~][-G͝/ }rhZ`?V.+OG:F&C;4 oo˜|O8?oz۝}~mDN[/{/vc'o@ Aͯ{0nAg.?pS\ AIt7n4*;u\* rH"12 P(j Hm"l K"+I -1$J4 1'*j|#O$.5s<EN`; F&ݰRK!k4E]4H1dIFy20(P2U>e,0"u%TUKbV^%5[Keث$-a--YdoնհM )tk嶨m)+\\2j5)ݺ\5^w;},8$VX愖^]sWމy;`mQ& '06X?!F~9ETJB.Qƅf/yOlԟv5Czڒ&tiZkN5S+[׳ZkPf0x8 ӫu]qoK^&63 F5)$ʁT PΤ{hD-zh={3=EzґJwEiK)Dbԥ3mNOtLu]>>jQ}$(ԨK5 R2U˜8ԩfNⲪUZЂQzVn3+Z*Ōo+Ժ5wwE^/L3%"MĢ!19Mk\fYfNUf=0v%mi{;unixODBC-2.3.12/doc/lst/InternalStructure7.html000066400000000000000000000032451446441710500212450ustar00rootroot00000000000000 LST - Cursor On Cursor - Add D
LST
Cursor On Cursor
Add D


LST - Cursor On Cursor - Add D

Description

This diagram depicts the creation of a new cursor list (D)... the second one based on the root list (A).

Reference counts are increased in (A), (A2), and (A6).

The filter function for (D) was never presented with (A4) as it is flagged for deletion.

Related Functions

lstOpenCursor


[Back][Next]

Page 7 of 9

unixODBC-2.3.12/doc/lst/InternalStructure8.gif000066400000000000000000000161061446441710500210470ustar00rootroot00000000000000GIF89a@ @ @@@@@``@``@@@@ @ @ @ @@ @ @ ` `@ ` ` @ @ @ @ @@@@@@ @ @@ @ @@@@@@@@@@`@`@@`@`@@@@@@@@@@@@@@@@@@@@``@``` ` @` ` `@`@@`@`@````@``````@````@````@````@``@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@!,@ H*\ȰÇ#JHŋ3jȱǏ C9ɓM\-c&| N͏*osO= *hCFY"MT!Ѧ"B*ujǪV.q+צXb +v'ٲ%6"۶fr<+w%]P0_'֝۠0Iă)آb17g~m2ilGv8jDU(c|qc&{!֞]дD࿓+{0{$rΕkNXfih||yӳbM?8 ˕?5|O;Y]pZ]gAB:ŠQ>( F! ui'ʹ!wo)"y'O2P4vۣ67=%scƚҩfJB*I꫓ʢlQ ,NI6WٺY;" ]zihr.x/$.aC)'U)n.zoZvڿLr*"":!_Q i ,Ʊa<ȁqn ջ}2J,$ܞVs|4ˌ3AmP:L M^t;b*T|r]a=EhFsؘ[vsϷeѤ|7{$GqWTb7m C>3u hd[>wЎ.'V 5:Wv껗%=2#jhTvSnԷW;JV:/>+t | IjGj>/ R/1Ėk}YZӘ0Zjhl)˜4o"QFgʼn$;{瓧L!)STβ] X=W`Hˉ0YKRu-|6ͺzMB+UpU2i>:V=^2F*=N8uTkJIAliI8 4m?~5] MrȚX뮜n"֛lD]0ez!ӉBAlps^umL%F(7"]5n07̴pI'g-򦶜vHϋ Y7Huq}hikxऋXTHw6.t\L^fg5?r~k xtMD\I\57eR&5dck`(uRN$w6Y~]|&q6AW0XjsG$*u+kv)vA3Svv^wՑ<\wlgmxo7U9d֒MӀ7&gEldU@O G#gEm(^钊8^ue ~JtWq;2q yZVVr?,Gr0BFv ti(OBރY虖Ɋv*6uǔHemZ)WczW)&󁨘yxig(wz׎'_QXXIbGYYV{q? AYQ{ T_e|9yvɞ([i%,fi$ٟ\l9㆟uX|hɠ4ړJulH xZ7&툠I6o9zJIe(zS I=ȝt,~$ŏe*f1=CZ=V2Yȣɞ3ՇGbQ*THʙVPT[J¤_ )cf :iz'J0lzHdqwwڧ燈~H4Hz3yԫjzڠ&x*lc-߸kѪH"(OF<)?z!#CE;kzo;sڭ1!mjgJaQGǭ'juޅg@ò nj8bgl'KZ'fY(ԖQGۮ$;6Lzڰfo%+XKz[+;RY+fk$.{0<uʫԒkkÅu-uhx&uoQkJW~۳KHEKBBk+;Fų|քW[ ù8Vv7_7ǝX8*U}{ʸGC,ZOKقUˍ1k>*ge;$ \KA8*[{QgJǸ븾{v_z"ӷa*;R{+ۿiDJ,Xq"[ҺyӳBEWKy,]kiGvx,I’Kߋ`\S hkk~5%ï!\BY[Zt5l!PygE2lzhRR31|2T!h ;l[!$xp2;M'ҘLa;z{2hㄙQQKJJj/68SJ;jlƯ %=\*w{Re,5 c Iwfoc=H^ب^Vyl#9- ȣ1wYKZaln̬ 8)[Ẍ/Y-ͰZt3~1DvӐiȩĪ}Hi ϣ.?jXB=z<RXZ]L[^HFWv9k`YS]9ތ+>mdK{emǀm}U<5eb8:mOq6P=agʱ4ʰ;}T2ڵTTˋ˹ILHaӬь>̡lաI, ST -D1%ݥݍl#G*5 ^7]lz4/qI]PM]MUܻb`ةHM] ݙ-'@Ζ\nɊUݧ }w%~@AN,@]>k-Lx}|ykڇًyFOӸxw%ք嫄vp =#ߡX Ns52WU\-kޏx[T-|ГZ:yݣۺ״ٻݼ[sN}_s9VJoۯM%ƨ|YJ%csǬ^s7zA0ĵL}D U,..*D>D.YۿM<؞1g# Yn\X^>Pc>҃fnyW") i)n&Txijzt^ "u7z.݉tbx,_&@nAx}̞"1$١B?uՋW;oZ4Y M_,aQ1K>'/\7I؎[;a@Ia@O :ZGS tݬܓ-/oc~2)ibyl-B?<=ӊbQ&qF*DsĤ(B\u480l#  rsʢ2S5xK*![L4sͮ$1C1ٔKԤ@5TA=tQD+QH4RJ3J313S+TRIjS[껣Juud|uVɼ32դu.W`ʄ` Ee-OgERiMZlMv[I?TEQu\^UDw€]k߅w^*^FT w>l .XHFXS2ÅxkUL)Ta3ɋc>9&㏓|ד4|e"~HOd]xN&C`-: LST - Cursor On Cursor - Del B
LST
Cursor On Cursor
Del B


LST - Cursor On Cursor - Del B

Description

This diagram depicts the closing of list (B) using the lstClose function.

Notice that no lists or items are actually removed. The reference counter in (B) is decremented but it is not actually closed because its reference count is still greater than zero. It is, in effect, flagged for deletion.

Related Functions

lstClose


[Back][Next]

Page 8 of 9

unixODBC-2.3.12/doc/lst/InternalStructure9.gif000066400000000000000000000307551446441710500210560ustar00rootroot00000000000000GIF89a@ @ @@@@@``@``@@@@ @ @ @ @@ @ @ ` `@ ` ` @ @ @ @ @@@@@@ @ @@ @ @@@@@@@@@@`@`@@`@`@@@@@@@@@@@@@@@@@@@@``@``` ` @` ` `@`@@`@`@````@``````@````@````@````@``@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@@ @ @@@@@``@``@@@@!,@ H*\ȰÇ#JHŋ3jȱǏ CIr"%SJ< @˔b0&88?6sΞ@d)&ѢHLr)ӧB%)uՐG̪ӮMZuƲfF"۶9­(w.Nv%ۏY[d0ʾ gx`NJaDQ1a{+[r̔g FȖ !Zе6X`Ks5ѧsKT۷ß;n#sɕG5moӡGv< ^/~5/!e͗ XU j_x ]Xj.(fTm~ 2(vVFX щ.D^o55XxDg$v"9`X$tPNC Z$6~OV)+f4&B&"M)dtndGWf})`Q(*&9Q|׏Fhe(:[5ĩyiaymZuᨣX&4[n9e{hFuWU嫃ȊgK (gr6鷄֞FuƋXl:믤Zzp_Vެp~Zbu-U秊񦲆ZJޚ$sȒ$]*/˶Ls3O1@{/s҈*T~nP. ԙV]C ]*S&fؤr5}0Jr1$@=#N tC#̶&yGԁl+p7m?=7_1_ENtG;e.tvh6. nkt ^rnp~#Qnk_[,m^ϑ͟=Ɲ9w"qzۘ!%} ܙ#x9d,2A`"7X L< Pp?:#9~ܱ }qe@hr=<6&ljE"$>LT"j` 0YC4f HG,ɱx̣W=Y%HBƌ=͢χlAƐ$'IJZ̤&7Nz (GIRL*Wʌ1ye^yAY2?.F˗rLH1Etd:SPĊlB4 "FAP5sov.|v+ѝ&9ɥ5"d]-h!*2*ԙ V ‡2 =FϗġeF%,!GhH{bl$d"BrP@j,T9.D1g-4*4ѯ"Q"U@)5'<ģҩ"c>Udy`렘VWRYk:E0{YK+7O%X V,i5仢6Բh$AΈVBee[j>E xZV wm)IꆀhPmIҺ+LPUԚ lM>QMbr&(Լoi8>.EsULNW̥|S// `3 -0}u_7Ql'<[5V} wj {^GL(NW0gLsx drZ@r 3"'tA2y,Ov)3e;Qΐz*G֩VMq9/Bs6׈^B`MZ̛"sla> "G`3Iփp h-oEǂ'%݌VBTts0MI%qVXBLw>,ԮR kcYz])yrz*uOjb+׮ffI2Lʂsz6Sq wˢUaxRd/=w~~mEVsSѼVm[qLJKwU)J8 Yog ݁G[В[pⱦVk\Nb[s8߈rj5bgsc]9yæT<мf+֋bmR6m ^K[+yl+حuϣ(ftqw~s=-|XJso4 .i̕=fT&Ń m+|Q]Hw3o_yQdj)}r+]Ҽdߖ-oh\c~^+cՔk9I[rY9ni(fwb8d$ixܘ%a{]8b|9/UȆ:ęd d26$aSDu (xݨ6U i=2م焎3)0ěie=iGY;0EWx G5.XDIٝ9YyIzn"%:-])j!zjbvd76'*c差x[E.;ԮjjvGu6k 咩v)Ⱥh%!ǵʕq5Һ_a0JK@兛[y$۸cA19׶Zk绒Zj f;{^S)hD0 >Ǽ9ל>|ynEJ P3'ߋZO4vdZMHW)[Hk2U쥿RGdd\'%x8J;KpڛvR t{]Z4It, ?2 S ~s# $W[,*4C %òtĝejzAiX9$w|KdEhh7vJbF(b5 lCi+.^=ܕ'ʍHgK1Iwac!(j3z[I#ܻw Lu a _V>v+Kyb _b}F̈́xp@%r-xt1m=g(%߄ľTɍ-!v!-*5$]-=Rd?v')J!^%Nx)~G-Y1_E5F;ᮌ>.R$C.lɍI O">DbXO`khL*/~+8lNHc/Lu~z\~舞芾̃^~阞难>^٨.Nqḫ`=봮F1zdV` *ZM^ҍ0ʷ/RXKJYTMr奭M,ޔn鎏g^%>N)+΁^=[*[mnfݶ-Lᴭ# ~/ 275' +t=),hh3Y8Y ?ߚDMm /ގ඲}-5%by ䷞)NNn/nofhTuob/cb{>.߁ܔ1mkA4k Dy:OS?%{]ȸ) ʕf_)ê̡ C6//șݫ>ܜWÿ́o/񰮻W"uЕopN -ܿe?}w*)ݤk0A "dC%NXѢÅ5nG!E"PrI)U, 0hrKqٓNA%$͢ImTiSN :U=fbS8lêgծe{pk[Wv)ݘ7k7܃iUxaR.^1O2,/g'cE<:pfehױ)nMew߽L6•/l杍s~pɣo.;FoVnyկg?/_{yݿo]$/ tm? P@A C.GBS|CXTEEkkNTF{G 3kD&# LF%/'lI)>+=-lJ/< K1L L3$l%4LM7|&SN/sO$BSPB"ωĭ+D= K |;M"$u3RO?DC2TVj5QWk%(u AaXd=P]ue/H6Xk.OJ'zsf( Y~dHF9剳i5HI$Rv*wy1{k @Lih=+NTx_iQD|MY02 &g&PE<xHR3<LRʙION_I,Z* SkzMU:I!Rߴ0\ igMa Hzja[Gֳ\Юvֲv3+gjuk4׳Pka"DYRv}z%NjZ``myZ ReOZӻ`[HohQZvG=oUܬ 1w={``V{J"m {^z.,=.׼k vmk4k;<\p!Q:67Ex}R{ ĵ3*g݁!ɇne)dȿGb[3s&!cerWYjD^khFq܏Jv\}fҪmu=$-SRfUڽpx?}[YO8Qe&+{3i%ϓq*+LOӏk>B~94gj)WT"itU)tOG_tɶFڏ坿ݏͼ=c3DuCd7\^Z_cA_))-k ٥=Ӓd 3@y ܞ 1>tC,K#,\cd"4! 㐰4 $ 5ʷkBЛ+:c,ŽK Byb[:Ad*;31;l%H ä4< r ,:<4|18cCCcDˤ[r?;CL$)4EN(#CPD?y죴:S$&.Md'UT 2Ea[h>sk#ut<*Ę۴KGI MLT;z3p,{ ?~T++B&#^F\H@ȟI E6pr qDh XNcgGC=t !d-y,:rɄɋ|JAy,vI<+D}ɸKIڗ1 4\'BI9[t>%HpJ<Ԗt G$ʺ<|K?TJtjL F\L$IrjLY> $LkA*AA0*q $MPgwJ MUr71)=(Nn* 4̕1眯V#"ōL A!#aMV ϚbaK 8 FrqO`a01٩OY;>bB¼4 UJ#4 DզnOwƜ%XݵM<ymqYªuJZڣVwHٴͰZQe[e !Yn,=|[΢QPZeXr\TWuZ%=y\[>/ܞW\ێūSеm@=]d5]5úEA-ҽݑ]QX]@y]KBuޑ%NY^8%\Mޗ%z5ue2E 1]}=eZ>mjݨ_„F(K[ۦNM\sd޴-\ !` !ښFa9faaYKa_a={e!&KFbu)a_&_l9(V}**bYb/(&G1㦩<,FcT=c6ncĦ3D8㸱ij2D<;&گdBGC.MdqFv [I㼝%'dd>OFcPH#=Qd7Ne#ceXeYeZc"`e]^Zΰ[Mц^2 m3=f,HfkUh[k_nn_&ld^$>F^gu^gvngw~gxgygzg{g|g}g~gghh.h>hNh^hnh~hhhhhhhhhii.iV =iMi&Ln1VUpIVnidiiiV M[v,j;j~g`.8jj~jF(jpj%F&eϲ.>#, Fڵ0Nk\cl>~2lHkԔp':v:lk^M*ZƙMla&)CZɾnԣ$l[.m&F\m嬭~mGmjF mIP&g Wr`#^io&r?OvN=fQxb=nfs>֍3Ui;^*l?7HBp ?x>sKrإtrppKot/iORSFnNFNuUbf/O,C}qs_agb'%<se[CL0$qnmqj_ov8D6j?7AV;lw Isgv7VX$P*F"cv }e_vy_/t>x?m=O`\h'vx_t=`xzydJN9[{`39?R襫%P:Is9&Ni1bS?_8 rٽ<T<jf[}s}Ό 3U!(!F<"%2N|"L4U\×XZ]R0jq\ 1e|a>57oxEJk 6ޱkcM)E2|$$#)IRr";unixODBC-2.3.12/doc/lst/InternalStructure9.html000066400000000000000000000027751446441710500212560ustar00rootroot00000000000000 LST - Cursor On Cursor - Del C
LST
Cursor On Cursor
Del C

LST - Cursor On Cursor - Del C

Description

This diagram depicts the state Before a call to close list (C) and After it has been called.

Notice that lstClose on list (C) detected that list (B) could be closed. Item (A4) was removed because it was flagged for delete and had no more references to it.

Related Functions

lstClose


[Back]

Page 9 of 9

unixODBC-2.3.12/doc/lst/Makefile.am000066400000000000000000000010321446441710500166170ustar00rootroot00000000000000EXTRA_DIST = \ InternalStructure.gif \ InternalStructure.html \ InternalStructure.vsd \ InternalStructure2.gif \ InternalStructure2.html \ InternalStructure3.gif \ InternalStructure3.html \ InternalStructure4.gif \ InternalStructure4.html \ InternalStructure5.gif \ InternalStructure5.html \ InternalStructure6.gif \ InternalStructure6.html \ InternalStructure7.gif \ InternalStructure7.html \ InternalStructure8.gif \ InternalStructure8.html \ InternalStructure9.gif \ InternalStructure9.html \ back.gif \ next.gif unixODBC-2.3.12/doc/lst/back.gif000066400000000000000000000003041446441710500161530ustar00rootroot00000000000000GIF87a , 8p)@8mAihz "Ap\lKwr݌ KM_4ENdZjU\ Ky 罷;=+Xyxtu&Rqrg0)~!,B  ;unixODBC-2.3.12/doc/lst/next.gif000066400000000000000000000003101446441710500162260ustar00rootroot00000000000000GIF87a , 8p)@8mAihz "Ap\lKw ^ʷ+Bu45yK`):aTˮZrY3°z&|b(8w}&CZH0joBfI{.e,A  ;unixODBC-2.3.12/doc/smallbook.gif000066400000000000000000000002171446441710500164370ustar00rootroot00000000000000GIF89a!Made with GIMP! ,B8^\3zހxQ%h) $(top_builddir)/exe/odbc.pc.tmp @mv -f $(top_builddir)/exe/odbc.pc.tmp $(top_builddir)/DriverManager/odbc.pc @sed "s![@]ODBC_CFLAGS[@]!`$(top_builddir)/exe/odbc_config$(EXEEXT) --cflags | sed 's/ -I.*//'`!" \ $(top_builddir)/DriverManager/odbc.pc > $(top_builddir)/exe/odbc.pc.tmp @mv -f $(top_builddir)/exe/odbc.pc.tmp $(top_builddir)/DriverManager/odbc.pc unixODBC-2.3.12/exe/README000066400000000000000000000032501446441710500146610ustar00rootroot00000000000000*************************************************************** * This code is GPL. * * This software is a unixODBC component and may NOT be * * distributed seperately. * * * * Peter Harvey 21.FEB.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | unixODBC | +-------------------------------------------------------------+ isql/iusql This is a utility which can be used to submit SQL to a data source and to format/output results. It can be used in batch or interactive mode. odbcinst This utility has been created for install script/RPM writers. It is a command line interface to key functionality in the odbcinst lib. It does not copy any files (ie libs) but it will modify the ODBC System Information for the user. dltest This is a utility which can be used to check a share library to see if it can be loaded and if a given symbol exists in it. This can be useful when debugging a problem with a share library or in a makefile situation. dbfio This utility is used to test the functionality of the DBFIO library. +-------------------------------------------------------------+ | Peter Harvey | | pharvey@codebydesign.com | | www.unixodbc.org | 27.JAN.99 | +-------------------------------------------------------------+ unixODBC-2.3.12/exe/dltest.c000066400000000000000000000065131446441710500154510ustar00rootroot00000000000000/************************************************** * dltest * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under GPL 31.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include #include #include char *szSyntax = "\n" \ "**********************************************\n" \ "* unixODBC - dltest *\n" \ "**********************************************\n" \ "* Syntax *\n" \ "* *\n" \ "* dltest libName Symbol *\n" \ "* *\n" \ "* libName *\n" \ "* *\n" \ "* Full path + file name of share to test*\n" \ "* *\n" \ "* Symbol *\n" \ "* *\n" \ "* ie a function name in the share *\n" \ "* *\n" \ "* Notes *\n" \ "* *\n" \ "* This can be placed into a makefile *\n" \ "* to throw an error if test fails. *\n" \ "* *\n" \ "* If this segfaults you probably have an*\n" \ "* unresolved symbol in the lib. This is *\n" \ "* not caught since dltest started using *\n" \ "* libtool. Linux users can refer to the *\n" \ "* man page for dlopen to create a *\n" \ "* better test. *\n" \ "* *\n" \ "* *\n" \ "* Examples *\n" \ "* *\n" \ "* dltest /usr/lib/libMy.so MyFunc *\n" \ "* *\n" \ "* Please visit; *\n" \ "* *\n" \ "* http://www.unixodbc.org/ *\n" \ "* Peter Harvey *\n" \ "**********************************************\n\n"; int main( int argc, char *argv[] ) { void *hDLL; void (*pFunc)(); const char *pError; if ( argc < 2 ) { puts( szSyntax ); exit( 1 ); } /* * initialize libtool */ if ( lt_dlinit() ) { printf( "ERROR: Failed to lt_dlinit()\n" ); exit( 1 ); } hDLL = lt_dlopen( argv[1] ); if ( !hDLL ) { printf( "[dltest] ERROR dlopen: %s\n", lt_dlerror() ); exit( 1 ); } printf( "SUCCESS: Loaded %s\n", argv[1] ); if ( argc > 2 ) { pFunc = (void (*)()) lt_dlsym( hDLL, argv[2] ); /* PAH - lt_dlerror() is not a good indicator of success */ /* if ( (pError = lt_dlerror()) != NULL ) */ if ( !pFunc ) { if ( (pError = lt_dlerror()) != NULL ) printf( "ERROR: %s\n Could not find %s\n", pError, argv[2] ); else printf( "ERROR: Could not find %s\n", argv[2] ); exit( 1 ); } printf( "SUCCESS: Found %s\n", argv[2] ); } lt_dlclose( hDLL ); return ( 0 ); } unixODBC-2.3.12/exe/isql.c000066400000000000000000001522101446441710500151160ustar00rootroot00000000000000 /************************************************** * isql * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under GPL 18.FEB.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include #include "isql.h" #ifdef HAVE_READLINE #include #include #endif #ifdef HAVE_EDITLINE #include #endif #ifdef HAVE_SETLOCALE #ifdef HAVE_LOCALE_H #include #endif #endif static int OpenDatabase( SQLHENV *phEnv, SQLHDBC *phDbc, char *szDSN, char *szUID, char *szPWD ); static int ExecuteSQL( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ); static int ExecuteHelp( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ); static int ExecuteSlash( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ); static int ExecuteEcho( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ); static int CloseDatabase( SQLHENV hEnv, SQLHDBC hDbc ); static void WriteHeaderHTMLTable( SQLHSTMT hStmt ); static void WriteHeaderNormal( SQLHSTMT hStmt, SQLCHAR **szSepLine ); static void WriteHeaderDelimited( SQLHSTMT hStmt, char cDelimiter ); static void WriteBodyHTMLTable( SQLHSTMT hStmt ); static SQLLEN WriteBodyNormal( SQLHSTMT hStmt ); static void WriteBodyDelimited( SQLHSTMT hStmt, char cDelimiter ); static void WriteFooterHTMLTable( SQLHSTMT hStmt ); static void WriteFooterNormal( SQLHSTMT hStmt, SQLCHAR *szSepLine, SQLLEN nRows ); static int DumpODBCLog( SQLHENV hEnv, SQLHDBC hDbc, SQLHSTMT hStmt ); static int get_args(char *string, char **args, int maxarg); static void free_args(char **args, int maxarg); static void output_help(void); int bVerbose = 0; int nUserWidth = 0; SQLHENV hEnv = 0; SQLHDBC hDbc = 0; int bQuote = 0; int version3 = 0; int bBatch = 0; int ac_off = 0; int bHTMLTable = 0; int cDelimiter = 0; int bColumnNames = 0; int buseDC = 0; int buseED = 0; int max_col_size = MAX_DATA_WIDTH; SQLUSMALLINT has_moreresults = 1; int main( int argc, char *argv[] ) { int nArg, count; int bNewStyle = 0; char *szDSN; char *szUID; char *szPWD; char *szSQL; char *line_buffer; int buffer_size = 9000; int line_buffer_size = 9000; int bufpos,linen; char prompt[24]; #if defined(HAVE_EDITLINE) || defined(HAVE_READLINE) char *rlhistory; /* readline history path */ rlhistory = strdup(getenv("HOME")); rlhistory = realloc(rlhistory, strlen(rlhistory)+16); strcat(rlhistory, "/.isql_history"); read_history(rlhistory); #endif szDSN = NULL; szUID = NULL; szPWD = NULL; if ( argc < 2 ) { fputs( szSyntax, stderr ); exit( 1 ); } #ifdef HAVE_SETLOCALE /* * Default locale */ setlocale( LC_ALL, "" ); #endif /**************************** * PARSE ARGS ***************************/ for ( nArg = 1, count = 1 ; nArg < argc; nArg++ ) { if ( argv[nArg][0] == '-' ) { /* Options */ switch ( argv[nArg][1] ) { case 'd': cDelimiter = argv[nArg][2]; break; case 'm': nUserWidth = atoi( &(argv[nArg][2]) ); break; case 's': buffer_size = atoi( &(argv[nArg][2]) ); line_buffer_size = buffer_size; break; case 'w': bHTMLTable = 1; break; case 'b': bBatch = 1; break; case 'c': bColumnNames = 1; break; case '3': version3 = 1; break; case 'v': bVerbose = 1; break; case 'q': bQuote = 1; break; case 'n': bNewStyle = 1; break; case 'k': buseDC = 1; break; case 'e': buseED = 1; break; case 'L': max_col_size = atoi( &(argv[nArg][2]) ); break; case '-': printf( "unixODBC " VERSION "\n" ); exit(0); #ifdef HAVE_STRTOL case 'x': cDelimiter = strtol( argv[nArg]+2, NULL, 0 ); break; #endif #ifdef HAVE_SETLOCALE case 'l': if ( !setlocale( LC_ALL, argv[nArg]+2 )) { fprintf( stderr, "isql: can't set locale to '%s'\n", argv[nArg]+2 ); exit ( -1 ); } break; #endif default: fputs( szSyntax, stderr ); exit( 1 ); } continue; } else if ( count == 1 ) szDSN = argv[nArg]; else if ( count == 2 ) szUID = argv[nArg]; else if ( count == 3 ) szPWD = argv[nArg]; count++; } szSQL = calloc( 1, buffer_size + 1 ); line_buffer = calloc( 1, buffer_size + 1 ); #ifdef HAVE_SETVBUF /* Ensure result lines are available to reader of whatever stdout */ if (bBatch) { (void)setvbuf(stdout, NULL, _IOLBF, (size_t) 0); } #endif /**************************** * CONNECT ***************************/ if ( !OpenDatabase( &hEnv, &hDbc, szDSN, szUID, szPWD ) ) exit( 1 ); /**************************** * EXECUTE ***************************/ if ( !bBatch ) { printf( "+---------------------------------------+\n" ); printf( "| Connected! |\n" ); printf( "| |\n" ); if ( bNewStyle ) { printf( "| sql-statement(s)[;] |\n" ); printf( "| go |\n" ); printf( "| \\noac |\n" ); printf( "| \\ac |\n" ); printf( "| \\commit |\n" ); printf( "| \\rollback |\n" ); printf( "| \\tables |\n" ); printf( "| \\columns |\n" ); printf( "| \\echo [string] |\n" ); printf( "| \\quit |\n" ); } else { printf( "| sql-statement |\n" ); printf( "| help [tablename] |\n" ); printf( "| echo [string] |\n" ); printf( "| quit |\n" ); } printf( "| |\n" ); printf( "+---------------------------------------+\n" ); } linen = 0; bufpos = 0; do { char *line = NULL; int malloced = 0; int len = 0; int dont_copy, exec_now; szSQL[ bufpos ] = '\0'; if ( bNewStyle ) { if ( ac_off ) { sprintf( prompt, "*%d SQL> ", ++linen ); } else { sprintf( prompt, "%d SQL> ", ++linen ); } } else { sprintf( prompt, "SQL> " ); } if ( !bBatch ) { #if defined(HAVE_EDITLINE) || defined(HAVE_READLINE) line=readline( prompt ); if ( !line ) /* EOF - ctrl D */ { malloced = 1; if ( bNewStyle ) { line = strdup( "\\quit" ); } else { line = strdup( "quit" ); } } else { malloced = 0; } if ( strcmp(line, "quit") && strcmp(line, "\\quit") ) { add_history(line); } #else fputs( prompt, stdout ); line = fgets( line_buffer, line_buffer_size, stdin ); if ( !line ) /* EOF - ctrl D */ { malloced = 1; if ( bNewStyle ) { line = strdup( "\\quit" ); } else { line = strdup( "quit" ); } } else { if ( line[ 0 ] == '\n' ) { malloced = 1; if ( bNewStyle ) { line = strdup( "\\quit" ); } else { line = strdup( "quit" ); } } else { malloced = 0; } } #endif } else { line = fgets( line_buffer, line_buffer_size, stdin ); if ( !line ) /* EOF - ctrl D */ { malloced = 1; if ( bNewStyle ) { line = strdup( "\\quit" ); } else { line = strdup( "quit" ); } } else { if ( line[ 0 ] == '\n' ) { malloced = 1; if ( bNewStyle ) { line = strdup( "\\quit" ); } else { line = strdup( "quit" ); } } else { malloced = 0; } } } /* remove any ctrl chars, and find the length */ len = 0; while ( line[ len ] ) { if ( line[ len ] == '\n' ) { line[ len ] = ' '; } if ( line[ len ] == '\r' ) { line[ len ] = ' '; } len ++; } /* remove trailing spaces */ while( len > 0 ) { if ( line[ len - 1 ] == ' ' ) { len --; } else { break; } } /* * is it a comment? */ if ( bNewStyle ) { if ( len >= 2 && line[ 0 ] == '-' && line[ 1 ] == '-' ) { /* * it can't have been malloc'd */ continue; } } dont_copy = 0; exec_now = 0; if ( bNewStyle ) { if ( len > 0 && line[ len - 1 ] == ';' ) { line[ len - 1 ] = '\0'; exec_now = 1; len --; } else if ( len == 3 && memcmp( line, "go", 2 ) == 0 ) { exec_now = 1; dont_copy = 1; } else if ( len > 1 && line[ 0 ] == '\\' ) { bufpos = 0; linen = 1; exec_now = 1; } } else { exec_now = 1; } if ( !bNewStyle ) { if ( len >= 4 && memcmp( line, "quit", 4 ) == 0 ) { if ( malloced ) { free(line); } break; } } /* * stop on a blank line */ if ( !bNewStyle ) { if ( line[ 0 ] == '\0' ) { break; } } if ( !dont_copy ) { /* * is there space */ if ( len > 0 && bufpos + len + 2 > buffer_size ) { szSQL = realloc( szSQL, bufpos + len + 2 ); buffer_size = bufpos + len + 2; } /* * insert space between the lines * the above length check will make sure there is room for * the extra space */ if ( linen > 1 ) { szSQL[ bufpos ] = ' '; bufpos ++; } memcpy( szSQL + bufpos, line, len ); bufpos += len; szSQL[ bufpos ] = '\0'; } if ( exec_now ) { if ( bNewStyle ) { if ( bufpos >= 1 && szSQL[ 0 ] == '\\' ) { if ( ExecuteSlash( hDbc, szSQL, cDelimiter, bColumnNames, bHTMLTable ) == 0 ) { break; } } else { ExecuteSQL( hDbc, szSQL, cDelimiter, bColumnNames, bHTMLTable ); } } else { if ( bufpos >= 4 && memcmp( szSQL, "help", 4 ) == 0 ) { ExecuteHelp( hDbc, szSQL, cDelimiter, bColumnNames, bHTMLTable ); } else if ( bufpos >= 4 && memcmp( szSQL, "echo", 4 ) == 0 ) { ExecuteEcho( hDbc, szSQL, cDelimiter, bColumnNames, bHTMLTable ); } else { ExecuteSQL( hDbc, szSQL, cDelimiter, bColumnNames, bHTMLTable ); } } linen = 0; bufpos = 0; } } while ( 1 ); /**************************** * DISCONNECT ***************************/ #if defined(HAVE_EDITLINE) || defined(HAVE_READLINE) write_history(rlhistory); #endif CloseDatabase( hEnv, hDbc ); exit( 0 ); } static void mem_error( int line ) { if ( bVerbose ) DumpODBCLog( hEnv, 0, 0 ); fprintf( stderr, "[ISQL]ERROR: memory allocation fail before line %d\n", line ); exit(-1); } /**************************** * OptimalDisplayWidth ***************************/ static SQLUINTEGER OptimalDisplayWidth( SQLHSTMT hStmt, SQLINTEGER nCol, int nUserWidth ) { SQLUINTEGER nLabelWidth = 10; SQLULEN nDataWidth = 10; SQLUINTEGER nOptimalDisplayWidth = 10; SQLCHAR szColumnName[MAX_DATA_WIDTH+1]; *szColumnName = '\0'; SQLColAttribute( hStmt, nCol, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, (SQLLEN*)&nDataWidth ); SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), NULL, NULL ); nLabelWidth = strlen((char*) szColumnName ); /* * catch sqlserver var(max) types */ if ( nDataWidth == 0 ) { nDataWidth = max_col_size; } nOptimalDisplayWidth = max( nLabelWidth, nDataWidth ); if ( nUserWidth > 0 ) nOptimalDisplayWidth = min( nOptimalDisplayWidth, nUserWidth ); if ( nOptimalDisplayWidth > max_col_size ) nOptimalDisplayWidth = max_col_size; return nOptimalDisplayWidth; } /**************************** * OpenDatabase - do everything we have to do to get a viable connection to szDSN ***************************/ static int OpenDatabase( SQLHENV *phEnv, SQLHDBC *phDbc, char *szDSN, char *szUID, char *szPWD ) { if ( version3 ) { if ( SQLAllocHandle( SQL_HANDLE_ENV, NULL, phEnv ) != SQL_SUCCESS ) { fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocHandle( SQL_HANDLE_ENV )\n" ); return 0; } if ( SQLSetEnvAttr( *phEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) 3, 0 ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, 0, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLSetEnvAttr( SQL_HANDLE_DBC )\n" ); SQLFreeHandle( SQL_HANDLE_ENV, *phEnv ); return 0; } if ( SQLAllocHandle( SQL_HANDLE_DBC, *phEnv, phDbc ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, 0, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocHandle( SQL_HANDLE_DBC )\n" ); SQLFreeHandle( SQL_HANDLE_ENV, *phEnv ); return 0; } if ( buseDC ) { if ( !SQL_SUCCEEDED( SQLDriverConnect( *phDbc, NULL, (SQLCHAR*)szDSN, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT ))) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLDriverConnect\n" ); SQLFreeHandle( SQL_HANDLE_DBC, *phDbc ); SQLFreeHandle( SQL_HANDLE_ENV, *phEnv ); return 0; } } else { if ( !SQL_SUCCEEDED( SQLConnect( *phDbc, (SQLCHAR*)szDSN, SQL_NTS, (SQLCHAR*)szUID, SQL_NTS, (SQLCHAR*)szPWD, SQL_NTS ))) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLConnect\n" ); SQLFreeHandle( SQL_HANDLE_DBC, *phDbc ); SQLFreeHandle( SQL_HANDLE_ENV, *phEnv ); return 0; } } } else { if ( SQLAllocEnv( phEnv ) != SQL_SUCCESS ) { fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocEnv\n" ); return 0; } if ( SQLAllocConnect( *phEnv, phDbc ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, 0, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocConnect\n" ); SQLFreeEnv( *phEnv ); return 0; } if ( buseDC ) { if ( !SQL_SUCCEEDED( SQLDriverConnect( *phDbc, NULL, (SQLCHAR*)szDSN, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT ))) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLDriverConnect\n" ); SQLFreeConnect( *phDbc ); SQLFreeEnv( *phEnv ); return 0; } } else { if ( !SQL_SUCCEEDED( SQLConnect( *phDbc, (SQLCHAR*)szDSN, SQL_NTS, (SQLCHAR*)szUID, SQL_NTS, (SQLCHAR*)szPWD, SQL_NTS ))) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLConnect\n" ); SQLFreeConnect( *phDbc ); SQLFreeEnv( *phEnv ); return 0; } } } /* * does the driver support SQLMoreResults */ if ( !SQL_SUCCEEDED( SQLGetFunctions( *phDbc, SQL_API_SQLMORERESULTS, &has_moreresults ))) { has_moreresults = 0; } return 1; } static void display_result_set( SQLHDBC hDbc, SQLHSTMT hStmt ) { SQLCHAR *szSepLine; SQLRETURN ret; int mr; SQLSMALLINT cols; SQLLEN nRows = 0; szSepLine = calloc(1, 32001); /* * Loop while SQLMoreResults returns success */ mr = 0; do { if ( mr ) { if ( ret == SQL_SUCCESS_WITH_INFO ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]INFO: SQLMoreResults returned SQL_SUCCESS_WITH_INFO\n" ); } else if ( ret == SQL_ERROR ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: SQLMoreResults returned SQL_ERROR\n" ); } } mr = 1; strcpy ((char*) szSepLine, "" ) ; /* * check to see if it has generated a result set */ if ( SQLNumResultCols( hStmt, &cols ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLNumResultCols\n" ); break; } if ( cols > 0 ) { /**************************** * WRITE HEADER ***************************/ if ( bHTMLTable ) WriteHeaderHTMLTable( hStmt ); else if ( cDelimiter == 0 ) WriteHeaderNormal( hStmt, &szSepLine ); else if ( cDelimiter && bColumnNames ) WriteHeaderDelimited( hStmt, cDelimiter ); /**************************** * WRITE BODY ***************************/ if ( bHTMLTable ) WriteBodyHTMLTable( hStmt ); else if ( cDelimiter == 0 ) nRows = WriteBodyNormal( hStmt ); else WriteBodyDelimited( hStmt, cDelimiter ); } /**************************** * WRITE FOOTER ***************************/ if ( bHTMLTable ) WriteFooterHTMLTable( hStmt ); else if ( cDelimiter == 0 ) WriteFooterNormal( hStmt, szSepLine, nRows ); } while ( has_moreresults && ( ret = SQLMoreResults( hStmt )) != SQL_NO_DATA ); free( szSepLine ); } static int display_tables( SQLHDBC hDbc ) { SQLHSTMT hStmt; SQLRETURN ret; if ( version3 ) { if ( SQLAllocHandle( SQL_HANDLE_STMT, hDbc, &hStmt ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocHandle( SQL_HANDLE_STMT )\n" ); return 0; } } else { if ( SQLAllocStmt( hDbc, &hStmt ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocStmt\n" ); return 0; } } ret = SQLTables( hStmt, NULL, 0, NULL, 0, NULL, 0, NULL, 0 ); if ( ret == SQL_ERROR ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLTables\n" ); } else { display_result_set( hDbc, hStmt ); } SQLFreeStmt( hStmt, SQL_DROP ); return 1; } static int display_columns( SQLHDBC hDbc, char *sql ) { SQLHSTMT hStmt; SQLRETURN ret; char *args[10]; int n_args; SQLCHAR *table; int len; if ( version3 ) { if ( SQLAllocHandle( SQL_HANDLE_STMT, hDbc, &hStmt ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocHandle( SQL_HANDLE_STMT )\n" ); return 0; } } else { if ( SQLAllocStmt( hDbc, &hStmt ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocStmt\n" ); return 0; } } n_args = get_args(sql, &args[0], sizeof(args) / sizeof(args[0])); if ( n_args == 0 ) { table = NULL; len = 0; } else { table = (SQLCHAR*)args[ 0 ]; len = SQL_NTS; } ret = SQLColumns( hStmt, NULL, 0, NULL, 0, table, len, NULL, 0 ); if ( ret == SQL_ERROR ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLTables\n" ); } else { display_result_set( hDbc, hStmt ); } SQLFreeStmt( hStmt, SQL_DROP ); free_args(args, sizeof(args) / sizeof(args[0])); return 1; } /**************************** * ExecuteSlash - meta commands ***************************/ static int ExecuteSlash( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ) { SQLRETURN ret; szSQL ++; if ( memcmp( szSQL, "tables", 6 ) == 0 ) { return display_tables( hDbc ); } else if ( memcmp( szSQL, "columns", 7 ) == 0 ) { return display_columns( hDbc, szSQL + 7 ); } else if ( memcmp( szSQL, "ac", 2 ) == 0 ) { if ( version3 ) { ret = SQLSetConnectAttr( hDbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0 ); if ( SQL_SUCCEEDED( ret ) ) { ac_off = 0; } } else { ret = SQLSetConnectOption( hDbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON ); if ( SQL_SUCCEEDED( ret ) ) { ac_off = 0; } } if ( !bBatch ) { printf( "AUTOCOMMIT ON (return status = %d)\n", ret ); } if ( bVerbose && !SQL_SUCCEEDED( ret )) { DumpODBCLog( hEnv, hDbc, 0 ); } } else if ( memcmp( szSQL, "noac", 4 ) == 0 ) { if ( version3 ) { ret = SQLSetConnectAttr( hDbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0 ); if ( SQL_SUCCEEDED( ret ) ) { ac_off = 1; } } else { ret = SQLSetConnectOption( hDbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF ); if ( SQL_SUCCEEDED( ret ) ) { ac_off = 1; } } if ( !bBatch ) { printf( "AUTOCOMMIT OFF (return status = %d)\n", ret ); } if ( bVerbose && !SQL_SUCCEEDED( ret )) { DumpODBCLog( hEnv, hDbc, 0 ); } } else if ( memcmp( szSQL, "commit", 6 ) == 0 ) { if ( version3 ) { ret = SQLEndTran( SQL_HANDLE_DBC, hDbc, SQL_COMMIT ); } else { ret = SQLTransact( hEnv, hDbc, SQL_COMMIT ); } if ( !bBatch ) { printf( "COMMIT (return status = %d)\n", ret ); } if ( bVerbose && !SQL_SUCCEEDED( ret )) { DumpODBCLog( hEnv, hDbc, 0 ); } } else if ( memcmp( szSQL, "rollback", 8 ) == 0 ) { if ( version3 ) { ret = SQLEndTran( SQL_HANDLE_DBC, hDbc, SQL_ROLLBACK ); } else { ret = SQLTransact( hEnv, hDbc, SQL_ROLLBACK ); } if ( !bBatch ) { printf( "ROLLBACK (return status = %d)\n", ret ); } if ( bVerbose && !SQL_SUCCEEDED( ret )) { DumpODBCLog( hEnv, hDbc, 0 ); } } else if ( memcmp( szSQL, "echo", 4 ) == 0 ) { char *p; for ( p = szSQL+4; *p != '\0' && isspace((int)*p) ; ++p ) ; if ( *p != '\0' && p == szSQL+4 ) { fprintf( stderr, "[ISQL]ERROR: incorrect echo call\n" ); return 0; } (void)printf( "%s\n", p ); } else if ( memcmp( szSQL, "quit", 4 ) == 0 ) { return 0; } else { printf( "\nUnknown metacommand '%s'\n\n", szSQL ); } return 1; } /**************************** * ExecuteSQL - create a statement, execute the SQL, and get rid of the statement * - show results as per request; bHTMLTable has precedence over other options ***************************/ static int ExecuteSQL( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ) { SQLHSTMT hStmt; SQLSMALLINT cols; SQLLEN nRows = 0; SQLINTEGER ret; SQLCHAR *szSepLine; int mr; szSepLine = calloc(1, 32001); /**************************** * EXECUTE SQL ***************************/ if ( version3 ) { if ( SQLAllocHandle( SQL_HANDLE_STMT, hDbc, &hStmt ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocHandle( SQL_HANDLE_STMT )\n" ); free(szSepLine); return 0; } } else { if ( SQLAllocStmt( hDbc, &hStmt ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocStmt\n" ); free(szSepLine); return 0; } } if ( buseED ) { ret = SQLExecDirect( hStmt, (SQLCHAR*)szSQL, strlen( szSQL )); if ( ret == SQL_NO_DATA ) { fprintf( stderr, "[ISQL]INFO: SQLExecDirect returned SQL_NO_DATA\n" ); } else if ( ret == SQL_SUCCESS_WITH_INFO ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]INFO: SQLExecDirect returned SQL_SUCCESS_WITH_INFO\n" ); } else if ( ret != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLExecDirect\n" ); SQLFreeStmt( hStmt, SQL_DROP ); free(szSepLine); return 0; } } else { ret = SQLPrepare( hStmt, (SQLCHAR*)szSQL, strlen( szSQL )); if ( ret == SQL_SUCCESS_WITH_INFO ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]INFO: SQLPrepare returned SQL_SUCCESS_WITH_INFO\n" ); } else if ( ret != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLPrepare\n" ); SQLFreeStmt( hStmt, SQL_DROP ); free(szSepLine); return 0; } ret = SQLExecute( hStmt ); if ( ret == SQL_NO_DATA ) { fprintf( stderr, "[ISQL]INFO: SQLExecute returned SQL_NO_DATA\n" ); } else if ( ret == SQL_SUCCESS_WITH_INFO ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]INFO: SQLExecute returned SQL_SUCCESS_WITH_INFO\n" ); } else if ( ret != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLExecute\n" ); SQLFreeStmt( hStmt, SQL_DROP ); free(szSepLine); return 0; } } /* * Loop while SQLMoreResults returns success */ mr = 0; do { if ( mr ) { if ( ret == SQL_SUCCESS_WITH_INFO ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]INFO: SQLMoreResults returned SQL_SUCCESS_WITH_INFO\n" ); } else if ( ret == SQL_ERROR ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: SQLMoreResults returned SQL_ERROR\n" ); } } mr = 1; strcpy ((char*) szSepLine, "" ) ; /* * check to see if it has generated a result set */ if ( SQLNumResultCols( hStmt, &cols ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLNumResultCols\n" ); SQLFreeStmt( hStmt, SQL_DROP ); free(szSepLine); return 0; } if ( cols > 0 ) { /**************************** * WRITE HEADER ***************************/ if ( bHTMLTable ) WriteHeaderHTMLTable( hStmt ); else if ( cDelimiter == 0 ) WriteHeaderNormal( hStmt, &szSepLine ); else if ( cDelimiter && bColumnNames ) WriteHeaderDelimited( hStmt, cDelimiter ); /**************************** * WRITE BODY ***************************/ if ( bHTMLTable ) WriteBodyHTMLTable( hStmt ); else if ( cDelimiter == 0 ) nRows = WriteBodyNormal( hStmt ); else WriteBodyDelimited( hStmt, cDelimiter ); } /**************************** * WRITE FOOTER ***************************/ if ( bHTMLTable ) WriteFooterHTMLTable( hStmt ); else if ( cDelimiter == 0 ) WriteFooterNormal( hStmt, szSepLine, nRows ); } while ( has_moreresults && ( ret = SQLMoreResults( hStmt )) != SQL_NO_DATA ); /**************************** * CLEANUP ***************************/ SQLFreeStmt( hStmt, SQL_DROP ); free(szSepLine); return 1; } /**************************** * ExecuteHelp - create a statement, execute the SQL, and get rid of the statement * - show results as per request; bHTMLTable has precedence over other options ***************************/ static int ExecuteHelp( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ) { SQLHSTMT hStmt; SQLLEN nRows = 0; SQLRETURN nReturn; SQLCHAR *szSepLine; char *args[10]; int n_args; if (!(szSepLine = calloc(1, 32001))) { fprintf(stderr, "[ISQL]ERROR: Failed to allocate line"); return 0; } /**************************** * EXECUTE SQL ***************************/ if ( version3 ) { if ( SQLAllocHandle( SQL_HANDLE_STMT, hDbc, &hStmt ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocHandle( SQL_HANDLE_STMT )\n" ); free(szSepLine); return 0; } } else { if ( SQLAllocStmt( hDbc, &hStmt ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocStmt\n" ); free(szSepLine); return 0; } } n_args = get_args(szSQL, &args[0], sizeof(args) / sizeof(args[0])); if (n_args == 2 ) { if (strcmp(args[1], "help") == 0) { output_help(); free(szSepLine); return 0; } /* COLUMNS */ nReturn = SQLColumns( hStmt, NULL, 0, NULL, 0, (SQLCHAR*)args[1], SQL_NTS, NULL, 0 ); if ( (nReturn != SQL_SUCCESS) && (nReturn != SQL_SUCCESS_WITH_INFO) ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLColumns\n" ); SQLFreeStmt( hStmt, SQL_DROP ); free(szSepLine); return 0; } } else { SQLCHAR *catalog = NULL; SQLCHAR *schema = NULL; SQLCHAR *table = NULL; SQLCHAR *type = NULL; if (n_args > 2) { catalog = (SQLCHAR*)args[1]; schema = (SQLCHAR*)args[2]; table = (SQLCHAR*)args[3]; type = (SQLCHAR*)args[4]; } /* TABLES */ nReturn = SQLTables( hStmt, catalog, SQL_NTS, schema, SQL_NTS, table, SQL_NTS, type, SQL_NTS ); if ( (nReturn != SQL_SUCCESS) && (nReturn != SQL_SUCCESS_WITH_INFO) ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLTables\n" ); SQLFreeStmt( hStmt, SQL_DROP ); free(szSepLine); free_args(args, sizeof(args) / sizeof(args[0])); return 0; } } /**************************** * WRITE HEADER ***************************/ if ( bHTMLTable ) WriteHeaderHTMLTable( hStmt ); else if ( cDelimiter == 0 ) WriteHeaderNormal( hStmt, &szSepLine ); else if ( cDelimiter && bColumnNames ) WriteHeaderDelimited( hStmt, cDelimiter ); /**************************** * WRITE BODY ***************************/ if ( bHTMLTable ) WriteBodyHTMLTable( hStmt ); else if ( cDelimiter == 0 ) nRows = WriteBodyNormal( hStmt ); else WriteBodyDelimited( hStmt, cDelimiter ); /**************************** * WRITE FOOTER ***************************/ if ( bHTMLTable ) WriteFooterHTMLTable( hStmt ); else if ( cDelimiter == 0 ) WriteFooterNormal( hStmt, szSepLine, nRows ); /**************************** * CLEANUP ***************************/ SQLFreeStmt( hStmt, SQL_DROP ); free(szSepLine); free_args(args, sizeof(args) / sizeof(args[0])); return 1; } /**************************** * ExecuteEcho - simply write as is the string (if any) to stdout ***************************/ static int ExecuteEcho( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ) { char *p; for ( p = szSQL+4; *p != '\0' && isspace((int)*p) ; ++p ) ; if ( *p != '\0' && p == szSQL+4 ) { fprintf( stderr, "[ISQL]ERROR: incorrect echo call\n" ); return 0; } (void)printf( "%s\n", p ); return 1; } /**************************** * CloseDatabase - cleanup in prep for exiting the program ***************************/ static int CloseDatabase( SQLHENV hEnv, SQLHDBC hDbc ) { SQLDisconnect( hDbc ); if ( version3 ) { SQLFreeHandle( SQL_HANDLE_DBC, hDbc ); SQLFreeHandle( SQL_HANDLE_ENV, hEnv ); } else { SQLFreeConnect( hDbc ); SQLFreeEnv( hEnv ); } return 1; } /**************************** * WRITE HTML ***************************/ static void WriteHeaderHTMLTable( SQLHSTMT hStmt ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLCHAR szColumnName[MAX_DATA_WIDTH+1]; *szColumnName = '\0'; printf( "\n" ); printf( "\n" ); if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; for ( nCol = 1; nCol <= nColumns; nCol++ ) { SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), NULL, NULL ); printf( "\n" ); } printf( "\n" ); } static void WriteBodyHTMLTable( SQLHSTMT hStmt ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLLEN nIndicator = 0; SQLCHAR *szColumnValue; SQLRETURN nReturn = 0; SQLRETURN ret; if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; szColumnValue = malloc( max_col_size + 1 ); if ( !szColumnValue ) { mem_error( __LINE__ ); } while ( (ret = SQLFetch( hStmt )) == SQL_SUCCESS ) /* ROWS */ { printf( "\n" ); for ( nCol = 1; nCol <= nColumns; nCol++ ) /* COLS */ { printf( "\n" ); } if (ret != SQL_SUCCESS) break; printf( "\n" ); } free( szColumnValue ); } static void WriteFooterHTMLTable( SQLHSTMT hStmt ) { printf( "
\n" ); printf( "\n" ); printf( "%s\n", szColumnName ); printf( "\n" ); printf( "
\n" ); printf( "\n" ); nReturn = SQLGetData( hStmt, nCol, SQL_C_CHAR, (SQLPOINTER)szColumnValue, max_col_size + 1, &nIndicator ); if ( nReturn == SQL_SUCCESS && nIndicator != SQL_NULL_DATA ) { fputs((char*) szColumnValue, stdout ); } else if ( nReturn == SQL_SUCCESS_WITH_INFO ) { szColumnValue[ max_col_size ] = '\0'; fputs((char*) szColumnValue, stdout ); fputs((char*) "...", stdout ); } else if ( nReturn == SQL_ERROR ) { ret = SQL_ERROR; break; } else printf( "%s\n", "" ); printf( "\n" ); printf( "
\n" ); } /**************************** * WRITE DELIMITED * - this output can be used by the ODBC Text File driver * - last column no longer has a delimit char (it is implicit)... * this is consistent with odbctxt ***************************/ static void WriteHeaderDelimited( SQLHSTMT hStmt, char cDelimiter ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLCHAR szColumnName[MAX_DATA_WIDTH+1]; *szColumnName = '\0'; if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; for ( nCol = 1; nCol <= nColumns; nCol++ ) { SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), NULL, NULL ); fputs((char*) szColumnName, stdout ); if ( nCol < nColumns ) putchar( cDelimiter ); } putchar( '\n' ); } static void WriteBodyDelimited( SQLHSTMT hStmt, char cDelimiter ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLLEN nIndicator = 0; SQLCHAR *szColumnValue; SQLRETURN nReturn = 0; SQLRETURN ret; SQLINTEGER *types; szColumnValue = malloc( max_col_size + 1 ); if ( !szColumnValue ) { mem_error( __LINE__ ); } if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; if ( bQuote && nColumns > 0 ) { types = malloc( nColumns * sizeof ( SQLINTEGER )); for ( nCol = 1; nCol <= nColumns && types; nCol++ ) { SQLSMALLINT type = 0; nReturn = SQLDescribeCol( hStmt, nCol, NULL, 0, NULL, &type, NULL, NULL, NULL ); switch ( type ) { case SQL_CHAR: case SQL_VARCHAR: case SQL_WCHAR: case SQL_WVARCHAR: case SQL_LONGVARCHAR: case SQL_WLONGVARCHAR: types[ nCol - 1 ] = 1; break; default: types[ nCol - 1 ] = 0; break; } } } else { types = NULL; } /* ROWS */ while (( ret = SQLFetch( hStmt )) == SQL_SUCCESS ) { /* COLS */ for ( nCol = 1; nCol <= nColumns; nCol++ ) { nReturn = SQLGetData( hStmt, nCol, SQL_C_CHAR, (SQLPOINTER)szColumnValue, max_col_size + 1, &nIndicator ); if ( nReturn == SQL_SUCCESS && nIndicator != SQL_NULL_DATA ) { if ( types && types[ nCol - 1 ] ) { putchar( '"' ); } fputs((char*) szColumnValue, stdout ); if ( types && types[ nCol - 1 ] ) { putchar( '"' ); } if ( nCol < nColumns ) { putchar( cDelimiter ); } } else if ( nReturn == SQL_SUCCESS_WITH_INFO ) { szColumnValue[ max_col_size ] = '\0'; if ( types && types[ nCol - 1 ] ) { putchar( '"' ); } fputs((char*) szColumnValue, stdout ); fputs((char*) "...", stdout ); if ( types && types[ nCol - 1 ] ) { putchar( '"' ); } if ( nCol < nColumns ) { putchar( cDelimiter ); } } else if ( nReturn == SQL_ERROR ) { ret = SQL_ERROR; break; } else { if ( nCol < nColumns ) { putchar( cDelimiter ); } } } if (ret != SQL_SUCCESS) { break; } printf( "\n" ); } if ( ret == SQL_ERROR ) { if ( bVerbose ) DumpODBCLog( 0, 0, hStmt ); } if ( types ) { free( types ); } free( szColumnValue ); } /**************************** * WRITE NORMAL ***************************/ static void WriteHeaderNormal( SQLHSTMT hStmt, SQLCHAR **szSepLine ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLCHAR *szColumn; SQLCHAR *szColumnName; SQLCHAR *szHdrLine; SQLUINTEGER nOptimalDisplayWidth = 10; szColumnName = malloc( max_col_size + 1 ); if ( !szColumnName ) { mem_error( __LINE__ ); } szColumn = malloc( max_col_size + 3 ); if ( !szColumn ) { free( szColumnName ); mem_error( __LINE__ ); } *szColumn = '\0'; *szColumnName = '\0'; if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; if ( nColumns > 0 ) { szHdrLine = calloc(1, 512 + max_col_size * nColumns ); if ( !szHdrLine ) { mem_error( __LINE__ ); } *szSepLine = realloc( *szSepLine, 512 + max_col_size * nColumns ); if ( !*szSepLine ) { mem_error( __LINE__ ); } } else { szHdrLine = calloc(1, 32001); } for ( nCol = 1; nCol <= nColumns; nCol++ ) { int sret; nOptimalDisplayWidth = OptimalDisplayWidth( hStmt, nCol, nUserWidth ); SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, max_col_size, NULL, NULL ); /* SEP */ memset( szColumn, '\0', max_col_size + 2 ); memset( szColumn, '-', nOptimalDisplayWidth + 1 ); strcat((char*) *szSepLine, "+" ); strcat((char*) *szSepLine,(char*) szColumn ); /* HDR */ sret = sprintf( (char*)szColumn, "| %-*.*s", (int)nOptimalDisplayWidth, (int)nOptimalDisplayWidth, szColumnName ); if (sret < 0) sprintf((char *)szColumn, "| %-*.*s", (int)nOptimalDisplayWidth, (int)nOptimalDisplayWidth, "**ERROR**"); strcat( (char*)szHdrLine,(char*) szColumn ); } strcat((char*) *szSepLine, "+\n" ); strcat((char*) szHdrLine, "|\n" ); fputs((char*) *szSepLine, stdout ); fputs((char*) szHdrLine, stdout ); fputs((char*) *szSepLine, stdout ); free(szHdrLine); free( szColumnName ); free( szColumn ); } static SQLLEN WriteBodyNormal( SQLHSTMT hStmt ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLLEN nIndicator = 0; SQLCHAR *szColumn; SQLCHAR *szColumnValue; SQLRETURN nReturn = 0; SQLLEN nRows = 0; SQLUINTEGER nOptimalDisplayWidth = 10; szColumnValue = malloc( max_col_size + 1 ); if ( !szColumnValue ) { mem_error( __LINE__ ); } szColumn = malloc( max_col_size + 21 ); if ( !szColumn ) { free( szColumnValue ); mem_error( __LINE__ ); } nReturn = SQLNumResultCols( hStmt, &nColumns ); if ( nReturn != SQL_SUCCESS && nReturn != SQL_SUCCESS_WITH_INFO ) nColumns = -1; /* ROWS */ nReturn = SQLFetch( hStmt ); while ( nReturn == SQL_SUCCESS || nReturn == SQL_SUCCESS_WITH_INFO ) { /* COLS */ for ( nCol = 1; nCol <= nColumns; nCol++ ) { int sret; nOptimalDisplayWidth = OptimalDisplayWidth( hStmt, nCol, nUserWidth ); nReturn = SQLGetData( hStmt, nCol, SQL_C_CHAR, (SQLPOINTER)szColumnValue, max_col_size + 1, &nIndicator ); szColumnValue[max_col_size] = '\0'; if ( nReturn == SQL_SUCCESS && nIndicator != SQL_NULL_DATA ) { sret = sprintf( (char*)szColumn, "| %-*.*s", (int)nOptimalDisplayWidth, (int)nOptimalDisplayWidth, szColumnValue ); if (sret < 0) sprintf( (char*)szColumn, "| %-*.*s", (int)nOptimalDisplayWidth, (int)nOptimalDisplayWidth, "**ERROR**" ); } else if ( nReturn == SQL_SUCCESS_WITH_INFO ) { sret = sprintf( (char*)szColumn, "| %-*.*s...", (int)nOptimalDisplayWidth - 3, (int)nOptimalDisplayWidth - 3, szColumnValue ); if (sret < 0) sprintf( (char*)szColumn, "| %-*.*s", (int)nOptimalDisplayWidth, (int)nOptimalDisplayWidth, "**ERROR**" ); } else if ( nReturn == SQL_ERROR ) { break; } else { sprintf( (char*)szColumn, "| %-*s", (int)nOptimalDisplayWidth, "" ); } fputs( (char*)szColumn, stdout ); } /* for columns */ nRows++; printf( "|\n" ); nReturn = SQLFetch( hStmt ); } /* while rows */ if ( nReturn == SQL_ERROR ) { if ( bVerbose ) DumpODBCLog( 0, 0, hStmt ); } free( szColumnValue ); free( szColumn); return nRows; } static void WriteFooterNormal( SQLHSTMT hStmt, SQLCHAR *szSepLine, SQLLEN nRows ) { SQLLEN nRowsAffected = -1; fputs( (char*)szSepLine, stdout ); SQLRowCount( hStmt, &nRowsAffected ); printf( "SQLRowCount returns %ld\n", nRowsAffected ); if ( nRows ) { printf( "%ld rows fetched\n", nRows ); } } static int DumpODBCLog( SQLHENV hEnv, SQLHDBC hDbc, SQLHSTMT hStmt ) { SQLCHAR szError[501]; SQLCHAR szSqlState[10]; SQLINTEGER nNativeError; SQLSMALLINT nErrorMsg; if ( version3 ) { int rec; if ( hStmt ) { rec = 0; while ( SQLGetDiagRec( SQL_HANDLE_STMT, hStmt, ++rec, szSqlState, &nNativeError, szError, 500, &nErrorMsg ) == SQL_SUCCESS ) { printf( "[%s]%s\n", szSqlState, szError ); } } if ( hDbc ) { rec = 0; while ( SQLGetDiagRec( SQL_HANDLE_DBC, hDbc, ++rec, szSqlState, &nNativeError, szError, 500, &nErrorMsg ) == SQL_SUCCESS ) { printf( "[%s]%s\n", szSqlState, szError ); } } if ( hEnv ) { rec = 0; while ( SQLGetDiagRec( SQL_HANDLE_ENV, hEnv, ++rec, szSqlState, &nNativeError, szError, 500, &nErrorMsg ) == SQL_SUCCESS ) { printf( "[%s]%s\n", szSqlState, szError ); } } } else { if ( hStmt ) { while ( SQL_SUCCEEDED( SQLError( hEnv, hDbc, hStmt, szSqlState, &nNativeError, szError, 500, &nErrorMsg ))) { printf( "[%s]%s\n", szSqlState, szError ); } } if ( hDbc ) { while ( SQL_SUCCEEDED( SQLError( hEnv, hDbc, 0, szSqlState, &nNativeError, szError, 500, &nErrorMsg ))) { printf( "[%s]%s\n", szSqlState, szError ); } } if ( hEnv ) { while ( SQL_SUCCEEDED( SQLError( hEnv, 0, 0, szSqlState, &nNativeError, szError, 500, &nErrorMsg ))) { printf( "[%s]%s\n", szSqlState, szError ); } } } return 1; } static int get_args(char *string, char **args, int maxarg) { int nargs = 0; char *copy; char *p; const char *sep = " "; char *arg; unsigned int i; if (!string || !args) return 0; if (!(copy = strdup(string))) return 0; for (i = 0; i < maxarg; i++) { args[i] = NULL; } p = copy; while ((arg = strtok(p, sep))) { p = NULL; if (strcmp(arg, "\"\"") == 0) args[nargs++] = strdup(""); else if (strcmp(arg, "null") == 0) args[nargs++] = NULL; else args[nargs++] = strdup(arg); if (nargs > maxarg) return maxarg; } free(copy); return nargs; } static void free_args(char **args, int maxarg) { unsigned int i; for (i = 0; i < maxarg; i++) { if (args[i]) { free(args[i]); args[i] = NULL; } } } static void output_help(void) { fprintf(stderr, \ "help usage:\n\n" \ "help help - output this help\n" \ "help - call SQLTables and output the result-set\n" \ "help table_name - call SQLColumns for table_name and output the result-set\n" \ "help catalog schema table type - call SQLTables with these arguments\n" \ " where any argument may be specified as \"\" (for the empty string) \n" \ " or null to pass a null pointer argument.\n" \ "\n" \ " e.g.\n" \ " help %% \"\" \"\" \"\" - output list of catalogs\n" \ " help \"\" %% \"\" \"\" - output list of schemas\n" \ " help null null b%% null - output all tables beginning with b\n" \ " help null null null VIEW - output list of views\n" \ "\n"); } unixODBC-2.3.12/exe/isql.h000066400000000000000000000134321446441710500151250ustar00rootroot00000000000000/************************************************** * isql * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under GPL 18.FEB.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include #include #include #ifdef HAVE_STRTOL char *szSyntax = "\n" "**********************************************\n" "* unixODBC - isql and iusql *\n" "**********************************************\n" "* Syntax *\n" "* *\n" "* isql DSN [UID [PWD]] [options] *\n" "* *\n" "* iusql DSN [UID [PWD]] [options] *\n" "* iusql \"Connection String\" [options] *\n" "* *\n" "* Options *\n" "* *\n" "* -b batch.(no prompting etc) *\n" "* -dx delimit columns with x *\n" "* -x0xXX delimit columns with XX, where *\n" "* x is in hex, ie 0x09 is tab *\n" "* -w wrap results in an HTML table *\n" "* -c column names on first row. *\n" "* (only used when -d) *\n" "* -mn limit column display width to n *\n" "* -v verbose. *\n" "* -lx set locale to x *\n" "* -q wrap char fields in dquotes *\n" "* -3 Use ODBC 3 calls *\n" "* -n Use new line processing *\n" "* -e Use SQLExecDirect not Prepare *\n" "* -k Use SQLDriverConnect *\n" "* -L Length of col display (def:300) *\n" "* --version version *\n" "* *\n" "* Commands *\n" "* *\n" "* help - list tables *\n" "* help table - list columns in table *\n" "* help help - list all help options *\n" "* *\n" "* Examples *\n" "* *\n" "* iusql -v WebDB MyID MyPWD -w < My.sql *\n" "* *\n" "* Each line in My.sql must contain *\n" "* exactly 1 SQL command except for the *\n" "* last line which must be blank (unless *\n" "* -n option specified). *\n" "* *\n" "* Datasources, drivers, etc: *\n" "* *\n" "* See \"man 1 isql\" *\n" "* *\n" "* Please visit; *\n" "* *\n" "* http://www.unixodbc.org *\n" "* nick@lurcher.org *\n" "* pharvey@codebydesign.com *\n" "**********************************************\n\n"; #else char *szSyntax = "\n" "**********************************************\n" "* unixODBC - isql and iusql *\n" "**********************************************\n" "* Syntax *\n" "* *\n" "* isql DSN [UID [PWD]] [options] *\n" "* *\n" "* iusql DSN [UID [PWD]] [options] *\n" "* *\n" "* Options *\n" "* *\n" "* -b batch.(no prompting etc) *\n" "* -dx delimit columns with x *\n" "* -x0xXX delimit columns with XX, where *\n" "* x is in hex, ie 0x09 is tab *\n" "* -w wrap results in an HTML table *\n" "* -c column names on first row. *\n" "* (only used when -d) *\n" "* -mn limit column display width to n *\n" "* -v verbose. *\n" "* -q wrap char fields in dquotes *\n" "* --version version *\n" "* *\n" "* Commands *\n" "* *\n" "* help - list tables *\n" "* help table - list columns in table *\n" "* help help - list all help options *\n" "* *\n" "* Examples *\n" "* *\n" "* iusql -v WebDB MyID MyPWD -w < My.sql *\n" "* *\n" "* Each line in My.sql must contain *\n" "* exactly 1 SQL command except for the *\n" "* last line which must be blank. *\n" "* *\n" "* Datasources, drivers, etc: *\n" "* *\n" "* See \"man 1 isql\" *\n" "* *\n" "* Please visit; *\n" "* *\n" "* http://www.unixodbc.org *\n" "* nick@lurcher.org *\n" "* pharvey@codebydesign.com *\n" "**********************************************\n\n"; #endif #define MAX_DATA_WIDTH 300 #ifndef max #define max( a, b ) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min( a, b ) (((a) < (b)) ? (a) : (b)) #endif unixODBC-2.3.12/exe/iusql.c000066400000000000000000000735241446441710500153150ustar00rootroot00000000000000/************************************************** * isql * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under GPL 18.FEB.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include #define UNICODE #include "isql.h" #include "ini.h" #include "sqlucode.h" #ifdef HAVE_READLINE #include #include #endif #ifdef HAVE_EDITLINE #include #endif #ifdef HAVE_SETLOCALE #ifdef HAVE_LOCALE_H #include #endif #endif static int OpenDatabase( SQLHENV *phEnv, SQLHDBC *phDbc, char *szDSN, char *szUID, char *szPWD ); static int CloseDatabase( SQLHENV hEnv, SQLHDBC hDbc ); static int ExecuteSQL( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ); static int ExecuteHelp( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ); static int ExecuteEcho( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ); static void WriteHeaderHTMLTable( SQLHSTMT hStmt ); static void WriteHeaderDelimited( SQLHSTMT hStmt, char cDelimiter ); static void WriteBodyHTMLTable( SQLHSTMT hStmt ); static SQLLEN WriteBodyNormal( SQLHSTMT hStmt ); static void WriteBodyDelimited( SQLHSTMT hStmt, char cDelimiter ); static void WriteFooterHTMLTable( SQLHSTMT hStmt ); static int DumpODBCLog( SQLHENV hEnv, SQLHDBC hDbc, SQLHSTMT hStmt ); int bVerbose = 0; int nUserWidth = 0; SQLHENV hEnv = 0; SQLHDBC hDbc = 0; int buseED = 0; void UWriteHeaderNormal( SQLHSTMT hStmt, SQLTCHAR *szSepLine ); void UWriteFooterNormal( SQLHSTMT hStmt, SQLTCHAR *szSepLine, SQLLEN nRows ); static char * uc_to_ascii( SQLWCHAR *uc ) { char *ascii = (char *)uc; int i; for ( i = 0; uc[ i ]; i ++ ) { ascii[ i ] = uc[ i ] & 0x00ff; } ascii[ i ] = 0; return ascii; } static void ansi_to_unicode( char *szSQL, SQLWCHAR *szUcSQL ) { int i; for ( i = 0; szSQL[ i ]; i ++ ) { szUcSQL[ i ] = szSQL[ i ]; } szUcSQL[ i ] = 0; } int main( int argc, char *argv[] ) { int nArg, count; int bHTMLTable = 0; int bBatch = 0; int cDelimiter = 0; int bColumnNames = 0; char *szDSN; char *szUID; char *szPWD; char *szSQL; char *pEscapeChar; int buffer_size = 9000; int len; szDSN = NULL; szUID = NULL; szPWD = NULL; if ( argc < 2 ) { fputs( szSyntax, stderr ); exit( 1 ); } #ifdef HAVE_SETLOCALE /* * Default locale */ setlocale( LC_ALL, "" ); #endif /**************************** * PARSE ARGS ***************************/ for ( nArg = 1, count = 1 ; nArg < argc; nArg++ ) { if ( argv[nArg][0] == '-' ) { /* Options */ switch ( argv[nArg][1] ) { case 'd': cDelimiter = argv[nArg][2]; break; case 's': buffer_size = atoi( &(argv[nArg][2]) ); break; case 'm': nUserWidth = atoi( &(argv[nArg][2]) ); break; case 'w': bHTMLTable = 1; break; case 'b': bBatch = 1; break; case 'c': bColumnNames = 1; break; case 'v': bVerbose = 1; break; case 'e': buseED = 1; break; case '-': printf( "unixODBC " VERSION "\n" ); exit(0); #ifdef HAVE_STRTOL case 'x': cDelimiter = strtol( argv[nArg]+2, NULL, 0 ); break; #endif #ifdef HAVE_SETLOCALE case 'l': if ( !setlocale( LC_ALL, argv[nArg]+2 )) { fprintf( stderr, "isql: can't set locale to '%s'\n", argv[nArg]+2 ); exit ( -1 ); } break; #endif default: fputs( szSyntax, stderr ); exit( 1 ); } continue; } else if ( count == 1 ) { if ( nArg < argc ) { szDSN = argv[nArg]; } } else if ( count == 2 ) { if ( nArg < argc ) { szUID = argv[nArg]; } } else if ( count == 3 ) { if ( nArg < argc ) { szPWD = argv[nArg]; } } count++; } szSQL = calloc( 1, buffer_size + 1 ); #ifdef HAVE_SETVBUF /* Ensure result lines are available to reader of whatever stdout */ if (bBatch) { (void)setvbuf(stdout, NULL, _IOLBF, (size_t) 0); } #endif /**************************** * CONNECT ***************************/ if ( !OpenDatabase( &hEnv, &hDbc, szDSN, szUID, szPWD ) ) exit( 1 ); /**************************** * EXECUTE ***************************/ if ( !bBatch ) { printf( "+---------------------------------------+\n" ); printf( "| Connected! |\n" ); printf( "| |\n" ); printf( "| sql-statement |\n" ); printf( "| help [tablename] |\n" ); printf( "| echo [string] |\n" ); printf( "| quit |\n" ); printf( "| |\n" ); printf( "+---------------------------------------+\n" ); } do { if ( !bBatch ) #if !defined(HAVE_EDITLINE) && !defined(HAVE_READLINE) printf( "SQL> " ); #else { char *line; int malloced; line=readline("SQL> "); if ( !line ) /* EOF - ctrl D */ { malloced = 1; line = strdup( "quit" ); } else { malloced = 0; } strncpy(szSQL, line, buffer_size ); add_history(line); if ( malloced ) { free(line); } } else #endif { char *line; int malloced; line = fgets( szSQL, buffer_size, stdin ); if ( !line ) /* EOF - ctrl D */ { malloced = 1; line = strdup( "quit" ); } else { malloced = 0; } strncpy(szSQL, line, buffer_size ); if ( malloced ) { free(line); } } /* strip away escape chars */ while ( (pEscapeChar=(char*)strchr(szSQL, '\n')) != NULL || (pEscapeChar=(char*)strchr(szSQL, '\r')) != NULL ) *pEscapeChar = ' '; len = strlen( szSQL ); /* remove trailing spaces */ while( len > 0 ) { len --; if ( szSQL[ len ] == ' ' ) { szSQL[ len ] = '\0'; } else { break; } } if ( szSQL[1] != '\0' ) { if ( strncmp( szSQL, "quit", 4 ) == 0 ) szSQL[1] = '\0'; else if ( strncmp( szSQL, "help", 4 ) == 0 ) ExecuteHelp( hDbc, szSQL, cDelimiter, bColumnNames, bHTMLTable ); else if ( strncmp( szSQL, "echo", 4 ) == 0 ) ExecuteEcho( hDbc, szSQL, cDelimiter, bColumnNames, bHTMLTable ); else if (memcmp(szSQL, "--", 2) != 0) ExecuteSQL( hDbc, szSQL, cDelimiter, bColumnNames, bHTMLTable ); } } while ( szSQL[1] != '\0' ); /**************************** * DISCONNECT ***************************/ CloseDatabase( hEnv, hDbc ); exit( 0 ); } /**************************** * OptimalDisplayWidth ***************************/ static SQLUINTEGER OptimalDisplayWidth( SQLHSTMT hStmt, SQLINTEGER nCol, int nUserWidth ) { SQLUINTEGER nLabelWidth = 10; SQLULEN nDataWidth = 10; SQLUINTEGER nOptimalDisplayWidth = 10; SQLCHAR szColumnName[MAX_DATA_WIDTH+1]; *szColumnName = '\0'; SQLColAttribute( hStmt, nCol, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, (SQLLEN*)&nDataWidth ); SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), NULL, NULL ); nLabelWidth = strlen((char*) szColumnName ); /* * catch sqlserver var(max) types */ if ( nDataWidth == 0 ) { nDataWidth = MAX_DATA_WIDTH; } nOptimalDisplayWidth = max( nLabelWidth, nDataWidth ); if ( nUserWidth > 0 ) nOptimalDisplayWidth = min( nOptimalDisplayWidth, nUserWidth ); if ( nOptimalDisplayWidth > MAX_DATA_WIDTH ) nOptimalDisplayWidth = MAX_DATA_WIDTH; return nOptimalDisplayWidth; } /**************************** * OpenDatabase - do everything we have to do to get a viable connection to szDSN ***************************/ static int OpenDatabase( SQLHENV *phEnv, SQLHDBC *phDbc, char *szDSN, char *szUID, char *szPWD ) { SQLCHAR dsn[ 1024 ], uid[ 1024 ], pwd[ 1024 ]; SQLTCHAR cstr[ 1024 ]; char zcstr[ 1024 * 2 ], tmp[ 1024 * 8 ]; int i; size_t zclen; if ( SQLAllocEnv( phEnv ) != SQL_SUCCESS ) { fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocEnv\n" ); return 0; } if ( SQLAllocConnect( *phEnv, phDbc ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, 0, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocConnect\n" ); SQLFreeEnv( *phEnv ); return 0; } if ( szDSN ) { size_t DSNlen=strlen( szDSN ); for ( i = 0; i < DSNlen && i < sizeof( dsn ) - 1; i ++ ) { dsn[ i ] = szDSN[ i ]; } dsn[ i ] = '\0'; } else { dsn[ 0 ] = '\0'; } if ( szUID ) { size_t UIDlen=strlen( szUID ); for ( i = 0; i < UIDlen && i < sizeof( uid ) - 1; i ++ ) { uid[ i ] = szUID[ i ]; } uid[ i ] = '\0'; } else { uid[ 0 ] = '\0'; } if ( szPWD ) { size_t PWDlen=strlen( szPWD ); for ( i = 0; i < PWDlen && i < sizeof( pwd ) - 1; i ++ ) { pwd[ i ] = szPWD[ i ]; } pwd[ i ] = '\0'; } else { pwd[ 0 ] = '\0'; } /* * Allow passing in a entire connect string in the first arg * * isql "DSN={Dsn Name};PWD={Pass world};UID={User Name}" */ if ( !szPWD && !szUID && ( strstr( dsn, "DSN=" ) || strstr( dsn, "DRIVER=" ) || strstr( dsn, "FILEDSN=" ))) { strcpy( zcstr, dsn ); } else { sprintf( zcstr, "DSN=%s", dsn ); if ( szUID ) { sprintf( tmp, ";UID=%s", uid ); strcat( zcstr, tmp ); } if ( szPWD ) { sprintf( tmp, ";PWD=%s", pwd ); strcat( zcstr, tmp ); } } zclen=strlen( zcstr ); for ( i = 0; i < zclen; i ++ ) { cstr[ i ] = zcstr[ i ]; } cstr[ i ] = 0; if ( !SQL_SUCCEEDED( SQLDriverConnect( *phDbc, NULL, cstr, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT ))) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLDriverConnect\n" ); SQLFreeConnect( *phDbc ); SQLFreeEnv( *phEnv ); return 0; } if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); return 1; } /**************************** * ExecuteSQL - create a statement, execute the SQL, and get rid of the statement * - show results as per request; bHTMLTable has precedence over other options ***************************/ static int ExecuteSQL( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ) { SQLHSTMT hStmt; SQLTCHAR szSepLine[32001]; SQLTCHAR szUcSQL[32001]; SQLSMALLINT cols; SQLINTEGER ret; SQLLEN nRows = 0; szSepLine[ 0 ] = 0; ansi_to_unicode( szSQL, szUcSQL ); /**************************** * EXECUTE SQL ***************************/ if ( SQLAllocStmt( hDbc, &hStmt ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocStmt\n" ); return 0; } if ( buseED ) { ret = SQLExecDirect( hStmt, szUcSQL, SQL_NTS ); if ( ret == SQL_NO_DATA ) { fprintf( stderr, "[ISQL]INFO: SQLExecDirect returned SQL_NO_DATA\n" ); } else if ( ret == SQL_SUCCESS_WITH_INFO ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]INFO: SQLExecDirect returned SQL_SUCCESS_WITH_INFO\n" ); } else if ( ret != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLExecDirect\n" ); SQLFreeStmt( hStmt, SQL_DROP ); return 0; } } else { if ( SQLPrepare( hStmt, szUcSQL, SQL_NTS ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLPrepare\n" ); SQLFreeStmt( hStmt, SQL_DROP ); return 0; } ret = SQLExecute( hStmt ); if ( ret == SQL_NO_DATA ) { fprintf( stderr, "[ISQL]INFO: SQLExecute returned SQL_NO_DATA\n" ); } else if ( ret == SQL_SUCCESS_WITH_INFO ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]INFO: SQLExecute returned SQL_SUCCESS_WITH_INFO\n" ); } else if ( ret != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLExecute\n" ); SQLFreeStmt( hStmt, SQL_DROP ); return 0; } } do { /* * check to see if it has generated a result set */ if ( SQLNumResultCols( hStmt, &cols ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLNumResultCols\n" ); SQLFreeStmt( hStmt, SQL_DROP ); return 0; } if ( cols > 0 ) { /**************************** * WRITE HEADER ***************************/ if ( bHTMLTable ) WriteHeaderHTMLTable( hStmt ); else if ( cDelimiter == 0 ) UWriteHeaderNormal( hStmt, szSepLine ); else if ( cDelimiter && bColumnNames ) WriteHeaderDelimited( hStmt, cDelimiter ); /**************************** * WRITE BODY ***************************/ if ( bHTMLTable ) WriteBodyHTMLTable( hStmt ); else if ( cDelimiter == 0 ) nRows = WriteBodyNormal( hStmt ); else WriteBodyDelimited( hStmt, cDelimiter ); } /**************************** * WRITE FOOTER ***************************/ if ( bHTMLTable ) WriteFooterHTMLTable( hStmt ); else if ( cDelimiter == 0 ) UWriteFooterNormal( hStmt, szSepLine, nRows ); } while ( SQL_SUCCEEDED( SQLMoreResults( hStmt ))); /**************************** * CLEANUP ***************************/ SQLFreeStmt( hStmt, SQL_DROP ); return 1; } /**************************** * ExecuteHelp - create a statement, execute the SQL, and get rid of the statement * - show results as per request; bHTMLTable has precedence over other options ***************************/ static int ExecuteHelp( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ) { char szTable[250] = ""; SQLHSTMT hStmt; SQLTCHAR szSepLine[32001]; SQLLEN nRows = 0; szSepLine[ 0 ] = 0; /**************************** * EXECUTE SQL ***************************/ if ( SQLAllocStmt( hDbc, &hStmt ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, 0 ); fprintf( stderr, "[ISQL]ERROR: Could not SQLAllocStmt\n" ); return 0; } if ( iniElement( szSQL, ' ', '\0', 1, szTable, sizeof(szTable) ) == INI_SUCCESS ) { SQLWCHAR tname[ 1024 ]; ansi_to_unicode( szTable, tname ); /* COLUMNS */ if ( SQLColumns( hStmt, NULL, 0, NULL, 0, tname, SQL_NTS, NULL, 0 ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLColumns\n" ); SQLFreeStmt( hStmt, SQL_DROP ); return 0; } } else { /* TABLES */ if ( SQLTables( hStmt, NULL, 0, NULL, 0, NULL, 0, NULL, 0 ) != SQL_SUCCESS ) { if ( bVerbose ) DumpODBCLog( hEnv, hDbc, hStmt ); fprintf( stderr, "[ISQL]ERROR: Could not SQLTables\n" ); SQLFreeStmt( hStmt, SQL_DROP ); return 0; } } /**************************** * WRITE HEADER ***************************/ if ( bHTMLTable ) WriteHeaderHTMLTable( hStmt ); else if ( cDelimiter == 0 ) UWriteHeaderNormal( hStmt, szSepLine ); else if ( cDelimiter && bColumnNames ) WriteHeaderDelimited( hStmt, cDelimiter ); /**************************** * WRITE BODY ***************************/ if ( bHTMLTable ) WriteBodyHTMLTable( hStmt ); else if ( cDelimiter == 0 ) nRows = WriteBodyNormal( hStmt ); else WriteBodyDelimited( hStmt, cDelimiter ); /**************************** * WRITE FOOTER ***************************/ if ( bHTMLTable ) WriteFooterHTMLTable( hStmt ); else if ( cDelimiter == 0 ) UWriteFooterNormal( hStmt, szSepLine, nRows ); /**************************** * CLEANUP ***************************/ SQLFreeStmt( hStmt, SQL_DROP ); return 1; } /**************************** * ExecuteEcho - simply write as is the string (if any) to stdout ***************************/ static int ExecuteEcho( SQLHDBC hDbc, char *szSQL, char cDelimiter, int bColumnNames, int bHTMLTable ) { char *p; for ( p = szSQL+4; *p != '\0' && isspace((int)*p) ; ++p ) ; if ( *p != '\0' && p == szSQL+4 ) { fprintf( stderr, "[ISQL]ERROR: incorrect echo call\n" ); return 0; } (void)printf( "%s\n", p ); return 1; } /**************************** * CloseDatabase - cleanup in prep for exiting the program ***************************/ int CloseDatabase( SQLHENV hEnv, SQLHDBC hDbc ) { SQLDisconnect( hDbc ); SQLFreeConnect( hDbc ); SQLFreeEnv( hEnv ); return 1; } /**************************** * WRITE HTML ***************************/ static void WriteHeaderHTMLTable( SQLHSTMT hStmt ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLTCHAR szColumnName[MAX_DATA_WIDTH+1]; szColumnName[ 0 ] = 0; printf( "\n" ); printf( "\n" ); if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; for ( nCol = 1; nCol <= nColumns; nCol++ ) { SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), NULL, NULL ); printf( "\n" ); } printf( "\n" ); } static void WriteBodyHTMLTable( SQLHSTMT hStmt ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLLEN nIndicator = 0; SQLTCHAR szColumnValue[MAX_DATA_WIDTH+1]; SQLRETURN nReturn = 0; SQLRETURN ret; szColumnValue[ 0 ] = 0; if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; while ( (ret = SQLFetch( hStmt )) == SQL_SUCCESS ) /* ROWS */ { printf( "\n" ); for ( nCol = 1; nCol <= nColumns; nCol++ ) /* COLS */ { printf( "\n" ); } if (ret != SQL_SUCCESS) break; printf( "\n" ); } } static void WriteFooterHTMLTable( SQLHSTMT hStmt ) { printf( "
\n" ); printf( "\n" ); printf( "%s\n", uc_to_ascii( szColumnName )); printf( "\n" ); printf( "
\n" ); printf( "\n" ); nReturn = SQLGetData( hStmt, nCol, SQL_C_WCHAR, (SQLPOINTER)szColumnValue, sizeof(szColumnValue), &nIndicator ); if ( nReturn == SQL_SUCCESS && nIndicator != SQL_NULL_DATA ) { uc_to_ascii( szColumnValue ); fputs((char*) szColumnValue, stdout ); } else if ( nReturn == SQL_ERROR ) { ret = SQL_ERROR; break; } else printf( "%s\n", "" ); printf( "\n" ); printf( "
\n" ); } /**************************** * WRITE DELIMITED * - this output can be used by the ODBC Text File driver * - last column no longer has a delimit char (it is implicit)... * this is consistent with odbctxt ***************************/ static void WriteHeaderDelimited( SQLHSTMT hStmt, char cDelimiter ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLTCHAR szColumnName[MAX_DATA_WIDTH+1]; szColumnName[ 0 ] = 0; if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; for ( nCol = 1; nCol <= nColumns; nCol++ ) { SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), NULL, NULL ); fputs((char*) uc_to_ascii( szColumnName ), stdout ); if ( nCol < nColumns ) putchar( cDelimiter ); } putchar( '\n' ); } static void WriteBodyDelimited( SQLHSTMT hStmt, char cDelimiter ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLLEN nIndicator = 0; SQLTCHAR szColumnValue[MAX_DATA_WIDTH+1]; SQLRETURN nReturn = 0; SQLRETURN ret; szColumnValue[ 0 ] = 0; if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; /* ROWS */ while (( ret = SQLFetch( hStmt )) == SQL_SUCCESS ) { /* COLS */ for ( nCol = 1; nCol <= nColumns; nCol++ ) { nReturn = SQLGetData( hStmt, nCol, SQL_C_WCHAR, (SQLPOINTER)szColumnValue, sizeof(szColumnValue), &nIndicator ); if ( nReturn == SQL_SUCCESS && nIndicator != SQL_NULL_DATA ) { uc_to_ascii( szColumnValue ); fputs((char*) szColumnValue, stdout ); if ( nCol < nColumns ) putchar( cDelimiter ); } else if ( nReturn == SQL_ERROR ) { ret = SQL_ERROR; break; } else { if ( nCol < nColumns ) putchar( cDelimiter ); } } if (ret != SQL_SUCCESS) break; printf( "\n" ); } if ( ret == SQL_ERROR ) { if ( bVerbose ) DumpODBCLog( 0, 0, hStmt ); } } /**************************** * WRITE NORMAL ***************************/ void UWriteHeaderNormal( SQLHSTMT hStmt, SQLTCHAR *szSepLine ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLTCHAR szColumn[MAX_DATA_WIDTH+20]; SQLTCHAR szColumnName[MAX_DATA_WIDTH+1]; SQLTCHAR szHdrLine[32001]; SQLUINTEGER nOptimalDisplayWidth = 10; szColumn[ 0 ] = 0; szColumnName[ 0 ] = 0; szHdrLine[ 0 ] = 0; if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; for ( nCol = 1; nCol <= nColumns; nCol++ ) { nOptimalDisplayWidth = OptimalDisplayWidth( hStmt, nCol, nUserWidth ); SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), NULL, NULL ); if ( nOptimalDisplayWidth > MAX_DATA_WIDTH ) nOptimalDisplayWidth = MAX_DATA_WIDTH; uc_to_ascii( szColumnName ); /* SEP */ memset( szColumn, '\0', sizeof(szColumn) ); memset( szColumn, '-', max( nOptimalDisplayWidth, strlen((char*)szColumnName) ) + 1 ); strcat((char*) szSepLine, "+" ); strcat((char*) szSepLine,(char*) szColumn ); /* HDR */ sprintf((char*) szColumn, "| %-*s", (int)max( nOptimalDisplayWidth, strlen((char*)szColumnName) ), (char*)szColumnName ); strcat((char*) szHdrLine,(char*) szColumn ); } strcat((char*) szSepLine, "+\n" ); strcat((char*) szHdrLine, "|\n" ); puts((char*) szSepLine ); puts((char*) szHdrLine ); puts((char*) szSepLine ); } static SQLLEN WriteBodyNormal( SQLHSTMT hStmt ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLLEN nIndicator = 0; SQLTCHAR szColumn[MAX_DATA_WIDTH+20]; SQLTCHAR szColumnValue[MAX_DATA_WIDTH+1]; SQLTCHAR szColumnName[MAX_DATA_WIDTH+1]; SQLRETURN nReturn = 0; SQLRETURN ret; SQLLEN nRows = 0; SQLUINTEGER nOptimalDisplayWidth = 10; szColumn[ 0 ] = 0; szColumnValue[ 0 ] = 0; szColumnName[ 0 ] = 0; if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; /* ROWS */ while (( ret = SQLFetch( hStmt )) == SQL_SUCCESS ) { /* COLS */ for ( nCol = 1; nCol <= nColumns; nCol++ ) { SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), NULL, NULL ); nOptimalDisplayWidth = OptimalDisplayWidth( hStmt, nCol, nUserWidth ); uc_to_ascii( szColumnName ); if ( nOptimalDisplayWidth > MAX_DATA_WIDTH ) nOptimalDisplayWidth = MAX_DATA_WIDTH; nReturn = SQLGetData( hStmt, nCol, SQL_C_WCHAR, (SQLPOINTER)szColumnValue, sizeof(szColumnValue), &nIndicator ); szColumnValue[MAX_DATA_WIDTH] = '\0'; uc_to_ascii( szColumnValue ); if ( nReturn == SQL_SUCCESS && nIndicator != SQL_NULL_DATA ) { if ( strlen((char*)szColumnValue) < max( nOptimalDisplayWidth, strlen((char*)szColumnName ))) { int i; size_t maxlen=max( nOptimalDisplayWidth, strlen((char*)szColumnName )); strcpy((char*) szColumn, "| " ); strcat((char*) szColumn, (char*) szColumnValue ); for ( i = strlen((char*) szColumnValue ); i < maxlen; i ++ ) { strcat((char*) szColumn, " " ); } } else { strcpy((char*) szColumn, "| " ); strcat((char*) szColumn, (char*) szColumnValue ); } } else if ( nReturn == SQL_ERROR ) { ret = SQL_ERROR; break; } else { sprintf((char*) szColumn, "| %-*s", (int)max( nOptimalDisplayWidth, strlen((char*) szColumnName) ), "" ); } fputs((char*) szColumn, stdout ); } if (ret != SQL_SUCCESS) break; printf( "|\n" ); nRows++; } if ( ret == SQL_ERROR ) { if ( bVerbose ) DumpODBCLog( 0, 0, hStmt ); } return nRows; } void UWriteFooterNormal( SQLHSTMT hStmt, SQLTCHAR *szSepLine, SQLLEN nRows ) { SQLLEN nRowsAffected = -1; puts( (char*)szSepLine ); SQLRowCount( hStmt, &nRowsAffected ); printf( "SQLRowCount returns %ld\n", nRowsAffected ); if ( nRows ) { printf( "%ld rows fetched\n", nRows ); } } static int DumpODBCLog( SQLHENV hEnv, SQLHDBC hDbc, SQLHSTMT hStmt ) { SQLTCHAR szError[501]; SQLTCHAR szSqlState[10]; SQLINTEGER nNativeError; SQLSMALLINT nErrorMsg; if ( hStmt ) { while ( SQLError( hEnv, hDbc, hStmt, szSqlState, &nNativeError, szError, 500, &nErrorMsg ) == SQL_SUCCESS ) { printf( "%s\n", uc_to_ascii( szError )); } } if ( hDbc ) { while ( SQLError( hEnv, hDbc, 0, szSqlState, &nNativeError, szError, 500, &nErrorMsg ) == SQL_SUCCESS ) { printf( "%s\n", uc_to_ascii( szError )); } } if ( hEnv ) { while ( SQLError( hEnv, 0, 0, szSqlState, &nNativeError, szError, 500, &nErrorMsg ) == SQL_SUCCESS ) { printf( "%s\n", uc_to_ascii( szError )); } } return 1; } unixODBC-2.3.12/exe/odbc-config.c000066400000000000000000000162531446441710500163260ustar00rootroot00000000000000/********************************************************************* * * Written, as part of unixODBC by Nick Gorham * (nick@lurcher.org). * * copyright (c) 2004 Nick Gorham * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * **********************************************************************/ #include #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include static void usage( void ) { fprintf( stderr, "Usage: odbc_config\n\t\t[--prefix]\n\t\t[--exec-prefix]\n\t\t[--include-prefix]\n\t\t[--lib-prefix]\n\t\t[--bin-prefix]\n\t\t[--version]\n\t\t[--libs]\n\t\t[--static-libs]\n\t\t[--libtool-libs]\n\t\t[--cflags]\n\t\t[--odbcversion]\n\t\t[--longodbcversion]\n\t\t[--odbcini]\n\t\t[--odbcinstini]\n\t\t[--header]\n\t\t[--ulen]\n" ); } static void cInc( void ) { #ifdef HAVE_UNISTD_H printf( "#ifndef HAVE_UNISTD_H\n #define HAVE_UNISTD_H\n#endif\n" ); #endif #ifdef HAVE_PWD_H printf( "#ifndef HAVE_PWD_H\n #define HAVE_PWD_H\n#endif\n" ); #endif #ifdef HAVE_SYS_TYPES_H printf( "#ifndef HAVE_SYS_TYPES_H\n #define HAVE_SYS_TYPES_H\n#endif\n" ); #endif #ifdef ODBC_STD printf( "#ifndef ODBC_STD\n #define ODBC_STD\n#endif\n" ); #endif #ifdef UNICODE printf( "#ifndef UNICODE\n #define UNICODE\n#endif\n" ); #endif #ifdef GUID_DEFINED printf( "#ifndef GUID_DEFINED\n #define GUID_DEFINED\n#endif\n" ); #endif #ifdef SQL_WCHART_CONVERT printf( "#ifndef SQL_WCHART_CONVERT\n #define SQL_WCHART_CONVERT\n#endif\n" ); #endif #ifdef HAVE_LONG_LONG printf( "#ifndef HAVE_LONG_LONG\n #define HAVE_LONG_LONG\n#endif\n" ); #endif #ifdef ODBCINT64_TYPE printf( "#ifndef ODBCINT64\n #define ODBCINT64 %s\n#endif\n", ODBCINT64_TYPE ); #endif #ifdef UODBCINT64_TYPE printf( "#ifndef UODBCINT64\n #define UODBCINT64 %s\n#endif\n", UODBCINT64_TYPE ); #endif #ifdef DISABLE_INI_CACHING printf( "#ifndef DISABLE_INI_CACHING\n #define DISABLE_INI_CACHING\n#endif\n" ); #endif #ifdef SIZEOF_LONG_INT printf( "#ifndef SIZEOF_LONG_INT\n #define SIZEOF_LONG_INT %d\n#endif\n", SIZEOF_LONG_INT ); #endif #ifdef ALREADY_HAVE_WINDOWS_TYPE printf( "#ifndef ALREADY_HAVE_WINDOWS_TYPE\n #define ALREADY_HAVE_WINDOWS_TYPE\n#endif\n" ); #endif #ifdef DONT_TD_VOID printf( "#ifndef DONT_TD_VOID\n #define DONT_TD_VOID\n#endif\n" ); #endif #ifdef DO_YOU_KNOW_WHAT_YOU_ARE_DOING printf( "#ifndef DO_YOU_KNOW_WHAT_YOU_ARE_DOING\n #define DO_YOU_KNOW_WHAT_YOU_ARE_DOING\n#endif\n" ); #endif #ifdef BUILD_LEGACY_64_BIT_MODE printf( "#ifndef BUILD_LEGACY_64_BIT_MODE\n #define BUILD_LEGACY_64_BIT_MODE\n#endif\n" ); #endif #ifdef HAVE_ICONV printf( "#ifndef HAVE_ICONV\n #define HAVE_ICONV\n#endif\n" ); #endif #ifdef ASCII_ENCODING printf( "#ifndef ASCII_ENCODING\n #define ASCII_ENCODING \"%s\"\n#endif\n", ASCII_ENCODING ); #endif #ifdef UNICODE_ENCODING printf( "#ifndef UNICODE_ENCODING\n #define UNICODE_ENCODING \"%s\"\n#endif\n", UNICODE_ENCODING ); #endif #ifdef ENABLE_DRIVER_ICONV printf( "#ifndef ENABLE_DRIVER_ICONV\n #define ENABLE_DRIVER_ICONV\n#endif\n" ); #endif } static void cflags( void ) { #ifdef HAVE_UNISTD_H printf( "-DHAVE_UNISTD_H " ); #endif #ifdef HAVE_PWD_H printf( "-DHAVE_PWD_H " ); #endif #ifdef HAVE_SYS_TYPES_H printf( "-DHAVE_SYS_TYPES_H " ); #endif #ifdef ODBC_STD printf( "-DODBC_STD " ); #endif #ifdef UNICODE printf( "-DUNICODE " ); #endif #ifdef GUID_DEFINED printf( "-DGUID_DEFINED " ); #endif #ifdef SQL_WCHART_CONVERT printf( "-DSQL_WCHART_CONVERT " ); #endif #ifdef HAVE_LONG_LONG printf( "-DHAVE_LONG_LONG " ); #endif #ifdef DISABLE_INI_CACHING printf( "-DDISABLE_INI_CACHING " ); #endif #ifdef SIZEOF_LONG_INT printf( "-DSIZEOF_LONG_INT=%d ", SIZEOF_LONG_INT ); #endif #ifdef ALREADY_HAVE_WINDOWS_TYPE printf( "-DALREADY_HAVE_WINDOWS_TYPE " ); #endif #ifdef DONT_TD_VOID printf( "-DDONT_TD_VOID " ); #endif #ifdef DO_YOU_KNOW_WHAT_YOU_ARE_DOING printf( "-DDO_YOU_KNOW_WHAT_YOU_ARE_DOING " ); #endif #ifdef BUILD_LEGACY_64_BIT_MODE printf( "-DBUILD_LEGACY_64_BIT_MODE " ); #endif #ifdef INCLUDE_PREFIX printf( "-I%s ", INCLUDE_PREFIX ); #else printf( "-I%s/include ", PREFIX ); #endif printf( "\n" ); } static void ulen( void ) { printf( "-DSIZEOF_SQLULEN=%d\n", (int)sizeof( SQLULEN )); } int main( int argc, char **argv ) { int i; if ( argc < 2 ) { usage(); exit( -1 ); } for ( i = 1; i < argc; i ++ ) { if ( strcmp( argv[ i ], "--prefix" ) == 0 ) { printf( "%s\n", PREFIX ); } else if ( strcmp( argv[ i ], "--exec-prefix" ) == 0 ) { printf( "%s\n", EXEC_PREFIX ); } else if ( strcmp( argv[ i ], "--bin-prefix" ) == 0 ) { printf( "%s\n", BIN_PREFIX ); } else if ( strcmp( argv[ i ], "--include-prefix" ) == 0 ) { printf( "%s\n", INCLUDE_PREFIX ); } else if ( strcmp( argv[ i ], "--lib-prefix" ) == 0 ) { printf( "%s\n", LIB_PREFIX ); } else if ( strcmp( argv[ i ], "--version" ) == 0 ) { printf( "%s\n", VERSION ); } else if ( strcmp( argv[ i ], "--libs" ) == 0 ) { printf( "-L%s -lodbc\n", LIB_PREFIX ); } else if ( strcmp( argv[ i ], "--static-libs" ) == 0 ) { printf( "%s/libodbc.a\n", LIB_PREFIX ); } else if ( strcmp( argv[ i ], "--libtool-libs" ) == 0 ) { printf( "%s/libodbc.la\n", LIB_PREFIX ); } else if ( strcmp( argv[ i ], "--cflags" ) == 0 ) { cflags(); } else if ( strcmp( argv[ i ], "--header" ) == 0 ) { cInc(); } else if ( strcmp( argv[ i ], "--odbcversion" ) == 0 ) { printf( "3\n" ); } else if ( strcmp( argv[ i ], "--longodbcversion" ) == 0 ) { printf( "3.52\n" ); } else if ( strcmp( argv[ i ], "--odbcini" ) == 0 ) { printf( "%s/odbc.ini\n", SYSTEM_FILE_PATH ); } else if ( strcmp( argv[ i ], "--odbcinstini" ) == 0 ) { printf( "%s/odbcinst.ini\n", SYSTEM_FILE_PATH ); } else if ( strcmp( argv[ i ], "--ulen" ) == 0 ) { ulen(); } else { usage(); exit( -1 ); } } exit(0); } unixODBC-2.3.12/exe/odbcinst.c000066400000000000000000000514741446441710500157650ustar00rootroot00000000000000/******************************************** * odbcinst - command line tool * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under GPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include char *szSyntax = "\n" \ "**********************************************\n" \ "* unixODBC - odbcinst *\n" \ "**********************************************\n" \ "* *\n" \ "* Purpose: *\n" \ "* *\n" \ "* An ODBC Installer and Uninstaller. *\n" \ "* Updates system files, and *\n" \ "* increases/decreases usage counts but *\n" \ "* does not actually copy or remove any *\n" \ "* files. *\n" \ "* *\n" \ "* Syntax: *\n" \ "* *\n" \ "* odbcinst Action Object Options *\n" \ "* *\n" \ "* Action: *\n" \ "* *\n" \ "* -i install *\n" \ "* -u uninstall *\n" \ "* -q query *\n" \ "* -j print config info *\n" \ "* -c call SQLCreateDataSource *\n" \ "* -m call SQLManageDataSources *\n" \ "* --version version *\n" \ "* *\n" \ "* Object: *\n" \ "* *\n" \ "* -d driver *\n" \ "* -s data source *\n" \ "* *\n" \ "* Options: *\n" \ "* *\n" \ "* -f file name of template.ini follows *\n" \ "* this (valid for -i) *\n" \ "* -r get template.ini from stdin, not *\n" \ "* a template file *\n" \ "* -n Driver or Data Source Name follows *\n" \ "* -v turn verbose off (no info, warning *\n" \ "* or error msgs) *\n" \ "* -l system dsn *\n" \ "* -h user dsn *\n" \ "* *\n" \ "* Returns: *\n" \ "* *\n" \ "* 0 Success *\n" \ "* !0 Failed *\n" \ "* *\n" \ "* Please visit; *\n" \ "* *\n" \ "* http://www.unixodbc.org *\n" \ "* pharvey@codebydesign.com *\n" \ "**********************************************\n\n"; char szError[ODBC_FILENAME_MAX+1]; DWORD nError; char cVerbose; int from_stdin = 0; int system_dsn = 0; int user_dsn = 0; /*! * \brief Invoke UI to Create Data Source wizard. * * This exists so we can test calling SQLCreateDataSource from an * app which does not provide the UI used by SQLCreateDataSource. * * At the moment we have "odbcinstQ4" (the Qt4 based UI) requested * explicitly but this could be changed to simply request the default * or to use a ncurses based UI when that becomes available. * * There are at least 3 ways to invoke SQLCreateDataSource; * * \li ODBCCreateDataSourceQ4 at the command-line * \li a custom application * \li "odbcinst -c [-nMyDsn]" at the command-line * * \sa ManageDataSources */ int CreateDataSource( char *pszDataSourceName ) { ODBCINSTWND odbcinstwnd; odbcinstwnd.hWnd = 0; strcpy( odbcinstwnd.szUI, ODBCINSTPLUGIN ); if ( SQLCreateDataSource( (HWND)&(odbcinstwnd), ( (pszDataSourceName && *pszDataSourceName) ? pszDataSourceName : 0 ) ) == FALSE ) return 1; return 0; } /*! * \brief Invoke UI to Manage Data Sources. * * This exists so we can test calling SQLManageDataSources from an * app which does not provide the UI used by SQLManageDataSources. * * At the moment we have "odbcinstQ4" (the Qt4 based UI) requested * explicitly but this could be changed to simply request the default * or to use a ncurses based UI when that becomes available. * * There are at least 3 ways to invoke SQLManageDataSources; * * \li ODBCManageDataSourcesQ4 at the command-line * \li a custom application * \li "odbcinst -m" at the command-line * * \sa CreateDataSource */ int ManageDataSources() { ODBCINSTWND odbcinstwnd; odbcinstwnd.hWnd = 0; strcpy( odbcinstwnd.szUI, ODBCINSTPLUGIN ); if ( SQLManageDataSources( (HWND)&(odbcinstwnd) ) == FALSE ) return 1; return 0; } int DriverInstall( char *pszTemplate ) { HINI hIni; char szObject[INI_MAX_OBJECT_NAME+1]; char szProperty[INI_MAX_PROPERTY_NAME+1]; char szValue[INI_MAX_PROPERTY_VALUE+1]; char szDriver[10000]; char szPathOut[ODBC_FILENAME_MAX+1]; DWORD nUsageCount = 0; char *pChar = NULL; #ifdef __OS2__ if ( iniOpen( &hIni, pszTemplate, "#;", '[', ']', '=', FALSE, 0L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, pszTemplate, "#;", '[', ']', '=', FALSE ) != INI_SUCCESS ) #endif { if ( cVerbose == 0 ) printf( "odbcinst: iniOpen failed on %s.\n", pszTemplate ); return 1; } memset( szDriver, '\0', 10000 ); pChar = szDriver; iniObjectFirst( hIni ); while ( iniObjectEOL( hIni ) == FALSE ) { iniObject( hIni, szObject ); sprintf( pChar, "%s", szObject ); pChar += ( strlen( szObject ) + 1 ); iniPropertyFirst( hIni ); while ( iniPropertyEOL( hIni ) == FALSE ) { iniProperty( hIni, szProperty ); iniValue( hIni, szValue ); #ifdef HAVE_SNPRINTF snprintf( pChar, 10000 - ( pChar - szDriver ), "%s=%s", szProperty, szValue ); #else sprintf( pChar, "%s=%s", szProperty, szValue ); #endif pChar += ( strlen( szProperty ) + strlen( szValue ) + 2 ); iniPropertyNext( hIni ); } if ( SQLInstallDriverEx( szDriver, NULL, szPathOut, ODBC_FILENAME_MAX, NULL, ODBC_INSTALL_COMPLETE, &nUsageCount ) == FALSE ) { SQLInstallerError( 1, &nError, szError, ODBC_FILENAME_MAX, NULL ); if ( cVerbose == 0 ) printf( "odbcinst: SQLInstallDriverEx failed with %s.\n", szError ); return 1; } if ( cVerbose == 0 ) printf( "odbcinst: Driver installed. Usage count increased to %d. \n Target directory is %s\n", (int)nUsageCount, szPathOut ); memset( szDriver, '\0', 10000 ); pChar = szDriver; iniObjectNext( hIni ); } iniClose( hIni ); return 0; } int DriverUninstall( char *pszDriver ) { DWORD nUsageCount; if ( SQLRemoveDriver( pszDriver, FALSE, &nUsageCount ) == FALSE ) { SQLInstallerError( 1, &nError, szError, ODBC_FILENAME_MAX, NULL ); if ( cVerbose == 0 ) printf( "odbcinst: SQLRemoveDriver failed with %s.\n", szError ); return 1; } if ( nUsageCount == 0 ) { if ( cVerbose == 0 ) printf( "%s has been deleted (if it existed at all) because its usage count became zero\n", pszDriver ); } else { if ( cVerbose == 0 ) printf( "%s usage count has been reduced to %d\n", pszDriver, (int)nUsageCount ); } return 0; } int DriverQuery( char *pszDriver ) { char szResults[4048]; char szValue[501]; char *ptr; if ( pszDriver && (*pszDriver) ) { /* list Driver details */ if ( SQLGetPrivateProfileString( pszDriver, NULL, NULL, szResults, sizeof( szResults ) - 1, "ODBCINST.INI" ) < 1 ) { SQLInstallerError( 1, &nError, szError, ODBC_FILENAME_MAX, NULL ); if ( cVerbose == 0 ) printf( "odbcinst: SQLGetPrivateProfileString failed with %s.\n", szError ); return 1; } printf( "[%s]\n", pszDriver ); ptr = szResults; while ( *ptr ) { printf( "%s=", ptr ); if ( SQLGetPrivateProfileString( pszDriver, ptr, "", szValue, sizeof( szValue ) - 1, "ODBCINST.INI" ) > 0 ) { printf( "%s", szValue ); } printf( "\n" ); ptr += strlen( ptr ) + 1; } } else { /* list Drivers */ if ( SQLGetPrivateProfileString( NULL, NULL, NULL, szResults, sizeof( szResults ) - 1, "ODBCINST.INI" ) < 1 ) { SQLInstallerError( 1, &nError, szError, ODBC_FILENAME_MAX, NULL ); if ( cVerbose == 0 ) printf( "odbcinst: SQLGetPrivateProfileString failed with %s.\n", szError ); return 1; } ptr = szResults; while ( *ptr ) { printf( "[%s]\n", ptr ); ptr += strlen( ptr ) + 1; } } return 0; } int DSNInstall( char *pszTemplate ) { HINI hIni; char szFileName[ODBC_FILENAME_MAX+1]; char szObject[INI_MAX_OBJECT_NAME+1]; char szProperty[INI_MAX_PROPERTY_NAME+1]; char szValue[INI_MAX_PROPERTY_VALUE+1]; #ifdef __OS2__ if ( iniOpen( &hIni, pszTemplate, "#;", '[', ']', '=', FALSE, 0L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, pszTemplate, "#;", '[', ']', '=', FALSE ) != INI_SUCCESS ) #endif { if ( cVerbose == 0 ) printf( "odbcinst: iniOpen failed on %s.\n", pszTemplate ); return 1; } if ( system_dsn ) { SQLSetConfigMode( ODBC_SYSTEM_DSN ); } else if ( user_dsn ) { SQLSetConfigMode( ODBC_USER_DSN ); } strcpy( szFileName, "ODBC.INI" ); iniObjectFirst( hIni ); while ( iniObjectEOL( hIni ) == FALSE ) { iniObject( hIni, szObject ); if ( SQLWritePrivateProfileString( szObject, NULL, NULL, szFileName ) == FALSE ) { int i = 1; int ret; do { ret = SQLInstallerError( i, &nError, szError, ODBC_FILENAME_MAX, NULL ); if ( cVerbose == 0 ) printf( "odbcinst: SQLWritePrivateProfileString failed with %s.\n", szError ); i ++; } while ( ret == SQL_SUCCESS ); iniClose( hIni ); SQLSetConfigMode( ODBC_BOTH_DSN ); return 1; } iniPropertyFirst( hIni ); while ( iniPropertyEOL( hIni ) == FALSE ) { iniProperty( hIni, szProperty ); iniValue( hIni, szValue ); if ( SQLWritePrivateProfileString( szObject, szProperty, szValue, szFileName ) == FALSE ) { SQLInstallerError( 1, &nError, szError, ODBC_FILENAME_MAX, NULL ); if ( cVerbose == 0 ) printf( "odbcinst: SQLWritePrivateProfileString failed with %s.\n", szError ); iniClose( hIni ); SQLSetConfigMode( ODBC_BOTH_DSN ); return 1; } iniPropertyNext( hIni ); } iniObjectNext( hIni ); } iniClose( hIni ); if ( cVerbose == 0 && from_stdin ) printf( "odbcinst: Sections and Entries from stdin have been added to %s\n", szFileName ); else if ( cVerbose ) printf( "odbcinst: Sections and Entries from %s have been added to %s\n", pszTemplate, szFileName ); return 0; } int DSNUninstall( char *pszDSN ) { UWORD nConfigMode; char *pMode; if ( system_dsn ) { SQLSetConfigMode( ODBC_SYSTEM_DSN ); } else if ( user_dsn ) { SQLSetConfigMode( ODBC_USER_DSN ); } if ( SQLGetConfigMode( &nConfigMode ) == FALSE ) { SQLInstallerError( 1, &nError, szError, ODBC_FILENAME_MAX, NULL ); if ( cVerbose == 0 ) printf( "odbcinst: SQLGetConfigMode failed with %s.\n", szError ); return 1; } if ( SQLRemoveDSNFromIni( pszDSN ) == FALSE ) { SQLInstallerError( 1, &nError, szError, ODBC_FILENAME_MAX, NULL ); if ( cVerbose == 0 ) printf( "odbcinst: SQLRemoveDSNFromIni failed with %s.\n", szError ); return 1; } switch ( nConfigMode ) { case ODBC_SYSTEM_DSN: pMode = "ODBC_SYSTEM_DSN"; break; case ODBC_USER_DSN: pMode = "ODBC_USER_DSN"; break; case ODBC_BOTH_DSN: pMode = "ODBC_BOTH_DSN"; break; default: pMode = "Unknown mode"; } if ( cVerbose == 0 ) printf( "odbcinst: DSN removed (if it existed at all). %s was used as the search path.\n", pMode ); return 0; } int DSNQuery( char *pszDSN ) { char szResults[9601]; char szValue[501]; char *ptr; szResults[0] = '\0'; if ( system_dsn ) SQLSetConfigMode( ODBC_SYSTEM_DSN ); else if ( user_dsn ) SQLSetConfigMode( ODBC_USER_DSN ); if ( pszDSN && (*pszDSN) ) { /* list DSN details */ if ( SQLGetPrivateProfileString( pszDSN, NULL, NULL, szResults, sizeof( szResults ) - 1, "ODBC.INI" ) < 1 ) { SQLInstallerError( 1, &nError, szError, ODBC_FILENAME_MAX, NULL ); if ( cVerbose == 0 ) printf( "odbcinst: SQLGetPrivateProfileString failed with %s.\n", szError ); SQLSetConfigMode( ODBC_BOTH_DSN ); return 1; } printf( "[%s]\n", pszDSN ); ptr = szResults; while ( *ptr ) { printf( "%s=", ptr ); if ( SQLGetPrivateProfileString( pszDSN, ptr, "", szValue, sizeof( szValue ) - 1, "ODBC.INI" ) > 0 ) { printf( "%s", szValue ); } printf( "\n" ); ptr += strlen( ptr ) + 1; } } else { /* list DSNs */ if ( SQLGetPrivateProfileString( NULL, NULL, NULL, szResults, sizeof( szResults ) - 1, "ODBC.INI" ) < 1 ) { SQLInstallerError( 1, &nError, szError, ODBC_FILENAME_MAX, NULL ); if ( cVerbose == 0 ) printf( "odbcinst: SQLGetPrivateProfileString failed with %s.\n", szError ); SQLSetConfigMode( ODBC_BOTH_DSN ); return 1; } ptr = szResults; while ( *ptr ) { printf( "[%s]\n", ptr ); ptr += strlen( ptr ) + 1; } } SQLSetConfigMode( ODBC_BOTH_DSN ); return 0; } void Syntax() { if ( cVerbose != 0 ) return; puts( szSyntax ); } void PrintConfigInfo() { char szFileName[ODBC_FILENAME_MAX+1]; char b1[ 256 ], b2[ 256 ]; printf( "unixODBC " VERSION "\n" ); *szFileName = '\0'; sprintf( szFileName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 )); printf( "DRIVERS............: %s\n", szFileName ); *szFileName = '\0'; _odbcinst_SystemINI( szFileName, FALSE ); printf( "SYSTEM DATA SOURCES: %s\n", szFileName ); *szFileName = '\0'; _odbcinst_FileINI( szFileName ); printf( "FILE DATA SOURCES..: %s\n", szFileName ); *szFileName = '\0'; _odbcinst_UserINI( szFileName, FALSE ); printf( "USER DATA SOURCES..: %s\n", szFileName ); printf( "SQLULEN Size.......: %ld\n", (long) sizeof( SQLULEN )); printf( "SQLLEN Size........: %ld\n", (long) sizeof( SQLLEN )); printf( "SQLSETPOSIROW Size.: %ld\n", (long) sizeof( SQLSETPOSIROW )); } int main( int argc, char *argv[] ) { int nArg; char cAction = 0; char cObject = 0; char szTemplateINI[ODBC_FILENAME_MAX+1]; char szObjectName[INI_MAX_OBJECT_NAME+1]; int nReturn = 0; cVerbose = 0; if ( argc < 2 ) { Syntax(); exit ( 1 ); } szTemplateINI[0] = '\0'; szObjectName[0] = '\0'; for ( nArg = 1; nArg < argc; nArg++ ) { if ( argv[nArg][0] == '-' ) { switch ( argv[nArg][1] ) { /* Action */ case 'i': case 'u': case 'q': cAction = argv[nArg][1]; break; case 'j': PrintConfigInfo(); exit(0); case '-': printf( "unixODBC " VERSION "\n" ); exit(0); /* Object */ case 'c': case 'd': case 's': case 'm': cObject = argv[nArg][1]; break; /* Options */ case 'n': if ( nArg < argc-1 ) strncpy( szObjectName, argv[nArg+1], INI_MAX_OBJECT_NAME ); break; case 'f': if ( nArg < argc-1 ) strncpy( szTemplateINI, argv[nArg+1], ODBC_FILENAME_MAX ); break; case 'r': from_stdin = 1; break; case 'v': cVerbose = argv[nArg][1]; break; case 'l': system_dsn = 1; if ( user_dsn ) { if ( cVerbose == 0 ) printf( "odbcinst: cannot install both user and system dsn at the same time"); exit( -2 ); } break; case 'h': user_dsn = 1; if ( system_dsn ) { if ( cVerbose == 0 ) printf( "odbcinst: cannot install both user and system dsn at the same time"); exit( -2 ); } break; default: if ( cVerbose == 0 ) printf( "odbcinst: Unknown option %c\n", argv[nArg][1] ); exit( -1 ); } } } /* DRIVERS */ if ( cObject == 'd' ) { /* install */ if ( cAction == 'i' ) { if ( szTemplateINI[0] != '\0' ) nReturn = DriverInstall( szTemplateINI ); else if ( from_stdin ) nReturn = DriverInstall( STDINFILE ); else { if ( cVerbose == 0 ) printf( "odbcinst: Please supply -f template.ini (The fileformat of template.ini is identical to odbcinst.ini and odbc.ini, respectively)\n" ); Syntax(); exit( 1 ); } } /* uninstall */ else if ( cAction == 'u' ) { if ( szObjectName[0] != '\0' ) nReturn = DriverUninstall( szObjectName ); else { if ( cVerbose == 0 ) printf( "odbcinst: Please supply -n FriendlyDriverName \n" ); Syntax(); exit( 1 ); } } /* query */ else if ( cAction == 'q' ) nReturn = DriverQuery( szObjectName ); else { if ( cVerbose == 0 ) printf( "odbcinst: Invalid Action for Object\n" ); Syntax(); exit( 1 ); } } /* DATA SOURCES */ else if ( cObject == 's' ) { /* install */ if ( cAction == 'i' ) { if ( szTemplateINI[0] != '\0' ) nReturn = DSNInstall( szTemplateINI ); else if ( from_stdin ) nReturn = DSNInstall( STDINFILE ); else { if ( cVerbose == 0 ) printf( "odbcinst: Please supply -f template.ini \n" ); Syntax(); exit( 1 ); } } /* uninstall */ else if ( cAction == 'u' ) { if ( szObjectName[0] != '\0' ) nReturn = DSNUninstall( szObjectName ); else { if ( cVerbose == 0 ) printf( "odbcinst: Please supply -n DataSourceName \n" ); Syntax(); exit( 1 ); } } /* query */ else if ( cAction == 'q' ) nReturn = DSNQuery( szObjectName ); else { if ( cVerbose == 0 ) printf( "odbcinst: Invalid Action for Object\n" ); Syntax(); exit( 1 ); } } else if ( cObject == 'c' ) { nReturn = CreateDataSource( szObjectName ); } else if ( cObject == 'm' ) { nReturn = ManageDataSources(); } else { if ( cVerbose == 0 ) printf( "odbcinst: Invalid Object\n" ); Syntax(); exit( 1 ); } exit( nReturn ); } unixODBC-2.3.12/exe/slencheck.c000066400000000000000000000075131446441710500161120ustar00rootroot00000000000000#include #include #include #include static void show_error( SQLHANDLE henv, SQLHANDLE hdbc, SQLHANDLE hstmt, char *func ) { SQLSMALLINT len; SQLCHAR state[ 7 ]; SQLCHAR msg[ 512 ]; SQLINTEGER native; SQLRETURN ret; SQLSMALLINT rec; fprintf( stderr, "slencheck: error from driver calling %s\n", func ); rec = 0; while( 1 ) { rec ++; if ( hstmt ) { ret = SQLGetDiagRec( SQL_HANDLE_STMT, hstmt, rec, state, &native, msg, sizeof( msg ), &len ); } else if ( hdbc ) { ret = SQLGetDiagRec( SQL_HANDLE_DBC, hdbc, rec, state, &native, msg, sizeof( msg ), &len ); } else { ret = SQLGetDiagRec( SQL_HANDLE_ENV, henv, rec, state, &native, msg, sizeof( msg ), &len ); } if ( SQL_SUCCEEDED( ret )) { fprintf( stderr, "\t[%s]:%d:%s\n", state, (int)native, msg ); } else { break; } } } int main( int argc, char **argv ) { SQLHANDLE henv, hdbc, hstmt; SQLRETURN ret; unsigned char mem[ 8 ]; int size; if ( argc < 2 || argc > 4 ) { fprintf( stderr, "usage: slencheck dsn [uid [pwd]]\n" ); exit( -1 ); } ret = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ); if ( ret != SQL_SUCCESS ) { fprintf( stderr, "slencheck: failed to call SQLAllocHandle(ENV)\n" ); exit( -1 ); } ret = SQLSetEnvAttr( henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_UINTEGER ); if ( ret != SQL_SUCCESS ) { show_error( henv, NULL, NULL, "SQLSetEnvAttr" ); exit( -1 ); } ret = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ); if ( ret != SQL_SUCCESS ) { show_error( henv, NULL, NULL, "SQLAllocHandle" ); exit( -1 ); } if ( argc == 2 ) { ret = SQLConnect( hdbc, (SQLCHAR*) argv[ 1 ], SQL_NTS, NULL, 0, NULL, 0 ); } else if ( argc == 3 ) { ret = SQLConnect( hdbc, (SQLCHAR*) argv[ 1 ], SQL_NTS, (SQLCHAR*) argv[ 2 ], SQL_NTS, NULL, 0 ); } else { ret = SQLConnect( hdbc, (SQLCHAR*) argv[ 1 ], SQL_NTS, (SQLCHAR*) argv[ 2 ], SQL_NTS, (SQLCHAR*) argv[ 3 ], SQL_NTS ); } if ( !SQL_SUCCEEDED( ret )) { show_error( henv, hdbc, NULL, "SQLConnect" ); exit( -1 ); } ret = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt ); if ( !SQL_SUCCEEDED( ret )) { show_error( henv, hdbc, NULL, "SQLAllocHandle" ); exit( -1 ); } ret = SQLTables( hstmt, NULL, 0, NULL, 0, NULL, 0, NULL, 0 ); if ( !SQL_SUCCEEDED( ret )) { show_error( henv, hdbc, hstmt, "SQLTables" ); exit( -1 ); } mem[ 0 ] = 0xde; mem[ 1 ] = 0xad; mem[ 2 ] = 0xbe; mem[ 3 ] = 0xef; mem[ 4 ] = 0xde; mem[ 5 ] = 0xad; mem[ 6 ] = 0xbe; mem[ 7 ] = 0xef; ret = SQLRowCount( hstmt, (SQLLEN*) mem ); if ( !SQL_SUCCEEDED( ret )) { show_error( henv, hdbc, hstmt, "SQLRowCount" ); exit( -1 ); } if ( mem[ 7 ] != 0xef && mem[ 6 ] != 0xbe ) { size = 8; } else if ( mem[ 7 ] == 0xef && mem[ 6 ] == 0xbe && mem[ 3 ] != 0xef && mem[ 2 ] != 0xbe ) { size = 4; } else { size = 0; } if ( size ) { printf( "slencheck: sizeof(SQLLEN) == %d\n", size ); if ( size == sizeof( SQLLEN )) { printf( "slencheck: driver manager and driver matched\n" ); } else { printf( "slencheck: driver manager and driver differ!!!\n" ); } } else { printf( "slencheck: can't decide on sizeof(SQLLEN)\n" ); } ret = SQLCloseCursor( hstmt ); ret = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ); ret = SQLDisconnect( hdbc ); ret = SQLFreeHandle( SQL_HANDLE_DBC, hdbc ); ret = SQLFreeHandle( SQL_HANDLE_ENV, henv ); return size; } unixODBC-2.3.12/extras/000077500000000000000000000000001446441710500145265ustar00rootroot00000000000000unixODBC-2.3.12/extras/Makefile.am000066400000000000000000000003211446441710500165560ustar00rootroot00000000000000noinst_LTLIBRARIES = libodbcextraslc.la AM_CPPFLAGS = -I@top_srcdir@/include EXTRA_DIST = vms.c libodbcextraslc_la_SOURCES = \ strcasecmp.c \ snprintf.c libodbcextraslc_la_LDFLAGS = -no-undefined unixODBC-2.3.12/extras/snprintf.c000066400000000000000000000421701446441710500165410ustar00rootroot00000000000000/* * Copyright Patrick Powell 1995 * This code is based on code written by Patrick Powell (papowell@astart.com) * It may be used for any purpose as long as this notice remains intact * on all source code distributions */ /************************************************************** * Original: * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 * A bombproof version of doprnt (dopr) included. * Sigh. This sort of thing is always nasty do deal with. Note that * the version here does not include floating point... * * snprintf() is used instead of sprintf() as it does limit checks * for string length. This covers a nasty loophole. * * The other functions are there to prevent NULL pointers from * causing nast effects. * * More Recently: * Brandon Long 9/15/96 for mutt 0.43 * This was ugly. It is still ugly. I opted out of floating point * numbers, but the formatter understands just about everything * from the normal C string format, at least as far as I can tell from * the Solaris 2.5 printf(3S) man page. * * Brandon Long 10/22/97 for mutt 0.87.1 * Ok, added some minimal floating point support, which means this * probably requires libm on most operating systems. Don't yet * support the exponent (e,E) and sigfig (g,G). Also, fmtint() * was pretty badly broken, it just wasn't being exercised in ways * which showed it, so that's been fixed. Also, formated the code * to mutt conventions, and removed dead code left over from the * original. Also, there is now a builtin-test, just compile with: * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm * and run snprintf for results. * * Thomas Roessler 01/27/98 for mutt 0.89i * The PGP code was using unsigned hexadecimal formats. * Unfortunately, unsigned formats simply didn't work. * * Michael Elkins 03/05/98 for mutt 0.90.8 * The original code assumed that both snprintf() and vsnprintf() were * missing. Some systems only have snprintf() but not vsnprintf(), so * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. * * Andrew Tridgell (tridge@samba.org) Oct 1998 * fixed handling of %.0f * added test for HAVE_LONG_DOUBLE * * Eric Sharkey Dec 2003 * fixed handling of floating point numbers less than 0.1 * * Eric Sharkey Mar 2005 * fixed return value to conform to C99 standard * **************************************************************/ /* XXX Hmm... Perhaps autoconf this up again? */ #include #define HAVE_LONG_DOUBLE #ifdef HAVE_STDDEF_H #include #endif #include #include #ifdef HAVE_SYS_TYPES_H #include #endif #include "uodbc_extras.h" /* varargs declarations: */ #if defined(HAVE_STDARG_H) # include # define VA_LOCAL_DECL va_list ap # define VA_START(f) va_start(ap, f) # define VA_SHIFT(v,t) ; /* no-op for ANSI */ # define VA_END va_end(ap) #else # if defined(HAVE_VARARGS_H) # define VA_LOCAL_DECL va_list ap # define VA_START(f) va_start(ap) /* f is ignored! */ # define VA_SHIFT(v,t) v = va_arg(ap,t) # define VA_END va_end(ap) # else /*XX ** NO VARARGS ** XX*/ # error No variable argument support # endif #endif #ifdef HAVE_LONG_DOUBLE #define LDOUBLE long double #else #define LDOUBLE double #endif /*int snprintf (char *str, size_t count, const char *fmt, ...);*/ /*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args); static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max); static void fmtint (char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags); static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags); static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); /* * dopr(): poor man's version of doprintf */ /* format read states */ #define DP_S_DEFAULT 0 #define DP_S_FLAGS 1 #define DP_S_MIN 2 #define DP_S_DOT 3 #define DP_S_MAX 4 #define DP_S_MOD 5 #define DP_S_CONV 6 #define DP_S_DONE 7 /* format flags - Bits */ #define DP_F_MINUS (1 << 0) #define DP_F_PLUS (1 << 1) #define DP_F_SPACE (1 << 2) #define DP_F_NUM (1 << 3) #define DP_F_ZERO (1 << 4) #define DP_F_UP (1 << 5) #define DP_F_UNSIGNED (1 << 6) /* Conversion Flags */ #define DP_C_SHORT 1 #define DP_C_LONG 2 #define DP_C_LDOUBLE 3 #define char_to_int(p) (p - '0') #define MAX(p,q) ((p >= q) ? p : q) static int dopr (char *buffer, size_t maxlen, const char *format, va_list args) { char ch; long value; LDOUBLE fvalue; char *strvalue; int min; int max; int state; int flags; int cflags; size_t currlen; state = DP_S_DEFAULT; currlen = flags = cflags = min = 0; max = -1; ch = *format++; while (state != DP_S_DONE) { if ((ch == '\0') || (currlen >= maxlen)) state = DP_S_DONE; switch(state) { case DP_S_DEFAULT: if (ch == '%') state = DP_S_FLAGS; else dopr_outch (buffer, &currlen, maxlen, ch); ch = *format++; break; case DP_S_FLAGS: switch (ch) { case '-': flags |= DP_F_MINUS; ch = *format++; break; case '+': flags |= DP_F_PLUS; ch = *format++; break; case ' ': flags |= DP_F_SPACE; ch = *format++; break; case '#': flags |= DP_F_NUM; ch = *format++; break; case '0': flags |= DP_F_ZERO; ch = *format++; break; default: state = DP_S_MIN; break; } break; case DP_S_MIN: if (isdigit((unsigned char)ch)) { min = 10*min + char_to_int (ch); ch = *format++; } else if (ch == '*') { min = va_arg (args, int); ch = *format++; state = DP_S_DOT; } else state = DP_S_DOT; break; case DP_S_DOT: if (ch == '.') { state = DP_S_MAX; ch = *format++; } else state = DP_S_MOD; break; case DP_S_MAX: if (isdigit((unsigned char)ch)) { if (max < 0) max = 0; max = 10*max + char_to_int (ch); ch = *format++; } else if (ch == '*') { max = va_arg (args, int); ch = *format++; state = DP_S_MOD; } else state = DP_S_MOD; break; case DP_S_MOD: /* Currently, we don't support Long Long, bummer */ switch (ch) { case 'h': cflags = DP_C_SHORT; ch = *format++; break; case 'l': cflags = DP_C_LONG; ch = *format++; break; case 'L': cflags = DP_C_LDOUBLE; ch = *format++; break; default: break; } state = DP_S_CONV; break; case DP_S_CONV: switch (ch) { case 'd': case 'i': if (cflags == DP_C_SHORT) /* value = va_arg (args, short int); */ value = va_arg (args, int); else if (cflags == DP_C_LONG) value = va_arg (args, long int); else value = va_arg (args, int); fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); break; case 'o': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) /* value = va_arg (args, unsigned short int); */ value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) value = (long)va_arg (args, unsigned long int); else value = (long)va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); break; case 'u': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) /* value = va_arg (args, unsigned short int); */ value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) value = (long)va_arg (args, unsigned long int); else value = (long)va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); break; case 'X': flags |= DP_F_UP; case 'x': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) /* value = va_arg (args, unsigned short int); */ value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) value = (long)va_arg (args, unsigned long int); else value = (long)va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); break; case 'f': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); /* um, floating point? */ fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); break; case 'E': flags |= DP_F_UP; case 'e': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); break; case 'G': flags |= DP_F_UP; case 'g': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); break; case 'c': dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); break; case 's': strvalue = va_arg (args, char *); if (max < 0) max = maxlen; /* ie, no max */ fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); break; case 'p': strvalue = (char*) va_arg (args, void *); #ifdef HAVE_PTRDIFF_T fmtint (buffer, &currlen, maxlen, (ptrdiff_t) strvalue, 16, min, max, flags); #else fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); #endif break; case 'n': if (cflags == DP_C_SHORT) { short int *num; num = va_arg (args, short int *); *num = currlen; } else if (cflags == DP_C_LONG) { long int *num; num = va_arg (args, long int *); *num = (long int)currlen; } else { int *num; num = va_arg (args, int *); *num = currlen; } break; case '%': dopr_outch (buffer, &currlen, maxlen, ch); break; case 'w': /* not supported yet, treat as next char */ ch = *format++; break; default: /* Unknown, skip */ break; } ch = *format++; state = DP_S_DEFAULT; flags = cflags = min = 0; max = -1; break; case DP_S_DONE: break; default: /* hmm? */ break; /* some picky compilers need this */ } } if (currlen < maxlen - 1) buffer[currlen] = '\0'; else buffer[maxlen - 1] = '\0'; return currlen; } static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max) { int padlen, strln; /* amount to pad */ int cnt = 0; if (value == 0) { value = ""; } for (strln = 0; value[strln]; ++strln); /* strlen */ padlen = min - strln; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justify */ while ((padlen > 0) && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, ' '); --padlen; ++cnt; } while (*value && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, *value++); ++cnt; } while ((padlen < 0) && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, ' '); ++padlen; ++cnt; } } /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ static void fmtint (char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags) { int signvalue = 0; unsigned long uvalue; char convert[20]; int place = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ int caps = 0; if (max < 0) max = 0; uvalue = value; if(!(flags & DP_F_UNSIGNED)) { if( value < 0 ) { signvalue = '-'; uvalue = -value; } else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ signvalue = '+'; else if (flags & DP_F_SPACE) signvalue = ' '; } if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ do { convert[place++] = (caps? "0123456789ABCDEF":"0123456789abcdef") [uvalue % (unsigned)base ]; uvalue = (uvalue / (unsigned)base ); } while(uvalue && (place < 20)); if (place == 20) place--; convert[place] = 0; zpadlen = max - place; spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ #ifdef DEBUG_SNPRINTF printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", zpadlen, spadlen, min, max, place); #endif /* Spaces */ while (spadlen > 0) { dopr_outch (buffer, currlen, maxlen, ' '); --spadlen; } /* Sign */ if (signvalue) dopr_outch (buffer, currlen, maxlen, signvalue); /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --zpadlen; } } /* Digits */ while (place > 0) dopr_outch (buffer, currlen, maxlen, convert[--place]); /* Left Justified spaces */ while (spadlen < 0) { dopr_outch (buffer, currlen, maxlen, ' '); ++spadlen; } } static LDOUBLE abs_val (LDOUBLE value) { LDOUBLE result = value; if (value < 0) result = -value; return result; } static LDOUBLE local_pow10 (int exponent) { LDOUBLE result = 1; while (exponent) { result *= 10; exponent--; } return result; } static long int_round (LDOUBLE value) { long intpart; intpart = (long)value; value = value - intpart; if (value >= 0.5) intpart++; return intpart; } static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags) { int signvalue = 0; LDOUBLE ufvalue; char iconvert[20]; char fconvert[20]; int iplace = 0; int fplace = 0; int padlen = 0; /* amount to pad */ int zpadlen = 0; int caps = 0; long intpart; long fracpart; /* * AIX manpage says the default is 0, but Solaris says the default * is 6, and sprintf on AIX defaults to 6 */ if (max < 0) max = 6; ufvalue = abs_val (fvalue); if (fvalue < 0) signvalue = '-'; else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ signvalue = '+'; else if (flags & DP_F_SPACE) signvalue = ' '; #if 0 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ #endif intpart = (long)ufvalue; /* * Sorry, we only support 9 digits past the decimal because of our * conversion method */ if (max > 9) max = 9; /* We "cheat" by converting the fractional part to integer by * multiplying by a factor of 10 */ fracpart = int_round ((local_pow10 (max)) * (ufvalue - intpart)); if (fracpart >= local_pow10 (max)) { intpart++; fracpart -= local_pow10 (max); } #ifdef DEBUG_SNPRINTF printf("fmtfp: %g %d.%d min=%d max=%d\n", (double)fvalue, intpart, fracpart, min, max); #endif /* Convert integer part */ do { iconvert[iplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; intpart = (intpart / 10); } while(intpart && (iplace < 20)); if (iplace == 20) iplace--; iconvert[iplace] = 0; /* Convert fractional part */ do { fconvert[fplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; fracpart = (fracpart / 10); } while(fplace < max); if (fplace == 20) fplace--; fconvert[fplace] = 0; /* -1 for decimal point, another -1 if we are printing a sign */ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); zpadlen = max - fplace; if (zpadlen < 0) zpadlen = 0; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justifty */ if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { dopr_outch (buffer, currlen, maxlen, signvalue); --padlen; signvalue = 0; } while (padlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --padlen; } } while (padlen > 0) { dopr_outch (buffer, currlen, maxlen, ' '); --padlen; } if (signvalue) dopr_outch (buffer, currlen, maxlen, signvalue); while (iplace > 0) dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); #ifdef DEBUG_SNPRINTF printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); #endif /* * Decimal point. This should probably use locale to find the correct * char to print out. */ if (max > 0) { dopr_outch (buffer, currlen, maxlen, '.'); while (fplace > 0) dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); } while (zpadlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --zpadlen; } while (padlen < 0) { dopr_outch (buffer, currlen, maxlen, ' '); ++padlen; } } static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) { if (*currlen < maxlen) buffer[(*currlen)] = c; (*currlen)++; } int uodbc_vsnprintf (char *str, size_t count, const char *fmt, va_list args) { int l; str[0] = 0; l=dopr(str, count, fmt, args); return l; } #ifdef HAVE_STDARGS int uodbc_snprintf (char *str,size_t count,const char *fmt,...) #else int uodbc_snprintf (va_alist) va_dcl #endif { int l; #ifndef HAVE_STDARGS char *str; size_t count; char *fmt; #endif VA_LOCAL_DECL; VA_START (fmt); VA_SHIFT (str, char *); VA_SHIFT (count, size_t ); VA_SHIFT (fmt, char *); l=uodbc_vsnprintf(str, count, fmt, ap); VA_END; return l; } unixODBC-2.3.12/extras/strcasecmp.c000066400000000000000000000020201446441710500170300ustar00rootroot00000000000000#include #include #include #ifndef HAVE_STRCASECMP int strcasecmp( const char *s1, const char * s2 ) { const unsigned char *p1 = (const unsigned char *) s1; const unsigned char *p2 = (const unsigned char *) s2; unsigned char c1, c2; if (p1 == p2) return 0; do { c1 = tolower(*p1++); c2 = tolower(*p2++); if (c1 == '\0') break; } while (c1 == c2); return c1 - c2; } #endif #ifndef HAVE_STRNCASECMP int strncasecmp (const char *s1, const char *s2, int n ) { const unsigned char *p1 = (const unsigned char *) s1; const unsigned char *p2 = (const unsigned char *) s2; unsigned char c1, c2; if (p1 == p2) return 0; do { c1 = tolower(*p1++); c2 = tolower(*p2++); if (c1 == '\0') break; n --; } while (c1 == c2 && n > 0 ); if ( n == 0 ) return 0; return c1 - c2; } #endif void ___extra_func_to_mollify_linker( void ) { } unixODBC-2.3.12/extras/vms.c000066400000000000000000000267131446441710500155100ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int error_status = SS$_NORMAL; static char error_buffer[256]; static char getenv_buffer[256]; typedef struct { struct dsc$descriptor_s fnmdes; struct dsc$descriptor_s imgdes; struct dsc$descriptor_s symdes; char filename[NAM$C_MAXRSS]; } vms_dl; int vms_dlsym (vms_dl *, void **, int); void * lt_dlsym (void *, const char *); int lt_dlinit (void) { return 0; } char translate_buffer[NAM$C_MAXRSS+1]; int to_vms_callback(char *name, int type) { strcpy(translate_buffer, name); return 1; } void * lt_dlopen (const char *filename) { /* * Locates and validates a shareable image. If the caller supplies a * path as part of the image name, that's where we look. Note that this * includes cases where the image name is a logical name pointing to a full * file spec including path. If there is no path, we look at wherever the * logical name LTDL_LIBRARY_PATH points (if it exists); it'd normally be a * search list logical defined in lt_dladdsearchdir, so it could point to a * number of places. As a last resort we look in SYS$SHARE. */ vms_dl *dh; int status; struct FAB imgfab; struct NAM imgnam; char defimg[NAM$C_MAXRSS+1]; char *defpath; char local_fspec[NAM$C_MAXRSS+1]; if (filename == NULL) { error_status = SS$_UNSUPPORTED; return NULL; } strcpy(local_fspec, filename); /* * The driver manager will handle a hard-coded path from a .ini file, but * only if it's an absolute path in unix syntax. To make those acceptable * to lib$find_image_symbol, we have to convert to VMS syntax. N.B. Because * of the static buffer, this is not thread-safe, but copying immediately to * local storage should limit the damage. */ if (filename[0] == '/') { int num_translated = decc$to_vms(local_fspec, to_vms_callback, 0, 1); if (num_translated == 1) strcpy(local_fspec, translate_buffer); } dh = (vms_dl *)malloc (sizeof (vms_dl)); memset( dh, 0, sizeof(vms_dl) ); if (dh == NULL) { error_status = SS$_INSFMEM; return NULL; } imgfab = cc$rms_fab; imgfab.fab$l_fna = local_fspec; imgfab.fab$b_fns = (int) strlen (local_fspec); imgfab.fab$w_ifi = 0; /* If the logical name LTDL_LIBRARY_PATH does not exist, we'll depend * on the image name being a logical name or on the image residing in * SYS$SHARE. */ if ( getvmsenv("LTDL_LIBRARY_PATH") == NULL ) { strcpy( defimg, ".EXE" ); } else { strcpy( defimg, "LTDL_LIBRARY_PATH:.EXE" ); } imgfab.fab$l_dna = defimg; imgfab.fab$b_dns = strlen(defimg); imgfab.fab$l_fop = FAB$M_NAM; imgfab.fab$l_nam = &imgnam; imgnam = cc$rms_nam; imgnam.nam$l_esa = dh->filename; imgnam.nam$b_ess = NAM$C_MAXRSS; status = sys$parse (&imgfab); if (!($VMS_STATUS_SUCCESS(status))) { /* No luck with LTDL_LIBRARY_PATH; try SYS$SHARE */ strcpy( defimg, "SYS$SHARE:.EXE" ); imgfab.fab$b_dns = strlen(defimg); status = sys$parse (&imgfab); if (!($VMS_STATUS_SUCCESS(status))) { error_status = status; return NULL; } } dh->fnmdes.dsc$b_dtype = DSC$K_DTYPE_T; dh->fnmdes.dsc$b_class = DSC$K_CLASS_S; dh->fnmdes.dsc$a_pointer = imgnam.nam$l_name; dh->fnmdes.dsc$w_length = imgnam.nam$b_name; dh->imgdes.dsc$b_dtype = DSC$K_DTYPE_T; dh->imgdes.dsc$b_class = DSC$K_CLASS_S; dh->imgdes.dsc$a_pointer = dh->filename; dh->imgdes.dsc$w_length = imgnam.nam$b_esl; /* ** Attempt to load a symbol at this stage to ** validate that the shared file can be loaded */ lt_dlsym (dh, "Fake_Symbol_Name"); if (!((error_status ^ LIB$_KEYNOTFOU) & ~7)) error_status = SS$_NORMAL; if (!($VMS_STATUS_SUCCESS(error_status))) { free (dh); return NULL; } return dh; } int lt_dlclose (void *handle) { free (handle); return 0; } void * lt_dlsym (void *handle, const char *name) { vms_dl *dh; void *ptr; int status, flags; dh = (vms_dl *)handle; if (!dh) return NULL; dh->symdes.dsc$b_dtype = DSC$K_DTYPE_T; dh->symdes.dsc$b_class = DSC$K_CLASS_S; dh->symdes.dsc$a_pointer = (char *) name; dh->symdes.dsc$w_length = strlen (name); /* firstly attempt with flags set to 0 case insensitive */ flags = 0; status = vms_dlsym (dh, &ptr, flags); if (!($VMS_STATUS_SUCCESS(status))) { /* ** Try again with mixed case flag set */ flags = LIB$M_FIS_MIXEDCASE; status = vms_dlsym (dh, &ptr, flags); if (!($VMS_STATUS_SUCCESS(status))) { error_status = status; return NULL; } } return ptr; } int vms_dlsym ( vms_dl *dh, void **ptr, int flags) { LIB$ESTABLISH (LIB$SIG_TO_RET); return LIB$FIND_IMAGE_SYMBOL (&dh->fnmdes, &dh->symdes, ptr, &dh->imgdes, flags); } const char *lt_dlerror (void) { struct dsc$descriptor desc; short outlen; int status; if (($VMS_STATUS_SUCCESS(error_status))) return NULL; desc.dsc$b_dtype = DSC$K_DTYPE_T; desc.dsc$b_class = DSC$K_CLASS_S; desc.dsc$a_pointer = error_buffer; desc.dsc$w_length = sizeof (error_buffer); status = sys$getmsg (error_status, &outlen, &desc, 15, 0); if ($VMS_STATUS_SUCCESS(status)) error_buffer[outlen] = '\0'; else sprintf (error_buffer, "OpenVMS exit status %8X", error_status); error_status = SS$_NORMAL; return (error_buffer); } struct itemlist3 { unsigned short buflen; unsigned short item; void *buf; unsigned short *retlen; }; int lt_dladdsearchdir (const char *search_dir) { /* * Adds a path to the list of paths where lt_dlopen will look for shareable images. * We do this via a user-mode search list logical, adding one more item to the end of * the list whenever called. */ $DESCRIPTOR(lib_path_d, "LTDL_LIBRARY_PATH"); $DESCRIPTOR( proc_table_d, "LNM$PROCESS_TABLE" ); unsigned int status = 0; unsigned char accmode = 0, lnm_exists = 1; int index = 0, max_index = 0; struct itemlist3 trnlnmlst[4] = {{sizeof(accmode), LNM$_ACMODE, &accmode, 0}, {sizeof(max_index), LNM$_MAX_INDEX, &max_index, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; struct itemlist3 *crelnmlst; struct eqvarray { char eqvname[256]; }; struct eqvarray *eqvlist; /* First just check to see whether the logical name exists and how many equivalence * names there are. */ status = SYS$TRNLNM ( NULL, &proc_table_d, &lib_path_d, NULL, trnlnmlst); /* If the logical name doesn't exist or exists at a privilege mode or table I * can't even look at, then I'll want to proceed with creating my user-mode logical. */ if ( status == SS$_NOLOGNAM || status == SS$_NOPRIV ) { status = SS$_NORMAL; lnm_exists = 0; /* skip further translation attempts */ max_index = 0; } if (!$VMS_STATUS_SUCCESS(status)) { error_status = status; return -1; } /* Also skip further translation if the first translation exists in any mode other * than user mode; we want to stick user mode logicals in front of these. */ if ( accmode != PSL$C_USER ) { lnm_exists = 0; max_index = 0; } /* Allocate an item list for logical name creation and an array of equivalence * name buffers. */ crelnmlst = (struct itemlist3 *) malloc( sizeof(struct itemlist3) * (max_index + 3) ); if (crelnmlst == NULL) { error_status = SS$_INSFMEM; return -1; } eqvlist = (struct eqvarray *) malloc( sizeof(struct eqvarray) * (max_index + 2) ); if (eqvlist == NULL) { error_status = SS$_INSFMEM; return -1; } trnlnmlst[1].buflen = sizeof(index); trnlnmlst[1].item = LNM$_INDEX; trnlnmlst[1].buf = &index; trnlnmlst[1].retlen = NULL; trnlnmlst[2].buflen = sizeof(eqvlist[0].eqvname); trnlnmlst[2].item = LNM$_STRING; /* The loops iterates over the search list index, getting the translation * for each index and storing it in the item list for re-creation. */ for (index = 0; index <= max_index && lnm_exists; index++ ) { /* Wire the input buffer for translation to the output buffer for creation */ trnlnmlst[2].buf = &eqvlist[index].eqvname; crelnmlst[index].buf = &eqvlist[index].eqvname; trnlnmlst[2].retlen = &crelnmlst[index].buflen; status = SYS$TRNLNM ( NULL, &proc_table_d, &lib_path_d, NULL, trnlnmlst); if (!$VMS_STATUS_SUCCESS(status)) { error_status = status; free(crelnmlst); free(eqvlist); return -1; } /* If we come across a non-user-mode translation, back up and get out * because we don't want to recreate those in user mode. */ if ( accmode != PSL$C_USER ) { index--; break; } crelnmlst[index].item = LNM$_STRING; crelnmlst[index].retlen = NULL; } /* At this point we have captured all the existing translations (if * any) and stored them in the item list for re-creation of the logical * name. All that's left is to add the new item to the end of the list * and terminate the list. */ crelnmlst[index].buflen = strlen(search_dir); crelnmlst[index].item = LNM$_STRING; crelnmlst[index].buf = (char *) search_dir; crelnmlst[index].retlen = NULL; crelnmlst[index+1].buflen = 0; crelnmlst[index+1].item = 0; crelnmlst[index+1].buf = NULL; crelnmlst[index+1].retlen = NULL; accmode = PSL$C_USER; status = SYS$CRELNM( NULL, &proc_table_d, &lib_path_d, &accmode, crelnmlst ); if (!$VMS_STATUS_SUCCESS(status)) { error_status = status; free(crelnmlst); free(eqvlist); return -1; } free(crelnmlst); free(eqvlist); error_status = SS$_NORMAL; return 0; } char * getvmsenv (char *symbol) { int status; unsigned short cbvalue; $DESCRIPTOR (logicalnametable, "LNM$FILE_DEV"); struct dsc$descriptor_s logicalname; struct itemlist3 itemlist[2]; logicalname.dsc$w_length = strlen (symbol); logicalname.dsc$b_dtype = DSC$K_DTYPE_T; logicalname.dsc$b_class = DSC$K_CLASS_S; logicalname.dsc$a_pointer = symbol; itemlist[0].buflen = sizeof (getenv_buffer) -1; itemlist[0].item = LNM$_STRING; itemlist[0].buf = getenv_buffer; itemlist[0].retlen = &cbvalue; itemlist[1].buflen = 0; itemlist[1].item = 0; itemlist[1].buf = 0; itemlist[1].retlen = 0; status = SYS$TRNLNM (0, &logicalnametable, &logicalname, 0, itemlist); if (!($VMS_STATUS_SUCCESS(status))) return NULL; if (cbvalue > 0) { getenv_buffer[cbvalue] = '\0'; return getenv_buffer; } return NULL; } unixODBC-2.3.12/include/000077500000000000000000000000001446441710500146435ustar00rootroot00000000000000unixODBC-2.3.12/include/Makefile.am000066400000000000000000000005741446441710500167050ustar00rootroot00000000000000EXTRA_DIST = \ ini.h \ log.h \ lst.h \ odbcinst.h \ odbcinstext.h \ sql.h \ sqlext.h \ sqltypes.h \ sqlucode.h \ sqlspi.h \ sqp.h \ uodbc_stats.h \ uodbc_extras.h \ autotest.h \ odbctrace.h \ odbctrac.h include_HEADERS = \ odbcinst.h \ odbcinstext.h \ sql.h \ sqlext.h \ sqltypes.h \ sqlucode.h \ sqlspi.h \ autotest.h \ uodbc_stats.h \ uodbc_extras.h unixODBC-2.3.12/include/autotest.h000066400000000000000000000140661446441710500166730ustar00rootroot00000000000000/*! * \file * * This file contains constants and prototypes required to compile an * Auto Test library/plugin. This is used by the unixODBC-Test and * unixODBC-GUI-Qt projects. * * \note * * The contents of this file must be consistent with MS version so as to * maintain source code portability. This should allow (for example) * Auto Tests to be compiled for all platforms without source changes. * */ #ifndef AUTOTEST_H #define AUTOTEST_H /* standard C stuff... */ #include #include /* platform specific... */ #ifdef _WINDOWS #include #endif /* standard ODBC stuff... */ #include #include #include #ifdef __cplusplus extern "C" { #endif #ifndef WIN32 #ifdef PATH_MAX #define _MAX_PATH PATH_MAX #else #define _MAX_PATH 256 #endif #endif extern HINSTANCE hLoadedInst; /*---------------------------------------------------------------------------------- Defines and Macros ----------------------------------------------------------------------------------*/ #define TEST_ABORTED (-1) #define AUTO_MAX_TEST_NAME 35 #define AUTO_MAX_TESTCASE_NAME 35 #define AUTO_MAX_TESTDESC_NAME 75 #define MAXFLUSH 300 #define MAX_USER_INFO 50 #define MAX_KEYWORD_LEN 149 /* */ #ifdef WIN32 #define EXTFUNCDECL _stdcall #define EXTFUN _stdcall #define MY_EXPORT __declspec(dllexport) #else #define EXTFUNCDECL #define EXTFUN #define MY_EXPORT #endif #define InitTest(lps) \ { lps->cErrors=0; } #define AbortTest(lps) \ { lps->cErrors=TEST_ABORTED; } #define AllocateMemory(cb) (calloc(cb,1)) #define ReleaseMemory(lp) (free(lp)) #define NumItems(s) (sizeof(s) / sizeof(s[0])) /* Following will access bit number pos in a bit array and return */ /* TRUE if it is set, FALSE if it is not */ #define CQBITS (sizeof(unsigned int) * 8) #define getqbit(lpa, pos) \ (lpa[((pos) / CQBITS)] & (1 << ((pos) - (CQBITS * ((pos) / CQBITS))))) #define GETBIT(p1,p2) getqbit(p1,(p2)-1) /* * Message box defines */ #ifndef WIN32 #define MB_OK (0x0000) #define MB_ABORTRETRYIGNORE (0x0001) #define MB_OKCANCEL (0x0002) #define MB_RETRYCANCEL (0x0003) #define MB_YESNO (0x0004) #define MB_YESNOCANCEL (0x0005) #define MB_ICONEXCLAMATION (0x0000) #define MB_ICONWARNING MB_ICONEXCLAMATION #define MB_ICONINFORMATION (0x0010) #define MB_ICONASTERISK MB_ICONINFORMATION #define MB_ICONQUESTION (0x0020) #define MB_ICONSTOP (0x0030) #define MB_ICONERROR MB_ICONSTOP #define MB_ICONHAND MB_ICONSTOP #define MB_DEFBUTTON1 (0x0000) #define MB_DEFBUTTON2 (0x0100) #define MB_DEFBUTTON3 (0x0200) #define MB_DEFBUTTON4 (0x0300) #define MB_APPMODAL (0x0000) #define MB_SYSTEMMODAL (0x1000) #define MB_TASKMODAL (0x2000) #define MB_DEFAULT_DESKTOP_ONLY (0x0000) #define MB_HELP (0x0000) #define MB_RIGHT (0x0000) #define MB_RTLREADING (0x0000) #define MB_SETFOREGROUND (0x0000) #define MB_TOPMOST (0x0000) #define MB_SERVICE_NOTIFICATION (0x0000) #define MB_SERVICE_NOTIFICATION_NT3X (0x0000) #endif /*! This structure contains the information found in the .INI file for a data source. The filled out structure is in turn passed to AutoTestFunc to drive the individual tests. */ typedef struct tagSERVERINFO { HWND hwnd; /* Output edit window */ CHAR szLogFile[_MAX_PATH]; /* Output log file */ HENV henv; /* .EXE's henv */ HDBC hdbc; /* .EXE's hdbc */ HSTMT hstmt; /* .EXE's hstmt */ /* The following items are gathered from the .INI file and may be defined */ /* via the "Manage Test Sources" menu item from ODBC Test */ CHAR szSource[SQL_MAX_DSN_LENGTH+1]; CHAR szValidServer0[SQL_MAX_DSN_LENGTH+1]; CHAR szValidLogin0[MAX_USER_INFO+1]; CHAR szValidPassword0[MAX_USER_INFO+1]; CHAR szKeywords[MAX_KEYWORD_LEN+1]; /* Following are used for run-time */ UINT FAR * rglMask; /* Run test mask */ int failed; /* Track failures on a test case basis */ int cErrors; /* Count of errors */ BOOL fDebug; /* TRUE if debugging is to be enabled */ BOOL fScreen; /* TRUE if test output goes to screen */ BOOL fLog; /* TRUE if test output goes to log */ BOOL fIsolate; /* TRUE to isolate output */ UDWORD vCursorLib; /* Value for SQL_ODBC_CURSOR on SQLSetConnectOption */ HINSTANCE hLoadedInst; /* Instance handle of loaded test */ /* Following are used for buffering output to edit window */ CHAR szBuff[MAXFLUSH]; /* Hold temporary results */ UINT cBuff; /* Number of TCHARs in szBuff */ } SERVERINFO; typedef SERVERINFO FAR * lpSERVERINFO; BOOL EXTFUNCDECL FAR szLogPrintf(lpSERVERINFO lps, BOOL fForce, LPTSTR szFmt, ...); int EXTFUNCDECL FAR szMessageBox(HWND hwnd, UINT style, LPTSTR szTitle, LPTSTR szFmt, ...); LPTSTR EXTFUN GetRCString(HINSTANCE hInst, LPTSTR buf, int cbbuf, UINT ids); #ifdef __cplusplus } #endif #endif unixODBC-2.3.12/include/ini.h000066400000000000000000000331671446441710500156050ustar00rootroot00000000000000/********************************************************************************** * ini.h * * Include file for libini.a. Coding? Include this and link against libini.a. * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #ifndef INCLUDED_INI_H #define INCLUDED_INI_H /*********[ CONSTANTS AND TYPES ]**************************************************/ #include #include #include #include #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define STDINFILE ((char*)-1) #define INI_NO_DATA 2 #define INI_SUCCESS 1 #define INI_ERROR 0 #define INI_MAX_LINE 1000 #define INI_MAX_OBJECT_NAME INI_MAX_LINE #define INI_MAX_PROPERTY_NAME INI_MAX_LINE #define INI_MAX_PROPERTY_VALUE INI_MAX_LINE #if HAVE_LIMITS_H #include #endif #ifdef PATH_MAX #define ODBC_FILENAME_MAX PATH_MAX #elif MAXPATHLEN #define ODBC_FILENAME_MAX MAXPATHLEN #else #define ODBC_FILENAME_MAX FILENAME_MAX #endif /******************************************** * tINIPROPERTY * * Each property line has Name=Value pair. * They are stored in this structure and linked together to provide a list * of all properties for a given Object. ********************************************/ typedef struct tINIPROPERTY { struct tINIPROPERTY *pNext; struct tINIPROPERTY *pPrev; char szName[INI_MAX_PROPERTY_NAME+1]; char szValue[INI_MAX_PROPERTY_VALUE+1]; } INIPROPERTY, *HINIPROPERTY; /******************************************** * tINIOBJECT * * Each object line has just an object name. This structure * stores the object name and its subordinate information. * The lines that follow are considered to be properties * and are stored in a list of tINIPROPERTY. ********************************************/ typedef struct tINIOBJECT { struct tINIOBJECT *pNext; struct tINIOBJECT *pPrev; char szName[INI_MAX_OBJECT_NAME+1]; HINIPROPERTY hFirstProperty; HINIPROPERTY hLastProperty; int nProperties; } INIOBJECT, *HINIOBJECT; /******************************************** * tINI * * Each INI file contains a list of objects. This * structure stores each object in a list of tINIOBJECT. ********************************************/ typedef struct tINI { #ifdef __OS2__ int iniFileType; /* ini file type 0 = text, 1 = binary (OS/2 only) */ #endif char szFileName[ODBC_FILENAME_MAX+1]; /* FULL INI FILE NAME */ char cComment[ 5 ]; /* COMMENT CHAR MUST BE IN FIRST COLUMN */ char cLeftBracket; /* BRACKETS DELIMIT THE OBJECT NAME, THE LEFT BRACKET MUST BE IN COLUMN ONE */ char cRightBracket; char cEqual; /* SEPERATES THE PROPERTY NAME FROM ITS VALUE */ int bChanged; /* IF true, THEN THE WHOLE FILE IS OVERWRITTEN UPON iniCommit */ int bReadOnly; /* TRUE IF AT LEAST ONE CALL HAS BEEN MADE TO iniAppend() */ HINIOBJECT hFirstObject; HINIOBJECT hLastObject; HINIOBJECT hCurObject; int nObjects; HINIPROPERTY hCurProperty; } INI, *HINI; /******************************************** * tINIBOOKMARK * * Used to store the current Object and Property pointers so * that the caller can quickly return to some point in the * INI data. ********************************************/ typedef struct tINIBOOKMARK { HINI hIni; HINIOBJECT hCurObject; HINIPROPERTY hCurProperty; } INIBOOKMARK, *HINIBOOKMARK; #if defined(__cplusplus) extern "C" { #endif /*********[ PRIMARY INTERFACE ]*****************************************************/ /****************************** * iniOpen * * 1. make sure file exists * 2. allocate memory for HINI * 3. initialize HINI * 4. load entire file into structured memory * 5. set TRUE if you want to create file if non-existing ******************************/ #ifdef __OS2__ int iniOpen( HINI *hIni, char *pszFileName, char *cComment, char cLeftBracket, char cRightBracket, char cEqual, int bCreate, int bFileType ); #else int iniOpen( HINI *hIni, char *pszFileName, char *cComment, char cLeftBracket, char cRightBracket, char cEqual, int bCreate ); #endif /****************************** * iniAppend * * 1. append Sections in pszFileName that do not already exist in hIni * 2. Makes hIni ReadOnly! ******************************/ int iniAppend( HINI hIni, char *pszFileName ); /****************************** * iniDelete * * 1. simple removes all objects (and their properties) from the list using iniObjectDelete() in a loop ******************************/ int iniDelete( HINI hIni ); /****************************** * iniClose * * 1. free memory previously allocated for HINI * 2. DO NOT SAVE ANY CHANGES (see iniCommit) ******************************/ int iniClose( HINI hIni ); /****************************** * iniCommit * * 1. replaces file contents with memory contents (overwrites the file) ******************************/ int iniCommit( HINI hIni ); /****************************** * iniObjectFirst * ******************************/ int iniObjectFirst( HINI hIni ); /****************************** * iniObjectLast * ******************************/ int iniObjectLast( HINI hIni ); /****************************** * iniObjectNext * * 1. iniObjects() if no current object name else * 2. find and store next object name ******************************/ int iniObjectNext( HINI hIni ); /****************************** * iniObjectSeek * * 1. find and store object name ******************************/ int iniObjectSeek( HINI hIni, char *pszObject ); /****************************** * iniObjectSeekSure * * 1. find and store object name * 2. ensure that it exists ******************************/ int iniObjectSeekSure( HINI hIni, char *pszObject ); /****************************** * iniObjectEOL * ******************************/ int iniObjectEOL( HINI hIni ); /****************************** * iniObject * * 1. returns the current object name ******************************/ int iniObject( HINI hIni, char *pszObject ); /****************************** * iniObjectDelete * * 1. deletes current Object ******************************/ int iniObjectDelete( HINI hIni ); /****************************** * iniObjectUpdate * * 1. update current Object ******************************/ int iniObjectUpdate( HINI hIni, char *pszObject ); /****************************** * iniPropertyObject * * 1. inserts a new Object * 2. becomes current ******************************/ int iniObjectInsert( HINI hIni, char *pszObject ); /****************************** * iniPropertyFirst * ******************************/ int iniPropertyFirst( HINI hIni ); /****************************** * iniPropertyLast * ******************************/ int iniPropertyLast( HINI hIni ); /****************************** * iniPropertyNext * * 1. iniProperties() if no current property name else * 2. find and store next property name ******************************/ int iniPropertyNext( HINI hIni ); /****************************** * iniPropertySeek * * 1. set current Object & Property positions where matching parameters * 2. any parms which are empty strings (ie pszObject[0]) are ignored * 3. it is kinda pointless to pass empty strings for all parms... you will get 1st Property in 1st Object ******************************/ int iniPropertySeek( HINI hIni, char *pszObject, char *pszProperty, char *pszValue ); /****************************** * iniPropertySeekSure * * 1. same as iniPropertySeek but * 2. will ensure that both Object and Property exist ******************************/ int iniPropertySeekSure( HINI hIni, char *pszObject, char *pszProperty, char *pszValue ); /****************************** * iniPropertyEOL * ******************************/ int iniPropertyEOL( HINI hIni ); /****************************** * iniProperty * * 1. returns the current property name ******************************/ int iniProperty( HINI hIni, char *pszProperty ); /****************************** * iniPropertyDelete * * 1. deletes current Property ******************************/ int iniPropertyDelete( HINI hIni ); /****************************** * iniPropertyUpdate * * 1. update current Property ******************************/ int iniPropertyUpdate( HINI hIni, char *pszProperty, char *pszValue ); /****************************** * iniPropertyInsert * * 1. inserts a new Property for current Object * 2. becomes current ******************************/ int iniPropertyInsert( HINI hIni, char *pszProperty, char *pszValue ); /****************************** * iniValue * * 1. returns the value for the current object/property ******************************/ int iniValue( HINI hIni, char *pszValue ); /****************************** * iniGetBookmark * * 1. Store the current data positions (Object and Property) * into hIniBookmark. * 2. Does not allocate memory for hIniBookmark so pass a * pointer to a valid bookmark. ******************************/ int iniGetBookmark( HINI hIni, HINIBOOKMARK hIniBookmark ); /****************************** * iniGotoBookmark * * 1. Sets the current Object and Property positions to * those stored in IniBookmark. * 2. Does not account for the bookmark becoming * invalid ie from the Object or Property being deleted. ******************************/ int iniGotoBookmark( INIBOOKMARK IniBookmark ); /****************************** * iniCursor * * 1. Returns a copy of the hIni with a new * set of position cursors (current Object and Property). * 2. Not safe to use when in the possibility of * deleting data in another cursor on same data. * 3. Use when reading data only. * 4. Does not allocate memory so hIniCursor should be valid. * 5. All calls, other than those for movement, are * global and will affect any other view of the data. ******************************/ int iniCursor( HINI hIni, HINI hIniCursor ); /*************************************************************************************/ /*********[ SUPPORT FUNCS ]***********************************************************/ /*************************************************************************************/ /****************************** * iniElement * ******************************/ int iniElement( char *pszData, char cSeperator, char cTerminator, int nElement, char *pszElement, int nMaxElement ); int iniElementMax( char *pData, char cSeperator, int nDataLen, int nElement, char *pszElement, int nMaxElement ); int iniElementToEnd( char *pszData, char cSeperator, char cTerminator, int nElement, char *pszElement, int nMaxElement ); int iniElementEOL( char *pszData, char cSeperator, char cTerminator, int nElement, char *pszElement, int nMaxElement ); /****************************** * iniElementCount * ******************************/ int iniElementCount( char *pszData, char cSeperator, char cTerminator ); /****************************** * iniPropertyValue * * 1. returns the property value for pszProperty in pszValue * 2. pszString example; * "PropertyName1=Value1;PropertyName2=Value2;..." * 3. cEqual is usually '=' * 4. cPropertySep is usually ';' * * This function can be called without calling any other functions in this lib. ******************************/ int iniPropertyValue( char *pszString, char *pszProperty, char *pszValue, char cEqual, char cPropertySep ); /****************************** * iniAllTrim * * 1. trims blanks, tabs and newlines from start and end of pszString * * This function can be called without calling any other functions in this lib. ******************************/ int iniAllTrim( char *pszString ); /****************************** * iniToUpper * * 1. Converts all chars in pszString to upper case. * * This function can be called without calling any other functions in this lib. ******************************/ int iniToUpper( char *pszString ); /****************************** * _iniObjectRead * ******************************/ int _iniObjectRead( HINI hIni, char *szLine, char *pszObjectName ); /****************************** * _iniPropertyRead * ******************************/ int _iniPropertyRead( HINI hIni, char *szLine, char *pszPropertyName, char *pszPropertyValue ); /****************************** * _iniDump * ******************************/ int _iniDump( HINI hIni, FILE *hStream ); /****************************** * _iniScanUntilObject * ******************************/ int _iniScanUntilObject( HINI hIni, FILE *hFile, char *pszLine ); int _iniScanUntilNextObject( HINI hIni, FILE *hFile, char *pszLine ); /* * Some changes to avoid a 255 file handle limit, thanks MQJoe. * Make it conditional as it does have some performance impact esp with LARGE ini files (like what I have :-) */ #if defined( HAVE_VSNPRINTF ) && defined( USE_LL_FIO ) FILE *uo_fopen( const char *filename, const char *mode ); int uo_fclose( FILE *stream ); char *uo_fgets( char *szbuffer, int n, FILE *stream ); int uo_fprintf( FILE *stream, const char *fmt, ...); int uo_vfprintf( FILE *stream, const char *fmt, va_list ap); #else #define uo_fopen fopen #define uo_fclose fclose #define uo_fgets fgets #define uo_fprintf fprintf #define uo_vfprintf vfprintf #endif #if defined(__cplusplus) } #endif #endif unixODBC-2.3.12/include/log.h000066400000000000000000000072541446441710500156050ustar00rootroot00000000000000/********************************************************************************** * log.h * * Include file for liblog.a. Coding? Include this and link against liblog.a. * * At this time; its a simple list manager but I expect that this will evolve into * a list manager which; * * - allows for messages of different severity and types to be stored * - allows for actions (such as saving to file or poping) to occur on selected message * types and severities * **********************************************************************************/ #ifndef INCLUDED_LOG_H #define INCLUDED_LOG_H #include #include #include #if defined(HAVE_STDARG_H) # include # define HAVE_STDARGS #else # if defined(HAVE_VARARGS_H) # include # ifdef HAVE_STDARGS # undef HAVE_STDARGS # endif # endif #endif #include /***************************************************************************** * FUNCTION RETURN CODES *****************************************************************************/ #define LOG_ERROR 0 #define LOG_SUCCESS 1 #define LOG_NO_DATA 2 /***************************************************************************** * SEVERITY *****************************************************************************/ #define LOG_INFO 0 #define LOG_WARNING 1 #define LOG_CRITICAL 2 /***************************************************************************** * *****************************************************************************/ #define LOG_MSG_MAX 1024 /***************************************************************************** * HANDLES *****************************************************************************/ typedef struct tLOGMSG { char * pszModuleName; /*!< file where message originated */ char * pszFunctionName; /*!< function where message originated. */ int nLine; /*!< File line where message originated. */ int nSeverity; int nCode; char * pszMessage; } LOGMSG, *HLOGMSG; typedef struct tLOG { HLST hMessages; /* list of messages (we may want to switch to vector) */ char *pszProgramName; /* liblog will malloc, copy, and free */ char *pszLogFile; /* NULL, or filename */ long nMaxMsgs; /* OLDEST WILL BE DELETED ONCE MAX */ int bOn; /* turn logging on/off (default=off) */ } LOG, *HLOG; /***************************************************************************** * API *****************************************************************************/ int logOpen( HLOG *phLog, char *pszProgramName, char *pszLogFile, long nMaxMsgs ); int logClose( HLOG hLog ); int logClear( HLOG hLog ); int logPushMsg( HLOG hLog, char *pszModule, char *pszFunctionName, int nLine, int nSeverity, int nCode, char *pszMsg ); int logPushMsgf( HLOG hLog, char *pszModule, char *pszFunctionName, int nLine, int nSeverity, int nCode, char *pszMessageFormat, ... ); int logvPushMsgf( HLOG hLog, char *pszModule, char *pszFunctionName, int nLine, int nSeverity, int nCode, char *pszMessageFormat, va_list args ); int logPeekMsg( HLOG hLog, long nMsg, HLOGMSG *phMsg ); int logPopMsg( HLOG hLog ); int logOn( HLOG hLog, int bOn ); /***************************************************************************** * SUPPORTING FUNCS (do not call directly) *****************************************************************************/ /****************************** * _logFreeMsg * * 1. This is called by lstDelete() ******************************/ void _logFreeMsg( void *pMsg ); #endif unixODBC-2.3.12/include/lst.h000066400000000000000000000232531446441710500156230ustar00rootroot00000000000000/********************************************************************************** * lst.h * * lib for creating/managing/deleting doubly-linked lists. * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 04.APR.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #ifndef INCLUDED_LST_H #define INCLUDED_LST_H /*********[ CONSTANTS AND TYPES ]**************************************************/ #include #include #include #include #ifndef true #define true 1 #endif #ifndef false #define false 0 #endif #define LST_NO_DATA 2 #define LST_SUCCESS 1 #define LST_ERROR 0 /******************************************** * tLSTITEM * ********************************************/ typedef struct tLSTITEM { struct tLSTITEM *pNext; struct tLSTITEM *pPrev; int bDelete; /* true if flagged for delete. do delete when refs = 0 */ /* will become invisible for new cursors */ /* ONLY APPLIES TO THE root LIST */ int bHide; /* used in nav funcs if HLST bShowHidden=false (default) */ long nRefs; /* the number of hItems that refer to this item to get pData */ /* if bDelete and refs = 0 then item is really removed */ void *hLst; /* ptr to its list handle. */ void *pData; /* ptr to user data or (if Cursor item) ptr to some base LSTITEM */ } LSTITEM, *HLSTITEM; /******************************************** * tLST * ********************************************/ typedef struct tLST { HLSTITEM hFirst; HLSTITEM hLast; HLSTITEM hCurrent; long nItems; /* number of items in the list (not counting where bDelete or bHide)*/ /* !!! not used anymore !!!! */ long nRefs; /* the number of cursors that are based upon this list */ int bExclusive; /* set this for exclusive access to list ie when navigating with */ /* hCurrent or when doing an insert or delete */ /* do this only for VERY short periods all other access will loop */ /* until this is set back to false */ /* THIS IS FOR INTERNAL USE... IT IS USED WHEN MAINTAINING INTERNAL */ /* LISTS SUCH AS REFERENCE LISTS DO NOT USE IT TO LOCK A ROOT OR */ /* CURSOR LIST */ int bShowHidden; /* true to have nav funcs show bHidden items(default=false) */ int bShowDeleted; /* true to have nav funcs show bDeleted items (default=false) */ void (*pFree)( void *pData ); /* function to use when need to free pData. default is free() */ int (*pFilter)( struct tLST *, void * ); /* this function returns true if we want the data in our result set */ /* default is all items included. no affect if root list */ struct tLST *hLstBase; /* this list was derived from hLstBase. NULL if root list. */ /* we must use this if we are adding a new item in an empty list */ /* and to dec nRefs in our base list */ void *pExtras; /* app can store what ever it wants here. no attempt to interpret it*/ /* or to free it is made by lst */ } LST, *HLST; /******************************************** * tLSTBOOKMARK * ********************************************/ typedef struct tLSTBOOKMARK { HLST hLst; HLSTITEM hCurrent; } LSTBOOKMARK, *HLSTBOOKMARK; #if defined(__cplusplus) extern "C" { #endif /*********[ PRIMARY INTERFACE ]*****************************************************/ /****************************** * lstAppend * * 1. Appends a new item to the end of the list. * 2. Makes the new item the current item. ******************************/ int lstAppend( HLST hLst, void *pData ); /****************************** * lstClose * * 1. free memory previously allocated for HLST * 2. Will call lstDelete with bFreeData for each (if any) * existing items. ******************************/ int lstClose( HLST hLst ); /****************************** * lstDelete * * 1. deletes current item * 2. dec ref count in root item * 3. deletes root item if ref count < 1 OR sets delete flag ******************************/ int lstDelete( HLST hLst ); /****************************** * lstEOL * ******************************/ int lstEOL( HLST hLst ); /****************************** * lstFirst * * 1. makes First item the current item. * 2. returns pData or NULL ******************************/ void *lstFirst( HLST hLst ); /****************************** * lstGet * * 1. Return pData for current item or NULL * 2. Will recurse down to base data if bIsCursor. ******************************/ void *lstGet( HLST hLst ); /****************************** * lstGetBookMark * * !!! BOOKMARKS ONLY SAFE WHEN READONLY !!! ******************************/ int lstGetBookMark( HLST hLst, HLSTBOOKMARK hLstBookMark ); /****************************** * lstGoto * * 1. Return pData for current item or NULL * 2. IF nIndex is out of range THEN * lstEOL = TRUE * returns NULL ******************************/ void *lstGoto( HLST hLst, long nIndex ); /****************************** * lstGotoBookMark * * !!! BOOKMARKS ONLY SAFE WHEN READONLY !!! ******************************/ int lstGotoBookMark( HLSTBOOKMARK hLstBookMark ); /****************************** * lstInsert * * 1. inserts a new item before the current item * 2. becomes current ******************************/ int lstInsert( HLST hLst, void *pData ); /****************************** * lstLast * * 1. makes last item the current item * 2. returns pData or NULL ******************************/ void *lstLast( HLST hLst ); /****************************** * lstNext * * 1. makes next item the current item * 2. returns pData or NULL ******************************/ void *lstNext( HLST hLst ); /****************************** * lstOpen * * 1. Create an empty list. * * *** MUST CALL lstClose WHEN DONE OR LOSE MEMORY *** * ******************************/ HLST lstOpen(); /****************************** * lstOpenCursor * * 1. If you are going to use cursors then just use cursors. Do * not use move funcs, get funcs, etc on base list and use * cursors as well. Garbage collection only accounts for * cursors when deleting items that have been flagged for * deletion... so direct access could result in the list * changing unexpectedly. * * 2. pFilterFunc is optional. If you provide this function * pointer the cursor list will be generated to include * all items where pFilterFunc( lstGet( hBase ) ) = true. * Leaving it NULL just means that all items in hBase will * be included in the cursor list. * * *** MUST CALL lstClose WHEN DONE OR LOSE MEMORY *** * ******************************/ HLST lstOpenCursor( HLST hBase, int (*pFilterFunc)( HLST, void * ), void *pExtras ); /****************************** * lstPrev * * 1. makes prev item the current item * 2. returns pData or NULL ******************************/ void *lstPrev( HLST hLst ); /****************************** * lstSet * * 1. replaces pData pointer * 2. returns pData * 3. Will recurse down to base data. * * *** THIS SHOULD BE CHANGED TO AVOID CHANGING THE pData POINTER AND RESIZE THE BUFFER INSTEAD * ******************************/ void *lstSet( HLST hLst, void *pData ); /****************************** * lstSetFreeFunc * * 1. The given function will be called when ever there is a need to free pData * 2. The default action is to simply free(pData). ******************************/ int lstSetFreeFunc( HLST hLst, void (*pFree)( void *pData ) ); /****************************** * lstSeek * * 1. Tries to set hCurrent to the item where pData is at * 2. simply scans from 1st to last so lsEOL() = true when not found * ******************************/ int lstSeek( HLST hLst, void *pData ); /****************************** * lstSeekItem * * 1. Tries to set hCurrent to the item where hItem is at * 2. simply scans from 1st to last so lsEOL() = true when not found * ******************************/ int lstSeekItem( HLST hLst, HLSTITEM hItem ); /***************[ FOR INTERNAL USE ]***********************/ /*************************** * ENSURE CURRENT IS NOT ON A bDelete ITEM ***************************/ void *_lstAdjustCurrent( HLST hLst ); /*************************** * ***************************/ void _lstDump( HLST hLst ); /****************************** * _lstFreeItem * * 1. Does a real delete. Frees memory used by item. * will delete root item as required. * ******************************/ int _lstFreeItem( HLSTITEM hItem ); /****************************** * _lstNextValidItem * * 1. Starts scanning hLst at hItem until a non-deleted Item found or EOL * ******************************/ HLSTITEM _lstNextValidItem( HLST hLst, HLSTITEM hItem ); /****************************** * _lstPrevValidItem * * 1. Starts scanning hLst at hItem until a non-deleted Item found or EOL * ******************************/ HLSTITEM _lstPrevValidItem( HLST hLst, HLSTITEM hItem ); /****************************** * _lstVisible * * ******************************/ int _lstVisible( HLSTITEM hItem ); /****************************** * _lstAppend * * ******************************/ int _lstAppend( HLST hLst, HLSTITEM hItem ); /****************************** * _lstInsert * * ******************************/ int _lstInsert( HLST hLst, HLSTITEM hItem ); #if defined(__cplusplus) } #endif #endif unixODBC-2.3.12/include/odbcinst.h000066400000000000000000000435461446441710500166350ustar00rootroot00000000000000/************************************************** * odbcinst.h * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #ifndef __ODBCINST_H #define __ODBCINST_H #include #ifndef BOOL #define BOOL int #endif #ifndef __SQL #include "sql.h" #endif /*! * \brief Our generic window handle. * * This is used wherever a HWND is needed. The caller inits this according * to which UI the caller has (or simply desires). This may be a; console, xlib, qt3, qt4, * gtk, mono, carbon, etc. * * SQLCreateDataSource * (maps to ODBCCreateDataSource entry point in UI plugin) * * This function requires a HWND (and it must NOT be NULL as per ODBC spec.). So * the caller should *always* init an ODBCINSTWND and cast it to HWND as it is passed to * SQLCreateDataSource. * * SQLManageDataSources * (maps to ODBCManageDataSources entry point in UI plugin) * * This function requires a HWND (and it must NOT be NULL as per ODBC spec.). So * the caller should *always* init an ODBCINSTWND and cast it to HWND as it is passed to * SQLManageDataSources. However; it may make sense to have a NULL hWnd... this is what * an ODBC Administrator program would typically do. * * Plugin Selection * * 1. Passing a NULL to a function instead of a valid HODBCINSTWND may result in an error * (this is the case with SQLCreateDataSource). In anycase; passing a NULL in this way * negates the use of any UI plugin. * * 2. szUI has a value and it is the file name (no path and no extension) of the UI * plugin. The plugin is loaded and the appropriate function is called with hWnd. The * caller must have init hWnd in a manner which is appropriate for the UI plugin. * * 3. Passing an empty szUI indicates that the UI plugin should be determined by other * means (see 4). In such a case it is dangerous to use hWnd because it may not match * the type expected by the plugin. hWnd will be ignored and a NULL will be passed to the UI * plugin. * * 4. The fallback logic for determining the UI plugin is as follows; * - use the ODBCINSTUI environment variable to get the UI plugin file name * - use the ODBCINSTUI value in odbcinst.ini to get the UI plugin file name * * NOTE: In the future we may want to consider making HWND of this type instead of having * two different types and having to cast HODBCINSTWND into a HWND. */ typedef struct tODBCINSTWND { char szUI[FILENAME_MAX]; /*!< Plugin file name (no path and no extension) ie "odbcinstQ4". */ HWND hWnd; /*!< this is passed to the UI plugin - caller must know what the plugin is expecting */ } ODBCINSTWND, *HODBCINSTWND; #ifdef __cplusplus extern "C" { #endif #ifndef ODBCVER #define ODBCVER 0x0351 #endif #ifndef WINVER #define WINVER 0x0400 #endif /* SQLConfigDataSource request flags */ #define ODBC_ADD_DSN 1 #define ODBC_CONFIG_DSN 2 #define ODBC_REMOVE_DSN 3 #if (ODBCVER >= 0x0250) #define ODBC_ADD_SYS_DSN 4 #define ODBC_CONFIG_SYS_DSN 5 #define ODBC_REMOVE_SYS_DSN 6 #if (ODBCVER >= 0x0300) #define ODBC_REMOVE_DEFAULT_DSN 7 #endif /* ODBCVER >= 0x0300 */ /* install request flags */ #define ODBC_INSTALL_INQUIRY 1 #define ODBC_INSTALL_COMPLETE 2 /* config driver flags */ #define ODBC_INSTALL_DRIVER 1 #define ODBC_REMOVE_DRIVER 2 #define ODBC_CONFIG_DRIVER 3 #define ODBC_CONFIG_DRIVER_MAX 100 #endif /* SQLGetConfigMode and SQLSetConfigMode flags */ #if (ODBCVER >= 0x0300) #define ODBC_BOTH_DSN 0 #define ODBC_USER_DSN 1 #define ODBC_SYSTEM_DSN 2 #endif /* ODBCVER >= 0x0300 */ /* SQLInstallerError code */ #if (ODBCVER >= 0x0300) #define ODBC_ERROR_GENERAL_ERR 1 #define ODBC_ERROR_INVALID_BUFF_LEN 2 #define ODBC_ERROR_INVALID_HWND 3 #define ODBC_ERROR_INVALID_STR 4 #define ODBC_ERROR_INVALID_REQUEST_TYPE 5 #define ODBC_ERROR_COMPONENT_NOT_FOUND 6 #define ODBC_ERROR_INVALID_NAME 7 #define ODBC_ERROR_INVALID_KEYWORD_VALUE 8 #define ODBC_ERROR_INVALID_DSN 9 #define ODBC_ERROR_INVALID_INF 10 #define ODBC_ERROR_REQUEST_FAILED 11 #define ODBC_ERROR_INVALID_PATH 12 #define ODBC_ERROR_LOAD_LIB_FAILED 13 #define ODBC_ERROR_INVALID_PARAM_SEQUENCE 14 #define ODBC_ERROR_INVALID_LOG_FILE 15 #define ODBC_ERROR_USER_CANCELED 16 #define ODBC_ERROR_USAGE_UPDATE_FAILED 17 #define ODBC_ERROR_CREATE_DSN_FAILED 18 #define ODBC_ERROR_WRITING_SYSINFO_FAILED 19 #define ODBC_ERROR_REMOVE_DSN_FAILED 20 #define ODBC_ERROR_OUT_OF_MEM 21 #define ODBC_ERROR_OUTPUT_STRING_TRUNCATED 22 #endif /* ODBCVER >= 0x0300 */ #ifndef EXPORT #define EXPORT #endif #ifdef __OS2__ #define INSTAPI _System #else #define INSTAPI #endif /* HIGH LEVEL CALLS */ BOOL INSTAPI SQLInstallODBC (HWND hwndParent, LPCSTR lpszInfFile, LPCSTR lpszSrcPath, LPCSTR lpszDrivers); BOOL INSTAPI SQLManageDataSources (HWND hwndParent); BOOL INSTAPI SQLCreateDataSource (HWND hwndParent, LPCSTR lpszDSN); BOOL INSTAPI SQLGetTranslator (HWND hwnd, LPSTR lpszName, WORD cbNameMax, WORD *pcbNameOut, LPSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut, DWORD *pvOption); /* LOW LEVEL CALLS */ BOOL INSTAPI SQLInstallDriver (LPCSTR lpszInfFile, LPCSTR lpszDriver, LPSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut); BOOL INSTAPI SQLInstallDriverManager (LPSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut); BOOL INSTAPI SQLGetInstalledDrivers (LPSTR lpszBuf, WORD cbBufMax, WORD * pcbBufOut); BOOL INSTAPI SQLGetAvailableDrivers (LPCSTR lpszInfFile, LPSTR lpszBuf, WORD cbBufMax, WORD * pcbBufOut); BOOL INSTAPI SQLConfigDataSource (HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttributes); BOOL INSTAPI SQLRemoveDefaultDataSource(void); BOOL INSTAPI SQLWriteDSNToIni (LPCSTR lpszDSN, LPCSTR lpszDriver); BOOL INSTAPI SQLRemoveDSNFromIni (LPCSTR lpszDSN); BOOL INSTAPI SQLValidDSN (LPCSTR lpszDSN); BOOL INSTAPI SQLWritePrivateProfileString(LPCSTR lpszSection, LPCSTR lpszEntry, LPCSTR lpszString, LPCSTR lpszFilename); int INSTAPI SQLGetPrivateProfileString( LPCSTR lpszSection, LPCSTR lpszEntry, LPCSTR lpszDefault, LPSTR lpszRetBuffer, int cbRetBuffer, LPCSTR lpszFilename); #if (ODBCVER >= 0x0250) BOOL INSTAPI SQLRemoveDriverManager(LPDWORD lpdwUsageCount); BOOL INSTAPI SQLInstallTranslator(LPCSTR lpszInfFile, LPCSTR lpszTranslator, LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount); BOOL INSTAPI SQLRemoveTranslator(LPCSTR lpszTranslator, LPDWORD lpdwUsageCount); BOOL INSTAPI SQLRemoveDriver(LPCSTR lpszDriver, BOOL fRemoveDSN, LPDWORD lpdwUsageCount); BOOL INSTAPI SQLConfigDriver(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszArgs, LPSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut); #endif #if (ODBCVER >= 0x0300) SQLRETURN INSTAPI SQLInstallerError(WORD iError, DWORD *pfErrorCode, LPSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg); SQLRETURN INSTAPI SQLPostInstallerError(DWORD dwErrorCode, LPCSTR lpszErrMsg); BOOL INSTAPI SQLWriteFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName, LPCSTR lpszKeyName, LPCSTR lpszString); BOOL INSTAPI SQLReadFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName, LPCSTR lpszKeyName, LPSTR lpszString, WORD cbString, WORD *pcbString); BOOL INSTAPI SQLInstallDriverEx(LPCSTR lpszDriver, LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount); BOOL INSTAPI SQLInstallTranslatorEx(LPCSTR lpszTranslator, LPCSTR lpszPathIn, LPSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount); BOOL INSTAPI SQLGetConfigMode(UWORD *pwConfigMode); BOOL INSTAPI SQLSetConfigMode(UWORD wConfigMode); #endif /* ODBCVER >= 0x0300 */ /* Driver specific Setup APIs called by installer */ BOOL INSTAPI ConfigDSN (HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttributes); BOOL INSTAPI ConfigTranslator ( HWND hwndParent, DWORD *pvOption); #if (ODBCVER >= 0x0250) BOOL INSTAPI ConfigDriver(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszArgs, LPSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut); #endif /* * UNICODE APIs */ BOOL INSTAPI SQLInstallODBCW (HWND hwndParent, LPCWSTR lpszInfFile, LPCWSTR lpszSrcPath, LPCWSTR lpszDrivers); BOOL INSTAPI SQLCreateDataSourceW (HWND hwndParent, LPCWSTR lpszDSN); BOOL INSTAPI SQLGetTranslatorW (HWND hwnd, LPWSTR lpszName, WORD cbNameMax, WORD *pcbNameOut, LPWSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut, DWORD *pvOption); BOOL INSTAPI SQLInstallDriverW (LPCWSTR lpszInfFile, LPCWSTR lpszDriver, LPWSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut); BOOL INSTAPI SQLInstallDriverManagerW (LPWSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut); BOOL INSTAPI SQLGetInstalledDriversW (LPWSTR lpszBuf, WORD cbBufMax, WORD * pcbBufOut); BOOL INSTAPI SQLGetAvailableDriversW (LPCWSTR lpszInfFile, LPWSTR lpszBuf, WORD cbBufMax, WORD * pcbBufOut); BOOL INSTAPI SQLConfigDataSourceW (HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver, LPCWSTR lpszAttributes); BOOL INSTAPI SQLWriteDSNToIniW (LPCWSTR lpszDSN, LPCWSTR lpszDriver); BOOL INSTAPI SQLRemoveDSNFromIniW (LPCWSTR lpszDSN); BOOL INSTAPI SQLValidDSNW (LPCWSTR lpszDSN); BOOL INSTAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry, LPCWSTR lpszString, LPCWSTR lpszFilename); int INSTAPI SQLGetPrivateProfileStringW( LPCWSTR lpszSection, LPCWSTR lpszEntry, LPCWSTR lpszDefault, LPWSTR lpszRetBuffer, int cbRetBuffer, LPCWSTR lpszFilename); #if (ODBCVER >= 0x0250) BOOL INSTAPI SQLInstallTranslatorW(LPCWSTR lpszInfFile, LPCWSTR lpszTranslator, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount); BOOL INSTAPI SQLRemoveTranslatorW(LPCWSTR lpszTranslator, LPDWORD lpdwUsageCount); BOOL INSTAPI SQLRemoveDriverW(LPCWSTR lpszDriver, BOOL fRemoveDSN, LPDWORD lpdwUsageCount); BOOL INSTAPI SQLConfigDriverW(HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver, LPCWSTR lpszArgs, LPWSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut); #endif #if (ODBCVER >= 0x0300) SQLRETURN INSTAPI SQLInstallerErrorW(WORD iError, DWORD *pfErrorCode, LPWSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg); SQLRETURN INSTAPI SQLPostInstallerErrorW(DWORD dwErrorCode, LPCWSTR lpszErrorMsg); BOOL INSTAPI SQLWriteFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName, LPCWSTR lpszKeyName, LPCWSTR lpszString); BOOL INSTAPI SQLReadFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName, LPCWSTR lpszKeyName, LPWSTR lpszString, WORD cbString, WORD *pcbString); BOOL INSTAPI SQLInstallDriverExW(LPCWSTR lpszDriver, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount); BOOL INSTAPI SQLInstallTranslatorExW(LPCWSTR lpszTranslator, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount); #endif /* ODBCVER >= 0x0300 */ /* Driver specific Setup APIs called by installer */ BOOL INSTAPI ConfigDSNW (HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver, LPCWSTR lpszAttributes); #if (ODBCVER >= 0x0250) BOOL INSTAPI ConfigDriverW(HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver, LPCWSTR lpszArgs, LPWSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut); #endif #ifndef SQL_NOUNICODEMAP /* define this to disable the mapping */ #ifdef UNICODE #define SQLInstallODBC SQLInstallODBCW #define SQLCreateDataSource SQLCreateDataSourceW #define SQLGetTranslator SQLGetTranslatorW #define SQLInstallDriver SQLInstallDriverW #define SQLInstallDriverManager SQLInstallDriverManagerW #define SQLGetInstalledDrivers SQLGetInstalledDriversW #define SQLGetAvailableDrivers SQLGetAvailableDriversW #define SQLConfigDataSource SQLConfigDataSourceW #define SQLWriteDSNToIni SQLWriteDSNToIniW #define SQLRemoveDSNFromIni SQLRemoveDSNFromIniW #define SQLValidDSN SQLValidDSNW #define SQLWritePrivateProfileString SQLWritePrivateProfileStringW #define SQLGetPrivateProfileString SQLGetPrivateProfileStringW #define SQLInstallTranslator SQLInstallTranslatorW #define SQLRemoveTranslator SQLRemoveTranslatorW #define SQLRemoveDriver SQLRemoveDriverW #define SQLConfigDriver SQLConfigDriverW #define SQLInstallerError SQLInstallerErrorW #define SQLPostInstallerError SQLPostInstallerErrorW #define SQLReadFileDSN SQLReadFileDSNW #define SQLWriteFileDSN SQLWriteFileDSNW #define SQLInstallDriverEx SQLInstallDriverExW #define SQLInstallTranslatorEx SQLInstallTranslatorExW #endif #endif #ifdef __cplusplus } #endif #endif unixODBC-2.3.12/include/odbcinstext.h000066400000000000000000000255371446441710500173560ustar00rootroot00000000000000/************************************************** * odbcinstext.h * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #ifndef _ODBCINST_H #define _ODBCINST_H #ifdef UNIXODBC_SOURCE #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_PWD_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifndef ODBCVER #define ODBCVER 0x0380 #endif #include #include #include /******************************************************** * CONSTANTS WHICH DO NOT EXIST ELSEWHERE ********************************************************/ #ifndef TRUE #define FALSE 0; #define TRUE 1; #endif #else /* not UNIXODBC_SOURCE */ /******************************************************** * outside the unixODBC source tree only the * * public interface is exposed * ********************************************************/ #include /******************************************************** * these limits are originally defined in ini.h * * but are needed to implement ODBCINSTGetProperties * * for the Driver Setup * ********************************************************/ #define INI_MAX_LINE 1000 #define INI_MAX_OBJECT_NAME INI_MAX_LINE #define INI_MAX_PROPERTY_NAME INI_MAX_LINE #define INI_MAX_PROPERTY_VALUE INI_MAX_LINE #endif /* UNIXODBC_SOURCE */ /******************************************************** * PUBLIC API ********************************************************/ #ifdef __cplusplus extern "C" { #endif BOOL INSTAPI SQLConfigDataSource( HWND hWnd, WORD nRequest, LPCSTR pszDriver, LPCSTR pszAttributes ); BOOL INSTAPI SQLGetConfigMode( UWORD *pnConfigMode ); BOOL INSTAPI SQLGetInstalledDrivers( LPSTR pszBuf, WORD nBufMax, WORD *pnBufOut ); BOOL INSTAPI SQLInstallDriverEx( LPCSTR pszDriver, LPCSTR pszPathIn, LPSTR pszPathOut, WORD nPathOutMax, WORD *nPathOut, WORD nRequest, LPDWORD pnUsageCount ); BOOL INSTAPI SQLInstallDriverManager( LPSTR pszPath, WORD nPathMax, WORD *pnPathOut ); RETCODE INSTAPI SQLInstallerError( WORD nError, DWORD *pnErrorCode, LPSTR pszErrorMsg, WORD nErrorMsgMax, WORD *nErrorMsg ); BOOL INSTAPI SQLManageDataSources( HWND hWnd ); BOOL INSTAPI SQLReadFileDSN( LPCSTR pszFileName, LPCSTR pszAppName, LPCSTR pszKeyName, LPSTR pszString, WORD nString, WORD *pnString ); BOOL INSTAPI SQLRemoveDriver( LPCSTR pszDriver, BOOL nRemoveDSN, LPDWORD pnUsageCount ); BOOL INSTAPI SQLRemoveDriverManager( LPDWORD pnUsageCount ); BOOL INSTAPI SQLRemoveDSNFromIni( LPCSTR pszDSN ); BOOL INSTAPI SQLRemoveTranslator( LPCSTR pszTranslator, LPDWORD pnUsageCount ); BOOL INSTAPI SQLSetConfigMode( UWORD nConfigMode ); BOOL INSTAPI SQLValidDSN( LPCSTR pszDSN ); BOOL INSTAPI SQLWriteDSNToIni( LPCSTR pszDSN, LPCSTR pszDriver ); BOOL INSTAPI SQLWriteFileDSN( LPCSTR pszFileName, LPCSTR pszAppName, LPCSTR pszKeyName, LPCSTR pszString ); BOOL INSTAPI SQLWritePrivateProfileString( LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszString, LPCSTR pszFileName ); #ifdef __cplusplus } #endif #ifdef UNIXODBC_SOURCE /******************************************************** * PRIVATE API ********************************************************/ #if defined(__cplusplus) extern "C" { #endif BOOL _odbcinst_UserINI( char *pszFileName, BOOL bVerify ); BOOL _odbcinst_SystemINI( char *pszFileName, BOOL bVerify ); BOOL _odbcinst_FileINI( char *pszPath ); char * INSTAPI odbcinst_system_file_path( char *buffer ); char * INSTAPI odbcinst_system_file_name( char *buffer ); char * INSTAPI odbcinst_user_file_path( char *buffer ); char * INSTAPI odbcinst_user_file_name( char *buffer ); BOOL _odbcinst_ConfigModeINI( char *pszFileName ); int _odbcinst_GetSections( HINI hIni, LPSTR pRetBuffer, int nRetBuffer, int *pnBufPos ); int _odbcinst_GetEntries( HINI hIni, LPCSTR pszSection, LPSTR pRetBuffer, int nRetBuffer, int *pnBufPos ); int _SQLGetInstalledDrivers( LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPCSTR pRetBuffer, int nRetBuffer ); BOOL _SQLWriteInstalledDrivers( LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszString ); BOOL _SQLDriverConnectPrompt( HWND hwnd, SQLCHAR *dsn, SQLSMALLINT len_dsn ); BOOL _SQLDriverConnectPromptW( HWND hwnd, SQLWCHAR *dsn, SQLSMALLINT len_dsn ); void __set_config_mode( int mode ); int __get_config_mode( void ); int inst_logPushMsg( char *pszModule, char *pszFunctionName, int nLine, int nSeverity, int nCode, char *pszMessage ); int inst_logPeekMsg( long nMsg, HLOGMSG *phMsg ); int inst_logClear(); /* * we should look at caching this info, the calls can become expensive */ #ifndef DISABLE_INI_CACHING struct ini_cache { char *fname; char *section; char *entry; char *value; char *default_value; int buffer_size; int ret_value; int config_mode; long timestamp; struct ini_cache *next; }; #endif #ifdef __cplusplus } #endif #endif /* UNIXODBC_SOURCE */ /********************************* * ODBCINST - PROPERTIES ********************************* * * PURPOSE: * * To provide the caller a mechanism to interact with Data Source properties * containing Driver specific options while avoiding embedding GUI code in * the ODBC infrastructure. * * DETAILS: * * 1. Application calls libodbcinst.ODBCINSTConstructProperties() * - odbcinst will load the driver and call libMyDrvS.ODBCINSTGetProperties() to build a list of all possible properties * 2. Application calls libodbcinst.ODBCINSTSetProperty() * - use, as required, to init values (ie if configuring existing DataSource) * - use libodbcinst.SetConfigMode() & libodbcinst.SQLGetPrivateProfileString() to read existing Data Source info (do not forget to set the mode back) * - do not forget to set mode back to ODBC_BOTH_DSN using SetConfigMode() when done reading * - no call to Driver Setup * 3. Application calls libodbcinst.ODBCINSTValidateProperty() * - use as required (ie on leave widget event) * - an assesment of the entire property list is also done * - this is passed onto the driver setup DLL * 4. Application should refresh widgets in case aPromptData or szValue has changed * - refresh should occur for each property where bRefresh = 1 * 5. Application calls libodbcinst.ODBCINSTValidateProperties() * - call this just before saving new Data Source or updating existing Data Source * - should always call this before saving * - use libodbcinst.SetConfigMode() & libodbcinst.SQLWritePrivateProfileString() to save Data Source info * - do not forget to set mode back to ODBC_BOTH_DSN using SetConfigMode() when done saving * - this is passed onto the driver setup DLL * 6. Application calls ODBCINSTDestructProperties() to free up memory * - unload Driver Setup DLL * - frees memory (Driver Setup allocates most of the memory but we free ALL of it in odbcinst) * * NOTES * * 1. odbcinst implements 5 functions to support this GUI config stuff * 2. Driver Setup DLL implements just 3 functions for its share of the work * *********************************/ #define ODBCINST_SUCCESS 0 #define ODBCINST_WARNING 1 #define ODBCINST_ERROR 2 #define ODBCINST_PROMPTTYPE_LABEL 0 /* readonly */ #define ODBCINST_PROMPTTYPE_TEXTEDIT 1 #define ODBCINST_PROMPTTYPE_LISTBOX 2 #define ODBCINST_PROMPTTYPE_COMBOBOX 3 #define ODBCINST_PROMPTTYPE_FILENAME 4 #define ODBCINST_PROMPTTYPE_HIDDEN 5 #define ODBCINST_PROMPTTYPE_TEXTEDIT_PASSWORD 6 typedef struct tODBCINSTPROPERTY { struct tODBCINSTPROPERTY *pNext; /* pointer to next property, NULL if last property */ char szName[INI_MAX_PROPERTY_NAME+1]; /* property name */ char szValue[INI_MAX_PROPERTY_VALUE+1]; /* property value */ int nPromptType; /* PROMPTTYPE_TEXTEDIT, PROMPTTYPE_LISTBOX, PROMPTTYPE_COMBOBOX, PROMPTTYPE_FILENAME */ char **aPromptData; /* array of pointers terminated with a NULL value in array. */ char *pszHelp; /* help on this property (driver setups should keep it short) */ void *pWidget; /* CALLER CAN STORE A POINTER TO ? HERE */ int bRefresh; /* app should refresh widget ie Driver Setup has changed aPromptData or szValue */ void *hDLL; /* for odbcinst internal use... only first property has valid one */ } ODBCINSTPROPERTY, *HODBCINSTPROPERTY; /* * Plugin name */ #define ODBCINSTPLUGIN "odbcinstQ5" /* * Conversion routines for wide interface */ char* _multi_string_alloc_and_copy( LPCWSTR in ); char* _single_string_alloc_and_copy( LPCWSTR in ); void _single_string_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len ); int _multi_string_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len ); int _single_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len ); SQLWCHAR* _multi_string_alloc_and_expand( LPCSTR in ); SQLWCHAR* _single_string_alloc_and_expand( LPCSTR in ); void _single_copy_from_wide( SQLCHAR *out, LPCWSTR in, int len ); int _multi_string_length( LPCSTR in ); /* * To support finding UI plugin */ char *_getUIPluginName( char *pszName, char *pszUI ); char *_appendUIPluginExtension( char *pszNameAndExtension, char *pszName ); char *_prependUIPluginPath( char *pszPathAndName, char *pszName ); #if defined(__cplusplus) extern "C" { #endif /* ONLY IMPLEMENTED IN ODBCINST (not in Driver Setup) */ int INSTAPI ODBCINSTConstructProperties( char *szDriver, HODBCINSTPROPERTY *hFirstProperty ); int INSTAPI ODBCINSTSetProperty( HODBCINSTPROPERTY hFirstProperty, char *pszProperty, char *pszValue ); int INSTAPI ODBCINSTDestructProperties( HODBCINSTPROPERTY *hFirstProperty ); int INSTAPI ODBCINSTAddProperty( HODBCINSTPROPERTY hFirstProperty, char *pszProperty, char *pszValue ); /* IMPLEMENTED IN ODBCINST AND DRIVER SETUP */ int INSTAPI ODBCINSTValidateProperty( HODBCINSTPROPERTY hFirstProperty, char *pszProperty, char *pszMessage ); int INSTAPI ODBCINSTValidateProperties( HODBCINSTPROPERTY hFirstProperty, HODBCINSTPROPERTY hBadProperty, char *pszMessage ); /* ONLY IMPLEMENTED IN DRIVER SETUP (not in ODBCINST) */ int INSTAPI ODBCINSTGetProperties( HODBCINSTPROPERTY hFirstProperty ); #if defined(__cplusplus) } #endif #endif unixODBC-2.3.12/include/odbctrac.h000066400000000000000000000064671446441710500166120ustar00rootroot00000000000000/*! * \file * * \author Peter Harvey www.peterharvey.org * \author \sa AUTHORS file * \version 1 * \date 2007 * \license Copyright unixODBC Project 2007-2008, LGPL */ /*! * \mainpage ODBC Trace PlugIn * * \section intro_sec Introduction * * This library provides a Driver with a cross-platform (including MS Windows) means of producing trace output. * This may also be used by Driver Managers. This is compat. with MS approach but not the same. * * This concept is based upon the MS odbctrac method of producing ODBC trace output. The main principle of this * is that the trace library can be swapped out with a custom trace library allowing the trace output to be * tailored to an organizations needs. It also allows trace code to be shared among Drivers and even the * Driver Manager. * * This library differs from the MS implementation in some significant ways. * * - all TraceSQL* functions return SQLPOINTER for call context... not SQLRETURN (this improves perf.) * - TraceReturn accepts an SQLPOINTER for call context... not SQLRETURN (this improves perf.) * - all functions accept SQLPOINTER as first arg - a trace handle (this can reduce concurrency issues) * * A notable weakness over MS odbctrac is the fact that we work with a HTRACE and that a Driver will want to * maintain this within environment and connection handles. This means that we can not produce trace output * for case when the environment/connection (whichever is relevant for the call) handle is invalid. This weakness * is offset by our ability to reduce conccurency issues and provide more options with regard to the granularity * of the tracing (environment/driver scope or connection/dsn scope for example). The driver can, at the developers * option, make a global HTRACE and thereby allow trace output even when the ODBC handles are invalid - but * this is not recommended. * * If an application is getting back an SQL_INVALID_HANDLE and no trace... then we can pretty much assume that * the application is providing an invalid handle :) * * unixODBC provides a cross-platform (including MS platforms) helper library called 'trace'. This is the * recommended method to use tracing. The text file driver (odbctxt) included with unixODBC demonstrates * how to use the 'trace' helper library. * * Why create a custom trace plugin? Here are a few possible reasons; * * - produce trace output showing a hierarchy (tree view) of calls * - allow config to limit or filter trace output * - allow trace output to be provided to some sort of UI like an IDE via shared mem or other * - allow trace output to be provided to remote machine via RPC or whatever * - produce trace output in XML * - produce trace output in a manner which can allow the calls to be played back (ie to reproduce bug * in a closed source app) */ #ifndef ODBCTRAC_H #define ODBCTRAC_H #include #include #include #endif unixODBC-2.3.12/include/odbctrace.h000066400000000000000000000632111446441710500167450ustar00rootroot00000000000000/*! * \file * * \author Peter Harvey www.peterharvey.org * \author \sa AUTHORS file * \version 1 * \date 2007 * \license Copyright unixODBC Project 2007-2008, LGPL */ /*! * \mainpage ODBC Trace Manager * * \section intro_sec Introduction * * This library provides an interface to trace code which is cross-platform and supports plugin trace * handlers. Drivers can use this to simplify support for producing trace output. * * odbctrac is an example of a trace plugin which can be used with this trace interface. * * odbctxt is an example of a Driver which uses this trace interface. */ #ifndef TRACE_H #define TRACE_H #include #include typedef SQLHANDLE *HTRACECALL; /*!< internal call handle of trace plugin */ /*! * \brief Trace handle. * * Create an instance of this at the desired scope. The scope could be 1 for driver or * 1 for each driver handle (env, dbc, stmt, desc) or some other scope. * * Use #traceAlloc to allocate the instance or otherwise init the struct. Then use #traceOpen * and #traceClose to open/close the trace plugin. Use #traceFree when your done with the * trace handle. * \code // init SQLHDBC pConnection; HTRACE pTrace = traceAlloc(); { char szTrace[50]; SQLGetPrivateProfileString( "odbctxt", "TraceFile", "/tmp/sql.log", pTrace->szTraceFile, FILENAME_MAX - 2, "odbcinst.ini" ); SQLGetPrivateProfileString( "odbctxt", "TraceLibrary", "libodbctrac.so", pTrace->szFileName, FILENAME_MAX - 2, "odbcinst.ini" ); SQLGetPrivateProfileString( "odbctxt", "Trace", "No", szTrace, sizeof( szTrace ), "odbcinst.ini" ); if ( szTrace[ 0 ] == '1' || toupper( szTrace[ 0 ] ) == 'Y' || ( toupper( szTrace[ 0 ] ) == 'O' && toupper( szTrace[ 1 ] ) == 'N' ) ) traceOpen( pTrace ); } // use (SQLConnect as example) { HTRACECALL hCall = traceConnect( pTrace, pConnection, "DataSource", SQL_NTS, "UID", SQL_NTS, "PWD", SQL_NTS ); // do connect here return traceReturn( pTrace, hCall, nReturn ); } // fini { traceFree( pTrace ); } \endcode */ typedef struct tTRACE { void * hPlugIn; /*!< library handle of trace plugin */ char szFileName[FILENAME_MAX]; /*!< file name of trace plugin */ char szTraceFile[FILENAME_MAX]; /*!< SQL_ATTR_TRACEFILE */ SQLUINTEGER nTrace; /*!< SQL_ATTR_TRACE */ SQLHANDLE hPlugInInternal; /*!< internal handle of trace plugin */ SQLHANDLE (*pTraceAlloc)(); void (*pTraceFree)(); SQLRETURN (*pTraceReturn)(); RETCODE (*pTraceOpenLogFile)(); RETCODE (*pTraceCloseLogFile)(); HTRACECALL (*pTraceSQLAlloConnect)(); HTRACECALL (*pTraceSQLAllocEnv)(); HTRACECALL (*pTraceSQLAllocHandle)(); HTRACECALL (*pTraceSQLAllocHandleStd)(); HTRACECALL (*pTraceSQLAllocStmt)(); HTRACECALL (*pTraceSQLBindCol)(); HTRACECALL (*pTraceSQLBindParam)(); HTRACECALL (*pTraceSQLBindParameter)(); HTRACECALL (*pTraceSQLBrowseConnect)(); HTRACECALL (*pTraceSQLBrowseConnectw)(); HTRACECALL (*pTraceSQLBulkOperations)(); HTRACECALL (*pTraceSQLCancel)(); HTRACECALL (*pTraceSQLCloseCursor)(); HTRACECALL (*pTraceSQLColAttribute)(); HTRACECALL (*pTraceSQLColAttributes)(); HTRACECALL (*pTraceSQLColAttributesW)(); HTRACECALL (*pTraceSQLColAttributeW)(); HTRACECALL (*pTraceSQLColumnPrivileges)(); HTRACECALL (*pTraceSQLColumnPrivilegesW)(); HTRACECALL (*pTraceSQLColumns)(); HTRACECALL (*pTraceSQLColumnsW)(); HTRACECALL (*pTraceSQLConnect)(); HTRACECALL (*pTraceSQLConnectW)(); HTRACECALL (*pTraceSQLCopyDesc)(); HTRACECALL (*pTraceSQLDataSources)(); HTRACECALL (*pTraceSQLDataSourcesW)(); HTRACECALL (*pTraceSQLDescribeCol)(); HTRACECALL (*pTraceSQLDescribeColW)(); HTRACECALL (*pTraceSQLDescribeParam)(); HTRACECALL (*pTraceSQLDisconnect)(); HTRACECALL (*pTraceSQLDriverConnect)(); HTRACECALL (*pTraceSQLDriverConnectW)(); HTRACECALL (*pTraceSQLDrivers)(); HTRACECALL (*pTraceSQLDriversW)(); HTRACECALL (*pTraceSQLEndTran)(); HTRACECALL (*pTraceSQLError)(); HTRACECALL (*pTraceSQLErrorW)(); HTRACECALL (*pTraceSQLExecDirect)(); HTRACECALL (*pTraceSQLExecDirectW)(); HTRACECALL (*pTraceSQLExecute)(); HTRACECALL (*pTraceSQLExtendedFetch)(); HTRACECALL (*pTraceSQLFetch)(); HTRACECALL (*pTraceSQLFetchScroll)(); HTRACECALL (*pTraceSQLForeignKeys)(); HTRACECALL (*pTraceSQLForeignKeysW)(); HTRACECALL (*pTraceSQLFreeConnect)(); HTRACECALL (*pTraceSQLFreeEnv)(); HTRACECALL (*pTraceSQLFreeHandle)(); HTRACECALL (*pTraceSQLFreeStmt)(); HTRACECALL (*pTraceSQLGetConnectAttr)(); HTRACECALL (*pTraceSQLGetConnectAttrW)(); HTRACECALL (*pTraceSQLGetConnectOption)(); HTRACECALL (*pTraceSQLGetConnectOptionW)(); HTRACECALL (*pTraceSQLGetCursorName)(); HTRACECALL (*pTraceSQLGetCursorNameW)(); HTRACECALL (*pTraceSQLGetData)(); HTRACECALL (*pTraceSQLGetDescField)(); HTRACECALL (*pTraceSQLGetDescFieldw)(); HTRACECALL (*pTraceSQLGetDescRec)(); HTRACECALL (*pTraceSQLGetDescRecW)(); HTRACECALL (*pTraceSQLGetDiagField)(); HTRACECALL (*pTraceSQLGetDiagFieldW)(); HTRACECALL (*pTraceSQLGetDiagRec)(); HTRACECALL (*pTraceSQLGetDiagRecW)(); HTRACECALL (*pTraceSQLGetEnvAttr)(); HTRACECALL (*pTraceSQLGetFunctions)(); HTRACECALL (*pTraceSQLGetInfo)(); HTRACECALL (*pTraceSQLGetInfoW)(); HTRACECALL (*pTraceSQLGetStmtAttr)(); HTRACECALL (*pTraceSQLGetStmtAttrW)(); HTRACECALL (*pTraceSQLGetStmtOption)(); HTRACECALL (*pTraceSQLGetTypeInfo)(); HTRACECALL (*pTraceSQLGetTypeInfoW)(); HTRACECALL (*pTraceSQLMoreResults)(); HTRACECALL (*pTraceSQLNativeSql)(); HTRACECALL (*pTraceSQLNativeSqlW)(); HTRACECALL (*pTraceSQLNumParams)(); HTRACECALL (*pTraceSQLNumResultCols)(); HTRACECALL (*pTraceSQLParamData)(); HTRACECALL (*pTraceSQLParamOptions)(); HTRACECALL (*pTraceSQLPrepare)(); HTRACECALL (*pTraceSQLPrepareW)(); HTRACECALL (*pTraceSQLPrimaryKeys)(); HTRACECALL (*pTraceSQLPrimaryKeysw)(); HTRACECALL (*pTraceSQLProcedureColumns)(); HTRACECALL (*pTraceSQLProcedureColumnsw)(); HTRACECALL (*pTraceSQLProcedures)(); HTRACECALL (*pTraceSQLProceduresW)(); HTRACECALL (*pTraceSQLPutData)(); HTRACECALL (*pTraceSQLRowCount)(); HTRACECALL (*pTraceSQLSetConnectAttr)(); HTRACECALL (*pTraceSQLSetConnectAttrW)(); HTRACECALL (*pTraceSQLSetConnectoption)(); HTRACECALL (*pTraceSQLSetConnectoptionW)(); HTRACECALL (*pTraceSQLSetCursorName)(); HTRACECALL (*pTraceSQLSetCursorNameW)(); HTRACECALL (*pTraceSQLSetDescField)(); HTRACECALL (*pTraceSQLSetDescFieldW)(); HTRACECALL (*pTraceSQLSetDescRec)(); HTRACECALL (*pTraceSQLSetDescRecW)(); HTRACECALL (*pTraceSQLSetEnvAttr)(); HTRACECALL (*pTraceSQLSetParam)(); HTRACECALL (*pTraceSQLSetPos)(); HTRACECALL (*pTraceSQLSetScrollOptions)(); HTRACECALL (*pTraceSQLSetStmtAttr)(); HTRACECALL (*pTraceSQLSetStmtAttrW)(); HTRACECALL (*pTraceSQLSetStmtOption)(); HTRACECALL (*pTraceSQLSetStmtOptionW)(); HTRACECALL (*pTraceSQLSpecialColumns)(); HTRACECALL (*pTraceSQLSpecialColumnsW)(); HTRACECALL (*pTraceSQLStatistics)(); HTRACECALL (*pTraceSQLStatisticsW)(); HTRACECALL (*pTraceSQLTablePrivileges)(); HTRACECALL (*pTraceSQLTablePrivilegesW)(); HTRACECALL (*pTraceSQLTables)(); HTRACECALL (*pTraceSQLTablesW)(); HTRACECALL (*pTraceSQLTransact)(); } TRACE, *HTRACE; /*! * \brief Allocates a trace handle. * * Tracing is turned off and no trace plugin is loaded. * * \return HTRACE */ HTRACE traceAlloc(); /*! * \brief Frees trace handle. * * Compliments #traceAlloc. Will call #traceClose as needed. * * This will call #traceClose as needed. * * \param pTrace */ void traceFree( HTRACE pTrace ); /*! * \brief Opens trace plugin. * * This will open/load the trace plugin/library specified in pTrace->szFileName. The * trace output will go to pTrace->szTraceFile. pTrace->nTrace is set to * SQL_OPT_TRACE_ON but can be set to SQL_OPT_TRACE_OFF at any time to 'pause' tracing. * Set it back to SQL_OPT_TRACE_ON to resume tracing. * * \param pTrace * \param pszApplication * * \return int */ int traceOpen( HTRACE pTrace, char *pszApplication ); /*! * \brief Close trace plugin. * * This will close/unload the trace plugin/library. pTrace->nTrace is set to SQL_OPT_TRACE_OFF * but pTrace->szTraceFile and pTrace->szFileName remain unchanged. * * The #traceFree function will silently call #traceClose as needed. * * \param pTrace */ void traceClose( HTRACE pTrace ); /* this is just to shorten the following macros */ #define traceOn ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ) /* these macros are used to call trace plugin functions - they help by calling ONLY if relevant */ #define traceAllocConnect( pTrace, B, C ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLAllocConnect( pTrace->hPlugInInternal, B, C ) : NULL ); #define traceAllocEnv( pTrace, B ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLAllocEnv( pTrace->hPlugInInternal, B ) : NULL ); #define traceAllocHandle( pTrace, B, C, D ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLAllocHandle( pTrace->hPlugInInternal, B, C, D ) : NULL ); #define traceAllocStmt( pTrace, B, C ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLAllocStmt( pTrace->hPlugInInternal, B, C ) : NULL ); #define traceBindCol( pTrace, B, C, D, E, F, G ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLBindCol( pTrace->hPlugInInternal, B, C, D, E, F, G ) : NULL ); #define traceBindParam( pTrace, B, C, D, E, F, G, H, I ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLBindParam( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I ) : NULL ); #define traceBindParameter( pTrace, B, C, D, E, F, G, H, I, J, K ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLBindParameter( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J, K ) : NULL ); #define traceBrowseConnect( pTrace, B, C, D, E, F, G ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLBrowseConnect( pTrace->hPlugInInternal, B, C, D, E, F, G ) : NULL ); #define traceBrowseConnectW( pTrace, B, C, D, E, F, G ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLBrowseConnectW( pTrace->hPlugInInternal, B, C, D, E, F, G ) : NULL ); #define traceBulkOperations( pTrace, B, C ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLBulkOperations( pTrace->hPlugInInternal, B, C ) : NULL ); #define traceCancel( pTrace, B ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLCancel( pTrace->hPlugInInternal, B ) : NULL ); #define traceCloseCursor( pTrace, B ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLCloseCursor( pTrace->hPlugInInternal, B ) : NULL ); #define traceColAttribute( pTrace, B, C, D, E, F, G, H ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLColAttribute( pTrace->hPlugInInternal, B, C, D, E, F, G, H ) : NULL ); #define traceColAttributes( pTrace, B, C, D, E, F, G, H ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLColAttributes( pTrace->hPlugInInternal, B, C, D, E, F, G, H ) : NULL ); #define traceColAttributesW( pTrace, B, C, D, E, F, G, H ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLColAttributesW( pTrace->hPlugInInternal, B, C, D, E, F, G, H ) : NULL ); #define traceColAttributeW( pTrace, B, C, D, E, F, G, H ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLColAttributeW( pTrace->hPlugInInternal, B, C, D, E, F, G, H ) : NULL ); #define traceColumnPrivileges( pTrace, B, C, D, E, F, G, H, I, J ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLColumnPrivileges( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J ) : NULL ); #define traceColumnPrivilegesW( pTrace, B, C, D, E, F, G, H, I, J ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLColumnPrivilegesW( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J ) : NULL ); #define traceColumns( pTrace, B, C, D, E, F, G, H, I, J ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLColumns( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J ) : NULL ); #define traceColumnsW( pTrace, B, C, D, E, F, G, H, I, J ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLColumnsW( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J ) : NULL ); #define traceConnect( pTrace, B, C, D, E, F, G, H ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLConnect( pTrace->hPlugInInternal, B, C, D, E, F, G, H ) : NULL ); #define traceConnectW( pTrace, B, C, D, E, F, G, H ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLConnectW( pTrace->hPlugInInternal, B, C, D, E, F, G, H ) : NULL ); #define traceCopyDesc( pTrace, B, C ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLCopyDesc( pTrace->hPlugInInternal, B, C ) : NULL ); #define traceDataSources( pTrace, B, C, D, E, F, G, H, I ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLDataSources( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I ) : NULL ); #define traceDataSourcesW( pTrace, B, C, D, E, F, G, H, I ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLDataSourcesW( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I ) : NULL ); #define traceDescribeCol( pTrace, B, C, D, E, F, G, H, I, J ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLDescribeCol( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J ) : NULL ); #define traceDescribeColW( pTrace, B, C, D, E, F, G, H, I, J ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLDescribeColW( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J ) : NULL ); #define traceDescribeParam( pTrace, B, C, D, E, F, G ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLDescribeParam( pTrace->hPlugInInternal, B, C, D, E, F, G ) : NULL ); #define traceDisconnect( pTrace, B ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLDisconnect( pTrace->hPlugInInternal, B ) : NULL ); #define traceDriverConnect( pTrace, B, C, D, E, F, G, H, I ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLDriverConnect( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I ) : NULL ); #define traceDriverConnectW( pTrace, B, C, D, E, F, G, H, I ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLDriverConnectW( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I ) : NULL ); #define traceDrivers( pTrace, B, C, D, E, F, G, H, I ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLDrivers( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I ) : NULL ); #define traceDriversW( pTrace, B, C, D, E, F, G, H, I ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLDriversW( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I ) : NULL ); #define traceEndTran( pTrace, B, C, D ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLEndTran( pTrace->hPlugInInternal, B, C, D ) : NULL ); #define traceError( pTrace, B, C, D, E, F, G, H, I ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLError( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I ) : NULL ); #define traceErrorW( pTrace, B, C, D, E, F, G, H, I ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLErrorW( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I ) : NULL ); #define traceExecDirect( pTrace, B, C, D ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLExecDirect( pTrace->hPlugInInternal, B, C, D ) : NULL ); #define traceExecDirectW( pTrace, B, C, D ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLExecDirectW( pTrace->hPlugInInternal, B, C, D ) : NULL ); #define traceExecute( pTrace, B ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLExecute( pTrace->hPlugInInternal, B ) : NULL ); #define traceExtendedFetch( pTrace, B, C, D, E, F ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLExtendedFetch( pTrace->hPlugInInternal, B, C, D, E, F ) : NULL ); #define traceFetch( pTrace, B ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLFetch( pTrace->hPlugInInternal, B ) : NULL ); #define traceFetchScroll( pTrace, B, C, D ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLFetchScroll( pTrace->hPlugInInternal, B, C, D ) : NULL ); #define traceForeignKeys( pTrace, B, C, D, E, F, G, H, I, J, K, L, M, N ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLForeignKeys( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J, K, L, M, N ) : NULL ); #define traceForeignKeysW( pTrace, B, C, D, E, F, G, H, I, J, K, L, M, N ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLForeignKeysW( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J, K, L, M, N ) : NULL ); #define traceFreeConnect( pTrace, B ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLFreeConnect( pTrace->hPlugInInternal, B ) : NULL ); #define traceFreeEnv( pTrace, B ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLFreeEnv( pTrace->hPlugInInternal, B ) : NULL ); #define traceFreeHandle( pTrace, B, C ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLFreeHandle( pTrace->hPlugInInternal, B, C ) : NULL ); #define traceFreeStmt( pTrace, B, C ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLFreeStmt( pTrace->hPlugInInternal, B, C ) : NULL ); #define traceGetConnectAttr( pTrace, B, C, D, E, F ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLGetConnectAttr( pTrace->hPlugInInternal, B, C, D, E, F ) : NULL ); #define traceGetCursorName( pTrace, B, C, D, E ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLGetCursorName( pTrace->hPlugInInternal, B, C, D, E ) : NULL ); #define traceGetData( pTrace, B, C, D, E, F, G ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLGetData( pTrace->hPlugInInternal, B, C, D, E, F, G ) : NULL ); #define traceGetDescField( pTrace, B, C, D, E, F, G ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLGetDescField( pTrace->hPlugInInternal, B, C, D, E, F, G ) : NULL ); #define traceGetDescRec( pTrace, B, C, D, E, F, G, H, I, J, K, L ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLGetDescRec( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J, K, L ) : NULL ); #define traceGetDiagField( pTrace, B, C, D, E, F, G, H ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLGetDiagField( pTrace->hPlugInInternal, B, C, D, E, F, G, H ) : NULL ); #define traceGetDiagRec( pTrace, B, C, D, E, F, G, H, I ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLGetDiagRec( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I ) : NULL ); #define traceGetEnvAttr( pTrace, B, C, D, E, F ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLGetEnvAttr( pTrace->hPlugInInternal, B, C, D, E, F ) : NULL ); #define traceGetFunctions( pTrace, B, C, D ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLGetFunctions( pTrace->hPlugInInternal, B, C, D ) : NULL ); #define traceGetInfo( pTrace, B, C, D, E, F ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLGetInfo( pTrace->hPlugInInternal, B, C, D, E, F ) : NULL ); #define traceGetStmtAttr( pTrace, B, C, D, E, F ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLGetStmtAttr( pTrace->hPlugInInternal, B, C, D, E, F ) : NULL ); #define traceGetTypeInfo( pTrace, B, C ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLGetTypeInfo( pTrace->hPlugInInternal, B, C ) : NULL ); #define traceMoreResults( pTrace, B ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLMoreResults( pTrace->hPlugInInternal, B ) : NULL ); #define traceNativeSql( pTrace, B, C, D, E, F, G ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLNativeSql( pTrace->hPlugInInternal, B, C, D, E, F, G ) : NULL ); #define traceNumParams( pTrace, B, C ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLNumParams( pTrace->hPlugInInternal, B, C ) : NULL ); #define traceNumResultCols( pTrace, B, C ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLNumResultCols( pTrace->hPlugInInternal, B, C ) : NULL ); #define traceNumParamData( pTrace, B, C ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLParamData( pTrace->hPlugInInternal, B, C ) : NULL ); #define traceParamOptions( pTrace, B, C, D ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLParamOptions( pTrace->hPlugInInternal, B, C, D ) : NULL ); #define tracePrepare( pTrace, B, C, D ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLPrepare( pTrace->hPlugInInternal, B, C, D ) : NULL ); #define tracePrimaryKeys( pTrace, B, C, D, E, F, G, H ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLPrimaryKeys( pTrace->hPlugInInternal, B, C, D, E, F, G, H ) : NULL ); #define traceProcedureColumns( pTrace, B, C, D, E, F, G, H, I, J ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLProcedureColumns( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J ) : NULL ); #define traceProcedures( pTrace, B, C, D, E, F, G, H ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLProcedures( pTrace->hPlugInInternal, B, C, D, E, F, G, H ) : NULL ); #define tracePutData( pTrace, B, C, D ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLPutData( pTrace->hPlugInInternal, B, C, D ) : NULL ); #define traceRowCount( pTrace, B, C ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLRowCount( pTrace->hPlugInInternal, B, C ) : NULL ); #define traceSetConnectAttr( pTrace, B, C, D, E ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLSetConnectAttr( pTrace->hPlugInInternal, B, C, D, E ) : NULL ); #define traceSetCursorName( pTrace, B, C, D ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLSetCursorName( pTrace->hPlugInInternal, B, C, D ) : NULL ); #define traceSetDescField( pTrace, B, C, D, E, F ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLSetDescField( pTrace->hPlugInInternal, B, C, D, E, F ) : NULL ); #define traceSetDescRec( pTrace, B, C, D, E, F, G, H, I, J, K ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLSetDescRec( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J, K ) : NULL ); #define traceSetEnvAttr( pTrace, B, C, D, E ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLSetEnvAttr( pTrace->hPlugInInternal, B, C, D, E ) : NULL ); #define traceSetPos( pTrace, B, C, D, E ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLSetPos( pTrace->hPlugInInternal, B, C, D, E ) : NULL ); #define traceSetScrollOptions( pTrace, B, C, D, E ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLSetScrollOptions( pTrace->hPlugInInternal, B, C, D, E ) : NULL ); #define traceSetStmtAttr( pTrace, B, C, D, E ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLSetStmtAttr( pTrace->hPlugInInternal, B, C, D, E ) : NULL ); #define traceSpecialColumns( pTrace, B, C, D, E, F, G, H, I, J, K ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLSpecialColumns( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J, K ) : NULL ); #define traceStatistics( pTrace, B, C, D, E, F, G, H, I, J ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLStatistics( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J ) : NULL ); #define traceTablePrivileges( pTrace, B, C, D, E, F, G, H ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLTablePrivileges( pTrace->hPlugInInternal, B, C, D, E, F, G, H ) : NULL ); #define traceTables( pTrace, B, C, D, E, F, G, H, I, J ) ( pTrace->hPlugIn && pTrace->nTrace == SQL_OPT_TRACE_ON ? pTrace->pTraceSQLTables( pTrace->hPlugInInternal, B, C, D, E, F, G, H, I, J ) : NULL ); #define traceReturn( pTrace, pCall, nReturn ) ( pCall ? pTrace->pTraceReturn( pCall, nReturn ) : nReturn ); #endif unixODBC-2.3.12/include/sql.h000066400000000000000000000771731446441710500156320ustar00rootroot00000000000000/************************************************** * sql.h * * These should be consistent with the MS version. * **************************************************/ #ifndef __SQL_H #define __SQL_H /**************************** * default to 3.51 declare something else before here and you get a whole new ball of wax ***************************/ #ifndef ODBCVER #define ODBCVER 0x0380 #endif #ifndef __SQLTYPES_H #include "sqltypes.h" #endif #ifdef __cplusplus extern "C" { #endif /**************************** * some ret values ***************************/ #define SQL_NULL_DATA (-1) #define SQL_DATA_AT_EXEC (-2) #define SQL_SUCCESS 0 #define SQL_SUCCESS_WITH_INFO 1 #if (ODBCVER >= 0x0300) #define SQL_NO_DATA 100 #endif #define SQL_ERROR (-1) #define SQL_INVALID_HANDLE (-2) #define SQL_STILL_EXECUTING 2 #define SQL_NEED_DATA 99 #define SQL_SUCCEEDED(rc) (((rc)&(~1))==0) #if (ODBCVER >= 0x0380) #define SQL_PARAM_DATA_AVAILABLE 101 #endif /**************************** * use these to indicate string termination to some function ***************************/ #define SQL_NTS (-3) #define SQL_NTSL (-3L) /* maximum message length */ #define SQL_MAX_MESSAGE_LENGTH 512 /* date/time length constants */ #if (ODBCVER >= 0x0300) #define SQL_DATE_LEN 10 #define SQL_TIME_LEN 8 /* add P+1 if precision is nonzero */ #define SQL_TIMESTAMP_LEN 19 /* add P+1 if precision is nonzero */ #endif /* handle type identifiers */ #if (ODBCVER >= 0x0300) #define SQL_HANDLE_ENV 1 #define SQL_HANDLE_DBC 2 #define SQL_HANDLE_STMT 3 #define SQL_HANDLE_DESC 4 #endif /* environment attribute */ #if (ODBCVER >= 0x0300) #define SQL_ATTR_OUTPUT_NTS 10001 #endif /* connection attributes */ #if (ODBCVER >= 0x0300) #define SQL_ATTR_AUTO_IPD 10001 #define SQL_ATTR_METADATA_ID 10014 #endif /* ODBCVER >= 0x0300 */ /* statement attributes */ #if (ODBCVER >= 0x0300) #define SQL_ATTR_APP_ROW_DESC 10010 #define SQL_ATTR_APP_PARAM_DESC 10011 #define SQL_ATTR_IMP_ROW_DESC 10012 #define SQL_ATTR_IMP_PARAM_DESC 10013 #define SQL_ATTR_CURSOR_SCROLLABLE (-1) #define SQL_ATTR_CURSOR_SENSITIVITY (-2) #endif /* SQL_ATTR_CURSOR_SCROLLABLE values */ #if (ODBCVER >= 0x0300) #define SQL_NONSCROLLABLE 0 #define SQL_SCROLLABLE 1 #endif /* ODBCVER >= 0x0300 */ /* identifiers of fields in the SQL descriptor */ #if (ODBCVER >= 0x0300) #define SQL_DESC_COUNT 1001 #define SQL_DESC_TYPE 1002 #define SQL_DESC_LENGTH 1003 #define SQL_DESC_OCTET_LENGTH_PTR 1004 #define SQL_DESC_PRECISION 1005 #define SQL_DESC_SCALE 1006 #define SQL_DESC_DATETIME_INTERVAL_CODE 1007 #define SQL_DESC_NULLABLE 1008 #define SQL_DESC_INDICATOR_PTR 1009 #define SQL_DESC_DATA_PTR 1010 #define SQL_DESC_NAME 1011 #define SQL_DESC_UNNAMED 1012 #define SQL_DESC_OCTET_LENGTH 1013 #define SQL_DESC_ALLOC_TYPE 1099 #endif /* identifiers of fields in the diagnostics area */ #if (ODBCVER >= 0x0300) #define SQL_DIAG_RETURNCODE 1 #define SQL_DIAG_NUMBER 2 #define SQL_DIAG_ROW_COUNT 3 #define SQL_DIAG_SQLSTATE 4 #define SQL_DIAG_NATIVE 5 #define SQL_DIAG_MESSAGE_TEXT 6 #define SQL_DIAG_DYNAMIC_FUNCTION 7 #define SQL_DIAG_CLASS_ORIGIN 8 #define SQL_DIAG_SUBCLASS_ORIGIN 9 #define SQL_DIAG_CONNECTION_NAME 10 #define SQL_DIAG_SERVER_NAME 11 #define SQL_DIAG_DYNAMIC_FUNCTION_CODE 12 #endif /* dynamic function codes */ #if (ODBCVER >= 0x0300) #define SQL_DIAG_ALTER_DOMAIN 3 #define SQL_DIAG_ALTER_TABLE 4 #define SQL_DIAG_CALL 7 #define SQL_DIAG_CREATE_ASSERTION 6 #define SQL_DIAG_CREATE_CHARACTER_SET 8 #define SQL_DIAG_CREATE_COLLATION 10 #define SQL_DIAG_CREATE_DOMAIN 23 #define SQL_DIAG_CREATE_INDEX (-1) #define SQL_DIAG_CREATE_SCHEMA 64 #define SQL_DIAG_CREATE_TABLE 77 #define SQL_DIAG_CREATE_TRANSLATION 79 #define SQL_DIAG_CREATE_VIEW 84 #define SQL_DIAG_DELETE_WHERE 19 #define SQL_DIAG_DROP_ASSERTION 24 #define SQL_DIAG_DROP_CHARACTER_SET 25 #define SQL_DIAG_DROP_COLLATION 26 #define SQL_DIAG_DROP_DOMAIN 27 #define SQL_DIAG_DROP_INDEX (-2) #define SQL_DIAG_DROP_SCHEMA 31 #define SQL_DIAG_DROP_TABLE 32 #define SQL_DIAG_DROP_TRANSLATION 33 #define SQL_DIAG_DROP_VIEW 36 #define SQL_DIAG_DYNAMIC_DELETE_CURSOR 38 #define SQL_DIAG_DYNAMIC_UPDATE_CURSOR 81 #define SQL_DIAG_GRANT 48 #define SQL_DIAG_INSERT 50 #define SQL_DIAG_REVOKE 59 #define SQL_DIAG_SELECT_CURSOR 85 #define SQL_DIAG_UNKNOWN_STATEMENT 0 #define SQL_DIAG_UPDATE_WHERE 82 #endif /* ODBCVER >= 0x0300 */ /* SQL data type codes */ #define SQL_UNKNOWN_TYPE 0 #define SQL_CHAR 1 #define SQL_NUMERIC 2 #define SQL_DECIMAL 3 #define SQL_INTEGER 4 #define SQL_SMALLINT 5 #define SQL_FLOAT 6 #define SQL_REAL 7 #define SQL_DOUBLE 8 #if (ODBCVER >= 0x0300) #define SQL_DATETIME 9 #endif #define SQL_VARCHAR 12 /* One-parameter shortcuts for date/time data types */ #if (ODBCVER >= 0x0300) #define SQL_TYPE_DATE 91 #define SQL_TYPE_TIME 92 #define SQL_TYPE_TIMESTAMP 93 #endif /* Statement attribute values for cursor sensitivity */ #if (ODBCVER >= 0x0300) #define SQL_UNSPECIFIED 0 #define SQL_INSENSITIVE 1 #define SQL_SENSITIVE 2 #endif /* GetTypeInfo() request for all data types */ #define SQL_ALL_TYPES 0 /* Default conversion code for SQLBindCol(), SQLBindParam() and SQLGetData() */ #if (ODBCVER >= 0x0300) #define SQL_DEFAULT 99 #endif /* SQLGetData() code indicating that the application row descriptor * specifies the data type */ #if (ODBCVER >= 0x0300) #define SQL_ARD_TYPE (-99) #endif /* SQL date/time type subcodes */ #if (ODBCVER >= 0x0300) #define SQL_CODE_DATE 1 #define SQL_CODE_TIME 2 #define SQL_CODE_TIMESTAMP 3 #endif /* CLI option values */ #if (ODBCVER >= 0x0300) #define SQL_FALSE 0 #define SQL_TRUE 1 #endif /* values of NULLABLE field in descriptor */ #define SQL_NO_NULLS 0 #define SQL_NULLABLE 1 /* Value returned by SQLGetTypeInfo() to denote that it is * not known whether or not a data type supports null values. */ #define SQL_NULLABLE_UNKNOWN 2 /* Values returned by SQLGetTypeInfo() to show WHERE clause * supported */ #if (ODBCVER >= 0x0300) #define SQL_PRED_NONE 0 #define SQL_PRED_CHAR 1 #define SQL_PRED_BASIC 2 #endif /* values of UNNAMED field in descriptor */ #if (ODBCVER >= 0x0300) #define SQL_NAMED 0 #define SQL_UNNAMED 1 #endif /* values of ALLOC_TYPE field in descriptor */ #if (ODBCVER >= 0x0300) #define SQL_DESC_ALLOC_AUTO 1 #define SQL_DESC_ALLOC_USER 2 #endif /* FreeStmt() options */ #define SQL_CLOSE 0 #define SQL_DROP 1 #define SQL_UNBIND 2 #define SQL_RESET_PARAMS 3 /* Codes used for FetchOrientation in SQLFetchScroll(), and in SQLDataSources() */ #define SQL_FETCH_NEXT 1 #define SQL_FETCH_FIRST 2 /* Other codes used for FetchOrientation in SQLFetchScroll() */ #define SQL_FETCH_LAST 3 #define SQL_FETCH_PRIOR 4 #define SQL_FETCH_ABSOLUTE 5 #define SQL_FETCH_RELATIVE 6 /* SQLEndTran() options */ #define SQL_COMMIT 0 #define SQL_ROLLBACK 1 /* null handles returned by SQLAllocHandle() */ #define SQL_NULL_HENV 0 #define SQL_NULL_HDBC 0 #define SQL_NULL_HSTMT 0 #if (ODBCVER >= 0x0300) #define SQL_NULL_HDESC 0 #define SQL_NULL_DESC 0 #endif /* null handle used in place of parent handle when allocating HENV */ #if (ODBCVER >= 0x0300) #define SQL_NULL_HANDLE 0L #endif /* Values that may appear in the result set of SQLSpecialColumns() */ #define SQL_SCOPE_CURROW 0 #define SQL_SCOPE_TRANSACTION 1 #define SQL_SCOPE_SESSION 2 #define SQL_PC_UNKNOWN 0 #if (ODBCVER >= 0x0300) #define SQL_PC_NON_PSEUDO 1 #endif #define SQL_PC_PSEUDO 2 /* Reserved value for the IdentifierType argument of SQLSpecialColumns() */ #if (ODBCVER >= 0x0300) #define SQL_ROW_IDENTIFIER 1 #endif /* Reserved values for UNIQUE argument of SQLStatistics() */ #define SQL_INDEX_UNIQUE 0 #define SQL_INDEX_ALL 1 /* Values that may appear in the result set of SQLStatistics() */ #define SQL_INDEX_CLUSTERED 1 #define SQL_INDEX_HASHED 2 #define SQL_INDEX_OTHER 3 /* SQLGetFunctions() values to identify ODBC APIs */ #define SQL_API_SQLALLOCCONNECT 1 #define SQL_API_SQLALLOCENV 2 #if (ODBCVER >= 0x0300) #define SQL_API_SQLALLOCHANDLE 1001 #endif #define SQL_API_SQLALLOCSTMT 3 #define SQL_API_SQLBINDCOL 4 #if (ODBCVER >= 0x0300) #define SQL_API_SQLBINDPARAM 1002 #endif #define SQL_API_SQLCANCEL 5 #if (ODBCVER >= 0x0300) #define SQL_API_SQLCLOSECURSOR 1003 #define SQL_API_SQLCOLATTRIBUTE 6 #endif #define SQL_API_SQLCOLUMNS 40 #define SQL_API_SQLCONNECT 7 #if (ODBCVER >= 0x0300) #define SQL_API_SQLCOPYDESC 1004 #endif #define SQL_API_SQLDATASOURCES 57 #define SQL_API_SQLDESCRIBECOL 8 #define SQL_API_SQLDISCONNECT 9 #if (ODBCVER >= 0x0300) #define SQL_API_SQLENDTRAN 1005 #endif #define SQL_API_SQLERROR 10 #define SQL_API_SQLEXECDIRECT 11 #define SQL_API_SQLEXECUTE 12 #define SQL_API_SQLFETCH 13 #if (ODBCVER >= 0x0300) #define SQL_API_SQLFETCHSCROLL 1021 #endif #define SQL_API_SQLFREECONNECT 14 #define SQL_API_SQLFREEENV 15 #if (ODBCVER >= 0x0300) #define SQL_API_SQLFREEHANDLE 1006 #endif #define SQL_API_SQLFREESTMT 16 #if (ODBCVER >= 0x0300) #define SQL_API_SQLGETCONNECTATTR 1007 #endif #define SQL_API_SQLGETCONNECTOPTION 42 #define SQL_API_SQLGETCURSORNAME 17 #define SQL_API_SQLGETDATA 43 #if (ODBCVER >= 0x0300) #define SQL_API_SQLGETDESCFIELD 1008 #define SQL_API_SQLGETDESCREC 1009 #define SQL_API_SQLGETDIAGFIELD 1010 #define SQL_API_SQLGETDIAGREC 1011 #define SQL_API_SQLGETENVATTR 1012 #endif #define SQL_API_SQLGETFUNCTIONS 44 #define SQL_API_SQLGETINFO 45 #if (ODBCVER >= 0x0300) #define SQL_API_SQLGETSTMTATTR 1014 #endif #define SQL_API_SQLGETSTMTOPTION 46 #define SQL_API_SQLGETTYPEINFO 47 #define SQL_API_SQLNUMRESULTCOLS 18 #define SQL_API_SQLPARAMDATA 48 #define SQL_API_SQLPREPARE 19 #define SQL_API_SQLPUTDATA 49 #define SQL_API_SQLROWCOUNT 20 #if (ODBCVER >= 0x0300) #define SQL_API_SQLSETCONNECTATTR 1016 #endif #define SQL_API_SQLSETCONNECTOPTION 50 #define SQL_API_SQLSETCURSORNAME 21 #if (ODBCVER >= 0x0300) #define SQL_API_SQLSETDESCFIELD 1017 #define SQL_API_SQLSETDESCREC 1018 #define SQL_API_SQLSETENVATTR 1019 #endif #define SQL_API_SQLSETPARAM 22 #if (ODBCVER >= 0x0300) #define SQL_API_SQLSETSTMTATTR 1020 #endif #define SQL_API_SQLSETSTMTOPTION 51 #define SQL_API_SQLSPECIALCOLUMNS 52 #define SQL_API_SQLSTATISTICS 53 #define SQL_API_SQLTABLES 54 #define SQL_API_SQLTRANSACT 23 #if (ODBCVER >= 0x0380) #define SQL_API_SQLCANCELHANDLE 1022 #endif /* Information requested by SQLGetInfo() */ #if (ODBCVER >= 0x0300) #define SQL_MAX_DRIVER_CONNECTIONS 0 #define SQL_MAXIMUM_DRIVER_CONNECTIONS SQL_MAX_DRIVER_CONNECTIONS #define SQL_MAX_CONCURRENT_ACTIVITIES 1 #define SQL_MAXIMUM_CONCURRENT_ACTIVITIES SQL_MAX_CONCURRENT_ACTIVITIES #endif #define SQL_DATA_SOURCE_NAME 2 #define SQL_FETCH_DIRECTION 8 #define SQL_SERVER_NAME 13 #define SQL_SEARCH_PATTERN_ESCAPE 14 #define SQL_DBMS_NAME 17 #define SQL_DBMS_VER 18 #define SQL_ACCESSIBLE_TABLES 19 #define SQL_ACCESSIBLE_PROCEDURES 20 #define SQL_CURSOR_COMMIT_BEHAVIOR 23 #define SQL_DATA_SOURCE_READ_ONLY 25 #define SQL_DEFAULT_TXN_ISOLATION 26 #define SQL_IDENTIFIER_CASE 28 #define SQL_IDENTIFIER_QUOTE_CHAR 29 #define SQL_MAX_COLUMN_NAME_LEN 30 #define SQL_MAXIMUM_COLUMN_NAME_LENGTH SQL_MAX_COLUMN_NAME_LEN #define SQL_MAX_CURSOR_NAME_LEN 31 #define SQL_MAXIMUM_CURSOR_NAME_LENGTH SQL_MAX_CURSOR_NAME_LEN #define SQL_MAX_SCHEMA_NAME_LEN 32 #define SQL_MAXIMUM_SCHEMA_NAME_LENGTH SQL_MAX_SCHEMA_NAME_LEN #define SQL_MAX_CATALOG_NAME_LEN 34 #define SQL_MAXIMUM_CATALOG_NAME_LENGTH SQL_MAX_CATALOG_NAME_LEN #define SQL_MAX_TABLE_NAME_LEN 35 #define SQL_SCROLL_CONCURRENCY 43 #define SQL_TXN_CAPABLE 46 #define SQL_TRANSACTION_CAPABLE SQL_TXN_CAPABLE #define SQL_USER_NAME 47 #define SQL_TXN_ISOLATION_OPTION 72 #define SQL_TRANSACTION_ISOLATION_OPTION SQL_TXN_ISOLATION_OPTION #define SQL_INTEGRITY 73 #define SQL_GETDATA_EXTENSIONS 81 #define SQL_NULL_COLLATION 85 #define SQL_ALTER_TABLE 86 #define SQL_ORDER_BY_COLUMNS_IN_SELECT 90 #define SQL_SPECIAL_CHARACTERS 94 #define SQL_MAX_COLUMNS_IN_GROUP_BY 97 #define SQL_MAXIMUM_COLUMNS_IN_GROUP_BY SQL_MAX_COLUMNS_IN_GROUP_BY #define SQL_MAX_COLUMNS_IN_INDEX 98 #define SQL_MAXIMUM_COLUMNS_IN_INDEX SQL_MAX_COLUMNS_IN_INDEX #define SQL_MAX_COLUMNS_IN_ORDER_BY 99 #define SQL_MAXIMUM_COLUMNS_IN_ORDER_BY SQL_MAX_COLUMNS_IN_ORDER_BY #define SQL_MAX_COLUMNS_IN_SELECT 100 #define SQL_MAXIMUM_COLUMNS_IN_SELECT SQL_MAX_COLUMNS_IN_SELECT #define SQL_MAX_COLUMNS_IN_TABLE 101 #define SQL_MAX_INDEX_SIZE 102 #define SQL_MAXIMUM_INDEX_SIZE SQL_MAX_INDEX_SIZE #define SQL_MAX_ROW_SIZE 104 #define SQL_MAXIMUM_ROW_SIZE SQL_MAX_ROW_SIZE #define SQL_MAX_STATEMENT_LEN 105 #define SQL_MAXIMUM_STATEMENT_LENGTH SQL_MAX_STATEMENT_LEN #define SQL_MAX_TABLES_IN_SELECT 106 #define SQL_MAXIMUM_TABLES_IN_SELECT SQL_MAX_TABLES_IN_SELECT #define SQL_MAX_USER_NAME_LEN 107 #define SQL_MAXIMUM_USER_NAME_LENGTH SQL_MAX_USER_NAME_LEN #if (ODBCVER >= 0x0300) #define SQL_OJ_CAPABILITIES 115 #define SQL_OUTER_JOIN_CAPABILITIES SQL_OJ_CAPABILITIES #endif /* ODBCVER >= 0x0300 */ #if (ODBCVER >= 0x0300) #define SQL_XOPEN_CLI_YEAR 10000 #define SQL_CURSOR_SENSITIVITY 10001 #define SQL_DESCRIBE_PARAMETER 10002 #define SQL_CATALOG_NAME 10003 #define SQL_COLLATION_SEQ 10004 #define SQL_MAX_IDENTIFIER_LEN 10005 #define SQL_MAXIMUM_IDENTIFIER_LENGTH SQL_MAX_IDENTIFIER_LEN #endif /* ODBCVER >= 0x0300 */ /* SQL_ALTER_TABLE bitmasks */ #if (ODBCVER >= 0x0200) #define SQL_AT_ADD_COLUMN 0x00000001L #define SQL_AT_DROP_COLUMN 0x00000002L #endif /* ODBCVER >= 0x0200 */ #if (ODBCVER >= 0x0300) #define SQL_AT_ADD_CONSTRAINT 0x00000008L /* The following bitmasks are ODBC extensions and defined in sqlext.h *#define SQL_AT_COLUMN_SINGLE 0x00000020L *#define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L *#define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L *#define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L *#define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L *#define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L *#define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L *#define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L *#define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L *#define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L *#define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L *#define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L *#define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L *#define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L *#define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L */ #endif /* ODBCVER >= 0x0300 */ /* SQL_ASYNC_MODE values */ #if (ODBCVER >= 0x0300) #define SQL_AM_NONE 0 #define SQL_AM_CONNECTION 1 #define SQL_AM_STATEMENT 2 #endif /* SQL_CURSOR_COMMIT_BEHAVIOR values */ #define SQL_CB_DELETE 0 #define SQL_CB_CLOSE 1 #define SQL_CB_PRESERVE 2 /* SQL_FETCH_DIRECTION bitmasks */ #define SQL_FD_FETCH_NEXT 0x00000001L #define SQL_FD_FETCH_FIRST 0x00000002L #define SQL_FD_FETCH_LAST 0x00000004L #define SQL_FD_FETCH_PRIOR 0x00000008L #define SQL_FD_FETCH_ABSOLUTE 0x00000010L #define SQL_FD_FETCH_RELATIVE 0x00000020L /* SQL_GETDATA_EXTENSIONS bitmasks */ #define SQL_GD_ANY_COLUMN 0x00000001L #define SQL_GD_ANY_ORDER 0x00000002L /* SQL_IDENTIFIER_CASE values */ #define SQL_IC_UPPER 1 #define SQL_IC_LOWER 2 #define SQL_IC_SENSITIVE 3 #define SQL_IC_MIXED 4 /* SQL_OJ_CAPABILITIES bitmasks */ /* NB: this means 'outer join', not what you may be thinking */ #if (ODBCVER >= 0x0201) #define SQL_OJ_LEFT 0x00000001L #define SQL_OJ_RIGHT 0x00000002L #define SQL_OJ_FULL 0x00000004L #define SQL_OJ_NESTED 0x00000008L #define SQL_OJ_NOT_ORDERED 0x00000010L #define SQL_OJ_INNER 0x00000020L #define SQL_OJ_ALL_COMPARISON_OPS 0x00000040L #endif /* SQL_SCROLL_CONCURRENCY bitmasks */ #define SQL_SCCO_READ_ONLY 0x00000001L #define SQL_SCCO_LOCK 0x00000002L #define SQL_SCCO_OPT_ROWVER 0x00000004L #define SQL_SCCO_OPT_VALUES 0x00000008L /* SQL_TXN_CAPABLE values */ #define SQL_TC_NONE 0 #define SQL_TC_DML 1 #define SQL_TC_ALL 2 #define SQL_TC_DDL_COMMIT 3 #define SQL_TC_DDL_IGNORE 4 /* SQL_TXN_ISOLATION_OPTION bitmasks */ #define SQL_TXN_READ_UNCOMMITTED 0x00000001L #define SQL_TRANSACTION_READ_UNCOMMITTED SQL_TXN_READ_UNCOMMITTED #define SQL_TXN_READ_COMMITTED 0x00000002L #define SQL_TRANSACTION_READ_COMMITTED SQL_TXN_READ_COMMITTED #define SQL_TXN_REPEATABLE_READ 0x00000004L #define SQL_TRANSACTION_REPEATABLE_READ SQL_TXN_REPEATABLE_READ #define SQL_TXN_SERIALIZABLE 0x00000008L #define SQL_TRANSACTION_SERIALIZABLE SQL_TXN_SERIALIZABLE /* SQL_NULL_COLLATION values */ #define SQL_NC_HIGH 0 #define SQL_NC_LOW 1 SQLRETURN SQL_API SQLAllocConnect(SQLHENV EnvironmentHandle, SQLHDBC *ConnectionHandle); SQLRETURN SQL_API SQLAllocEnv(SQLHENV *EnvironmentHandle); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandle); #endif SQLRETURN SQL_API SQLAllocStmt(SQLHDBC ConnectionHandle, SQLHSTMT *StatementHandle); SQLRETURN SQL_API SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLBindParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, SQLSMALLINT ParameterType, SQLULEN LengthPrecision, SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue, SQLLEN *StrLen_or_Ind); #endif SQLRETURN SQL_API SQLCancel(SQLHSTMT StatementHandle); #if (ODBCVER >= 0x0380) SQLRETURN SQL_API SQLCancelHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle); #endif #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLCloseCursor(SQLHSTMT StatementHandle); SQLRETURN SQL_API SQLColAttribute(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier, SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, SQLLEN *NumericAttribute ); /* spec says (SQLPOINTER) not (SQLEN*) - PAH */ /* Ms now say SQLLEN* http://msdn.microsoft.com/library/en-us/odbc/htm/dasdkodbcoverview_64bit.asp - NG */ #endif SQLRETURN SQL_API SQLColumns(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLSMALLINT NameLength1, SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLCHAR *ColumnName, SQLSMALLINT NameLength4); SQLRETURN SQL_API SQLConnect(SQLHDBC ConnectionHandle, SQLCHAR *ServerName, SQLSMALLINT NameLength1, SQLCHAR *UserName, SQLSMALLINT NameLength2, SQLCHAR *Authentication, SQLSMALLINT NameLength3); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLCopyDesc(SQLHDESC SourceDescHandle, SQLHDESC TargetDescHandle); #endif SQLRETURN SQL_API SQLDataSources(SQLHENV EnvironmentHandle, SQLUSMALLINT Direction, SQLCHAR *ServerName, SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, SQLCHAR *Description, SQLSMALLINT BufferLength2, SQLSMALLINT *NameLength2); SQLRETURN SQL_API SQLDescribeCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLCHAR *ColumnName, SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, SQLSMALLINT *DataType, SQLULEN *ColumnSize, SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable); SQLRETURN SQL_API SQLDisconnect(SQLHDBC ConnectionHandle); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT CompletionType); #endif SQLRETURN SQL_API SQLError(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle, SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLength); SQLRETURN SQL_API SQLExecDirect(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength); SQLRETURN SQL_API SQLExecute(SQLHSTMT StatementHandle); SQLRETURN SQL_API SQLFetch(SQLHSTMT StatementHandle); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLFetchScroll(SQLHSTMT StatementHandle, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset); #endif SQLRETURN SQL_API SQLFreeConnect(SQLHDBC ConnectionHandle); SQLRETURN SQL_API SQLFreeEnv(SQLHENV EnvironmentHandle); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle); #endif SQLRETURN SQL_API SQLFreeStmt(SQLHSTMT StatementHandle, SQLUSMALLINT Option); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength); #endif SQLRETURN SQL_API SQLGetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLPOINTER Value); SQLRETURN SQL_API SQLGetCursorName(SQLHSTMT StatementHandle, SQLCHAR *CursorName, SQLSMALLINT BufferLength, SQLSMALLINT *NameLength); SQLRETURN SQL_API SQLGetData(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind); #if (ODBCVER >= 0x0300) SQLRETURN SQLGetDescField(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength); SQLRETURN SQL_API SQLGetDescRec(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLCHAR *Name, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, SQLSMALLINT *Type, SQLSMALLINT *SubType, SQLLEN *Length, SQLSMALLINT *Precision, SQLSMALLINT *Scale, SQLSMALLINT *Nullable); SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier, SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength); SQLRETURN SQL_API SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLength); SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength); #endif /* ODBCVER >= 0x0300 */ SQLRETURN SQL_API SQLGetFunctions(SQLHDBC ConnectionHandle, SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported); SQLRETURN SQL_API SQLGetInfo(SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValue, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLGetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength); #endif /* ODBCVER >= 0x0300 */ SQLRETURN SQL_API SQLGetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, SQLPOINTER Value); SQLRETURN SQL_API SQLGetTypeInfo(SQLHSTMT StatementHandle, SQLSMALLINT DataType); SQLRETURN SQL_API SQLNumResultCols(SQLHSTMT StatementHandle, SQLSMALLINT *ColumnCount); SQLRETURN SQL_API SQLParamData(SQLHSTMT StatementHandle, SQLPOINTER *Value); SQLRETURN SQL_API SQLPrepare(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength); SQLRETURN SQL_API SQLPutData(SQLHSTMT StatementHandle, SQLPOINTER Data, SQLLEN StrLen_or_Ind); SQLRETURN SQL_API SQLRowCount(SQLHSTMT StatementHandle, SQLLEN *RowCount); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength); #endif /* ODBCVER >= 0x0300 */ SQLRETURN SQL_API SQLSetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLULEN Value); SQLRETURN SQL_API SQLSetCursorName(SQLHSTMT StatementHandle, SQLCHAR *CursorName, SQLSMALLINT NameLength); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLSetDescField(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength); SQLRETURN SQL_API SQLSetDescRec(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT Type, SQLSMALLINT SubType, SQLLEN Length, SQLSMALLINT Precision, SQLSMALLINT Scale, SQLPOINTER Data, SQLLEN *StringLength, SQLLEN *Indicator); SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength); #endif /* ODBCVER >= 0x0300 */ SQLRETURN SQL_API SQLSetParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, SQLSMALLINT ParameterType, SQLULEN LengthPrecision, SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue, SQLLEN *StrLen_or_Ind); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength); #endif SQLRETURN SQL_API SQLSetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, SQLULEN Value); SQLRETURN SQL_API SQLSpecialColumns(SQLHSTMT StatementHandle, SQLUSMALLINT IdentifierType, SQLCHAR *CatalogName, SQLSMALLINT NameLength1, SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLUSMALLINT Scope, SQLUSMALLINT Nullable); SQLRETURN SQL_API SQLStatistics(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLSMALLINT NameLength1, SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLUSMALLINT Unique, SQLUSMALLINT Reserved); SQLRETURN SQL_API SQLTables(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLSMALLINT NameLength1, SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLCHAR *TableType, SQLSMALLINT NameLength4); SQLRETURN SQL_API SQLTransact(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, SQLUSMALLINT CompletionType); #ifdef __cplusplus } #endif #endif unixODBC-2.3.12/include/sqlext.h000066400000000000000000002424701446441710500163450ustar00rootroot00000000000000/***************************************************** * sqlext.h * * These should be consistent with the MS version. * *****************************************************/ #ifndef __SQLEXT_H #define __SQLEXT_H /* BEGIN - unixODBC ONLY (programs like ODBCConfig and DataManager use these) */ /* COLUMNS IN SQLTables() RESULT SET */ #define SQLTables_TABLE_CATALOG 1 #define SQLTables_TABLE_SCHEM 2 #define SQLTables_TABLE_NAME 3 #define SQLTables_TABLE_TYPE 4 #define SQLTables_REMARKS 5 /* COLUMNS IN SQLColumns() RESULT SET */ #define SQLColumns_TABLE_CAT 1 #define SQLColumns_TABLE_SCHEM 2 #define SQLColumns_TABLE_NAME 3 #define SQLColumns_COLUMN_NAME 4 #define SQLColumns_DATA_TYPE 5 #define SQLColumns_TYPE_NAME 6 #define SQLColumns_COLUMN_SIZE 7 #define SQLColumns_BUFFER_LENGTH 8 #define SQLColumns_DECIMAL_DIGITS 9 #define SQLColumns_NUM_PREC_RADIX 10 #define SQLColumns_NULLABLE 11 #define SQLColumns_REMARKS 12 #define SQLColumns_COLUMN_DEF 13 #define SQLColumns_SQL_DATA_TYPE 14 #define SQLColumns_SQL_DATETIME_SUB 15 #define SQLColumns_CHAR_OCTET_LENGTH 16 #define SQLColumns_ORDINAL_POSITION 17 #define SQLColumns_IS_NULLABLE 18 /* END - unixODBC ONLY */ #ifndef __SQL_H #include "sql.h" #endif #ifdef __cplusplus extern "C" { /* Assume C declarations for C++ */ #endif /* generally useful constants */ #define SQL_SPEC_MAJOR 3 /* Major version of specification */ #define SQL_SPEC_MINOR 52 /* Minor version of specification */ #define SQL_SPEC_STRING "03.52" /* String constant for version */ #define SQL_SQLSTATE_SIZE 5 /* size of SQLSTATE */ #define SQL_MAX_DSN_LENGTH 32 /* maximum data source name size */ #define SQL_MAX_OPTION_STRING_LENGTH 256 /* return code SQL_NO_DATA_FOUND is the same as SQL_NO_DATA */ #if (ODBCVER < 0x0300) #define SQL_NO_DATA_FOUND 100 #else #define SQL_NO_DATA_FOUND SQL_NO_DATA #endif /* an end handle type */ #if (ODBCVER >= 0x0300) #define SQL_HANDLE_SENV 5 #endif /* ODBCVER >= 0x0300 */ /* env attribute */ #if (ODBCVER >= 0x0300) #define SQL_ATTR_ODBC_VERSION 200 #define SQL_ATTR_CONNECTION_POOLING 201 #define SQL_ATTR_CP_MATCH 202 /* unixODBC additions */ #define SQL_ATTR_UNIXODBC_SYSPATH 65001 #define SQL_ATTR_UNIXODBC_VERSION 65002 #define SQL_ATTR_UNIXODBC_ENVATTR 65003 #endif /* ODBCVER >= 0x0300 */ #if (ODBCVER >= 0x0300) /* values for SQL_ATTR_CONNECTION_POOLING */ #define SQL_CP_OFF 0UL #define SQL_CP_ONE_PER_DRIVER 1UL #define SQL_CP_ONE_PER_HENV 2UL #define SQL_CP_DEFAULT SQL_CP_OFF /* values for SQL_ATTR_CP_MATCH */ #define SQL_CP_STRICT_MATCH 0UL #define SQL_CP_RELAXED_MATCH 1UL #define SQL_CP_MATCH_DEFAULT SQL_CP_STRICT_MATCH /* values for SQL_ATTR_ODBC_VERSION */ #define SQL_OV_ODBC2 2UL #define SQL_OV_ODBC3 3UL #endif /* ODBCVER >= 0x0300 */ #if (ODBCVER >= 0x0380) /* new values for SQL_ATTR_ODBC_VERSION */ /* From ODBC 3.8 onwards, we should use * 100 + */ #define SQL_OV_ODBC3_80 380UL #endif /* ODBCVER >= 0x0380 */ /* connection attributes */ #define SQL_ACCESS_MODE 101 #define SQL_AUTOCOMMIT 102 #define SQL_LOGIN_TIMEOUT 103 #define SQL_OPT_TRACE 104 #define SQL_OPT_TRACEFILE 105 #define SQL_TRANSLATE_DLL 106 #define SQL_TRANSLATE_OPTION 107 #define SQL_TXN_ISOLATION 108 #define SQL_CURRENT_QUALIFIER 109 #define SQL_ODBC_CURSORS 110 #define SQL_QUIET_MODE 111 #define SQL_PACKET_SIZE 112 /* connection attributes with new names */ #if (ODBCVER >= 0x0300) #define SQL_ATTR_ACCESS_MODE SQL_ACCESS_MODE #define SQL_ATTR_AUTOCOMMIT SQL_AUTOCOMMIT #define SQL_ATTR_CONNECTION_TIMEOUT 113 #define SQL_ATTR_CURRENT_CATALOG SQL_CURRENT_QUALIFIER #define SQL_ATTR_DISCONNECT_BEHAVIOR 114 #define SQL_ATTR_ENLIST_IN_DTC 1207 #define SQL_ATTR_ENLIST_IN_XA 1208 #define SQL_ATTR_LOGIN_TIMEOUT SQL_LOGIN_TIMEOUT #define SQL_ATTR_ODBC_CURSORS SQL_ODBC_CURSORS #define SQL_ATTR_PACKET_SIZE SQL_PACKET_SIZE #define SQL_ATTR_QUIET_MODE SQL_QUIET_MODE #define SQL_ATTR_TRACE SQL_OPT_TRACE #define SQL_ATTR_TRACEFILE SQL_OPT_TRACEFILE #define SQL_ATTR_TRANSLATE_LIB SQL_TRANSLATE_DLL #define SQL_ATTR_TRANSLATE_OPTION SQL_TRANSLATE_OPTION #define SQL_ATTR_TXN_ISOLATION SQL_TXN_ISOLATION #endif /* ODBCVER >= 0x0300 */ #define SQL_ATTR_CONNECTION_DEAD 1209 /* GetConnectAttr only */ #define SQL_ATTR_DRIVER_THREADING 1028 /* Driver threading level */ #if (ODBCVER >= 0x0351) /* ODBC Driver Manager sets this connection attribute to a unicode driver (which supports SQLConnectW) when the application is an ANSI application (which calls SQLConnect, SQLDriverConnect, or SQLBrowseConnect). This is SetConnectAttr only and application does not set this attribute This attribute was introduced because some unicode driver's some APIs may need to behave differently on ANSI or Unicode applications. A unicode driver, which has same behavior for both ANSI or Unicode applications, should return SQL_ERROR when the driver manager sets this connection attribute. When a unicode driver returns SQL_SUCCESS on this attribute, the driver manager treates ANSI and Unicode connections differently in connection pooling. */ #define SQL_ATTR_ANSI_APP 115 #endif #if (ODBCVER >= 0x0380) #define SQL_ATTR_RESET_CONNECTION 116 #define SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE 117 #endif /* SQL_CONNECT_OPT_DRVR_START is not meaningful for 3.0 driver */ #if (ODBCVER < 0x0300) #define SQL_CONNECT_OPT_DRVR_START 1000 #endif /* ODBCVER < 0x0300 */ #if (ODBCVER < 0x0300) #define SQL_CONN_OPT_MAX SQL_PACKET_SIZE #define SQL_CONN_OPT_MIN SQL_ACCESS_MODE #endif /* ODBCVER < 0x0300 */ /* SQL_ACCESS_MODE options */ #define SQL_MODE_READ_WRITE 0UL #define SQL_MODE_READ_ONLY 1UL #define SQL_MODE_DEFAULT SQL_MODE_READ_WRITE /* SQL_AUTOCOMMIT options */ #define SQL_AUTOCOMMIT_OFF 0UL #define SQL_AUTOCOMMIT_ON 1UL #define SQL_AUTOCOMMIT_DEFAULT SQL_AUTOCOMMIT_ON /* SQL_LOGIN_TIMEOUT options */ #define SQL_LOGIN_TIMEOUT_DEFAULT 15UL /* SQL_OPT_TRACE options */ #define SQL_OPT_TRACE_OFF 0UL #define SQL_OPT_TRACE_ON 1UL #define SQL_OPT_TRACE_DEFAULT SQL_OPT_TRACE_OFF #ifdef _WINDOWS_ #define SQL_OPT_TRACE_FILE_DEFAULT "\\temp\\SQL.LOG" #else #define SQL_OPT_TRACE_FILE_DEFAULT "/tmp/SQL.LOG" #endif /* SQL_ODBC_CURSORS options */ #define SQL_CUR_USE_IF_NEEDED 0UL #define SQL_CUR_USE_ODBC 1UL #define SQL_CUR_USE_DRIVER 2UL #define SQL_CUR_DEFAULT SQL_CUR_USE_DRIVER #if (ODBCVER >= 0x0300) /* values for SQL_ATTR_DISCONNECT_BEHAVIOR */ #define SQL_DB_RETURN_TO_POOL 0UL #define SQL_DB_DISCONNECT 1UL #define SQL_DB_DEFAULT SQL_DB_RETURN_TO_POOL /* values for SQL_ATTR_ENLIST_IN_DTC */ #define SQL_DTC_DONE 0L #endif /* ODBCVER >= 0x0300 */ /* values for SQL_ATTR_CONNECTION_DEAD */ #define SQL_CD_TRUE 1L /* Connection is closed/dead */ #define SQL_CD_FALSE 0L /* Connection is open/available */ /* values for SQL_ATTR_ANSI_APP */ #if (ODBCVER >= 0x0351) #define SQL_AA_TRUE 1L /* the application is an ANSI app */ #define SQL_AA_FALSE 0L /* the application is a Unicode app */ #endif /* values for SQL_ATTR_RESET_CONNECTION */ #if (ODBCVER >= 0x0380) #define SQL_RESET_CONNECTION_YES 1UL #endif /* values for SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE */ #if (ODBCVER >= 0x0380) #define SQL_ASYNC_DBC_ENABLE_ON 1UL #define SQL_ASYNC_DBC_ENABLE_OFF 0UL #define SQL_ASYNC_DBC_ENABLE_DEFAULT SQL_ASYNC_DBC_ENABLE_OFF #endif /* statement attributes */ #define SQL_QUERY_TIMEOUT 0 #define SQL_MAX_ROWS 1 #define SQL_NOSCAN 2 #define SQL_MAX_LENGTH 3 #define SQL_ASYNC_ENABLE 4 /* same as SQL_ATTR_ASYNC_ENABLE */ #define SQL_BIND_TYPE 5 #define SQL_CURSOR_TYPE 6 #define SQL_CONCURRENCY 7 #define SQL_KEYSET_SIZE 8 #define SQL_ROWSET_SIZE 9 #define SQL_SIMULATE_CURSOR 10 #define SQL_RETRIEVE_DATA 11 #define SQL_USE_BOOKMARKS 12 #define SQL_GET_BOOKMARK 13 /* GetStmtOption Only */ #define SQL_ROW_NUMBER 14 /* GetStmtOption Only */ /* statement attributes for ODBC 3.0 */ #if (ODBCVER >= 0x0300) #define SQL_ATTR_ASYNC_ENABLE 4 #define SQL_ATTR_CONCURRENCY SQL_CONCURRENCY #define SQL_ATTR_CURSOR_TYPE SQL_CURSOR_TYPE #define SQL_ATTR_ENABLE_AUTO_IPD 15 #define SQL_ATTR_FETCH_BOOKMARK_PTR 16 #define SQL_ATTR_KEYSET_SIZE SQL_KEYSET_SIZE #define SQL_ATTR_MAX_LENGTH SQL_MAX_LENGTH #define SQL_ATTR_MAX_ROWS SQL_MAX_ROWS #define SQL_ATTR_NOSCAN SQL_NOSCAN #define SQL_ATTR_PARAM_BIND_OFFSET_PTR 17 #define SQL_ATTR_PARAM_BIND_TYPE 18 #define SQL_ATTR_PARAM_OPERATION_PTR 19 #define SQL_ATTR_PARAM_STATUS_PTR 20 #define SQL_ATTR_PARAMS_PROCESSED_PTR 21 #define SQL_ATTR_PARAMSET_SIZE 22 #define SQL_ATTR_QUERY_TIMEOUT SQL_QUERY_TIMEOUT #define SQL_ATTR_RETRIEVE_DATA SQL_RETRIEVE_DATA #define SQL_ATTR_ROW_BIND_OFFSET_PTR 23 #define SQL_ATTR_ROW_BIND_TYPE SQL_BIND_TYPE #define SQL_ATTR_ROW_NUMBER SQL_ROW_NUMBER /*GetStmtAttr*/ #define SQL_ATTR_ROW_OPERATION_PTR 24 #define SQL_ATTR_ROW_STATUS_PTR 25 #define SQL_ATTR_ROWS_FETCHED_PTR 26 #define SQL_ATTR_ROW_ARRAY_SIZE 27 #define SQL_ATTR_SIMULATE_CURSOR SQL_SIMULATE_CURSOR #define SQL_ATTR_USE_BOOKMARKS SQL_USE_BOOKMARKS #endif /* ODBCVER >= 0x0300 */ #if (ODBCVER >= 0x0380) #define SQL_ATTR_ASYNC_STMT_EVENT 29 #endif /* ODBCVER >= 0x0380 */ #if (ODBCVER < 0x0300) #define SQL_STMT_OPT_MAX SQL_ROW_NUMBER #define SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT #endif /* ODBCVER < 0x0300 */ /* New defines for SEARCHABLE column in SQLGetTypeInfo */ #if (ODBCVER >= 0x0300) #define SQL_COL_PRED_CHAR SQL_LIKE_ONLY #define SQL_COL_PRED_BASIC SQL_ALL_EXCEPT_LIKE #endif /* ODBCVER >= 0x0300 */ /* whether an attribute is a pointer or not */ #if (ODBCVER >= 0x0300) #define SQL_IS_POINTER (-4) #define SQL_IS_UINTEGER (-5) #define SQL_IS_INTEGER (-6) #define SQL_IS_USMALLINT (-7) #define SQL_IS_SMALLINT (-8) #endif /* ODBCVER >= 0x0300 */ /* the value of SQL_ATTR_PARAM_BIND_TYPE */ #if (ODBCVER >= 0x0300) #define SQL_PARAM_BIND_BY_COLUMN 0UL #define SQL_PARAM_BIND_TYPE_DEFAULT SQL_PARAM_BIND_BY_COLUMN #endif /* ODBCVER >= 0x0300 */ /* SQL_QUERY_TIMEOUT options */ #define SQL_QUERY_TIMEOUT_DEFAULT 0UL /* SQL_MAX_ROWS options */ #define SQL_MAX_ROWS_DEFAULT 0UL /* SQL_NOSCAN options */ #define SQL_NOSCAN_OFF 0UL /* 1.0 FALSE */ #define SQL_NOSCAN_ON 1UL /* 1.0 TRUE */ #define SQL_NOSCAN_DEFAULT SQL_NOSCAN_OFF /* SQL_MAX_LENGTH options */ #define SQL_MAX_LENGTH_DEFAULT 0UL /* values for SQL_ATTR_ASYNC_ENABLE */ #define SQL_ASYNC_ENABLE_OFF 0UL #define SQL_ASYNC_ENABLE_ON 1UL #define SQL_ASYNC_ENABLE_DEFAULT SQL_ASYNC_ENABLE_OFF /* SQL_BIND_TYPE options */ #define SQL_BIND_BY_COLUMN 0UL #define SQL_BIND_TYPE_DEFAULT SQL_BIND_BY_COLUMN /* Default value */ /* SQL_CONCURRENCY options */ #define SQL_CONCUR_READ_ONLY 1 #define SQL_CONCUR_LOCK 2 #define SQL_CONCUR_ROWVER 3 #define SQL_CONCUR_VALUES 4 #define SQL_CONCUR_DEFAULT SQL_CONCUR_READ_ONLY /* Default value */ /* SQL_CURSOR_TYPE options */ #define SQL_CURSOR_FORWARD_ONLY 0UL #define SQL_CURSOR_KEYSET_DRIVEN 1UL #define SQL_CURSOR_DYNAMIC 2UL #define SQL_CURSOR_STATIC 3UL #define SQL_CURSOR_TYPE_DEFAULT SQL_CURSOR_FORWARD_ONLY /* Default value */ /* SQL_ROWSET_SIZE options */ #define SQL_ROWSET_SIZE_DEFAULT 1UL /* SQL_KEYSET_SIZE options */ #define SQL_KEYSET_SIZE_DEFAULT 0UL /* SQL_SIMULATE_CURSOR options */ #define SQL_SC_NON_UNIQUE 0UL #define SQL_SC_TRY_UNIQUE 1UL #define SQL_SC_UNIQUE 2UL /* SQL_RETRIEVE_DATA options */ #define SQL_RD_OFF 0UL #define SQL_RD_ON 1UL #define SQL_RD_DEFAULT SQL_RD_ON /* SQL_USE_BOOKMARKS options */ #define SQL_UB_OFF 0UL #define SQL_UB_ON 01UL #define SQL_UB_DEFAULT SQL_UB_OFF /* New values for SQL_USE_BOOKMARKS attribute */ #if (ODBCVER >= 0x0300) #define SQL_UB_FIXED SQL_UB_ON #define SQL_UB_VARIABLE 2UL #endif /* ODBCVER >= 0x0300 */ /* extended descriptor field */ #if (ODBCVER >= 0x0300) #define SQL_DESC_ARRAY_SIZE 20 #define SQL_DESC_ARRAY_STATUS_PTR 21 #define SQL_DESC_AUTO_UNIQUE_VALUE SQL_COLUMN_AUTO_INCREMENT #define SQL_DESC_BASE_COLUMN_NAME 22 #define SQL_DESC_BASE_TABLE_NAME 23 #define SQL_DESC_BIND_OFFSET_PTR 24 #define SQL_DESC_BIND_TYPE 25 #define SQL_DESC_CASE_SENSITIVE SQL_COLUMN_CASE_SENSITIVE #define SQL_DESC_CATALOG_NAME SQL_COLUMN_QUALIFIER_NAME #define SQL_DESC_CONCISE_TYPE SQL_COLUMN_TYPE #define SQL_DESC_DATETIME_INTERVAL_PRECISION 26 #define SQL_DESC_DISPLAY_SIZE SQL_COLUMN_DISPLAY_SIZE #define SQL_DESC_FIXED_PREC_SCALE SQL_COLUMN_MONEY #define SQL_DESC_LABEL SQL_COLUMN_LABEL #define SQL_DESC_LITERAL_PREFIX 27 #define SQL_DESC_LITERAL_SUFFIX 28 #define SQL_DESC_LOCAL_TYPE_NAME 29 #define SQL_DESC_MAXIMUM_SCALE 30 #define SQL_DESC_MINIMUM_SCALE 31 #define SQL_DESC_NUM_PREC_RADIX 32 #define SQL_DESC_PARAMETER_TYPE 33 #define SQL_DESC_ROWS_PROCESSED_PTR 34 #if (ODBCVER >= 0x0350) #define SQL_DESC_ROWVER 35 #endif /* ODBCVER >= 0x0350 */ #define SQL_DESC_SCHEMA_NAME SQL_COLUMN_OWNER_NAME #define SQL_DESC_SEARCHABLE SQL_COLUMN_SEARCHABLE #define SQL_DESC_TYPE_NAME SQL_COLUMN_TYPE_NAME #define SQL_DESC_TABLE_NAME SQL_COLUMN_TABLE_NAME #define SQL_DESC_UNSIGNED SQL_COLUMN_UNSIGNED #define SQL_DESC_UPDATABLE SQL_COLUMN_UPDATABLE #endif /* ODBCVER >= 0x0300 */ /* defines for diagnostics fields */ #if (ODBCVER >= 0x0300) #define SQL_DIAG_CURSOR_ROW_COUNT (-1249) #define SQL_DIAG_ROW_NUMBER (-1248) #define SQL_DIAG_COLUMN_NUMBER (-1247) #endif /* ODBCVER >= 0x0300 */ /* SQL extended datatypes */ #define SQL_DATE 9 #if (ODBCVER >= 0x0300) #define SQL_INTERVAL 10 #endif /* ODBCVER >= 0x0300 */ #define SQL_TIME 10 #define SQL_TIMESTAMP 11 #define SQL_LONGVARCHAR (-1) #define SQL_BINARY (-2) #define SQL_VARBINARY (-3) #define SQL_LONGVARBINARY (-4) #define SQL_BIGINT (-5) #define SQL_TINYINT (-6) #define SQL_BIT (-7) #if (ODBCVER >= 0x0350) #define SQL_GUID (-11) #endif /* ODBCVER >= 0x0350 */ #if (ODBCVER >= 0x0300) /* interval code */ #define SQL_CODE_YEAR 1 #define SQL_CODE_MONTH 2 #define SQL_CODE_DAY 3 #define SQL_CODE_HOUR 4 #define SQL_CODE_MINUTE 5 #define SQL_CODE_SECOND 6 #define SQL_CODE_YEAR_TO_MONTH 7 #define SQL_CODE_DAY_TO_HOUR 8 #define SQL_CODE_DAY_TO_MINUTE 9 #define SQL_CODE_DAY_TO_SECOND 10 #define SQL_CODE_HOUR_TO_MINUTE 11 #define SQL_CODE_HOUR_TO_SECOND 12 #define SQL_CODE_MINUTE_TO_SECOND 13 #define SQL_INTERVAL_YEAR (100 + SQL_CODE_YEAR) #define SQL_INTERVAL_MONTH (100 + SQL_CODE_MONTH) #define SQL_INTERVAL_DAY (100 + SQL_CODE_DAY) #define SQL_INTERVAL_HOUR (100 + SQL_CODE_HOUR) #define SQL_INTERVAL_MINUTE (100 + SQL_CODE_MINUTE) #define SQL_INTERVAL_SECOND (100 + SQL_CODE_SECOND) #define SQL_INTERVAL_YEAR_TO_MONTH (100 + SQL_CODE_YEAR_TO_MONTH) #define SQL_INTERVAL_DAY_TO_HOUR (100 + SQL_CODE_DAY_TO_HOUR) #define SQL_INTERVAL_DAY_TO_MINUTE (100 + SQL_CODE_DAY_TO_MINUTE) #define SQL_INTERVAL_DAY_TO_SECOND (100 + SQL_CODE_DAY_TO_SECOND) #define SQL_INTERVAL_HOUR_TO_MINUTE (100 + SQL_CODE_HOUR_TO_MINUTE) #define SQL_INTERVAL_HOUR_TO_SECOND (100 + SQL_CODE_HOUR_TO_SECOND) #define SQL_INTERVAL_MINUTE_TO_SECOND (100 + SQL_CODE_MINUTE_TO_SECOND) #else #define SQL_INTERVAL_YEAR (-80) #define SQL_INTERVAL_MONTH (-81) #define SQL_INTERVAL_YEAR_TO_MONTH (-82) #define SQL_INTERVAL_DAY (-83) #define SQL_INTERVAL_HOUR (-84) #define SQL_INTERVAL_MINUTE (-85) #define SQL_INTERVAL_SECOND (-86) #define SQL_INTERVAL_DAY_TO_HOUR (-87) #define SQL_INTERVAL_DAY_TO_MINUTE (-88) #define SQL_INTERVAL_DAY_TO_SECOND (-89) #define SQL_INTERVAL_HOUR_TO_MINUTE (-90) #define SQL_INTERVAL_HOUR_TO_SECOND (-91) #define SQL_INTERVAL_MINUTE_TO_SECOND (-92) #endif /* ODBCVER >= 0x0300 */ #if (ODBCVER <= 0x0300) #define SQL_UNICODE (-95) #define SQL_UNICODE_VARCHAR (-96) #define SQL_UNICODE_LONGVARCHAR (-97) #define SQL_UNICODE_CHAR SQL_UNICODE #else /* The previous definitions for SQL_UNICODE_ are historical and obsolete */ #define SQL_UNICODE SQL_WCHAR #define SQL_UNICODE_VARCHAR SQL_WVARCHAR #define SQL_UNICODE_LONGVARCHAR SQL_WLONGVARCHAR #define SQL_UNICODE_CHAR SQL_WCHAR #endif #if (ODBCVER < 0x0300) #define SQL_TYPE_DRIVER_START SQL_INTERVAL_YEAR #define SQL_TYPE_DRIVER_END SQL_UNICODE_LONGVARCHAR #endif /* ODBCVER < 0x0300 */ /* C datatype to SQL datatype mapping SQL types ------------------- */ #define SQL_C_CHAR SQL_CHAR /* CHAR, VARCHAR, DECIMAL, NUMERIC */ #define SQL_C_LONG SQL_INTEGER /* INTEGER */ #define SQL_C_SHORT SQL_SMALLINT /* SMALLINT */ #define SQL_C_FLOAT SQL_REAL /* REAL */ #define SQL_C_DOUBLE SQL_DOUBLE /* FLOAT, DOUBLE */ #if (ODBCVER >= 0x0300) #define SQL_C_NUMERIC SQL_NUMERIC #endif /* ODBCVER >= 0x0300 */ #define SQL_C_DEFAULT 99 #define SQL_SIGNED_OFFSET (-20) #define SQL_UNSIGNED_OFFSET (-22) /* C datatype to SQL datatype mapping */ #define SQL_C_DATE SQL_DATE #define SQL_C_TIME SQL_TIME #define SQL_C_TIMESTAMP SQL_TIMESTAMP #if (ODBCVER >= 0x0300) #define SQL_C_TYPE_DATE SQL_TYPE_DATE #define SQL_C_TYPE_TIME SQL_TYPE_TIME #define SQL_C_TYPE_TIMESTAMP SQL_TYPE_TIMESTAMP #define SQL_C_INTERVAL_YEAR SQL_INTERVAL_YEAR #define SQL_C_INTERVAL_MONTH SQL_INTERVAL_MONTH #define SQL_C_INTERVAL_DAY SQL_INTERVAL_DAY #define SQL_C_INTERVAL_HOUR SQL_INTERVAL_HOUR #define SQL_C_INTERVAL_MINUTE SQL_INTERVAL_MINUTE #define SQL_C_INTERVAL_SECOND SQL_INTERVAL_SECOND #define SQL_C_INTERVAL_YEAR_TO_MONTH SQL_INTERVAL_YEAR_TO_MONTH #define SQL_C_INTERVAL_DAY_TO_HOUR SQL_INTERVAL_DAY_TO_HOUR #define SQL_C_INTERVAL_DAY_TO_MINUTE SQL_INTERVAL_DAY_TO_MINUTE #define SQL_C_INTERVAL_DAY_TO_SECOND SQL_INTERVAL_DAY_TO_SECOND #define SQL_C_INTERVAL_HOUR_TO_MINUTE SQL_INTERVAL_HOUR_TO_MINUTE #define SQL_C_INTERVAL_HOUR_TO_SECOND SQL_INTERVAL_HOUR_TO_SECOND #define SQL_C_INTERVAL_MINUTE_TO_SECOND SQL_INTERVAL_MINUTE_TO_SECOND #endif /* ODBCVER >= 0x0300 */ #define SQL_C_BINARY SQL_BINARY #define SQL_C_BIT SQL_BIT #if (ODBCVER >= 0x0300) #define SQL_C_SBIGINT (SQL_BIGINT+SQL_SIGNED_OFFSET) /* SIGNED BIGINT */ #define SQL_C_UBIGINT (SQL_BIGINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED BIGINT */ #endif /* ODBCVER >= 0x0300 */ #define SQL_C_TINYINT SQL_TINYINT #define SQL_C_SLONG (SQL_C_LONG+SQL_SIGNED_OFFSET) /* SIGNED INTEGER */ #define SQL_C_SSHORT (SQL_C_SHORT+SQL_SIGNED_OFFSET) /* SIGNED SMALLINT */ #define SQL_C_STINYINT (SQL_TINYINT+SQL_SIGNED_OFFSET) /* SIGNED TINYINT */ #define SQL_C_ULONG (SQL_C_LONG+SQL_UNSIGNED_OFFSET) /* UNSIGNED INTEGER*/ #define SQL_C_USHORT (SQL_C_SHORT+SQL_UNSIGNED_OFFSET) /* UNSIGNED SMALLINT*/ #define SQL_C_UTINYINT (SQL_TINYINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED TINYINT*/ #if (ODBCVER >= 0x0300) && (SIZEOF_LONG_INT == 8) && !defined(BUILD_LEGACY_64_BIT_MODE) #define SQL_C_BOOKMARK SQL_C_UBIGINT /* BOOKMARK */ #else #define SQL_C_BOOKMARK SQL_C_ULONG /* BOOKMARK */ #endif #if (ODBCVER >= 0x0350) #define SQL_C_GUID SQL_GUID #endif /* ODBCVER >= 0x0350 */ #define SQL_TYPE_NULL 0 #if (ODBCVER < 0x0300) #define SQL_TYPE_MIN SQL_BIT #define SQL_TYPE_MAX SQL_VARCHAR #endif /* base value of driver-specific C-Type (max is 0x7fff) */ /* define driver-specific C-Type, named as SQL_DRIVER_C_TYPE_BASE, */ /* SQL_DRIVER_C_TYPE_BASE+1, SQL_DRIVER_C_TYPE_BASE+2, etc. */ #if (ODBCVER >= 0x380) #define SQL_DRIVER_C_TYPE_BASE 0x4000 #endif /* base value of driver-specific fields/attributes (max are 0x7fff [16-bit] or 0x00007fff [32-bit]) */ /* define driver-specific SQL-Type, named as SQL_DRIVER_SQL_TYPE_BASE, */ /* SQL_DRIVER_SQL_TYPE_BASE+1, SQL_DRIVER_SQL_TYPE_BASE+2, etc. */ /* */ /* Please note that there is no runtime change in this version of DM. */ /* However, we suggest that driver manufacturers adhere to this range */ /* as future versions of the DM may enforce these constraints */ #if (ODBCVER >= 0x380) #define SQL_DRIVER_SQL_TYPE_BASE 0x4000 #define SQL_DRIVER_DESC_FIELD_BASE 0x4000 #define SQL_DRIVER_DIAG_FIELD_BASE 0x4000 #define SQL_DRIVER_INFO_TYPE_BASE 0x4000 #define SQL_DRIVER_CONN_ATTR_BASE 0x00004000 #define SQL_DRIVER_STMT_ATTR_BASE 0x00004000 #endif #if (ODBCVER >= 0x0300) #define SQL_C_VARBOOKMARK SQL_C_BINARY #endif /* ODBCVER >= 0x0300 */ /* define for SQL_DIAG_ROW_NUMBER and SQL_DIAG_COLUMN_NUMBER */ #if (ODBCVER >= 0x0300) #define SQL_NO_ROW_NUMBER (-1) #define SQL_NO_COLUMN_NUMBER (-1) #define SQL_ROW_NUMBER_UNKNOWN (-2) #define SQL_COLUMN_NUMBER_UNKNOWN (-2) #endif /* SQLBindParameter extensions */ #define SQL_DEFAULT_PARAM (-5) #define SQL_IGNORE (-6) #if (ODBCVER >= 0x0300) #define SQL_COLUMN_IGNORE SQL_IGNORE #endif /* ODBCVER >= 0x0300 */ #define SQL_LEN_DATA_AT_EXEC_OFFSET (-100) #define SQL_LEN_DATA_AT_EXEC(length) (-(length)+SQL_LEN_DATA_AT_EXEC_OFFSET) /* binary length for driver specific attributes */ #define SQL_LEN_BINARY_ATTR_OFFSET (-100) #define SQL_LEN_BINARY_ATTR(length) (-(length)+SQL_LEN_BINARY_ATTR_OFFSET) /* Defines used by Driver Manager when mapping SQLSetParam to SQLBindParameter */ #define SQL_PARAM_TYPE_DEFAULT SQL_PARAM_INPUT_OUTPUT #define SQL_SETPARAM_VALUE_MAX (-1L) /* SQLColAttributes defines */ #define SQL_COLUMN_COUNT 0 #define SQL_COLUMN_NAME 1 #define SQL_COLUMN_TYPE 2 #define SQL_COLUMN_LENGTH 3 #define SQL_COLUMN_PRECISION 4 #define SQL_COLUMN_SCALE 5 #define SQL_COLUMN_DISPLAY_SIZE 6 #define SQL_COLUMN_NULLABLE 7 #define SQL_COLUMN_UNSIGNED 8 #define SQL_COLUMN_MONEY 9 #define SQL_COLUMN_UPDATABLE 10 #define SQL_COLUMN_AUTO_INCREMENT 11 #define SQL_COLUMN_CASE_SENSITIVE 12 #define SQL_COLUMN_SEARCHABLE 13 #define SQL_COLUMN_TYPE_NAME 14 #define SQL_COLUMN_TABLE_NAME 15 #define SQL_COLUMN_OWNER_NAME 16 #define SQL_COLUMN_QUALIFIER_NAME 17 #define SQL_COLUMN_LABEL 18 #define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL #if (ODBCVER < 0x0300) #define SQL_COLUMN_DRIVER_START 1000 #endif /* ODBCVER < 0x0300 */ #define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT /* SQLColAttributes subdefines for SQL_COLUMN_UPDATABLE */ #define SQL_ATTR_READONLY 0 #define SQL_ATTR_WRITE 1 #define SQL_ATTR_READWRITE_UNKNOWN 2 /* SQLColAttributes subdefines for SQL_COLUMN_SEARCHABLE */ /* These are also used by SQLGetInfo */ #define SQL_UNSEARCHABLE 0 #define SQL_LIKE_ONLY 1 #define SQL_ALL_EXCEPT_LIKE 2 #define SQL_SEARCHABLE 3 #define SQL_PRED_SEARCHABLE SQL_SEARCHABLE /* Special return values for SQLGetData */ #define SQL_NO_TOTAL (-4) /********************************************/ /* SQLGetFunctions: additional values for */ /* fFunction to represent functions that */ /* are not in the X/Open spec. */ /********************************************/ #if (ODBCVER >= 0x0300) #define SQL_API_SQLALLOCHANDLESTD 73 #define SQL_API_SQLBULKOPERATIONS 24 #endif /* ODBCVER >= 0x0300 */ #define SQL_API_SQLBINDPARAMETER 72 #define SQL_API_SQLBROWSECONNECT 55 #define SQL_API_SQLCOLATTRIBUTES 6 #define SQL_API_SQLCOLUMNPRIVILEGES 56 #define SQL_API_SQLDESCRIBEPARAM 58 #define SQL_API_SQLDRIVERCONNECT 41 #define SQL_API_SQLDRIVERS 71 #define SQL_API_SQLEXTENDEDFETCH 59 #define SQL_API_SQLFOREIGNKEYS 60 #define SQL_API_SQLMORERESULTS 61 #define SQL_API_SQLNATIVESQL 62 #define SQL_API_SQLNUMPARAMS 63 #define SQL_API_SQLPARAMOPTIONS 64 #define SQL_API_SQLPRIMARYKEYS 65 #define SQL_API_SQLPROCEDURECOLUMNS 66 #define SQL_API_SQLPROCEDURES 67 #define SQL_API_SQLSETPOS 68 #define SQL_API_SQLSETSCROLLOPTIONS 69 #define SQL_API_SQLTABLEPRIVILEGES 70 /*-------------------------------------------*/ /* SQL_EXT_API_LAST is not useful with ODBC */ /* version 3.0 because some of the values */ /* from X/Open are in the 10000 range. */ /*-------------------------------------------*/ #if (ODBCVER < 0x0300) #define SQL_EXT_API_LAST SQL_API_SQLBINDPARAMETER #define SQL_NUM_FUNCTIONS 23 #define SQL_EXT_API_START 40 #define SQL_NUM_EXTENSIONS (SQL_EXT_API_LAST-SQL_EXT_API_START+1) #endif /*--------------------------------------------*/ /* SQL_API_ALL_FUNCTIONS returns an array */ /* of 'booleans' representing whether a */ /* function is implemented by the driver. */ /* */ /* CAUTION: Only functions defined in ODBC */ /* version 2.0 and earlier are returned, the */ /* new high-range function numbers defined by */ /* X/Open break this scheme. See the new */ /* method -- SQL_API_ODBC3_ALL_FUNCTIONS */ /*--------------------------------------------*/ #define SQL_API_ALL_FUNCTIONS 0 /* See CAUTION above */ /*----------------------------------------------*/ /* 2.X drivers export a dummy function with */ /* ordinal number SQL_API_LOADBYORDINAL to speed*/ /* loading under the windows operating system. */ /* */ /* CAUTION: Loading by ordinal is not supported */ /* for 3.0 and above drivers. */ /*----------------------------------------------*/ #define SQL_API_LOADBYORDINAL 199 /* See CAUTION above */ /*----------------------------------------------*/ /* SQL_API_ODBC3_ALL_FUNCTIONS */ /* This returns a bitmap, which allows us to */ /* handle the higher-valued function numbers. */ /* Use SQL_FUNC_EXISTS(bitmap,function_number) */ /* to determine if the function exists. */ /*----------------------------------------------*/ #if (ODBCVER >= 0x0300) #define SQL_API_ODBC3_ALL_FUNCTIONS 999 #define SQL_API_ODBC3_ALL_FUNCTIONS_SIZE 250 /* array of 250 words */ #define SQL_FUNC_EXISTS(pfExists, uwAPI) ((*(((UWORD*) (pfExists)) + ((uwAPI) >> 4)) & (1 << ((uwAPI) & 0x000F)) ) ? SQL_TRUE : SQL_FALSE ) #endif /* ODBCVER >= 0x0300 */ /************************************************/ /* Extended definitions for SQLGetInfo */ /************************************************/ /*---------------------------------*/ /* Values in ODBC 2.0 that are not */ /* in the X/Open spec */ /*---------------------------------*/ #define SQL_INFO_FIRST 0 #define SQL_ACTIVE_CONNECTIONS 0 /* MAX_DRIVER_CONNECTIONS */ #define SQL_ACTIVE_STATEMENTS 1 /* MAX_CONCURRENT_ACTIVITIES */ #define SQL_DRIVER_HDBC 3 #define SQL_DRIVER_HENV 4 #define SQL_DRIVER_HSTMT 5 #define SQL_DRIVER_NAME 6 #define SQL_DRIVER_VER 7 #define SQL_ODBC_API_CONFORMANCE 9 #define SQL_ODBC_VER 10 #define SQL_ROW_UPDATES 11 #define SQL_ODBC_SAG_CLI_CONFORMANCE 12 #define SQL_ODBC_SQL_CONFORMANCE 15 #define SQL_PROCEDURES 21 #define SQL_CONCAT_NULL_BEHAVIOR 22 #define SQL_CURSOR_ROLLBACK_BEHAVIOR 24 #define SQL_EXPRESSIONS_IN_ORDERBY 27 #define SQL_MAX_OWNER_NAME_LEN 32 /* MAX_SCHEMA_NAME_LEN */ #define SQL_MAX_PROCEDURE_NAME_LEN 33 #define SQL_MAX_QUALIFIER_NAME_LEN 34 /* MAX_CATALOG_NAME_LEN */ #define SQL_MULT_RESULT_SETS 36 #define SQL_MULTIPLE_ACTIVE_TXN 37 #define SQL_OUTER_JOINS 38 #define SQL_OWNER_TERM 39 #define SQL_PROCEDURE_TERM 40 #define SQL_QUALIFIER_NAME_SEPARATOR 41 #define SQL_QUALIFIER_TERM 42 #define SQL_SCROLL_OPTIONS 44 #define SQL_TABLE_TERM 45 #define SQL_CONVERT_FUNCTIONS 48 #define SQL_NUMERIC_FUNCTIONS 49 #define SQL_STRING_FUNCTIONS 50 #define SQL_SYSTEM_FUNCTIONS 51 #define SQL_TIMEDATE_FUNCTIONS 52 #define SQL_CONVERT_BIGINT 53 #define SQL_CONVERT_BINARY 54 #define SQL_CONVERT_BIT 55 #define SQL_CONVERT_CHAR 56 #define SQL_CONVERT_DATE 57 #define SQL_CONVERT_DECIMAL 58 #define SQL_CONVERT_DOUBLE 59 #define SQL_CONVERT_FLOAT 60 #define SQL_CONVERT_INTEGER 61 #define SQL_CONVERT_LONGVARCHAR 62 #define SQL_CONVERT_NUMERIC 63 #define SQL_CONVERT_REAL 64 #define SQL_CONVERT_SMALLINT 65 #define SQL_CONVERT_TIME 66 #define SQL_CONVERT_TIMESTAMP 67 #define SQL_CONVERT_TINYINT 68 #define SQL_CONVERT_VARBINARY 69 #define SQL_CONVERT_VARCHAR 70 #define SQL_CONVERT_LONGVARBINARY 71 #define SQL_CONVERT_GUID 173 #define SQL_ODBC_SQL_OPT_IEF 73 /* SQL_INTEGRITY */ #define SQL_CORRELATION_NAME 74 #define SQL_NON_NULLABLE_COLUMNS 75 #define SQL_DRIVER_HLIB 76 #define SQL_DRIVER_ODBC_VER 77 #define SQL_LOCK_TYPES 78 #define SQL_POS_OPERATIONS 79 #define SQL_POSITIONED_STATEMENTS 80 #define SQL_BOOKMARK_PERSISTENCE 82 #define SQL_STATIC_SENSITIVITY 83 #define SQL_FILE_USAGE 84 #define SQL_COLUMN_ALIAS 87 #define SQL_GROUP_BY 88 #define SQL_KEYWORDS 89 #define SQL_OWNER_USAGE 91 #define SQL_QUALIFIER_USAGE 92 #define SQL_QUOTED_IDENTIFIER_CASE 93 #define SQL_SUBQUERIES 95 #define SQL_UNION 96 #define SQL_MAX_ROW_SIZE_INCLUDES_LONG 103 #define SQL_MAX_CHAR_LITERAL_LEN 108 #define SQL_TIMEDATE_ADD_INTERVALS 109 #define SQL_TIMEDATE_DIFF_INTERVALS 110 #define SQL_NEED_LONG_DATA_LEN 111 #define SQL_MAX_BINARY_LITERAL_LEN 112 #define SQL_LIKE_ESCAPE_CLAUSE 113 #define SQL_QUALIFIER_LOCATION 114 #if (ODBCVER >= 0x0201 && ODBCVER < 0x0300) #ifndef SQL_OJ_CAPABILITIES #define SQL_OJ_CAPABILITIES 65003 /* Temp value until ODBC 3.0 */ #endif #endif /* ODBCVER >= 0x0201 && ODBCVER < 0x0300 */ /*----------------------------------------------*/ /* SQL_INFO_LAST and SQL_INFO_DRIVER_START are */ /* not useful anymore, because X/Open has */ /* values in the 10000 range. You */ /* must contact X/Open directly to get a range */ /* of numbers for driver-specific values. */ /*----------------------------------------------*/ #if (ODBCVER < 0x0300) #define SQL_INFO_LAST SQL_QUALIFIER_LOCATION #define SQL_INFO_DRIVER_START 1000 #endif /* ODBCVER < 0x0300 */ /*-----------------------------------------------*/ /* ODBC 3.0 SQLGetInfo values that are not part */ /* of the X/Open standard at this time. X/Open */ /* standard values are in sql.h. */ /*-----------------------------------------------*/ #if (ODBCVER >= 0x0300) #define SQL_ACTIVE_ENVIRONMENTS 116 #define SQL_ALTER_DOMAIN 117 #define SQL_SQL_CONFORMANCE 118 #define SQL_DATETIME_LITERALS 119 #define SQL_ASYNC_MODE 10021 /* new X/Open spec */ #define SQL_BATCH_ROW_COUNT 120 #define SQL_BATCH_SUPPORT 121 #define SQL_CATALOG_LOCATION SQL_QUALIFIER_LOCATION #define SQL_CATALOG_NAME_SEPARATOR SQL_QUALIFIER_NAME_SEPARATOR #define SQL_CATALOG_TERM SQL_QUALIFIER_TERM #define SQL_CATALOG_USAGE SQL_QUALIFIER_USAGE #define SQL_CONVERT_WCHAR 122 #define SQL_CONVERT_INTERVAL_DAY_TIME 123 #define SQL_CONVERT_INTERVAL_YEAR_MONTH 124 #define SQL_CONVERT_WLONGVARCHAR 125 #define SQL_CONVERT_WVARCHAR 126 #define SQL_CREATE_ASSERTION 127 #define SQL_CREATE_CHARACTER_SET 128 #define SQL_CREATE_COLLATION 129 #define SQL_CREATE_DOMAIN 130 #define SQL_CREATE_SCHEMA 131 #define SQL_CREATE_TABLE 132 #define SQL_CREATE_TRANSLATION 133 #define SQL_CREATE_VIEW 134 #define SQL_DRIVER_HDESC 135 #define SQL_DROP_ASSERTION 136 #define SQL_DROP_CHARACTER_SET 137 #define SQL_DROP_COLLATION 138 #define SQL_DROP_DOMAIN 139 #define SQL_DROP_SCHEMA 140 #define SQL_DROP_TABLE 141 #define SQL_DROP_TRANSLATION 142 #define SQL_DROP_VIEW 143 #define SQL_DYNAMIC_CURSOR_ATTRIBUTES1 144 #define SQL_DYNAMIC_CURSOR_ATTRIBUTES2 145 #define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 146 #define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 147 #define SQL_INDEX_KEYWORDS 148 #define SQL_INFO_SCHEMA_VIEWS 149 #define SQL_KEYSET_CURSOR_ATTRIBUTES1 150 #define SQL_KEYSET_CURSOR_ATTRIBUTES2 151 #define SQL_MAX_ASYNC_CONCURRENT_STATEMENTS 10022 /* new X/Open spec */ #define SQL_ODBC_INTERFACE_CONFORMANCE 152 #define SQL_PARAM_ARRAY_ROW_COUNTS 153 #define SQL_PARAM_ARRAY_SELECTS 154 #define SQL_SCHEMA_TERM SQL_OWNER_TERM #define SQL_SCHEMA_USAGE SQL_OWNER_USAGE #define SQL_SQL92_DATETIME_FUNCTIONS 155 #define SQL_SQL92_FOREIGN_KEY_DELETE_RULE 156 #define SQL_SQL92_FOREIGN_KEY_UPDATE_RULE 157 #define SQL_SQL92_GRANT 158 #define SQL_SQL92_NUMERIC_VALUE_FUNCTIONS 159 #define SQL_SQL92_PREDICATES 160 #define SQL_SQL92_RELATIONAL_JOIN_OPERATORS 161 #define SQL_SQL92_REVOKE 162 #define SQL_SQL92_ROW_VALUE_CONSTRUCTOR 163 #define SQL_SQL92_STRING_FUNCTIONS 164 #define SQL_SQL92_VALUE_EXPRESSIONS 165 #define SQL_STANDARD_CLI_CONFORMANCE 166 #define SQL_STATIC_CURSOR_ATTRIBUTES1 167 #define SQL_STATIC_CURSOR_ATTRIBUTES2 168 #define SQL_AGGREGATE_FUNCTIONS 169 #define SQL_DDL_INDEX 170 #define SQL_DM_VER 171 #define SQL_INSERT_STATEMENT 172 #define SQL_UNION_STATEMENT SQL_UNION #endif /* ODBCVER >= 0x0300 */ #if (ODBCVER >= 0x0380) /* Info Types */ #define SQL_ASYNC_DBC_FUNCTIONS 10023 #endif #define SQL_DRIVER_AWARE_POOLING_SUPPORTED 10024 #if (ODBCVER >= 0x0380) #define SQL_ASYNC_NOTIFICATION 10025 /* Possible values for SQL_ASYNC_NOTIFICATION */ #define SQL_ASYNC_NOTIFICATION_NOT_CAPABLE 0x00000000L #define SQL_ASYNC_NOTIFICATION_CAPABLE 0x00000001L #endif /* ODBCVER >= 0x0380 */ #define SQL_DTC_TRANSITION_COST 1750 /* SQL_ALTER_TABLE bitmasks */ #if (ODBCVER >= 0x0300) /* the following 5 bitmasks are defined in sql.h *#define SQL_AT_ADD_COLUMN 0x00000001L *#define SQL_AT_DROP_COLUMN 0x00000002L *#define SQL_AT_ADD_CONSTRAINT 0x00000008L */ #define SQL_AT_ADD_COLUMN_SINGLE 0x00000020L #define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L #define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L #define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L #define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L #define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L #define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L #define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L #define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L #define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L #define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L #define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L #define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L #define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L #define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L #endif /* ODBCVER >= 0x0300 */ /* SQL_CONVERT_* return value bitmasks */ #define SQL_CVT_CHAR 0x00000001L #define SQL_CVT_NUMERIC 0x00000002L #define SQL_CVT_DECIMAL 0x00000004L #define SQL_CVT_INTEGER 0x00000008L #define SQL_CVT_SMALLINT 0x00000010L #define SQL_CVT_FLOAT 0x00000020L #define SQL_CVT_REAL 0x00000040L #define SQL_CVT_DOUBLE 0x00000080L #define SQL_CVT_VARCHAR 0x00000100L #define SQL_CVT_LONGVARCHAR 0x00000200L #define SQL_CVT_BINARY 0x00000400L #define SQL_CVT_VARBINARY 0x00000800L #define SQL_CVT_BIT 0x00001000L #define SQL_CVT_TINYINT 0x00002000L #define SQL_CVT_BIGINT 0x00004000L #define SQL_CVT_DATE 0x00008000L #define SQL_CVT_TIME 0x00010000L #define SQL_CVT_TIMESTAMP 0x00020000L #define SQL_CVT_LONGVARBINARY 0x00040000L #if (ODBCVER >= 0x0300) #define SQL_CVT_INTERVAL_YEAR_MONTH 0x00080000L #define SQL_CVT_INTERVAL_DAY_TIME 0x00100000L #define SQL_CVT_WCHAR 0x00200000L #define SQL_CVT_WLONGVARCHAR 0x00400000L #define SQL_CVT_WVARCHAR 0x00800000L #define SQL_CVT_GUID 0x01000000L #endif /* ODBCVER >= 0x0300 */ /* SQL_CONVERT_FUNCTIONS functions */ #define SQL_FN_CVT_CONVERT 0x00000001L #if (ODBCVER >= 0x0300) #define SQL_FN_CVT_CAST 0x00000002L #endif /* ODBCVER >= 0x0300 */ /* SQL_STRING_FUNCTIONS functions */ #define SQL_FN_STR_CONCAT 0x00000001L #define SQL_FN_STR_INSERT 0x00000002L #define SQL_FN_STR_LEFT 0x00000004L #define SQL_FN_STR_LTRIM 0x00000008L #define SQL_FN_STR_LENGTH 0x00000010L #define SQL_FN_STR_LOCATE 0x00000020L #define SQL_FN_STR_LCASE 0x00000040L #define SQL_FN_STR_REPEAT 0x00000080L #define SQL_FN_STR_REPLACE 0x00000100L #define SQL_FN_STR_RIGHT 0x00000200L #define SQL_FN_STR_RTRIM 0x00000400L #define SQL_FN_STR_SUBSTRING 0x00000800L #define SQL_FN_STR_UCASE 0x00001000L #define SQL_FN_STR_ASCII 0x00002000L #define SQL_FN_STR_CHAR 0x00004000L #define SQL_FN_STR_DIFFERENCE 0x00008000L #define SQL_FN_STR_LOCATE_2 0x00010000L #define SQL_FN_STR_SOUNDEX 0x00020000L #define SQL_FN_STR_SPACE 0x00040000L #if (ODBCVER >= 0x0300) #define SQL_FN_STR_BIT_LENGTH 0x00080000L #define SQL_FN_STR_CHAR_LENGTH 0x00100000L #define SQL_FN_STR_CHARACTER_LENGTH 0x00200000L #define SQL_FN_STR_OCTET_LENGTH 0x00400000L #define SQL_FN_STR_POSITION 0x00800000L #endif /* ODBCVER >= 0x0300 */ /* SQL_SQL92_STRING_FUNCTIONS */ #if (ODBCVER >= 0x0300) #define SQL_SSF_CONVERT 0x00000001L #define SQL_SSF_LOWER 0x00000002L #define SQL_SSF_UPPER 0x00000004L #define SQL_SSF_SUBSTRING 0x00000008L #define SQL_SSF_TRANSLATE 0x00000010L #define SQL_SSF_TRIM_BOTH 0x00000020L #define SQL_SSF_TRIM_LEADING 0x00000040L #define SQL_SSF_TRIM_TRAILING 0x00000080L #endif /* ODBCVER >= 0x0300 */ /* SQL_NUMERIC_FUNCTIONS functions */ #define SQL_FN_NUM_ABS 0x00000001L #define SQL_FN_NUM_ACOS 0x00000002L #define SQL_FN_NUM_ASIN 0x00000004L #define SQL_FN_NUM_ATAN 0x00000008L #define SQL_FN_NUM_ATAN2 0x00000010L #define SQL_FN_NUM_CEILING 0x00000020L #define SQL_FN_NUM_COS 0x00000040L #define SQL_FN_NUM_COT 0x00000080L #define SQL_FN_NUM_EXP 0x00000100L #define SQL_FN_NUM_FLOOR 0x00000200L #define SQL_FN_NUM_LOG 0x00000400L #define SQL_FN_NUM_MOD 0x00000800L #define SQL_FN_NUM_SIGN 0x00001000L #define SQL_FN_NUM_SIN 0x00002000L #define SQL_FN_NUM_SQRT 0x00004000L #define SQL_FN_NUM_TAN 0x00008000L #define SQL_FN_NUM_PI 0x00010000L #define SQL_FN_NUM_RAND 0x00020000L #define SQL_FN_NUM_DEGREES 0x00040000L #define SQL_FN_NUM_LOG10 0x00080000L #define SQL_FN_NUM_POWER 0x00100000L #define SQL_FN_NUM_RADIANS 0x00200000L #define SQL_FN_NUM_ROUND 0x00400000L #define SQL_FN_NUM_TRUNCATE 0x00800000L /* SQL_SQL92_NUMERIC_VALUE_FUNCTIONS */ #if (ODBCVER >= 0x0300) #define SQL_SNVF_BIT_LENGTH 0x00000001L #define SQL_SNVF_CHAR_LENGTH 0x00000002L #define SQL_SNVF_CHARACTER_LENGTH 0x00000004L #define SQL_SNVF_EXTRACT 0x00000008L #define SQL_SNVF_OCTET_LENGTH 0x00000010L #define SQL_SNVF_POSITION 0x00000020L #endif /* ODBCVER >= 0x0300 */ /* SQL_TIMEDATE_FUNCTIONS functions */ #define SQL_FN_TD_NOW 0x00000001L #define SQL_FN_TD_CURDATE 0x00000002L #define SQL_FN_TD_DAYOFMONTH 0x00000004L #define SQL_FN_TD_DAYOFWEEK 0x00000008L #define SQL_FN_TD_DAYOFYEAR 0x00000010L #define SQL_FN_TD_MONTH 0x00000020L #define SQL_FN_TD_QUARTER 0x00000040L #define SQL_FN_TD_WEEK 0x00000080L #define SQL_FN_TD_YEAR 0x00000100L #define SQL_FN_TD_CURTIME 0x00000200L #define SQL_FN_TD_HOUR 0x00000400L #define SQL_FN_TD_MINUTE 0x00000800L #define SQL_FN_TD_SECOND 0x00001000L #define SQL_FN_TD_TIMESTAMPADD 0x00002000L #define SQL_FN_TD_TIMESTAMPDIFF 0x00004000L #define SQL_FN_TD_DAYNAME 0x00008000L #define SQL_FN_TD_MONTHNAME 0x00010000L #if (ODBCVER >= 0x0300) #define SQL_FN_TD_CURRENT_DATE 0x00020000L #define SQL_FN_TD_CURRENT_TIME 0x00040000L #define SQL_FN_TD_CURRENT_TIMESTAMP 0x00080000L #define SQL_FN_TD_EXTRACT 0x00100000L #endif /* ODBCVER >= 0x0300 */ /* SQL_SQL92_DATETIME_FUNCTIONS */ #if (ODBCVER >= 0x0300) #define SQL_SDF_CURRENT_DATE 0x00000001L #define SQL_SDF_CURRENT_TIME 0x00000002L #define SQL_SDF_CURRENT_TIMESTAMP 0x00000004L #endif /* ODBCVER >= 0x0300 */ /* SQL_SYSTEM_FUNCTIONS functions */ #define SQL_FN_SYS_USERNAME 0x00000001L #define SQL_FN_SYS_DBNAME 0x00000002L #define SQL_FN_SYS_IFNULL 0x00000004L /* SQL_TIMEDATE_ADD_INTERVALS and SQL_TIMEDATE_DIFF_INTERVALS functions */ #define SQL_FN_TSI_FRAC_SECOND 0x00000001L #define SQL_FN_TSI_SECOND 0x00000002L #define SQL_FN_TSI_MINUTE 0x00000004L #define SQL_FN_TSI_HOUR 0x00000008L #define SQL_FN_TSI_DAY 0x00000010L #define SQL_FN_TSI_WEEK 0x00000020L #define SQL_FN_TSI_MONTH 0x00000040L #define SQL_FN_TSI_QUARTER 0x00000080L #define SQL_FN_TSI_YEAR 0x00000100L /* bitmasks for SQL_DYNAMIC_CURSOR_ATTRIBUTES1, * SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, * SQL_KEYSET_CURSOR_ATTRIBUTES1, and SQL_STATIC_CURSOR_ATTRIBUTES1 */ #if (ODBCVER >= 0x0300) /* supported SQLFetchScroll FetchOrientation's */ #define SQL_CA1_NEXT 0x00000001L #define SQL_CA1_ABSOLUTE 0x00000002L #define SQL_CA1_RELATIVE 0x00000004L #define SQL_CA1_BOOKMARK 0x00000008L /* supported SQLSetPos LockType's */ #define SQL_CA1_LOCK_NO_CHANGE 0x00000040L #define SQL_CA1_LOCK_EXCLUSIVE 0x00000080L #define SQL_CA1_LOCK_UNLOCK 0x00000100L /* supported SQLSetPos Operations */ #define SQL_CA1_POS_POSITION 0x00000200L #define SQL_CA1_POS_UPDATE 0x00000400L #define SQL_CA1_POS_DELETE 0x00000800L #define SQL_CA1_POS_REFRESH 0x00001000L /* positioned updates and deletes */ #define SQL_CA1_POSITIONED_UPDATE 0x00002000L #define SQL_CA1_POSITIONED_DELETE 0x00004000L #define SQL_CA1_SELECT_FOR_UPDATE 0x00008000L /* supported SQLBulkOperations operations */ #define SQL_CA1_BULK_ADD 0x00010000L #define SQL_CA1_BULK_UPDATE_BY_BOOKMARK 0x00020000L #define SQL_CA1_BULK_DELETE_BY_BOOKMARK 0x00040000L #define SQL_CA1_BULK_FETCH_BY_BOOKMARK 0x00080000L #endif /* ODBCVER >= 0x0300 */ /* bitmasks for SQL_DYNAMIC_CURSOR_ATTRIBUTES2, * SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2, * SQL_KEYSET_CURSOR_ATTRIBUTES2, and SQL_STATIC_CURSOR_ATTRIBUTES2 */ #if (ODBCVER >= 0x0300) /* supported values for SQL_ATTR_SCROLL_CONCURRENCY */ #define SQL_CA2_READ_ONLY_CONCURRENCY 0x00000001L #define SQL_CA2_LOCK_CONCURRENCY 0x00000002L #define SQL_CA2_OPT_ROWVER_CONCURRENCY 0x00000004L #define SQL_CA2_OPT_VALUES_CONCURRENCY 0x00000008L /* sensitivity of the cursor to its own inserts, deletes, and updates */ #define SQL_CA2_SENSITIVITY_ADDITIONS 0x00000010L #define SQL_CA2_SENSITIVITY_DELETIONS 0x00000020L #define SQL_CA2_SENSITIVITY_UPDATES 0x00000040L /* semantics of SQL_ATTR_MAX_ROWS */ #define SQL_CA2_MAX_ROWS_SELECT 0x00000080L #define SQL_CA2_MAX_ROWS_INSERT 0x00000100L #define SQL_CA2_MAX_ROWS_DELETE 0x00000200L #define SQL_CA2_MAX_ROWS_UPDATE 0x00000400L #define SQL_CA2_MAX_ROWS_CATALOG 0x00000800L #define SQL_CA2_MAX_ROWS_AFFECTS_ALL (SQL_CA2_MAX_ROWS_SELECT | SQL_CA2_MAX_ROWS_INSERT | SQL_CA2_MAX_ROWS_DELETE | SQL_CA2_MAX_ROWS_UPDATE | SQL_CA2_MAX_ROWS_CATALOG) /* semantics of SQL_DIAG_CURSOR_ROW_COUNT */ #define SQL_CA2_CRC_EXACT 0x00001000L #define SQL_CA2_CRC_APPROXIMATE 0x00002000L /* the kinds of positioned statements that can be simulated */ #define SQL_CA2_SIMULATE_NON_UNIQUE 0x00004000L #define SQL_CA2_SIMULATE_TRY_UNIQUE 0x00008000L #define SQL_CA2_SIMULATE_UNIQUE 0x00010000L #endif /* ODBCVER >= 0x0300 */ /* SQL_ODBC_API_CONFORMANCE values */ #define SQL_OAC_NONE 0x0000 #define SQL_OAC_LEVEL1 0x0001 #define SQL_OAC_LEVEL2 0x0002 /* SQL_ODBC_SAG_CLI_CONFORMANCE values */ #define SQL_OSCC_NOT_COMPLIANT 0x0000 #define SQL_OSCC_COMPLIANT 0x0001 /* SQL_ODBC_SQL_CONFORMANCE values */ #define SQL_OSC_MINIMUM 0x0000 #define SQL_OSC_CORE 0x0001 #define SQL_OSC_EXTENDED 0x0002 /* SQL_CONCAT_NULL_BEHAVIOR values */ #define SQL_CB_NULL 0x0000 #define SQL_CB_NON_NULL 0x0001 /* SQL_SCROLL_OPTIONS masks */ #define SQL_SO_FORWARD_ONLY 0x00000001L #define SQL_SO_KEYSET_DRIVEN 0x00000002L #define SQL_SO_DYNAMIC 0x00000004L #define SQL_SO_MIXED 0x00000008L #define SQL_SO_STATIC 0x00000010L /* SQL_FETCH_DIRECTION masks */ /* SQL_FETCH_RESUME is no longer supported #define SQL_FD_FETCH_RESUME 0x00000040L */ #define SQL_FD_FETCH_BOOKMARK 0x00000080L /* SQL_TXN_ISOLATION_OPTION masks */ /* SQL_TXN_VERSIONING is no longer supported #define SQL_TXN_VERSIONING 0x00000010L */ /* SQL_CORRELATION_NAME values */ #define SQL_CN_NONE 0x0000 #define SQL_CN_DIFFERENT 0x0001 #define SQL_CN_ANY 0x0002 /* SQL_NON_NULLABLE_COLUMNS values */ #define SQL_NNC_NULL 0x0000 #define SQL_NNC_NON_NULL 0x0001 /* SQL_NULL_COLLATION values */ #define SQL_NC_START 0x0002 #define SQL_NC_END 0x0004 /* SQL_FILE_USAGE values */ #define SQL_FILE_NOT_SUPPORTED 0x0000 #define SQL_FILE_TABLE 0x0001 #define SQL_FILE_QUALIFIER 0x0002 #define SQL_FILE_CATALOG SQL_FILE_QUALIFIER /* ODBC 3.0 */ /* SQL_GETDATA_EXTENSIONS values */ #define SQL_GD_BLOCK 0x00000004L #define SQL_GD_BOUND 0x00000008L #if (ODBCVER >= 0x0380) #define SQL_GD_OUTPUT_PARAMS 0x00000010L #endif /* SQL_POSITIONED_STATEMENTS masks */ #define SQL_PS_POSITIONED_DELETE 0x00000001L #define SQL_PS_POSITIONED_UPDATE 0x00000002L #define SQL_PS_SELECT_FOR_UPDATE 0x00000004L /* SQL_GROUP_BY values */ #define SQL_GB_NOT_SUPPORTED 0x0000 #define SQL_GB_GROUP_BY_EQUALS_SELECT 0x0001 #define SQL_GB_GROUP_BY_CONTAINS_SELECT 0x0002 #define SQL_GB_NO_RELATION 0x0003 #if (ODBCVER >= 0x0300) #define SQL_GB_COLLATE 0x0004 #endif /* ODBCVER >= 0x0300 */ /* SQL_OWNER_USAGE masks */ #define SQL_OU_DML_STATEMENTS 0x00000001L #define SQL_OU_PROCEDURE_INVOCATION 0x00000002L #define SQL_OU_TABLE_DEFINITION 0x00000004L #define SQL_OU_INDEX_DEFINITION 0x00000008L #define SQL_OU_PRIVILEGE_DEFINITION 0x00000010L /* SQL_SCHEMA_USAGE masks */ #if (ODBCVER >= 0x0300) #define SQL_SU_DML_STATEMENTS SQL_OU_DML_STATEMENTS #define SQL_SU_PROCEDURE_INVOCATION SQL_OU_PROCEDURE_INVOCATION #define SQL_SU_TABLE_DEFINITION SQL_OU_TABLE_DEFINITION #define SQL_SU_INDEX_DEFINITION SQL_OU_INDEX_DEFINITION #define SQL_SU_PRIVILEGE_DEFINITION SQL_OU_PRIVILEGE_DEFINITION #endif /* ODBCVER >= 0x0300 */ /* SQL_QUALIFIER_USAGE masks */ #define SQL_QU_DML_STATEMENTS 0x00000001L #define SQL_QU_PROCEDURE_INVOCATION 0x00000002L #define SQL_QU_TABLE_DEFINITION 0x00000004L #define SQL_QU_INDEX_DEFINITION 0x00000008L #define SQL_QU_PRIVILEGE_DEFINITION 0x00000010L #if (ODBCVER >= 0x0300) /* SQL_CATALOG_USAGE masks */ #define SQL_CU_DML_STATEMENTS SQL_QU_DML_STATEMENTS #define SQL_CU_PROCEDURE_INVOCATION SQL_QU_PROCEDURE_INVOCATION #define SQL_CU_TABLE_DEFINITION SQL_QU_TABLE_DEFINITION #define SQL_CU_INDEX_DEFINITION SQL_QU_INDEX_DEFINITION #define SQL_CU_PRIVILEGE_DEFINITION SQL_QU_PRIVILEGE_DEFINITION #endif /* ODBCVER >= 0x0300 */ /* SQL_SUBQUERIES masks */ #define SQL_SQ_COMPARISON 0x00000001L #define SQL_SQ_EXISTS 0x00000002L #define SQL_SQ_IN 0x00000004L #define SQL_SQ_QUANTIFIED 0x00000008L #define SQL_SQ_CORRELATED_SUBQUERIES 0x00000010L /* SQL_UNION masks */ #define SQL_U_UNION 0x00000001L #define SQL_U_UNION_ALL 0x00000002L /* SQL_BOOKMARK_PERSISTENCE values */ #define SQL_BP_CLOSE 0x00000001L #define SQL_BP_DELETE 0x00000002L #define SQL_BP_DROP 0x00000004L #define SQL_BP_TRANSACTION 0x00000008L #define SQL_BP_UPDATE 0x00000010L #define SQL_BP_OTHER_HSTMT 0x00000020L #define SQL_BP_SCROLL 0x00000040L /* SQL_STATIC_SENSITIVITY values */ #define SQL_SS_ADDITIONS 0x00000001L #define SQL_SS_DELETIONS 0x00000002L #define SQL_SS_UPDATES 0x00000004L /* SQL_VIEW values */ #define SQL_CV_CREATE_VIEW 0x00000001L #define SQL_CV_CHECK_OPTION 0x00000002L #define SQL_CV_CASCADED 0x00000004L #define SQL_CV_LOCAL 0x00000008L /* SQL_LOCK_TYPES masks */ #define SQL_LCK_NO_CHANGE 0x00000001L #define SQL_LCK_EXCLUSIVE 0x00000002L #define SQL_LCK_UNLOCK 0x00000004L /* SQL_POS_OPERATIONS masks */ #define SQL_POS_POSITION 0x00000001L #define SQL_POS_REFRESH 0x00000002L #define SQL_POS_UPDATE 0x00000004L #define SQL_POS_DELETE 0x00000008L #define SQL_POS_ADD 0x00000010L /* SQL_QUALIFIER_LOCATION values */ #define SQL_QL_START 0x0001 #define SQL_QL_END 0x0002 /* Here start return values for ODBC 3.0 SQLGetInfo */ #if (ODBCVER >= 0x0300) /* SQL_AGGREGATE_FUNCTIONS bitmasks */ #define SQL_AF_AVG 0x00000001L #define SQL_AF_COUNT 0x00000002L #define SQL_AF_MAX 0x00000004L #define SQL_AF_MIN 0x00000008L #define SQL_AF_SUM 0x00000010L #define SQL_AF_DISTINCT 0x00000020L #define SQL_AF_ALL 0x00000040L /* SQL_SQL_CONFORMANCE bit masks */ #define SQL_SC_SQL92_ENTRY 0x00000001L #define SQL_SC_FIPS127_2_TRANSITIONAL 0x00000002L #define SQL_SC_SQL92_INTERMEDIATE 0x00000004L #define SQL_SC_SQL92_FULL 0x00000008L /* SQL_DATETIME_LITERALS masks */ #define SQL_DL_SQL92_DATE 0x00000001L #define SQL_DL_SQL92_TIME 0x00000002L #define SQL_DL_SQL92_TIMESTAMP 0x00000004L #define SQL_DL_SQL92_INTERVAL_YEAR 0x00000008L #define SQL_DL_SQL92_INTERVAL_MONTH 0x00000010L #define SQL_DL_SQL92_INTERVAL_DAY 0x00000020L #define SQL_DL_SQL92_INTERVAL_HOUR 0x00000040L #define SQL_DL_SQL92_INTERVAL_MINUTE 0x00000080L #define SQL_DL_SQL92_INTERVAL_SECOND 0x00000100L #define SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH 0x00000200L #define SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR 0x00000400L #define SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE 0x00000800L #define SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND 0x00001000L #define SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE 0x00002000L #define SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND 0x00004000L #define SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND 0x00008000L /* SQL_CATALOG_LOCATION values */ #define SQL_CL_START SQL_QL_START #define SQL_CL_END SQL_QL_END /* values for SQL_BATCH_ROW_COUNT */ #define SQL_BRC_PROCEDURES 0x0000001 #define SQL_BRC_EXPLICIT 0x0000002 #define SQL_BRC_ROLLED_UP 0x0000004 /* bitmasks for SQL_BATCH_SUPPORT */ #define SQL_BS_SELECT_EXPLICIT 0x00000001L #define SQL_BS_ROW_COUNT_EXPLICIT 0x00000002L #define SQL_BS_SELECT_PROC 0x00000004L #define SQL_BS_ROW_COUNT_PROC 0x00000008L /* Values for SQL_PARAM_ARRAY_ROW_COUNTS getinfo */ #define SQL_PARC_BATCH 1 #define SQL_PARC_NO_BATCH 2 /* values for SQL_PARAM_ARRAY_SELECTS */ #define SQL_PAS_BATCH 1 #define SQL_PAS_NO_BATCH 2 #define SQL_PAS_NO_SELECT 3 /* Bitmasks for SQL_INDEX_KEYWORDS */ #define SQL_IK_NONE 0x00000000L #define SQL_IK_ASC 0x00000001L #define SQL_IK_DESC 0x00000002L #define SQL_IK_ALL (SQL_IK_ASC | SQL_IK_DESC) /* Bitmasks for SQL_INFO_SCHEMA_VIEWS */ #define SQL_ISV_ASSERTIONS 0x00000001L #define SQL_ISV_CHARACTER_SETS 0x00000002L #define SQL_ISV_CHECK_CONSTRAINTS 0x00000004L #define SQL_ISV_COLLATIONS 0x00000008L #define SQL_ISV_COLUMN_DOMAIN_USAGE 0x00000010L #define SQL_ISV_COLUMN_PRIVILEGES 0x00000020L #define SQL_ISV_COLUMNS 0x00000040L #define SQL_ISV_CONSTRAINT_COLUMN_USAGE 0x00000080L #define SQL_ISV_CONSTRAINT_TABLE_USAGE 0x00000100L #define SQL_ISV_DOMAIN_CONSTRAINTS 0x00000200L #define SQL_ISV_DOMAINS 0x00000400L #define SQL_ISV_KEY_COLUMN_USAGE 0x00000800L #define SQL_ISV_REFERENTIAL_CONSTRAINTS 0x00001000L #define SQL_ISV_SCHEMATA 0x00002000L #define SQL_ISV_SQL_LANGUAGES 0x00004000L #define SQL_ISV_TABLE_CONSTRAINTS 0x00008000L #define SQL_ISV_TABLE_PRIVILEGES 0x00010000L #define SQL_ISV_TABLES 0x00020000L #define SQL_ISV_TRANSLATIONS 0x00040000L #define SQL_ISV_USAGE_PRIVILEGES 0x00080000L #define SQL_ISV_VIEW_COLUMN_USAGE 0x00100000L #define SQL_ISV_VIEW_TABLE_USAGE 0x00200000L #define SQL_ISV_VIEWS 0x00400000L /* Bitmasks for SQL_ASYNC_MODE */ #define SQL_AM_NONE 0 #define SQL_AM_CONNECTION 1 #define SQL_AM_STATEMENT 2 /* Bitmasks for SQL_ALTER_DOMAIN */ #define SQL_AD_CONSTRAINT_NAME_DEFINITION 0x00000001L #define SQL_AD_ADD_DOMAIN_CONSTRAINT 0x00000002L #define SQL_AD_DROP_DOMAIN_CONSTRAINT 0x00000004L #define SQL_AD_ADD_DOMAIN_DEFAULT 0x00000008L #define SQL_AD_DROP_DOMAIN_DEFAULT 0x00000010L #define SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L #define SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L #define SQL_AD_ADD_CONSTRAINT_DEFERRABLE 0x00000080L #define SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE 0x00000100L /* SQL_CREATE_SCHEMA bitmasks */ #define SQL_CS_CREATE_SCHEMA 0x00000001L #define SQL_CS_AUTHORIZATION 0x00000002L #define SQL_CS_DEFAULT_CHARACTER_SET 0x00000004L /* SQL_CREATE_TRANSLATION bitmasks */ #define SQL_CTR_CREATE_TRANSLATION 0x00000001L /* SQL_CREATE_ASSERTION bitmasks */ #define SQL_CA_CREATE_ASSERTION 0x00000001L #define SQL_CA_CONSTRAINT_INITIALLY_DEFERRED 0x00000010L #define SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000020L #define SQL_CA_CONSTRAINT_DEFERRABLE 0x00000040L #define SQL_CA_CONSTRAINT_NON_DEFERRABLE 0x00000080L /* SQL_CREATE_CHARACTER_SET bitmasks */ #define SQL_CCS_CREATE_CHARACTER_SET 0x00000001L #define SQL_CCS_COLLATE_CLAUSE 0x00000002L #define SQL_CCS_LIMITED_COLLATION 0x00000004L /* SQL_CREATE_COLLATION bitmasks */ #define SQL_CCOL_CREATE_COLLATION 0x00000001L /* SQL_CREATE_DOMAIN bitmasks */ #define SQL_CDO_CREATE_DOMAIN 0x00000001L #define SQL_CDO_DEFAULT 0x00000002L #define SQL_CDO_CONSTRAINT 0x00000004L #define SQL_CDO_COLLATION 0x00000008L #define SQL_CDO_CONSTRAINT_NAME_DEFINITION 0x00000010L #define SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L #define SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L #define SQL_CDO_CONSTRAINT_DEFERRABLE 0x00000080L #define SQL_CDO_CONSTRAINT_NON_DEFERRABLE 0x00000100L /* SQL_CREATE_TABLE bitmasks */ #define SQL_CT_CREATE_TABLE 0x00000001L #define SQL_CT_COMMIT_PRESERVE 0x00000002L #define SQL_CT_COMMIT_DELETE 0x00000004L #define SQL_CT_GLOBAL_TEMPORARY 0x00000008L #define SQL_CT_LOCAL_TEMPORARY 0x00000010L #define SQL_CT_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L #define SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L #define SQL_CT_CONSTRAINT_DEFERRABLE 0x00000080L #define SQL_CT_CONSTRAINT_NON_DEFERRABLE 0x00000100L #define SQL_CT_COLUMN_CONSTRAINT 0x00000200L #define SQL_CT_COLUMN_DEFAULT 0x00000400L #define SQL_CT_COLUMN_COLLATION 0x00000800L #define SQL_CT_TABLE_CONSTRAINT 0x00001000L #define SQL_CT_CONSTRAINT_NAME_DEFINITION 0x00002000L /* SQL_DDL_INDEX bitmasks */ #define SQL_DI_CREATE_INDEX 0x00000001L #define SQL_DI_DROP_INDEX 0x00000002L /* SQL_DROP_COLLATION bitmasks */ #define SQL_DC_DROP_COLLATION 0x00000001L /* SQL_DROP_DOMAIN bitmasks */ #define SQL_DD_DROP_DOMAIN 0x00000001L #define SQL_DD_RESTRICT 0x00000002L #define SQL_DD_CASCADE 0x00000004L /* SQL_DROP_SCHEMA bitmasks */ #define SQL_DS_DROP_SCHEMA 0x00000001L #define SQL_DS_RESTRICT 0x00000002L #define SQL_DS_CASCADE 0x00000004L /* SQL_DROP_CHARACTER_SET bitmasks */ #define SQL_DCS_DROP_CHARACTER_SET 0x00000001L /* SQL_DROP_ASSERTION bitmasks */ #define SQL_DA_DROP_ASSERTION 0x00000001L /* SQL_DROP_TABLE bitmasks */ #define SQL_DT_DROP_TABLE 0x00000001L #define SQL_DT_RESTRICT 0x00000002L #define SQL_DT_CASCADE 0x00000004L /* SQL_DROP_TRANSLATION bitmasks */ #define SQL_DTR_DROP_TRANSLATION 0x00000001L /* SQL_DROP_VIEW bitmasks */ #define SQL_DV_DROP_VIEW 0x00000001L #define SQL_DV_RESTRICT 0x00000002L #define SQL_DV_CASCADE 0x00000004L /* SQL_INSERT_STATEMENT bitmasks */ #define SQL_IS_INSERT_LITERALS 0x00000001L #define SQL_IS_INSERT_SEARCHED 0x00000002L #define SQL_IS_SELECT_INTO 0x00000004L /* SQL_ODBC_INTERFACE_CONFORMANCE values */ #define SQL_OIC_CORE 1UL #define SQL_OIC_LEVEL1 2UL #define SQL_OIC_LEVEL2 3UL /* SQL_SQL92_FOREIGN_KEY_DELETE_RULE bitmasks */ #define SQL_SFKD_CASCADE 0x00000001L #define SQL_SFKD_NO_ACTION 0x00000002L #define SQL_SFKD_SET_DEFAULT 0x00000004L #define SQL_SFKD_SET_NULL 0x00000008L /* SQL_SQL92_FOREIGN_KEY_UPDATE_RULE bitmasks */ #define SQL_SFKU_CASCADE 0x00000001L #define SQL_SFKU_NO_ACTION 0x00000002L #define SQL_SFKU_SET_DEFAULT 0x00000004L #define SQL_SFKU_SET_NULL 0x00000008L /* SQL_SQL92_GRANT bitmasks */ #define SQL_SG_USAGE_ON_DOMAIN 0x00000001L #define SQL_SG_USAGE_ON_CHARACTER_SET 0x00000002L #define SQL_SG_USAGE_ON_COLLATION 0x00000004L #define SQL_SG_USAGE_ON_TRANSLATION 0x00000008L #define SQL_SG_WITH_GRANT_OPTION 0x00000010L #define SQL_SG_DELETE_TABLE 0x00000020L #define SQL_SG_INSERT_TABLE 0x00000040L #define SQL_SG_INSERT_COLUMN 0x00000080L #define SQL_SG_REFERENCES_TABLE 0x00000100L #define SQL_SG_REFERENCES_COLUMN 0x00000200L #define SQL_SG_SELECT_TABLE 0x00000400L #define SQL_SG_UPDATE_TABLE 0x00000800L #define SQL_SG_UPDATE_COLUMN 0x00001000L /* SQL_SQL92_PREDICATES bitmasks */ #define SQL_SP_EXISTS 0x00000001L #define SQL_SP_ISNOTNULL 0x00000002L #define SQL_SP_ISNULL 0x00000004L #define SQL_SP_MATCH_FULL 0x00000008L #define SQL_SP_MATCH_PARTIAL 0x00000010L #define SQL_SP_MATCH_UNIQUE_FULL 0x00000020L #define SQL_SP_MATCH_UNIQUE_PARTIAL 0x00000040L #define SQL_SP_OVERLAPS 0x00000080L #define SQL_SP_UNIQUE 0x00000100L #define SQL_SP_LIKE 0x00000200L #define SQL_SP_IN 0x00000400L #define SQL_SP_BETWEEN 0x00000800L #define SQL_SP_COMPARISON 0x00001000L #define SQL_SP_QUANTIFIED_COMPARISON 0x00002000L /* SQL_SQL92_RELATIONAL_JOIN_OPERATORS bitmasks */ #define SQL_SRJO_CORRESPONDING_CLAUSE 0x00000001L #define SQL_SRJO_CROSS_JOIN 0x00000002L #define SQL_SRJO_EXCEPT_JOIN 0x00000004L #define SQL_SRJO_FULL_OUTER_JOIN 0x00000008L #define SQL_SRJO_INNER_JOIN 0x00000010L #define SQL_SRJO_INTERSECT_JOIN 0x00000020L #define SQL_SRJO_LEFT_OUTER_JOIN 0x00000040L #define SQL_SRJO_NATURAL_JOIN 0x00000080L #define SQL_SRJO_RIGHT_OUTER_JOIN 0x00000100L #define SQL_SRJO_UNION_JOIN 0x00000200L /* SQL_SQL92_REVOKE bitmasks */ #define SQL_SR_USAGE_ON_DOMAIN 0x00000001L #define SQL_SR_USAGE_ON_CHARACTER_SET 0x00000002L #define SQL_SR_USAGE_ON_COLLATION 0x00000004L #define SQL_SR_USAGE_ON_TRANSLATION 0x00000008L #define SQL_SR_GRANT_OPTION_FOR 0x00000010L #define SQL_SR_CASCADE 0x00000020L #define SQL_SR_RESTRICT 0x00000040L #define SQL_SR_DELETE_TABLE 0x00000080L #define SQL_SR_INSERT_TABLE 0x00000100L #define SQL_SR_INSERT_COLUMN 0x00000200L #define SQL_SR_REFERENCES_TABLE 0x00000400L #define SQL_SR_REFERENCES_COLUMN 0x00000800L #define SQL_SR_SELECT_TABLE 0x00001000L #define SQL_SR_UPDATE_TABLE 0x00002000L #define SQL_SR_UPDATE_COLUMN 0x00004000L /* SQL_SQL92_ROW_VALUE_CONSTRUCTOR bitmasks */ #define SQL_SRVC_VALUE_EXPRESSION 0x00000001L #define SQL_SRVC_NULL 0x00000002L #define SQL_SRVC_DEFAULT 0x00000004L #define SQL_SRVC_ROW_SUBQUERY 0x00000008L /* SQL_SQL92_VALUE_EXPRESSIONS bitmasks */ #define SQL_SVE_CASE 0x00000001L #define SQL_SVE_CAST 0x00000002L #define SQL_SVE_COALESCE 0x00000004L #define SQL_SVE_NULLIF 0x00000008L /* SQL_STANDARD_CLI_CONFORMANCE bitmasks */ #define SQL_SCC_XOPEN_CLI_VERSION1 0x00000001L #define SQL_SCC_ISO92_CLI 0x00000002L /* SQL_UNION_STATEMENT bitmasks */ #define SQL_US_UNION SQL_U_UNION #define SQL_US_UNION_ALL SQL_U_UNION_ALL /* values for SQL_DRIVER_AWARE_POOLING_SUPPORTED */ #define SQL_DRIVER_AWARE_POOLING_NOT_CAPABLE 0x00000000L #define SQL_DRIVER_AWARE_POOLING_CAPABLE 0x00000001L #endif /* ODBCVER >= 0x0300 */ /* SQL_DTC_TRANSITION_COST bitmasks */ #define SQL_DTC_ENLIST_EXPENSIVE 0x00000001L #define SQL_DTC_UNENLIST_EXPENSIVE 0x00000002L #if (ODBCVER >= 0x0380) /* possible values for SQL_ASYNC_DBC_FUNCTIONS */ #define SQL_ASYNC_DBC_NOT_CAPABLE 0x00000000L #define SQL_ASYNC_DBC_CAPABLE 0x00000001L #endif /* additional SQLDataSources fetch directions */ #if (ODBCVER >= 0x0300) #define SQL_FETCH_FIRST_USER 31 #define SQL_FETCH_FIRST_SYSTEM 32 #endif /* ODBCVER >= 0x0300 */ /* Defines for SQLSetPos */ #define SQL_ENTIRE_ROWSET 0 /* Operations in SQLSetPos */ #define SQL_POSITION 0 /* 1.0 FALSE */ #define SQL_REFRESH 1 /* 1.0 TRUE */ #define SQL_UPDATE 2 #define SQL_DELETE 3 /* Operations in SQLBulkOperations */ #define SQL_ADD 4 #define SQL_SETPOS_MAX_OPTION_VALUE SQL_ADD #if (ODBCVER >= 0x0300) #define SQL_UPDATE_BY_BOOKMARK 5 #define SQL_DELETE_BY_BOOKMARK 6 #define SQL_FETCH_BY_BOOKMARK 7 #endif /* ODBCVER >= 0x0300 */ /* Lock options in SQLSetPos */ #define SQL_LOCK_NO_CHANGE 0 /* 1.0 FALSE */ #define SQL_LOCK_EXCLUSIVE 1 /* 1.0 TRUE */ #define SQL_LOCK_UNLOCK 2 #define SQL_SETPOS_MAX_LOCK_VALUE SQL_LOCK_UNLOCK /* Macros for SQLSetPos */ #define SQL_POSITION_TO(hstmt,irow) SQLSetPos(hstmt,irow,SQL_POSITION,SQL_LOCK_NO_CHANGE) #define SQL_LOCK_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_POSITION,fLock) #define SQL_REFRESH_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_REFRESH,fLock) #define SQL_UPDATE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_UPDATE,SQL_LOCK_NO_CHANGE) #define SQL_DELETE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_DELETE,SQL_LOCK_NO_CHANGE) #define SQL_ADD_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_ADD,SQL_LOCK_NO_CHANGE) /* Column types and scopes in SQLSpecialColumns. */ #define SQL_BEST_ROWID 1 #define SQL_ROWVER 2 /* Defines for SQLSpecialColumns (returned in the result set) SQL_PC_UNKNOWN and SQL_PC_PSEUDO are defined in sql.h */ #define SQL_PC_NOT_PSEUDO 1 /* Defines for SQLStatistics */ #define SQL_QUICK 0 #define SQL_ENSURE 1 /* Defines for SQLStatistics (returned in the result set) SQL_INDEX_CLUSTERED, SQL_INDEX_HASHED, and SQL_INDEX_OTHER are defined in sql.h */ #define SQL_TABLE_STAT 0 /* Defines for SQLTables */ #if (ODBCVER >= 0x0300) #define SQL_ALL_CATALOGS "%" #define SQL_ALL_SCHEMAS "%" #define SQL_ALL_TABLE_TYPES "%" #endif /* ODBCVER >= 0x0300 */ /* Options for SQLDriverConnect */ #define SQL_DRIVER_NOPROMPT 0 #define SQL_DRIVER_COMPLETE 1 #define SQL_DRIVER_PROMPT 2 #define SQL_DRIVER_COMPLETE_REQUIRED 3 SQLRETURN SQL_API SQLDriverConnect( SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut, SQLUSMALLINT fDriverCompletion); /* Level 2 Functions */ /* SQLExtendedFetch "fFetchType" values */ #define SQL_FETCH_BOOKMARK 8 /* SQLExtendedFetch "rgfRowStatus" element values */ #define SQL_ROW_SUCCESS 0 #define SQL_ROW_DELETED 1 #define SQL_ROW_UPDATED 2 #define SQL_ROW_NOROW 3 #define SQL_ROW_ADDED 4 #define SQL_ROW_ERROR 5 #if (ODBCVER >= 0x0300) #define SQL_ROW_SUCCESS_WITH_INFO 6 #define SQL_ROW_PROCEED 0 #define SQL_ROW_IGNORE 1 #endif /* value for SQL_DESC_ARRAY_STATUS_PTR */ #if (ODBCVER >= 0x0300) #define SQL_PARAM_SUCCESS 0 #define SQL_PARAM_SUCCESS_WITH_INFO 6 #define SQL_PARAM_ERROR 5 #define SQL_PARAM_UNUSED 7 #define SQL_PARAM_DIAG_UNAVAILABLE 1 #define SQL_PARAM_PROCEED 0 #define SQL_PARAM_IGNORE 1 #endif /* ODBCVER >= 0x0300 */ /* Defines for SQLForeignKeys (UPDATE_RULE and DELETE_RULE) */ #define SQL_CASCADE 0 #define SQL_RESTRICT 1 #define SQL_SET_NULL 2 #if (ODBCVER >= 0x0250) #define SQL_NO_ACTION 3 #define SQL_SET_DEFAULT 4 #endif /* ODBCVER >= 0x0250 */ #if (ODBCVER >= 0x0300) /* Note that the following are in a different column of SQLForeignKeys than */ /* the previous #defines. These are for DEFERRABILITY. */ #define SQL_INITIALLY_DEFERRED 5 #define SQL_INITIALLY_IMMEDIATE 6 #define SQL_NOT_DEFERRABLE 7 #endif /* ODBCVER >= 0x0300 */ /* Defines for SQLBindParameter and SQLProcedureColumns (returned in the result set) */ #define SQL_PARAM_TYPE_UNKNOWN 0 #define SQL_PARAM_INPUT 1 #define SQL_PARAM_INPUT_OUTPUT 2 #define SQL_RESULT_COL 3 #define SQL_PARAM_OUTPUT 4 #define SQL_RETURN_VALUE 5 #if (ODBCVER >= 0x0380) #define SQL_PARAM_INPUT_OUTPUT_STREAM 8 #define SQL_PARAM_OUTPUT_STREAM 16 #endif /* Defines for SQLProcedures (returned in the result set) */ #define SQL_PT_UNKNOWN 0 #define SQL_PT_PROCEDURE 1 #define SQL_PT_FUNCTION 2 /* This define is too large for RC */ #define SQL_ODBC_KEYWORDS "ABSOLUTE,ACTION,ADA,ADD,ALL,ALLOCATE,ALTER,AND,ANY,ARE,AS,"\ "ASC,ASSERTION,AT,AUTHORIZATION,AVG,"\ "BEGIN,BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,CATALOG,"\ "CHAR,CHAR_LENGTH,CHARACTER,CHARACTER_LENGTH,CHECK,CLOSE,COALESCE,"\ "COLLATE,COLLATION,COLUMN,COMMIT,CONNECT,CONNECTION,CONSTRAINT,"\ "CONSTRAINTS,CONTINUE,CONVERT,CORRESPONDING,COUNT,CREATE,CROSS,CURRENT,"\ "CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,"\ "DATE,DAY,DEALLOCATE,DEC,DECIMAL,DECLARE,DEFAULT,DEFERRABLE,"\ "DEFERRED,DELETE,DESC,DESCRIBE,DESCRIPTOR,DIAGNOSTICS,DISCONNECT,"\ "DISTINCT,DOMAIN,DOUBLE,DROP,"\ "ELSE,END,END-EXEC,ESCAPE,EXCEPT,EXCEPTION,EXEC,EXECUTE,"\ "EXISTS,EXTERNAL,EXTRACT,"\ "FALSE,FETCH,FIRST,FLOAT,FOR,FOREIGN,FORTRAN,FOUND,FROM,FULL,"\ "GET,GLOBAL,GO,GOTO,GRANT,GROUP,HAVING,HOUR,"\ "IDENTITY,IMMEDIATE,IN,INCLUDE,INDEX,INDICATOR,INITIALLY,INNER,"\ "INPUT,INSENSITIVE,INSERT,INT,INTEGER,INTERSECT,INTERVAL,INTO,IS,ISOLATION,"\ "JOIN,KEY,LANGUAGE,LAST,LEADING,LEFT,LEVEL,LIKE,LOCAL,LOWER,"\ "MATCH,MAX,MIN,MINUTE,MODULE,MONTH,"\ "NAMES,NATIONAL,NATURAL,NCHAR,NEXT,NO,NONE,NOT,NULL,NULLIF,NUMERIC,"\ "OCTET_LENGTH,OF,ON,ONLY,OPEN,OPTION,OR,ORDER,OUTER,OUTPUT,OVERLAPS,"\ "PAD,PARTIAL,PASCAL,PLI,POSITION,PRECISION,PREPARE,PRESERVE,"\ "PRIMARY,PRIOR,PRIVILEGES,PROCEDURE,PUBLIC,"\ "READ,REAL,REFERENCES,RELATIVE,RESTRICT,REVOKE,RIGHT,ROLLBACK,ROWS"\ "SCHEMA,SCROLL,SECOND,SECTION,SELECT,SESSION,SESSION_USER,SET,SIZE,"\ "SMALLINT,SOME,SPACE,SQL,SQLCA,SQLCODE,SQLERROR,SQLSTATE,SQLWARNING,"\ "SUBSTRING,SUM,SYSTEM_USER,"\ "TABLE,TEMPORARY,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,"\ "TO,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,TRUE,"\ "UNION,UNIQUE,UNKNOWN,UPDATE,UPPER,USAGE,USER,USING,"\ "VALUE,VALUES,VARCHAR,VARYING,VIEW,WHEN,WHENEVER,WHERE,WITH,WORK,WRITE,"\ "YEAR,ZONE" SQLRETURN SQL_API SQLBrowseConnect( SQLHDBC hdbc, SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLBulkOperations( SQLHSTMT StatementHandle, SQLSMALLINT Operation); #endif /* ODBCVER >= 0x0300 */ SQLRETURN SQL_API SQLColAttributes( SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLPOINTER rgbDesc, SQLSMALLINT cbDescMax, SQLSMALLINT *pcbDesc, SQLLEN *pfDesc); SQLRETURN SQL_API SQLColumnPrivileges( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName, SQLSMALLINT cbTableName, SQLCHAR *szColumnName, SQLSMALLINT cbColumnName); SQLRETURN SQL_API SQLDescribeParam( SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT *pfSqlType, SQLULEN *pcbParamDef, SQLSMALLINT *pibScale, SQLSMALLINT *pfNullable); SQLRETURN SQL_API SQLExtendedFetch( SQLHSTMT hstmt, SQLUSMALLINT fFetchType, SQLLEN irow, SQLULEN *pcrow, SQLUSMALLINT *rgfRowStatus); SQLRETURN SQL_API SQLForeignKeys( SQLHSTMT hstmt, SQLCHAR *szPkCatalogName, SQLSMALLINT cbPkCatalogName, SQLCHAR *szPkSchemaName, SQLSMALLINT cbPkSchemaName, SQLCHAR *szPkTableName, SQLSMALLINT cbPkTableName, SQLCHAR *szFkCatalogName, SQLSMALLINT cbFkCatalogName, SQLCHAR *szFkSchemaName, SQLSMALLINT cbFkSchemaName, SQLCHAR *szFkTableName, SQLSMALLINT cbFkTableName); SQLRETURN SQL_API SQLMoreResults( SQLHSTMT hstmt); SQLRETURN SQL_API SQLNativeSql( SQLHDBC hdbc, SQLCHAR *szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLCHAR *szSqlStr, SQLINTEGER cbSqlStrMax, SQLINTEGER *pcbSqlStr); SQLRETURN SQL_API SQLNumParams( SQLHSTMT hstmt, SQLSMALLINT *pcpar); SQLRETURN SQL_API SQLParamOptions( SQLHSTMT hstmt, SQLULEN crow, SQLULEN *pirow); SQLRETURN SQL_API SQLPrimaryKeys( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName, SQLSMALLINT cbTableName); SQLRETURN SQL_API SQLProcedureColumns( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szProcName, SQLSMALLINT cbProcName, SQLCHAR *szColumnName, SQLSMALLINT cbColumnName); SQLRETURN SQL_API SQLProcedures( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szProcName, SQLSMALLINT cbProcName); SQLRETURN SQL_API SQLSetPos( SQLHSTMT hstmt, SQLSETPOSIROW irow, SQLUSMALLINT fOption, SQLUSMALLINT fLock); SQLRETURN SQL_API SQLTablePrivileges( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName, SQLSMALLINT cbTableName); SQLRETURN SQL_API SQLDrivers( SQLHENV henv, SQLUSMALLINT fDirection, SQLCHAR *szDriverDesc, SQLSMALLINT cbDriverDescMax, SQLSMALLINT *pcbDriverDesc, SQLCHAR *szDriverAttributes, SQLSMALLINT cbDrvrAttrMax, SQLSMALLINT *pcbDrvrAttr); SQLRETURN SQL_API SQLBindParameter( SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType, SQLSMALLINT fCType, SQLSMALLINT fSqlType, SQLULEN cbColDef, SQLSMALLINT ibScale, SQLPOINTER rgbValue, SQLLEN cbValueMax, SQLLEN *pcbValue); /*---------------------------------------------------------*/ /* SQLAllocHandleStd is implemented to make SQLAllocHandle */ /* compatible with X/Open standard. an application should */ /* not call SQLAllocHandleStd directly */ /*---------------------------------------------------------*/ #ifdef ODBC_STD #define SQLAllocHandle SQLAllocHandleStd #define SQLAllocEnv(phenv) SQLAllocHandleStd(SQL_HANDLE_ENV, SQL_NULL_HANDLE, phenv) /* Internal type subcodes */ #define SQL_YEAR SQL_CODE_YEAR #define SQL_MONTH SQL_CODE_MONTH #define SQL_DAY SQL_CODE_DAY #define SQL_HOUR SQL_CODE_HOUR #define SQL_MINUTE SQL_CODE_MINUTE #define SQL_SECOND SQL_CODE_SECOND #define SQL_YEAR_TO_MONTH SQL_CODE_YEAR_TO_MONTH #define SQL_DAY_TO_HOUR SQL_CODE_DAY_TO_HOUR #define SQL_DAY_TO_MINUTE SQL_CODE_DAY_TO_MINUTE #define SQL_DAY_TO_SECOND SQL_CODE_DAY_TO_SECOND #define SQL_HOUR_TO_MINUTE SQL_CODE_HOUR_TO_MINUTE #define SQL_HOUR_TO_SECOND SQL_CODE_HOUR_TO_SECOND #define SQL_MINUTE_TO_SECOND SQL_CODE_MINUTE_TO_SECOND #endif /* ODBC_STD */ #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLAllocHandleStd( SQLSMALLINT fHandleType, SQLHANDLE hInput, SQLHANDLE *phOutput); #endif /* Deprecated defines from prior versions of ODBC */ #define SQL_DATABASE_NAME 16 /* Use SQLGetConnectOption/SQL_CURRENT_QUALIFIER */ #define SQL_FD_FETCH_PREV SQL_FD_FETCH_PRIOR #define SQL_FETCH_PREV SQL_FETCH_PRIOR #define SQL_CONCUR_TIMESTAMP SQL_CONCUR_ROWVER #define SQL_SCCO_OPT_TIMESTAMP SQL_SCCO_OPT_ROWVER #define SQL_CC_DELETE SQL_CB_DELETE #define SQL_CR_DELETE SQL_CB_DELETE #define SQL_CC_CLOSE SQL_CB_CLOSE #define SQL_CR_CLOSE SQL_CB_CLOSE #define SQL_CC_PRESERVE SQL_CB_PRESERVE #define SQL_CR_PRESERVE SQL_CB_PRESERVE /* SQL_FETCH_RESUME is not supported by 2.0+ drivers #define SQL_FETCH_RESUME 7 */ #define SQL_SCROLL_FORWARD_ONLY 0L /*-SQL_CURSOR_FORWARD_ONLY */ #define SQL_SCROLL_KEYSET_DRIVEN (-1L) /*-SQL_CURSOR_KEYSET_DRIVEN */ #define SQL_SCROLL_DYNAMIC (-2L) /*-SQL_CURSOR_DYNAMIC */ #define SQL_SCROLL_STATIC (-3L) /*-SQL_CURSOR_STATIC */ /* Deprecated functions from prior versions of ODBC */ SQLRETURN SQL_API SQLSetScrollOptions( /* Use SQLSetStmtOptions */ SQLHSTMT hstmt, SQLUSMALLINT fConcurrency, SQLLEN crowKeyset, SQLUSMALLINT crowRowset); /*! * \defgroup Tracing. * * unixODBC implements a slight variation of the tracing mechanism used * on MS platforms. The unixODBC method loses the ability to produce trace * output for invalid handles but gains the following; * * - better concurrency * - allows tracing to be turned on/off and configured at finer granularity * - hopefully; better performance * * unixODBC provides a cross-platform helper library called 'trace' and an * example/default trace plugin called 'odbctrac'. Those writing an ODBC * driver can use the 'trace' helper library (a static library). Those wanting * to create custom trace output can implement a different version of the * 'odbctrac' plugin. * * The text file driver (odbctxt) included with unixODBC is an example of a * driver using the 'trace' helper library. * * The 'trace' library and the example plugin 'odbctrac' are designed to be * portable on all platforms where unixODBC is available and on MS platforms. * This will allow drivers using 'trace' and 'odbctrac' plugin to equilly * portable. On MS platforms - this compliments traditional tracing (mostly * just used by the Driver Manager). * * \sa trace * odbctxt * odbctrac */ /**@{*/ #define TRACE_VERSION 1000 /*!< Version of trace API */ #ifdef UNICODE RETCODE TraceOpenLogFile(SQLPOINTER,LPWSTR,LPWSTR,DWORD); /*!< open a trace log file */ #else RETCODE TraceOpenLogFile(SQLPOINTER,LPSTR,LPSTR,DWORD); /*!< open a trace log file */ #endif RETCODE TraceCloseLogFile(SQLPOINTER); /*!< Request to close a trace log */ SQLRETURN TraceReturn(SQLPOINTER,SQLRETURN); /*!< Call to produce trace output upon function return. */ DWORD TraceVersion(void); /*!< Returns trace API version */ /* Functions for Visual Studio Analyzer*/ /* to turn on/off tracing or VS events, call TraceVSControl by setting or clearing the following bits */ #define TRACE_ON 0x00000001L #define TRACE_VS_EVENT_ON 0x00000002L RETCODE TraceVSControl(DWORD); /* the flags in ODBC_VS_ARGS */ #define ODBC_VS_FLAG_UNICODE_ARG 0x00000001L /* the argument is unicode */ #define ODBC_VS_FLAG_UNICODE_COR 0x00000002L /* the correlation is unicode */ #define ODBC_VS_FLAG_RETCODE 0x00000004L /* RetCode field is set */ #define ODBC_VS_FLAG_STOP 0x00000008L /* Stop firing visual studio analyzer events */ typedef struct tagODBC_VS_ARGS { #ifdef GUID_DEFINED const GUID *pguidEvent; /* the GUID for event */ #else const void *pguidEvent; /* the GUID for event */ #endif DWORD dwFlags; /* flags for the call */ union { WCHAR *wszArg; CHAR *szArg; }u1; union { WCHAR *wszCorrelation; CHAR *szCorrelation; }u2; RETCODE RetCode; } ODBC_VS_ARGS, *PODBC_VS_ARGS; void FireVSDebugEvent(PODBC_VS_ARGS); /**@}*/ #ifdef __cplusplus } #endif /* * connection pooling retry times */ BOOL ODBCSetTryWaitValue ( DWORD dwValue ); #ifdef __cplusplus DWORD ODBCGetTryWaitValue ( ); #else DWORD ODBCGetTryWaitValue ( void ); #endif #ifndef __SQLUCODE_H #include "sqlucode.h" #endif #endif unixODBC-2.3.12/include/sqlspi.h000066400000000000000000000155071446441710500163370ustar00rootroot00000000000000/*----------------------------------------------------------------------------- File: sqlspi.h Contents: This is the header for driver writers to support new ODBC features. Application writers should not include this header file Please include and before including this file Based on the sqlspi.h provided by Microsoft -----------------------------------------------------------------------------*/ #ifndef __SQLSPI__ #define __SQLSPI__ #ifdef __cplusplus extern "C" { // Assume C declarations for C++ #endif // End of __cplusplus /* SQL_SPI is just a marker for "Service Provider Interface", otherwise it is the same as API Application should not call functions that are marked as SQL_SPI directly */ #define SQL_SPI SQL_API /*-------------------- ODBC Connection Info Handle -----------------------------*/ /* handle for storing connection information for ODBC driver connection pooling */ #define SQL_HANDLE_DBC_INFO_TOKEN 6 // Handle type, used in SQLAllocHandle typedef SQLHANDLE SQLHDBC_INFO_TOKEN; /*-------------------- ODBC Pool ID for driver-aware pooling -----------------------------*/ typedef SQLULEN POOLID; typedef DWORD* TRANSID; /*-------------------- Driver-aware Connection Pooling --------------------------*/ /* We define a few scores with special meaning */ /* But driver can return any score between 0 and 100 */ typedef DWORD SQLConnPoolRating; #define SQL_CONN_POOL_RATING_BEST 100 /* the best of the rating */ #define SQL_CONN_POOL_RATING_GOOD_ENOUGH 99 /* the rating is good enough and we can stop rating */ #define SQL_CONN_POOL_RATING_USELESS 0 /* the candidate connection must not be reused for the current request */ /* SQLSetConnectAttr */ #define SQL_ATTR_DBC_INFO_TOKEN 118 /* reset the pooled connection in case it is not a perfect match */ /* Set connection attributes into DBC info token */ SQLRETURN SQL_SPI SQLSetConnectAttrForDbcInfoW( SQLHDBC_INFO_TOKEN hDbcInfoToken, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength); /* Set connection information for SQLDriverConnect */ SQLRETURN SQL_SPI SQLSetDriverConnectInfoW( SQLHDBC_INFO_TOKEN hDbcInfoToken, SQLWCHAR *szConnStrIn, SQLSMALLINT cchConnStrIn); /* Set connection information for SQLConnect */ SQLRETURN SQL_SPI SQLSetConnectInfoW ( SQLHDBC_INFO_TOKEN hDbcInfoToken, SQLWCHAR *szDSN, SQLSMALLINT cchDSN, SQLWCHAR *szUID, SQLSMALLINT cchUID, SQLWCHAR *szAuthStr, SQLSMALLINT cchAuthStr ); /* Get the pool ID for the token */ SQLRETURN SQL_SPI SQLGetPoolID( SQLHDBC_INFO_TOKEN hDbcInfoToken, POOLID* pPoolID); /* Return how close hCandidateConnection matches with hRequest */ /* *pRating must be between SQL_CONN_POOL_RATING_USELESS and SQL_CONN_POOL_RATING_BEST (inclusively) */ /* If return value is not SQL_SUCCESS or *pRating > SQL_CONN_POOL_RATING_BEST, the candidate */ /* connection will not be used any more in any other connection request */ /* If fRequiresTransactionEnlistment is TRUE, transId represents the DTC transaction ID that */ /* should be enlisted to (transId == 0 means unenlistment). Otherwise, transId should be ignored */ SQLRETURN SQL_SPI SQLRateConnection( SQLHDBC_INFO_TOKEN hRequest, SQLHDBC hCandidateConnection, BOOL fRequiresTransactionEnlistment, TRANSID transId, SQLConnPoolRating *pRating); /* Create a physical connection */ /* If application is calling SQLDriverConnect, szConnStrOut is non-NULL at input. */ /* Otherwise, it will be set to NULL */ SQLRETURN SQL_SPI SQLPoolConnectW( SQLHDBC hdbc, SQLHDBC_INFO_TOKEN hDbcInfoToken, SQLWCHAR *szConnStrOut, SQLSMALLINT cchConnStrOutMax, SQLSMALLINT *pcchConnStrOut); /* Clean up a pool Id that was timed out */ /*/ poolID [in]: the pool ID (under EnvironmentHandle) to be cleaned */ SQLRETURN SQL_SPI SQLCleanupConnectionPoolID( SQLHENV EnvironmentHandle, POOLID poolID); /*-----------------------------------------------------------------------------*/ /* functions for ANSI drivers */ /* Set connection attributes into DBC info token */ SQLRETURN SQL_SPI SQLSetConnectAttrForDbcInfoA( SQLHDBC_INFO_TOKEN hDbcInfoToken, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength); /* Set connection information for SQLDriverConnect */ SQLRETURN SQL_SPI SQLSetDriverConnectInfoA( SQLHDBC_INFO_TOKEN hDbcInfoToken, SQLCHAR *szConnStrIn, SQLSMALLINT cchConnStrIn); /* Set connection information for SQLConnect */ SQLRETURN SQL_SPI SQLSetConnectInfoA ( SQLHDBC_INFO_TOKEN hDbcInfoToken, SQLCHAR *szDSN, SQLSMALLINT cchDSN, SQLCHAR *szUID, SQLSMALLINT cchUID, SQLCHAR *szAuthStr, SQLSMALLINT cchAuthStr ); /* Create a physical connection */ /* If application is calling SQLDriverConnect, szConnStrOut is non-NULL at input. */ /* Otherwise, it will be set to NULL */ SQLRETURN SQL_SPI SQLPoolConnectA( SQLHDBC hdbc, SQLHDBC_INFO_TOKEN hDbcInfoToken, SQLCHAR *szConnStrOut, SQLSMALLINT cchConnStrOutMax, SQLSMALLINT *pcchConnStrOut); /*-----------------------------------------------------------------------------*/ /* Unicode mapping */ /* Define SQL_NOUNICODEMAP to disable the mapping */ #if (!defined(SQL_NOUNICODEMAP) && defined(UNICODE)) #define SQLSetConnectAttrForDbcInfo SQLSetConnectAttrForDbcInfoW #define SQLSetDriverConnectInfo SQLSetDriverConnectInfoW #define SQLSetConnectInfo SQLSetConnectInfoW #define SQLPoolConnect SQLPoolConnectW #else #define SQLSetConnectAttrForDbcInfo SQLSetConnectAttrForDbcInfoA #define SQLSetDriverConnectInfo SQLSetDriverConnectInfoA #define SQLSetConnectInfo SQLSetConnectInfoA #define SQLPoolConnect SQLPoolConnectA #endif /*------------------------------------------------------------------------------*/ /*-------------------- Async Notification --------------------------*/ #if (ODBCVER >= 0x0380) #define SQL_ATTR_ASYNC_DBC_NOTIFICATION_CALLBACK 120 #define SQL_ATTR_ASYNC_DBC_NOTIFICATION_CONTEXT 121 #define SQL_ATTR_ASYNC_STMT_NOTIFICATION_CALLBACK 30 #define SQL_ATTR_ASYNC_STMT_NOTIFICATION_CONTEXT 31 typedef SQLRETURN (SQL_API *SQL_ASYNC_NOTIFICATION_CALLBACK)(SQLPOINTER pContext, BOOL fLast); #endif /* ODBCVER >= 0x0380 */ #ifdef __cplusplus } // End of extern "C" { #endif #endif unixODBC-2.3.12/include/sqltypes.h000066400000000000000000000264111446441710500167040ustar00rootroot00000000000000/************************************************************* * sqltypes.h * * This is the lowest level include in unixODBC. It defines * the basic types required by unixODBC and is heavily based * upon the MS include of the same name (it has to be for * binary compatability between drivers developed under different * packages). * * You can include this file directly, but it is almost always * included indirectly, by including, for example sqlext.h * * This include makes no effort to be useful on any platforms other * than Linux (with some exceptions for UNIX in general). * * !!!DO NOT CONTAMINATE THIS FILE WITH NON-Linux CODE!!! * *************************************************************/ #ifndef __SQLTYPES_H #define __SQLTYPES_H /**************************** * default to the 3.80 definitions. should define ODBCVER before here if you want an older set of defines ***************************/ #ifndef ODBCVER #define ODBCVER 0x0380 #endif /* * if this is set, then use a 4 byte unicode definition, instead of the 2 byte definition that MS use */ #ifdef SQL_WCHART_CONVERT /* * Use this if you want to use the C/C++ portable definition of a wide char, wchar_t * Microsoft hardcoded a definition of unsigned short which may not be compatible with * your platform specific wide char definition. */ #include #endif #ifdef __cplusplus extern "C" { #endif /* * unixODBC needs to know the size of a long integer to #define certain data types. * SIZEOF_LONG_INT is defined by unixODBC but is not usually defined by other programs. * In these cases, the compiler uses #defines stored in unixodbc.h to determine the * correct data types for the target system. * * Refer to unixodbc_conf.h for other build-time settings. */ #ifndef SIZEOF_LONG_INT #include "unixodbc.h" #endif #ifndef SIZEOF_LONG_INT #error "unixODBC needs to know the size of a `long int' to continue!!!" #endif /**************************** * These make up for having no windows.h ***************************/ #ifndef ALREADY_HAVE_WINDOWS_TYPE #define FAR #define CALLBACK #ifdef __OS2__ #define SQL_API _System #else #define SQL_API #endif #define BOOL int #ifndef _WINDOWS_ typedef void* HWND; #endif typedef char CHAR; #ifdef UNICODE /* * NOTE: The Microsoft unicode define is only for apps that want to use TCHARs and * be able to compile for both unicode and non-unicode with the same source. * This is not recommended for linux applications and is not supported * by the standard linux string header files. */ #ifdef SQL_WCHART_CONVERT typedef wchar_t TCHAR; #else typedef signed short TCHAR; #endif #else typedef char TCHAR; #endif typedef unsigned short WORD; #if (SIZEOF_LONG_INT == 4) typedef unsigned long DWORD; #else typedef unsigned int DWORD; #endif typedef unsigned char BYTE; #ifdef SQL_WCHART_CONVERT typedef wchar_t WCHAR; #else typedef unsigned short WCHAR; #endif typedef WCHAR* LPWSTR; typedef const char* LPCSTR; typedef const WCHAR* LPCWSTR; typedef TCHAR* LPTSTR; typedef char* LPSTR; typedef DWORD* LPDWORD; #ifndef _WINDOWS_ typedef void* HINSTANCE; #endif #endif /**************************** * standard SQL* data types. use these as much as possible when using ODBC calls/vars ***************************/ typedef unsigned char SQLCHAR; #if (ODBCVER >= 0x0300) typedef unsigned char SQLDATE; typedef unsigned char SQLDECIMAL; typedef double SQLDOUBLE; typedef double SQLFLOAT; #endif /* * can't use a long; it fails on 64 platforms */ /* * Hopefully by now it should be safe to assume most drivers know about SQLLEN now * and the default is now sizeof( SQLLEN ) = 8 on 64 bit platforms * */ #if (SIZEOF_LONG_INT == 8) #ifdef BUILD_LEGACY_64_BIT_MODE typedef int SQLINTEGER; typedef unsigned int SQLUINTEGER; #define SQLLEN SQLINTEGER #define SQLULEN SQLUINTEGER #define SQLSETPOSIROW SQLUSMALLINT /* * These are not supprted on 64bit ODBC according to MS, removed, so use at your peril * typedef SQLULEN SQLROWCOUNT; typedef SQLULEN SQLROWSETSIZE; typedef SQLULEN SQLTRANSID; typedef SQLLEN SQLROWOFFSET; */ #else typedef int SQLINTEGER; typedef unsigned int SQLUINTEGER; typedef long SQLLEN; typedef unsigned long SQLULEN; typedef unsigned long SQLSETPOSIROW; /* * These are not supprted on 64bit ODBC according to MS, removed, so use at your peril * typedef SQLULEN SQLTRANSID; typedef SQLULEN SQLROWCOUNT; typedef SQLUINTEGER SQLROWSETSIZE; typedef SQLLEN SQLROWOFFSET; */ #endif #else typedef long SQLINTEGER; typedef unsigned long SQLUINTEGER; /* Handle case of building on mingw-w64 */ #ifdef _WIN64 typedef long long SQLLEN; typedef unsigned long long SQLULEN; typedef unsigned long long SQLSETPOSIROW; #else #define SQLLEN SQLINTEGER #define SQLULEN SQLUINTEGER #define SQLSETPOSIROW SQLUSMALLINT #endif typedef SQLULEN SQLROWCOUNT; typedef SQLULEN SQLROWSETSIZE; typedef SQLULEN SQLTRANSID; typedef SQLLEN SQLROWOFFSET; #endif #if (ODBCVER >= 0x0300) typedef unsigned char SQLNUMERIC; #endif typedef void * SQLPOINTER; #if (ODBCVER >= 0x0300) typedef float SQLREAL; #endif typedef signed short int SQLSMALLINT; typedef unsigned short SQLUSMALLINT; #if (ODBCVER >= 0x0300) typedef unsigned char SQLTIME; typedef unsigned char SQLTIMESTAMP; typedef unsigned char SQLVARCHAR; #endif typedef SQLSMALLINT SQLRETURN; #if (ODBCVER >= 0x0300) typedef void * SQLHANDLE; typedef SQLHANDLE SQLHENV; typedef SQLHANDLE SQLHDBC; typedef SQLHANDLE SQLHSTMT; typedef SQLHANDLE SQLHDESC; #else typedef void * SQLHENV; typedef void * SQLHDBC; typedef void * SQLHSTMT; /* * some things like PHP won't build without this */ typedef void * SQLHANDLE; #endif /**************************** * These are cast into the actual struct that is being passed around. The * DriverManager knows what its structs look like and the Driver knows about its * structs... the app knows nothing about them... just void* * These are deprecated in favour of SQLHENV, SQLHDBC, SQLHSTMT ***************************/ #if (ODBCVER >= 0x0300) typedef SQLHANDLE HENV; typedef SQLHANDLE HDBC; typedef SQLHANDLE HSTMT; #else typedef void * HENV; typedef void * HDBC; typedef void * HSTMT; #endif /**************************** * more basic data types to augment what windows.h provides ***************************/ #ifndef ALREADY_HAVE_WINDOWS_TYPE typedef unsigned char UCHAR; typedef signed char SCHAR; typedef SCHAR SQLSCHAR; #if (SIZEOF_LONG_INT == 4) typedef long int SDWORD; typedef unsigned long int UDWORD; #else typedef int SDWORD; typedef unsigned int UDWORD; #endif typedef signed short int SWORD; typedef unsigned short int UWORD; typedef unsigned int UINT; typedef signed long SLONG; typedef signed short SSHORT; typedef unsigned long ULONG; typedef unsigned short USHORT; typedef double SDOUBLE; typedef double LDOUBLE; typedef float SFLOAT; typedef void* PTR; typedef signed short RETCODE; typedef void* SQLHWND; #endif /**************************** * standard structs for working with date/times ***************************/ #ifndef __SQLDATE #define __SQLDATE typedef struct tagDATE_STRUCT { SQLSMALLINT year; SQLUSMALLINT month; SQLUSMALLINT day; } DATE_STRUCT; #if (ODBCVER >= 0x0300) typedef DATE_STRUCT SQL_DATE_STRUCT; #endif typedef struct tagTIME_STRUCT { SQLUSMALLINT hour; SQLUSMALLINT minute; SQLUSMALLINT second; } TIME_STRUCT; #if (ODBCVER >= 0x0300) typedef TIME_STRUCT SQL_TIME_STRUCT; #endif typedef struct tagTIMESTAMP_STRUCT { SQLSMALLINT year; SQLUSMALLINT month; SQLUSMALLINT day; SQLUSMALLINT hour; SQLUSMALLINT minute; SQLUSMALLINT second; SQLUINTEGER fraction; } TIMESTAMP_STRUCT; #if (ODBCVER >= 0x0300) typedef TIMESTAMP_STRUCT SQL_TIMESTAMP_STRUCT; #endif #if (ODBCVER >= 0x0300) typedef enum { SQL_IS_YEAR = 1, SQL_IS_MONTH = 2, SQL_IS_DAY = 3, SQL_IS_HOUR = 4, SQL_IS_MINUTE = 5, SQL_IS_SECOND = 6, SQL_IS_YEAR_TO_MONTH = 7, SQL_IS_DAY_TO_HOUR = 8, SQL_IS_DAY_TO_MINUTE = 9, SQL_IS_DAY_TO_SECOND = 10, SQL_IS_HOUR_TO_MINUTE = 11, SQL_IS_HOUR_TO_SECOND = 12, SQL_IS_MINUTE_TO_SECOND = 13 } SQLINTERVAL; #endif #if (ODBCVER >= 0x0300) typedef struct tagSQL_YEAR_MONTH { SQLUINTEGER year; SQLUINTEGER month; } SQL_YEAR_MONTH_STRUCT; typedef struct tagSQL_DAY_SECOND { SQLUINTEGER day; SQLUINTEGER hour; SQLUINTEGER minute; SQLUINTEGER second; SQLUINTEGER fraction; } SQL_DAY_SECOND_STRUCT; typedef struct tagSQL_INTERVAL_STRUCT { SQLINTERVAL interval_type; SQLSMALLINT interval_sign; union { SQL_YEAR_MONTH_STRUCT year_month; SQL_DAY_SECOND_STRUCT day_second; } intval; } SQL_INTERVAL_STRUCT; #endif #endif /**************************** * ***************************/ #ifndef ODBCINT64 # if (ODBCVER >= 0x0300) # if (SIZEOF_LONG_INT == 8) # define ODBCINT64 long # define UODBCINT64 unsigned long # define ODBCINT64_TYPE "long" # define UODBCINT64_TYPE "unsigned long" # else # ifdef HAVE_LONG_LONG # define ODBCINT64 long long # define UODBCINT64 unsigned long long # define ODBCINT64_TYPE "long long" # define UODBCINT64_TYPE "unsigned long long" # else /* * may fail in some cases, but what else can we do ? */ struct __bigint_struct { int hiword; unsigned int loword; }; struct __bigint_struct_u { unsigned int hiword; unsigned int loword; }; # define ODBCINT64 struct __bigint_struct # define UODBCINT64 struct __bigint_struct_u # define ODBCINT64_TYPE "struct __bigint_struct" # define UODBCINT64_TYPE "struct __bigint_struct_u" # endif # endif #endif #endif #ifdef ODBCINT64 typedef ODBCINT64 SQLBIGINT; #endif #ifdef UODBCINT64 typedef UODBCINT64 SQLUBIGINT; #endif /**************************** * cursor and bookmark ***************************/ #if (ODBCVER >= 0x0300) #define SQL_MAX_NUMERIC_LEN 16 typedef struct tagSQL_NUMERIC_STRUCT { SQLCHAR precision; SQLSCHAR scale; SQLCHAR sign; /* 1=pos 0=neg */ SQLCHAR val[SQL_MAX_NUMERIC_LEN]; } SQL_NUMERIC_STRUCT; #endif #if (ODBCVER >= 0x0350) #ifdef GUID_DEFINED #ifndef ALREADY_HAVE_WINDOWS_TYPE typedef GUID SQLGUID; #else typedef struct tagSQLGUID { DWORD Data1; WORD Data2; WORD Data3; BYTE Data4[ 8 ]; } SQLGUID; #endif #else typedef struct tagSQLGUID { DWORD Data1; WORD Data2; WORD Data3; BYTE Data4[ 8 ]; } SQLGUID; #endif #endif typedef SQLULEN BOOKMARK; typedef WCHAR SQLWCHAR; #ifdef UNICODE typedef SQLWCHAR SQLTCHAR; #else typedef SQLCHAR SQLTCHAR; #endif #ifdef __cplusplus } #endif #endif unixODBC-2.3.12/include/sqlucode.h000066400000000000000000000522421446441710500166400ustar00rootroot00000000000000/************************************************** * sqlucode.h * * These should be consistent with the MS version. * **************************************************/ #ifndef __SQLUCODE_H #define __SQLUCODE_H #ifdef __cplusplus extern "C" { #endif #define SQL_WCHAR (-8) #define SQL_WVARCHAR (-9) #define SQL_WLONGVARCHAR (-10) #define SQL_C_WCHAR SQL_WCHAR #ifdef UNICODE #define SQL_C_TCHAR SQL_C_WCHAR #else #define SQL_C_TCHAR SQL_C_CHAR #endif #define SQL_SQLSTATE_SIZEW 10 /* size of SQLSTATE for unicode */ /* UNICODE versions */ SQLRETURN SQL_API SQLColAttributeW( SQLHSTMT hstmt, SQLUSMALLINT iCol, SQLUSMALLINT iField, SQLPOINTER pCharAttr, SQLSMALLINT cbCharAttrMax, SQLSMALLINT *pcbCharAttr, SQLLEN *pNumAttr); SQLRETURN SQL_API SQLColAttributesW( SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLPOINTER rgbDesc, SQLSMALLINT cbDescMax, SQLSMALLINT *pcbDesc, SQLLEN *pfDesc); SQLRETURN SQL_API SQLConnectW( SQLHDBC hdbc, SQLWCHAR *szDSN, SQLSMALLINT cbDSN, SQLWCHAR *szUID, SQLSMALLINT cbUID, SQLWCHAR *szAuthStr, SQLSMALLINT cbAuthStr); SQLRETURN SQL_API SQLDescribeColW( SQLHSTMT hstmt, SQLUSMALLINT icol, SQLWCHAR *szColName, SQLSMALLINT cbColNameMax, SQLSMALLINT *pcbColName, SQLSMALLINT *pfSqlType, SQLULEN *pcbColDef, SQLSMALLINT *pibScale, SQLSMALLINT *pfNullable); SQLRETURN SQL_API SQLErrorW( SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLWCHAR *szSqlState, SQLINTEGER *pfNativeError, SQLWCHAR *szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT *pcbErrorMsg); SQLRETURN SQL_API SQLExecDirectW( SQLHSTMT hstmt, SQLWCHAR *szSqlStr, SQLINTEGER cbSqlStr); SQLRETURN SQL_API SQLGetConnectAttrW( SQLHDBC hdbc, SQLINTEGER fAttribute, SQLPOINTER rgbValue, SQLINTEGER cbValueMax, SQLINTEGER *pcbValue); SQLRETURN SQL_API SQLGetCursorNameW( SQLHSTMT hstmt, SQLWCHAR *szCursor, SQLSMALLINT cbCursorMax, SQLSMALLINT *pcbCursor); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength); SQLRETURN SQL_API SQLGetDescFieldW( SQLHDESC hdesc, SQLSMALLINT iRecord, SQLSMALLINT iField, SQLPOINTER rgbValue, SQLINTEGER cbValueMax, SQLINTEGER *pcbValue); SQLRETURN SQL_API SQLGetDescRecW( SQLHDESC hdesc, SQLSMALLINT iRecord, SQLWCHAR *szName, SQLSMALLINT cbNameMax, SQLSMALLINT *pcbName, SQLSMALLINT *pfType, SQLSMALLINT *pfSubType, SQLLEN *pLength, SQLSMALLINT *pPrecision, SQLSMALLINT *pScale, SQLSMALLINT *pNullable); SQLRETURN SQL_API SQLGetDiagFieldW( SQLSMALLINT fHandleType, SQLHANDLE handle, SQLSMALLINT iRecord, SQLSMALLINT fDiagField, SQLPOINTER rgbDiagInfo, SQLSMALLINT cbDiagInfoMax, SQLSMALLINT *pcbDiagInfo); SQLRETURN SQL_API SQLGetDiagRecW( SQLSMALLINT fHandleType, SQLHANDLE handle, SQLSMALLINT iRecord, SQLWCHAR *szSqlState, SQLINTEGER *pfNativeError, SQLWCHAR *szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT *pcbErrorMsg); #endif SQLRETURN SQL_API SQLPrepareW( SQLHSTMT hstmt, SQLWCHAR *szSqlStr, SQLINTEGER cbSqlStr); SQLRETURN SQL_API SQLSetConnectAttrW( SQLHDBC hdbc, SQLINTEGER fAttribute, SQLPOINTER rgbValue, SQLINTEGER cbValue); SQLRETURN SQL_API SQLSetCursorNameW( SQLHSTMT hstmt, SQLWCHAR *szCursor, SQLSMALLINT cbCursor); SQLRETURN SQL_API SQLColumnsW( SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szTableName, SQLSMALLINT cbTableName, SQLWCHAR *szColumnName, SQLSMALLINT cbColumnName); SQLRETURN SQL_API SQLGetConnectOptionW( SQLHDBC hdbc, SQLUSMALLINT fOption, SQLPOINTER pvParam); SQLRETURN SQL_API SQLGetInfoW( SQLHDBC hdbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLSMALLINT cbInfoValueMax, SQLSMALLINT *pcbInfoValue); SQLRETURN SQL_API SQLGetTypeInfoW( SQLHSTMT StatementHandle, SQLSMALLINT DataType); SQLRETURN SQL_API SQLSetConnectOptionW( SQLHDBC hdbc, SQLUSMALLINT fOption, SQLULEN vParam); SQLRETURN SQL_API SQLSpecialColumnsW( SQLHSTMT hstmt, SQLUSMALLINT fColType, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szTableName, SQLSMALLINT cbTableName, SQLUSMALLINT fScope, SQLUSMALLINT fNullable); SQLRETURN SQL_API SQLStatisticsW( SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szTableName, SQLSMALLINT cbTableName, SQLUSMALLINT fUnique, SQLUSMALLINT fAccuracy); SQLRETURN SQL_API SQLTablesW( SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szTableName, SQLSMALLINT cbTableName, SQLWCHAR *szTableType, SQLSMALLINT cbTableType); SQLRETURN SQL_API SQLDataSourcesW( SQLHENV henv, SQLUSMALLINT fDirection, SQLWCHAR *szDSN, SQLSMALLINT cbDSNMax, SQLSMALLINT *pcbDSN, SQLWCHAR *szDescription, SQLSMALLINT cbDescriptionMax, SQLSMALLINT *pcbDescription); SQLRETURN SQL_API SQLDriverConnectW( SQLHDBC hdbc, SQLHWND hwnd, SQLWCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLWCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut, SQLUSMALLINT fDriverCompletion); SQLRETURN SQL_API SQLBrowseConnectW( SQLHDBC hdbc, SQLWCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLWCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut); SQLRETURN SQL_API SQLColumnPrivilegesW( SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szTableName, SQLSMALLINT cbTableName, SQLWCHAR *szColumnName, SQLSMALLINT cbColumnName); SQLRETURN SQL_API SQLGetStmtAttrW( SQLHSTMT hstmt, SQLINTEGER fAttribute, SQLPOINTER rgbValue, SQLINTEGER cbValueMax, SQLINTEGER *pcbValue); SQLRETURN SQL_API SQLSetStmtAttrW( SQLHSTMT hstmt, SQLINTEGER fAttribute, SQLPOINTER rgbValue, SQLINTEGER cbValueMax); SQLRETURN SQL_API SQLForeignKeysW( SQLHSTMT hstmt, SQLWCHAR *szPkCatalogName, SQLSMALLINT cbPkCatalogName, SQLWCHAR *szPkSchemaName, SQLSMALLINT cbPkSchemaName, SQLWCHAR *szPkTableName, SQLSMALLINT cbPkTableName, SQLWCHAR *szFkCatalogName, SQLSMALLINT cbFkCatalogName, SQLWCHAR *szFkSchemaName, SQLSMALLINT cbFkSchemaName, SQLWCHAR *szFkTableName, SQLSMALLINT cbFkTableName); SQLRETURN SQL_API SQLNativeSqlW( SQLHDBC hdbc, SQLWCHAR *szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLWCHAR *szSqlStr, SQLINTEGER cbSqlStrMax, SQLINTEGER *pcbSqlStr); SQLRETURN SQL_API SQLPrimaryKeysW( SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szTableName, SQLSMALLINT cbTableName); SQLRETURN SQL_API SQLProcedureColumnsW( SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szProcName, SQLSMALLINT cbProcName, SQLWCHAR *szColumnName, SQLSMALLINT cbColumnName); SQLRETURN SQL_API SQLProceduresW( SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szProcName, SQLSMALLINT cbProcName); SQLRETURN SQL_API SQLTablePrivilegesW( SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szTableName, SQLSMALLINT cbTableName); SQLRETURN SQL_API SQLDriversW( SQLHENV henv, SQLUSMALLINT fDirection, SQLWCHAR *szDriverDesc, SQLSMALLINT cbDriverDescMax, SQLSMALLINT *pcbDriverDesc, SQLWCHAR *szDriverAttributes, SQLSMALLINT cbDrvrAttrMax, SQLSMALLINT *pcbDrvrAttr); /* ANSI versions */ SQLRETURN SQL_API SQLColAttributeA( SQLHSTMT hstmt, SQLSMALLINT iCol, SQLSMALLINT iField, SQLPOINTER pCharAttr, SQLSMALLINT cbCharAttrMax, SQLSMALLINT *pcbCharAttr, SQLLEN *pNumAttr); SQLRETURN SQL_API SQLColAttributesA( SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLPOINTER rgbDesc, SQLSMALLINT cbDescMax, SQLSMALLINT *pcbDesc, SQLLEN *pfDesc); SQLRETURN SQL_API SQLConnectA( SQLHDBC hdbc, SQLCHAR *szDSN, SQLSMALLINT cbDSN, SQLCHAR *szUID, SQLSMALLINT cbUID, SQLCHAR *szAuthStr, SQLSMALLINT cbAuthStr); SQLRETURN SQL_API SQLDescribeColA( SQLHSTMT hstmt, SQLUSMALLINT icol, SQLCHAR *szColName, SQLSMALLINT cbColNameMax, SQLSMALLINT *pcbColName, SQLSMALLINT *pfSqlType, SQLULEN *pcbColDef, SQLSMALLINT *pibScale, SQLSMALLINT *pfNullable); SQLRETURN SQL_API SQLErrorA( SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLCHAR *szSqlState, SQLINTEGER *pfNativeError, SQLCHAR *szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT *pcbErrorMsg); SQLRETURN SQL_API SQLExecDirectA( SQLHSTMT hstmt, SQLCHAR *szSqlStr, SQLINTEGER cbSqlStr); SQLRETURN SQL_API SQLGetConnectAttrA( SQLHDBC hdbc, SQLINTEGER fAttribute, SQLPOINTER rgbValue, SQLINTEGER cbValueMax, SQLINTEGER *pcbValue); SQLRETURN SQL_API SQLGetCursorNameA( SQLHSTMT hstmt, SQLCHAR *szCursor, SQLSMALLINT cbCursorMax, SQLSMALLINT *pcbCursor); #if (ODBCVER >= 0x0300) SQLRETURN SQL_API SQLGetDescFieldA( SQLHDESC hdesc, SQLSMALLINT iRecord, SQLSMALLINT iField, SQLPOINTER rgbValue, SQLINTEGER cbValueMax, SQLINTEGER *pcbValue); SQLRETURN SQL_API SQLGetDescRecA( SQLHDESC hdesc, SQLSMALLINT iRecord, SQLCHAR *szName, SQLSMALLINT cbNameMax, SQLSMALLINT *pcbName, SQLSMALLINT *pfType, SQLSMALLINT *pfSubType, SQLLEN *pLength, SQLSMALLINT *pPrecision, SQLSMALLINT *pScale, SQLSMALLINT *pNullable); SQLRETURN SQL_API SQLGetDiagFieldA( SQLSMALLINT fHandleType, SQLHANDLE handle, SQLSMALLINT iRecord, SQLSMALLINT fDiagField, SQLPOINTER rgbDiagInfo, SQLSMALLINT cbDiagInfoMax, SQLSMALLINT *pcbDiagInfo); SQLRETURN SQL_API SQLGetDiagRecA( SQLSMALLINT fHandleType, SQLHANDLE handle, SQLSMALLINT iRecord, SQLCHAR *szSqlState, SQLINTEGER *pfNativeError, SQLCHAR *szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT *pcbErrorMsg); SQLRETURN SQL_API SQLGetStmtAttrA( SQLHSTMT hstmt, SQLINTEGER fAttribute, SQLPOINTER rgbValue, SQLINTEGER cbValueMax, SQLINTEGER *pcbValue); #endif SQLRETURN SQL_API SQLGetTypeInfoA( SQLHSTMT StatementHandle, SQLSMALLINT DataTyoe); SQLRETURN SQL_API SQLPrepareA( SQLHSTMT hstmt, SQLCHAR *szSqlStr, SQLINTEGER cbSqlStr); SQLRETURN SQL_API SQLSetConnectAttrA( SQLHDBC hdbc, SQLINTEGER fAttribute, SQLPOINTER rgbValue, SQLINTEGER cbValue); SQLRETURN SQL_API SQLSetCursorNameA( SQLHSTMT hstmt, SQLCHAR *szCursor, SQLSMALLINT cbCursor); SQLRETURN SQL_API SQLColumnsA( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName, SQLSMALLINT cbTableName, SQLCHAR *szColumnName, SQLSMALLINT cbColumnName); SQLRETURN SQL_API SQLGetConnectOptionA( SQLHDBC hdbc, SQLUSMALLINT fOption, SQLPOINTER pvParam); SQLRETURN SQL_API SQLGetInfoA( SQLHDBC hdbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLSMALLINT cbInfoValueMax, SQLSMALLINT* pcbInfoValue); SQLRETURN SQL_API SQLGetStmtOptionA( SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLPOINTER pvParam); SQLRETURN SQL_API SQLSetConnectOptionA( SQLHDBC hdbc, SQLUSMALLINT fOption, SQLULEN vParam); SQLRETURN SQL_API SQLSetStmtOptionA( SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam); SQLRETURN SQL_API SQLSpecialColumnsA( SQLHSTMT hstmt, SQLUSMALLINT fColType, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName, SQLSMALLINT cbTableName, SQLUSMALLINT fScope, SQLUSMALLINT fNullable); SQLRETURN SQL_API SQLStatisticsA( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName, SQLSMALLINT cbTableName, SQLUSMALLINT fUnique, SQLUSMALLINT fAccuracy); SQLRETURN SQL_API SQLTablesA( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName, SQLSMALLINT cbTableName, SQLCHAR *szTableType, SQLSMALLINT cbTableType); SQLRETURN SQL_API SQLDataSourcesA( SQLHENV henv, SQLUSMALLINT fDirection, SQLCHAR *szDSN, SQLSMALLINT cbDSNMax, SQLSMALLINT *pcbDSN, SQLCHAR *szDescription, SQLSMALLINT cbDescriptionMax, SQLSMALLINT *pcbDescription); SQLRETURN SQL_API SQLDriverConnectA( SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut, SQLUSMALLINT fDriverCompletion); SQLRETURN SQL_API SQLBrowseConnectA( SQLHDBC hdbc, SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut); SQLRETURN SQL_API SQLColumnPrivilegesA( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName, SQLSMALLINT cbTableName, SQLCHAR *szColumnName, SQLSMALLINT cbColumnName); SQLRETURN SQL_API SQLDescribeParamA( SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT *pfSqlType, SQLUINTEGER *pcbParamDef, SQLSMALLINT *pibScale, SQLSMALLINT *pfNullable); SQLRETURN SQL_API SQLForeignKeysA( SQLHSTMT hstmt, SQLCHAR *szPkCatalogName, SQLSMALLINT cbPkCatalogName, SQLCHAR *szPkSchemaName, SQLSMALLINT cbPkSchemaName, SQLCHAR *szPkTableName, SQLSMALLINT cbPkTableName, SQLCHAR *szFkCatalogName, SQLSMALLINT cbFkCatalogName, SQLCHAR *szFkSchemaName, SQLSMALLINT cbFkSchemaName, SQLCHAR *szFkTableName, SQLSMALLINT cbFkTableName); SQLRETURN SQL_API SQLNativeSqlA( SQLHDBC hdbc, SQLCHAR *szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLCHAR *szSqlStr, SQLINTEGER cbSqlStrMax, SQLINTEGER *pcbSqlStr); SQLRETURN SQL_API SQLPrimaryKeysA( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName, SQLSMALLINT cbTableName); SQLRETURN SQL_API SQLProcedureColumnsA( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szProcName, SQLSMALLINT cbProcName, SQLCHAR *szColumnName, SQLSMALLINT cbColumnName); SQLRETURN SQL_API SQLProceduresA( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szProcName, SQLSMALLINT cbProcName); SQLRETURN SQL_API SQLTablePrivilegesA( SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName, SQLSMALLINT cbTableName); SQLRETURN SQL_API SQLDriversA( SQLHENV henv, SQLUSMALLINT fDirection, SQLCHAR *szDriverDesc, SQLSMALLINT cbDriverDescMax, SQLSMALLINT *pcbDriverDesc, SQLCHAR *szDriverAttributes, SQLSMALLINT cbDrvrAttrMax, SQLSMALLINT *pcbDrvrAttr); /*---------------------------------------------*/ /* Mapping macros for Unicode */ /*---------------------------------------------*/ #ifndef SQL_NOUNICODEMAP /* define this to disable the mapping */ #ifdef UNICODE #define SQLColAttribute SQLColAttributeW #define SQLColAttributes SQLColAttributesW #define SQLConnect SQLConnectW #define SQLDescribeCol SQLDescribeColW #define SQLError SQLErrorW #define SQLExecDirect SQLExecDirectW #define SQLGetConnectAttr SQLGetConnectAttrW #define SQLGetCursorName SQLGetCursorNameW #define SQLGetDescField SQLGetDescFieldW #define SQLGetDescRec SQLGetDescRecW #define SQLGetDiagField SQLGetDiagFieldW #define SQLGetDiagRec SQLGetDiagRecW #define SQLPrepare SQLPrepareW #define SQLSetConnectAttr SQLSetConnectAttrW #define SQLSetCursorName SQLSetCursorNameW #define SQLSetDescField SQLSetDescFieldW #define SQLSetStmtAttr SQLSetStmtAttrW #define SQLGetStmtAttr SQLGetStmtAttrW #define SQLColumns SQLColumnsW #define SQLGetConnectOption SQLGetConnectOptionW #define SQLGetInfo SQLGetInfoW #define SQLGetTypeInfo SQLGetTypeInfoW #define SQLSetConnectOption SQLSetConnectOptionW #define SQLSpecialColumns SQLSpecialColumnsW #define SQLStatistics SQLStatisticsW #define SQLTables SQLTablesW #define SQLDataSources SQLDataSourcesW #define SQLDriverConnect SQLDriverConnectW #define SQLBrowseConnect SQLBrowseConnectW #define SQLColumnPrivileges SQLColumnPrivilegesW #define SQLForeignKeys SQLForeignKeysW #define SQLNativeSql SQLNativeSqlW #define SQLPrimaryKeys SQLPrimaryKeysW #define SQLProcedureColumns SQLProcedureColumnsW #define SQLProcedures SQLProceduresW #define SQLTablePrivileges SQLTablePrivilegesW #define SQLDrivers SQLDriversW #endif /* UNICODE */ #endif /* SQL_NOUNICODEMAP */ #ifdef __cplusplus } #endif #ifndef __SQLEXT_H #include #endif #endif unixODBC-2.3.12/include/sqp.h000066400000000000000000000177761446441710500156410ustar00rootroot00000000000000#ifndef _SQP_H #define _SQP_H #include /* #define SQPDEBUG */ /***[ PARSED, SUPPORTED, SQL PARTS ]**********************************************/ typedef enum sqpStatementType { sqpcreatetable, sqpdroptable, sqpselect, sqpdelete, sqpinsert, sqpupdate } sqpStatementType; typedef enum sqpOrder { sqpnone, sqpasc, sqpdesc } sqpOrder; typedef struct tSQPTABLE { char *pszOwner; char *pszTable; } SQPTABLE, *HSQPTABLE; typedef struct tSQPCOLUMN { char *pszTable; char *pszColumn; int nColumn; /* index into row data for col value */ } SQPCOLUMN, *HSQPCOLUMN; typedef struct tSQPCOMPARISON { char *pszLValue; /* must be a column name */ char *pszOperator; /* > < >= <= = LIKE NOTLIKE */ char *pszRValue; /* must be a string (quotes removed) */ char cEscape; /* escape char for LIKE operator */ int nLColumn; /* index into row data for col value */ } SQPCOMPARISON, *HSQPCOMPARISON; typedef struct tSQPASSIGNMENT { char *pszColumn; char *pszValue; int nColumn; /* index into row data for col value */ } SQPASSIGNMENT, *HSQPASSIGNMENT; typedef struct tSQPDATATYPE { char *pszType; short nType; int nPrecision; int nScale; } SQPDATATYPE, *HSQPDATATYPE; typedef struct tSQPCOLUMNDEF { char * pszColumn; HSQPDATATYPE hDataType; int bNulls; } SQPCOLUMNDEF, *HSQPCOLUMNDEF; typedef struct tSQPPARAM { char *pszValue; } SQPPARAM, *HSQPPARAM; typedef enum sqpCondType { sqpor, sqpand, sqpnot, sqppar, sqpcomp } sqpCondType; typedef struct tSQPCOND { sqpCondType nType; struct tSQPCOND *hLCond; struct tSQPCOND *hRCond; HSQPCOMPARISON hComp; } SQPCOND, *HSQPCOND; /***[ PARSED, SUPPORTED, SQL STATEMENTS ]**********************************************/ typedef struct tSQPCREATETABLE { char *pszTable; HLST hColumnDefs; /* list of HSQPCOLUMNDEF */ } SQPCREATETABLE, *HSQPCREATETABLE; typedef char SQPDROPTABLE; typedef SQPDROPTABLE * HSQPDROPTABLE; typedef struct tSQPSELECT { HLST hColumns; /* list of HSQPCOLUMN */ char *pszTable; HSQPCOND hWhere; /* tree of HSQPCOND */ HLST hOrderBy; /* list of HSQPCOLUMN */ sqpOrder nOrderDirection; } SQPSELECT, *HSQPSELECT; typedef struct tSQPDELETE { char *pszTable; HSQPCOND hWhere; /* tree of HSQPCOND */ char *pszCursor; } SQPDELETE, *HSQPDELETE; typedef struct tSQPINSERT { HLST hColumns; /* list of HSQPCOLUMN */ char *pszTable; HLST hValues; /* list of strings */ } SQPINSERT, *HSQPINSERT; typedef struct tSQPUPDATE { char *pszTable; HLST hAssignments; /* list of HSQPASSIGNMENT */ HSQPCOND hWhere; /* tree of HSQPCOND */ char *pszCursor; } SQPUPDATE, *HSQPUPDATE; /***[ TOP LEVEL STRUCT ]**********************************************/ typedef struct tSQPPARSEDSQL { sqpStatementType nType; union { HSQPCREATETABLE hCreateTable; HSQPDROPTABLE hDropTable; HSQPSELECT hSelect; HSQPDELETE hDelete; HSQPINSERT hInsert; HSQPUPDATE hUpdate; } h; } SQPPARSEDSQL, *HSQPPARSEDSQL; /*********************** * GLOBALS (yuck... gotta get rid of them): * * TEMPS USED WHEN LEX/YACC DO THEIR THING ***********************/ extern char g_szError[1024]; extern HSQPPARSEDSQL g_hParsedSQL; extern char * g_pszTable; extern char * g_pszType; extern HLST g_hColumns; extern HSQPDATATYPE g_hDataType; extern HLST g_hColumnDefs; extern HLST g_hValues; extern HLST g_hAssignments; extern char * g_pszCursor; extern HLST g_hOrderBy; extern sqpOrder g_nOrderDirection; extern int g_nNulls; extern char * g_pszSQLCursor; /* yyparse position init to start of SQL string before yyparse */ extern char * g_pszSQLLimit; /* ptr to NULL terminator of SQL string (yyparse stops here) */ extern int g_nLineNo; extern HLST g_hParams; extern HSQPCOND g_hConds; /********************************************************************************************* * PUBLIC INTERFACE *********************************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*********************** * sqpOpen * * Inits parser globals. Must call this before any other functions * and sqpClose MUST be called before next sqpOpen. * * pszFirstChar - pointer to 1st char in sql string * pszLastChar - pointer to last char in sql string (typically a pointer to a '\0' char) * hParams - list of bound parameters * ***********************/ void sqpOpen( char *pszFirstChar, char *pszLastChar, HLST hParams ); /*********************** * sqpParse * * Attempts to parse the sql given in sqpOpen. * Returns true if success else error. Use sqpError to get exact error after call. * Only call this once per sqpOpen. * ***********************/ int sqpParse(); /*********************** * sqpError * * Returns the last error message (i.e. why a parse failed). Will * be an empty string if no error. * ***********************/ char * sqpError(); /*********************** * sqpClose * * Cleans up globals in prep for next call to sqpOpen. * ***********************/ void sqpClose(); /*********************** * sqpAdoptParsedSQL * * Caller adopts the top level pointer to the parsed sql. This means * that the caller must also call sqpFreeParsedSQL when done with it! * ***********************/ HSQPPARSEDSQL sqpAdoptParsedSQL(); /*********************** * sqpFreeParsedSQL * * Frees the parsed sql from memory. * If this is being called as a result if a prior call to * sqpAdoptParsedSQL (which is the only reason it should be called in * this interface) then it can be called even after the sqpClose. * ***********************/ int sqpFreeParsedSQL( HSQPPARSEDSQL hParsedSQL ); /*********************** * sqpFreeParam * * Frees a bound param from memory. * ***********************/ void sqpFreeParam( void *pData ); #if defined(__cplusplus) } #endif /********************************************************************************************* * INTERNAL FUNCS *********************************************************************************************/ int my_yyinput(char *buf, int max_size); void yyerror( char *s ); int yyparse(); int yywrap(); short sqpStringTypeToSQLTYPE (char * pszType); void sqpFreeAssignment( void *pData ); void sqpFreeColumn( void *pData ); void sqpFreeColumnDef( void *pData ); void sqpFreeDataType( void *pData ); void sqpFreeComparison( void *pData ); void sqpFreeCond( void *pData ); void sqpFreeCreateTable( void *pData ); void sqpFreeDropTable( void *pData ); void sqpFreeDelete( void *pData ); void sqpFreeInsert( void *pData ); void sqpFreeSelect( void *pData ); void sqpFreeUpdate( void *pData ); void sqpStoreAssignment( char *pszColumn, char *pszValue ); void sqpStoreColumn( HLST *ph, char *pszColumn, int nColumn ); void sqpStoreColumnDef( char *pszColumn ); void sqpStoreDataType( char *pszType, int nPrecision, int nScale ); HSQPCOMPARISON sqpStoreComparison( char *pszLValue, char *pszOperator, char *pszRValue, char *pszEscape ); HSQPCOND sqpStoreCond( sqpCondType nType, HSQPCOND pLCond, HSQPCOND pRCond, HSQPCOMPARISON pComp ); void sqpStoreCreateTable(); void sqpStoreDropTable(); void sqpStoreDelete(); void sqpStoreInsert(); void sqpStorePositioned( char *pszCursor ); void sqpStoreSelect(); void sqpStoreTable( char *pszTable ); void sqpStoreUpdate(); void sqpStoreValue( char *pszValue ); #endif unixODBC-2.3.12/include/uodbc_extras.h000066400000000000000000000043751446441710500175070ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Further modified and extend by Eric Sharkey * (sharkey@netrics.com). * * Any bugs or problems should be considered the fault of Nick or * Eric and not Peter. * * copyright (c) 2005 Eric Sharkey * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: uodbc_extras.h,v 1.1 2005/03/04 20:08:45 sharkey Exp $ * **********************************************************************/ #ifndef UODBC__extras_h #define UODBC__extras_h 1 #if defined(HAVE_STDARG_H) # include # define HAVE_STDARGS #else # if defined(HAVE_VARARGS_H) # include # ifdef HAVE_STDARGS # undef HAVE_STDARGS # endif # endif #endif #if defined(__cplusplus) extern "C" { #endif extern int uodbc_vsnprintf (char *str, size_t count, const char *fmt, va_list args); #ifdef HAVE_STDARGS int uodbc_snprintf (char *str,size_t count,const char *fmt,...); #else int uodbc_snprintf (va_alist) va_dcl; #endif #ifndef HAVE_SNPRINTF #define snprintf uodbc_snprintf #endif #ifndef HAVE_VSNPRINTF #define vsnprintf uodbc_vsnprintf #endif #ifndef HAVE_STRCASECMP extern int strcasecmp( const char *s1, const char * s2 ); #endif #ifndef HAVE_STRNCASECMP extern int strncasecmp (const char *s1, const char *s2, int n ); #endif #if defined(__cplusplus) } #endif #endif /* UODBC__extras_h */ unixODBC-2.3.12/include/uodbc_stats.h000066400000000000000000000050361446441710500173320ustar00rootroot00000000000000/********************************************************************* * * This is based on code created by Peter Harvey, * (pharvey@codebydesign.com). * * Modified and extended by Nick Gorham * (nick@lurcher.org). * * Any bugs or problems should be considered the fault of Nick and not * Peter. * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: uodbc_stats.h,v 1.1.1.1 2001/10/17 16:40:28 lurcher Exp $ * * $Log: uodbc_stats.h,v $ * Revision 1.1.1.1 2001/10/17 16:40:28 lurcher * * First upload to SourceForge * * Revision 1.2 2000/12/19 07:28:45 pharvey * - added first pass at Stats page content * - wrapped public stats functions for C++ * * Revision 1.1 2000/12/18 11:54:22 martin * * handle statistic API. * * **********************************************************************/ #ifndef UODBC__stats_h #define UODBC__stats_h 1 #include #include typedef struct uodbc_stats_retentry { unsigned long type; /* type of statistic */ # define UODBC_STAT_STRING 1 # define UODBC_STAT_LONG 2 union { char s_value[256]; /* string type */ long l_value; /* number type */ } value; char name[32]; /* name of statistic */ } uodbc_stats_retentry; #if defined(__cplusplus) extern "C" { #endif int uodbc_open_stats(void **rh, unsigned int mode); #define UODBC_STATS_READ 0x1 #define UODBC_STATS_WRITE 0x2 int uodbc_close_stats(void *rh); int uodbc_get_stats(void *h, pid_t request_pid, uodbc_stats_retentry *s, int n_stats); char *uodbc_stats_error(char *buf, size_t buflen); #if defined(__cplusplus) } #endif #endif /* UODBC__stats_h */ unixODBC-2.3.12/ini/000077500000000000000000000000001446441710500137775ustar00rootroot00000000000000unixODBC-2.3.12/ini/Makefile.am000066400000000000000000000016231446441710500160350ustar00rootroot00000000000000noinst_LTLIBRARIES = libinilc.la AM_CPPFLAGS = -I@top_srcdir@/include libinilc_la_LDFLAGS = -no-undefined libinilc_la_LIBADD = \ ../extras/libodbcextraslc.la libinilc_la_SOURCES = \ iniAllTrim.c \ iniAppend.c \ iniDelete.c \ iniClose.c \ iniCommit.c \ iniObject.c \ iniObjectFirst.c \ iniObjectLast.c \ iniObjectNext.c \ iniObjectSeek.c \ iniObjectSeekSure.c \ iniObjectUpdate.c \ iniObjectInsert.c \ iniObjectDelete.c \ iniObjectEOL.c \ iniOpen.c \ iniProperty.c \ iniPropertyFirst.c \ iniPropertyLast.c \ iniPropertyNext.c \ iniPropertySeek.c \ iniPropertySeekSure.c \ iniPropertyUpdate.c \ iniPropertyInsert.c \ iniPropertyDelete.c \ iniPropertyEOL.c \ iniPropertyValue.c \ iniValue.c \ iniToUpper.c \ iniElement.c \ iniElementCount.c \ iniGetBookmark.c \ iniGotoBookmark.c \ iniCursor.c \ _iniObjectRead.c \ _iniPropertyRead.c \ _iniDump.c \ _iniScanUntilObject.c unixODBC-2.3.12/ini/README000066400000000000000000000021441446441710500146600ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * * * * Peter Harvey 21.FEB.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | INI lib (libini.so) | +-------------------------------------------------------------+ This library provides some usefull functions for processing INI files (such as odbc.ini). It is heavily used in unixODBC by the ODBCConfig and unixODBC Driver Config libs. Peter Harvey pharvey@codebydesign.com 22.MAR.99 +-------------------------------------------------------------+ | Please visit; | | www.unixodbc.org | +-------------------------------------------------------------+ unixODBC-2.3.12/ini/_iniDump.c000066400000000000000000000051311446441710500157070ustar00rootroot00000000000000/********************************************************************************** * _iniDump * * Dump contents to hStream. * * - iniCommit calls this. You can bypass iniCommit restrictions to get some debugging information by calling directly. * - Make sure the stream is open before calling. * - leaves list position at iniObjectFirst() * - always returns true * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int __iniDebug( HINI hIni ) { /* SANITY CHECK */ if ( hIni == NULL ) return INI_ERROR; /* SCAN OBJECTS */ iniObjectFirst( hIni ); while ( iniObjectEOL( hIni ) == FALSE ) { printf( "%c%s%c\n", hIni->cLeftBracket, hIni->hCurObject->szName, hIni->cRightBracket ); iniPropertyFirst( hIni ); while ( iniPropertyEOL( hIni ) == FALSE ) { printf( "%s%c%s\n", hIni->hCurProperty->szName, hIni->cEqual, hIni->hCurProperty->szValue ); iniPropertyNext( hIni ); } printf( "\n" ); iniPropertyFirst( hIni ); iniObjectNext( hIni ); } iniObjectFirst( hIni ); return INI_SUCCESS; } int _iniDump( HINI hIni, FILE *hStream ) { /* SANITY CHECK */ if ( hIni == NULL ) return INI_ERROR; if ( !hStream ) return INI_ERROR; /* SCAN OBJECTS */ iniObjectFirst( hIni ); while ( iniObjectEOL( hIni ) == FALSE ) { #ifdef __OS2__ if ( hIni->iniFileType == 0 ) #endif uo_fprintf( hStream, "%c%s%c\n", hIni->cLeftBracket, hIni->hCurObject->szName, hIni->cRightBracket ); iniPropertyFirst( hIni ); while ( iniPropertyEOL( hIni ) == FALSE ) { #ifdef __OS2__ if ( hIni->iniFileType == 0 ) { #endif uo_fprintf( hStream, "%s%c%s\n", hIni->hCurProperty->szName, hIni->cEqual, hIni->hCurProperty->szValue ); #ifdef __OS2__ } else { iniOS2Write( hStream, hIni->hCurObject->szName, hIni->hCurProperty->szName, hIni->hCurProperty->szValue); } #endif iniPropertyNext( hIni ); } #ifdef __OS2__ if ( hIni->iniFileType == 0 ) #endif uo_fprintf( hStream, "\n" ); iniPropertyFirst( hIni ); iniObjectNext( hIni ); } iniObjectFirst( hIni ); return INI_SUCCESS; } unixODBC-2.3.12/ini/_iniObjectRead.c000066400000000000000000000021721446441710500170060ustar00rootroot00000000000000/********************************************************************************** * _iniObjectRead * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int _iniObjectRead( HINI hIni, char *szLine, char *pszObjectName ) { int nChar; /* SANITY CHECK */ if ( hIni == NULL ) return INI_ERROR; /* SCAN LINE TO EXTRACT OBJECT NAME WITH NO BRACKETS */ nChar = 1; while ( 1 ) { if ( (szLine[nChar] == '\0') || (nChar == INI_MAX_OBJECT_NAME) ) { pszObjectName[nChar-1] = '\0'; break; } if ( szLine[nChar] == hIni->cRightBracket ) { pszObjectName[nChar-1] = '\0'; break; } pszObjectName[nChar-1] = szLine[nChar]; nChar++; } iniAllTrim( pszObjectName ); return INI_SUCCESS; } unixODBC-2.3.12/ini/_iniPropertyRead.c000066400000000000000000000021061446441710500174210ustar00rootroot00000000000000/********************************************************************************** * _iniPropertyRead * * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int _iniPropertyRead( HINI hIni, char *szLine, char *pszPropertyName, char *pszPropertyValue ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_ERROR; /* SCAN LINE TO EXTRACT PROPERTY NAME AND VALUE WITH NO TRAILING SPACES */ strcpy( pszPropertyName, "" ); strcpy( pszPropertyValue, "" ); iniElement( szLine, '=', '\0', 0, pszPropertyName, INI_MAX_PROPERTY_NAME ); iniElementToEnd( szLine, '=', '\0', 1, pszPropertyValue, INI_MAX_PROPERTY_VALUE ); iniAllTrim( pszPropertyName ); iniAllTrim( pszPropertyValue ); return INI_SUCCESS; } unixODBC-2.3.12/ini/_iniScanUntilObject.c000066400000000000000000000030431446441710500200310ustar00rootroot00000000000000/********************************************************************************** * _iniScanUntilObject * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int _iniScanUntilObject( HINI hIni, FILE *hFile, char *pszLine ) { /* SCAN UNTIL WE GET TO AN OBJECT NAME OR EOF */ pszLine[0] = '\0'; while ( 1 ) { if ( uo_fgets( pszLine, INI_MAX_LINE, hFile ) == NULL ) { return INI_NO_DATA; } /* printf( "[PAH][%s][%d] Line=[%s]\n", __FILE__, __LINE__, pszLine ); */ if ( pszLine[0] == hIni->cLeftBracket ) { return INI_SUCCESS; } iniAllTrim( pszLine ); if ( pszLine[0] == '\0' ) { continue; } if ( strchr( hIni->cComment, pszLine[0] ) == NULL ) { return INI_ERROR; } } return INI_SUCCESS; } int _iniScanUntilNextObject( HINI hIni, FILE *hFile, char *pszLine ) { /* SCAN UNTIL WE GET TO AN OBJECT NAME OR EOF, SKIPPING BODY */ pszLine[0] = '\0'; while ( 1 ) { if ( uo_fgets( pszLine, INI_MAX_LINE, hFile ) == NULL ) { return INI_NO_DATA; } if ( pszLine[0] == hIni->cLeftBracket ) { return INI_SUCCESS; } } return INI_SUCCESS; } unixODBC-2.3.12/ini/iniAllTrim.c000066400000000000000000000021251446441710500162070ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniAllTrim( char *pszString ) { int nForwardCursor = 0; int nTrailingCursor = 0; int bTrim = 1; /* TRIM LEFT */ for ( nForwardCursor=0; pszString[nForwardCursor] != '\0'; nForwardCursor++ ) { if ( bTrim && isspace( pszString[nForwardCursor] ) ) { /* DO NOTHING */ } else { bTrim = 0; pszString[nTrailingCursor] = pszString[nForwardCursor]; nTrailingCursor++; } } pszString[nTrailingCursor] = '\0'; /* TRIM RIGHT */ for ( nForwardCursor=strlen(pszString)-1; nForwardCursor >= 0 && isspace( pszString[nForwardCursor] ); nForwardCursor-- ) { } pszString[nForwardCursor+1] = '\0'; return INI_SUCCESS; } unixODBC-2.3.12/ini/iniAppend.c000066400000000000000000000044531446441710500160600ustar00rootroot00000000000000/********************************************************************************** * iniAppend * * - Appends Sections which do not exist in hIni. Ignores all else. * - Does not try to append 'missing' Entries to existing Sections (does not try to merge). * - hIni will become ReadOnly * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniAppend( HINI hIni, char *pszFileName ) { FILE *hFile; char szLine[INI_MAX_LINE+1]; char szObjectName[INI_MAX_OBJECT_NAME+1]; char szPropertyName[INI_MAX_PROPERTY_NAME+1]; char szPropertyValue[INI_MAX_PROPERTY_VALUE+1]; /* SANITY CHECK */ if ( strlen( pszFileName ) > ODBC_FILENAME_MAX ) return INI_ERROR; /* OPEN FILE */ hFile = uo_fopen( pszFileName, "r" ); if ( !hFile ) return INI_ERROR; iniObjectLast( hIni ); iniPropertyLast( hIni ); /* SCAN UNTIL WE GET TO AN OBJECT NAME OR EOF */ szLine[0] = '\0'; if ( _iniScanUntilObject( hIni, hFile, szLine ) == INI_SUCCESS ) { do { if ( szLine[0] == hIni->cLeftBracket ) { _iniObjectRead( hIni, szLine, szObjectName ); if ( iniObjectSeek( hIni, szObjectName ) == INI_SUCCESS ) { iniObjectLast( hIni ); iniPropertyLast( hIni ); if ( _iniScanUntilNextObject( hIni, hFile, szLine ) != INI_SUCCESS) break; } else { iniObjectInsert( hIni, szObjectName ); if ( uo_fgets( szLine, INI_MAX_LINE, hFile ) == NULL ) break; } } else if ( (strchr( hIni->cComment, szLine[0] ) == NULL ) && isalnum(szLine[0]) ) { _iniPropertyRead( hIni, szLine, szPropertyName, szPropertyValue ); iniPropertyInsert( hIni, szPropertyName, szPropertyValue ); if ( uo_fgets( szLine, INI_MAX_LINE, hFile ) == NULL ) break; } else { if ( uo_fgets( szLine, INI_MAX_LINE, hFile ) == NULL ) break; } } while( 1 ); } /* WE ARE NOT GOING TO TRY TO BE SMART ENOUGH TO SAVE THIS STUFF */ hIni->bReadOnly = 1; /* CLEANUP */ if ( hFile != NULL ) uo_fclose( hFile ); return INI_SUCCESS; } unixODBC-2.3.12/ini/iniClose.c000066400000000000000000000015461446441710500157160ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" /****************************** * iniClose * * 1. free memory previously allocated for HINI * 2. DO NOT save any changes (see iniCommit) ******************************/ int iniClose( HINI hIni ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; hIni->hCurObject = hIni->hFirstObject; while ( iniObjectDelete( hIni ) == INI_SUCCESS ) { } free( hIni ); return INI_SUCCESS; } unixODBC-2.3.12/ini/iniCommit.c000066400000000000000000000022361446441710500160760ustar00rootroot00000000000000/********************************************************************************** * iniCommit * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniCommit( HINI hIni ) { FILE *hFile; /* SANITY CHECK */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->bReadOnly ) return INI_ERROR; /* OPEN FILE */ #ifdef __OS2__ if (hIni->iniFileType == 0) { #endif hFile = uo_fopen( hIni->szFileName, "w" ); #ifdef __OS2__ } else { hFile = (FILE *)iniOS2Open (hIni->szFileName); } #endif if ( !hFile ) return INI_ERROR; _iniDump( hIni, hFile ); /* CLEANUP */ if ( hFile != NULL ) { #ifdef __OS2__ if (hIni->iniFileType == 0) #endif uo_fclose( hFile ); #ifdef __OS2__ else iniOS2Close( hFile); #endif } return INI_SUCCESS; } unixODBC-2.3.12/ini/iniCursor.c000066400000000000000000000013301446441710500161150ustar00rootroot00000000000000/********************************************************************************** * iniCursor * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * PAH = Peter Harvey - pharvey@codebydesign.com * ----------------------------------------------- * * PAH 18.MAR.99 Created. **************************************************/ #include #include "ini.h" int iniCursor( HINI hIni, HINI hIniCursor ) { if ( hIni == NULL || hIniCursor == NULL ) return INI_ERROR; memcpy( hIniCursor, hIni, sizeof(INI) ); return INI_SUCCESS; } unixODBC-2.3.12/ini/iniDelete.c000066400000000000000000000014141446441710500160450ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" /****************************** * iniDelete * ******************************/ int iniDelete( HINI hIni ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; /* REMOVE ALL SUBORDINATE INFO */ iniObjectFirst( hIni ); while ( iniObjectDelete( hIni ) == INI_SUCCESS ) { } return INI_SUCCESS; } unixODBC-2.3.12/ini/iniElement.c000066400000000000000000000077371446441710500162520ustar00rootroot00000000000000/********************************************************************************** * iniElement * * Use when; * 1. strtok is scary (also does not handle empty elements well) * 2. strstr is not portable * 3. performance is less important than simplicity and the above (feel free to improve on this) * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniElement( char *pszData, char cSeperator, char cTerminator, int nElement, char *pszElement, int nMaxElement ) { int nCurElement = 0; int nChar = 0; int nCharInElement = 0; memset( pszElement, '\0', nMaxElement ); for ( ; nCurElement <= nElement && (nCharInElement+1) < nMaxElement; nChar++ ) { /* check for end of data */ if ( cSeperator != cTerminator && pszData[nChar] == cTerminator ) { break; } if ( cSeperator == cTerminator && pszData[nChar] == cSeperator && pszData[nChar+1] == cTerminator ) { break; } /* check for end of element */ if ( pszData[nChar] == cSeperator ) { nCurElement++; } else if ( nCurElement == nElement ) { pszElement[nCharInElement] = pszData[nChar]; nCharInElement++; } } if ( pszElement[0] == '\0' ) { return INI_NO_DATA; } return INI_SUCCESS; } /* Like iniElement(), but rather than a terminator, the input buffer length is given */ int iniElementMax( char *pData, char cSeperator, int nDataLen, int nElement, char *pszElement, int nMaxElement ) { int nCurElement = 0; int nChar = 0; int nCharInElement = 0; memset( pszElement, '\0', nMaxElement ); for ( ; nCurElement <= nElement && (nCharInElement+1) < nMaxElement && nChar < nDataLen ; nChar++ ) { /* check for end of element */ if ( pData[nChar] == cSeperator ) { nCurElement++; } else if ( nCurElement == nElement ) { pszElement[nCharInElement] = pData[nChar]; nCharInElement++; } } if ( pszElement[0] == '\0' ) { return INI_NO_DATA; } return INI_SUCCESS; } int iniElementEOL( char *pszData, char cSeperator, char cTerminator, int nElement, char *pszElement, int nMaxElement ) { int nCurElement = 0; int nChar = 0; int nCharInElement = 0; memset( pszElement, '\0', nMaxElement ); for ( ;(nCharInElement+1) < nMaxElement; nChar++ ) { /* check for end of data */ if ( cSeperator != cTerminator && pszData[nChar] == cTerminator ) { break; } if ( cSeperator == cTerminator && pszData[nChar] == cSeperator && pszData[nChar+1] == cTerminator ) { break; } /* check for end of element */ if ( pszData[nChar] == cSeperator && nCurElement < nElement ) { nCurElement++; } else if ( nCurElement >= nElement ) { pszElement[nCharInElement] = pszData[nChar]; nCharInElement++; } } if ( pszElement[0] == '\0' ) { return INI_NO_DATA; } return INI_SUCCESS; } int iniElementToEnd( char *pszData, char cSeperator, char cTerminator, int nElement, char *pszElement, int nMaxElement ) { int nCurElement = 0; int nChar = 0; int nCharInElement = 0; memset( pszElement, '\0', nMaxElement ); for ( ; nCurElement <= nElement && (nCharInElement+1) < nMaxElement; nChar++ ) { /* check for end of data */ if ( cSeperator != cTerminator && pszData[nChar] == cTerminator ) break; if ( cSeperator == cTerminator && pszData[nChar] == cSeperator && pszData[nChar+1] == cTerminator ) break; /* check for end of element */ if ( pszData[nChar] == cSeperator && ( nCurElement < nElement )) nCurElement++; else if ( nCurElement == nElement ) { pszElement[nCharInElement] = pszData[nChar]; nCharInElement++; } } if ( pszElement[0] == '\0' ) return INI_NO_DATA; return INI_SUCCESS; } unixODBC-2.3.12/ini/iniElementCount.c000066400000000000000000000017601446441710500172510ustar00rootroot00000000000000/********************************************************************************** * iniElementCount * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 05.APR.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniElementCount( char *pszData, char cSeperator, char cTerminator ) { int nToManyElements = 30000; int nCurElement = 0; int nChar = 0; for ( ; nCurElement <= nToManyElements; nChar++ ) { /* check for end of data */ if ( cSeperator != cTerminator && pszData[nChar] == cTerminator ) break; if ( cSeperator == cTerminator && pszData[nChar] == cSeperator && pszData[nChar+1] == cTerminator ) break; /* check for end of element */ if ( pszData[nChar] == cSeperator ) nCurElement++; } return nCurElement; } unixODBC-2.3.12/ini/iniGetBookmark.c000066400000000000000000000015061446441710500170520ustar00rootroot00000000000000/********************************************************************************** * iniGetBookmark * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * PAH = Peter Harvey - pharvey@codebydesign.com * ----------------------------------------------- * * PAH 18.MAR.99 Created. **************************************************/ #include #include "ini.h" int iniGetBookmark( HINI hIni, HINIBOOKMARK hIniBookmark ) { if ( hIni == NULL || hIniBookmark == NULL ) return INI_ERROR; hIniBookmark->hIni = hIni; hIniBookmark->hCurObject = hIni->hCurObject; hIniBookmark->hCurProperty = hIni->hCurProperty; return INI_SUCCESS; } unixODBC-2.3.12/ini/iniGotoBookmark.c000066400000000000000000000014471446441710500172470ustar00rootroot00000000000000/********************************************************************************** * iniGotoBookmark * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * PAH = Peter Harvey - pharvey@codebydesign.com * ----------------------------------------------- * * PAH 18.MAR.99 Created. **************************************************/ #include #include "ini.h" int iniGotoBookmark( INIBOOKMARK IniBookmark ) { if ( IniBookmark.hIni == NULL ) return INI_ERROR; (IniBookmark.hIni)->hCurObject = IniBookmark.hCurObject; (IniBookmark.hIni)->hCurProperty = IniBookmark.hCurProperty; return INI_SUCCESS; } unixODBC-2.3.12/ini/iniObject.c000066400000000000000000000014721446441710500160550ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" /****************************** * iniObject * ******************************/ int iniObject( HINI hIni, char *pszObject ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_NO_DATA; /* Ok */ strncpy( pszObject, hIni->hCurObject->szName, INI_MAX_OBJECT_NAME ); return INI_SUCCESS; } unixODBC-2.3.12/ini/iniObjectDelete.c000066400000000000000000000026311446441710500171760ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" /****************************** * iniObjectDelete * ******************************/ int iniObjectDelete( HINI hIni ) { HINIOBJECT hObject; /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_NO_DATA; hObject = hIni->hCurObject; /* REMOVE ALL SUBORDINATE INFO */ hIni->hCurProperty = hObject->hFirstProperty; while ( iniPropertyDelete( hIni ) == INI_SUCCESS ) { } /* REMOVE FROM LIST */ if ( hIni->hFirstObject == hObject ) hIni->hFirstObject = hObject->pNext; if ( hIni->hLastObject == hObject ) hIni->hLastObject = hObject->pPrev; hIni->hCurObject = NULL; if ( hObject->pNext ) { hObject->pNext->pPrev = hObject->pPrev; hIni->hCurObject = hObject->pNext; } if ( hObject->pPrev ) { hObject->pPrev->pNext = hObject->pNext; hIni->hCurObject = hObject->pPrev; } hIni->nObjects--; /* FREE MEMORY */ free( hObject ); iniPropertyFirst( hIni ); return INI_SUCCESS; } unixODBC-2.3.12/ini/iniObjectEOL.c000066400000000000000000000011631446441710500164120ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniObjectEOL( HINI hIni ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return TRUE; return FALSE; } unixODBC-2.3.12/ini/iniObjectFirst.c000066400000000000000000000015121446441710500170600ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * PAH = Peter Harvey - pharvey@codebydesign.com * ----------------------------------------------- * * PAH 19.MAR.99 Now sets hCurProperty to hFirstProperty when found **************************************************/ #include #include "ini.h" int iniObjectFirst( HINI hIni ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; hIni->hCurObject = hIni->hFirstObject; iniPropertyFirst( hIni ); if ( hIni->hCurObject == NULL ) return INI_NO_DATA; return INI_SUCCESS; } unixODBC-2.3.12/ini/iniObjectInsert.c000066400000000000000000000026331446441710500172420ustar00rootroot00000000000000/********************************************************************************** * iniObjectInsert * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniObjectInsert( HINI hIni, char *pszObject ) { HINIOBJECT hObject; char szObjectName[INI_MAX_OBJECT_NAME+1]; /* SANITY CHECK */ if ( hIni == NULL ) return INI_ERROR; if ( pszObject == NULL ) return INI_ERROR; strncpy( szObjectName, pszObject, INI_MAX_OBJECT_NAME ); iniAllTrim( szObjectName ); /* CREATE OBJECT STRUCT */ hObject = malloc( sizeof(INIOBJECT) ); hIni->hCurProperty = NULL; hObject->hFirstProperty = NULL; hObject->hLastProperty = NULL; hObject->nProperties = 0; hObject->pNext = NULL; hObject->pPrev = NULL; strncpy( hObject->szName, szObjectName, INI_MAX_OBJECT_NAME ); /* APPEND TO OBJECT LIST */ if ( hIni->hFirstObject == NULL ) hIni->hFirstObject = hObject; hObject->pPrev = hIni->hLastObject; hIni->hLastObject = hObject; if ( hObject->pPrev != NULL ) hObject->pPrev->pNext = hObject; hIni->hCurObject = hObject; hIni->nObjects++; return INI_SUCCESS; } unixODBC-2.3.12/ini/iniObjectLast.c000066400000000000000000000015231446441710500166760ustar00rootroot00000000000000/********************************************************************************** * iniObjectLast * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * PAH = Peter Harvey - pharvey@codebydesign.com * ----------------------------------------------- * * PAH 19.MAR.99 Now sets hCurProperty to hFirstProperty when found **************************************************/ #include #include "ini.h" int iniObjectLast( HINI hIni ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; hIni->hCurObject = hIni->hLastObject; iniPropertyFirst( hIni ); if ( hIni->hCurObject == NULL ) return INI_NO_DATA; return INI_SUCCESS; } unixODBC-2.3.12/ini/iniObjectNext.c000066400000000000000000000016041446441710500167110ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * PAH = Peter Harvey - pharvey@codebydesign.com * ----------------------------------------------- * * PAH 19.MAR.99 Now sets hCurProperty to hFirstProperty when found **************************************************/ #include #include "ini.h" int iniObjectNext( HINI hIni ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_NO_DATA; hIni->hCurObject = hIni->hCurObject->pNext; iniPropertyFirst( hIni ); if ( hIni->hCurObject == NULL ) return INI_NO_DATA; return INI_SUCCESS; } unixODBC-2.3.12/ini/iniObjectSeek.c000066400000000000000000000016421446441710500166640ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * PAH = Peter Harvey - pharvey@codebydesign.com * ----------------------------------------------- * * PAH 19.MAR.99 Now sets hCurProperty to hFirstProperty when found **************************************************/ #include #include "ini.h" int iniObjectSeek( HINI hIni, char *pszObject ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; iniObjectFirst( hIni ); while ( iniObjectEOL( hIni ) == FALSE ) { if ( strcasecmp( pszObject, hIni->hCurObject->szName ) == 0 ) return INI_SUCCESS; iniObjectNext( hIni ); } return INI_NO_DATA; } unixODBC-2.3.12/ini/iniObjectSeekSure.c000066400000000000000000000015451446441710500175250ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com * ----------------------------------------------- * * PAH 06.MAR.99 Added this func **************************************************/ #include #include "ini.h" int iniObjectSeekSure( HINI hIni, char *pszObject ) { int nReturn; /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( !pszObject ) return INI_ERROR; if ( (nReturn = iniObjectSeek( hIni, pszObject )) == INI_NO_DATA ) return iniObjectInsert( hIni, pszObject ); return nReturn; } unixODBC-2.3.12/ini/iniObjectUpdate.c000066400000000000000000000013661446441710500172220ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniObjectUpdate( HINI hIni, char *pszObject ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_ERROR; /* Ok */ strncpy( hIni->hCurObject->szName, pszObject, INI_MAX_OBJECT_NAME ); return INI_SUCCESS; } unixODBC-2.3.12/ini/iniOpen.c000066400000000000000000000304001446441710500155410ustar00rootroot00000000000000/********************************************************************************** * iniOpen * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * PAH = Peter Harvey - pharvey@codebydesign.com * ----------------------------------------------- * * PAH 06.MAR.99 Can now create file-less INI. Pass NULL for * pszFileName. Then copy a file name into hIni->szFileName * before calling iniCommit. **************************************************/ #include #include "ini.h" /* * Changes sent by MQJoe, to avoid limit on number of open file handles */ /*************************************************** * Override fstream command to overcome 255 file * handle limit ***************************************************/ #include #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #if defined( HAVE_VSNPRINTF ) && defined( USE_LL_FIO ) FILE *uo_fopen( const char *filename, const char *mode ) { int fp; long oMode = 0, pMode = 0; pMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; switch ( mode[0] ) { case 'r': oMode = O_RDONLY; break; case 'w': oMode = O_RDWR | O_CREAT | O_TRUNC; break; case 'o': oMode = O_RDWR | O_CREAT | O_TRUNC; break; case 'a': oMode = O_CREAT | O_APPEND | O_WRONLY; break; default: return FALSE; } fp = open(filename, oMode, pMode ); return(fp != -1) ? (FILE*)fp : NULL; } int uo_fclose( FILE *stream ) { close((int)stream); return 0; } char *uo_fgets( char *buffer, int n, FILE *stream ) { int fp = (int)stream; char ch; int i = 0, c = 0; buffer[0] = 0; do { c = read(fp, &ch, 1); if ( c == 1 ) { buffer[i++] = ch; if ( ch == '\n' ) break; } } while ( c && i < n ); buffer[i] = 0; return(c) ? buffer : NULL; } int uo_vfprintf( FILE *stream, const char *fmt, va_list ap) { int fp = (int)stream; long lNeededSize = 256; char* szBuffer = NULL; long lBufSize = 0; int r = 0; do { if ( lNeededSize > lBufSize ) { if ( szBuffer ) free(szBuffer); szBuffer = (char*)malloc(lNeededSize); lBufSize = lNeededSize; } lNeededSize = vsnprintf(szBuffer, lBufSize, fmt, ap); lNeededSize++; } while ( lNeededSize > lBufSize ); r = write(fp, szBuffer, (lNeededSize - 1) ); if ( szBuffer ) free(szBuffer); return r; } int uo_fprintf( FILE *stream, const char *fmt, ...) { int r; va_list ap; va_start(ap, fmt); r = uo_vfprintf(stream,fmt,ap); va_end(ap); return r; } #endif /***************************************************/ #ifdef __OS2__ int iniOpen( HINI *hIni, char *pszFileName, char *cComment, char cLeftBracket, char cRightBracket, char cEqual, int bCreate, int bFileType ) { FILE *hFile; char szLine[INI_MAX_LINE+1]; char szObjectName[INI_MAX_OBJECT_NAME+1]; char szPropertyName[INI_MAX_PROPERTY_NAME+1]; char szPropertyValue[INI_MAX_PROPERTY_VALUE+1]; int nValidFile; char *ObjectList; char *PropertyList; char *ValueList; int numberObject; int ObjectNumber; int numberProperty; int PropertyNumber; int nValidProperty; char *tmpObjectName; char *tmpPropertyName; char *tmpProperyValue; #ifdef __OS2DEBUG__ printf("iniOpen entered \n"); #endif /* INIT STATEMENT */ *hIni = malloc( sizeof(INI) ); if ( pszFileName && pszFileName != STDINFILE ) strncpy((*hIni)->szFileName, pszFileName, ODBC_FILENAME_MAX ); else if ( pszFileName == STDINFILE ) strncpy((*hIni)->szFileName, "stdin", ODBC_FILENAME_MAX ); else strncpy((*hIni)->szFileName, "", ODBC_FILENAME_MAX ); strcpy( (*hIni)->cComment, cComment ); (*hIni)->cLeftBracket = cLeftBracket; (*hIni)->cRightBracket = cRightBracket; (*hIni)->cEqual = cEqual; (*hIni)->bChanged = FALSE; (*hIni)->hCurObject = NULL; (*hIni)->hFirstObject = NULL; (*hIni)->hLastObject = NULL; (*hIni)->nObjects = 0; (*hIni)->bReadOnly = 0; (*hIni)->iniFileType = bFileType; #ifdef __OS2DEBUG__ printf("iniOpen file is mode %d \n", bFileType); #endif /* OPEN FILE */ if ( pszFileName ) { if ( pszFileName == STDINFILE ) { hFile = stdin; (*hIni)->iniFileType = 0; /* stdin is always text */ } else { if ( (*hIni)->iniFileType == 0 ) hFile = uo_fopen( pszFileName, "r" ); else hFile = (FILE *)iniOS2Open( pszFileName); } if ( !hFile ) { /* * This could fail because of something other than the file not existing... */ if ( bCreate == TRUE ) { if ( (*hIni)->iniFileType == 0 ) hFile = uo_fopen( pszFileName, "w+" ); else hFile = (FILE *)iniOS2Open( pszFileName); } } if ( !hFile ) { free( *hIni ); *hIni = NULL; return INI_ERROR; } if ( (*hIni)->iniFileType == 1 ) { nValidFile = INI_ERROR; ObjectList = (char *)iniOS2LoadObjectList( hFile, &numberObject); if ( numberObject > 0 ) { nValidFile = INI_SUCCESS; ObjectNumber = 0; do { tmpObjectName = (char *)(ObjectList + ObjectNumber); strcpy(szObjectName, tmpObjectName); iniObjectInsert( (*hIni), szObjectName ); PropertyList = (char *)iniOS2LoadPropertyList( hFile, szObjectName, &numberProperty); if ( numberProperty > 0 ) { PropertyNumber = 0; do { tmpPropertyName = PropertyList + PropertyNumber; strcpy(szPropertyName, tmpPropertyName); ValueList = (char *)iniOS2Read( hFile, szObjectName, szPropertyName, szPropertyValue); strcpy(szPropertyValue, ValueList); iniPropertyInsert( (*hIni), szPropertyName, szPropertyValue); PropertyNumber = PropertyNumber + strlen(szPropertyName) + 1; } while ( PropertyNumber < numberProperty ); free(PropertyList); } ObjectNumber = ObjectNumber + strlen(szObjectName) + 1; } while ( ObjectNumber < numberObject ); free(ObjectList); } } else { nValidFile = _iniScanUntilObject( *hIni, hFile, szLine ); if ( nValidFile == INI_SUCCESS ) { char *ptr; do { if ( szLine[0] == cLeftBracket ) { _iniObjectRead( (*hIni), szLine, szObjectName ); iniObjectInsert( (*hIni), szObjectName ); } else if ( (strchr( cComment, szLine[0] ) == NULL ) && !isspace(szLine[0]) ) { _iniPropertyRead( (*hIni), szLine, szPropertyName, szPropertyValue ); iniPropertyInsert( (*hIni), szPropertyName, szPropertyValue ); } } while ( (ptr = uo_fgets( szLine, INI_MAX_LINE, hFile )) != NULL ); } } if ( nValidFile == INI_ERROR ) { /* INVALID FILE */ if ( hFile != NULL ) { if ( (*hIni)->iniFileType == 0 ) uo_fclose( hFile ); else iniOS2Close(hFile); } free( *hIni ); *hIni = NULL; return INI_ERROR; } /* CLEANUP */ if ( hFile != NULL ) { if ( (*hIni)->iniFileType == 0 ) { uo_fclose( hFile ); } else iniOS2Close(hFile); } iniObjectFirst( *hIni ); } /* if file given */ return INI_SUCCESS; } #else int iniOpen( HINI *hIni, char *pszFileName, char *cComment, char cLeftBracket, char cRightBracket, char cEqual, int bCreate ) { FILE *hFile; char szLine[INI_MAX_LINE+1]; char szObjectName[INI_MAX_OBJECT_NAME+1]; char szPropertyName[INI_MAX_PROPERTY_NAME+1]; char szPropertyValue[INI_MAX_PROPERTY_VALUE+1]; int nValidFile; /* INIT STATEMENT */ *hIni = malloc( sizeof(INI) ); if ( pszFileName && pszFileName != STDINFILE ) strncpy((*hIni)->szFileName, pszFileName, ODBC_FILENAME_MAX ); else if ( pszFileName == STDINFILE ) strncpy((*hIni)->szFileName, "stdin", ODBC_FILENAME_MAX ); else strncpy((*hIni)->szFileName, "", ODBC_FILENAME_MAX ); strcpy( (*hIni)->cComment, cComment ); (*hIni)->cLeftBracket = cLeftBracket; (*hIni)->cRightBracket = cRightBracket; (*hIni)->cEqual = cEqual; (*hIni)->bChanged = FALSE; (*hIni)->hCurObject = NULL; (*hIni)->hFirstObject = NULL; (*hIni)->hLastObject = NULL; (*hIni)->nObjects = 0; (*hIni)->bReadOnly = 0; /* OPEN FILE */ if ( pszFileName ) { errno = 0; if ( pszFileName == STDINFILE ) { hFile = stdin; } else { hFile = uo_fopen( pszFileName, "r" ); } if ( ( !hFile ) && ( errno != ENFILE ) && ( errno != EMFILE ) && ( errno != ENOMEM ) && ( errno != EACCES ) && ( errno != EFBIG ) && ( errno != EINTR ) && ( errno != ENOSPC ) && ( errno != EOVERFLOW ) && ( errno != EWOULDBLOCK )) { /* * This could fail because of something other than the file not existing... * so open as w+ just in case */ if ( bCreate == TRUE ) { hFile = uo_fopen( pszFileName, "w+" ); } } if ( !hFile ) { free( *hIni ); *hIni = NULL; return INI_ERROR; } nValidFile = _iniScanUntilObject( *hIni, hFile, szLine ); if ( nValidFile == INI_SUCCESS ) { char *ptr; ptr = szLine; do { /* * remove leading spaces */ while( isspace( *ptr )) { ptr ++; } if ( *ptr == '\0' ) { continue; } if ( *ptr == cLeftBracket ) { _iniObjectRead( (*hIni), ptr, szObjectName ); iniObjectInsert( (*hIni), szObjectName ); } else if ((strchr( cComment, *ptr ) == NULL )) { _iniPropertyRead( (*hIni), ptr, szPropertyName, szPropertyValue ); iniPropertyInsert( (*hIni), szPropertyName, szPropertyValue ); } } while ( (ptr = uo_fgets( szLine, INI_MAX_LINE, hFile )) != NULL ); } else if ( nValidFile == INI_ERROR ) { /* INVALID FILE */ if ( hFile != NULL ) uo_fclose( hFile ); free( *hIni ); *hIni = NULL; return INI_ERROR; } /* CLEANUP */ if ( hFile != NULL ) uo_fclose( hFile ); iniObjectFirst( *hIni ); } /* if file given */ return INI_SUCCESS; } #endif unixODBC-2.3.12/ini/iniProperty.c000066400000000000000000000014561446441710500164750ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniProperty( HINI hIni, char *pszProperty ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_NO_DATA; if ( hIni->hCurProperty == NULL ) return INI_NO_DATA; /* Ok */ strncpy( pszProperty, hIni->hCurProperty->szName, INI_MAX_PROPERTY_NAME ); return INI_SUCCESS; } unixODBC-2.3.12/ini/iniPropertyDelete.c000066400000000000000000000026071446441710500176170ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" /****************************** * iniPropertyDelete * ******************************/ int iniPropertyDelete( HINI hIni ) { HINIPROPERTY hProperty; HINIOBJECT hObject; /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_ERROR; if ( hIni->hCurProperty == NULL ) return INI_NO_DATA; hObject = hIni->hCurObject; hProperty = hIni->hCurProperty; if ( hObject->hFirstProperty == hProperty ) hObject->hFirstProperty = hProperty->pNext; if ( hObject->hLastProperty == hProperty ) hObject->hLastProperty = hProperty->pPrev; hIni->hCurProperty = NULL; if ( hProperty->pNext ) { hProperty->pNext->pPrev = hProperty->pPrev; hIni->hCurProperty = hProperty->pNext; } if ( hProperty->pPrev ) { hProperty->pPrev->pNext = hProperty->pNext; hIni->hCurProperty = hProperty->pPrev; } hObject->nProperties--; /* FREE MEMORY */ free( hProperty ); return INI_SUCCESS; } unixODBC-2.3.12/ini/iniPropertyEOL.c000066400000000000000000000012441446441710500170300ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniPropertyEOL( HINI hIni ) { /* SANITY CHECKS */ if ( hIni == NULL ) return TRUE; if ( hIni->hCurObject == NULL ) return TRUE; if ( hIni->hCurProperty == NULL ) return TRUE; return FALSE; } unixODBC-2.3.12/ini/iniPropertyFirst.c000066400000000000000000000013731446441710500175030ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniPropertyFirst( HINI hIni ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_NO_DATA; hIni->hCurProperty = hIni->hCurObject->hFirstProperty; if ( hIni->hCurProperty == NULL ) return INI_NO_DATA; return INI_SUCCESS; } unixODBC-2.3.12/ini/iniPropertyInsert.c000066400000000000000000000030351446441710500176550ustar00rootroot00000000000000/********************************************************************************** * iniPropertyInsert * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniPropertyInsert( HINI hIni, char *pszProperty, char *pszValue ) { HINIOBJECT hObject; HINIPROPERTY hProperty; /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_ERROR; if ( pszProperty == NULL ) return INI_ERROR; hObject = hIni->hCurObject; /* CREATE PROPERTY STRUCT */ hProperty = (HINIPROPERTY)malloc( sizeof(INIPROPERTY) ); strncpy( hProperty->szName, pszProperty, INI_MAX_PROPERTY_NAME ); if ( pszValue ) { strncpy( hProperty->szValue, pszValue, INI_MAX_PROPERTY_VALUE ); } else { strcpy( hProperty->szValue, "" ); } hProperty->pNext = NULL; iniAllTrim( hProperty->szName ); iniAllTrim( hProperty->szValue ); /* APPEND TO LIST */ if ( hObject->hFirstProperty == NULL ) hObject->hFirstProperty = hProperty; hProperty->pPrev = hObject->hLastProperty; hObject->hLastProperty = hProperty; if ( hProperty->pPrev != NULL ) hProperty->pPrev->pNext = hProperty; hIni->hCurProperty = hProperty; hObject->nProperties++; return INI_SUCCESS; } unixODBC-2.3.12/ini/iniPropertyLast.c000066400000000000000000000014071446441710500173150ustar00rootroot00000000000000/********************************************************************************** * iniPropertyLast * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniPropertyLast( HINI hIni ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_NO_DATA; hIni->hCurProperty = hIni->hCurObject->hLastProperty; if ( hIni->hCurProperty == NULL ) return INI_NO_DATA; return INI_SUCCESS; } unixODBC-2.3.12/ini/iniPropertyNext.c000066400000000000000000000015101446441710500173230ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniPropertyNext( HINI hIni ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_NO_DATA; if ( hIni->hCurProperty == NULL ) return INI_NO_DATA; hIni->hCurProperty = hIni->hCurProperty->pNext; if ( hIni->hCurProperty == NULL ) return INI_NO_DATA; return INI_SUCCESS; } unixODBC-2.3.12/ini/iniPropertySeek.c000066400000000000000000000026531446441710500173050ustar00rootroot00000000000000/********************************************************************************** * iniPropertySeek * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniPropertySeek( HINI hIni, char *pszObject, char *pszProperty, char *pszValue ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; /* Ok */ iniObjectFirst( hIni ); while ( iniObjectEOL( hIni ) != TRUE ) { if ( pszObject[0] == '\0' || strcasecmp( pszObject, hIni->hCurObject->szName ) == 0 ) { /* EITHER THE OBJECT HAS BEEN FOUND OR THE OBJECT DOES NOT MATTER */ /* IN ANYCASE LETS SCAN FOR PROPERTY */ iniPropertyFirst( hIni ); while ( iniPropertyEOL( hIni ) != TRUE ) { if ( pszProperty[0] == '\0' || strcasecmp( pszProperty, hIni->hCurProperty->szName ) == 0 ) { if ( pszValue[0] == '\0' || strcasecmp( pszValue, hIni->hCurProperty->szValue ) == 0 ) { /* FOUND IT !! */ return INI_SUCCESS; } } iniPropertyNext( hIni ); } if ( pszObject[0] != '\0' ) { hIni->hCurObject = NULL; return INI_NO_DATA; } } iniObjectNext( hIni ); } return INI_NO_DATA; } unixODBC-2.3.12/ini/iniPropertySeekSure.c000066400000000000000000000021751446441710500201430ustar00rootroot00000000000000/********************************************************************************** * iniPropertySeek * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com * ----------------------------------------------- * * PAH 06.MAR.99 Added this func **************************************************/ #include #include "ini.h" int iniPropertySeekSure( HINI hIni, char *pszObject, char *pszProperty, char *pszValue ) { int nReturn; /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( !pszObject ) return INI_ERROR; if ( !pszProperty ) return INI_ERROR; if ( !pszValue ) return INI_ERROR; /* OK */ if ( (nReturn = iniPropertySeek( hIni, pszObject, pszProperty, "" )) == INI_NO_DATA ) { iniObjectSeekSure( hIni, pszObject ); return iniPropertyInsert( hIni, pszProperty, pszValue ); } else if ( nReturn == INI_SUCCESS ) return iniValue( hIni, pszValue ); return nReturn; } unixODBC-2.3.12/ini/iniPropertyUpdate.c000066400000000000000000000016321446441710500176340ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniPropertyUpdate( HINI hIni, char *pszProperty, char *pszValue ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_ERROR; if ( hIni->hCurProperty == NULL ) return INI_ERROR; /* Ok */ strncpy( hIni->hCurProperty->szName, pszProperty, INI_MAX_PROPERTY_NAME ); strncpy( hIni->hCurProperty->szValue, pszValue, INI_MAX_PROPERTY_VALUE ); return INI_SUCCESS; } unixODBC-2.3.12/ini/iniPropertyValue.c000066400000000000000000000025241446441710500174670ustar00rootroot00000000000000/********************************************************************************** * . * totally untested * * see iniElement instead **********************************************************************************/ #include #include "ini.h" int iniPropertyValue( char *pszString, char *pszProperty, char *pszValue, char cEqual, char cPropertySep ) { char szBuffer[INI_MAX_LINE+1]; char szEqual[2]; char szPropertySep[2]; char *pProperty; char *pValue; char *pValueLastChar; szEqual[0] = cEqual; szEqual[1] = '\0'; szPropertySep[0] = cPropertySep; szPropertySep[1] = '\0'; strcpy( pszValue, "" ); strncpy( szBuffer, pszString, INI_MAX_LINE ); /* find pszProperty */ while ( 1 ) { pProperty = (char *)strtok( szBuffer, (const char *)szPropertySep ); if ( pProperty == NULL ) break; else { /* extract pszValue */ if ( strncmp( pProperty, pszProperty, strlen(pszProperty) ) == 0 ) { pValue = (char *)strtok( szBuffer, (const char *)szEqual ); if ( pValue ) { /* truncate any other data */ pValueLastChar = (char *)strchr( pValue, szPropertySep[ 0 ] ); if ( pValueLastChar ) pValueLastChar[0] = '\0'; strncpy( pszValue, pValue, INI_MAX_PROPERTY_VALUE ); iniAllTrim( pszValue ); } break; } } } return INI_SUCCESS; } unixODBC-2.3.12/ini/iniToUpper.c000066400000000000000000000011651446441710500162440ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" int iniToUpper( char *pszString ) { int n = 0; for ( n = 0; pszString[n] != '\0'; n++ ) pszString[n] = toupper((unsigned char)pszString[n]); return INI_SUCCESS; } unixODBC-2.3.12/ini/iniValue.c000066400000000000000000000015531446441710500157230ustar00rootroot00000000000000/********************************************************************************** * . * * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include "ini.h" /****************************** * iniValue * ******************************/ int iniValue( HINI hIni, char *pszValue ) { /* SANITY CHECKS */ if ( hIni == NULL ) return INI_ERROR; if ( hIni->hCurObject == NULL ) return INI_NO_DATA; if ( hIni->hCurProperty == NULL ) return INI_NO_DATA; strncpy( pszValue, hIni->hCurProperty->szValue, INI_MAX_PROPERTY_VALUE ); return INI_SUCCESS; } unixODBC-2.3.12/log/000077500000000000000000000000001446441710500140015ustar00rootroot00000000000000unixODBC-2.3.12/log/Makefile.am000066400000000000000000000003511446441710500160340ustar00rootroot00000000000000noinst_LTLIBRARIES = libloglc.la AM_CPPFLAGS = -I@top_srcdir@/include libloglc_la_SOURCES = \ _logFreeMsg.c \ logClear.c \ logClose.c \ logOn.c \ logOpen.c \ logPeekMsg.c \ logPopMsg.c \ logPushMsg.c libloglc_la_LIBADD = unixODBC-2.3.12/log/README000066400000000000000000000021261446441710500146620ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * * * * Peter Harvey 21.FEB.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | LOG lib (liblog.so) | +-------------------------------------------------------------+ This library provides some usefull functions for managing log/debug messages. +-------------------------------------------------------------+ | Peter Harvey | | http://www.genix.net/unixODBC | | pharvey@codebydesign.com | | 10.APR.99 | +-------------------------------------------------------------+ unixODBC-2.3.12/log/_logFreeMsg.c000066400000000000000000000020241446441710500163340ustar00rootroot00000000000000/********************************************************************** * _logFreeMsg * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "log.h" /*! * \brief Callback function to free mem used by a message. * * This function is set in logOpen and is automatically used * to free mem used by a message when the message is deleted. * * \param pMsg * * \sa logOpen */ void _logFreeMsg( void *pMsg ) { HLOGMSG hMsg = (HLOGMSG)pMsg; if ( !hMsg ) return; /* free msg memory */ if ( hMsg->pszModuleName != NULL ) free(hMsg->pszModuleName); if ( hMsg->pszFunctionName != NULL ) free(hMsg->pszFunctionName); if ( hMsg->pszMessage != NULL ) free(hMsg->pszMessage); free( hMsg ); } unixODBC-2.3.12/log/logClear.c000066400000000000000000000013711446441710500156770ustar00rootroot00000000000000#include #include "log.h" /*! * \brief Clear all log messages. * * \param hLog * * \return int * \retval LOG_ERROR * \retval LOG_SUCCESS * * \sa logOpen * logClose */ int logClear( HLOG hLog ) { /* we have to be logOpen to logClear messages */ if ( !hLog ) return LOG_ERROR; /* We rely upon a callback being set to handle clearing mem used by each msg. This should be set in logOpen but just in case - we check it here. */ if ( !hLog->hMessages->pFree ) return LOG_ERROR; /* go to last message and delete until no more messages */ lstLast( hLog->hMessages ); while ( !lstEOL( hLog->hMessages ) ) { lstDelete( hLog->hMessages ); } return LOG_SUCCESS; } unixODBC-2.3.12/log/logClose.c000066400000000000000000000025401446441710500157150ustar00rootroot00000000000000/********************************************************************** * logClose * * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "log.h" /*! * \brief Closes log. * * This will clear all messages and close the log. All memory used * by the messages is automatically freed by calls to _logFreeMsg. * All remaining mem used by the log is also freed - including the * log handle itself. * * \param hLog A log handle init by \sa logOpen. * * \return int * \retval LOG_SUCCESS * * \sa logOpen */ int logClose( HLOG hLog ) { /* we must be logOpen to logClose */ if ( !hLog ) return LOG_ERROR; /* clear all messages - including the handle */ /* _logFreeMsg will automatically be called for each msg */ lstClose( hLog->hMessages ); /* free remaining mem used by log - including the handle */ if ( hLog->pszProgramName ) free( hLog->pszProgramName ); if ( hLog->pszLogFile ) free( hLog->pszLogFile ); free( hLog ); return LOG_SUCCESS; } unixODBC-2.3.12/log/logOn.c000066400000000000000000000020611446441710500152220ustar00rootroot00000000000000/********************************************************************** * logOn * * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "log.h" /*! * \brief Turn logging on/off. * * Logging is turned OFF by default. Turn it on when you want * logged messages to be stored. Turn it back off when you want to * 'pause' logging. * * This may be used during debugging sessions to reduce clutter * in the log results. * * \param hLog * \param bOn * * \return int * \retval LOG_SUCCESS * * \sa logOpen * logClose */ int logOn( HLOG hLog, int bOn ) { /* log must be logOpen to logOn */ if ( !hLog ) return LOG_ERROR; hLog->bOn = bOn; return LOG_SUCCESS; } unixODBC-2.3.12/log/logOpen.c000066400000000000000000000041421446441710500155510ustar00rootroot00000000000000/********************************************************************** * logOpen * * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "log.h" /*! * \brief Open (init) a log (hLog). * * This function must be called before any other in this API. * _logFreeMsg is applied to the log to ensure that all message * mem is freed. * * \param phLog Output. Log handle returned here. * \param pszProgramName Input. Default program name. This is attached to * each message when written to file. It is only used * if a viable pszLogFile given. Can be NULL. * \param pszLogFile Input. File name of log file. Can be NULL. * \param nMaxMsgs Input. Max messages to store. When this limit is * reached - oldest message will be deleted. This * can be set to 0 to remove any limit. * * \return int * \retval LOG_ERROR * \retval LOG_SUCCESS * * \sa logClose */ int logOpen( HLOG *phLog, char *pszProgramName, char *pszLogFile, long nMaxMsgs ) { /* sanity check */ if ( !phLog ) return LOG_ERROR; /* LOG STRUCT */ *phLog = malloc( sizeof(LOG) ); (*phLog)->nMaxMsgs = nMaxMsgs; (*phLog)->hMessages = lstOpen(); (*phLog)->bOn = 0; (*phLog)->pszLogFile = NULL; (*phLog)->pszProgramName = NULL; /* each msg will be freed when deleted by this (_logFreeMsg) callback */ lstSetFreeFunc( (*phLog)->hMessages, _logFreeMsg ); /* PROGRAM NAME */ if ( pszProgramName ) (*phLog)->pszProgramName = (char *)strdup( pszProgramName ); else (*phLog)->pszProgramName = (char *)strdup( "UNKNOWN" ); /* LOG FILE */ if ( pszLogFile ) (*phLog)->pszLogFile = (char*)strdup( pszLogFile ); return LOG_SUCCESS; } unixODBC-2.3.12/log/logPeekMsg.c000066400000000000000000000033611446441710500162050ustar00rootroot00000000000000/********************************************************************** * logPopMsg * * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "log.h" /*! * \brief Returns a specific message. * * This returns a reference to a specific message and does * NOT delete the message or remove it from the log. This is * good for 'peeking' at messages in the stack. * * \param hLog Input. Viable log handle. * \param nMsg Input. This is the index to the desired message. The * index is 1 based with 1 being the oldest message. * \param phMsg Output. A reference to the message in the log. This * message is still maintained/owned by the log. The * reference is only valid until some other code modifies * the log. * * \return int * \retval LOG_NO_DATA No message at nMsg. * \retval LOG_ERROR * \retval LOG_SUCCESS * * \sa logPopMsg */ int logPeekMsg( HLOG hLog, long nMsg, HLOGMSG *phMsg ) { /* we must be logOpen to logPeekMsg */ if ( !hLog ) return LOG_ERROR; /* get reference */ /* \todo This can be terribly slow as we scan for each call. We may want to implement this over a vector instead of a list. */ *phMsg = (HLOGMSG)lstGoto( hLog->hMessages, nMsg - 1 ); /* was it found? */ if ( lstEOL( hLog->hMessages ) ) return LOG_NO_DATA; return LOG_SUCCESS; } unixODBC-2.3.12/log/logPopMsg.c000066400000000000000000000023551446441710500160610ustar00rootroot00000000000000/********************************************************************** * logPopMsg * * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "log.h" /*! * \brief Removes the oldest message from the log. * * The log is a FIFO stack and we implement a possible max on the * number of messages we can store. When we hot the max we 'pop' * a message out. The mem used by the message is automatically * freed with a call to \sa _logFreeMsg. * * \param hLog * * \return int * \retval LOG_NO_DATA * \retval LOG_ERROR * \retval LOG_SUCCESS * * \sa logPushMsg * logPeekMsg */ int logPopMsg( HLOG hLog ) { /* we must be logOpen to logPopMsg */ if ( !hLog ) return LOG_ERROR; /* FIFO */ lstFirst( hLog->hMessages ); /* do we have a message to delete? */ if ( lstEOL( hLog->hMessages ) ) return LOG_NO_DATA; return lstDelete( hLog->hMessages ); } unixODBC-2.3.12/log/logPushMsg.c000066400000000000000000000137121446441710500162410ustar00rootroot00000000000000/********************************************************************** * logPushMsg * * * This code was created by Peter Harvey (mostly during Christmas 98/99). * This code is LGPL. Please ensure that this message remains in future * distributions and uses of this code (thats about all I get out of it). * - Peter Harvey pharvey@codebydesign.com * **********************************************************************/ #include #include "log.h" #include "ini.h" /* Define this as a fall through, HAVE_STDARG_H is probably already set */ /*#define HAVE_VARARGS_H*/ /* varargs declarations: */ #if defined(HAVE_STDARG_H) # include #define VA_LOCAL_DECL va_list ap #define VA_START(f) va_start(ap, f) #define VA_SHIFT(v,t) ; /* no-op for ANSI */ #define VA_END va_end(ap) #else #if defined(HAVE_VARARGS_H) #define VA_LOCAL_DECL va_list ap #define VA_START(f) va_start(ap) /* f is ignored! */ #define VA_SHIFT(v,t) v = va_arg(ap,t) #define VA_END va_end(ap) #else #error No variable argument support #endif #endif #ifndef HAVE_VSNPRINTF int uodbc_vsnprintf (char *str, size_t count, const char *fmt, va_list args); #endif int logPushMsg( HLOG hLog, char *pszModule, char *pszFunctionName, int nLine, int nSeverity, int nCode, char *pszMessage ) { HLOGMSG hMsg; FILE *hFile; if ( !hLog ) return LOG_ERROR; if ( !hLog->hMessages ) return LOG_ERROR; if ( !hLog->bOn ) return LOG_SUCCESS; if ( !pszModule ) return LOG_ERROR; if ( !pszFunctionName ) return LOG_ERROR; if ( !pszMessage ) return LOG_ERROR; /* check for, and handle, max msg */ if ( hLog->nMaxMsgs && hLog->hMessages->nItems >= hLog->nMaxMsgs ) logPopMsg( hLog ); hMsg = malloc( sizeof(LOGMSG) ); if (!hMsg) goto error_abort0; hMsg->pszModuleName = (char *)strdup( pszModule ); if (!hMsg->pszModuleName) goto error_abort1; hMsg->pszFunctionName = (char *)strdup( pszFunctionName ); if (!hMsg->pszFunctionName) goto error_abort2; hMsg->pszMessage = (char *)strdup( pszMessage ); if (!hMsg->pszMessage) goto error_abort3; hMsg->nLine = nLine; hMsg->nSeverity = nSeverity; hMsg->nCode = nCode; /* append to list */ lstAppend( hLog->hMessages, hMsg ); /* append to file */ if ( hLog->pszLogFile ) { hFile = uo_fopen( hLog->pszLogFile, "a" ); if ( !hFile ) return LOG_ERROR; uo_fprintf( hFile, "[%s][%s][%s][%d]%s\n", hLog->pszProgramName, pszModule, pszFunctionName, nLine, pszMessage ); uo_fclose( hFile ); } return LOG_SUCCESS; error_abort3: free(hMsg->pszFunctionName); error_abort2: free(hMsg->pszModuleName); error_abort1: free(hMsg); error_abort0: return LOG_ERROR; } int logvPushMsgf( HLOG hLog, char *pszModule, char *pszFunctionName, int nLine, int nSeverity, int nCode, char *pszMessageFormat, va_list args ) { HLOGMSG hMsg=NULL; FILE *hFile; int mlen=0; if ( !hLog ) return LOG_ERROR; if ( !hLog->hMessages ) return LOG_ERROR; if ( !hLog->bOn ) return LOG_SUCCESS; if ( !pszModule ) return LOG_ERROR; if ( !pszFunctionName ) return LOG_ERROR; if ( !pszMessageFormat ) return LOG_ERROR; /* check for, and handle, max msg */ if ( hLog->nMaxMsgs && hLog->hMessages->nItems == hLog->nMaxMsgs ) logPopMsg( hLog ); hMsg = malloc( sizeof(LOGMSG) ); if (!hMsg) goto error_abort0; hMsg->pszModuleName = (char *)strdup( pszModule ); if (!hMsg->pszModuleName) goto error_abort1; hMsg->pszFunctionName = (char *)strdup( pszFunctionName ); if (!hMsg->pszFunctionName) goto error_abort2; #if defined( HAVE_VSNPRINTF ) mlen=vsnprintf(NULL,0,pszMessageFormat,args); #else mlen=uodbc_vsnprintf(NULL,0,pszMessageFormat,args); #endif mlen++; hMsg->pszMessage = malloc(mlen); if (!hMsg->pszMessage) goto error_abort3; #if defined( HAVE_VSNPRINTF ) vsnprintf(hMsg->pszMessage,mlen,pszMessageFormat,args); #else uodbc_vsnprintf(hMsg->pszMessage,mlen,pszMessageFormat,args); #endif hMsg->nLine = nLine; hMsg->nSeverity = nSeverity; hMsg->nCode = nCode; /* append to list */ lstAppend( hLog->hMessages, hMsg ); /* append to file */ if ( hLog->pszLogFile ) { hFile = uo_fopen( hLog->pszLogFile, "a" ); if ( !hFile ) return LOG_ERROR; if (hMsg) { uo_fprintf( hFile, "[%s][%s][%s][%d]%s\n", hLog->pszProgramName, pszModule, pszFunctionName, nLine, hMsg->pszMessage ); } else { uo_fprintf( hFile, "[%s][%s][%s][%d]", hLog->pszProgramName, pszModule, pszFunctionName, nLine ); uo_vfprintf( hFile, pszMessageFormat, args ); uo_fprintf( hFile, "\n" ); } uo_fclose( hFile ); } return LOG_SUCCESS; error_abort3: free(hMsg->pszFunctionName); error_abort2: free(hMsg->pszModuleName); error_abort1: free(hMsg); error_abort0: return LOG_ERROR; } #ifdef HAVE_STDARGS int logPushMsgf( HLOG hLog, char *pszModule, char *pszFunctionName, int nLine, int nSeverity, int nCode, char *pszMessageFormat, ... ) #else int logPushMsgf( va_alist ) va_dcl #endif { int err; #ifndef HAVE_STDARGS HLOG hLog; char *pszModule; char *pszFunctionName; int nLine; int nSeverity; int nCode; char *pszMessageFormat; #endif VA_LOCAL_DECL; VA_START (pszMessageFormat); VA_SHIFT (hLog, HLOG); VA_SHIFT (pszModule, char *); VA_SHIFT (pszFunctionName, char *); VA_SHIFT (nLine, int ); VA_SHIFT (nSeverity, int ); VA_SHIFT (nCode, int ); VA_SHIFT (pszMessageFormat, char *); err=logvPushMsgf(hLog,pszModule,pszFunctionName,nLine,nSeverity,nCode,pszMessageFormat,ap); VA_END; return err; } unixODBC-2.3.12/lst/000077500000000000000000000000001446441710500140225ustar00rootroot00000000000000unixODBC-2.3.12/lst/ChangeLog000066400000000000000000000011131446441710500155700ustar00rootroot000000000000001999-04-30 Peter Harvey * bVisible: Added bVisible to HLSTITEM and it is used by nav funcs. 1999-04-28 Peter Harvey * lstOpen: Now inits nItem to 0 (got removed somehow) 1999-04-21 Peter Harvey * _lstDump: Added 1999-04-15 Peter Harvey * All: Added lstOpenCursor and cursor support (still needs locking) 1999-04-07 Peter Harvey * BookMarks: Added 1999-04-04 Peter Harvey * ChangeLog: Started ChangeLog unixODBC-2.3.12/lst/Makefile.am000066400000000000000000000010261446441710500160550ustar00rootroot00000000000000noinst_LTLIBRARIES = liblstlc.la AM_CPPFLAGS = -I@top_srcdir@/include liblstlc_la_LDFLAGS = -no-undefined liblstlc_la_SOURCES = \ _lstAdjustCurrent.c \ _lstDump.c \ _lstFreeItem.c \ _lstNextValidItem.c \ _lstPrevValidItem.c \ _lstVisible.c \ lstAppend.c \ lstClose.c \ lstDelete.c \ lstEOL.c \ lstFirst.c \ lstGet.c \ lstGetBookMark.c \ lstGoto.c \ lstGotoBookMark.c \ lstInsert.c \ lstLast.c \ lstNext.c \ lstOpen.c \ lstOpenCursor.c \ lstPrev.c \ lstSeek.c \ lstSeekItem.c \ lstSet.c \ lstSetFreeFunc.c unixODBC-2.3.12/lst/README000066400000000000000000000025741446441710500147120ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * * * * Peter Harvey 04.APR.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | LST lib (liblst.so) | +-------------------------------------------------------------+ README Description: A linked list lib. Provides user with a set of very easy to use and proven functions for a doubly-linked list. Supports the creation of cursor sets which may, optionally, be based upon a user supplied filter function. Concurrency is handled to a certian extent but this lib is no substitute for the fine concurrency handling of a full DBMS. +-------------------------------------------------------------+ | Peter Harvey | | pharvey@codebydesign.com | | www.unixodbc.org | | 16.APR.99 | +-------------------------------------------------------------+ unixODBC-2.3.12/lst/TODO000066400000000000000000000024471446441710500145210ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * * * * Peter Harvey 04.APR.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | LST lib (liblst.so) | +-------------------------------------------------------------+ TODO 1. Improve the handling of concurrency issues. 2. Add support for user defined sort function. 3. Enhance lstSeek() so as to use sort order to improve search efficiency. 4. Improve handling of serious errors where memory is likely to be lost... for example printf a message. +-------------------------------------------------------------+ | Peter Harvey | | pharvey@codebydesign.com | | www.genix.net/unixODBC | | 16.APR.99 | +-------------------------------------------------------------+ unixODBC-2.3.12/lst/_lstAdjustCurrent.c000066400000000000000000000015131446441710500176450ustar00rootroot00000000000000#include #include "lst.h" /*************************** * ENSURE CURRENT IS NOT ON A bDelete ITEM * * 1. Should only be required for root list. ***************************/ void *_lstAdjustCurrent( HLST hLst ) { HLSTITEM h; if ( !hLst ) return NULL; if ( !hLst->hCurrent ) return NULL; if ( _lstVisible( hLst->hCurrent ) ) return hLst->hCurrent; h = hLst->hCurrent; while ( !_lstVisible( hLst->hCurrent ) && hLst->hCurrent->pPrev ) { hLst->hCurrent = hLst->hCurrent->pPrev; } if ( _lstVisible( hLst->hCurrent ) ) return hLst->hCurrent; hLst->hCurrent = h; while ( !_lstVisible( hLst->hCurrent ) && hLst->hCurrent->pNext ) { hLst->hCurrent = hLst->hCurrent->pNext; } if ( _lstVisible( hLst->hCurrent ) ) return hLst->hCurrent; hLst->hCurrent = NULL; return NULL; } unixODBC-2.3.12/lst/_lstDump.c000066400000000000000000000012431446441710500157550ustar00rootroot00000000000000#include #include "lst.h" void _lstDump( HLST hLst ) { HLSTITEM hItem; int nItem = 0; printf( "LST - BEGIN DUMP\n" ); if ( hLst ) { printf( "\thLst = %p\n", hLst ); printf( "\t\thLst->hLstBase = %p\n", hLst->hLstBase ); hItem = hLst->hFirst; while ( hItem ) { printf( "\t%d\n", nItem ); printf( "\t\thItem = %p\n", hItem ); printf( "\t\thItem->bDelete = %d\n", hItem->bDelete ); printf( "\t\thItem->bHide = %d\n", hItem->bHide ); printf( "\t\thItem->pData = %p\n", hItem->pData ); printf( "\t\thItem->hLst = %p\n", hItem->hLst ); nItem++; hItem = hItem->pNext; } } printf( "LST - END DUMP\n" ); } unixODBC-2.3.12/lst/_lstFreeItem.c000066400000000000000000000032321446441710500165500ustar00rootroot00000000000000#include #include "lst.h" /*************************** * _lstFreeItem * * 1. FREES MEMORY USED BY THE LIST ITEM AND REMOVES IT FROM ITS LIST * 2. WILL CLEAN UP root ITEM IF REQUIRED.. NEVER SETS bDelete... lstDelete DOES SET bDelete * 3. CALLS _lstAdjustCurrent TO ENSURE THAT CURRENT DOES NOT END UP ON bDelete ITEM ***************************/ int _lstFreeItem( HLSTITEM hItem ) { HLST hLst; HLSTITEM hItemRoot; HLSTITEM hNewCurrent = NULL; if ( !hItem ) return LST_ERROR; hLst = (HLST)hItem->hLst; /************* * FREE root ITEM AS REQUIRED *************/ if ( hLst->hLstBase ) { hItemRoot = (HLSTITEM)hItem->pData; /************* * dec ref count in root item *************/ hItemRoot->nRefs--; /************* * DELETE root ITEM IF REF = 0 AND SOMEONE SAID DELETE IT *************/ if ( hItemRoot->nRefs < 1 && hItemRoot->bDelete ) { _lstFreeItem( hItemRoot ); } } /************* * WE ALWAYS FREE hItem *************/ if ( hItem->pData && hLst->pFree ) hLst->pFree( hItem->pData ); if ( !hItem->bDelete ) /* THIS IS REALLY ONLY A FACTOR FOR ROOT ITEMS */ hLst->nItems--; if ( hItem == hLst->hFirst ) hLst->hFirst = hItem->pNext; if ( hItem == hLst->hLast ) hLst->hLast = hItem->pPrev; if ( hItem->pPrev ) { hItem->pPrev->pNext = hItem->pNext; if ( hItem == hLst->hCurrent ) hNewCurrent = hItem->pPrev; } if ( hItem->pNext ) { hItem->pNext->pPrev = hItem->pPrev; if ( !hNewCurrent && hItem == hLst->hCurrent ) hNewCurrent = hItem->pNext; } free( hItem ); hLst->hCurrent = hNewCurrent; _lstAdjustCurrent( hLst ); return LST_SUCCESS; } unixODBC-2.3.12/lst/_lstNextValidItem.c000066400000000000000000000004751446441710500175730ustar00rootroot00000000000000#include #include "lst.h" HLSTITEM _lstNextValidItem( HLST hLst, HLSTITEM hItem ) { if ( !hLst ) return NULL; if ( !hItem ) return NULL; hItem = hItem->pNext; while ( hItem ) { if ( _lstVisible( hItem ) ) return hItem; hItem = hItem->pNext; } return NULL; } unixODBC-2.3.12/lst/_lstPrevValidItem.c000066400000000000000000000004761446441710500175720ustar00rootroot00000000000000#include #include "lst.h" HLSTITEM _lstPrevValidItem( HLST hLst, HLSTITEM hItem ) { if ( !hLst ) return NULL; if ( !hItem ) return NULL; hItem = hItem->pPrev; while ( hItem ) { if ( _lstVisible( hItem ) ) return hItem; hItem = hItem->pPrev; } return NULL; } unixODBC-2.3.12/lst/_lstVisible.c000066400000000000000000000004661446441710500164530ustar00rootroot00000000000000#include #include "lst.h" int _lstVisible( HLSTITEM hItem ) { HLST hLst; if ( !hItem ) return false; hLst = (HLST)hItem->hLst; if ( hItem->bDelete && hLst->bShowDeleted == false ) return false; if ( hItem->bHide && hLst->bShowHidden == false ) return false; return true; } unixODBC-2.3.12/lst/lstAppend.c000066400000000000000000000030261446441710500161210ustar00rootroot00000000000000#include #include "lst.h" /************************* * lstAppend * * 1. APPEND TO BASE LIST IF hLst IS A CURSOR * 2. APPEND REF TO THIS LIST *************************/ int lstAppend( HLST hLst, void *pData ) { HLSTITEM hItem; if ( !hLst ) return LST_ERROR; /********************** * CREATE AN ITEM **********************/ hItem = (HLSTITEM) malloc( sizeof(LSTITEM) ); if ( !hItem ) return LST_ERROR; hItem->bDelete = false; hItem->bHide = false; hItem->hLst = hLst; hItem->nRefs = 0; hItem->pData = NULL; hItem->pNext = NULL; hItem->pPrev = NULL; if ( hLst->hLstBase ) { /********************** * WE ARE A CURSOR LIST SO... * 1. ADD TO BASE LIST * 2. ADD TO THIS LIST (ref to base list) **********************/ lstAppend( hLst->hLstBase, pData ); hItem->pData = hLst->hLstBase->hCurrent; hLst->hLstBase->hCurrent->nRefs++; _lstAppend( hLst, hItem ); } else { /********************** * WE ARE THE ROOT SO... * 1. ADD TO THIS LIST **********************/ hItem->pData = pData; _lstAppend( hLst, hItem ); } return LST_SUCCESS; } /************************* * SIMPLY CONNECTS THE LINKS/POINTERS AND SETS CURRENT *************************/ int _lstAppend( HLST hLst, HLSTITEM hItem ) { if ( hLst->hFirst ) { hItem->pPrev = hLst->hLast; hLst->hLast->pNext = hItem; hLst->hLast = hItem; } else { hItem->pPrev = NULL; hLst->hFirst = hItem; hLst->hLast = hItem; } hLst->hCurrent = hItem; hLst->nItems++; return LST_SUCCESS; } unixODBC-2.3.12/lst/lstClose.c000066400000000000000000000022501446441710500157550ustar00rootroot00000000000000#include #include "lst.h" /********************* * lstClose * * Call for Cursor or root list. *********************/ int lstClose( HLST hLst ) { HLSTITEM hItem; if ( !hLst ) return LST_ERROR; hLst->nRefs--; /********************* * We will not really remove the list if we have * refs to it... we will just decrement ref. * We will be deleted when the last ref is being removed. *********************/ if ( hLst->nRefs > 0 ) return LST_SUCCESS; /************************ * DELETE ITEMS (and their refs) * - do not use standard nav funcs because they will skip items where bDelete ************************/ hItem = hLst->hFirst; while ( hItem ) { _lstFreeItem( hItem ); hItem = hLst->hFirst; } /************************ * RECURSE AS REQUIRED. RECURSION WILL STOP AS SOON AS WE GET TO A LIST WHICH * DOES NOT NEED TO BE DELETED YET (refs >= 0). ************************/ if ( hLst->hLstBase ) /* we are a cursor */ lstClose( hLst->hLstBase ); /* dec ref count and close if < 0 */ /************************ * FREE LIST HANDLE ************************/ free( hLst ); return LST_SUCCESS; } unixODBC-2.3.12/lst/lstDelete.c000066400000000000000000000030021446441710500161060ustar00rootroot00000000000000#include #include "lst.h" int _lstDeleteFlag( HLSTITEM hItem ); /*********************** * lstDelete * * Do not call unless you want to delete the item * from the cursor (if the list is one) **AND** the * root list. In other words; this should not be * called from functions such as lstClose() which * desire to simply free memory used by a specific * the list. * * This is the only function to set bDelete in the root * item (as required). * * lstFreeItem will decrement ref counters and do a real * delete when refs are 0. ************************/ int lstDelete( HLST hLst ) { HLSTITEM hItem = NULL; HLSTITEM hItemRoot = NULL; if ( !hLst ) return LST_ERROR; hItem = hLst->hCurrent; if ( !hItem ) return LST_ERROR; /********************* * ARE WE A CURSOR LIST *********************/ if ( hLst->hLstBase ) { hItemRoot = (HLSTITEM)hItem->pData; _lstDeleteFlag( hItemRoot ); return _lstFreeItem( hItem ); } /********************* * WE ARE root LIST. CHECK FOR REFS BEFORE CALLING FREE *********************/ _lstDeleteFlag( hItem ); if ( hItem->nRefs < 1 ) return _lstFreeItem( hItem ); return LST_SUCCESS; } /*************************** * FLAG FOR DELETE (should only be called if root list) ***************************/ int _lstDeleteFlag( HLSTITEM hItem ) { HLST hLst; hLst = (HLST)hItem->hLst; if ( !hItem->bDelete ) hLst->nItems--; hItem->bDelete = true; if ( hLst->hCurrent == hItem ) _lstAdjustCurrent( hLst ); return true; } unixODBC-2.3.12/lst/lstEOL.c000066400000000000000000000002421446441710500153260ustar00rootroot00000000000000#include #include "lst.h" int lstEOL( HLST hLst ) { if ( !hLst ) return true; if ( !hLst->hCurrent ) return true; return false; } unixODBC-2.3.12/lst/lstFirst.c000066400000000000000000000004741446441710500160050ustar00rootroot00000000000000#include #include "lst.h" void *lstFirst( HLST hLst ) { if ( !hLst ) return NULL; if ( !hLst->hFirst ) return NULL; if ( !_lstVisible( hLst->hFirst ) ) hLst->hCurrent = _lstNextValidItem( hLst, hLst->hFirst ); else hLst->hCurrent = hLst->hFirst; return hLst->hCurrent; } unixODBC-2.3.12/lst/lstGet.c000066400000000000000000000007351446441710500154350ustar00rootroot00000000000000#include #include "lst.h" /* * */ void *lstGet( HLST hLst ) { HLSTITEM hItem; if ( !hLst ) return NULL; if ( !hLst->hCurrent ) return NULL; if ( hLst->hLstBase ) hItem = (HLSTITEM)hLst->hCurrent->pData; /* cursor pData points directly to the root Item (not the roots pData) */ else /* a cursor may be based upon another cursor but pData is always ptr to root item */ hItem = hLst->hCurrent; return hItem->pData; } unixODBC-2.3.12/lst/lstGetBookMark.c000066400000000000000000000004521446441710500170570ustar00rootroot00000000000000#include #include "lst.h" int lstGetBookMark( HLST hLst, HLSTBOOKMARK hLstBookMark ) { if ( !hLst ) return LST_ERROR; if ( !hLstBookMark ) return LST_ERROR; hLstBookMark->hCurrent = hLst->hCurrent; hLstBookMark->hLst = hLst; return LST_SUCCESS; } unixODBC-2.3.12/lst/lstGoto.c000066400000000000000000000017741446441710500156320ustar00rootroot00000000000000#include #include "lst.h" /*! * \brief Returns the data stored at nIndex. * * This does a scan from first-to-last until nIndex or until EOL. This * can be slow if there are many items in the list. * * This does not return the item handle - it returns the user data stored * in the item. * * When done; the current item is either the item at nIndex or EOL. * * \param hLst Input. Viable list handle. * \param nIndex Input. 0-based index of the desired item. * * \return void* * \retval NULL Item at index could not be found - effectively data is NULL. * \retval !NULL Reference to the data stored at nIndex */ void *lstGoto( HLST hLst, long nIndex ) { long n = 0; if ( !hLst ) return NULL; lstFirst( hLst ); while ( n <= nIndex ) { if ( lstEOL( hLst ) ) break; if ( n == nIndex ) return hLst->hCurrent->pData; n++; lstNext( hLst ); } return NULL; } unixODBC-2.3.12/lst/lstGotoBookMark.c000066400000000000000000000003441446441710500172500ustar00rootroot00000000000000#include #include "lst.h" int lstGotoBookMark( HLSTBOOKMARK hLstBookMark ) { if ( !hLstBookMark ) return LST_ERROR; hLstBookMark->hLst->hCurrent = hLstBookMark->hCurrent; return LST_SUCCESS; } unixODBC-2.3.12/lst/lstInsert.c000066400000000000000000000033721446441710500161620ustar00rootroot00000000000000#include #include "lst.h" int lstInsert( HLST hLst, void *pData ) { HLSTITEM hItem; if ( !hLst ) return LST_ERROR; if ( !hLst->hCurrent ) return lstAppend( hLst, pData ); /********************** * CREATE AN ITEM **********************/ hItem = malloc( sizeof(LSTITEM) ); if ( !hItem ) return LST_ERROR; hItem->bDelete = false; hItem->bHide = false; hItem->hLst = hLst; hItem->nRefs = 0; hItem->pData = NULL; hItem->pNext = NULL; hItem->pPrev = NULL; if ( hLst->hLstBase ) { /********************** * WE ARE A CURSOR LIST SO... * 1. ADD TO BASE LIST * 2. inc BASE LIST ITEM REF COUNT * 3. ADD TO THIS LIST (ref to base list) **********************/ lstInsert( hLst->hLstBase, pData ); /* !!! INSERT POS IN BASE LIST IS UNPREDICTABLE !!! */ /* BECAUSE hCurrent MAY HAVE CHANGED AND WE */ /* ARE NOT TRYING TO PUT IT BACK */ hItem->pData = hLst->hLstBase->hCurrent; hLst->hLstBase->hCurrent->nRefs++; _lstInsert( hLst, hItem ); } else { /********************** * WE ARE THE ROOT SO... * 1. ADD TO THIS LIST **********************/ hItem->pData = pData; _lstInsert( hLst, hItem ); } return LST_SUCCESS; } /************************* * SIMPLY CONNECTS THE LINKS/POINTERS AND SETS CURRENT *************************/ int _lstInsert( HLST hLst, HLSTITEM hItem ) { if ( !hLst->hCurrent ) return _lstAppend( hLst, hItem ); hItem->pPrev = hLst->hCurrent->pPrev; hItem->pNext = hLst->hCurrent; if ( hLst->hCurrent->pPrev ) hLst->hCurrent->pPrev->pNext = hItem; hLst->hCurrent->pPrev = hItem; if ( hLst->hCurrent == hLst->hFirst ) hLst->hFirst = hItem; hLst->hCurrent = hItem; hLst->nItems++; return LST_SUCCESS; } unixODBC-2.3.12/lst/lstLast.c000066400000000000000000000004671446441710500156230ustar00rootroot00000000000000#include #include "lst.h" void *lstLast( HLST hLst ) { if ( !hLst ) return NULL; if ( !hLst->hLast ) return NULL; if ( !_lstVisible( hLst->hLast ) ) hLst->hCurrent = _lstPrevValidItem( hLst, hLst->hLast ); else hLst->hCurrent = hLst->hLast; return hLst->hCurrent; } unixODBC-2.3.12/lst/lstNext.c000066400000000000000000000005351446441710500156320ustar00rootroot00000000000000#include #include "lst.h" void *lstNext( HLST hLst ) { if ( !hLst ) return NULL; if ( !hLst->hCurrent ) return NULL; hLst->hCurrent = hLst->hCurrent->pNext; if ( hLst->hCurrent ) { if ( !_lstVisible( hLst->hCurrent ) ) hLst->hCurrent = _lstNextValidItem( hLst, hLst->hCurrent ); } return hLst->hCurrent; } unixODBC-2.3.12/lst/lstOpen.c000066400000000000000000000007521446441710500156160ustar00rootroot00000000000000#include #include "lst.h" HLST lstOpen() { HLST hLst = NULL; hLst = malloc( sizeof(LST) ); if ( hLst ) { hLst->bExclusive = false; hLst->hCurrent = NULL; hLst->hFirst = NULL; hLst->hLast = NULL; hLst->hLstBase = NULL; hLst->nRefs = 1; /* someone created us so lets assume that it counts as one ref */ hLst->pFilter = NULL; hLst->pFree = free; hLst->nItems = 0; hLst->bShowDeleted = false; hLst->bShowHidden = false; } return hLst; } unixODBC-2.3.12/lst/lstOpenCursor.c000066400000000000000000000020771446441710500170160ustar00rootroot00000000000000#include #include "lst.h" HLST lstOpenCursor( HLST hBase, int (*pFilterFunc)( HLST, void * ), void *pExtras ) { HLST hLst = NULL; if ( !hBase ) return NULL; /************************* * CREATE A NEW LIST *************************/ hLst = lstOpen(); if ( !hLst ) return NULL; hBase->nRefs++; hLst->pFilter = pFilterFunc; hLst->pFree = NULL; /* never free pData in a cursor */ hLst->pExtras = pExtras; /************************* * ADD ITEMS FROM hBase (skipping any bDelete items) *************************/ lstFirst( hBase ); if ( pFilterFunc ) { while ( !lstEOL( hBase ) ) { if ( pFilterFunc( hLst, lstGet( hBase ) ) ) lstAppend( hLst, hBase->hCurrent ); lstNext( hBase ); } } else { while ( !lstEOL( hBase ) ) { lstAppend( hLst, hBase->hCurrent ); lstNext( hBase ); } } /************************* * THIS *MUST* BE DONE AFTER THE LIST IS LOADED * OTHERWISE lstAppend() WILL APPEND INTO ROOT LIST AND MAKE A REF IN THIS LIST *************************/ hLst->hLstBase = hBase; return hLst; } unixODBC-2.3.12/lst/lstPrev.c000066400000000000000000000005371446441710500156320ustar00rootroot00000000000000#include #include "lst.h" void *lstPrev( HLST hLst ) { if ( !hLst ) return NULL; if ( !hLst->hCurrent ) return NULL; hLst->hCurrent = hLst->hCurrent->pPrev; if ( hLst->hCurrent ) { if ( !_lstVisible( hLst->hCurrent ) ) hLst->hCurrent = _lstPrevValidItem( hLst, hLst->hCurrent ); } return hLst->hCurrent; } unixODBC-2.3.12/lst/lstSeek.c000066400000000000000000000004071446441710500156010ustar00rootroot00000000000000#include #include "lst.h" int lstSeek( HLST hLst, void *pData ) { if ( !hLst ) return false; lstFirst( hLst ); while ( !lstEOL( hLst ) ) { if ( lstGet( hLst ) == pData ) return true; lstNext( hLst ); } return false; } unixODBC-2.3.12/lst/lstSeekItem.c000066400000000000000000000004161446441710500164200ustar00rootroot00000000000000#include #include "lst.h" int lstSeekItem( HLST hLst, HLSTITEM hItem ) { if ( !hLst ) return false; lstFirst( hLst ); while ( !lstEOL( hLst ) ) { if ( hLst->hCurrent == hItem ) return true; lstNext( hLst ); } return false; } unixODBC-2.3.12/lst/lstSet.c000066400000000000000000000010121446441710500154360ustar00rootroot00000000000000#include #include "lst.h" void *lstSet( HLST hLst, void *pData ) { HLSTITEM hItem; HLST hLstRoot; if ( !hLst ) return NULL; if ( !hLst->hCurrent ) return NULL; if ( hLst->hLstBase ) hItem = (HLSTITEM)hLst->hCurrent->pData; else hItem = hLst->hCurrent; hLstRoot = (HLST)hItem->hLst; /************************** * SET VALUE **************************/ if ( hItem->pData && hLstRoot->pFree ) hLstRoot->pFree( hItem->pData ); hItem->pData = pData; return pData; } unixODBC-2.3.12/lst/lstSetFreeFunc.c000066400000000000000000000002561446441710500170650ustar00rootroot00000000000000#include #include "lst.h" int lstSetFreeFunc( HLST hLst, void (*pFree)( void *pData ) ) { if ( !hLst ) return false; hLst->pFree = pFree; return true; } unixODBC-2.3.12/m4/000077500000000000000000000000001446441710500135405ustar00rootroot00000000000000unixODBC-2.3.12/m4/argz.m4000066400000000000000000000050671446441710500147550ustar00rootroot00000000000000# Portability macros for glibc argz. -*- Autoconf -*- # # Copyright (C) 2004-2007, 2011-2013 Free Software Foundation, Inc. # Written by Gary V. Vaughan # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 argz.m4 AC_DEFUN([gl_FUNC_ARGZ], [gl_PREREQ_ARGZ AC_CHECK_HEADERS([argz.h], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_TYPES([error_t], [], [AC_DEFINE([error_t], [int], [Define to a type to use for 'error_t' if it is not otherwise available.]) AC_DEFINE([__error_t_defined], [1], [Define so that glibc/gnulib argp.h does not typedef error_t.])], [#if defined(HAVE_ARGZ_H) # include #endif]) ARGZ_H= AC_CHECK_FUNCS([argz_add argz_append argz_count argz_create_sep argz_insert \ argz_next argz_stringify], [], [ARGZ_H=argz.h; AC_LIBOBJ([argz])]) dnl if have system argz functions, allow forced use of dnl libltdl-supplied implementation (and default to do so dnl on "known bad" systems). Could use a runtime check, but dnl (a) detecting malloc issues is notoriously unreliable dnl (b) only known system that declares argz functions, dnl provides them, yet they are broken, is cygwin dnl releases prior to 16-Mar-2007 (1.5.24 and earlier) dnl So, it's more straightforward simply to special case dnl this for known bad systems. AS_IF([test -z "$ARGZ_H"], [AC_CACHE_CHECK( [if argz actually works], [lt_cv_sys_argz_works], [[case $host_os in #( *cygwin*) lt_cv_sys_argz_works=no if test no != "$cross_compiling"; then lt_cv_sys_argz_works="guessing no" else lt_sed_extract_leading_digits='s/^\([0-9\.]*\).*/\1/' save_IFS=$IFS IFS=-. set x `uname -r | sed -e "$lt_sed_extract_leading_digits"` IFS=$save_IFS lt_os_major=${2-0} lt_os_minor=${3-0} lt_os_micro=${4-0} if test 1 -lt "$lt_os_major" \ || { test 1 -eq "$lt_os_major" \ && { test 5 -lt "$lt_os_minor" \ || { test 5 -eq "$lt_os_minor" \ && test 24 -lt "$lt_os_micro"; }; }; }; then lt_cv_sys_argz_works=yes fi fi ;; #( *) lt_cv_sys_argz_works=yes ;; esac]]) AS_IF([test yes = "$lt_cv_sys_argz_works"], [AC_DEFINE([HAVE_WORKING_ARGZ], 1, [This value is set to 1 to indicate that the system argz facility works])], [ARGZ_H=argz.h AC_LIBOBJ([argz])])]) AC_SUBST([ARGZ_H]) ]) # Prerequisites of lib/argz.c. AC_DEFUN([gl_PREREQ_ARGZ], [:]) unixODBC-2.3.12/m4/ltargz.m4000066400000000000000000000050111446441710500153020ustar00rootroot00000000000000# Portability macros for glibc argz. -*- Autoconf -*- # # Copyright (C) 2004-2007, 2011-2015 Free Software Foundation, Inc. # Written by Gary V. Vaughan # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 1 ltargz.m4 AC_DEFUN([LT_FUNC_ARGZ], [ AC_CHECK_HEADERS([argz.h], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_TYPES([error_t], [], [AC_DEFINE([error_t], [int], [Define to a type to use for 'error_t' if it is not otherwise available.]) AC_DEFINE([__error_t_defined], [1], [Define so that glibc/gnulib argp.h does not typedef error_t.])], [#if defined(HAVE_ARGZ_H) # include #endif]) LT_ARGZ_H= AC_CHECK_FUNCS([argz_add argz_append argz_count argz_create_sep argz_insert \ argz_next argz_stringify], [], [LT_ARGZ_H=lt__argz.h; AC_LIBOBJ([lt__argz])]) dnl if have system argz functions, allow forced use of dnl libltdl-supplied implementation (and default to do so dnl on "known bad" systems). Could use a runtime check, but dnl (a) detecting malloc issues is notoriously unreliable dnl (b) only known system that declares argz functions, dnl provides them, yet they are broken, is cygwin dnl releases prior to 16-Mar-2007 (1.5.24 and earlier) dnl So, it's more straightforward simply to special case dnl this for known bad systems. AS_IF([test -z "$LT_ARGZ_H"], [AC_CACHE_CHECK( [if argz actually works], [lt_cv_sys_argz_works], [[case $host_os in #( *cygwin*) lt_cv_sys_argz_works=no if test no != "$cross_compiling"; then lt_cv_sys_argz_works="guessing no" else lt_sed_extract_leading_digits='s/^\([0-9\.]*\).*/\1/' save_IFS=$IFS IFS=-. set x `uname -r | sed -e "$lt_sed_extract_leading_digits"` IFS=$save_IFS lt_os_major=${2-0} lt_os_minor=${3-0} lt_os_micro=${4-0} if test 1 -lt "$lt_os_major" \ || { test 1 -eq "$lt_os_major" \ && { test 5 -lt "$lt_os_minor" \ || { test 5 -eq "$lt_os_minor" \ && test 24 -lt "$lt_os_micro"; }; }; }; then lt_cv_sys_argz_works=yes fi fi ;; #( *) lt_cv_sys_argz_works=yes ;; esac]]) AS_IF([test yes = "$lt_cv_sys_argz_works"], [AC_DEFINE([HAVE_WORKING_ARGZ], 1, [This value is set to 1 to indicate that the system argz facility works])], [LT_ARGZ_H=lt__argz.h AC_LIBOBJ([lt__argz])])]) AC_SUBST([LT_ARGZ_H]) ]) unixODBC-2.3.12/m4/ltdl.m4000066400000000000000000000725161446441710500147540ustar00rootroot00000000000000# ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*- # # Copyright (C) 1999-2008, 2011-2015 Free Software Foundation, Inc. # Written by Thomas Tanner, 1999 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 20 LTDL_INIT # LT_CONFIG_LTDL_DIR(DIRECTORY, [LTDL-MODE]) # ------------------------------------------ # DIRECTORY contains the libltdl sources. It is okay to call this # function multiple times, as long as the same DIRECTORY is always given. AC_DEFUN([LT_CONFIG_LTDL_DIR], [AC_BEFORE([$0], [LTDL_INIT]) _$0($*) ])# LT_CONFIG_LTDL_DIR # We break this out into a separate macro, so that we can call it safely # internally without being caught accidentally by the sed scan in libtoolize. m4_defun([_LT_CONFIG_LTDL_DIR], [dnl remove trailing slashes m4_pushdef([_ARG_DIR], m4_bpatsubst([$1], [/*$])) m4_case(_LTDL_DIR, [], [dnl only set lt_ltdl_dir if _ARG_DIR is not simply '.' m4_if(_ARG_DIR, [.], [], [m4_define([_LTDL_DIR], _ARG_DIR) _LT_SHELL_INIT([lt_ltdl_dir=']_ARG_DIR['])])], [m4_if(_ARG_DIR, _LTDL_DIR, [], [m4_fatal([multiple libltdl directories: ']_LTDL_DIR[', ']_ARG_DIR['])])]) m4_popdef([_ARG_DIR]) ])# _LT_CONFIG_LTDL_DIR # Initialise: m4_define([_LTDL_DIR], []) # _LT_BUILD_PREFIX # ---------------- # If Autoconf is new enough, expand to '$(top_build_prefix)', otherwise # to '$(top_builddir)/'. m4_define([_LT_BUILD_PREFIX], [m4_ifdef([AC_AUTOCONF_VERSION], [m4_if(m4_version_compare(m4_defn([AC_AUTOCONF_VERSION]), [2.62]), [-1], [m4_ifdef([_AC_HAVE_TOP_BUILD_PREFIX], [$(top_build_prefix)], [$(top_builddir)/])], [$(top_build_prefix)])], [$(top_builddir)/])[]dnl ]) # LTDL_CONVENIENCE # ---------------- # sets LIBLTDL to the link flags for the libltdl convenience library and # LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-convenience to the configure arguments. Note that # AC_CONFIG_SUBDIRS is not called here. LIBLTDL will be prefixed with # '$(top_build_prefix)' if available, otherwise with '$(top_builddir)/', # and LTDLINCL will be prefixed with '$(top_srcdir)/' (note the single # quotes!). If your package is not flat and you're not using automake, # define top_build_prefix, top_builddir, and top_srcdir appropriately # in your Makefiles. AC_DEFUN([LTDL_CONVENIENCE], [AC_BEFORE([$0], [LTDL_INIT])dnl dnl Although the argument is deprecated and no longer documented, dnl LTDL_CONVENIENCE used to take a DIRECTORY orgument, if we have one dnl here make sure it is the same as any other declaration of libltdl's dnl location! This also ensures lt_ltdl_dir is set when configure.ac is dnl not yet using an explicit LT_CONFIG_LTDL_DIR. m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl _$0() ])# LTDL_CONVENIENCE # AC_LIBLTDL_CONVENIENCE accepted a directory argument in older libtools, # now we have LT_CONFIG_LTDL_DIR: AU_DEFUN([AC_LIBLTDL_CONVENIENCE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_CONVENIENCE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBLTDL_CONVENIENCE], []) # _LTDL_CONVENIENCE # ----------------- # Code shared by LTDL_CONVENIENCE and LTDL_INIT([convenience]). m4_defun([_LTDL_CONVENIENCE], [case $enable_ltdl_convenience in no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; "") enable_ltdl_convenience=yes ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; esac LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdlc.la" LTDLDEPS=$LIBLTDL LTDLINCL='-I$(top_srcdir)'"${lt_ltdl_dir+/$lt_ltdl_dir}" AC_SUBST([LIBLTDL]) AC_SUBST([LTDLDEPS]) AC_SUBST([LTDLINCL]) # For backwards non-gettext consistent compatibility... INCLTDL=$LTDLINCL AC_SUBST([INCLTDL]) ])# _LTDL_CONVENIENCE # LTDL_INSTALLABLE # ---------------- # sets LIBLTDL to the link flags for the libltdl installable library # and LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-install to the configure arguments. Note that # AC_CONFIG_SUBDIRS is not called from here. If an installed libltdl # is not found, LIBLTDL will be prefixed with '$(top_build_prefix)' if # available, otherwise with '$(top_builddir)/', and LTDLINCL will be # prefixed with '$(top_srcdir)/' (note the single quotes!). If your # package is not flat and you're not using automake, define top_build_prefix, # top_builddir, and top_srcdir appropriately in your Makefiles. # In the future, this macro may have to be called after LT_INIT. AC_DEFUN([LTDL_INSTALLABLE], [AC_BEFORE([$0], [LTDL_INIT])dnl dnl Although the argument is deprecated and no longer documented, dnl LTDL_INSTALLABLE used to take a DIRECTORY orgument, if we have one dnl here make sure it is the same as any other declaration of libltdl's dnl location! This also ensures lt_ltdl_dir is set when configure.ac is dnl not yet using an explicit LT_CONFIG_LTDL_DIR. m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl _$0() ])# LTDL_INSTALLABLE # AC_LIBLTDL_INSTALLABLE accepted a directory argument in older libtools, # now we have LT_CONFIG_LTDL_DIR: AU_DEFUN([AC_LIBLTDL_INSTALLABLE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_INSTALLABLE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBLTDL_INSTALLABLE], []) # _LTDL_INSTALLABLE # ----------------- # Code shared by LTDL_INSTALLABLE and LTDL_INIT([installable]). m4_defun([_LTDL_INSTALLABLE], [if test -f "$prefix/lib/libltdl.la"; then lt_save_LDFLAGS=$LDFLAGS LDFLAGS="-L$prefix/lib $LDFLAGS" AC_CHECK_LIB([ltdl], [lt_dlinit], [lt_lib_ltdl=yes]) LDFLAGS=$lt_save_LDFLAGS if test yes = "${lt_lib_ltdl-no}"; then if test yes != "$enable_ltdl_install"; then # Don't overwrite $prefix/lib/libltdl.la without --enable-ltdl-install AC_MSG_WARN([not overwriting libltdl at $prefix, force with '--enable-ltdl-install']) enable_ltdl_install=no fi elif test no = "$enable_ltdl_install"; then AC_MSG_WARN([libltdl not installed, but installation disabled]) fi fi # If configure.ac declared an installable ltdl, and the user didn't override # with --disable-ltdl-install, we will install the shipped libltdl. case $enable_ltdl_install in no) ac_configure_args="$ac_configure_args --enable-ltdl-install=no" LIBLTDL=-lltdl LTDLDEPS= LTDLINCL= ;; *) enable_ltdl_install=yes ac_configure_args="$ac_configure_args --enable-ltdl-install" LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdl.la" LTDLDEPS=$LIBLTDL LTDLINCL='-I$(top_srcdir)'"${lt_ltdl_dir+/$lt_ltdl_dir}" ;; esac AC_SUBST([LIBLTDL]) AC_SUBST([LTDLDEPS]) AC_SUBST([LTDLINCL]) # For backwards non-gettext consistent compatibility... INCLTDL=$LTDLINCL AC_SUBST([INCLTDL]) ])# LTDL_INSTALLABLE # _LTDL_MODE_DISPATCH # ------------------- m4_define([_LTDL_MODE_DISPATCH], [dnl If _LTDL_DIR is '.', then we are configuring libltdl itself: m4_if(_LTDL_DIR, [], [], dnl if _LTDL_MODE was not set already, the default value is 'subproject': [m4_case(m4_default(_LTDL_MODE, [subproject]), [subproject], [AC_CONFIG_SUBDIRS(_LTDL_DIR) _LT_SHELL_INIT([lt_dlopen_dir=$lt_ltdl_dir])], [nonrecursive], [_LT_SHELL_INIT([lt_dlopen_dir=$lt_ltdl_dir; lt_libobj_prefix=$lt_ltdl_dir/])], [recursive], [], [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])])dnl dnl Be careful not to expand twice: m4_define([$0], []) ])# _LTDL_MODE_DISPATCH # _LT_LIBOBJ(MODULE_NAME) # ----------------------- # Like AC_LIBOBJ, except that MODULE_NAME goes into _LT_LIBOBJS instead # of into LIBOBJS. AC_DEFUN([_LT_LIBOBJ], [ m4_pattern_allow([^_LT_LIBOBJS$]) _LT_LIBOBJS="$_LT_LIBOBJS $1.$ac_objext" ])# _LT_LIBOBJS # LTDL_INIT([OPTIONS]) # -------------------- # Clients of libltdl can use this macro to allow the installer to # choose between a shipped copy of the ltdl sources or a preinstalled # version of the library. If the shipped ltdl sources are not in a # subdirectory named libltdl, the directory name must be given by # LT_CONFIG_LTDL_DIR. AC_DEFUN([LTDL_INIT], [dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) dnl We need to keep our own list of libobjs separate from our parent project, dnl and the easiest way to do that is redefine the AC_LIBOBJs macro while dnl we look for our own LIBOBJs. m4_pushdef([AC_LIBOBJ], m4_defn([_LT_LIBOBJ])) m4_pushdef([AC_LIBSOURCES]) dnl If not otherwise defined, default to the 1.5.x compatible subproject mode: m4_if(_LTDL_MODE, [], [m4_define([_LTDL_MODE], m4_default([$2], [subproject])) m4_if([-1], [m4_bregexp(_LTDL_MODE, [\(subproject\|\(non\)?recursive\)])], [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])]) AC_ARG_WITH([included_ltdl], [AS_HELP_STRING([--with-included-ltdl], [use the GNU ltdl sources included here])]) if test yes != "$with_included_ltdl"; then # We are not being forced to use the included libltdl sources, so # decide whether there is a useful installed version we can use. AC_CHECK_HEADER([ltdl.h], [AC_CHECK_DECL([lt_dlinterface_register], [AC_CHECK_LIB([ltdl], [lt_dladvise_preload], [with_included_ltdl=no], [with_included_ltdl=yes])], [with_included_ltdl=yes], [AC_INCLUDES_DEFAULT #include ])], [with_included_ltdl=yes], [AC_INCLUDES_DEFAULT] ) fi dnl If neither LT_CONFIG_LTDL_DIR, LTDL_CONVENIENCE nor LTDL_INSTALLABLE dnl was called yet, then for old times' sake, we assume libltdl is in an dnl eponymous directory: AC_PROVIDE_IFELSE([LT_CONFIG_LTDL_DIR], [], [_LT_CONFIG_LTDL_DIR([libltdl])]) AC_ARG_WITH([ltdl_include], [AS_HELP_STRING([--with-ltdl-include=DIR], [use the ltdl headers installed in DIR])]) if test -n "$with_ltdl_include"; then if test -f "$with_ltdl_include/ltdl.h"; then : else AC_MSG_ERROR([invalid ltdl include directory: '$with_ltdl_include']) fi else with_ltdl_include=no fi AC_ARG_WITH([ltdl_lib], [AS_HELP_STRING([--with-ltdl-lib=DIR], [use the libltdl.la installed in DIR])]) if test -n "$with_ltdl_lib"; then if test -f "$with_ltdl_lib/libltdl.la"; then : else AC_MSG_ERROR([invalid ltdl library directory: '$with_ltdl_lib']) fi else with_ltdl_lib=no fi case ,$with_included_ltdl,$with_ltdl_include,$with_ltdl_lib, in ,yes,no,no,) m4_case(m4_default(_LTDL_TYPE, [convenience]), [convenience], [_LTDL_CONVENIENCE], [installable], [_LTDL_INSTALLABLE], [m4_fatal([unknown libltdl build type: ]_LTDL_TYPE)]) ;; ,no,no,no,) # If the included ltdl is not to be used, then use the # preinstalled libltdl we found. AC_DEFINE([HAVE_LTDL], [1], [Define this if a modern libltdl is already installed]) LIBLTDL=-lltdl LTDLDEPS= LTDLINCL= ;; ,no*,no,*) AC_MSG_ERROR(['--with-ltdl-include' and '--with-ltdl-lib' options must be used together]) ;; *) with_included_ltdl=no LIBLTDL="-L$with_ltdl_lib -lltdl" LTDLDEPS= LTDLINCL=-I$with_ltdl_include ;; esac INCLTDL=$LTDLINCL # Report our decision... AC_MSG_CHECKING([where to find libltdl headers]) AC_MSG_RESULT([$LTDLINCL]) AC_MSG_CHECKING([where to find libltdl library]) AC_MSG_RESULT([$LIBLTDL]) _LTDL_SETUP dnl restore autoconf definition. m4_popdef([AC_LIBOBJ]) m4_popdef([AC_LIBSOURCES]) AC_CONFIG_COMMANDS_PRE([ _ltdl_libobjs= _ltdl_ltlibobjs= if test -n "$_LT_LIBOBJS"; then # Remove the extension. _lt_sed_drop_objext='s/\.o$//;s/\.obj$//' for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | sed "$_lt_sed_drop_objext" | sort -u`; do _ltdl_libobjs="$_ltdl_libobjs $lt_libobj_prefix$i.$ac_objext" _ltdl_ltlibobjs="$_ltdl_ltlibobjs $lt_libobj_prefix$i.lo" done fi AC_SUBST([ltdl_LIBOBJS], [$_ltdl_libobjs]) AC_SUBST([ltdl_LTLIBOBJS], [$_ltdl_ltlibobjs]) ]) # Only expand once: m4_define([LTDL_INIT]) ])# LTDL_INIT # Old names: AU_DEFUN([AC_LIB_LTDL], [LTDL_INIT($@)]) AU_DEFUN([AC_WITH_LTDL], [LTDL_INIT($@)]) AU_DEFUN([LT_WITH_LTDL], [LTDL_INIT($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIB_LTDL], []) dnl AC_DEFUN([AC_WITH_LTDL], []) dnl AC_DEFUN([LT_WITH_LTDL], []) # _LTDL_SETUP # ----------- # Perform all the checks necessary for compilation of the ltdl objects # -- including compiler checks and header checks. This is a public # interface mainly for the benefit of libltdl's own configure.ac, most # other users should call LTDL_INIT instead. AC_DEFUN([_LTDL_SETUP], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_SYS_MODULE_EXT])dnl AC_REQUIRE([LT_SYS_MODULE_PATH])dnl AC_REQUIRE([LT_SYS_DLSEARCH_PATH])dnl AC_REQUIRE([LT_LIB_DLLOAD])dnl AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl AC_REQUIRE([LT_FUNC_DLSYM_USCORE])dnl AC_REQUIRE([LT_SYS_DLOPEN_DEPLIBS])dnl AC_REQUIRE([LT_FUNC_ARGZ])dnl m4_require([_LT_CHECK_OBJDIR])dnl m4_require([_LT_HEADER_DLFCN])dnl m4_require([_LT_CHECK_DLPREOPEN])dnl m4_require([_LT_DECL_SED])dnl dnl Don't require this, or it will be expanded earlier than the code dnl that sets the variables it relies on: _LT_ENABLE_INSTALL dnl _LTDL_MODE specific code must be called at least once: _LTDL_MODE_DISPATCH # In order that ltdl.c can compile, find out the first AC_CONFIG_HEADERS # the user used. This is so that ltdl.h can pick up the parent projects # config.h file, The first file in AC_CONFIG_HEADERS must contain the # definitions required by ltdl.c. # FIXME: Remove use of undocumented AC_LIST_HEADERS (2.59 compatibility). AC_CONFIG_COMMANDS_PRE([dnl m4_pattern_allow([^LT_CONFIG_H$])dnl m4_ifset([AH_HEADER], [LT_CONFIG_H=AH_HEADER], [m4_ifset([AC_LIST_HEADERS], [LT_CONFIG_H=`echo "AC_LIST_HEADERS" | $SED 's|^[[ ]]*||;s|[[ :]].*$||'`], [])])]) AC_SUBST([LT_CONFIG_H]) AC_CHECK_HEADERS([unistd.h dl.h sys/dl.h dld.h mach-o/dyld.h dirent.h], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_FUNCS([closedir opendir readdir], [], [AC_LIBOBJ([lt__dirent])]) AC_CHECK_FUNCS([strlcat strlcpy], [], [AC_LIBOBJ([lt__strl])]) m4_pattern_allow([LT_LIBEXT])dnl AC_DEFINE_UNQUOTED([LT_LIBEXT],["$libext"],[The archive extension]) name= eval "lt_libprefix=\"$libname_spec\"" m4_pattern_allow([LT_LIBPREFIX])dnl AC_DEFINE_UNQUOTED([LT_LIBPREFIX],["$lt_libprefix"],[The archive prefix]) name=ltdl eval "LTDLOPEN=\"$libname_spec\"" AC_SUBST([LTDLOPEN]) ])# _LTDL_SETUP # _LT_ENABLE_INSTALL # ------------------ m4_define([_LT_ENABLE_INSTALL], [AC_ARG_ENABLE([ltdl-install], [AS_HELP_STRING([--enable-ltdl-install], [install libltdl])]) case ,$enable_ltdl_install,$enable_ltdl_convenience in *yes*) ;; *) enable_ltdl_convenience=yes ;; esac m4_ifdef([AM_CONDITIONAL], [AM_CONDITIONAL(INSTALL_LTDL, test no != "${enable_ltdl_install-no}") AM_CONDITIONAL(CONVENIENCE_LTDL, test no != "${enable_ltdl_convenience-no}")]) ])# _LT_ENABLE_INSTALL # LT_SYS_DLOPEN_DEPLIBS # --------------------- AC_DEFUN([LT_SYS_DLOPEN_DEPLIBS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_CACHE_CHECK([whether deplibs are loaded by dlopen], [lt_cv_sys_dlopen_deplibs], [# PORTME does your system automatically load deplibs for dlopen? # or its logical equivalent (e.g. shl_load for HP-UX < 11) # For now, we just catch OSes we know something about -- in the # future, we'll try test this programmatically. lt_cv_sys_dlopen_deplibs=unknown case $host_os in aix3*|aix4.1.*|aix4.2.*) # Unknown whether this is true for these versions of AIX, but # we want this 'case' here to explicitly catch those versions. lt_cv_sys_dlopen_deplibs=unknown ;; aix[[4-9]]*) lt_cv_sys_dlopen_deplibs=yes ;; amigaos*) case $host_cpu in powerpc) lt_cv_sys_dlopen_deplibs=no ;; esac ;; bitrig*) lt_cv_sys_dlopen_deplibs=yes ;; darwin*) # Assuming the user has installed a libdl from somewhere, this is true # If you are looking for one http://www.opendarwin.org/projects/dlcompat lt_cv_sys_dlopen_deplibs=yes ;; freebsd* | dragonfly*) lt_cv_sys_dlopen_deplibs=yes ;; gnu* | linux* | k*bsd*-gnu | kopensolaris*-gnu) # GNU and its variants, using gnu ld.so (Glibc) lt_cv_sys_dlopen_deplibs=yes ;; hpux10*|hpux11*) lt_cv_sys_dlopen_deplibs=yes ;; interix*) lt_cv_sys_dlopen_deplibs=yes ;; irix[[12345]]*|irix6.[[01]]*) # Catch all versions of IRIX before 6.2, and indicate that we don't # know how it worked for any of those versions. lt_cv_sys_dlopen_deplibs=unknown ;; irix*) # The case above catches anything before 6.2, and it's known that # at 6.2 and later dlopen does load deplibs. lt_cv_sys_dlopen_deplibs=yes ;; netbsd*) lt_cv_sys_dlopen_deplibs=yes ;; openbsd*) lt_cv_sys_dlopen_deplibs=yes ;; osf[[1234]]*) # dlopen did load deplibs (at least at 4.x), but until the 5.x series, # it did *not* use an RPATH in a shared library to find objects the # library depends on, so we explicitly say 'no'. lt_cv_sys_dlopen_deplibs=no ;; osf5.0|osf5.0a|osf5.1) # dlopen *does* load deplibs and with the right loader patch applied # it even uses RPATH in a shared library to search for shared objects # that the library depends on, but there's no easy way to know if that # patch is installed. Since this is the case, all we can really # say is unknown -- it depends on the patch being installed. If # it is, this changes to 'yes'. Without it, it would be 'no'. lt_cv_sys_dlopen_deplibs=unknown ;; osf*) # the two cases above should catch all versions of osf <= 5.1. Read # the comments above for what we know about them. # At > 5.1, deplibs are loaded *and* any RPATH in a shared library # is used to find them so we can finally say 'yes'. lt_cv_sys_dlopen_deplibs=yes ;; qnx*) lt_cv_sys_dlopen_deplibs=yes ;; solaris*) lt_cv_sys_dlopen_deplibs=yes ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) libltdl_cv_sys_dlopen_deplibs=yes ;; esac ]) if test yes != "$lt_cv_sys_dlopen_deplibs"; then AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1], [Define if the OS needs help to load dependent libraries for dlopen().]) fi ])# LT_SYS_DLOPEN_DEPLIBS # Old name: AU_ALIAS([AC_LTDL_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], []) # LT_SYS_MODULE_EXT # ----------------- AC_DEFUN([LT_SYS_MODULE_EXT], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl AC_CACHE_CHECK([what extension is used for runtime loadable modules], [libltdl_cv_shlibext], [ module=yes eval libltdl_cv_shlibext=$shrext_cmds module=no eval libltdl_cv_shrext=$shrext_cmds ]) if test -n "$libltdl_cv_shlibext"; then m4_pattern_allow([LT_MODULE_EXT])dnl AC_DEFINE_UNQUOTED([LT_MODULE_EXT], ["$libltdl_cv_shlibext"], [Define to the extension used for runtime loadable modules, say, ".so".]) fi if test "$libltdl_cv_shrext" != "$libltdl_cv_shlibext"; then m4_pattern_allow([LT_SHARED_EXT])dnl AC_DEFINE_UNQUOTED([LT_SHARED_EXT], ["$libltdl_cv_shrext"], [Define to the shared library suffix, say, ".dylib".]) fi if test -n "$shared_archive_member_spec"; then m4_pattern_allow([LT_SHARED_LIB_MEMBER])dnl AC_DEFINE_UNQUOTED([LT_SHARED_LIB_MEMBER], ["($shared_archive_member_spec.o)"], [Define to the shared archive member specification, say "(shr.o)".]) fi ])# LT_SYS_MODULE_EXT # Old name: AU_ALIAS([AC_LTDL_SHLIBEXT], [LT_SYS_MODULE_EXT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SHLIBEXT], []) # LT_SYS_MODULE_PATH # ------------------ AC_DEFUN([LT_SYS_MODULE_PATH], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl AC_CACHE_CHECK([what variable specifies run-time module search path], [lt_cv_module_path_var], [lt_cv_module_path_var=$shlibpath_var]) if test -n "$lt_cv_module_path_var"; then m4_pattern_allow([LT_MODULE_PATH_VAR])dnl AC_DEFINE_UNQUOTED([LT_MODULE_PATH_VAR], ["$lt_cv_module_path_var"], [Define to the name of the environment variable that determines the run-time module search path.]) fi ])# LT_SYS_MODULE_PATH # Old name: AU_ALIAS([AC_LTDL_SHLIBPATH], [LT_SYS_MODULE_PATH]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SHLIBPATH], []) # LT_SYS_DLSEARCH_PATH # -------------------- AC_DEFUN([LT_SYS_DLSEARCH_PATH], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl AC_CACHE_CHECK([for the default library search path], [lt_cv_sys_dlsearch_path], [lt_cv_sys_dlsearch_path=$sys_lib_dlsearch_path_spec]) if test -n "$lt_cv_sys_dlsearch_path"; then sys_dlsearch_path= for dir in $lt_cv_sys_dlsearch_path; do if test -z "$sys_dlsearch_path"; then sys_dlsearch_path=$dir else sys_dlsearch_path=$sys_dlsearch_path$PATH_SEPARATOR$dir fi done m4_pattern_allow([LT_DLSEARCH_PATH])dnl AC_DEFINE_UNQUOTED([LT_DLSEARCH_PATH], ["$sys_dlsearch_path"], [Define to the system default library search path.]) fi ])# LT_SYS_DLSEARCH_PATH # Old name: AU_ALIAS([AC_LTDL_SYSSEARCHPATH], [LT_SYS_DLSEARCH_PATH]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SYSSEARCHPATH], []) # _LT_CHECK_DLPREOPEN # ------------------- m4_defun([_LT_CHECK_DLPREOPEN], [m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen], [libltdl_cv_preloaded_symbols], [if test -n "$lt_cv_sys_global_symbol_pipe"; then libltdl_cv_preloaded_symbols=yes else libltdl_cv_preloaded_symbols=no fi ]) if test yes = "$libltdl_cv_preloaded_symbols"; then AC_DEFINE([HAVE_PRELOADED_SYMBOLS], [1], [Define if libtool can extract symbol lists from object files.]) fi ])# _LT_CHECK_DLPREOPEN # LT_LIB_DLLOAD # ------------- AC_DEFUN([LT_LIB_DLLOAD], [m4_pattern_allow([^LT_DLLOADERS$]) LT_DLLOADERS= AC_SUBST([LT_DLLOADERS]) AC_LANG_PUSH([C]) lt_dlload_save_LIBS=$LIBS LIBADD_DLOPEN= AC_SEARCH_LIBS([dlopen], [dl], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) if test "$ac_cv_search_dlopen" != "none required"; then LIBADD_DLOPEN=-ldl fi libltdl_cv_lib_dl_dlopen=yes LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#if HAVE_DLFCN_H # include #endif ]], [[dlopen(0, 0);]])], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) libltdl_cv_func_dlopen=yes LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], [AC_CHECK_LIB([svld], [dlopen], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) LIBADD_DLOPEN=-lsvld libltdl_cv_func_dlopen=yes LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"])])]) if test yes = "$libltdl_cv_func_dlopen" || test yes = "$libltdl_cv_lib_dl_dlopen" then lt_save_LIBS=$LIBS LIBS="$LIBS $LIBADD_DLOPEN" AC_CHECK_FUNCS([dlerror]) LIBS=$lt_save_LIBS fi AC_SUBST([LIBADD_DLOPEN]) LIBADD_SHL_LOAD= AC_CHECK_FUNC([shl_load], [AC_DEFINE([HAVE_SHL_LOAD], [1], [Define if you have the shl_load function.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"], [AC_CHECK_LIB([dld], [shl_load], [AC_DEFINE([HAVE_SHL_LOAD], [1], [Define if you have the shl_load function.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" LIBADD_SHL_LOAD=-ldld])]) AC_SUBST([LIBADD_SHL_LOAD]) case $host_os in darwin[[1567]].*) # We only want this for pre-Mac OS X 10.4. AC_CHECK_FUNC([_dyld_func_lookup], [AC_DEFINE([HAVE_DYLD], [1], [Define if you have the _dyld_func_lookup function.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la"]) ;; beos*) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la" ;; cygwin* | mingw* | pw32*) AC_CHECK_DECLS([cygwin_conv_path], [], [], [[#include ]]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la" ;; esac AC_CHECK_LIB([dld], [dld_link], [AC_DEFINE([HAVE_DLD], [1], [Define if you have the GNU dld library.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la"]) AC_SUBST([LIBADD_DLD_LINK]) m4_pattern_allow([^LT_DLPREOPEN$]) LT_DLPREOPEN= if test -n "$LT_DLLOADERS" then for lt_loader in $LT_DLLOADERS; do LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader " done AC_DEFINE([HAVE_LIBDLLOADER], [1], [Define if libdlloader will be built on this platform]) fi AC_SUBST([LT_DLPREOPEN]) dnl This isn't used anymore, but set it for backwards compatibility LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD" AC_SUBST([LIBADD_DL]) LIBS=$lt_dlload_save_LIBS AC_LANG_POP ])# LT_LIB_DLLOAD # Old name: AU_ALIAS([AC_LTDL_DLLIB], [LT_LIB_DLLOAD]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_DLLIB], []) # LT_SYS_SYMBOL_USCORE # -------------------- # does the compiler prefix global symbols with an underscore? AC_DEFUN([LT_SYS_SYMBOL_USCORE], [m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl AC_CACHE_CHECK([for _ prefix in compiled symbols], [lt_cv_sys_symbol_underscore], [lt_cv_sys_symbol_underscore=no cat > conftest.$ac_ext <<_LT_EOF void nm_test_func(){} int main(){nm_test_func;return 0;} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. ac_nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then # See whether the symbols have a leading underscore. if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then lt_cv_sys_symbol_underscore=yes else if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then : else echo "configure: cannot find nm_test_func in $ac_nlist" >&AS_MESSAGE_LOG_FD fi fi else echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.c >&AS_MESSAGE_LOG_FD fi rm -rf conftest* ]) sys_symbol_underscore=$lt_cv_sys_symbol_underscore AC_SUBST([sys_symbol_underscore]) ])# LT_SYS_SYMBOL_USCORE # Old name: AU_ALIAS([AC_LTDL_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SYMBOL_USCORE], []) # LT_FUNC_DLSYM_USCORE # -------------------- AC_DEFUN([LT_FUNC_DLSYM_USCORE], [AC_REQUIRE([_LT_COMPILER_PIC])dnl for lt_prog_compiler_wl AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl for lt_cv_sys_symbol_underscore AC_REQUIRE([LT_SYS_MODULE_EXT])dnl for libltdl_cv_shlibext if test yes = "$lt_cv_sys_symbol_underscore"; then if test yes = "$libltdl_cv_func_dlopen" || test yes = "$libltdl_cv_lib_dl_dlopen"; then AC_CACHE_CHECK([whether we have to add an underscore for dlsym], [libltdl_cv_need_uscore], [libltdl_cv_need_uscore=unknown dlsym_uscore_save_LIBS=$LIBS LIBS="$LIBS $LIBADD_DLOPEN" libname=conftmod # stay within 8.3 filename limits! cat >$libname.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; }] _LT_EOF # ltfn_module_cmds module_cmds # Execute tilde-delimited MODULE_CMDS with environment primed for # $module_cmds or $archive_cmds type content. ltfn_module_cmds () {( # subshell avoids polluting parent global environment module_cmds_save_ifs=$IFS; IFS='~' for cmd in @S|@1; do IFS=$module_cmds_save_ifs libobjs=$libname.$ac_objext; lib=$libname$libltdl_cv_shlibext rpath=/not-exists; soname=$libname$libltdl_cv_shlibext; output_objdir=. major=; versuffix=; verstring=; deplibs= ECHO=echo; wl=$lt_prog_compiler_wl; allow_undefined_flag= eval $cmd done IFS=$module_cmds_save_ifs )} # Compile a loadable module using libtool macro expansion results. $CC $pic_flag -c $libname.$ac_ext ltfn_module_cmds "${module_cmds:-$archive_cmds}" # Try to fetch fnord with dlsym(). libltdl_dlunknown=0; libltdl_dlnouscore=1; libltdl_dluscore=2 cat >conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifndef RTLD_GLOBAL # ifdef DL_GLOBAL # define RTLD_GLOBAL DL_GLOBAL # else # define RTLD_GLOBAL 0 # endif #endif #ifndef RTLD_NOW # ifdef DL_NOW # define RTLD_NOW DL_NOW # else # define RTLD_NOW 0 # endif #endif int main () { void *handle = dlopen ("`pwd`/$libname$libltdl_cv_shlibext", RTLD_GLOBAL|RTLD_NOW); int status = $libltdl_dlunknown; if (handle) { if (dlsym (handle, "fnord")) status = $libltdl_dlnouscore; else { if (dlsym (handle, "_fnord")) status = $libltdl_dluscore; else puts (dlerror ()); } dlclose (handle); } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null libltdl_status=$? case x$libltdl_status in x$libltdl_dlnouscore) libltdl_cv_need_uscore=no ;; x$libltdl_dluscore) libltdl_cv_need_uscore=yes ;; x*) libltdl_cv_need_uscore=unknown ;; esac fi rm -rf conftest* $libname* LIBS=$dlsym_uscore_save_LIBS ]) fi fi if test yes = "$libltdl_cv_need_uscore"; then AC_DEFINE([NEED_USCORE], [1], [Define if dlsym() requires a leading underscore in symbol names.]) fi ])# LT_FUNC_DLSYM_USCORE # Old name: AU_ALIAS([AC_LTDL_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], []) unixODBC-2.3.12/m4/ltoptions.m4000066400000000000000000000342621446441710500160440ustar00rootroot00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) unixODBC-2.3.12/m4/ltsugar.m4000066400000000000000000000104401446441710500154620ustar00rootroot00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) unixODBC-2.3.12/m4/ltversion.m4000066400000000000000000000012731446441710500160320ustar00rootroot00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4179 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.6]) m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.6' macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) unixODBC-2.3.12/m4/lt~obsolete.m4000066400000000000000000000137741446441710500163700ustar00rootroot00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software # Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) unixODBC-2.3.12/man/000077500000000000000000000000001446441710500137735ustar00rootroot00000000000000unixODBC-2.3.12/man/Makefile.am000066400000000000000000000001521446441710500160250ustar00rootroot00000000000000dist_man_MANS = isql.1 odbc.ini.5 odbcinst.1 odbcinst.ini.5 unixODBC.7 dltest.1 iusql.1 odbc_config.1 unixODBC-2.3.12/man/dltest.1000066400000000000000000000016401446441710500153550ustar00rootroot00000000000000.TH dltest 1 "Thu 07 Jan 2021" "version 2.3.12" "unixODBC manual pages" .SH NAME dltest - A simple library symbol test program .SH SYNOPSIS .B dltest [ .I library symbol ] .SH DESCRIPTION \fBdltest\fR is a simple program that determines whether a \fIsymbol\fR appears in a (shared object) \fIlibrary\fR. The name of the \fIlibrary\fR must be prefixed by a full system path. If no parameters are provided, \fBdltest\fR prints a short help message. .SH EXAMPLES To determine if the symbol \fBprintf\fR is found in \fIlibc-2\.18\.so\fR, run: .RS $ dltest /usr/lib/libc-2.18.so printf .RE .SH AUTHORS The authors of unixODBC are Peter Harvey <\fIpharvey@codebydesign.com\fR> and Nick Gorham <\fInick@lurcher.org\fR>. For a full list of contributors, refer to the \fIAUTHORS\fR file. .SH COPYRIGHT unixODBC is licensed under the GNU Lesser General Public License. For details about the license, see the \fICOPYING\fR file. unixODBC-2.3.12/man/isql.1000066400000000000000000000151521446441710500150310ustar00rootroot00000000000000.TH isql 1 "Thu 14 Jan 2021" "version 2.3.12" "unixODBC manual pages" .SH NAME isql, iusql - unixODBC interactive SQL command-line tools .SH SYNOPSIS \fBisql\fR \fIDSN\fR [\fIUSER\fR [\fIPASSWORD\fR]] [\fIoptions\fR] \fBiusql\fR \fIDSN\fR [\fIUSER\fR [\fIPASSWORD\fR]] [\fIoptions\fR] \fBiusql\fR \fI"ConnectionString"\fR [\fIoptions\fR] .SH DESCRIPTION \fBisql\fR and \fBiusql\fR are command-line tools allowing users to execute SQL interactively or in batches. The tools provide several useful features, including an option to generate output wrapped in an HTML table. \fBiusql\fR is the same as \fBisql\fR but includes built-in Unicode support. Some data sources only work with \fBiusql\fR. An important difference between the two tools is that \fBisql\fR connects using SQLConnect and \fBiusql\fR connects using SQLDriverConnect. .SH ARGUMENTS .IP \fBDSN\fR The Data Source Name (DSN) used to connect to the SQL database. unixODBC looks for the specified DSN in /etc/odbc.ini and $HOME/.odbc.ini, with the latter taking precedence. When searching the configuration files, unixODBC looks for a bare name. If the DSN begins with a semicolon, it is treated as a connection string. The connection string can contain a DSN and/or other semicolon-separated parameters. .IP \fBUSER\fR Specifies the database user or role under which the connection should be made. This parameter overrides any \fBUID\fR specified in the data source configuration files. .IP \fBPASSWORD\fR Password required to access the database for the specified \fBUSER\fR. This parameter overrides any \fBPASSWORD\fR specified in the data source configuration files. When using \fBiusql\fR, passwords containing semicolons should be escaped with braces (curly brackets) and terminated with a semicolon. Refer to the Examples section below for syntax. .IP \fB"ConnectionString"\fR A connection string starting with DSN=, DRIVER= or FILEDSN= will be passed unchanged to SQLDriverConnect. This option allows for the use of more complex syntax in a connection string than would otherwise be possible by just using DSN, UID and PWD. It also (and this was the main reason for its inclusion) allows passwords to contain semicolons without having to add complex escape syntax to the existing code. .SH OPTIONS .IP \fB\-b\fR Run 'isql' in non-interactive batch mode. In this mode, 'isql' processes from standard input, expecting one SQL command per line. .IP \fB\-d\fIDELIMITER\fR Delimit columns with the specified \fIdelimiter\fR. .IP \fB\-x\fIHEX\fR Delimit columns with the character represented in hexadecimal by \fIHEX\fR. The hexadecimal code must be in the format 0xNN (e.g. 0x09 for the TAB character). .IP \fB\-w\fR Format the result as an HTML table. .IP \fB\-c\fR Output the names of the columns on the first row. This option can only be used with the \fB\-d\fR or \fB\-x\fR options. .IP \fB\-m\fINUM\fR Limit the column display width to \fINUM\fR characters. .IP \fB\-l\fILOCALE\fR Set the character locale to \fILOCALE\fR. .IP \fB\-q\fR Wrap the character fields in double quotes. .IP \fB\-3\fR Use calls from ODBC version 3. .IP \fB\-n\fR Process multiple lines of SQL, terminated with the GO command. .IP \fB\-e\fR Use SQLExecDirect instead of Prepare. .IP \fB\-k\fR Use SQLDriverConnect. .IP \fB\-v\fR Enable verbose mode, fully describing all errors. This option is useful for debugging. .IP \fB\-\-version\fR Display the program version. .IP \fB\-L\fINUM\fR Set the maximum number of characters displayed from a character field to \fINUM\fR. The default value is 300 characters. .SH COMMANDS This section briefly describes some \fBisql\fR and \fBiusql\fR run-time commands. .B help .RS List all tables in the database. .RE .B help \fItable\fR .RS List all columns in the \fItable\fR. .RE .B help help .RS List all help options. .RE .SH EXAMPLES .IP "A bare DSN:" .nf $ iusql WebDB MyID MyPWD \-w \-b < My.sql .fi Connects to the WebDB DSN as user MyID with password MyPWD, then executes the commands in the My.sql file and returns the results wrapped in an HTML table. Each line in My.sql must only contain one SQL command, except for the last line, which must be blank (unless the \fB\-n\fR option is specified). .IP "A DSN in a connection string:" Note the leading semicolon on the connection string. .nf $ iusql ";DSN=WebDB" MyID MyPWD \-w \-b < My.sql .fi Options in the DSN may be overridden in the connection string: .nf $ iusql ";DSN=WebDB;Driver=PostgreSQL ODBC;UID=MyID;PASSWORD=secret;Debug=1;CommLog=1" \-v .fi .IP "A string DSN:" A string DSN may be provided in its entirety, with no file DSN reference at all: .nf $ iusql ";Driver=PostgreSQL Unicode;UID=MyID;PASSWORD=secret" \-v .fi .IP "A password containing a semicolon (\fBiusql\fR):" .nf $ iusql WebDB MyID '{My;PWD};' .fi .nf $ iusql 'DSN=WebDB;UID=MyID;PWD={My;PWD};' .fi .SH TROUBLESHOOTING .IP "Cryptic error messages" Re-run \fBisql\fR or \fBiusql\fR with the \fB\-v\fR flag to get more information from errors, and/or enable \fBTrace\fR mode in \fBodbcinst.ini\fR. .IP "Missing driver definition" Check that the driver name specified by the \fBDriver\fR entry in the \fBodbc.ini\fR data-source definition is present in \fBodbcinst.ini\fR and exactly matches the odbcinst.ini \fI[section name]\fR. .IP "Unloadable or incompatible driver" If the ODBC driver is properly specified for the data source, it is possible that the driver is not loadable. Check for mix-ups between Unicode and ANSI drivers, and verify the driver paths in the odbcinst.ini \fI[section name]\fR. .IP "Unicode data sources with ANSI clients" Some data sources are Unicode-only and require the use of \fBiusql\fR. If \fBisql\fR reports .nf [IM002][unixODBC][Driver Manager]Data source name not found and no default driver specified [ISQL]ERROR: Could not SQLConnect .fi but the data source and driver required are listed by .nf odbcinst \-q \-d .fi and .nf odbcinst \-q \-s .fi then try \fBiusql\fR. .SH FILES .I /etc/odbc.ini .RS Configuration file containing system-wide Data Source Name (DSN) definitions. See .BR odbc.ini (5) for more information. .RE .I $HOME/.odbc.ini .RS Configuration file containing user-specific Data Source Name (DSN) definitions. See .BR odbc.ini (5) for more information. .RE .SH SEE ALSO .BR unixODBC (7), .BR odbcinst (1), .BR odbc.ini (5) "The \fIunixODBC\fB Administrator Manual (HTML)\fR" .SH AUTHORS The authors of unixODBC are Peter Harvey <\fIpharvey@codebydesign.com\fR> and Nick Gorham <\fInick@lurcher.org\fR>. For a full list of contributors, refer to the \fIAUTHORS\fR file. .SH COPYRIGHT unixODBC is licensed under the GNU Lesser General Public License. For details about the license, see the \fICOPYING\fR file. unixODBC-2.3.12/man/iusql.1000066400000000000000000000000201446441710500152020ustar00rootroot00000000000000.so man1/isql.1 unixODBC-2.3.12/man/odbc.ini.5000066400000000000000000000053701446441710500155530ustar00rootroot00000000000000.TH odbc.ini 5 "Sun 10 Jan 2021" "version 2.3.12" "unixODBC manual pages" .SH NAME /etc/odbc.ini, $HOME/.odbc.ini - unixODBC data source configuration files .SH DESCRIPTION .B /etc/odbc.ini is a system-wide configuration file for ODBC Data Source Names (DSNs). .B $HOME/.odbc.ini is a user-specific configuration file for ODBC Data Source Names (DSNs). Paths to both configuration files can be overridden by \fIunixODBC\fR build options. Call \fBodbcinst \-j\fR to determine the default configuration file paths on your system. .SH NOTES .SS "Templates" Many ODBC drivers come with .ini file templates. Using \fBodbcinst\fR to install these templates is recommended. .SS "FILE FORMAT" \fBodbc.ini\fR follows the pesudo-standard \fIini file\fR syntax convention of one or more \fB[section headings]\fR, each followed by zero or more \fBkey = value\fR attributes. .IP "\fB[ODBC Data Sources]\fR section" 4 This mandatory section lists each data source name (\fIDSN\fR) as a key. The associated values serve as comments. Each entry must be matched by an ini file \fB[section]\fR describing the data source. .IP "Data Source Name \fB[section]\fR" 4 Each data source is identified by a \fB[section header]\fR, which is the DSN name used by applications. Each DSN definition section may contain values for the keys: .RS 4 .IP "\(bu Driver (\fBREQUIRED\fR)" 8 The name of the ODBC driver to use for the DSN. The name must exactly match the \fB[section name]\fR of the driver definition stored in \fBodbcinst.ini\fR (and listed by \fBodbcinst \-q \-d\fR). .IP "\(bu Description" 8 Human-readable data source description. .IP "\(bu Database" 8 Database name or identifier. The meaning is driver-specific and can specify a file path, Unix socket path, an identifier relative to a server name, etc. .IP "\(bu Servername" 8 Server name. The meaning is driver-specific but generally specifies a DNS name, IP network address or driver-specific discovery identifier. .RE For a full list of supported parameters, refer to the HTML-formatted "Administrator Manual" shipped with \fIunixODBC\fR, the documentation for your ODBC driver and any data-source templates supplied by your driver. .SH EXAMPLES An example \fBodbc.ini\fR configuration file is shown in the "Administrator Manual" shipped with \fIunixODBC\fR. .SH "SEE ALSO" .BR unixODBC (7), .BR odbcinst (1), .BR isql (1), .BR iusql (1), .BR odbcinst.ini (5) "The \fIunixODBC\fB Administrator Manual (HTML)\fR" .SH AUTHORS The authors of unixODBC are Peter Harvey <\fIpharvey@codebydesign.com\fR> and Nick Gorham <\fInick@lurcher.org\fR>. For a full list of contributors, refer to the \fIAUTHORS\fR file. .SH COPYRIGHT unixODBC is licensed under the GNU Lesser General Public License. For details about the license, see the \fICOPYING\fR file. unixODBC-2.3.12/man/odbc_config.1000066400000000000000000000045611446441710500163170ustar00rootroot00000000000000.TH odbc_config 1 "Thu 07 Jan 2021" "version 2.3.12" "unixODBC manual pages" .SH NAME odbc_config - Generates compiler information intended for use when developing a unixODBC client .SH SYNOPSIS .SY odbc_config .OP \-\-prefix .OP \-\-exec-prefix .OP \-\-include-prefix .OP \-\-lib-prefix .OP \-\-bin-prefix .OP \-\-version .OP \-\-libs .OP \-\-static-libs .OP \-\-libtool-libs .OP \-\-cflags .OP \-\-odbcversion .OP \-\-odbcini .OP \-\-odbcinstini .OP \-\-header .OP \-\-ulen .YS .SH DESCRIPTION \fBodbc_config\fR provides information about how unixODBC was compiled for your system and architecture. The information generated is useful for building unixODBC clients and similar programs. .SH OPTIONS .B .IP \-\-prefix Prefix for architecture-independent files. .B .IP \-\-exec-prefix Prefix for architecture-dependent files. .B .IP \-\-include-prefix Directory containing C header files for unixODBC. .B .IP \-\-lib-prefix Directory containing unixODBC shared libraries. .B .IP \-\-bin-prefix Directory containing unixODBC utilities. .B .IP \-\-version Current version of unixODBC. .B .IP \-\-libs Compiler flags for linking dynamic libraries. .B .IP \-\-static-libs Absolute file name of the unixODBC static library (libodbc.a). .B .IP \-\-libtool-libs Absolute file name of the unixODBC libtool library (libodbc.la). .B .IP \-\-cflags Outputs compiler flags to find header files, as well as critical compiler flags and defines used when compiling the libodbc library. .B .IP \-\-odbcversion Version of the ODBC specification used by unixODBC. .B .IP \-\-odbcini Absolute file name of the system-wide DSN configuration file \fIodbc.ini\fR. .B .IP \-\-odbcinstini Absolute file name of the unixODBC driver configuration file \fIodbcinst.ini\fR. .B .IP \-\-header Definitions of C preprocessor constants used by unixODBC. Generated output can be piped into a C header file. .B .IP \-\-ulen Compiler flag that defines \fISIZEOF_SQLULEN\fR. .SH SEE ALSO .BR unixODBC (7), .BR odbcinst.ini (5), .BR odbc.ini (5) "The \fIunixODBC\fB Administrator Manual (HTML)\fR" .SH AUTHORS The authors of unixODBC are Peter Harvey <\fIpharvey@codebydesign.com\fR> and Nick Gorham <\fInick@lurcher.org\fR>. For a full list of contributors, refer to the \fIAUTHORS\fR file. .SH COPYRIGHT unixODBC is licensed under the GNU Lesser General Public License. For details about the license, see the \fICOPYING\fR file. unixODBC-2.3.12/man/odbcinst.1000066400000000000000000000053751446441710500156740ustar00rootroot00000000000000.TH odbcinst 1 "Sat 09 Jan 2021" "version 2.3.12" "unixODBC manual pages" .SH NAME odbcinst - A unixODBC utility for managing configuration files .SH SYNOPSIS .B odbcinst .I ACTION OBJECT OPTIONS .SH DESCRIPTION \fBodbcinst\fR is a command-line utility allowing users who develop install scripts or packages for ODBC drivers to easily create or remove entries in odbc.ini and odbcinst.ini. The utility is part of the odbcinst component of unixODBC and complements the shared library of the same name (libodbcinst). .SH OPTIONS .SS ACTIONS .IP \-i Install a new \fIOBJECT\fR (by adding a section to a configuration file). .IP \-u Uninstall an existing \fIOBJECT\fR (by removing a section from a configuration file). .IP \-q Query ODBC configuration files and print available options for the specified \fIOBJECT\fR. .IP \-j Print the current configuration of unixODBC, including paths to configuration files. .IP \-c Call SQLCreateDataSource. .IP \-m Call SQLManageDataSources. .IP \-\-version Display the program version. .SS OBJECTS .IP \-d The specified \fIACTION\fR affects a driver (and thus the odbcinst.ini configuration file). .IP \-s The specified \fIACTION\fR affects a data source (and thus the user or system odbc.ini configuration file). .SS OPTIONS .IP "\-f \fIFILE\fR" \fIFILE\fR is a template describing the configuration of the installed \fIOBJECT\fR (only valid with the -i \fIACTION\fR). .IP \-r Act in the same way as for the \-f \fIOPTION\fR, but take standard input as the template file. .IP "\-n \fINAME\fR" Specifies the \fINAME\fR of the \fIOBJECT\fR. .IP \-v Disable all information, warning and error messages. .IP \-l The specified data source is system-wide. This option is only valid when used with the \-s \fIOBJECT\fR. .IP \-h The specified data source is user-specific. This option is only valid when used with the \-s \fIOBJECT\fR. .SH "RETURN VALUES" odbcinst returns zero on success and a non-zero value on failure. .SH FILES .I /etc/odbcinst.ini .RS Configuration file containing all database driver definitions. See .BR odbcinst.ini (5) for more information. .RE .I /etc/odbc.ini .RS Configuration file containing system-wide Data Source Name (DSN) definitions. See .BR odbc.ini (5) for more information. .RE .I $HOME/.odbc.ini .RS Configuration file containing user-specific Data Source Name (DSN) definitions. See .BR odbc.ini (5) for more information. .RE .SH "SEE ALSO" .BR odbcinst.ini (5), .BR odbc.ini (5) .SH AUTHORS The authors of unixODBC are Peter Harvey <\fIpharvey@codebydesign.com\fR> and Nick Gorham <\fInick@lurcher.org\fR>. For a full list of contributors, refer to the \fIAUTHORS\fR file. .SH COPYRIGHT unixODBC is licensed under the GNU Lesser General Public License. For details about the license, see the \fICOPYING\fR file. unixODBC-2.3.12/man/odbcinst.ini.5000066400000000000000000000065301446441710500164500ustar00rootroot00000000000000.TH odbcinst.ini 5 "Tue 12 Jan 2021" "version 2.3.12" "unixODBC manual pages" .SH NAME /etc/odbcinst.ini - unixODBC driver configuration file .SH DESCRIPTION \fB/etc/odbcinst.ini\fR is a configuration file for unixODBC drivers. The file can be updated by using the \fB odbcinst\fR utility (recommended) or edited by hand. .SH FILE FORMAT The general .ini file format is: .RS .nf .BI [ SectionName1 ] .IB key1 " = " value1 .IB key2 " = " value2 .B ... .BI [ SectionName2 ] .IB key1 " = " value1 .IB key2 " = " value2 .B ... .fi .RE Each ODBC driver has its own section and can be referred to by the name of that section in files such as odbc.ini. Within each section, unixODBC also recognises the following configuration keys: .IP \fBDescription A text string briefly describing the driver. .IP \fBDriver A filesystem path to the actual driver library. .IP \fBSetup A filesystem path to the driver setup library. .IP \fBFileUsage The section named \fB[ODBC]\fR configures global options. Keys recognised in the \fB[ODBC]\fR section include: .RS .IP \fBTrace Enable ODBC driver trace output, which is written to the file path specified by \fBTraceFile\fR. Some ODBC drivers have their own trace control options. Unlike the \fBTrace\fR option, these separate options are usually specified at the Data Source Name (DSN) level. \fBTrace\fR will be enabled if the corresponding value contains any case variant of "1", "y", "yes" or "on". .IP \fBTraceFile Specifies the system path or path-pattern to which ODBC driver trace output will be written. This option has no effect unless \fBTrace\fR is enabled. The default file location for trace output is \fB/tmp/sql.log\fR. \fIWARNING\fR: Setting \fBTraceFile\fR to a path writable by multiple users might not work correctly, as only the first user will be able to create and open the file. .RE .SH TEMPLATE FILES Many ODBC drivers come with .ini file templates, which can be installed by using the \fBodbcinst\fR utility. Template files use the same format as odbcinst.ini. .SH EXAMPLES To install the unixODBC PostgreSQL driver, the following configuration can be entered into odbcinst.ini: .RS .nf [PostgreSQL] Description = PostgreSQL driver for GNU/Linux Driver = /usr/lib/psqlodbcw.so Setup = /usr/lib/libodbcpsqlS.so FileUsage = 1 .fi .RE Driver paths can vary, depending on your operating system and whether your distribution is multi-arch enabled. Some drivers also require \fBDriver64\fR and \fBSetup64\fR entries. The above section can be referenced in \fBodbc.ini\fR as follows: .RS .nf Driver = PostgreSQL .fi .RE The recommended way of adding the PostgreSQL driver to your system is by creating a template file containing: .RS .nf [PostgreSQL] Description = PostgreSQL driver for GNU/Linux Driver = /usr/lib/psqlodbcw.so Setup = /usr/lib/libodbcpsqlS.so .fi .RE and calling \fBodbcinst\fR as follows: .RS .BI "# odbcinst \-i \-d \-f " template.ini .RE .SH "SEE ALSO" .BR unixODBC (7), .BR odbcinst (1), .BR odbc.ini (5) "The \fIunixODBC\fB Administrator Manual (HTML)\fR" .SH AUTHORS The authors of unixODBC are Peter Harvey <\fIpharvey@codebydesign.com\fR> and Nick Gorham <\fInick@lurcher.org\fR>. For a full list of contributors, refer to the \fIAUTHORS\fR file. .SH COPYRIGHT unixODBC is licensed under the GNU Lesser General Public License. For details about the license, see the \fICOPYING\fR file. unixODBC-2.3.12/man/unixODBC.7000066400000000000000000000037561446441710500155110ustar00rootroot00000000000000.TH unixODBC 7 "Thu 07 Jan 2021" "version 2.3.12" "unixODBC manual pages" .SH NAME unixODBC - An ODBC implementation for Unix .SH DESCRIPTION ODBC is an open specification providing application developers with a predictable API with which to access data sources. Data sources include SQL servers and any data source with an ODBC driver. The unixODBC project goals are to develop and promote unixODBC as the definitive standard for ODBC on non-Windows platforms. The HTML-formatted "Administrator Manual" shipped with unixODBC provides additional details on configuration and usage to supplement these man pages. .SH ENVIRONMENT VARIABLES .IP \fBODBCSYSINI Sets the full path to the directory containing the unixODBC configuration files. By default, this is '/etc'. .IP \fBODBCINSTINI Sets the name of the unixODBC driver configuration file. The file name is relative to \fBODBCSYSINI\fR and is set by default to 'odbcinst.ini'. .IP \fBODBCINI Sets the full path to the system-wide unixODBC configuration file containing Data Source Names (DSNs). By default, this is set to '/etc/odbc.ini'. .IP \fBODBCINSTUI Sets the library name for the UI. The final name that is searched for is evaluated as "lib$ODBCINSTUI". By default, this variable is set to 'odbcinstQ4', so the resulting library name is 'libodbcinstQ4'. .IP \fBODBCSEARCH Sets the configuration mode and determines where to look for configuration files. This variable must be set to one of ODBC_SYSTEM_DSN, ODBC_USER_DSN or ODBC_BOTH_DSN, which is the default value. .SH SEE ALSO .BR isql (1), .BR odbc_config (1), .BR odbcinst (1), .BR odbc.ini (5), .BR odbcinst.ini (5) "The \fIunixODBC\fB Administrator Manual (HTML)\fR" .SH AUTHORS The authors of unixODBC are Peter Harvey <\fIpharvey@codebydesign.com\fR> and Nick Gorham <\fInick@lurcher.org\fR>. For a full list of contributors, refer to the \fIAUTHORS\fR file. .SH COPYRIGHT unixODBC is licensed under the GNU Lesser General Public License. For details about the license, see the \fICOPYING\fR file. unixODBC-2.3.12/odbcinst/000077500000000000000000000000001446441710500150255ustar00rootroot00000000000000unixODBC-2.3.12/odbcinst/Makefile.am000066400000000000000000000050601446441710500170620ustar00rootroot00000000000000lib_LTLIBRARIES = libodbcinst.la AM_CPPFLAGS = -I@top_srcdir@/include \ $(LTDLINCL) EXTRA_DIST = \ odbcinst.exp libodbcinst_la_LDFLAGS = \ -no-undefined \ -version-info @LIB_VERSION@ \ -export-dynamic \ -export-symbols @srcdir@/odbcinst.exp libodbcinst_la_LIBADD = \ ../ini/libinilc.la \ ../log/libloglc.la \ ../lst/liblstlc.la \ $(LIBLTDL) libodbcinst_la_DEPENDENCIES = \ ../log/libloglc.la \ ../ini/libinilc.la \ ../lst/liblstlc.la \ $(LTDLDEPS) sysconf_DATA= libodbcinst_la_SOURCES = \ ODBCINSTConstructProperties.c \ ODBCINSTDestructProperties.c \ ODBCINSTSetProperty.c \ ODBCINSTValidateProperties.c \ ODBCINSTValidateProperty.c \ SQLConfigDataSource.c \ SQLConfigDriver.c \ SQLCreateDataSource.c \ SQLGetAvailableDrivers.c \ SQLGetConfigMode.c \ SQLGetInstalledDrivers.c \ SQLGetPrivateProfileString.c \ SQLGetTranslator.c \ SQLInstallDriverEx.c \ SQLInstallDriverManager.c \ SQLInstallTranslatorEx.c \ SQLInstallerError.c \ SQLManageDataSources.c \ SQLPostInstallerError.c \ SQLReadFileDSN.c \ SQLRemoveDSNFromIni.c \ SQLRemoveDriver.c \ SQLRemoveDriverManager.c \ SQLRemoveTranslator.c \ SQLSetConfigMode.c \ SQLValidDSN.c \ SQLWriteDSNToIni.c \ SQLWriteFileDSN.c \ SQLWritePrivateProfileString.c \ SQLInstallODBC.c \ _logging.c \ _odbcinst_ConfigModeINI.c \ _odbcinst_UserINI.c \ _odbcinst_SystemINI.c \ _odbcinst_GetSections.c \ _odbcinst_GetEntries.c \ _SQLGetInstalledDrivers.c \ _SQLWriteInstalledDrivers.c \ _SQLDriverConnectPrompt.c libodbcinstlc_la_LDFLAGS = noinst_LTLIBRARIES = libodbcinstlc.la libodbcinstlc_la_SOURCES = \ ODBCINSTConstructProperties.c \ ODBCINSTDestructProperties.c \ ODBCINSTSetProperty.c \ ODBCINSTValidateProperties.c \ ODBCINSTValidateProperty.c \ SQLConfigDataSource.c \ SQLConfigDriver.c \ SQLCreateDataSource.c \ SQLGetAvailableDrivers.c \ SQLGetConfigMode.c \ SQLGetInstalledDrivers.c \ SQLGetPrivateProfileString.c \ SQLGetTranslator.c \ SQLInstallDriverEx.c \ SQLInstallDriverManager.c \ SQLInstallTranslatorEx.c \ SQLInstallerError.c \ SQLManageDataSources.c \ SQLPostInstallerError.c \ SQLReadFileDSN.c \ SQLRemoveDSNFromIni.c \ SQLRemoveDriver.c \ SQLRemoveDriverManager.c \ SQLRemoveTranslator.c \ SQLSetConfigMode.c \ SQLValidDSN.c \ SQLWriteDSNToIni.c \ SQLWriteFileDSN.c \ SQLWritePrivateProfileString.c \ _logging.c \ _odbcinst_ConfigModeINI.c \ _odbcinst_UserINI.c \ _odbcinst_SystemINI.c \ _odbcinst_GetSections.c \ _odbcinst_GetEntries.c \ _SQLGetInstalledDrivers.c \ _SQLWriteInstalledDrivers.c \ _SQLDriverConnectPrompt.c unixODBC-2.3.12/odbcinst/ODBCINSTConstructProperties.c000066400000000000000000000227511446441710500223670ustar00rootroot00000000000000/************************************************** * ODBCINSTConstructProperties * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #ifdef UNIXODBC_SOURCE #include #endif #include /* static const char *aYesNo[] = { "Yes", "No", NULL }; */ /*! * \brief Builds a property list for pszDriver. * * Adds common DSN properties (Name,Driver,Description) and then asks the * drivers setup to load any additional properties. * * This is used to support editing DSN properties without forcing the driver * developer to create a UI for the many different UI implementations. The * driver developer can just implement ODBCINSTGetProperties. This function * can then call ODBCINSTGetProperties to get properties. The code that calls * this function can then display the properties in the UI in use. * * \param pszDriver Friendly driver name. * \param hFirstProperty Place to store the properties list. The properties (including * some of the elements within each HODBCINSTPROPERTY may * need to be freed using \sa ODBCINSTDestructProperties. * * \return int * \retval ODBCINST_ERROR Called failed. No memory was allocated at hFirstProperty. The * likely reasons for this; \li failed to lookup setup library name * \li failed to load setup library \li failed to find * ODBCINSTGetProperties symbol in setup library * \retval ODBCINST_SUCCESS Success! Do not forget to call ODBCINSTDestructProperties to * free memory used by the properties when you are done. * * \sa ODBCINSTDestructProperties */ int ODBCINSTConstructProperties( char *pszDriver, HODBCINSTPROPERTY *hFirstProperty ) { char szError[LOG_MSG_MAX+1]; char szDriverSetup[ODBC_FILENAME_MAX+1]; HINI hIni; int (*pODBCINSTGetProperties)( HODBCINSTPROPERTY ); void *hDLL = NULL; HODBCINSTPROPERTY hLastProperty; char szSectionName[INI_MAX_OBJECT_NAME+1]; char szIniName[ ODBC_FILENAME_MAX * 2 + 1 ]; char b1[ ODBC_FILENAME_MAX + 1 ], b2[ ODBC_FILENAME_MAX + 1 ]; /* SANITY CHECKS */ if ( pszDriver == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Need a driver name. Make it the friendly name." ); return ODBCINST_ERROR; } #ifdef VMS sprintf( szIniName, "%s:%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 )); #else sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 )); #endif /* GET DRIVER SETUP FILE NAME FOR GIVEN DRIVER */ #ifdef __OS2__ if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', FALSE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', FALSE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Could not open odbcinst.ini" ); return ODBCINST_ERROR; } #ifdef PLATFORM64 /* ASSUME USER FRIENDLY NAME FOR STARTERS */ if ( iniPropertySeek( hIni, pszDriver, "Setup64", "" ) == INI_SUCCESS ) { } else if ( iniPropertySeek( hIni, pszDriver, "Setup", "" ) == INI_SUCCESS ) { } else { /* NOT USER FRIENDLY NAME I GUESS SO ASSUME DRIVER FILE NAME */ if ( iniPropertySeek( hIni, "", "Driver64", pszDriver ) == INI_SUCCESS ) { iniObject( hIni, szSectionName ); if ( iniPropertySeek( hIni, szSectionName, "Setup64", "" ) != INI_SUCCESS ) { sprintf( szError, "Could not find Setup property for (%s) in system information", pszDriver ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError ); iniClose( hIni ); return ODBCINST_ERROR; } } else if ( iniPropertySeek( hIni, "", "Driver", pszDriver ) == INI_SUCCESS ) { iniObject( hIni, szSectionName ); if ( iniPropertySeek( hIni, szSectionName, "Setup", "" ) != INI_SUCCESS ) { sprintf( szError, "Could not find Setup property for (%s) in system information", pszDriver ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError ); iniClose( hIni ); return ODBCINST_ERROR; } } else { sprintf( szError, "Could not find driver (%s) in system information", pszDriver ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError ); iniClose( hIni ); return ODBCINST_ERROR; } } #else /* ASSUME USER FRIENDLY NAME FOR STARTERS */ if ( iniPropertySeek( hIni, pszDriver, "Setup", "" ) != INI_SUCCESS ) { /* NOT USER FRIENDLY NAME I GUESS SO ASSUME DRIVER FILE NAME */ if ( iniPropertySeek( hIni, "", "Driver", pszDriver ) != INI_SUCCESS ) { sprintf( szError, "Could not find driver (%s) in system information", pszDriver ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError ); iniClose( hIni ); return ODBCINST_ERROR; } else { iniObject( hIni, szSectionName ); if ( iniPropertySeek( hIni, szSectionName, "Setup", "" ) != INI_SUCCESS ) { sprintf( szError, "Could not find Setup property for (%s) in system information", pszDriver ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError ); iniClose( hIni ); return ODBCINST_ERROR; } } } #endif iniValue( hIni, szDriverSetup ); iniClose( hIni ); if ( szDriverSetup[ 0 ] == '\0' ) { sprintf( szError, "Could not find Setup property for (%s) in system information", pszDriver ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError ); return ODBCINST_ERROR; } /* * initialize libtool */ lt_dlinit(); #ifdef MODULEDIR lt_dlsetsearchpath(MODULEDIR); #endif /* TRY GET FUNC FROM DRIVER SETUP */ if ( !(hDLL = lt_dlopen( szDriverSetup )) ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Could not load library" ); return ODBCINST_ERROR; } pODBCINSTGetProperties = (int(*)(struct tODBCINSTPROPERTY*)) lt_dlsym( hDLL, "ODBCINSTGetProperties" ); /* PAH - This can be true even when we found the symbol. if ( lt_dlerror() != NULL ) */ if ( pODBCINSTGetProperties == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Could not find ODBCINSTGetProperties()" ); return ODBCINST_ERROR; } /* MANDATORY PROPERTIES */ (*hFirstProperty) = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); memset( (*hFirstProperty), 0, sizeof(ODBCINSTPROPERTY) ); (*hFirstProperty)->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; (*hFirstProperty)->pNext = NULL; (*hFirstProperty)->bRefresh = 0; (*hFirstProperty)->hDLL = hDLL; (*hFirstProperty)->pWidget = NULL; (*hFirstProperty)->pszHelp = NULL; (*hFirstProperty)->aPromptData = NULL; strncpy( (*hFirstProperty)->szName, "Name", INI_MAX_PROPERTY_NAME ); strcpy( (*hFirstProperty)->szValue, "" ); hLastProperty = (*hFirstProperty); (*hFirstProperty)->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = (*hFirstProperty)->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT; hLastProperty->pNext = NULL; hLastProperty->bRefresh = 0; hLastProperty->hDLL = hDLL; hLastProperty->pWidget = NULL; (*hFirstProperty)->pszHelp = NULL; (*hFirstProperty)->aPromptData = NULL; strncpy( hLastProperty->szName, "Description", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, pszDriver, INI_MAX_PROPERTY_VALUE ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LABEL; hLastProperty->pNext = NULL; hLastProperty->bRefresh = 0; hLastProperty->hDLL = hDLL; hLastProperty->pWidget = NULL; (*hFirstProperty)->pszHelp = NULL; (*hFirstProperty)->aPromptData = NULL; strncpy( hLastProperty->szName, "Driver", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, pszDriver, INI_MAX_PROPERTY_VALUE ); /* hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX; hLastProperty->aPromptData = malloc( sizeof(aYesNo) ); memcpy( hLastProperty->aPromptData, aYesNo, sizeof(aYesNo) ); strncpy( hLastProperty->szName, "Trace", INI_MAX_PROPERTY_NAME ); strcpy( hLastProperty->szValue, "No" ); hLastProperty->pNext = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); hLastProperty = hLastProperty->pNext; memset( hLastProperty, 0, sizeof(ODBCINSTPROPERTY) ); hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_FILENAME; strncpy( hLastProperty->szName, "TraceFile", INI_MAX_PROPERTY_NAME ); strncpy( hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE ); */ /* APPEND OTHERS */ pODBCINSTGetProperties( hLastProperty ); lt_dlclose( hDLL ); return ODBCINST_SUCCESS; } unixODBC-2.3.12/odbcinst/ODBCINSTDestructProperties.c000066400000000000000000000030051446441710500221670ustar00rootroot00000000000000/************************************************** * ODBCINSTDestructProperties * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #ifdef UNIXODBC_SOURCE #include #endif #include int ODBCINSTDestructProperties( HODBCINSTPROPERTY *hFirstProperty ) { HODBCINSTPROPERTY hNextProperty; HODBCINSTPROPERTY hCurProperty; /* SANITY CHECKS */ if ( (*hFirstProperty) == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Invalid property list handle" ); return ODBCINST_ERROR; } /* FREE MEMORY */ for ( hCurProperty = (*hFirstProperty); hCurProperty != NULL; hCurProperty = hNextProperty ) { hNextProperty = hCurProperty->pNext; /* FREE ANY PROMPT DATA (ie pick list options and such) */ if ( hCurProperty->aPromptData != NULL ) free( hCurProperty->aPromptData ); /* 1st PROPERTY HAS HANDLE TO DriverSetup DLL; LETS LET THE O/S KNOW WE ARE DONE WITH IT */ if ( hCurProperty == (*hFirstProperty) && hCurProperty->hDLL != NULL ) lt_dlclose( hCurProperty->hDLL ); /* FREE OTHER STUFF */ if ( hCurProperty->pszHelp != NULL ) free( hCurProperty->pszHelp ); free( hCurProperty ); } (*hFirstProperty) = NULL; return ODBCINST_SUCCESS; } unixODBC-2.3.12/odbcinst/ODBCINSTSetProperty.c000066400000000000000000000045641446441710500206300ustar00rootroot00000000000000/************************************************** * ODBCINSTSetProperty * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include int ODBCINSTSetProperty( HODBCINSTPROPERTY hFirstProperty, char *pszProperty, char *pszValue ) { char szError[LOG_MSG_MAX+1]; HODBCINSTPROPERTY hCurProperty; /* SANITY CHECKS */ if ( hFirstProperty == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Invalid property list handle" ); return ODBCINST_ERROR; } if ( pszProperty == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Invalid Property Name" ); return ODBCINST_ERROR; } if ( pszValue == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Invalid Value buffer" ); return ODBCINST_ERROR; } /* FIND pszProperty */ for ( hCurProperty = hFirstProperty; hCurProperty != NULL; hCurProperty = hCurProperty->pNext ) { if ( strcasecmp( pszProperty, hCurProperty->szName ) == 0 ) { /* CHANGE IT */ strncpy( hCurProperty->szValue, pszValue, INI_MAX_PROPERTY_VALUE ); return ODBCINST_SUCCESS; } } sprintf( szError, "Could not find property (%s)", pszProperty ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_WARNING, ODBC_ERROR_GENERAL_ERR, szError ); return ODBCINST_ERROR; } int ODBCINSTAddProperty( HODBCINSTPROPERTY hFirstProperty, char *pszProperty, char *pszValue ) { HODBCINSTPROPERTY hNew; hNew = (HODBCINSTPROPERTY)malloc( sizeof(ODBCINSTPROPERTY) ); memset(hNew, 0, sizeof(ODBCINSTPROPERTY)); hNew->nPromptType = ODBCINST_PROMPTTYPE_HIDDEN; hNew->pNext = NULL; hNew->bRefresh = 0; hNew->hDLL = hFirstProperty->hDLL; hNew->pWidget = NULL; hNew->pszHelp = NULL; hNew->aPromptData = NULL; strcpy(hNew->szName, pszProperty ); strcpy( hNew->szValue, pszValue ); /* * add to end of list */ while ( hFirstProperty -> pNext ) { hFirstProperty = hFirstProperty -> pNext; } hNew -> pNext = NULL; hFirstProperty -> pNext = hNew; return 0; } unixODBC-2.3.12/odbcinst/ODBCINSTValidateProperties.c000066400000000000000000000011271446441710500221260ustar00rootroot00000000000000/************************************************** * ODBCINSTValidateProperties * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include int ODBCINSTValidateProperties( HODBCINSTPROPERTY hFirstProperty, HODBCINSTPROPERTY hBadProperty, char *pszMessage ) { return ODBCINST_SUCCESS; } unixODBC-2.3.12/odbcinst/ODBCINSTValidateProperty.c000066400000000000000000000011041446441710500216110ustar00rootroot00000000000000/************************************************** * ODBCINSTValidateProperty * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include int ODBCINSTValidateProperty( HODBCINSTPROPERTY hFirstProperty, char *pszProperty, char *pszMessage ) { return ODBCINST_SUCCESS; } unixODBC-2.3.12/odbcinst/README000066400000000000000000000030161446441710500157050ustar00rootroot00000000000000*************************************************************** * This code is LGPL. You CAN make commercial solutions using * * LGPL software. * * * * Peter Harvey 21.FEB.99 pharvey@codebydesign.com * *************************************************************** +-------------------------------------------------------------+ | unixODBC | | ODBCINST lib (libodbcinst.so) | +-------------------------------------------------------------+ This share library supports ODBC Install/Setup and Config options. It is modelled after MS'isms and should, therefore, allow for an easy transition from MS'isms to other platforms (ie Linux). A complicating factor for unixODBC is that the GUI may not be present - or if it is - it may be any number of types (X, KDE, GNOME etc). So the GUI bits of odbcinst must be plugable. This library handles this. See SQLManageDataSources() and the unixODBC-GUI-Qt project. This lib also has a command line tool called odbcinst. +-------------------------------------------------------------+ | Peter Harvey | | pharvey@codebydesign.com | | http://www.unixodbc.org | | 10.APR.99 | +-------------------------------------------------------------+ unixODBC-2.3.12/odbcinst/SQLConfigDataSource.c000066400000000000000000000156221446441710500207370ustar00rootroot00000000000000/************************************************** * SQLConfigDataSource * * Determine the DriverSetup file name and then try to pass * the work along to its ConfigDSN(). * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #ifdef UNIXODBC_SOURCE #include #endif #include static BOOL SQLConfigDataSourceWide( HWND hWnd, WORD nRequest, LPCSTR pszDriver, /* USER FRIENDLY NAME (not file name) */ LPCSTR pszAttributes, LPCWSTR pszDriverW, LPCWSTR pszAttributesW ) { BOOL (*pFunc)( HWND, WORD, LPCSTR, LPCSTR ); BOOL (*pFuncW)( HWND, WORD, LPCWSTR, LPCWSTR ); BOOL nReturn; void *hDLL = FALSE; HINI hIni; char szDriverSetup[INI_MAX_PROPERTY_VALUE+1]; char szIniName[ ODBC_FILENAME_MAX * 2 + 3 ]; char b1[ ODBC_FILENAME_MAX + 1 ], b2[ ODBC_FILENAME_MAX + 1 ]; /* SANITY CHECKS */ if ( pszDriver == NULL || pszAttributes == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } if ( pszDriver[0] == '\0' ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } switch ( nRequest ) { case ODBC_ADD_DSN: case ODBC_CONFIG_DSN: case ODBC_REMOVE_DSN: case ODBC_ADD_SYS_DSN: case ODBC_CONFIG_SYS_DSN: case ODBC_REMOVE_SYS_DSN: case ODBC_REMOVE_DEFAULT_DSN: break; default: inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_REQUEST_TYPE, "" ); return FALSE; } #ifdef VMS sprintf( szIniName, "%s:%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ) ); #else sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ) ); #endif /* OK */ #ifdef __OS2__ if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } /* * initialize libtool */ lt_dlinit(); #ifdef MODULEDIR lt_dlsetsearchpath(MODULEDIR); #endif #ifdef PLATFORM64 if ( iniPropertySeek( hIni, (char *)pszDriver, "Setup64", "" ) == INI_SUCCESS || iniPropertySeek( hIni, (char *)pszDriver, "Setup", "" ) == INI_SUCCESS ) #else if ( iniPropertySeek( hIni, (char *)pszDriver, "Setup", "" ) == INI_SUCCESS ) #endif { iniValue( hIni, szDriverSetup ); iniClose( hIni ); if ( szDriverSetup[ 0 ] == '\0' ) { char szError[ 512 ]; sprintf( szError, "Could not find Setup property for (%.400s) in system information", pszDriver ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, szError ); __set_config_mode( ODBC_BOTH_DSN ); return FALSE; } nReturn = FALSE; if ( (hDLL = lt_dlopen( szDriverSetup )) ) { pFunc = (BOOL (*)(HWND, WORD, LPCSTR, LPCSTR )) lt_dlsym( hDLL, "ConfigDSN" ); pFuncW = (BOOL (*)(HWND, WORD, LPCWSTR, LPCWSTR )) lt_dlsym( hDLL, "ConfigDSNW" ); if ( pFunc ) { /* * set the mode */ switch ( nRequest ) { case ODBC_ADD_DSN: case ODBC_CONFIG_DSN: case ODBC_REMOVE_DSN: case ODBC_REMOVE_DEFAULT_DSN: __set_config_mode( ODBC_USER_DSN ); break; case ODBC_ADD_SYS_DSN: __set_config_mode( ODBC_SYSTEM_DSN ); nRequest = ODBC_ADD_DSN; break; case ODBC_CONFIG_SYS_DSN: __set_config_mode( ODBC_SYSTEM_DSN ); nRequest = ODBC_CONFIG_DSN; break; case ODBC_REMOVE_SYS_DSN: __set_config_mode( ODBC_SYSTEM_DSN ); nRequest = ODBC_REMOVE_DSN; break; } nReturn = pFunc( hWnd, nRequest, pszDriver, pszAttributes ); } else if ( pFuncW ) { /* * set the mode */ switch ( nRequest ) { case ODBC_ADD_DSN: case ODBC_CONFIG_DSN: case ODBC_REMOVE_DSN: case ODBC_REMOVE_DEFAULT_DSN: __set_config_mode( ODBC_USER_DSN ); break; case ODBC_ADD_SYS_DSN: __set_config_mode( ODBC_SYSTEM_DSN ); nRequest = ODBC_ADD_DSN; break; case ODBC_CONFIG_SYS_DSN: __set_config_mode( ODBC_SYSTEM_DSN ); nRequest = ODBC_CONFIG_DSN; break; case ODBC_REMOVE_SYS_DSN: __set_config_mode( ODBC_SYSTEM_DSN ); nRequest = ODBC_REMOVE_DSN; break; } nReturn = pFuncW( hWnd, nRequest, pszDriverW, pszAttributesW ); } else { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); } } else inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); __set_config_mode( ODBC_BOTH_DSN ); return nReturn; } inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); iniClose( hIni ); __set_config_mode( ODBC_BOTH_DSN ); return FALSE; } BOOL INSTAPI SQLConfigDataSourceW (HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver, LPCWSTR lpszAttributes) { char *drv, *attr; BOOL ret; inst_logClear(); drv = _single_string_alloc_and_copy( lpszDriver ); attr = _multi_string_alloc_and_copy( lpszAttributes ); ret = SQLConfigDataSourceWide( hwndParent, fRequest, drv, attr, lpszDriver, lpszAttributes ); free( drv ); free( attr ); return ret; } BOOL INSTAPI SQLConfigDataSource (HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttributes) { SQLWCHAR *drv, *attr; BOOL ret; inst_logClear(); drv = _single_string_alloc_and_expand( lpszDriver ); attr = _multi_string_alloc_and_expand( lpszAttributes ); ret = SQLConfigDataSourceWide( hwndParent, fRequest, lpszDriver, lpszAttributes, drv, attr ); free( drv ); free( attr ); return ret; } unixODBC-2.3.12/odbcinst/SQLConfigDriver.c000066400000000000000000000150041446441710500201320ustar00rootroot00000000000000/************************************************** * SQLConfigDriver * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #ifdef UNIXODBC_SOURCE #include #endif #include static BOOL SQLConfigDriverWide( HWND hWnd, WORD nRequest, LPCSTR pszDriver, LPCSTR pszArgs, LPSTR pszMsg, WORD nMsgMax, WORD *pnMsgOut, LPCWSTR pszDriverW, LPCWSTR pszArgsW, LPWSTR pszMsgW, int *iswide ) { void *hDLL; BOOL (*pConfigDriver)( HWND, WORD, LPCSTR, LPCSTR, LPCSTR, WORD, WORD * ); BOOL (*pConfigDriverW)( HWND, WORD, LPCWSTR, LPCWSTR, LPCWSTR, WORD, WORD * ); char szDriverSetup[ODBC_FILENAME_MAX+1]; HINI hIni; char szIniName[ ODBC_FILENAME_MAX * 2 + 1 ]; char b1[ ODBC_FILENAME_MAX + 1 ], b2[ ODBC_FILENAME_MAX + 1 ]; *iswide = 0; /* SANITY CHECKS */ if ( pszDriver == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_NAME, "" ); return FALSE; } if ( nRequest > ODBC_CONFIG_DRIVER ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_REQUEST_TYPE, "" ); return FALSE; } /* OK */ #ifdef VMS sprintf( szIniName, "%s:%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 )); #else sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 )); #endif /* lets get driver setup file name from odbcinst.ini */ #ifdef __OS2__ if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_NAME, "" ); return FALSE; } #ifdef PLATFORM64 if ( iniPropertySeek( hIni, (char *)pszDriver, "Setup64", "" ) == INI_SUCCESS || iniPropertySeek( hIni, (char *)pszDriver, "Setup", "" ) == INI_SUCCESS ) #else if ( iniPropertySeek( hIni, (char *)pszDriver, "Setup", "" ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_NAME, "" ); iniClose( hIni ); return FALSE; } iniValue( hIni, szDriverSetup ); iniClose( hIni ); /* * initialize libtool */ lt_dlinit(); #ifdef MODULEDIR lt_dlsetsearchpath(MODULEDIR); #endif /* process request */ switch ( nRequest ) { case ODBC_CONFIG_DRIVER: /* WHAT OPTIONS CAN WE EXPECT IN pszArgs?? * Sounds like just connection pooling options * In anycase, the spec says handle this in the * odbcinst so we probably want to make some calls here... * How common are Driver config options (not DSN options) anyway? * - Peter */ break; case ODBC_INSTALL_DRIVER: case ODBC_REMOVE_DRIVER: default : /* DRIVER SEPCIFIC are default; HANDLE AS PER INSTALL & REMOVE */ /* errors in here are ignored, according to the spec; perhaps I should ret error and let app ignore? */ if ( (hDLL = lt_dlopen( szDriverSetup )) ) { pConfigDriver = (BOOL (*)(HWND, WORD, LPCSTR, LPCSTR, LPCSTR, WORD, WORD * )) lt_dlsym( hDLL, "ConfigDriver" ); pConfigDriverW = (BOOL (*)(HWND, WORD, LPCWSTR, LPCWSTR, LPCWSTR, WORD, WORD * )) lt_dlsym( hDLL, "ConfigDriverW" ); /* if ( lt_dlerror() == NULL ) */ if ( pConfigDriver ) pConfigDriver( hWnd, nRequest, pszDriver, pszArgs, pszMsg, nMsgMax, pnMsgOut); else if ( pConfigDriverW ) { pConfigDriverW( hWnd, nRequest, pszDriverW, pszArgsW, pszMsgW, nMsgMax, pnMsgOut); *iswide = 1; } else { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); } lt_dlclose( hDLL ); } else inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); } return TRUE; } BOOL INSTAPI SQLConfigDriver(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszArgs, LPSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut) { SQLWCHAR *drv; SQLWCHAR *args; SQLWCHAR *msg; BOOL ret; WORD len; int iswide; inst_logClear(); drv = lpszDriver ? _single_string_alloc_and_expand( lpszDriver ) : (SQLWCHAR*)NULL; args = lpszArgs ? _multi_string_alloc_and_expand( lpszArgs ) : (SQLWCHAR*)NULL; if ( lpszMsg ) { if ( cbMsgMax > 0 ) { msg = calloc( cbMsgMax + 1, sizeof( SQLWCHAR )); } else { msg = NULL; } } else { msg = NULL; } ret = SQLConfigDriverWide( hwndParent, fRequest, lpszDriver, lpszArgs, lpszMsg, cbMsgMax, &len, drv, args, msg, &iswide ); if ( drv ) free( drv ); if ( args ) free( args ); if ( iswide ) { if ( ret && msg ) { _single_copy_from_wide((SQLCHAR*) lpszMsg, msg, len + 1 ); } } else { /* * the output is already in the right buffer */ } if ( msg ) free( msg ); if ( pcbMsgOut ) *pcbMsgOut = len; return ret; } BOOL INSTAPI SQLConfigDriverW(HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver, LPCWSTR lpszArgs, LPWSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut) { char *drv; char *args; char *msg; BOOL ret; WORD len; int iswide; inst_logClear(); drv = lpszDriver ? _single_string_alloc_and_copy( lpszDriver ) : (char*)NULL; args = lpszArgs ? _multi_string_alloc_and_copy( lpszArgs ) : (char*)NULL; if ( lpszMsg ) { if ( cbMsgMax > 0 ) { msg = calloc( cbMsgMax + 1, 1 ); } else { msg = NULL; } } else { msg = NULL; } ret = SQLConfigDriverWide( hwndParent, fRequest, drv, args, msg, cbMsgMax, &len, lpszDriver, lpszArgs, lpszMsg, &iswide ); if ( drv ) free( drv ); if ( args ) free( args ); if ( iswide ) { /* * the output is already in the right buffer */ } else { if ( ret && msg ) { _single_copy_to_wide( lpszMsg, msg, len + 1 ); } } if ( msg ) free( msg ); if ( pcbMsgOut ) *pcbMsgOut = len; return ret; } unixODBC-2.3.12/odbcinst/SQLCreateDataSource.c000066400000000000000000000274771446441710500207500ustar00rootroot00000000000000/************************************************** * SQLCreateDataSource * * This is a 100% UI so simply pass it on to odbcinst's UI * shadow share. * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #ifdef UNIXODBC_SOURCE #include #endif #include /* * Take a wide string consisting of null terminated sections, and copy to a ASCII version */ char* _multi_string_alloc_and_copy( LPCWSTR in ) { char *chr; int len = 0; if ( !in ) { return NULL; } while ( in[ len ] != 0 || in[ len + 1 ] != 0 ) { len ++; } chr = malloc( len + 2 ); len = 0; while ( in[ len ] != 0 || in[ len + 1 ] != 0 ) { chr[ len ] = 0xFF & in[ len ]; len ++; } chr[ len ++ ] = '\0'; chr[ len ++ ] = '\0'; return chr; } #ifdef WITH_UTF8_INI char* _single_string_alloc_and_copy( LPCWSTR in ) { char *chr; int len = 0, ulen = 0; if ( !in ) { return NULL; } while ( in[ len ] != 0 ) { if ( in[ len ] < 0x80 ) { ulen ++; } else if ( in[ len ] < 0x800 ) { ulen += 2; } else { ulen += 3; } len ++; } chr = malloc( ulen + 1 ); len = 0; ulen = 0; while ( in[ len ] != 0 ) { if ( in[ len ] < 0x80 ) { chr[ ulen ] = in[ len ]; len ++; ulen ++; } else if ( in[ len ] < 0x800 ) { chr[ ulen ++ ] = ( 0xC0 | ( in[ len ] >> 6 )); chr[ ulen ] = ( 0x80 | ( in[ len ] & 0x3F )); len ++; ulen ++; } else { chr[ ulen ++ ] = ( 0xE0 | ( in[ len ] >> 12 )); chr[ ulen ++ ] = ( 0x80 | ( in[ len ] >> 6 & 0x3F )); chr[ ulen ] = ( 0x80 | ( in[ len ] & 0x3F )); len ++; ulen ++; } } chr[ ulen ++ ] = '\0'; return chr; } #else char* _single_string_alloc_and_copy( LPCWSTR in ) { char *chr; int len = 0; if ( !in ) { return NULL; } while ( in[ len ] != 0 ) { len ++; } chr = malloc( len + 1 ); len = 0; while ( in[ len ] != 0 ) { chr[ len ] = 0xFF & in[ len ]; len ++; } chr[ len ++ ] = '\0'; return chr; } #endif SQLWCHAR* _multi_string_alloc_and_expand( LPCSTR in ) { SQLWCHAR *chr; int len = 0; if ( !in ) { return NULL; } while ( in[ len ] != 0 || in[ len + 1 ] != 0 ) { len ++; } chr = malloc(sizeof( SQLWCHAR ) * ( len + 2 )); len = 0; while ( in[ len ] != 0 || in[ len + 1 ] != 0 ) { chr[ len ] = in[ len ]; len ++; } chr[ len ++ ] = 0; chr[ len ++ ] = 0; return chr; } SQLWCHAR* _single_string_alloc_and_expand( LPCSTR in ) { SQLWCHAR *chr; int len = 0; if ( !in ) { return NULL; } while ( in[ len ] != 0 ) { len ++; } chr = malloc( sizeof( SQLWCHAR ) * ( len + 1 )); len = 0; while ( in[ len ] != 0 ) { chr[ len ] = in[ len ]; len ++; } chr[ len ++ ] = 0; return chr; } void _single_string_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len ) { while ( len > 0 && *in ) { *out = *in; out++; in++; len --; } *out = 0; } #ifdef WITH_UTF8_INI int _single_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len ) { int clen = 0; while ( len >= 0 ) { if ((*in & 0x80) == 0x00 ) { *out = *in; in ++; len --; if ( *out == 0 ) { break; } } else if ((*in & 0xE0) == 0xC0) { *out = (*in++ & 0x3F); *out = *out << 6; *out |= (*in & 0x7F); in ++; len -= 2; } else if ((*in & 0xF0) == 0xE0) { *out = *in++ & 0x1F; *out = *out << 12; *out |= ((*in++ & 0x7F) << 6); *out |= (*in & 0x3F); in ++; len -= 3; } out ++; clen ++; } return clen; } #else int _single_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len ) { int clen; clen = len; while ( len >= 0 ) { *out = *in; out++; in++; len --; } return clen; } #endif void _single_copy_from_wide( SQLCHAR *out, LPCWSTR in, int len ) { while ( len >= 0 ) { *out = *in; out++; in++; len --; } } #ifdef WITH_UTF8_INI int _multi_string_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len ) { int clen = 0; while ( len > 0 && ( in[ 0 ] || in[ 1 ] )) { if ((*in & 0x80) == 0x00 ) { *out = *in; in ++; len --; } else if ((*in & 0xE0) == 0xC0) { *out = (*in++ & 0x3F); *out = *out << 6; *out |= (*in & 0x7F); in ++; len -= 2; } else if ((*in & 0xF0) == 0xE0) { *out = *in++ & 0x1F; *out = *out << 12; *out |= ((*in++ & 0x7F) << 6); *out |= (*in & 0x3F); in ++; len -= 3; } out ++; clen ++; } *out++ = 0; *out++ = 0; return clen; } #else int _multi_string_copy_to_wide( SQLWCHAR *out, LPCSTR in, int len ) { int clen = 0; while ( len > 0 && ( in[ 0 ] || in[ 1 ] )) { *out = *in; out++; in++; len --; clen ++; } *out++ = 0; *out++ = 0; return clen; } #endif int _multi_string_length( LPCSTR in ) { LPCSTR ch; if ( !in ) return 0; for ( ch = in ; !(*ch == 0 && *(ch + 1) == 0) ; ch ++ ); /* The convention seems to be to exclude the very last '\0' character from * the count, so that is what we do here. */ return ch - in + 1; } /*! * \brief Invokes a UI (a wizard) to walk User through creating a DSN. * * \param hWnd Input. Parent window handle. This is HWND as per the ODBC * specification but in unixODBC we use a generic window * handle. Caller must cast a HODBCINSTWND to HWND at call. * \param pszDS Input. Data Source Name. This can be a NULL pointer. * * \return BOOL * * \sa ODBCINSTWND */ BOOL SQLCreateDataSource( HWND hWnd, LPCSTR pszDS ) { HODBCINSTWND hODBCInstWnd = (HODBCINSTWND)hWnd; char szName[FILENAME_MAX]; char szNameAndExtension[FILENAME_MAX]; char szPathAndName[FILENAME_MAX]; void * hDLL; BOOL (*pSQLCreateDataSource)(HWND, LPCSTR); inst_logClear(); /* ODBC specification states that hWnd is mandatory. */ if ( !hWnd ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_HWND, "" ); return FALSE; } /* initialize libtool */ if ( lt_dlinit() ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "lt_dlinit() failed" ); return FALSE; } #ifdef MODULEDIR lt_dlsetsearchpath(MODULEDIR); #endif /* get plugin name */ _appendUIPluginExtension( szNameAndExtension, _getUIPluginName( szName, hODBCInstWnd->szUI ) ); /* lets try loading the plugin using an implicit path */ hDLL = lt_dlopen( szNameAndExtension ); if ( hDLL ) { /* change the name, as it avoids it finding it in the calling lib */ pSQLCreateDataSource = (BOOL (*)(HWND, LPCSTR))lt_dlsym( hDLL, "ODBCCreateDataSource" ); if ( pSQLCreateDataSource ) { BOOL ret; ret = pSQLCreateDataSource( ( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ), pszDS ); lt_dlclose( hDLL ); return ret; } else inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() ); lt_dlclose( hDLL ); } else { /* try with explicit path */ _prependUIPluginPath( szPathAndName, szNameAndExtension ); hDLL = lt_dlopen( szPathAndName ); if ( hDLL ) { /* change the name, as it avoids linker finding it in the calling lib */ pSQLCreateDataSource = (BOOL (*)(HWND,LPCSTR))lt_dlsym( hDLL, "ODBCCreateDataSource" ); if ( pSQLCreateDataSource ) { BOOL ret; ret = pSQLCreateDataSource( ( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ), pszDS ); lt_dlclose( hDLL ); return ret; } else inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() ); lt_dlclose( hDLL ); } } /* report failure to caller */ inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } /*! * \brief A wide char version of \sa SQLCreateDataSource. * * \sa SQLCreateDataSource */ BOOL INSTAPI SQLCreateDataSourceW( HWND hwndParent, LPCWSTR lpszDSN ) { HODBCINSTWND hODBCInstWnd = (HODBCINSTWND)hwndParent; char szName[FILENAME_MAX]; char szNameAndExtension[FILENAME_MAX]; char szPathAndName[FILENAME_MAX]; void * hDLL; BOOL (*pSQLCreateDataSource)(HWND, LPCWSTR); inst_logClear(); /* ODBC specification states that hWnd is mandatory. */ if ( !hwndParent ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_HWND, "" ); return FALSE; } /* initialize libtool */ if ( lt_dlinit() ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "lt_dlinit() failed" ); return FALSE; } /* get plugin name */ _appendUIPluginExtension( szNameAndExtension, _getUIPluginName( szName, hODBCInstWnd->szUI ) ); /* lets try loading the plugin using an implicit path */ hDLL = lt_dlopen( szNameAndExtension ); if ( hDLL ) { /* change the name, as it avoids it finding it in the calling lib */ pSQLCreateDataSource = (BOOL (*)(HWND, LPCWSTR))lt_dlsym( hDLL, "ODBCCreateDataSourceW" ); if ( pSQLCreateDataSource ) { BOOL ret; ret = pSQLCreateDataSource( ( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ), lpszDSN ); lt_dlclose( hDLL ); return ret; } else inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() ); lt_dlclose( hDLL ); } else { /* try with explicit path */ _prependUIPluginPath( szPathAndName, szNameAndExtension ); hDLL = lt_dlopen( szPathAndName ); if ( hDLL ) { /* change the name, as it avoids linker finding it in the calling lib */ pSQLCreateDataSource = (BOOL (*)(HWND,LPCWSTR))lt_dlsym( hDLL, "ODBCCreateDataSourceW" ); if ( pSQLCreateDataSource ) { BOOL ret; ret = pSQLCreateDataSource( ( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ), lpszDSN ); lt_dlclose( hDLL ); return ret; } else inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() ); lt_dlclose( hDLL ); } } /* report failure to caller */ inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } unixODBC-2.3.12/odbcinst/SQLGetAvailableDrivers.c000066400000000000000000000016771446441710500214430ustar00rootroot00000000000000/************************************************** * SQLGetAvailableDrivers * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL SQLGetAvailableDrivers( LPCSTR pszInfFile, LPSTR pszBuf, WORD nBufMax, WORD *pnBufOut) { return SQLGetInstalledDrivers( pszBuf, nBufMax, pnBufOut ); } BOOL INSTAPI SQLGetAvailableDriversW (LPCWSTR lpszInfFile, LPWSTR lpszBuf, WORD cbBufMax, WORD * pcbBufOut) { return SQLGetInstalledDriversW( lpszBuf, cbBufMax, pcbBufOut ); } unixODBC-2.3.12/odbcinst/SQLGetConfigMode.c000066400000000000000000000011661446441710500202270ustar00rootroot00000000000000/************************************************** * SQLGetConfigMode * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com * Nick Gorham - nick@lurcher.org **************************************************/ #include #include #include BOOL SQLGetConfigMode( UWORD *pnConfigMode ) { inst_logClear(); *pnConfigMode = __get_config_mode(); return TRUE; } unixODBC-2.3.12/odbcinst/SQLGetInstalledDrivers.c000066400000000000000000000045321446441710500214730ustar00rootroot00000000000000/************************************************** * SQLGetInstalledDrivers * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL SQLGetInstalledDrivers( LPSTR pszBuf, WORD nBufMax, WORD *pnBufOut ) { HINI hIni; WORD nBufPos = 0; WORD nToCopySize = 0; char szObjectName[INI_MAX_OBJECT_NAME+1]; char szIniName[ ODBC_FILENAME_MAX * 2 + 1 ]; char b1[ ODBC_FILENAME_MAX + 1 ], b2[ ODBC_FILENAME_MAX + 1 ]; inst_logClear(); #ifdef VMS sprintf( szIniName, "%s:%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ) ); #else sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ) ); #endif #ifdef __OS2__ if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" ); return FALSE; } memset( pszBuf, '\0', nBufMax ); iniObjectFirst( hIni ); while ( iniObjectEOL( hIni ) == FALSE ) { iniObject( hIni, szObjectName ); if ( strcmp( szObjectName, "ODBC" ) == 0 ) { iniObjectNext( hIni ); continue; } if ( (strlen( szObjectName )+1) > (nBufMax - nBufPos) ) { nToCopySize = nBufMax - nBufPos; strncpy( &(pszBuf[nBufPos]), szObjectName, nToCopySize ); nBufPos = nBufMax; break; } else { strcpy( &(pszBuf[nBufPos]), szObjectName ); nBufPos += strlen( szObjectName )+1; } iniObjectNext( hIni ); } iniClose( hIni ); if ( pnBufOut ) *pnBufOut = nBufPos; return TRUE; } BOOL INSTAPI SQLGetInstalledDriversW (LPWSTR lpszBuf, WORD cbBufMax, WORD * pcbBufOut) { char *path; BOOL ret; inst_logClear(); path = calloc( cbBufMax, 1 ); ret = SQLGetInstalledDrivers( path, cbBufMax, pcbBufOut ); if ( ret ) { _multi_string_copy_to_wide( lpszBuf, path, cbBufMax ); } free( path ); return ret; } unixODBC-2.3.12/odbcinst/SQLGetPrivateProfileString.c000066400000000000000000000435361446441710500223460ustar00rootroot00000000000000/**************************************************** * SQLGetPrivateProfileString * * Mostly used with odbc.ini files but can be used for odbcinst.ini * * IF pszFileName[0] == '/' THEN * use pszFileName * ELSE * use _odbcinst_ConfigModeINI() to get the complete file name for the current mode. * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include #include #ifdef ENABLE_INI_CACHING #ifdef HAVE_LIBPTH #include static pth_mutex_t mutex_ini = PTH_MUTEX_INIT; static int pth_init_called = 0; static int mutex_entry( pth_mutex_t *mutex ) { if ( !pth_init_called ) { pth_init(); pth_init_called = 1; } return pth_mutex_acquire( mutex, 0, NULL ); } static int mutex_exit( pth_mutex_t *mutex ) { return pth_mutex_release( mutex ); } #elif HAVE_LIBPTHREAD #include static pthread_mutex_t mutex_ini = PTHREAD_MUTEX_INITIALIZER; static int mutex_entry( pthread_mutex_t *mutex ) { return pthread_mutex_lock( mutex ); } static int mutex_exit( pthread_mutex_t *mutex ) { return pthread_mutex_unlock( mutex ); } #elif HAVE_LIBTHREAD #include static mutex_t mutex_ini; static int mutex_entry( mutex_t *mutex ) { return mutex_lock( mutex ); } static int mutex_exit( mutex_t *mutex ) { return mutex_unlock( mutex ); } #else #define mutex_entry(x) #define mutex_exit(x) #endif static struct ini_cache *ini_cache_head = NULL; static int _check_ini_cache( int *ret, LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer, LPCSTR pszFileName ) { struct ini_cache *ini_cache = ini_cache_head, *prev = NULL; UWORD config_mode; long tstamp = time( NULL ); if ( pszSection == NULL || pszEntry == NULL ) { return 0; } config_mode = __get_config_mode(); /* * look for expired entries, remove one each call */ for ( prev = NULL, ini_cache = ini_cache_head; ini_cache; ini_cache = ini_cache -> next ) { if ( ini_cache -> timestamp < tstamp ) { if ( prev ) { prev -> next = ini_cache -> next; } else { ini_cache_head = ini_cache -> next; } if ( ini_cache -> fname ) free( ini_cache -> fname ); if ( ini_cache -> section ) free( ini_cache -> section ); if ( ini_cache -> entry ) free( ini_cache -> entry ); if ( ini_cache -> value ) free( ini_cache -> value ); if ( ini_cache -> default_value ) free( ini_cache -> default_value ); free( ini_cache ); break; } prev = ini_cache; } for ( ini_cache = ini_cache_head; ini_cache; ini_cache = ini_cache -> next ) { if ( !pszFileName && ini_cache -> fname ) continue; if ( pszFileName && !ini_cache -> fname ) continue; if ( pszFileName && ini_cache -> fname && strcmp( pszFileName, ini_cache -> fname )) continue; if ( ini_cache -> config_mode != config_mode ) continue; if ( !pszSection && ini_cache -> section ) continue; if ( pszSection && !ini_cache -> section ) continue; if ( pszSection && ini_cache -> section && strcmp( pszSection, ini_cache -> section )) continue; if ( !pszEntry && ini_cache -> entry ) continue; if ( pszEntry && !ini_cache -> entry ) continue; if ( pszEntry && ini_cache -> entry && strcmp( pszEntry, ini_cache -> entry )) continue; if ( !pszDefault && ini_cache -> default_value ) continue; if ( pszDefault && !ini_cache -> default_value ) continue; if ( pszDefault && ini_cache -> default_value && strcmp( pszDefault, ini_cache -> default_value )) continue; if ( !pRetBuffer && ini_cache -> value ) continue; if ( pRetBuffer && !ini_cache -> value ) continue; if ( nRetBuffer < ini_cache -> buffer_size ) continue; if ( pRetBuffer ) { if ( ini_cache -> value ) { if ( nRetBuffer < strlen( ini_cache -> value )) { strncpy( pRetBuffer, ini_cache -> value, nRetBuffer ); pRetBuffer[ nRetBuffer - 1 ] = '\0'; } else { strcpy( pRetBuffer, ini_cache -> value ); } } *ret = ini_cache -> ret_value; return 1; } } return 0; } static void _save_ini_cache( int ret, LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer, LPCSTR pszFileName ) { struct ini_cache *ini_cache; UWORD config_mode; long tstamp = time( NULL ) + 20; /* expiry every 20 seconds */ ini_cache = calloc( sizeof( struct ini_cache ), 1 ); if ( !ini_cache ) { return; } if ( pszFileName ) ini_cache -> fname = strdup( pszFileName ); if ( pszSection ) ini_cache -> section = strdup( pszSection ); if ( pszEntry ) ini_cache -> entry = strdup( pszEntry ); if ( pRetBuffer && ret >= 0 ) ini_cache -> value = strdup( pRetBuffer ); if ( pszDefault ) ini_cache -> default_value = strdup( pszDefault ); ini_cache -> buffer_size = nRetBuffer; ini_cache -> ret_value = ret; config_mode = __get_config_mode(); ini_cache -> config_mode = config_mode; ini_cache -> timestamp = tstamp; ini_cache -> next = ini_cache_head; ini_cache_head = ini_cache; } static void _clear_ini_cache( void ) { struct ini_cache *ini_cache = ini_cache_head; while (( ini_cache = ini_cache_head ) != NULL ) { ini_cache_head = ini_cache -> next; if ( ini_cache -> fname ) free( ini_cache -> fname ); if ( ini_cache -> section ) free( ini_cache -> section ); if ( ini_cache -> entry ) free( ini_cache -> entry ); if ( ini_cache -> value ) free( ini_cache -> value ); if ( ini_cache -> default_value ) free( ini_cache -> default_value ); free( ini_cache ); } } /* * wrappers to provide thread safety */ static int check_ini_cache( int *ret, LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer, LPCSTR pszFileName ) { int rval; mutex_entry( &mutex_ini ); rval = _check_ini_cache( ret, pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer, pszFileName ); mutex_exit( &mutex_ini ); return rval; } static void save_ini_cache( int ret, LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer, LPCSTR pszFileName ) { int cval; mutex_entry( &mutex_ini ); /* * check its not been inserted since the last check */ if ( !_check_ini_cache( &cval, pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer, pszFileName )) { _save_ini_cache( ret, pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer, pszFileName ); } mutex_exit( &mutex_ini ); } void __clear_ini_cache( void ) { mutex_entry( &mutex_ini ); _clear_ini_cache(); mutex_exit( &mutex_ini ); } #else static int check_ini_cache( int *ret, LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer, LPCSTR pszFileName ) { return 0; } static void save_ini_cache( int ret, LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer, LPCSTR pszFileName ) { } void __clear_ini_cache( void ) { } #endif int SQLGetPrivateProfileString( LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPSTR pRetBuffer, int nRetBuffer, LPCSTR pszFileName ) { HINI hIni; int nBufPos = 0; char szValue[INI_MAX_PROPERTY_VALUE+1]; char szFileName[ODBC_FILENAME_MAX+1]; UWORD nConfigMode; int ini_done = 0; int ret; inst_logClear(); if ( check_ini_cache( &ret, pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer, pszFileName )) { return ret; } /* SANITY CHECKS */ if ( pRetBuffer == NULL || nRetBuffer < 2 ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return -1; } if ( pszSection != NULL && pszEntry != NULL && pszDefault == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "need default value - try empty string" ); return -1; } *pRetBuffer = '\0'; /***************************************************** * SOME MS CODE (ie some drivers) MAY USE THIS FUNCTION TO GET ODBCINST INFO SO... *****************************************************/ if ( pszFileName != NULL ) { if ( strstr( pszFileName, "odbcinst" ) || strstr( pszFileName, "ODBCINST" ) ) { ret = _SQLGetInstalledDrivers( pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer ); if ( ret == -1 ) { /* try to use any default provided */ if ( pRetBuffer && nRetBuffer > 0 ) { if ( pszDefault ) { strncpy( pRetBuffer, pszDefault, nRetBuffer ); pRetBuffer[ nRetBuffer - 1 ] = '\0'; } } } else { save_ini_cache( ret, pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer, pszFileName ); } return ret; } else if ( !*pszFileName ) { return 0; /* Asking for empty filename returns nothing, not even default */ } } /***************************************************** * GATHER ALL RELEVANT DSN INFORMATION INTO AN hIni *****************************************************/ if ( pszFileName != 0 && pszFileName[0] == '/' ) { #ifdef __OS2__ if ( iniOpen( &hIni, (char*)pszFileName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, (char*)pszFileName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" ); return -1; } } else { nConfigMode = __get_config_mode(); nBufPos = 0; szFileName[0] = '\0'; switch ( nConfigMode ) { case ODBC_BOTH_DSN: if ( _odbcinst_UserINI( szFileName, TRUE )) { #ifdef __OS2__ if ( iniOpen( &hIni, (char*) szFileName, "#;", '[', ']', '=', TRUE, 1L ) == INI_SUCCESS ) #else if ( iniOpen( &hIni, (char*) szFileName, "#;", '[', ']', '=', TRUE ) == INI_SUCCESS ) #endif { ini_done = 1; } } _odbcinst_SystemINI( szFileName, TRUE ); if ( !ini_done ) { #ifdef __OS2__ if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" ); return -1; } } else { iniAppend( hIni, szFileName ); } break; case ODBC_USER_DSN: _odbcinst_UserINI( szFileName, TRUE ); #ifdef __OS2__ if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" ); return -1; } break; case ODBC_SYSTEM_DSN: _odbcinst_SystemINI( szFileName, TRUE ); #ifdef __OS2__ if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" ); return -1; } break; default: inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Invalid Config Mode" ); return -1; } } /***************************************************** * EXTRACT SECTIONS *****************************************************/ if ( pszSection == NULL ) { _odbcinst_GetSections( hIni, pRetBuffer, nRetBuffer, &nBufPos ); if (nBufPos > 0) ret = _multi_string_length(pRetBuffer); else ret = 0; /* Indicate not found */ } /***************************************************** * EXTRACT ENTRIES *****************************************************/ else if ( pszEntry == NULL ) { _odbcinst_GetEntries( hIni, pszSection, pRetBuffer, nRetBuffer, &nBufPos ); if (nBufPos > 0) ret = _multi_string_length(pRetBuffer); else ret = 0; /* Indicate not found */ } /***************************************************** * EXTRACT AN ENTRY *****************************************************/ else { if ( pszSection == NULL || pszEntry == NULL || pszDefault == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return -1; } /* TRY TO GET THE ONE ITEM MATCHING Section & Entry */ if ( iniPropertySeek( hIni, (char *)pszSection, (char *)pszEntry, "" ) != INI_SUCCESS ) { /* * (NG) this seems to be ignoring the length of pRetBuffer !!! */ /* strncpy( pRetBuffer, pszDefault, INI_MAX_PROPERTY_VALUE ); */ if ( pRetBuffer && nRetBuffer > 0 && pszDefault ) { strncpy( pRetBuffer, pszDefault, nRetBuffer ); pRetBuffer[ nRetBuffer - 1 ] = '\0'; } } else { iniValue( hIni, szValue ); if ( pRetBuffer ) { strncpy( pRetBuffer, szValue, nRetBuffer ); pRetBuffer[ nRetBuffer - 1 ] = '\0'; } nBufPos = strlen( szValue ); } ret = strlen( pRetBuffer ); } iniClose( hIni ); save_ini_cache( ret, pszSection, pszEntry, pszDefault, pRetBuffer, nRetBuffer, pszFileName ); return ret; } int INSTAPI SQLGetPrivateProfileStringW( LPCWSTR lpszSection, LPCWSTR lpszEntry, LPCWSTR lpszDefault, LPWSTR lpszRetBuffer, int cbRetBuffer, LPCWSTR lpszFilename) { int ret; char *sect; char *entry; char *def; char *buf; char *name; inst_logClear(); sect = lpszSection ? _single_string_alloc_and_copy( lpszSection ) : (char*)NULL; entry = lpszEntry ? _single_string_alloc_and_copy( lpszEntry ) : (char*)NULL; def = lpszDefault ? _single_string_alloc_and_copy( lpszDefault ) : (char*)NULL; name = lpszFilename ? _single_string_alloc_and_copy( lpszFilename ) : (char*)NULL; if ( lpszRetBuffer ) { if ( cbRetBuffer > 0 ) { buf = calloc( cbRetBuffer + 1, 1 ); } else { buf = NULL; } } else { buf = NULL; } ret = SQLGetPrivateProfileString( sect, entry, def, buf, cbRetBuffer, name ); if ( sect ) free( sect ); if ( entry ) free( entry ); if ( def ) free( def ); if ( name ) free( name ); if ( ret > 0 ) { if ( buf && lpszRetBuffer ) { if ( !lpszSection || !lpszEntry ) ret = _multi_string_copy_to_wide( lpszRetBuffer, buf, ret ); else ret = _single_copy_to_wide( lpszRetBuffer, buf, ret ); } } if ( buf ) { free( buf ); } return ret; } unixODBC-2.3.12/odbcinst/SQLGetTranslator.c000066400000000000000000000022361446441710500203450ustar00rootroot00000000000000/************************************************** * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL SQLGetTranslator( HWND hWnd, LPSTR pszName, WORD nNameMax, WORD *pnNameOut, LPSTR pszPath, WORD nPathMax, WORD *pnPathOut, DWORD *pnOption ) { inst_logClear(); return FALSE; } BOOL INSTAPI SQLGetTranslatorW (HWND hwnd, LPWSTR lpszName, WORD cbNameMax, WORD *pcbNameOut, LPWSTR lpszPath, WORD cbPathMax, WORD *pcbPathOut, DWORD *pvOption) { inst_logClear(); return FALSE; } unixODBC-2.3.12/odbcinst/SQLInstallDriverEx.c000066400000000000000000000160551446441710500206370ustar00rootroot00000000000000/************************************************* * SQLInstallDriverEx * * pnUsageCount UsageCount is incremented and decremented * only in this lib. This is done whenever * a request is made to install or remove * a driver. * This differs slightly from the MS spec. * see UsageCount entries in odbcinst.ini * * pszPathOut This lacks some smarts. I will pass pszPathIn * back here or, if pszPathIn=NULL, I will default * to /usr/lib * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL SQLInstallDriverEx( LPCSTR pszDriver, LPCSTR pszPathIn, LPSTR pszPathOut, WORD nPathOutMax, WORD *pnPathOut, WORD nRequest, LPDWORD pnUsageCount ) { HINI hIni; char szObjectName[INI_MAX_OBJECT_NAME+1]; char szNameValue[INI_MAX_PROPERTY_NAME+INI_MAX_PROPERTY_VALUE+3]; char szPropertyName[INI_MAX_PROPERTY_NAME+1]; char szValue[INI_MAX_PROPERTY_VALUE+1]; char szIniName[ ODBC_FILENAME_MAX * 2 + 1 ]; BOOL bInsertUsageCount; int nElement; int nUsageCount = 0; /* SHOULD GET THIS FROM SOMEWHERE ? */ char b1[ ODBC_FILENAME_MAX + 1 ], b2[ ODBC_FILENAME_MAX + 1 ]; inst_logClear(); /* SANITY CHECKS */ if ( pszDriver == NULL || pszPathOut == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } if ( nRequest != ODBC_INSTALL_INQUIRY && nRequest != ODBC_INSTALL_COMPLETE ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_REQUEST_TYPE, "" ); return FALSE; } memset( pszPathOut, '\0', nPathOutMax ); if ( pszPathIn ) { #ifdef VMS snprintf( szIniName, sizeof(szIniName), "%s:%s", pszPathIn, odbcinst_system_file_name( b2 ) ); #else snprintf( szIniName, sizeof(szIniName), "%s/%s", pszPathIn, odbcinst_system_file_name( b2 ) ); #endif } else { #ifdef VMS sprintf( szIniName, "%s:%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ) ); #else sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ) ); #endif } /* PROCESS ODBC INST INI FILE */ #ifdef __OS2__ if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" ); return FALSE; } if ( iniElement( (char *)pszDriver, '\0', '\0', 0, szObjectName, INI_MAX_OBJECT_NAME ) != INI_SUCCESS ) { iniClose( hIni ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_KEYWORD_VALUE, "" ); return FALSE; } /* LETS GET ITS FILE USAGE VALUE (if any) */ if ( iniPropertySeek( hIni, szObjectName, "UsageCount", "" ) == INI_SUCCESS ) { iniValue( hIni, szValue ); nUsageCount = atoi( szValue ); } /* DOES THE OBJECT ALREADY EXIST? (also ensures that we have correct current object) */ if ( iniObjectSeek( hIni, szObjectName ) == INI_SUCCESS ) { if ( nUsageCount == 0 ) nUsageCount = 1; if ( nRequest == ODBC_INSTALL_COMPLETE ) { iniObjectDelete( hIni ); } } /* LETS ADD THE SECTION AND ENTRY */ nUsageCount++; if ( nRequest == ODBC_INSTALL_COMPLETE ) { bInsertUsageCount = TRUE; iniObjectInsert( hIni, szObjectName ); for ( nElement=1; iniElement( (char *)pszDriver, '\0', '\0', nElement, szNameValue, INI_MAX_PROPERTY_NAME+INI_MAX_PROPERTY_VALUE+3 ) == INI_SUCCESS; nElement++ ) { iniElement( szNameValue, '=', '\0', 0, szPropertyName, INI_MAX_PROPERTY_NAME ); iniElementEOL( szNameValue, '=', '\0', 1, szValue, INI_MAX_PROPERTY_VALUE ); if ( szPropertyName[0] != '\0' ) { /* OVERRIDE ANY USAGE COUNT CHANGES */ if ( strcasecmp( szPropertyName, "UsageCount" ) == 0 ) { bInsertUsageCount = FALSE; sprintf( szValue, "%d", nUsageCount ); } iniPropertyInsert( hIni, szPropertyName, szValue ); } else { iniClose( hIni ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_KEYWORD_VALUE, "" ); return FALSE; } } /* for */ if ( bInsertUsageCount ) { /* LETS INSERT USAGE COUNT */ sprintf( szValue, "%d", nUsageCount ); iniPropertyInsert( hIni, "UsageCount", szValue ); } if ( iniCommit( hIni ) != INI_SUCCESS ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_PATH, "" ); iniClose( hIni ); return FALSE; } } iniClose( hIni ); /* OK, SO WHATS LEFT? */ if ( pszPathIn == NULL ) { if ( pszPathOut ) { if ( strlen( odbcinst_system_file_path( b1 )) < nPathOutMax ) { strcpy( pszPathOut, odbcinst_system_file_path( b1 )); } else { strncpy( pszPathOut, odbcinst_system_file_path( b1 ), nPathOutMax ); pszPathOut[ nPathOutMax - 1 ] = '\0'; } } } else { if ( pszPathOut && nPathOutMax > 0 ) { if ( strlen( pszPathIn ) < nPathOutMax ) { strcpy( pszPathOut, pszPathIn ); } else { strncpy( pszPathOut, pszPathIn, nPathOutMax ); pszPathOut[ nPathOutMax - 1 ] = '\0'; } } } if ( pnPathOut != NULL ) { if ( pszPathIn == NULL ) { *pnPathOut = strlen( odbcinst_system_file_path( b1 )); } else { *pnPathOut = strlen( pszPathIn ); } } if ( pnUsageCount != NULL ) { *pnUsageCount = nUsageCount; } return TRUE; } BOOL INSTAPI SQLInstallDriverExW(LPCWSTR lpszDriver, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount) { char *drv; char *pth; char *pout; WORD len; BOOL ret; inst_logClear(); drv = lpszDriver ? _multi_string_alloc_and_copy( lpszDriver ) : (char*)NULL; pth = lpszPathIn ? _single_string_alloc_and_copy( lpszPathIn ) : (char*)NULL; if ( lpszPathOut ) { if ( cbPathOutMax > 0 ) { pout = calloc( cbPathOutMax + 1, 1 ); } else { pout = NULL; } } else { pout = NULL; } ret = SQLInstallDriverEx( drv, pth, pout, cbPathOutMax, &len, fRequest, lpdwUsageCount ); if ( ret ) { if ( pout && lpszPathOut ) { _single_copy_to_wide( lpszPathOut, pout, len + 1 ); } } if ( pcbPathOut ) { *pcbPathOut = len; } if ( drv ) free( drv ); if ( pth ) free( pth ); if ( pout ) free( pout ); return ret; } unixODBC-2.3.12/odbcinst/SQLInstallDriverManager.c000066400000000000000000000030621446441710500216270ustar00rootroot00000000000000/************************************************* * SQLInstallDriverManager * * I return the default dir for core components.. but * thats it. * This may differ slightly from the spec. * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL SQLInstallDriverManager( LPSTR pszPath, WORD nPathMax, WORD *pnPathOut ) { char szIniName[ INI_MAX_OBJECT_NAME + 1 ]; char b1[ ODBC_FILENAME_MAX + 1 ]; inst_logClear(); /* SANITY CHECKS */ if ( pszPath == NULL || nPathMax < 2 ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return 0; } sprintf( szIniName, "%s", odbcinst_system_file_path( b1 ) ); /* DO SOMETHING */ strncpy( pszPath, szIniName, nPathMax ); if ( pnPathOut != NULL ) *pnPathOut = strlen( pszPath ); return TRUE; } BOOL INSTAPI SQLInstallDriverManagerW (LPWSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut) { char *path; BOOL ret; inst_logClear(); path = calloc( cbPathMax, 1 ); ret = SQLInstallDriverManager( path, cbPathMax, pcbPathOut ); if ( ret ) { _single_string_copy_to_wide( lpszPath, path, cbPathMax ); } free( path ); return ret; } unixODBC-2.3.12/odbcinst/SQLInstallODBC.c000066400000000000000000000042451446441710500176140ustar00rootroot00000000000000/************************************************* * SQLInstallODBC * * Just provide stub for ODBC 2 installer functions * **************************************************/ #include #include BOOL INSTAPI SQLInstallODBC(HWND hwndParent, LPCSTR lpszInfFile, LPCSTR lpszSrcPath, LPCSTR lpszDrivers) { return FALSE; } BOOL INSTAPI SQLInstallDriver (LPCSTR lpszInfFile, LPCSTR lpszDriver, LPSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut) { return FALSE; } BOOL INSTAPI SQLInstallTranslator( LPCSTR lpszInfFile, LPCSTR pszTranslator, LPCSTR pszPathIn, LPSTR pszPathOut, WORD nPathOutMax, WORD *pnPathOut, WORD nRequest, LPDWORD pnUsageCount ) { inst_logClear(); return FALSE; } BOOL INSTAPI SQLRemoveDefaultDataSource( void ) { inst_logClear(); return SQLConfigDataSource (NULL, ODBC_REMOVE_DEFAULT_DSN, NULL, NULL); } BOOL INSTAPI SQLInstallDriverW (LPCWSTR lpszInfFile, LPCWSTR lpszDriver, LPWSTR lpszPath, WORD cbPathMax, WORD * pcbPathOut) { return FALSE; } BOOL INSTAPI SQLInstallODBCW (HWND hwndParent, LPCWSTR lpszInfFile, LPCWSTR lpszSrcPath, LPCWSTR lpszDrivers) { return FALSE; } BOOL INSTAPI SQLInstallTranslatorW(LPCWSTR lpszInfFile, LPCWSTR lpszTranslator, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount) { inst_logClear(); return FALSE; } unixODBC-2.3.12/odbcinst/SQLInstallTranslatorEx.c000066400000000000000000000021151446441710500215250ustar00rootroot00000000000000/************************************************** * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL SQLInstallTranslatorEx( LPCSTR pszTranslator, LPCSTR pszPathIn, LPSTR pszPathOut, WORD nPathOutMax, WORD *pnPathOut, WORD nRequest, LPDWORD pnUsageCount ) { inst_logClear(); return FALSE; } BOOL INSTAPI SQLInstallTranslatorExW(LPCWSTR lpszTranslator, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount) { inst_logClear(); return FALSE; } unixODBC-2.3.12/odbcinst/SQLInstallerError.c000066400000000000000000000147651446441710500205350ustar00rootroot00000000000000/************************************************** * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include /*! * \brief Standard installer error. */ typedef struct tODBCINSTErrorMsg { int nCode; /*!< error code */ char * szMsg; /*!< error text */ } ODBCINSTErrorMsg; /*! * \brief A lookup for all standard installer (odbcinst) error codes and * corresponding message text. * * An odd thing that we do here is that we assume the values of error codes * (ODBC_ERROR_GENERAL_ERR, ODBC_ERROR_INVALID_BUFF_LEN, etc) are in the same * sequence we have layed out here... ascending order starting at 1. We then * can index into here using the standard error code and get the standard error * text. This is why we have 0,"Filler" in here. */ static ODBCINSTErrorMsg aODBCINSTErrorMsgs[] = { { 0, "Filler" }, { ODBC_ERROR_GENERAL_ERR, "General installer error" }, { ODBC_ERROR_INVALID_BUFF_LEN, "Invalid buffer length" }, { ODBC_ERROR_INVALID_HWND, "Invalid window handle" }, { ODBC_ERROR_INVALID_STR, "Invalid string" }, { ODBC_ERROR_INVALID_REQUEST_TYPE, "Invalid type of request" }, { ODBC_ERROR_COMPONENT_NOT_FOUND, "Unable to find component name" }, { ODBC_ERROR_INVALID_NAME, "Invalid driver or translator name" }, { ODBC_ERROR_INVALID_KEYWORD_VALUE, "Invalid keyword-value pairs" }, { ODBC_ERROR_INVALID_DSN, "Invalid DSN" }, { ODBC_ERROR_INVALID_INF, "Invalid INF" }, { ODBC_ERROR_REQUEST_FAILED, "General error request failed" }, { ODBC_ERROR_INVALID_PATH, "Invalid install path" }, { ODBC_ERROR_LOAD_LIB_FAILED, "Could not load the driver or translator setup library" }, { ODBC_ERROR_INVALID_PARAM_SEQUENCE, "Invalid parameter sequence" }, { ODBC_ERROR_INVALID_LOG_FILE, "Invalid log file" }, { ODBC_ERROR_USER_CANCELED, "User canceled operation" }, { ODBC_ERROR_USAGE_UPDATE_FAILED, "Could not increment or decrement the component usage count" }, { ODBC_ERROR_CREATE_DSN_FAILED, "Could not create the requested DSN" }, { ODBC_ERROR_WRITING_SYSINFO_FAILED, "Error writing sysinfo" }, { ODBC_ERROR_REMOVE_DSN_FAILED, "Removing DSN failed" }, { ODBC_ERROR_OUT_OF_MEM, "Out of memory" }, { ODBC_ERROR_OUTPUT_STRING_TRUNCATED, "String right truncated" } }; /*! * \brief Returns error information from odbcinst. * * All calls to odbcinst, except SQLInstallerError and SQLPostInstallerError, may * post/log messages. An application checks the return value of a call and then * calls SQLInstallerError, as needed, to get any error information. * * All calls to odbcinst, except SQLInstallerError and SQLPostInstallerError, will * start by clearing out existing messages. * * \param nError Input. Messages are enumerated starting with 1 as the oldest. The * ODBC specification states that there are a max 8 messages stored at * any time but unixODBC may provide more than that. * \param pnErrorCode Output. The odbcinst error code as per the ODBC specification. * \param pszErrorMsg Output. The error text. In general this is the error text from * the ODBC specification but unixODBC may provide an alternate, more * meaningfull text. * \param nErrorMsgMax Input. Max chars which can be returned in pszErrorMsg. * \param pnErrorMsg Output. strlen of error text available to be returned. * * \return RETCODE * \retval SQL_NO_DATA No data to be returned for nError. * \retval SQL_ERROR Something went wrong - most likley bad args in call. * \retval SQL_SUCCESS_WITH_INFO Text was truncated. * \retval SQL_SUCCESS Error information was returned. * * \sa SQLPostInstallerError * ODBCINSTErrorMsg */ RETCODE SQLInstallerError( WORD nError, DWORD *pnErrorCode, LPSTR pszErrorMsg, WORD nErrorMsgMax, WORD *pnErrorMsg ) { HLOGMSG hLogMsg = NULL; WORD nErrorMsg = 0; char * pszText = NULL; /* these are mandatory so... */ if ( pnErrorCode == NULL || pszErrorMsg == NULL ) return SQL_ERROR; /* this is optional so... */ if ( !pnErrorMsg ) pnErrorMsg = &nErrorMsg; /* get our message */ if ( inst_logPeekMsg( nError, &hLogMsg ) != LOG_SUCCESS ) return SQL_NO_DATA; /* return code */ *pnErrorCode = hLogMsg->nCode; /* any custom message has precedence over the standard messages since its probably more meaningfull */ if ( *(hLogMsg->pszMessage) ) pszText = hLogMsg->pszMessage; else pszText = aODBCINSTErrorMsgs[hLogMsg->nCode].szMsg; /* how many chars in error text? */ *pnErrorMsg = strlen( pszText ); /* are we going to have to truncate the text due to lack of buffer space? */ if ( *pnErrorMsg > nErrorMsgMax ) { strncpy( pszErrorMsg, pszText, nErrorMsgMax ); pszErrorMsg[ nErrorMsgMax ] = '\0'; return SQL_SUCCESS_WITH_INFO; } /* success without further complications :) */ strcpy( pszErrorMsg, pszText ); return SQL_SUCCESS; } /*! * \brief A wide char version of SQLInstallerError. * * \sa SQLInstallerError */ SQLRETURN INSTAPI SQLInstallerErrorW(WORD iError, DWORD *pfErrorCode, LPWSTR lpszErrorMsg, WORD cbErrorMsgMax, WORD *pcbErrorMsg) { char *msg; SQLRETURN ret; WORD len; if ( lpszErrorMsg ) { if ( cbErrorMsgMax > 0 ) { msg = calloc( cbErrorMsgMax + 1, 1 ); } else { msg = NULL; } } else { msg = NULL; } ret = SQLInstallerError( iError, pfErrorCode, msg, cbErrorMsgMax, &len ); if ( ret == SQL_SUCCESS ) { if ( pcbErrorMsg ) *pcbErrorMsg = len; if ( msg && lpszErrorMsg ) { _single_copy_to_wide( lpszErrorMsg, msg, len + 1 ); } } else if ( ret == SQL_SUCCESS_WITH_INFO ) { if ( pcbErrorMsg ) *pcbErrorMsg = len; if ( msg && lpszErrorMsg ) { _single_copy_to_wide( lpszErrorMsg, msg, cbErrorMsgMax ); } } if ( msg ) { free( msg ); } return ret; } unixODBC-2.3.12/odbcinst/SQLManageDataSources.c000066400000000000000000000147401446441710500211050ustar00rootroot00000000000000/************************************************** * SQLManageDataSources * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #ifdef UNIXODBC_SOURCE #include #endif #include /*! * \brief Get the short name of the UI plugin. * * The short name is the file name without path or file extension. * * We silently prepend "lib" here as well. * * \param pszName Place to put short name. Should be FILENAME_MAX bytes. * \param pszUI Our generic window handle. * * \return char* pszName returned for convenience. */ char *_getUIPluginName( char *pszName, char *pszUI ) { *pszName = '\0'; /* is it being provided by caller? */ if ( pszUI && *pszUI ) { sprintf( pszName, "lib%s", pszUI ); return pszName; } /* is it being provided by env var? */ { char *pEnvVar = getenv( "ODBCINSTUI" ); if ( pEnvVar ) { sprintf( pszName, "lib%s", pEnvVar ); return pszName; } } /* is it being provided by odbcinst.ini? */ { char sz[FILENAME_MAX]; *sz='\0'; SQLGetPrivateProfileString( "ODBC", "ODBCINSTUI", "", sz, FILENAME_MAX, "odbcinst.ini" ); if ( *sz ) { sprintf( pszName, "lib%s", sz ); return pszName; } } /* default to qt4 */ strcpy( pszName, ODBCINSTPLUGIN ); return pszName; } /*! * \brief Append the file extension used by the OS for plugins. * * We use SHLIBEXT which is picked up at configure/build time. * * \param pszNameAndExtension Output. Needs to be FILENAME_MAX bytes. * \param pszName Input. * * \return char* pszNameAndExtension returned for convenience. */ char *_appendUIPluginExtension( char *pszNameAndExtension, char *pszName ) { if ( strlen( SHLIBEXT ) > 0 ) sprintf( pszNameAndExtension, "%s%s", pszName, SHLIBEXT ); else sprintf( pszNameAndExtension, "%s.so", pszName ); return pszName; } /*! * \brief Prepends the path used for the plugins. * * We use DEFLIB_PATH and if it is not available... * path may not get prepended. * * \param pszPathAndName Output. Needs to be FILENAME_MAX bytes. * \param pszName Input. * * \return char* pszPathAndName is returned for convenience. */ char *_prependUIPluginPath( char *pszPathAndName, char *pszName ) { if ( strlen( DEFLIB_PATH ) > 0 ) sprintf( pszPathAndName, "%s/%s", DEFLIB_PATH, pszName ); else sprintf( pszPathAndName, "%s", pszName ); return pszPathAndName; } /*! * \brief UI to manage most ODBC system information. * * This calls into the UI plugin library to do our work for us. The caller can provide * the name (base name) of the library or let us determine which library to use. * See \sa _getUIPluginName for details on how the choice is made. * * \param hWnd Input. Parent window handle. This is HWND as per the ODBC * specification but in unixODBC we use a generic window * handle. Caller must cast a HODBCINSTWND to HWND at call. * * \return BOOL * * \sa ODBCINSTWND */ BOOL SQLManageDataSources( HWND hWnd ) { HODBCINSTWND hODBCInstWnd = (HODBCINSTWND)hWnd; char szName[FILENAME_MAX]; char szNameAndExtension[FILENAME_MAX]; char szPathAndName[FILENAME_MAX]; void * hDLL; BOOL (*pSQLManageDataSources)(HWND); inst_logClear(); /* ODBC specification states that hWnd is mandatory. */ if ( !hWnd ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_HWND, "No hWnd" ); return FALSE; } /* initialize libtool */ if ( lt_dlinit() ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "lt_dlinit() failed" ); return FALSE; } #ifdef MODULEDIR lt_dlsetsearchpath(MODULEDIR); #endif /* get plugin name */ _appendUIPluginExtension( szNameAndExtension, _getUIPluginName( szName, hODBCInstWnd->szUI ) ); /* lets try loading the plugin using an implicit path */ hDLL = lt_dlopen( szNameAndExtension ); if ( hDLL ) { /* change the name (SQLManageDataSources to ODBCManageDataSources) to prevent us from calling ourself */ pSQLManageDataSources = (BOOL (*)(HWND))lt_dlsym( hDLL, "ODBCManageDataSources" ); if ( pSQLManageDataSources ) { BOOL ret; ret = pSQLManageDataSources( ( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ) ); lt_dlclose( hDLL ); return ret; } else inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() ); lt_dlclose( hDLL ); } else { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_WARNING, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() ); /* try with explicit path */ _prependUIPluginPath( szPathAndName, szNameAndExtension ); hDLL = lt_dlopen( szPathAndName ); if ( hDLL ) { /* change the name (SQLManageDataSources to ODBCManageDataSources) to prevent us from calling ourself */ /* its only safe to use hWnd if szUI was specified by the caller */ pSQLManageDataSources = (BOOL (*)(HWND))lt_dlsym( hDLL, "ODBCManageDataSources" ); if ( pSQLManageDataSources ) { BOOL ret; ret = pSQLManageDataSources( ( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ) ); lt_dlclose( hDLL ); return ret; } else inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() ); lt_dlclose( hDLL ); } else inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, (char*)lt_dlerror() ); } /* report failure to caller */ inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "Failed to load/use a UI plugin." ); return FALSE; } unixODBC-2.3.12/odbcinst/SQLPostInstallerError.c000066400000000000000000000023711446441710500213710ustar00rootroot00000000000000/********************************************** * SQLPostInstallerError * * Drivers can call me to let me know there was a * problem. This can be retreived by the app using * SQLInstallerError. * * Does not currently use szErrorMsg due to extreme * limitations of logging here. This should be corrected. * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include RETCODE SQLPostInstallerError( DWORD nErrorCode, LPCSTR szErrorMsg ) { if ( nErrorCode > ODBC_ERROR_OUTPUT_STRING_TRUNCATED ) return SQL_ERROR; inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, nErrorCode, (char *)szErrorMsg ); return SQL_SUCCESS; } SQLRETURN INSTAPI SQLPostInstallerErrorW(DWORD dwErrorCode, LPCWSTR lpszErrorMsg) { char *msg = lpszErrorMsg ? _single_string_alloc_and_copy( lpszErrorMsg ) : (char*)NULL; SQLRETURN ret; ret = SQLPostInstallerError( dwErrorCode, msg ); if ( msg ) free( msg ); return ret; } unixODBC-2.3.12/odbcinst/SQLReadFileDSN.c000066400000000000000000000173051446441710500175770ustar00rootroot00000000000000/************************************************** * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include static void GetEntries( HINI hIni, LPCSTR pszSection, LPSTR pRetBuffer, int nRetBuffer ) { char szPropertyName[INI_MAX_PROPERTY_NAME+1]; char szValueName[INI_MAX_PROPERTY_NAME+1]; /* COLLECT ALL ENTRIES FOR THE GIVEN SECTION */ iniObjectSeek( hIni, (char *)pszSection ); iniPropertyFirst( hIni ); *pRetBuffer = '\0'; while ( iniPropertyEOL( hIni ) != TRUE ) { iniProperty( hIni, szPropertyName ); iniValue( hIni, szValueName ); if ( strlen( pRetBuffer ) + strlen( szPropertyName ) < nRetBuffer ) { strcat( pRetBuffer, szPropertyName ); if ( strlen( pRetBuffer ) + 1 < nRetBuffer ) { strcat( pRetBuffer, "=" ); if ( strlen( pRetBuffer ) + strlen( szValueName ) < nRetBuffer ) { strcat( pRetBuffer, szValueName ); if ( strlen( pRetBuffer ) + 1 < nRetBuffer ) { strcat( pRetBuffer, ";" ); } } } } iniPropertyNext( hIni ); } } static void GetSections( HINI hIni, LPSTR pRetBuffer, int nRetBuffer ) { char szObjectName[INI_MAX_OBJECT_NAME+1]; *pRetBuffer = '\0'; /* JUST COLLECT SECTION NAMES */ iniObjectFirst( hIni ); while ( iniObjectEOL( hIni ) != TRUE ) { iniObject( hIni, szObjectName ); if ( strcasecmp( szObjectName, "ODBC Data Sources" ) != 0 ) { if ( strlen( pRetBuffer ) + strlen( szObjectName ) + 1 < nRetBuffer ) { strcat( pRetBuffer, szObjectName ); strcat( pRetBuffer, ";" ); } } iniObjectNext( hIni ); } } BOOL SQLReadFileDSN( LPCSTR pszFileName, LPCSTR pszAppName, LPCSTR pszKeyName, LPSTR pszString, WORD nString, WORD *pnString ) { HINI hIni; char szValue[INI_MAX_PROPERTY_VALUE+1]; char szFileName[ODBC_FILENAME_MAX+1]; inst_logClear(); /* SANITY CHECKS */ if ( pszString == NULL || nString < 1 ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_BUFF_LEN, "" ); return FALSE; } if ( pszFileName == NULL && pszAppName == NULL && pszKeyName == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } if ( pszAppName == NULL && pszKeyName != NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_REQUEST_TYPE, "" ); return FALSE; } if ( pszFileName && strlen( pszFileName ) > ODBC_FILENAME_MAX ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_PATH, "" ); return FALSE; } *pszString = '\0'; /***************************************************** * GATHER ALL RELEVANT DSN INFORMATION INTO AN hIni *****************************************************/ if ( pszFileName && pszFileName[0] == '/' ) { strcpy( szFileName, pszFileName ); if ( strlen( szFileName ) < 4 || strcmp( szFileName + strlen( szFileName ) - 4, ".dsn" )) { strcat( szFileName, ".dsn" ); } /* on OS/2 the file DSN is a text file */ #ifdef __OS2__ if ( iniOpen( &hIni, (char*)szFileName, "#;", '[', ']', '=', TRUE, 0L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, (char*)szFileName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_PATH, "" ); return FALSE; } } else if ( pszFileName ) { char szPath[ODBC_FILENAME_MAX+1]; *szPath = '\0'; _odbcinst_FileINI( szPath ); #ifdef HAVE_SNPRINTF snprintf( szFileName, sizeof( szFileName ), "%s/%s", szPath, pszFileName ); #else sprintf( szFileName, "%s/%s", szPath, pszFileName ); #endif if ( strlen( szFileName ) < 4 || strcmp( szFileName + strlen( szFileName ) - 4, ".dsn" )) { strcat( szFileName, ".dsn" ); } /* on OS/2 the file DSN is a text file */ #ifdef __OS2__ if ( iniOpen( &hIni, (char*) szFileName, "#;", '[', ']', '=', TRUE, 0L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, (char*) szFileName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_PATH, "" ); return FALSE; } } if ( pszAppName == NULL && pszKeyName == NULL ) { GetSections( hIni, pszString, nString ); } else if ( pszAppName != NULL && pszKeyName == NULL ) { GetEntries( hIni, pszAppName, pszString, nString ); } else { /* TRY TO GET THE ONE ITEM MATCHING Section & Entry */ if ( iniPropertySeek( hIni, (char *)pszAppName, (char *)pszKeyName, "" ) != INI_SUCCESS ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_REQUEST_FAILED, "" ); if ( pszFileName ) { iniClose( hIni ); } return FALSE; } else { iniValue( hIni, szValue ); strncpy( pszString, szValue, nString ); pszString[ nString - 1 ] = '\0'; } } if ( pszFileName ) { iniClose( hIni ); } if ( pnString ) { *pnString = strlen( pszString ); } return TRUE; } BOOL INSTAPI SQLReadFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName, LPCWSTR lpszKeyName, LPWSTR lpszString, WORD cbString, WORD *pcbString) { char *file; char *app; char *key; char *str; WORD len; BOOL ret; inst_logClear(); file = lpszFileName ? _single_string_alloc_and_copy( lpszFileName ) : (char*)NULL; app = lpszAppName ? _single_string_alloc_and_copy( lpszAppName ) : (char*)NULL; key = lpszKeyName ? _single_string_alloc_and_copy( lpszKeyName ) : (char*)NULL; if ( lpszString ) { if ( cbString > 0 ) { str = calloc( cbString + 1, 1 ); } else { str = NULL; } } else { str = NULL; } ret = SQLReadFileDSN( file, app, key, str, cbString, &len ); if ( ret ) { if ( str && lpszString ) { len = _single_copy_to_wide( lpszString, str, len + 1 ); } } if ( file ) free( file ); if ( app ) free( app ); if ( key ) free( key ); if ( str ) free( str ); if ( pcbString ) *pcbString = len; return ret; } unixODBC-2.3.12/odbcinst/SQLRemoveDSNFromIni.c000066400000000000000000000037441446441710500206470ustar00rootroot00000000000000/******************************************** * SQLRemoveDSNFromIni * * Use the current Config Mode to determine the * odbc.ini we will use. * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL SQLRemoveDSNFromIni(LPCSTR pszDSN ) { HINI hIni; char szINIFileName[ODBC_FILENAME_MAX+1]; inst_logClear(); /* SANITY CHECKS */ if ( pszDSN == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_DSN, "" ); return FALSE; } if ( pszDSN[0] == '\0' ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_DSN, "" ); return FALSE; } /* GET ODBC INI FILE NAME */ if ( _odbcinst_ConfigModeINI( szINIFileName ) == FALSE ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" ); return FALSE; } #ifdef __OS2__ if ( iniOpen( &hIni, szINIFileName, "#;", '[', ']', '=', FALSE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szINIFileName, "#;", '[', ']', '=', FALSE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" ); return FALSE; } if ( iniObjectSeek( hIni, (char *)pszDSN ) == INI_SUCCESS ) { iniObjectDelete( hIni ); if ( iniCommit( hIni ) != INI_SUCCESS ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); iniClose( hIni ); return FALSE; } } iniClose( hIni ); return TRUE; } BOOL INSTAPI SQLRemoveDSNFromIniW(LPCWSTR lpszDSN) { char *dsn; BOOL ret; inst_logClear(); dsn = _single_string_alloc_and_copy( lpszDSN ); ret = SQLRemoveDSNFromIni( dsn ); free( dsn ); return ret; } unixODBC-2.3.12/odbcinst/SQLRemoveDriver.c000066400000000000000000000065131446441710500201670ustar00rootroot00000000000000/************************************************** * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL SQLRemoveDriver( LPCSTR pszDriver, BOOL nRemoveDSN, LPDWORD pnUsageCount ) { HINI hODBCInstIni; char szValue[INI_MAX_PROPERTY_VALUE+1]; char szIniName[ ODBC_FILENAME_MAX * 2 + 1 ]; char b1[ ODBC_FILENAME_MAX + 1 ], b2[ ODBC_FILENAME_MAX + 1 ]; inst_logClear(); /* SANITY CHECKS */ if ( pszDriver == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_NAME, "" ); return FALSE; } if ( pszDriver[0] == '\0' ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_NAME, "" ); return FALSE; } if ( nRemoveDSN != TRUE && nRemoveDSN != FALSE ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } (*pnUsageCount) = 0; #ifdef VMS sprintf( szIniName, "%s:%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ) ); #else sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ) ); #endif /* PROCESS ODBC INST INI FILE */ #ifdef __OS2__ if ( iniOpen( &hODBCInstIni, szIniName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hODBCInstIni, szIniName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" ); return FALSE; } /* LETS GET ITS FILE USAGE VALUE (if any) */ if ( iniPropertySeek( hODBCInstIni, (char *)pszDriver, "UsageCount", "" ) == INI_SUCCESS ) { iniValue( hODBCInstIni, szValue ); (*pnUsageCount) = atoi( szValue ); } /* DOES THE OBJECT ALREADY EXIST? (also ensures that we have correct current object) */ if ( iniObjectSeek( hODBCInstIni, (char *)pszDriver ) == INI_SUCCESS ) { if ( (*pnUsageCount) == 0 ) (*pnUsageCount) = 1; (*pnUsageCount)--; if ( (*pnUsageCount) == 0 ) { iniObjectDelete( hODBCInstIni ); if ( nRemoveDSN ) { /*********************************** * TO DO ***********************************/ } } else { if ( iniPropertySeek( hODBCInstIni, (char *)pszDriver, "UsageCount", "" ) == INI_SUCCESS ) { sprintf( szValue, "%ld", (long int)(*pnUsageCount) ); iniPropertyUpdate( hODBCInstIni, "UsageCount", szValue ); } else { iniPropertyInsert( hODBCInstIni, "UsageCount", szValue ); } } if ( iniCommit( hODBCInstIni ) != INI_SUCCESS ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); iniClose( hODBCInstIni ); return FALSE; } } iniClose( hODBCInstIni ); return TRUE; } BOOL INSTAPI SQLRemoveDriverW(LPCWSTR lpszDriver, BOOL fRemoveDSN, LPDWORD lpdwUsageCount) { BOOL ret; char *drv = _single_string_alloc_and_copy( lpszDriver ); inst_logClear(); ret = SQLRemoveDriver( drv, fRemoveDSN, lpdwUsageCount ); free( drv ); return ret; } unixODBC-2.3.12/odbcinst/SQLRemoveDriverManager.c000066400000000000000000000012601446441710500214540ustar00rootroot00000000000000/************************************************** * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL SQLRemoveDriverManager( LPDWORD pnUsageCount ) { inst_logClear(); if ( pnUsageCount == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } *pnUsageCount = 1; return TRUE; } unixODBC-2.3.12/odbcinst/SQLRemoveTranslator.c000066400000000000000000000012711446441710500210610ustar00rootroot00000000000000/************************************************** * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL SQLRemoveTranslator( LPCSTR pszTranslator, LPDWORD pnUsageCount ) { inst_logClear(); return FALSE; } BOOL INSTAPI SQLRemoveTranslatorW(LPCWSTR lpszTranslator, LPDWORD lpdwUsageCount) { inst_logClear(); return FALSE; } unixODBC-2.3.12/odbcinst/SQLSetConfigMode.c000066400000000000000000000024751446441710500202470ustar00rootroot00000000000000/************************************************** * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com * Nick Gorham - nick@lurcher.org **************************************************/ #include #include #include /* * This avoids all sorts of problems with using putenv, we need to check * that drivers can see this as well though.... */ static int __config_mode = ODBC_BOTH_DSN; void __set_config_mode( int mode ) { __config_mode = mode; } int __get_config_mode( void ) { char *p; /* * if the environment var is set then it overrides the flag */ p = getenv( "ODBCSEARCH" ); if ( p ) { if ( strcmp( p, "ODBC_SYSTEM_DSN" ) == 0 ) { __config_mode = ODBC_SYSTEM_DSN; } else if ( strcmp( p, "ODBC_USER_DSN" ) == 0 ) { __config_mode = ODBC_USER_DSN; } else if ( strcmp( p, "ODBC_BOTH_DSN" ) == 0 ) { __config_mode = ODBC_BOTH_DSN; } } return __config_mode; } BOOL SQLSetConfigMode( UWORD nConfigMode ) { inst_logClear(); __set_config_mode( nConfigMode ); return TRUE; } unixODBC-2.3.12/odbcinst/SQLValidDSN.c000066400000000000000000000031271446441710500171600ustar00rootroot00000000000000/************************************************** * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include #define SQL_MAX_DSN_LENGTH 32 BOOL SQLValidDSN( LPCSTR pszDSN ) { inst_logClear(); if ( pszDSN == NULL ) return FALSE; if ( strlen( pszDSN ) < 1 || strlen( pszDSN ) > SQL_MAX_DSN_LENGTH ) return FALSE; if ( strstr( pszDSN, "[" ) != NULL ) return FALSE; if ( strstr( pszDSN, "]" ) != NULL ) return FALSE; if ( strstr( pszDSN, "{" ) != NULL ) return FALSE; if ( strstr( pszDSN, "}" ) != NULL ) return FALSE; if ( strstr( pszDSN, "(" ) != NULL ) return FALSE; if ( strstr( pszDSN, ")" ) != NULL ) return FALSE; if ( strstr( pszDSN, "," ) != NULL ) return FALSE; if ( strstr( pszDSN, ";" ) != NULL ) return FALSE; if ( strstr( pszDSN, "?" ) != NULL ) return FALSE; if ( strstr( pszDSN, "*" ) != NULL ) return FALSE; if ( strstr( pszDSN, "=" ) != NULL ) return FALSE; if ( strstr( pszDSN, "!" ) != NULL ) return FALSE; if ( strstr( pszDSN, "@" ) != NULL ) return FALSE; if ( strstr( pszDSN, "\\" ) != NULL ) return FALSE; return TRUE; } BOOL INSTAPI SQLValidDSNW(LPCWSTR lpszDSN) { char *dsn; BOOL ret; inst_logClear(); dsn = _single_string_alloc_and_copy( lpszDSN ); ret = SQLValidDSN( dsn ); free( dsn ); return ret; } unixODBC-2.3.12/odbcinst/SQLWriteDSNToIni.c000066400000000000000000000052411446441710500201550ustar00rootroot00000000000000/************************************************** * SQLWriteDSNToIni * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include extern void __clear_ini_cache( void ); BOOL SQLWriteDSNToIni( LPCSTR pszDSN, LPCSTR pszDriver ) { HINI hIni; char szFileName[ODBC_FILENAME_MAX+1]; SQLRemoveDSNFromIni( pszDSN ); /* SANITY CHECKS */ if ( pszDSN == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } if ( pszDSN[0] == '\0' ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } if ( (strcasecmp( pszDSN, "DEFAULT" ) != 0 ) && (pszDriver == NULL ) ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_NAME, "" ); return FALSE; } if ( (strcasecmp( pszDSN, "DEFAULT" ) != 0 ) && (pszDriver[0] == '\0') ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_NAME, "" ); return FALSE; } if ( SQLValidDSN( pszDSN ) == FALSE ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_DSN, "" ); return FALSE; } /* OK */ if ( _odbcinst_ConfigModeINI( szFileName ) == FALSE ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_REQUEST_FAILED, "" ); return FALSE; } #ifdef __OS2__ if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_REQUEST_FAILED, "" ); return FALSE; } iniObjectInsert( hIni, (char *)pszDSN ); if ( pszDriver != NULL ) { iniPropertyInsert( hIni, "Driver", (char *)pszDriver ); } if ( iniCommit( hIni ) != INI_SUCCESS ) { iniClose( hIni ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_REQUEST_FAILED, "" ); return FALSE; } iniClose( hIni ); __clear_ini_cache(); return TRUE; } BOOL INSTAPI SQLWriteDSNToIniW (LPCWSTR lpszDSN, LPCWSTR lpszDriver) { char *drv, *dsn; BOOL ret; dsn = _single_string_alloc_and_copy( lpszDSN ); drv = _single_string_alloc_and_copy( lpszDriver ); ret = SQLWriteDSNToIni( dsn, drv ); free( dsn ); free( drv ); return ret; } unixODBC-2.3.12/odbcinst/SQLWriteFileDSN.c000066400000000000000000000063031446441710500200120ustar00rootroot00000000000000/************************************************** * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL SQLWriteFileDSN( LPCSTR pszFileName, LPCSTR pszAppName, LPCSTR pszKeyName, LPCSTR pszString ) { HINI hIni; char szFileName[ODBC_FILENAME_MAX+1]; if ( pszFileName[0] == '/' ) { strncpy( szFileName, pszFileName, sizeof(szFileName) - 5 ); } else { char szPath[ODBC_FILENAME_MAX+1]; *szPath = '\0'; _odbcinst_FileINI( szPath ); snprintf( szFileName, sizeof(szFileName) - 5, "%s/%s", szPath, pszFileName ); } if ( strlen( szFileName ) < 4 || strcmp( szFileName + strlen( szFileName ) - 4, ".dsn" )) { strcat( szFileName, ".dsn" ); } #ifdef __OS2__ if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE, 0L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_INVALID_PATH, "" ); return FALSE; } /* delete section */ if ( pszString == NULL && pszKeyName == NULL ) { if ( iniObjectSeek( hIni, (char *)pszAppName ) == INI_SUCCESS ) { iniObjectDelete( hIni ); } } /* delete entry */ else if ( pszString == NULL ) { if ( iniPropertySeek( hIni, (char *)pszAppName, (char *)pszKeyName, "" ) == INI_SUCCESS ) { iniPropertyDelete( hIni ); } } else { /* add section */ if ( iniObjectSeek( hIni, (char *)pszAppName ) != INI_SUCCESS ) { iniObjectInsert( hIni, (char *)pszAppName ); } /* update entry */ if ( iniPropertySeek( hIni, (char *)pszAppName, (char *)pszKeyName, "" ) == INI_SUCCESS ) { iniObjectSeek( hIni, (char *)pszAppName ); iniPropertyUpdate( hIni, (char *)pszKeyName, (char *)pszString ); } /* add entry */ else { iniObjectSeek( hIni, (char *)pszAppName ); iniPropertyInsert( hIni, (char *)pszKeyName, (char *)pszString ); } } if ( iniCommit( hIni ) != INI_SUCCESS ) { iniClose( hIni ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_REQUEST_FAILED, "" ); return FALSE; } iniClose( hIni ); return TRUE; } BOOL INSTAPI SQLWriteFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName, LPCWSTR lpszKeyName, LPCWSTR lpszString) { BOOL ret; char *file; char *app; char *key; char *str; file = lpszFileName ? _single_string_alloc_and_copy( lpszFileName ) : (char*)NULL; app = lpszAppName ? _single_string_alloc_and_copy( lpszAppName ) : (char*)NULL; key = lpszKeyName ? _single_string_alloc_and_copy( lpszKeyName ) : (char*)NULL; str = lpszString ? _single_string_alloc_and_copy( lpszString ) : (char*)NULL; ret = SQLWriteFileDSN( file, app, key, str ); if ( file ) free( file ); if ( app ) free( app ); if ( key ) free( key ); if ( str ) free( str ); return ret; } unixODBC-2.3.12/odbcinst/SQLWritePrivateProfileString.c000066400000000000000000000102441446441710500227070ustar00rootroot00000000000000/************************************************** * SQLWritePrivateProfileString * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include extern void __clear_ini_cache( void ); BOOL SQLWritePrivateProfileString( LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszString, LPCSTR pszFileName ) { HINI hIni; char szFileName[ODBC_FILENAME_MAX+1]; inst_logClear(); /* SANITY CHECKS */ if ( pszSection == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } if ( pszSection[0] == '\0' ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } if ( pszFileName == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } /***************************************************** * SOME MS CODE (ie some drivers) MAY USE THIS FUNCTION TO WRITE ODBCINST INFO SO... *****************************************************/ if ( strstr( pszFileName, "odbcinst" ) || strstr( pszFileName, "ODBCINST" ) ) return _SQLWriteInstalledDrivers( pszSection, pszEntry, pszString ); if ( pszFileName[0] == '/' ) { strcpy( szFileName, pszFileName ); } else { if ( !*pszFileName || _odbcinst_ConfigModeINI( szFileName ) == FALSE ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_REQUEST_FAILED, "" ); return FALSE; } } #ifdef __OS2__ if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szFileName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_REQUEST_FAILED, "" ); return FALSE; } /* delete section */ if ( pszEntry == NULL ) { if ( iniObjectSeek( hIni, (char *)pszSection ) == INI_SUCCESS ) iniObjectDelete( hIni ); } /* delete entry */ else if ( pszString == NULL ) { if ( iniPropertySeek( hIni, (char *)pszSection, (char *)pszEntry, "" ) == INI_SUCCESS ) { iniPropertyDelete( hIni ); } } else { /* add section */ if ( iniObjectSeek( hIni, (char *)pszSection ) != INI_SUCCESS ) iniObjectInsert( hIni, (char *)pszSection ); /* update entry */ if ( iniPropertySeek( hIni, (char *)pszSection, (char *)pszEntry, "" ) == INI_SUCCESS ) { iniObjectSeek( hIni, (char *)pszSection ); /* * Get the correct property to update */ iniPropertySeek( hIni, (char *)pszSection, (char *)pszEntry, "" ); iniPropertyUpdate( hIni, (char *)pszEntry, (char *)pszString ); } /* add entry */ else { iniObjectSeek( hIni, (char *)pszSection ); iniPropertyInsert( hIni, (char *)pszEntry, (char *)pszString ); } } if ( iniCommit( hIni ) != INI_SUCCESS ) { iniClose( hIni ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_REQUEST_FAILED, "" ); return FALSE; } iniClose( hIni ); __clear_ini_cache(); return TRUE; } BOOL INSTAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry, LPCWSTR lpszString, LPCWSTR lpszFilename) { char *sect; char *entry; char *string; char *file; BOOL ret; sect = lpszSection ? _single_string_alloc_and_copy( lpszSection ) : (char*)NULL; entry = lpszEntry ? _single_string_alloc_and_copy( lpszEntry ) : (char*)NULL; string = lpszString ? _single_string_alloc_and_copy( lpszString ) : (char*)NULL; file = lpszFilename ? _single_string_alloc_and_copy( lpszFilename ) : (char*)NULL; ret = SQLWritePrivateProfileString( sect, entry, string, file ); if ( sect ) free( sect ); if ( entry ) free( entry ); if ( string ) free( string ); if ( file ) free( file ); return ret; } unixODBC-2.3.12/odbcinst/_SQLDriverConnectPrompt.c000066400000000000000000000110541446441710500216600ustar00rootroot00000000000000#include #ifdef UNIXODBC_SOURCE #include #endif #include BOOL _SQLDriverConnectPrompt( HWND hwnd, SQLCHAR *dsn, SQLSMALLINT len_dsn ) { HODBCINSTWND hODBCInstWnd = (HODBCINSTWND)hwnd; char szName[FILENAME_MAX]; char szNameAndExtension[FILENAME_MAX]; char szPathAndName[FILENAME_MAX]; void * hDLL; BOOL (*pODBCDriverConnectPrompt)(HWND, SQLCHAR *, SQLSMALLINT ); BOOL ret; /* initialize libtool */ if ( lt_dlinit() ) { return FALSE; } /* get plugin name */ if ( hODBCInstWnd ) { _appendUIPluginExtension( szNameAndExtension, _getUIPluginName( szName, hODBCInstWnd->szUI ) ); } else { _appendUIPluginExtension( szNameAndExtension, _getUIPluginName( szName, NULL ) ); } /* lets try loading the plugin using an implicit path */ hDLL = lt_dlopen( szNameAndExtension ); if ( hDLL ) { /* change the name, as it avoids it finding it in the calling lib */ pODBCDriverConnectPrompt = (BOOL (*)( HWND, SQLCHAR *, SQLSMALLINT ))lt_dlsym( hDLL, "ODBCDriverConnectPrompt" ); if ( pODBCDriverConnectPrompt ) { if ( hODBCInstWnd ) { ret = pODBCDriverConnectPrompt(( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ), dsn, len_dsn ); } else { ret = pODBCDriverConnectPrompt( NULL, dsn, len_dsn ); } } else { ret = FALSE; } lt_dlclose( hDLL ); return ret; } else { /* try with explicit path */ _prependUIPluginPath( szPathAndName, szNameAndExtension ); hDLL = lt_dlopen( szPathAndName ); if ( hDLL ) { /* change the name, as it avoids linker finding it in the calling lib */ pODBCDriverConnectPrompt = (BOOL (*)(HWND, SQLCHAR *, SQLSMALLINT ))lt_dlsym( hDLL, "ODBCDriverConnectPrompt" ); if ( pODBCDriverConnectPrompt ) { if ( hODBCInstWnd ) { ret = pODBCDriverConnectPrompt(( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ), dsn, len_dsn ); } else { ret = pODBCDriverConnectPrompt( NULL, dsn, len_dsn ); } } else { ret = FALSE; } lt_dlclose( hDLL ); return ret; } } return FALSE; } BOOL _SQLDriverConnectPromptW( HWND hwnd, SQLWCHAR *dsn, SQLSMALLINT len_dsn ) { HODBCINSTWND hODBCInstWnd = (HODBCINSTWND)hwnd; char szName[FILENAME_MAX]; char szNameAndExtension[FILENAME_MAX]; char szPathAndName[FILENAME_MAX]; void * hDLL; BOOL (*pODBCDriverConnectPromptW)(HWND, SQLWCHAR *, SQLSMALLINT ); BOOL ret; /* initialize libtool */ if ( lt_dlinit() ) { return FALSE; } /* get plugin name */ if ( hODBCInstWnd ) { _appendUIPluginExtension( szNameAndExtension, _getUIPluginName( szName, hODBCInstWnd->szUI ) ); } else { _appendUIPluginExtension( szNameAndExtension, _getUIPluginName( szName, NULL ) ); } /* lets try loading the plugin using an implicit path */ hDLL = lt_dlopen( szNameAndExtension ); if ( hDLL ) { /* change the name, as it avoids it finding it in the calling lib */ pODBCDriverConnectPromptW = (BOOL (*)( HWND, SQLWCHAR *, SQLSMALLINT ))lt_dlsym( hDLL, "ODBCDriverConnectPromptW" ); if ( pODBCDriverConnectPromptW ) { if ( hODBCInstWnd ) { ret = pODBCDriverConnectPromptW(( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ), dsn, len_dsn ); } else { ret = pODBCDriverConnectPromptW( NULL, dsn, len_dsn ); } } else { ret = FALSE; } lt_dlclose( hDLL ); return ret; } else { /* try with explicit path */ _prependUIPluginPath( szPathAndName, szNameAndExtension ); hDLL = lt_dlopen( szPathAndName ); if ( hDLL ) { /* change the name, as it avoids linker finding it in the calling lib */ pODBCDriverConnectPromptW = (BOOL (*)(HWND, SQLWCHAR *, SQLSMALLINT ))lt_dlsym( hDLL, "ODBCDriverConnectPromptW" ); if ( pODBCDriverConnectPromptW ) { if ( hODBCInstWnd ) { ret = pODBCDriverConnectPromptW(( *(hODBCInstWnd->szUI) ? hODBCInstWnd->hWnd : NULL ), dsn, len_dsn ); } else { ret = pODBCDriverConnectPromptW( NULL, dsn, len_dsn ); } } else { ret = FALSE; } lt_dlclose( hDLL ); return ret; } } return FALSE; } unixODBC-2.3.12/odbcinst/_SQLGetInstalledDrivers.c000066400000000000000000000124261446441710500216330ustar00rootroot00000000000000/************************************************** * _SQLGetInstalledDrivers * * Added to allow ODBC Config programs and the ODBC * driver manager to access system information without * having to worry about where it is... just like accessing * Data Source information. So no surprise... its just * like SQLGetPrivateProfileString()! * * see SQLGetPrivateProfileString to see how this is called. * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include int _SQLGetInstalledDrivers( LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszDefault, LPCSTR pRetBuffer, int nRetBuffer ) { HINI hIni; int nBufPos = 0; int nStrToCopy; char szObjectName[INI_MAX_OBJECT_NAME+1]; char szPropertyName[INI_MAX_PROPERTY_NAME+1]; char szValue[INI_MAX_PROPERTY_VALUE+1]; char szIniName[ ODBC_FILENAME_MAX * 2 + 3 ]; char *ptr; char b1[ ODBC_FILENAME_MAX + 1 ], b2[ ODBC_FILENAME_MAX + 1 ]; /* SANITY CHECKS */ if ( pRetBuffer == NULL || nRetBuffer < 2 ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return -1; } /* * first try in the system odbcinst.ini */ #ifdef VMS sprintf( szIniName, "%s:%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 )); #else sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 )); #endif /* PROCESS ODBC INI FILE */ #ifdef __OS2__ if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', 1, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', 1 ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_COMPONENT_NOT_FOUND, "" ); return -1; } /* * now try the user odbcinst.ini if it exists */ #ifdef VMS sprintf( szIniName, "%s:%s", odbcinst_user_file_path( b1 ), odbcinst_user_file_name( b2 )); #else sprintf( szIniName, "%s/%s", odbcinst_user_file_path( b1 ), odbcinst_user_file_name( b2 )); #endif /* PROCESS .ODBCINST INI FILE */ iniAppend( hIni, szIniName ); nBufPos = 0; if ( pszSection == NULL ) { ptr = (char*) pRetBuffer; *ptr = '\0'; /* JUST COLLECT SECTION NAMES */ for( iniObjectFirst( hIni ); iniObjectEOL( hIni ) != TRUE; iniObjectNext( hIni )) { iniObject( hIni, szObjectName ); if ( strcasecmp( szObjectName, "ODBC" ) == 0 ) { continue; } else if ( nBufPos + 1 + strlen( szObjectName ) >= nRetBuffer ) { break; } else { strcpy( ptr, szObjectName ); ptr += strlen( ptr ) + 1; nBufPos += strlen( szObjectName ) + 1; } } /* * Add final NULL */ if ( nBufPos == 0 ) { ptr ++; } *ptr = '\0'; } else if ( pszEntry == NULL ) { ptr = (char*) pRetBuffer; *ptr = '\0'; iniObjectSeek( hIni, (char *)pszSection ); /* COLLECT ALL ENTRIES FOR THE GIVEN SECTION */ for( iniPropertyFirst( hIni ); iniPropertyEOL( hIni ) != TRUE; iniPropertyNext( hIni )) { iniProperty( hIni, szPropertyName ); if ( nBufPos + 1 + strlen( szPropertyName ) >= nRetBuffer ) { break; } else { strcpy( ptr, szPropertyName ); ptr += strlen( ptr ) + 1; nBufPos += strlen( szPropertyName ) + 1; } } /* * Add final NULL */ if ( nBufPos == 0 ) { ptr ++; } } else { /* TRY TO GET THE ONE ITEM MATCHING Section & Entry */ if ( iniPropertySeek( hIni, (char *)pszSection, (char *)pszEntry, "" ) != INI_SUCCESS ) { /* try to use any default provided */ if ( pRetBuffer && nRetBuffer > 0 ) { if ( pszDefault ) { strncpy( (char *)pRetBuffer, pszDefault, nRetBuffer ); ((char*)pRetBuffer)[ nRetBuffer - 1 ] = '\0'; } } } else { iniValue( hIni, szValue ); nStrToCopy = strlen( szValue ) + 1; /* factor NULL terminator for string */ if ( nBufPos + nStrToCopy + 1 > nRetBuffer ) /* factor NULL terminator for buffer */ nStrToCopy = nRetBuffer - nBufPos - 2; strncpy( (char *)&(pRetBuffer[nBufPos]), szValue, nStrToCopy ); nBufPos += nStrToCopy; /* * length doesn't include NULL */ nBufPos--; } } /* CLOSE */ iniClose( hIni ); return nBufPos; } unixODBC-2.3.12/odbcinst/_SQLWriteInstalledDrivers.c000066400000000000000000000055461446441710500222130ustar00rootroot00000000000000/************************************************** * _SQLWriteInstalledDrivers * * Added to allow ODBC Config programs and the iODBC * driver manager to access system information without * having to worry about where it is... just like accessing * Data Source information. So no surprise... its just * like SQLWritePrivateProfileString()! ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL _SQLWriteInstalledDrivers( LPCSTR pszSection, LPCSTR pszEntry, LPCSTR pszString ) { HINI hIni; char szIniName[ ODBC_FILENAME_MAX * 2 + 1 ]; char b1[ ODBC_FILENAME_MAX + 1 ], b2[ ODBC_FILENAME_MAX + 1 ]; /* SANITY CHECKS */ if ( pszSection == NULL ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } if ( pszSection[0] == '\0' ) { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_GENERAL_ERR, "" ); return FALSE; } /* OK */ #ifdef VMS sprintf( szIniName, "%s:%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ) ); #else sprintf( szIniName, "%s/%s", odbcinst_system_file_path( b1 ), odbcinst_system_file_name( b2 ) ); #endif #ifdef __OS2__ if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', TRUE, 1L ) != INI_SUCCESS ) #else if ( iniOpen( &hIni, szIniName, "#;", '[', ']', '=', TRUE ) != INI_SUCCESS ) #endif { inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_REQUEST_FAILED, "" ); return FALSE; } /* delete section */ if ( pszEntry == NULL ) { if ( iniObjectSeek( hIni, (char *)pszSection ) == INI_SUCCESS ) iniObjectDelete( hIni ); } /* delete entry */ else if ( pszString == NULL ) { if ( iniPropertySeek( hIni, (char *)pszSection, (char *)pszEntry, "" ) == INI_SUCCESS ) iniPropertyDelete( hIni ); } else { /* add section */ if ( iniObjectSeek( hIni, (char *)pszSection ) != INI_SUCCESS ) { iniObjectInsert( hIni, (char *)pszSection ); } /* update entry */ if ( iniPropertySeek( hIni, (char *)pszSection, (char *)pszEntry, "" ) == INI_SUCCESS ) { /* iniObjectSeek( hIni, (char *)pszSection ); */ iniPropertyUpdate( hIni, (char *)pszEntry, (char *)pszString ); } /* add entry */ else { iniObjectSeek( hIni, (char *)pszSection ); iniPropertyInsert( hIni, (char *)pszEntry, (char *)pszString ); } } if ( iniCommit( hIni ) != INI_SUCCESS ) { iniClose( hIni ); inst_logPushMsg( __FILE__, __FILE__, __LINE__, LOG_CRITICAL, ODBC_ERROR_REQUEST_FAILED, "" ); return FALSE; } iniClose( hIni ); return TRUE; } unixODBC-2.3.12/odbcinst/_logging.c000066400000000000000000000113361446441710500167620ustar00rootroot00000000000000/********************************************************************* * * Written by Nick Gorham * (nick@lurcher.org). * * copyright (c) 1999 Nick Gorham * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ********************************************************************** * * $Id: _logging.c,v 1.5 2009/02/18 17:59:27 lurcher Exp $ * * $Log: _logging.c,v $ * Revision 1.5 2009/02/18 17:59:27 lurcher * Shift to using config.h, the compile lines were making it hard to spot warnings * * Revision 1.4 2008/05/12 13:07:21 lurcher * Push a couple of small changes back into CVS, ready for new release * * Revision 1.3 2008/02/15 15:47:12 lurcher * Add thread protection around ini caching * * Revision 1.2 2007/11/27 17:52:57 peteralexharvey * - changes made during QT4 implementation * * Revision 1.1.1.1 2001/10/17 16:40:30 lurcher * * First upload to SourceForge * * Revision 1.1.1.1 2000/09/04 16:42:53 nick * Imported Sources * * Revision 1.1 1999/07/15 06:23:39 ngorham * * Added functions to remove the need for _init and _fini * * *********************************************************************/ #include #include #include #ifdef HAVE_LIBPTH #include static pth_mutex_t mutex_log = PTH_MUTEX_INIT; static int pth_init_called = 0; static int local_mutex_entry( void ) { if ( !pth_init_called ) { pth_init(); pth_init_called = 1; } return pth_mutex_acquire( &mutex_log, 0, NULL ); } static int local_mutex_exit( void ) { return pth_mutex_release( &mutex_log ); } #elif HAVE_LIBPTHREAD #include static pthread_mutex_t mutex_log = PTHREAD_MUTEX_INITIALIZER; static int local_mutex_entry( void ) { return pthread_mutex_lock( &mutex_log ); } static int local_mutex_exit( void ) { return pthread_mutex_unlock( &mutex_log ); } #elif HAVE_LIBTHREAD #include static mutex_t mutex_log; static int local_mutex_entry( void ) { return mutex_lock( &mutex_log ); } static int local_mutex_exit( void ) { return mutex_unlock( &mutex_log ); } #else #define local_mutex_entry() #define local_mutex_exit() #endif /* * I don't like these statics but not sure what else we can do... * * Indeed, access to these statics was in fact not thread safe ! * So they are now protected by mutex_log... */ static HLOG hODBCINSTLog = NULL; static int log_tried = 0; int inst_logPushMsg( char *pszModule, char *pszFunctionName, int nLine, int nSeverity, int nCode, char *pszMessage ) { int ret = LOG_ERROR; local_mutex_entry(); if ( !log_tried ) { long nMaxMessages = 10; /* \todo ODBC spec says 8 max. We would make it 0 (unlimited) but at the moment logPeekMsg would be slow if many messages. Revisit when opt is made to log storage. */ log_tried = 1; if ( logOpen( &hODBCINSTLog, "odbcinst", NULL, nMaxMessages ) != LOG_SUCCESS ) { hODBCINSTLog = NULL; } else { logOn( hODBCINSTLog, 1 ); } } if ( hODBCINSTLog ) { ret = logPushMsg( hODBCINSTLog, pszModule, pszFunctionName, nLine, nSeverity, nCode, pszMessage ); } local_mutex_exit(); return ret; } /*! * \brief Get a reference to a message in the log. * * The caller (SQLInstallerError) could call logPeekMsg directly * but we would have to extern hODBCINSTLog and I have not given * any thought to that at this time. * * \param nMsg * \param phMsg * * \return int */ int inst_logPeekMsg( long nMsg, HLOGMSG *phMsg ) { int ret = LOG_NO_DATA; local_mutex_entry(); if ( hODBCINSTLog ) ret = logPeekMsg( hODBCINSTLog, nMsg, phMsg ); local_mutex_exit(); return ret; } int inst_logClear( void ) { int ret = LOG_ERROR; local_mutex_entry(); if ( hODBCINSTLog ) ret = logClear( hODBCINSTLog ); local_mutex_exit(); return ret; } unixODBC-2.3.12/odbcinst/_odbcinst_ConfigModeINI.c000066400000000000000000000023641446441710500215740ustar00rootroot00000000000000/******************************************************* * _odbcinst_ConfigModeINI * * Get first valid INI file name. If we can open it for read then we assume its valid. * 1. ODBC_SYSTEM_DSN * - /etc/odbc.ini * 2. ODBC_USER_DSN * - ODBCINI * - ~/.odbc.ini * - /home/.odbc.ini * 3. ODBC_BOTH_DSN * - ODBC_USER_DSN * - ODBC_SYSTEM_DSN * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include BOOL _odbcinst_ConfigModeINI( char *pszFileName ) { UWORD nConfigMode = __get_config_mode(); pszFileName[0] = '\0'; switch ( nConfigMode ) { case ODBC_SYSTEM_DSN: if ( !_odbcinst_SystemINI( pszFileName, TRUE ) ) return FALSE; break; case ODBC_USER_DSN: if ( !_odbcinst_UserINI( pszFileName, TRUE ) ) return FALSE; break; case ODBC_BOTH_DSN: if ( !_odbcinst_UserINI( pszFileName, TRUE ) ) { if ( !_odbcinst_SystemINI( pszFileName, TRUE ) ) return FALSE; } break; default: return FALSE; } return TRUE; } unixODBC-2.3.12/odbcinst/_odbcinst_GetEntries.c000066400000000000000000000025151446441710500212710ustar00rootroot00000000000000/**************************************************** * _odbcinst_GetEntries * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include int _odbcinst_GetEntries( HINI hIni, LPCSTR pszSection, LPSTR pRetBuffer, int nRetBuffer, int *pnBufPos ) { char szPropertyName[INI_MAX_PROPERTY_NAME+1]; char *ptr; *pnBufPos = 0; *pRetBuffer = '\0'; ptr = pRetBuffer; iniObjectSeek( hIni, (char *)pszSection ); /* COLLECT ALL ENTRIES FOR THE GIVEN SECTION */ for( iniPropertyFirst( hIni ); iniPropertyEOL( hIni ) != TRUE; iniPropertyNext( hIni )) { iniProperty( hIni, szPropertyName ); if ( *pnBufPos + 1 + strlen( szPropertyName ) >= nRetBuffer ) { break; } else { strcpy( ptr, szPropertyName ); ptr += strlen( ptr ) + 1; (*pnBufPos) += strlen( szPropertyName ) + 1; } } /* * Add final NULL */ if ( *pnBufPos == 0 ) { ptr ++; } *ptr = '\0'; return (*pnBufPos); } unixODBC-2.3.12/odbcinst/_odbcinst_GetSections.c000066400000000000000000000026261446441710500214520ustar00rootroot00000000000000/**************************************************** * _odbcinst_GetSections * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include int _odbcinst_GetSections( HINI hIni, LPSTR pRetBuffer, int nRetBuffer, int *pnBufPos /* SET TO 0 IF RESULT DATA IS EMPTY */ ) { char szObjectName[INI_MAX_OBJECT_NAME+1]; char *ptr; *pnBufPos = 0; *pRetBuffer = '\0'; ptr = pRetBuffer; /* JUST COLLECT SECTION NAMES */ for( iniObjectFirst( hIni ); iniObjectEOL( hIni ) != TRUE; iniObjectNext( hIni )) { iniObject( hIni, szObjectName ); if ( strcasecmp( szObjectName, "ODBC Data Sources" ) == 0 ) { continue; } else if ( *pnBufPos + 1 + strlen( szObjectName ) >= nRetBuffer ) { break; } else { strcpy( ptr, szObjectName ); ptr += strlen( ptr ) + 1; (*pnBufPos) += strlen( szObjectName ) + 1; } } /* * Add final NULL */ if ( *pnBufPos == 0 ) { ptr ++; } *ptr = '\0'; return (*pnBufPos); } unixODBC-2.3.12/odbcinst/_odbcinst_SystemINI.c000066400000000000000000000077141446441710500210520ustar00rootroot00000000000000/************************************************** * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #include #include /* * Add the historic ODBCINI value, mainly for applix. */ #ifdef VMS char *odbcinst_system_file_path( char *buffer ) { char *path; if (( path = getvmsenv( "ODBCSYSINI" ))) { strcpy( buffer, path ); return buffer; } #ifdef SYSTEM_FILE_PATH else { return SYSTEM_FILE_PATH; } #else else { return "ODBC_LIBDIR:"; } #endif } char *odbcinst_system_file_name( char *buffer ) { char *path; if (( path = getvmsenv( "ODBCINSTINI" ))) { strcpy( buffer, path ); return path; } else { return "ODBCINST.INI"; } } char *odbcinst_user_file_path( char *buffer ) { return "ODBC_LIBDIR:"; } char *odbcinst_user_file_name( char *buffer ) { return "ODBCINST.INI"; } BOOL _odbcinst_SystemINI( char *pszFileName, BOOL bVerify ) { FILE *hFile; char b1[ ODBC_FILENAME_MAX + 1 ]; sprintf( pszFileName, "%s:odbc.ini", odbcinst_system_file_path( b1 )); if ( bVerify ) { hFile = uo_fopen( pszFileName, "r" ); if ( hFile ) uo_fclose( hFile ); else return FALSE; } return TRUE; } #else char *odbcinst_system_file_name( char *buffer ) { char *path; static char save_path[ ODBC_FILENAME_MAX + 1 ]; static int saved = 0; if ( saved ) { return save_path; } if (( path = getenv( "ODBCINSTINI" ))) { strncpy( buffer, path, ODBC_FILENAME_MAX ); strncpy( save_path, buffer, ODBC_FILENAME_MAX ); saved = 1; return buffer; } else { strcpy( save_path, "odbcinst.ini" ); saved = 1; return "odbcinst.ini"; } } char *odbcinst_system_file_path( char *buffer ) { char *path; static char save_path[ ODBC_FILENAME_MAX + 1 ]; static int saved = 0; if ( saved ) { return save_path; } if (( path = getenv( "ODBCSYSINI" ))) { strncpy( buffer, path, ODBC_FILENAME_MAX ); strncpy( save_path, buffer, ODBC_FILENAME_MAX ); saved = 1; return buffer; } #ifdef SYSTEM_FILE_PATH else { strcpy( save_path, SYSTEM_FILE_PATH ); saved = 1; return SYSTEM_FILE_PATH; } #else else { strcpy( save_path, "/etc" ); saved = 1; return "/etc"; } #endif } char *odbcinst_user_file_name( char *buffer ) { return ".odbcinst.ini"; } char *odbcinst_user_file_path( char *buffer ) { char *path; static char save_path[ ODBC_FILENAME_MAX + 1 ]; static int saved = 0; if ( saved ) { return save_path; } if (( path = getenv( "HOME" ))) { strncpy( buffer, path, ODBC_FILENAME_MAX ); strncpy( save_path, buffer, ODBC_FILENAME_MAX ); saved = 1; return buffer; } else { return "/home"; } } BOOL _odbcinst_SystemINI( char *pszFileName, BOOL bVerify ) { FILE *hFile; char b1[ ODBC_FILENAME_MAX + 1 ]; sprintf( pszFileName, "%s/odbc.ini", odbcinst_system_file_path( b1 )); if ( bVerify ) { /* try opening for read */ hFile = uo_fopen( pszFileName, "r" ); if ( hFile ) { uo_fclose( hFile ); } else { if ( ( !hFile ) && ( errno != ENFILE ) && ( errno != EMFILE ) && ( errno != ENOMEM ) && ( errno != EACCES ) && ( errno != EFBIG ) && ( errno != EINTR ) && ( errno != ENOSPC ) && ( errno != EOVERFLOW ) && ( errno != EWOULDBLOCK )) { return FALSE; } /* does not exist so try creating it */ hFile = uo_fopen( pszFileName, "w" ); if ( hFile ) uo_fclose( hFile ); else return FALSE; } } return TRUE; } #endif unixODBC-2.3.12/odbcinst/_odbcinst_UserINI.c000066400000000000000000000063751446441710500205060ustar00rootroot00000000000000/************************************************** * ************************************************** * This code was created by Peter Harvey @ CodeByDesign. * Released under LGPL 28.JAN.99 * * Contributions from... * ----------------------------------------------- * Peter Harvey - pharvey@codebydesign.com **************************************************/ #include #ifdef HAVE_PWD_H #include #endif #include #ifdef VMS BOOL _odbcinst_UserINI( char *pszFileName, BOOL bVerify ) { FILE *hFile; char *szEnv_INIUSER = getvmsenv("ODBCINI"); struct passwd *pPasswd = NULL; char *pHomeDir = NULL; pszFileName[0] = '\0'; if ( szEnv_INIUSER ) { strncpy( pszFileName, szEnv_INIUSER, ODBC_FILENAME_MAX ); } else { sprintf( pszFileName, "SYS$LOGIN:ODBC.INI" ); } if ( bVerify ) { hFile = uo_fopen( pszFileName, "r" ); if ( hFile ) uo_fclose( hFile ); else return FALSE; } return TRUE; } #else BOOL _odbcinst_UserINI( char *pszFileName, BOOL bVerify ) { FILE *hFile; char *szEnv_INIUSER = getenv("ODBCINI"); #ifdef HAVE_GETUID uid_t nUserID = getuid(); #else uid_t nUserID = 0; #endif struct passwd *pPasswd = NULL; char *pHomeDir = NULL; #ifdef HAVE_GETPWUID_R char buf[ 1024 ]; struct passwd pwent; struct passwd *pwentp; #endif pHomeDir = "/home"; #ifdef HAVE_GETPWUID_R pwentp = NULL; getpwuid_r( nUserID, &pwent, buf, sizeof( buf ), &pwentp ); if ( pwentp == &pwent ) { pPasswd = &pwent; } #elif HAVE_GETPWUID pPasswd = (struct passwd *)getpwuid(nUserID); #endif pszFileName[0] = '\0'; #ifdef HAVE_PWD_H if ( pPasswd != NULL ) if ( ( char *)pPasswd->pw_dir != NULL ) pHomeDir = pPasswd->pw_dir; #else pHomeDir = getenv("HOME"); #endif if ( szEnv_INIUSER ) { strncpy( pszFileName, szEnv_INIUSER, ODBC_FILENAME_MAX ); } if ( pszFileName[0] == '\0' ) { sprintf( pszFileName, "%s%s", pHomeDir, "/.odbc.ini" ); } #ifdef DHAVE_ENDPWENT /* * close the password file */ endpwent(); #endif if ( bVerify ) { /* * create it of it doesn't exist */ hFile = uo_fopen( pszFileName, "a" ); if ( hFile ) uo_fclose( hFile ); else return FALSE; } return TRUE; } #endif BOOL _odbcinst_FileINI( char *pszPath ) { char b1[ ODBC_FILENAME_MAX + 1 ]; /* we need a viable buffer (with space for FILENAME_MAX chars)... */ if ( !pszPath ) return FALSE; /* system configured to use a special location... */ *pszPath = '\0'; SQLGetPrivateProfileString( "ODBC", "FileDSNPath", "", pszPath, FILENAME_MAX - 2, "odbcinst.ini" ); if ( *pszPath ) return TRUE; /* default location... */ sprintf( pszPath, "%s/ODBCDataSources", odbcinst_system_file_path( b1 )); return TRUE; } unixODBC-2.3.12/odbcinst/odbcinst.exp000066400000000000000000000032321446441710500173500ustar00rootroot00000000000000SQLInstallODBC SQLManageDataSources SQLCreateDataSource SQLGetTranslator SQLInstallDriver SQLInstallDriverManager SQLGetInstalledDrivers SQLGetAvailableDrivers SQLConfigDataSource SQLRemoveDefaultDataSource SQLWriteDSNToIni SQLRemoveDSNFromIni SQLValidDSN SQLWritePrivateProfileString SQLGetPrivateProfileString SQLRemoveDriverManager SQLInstallTranslator SQLRemoveTranslator SQLRemoveDriver SQLConfigDriver SQLInstallerError SQLPostInstallerError SQLWriteFileDSN SQLReadFileDSN SQLInstallDriverEx SQLInstallTranslatorEx SQLGetConfigMode SQLSetConfigMode SQLInstallODBCW SQLCreateDataSourceW SQLGetTranslatorW SQLInstallDriverW SQLInstallDriverManagerW SQLGetInstalledDriversW SQLGetAvailableDriversW SQLConfigDataSourceW SQLWriteDSNToIniW SQLRemoveDSNFromIniW SQLValidDSNW SQLWritePrivateProfileStringW SQLGetPrivateProfileStringW SQLInstallTranslatorW SQLRemoveTranslatorW SQLRemoveDriverW SQLConfigDriverW SQLInstallerErrorW SQLPostInstallerErrorW SQLReadFileDSNW SQLWriteFileDSNW SQLInstallDriverExW SQLInstallTranslatorExW ODBCINSTConstructProperties ODBCINSTSetProperty ODBCINSTDestructProperties ODBCINSTAddProperty ODBCINSTValidateProperty ODBCINSTValidateProperties odbcinst_system_file_path odbcinst_system_file_name odbcinst_user_file_path odbcinst_user_file_name _odbcinst_SystemINI _odbcinst_UserINI _odbcinst_FileINI _SQLDriverConnectPrompt _SQLDriverConnectPromptW iniClose iniCommit iniElement iniObject iniObjectDelete iniObjectEOL iniObjectFirst iniObjectNext iniObjectSeek iniObjectSeekSure iniOpen iniProperty iniPropertyEOL iniPropertyFirst iniPropertyInsert iniPropertyNext iniToUpper iniValue inst_logPushMsg __clear_ini_cache unixODBC-2.3.12/odbcinst/odbcinst.pc.in000066400000000000000000000004471446441710500175700ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ Name: odbcinst (@PACKAGE_NAME@) Description: unixODBC Configuration Library URL: http://unixodbc.org Version: @PACKAGE_VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -lodbcinst Libs.private: @LIBLTDL@ @LIBS@ unixODBC-2.3.12/samples/000077500000000000000000000000001446441710500146645ustar00rootroot00000000000000unixODBC-2.3.12/samples/Makefile.am000066400000000000000000000000351446441710500167160ustar00rootroot00000000000000EXTRA_DIST = \ cursor.c unixODBC-2.3.12/samples/cursor.c000066400000000000000000000171151446441710500163520ustar00rootroot00000000000000#include #include #include #define ROWS 20 #define STATUS_LEN 6 #define OPENDATE_LEN 11 #define DONE -1 int res[][ 3 ] = { { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_PRIOR, 0, 0 }, { SQL_FETCH_FIRST, 0, 0 }, { SQL_FETCH_ABSOLUTE, -100, 0 }, { SQL_FETCH_ABSOLUTE, -400, 0 }, { SQL_FETCH_ABSOLUTE, 200, 0 }, { SQL_FETCH_ABSOLUTE, 350, 0 }, { SQL_FETCH_LAST, 0, 0 }, { SQL_FETCH_NEXT, 0, 0 }, { SQL_FETCH_LAST, 0, 0 }, { SQL_FETCH_FIRST, 0, 0 }, { SQL_FETCH_RELATIVE, 20, 0 }, { SQL_FETCH_RELATIVE, 50, 0 }, { SQL_FETCH_RELATIVE, 101, 0 }, { SQL_FETCH_RELATIVE, -5, 0 }, { SQL_FETCH_RELATIVE, 60, 0 }, { SQL_FETCH_RELATIVE, -60, 0 }, { SQL_FETCH_RELATIVE, 0, 0 }, { SQL_FETCH_RELATIVE, 0, 0 }, { SQL_FETCH_NEXT, 0, -1 }, }; int PromptScroll( SQLUINTEGER *ort, SQLUINTEGER *offset ) { static int count = 0; int ret; *ort = res[ count ][ 0 ]; *offset = res[ count ][ 1 ]; ret = res[ count ][ 2 ]; count ++; return ret; } int DumpODBCLog( SQLHENV hEnv, SQLHDBC hDbc, SQLHSTMT hStmt ) { SQLCHAR szError[501]; SQLCHAR szSqlState[10]; SQLINTEGER nNativeError; SQLSMALLINT nErrorMsg; if ( hStmt ) { while ( SQLError( hEnv, hDbc, hStmt, szSqlState, &nNativeError, szError, 500, &nErrorMsg ) == SQL_SUCCESS ) { printf( "%s\n", szError ); } } if ( hDbc ) { while ( SQLError( hEnv, hDbc, 0, szSqlState, &nNativeError, szError, 500, &nErrorMsg ) == SQL_SUCCESS ) { printf( "%s\n", szError ); } } if ( hEnv ) { while ( SQLError( hEnv, 0, 0, szSqlState, &nNativeError, szError, 500, &nErrorMsg ) == SQL_SUCCESS ) { printf( "%s\n", szError ); } } return 1; } static int Display( SQLUSMALLINT *rsa, SQLUINTEGER crow, SQLSMALLINT *sOrderID, SQLINTEGER *cbOrderID, SQLCHAR szOrderDate[][OPENDATE_LEN], SQLINTEGER *cbOrderDate, SQLCHAR szStatus[][STATUS_LEN], SQLINTEGER *cbStatus ) { int i; printf( "crow = %d\n", crow ); for ( i = 0; i < crow; i ++ ) { printf( "%d %d |%d:%d|%s:%d|%s:%d\n", i, rsa[ i ], sOrderID[ i ], cbOrderID[ i ], szOrderDate[ i ], cbOrderDate[ i ], szStatus[ i ], cbStatus[ i ] ); } } void create_file( SQLHANDLE hstmt ) { SQLRETURN ret; int i; ret = SQLExecDirect( hstmt, "drop table ctest", SQL_NTS ); ret = SQLExecDirect( hstmt, "create table ctest ( id integer, dt character( 10 ), status character( 5 ), other character varying( 40 ))", SQL_NTS ); for ( i = 1; i < 1000; i ++ ) { char sql[ 256 ]; sprintf( sql, "insert into ctest values( %d, '%10d', '%05d', 'other line %d' )", i, i, i, i ); ret = SQLExecDirect( hstmt, sql, SQL_NTS ); printf( "%s - %d\n", sql, ret ); } } void cursor_test() { SQLHENV henv; SQLHDBC hdbc; SQLHSTMT hstmt1, hstmt2; SQLRETURN retcode; SQLCHAR szStatus[ROWS][STATUS_LEN], szOpenDate[ROWS][OPENDATE_LEN]; SQLCHAR szNewStatus[STATUS_LEN], szNewOpenDate[OPENDATE_LEN]; SQLSMALLINT sOrderID[ROWS], sNewOrderID[ROWS]; SQLINTEGER cbStatus[ROWS], cbOrderID[ROWS], cbOpenDate[ROWS]; SQLUINTEGER FetchOrientation, crow, FetchOffset, irowUpdt; SQLUSMALLINT RowStatusArray[ROWS]; SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ); SQLSetEnvAttr( henv, SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3, 0 ); SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ); /* Specify the ODBC Cursor Library is always used then connect. */ SQLSetConnectAttr( hdbc, SQL_ATTR_ODBC_CURSORS, SQL_CUR_USE_ODBC, 0 ); retcode = SQLConnect( hdbc, "postgres", SQL_NTS, "", SQL_NTS, "", SQL_NTS ); DumpODBCLog( NULL, hdbc, NULL ); if ( retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO ) { /* Allocate a statement handle for the result set and a statement */ /* handle for a positioned update statement */ SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt1 ); SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt2 ); /* * create the data */ create_file( hstmt1 ); /* Specify an updateable statis cursor with 20 rows of data. Set */ /* the cursor name, execute the SELECT statement, and bind the */ /* rowset buffer to result set columns in column-wise fashion */ SQLSetStmtAttr( hstmt1, SQL_ATTR_CONCURRENCY, SQL_CONCUR_VALUES, 0 ); SQLSetStmtAttr( hstmt1, SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_STATIC, 0 ); SQLSetStmtAttr( hstmt1, SQL_ATTR_ROW_ARRAY_SIZE, ROWS, 20 ); SQLSetStmtAttr( hstmt1, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0 ); SQLSetStmtAttr( hstmt1, SQL_ATTR_ROWS_FETCHED_PTR, &crow, 0 ); SQLSetCursorName( hstmt1, "ORDERCURSOR", SQL_NTS ); SQLPrepare( hstmt1, "select id, dt, status from ctest", SQL_NTS ); { char cname[ 30 ]; retcode = SQLDescribeCol( hstmt1, 1, cname, sizeof( cname ), NULL, NULL, NULL, NULL, NULL ); printf( "ret = %d %s\n", retcode, cname ); DumpODBCLog( NULL, NULL, hstmt1 ); } SQLExecute( hstmt1 ); SQLBindCol( hstmt1, 1, SQL_C_SSHORT, sOrderID, 0, cbOrderID ); SQLBindCol( hstmt1, 2, SQL_C_CHAR, szOpenDate, OPENDATE_LEN, cbOpenDate ); SQLBindCol( hstmt1, 3, SQL_C_CHAR, szStatus, STATUS_LEN, cbStatus ); FetchOrientation = SQL_FETCH_FIRST; FetchOffset = 0; do { int ret; int count; printf( "fetch %d %d\n", FetchOrientation, FetchOffset ); ret = SQLFetchScroll( hstmt1, FetchOrientation, FetchOffset ); SQLRowCount( hstmt1, &count ); printf( "ret = %d count = %d\n", ret, count ); Display( RowStatusArray, crow, sOrderID, cbOrderID, szOpenDate, cbOpenDate, szStatus, cbStatus ); if ( SQL_SUCCEEDED( ret )) { char txt[ 50 ]; SQLINTEGER len; ret = SQLSetPos( hstmt1, 5, SQL_POSITION, SQL_LOCK_NO_CHANGE ); ret = SQLGetData( hstmt1, 2, SQL_C_CHAR, txt, sizeof( txt ), &len ); printf( "ret = %d %s:%d\n", ret, txt, len ); } } while( PromptScroll( &FetchOrientation, &FetchOffset ) != DONE ); SQLCloseCursor( hstmt1 ); SQLFreeStmt( hstmt1, SQL_DROP ); SQLFreeStmt( hstmt2, SQL_DROP ); SQLDisconnect( hdbc ); SQLFreeHandle( SQL_HANDLE_DBC, hdbc ); } SQLFreeHandle( SQL_HANDLE_ENV, henv ); } int main() { cursor_test(); } unixODBC-2.3.12/unixodbc.h.in000066400000000000000000000006441446441710500156150ustar00rootroot00000000000000/* Preprocessor constants for unixODBC */ /* Define to 1 if `long long' is available */ #undef HAVE_LONG_LONG /* Define to 1 if the header file is present */ #undef HAVE_PWD_H /* Define to 1 if the header file is present */ #undef HAVE_SYS_TYPES_H /* Define to 1 if the header file is present */ #undef HAVE_UNISTD_H /* Define to the value of sizeof(long) */ #undef SIZEOF_LONG_INT unixODBC-2.3.12/unixodbc_conf.h.in000066400000000000000000000277131446441710500166300ustar00rootroot00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Encoding to use for CHAR */ #undef ASCII_ENCODING /* Install bindir */ #undef BIN_PREFIX /* Use a semaphore to allow ODBCConfig to display running counts */ #undef COLLECT_STATS /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #undef CRAY_STACKSEG_END /* Define to 1 if using `alloca.c'. */ #undef C_ALLOCA /* Lib directory */ #undef DEFLIB_PATH /* Using perdriver iconv */ #undef ENABLE_DRIVER_ICONV /* Using ini cacheing */ #undef ENABLE_INI_CACHING /* Install exec_prefix */ #undef EXEC_PREFIX /* Disable the precise but slow checking of the validity of handles */ #undef FAST_HANDLE_VALIDATE /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define to 1 if you have the `argz_add' function. */ #undef HAVE_ARGZ_ADD /* Define to 1 if you have the `argz_append' function. */ #undef HAVE_ARGZ_APPEND /* Define to 1 if you have the `argz_count' function. */ #undef HAVE_ARGZ_COUNT /* Define to 1 if you have the `argz_create_sep' function. */ #undef HAVE_ARGZ_CREATE_SEP /* Define to 1 if you have the header file. */ #undef HAVE_ARGZ_H /* Define to 1 if you have the `argz_insert' function. */ #undef HAVE_ARGZ_INSERT /* Define to 1 if you have the `argz_next' function. */ #undef HAVE_ARGZ_NEXT /* Define to 1 if you have the `argz_stringify' function. */ #undef HAVE_ARGZ_STRINGIFY /* Define to 1 if you have the `atoll' function. */ #undef HAVE_ATOLL /* Define to 1 if you have the `closedir' function. */ #undef HAVE_CLOSEDIR /* Define to 1 if you have the header file. */ #undef HAVE_CRYPT_H /* Define to 1 if you have the declaration of `cygwin_conv_path', and to 0 if you don't. */ #undef HAVE_DECL_CYGWIN_CONV_PATH /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_DIRENT_H /* Define if you have the GNU dld library. */ #undef HAVE_DLD /* Define to 1 if you have the header file. */ #undef HAVE_DLD_H /* Define to 1 if you have the `dlerror' function. */ #undef HAVE_DLERROR /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_DL_H /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT /* Define if you have the _dyld_func_lookup function. */ #undef HAVE_DYLD /* Add editline support */ #undef HAVE_EDITLINE /* Define to 1 if you have the header file. */ #undef HAVE_EDITLINE_READLINE_H /* Define to 1 if you have the `endpwent' function. */ #undef HAVE_ENDPWENT /* Define to 1 if the system has the type `error_t'. */ #undef HAVE_ERROR_T /* Define to 1 if you have the `ftime' function. */ #undef HAVE_FTIME /* Define to 1 if you have the `ftok' function. */ #undef HAVE_FTOK /* Define to 1 if you have the `getpwuid' function. */ #undef HAVE_GETPWUID /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define to 1 if you have the `getuid' function. */ #undef HAVE_GETUID /* Define if you have the iconv() function. */ #undef HAVE_ICONV /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define if you have and nl_langinfo(CODESET). */ #undef HAVE_LANGINFO_CODESET /* Define to 1 if you have the header file. */ #undef HAVE_LANGINFO_H /* Add -lcrypt to lib list */ #undef HAVE_LIBCRYPT /* Define if you have the libdl library or equivalent. */ #undef HAVE_LIBDL /* Define if libdlloader will be built on this platform */ #undef HAVE_LIBDLLOADER /* Use the -lpth thread library */ #undef HAVE_LIBPTH /* Use -lpthread threading lib */ #undef HAVE_LIBPTHREAD /* Use the -lthread threading lib */ #undef HAVE_LIBTHREAD /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* Use rentrant version of localtime */ #undef HAVE_LOCALTIME_R /* Define this if a modern libltdl is already installed */ #undef HAVE_LTDL /* Define to 1 if you have the header file. */ #undef HAVE_MACH_O_DYLD_H /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_MSQL_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_NDIR_H /* Define to 1 if you have the `nl_langinfo' function. */ #undef HAVE_NL_LANGINFO /* Define to 1 if you have the `opendir' function. */ #undef HAVE_OPENDIR /* Define if libtool can extract symbol lists from object files. */ #undef HAVE_PRELOADED_SYMBOLS /* Define to 1 if the system has the type `ptrdiff_t'. */ #undef HAVE_PTRDIFF_T /* Define to 1 if you have the `putenv' function. */ #undef HAVE_PUTENV /* Define to 1 if you have the `readdir' function. */ #undef HAVE_READDIR /* Add readline support */ #undef HAVE_READLINE /* Define to 1 if you have the header file. */ #undef HAVE_READLINE_HISTORY_H /* Use the scandir lib */ #undef HAVE_SCANDIR /* Define to 1 if you have the `semget' function. */ #undef HAVE_SEMGET /* Define to 1 if you have the `semop' function. */ #undef HAVE_SEMOP /* Define to 1 if you have the `setenv' function. */ #undef HAVE_SETENV /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE /* Define if you have the shl_load function. */ #undef HAVE_SHL_LOAD /* Define to 1 if you have the `shmget' function. */ #undef HAVE_SHMGET /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `stricmp' function. */ #undef HAVE_STRICMP /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strlcat' function. */ #undef HAVE_STRLCAT /* Define to 1 if you have the `strlcpy' function. */ #undef HAVE_STRLCPY /* Define to 1 if you have the `strncasecmp' function. */ #undef HAVE_STRNCASECMP /* Define to 1 if you have the `strnicmp' function. */ #undef HAVE_STRNICMP /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the `strtol' function. */ #undef HAVE_STRTOL /* Define to 1 if you have the `strtoll' function. */ #undef HAVE_STRTOLL /* Define to 1 if you have the header file. */ #undef HAVE_SYNCH_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_DL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MALLOC_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SEM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIMEB_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the `time' function. */ #undef HAVE_TIME /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_VARARGS_H /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF /* Define to 1 if you have the `vsnprintf' function. */ #undef HAVE_VSNPRINTF /* This value is set to 1 to indicate that the system argz facility works */ #undef HAVE_WORKING_ARGZ /* Define as const if the declaration of iconv() needs const. */ #undef ICONV_CONST /* Install includedir */ #undef INCLUDE_PREFIX /* Lib directory */ #undef LIB_PREFIX /* Define if the OS needs help to load dependent libraries for dlopen(). */ #undef LTDL_DLOPEN_DEPLIBS /* Define to the system default library search path. */ #undef LT_DLSEARCH_PATH /* The archive extension */ #undef LT_LIBEXT /* The archive prefix */ #undef LT_LIBPREFIX /* Define to the extension used for runtime loadable modules, say, ".so". */ #undef LT_MODULE_EXT /* Define to the name of the environment variable that determines the run-time module search path. */ #undef LT_MODULE_PATH_VAR /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to the shared library suffix, say, ".dylib". */ #undef LT_SHARED_EXT /* Define to the shared archive member specification, say "(shr.o)". */ #undef LT_SHARED_LIB_MEMBER /* Define if you need semundo union */ #undef NEED_SEMUNDO_UNION /* Define if dlsym() requires a leading underscore in symbol names. */ #undef NEED_USCORE /* Using OSX */ #undef OSXHEADER /* Name of package */ /* Define to the address where bug reports for this package should be sent. */ /* Define to the full name of this package. */ /* Define to the full name and version of this package. */ /* Define to the one symbol short name of this package. */ /* Define to the home page for this package. */ /* Define to the version of this package. */ /* Platform is 64 bit */ #undef PLATFORM64 /* Install prefix */ #undef PREFIX /* Using QNX */ #undef QNX_LIBLTDL /* Shared lib extension */ #undef SHLIBEXT /* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Filename to use for ftok */ #undef STATS_FTOK_NAME /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* don't include unixODBC prefix in driver error messages */ #undef STRICT_ODBC_ERROR /* System file path */ #undef SYSTEM_FILE_PATH /* Lib path */ #undef SYSTEM_LIB_PATH /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to 1 if your declares `struct tm'. */ #undef TM_IN_SYS_TIME /* Encoding to use for UNICODE */ #undef UNICODE_ENCODING /* Flag that we are not using another DM */ #undef UNIXODBC /* We are building inside the unixODBC source tree */ /* Version number of package */ /* Work with IBM drivers that use 32 bit handles on 64 bit platforms */ #undef WITH_HANDLE_REDIRECT /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* Build flag for AIX */ #undef _ALL_SOURCE /* Build flag for AIX */ #undef _LONG_LONG /* Build flag for AIX */ #undef _THREAD_SAFE /* Define so that glibc/gnulib argp.h does not typedef error_t. */ #undef __error_t_defined /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to a type to use for 'error_t' if it is not otherwise available. */ #undef error_t /* Define to `int' if doesn't define. */ #undef gid_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to `int' if doesn't define. */ #undef uid_t unixODBC-2.3.12/vms/000077500000000000000000000000001446441710500140255ustar00rootroot00000000000000unixODBC-2.3.12/vms/drivermanager_axp.opt000066400000000000000000000044401446441710500202510ustar00rootroot00000000000000CASE_SENSITIVE=YES SYMBOL_VECTOR = (SQLAllocConnect=PROCEDURE,- SQLAllocEnv=PROCEDURE,- SQLAllocHandle=PROCEDURE,- SQLAllocHandleStd=PROCEDURE,- SQLAllocStmt=PROCEDURE,- SQLBindCol=PROCEDURE,- SQLBindParam=PROCEDURE,- SQLBindParameter=PROCEDURE,- SQLBrowseConnect=PROCEDURE,- SQLBulkOperations=PROCEDURE,- SQLCancel=PROCEDURE,- SQLCloseCursor=PROCEDURE,- SQLColAttribute=PROCEDURE,- SQLColAttributes=PROCEDURE,- SQLColumnPrivileges=PROCEDURE,- SQLColumns=PROCEDURE,- SQLConnect=PROCEDURE,- SQLCopyDesc=PROCEDURE,- SQLDataSources=PROCEDURE,- SQLDescribeCol=PROCEDURE,- SQLDescribeParam=PROCEDURE,- SQLDisconnect=PROCEDURE,- SQLDriverConnect=PROCEDURE,- SQLDrivers=PROCEDURE,- SQLEndTran=PROCEDURE,- SQLError=PROCEDURE,- SQLExecDirect=PROCEDURE,- SQLExecute=PROCEDURE,- SQLExtendedFetch=PROCEDURE,- SQLFetch=PROCEDURE,- SQLFetchScroll=PROCEDURE,- SQLForeignKeys=PROCEDURE,- SQLFreeConnect=PROCEDURE,- SQLFreeEnv=PROCEDURE,- SQLFreeHandle=PROCEDURE,- SQLFreeStmt=PROCEDURE,- SQLGetConnectAttr=PROCEDURE,- SQLGetConnectOption=PROCEDURE,- SQLGetCursorName=PROCEDURE,- SQLGetData=PROCEDURE,- SQLGetDescField=PROCEDURE,- SQLGetDescRec=PROCEDURE,- SQLGetDiagField=PROCEDURE,- SQLGetDiagRec=PROCEDURE,- SQLGetEnvAttr=PROCEDURE,- SQLGetFunctions=PROCEDURE,- SQLGetInfo=PROCEDURE,- SQLGetStmtAttr=PROCEDURE,- SQLGetStmtOption=PROCEDURE,- SQLGetTypeInfo=PROCEDURE,- SQLMoreResults=PROCEDURE,- SQLNativeSql=PROCEDURE,- SQLNumParams=PROCEDURE,- SQLNumResultCols=PROCEDURE,- SQLParamData=PROCEDURE,- SQLParamOptions=PROCEDURE,- SQLPrepare=PROCEDURE,- SQLPrimaryKeys=PROCEDURE,- SQLProcedureColumns=PROCEDURE,- SQLProcedures=PROCEDURE,- SQLPutData=PROCEDURE,- SQLRowCount=PROCEDURE,- SQLSetConnectAttr=PROCEDURE,- SQLSetConnectOption=PROCEDURE,- SQLSetCursorName=PROCEDURE,- SQLSetDescField=PROCEDURE,- SQLSetDescRec=PROCEDURE,- SQLSetEnvAttr=PROCEDURE,- SQLSetParam=PROCEDURE,- SQLSetPos=PROCEDURE,- SQLSetScrollOptions=PROCEDURE,- SQLSetStmtAttr=PROCEDURE,- SQLSetStmtOption=PROCEDURE,- SQLSpecialColumns=PROCEDURE,- SQLStatistics=PROCEDURE,- SQLTablePrivileges=PROCEDURE,- SQLTables=PROCEDURE,- SQLTransact=PROCEDURE) unixODBC-2.3.12/vms/install_image.com000066400000000000000000000010431446441710500173330ustar00rootroot00000000000000$ $ if p1 .eqs. "" then $goto ERR_NOPARAMS $ $ install :== $install/command $ $ if (f$file ("''p1'", "KNOWN")) $ then install replace/open/header/shared 'p1' $ else install create/open/header/shared 'p1' $ endif $done: $ exit $ $ERR_NOPARAMS: $ write sys$output " " $ write sys$output "The correct calling sequence is: " $ write sys$output " " $ write sys$output "$ @install_server p1 $ write sys$output " " $ write sys$output "Where: " $ write sys$output " " $ write sys$output " p1 = Image to be installed" $ write sys$output " " $ exit 44 $ unixODBC-2.3.12/vms/odbc2_axp.opt000066400000000000000000000030321446441710500164100ustar00rootroot00000000000000LIBODBCINST.EXE/SHARE CASE_SENSITIVE=YES SYMBOL_VECTOR = (SQLAllocConnect=PROCEDURE,- SQLAllocEnv=PROCEDURE,- SQLAllocStmt=PROCEDURE,- SQLBindCol=PROCEDURE,- SQLBindParameter=PROCEDURE,- SQLBrowseConnect=PROCEDURE,- SQLCancel=PROCEDURE,- SQLColAttributes=PROCEDURE,- SQLColumnPrivileges=PROCEDURE,- SQLColumns=PROCEDURE,- SQLConnect=PROCEDURE,- SQLDescribeCol=PROCEDURE,- SQLDescribeParam=PROCEDURE,- SQLDisconnect=PROCEDURE,- SQLDriverConnect=PROCEDURE,- SQLError=PROCEDURE,- SQLExecDirect=PROCEDURE,- SQLExecute=PROCEDURE,- SQLExtendedFetch=PROCEDURE,- SQLFetch=PROCEDURE,- SQLForeignKeys=PROCEDURE,- SQLFreeConnect=PROCEDURE,- SQLFreeEnv=PROCEDURE,- SQLFreeStmt=PROCEDURE,- SQLGetConnectOption=PROCEDURE,- SQLGetCursorName=PROCEDURE,- SQLGetData=PROCEDURE,- SQLGetFunctions=PROCEDURE,- SQLGetInfo=PROCEDURE,- SQLGetStmtOption=PROCEDURE,- SQLGetTypeInfo=PROCEDURE,- SQLMoreResults=PROCEDURE,- SQLNativeSql=PROCEDURE,- SQLNumParams=PROCEDURE,- SQLNumResultCols=PROCEDURE,- SQLParamData=PROCEDURE,- SQLParamOptions=PROCEDURE,- SQLPrepare=PROCEDURE,- SQLPrimaryKeys=PROCEDURE,- SQLProcedureColumns=PROCEDURE,- SQLProcedures=PROCEDURE,- SQLPutData=PROCEDURE,- SQLRowCount=PROCEDURE,- SQLSetConnectOption=PROCEDURE,- SQLSetCursorName=PROCEDURE,- SQLSetPos=PROCEDURE,- SQLSetScrollOptions=PROCEDURE,- SQLSetStmtOption=PROCEDURE,- SQLSpecialColumns=PROCEDURE,- SQLStatistics=PROCEDURE,- SQLTablePrivileges=PROCEDURE,- SQLTables=PROCEDURE,- SQLTransact=PROCEDURE) unixODBC-2.3.12/vms/odbc_axp.opt000066400000000000000000000045201446441710500163310ustar00rootroot00000000000000LIBODBCINST.EXE/SHARE CASE_SENSITIVE=YES SYMBOL_VECTOR = (SQLAllocConnect=PROCEDURE,- SQLAllocEnv=PROCEDURE,- SQLAllocHandle=PROCEDURE,- SQLAllocHandleStd=PROCEDURE,- SQLAllocStmt=PROCEDURE,- SQLBindCol=PROCEDURE,- SQLBindParam=PROCEDURE,- SQLBindParameter=PROCEDURE,- SQLBrowseConnect=PROCEDURE,- SQLBulkOperations=PROCEDURE,- SQLCancel=PROCEDURE,- SQLCloseCursor=PROCEDURE,- SQLColAttribute=PROCEDURE,- SQLColAttributes=PROCEDURE,- SQLColumnPrivileges=PROCEDURE,- SQLColumns=PROCEDURE,- SQLConnect=PROCEDURE,- SQLCopyDesc=PROCEDURE,- SQLDataSources=PROCEDURE,- SQLDescribeCol=PROCEDURE,- SQLDescribeParam=PROCEDURE,- SQLDisconnect=PROCEDURE,- SQLDriverConnect=PROCEDURE,- SQLDrivers=PROCEDURE,- SQLEndTran=PROCEDURE,- SQLError=PROCEDURE,- SQLExecDirect=PROCEDURE,- SQLExecute=PROCEDURE,- SQLExtendedFetch=PROCEDURE,- SQLFetch=PROCEDURE,- SQLFetchScroll=PROCEDURE,- SQLForeignKeys=PROCEDURE,- SQLFreeConnect=PROCEDURE,- SQLFreeEnv=PROCEDURE,- SQLFreeHandle=PROCEDURE,- SQLFreeStmt=PROCEDURE,- SQLGetConnectAttr=PROCEDURE,- SQLGetConnectOption=PROCEDURE,- SQLGetCursorName=PROCEDURE,- SQLGetData=PROCEDURE,- SQLGetDescField=PROCEDURE,- SQLGetDescRec=PROCEDURE,- SQLGetDiagField=PROCEDURE,- SQLGetDiagRec=PROCEDURE,- SQLGetEnvAttr=PROCEDURE,- SQLGetFunctions=PROCEDURE,- SQLGetInfo=PROCEDURE,- SQLGetStmtAttr=PROCEDURE,- SQLGetStmtOption=PROCEDURE,- SQLGetTypeInfo=PROCEDURE,- SQLMoreResults=PROCEDURE,- SQLNativeSql=PROCEDURE,- SQLNumParams=PROCEDURE,- SQLNumResultCols=PROCEDURE,- SQLParamData=PROCEDURE,- SQLParamOptions=PROCEDURE,- SQLPrepare=PROCEDURE,- SQLPrimaryKeys=PROCEDURE,- SQLProcedureColumns=PROCEDURE,- SQLProcedures=PROCEDURE,- SQLPutData=PROCEDURE,- SQLRowCount=PROCEDURE,- SQLSetConnectAttr=PROCEDURE,- SQLSetConnectOption=PROCEDURE,- SQLSetCursorName=PROCEDURE,- SQLSetDescField=PROCEDURE,- SQLSetDescRec=PROCEDURE,- SQLSetEnvAttr=PROCEDURE,- SQLSetParam=PROCEDURE,- SQLSetPos=PROCEDURE,- SQLSetScrollOptions=PROCEDURE,- SQLSetStmtAttr=PROCEDURE,- SQLSetStmtOption=PROCEDURE,- SQLSpecialColumns=PROCEDURE,- SQLStatistics=PROCEDURE,- SQLTablePrivileges=PROCEDURE,- SQLTables=PROCEDURE,- SQLTransact=PROCEDURE,- iniElement=PROCEDURE) unixODBC-2.3.12/vms/odbc_setup.com000066400000000000000000000007731446441710500166630ustar00rootroot00000000000000$ whoami = f$parse(f$environment("PROCEDURE"),,,,"NO_CONCEAL") $ whereami = f$parse(whoami,,,"DEVICE") + f$parse(whoami,,,"DIRECTORY") - ".][000000]" - "][" - ".]" - "]" + "]" $ define ODBC_LIBDIR 'whereami' $! $ file_loop: $ file = f$search("ODBC_LIBDIR:*ODBC*.EXE") $ if file .eqs. "" then goto file_loop_end $ image_name = f$parse(file,,,"NAME") $ define 'f$edit(image_name,"UPCASE")' "ODBC_LIBDIR:''image_name'.EXE" $ goto file_loop $ file_loop_end: $! $ isql :== $ODBC_LIBDIR:ISQL.EXE $ exit unixODBC-2.3.12/vms/odbcinst_axp.opt000066400000000000000000000016201446441710500172250ustar00rootroot00000000000000CASE_SENSITIVE=YES SYMBOL_VECTOR = (- _SQLDriverConnectPrompt=PROCEDURE,- SQLManageDataSources=PROCEDURE,- SQLCreateDataSource=PROCEDURE,- SQLGetTranslator=PROCEDURE,- SQLInstallDriverManager=PROCEDURE,- SQLGetInstalledDrivers=PROCEDURE,- SQLGetAvailableDrivers=PROCEDURE,- SQLConfigDataSource=PROCEDURE,- SQLWriteDSNToIni=PROCEDURE,- SQLRemoveDSNFromIni=PROCEDURE,- SQLValidDSN=PROCEDURE,- SQLWritePrivateProfileString=PROCEDURE,- SQLGetPrivateProfileString=PROCEDURE,- SQLRemoveDriverManager=PROCEDURE,- SQLRemoveTranslator=PROCEDURE,- SQLRemoveDriver=PROCEDURE,- SQLConfigDriver=PROCEDURE,- SQLInstallerError=PROCEDURE,- SQLPostInstallerError=PROCEDURE,- SQLWriteFileDSN=PROCEDURE,- SQLReadFileDSN=PROCEDURE,- SQLInstallDriverEx=PROCEDURE,- SQLInstallTranslatorEx=PROCEDURE,- SQLGetConfigMode=PROCEDURE,- SQLSetConfigMode=PROCEDURE,- odbcinst_system_file_name=PROCEDURE,- odbcinst_system_file_path=PROCEDURE) unixODBC-2.3.12/vmsbuild.com000066400000000000000000000226531446441710500155550ustar00rootroot00000000000000$! vmsbuild.com -- DCL procedure to build unixODBC on OpenVMS $! $ say := "write sys$OUTPUT" $ whoami = f$parse(f$environment("PROCEDURE"),,,,"NO_CONCEAL") $ cwd = f$parse(whoami,,,"DEVICE") + f$parse(whoami,,,"DIRECTORY") - ".][000000]" - "][" - ".]" - "]" + "]" $ set default 'cwd' $! $ basedir = cwd - "]" $ define/translation=concealed ODBCSRC "''basedir'.]" $! $ if p1 .eqs. "" then $goto ERR_NOPARAMS $! $ includes = "ODBCSRC:[include],ODBCSRC:[extras],""/ODBCSRC/libltdl""" $! /first_include requires CC 6.4 or later but avoids impossibly long /define qualifier $ CFLAGS="/names=as_is/prefix=all/include=(" + includes + ")/first_include=(ODBCSRC:[include]vmsconfig.h) $ LFLAGS="/nodebug/notrace" $! $ if p2 .eqs. "DEBUG" $ then $ CFLAGS = CFLAGS + "/noopt/debug" $ LFLAGS = LFLAGS + "/debug/trace" $ endif $! $ if p1 .eqs. "CLEAN" $ then $ set default 'cwd' $ d = f$parse(whoami,,,"DEVICE") + f$parse(whoami,,,"DIRECTORY") - ".][000000]" - "][" - ".]" - "]" + "]" $ say "Removing all object files and listings" $ delete/noconfirm [...]*.obj;*, *.lis;* $ say "Removing all object libraries and linker maps" $ delete/noconfirm [...]*.olb;*, *.map;* $ goto all_done $ endif $! $ if p1 .eqs. "COMPILE" .or. p1 .eqs. "ALL" $ then $ say "Compiling unixODBC" $ if f$search("ODBCSRC:[vms]libodbcinst.olb") .eqs. "" then library/create ODBCSRC:[vms]libodbcinst.olb $ if f$search("ODBCSRC:[vms]libodbc.olb") .eqs. "" then library/create ODBCSRC:[vms]libodbc.olb $ if f$search("ODBCSRC:[vms]libodbcpsql.olb") .eqs. "" then library/create ODBCSRC:[vms]libodbcpsql.olb $ call create_vmsconfig_h $ call compile "ODBCSRC:[extras]" "*.c" "ODBCSRC:[vms]libodbcinst.olb" "ODBCSRC:[vms]libodbc.olb" $ call compile "ODBCSRC:[ini]" "*.c" "ODBCSRC:[vms]libodbcinst.olb" "ODBCSRC:[vms]libodbc.olb" $ call compile "ODBCSRC:[log]" "*.c" "ODBCSRC:[vms]libodbcinst.olb" $ call compile "ODBCSRC:[lst]" "*.c" "ODBCSRC:[vms]libodbcinst.olb" "ODBCSRC:[vms]libodbc.olb" $ call compile "ODBCSRC:[odbcinst]" "*.c" "ODBCSRC:[vms]libodbcinst.olb" $ call compile "ODBCSRC:[drivermanager]" "*.c" "ODBCSRC:[vms]libodbc.olb" $ call compile "ODBCSRC:[exe]" "*.c" $ if f$getdvi("ODBCSRC:", "ACPTYPE") .eqs. "F11V5" $ then $ set process/parse=extended $ call compile "ODBCSRC:[Drivers.Postgre7^.1]" "*.c" "ODBCSRC:[vms]libodbcpsql.olb" $ else $ call compile "ODBCSRC:[Drivers.Postgre7_1]" "*.c" "ODBCSRC:[vms]libodbcpsql.olb" $ endif $ set default 'cwd' $! $ endif $! $ if f$trnlnm("ODBC_LIBDIR").eqs."" $ then $ if f$search("ODBCSRC:[000000]odbclib.dir") .eqs. "" $ then $ create/directory/log ODBCSRC:[odbclib] $ endif $ libdir = f$parse("ODBCSRC:[odbclib]",,,,"NO_CONCEAL") -".][000000"-"]["-"].;"+"]" $ define/process ODBC_LIBDIR 'libdir' $ say "Defining ODBC_LIBDIR as """ + f$trnlnm("ODBC_LIBDIR") + """ $ else $ if f$search("ODBC_LIBDIR") .eqs. "" $ then $ create/directory/log ODBC_LIBDIR $ endif $ endif $! $! Build Shared objects $! $ if p1 .eqs. "LINK" .or. p1 .eqs. "ALL" $ then $ set default ODBCSRC:[vms] $! $ say "Linking libodbcinst.exe" $ link 'LFLAGS' libodbcinst.olb/library,odbcinst_axp.opt/opt/share=libodbcinst.exe $! $ say "Linking libodbc.exe" $ link 'LFLAGS' libodbc.olb/library,odbc_axp.opt/opt/share=libodbc.exe $! $! The following kludge brought to you by the fact that on ODS-5 disks the C compiler $! may create module names in upper or mixed case depending on how the archive was $! unpacked. Try lower case and if it's not there, assume uppper case. $! $ module = "psqlodbc" $ module_exists == 0 $ call check_module "''module'" "libodbcpsql.olb" $ if .not. module_exists then module = f$edit(module,"UPCASE") $! $ say "Linking libodbcpsql.exe" $ link 'LFLAGS' libodbcpsql.olb/library/include="''module'",odbc2_axp.opt/opt/share=libodbcpsql.exe $! $ set default ODBCSRC:[exe] $ say "Linking isql.exe, dltest.exe and odbc-config.exe" $ link 'LFLAGS' isql.OBJ,SYS$INPUT/OPT ODBCSRC:[vms]libodbc.exe/SHARE $ eod $! $ link 'LFLAGS' dltest.OBJ,ODBCSRC:[vms]libodbcinst.olb/library $ link 'LFLAGS' odbc-config.OBJ $ endif $! $ if p1 .eqs. "INSTALL" .or. p1 .eqs. "ALL" $ then $! $ copy/log ODBCSRC:[vms]libodbc*.exe ODBC_LIBDIR: $ copy/log ODBCSRC:[vms]odbc_setup.com ODBC_LIBDIR: $ copy/log ODBCSRC:[exe]isql.exe ODBC_LIBDIR: $ copy/log ODBCSRC:[exe]dltest.exe ODBC_LIBDIR: $ copy/log ODBCSRC:[exe]odbc-config.exe ODBC_LIBDIR: $! $! check for odbc.ini and odbcinst.ini in ODBC_LIBDIR $! $ file = f$search ("ODBC_LIBDIR:odbc.ini") $ if file .eqs. "" $ then $ say "Creating ODBC_LIBDIR:odbc.ini" $ create ODBC_LIBDIR:odbc.ini $ endif $! $ file = f$search ("ODBC_LIBDIR:odbcinst.ini") $ if file .eqs. "" $ then $ say "Creating ODBC_LIBDIR:odbcinst.ini" $ create ODBC_LIBDIR:odbcinst.ini $ endif $! $ set file ODBC_LIBDIR:*.*/protection=(w:re) $ endif $! $ all_done: $ set default 'cwd' $ exit (1) $! $ ERR_NOPARAMS: $ say " " $ say "The correct calling sequence is: " $ say " " $ say "$ @vmsbuild p1 [p2] $ say " " $ say "Where p1 is : " $ say " " $ say " ALL : COMPILE LINK, and INSTALL steps." $ say " CLEAN : Remove all objects and object libraries." $ say " COMPILE : Compile all source and produce object libraries" $ say " LINK : Create shareable images" $ say " INSTALL : Copy shareable images to ODBC_LIBDIR:" $ say " " $ say "and DEBUG may optionally be specified for p2 when p1 is COMPILE, LINK, or ALL" $ say " " $ exit 44 $! $! compile subroutine will compile all p2 source files $! and place the resulting object files in libraries $! specified as p3 and/or p4 $! $ compile : subroutine $ set default 'p1' $ loop: $ file = f$search ("''p2'",1) $ if file .eqs. "" then goto complete $ filename = f$parse (file,,,"name") $ if f$edit(filename,"UPCASE") .eqs. "INIOS2PROFILE" then goto loop $ object = F$SEARCH ("''filename'.OBJ;*",2) $ if object .eqs. "" $ then $ say "cc" + CFLAGS + " ''filename'.c" $ on warning then continue $ cc 'CFLAGS' 'filename' $! keep module names upper case to avoid insanity on ODS-5 volumes $ if p3 .nes. "" then library/replace/log 'p3' 'f$edit(filename,"UPCASE")' $ if p4 .nes. "" then library/replace/log 'p4' 'f$edit(filename,"UPCASE")' $ endif $ goto loop $ complete: $ set default 'cwd' $ exit $ endsubroutine ! compile $ $! $ create_vmsconfig_h : subroutine $! $ SEARCH/KEY=(POS:2,SIZE:8) ODBCSRC:[000000]CONFIGURE. "VERSION="/EXACT/OUTPUT=version.tmp $ open/read version version.tmp $ read version versionline $ close version $ delete/noconfirm/nolog version.tmp;* $ versionstring = f$element(1, "=", f$edit(versionline, "COLLAPSE")) $! $ if f$search("ODBCSRC:[include]vmsconfig.h") .nes. "" then delete/noconfirm/nolog ODBCSRC:[include]vmsconfig.h;* $ open/write vmsconfig ODBCSRC:[include]vmsconfig.h $ write vmsconfig "/* auto-generated definitions for VMS port */ $ write vmsconfig "#define UNIXODBC" $ write vmsconfig "#define HAVE_PWD_H 1" $ write vmsconfig "#if __VMS_VER >= 70000000" $ write vmsconfig "#define HAVE_STRCASECMP" $ write vmsconfig "#define HAVE_STRNCASECMP" $ write vmsconfig "#define HAVE_STDARG_H" $ write vmsconfig "#define HAVE_STDLIB_H" $ write vmsconfig "#define HAVE_STRING_H" $ write vmsconfig "#define HAVE_STRINGS_H" $ write vmsconfig "#define HAVE_DTIME" $ write vmsconfig "#define HAVE_SYS_TIME_H" $ write vmsconfig "#define HAVE_GETTIMEOFDAY" $ write vmsconfig "#define HAVE_UNISTD_H" $ write vmsconfig "#endif" $ write vmsconfig "#define SIZEOF_LONG_INT 4" $ write vmsconfig "#define UNIXODBC_SOURCE" $ write vmsconfig "#define readonly __readonly" $ write vmsconfig "#define DEFLIB_PATH ""ODBC_LIBDIR:[LIB]""" $ write vmsconfig "#define SYSTEM_LIB_PATH ""ODBC_LIBDIR:[LIB]""" $ write vmsconfig "#define SHLIBEXT "".exe""" $ write vmsconfig "#define VERSION ""''versionstring'""" $ write vmsconfig "#define PREFIX ""ODBC_LIBDIR:""" $ write vmsconfig "#define EXEC_PREFIX ""ODBC_LIBDIR:[BIN]""" $ write vmsconfig "#define BIN_PREFIX ""ODBC_LIBDIR:[BIN]""" $ write vmsconfig "#define INCLUDE_PREFIX ""ODBC_LIBDIR:[INCLUDE]""" $ write vmsconfig "#define LIB_PREFIX ""ODBC_LIBDIR:[ETC]""" $ write vmsconfig "#define SYSTEM_FILE_PATH ""ODBC_LIBDIR:[ETC]""" $ write vmsconfig "char* getvmsenv (char* symbol);" $ close vmsconfig $! $ if f$search("ODBCSRC:[include]unixodbc_conf.h") .nes. "" then delete/noconfirm/nolog ODBCSRC:[include]unixodbc_conf.h;* $ open/write unixodbcconfig ODBCSRC:[include]unixodbc_conf.h $ write unixodbcconfig "/* auto-generated definitions for VMS port */ $ write unixodbcconfig "#ifndef HAVE_PWD_H" $ write unixodbcconfig " #define HAVE_PWD_H" $ write unixodbcconfig "#endif" $ write unixodbcconfig "#ifndef SIZEOF_LONG_INT" $ write unixodbcconfig " #define SIZEOF_LONG_INT 8" $ write unixodbcconfig "#endif" $ close unixodbcconfig $ if f$search("ODBCSRC:[include]config.h") .nes. "" then delete/noconfirm/nolog ODBCSRC:[include]config.h;* $ open/write config_h ODBCSRC:[include]config.h $ write config_h "/* The real stuff is in vmsconfig.h */ $ close config_h $ exit $ endsubroutine ! create_vmsconfig_h $! $ check_module : subroutine $! Check for presence of a particular module in an object library. $! p1: module name, p2: object library $ set noon $ define/user_mode sys$output nl: $ define/user_mode sys$error nl: $ library/list/only="''p1'" 'p2' $ if .not. $status $ then $! probably LBR$_KEYNOTFND; defer other errors until link time $ module_exists == 0 $ else $ module_exists == 1 $ endif $ set on $ exit $ endsubroutine ! check_module