From 254e1914dfc9508dc39890f0340557164d83d340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9mi=20V=C3=A1nyi?= Date: Tue, 21 Jan 2020 11:18:39 +0100 Subject: [PATCH] Use github.com/godror/godror instead of goracle.v2 (#15683) From the README of goracle: > Goracle is deprecated because of naming (trademark) issues. From now on we are using github.com/godror/godror instead. (cherry picked from commit d0a80a2aa29c46e469c8659d9f43ffd8dae7aac8) --- NOTICE.txt | 500 +++++++------- .../godror/godror}/CHANGELOG.md | 99 ++- .../godror/godror}/LICENSE.md | 19 +- .../godror/godror}/NOTES.md | 0 .../godror/godror}/README.md | 62 +- .../godror/godror}/conn.go | 257 +++++-- .../godror/godror/contrib/free.db/cwallet.sso | Bin 0 -> 6733 bytes .../godror/godror/contrib/free.db/env.sh | 5 + .../godror/godror/contrib/free.db/ewallet.p12 | Bin 0 -> 6688 bytes .../godror/contrib/free.db/keystore.jks | Bin 0 -> 3241 bytes .../godror/contrib/free.db/ojdbc.properties | 1 + .../godror/godror/contrib/free.db/sqlnet.ora | 2 + .../godror/contrib/free.db/tnsnames.ora | 6 + .../godror/contrib/free.db/truststore.jks | Bin 0 -> 3335 bytes .../contrib/oracle-instant-client/Dockerfile | 14 + .../contrib/oracle-instant-client/README.md | 0 .../godror}/contrib/oracle-xe-18c/Dockerfile | 0 .../godror}/contrib/oracle-xe-18c/README.md | 0 .../godror/godror}/data.go | 213 +++++- .../godror/godror}/drv.go | 372 +++++++--- vendor/github.com/godror/godror/drv_posix.go | 11 + vendor/github.com/godror/godror/go.mod | 12 + vendor/github.com/godror/godror/go.sum | 14 + .../godror/godror}/lob.go | 60 +- .../godror/godror}/obj.go | 272 +++++--- .../godror/godror}/odpi/CONTRIBUTING.md | 0 .../godror/godror}/odpi/LICENSE.md | 1 - .../godror/godror}/odpi/README.md | 3 +- .../godror/godror}/odpi/embed/README.md | 1 - .../godror/godror}/odpi/embed/dpi.c | 2 +- .../godror/godror}/odpi/include/dpi.h | 65 +- .../godror/godror}/odpi/src/dpiConn.c | 249 ++++--- .../godror/godror}/odpi/src/dpiContext.c | 43 +- .../godror/godror}/odpi/src/dpiData.c | 83 ++- .../godror/godror}/odpi/src/dpiDebug.c | 1 - .../godror/godror}/odpi/src/dpiDeqOptions.c | 9 +- .../godror/godror}/odpi/src/dpiEnqOptions.c | 5 +- .../godror/godror}/odpi/src/dpiEnv.c | 107 ++- .../godror/godror}/odpi/src/dpiError.c | 214 +++--- .../godror}/odpi/src/dpiErrorMessages.h | 5 +- .../godror/godror}/odpi/src/dpiGen.c | 18 +- .../godror/godror}/odpi/src/dpiGlobal.c | 1 - .../godror/godror}/odpi/src/dpiHandleList.c | 3 +- .../godror/godror}/odpi/src/dpiHandlePool.c | 9 +- .../godror/godror}/odpi/src/dpiImpl.h | 182 ++++- .../godror/godror}/odpi/src/dpiLob.c | 38 +- .../godror/godror}/odpi/src/dpiMsgProps.c | 185 +++-- .../godror/godror}/odpi/src/dpiObject.c | 168 +++-- .../godror/godror}/odpi/src/dpiObjectAttr.c | 3 +- .../godror/godror}/odpi/src/dpiObjectType.c | 5 +- .../godror/godror}/odpi/src/dpiOci.c | 653 +++++++++++++----- .../godror/godror}/odpi/src/dpiOracleType.c | 10 +- .../godror/godror}/odpi/src/dpiPool.c | 22 +- .../godror/godror/odpi/src/dpiQueue.c | 560 +++++++++++++++ .../godror/godror}/odpi/src/dpiRowid.c | 4 +- .../godror/godror}/odpi/src/dpiSodaColl.c | 129 +++- .../godror}/odpi/src/dpiSodaCollCursor.c | 3 +- .../godror/godror}/odpi/src/dpiSodaDb.c | 5 +- .../godror/godror}/odpi/src/dpiSodaDoc.c | 3 +- .../godror}/odpi/src/dpiSodaDocCursor.c | 3 +- .../godror/godror}/odpi/src/dpiStmt.c | 133 +++- .../godror/godror}/odpi/src/dpiSubscr.c | 57 +- .../godror/godror}/odpi/src/dpiUtils.c | 3 +- .../godror/godror}/odpi/src/dpiVar.c | 52 +- .../godror/godror}/orahlp.go | 66 +- vendor/github.com/godror/godror/queue.go | 639 +++++++++++++++++ .../godror/godror}/rows.go | 70 +- vendor/github.com/godror/godror/sid/sid.go | 531 ++++++++++++++ .../godror/godror}/stmt.go | 289 +++++--- .../godror/godror}/subscr.c | 0 .../godror/godror}/subscr.go | 32 +- .../godror/godror}/version.go | 10 +- vendor/golang.org/x/xerrors/LICENSE | 27 + vendor/golang.org/x/xerrors/PATENTS | 22 + vendor/golang.org/x/xerrors/README | 2 + vendor/golang.org/x/xerrors/adaptor.go | 193 ++++++ vendor/golang.org/x/xerrors/codereview.cfg | 1 + vendor/golang.org/x/xerrors/doc.go | 22 + vendor/golang.org/x/xerrors/errors.go | 33 + vendor/golang.org/x/xerrors/fmt.go | 187 +++++ vendor/golang.org/x/xerrors/format.go | 34 + vendor/golang.org/x/xerrors/frame.go | 56 ++ vendor/golang.org/x/xerrors/go.mod | 3 + .../golang.org/x/xerrors/internal/internal.go | 8 + vendor/golang.org/x/xerrors/wrap.go | 106 +++ .../contrib/oracle-instant-client/Dockerfile | 24 - vendor/gopkg.in/goracle.v2/drv_10.go | 106 --- vendor/gopkg.in/goracle.v2/drv_posix.go | 21 - vendor/gopkg.in/goracle.v2/go.mod | 10 - vendor/gopkg.in/goracle.v2/go.sum | 14 - vendor/gopkg.in/goracle.v2/stmt_go09.go | 52 -- vendor/gopkg.in/goracle.v2/stmt_go10.go | 78 --- vendor/vendor.json | 33 +- x-pack/metricbeat/module/oracle/connection.go | 6 +- .../oracle/performance/metricset_test.go | 2 +- .../oracle/tablespace/metricset_test.go | 2 +- x-pack/metricbeat/module/oracle/testing.go | 4 +- 97 files changed, 5873 insertions(+), 1766 deletions(-) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/CHANGELOG.md (69%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/LICENSE.md (95%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/NOTES.md (100%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/README.md (72%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/conn.go (74%) create mode 100644 vendor/github.com/godror/godror/contrib/free.db/cwallet.sso create mode 100644 vendor/github.com/godror/godror/contrib/free.db/env.sh create mode 100644 vendor/github.com/godror/godror/contrib/free.db/ewallet.p12 create mode 100644 vendor/github.com/godror/godror/contrib/free.db/keystore.jks create mode 100644 vendor/github.com/godror/godror/contrib/free.db/ojdbc.properties create mode 100644 vendor/github.com/godror/godror/contrib/free.db/sqlnet.ora create mode 100644 vendor/github.com/godror/godror/contrib/free.db/tnsnames.ora create mode 100644 vendor/github.com/godror/godror/contrib/free.db/truststore.jks create mode 100644 vendor/github.com/godror/godror/contrib/oracle-instant-client/Dockerfile rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/contrib/oracle-instant-client/README.md (100%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/contrib/oracle-xe-18c/Dockerfile (100%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/contrib/oracle-xe-18c/README.md (100%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/data.go (52%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/drv.go (67%) create mode 100644 vendor/github.com/godror/godror/drv_posix.go create mode 100644 vendor/github.com/godror/godror/go.mod create mode 100644 vendor/github.com/godror/godror/go.sum rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/lob.go (77%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/obj.go (62%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/CONTRIBUTING.md (100%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/LICENSE.md (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/README.md (95%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/embed/README.md (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/embed/dpi.c (98%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/include/dpi.h (96%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiConn.c (92%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiContext.c (92%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiData.c (89%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiDebug.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiDeqOptions.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiEnqOptions.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiEnv.c (68%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiError.c (85%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiErrorMessages.h (94%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiGen.c (95%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiGlobal.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiHandleList.c (98%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiHandlePool.c (94%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiImpl.h (92%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiLob.c (94%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiMsgProps.c (72%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiObject.c (87%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiObjectAttr.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiObjectType.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiOci.c (85%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiOracleType.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiPool.c (96%) create mode 100644 vendor/github.com/godror/godror/odpi/src/dpiQueue.c rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiRowid.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiSodaColl.c (84%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiSodaCollCursor.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiSodaDb.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiSodaDoc.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiSodaDocCursor.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiStmt.c (95%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiSubscr.c (93%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiUtils.c (99%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/odpi/src/dpiVar.c (97%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/orahlp.go (83%) create mode 100644 vendor/github.com/godror/godror/queue.go rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/rows.go (92%) create mode 100644 vendor/github.com/godror/godror/sid/sid.go rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/stmt.go (88%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/subscr.c (100%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/subscr.go (86%) rename vendor/{gopkg.in/goracle.v2 => github.com/godror/godror}/version.go (57%) create mode 100644 vendor/golang.org/x/xerrors/LICENSE create mode 100644 vendor/golang.org/x/xerrors/PATENTS create mode 100644 vendor/golang.org/x/xerrors/README create mode 100644 vendor/golang.org/x/xerrors/adaptor.go create mode 100644 vendor/golang.org/x/xerrors/codereview.cfg create mode 100644 vendor/golang.org/x/xerrors/doc.go create mode 100644 vendor/golang.org/x/xerrors/errors.go create mode 100644 vendor/golang.org/x/xerrors/fmt.go create mode 100644 vendor/golang.org/x/xerrors/format.go create mode 100644 vendor/golang.org/x/xerrors/frame.go create mode 100644 vendor/golang.org/x/xerrors/go.mod create mode 100644 vendor/golang.org/x/xerrors/internal/internal.go create mode 100644 vendor/golang.org/x/xerrors/wrap.go delete mode 100644 vendor/gopkg.in/goracle.v2/contrib/oracle-instant-client/Dockerfile delete mode 100644 vendor/gopkg.in/goracle.v2/drv_10.go delete mode 100644 vendor/gopkg.in/goracle.v2/drv_posix.go delete mode 100644 vendor/gopkg.in/goracle.v2/go.mod delete mode 100644 vendor/gopkg.in/goracle.v2/go.sum delete mode 100644 vendor/gopkg.in/goracle.v2/stmt_go09.go delete mode 100644 vendor/gopkg.in/goracle.v2/stmt_go10.go diff --git a/NOTICE.txt b/NOTICE.txt index 0744d93a3ec..969d971d56c 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -2133,6 +2133,239 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-------------------------------------------------------------------- +Dependency: github.com/godror/godror +Version: v0.9.0 +Revision: 446a29355d2967f04604e8e015a3343917860adf +License type (autodetected): Apache-2.0 +./vendor/github.com/godror/godror/LICENSE.md: +-------------------------------------------------------------------- +Apache License 2.0 + + +-------------------------------------------------------------------- +Dependency: github.com/godror/godror/odpi +License type (autodetected): UPL-1.0 +./vendor/github.com/godror/godror/odpi/LICENSE.md: +-------------------------------------------------------------------- +Copyright (c) 2016, 2018 Oracle and/or its affiliates. All rights reserved. + +This program is free software: you can modify it and/or redistribute it under +the terms of: + +(i) the Universal Permissive License v 1.0 or at your option, any + later version (); and/or + +(ii) the Apache License v 2.0. () + + +The Universal Permissive License (UPL), Version 1.0 +=================================================== + +Subject to the condition set forth below, permission is hereby granted to any +person obtaining a copy of this software, associated documentation and/or data +(collectively the "Software"), free of charge and under any and all copyright +rights in the Software, and any and all patent rights owned or freely +licensable by each licensor hereunder covering either (i) the unmodified +Software as contributed to or provided by such licensor, or (ii) the Larger +Works (as defined below), to deal in both + +(a) the Software, and + +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + one is included with the Software (each a "Larger Work" to which the + Software is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create +derivative works of, display, perform, and distribute the Software and make, +use, sell, offer for sale, import, export, have made, and have sold the +Software and the Larger Work(s), and to sublicense the foregoing rights on +either these or other terms. + +This license is subject to the following condition: + +The above copyright notice and either this complete permission notice or at a +minimum a reference to the UPL must be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +Apache License +============== + +Version 2.0, January 2004 + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. **Definitions**. + + "License" shall mean the terms and conditions for use, reproduction, and + distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the + copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other + entities that control, are controlled by, or are under common control with + that entity. For the purposes of this definition, "control" means (i) the + power, direct or indirect, to cause the direction or management of such + entity, whether by contract or otherwise, or (ii) ownership of fifty + percent (50%) or more of the outstanding shares, or (iii) beneficial + ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising + permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation source, + and configuration files. + + "Object" form shall mean any form resulting from mechanical transformation + or translation of a Source form, including but not limited to compiled + object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, + made available under the License, as indicated by a copyright notice that + is included in or attached to the work (an example is provided in the + Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object form, + that is based on (or derived from) the Work and for which the editorial + revisions, annotations, elaborations, or other modifications represent, as + a whole, an original work of authorship. For the purposes of this License, + Derivative Works shall not include works that remain separable from, or + merely link (or bind by name) to the interfaces of, the Work and Derivative + Works thereof. + + "Contribution" shall mean any work of authorship, including the original + version of the Work and any modifications or additions to that Work or + Derivative Works thereof, that is intentionally submitted to Licensor for + inclusion in the Work by the copyright owner or by an individual or Legal + Entity authorized to submit on behalf of the copyright owner. For the + purposes of this definition, "submitted" means any form of electronic, + verbal, or written communication sent to the Licensor or its + representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, the Licensor for the purpose of discussing + and improving the Work, but excluding communication that is conspicuously + marked or otherwise designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on + behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. **Grant of Copyright License.** Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license to + reproduce, prepare Derivative Works of, publicly display, publicly perform, + sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. **Grant of Patent License.** Subject to the terms and conditions of this + License, each Contributor hereby grants to You a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated in + this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to + those patent claims licensable by such Contributor that are necessarily + infringed by their Contribution(s) alone or by combination of their + Contribution(s) with the Work to which such Contribution(s) was submitted. + If You institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work or a + Contribution incorporated within the Work constitutes direct or + contributory patent infringement, then any patent licenses granted to You + under this License for that Work shall terminate as of the date such + litigation is filed. + +4. **Redistribution.** You may reproduce and distribute copies of the Work or + Derivative Works thereof in any medium, with or without modifications, and + in Source or Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works a + copy of this License; and + + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + + 3. You must retain, in the Source form of any Derivative Works that You + distribute, all copyright, patent, trademark, and attribution notices + from the Source form of the Work, excluding those notices that do not + pertain to any part of the Derivative Works; and + + 4. If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable + copy of the attribution notices contained within such NOTICE file, + excluding those notices that do not pertain to any part of the + Derivative Works, in at least one of the following places: within a + NOTICE text file distributed as part of the Derivative Works; within + the Source form or documentation, if provided along with the Derivative + Works; or, within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents of the + NOTICE file are for informational purposes only and do not modify the + License. You may add Your own attribution notices within Derivative + Works that You distribute, alongside or as an addendum to the NOTICE + text from the Work, provided that such additional attribution notices + cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of Your modifications, or for any such + Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated + in this License. + +5. **Submission of Contributions.** Unless You explicitly state otherwise, any + Contribution intentionally submitted for inclusion in the Work by You to + the Licensor shall be under the terms and conditions of this License, + without any additional terms or conditions. Notwithstanding the above, + nothing herein shall supersede or modify the terms of any separate license + agreement you may have executed with Licensor regarding such Contributions. + +6. **Trademarks.** This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, except + as required for reasonable and customary use in describing the origin of + the Work and reproducing the content of the NOTICE file. + +7. **Disclaimer of Warranty.** Unless required by applicable law or agreed to + in writing, Licensor provides the Work (and each Contributor provides its + Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied, including, without limitation, any + warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or + FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for + determining the appropriateness of using or redistributing the Work and + assume any risks associated with Your exercise of permissions under this + License. + +8. **Limitation of Liability.** In no event and under no legal theory, whether + in tort (including negligence), contract, or otherwise, unless required by + applicable law (such as deliberate and grossly negligent acts) or agreed to + in writing, shall any Contributor be liable to You for damages, including + any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or + inability to use the Work (including but not limited to damages for loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor has been + advised of the possibility of such damages. + +9. **Accepting Warranty or Additional Liability.** While redistributing the + Work or Derivative Works thereof, You may choose to offer, and charge a fee + for, acceptance of support, warranty, indemnity, or other liability + obligations and/or rights consistent with this License. However, in + accepting such obligations, You may act only on Your own behalf and on Your + sole responsibility, not on behalf of any other Contributor, and only if + You agree to indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor by + reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + -------------------------------------------------------------------- Dependency: github.com/gofrs/flock Revision: 5135e617513b1e6e205a3a89b042249dee6730c8 @@ -6097,6 +6330,40 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-------------------------------------------------------------------- +Dependency: golang.org/x/xerrors +Revision: 9bdfabe68543c54f90421aeb9a60ef8061b5b544 +License type (autodetected): BSD-3-Clause +./vendor/golang.org/x/xerrors/LICENSE: +-------------------------------------------------------------------- +Copyright (c) 2019 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + -------------------------------------------------------------------- Dependency: google.golang.org/api Version: v0.7.0 @@ -6222,239 +6489,6 @@ License type (autodetected): Apache-2.0 Apache License 2.0 --------------------------------------------------------------------- -Dependency: gopkg.in/goracle.v2 -Revision: 3222d7159b45fce95150f06a57e1bcc2868108d3 -License type (autodetected): Apache-2.0 -./vendor/gopkg.in/goracle.v2/LICENSE.md: --------------------------------------------------------------------- -Apache License 2.0 - - --------------------------------------------------------------------- -Dependency: gopkg.in/goracle.v2/odpi -License type (autodetected): UPL-1.0 -./vendor/gopkg.in/goracle.v2/odpi/LICENSE.md: --------------------------------------------------------------------- -Copyright (c) 2016, 2018 Oracle and/or its affiliates. All rights reserved. - -This program is free software: you can modify it and/or redistribute it under -the terms of: - -(i) the Universal Permissive License v 1.0 or at your option, any - later version (); and/or - -(ii) the Apache License v 2.0. () - - -The Universal Permissive License (UPL), Version 1.0 -=================================================== - -Subject to the condition set forth below, permission is hereby granted to any -person obtaining a copy of this software, associated documentation and/or data -(collectively the "Software"), free of charge and under any and all copyright -rights in the Software, and any and all patent rights owned or freely -licensable by each licensor hereunder covering either (i) the unmodified -Software as contributed to or provided by such licensor, or (ii) the Larger -Works (as defined below), to deal in both - -(a) the Software, and - -(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - one is included with the Software (each a "Larger Work" to which the - Software is contributed by such licensors), - -without restriction, including without limitation the rights to copy, create -derivative works of, display, perform, and distribute the Software and make, -use, sell, offer for sale, import, export, have made, and have sold the -Software and the Larger Work(s), and to sublicense the foregoing rights on -either these or other terms. - -This license is subject to the following condition: - -The above copyright notice and either this complete permission notice or at a -minimum a reference to the UPL must be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -Apache License -============== - -Version 2.0, January 2004 - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. **Definitions**. - - "License" shall mean the terms and conditions for use, reproduction, and - distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by the - copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all other - entities that control, are controlled by, or are under common control with - that entity. For the purposes of this definition, "control" means (i) the - power, direct or indirect, to cause the direction or management of such - entity, whether by contract or otherwise, or (ii) ownership of fifty - percent (50%) or more of the outstanding shares, or (iii) beneficial - ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity exercising - permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation source, - and configuration files. - - "Object" form shall mean any form resulting from mechanical transformation - or translation of a Source form, including but not limited to compiled - object code, generated documentation, and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or Object form, - made available under the License, as indicated by a copyright notice that - is included in or attached to the work (an example is provided in the - Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object form, - that is based on (or derived from) the Work and for which the editorial - revisions, annotations, elaborations, or other modifications represent, as - a whole, an original work of authorship. For the purposes of this License, - Derivative Works shall not include works that remain separable from, or - merely link (or bind by name) to the interfaces of, the Work and Derivative - Works thereof. - - "Contribution" shall mean any work of authorship, including the original - version of the Work and any modifications or additions to that Work or - Derivative Works thereof, that is intentionally submitted to Licensor for - inclusion in the Work by the copyright owner or by an individual or Legal - Entity authorized to submit on behalf of the copyright owner. For the - purposes of this definition, "submitted" means any form of electronic, - verbal, or written communication sent to the Licensor or its - representatives, including but not limited to communication on electronic - mailing lists, source code control systems, and issue tracking systems that - are managed by, or on behalf of, the Licensor for the purpose of discussing - and improving the Work, but excluding communication that is conspicuously - marked or otherwise designated in writing by the copyright owner as "Not a - Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity on - behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. **Grant of Copyright License.** Subject to the terms and conditions of this - License, each Contributor hereby grants to You a perpetual, worldwide, - non-exclusive, no-charge, royalty-free, irrevocable copyright license to - reproduce, prepare Derivative Works of, publicly display, publicly perform, - sublicense, and distribute the Work and such Derivative Works in Source or - Object form. - -3. **Grant of Patent License.** Subject to the terms and conditions of this - License, each Contributor hereby grants to You a perpetual, worldwide, - non-exclusive, no-charge, royalty-free, irrevocable (except as stated in - this section) patent license to make, have made, use, offer to sell, sell, - import, and otherwise transfer the Work, where such license applies only to - those patent claims licensable by such Contributor that are necessarily - infringed by their Contribution(s) alone or by combination of their - Contribution(s) with the Work to which such Contribution(s) was submitted. - If You institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work or a - Contribution incorporated within the Work constitutes direct or - contributory patent infringement, then any patent licenses granted to You - under this License for that Work shall terminate as of the date such - litigation is filed. - -4. **Redistribution.** You may reproduce and distribute copies of the Work or - Derivative Works thereof in any medium, with or without modifications, and - in Source or Object form, provided that You meet the following conditions: - - 1. You must give any other recipients of the Work or Derivative Works a - copy of this License; and - - 2. You must cause any modified files to carry prominent notices stating - that You changed the files; and - - 3. You must retain, in the Source form of any Derivative Works that You - distribute, all copyright, patent, trademark, and attribution notices - from the Source form of the Work, excluding those notices that do not - pertain to any part of the Derivative Works; and - - 4. If the Work includes a "NOTICE" text file as part of its distribution, - then any Derivative Works that You distribute must include a readable - copy of the attribution notices contained within such NOTICE file, - excluding those notices that do not pertain to any part of the - Derivative Works, in at least one of the following places: within a - NOTICE text file distributed as part of the Derivative Works; within - the Source form or documentation, if provided along with the Derivative - Works; or, within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents of the - NOTICE file are for informational purposes only and do not modify the - License. You may add Your own attribution notices within Derivative - Works that You distribute, alongside or as an addendum to the NOTICE - text from the Work, provided that such additional attribution notices - cannot be construed as modifying the License. - - You may add Your own copyright statement to Your modifications and may - provide additional or different license terms and conditions for use, - reproduction, or distribution of Your modifications, or for any such - Derivative Works as a whole, provided Your use, reproduction, and - distribution of the Work otherwise complies with the conditions stated - in this License. - -5. **Submission of Contributions.** Unless You explicitly state otherwise, any - Contribution intentionally submitted for inclusion in the Work by You to - the Licensor shall be under the terms and conditions of this License, - without any additional terms or conditions. Notwithstanding the above, - nothing herein shall supersede or modify the terms of any separate license - agreement you may have executed with Licensor regarding such Contributions. - -6. **Trademarks.** This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, except - as required for reasonable and customary use in describing the origin of - the Work and reproducing the content of the NOTICE file. - -7. **Disclaimer of Warranty.** Unless required by applicable law or agreed to - in writing, Licensor provides the Work (and each Contributor provides its - Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied, including, without limitation, any - warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or - FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for - determining the appropriateness of using or redistributing the Work and - assume any risks associated with Your exercise of permissions under this - License. - -8. **Limitation of Liability.** In no event and under no legal theory, whether - in tort (including negligence), contract, or otherwise, unless required by - applicable law (such as deliberate and grossly negligent acts) or agreed to - in writing, shall any Contributor be liable to You for damages, including - any direct, indirect, special, incidental, or consequential damages of any - character arising as a result of this License or out of the use or - inability to use the Work (including but not limited to damages for loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor has been - advised of the possibility of such damages. - -9. **Accepting Warranty or Additional Liability.** While redistributing the - Work or Derivative Works thereof, You may choose to offer, and charge a fee - for, acceptance of support, warranty, indemnity, or other liability - obligations and/or rights consistent with this License. However, in - accepting such obligations, You may act only on Your own behalf and on Your - sole responsibility, not on behalf of any other Contributor, and only if - You agree to indemnify, defend, and hold each Contributor harmless for any - liability incurred by, or claims asserted against, such Contributor by - reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - - -------------------------------------------------------------------- Dependency: gopkg.in/inf.v0 Revision: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 diff --git a/vendor/gopkg.in/goracle.v2/CHANGELOG.md b/vendor/github.com/godror/godror/CHANGELOG.md similarity index 69% rename from vendor/gopkg.in/goracle.v2/CHANGELOG.md rename to vendor/github.com/godror/godror/CHANGELOG.md index 7dd02ae08e3..0541bbe23b5 100644 --- a/vendor/gopkg.in/goracle.v2/CHANGELOG.md +++ b/vendor/github.com/godror/godror/CHANGELOG.md @@ -5,6 +5,102 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added + +## [2.24.0] +### Changed +- License: SPDX-License-Identifier: UPL-1.0 OR APL-2.0 + +## [2.23.5] +### Changed +- ODPI-C v3.3.0 + +## [2.23.2] +### Changed +- Close statement (and dpiStmt) on Break/bad conn. + +## [2.23.0] +### Added +- Conn.Timezone() returns the connection's timezone +- allow setting the timezone with Timezone ConnectionParam. +- Support to change password with NewPassword ConnectionParams. + +### Changed +- set DefaultEnqOptions and DefaultDeqOptions in NewQueue. +- make ConnectionParams.WaitTimeout, SessionMaxLifeTime, SessionTimeout be time.Duration. + +## [2.21.3] - 2019-10-03 +### Added +- Export Queue.PayloadObjectType +- Queue.SetEnqOptions, Queue.SetDeqOptions, Queue.SetDeqCorrelation + +## [2.21.1] - 2019-10-02 +### Changed +- Really close the connection if it's bad. For #194. +- ODPI-C v3.2.2 +- de-embed conn from Queue. + +## [2.20.1] - 2019-09-05 +### Added +- AsOraErr function + +### Changed +- Object.reset set attributes to null. +- Use golang.org/x/xerrors instead of github.com/pkg/errors. +- ObjectType.Close became unexported. + +## [2.20.0] - 2019-09-04 +### Added +- ObjectType cache in connection. +- Queue support with Objects. + +### Changed +- ObjectType.Close became unexported. +- Change Object Set/Get +- use golang.org/x/xerrors instead of github.com/pkg/errors. + +## [2.19.0] - 2019-08-15 +### Changed +- Require Context for getConn and thus in ClientVersion, ServerVersion, GetObjectType, DriverConn functions. + +## [2.18.5] - 2019-08-14 +### Changed +- Remove log.Println left in... + +## [2.18.4] - 2019-08-14 +### Changed +- Timezone detection: DBTIMEZONE is plain wrong, parse from SYSTIMESTAMP. + +## [2.18.3] - 2019-08-13 +### Changed +- GetObjectType uppercases the name by default. +- Upgrade to ODPI-C v3.2.1 + +## [2.18.2] - 2019-07-23 +### Changed +- Force copying of bytes (garbage appears Out with RAW). + +## [2.18.0] - 2019-07-16 +### Added +- Setable pool session timeouts. + +## [2.16.4] - 2019-06-26 +### Changed +- Fix bool input (#166). +- Allow region name from DBTIMEZONE, not just offset. + +## [2.16.2] - 2019-05-27 +### Changed +- Make Query AUTOCOMMIT like Exec - it's needed to release Rows for "FOR UPDATE". + +## [2.16.1] - 2019-05-27 +### Added +- Data.SetNull +- Expose dpiConn_newVar + +## [2.16.0] - 2019-05-17 +### Changed +- NumberAsString new option for #159. ## [2.15.3] - 2019-05-16 ### Changed @@ -70,7 +166,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed - Use ODPI-C v3.1.1 ### Added -- Make goracle.drv implement driver.DriverContext with OpenConnector. +- Make godror.drv implement driver.DriverContext with OpenConnector. ## [2.12.2] - 2019-02-15 ### Changed @@ -213,4 +309,3 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - initialize context / load lib only on first Open, to allow import without Oracle Client installed - use golangci-lint - diff --git a/vendor/gopkg.in/goracle.v2/LICENSE.md b/vendor/github.com/godror/godror/LICENSE.md similarity index 95% rename from vendor/gopkg.in/goracle.v2/LICENSE.md rename to vendor/github.com/godror/godror/LICENSE.md index f634025b67c..7ca5c6c439f 100644 --- a/vendor/gopkg.in/goracle.v2/LICENSE.md +++ b/vendor/github.com/godror/godror/LICENSE.md @@ -1,19 +1,12 @@ -goracle +godror ======= -Copyright 2017 Tamás Gulácsi +Copyright 2017, 2018, 2019 Tamás Gulácsi -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +You can use either the + Apache License, Version 2.0 (APL-2.0), +or the + Universal Permissive License, Version 1.0 (UPL-1.0). ODPI-C ====== diff --git a/vendor/gopkg.in/goracle.v2/NOTES.md b/vendor/github.com/godror/godror/NOTES.md similarity index 100% rename from vendor/gopkg.in/goracle.v2/NOTES.md rename to vendor/github.com/godror/godror/NOTES.md diff --git a/vendor/gopkg.in/goracle.v2/README.md b/vendor/github.com/godror/godror/README.md similarity index 72% rename from vendor/gopkg.in/goracle.v2/README.md rename to vendor/github.com/godror/godror/README.md index 8673ff1a789..97697086919 100644 --- a/vendor/gopkg.in/goracle.v2/README.md +++ b/vendor/github.com/godror/godror/README.md @@ -1,25 +1,29 @@ -[![Build Status](https://travis-ci.org/go-goracle/goracle.svg?branch=v2)](https://travis-ci.org/go-goracle/goracle) -[![GoDoc](https://godoc.org/gopkg.in/goracle.v2?status.svg)](http://godoc.org/gopkg.in/goracle.v2) -[![Go Report Card](https://goreportcard.com/badge/github.com/go-goracle/goracle)](https://goreportcard.com/report/github.com/go-goracle/goracle) -[![codecov](https://codecov.io/gh/go-goracle/goracle/branch/master/graph/badge.svg)](https://codecov.io/gh/go-goracle/goracle) +[![Travis](https://travis-ci.org/godror/godror.svg?branch=v2)](https://travis-ci.org/godror/godror) +[![CircleCI](https://circleci.com/gh/godror/godror.svg?style=svg)](https://circleci.com/gh/godror/godror) +[![GoDoc](https://godoc.org/github.com/godror/godror?status.svg)](http://godoc.org/github.com/godror/godror) +[![Go Report Card](https://goreportcard.com/badge/github.com/godror/godror)](https://goreportcard.com/report/github.com/godror/godror) +[![codecov](https://codecov.io/gh/godror/godror/branch/master/graph/badge.svg)](https://codecov.io/gh/godror/godror) -# goracle +# Go DRiver for ORacle -[goracle](driver.go) is a package which is a +[godror](https://godoc.org/pkg/github.com/godror/godror) is a package which is a [database/sql/driver.Driver](http://golang.org/pkg/database/sql/driver/#Driver) for connecting to Oracle DB, using Anthony Tuininga's excellent OCI wrapper, [ODPI-C](https://www.github.com/oracle/odpi). At least Go 1.11 is required! +Although an Oracle client is NOT required for compiling, it is at run time. +One can download it from https://www.oracle.com/database/technologies/instant-client/downloads.html + ## Connect -In `sql.Open("goracle", connString)`, you can provide the classic "user/passw@service_name" +In `sql.Open("godror", connString)`, you can provide the classic "user/passw@service_name" as connString, or an URL like "oracle://user:passw@service_name". You can provide all possible options with `ConnectionParams`. Watch out the `ConnectionParams.String()` does redact the password -(for security, to avoid logging it - see https://github.com/go-goracle/goracle/issues/79). +(for security, to avoid logging it - see https://github.com/godror/godror/issues/79). So use `ConnectionParams.StringWithPassword()`. More advanced configurations can be set with a connection string such as: @@ -29,22 +33,22 @@ A configuration like this is how you would add functionality such as load balanc described in parenthesis above can also be set in the `SID` field of `ConnectionParams`. For other possible connection strings, see https://oracle.github.io/node-oracledb/doc/api.html#connectionstrings -and https://docs.oracle.com/en/database/oracle/oracle-database/12.2/netag/configuring-naming-methods.html#GUID-B0437826-43C1-49EC-A94D-B650B6A4A6EE . +and https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-B0437826-43C1-49EC-A94D-B650B6A4A6EE . TL;DR; the short form is `username@[//]host[:port][/service_name][:server][/instance_name]`, the long form is `(DESCRIPTION= (ADDRESS=(PROTOCOL=tcp)(HOST=host)(PORT=port)) (CONNECT_DATA= (SERVICE_NAME=service_name) (SERVER=server) (INSTANCE_NAME=instance_name)))`. To use heterogeneous pools, set `heterogeneousPool=1` and provide the username/password through -`goracle.ContextWithUserPassw`. +`godror.ContextWithUserPassw`. ## Rationale With Go 1.9, driver-specific things are not needed, everything (I need) can be achieved with the standard _database/sql_ library. Even calling stored procedures with OUT parameters, or sending/retrieving PL/SQL array types - just give a -`goracle.PlSQLArrays` Option within the parameters of `Exec`! +`godror.PlSQLArrays` Option within the parameters of `Exec`! -The array size of the returned PL/SQL arrays can be set with `goracle.ArraySize(2000)` +The array size of the returned PL/SQL arrays can be set with `godror.ArraySize(2000)` * the default is 1024. @@ -56,7 +60,7 @@ Correctness and simplicity is more important than speed, but the underlying ODPI helps a lot with the lower levels, so the performance is not bad. Queries are prefetched (256 rows by default, can be changed by adding a -`goracle.FetchRowCount(1000)` argument to the call of Query), +`godror.FetchRowCount(1000)` argument to the call of Query), but you can speed up INSERT/UPDATE/DELETE statements by providing all the subsequent parameters at once, by putting each param's subsequent elements in a separate slice: @@ -72,28 +76,28 @@ do ## Logging -Goracle uses `github.com/go-kit/kit/log`'s concept of a `Log` function. -Either set `goracle.Log` to a logging function globally, +godror uses `github.com/go-kit/kit/log`'s concept of a `Log` function. +Either set `godror.Log` to a logging function globally, or (better) set the logger in the Context of ExecContext or QueryContext: - db.QueryContext(goracle.ContextWithLog(ctx, logger.Log), qry) + db.QueryContext(godror.ContextWithLog(ctx, logger.Log), qry) ## Tracing To set ClientIdentifier, ClientInfo, Module, Action and DbOp on the session, -to be seen in the Database by the Admin, set goracle.TraceTag on the Context: +to be seen in the Database by the Admin, set godror.TraceTag on the Context: - db.QueryContext(goracle.ContextWithTraceTag(goracle.TraceTag{ + db.QueryContext(godror.ContextWithTraceTag(godror.TraceTag{ Module: "processing", Action: "first", }), qry) ## Extras -To use the goracle-specific functions, you'll need a `*goracle.conn`. -That's what `goracle.DriverConn` is for! +To use the godror-specific functions, you'll need a `*godror.conn`. +That's what `godror.DriverConn` is for! See [z_qrcn_test.go](./z_qrcn_test.go) for using that to reach -[NewSubscription](https://godoc.org/gopkg.in/goracle.v2#Subscription). +[NewSubscription](https://godoc.org/github.com/godror/godror#Subscription). ### Calling stored procedures Use `ExecContext` and mark each OUT parameter with `sql.Out`. @@ -101,7 +105,7 @@ Use `ExecContext` and mark each OUT parameter with `sql.Out`. ### Using cursors returned by stored procedures Use `ExecContext` and an `interface{}` or a `database/sql/driver.Rows` as the `sql.Out` destination, then either use the `driver.Rows` interface, -or transform it into a regular `*sql.Rows` with `goracle.WrapRows`, +or transform it into a regular `*sql.Rows` with `godror.WrapRows`, or (since Go 1.12) just Scan into `*sql.Rows`. For examples, see Anthony Tuininga's @@ -124,7 +128,7 @@ Just use plain old `string` ! ### NUMBER -`NUMBER`s are transferred as `goracle.Number` (which is a `string`) to Go under the hood. +`NUMBER`s are transferred as `godror.Number` (which is a `string`) to Go under the hood. This ensures that we don't lose any precision (Oracle's NUMBER has 38 decimal digits), and `sql.Scan` will hide this and `Scan` into your `int64`, `float64` or `string`, as you wish. @@ -158,11 +162,11 @@ See #121. Just - go get gopkg.in/goracle.v2 + go get github.com/godror/godror Or if you prefer `dep` - dep ensure -add gopkg.in/goracle.v2 + dep ensure -add github.com/godror/godror and you're ready to go! @@ -173,14 +177,14 @@ Note that Windows may need some newer gcc (mingw-w64 with gcc 7.2.0). Just as with other Go projects, you don't want to change the import paths, but you can hack on the library in place, just set up different remotes: - cd $GOPATH.src/gopkg.in/goracle.v2 - git remote add upstream https://github.com/go-goracle/goracle.git + cd $GOPATH.src/github.com/godror/godror + git remote add upstream https://github.com/godror/godror.git git fetch upstream git checkout -b master upstream/master git checkout -f master git pull upstream master - git remote add fork git@github.com:mygithubacc/goracle + git remote add fork git@github.com:mygithubacc/godror git checkout -b newfeature upstream/master Change, experiment as you wish, then @@ -188,7 +192,7 @@ Change, experiment as you wish, then git commit -m 'my great changes' *.go git push fork newfeature -and you're ready to send a GitHub Pull Request from `github.com/mygithubacc/goracle`, `newfeature` branch. +and you're ready to send a GitHub Pull Request from `github.com/mygithubacc/godror`, `newfeature` branch. ### pre-commit diff --git a/vendor/gopkg.in/goracle.v2/conn.go b/vendor/github.com/godror/godror/conn.go similarity index 74% rename from vendor/gopkg.in/goracle.v2/conn.go rename to vendor/github.com/godror/godror/conn.go index e5a9bb6c3a2..f1476349729 100644 --- a/vendor/gopkg.in/goracle.v2/conn.go +++ b/vendor/github.com/godror/godror/conn.go @@ -1,19 +1,9 @@ // Copyright 2019 Tamás Gulácsi // // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include @@ -22,16 +12,18 @@ package goracle import "C" import ( + "bytes" "context" "database/sql" "database/sql/driver" "io" + "strconv" "strings" "sync" "time" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) const getConnection = "--GET_CONNECTION--" @@ -40,14 +32,16 @@ const wrapResultset = "--WRAP_RESULTSET--" // The maximum capacity is limited to (2^32 / sizeof(dpiData))-1 to remain compatible // with 32-bit platforms. The size of a `C.dpiData` is 32 Byte on a 64-bit system, `C.dpiSubscrMessageTable` is 40 bytes. // So this is 2^25. -// See https://github.com/go-goracle/goracle/issues/73#issuecomment-401281714 -const maxArraySize = (1<<30)/C.sizeof_dpiSubscrMessageTable - 1 +// See https://github.com/go-godror/godror/issues/73#issuecomment-401281714 +const maxArraySize = (1<<32)/C.sizeof_dpiSubscrMessageTable - 1 var _ = driver.Conn((*conn)(nil)) var _ = driver.ConnBeginTx((*conn)(nil)) var _ = driver.ConnPrepareContext((*conn)(nil)) var _ = driver.Pinger((*conn)(nil)) +//var _ = driver.ExecerContext((*conn)(nil)) + type conn struct { connParams ConnectionParams currentTT TraceTag @@ -61,6 +55,7 @@ type conn struct { newSession bool timeZone *time.Location tzOffSecs int + objTypes map[string]ObjectType } func (c *conn) getError() error { @@ -77,7 +72,7 @@ func (c *conn) Break() error { Log("msg", "Break", "dpiConn", c.dpiConn) } if C.dpiConn_breakExecution(c.dpiConn) == C.DPI_FAILURE { - return maybeBadConn(errors.Wrap(c.getError(), "Break")) + return maybeBadConn(errors.Errorf("Break: %w", c.getError()), c) } return nil } @@ -102,7 +97,7 @@ func (c *conn) Ping(ctx context.Context) error { defer close(done) failure := C.dpiConn_ping(c.dpiConn) == C.DPI_FAILURE if failure { - done <- maybeBadConn(errors.Wrap(c.getError(), "Ping")) + done <- maybeBadConn(errors.Errorf("Ping: %w", c.getError()), c) return } done <- nil @@ -118,6 +113,7 @@ func (c *conn) Ping(ctx context.Context) error { return err default: _ = c.Break() + c.close(true) return driver.ErrBadConn } } @@ -142,28 +138,49 @@ func (c *conn) Close() error { } c.Lock() defer c.Unlock() + return c.close(true) +} + +func (c *conn) close(doNotReuse bool) error { + if c == nil { + return nil + } c.setTraceTag(TraceTag{}) - dpiConn := c.dpiConn - c.dpiConn = nil + dpiConn, objTypes := c.dpiConn, c.objTypes + c.dpiConn, c.objTypes = nil, nil if dpiConn == nil { return nil } + defer C.dpiConn_release(dpiConn) + + seen := make(map[string]struct{}, len(objTypes)) + for _, o := range objTypes { + nm := o.FullName() + if _, seen := seen[nm]; seen { + continue + } + seen[nm] = struct{}{} + o.close() + } + if !doNotReuse { + return nil + } + // Just to be sure, break anything in progress. done := make(chan struct{}) go func() { select { case <-done: case <-time.After(10 * time.Second): + if Log != nil { + Log("msg", "TIMEOUT releasing connection") + } C.dpiConn_breakExecution(dpiConn) } }() - rc := C.dpiConn_release(dpiConn) + C.dpiConn_close(dpiConn, C.DPI_MODE_CONN_CLOSE_DROP, nil, 0) close(done) - var err error - if rc == C.DPI_FAILURE { - err = maybeBadConn(errors.Wrap(c.getError(), "Close")) - } - return err + return nil } // Begin starts and returns a new transaction. @@ -210,7 +227,7 @@ func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, e case sql.LevelSerializable: todo.Level = trLS default: - return nil, errors.Errorf("%v isolation level is not supported", sql.IsolationLevel(opts.Isolation)) + return nil, errors.Errorf("isolation level is not supported: %s", sql.IsolationLevel(opts.Isolation)) } if todo != c.tranParams { @@ -229,7 +246,7 @@ func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, e stmt.Close() } if err != nil { - return nil, maybeBadConn(errors.Wrap(err, qry)) + return nil, maybeBadConn(errors.Errorf("%s: %w", qry, err), c) } } c.tranParams = todo @@ -288,7 +305,7 @@ func (c *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, e if C.dpiConn_prepareStmt(c.dpiConn, 0, cSQL, C.uint32_t(len(query)), nil, 0, (**C.dpiStmt)(unsafe.Pointer(&dpiStmt)), ) == C.DPI_FAILURE { - return nil, maybeBadConn(errors.Wrap(c.getError(), "Prepare: "+query)) + return nil, maybeBadConn(errors.Errorf("Prepare: %s: %w", query, c.getError()), c) } return &statement{conn: c, dpiStmt: dpiStmt, query: query}, nil } @@ -307,12 +324,12 @@ func (c *conn) endTran(isCommit bool) error { //msg := "Commit" if isCommit { if C.dpiConn_commit(c.dpiConn) == C.DPI_FAILURE { - err = maybeBadConn(errors.Wrap(c.getError(), "Commit")) + err = maybeBadConn(errors.Errorf("Commit: %w", c.getError()), c) } } else { //msg = "Rollback" if C.dpiConn_rollback(c.dpiConn) == C.DPI_FAILURE { - err = maybeBadConn(errors.Wrap(c.getError(), "Rollback")) + err = maybeBadConn(errors.Errorf("Rollback: %w", c.getError()), c) } } c.Unlock() @@ -350,7 +367,7 @@ func (c *conn) newVar(vi varInfo) (*C.dpiVar, []C.dpiData, error) { isArray, vi.ObjectType, &v, &dataArr, ) == C.DPI_FAILURE { - return nil, nil, errors.Wrapf(c.getError(), "newVar(typ=%d, natTyp=%d, sliceLen=%d, bufSize=%d)", vi.Typ, vi.NatTyp, vi.SliceLen, vi.BufSize) + return nil, nil, errors.Errorf("newVar(typ=%d, natTyp=%d, sliceLen=%d, bufSize=%d): %w", vi.Typ, vi.NatTyp, vi.SliceLen, vi.BufSize, c.getError()) } // https://github.com/golang/go/wiki/cgo#Turning_C_arrays_into_Go_slices /* @@ -380,59 +397,142 @@ func (c *conn) init() error { var release *C.char var releaseLen C.uint32_t if C.dpiConn_getServerVersion(c.dpiConn, &release, &releaseLen, &v) == C.DPI_FAILURE { - return errors.Wrap(c.getError(), "getServerVersion") + if c.connParams.IsPrelim { + return nil + } + return errors.Errorf("getServerVersion: %w", c.getError()) } c.Server.set(&v) - c.Server.ServerRelease = C.GoStringN(release, C.int(releaseLen)) + c.Server.ServerRelease = string(bytes.Replace( + ((*[maxArraySize]byte)(unsafe.Pointer(release)))[:releaseLen:releaseLen], + []byte{'\n'}, []byte{';', ' '}, -1)) } - if c.timeZone != nil { + if c.timeZone != nil && (c.timeZone != time.Local || c.tzOffSecs != 0) { return nil } c.timeZone = time.Local - _, c.tzOffSecs = (time.Time{}).In(c.timeZone).Zone() + _, c.tzOffSecs = time.Now().In(c.timeZone).Zone() + if Log != nil { + Log("tz", c.timeZone, "offSecs", c.tzOffSecs) + } - const qry = "SELECT DBTIMEZONE FROM DUAL" + // DBTIMEZONE is useless, false, and misdirecting! + // https://stackoverflow.com/questions/52531137/sysdate-and-dbtimezone-different-in-oracle-database + const qry = "SELECT DBTIMEZONE, LTRIM(REGEXP_SUBSTR(TO_CHAR(SYSTIMESTAMP), ' [^ ]+$')) FROM DUAL" ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() st, err := c.PrepareContext(ctx, qry) if err != nil { - return errors.Wrap(err, qry) + return errors.Errorf("%s: %w", qry, err) } defer st.Close() - rows, err := st.Query([]driver.Value{}) + rows, err := st.Query(nil) //lint:ignore SA1019 - it's hard to use QueryContext here if err != nil { - return errors.Wrap(err, qry) + if Log != nil { + Log("qry", qry, "error", err) + } + return nil } defer rows.Close() - var timezone string - vals := []driver.Value{timezone} - for { - if err = rows.Next(vals); err != nil { - if err == io.EOF { - break + var dbTZ, timezone string + vals := []driver.Value{dbTZ, timezone} + if err = rows.Next(vals); err != nil && err != io.EOF { + return errors.Errorf("%s: %w", qry, err) + } + dbTZ = vals[0].(string) + timezone = vals[1].(string) + + tz, off, err := calculateTZ(dbTZ, timezone) + if Log != nil { + Log("timezone", timezone, "tz", tz, "offSecs", off) + } + if err != nil || tz == nil { + return err + } + c.timeZone, c.tzOffSecs = tz, off + + return nil +} + +func calculateTZ(dbTZ, timezone string) (*time.Location, int, error) { + if Log != nil { + Log("dbTZ", dbTZ, "timezone", timezone) + } + var tz *time.Location + now := time.Now() + _, localOff := time.Now().Local().Zone() + off := localOff + var ok bool + var err error + if dbTZ != "" && strings.Contains(dbTZ, "/") { + tz, err = time.LoadLocation(dbTZ) + if ok = err == nil; ok { + if tz == time.Local { + return tz, off, nil } - return errors.Wrap(err, qry) + _, off = now.In(tz).Zone() + } else if Log != nil { + Log("LoadLocation", dbTZ, "error", err) } - timezone = strings.TrimSpace(vals[0].(string)) + } + if !ok { if timezone != "" { - break + if off, err = parseTZ(timezone); err != nil { + return tz, off, errors.Errorf("%s: %w", timezone, err) + } + } else if off, err = parseTZ(dbTZ); err != nil { + return tz, off, errors.Errorf("%s: %w", dbTZ, err) } } - if timezone == "" { - return errors.New("empty DBTIMEZONE") + // This is dangerous, but I just cannot get whether the DB time zone + // setting has DST or not - DBTIMEZONE returns just a fixed offset. + if off != localOff && tz == nil { + tz = time.FixedZone(timezone, off) + } + return tz, off, nil +} +func parseTZ(s string) (int, error) { + s = strings.TrimSpace(s) + if s == "" { + return 0, io.EOF + } + if s == "Z" || s == "UTC" { + return 0, nil } - if off, err := parseTZ(timezone); err != nil { - return errors.Wrap(err, timezone) + var tz int + var ok bool + if i := strings.IndexByte(s, ':'); i >= 0 { + if i64, err := strconv.ParseInt(s[i+1:], 10, 6); err != nil { + return tz, errors.Errorf("%s: %w", s, err) + } else { + tz = int(i64 * 60) + } + s = s[:i] + ok = true + } + if !ok { + if i := strings.IndexByte(s, '/'); i >= 0 { + targetLoc, err := time.LoadLocation(s) + if err != nil { + return tz, errors.Errorf("%s: %w", s, err) + } + + _, localOffset := time.Now().In(targetLoc).Zone() + + tz = localOffset + return tz, nil + } + } + if i64, err := strconv.ParseInt(s, 10, 5); err != nil { + return tz, errors.Errorf("%s: %w", s, err) } else { - // This is dangerous, but I just cannot get whether the DB time zone - // setting has DST or not - DBTIMEZONE returns just a fixed offset. - if _, localOff := time.Now().Local().Zone(); localOff != off { - c.tzOffSecs = off - c.timeZone = time.FixedZone(timezone, c.tzOffSecs) + if i64 < 0 { + tz = -tz } + tz += int(i64 * 3600) } - return nil + return tz, nil } func (c *conn) setCallTimeout(ctx context.Context) { @@ -447,21 +547,34 @@ func (c *conn) setCallTimeout(ctx context.Context) { C.dpiConn_setCallTimeout(c.dpiConn, ms) } -func maybeBadConn(err error) error { +// maybeBadConn checks whether the error is because of a bad connection, and returns driver.ErrBadConn, +// as database/sql requires. +// +// Also in this case, iff c != nil, closes it. +func maybeBadConn(err error, c *conn) error { if err == nil { return nil } - root := errors.Cause(err) - if root == driver.ErrBadConn { - return root + cl := func() {} + if c != nil { + cl = func() { + if Log != nil { + Log("msg", "maybeBadConn close", "conn", c) + } + c.close(true) + } } - if cd, ok := root.(interface { - Code() int - }); ok { + if errors.Is(err, driver.ErrBadConn) { + cl() + return driver.ErrBadConn + } + var cd interface{ Code() int } + if errors.As(err, &cd) { // Yes, this is copied from rana/ora, but I've put it there, so it's mine. @tgulacsi switch cd.Code() { case 0: if strings.Contains(err.Error(), " DPI-1002: ") { + cl() return driver.ErrBadConn } // cases by experience: @@ -500,6 +613,7 @@ func maybeBadConn(err error) error { 27146, // post/wait initialization failed 28511, // lost RPC connection 56600: // an illegal OCI function call was issued + cl() return driver.ErrBadConn } } @@ -542,7 +656,7 @@ func (c *conn) setTraceTag(tt TraceTag) error { C.free(unsafe.Pointer(s)) } if rc == C.DPI_FAILURE { - return errors.Wrap(c.getError(), nm) + return errors.Errorf("%s: %w", nm, c.getError()) } } c.currentTT = tt @@ -592,7 +706,7 @@ func (c *conn) ensureContextUser(ctx context.Context) error { } if c.dpiConn != nil { - if err := c.Close(); err != nil { + if err := c.close(false); err != nil { return driver.ErrBadConn } } @@ -625,7 +739,7 @@ const ( // See https://docs.oracle.com/en/database/oracle/oracle-database/18/lnoci/database-startup-and-shutdown.html#GUID-44B24F65-8C24-4DF3-8FBF-B896A4D6F3F3 func (c *conn) Startup(mode StartupMode) error { if C.dpiConn_startupDatabase(c.dpiConn, C.dpiStartupMode(mode)) == C.DPI_FAILURE { - return errors.Wrapf(c.getError(), "startup(%v)", mode) + return errors.Errorf("startup(%v): %w", mode, c.getError()) } return nil } @@ -654,7 +768,12 @@ const ( // See https://docs.oracle.com/en/database/oracle/oracle-database/18/lnoci/database-startup-and-shutdown.html#GUID-44B24F65-8C24-4DF3-8FBF-B896A4D6F3F3 func (c *conn) Shutdown(mode ShutdownMode) error { if C.dpiConn_shutdownDatabase(c.dpiConn, C.dpiShutdownMode(mode)) == C.DPI_FAILURE { - return errors.Wrapf(c.getError(), "shutdown(%v)", mode) + return errors.Errorf("shutdown(%v): %w", mode, c.getError()) } return nil } + +// Timezone returns the connection's timezone. +func (c *conn) Timezone() *time.Location { + return c.timeZone +} diff --git a/vendor/github.com/godror/godror/contrib/free.db/cwallet.sso b/vendor/github.com/godror/godror/contrib/free.db/cwallet.sso new file mode 100644 index 0000000000000000000000000000000000000000..c9eeffc2ffed3f7b333ef773cd5b77090a13f97b GIT binary patch literal 6733 zcmV-T8nWe~_)aze000I6001Edk^buV=5@>Lk>Tc^gHgxCF%cEXrg&nLD++JAr->s0 zFoGH!0s#Xsf*Ill2`Yw2hW8Bt2LYgh8Pf!U8P70+8Otz&8OH_*Duzgg_YDCD2B3l& zxG;hlv;qMDFoGGa1_>&LNQUUfitFOPpEvDqrS;Xh-i@)`zfSV zChNRZNeu~jHEty?;|~O!Y<6iNRC8xT^;q%*=uUL05;Nhk<6cBKU)!A(BUlW^#{B%o zbmTcBU={|wN+zSEHfS_Mm8{Xp$e{5faQy(M?}447TK1U}39K=VAiwLltJ;n)JM)OA zs+Lfgm@()4i`ajO&R=ig$uMwgdvHk_+fzUNEA8d&#iIGRum9+QzO2s70Y4TA4} zEx%L^)>}oHtcYP#rF^)CZ3|B;j9dZT?FDyDDtH%Dwmk&ppw4dnnCNGe)yq&Qf}w`! z=n?jcs9<{J^tLOLKQZ=8!QW5wqZedS{Yg&hWGwR>t?05iihG?H{M0Q=zJ&6Elj55AI?v{K^npW> zU=^dSz+Qm96vMjk)soL*RsGOQ0NsvYvwIgfw7eHo!m#QZLsTy4{LZAPK!yVD6+d2A zs&@yNCIxe<#cH--f=Z-b2?Za7Q37Tclsiz5o<^pEaJuFa!b^QfJr8?}E|aiUm0ahF zCl>lMR~#y=_P1Q40VqcYhtTT&2Tq^~_e@;mAb2c}e>#iTWzjiGoFA|=sLH4ML%y?m zcv)D)LV7fg+jYcY;T(&o@Zw>_$cVL1%3f9#!fW~vjY2rNKKJmxH_awb-a~-)k{i*? zOvQi^?QGLPjci>|D)S!-W+$~usA$$+ef*OP%+TQqT~XPUiFsxXP-lZxfE&mPuGeU1 z>6VD7USll`I)3-vNC6mQiyS$2V-I;=l3JTboNiAXh+v&439)jMN4~1B^|(w{sORcY|H0@rzNtXPN$6);{Xt7k zI1=rcey~G%{%=WOma_pHj*p)`#ErebD$piv`Ji{$`e2Zr4E8%#;lTws=TEyT&-T5$Gg6F2EB4iQ*G7PrVX(y5O`QbUDAC3Opc;*<_y(X8{;{sCWT@>*mUf zt#gxMhC?7g)-?Eir6fkolz1oI*5Tms$Fca*#-&#+3YAP_~dbj9qmDl93X zs>T$?R-Eu)5jTuyII?A`s+zjF_Ch&MPi@@qmVvMCJslgb=yy-Nan+Fn5GOYO`Pi+} z^A)9nL|jFu-dr(kyoe~z7<;bOc}4XDAa-Uoj;{68KOKy<{d$&3dAvx_KX#KdA$KSM zT9ycnGwmhle(N~r3WcBW__JHWas5O_aPghIA-4Wp84*<&nf``zsWR?RU_PBP?$bBWmVpVXP;;+gm62T|Lv8#g~qnTB9}!KPp&nL<)X_9 zRC5m{T+-sW(S&y>#3-e=3ZY@=k|0R-ehX|6bzvpVdr~s3bm<8EKM6^jmZi~7)atRs z)2xE+8N>|VKhO!&>^pIwp9A4 zYtVx4F@V53SLP@tO@T-MAR_Z}{ImEqkMqHwU+cx0&5<80lFp|{)5~myiVqD|`%Q4> z$f9JjKqP!a3+}O`mEy}3UZ_YZH&!PLhcBY$cfd1FW3DzL!n6hIuU4n+@Xa* z2VQ_%+c60iSttkT6O5bsj|FTH@OR0pAMA zvTrVzS>YfupC&D2@B{MD}$r;SpiP=TP z6Sj*!FSaF=}icXhJg(I~0-JBpQpe4`D4*( z!%E&{yw{5WT|{0LbX!?i`LI<&d;F!(W_O=$Tbo|?_BXJ%lQ1R{8nCH zi@+M|5zw}mZ>J%Xb){igJtM6J0v3oJrHvLByYtc9+pEbUPT+;WONl^6uUMGzoPQ+$ z9<4PFDnGor9L7L z3KopuXi|DEpWY%O!_1%1%{VA__Yt^Wl7FIWWx+-BGn31_m3M8sZK51i!B(51c8F>e~{0{WS(z zlpB0e>#FAQySJH^JKg_qXv-05n0r|lbC_bwxjJeEUWI!s3midnM&{mDiEqt2EsYk| z>uw+tS{x`_goZ-SbRLSXOJ{=XbrGS;Th%$0rB&Q!2j>6)G&_65Z(p4`jaB<@b<@ z*s>c)lnGdRt&+69H}$V{gWd+fYWYn(nwOMN`$&u6s1aDl14?tklUykC}3p9@-$n znfAi8k87WcwtM)j;YMUBU$LpXRs0z)t8=kQMIJwCEupAF1=3NlN!fVM1{Lx*ifwx| zKq#?=n`ON(uU_q@eD%UQ;~KdQ#L0#5%y6Whc@ov$?$~18NOL!^CRTpQvDfOa>M9Ii z2>a(7uU5xdRx2PU93GPx0%1{lS2UBwAgbp5VHB^(?O$p$ZJiSR zOx3uiSQQOXr?(bV!guiuzs*0Evk#SbXOej3!MDGce=a%*Us=?Q+EE(iZZu`JjgnKh z3WA3E0q}x+6m>B0lbiQWOrK>i?fqzDJBC}OIF+`8H`rTall@9=`vQ3i*E|!>f2N0i zBLywBfn)B+c?1%qrq&v{XF#&|D}%w$ZSgxF6AF?m)B_FZ8H&L@9sJop?hlRALF&cS!5jCul>UY}dpk0= zj+QLqT|vkc{YX(0i6b#=Z{h@5AN*m}oSZVb!s^@61x=%@jCG%64j9x>wK3+jAZ$M% zbRkx2VC@NY?RS(QFi|R5suzDNHvFd-HVoqyv>6f+*Ki6 zn}UC4=)0ocABssTs;o2MaE2lETp81*+Xjd+5K}#wgG2)_iC|VJ$Ds8TtamClcH2LW!y1$*^?-Jg+qRrG0^e^#@vA@|q(1hb zjq%1d7Zfy1IbTD{!F*`EVmDT+K9dfe%UUe+(A!9Jx=<##2NAFsi?q}nBX)3S9BW;POTh*atG?bgnYS1F%!(^qtqRszr-p+%qhlf zbh|oKnFX5>)we)NeS%PVy2}ujV|6t<*umHX4(b2ZqcqE}CiA?QMr`c2 zQ!^PFpoUm}ZKv6gugpjgWe_m0h9tpsnB?gzUAk#v@3FRiDYK%UCqNHXedHmoUQ34q zE78(~Le2b>4~piKgce!`&||ywty^y?M$ljhWIlx9oAh7la}{@>CgEJBk2_hc@z&=M zARxIhinm^~#b_`$)P{HF0i}yEsgri6B6%&iSJ&(y)POuPF(UXL&gXRZtx(A(hFZ*= zNj~qKO;ilf!wD&{){w-#^WqqjxG@*MEhOFiK_yp#%7lLG)q_f!kbI9m!yhj)=^)Xv zmdsT$5TsiYs=vkE9(qA#oAHAx%HIO0*0gqCe_?F72?ed%lX*J{#uFY1yA zXWJ2UE6x(rYVye<+Lz*nMm1eTuK+e&6t6I#reVJ<;jOr~>O59F1Wo`gV9xdPfd-fv zU3&iO5LfNv3}?;bHo{4!I7GWED@w*q$~Q90 z$Rpclkxzw@cisXpVt6d_)a;F(8mpbrRH*x%oz|ETkS2<>!(oCt-oy#Cz4wb$m5c2) z>15$l_QF~$y~*QWM}i^^(8&35^pCk86kPz1oF^-Fur+DodL{>_6rvQ>cUOz=vtPsw zeInE1fH);I6U$6Q_qxIejKIR5%)Gz~iZza7eeBY@a7p73y@iQkdB(H7ltB5~Z_uze}M7VrNNaw1@}o4tU4z>-j%=s*?12h)YUD$}>9wQ5u{~ z%cP%_@IUTcm@48A0=x+)OF#wQ>QfHVQJ21;eLotQM@sWDQ|I>xrTIrtCp?o_8?uuT z(Kx{Khn`Ve4P?vNB}5$UM(r7xpOti{+9{(PG8Gw1hKsNT733d5hs9*Y;WT>*!I4|s zXM7AwDHx0}`+r6&21b!Q3c0qjN7tN3-cX~uRkXG=wNpp#FQpJ8nCDK@7{y048_+!3 z&IXvMJ4l3xnt+8zZ`7t%H_|wnM3~s`>Nnn)0)uIo^o-03Td-nY1WL>+Z#zLE#!F>s z`o111Y_JUrBr)N$-}EonZMET9*yn_^LYB!@O_F+hNp6dErQwRo6)U9RmRtaBe=$He z9K_Qf45#h53EB3;p;j1djI(ZE19s2|lnkRcOF1k5MA1BBUU;2x3sJiGw7kPH^rK!7 zzMOxX=%<^2jE%PvD?T1uuF-|=S-!_kyOe<%xVL8Ae|Ud?n=pEi6JY6K&E-{AGDcfG zYzT@zyrZl`&ko&3$HIx9Xn|P1x6Kxc`8`NzQs=^CPgaQg+-%*&3%hgU(Mt;lL#NgyFbKi7{W zxtSuX0YvMw!gl4{Hab@kg#dxJY$DC+5n&P$0350#qd8!ebjlwo%lWsVj*TGSXG?Ma z9F0>qDQ$`$dHM9e33)%eL}i7YU2sw7A= zV?-gzo{M4xKY=4*s9d>z`rLX0GX30$zQLrdZyPCYvr?y9ddl>JIPx`k(sgZfGyol@ zqn=3sTGJ!WuXY*76$lVlwX;q909-p`;g!|8c#@Mp%c^<;2kGp)OdBUbk=GUP1JiEo zGd%2_s3^@7M6!x3*GYf0=8A8{xC1XnDf}JmU}5(f5eIKPGTIUrGD$t zcCTQTx9H!RQP8I{O`oxhKW;PQ+rVnDWYwPgn@2DuTf7H3P2H(1;>R7yl3pdkooOT=dc!9W)%PJI)_LY-TAxQPum%Ab^ABxoRpLrX3=Bj~fFop|S z;1OSF9_J+6$GEMJ7Kh!GihrC+hl?@7Zc|aIS7X|;3cH}{qe@AFkMWUn12|PtWb3fh z%6`H$E&sjH1Q_GfKy6dZv_ddfFvj+`UQ$w=!{t*x7S!~^-}^jmuuKgq6#Wrl3s^Dx zGZ0FD{Q^nkx_Ok`92N6l*le;I8FVDp&PwZ}oz#1CI^A;Qqw80_-oAy;C<;8<+a==+ zRR_ykDbZP4e^jD26iF%B8x-p6LPmt;4WM->mrJUuZDqF{-jaTWZ?IoEoE$YAlAY-u zFebrjh3?J-H#MwkV<@`!f##wvO>LRIrPb0jQG5#L5n>!&W(tN3g|sasc;-=$60Db{ zyVyFBUO^USW{9|g$A;|We4z00|5S_=YNu6ISNY8gf$rEp$ZG`YXjw#)D>|r`UH<1x z#t(tEXBL!u=K%?Uy=%)wL6fQi<3FI$oCBfLCv!avF8mr3H&*H-_mKDbw~e73Q^0U? ztihn#LV7p=QQq=xRwcb6AHE8FmH6iifGr%GfHK#1YoX$L!HLuAn%I~} z0cjP{)(33OZR$qSM7b8oBbyWP77)<(BI;~>2QZ*SWWsSG4>7sc`BO0&Xrs~b?kuirviQjxlr#zuHvh1xq4+ks*Y8zM)40i zzRTf6u}Rz z`PyXlL;+gbTu-~Rf~Rv-6c>jmSjjZ8X5b%kHlIwOyGwZBfh#6d_$0MeNcHmB3hfT+1&^9rrOmQO0OftLj=5zeYJ) zX|VVhrD+_;Ht!c#rBjWqI?CxLPo7MNOZ~BxgD{CbinmNHYPSD%XjM%qM(C8}FU5vj zyX=@JQnWosb_hb0(L!-@d3-?Kd}Rzqv)xz`|6yoUO#jC(#!LnE#qb&~!hN7( zPP0*UOhg(C!nTSies8Vro3@&t0*1nG-_*Yjy_avbtz*UW-2aa^1CVnhUWJjltY{q^8Egfhu}RAL(UZEc;#`0@++V0P>XuDk1ONz z26TGZ7^$#?==Suunjhxr6kA72my|iy*Ew#q%A7Lu>iOA@NRIo( zA?KeI<>(v&I^7)h4!y-`=617&$5c<3I=(Bo*%-8&4*QbcZfHj!>|i1vX&>}Q-pDMJ z3C%!%yN=%6t-57yAAkpY2v=Iu^U&espvwE+$*iU^L@m4YAg+*dNx)1p7I%Q6F--M* zMn!RpS9^xq)E0j|V1@0DocP~+1I0B7PLn!{3it68i3hP!oR!%HT@VV#!`=0 zH?xQ09L(gSO4+>X)$laRGse{1`t#D%SH6Aes^-5|-gPqzTEvzvsCNJ|ks~S^74!&y zFxyks9IAa?7GeWRHGg7oA-7ZBhZ525CHt*x<2=Sg&zZy6AvFHf-1_WhSa12?2yR(x zL&IZzNa^6+$rwcdE8D$wd~^VDg($W(L-}?5T85yYyohrlq<1f4?~5hRXunNj^c2xf zJ5z~z8yT$CPoArE-(rFR^T8Q}4pr(xu&$jTq>SUGZkBXI6 z-3Y9gzQfCQpsZTnR3F4H2_)t;^R9z9F0C!Jic^f`JG@d&;HRJ7w{1+qVPV&29PxfP zk&tb8x`W1q(rRoIZ43Em519e1ge>I7>j3@7(sTh~3ilw@B9!QZ-FH!~9|3{m_-KnJ zk+C|9D*XM})Tl%iYWkhf!eOu`d(`U@iLbXC2z+EM1<5P1iB2lg+NGF^2c1% zs&9Ll8)zd;k5|yBBEdXBt-D9c>gM1HSc+t!;(*48)A8LC0yTx;$`nW|nKDC+SGesu z3-yOio3_R5JsAril}QkPj40?kF#DrjIDwJ-3G^wZO5dO%#>Y9zj26&!BgMt*Ck1X> zmz+x_z~pnQ^>aAY z3e8~%vJ=0e>Nxu0Tc|K#D^j)KqVNTYYw(P}V;Q2b`_?z_d=P9O@_trNy`@mYay_k> z8eU#H$k%&W${G^Pmq_W)NDEMQflTg7D(64~iY{Vp93;N*l9Yf}&m#8qENfhjMv~w_-xW2O&u3sj|O#qWOh4OjCdt$17NfET`DK9!fiF!{o^6$I}E^s3)Rmn z`KfC}*~Z7080(e%`!>&>oGL8f3dwx-!WKl6)2XmoF{AI+RfU7Nd01|(%_E>J2(^|- zAFv!lzj?>N;ts~g_(uVh%~8p=W$0Ric$_sf8Z;W>j%1O|5p0&elD*)}ArSzjWbsW4 zEm`p`b$*rVb3g*(cJRbHaDo(|=mj}C(6%$Iybx7Dq2Fio%OBZ5Z+yz)H@;tU#dXAv z&YBMcil|6idr;|;t6KmGTPKaSBjCVWGBw;$gSgjsBdyfvWb3*ze}D7Ai9hEvMamrLA4GaBuPxihUD#|I(+_KBsZr+sFatX3^IfPX0og7%i+S&#kd>>C#t< zK5C&KZbFl%C@HbRDnxMCG6hO%jU=IXl}SpF6@+xQc#LjfW!*OJt;Y%d0Y=4tksX`!>S#838qJFHPiw<2gTtpQZV6#k=@+&Oq{88#7?@1N3AkQ zpD;^lp@=r}-%pz;gcAEYKE>T!gAEUu2x!dh&okkXlvwjv9j;-0w;p!F85BeM1*u@e<&*+3XbEQu%_ZPZy7_jLvHe z4V6gH!V)3t5ljc8E3#5P7v$*aObnV4SWfR*xxX|!cs62zi@ak8lxE;dKv9z#gJZDL zR5E~oz#Q_Isy`T041YTgCnWyNgqqX@dVnKcL0M2=w6+xtxeQOGcW9>8em=qa$b2K& zHJ&U}FvYw;54li$skS%2i!zn}kA+Ed6ueklnvhv9h9TljnM`7e3#*gqeB=U)2HQiX z43m2^dG1)_S$dQq42c(eb*U-?FuXB+vWVxDb;pPKu>(K}^m!<$6MCu7R<}y)2eo55 z3UTz?U60ebY=Gc_a0qtl71AD#zrw(DCNdh$DAo>Wg$C13t$vK@8cRCU<5nkvczw#F zK%LzPUCIe0H)w)C|AaNrS5_Zx*c?A zf?QOauZCugf5u=a15_CesQCG%oJk$L^NywPi=E~Q0ttj^Nwx#Rs-0YiML<|aDa|pY z$|eQrKyco(80cZJNYYu)3v8o;4TYZM(o@gmY;^)~v)qK|$k&x`p?Y^BlvnlWTS~uAqhc;`C*Zid; zPFbu;Ou#rRoXc6yT_z z{AVGVrj(jLKiPp)RH+C`gNi<42&6fP2Oe9TE1fgwD>673SpVqgGeVc&<#WjTtn^G3 z#m&PKve}b4xX1SY!)jx%QjBZOG}4H89udKxknzYUxh}3R4`t#&G*aHHlC8J z80K;4gR*mv zS*r))`q$DYfzrNF0(e@Ezr1>u2HeE)hc8&y90BQ+p7(#iin_EqAWUI?xOFDvW>p20(xyR zGDei&Yu9^r+-m(3u(Un5vjk2*Tw-GG5Mdbg02qIReA_U^@S$&}w>?7*+QiTX4p>5_ zJeXqJ`LlheFjG=7bt2`53;uMD^)&A`V!y5GPnfMe_O42#>0+G8^)DrlnXcuc9kKxD z-CDsDwKA#TiM1?`$DO0k`TNg&?Quc-dDR*N%Qi8>-9y?V@ihV73TEQD%o?2f zz(;NHwYsR))pC;m>ecj0lE;E2H*U#}5P$ZR)njYRWKh=eZS8Q#l|+Nbe_r(6F*1PS zui*Q}fypAjox_E!i#vp%3VWm5Oq>V|752ErAZV8jW(-Iu$3sHzciqY1q(8l3)`FOBdr8tte=drNyfFBW?zK(%MQ z<<{eN4&XtNSN(~I77VidO^?gFvbnvFCnA!Wm&g`lk&bsM1fM6&jY!FpPWkAHjHI?o zP&#Pfk($)zhJbnJ==C(i*{?hBpT@dou^(%27RjFAJ4MsKOs`gS2Qjb+dOx_lyNXw1?V$Hgso%FD5YLAc zaRMy4_8wVKXSR8UA%I;u3Q___eXzH4!a%uPlqv-ri(45aKFZlJ*s=$4lG#zZ3fMF! zM)D-_mG1obxmvB?cV0atr`RU*=+(8LDwyya7cFaKj=QY60ly|&R72@jGT|F|bgX|@ zatf=wc=bAMQ40*d-*qpb`gA;!17YbX#l#zjX&_tm-5C4{TMuTs0|@yG(? z`Uh?yzjR9AZfst7|MGuNAs6d}5g_)jz})XRO4lv}_P40YwA zw281+lAYm~DhciB;f*^65nDf~i0tPs$=OjxPq6s!ngx&%;^>4wF^0^>wGD)}d?Cu6 zKSXkIc$Ujkx*;D+zM90WFh$F4`@J*p~uJxf|G*<{()vZ7tfD)Jh^vpb@9aMkaMmY#- zWn*XQ`2GM#{)Qx6)0kC)fWno-z@ z<4l3Nr<7R~@WFLXG;0L}M-i#e0@5?vr#0!74^^^e_bDAm2v1(qb;aM6Vq)|LO}pw# zuvplZHtcOtjQ}tRPZVgbt)1OD9Bh}@54jLq*zxjm+XyC1j;$wDAkfL6)xCX`79qWXb!3OmY?mF25ALk;ZXcogra$I&VNdwVwhWgOYY z63eJ$DMe&)2zVjJ;`w}fCx|~zQP+ClazkKGw> z0te1@KpbC-suxwIR_}o#sJ?O#J_p3BpqX9HxumqyKPKy;CGxrA{?JTIwA*=(zo4UE z5>~PF4a$$t@JW)2J6b}}x_mvx7boC47@AUn##KX9iITWdQxj@jt3(tMi)~7?_&`dQ z>%QTF3hmpb!o9x#$tq$*PKRXh^!E>J_{hM@1u>n|Uq4-(Ds(WTiy%T@S-#Kq59&D} ztIvwjkkdX|W7T$juHK%Cy%eEkmR~(sCOpzTBhsRV!yt0&GpB#QY zOto<;5Fc^zPcGzr(lY8EJA_~Fn(lT%{k6Hs?YCGVM5qaTgV;%{90%p?{YT(XjN;S8 zSme_ij!4u$h31yowsav4(-%yLj}}+fjgL)*0V6M@QVkNkp3iw>#G1}caW$AVwxf=O z38__w*6H$kgj^QwaR5UZL9uXpZ~PV_jj6$U*NxKTZ3#j_|1%yU$_V1tiYd=%u`iES zMBNwe1jmGQsZ{Ol2(`Y+Mcgj&Th&MJpg}T0506(Ct)m(F>NrnI?W~!jc_-b(W`Hpg z4BPmu2VTiXcrsy^g^d*`Xm5t4p@LKeQ~mJ*P;X)V@fS;;-~n=jRdc=u^Go$hFeCP~ zhWZpNM*)vh#Y{C^S02T{MK?&sqD9qOWL2CPEEmmu~%5n0-dWyfXSx=S{&5FYqKY|2&;9yG&E>#~+646}C<=a+5ChZUgmjNW9 z1FAEmPx)J8tnGoA3&Kb|jncYM_v;Wi#dQ(rmP~rq9xw{q2@AWkVMTKqcxXkQt|$ct z2nN12LkOMhKLjxjJ{ng2JBs9c%r-dKl%0QtE?coHq>PF@7aUmZiH$NXd7P@}#ig_L zdbz+$pd^RLVXV6n*2vkbO!7LF0@yf{etroVyX{Whf_Axrbduva z`WPw_n8z7!Yr%g3tTERHmO8>Ix%ctGdusI^)_%1UI{Rv#c&PGPqT#>bCCr@V;LJsb zh6`8_eBZw<&t?rv$`(tz(GS0p5jS9wqt*d(w4R?h5v8;)*eVV-ui(*Lr(>yGB*net zfXN*Xy+DI#Ro~i`c;GHl>=T5`fl|5|OPmk6=BpfH!>8(CQYTYQ(s-n+k`>xmkAdQ` zvO6O@5c@&M_UAjt@eB9A?&o5D$y@h(21<>NG-JF2<)F^Aub=3v*AJP&xvw!f{h2oy zuSz>H=o&A{M8uLmO+P2M>(~*u`RyXh23<2^J^X|K!DjDzu{EjOdA=&lvzFRxU;FYxKZiSVh{dA6u0-pDE64Gwzj-1SegK0+(X~nV>PvCLwZ%_*7 z>dN7~ym#W#*F=*ZwdIQG=P+%YD|Sz_qvs}TLC5wr(l7i6AJ`H3FflM8FbM_)D-Ht! q8U+9Z6gdjLc)kXmwXR1ZQ^CcRMvR<6rvwP)m=)>Oo<1!C0t5iE&F>um literal 0 HcmV?d00001 diff --git a/vendor/github.com/godror/godror/contrib/free.db/keystore.jks b/vendor/github.com/godror/godror/contrib/free.db/keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..1923759914e9ef2ac4e5be310afded0e521bb038 GIT binary patch literal 3241 zcmdT_S5Om(7ELqKtDy->(M5V1RTLqB1}qo|MHC1Lp#=hg2!gcGL=Y(=J&N=uqDT=# z6{%7M1yKSDC{>CJN^x;#-V}7=ZQv4XIN!6U3<6V=EDYBAhC6*SRB8|>_IG-1UCIU*ElDoY?N-S(0291!`Fall>N_{qvtjW^!-cnm_vzN zvE68~Y|H*k`@yruxtH9+IDgD%+oxn`yT9~+Z+~O^T(>&-=;zbSQsrQ7%+M3qDJvotgyKG?LEH zHxeh`-OR|<633aXwz;8#@731ApT_e+3sSejAl%6TriZwb#k$Pxntpaaczd34siNMx z0=c8|Kp&Wh{XTXIO;X0i*BF}^JezFs*wiTh|Ns z8rZ2g+)gFFb)h%NONEM=#`9I4<~IDYRpohWIKFDXS`}=DMk`%Mu|TXJM{aWF57bZh zrX_VseTWvTZivH$3&~0LnTd)0j%y99?5)0VHbz7H^SF?k;{bDZn(T4nR(QdLZk{W$ ztNB&=QtgjW|CUb+5mL)pU3d*a_);wp(l`eznUAhq6Fj=0t(+YBle?P8xhrt!Y>QLR z$oEf%wjm+%SF&F*tIhQ7uqJ}hGtoAKj1i0CF5zsljtHKv{p7gAG~&?Jw1c#zp$53Ere_&Z*wg1wLaD*qZXKy?BMQ6+Hmk8cG8A5@hzcoEy z1C`_k`S&!MZK825Gfx8M?xf-2D*@LE?FHgQocP;kpXre5-e3H>EVR!tb*DOd?F@@p z8{k;~(g@15lkphXVZ8ZB+~?3v7Zmj$uu$;#`ZjVeIw55p`($i*)HX3NyWnU0vkC6p z+tJM2ASEnx?aI?8rqq6|_0S!ztJ&g&rnS=LO!}5M#*_`H_rEZ#t;?rniI^ZmI`rEw6+cY=*GcK zdPa)D@QunC*hFz;B?PY+0)1O5x4{t{o8earrR#~n#MIok3>B7tO9WifIC9W0hhUh} zGhuQ%qwJz+obHeE()Z*XFiO1*wqk>f+q4Sw%M<+?TfP|CVLui+e^=;S>1GEw*M2LN zrT&oDu#HrfJ}Z%D2i*UnFfHs=l+oqxLtofl_P&D}juhKjfXWNL%GKV`wV1BsUSssf z2Lp0*oMl?3ZWn+&^}b##D%)faD6g{R0M-?n?XX3GaIDoE@R?Vc!x{_Ge;&wv)~f1o zZ2$o51ZRK=a0Unq0s`Q?P)^0DGf^A7Kp^)%06eS;p#)ceg7FZru&h4am+DFNpwfM$ z4GF#kX)6NF$z=~YNnz4q+|~f#OQ0(mY)W2yQs% zFDFzOgg1vD66Hl`!?h7w2u(B^fx0Bhi$v@}&A%XA>p$tL!XQfoLIE!Ss}?LQjnXpK z(!wCo>c%KTw6Quy8>5ZDAdEDTnixX^4WvGt0hIkaM|+=YUnw<;f(^*&H}e#6F~E&}I<2-789ca#wZPd%u{o`3ygl}~{g_7U@gfmL{ZYxorYZs|Ftv_tRKWiH?(TMrYbj$xGpUW9 z&HHUcjBH#Yf?u5&Yze(;y?J%Y;xe9B{_wm!7FfuEW)>Z(~ zf$oHbpZd~@=ZoX z2byn~-K_h_(LoQlb6<4Og?_-KJ(IV_ofa~x)i9Vk`5xoh%8><+VIlhTL0}*N_;-f( zwrGzbAb@i$=^iMiM~Q9@%`uIntPmB6&m?cVXftlhZLmO#UL7 znz#~56Q2yJ9zRq4sD5WH(0e8$IT;gac=U*=3okZy)34w54#2pu?)}l8Es=99{i;(H z3FbpXz@#>WYd#}w9w*;hyv457Fx8q5D6hX1KhoaMM}xt{+)i9!xr3CkVrszVGfN#KBHHgdh8fr87L&{v-O!{quSYZ^mWW22;DgpKZYj zWK~M6J~bgOd!r4|HIi|-Bfb=+2xnumjqEuQQqi4yu?^p5xfPGs>yu^EX=B+_{sNp~ zy>b&68f+tUyInJlNI8F64xqI6SrW-PTLnC8ozrvMzO^N-Ye6w^2yBFTEk?m>}95yqtbLh3l@C)`sH62T@PRn|JO4vB zMI#=we2!Rsbw%+)b?&4#4fLtsD7W1(@@zEk_ zKuZ73Iz9HLevsCI3e$1s>|jy+s|~*GOoy%Qto+u{KquM4iP0KMs9K4gL-2%IQ1E7Y z9a9F$yJ^_b-ZiR{zqWP+9iw;ZvRUytd;esSr@KYapiryD`!Y3>5NO?)v+`){ZzZA_ d`{!o2b@a9XYAsw(k|<1BOGnD%i9X(0*dI#Neaip< literal 0 HcmV?d00001 diff --git a/vendor/github.com/godror/godror/contrib/free.db/ojdbc.properties b/vendor/github.com/godror/godror/contrib/free.db/ojdbc.properties new file mode 100644 index 00000000000..9fc350ca425 --- /dev/null +++ b/vendor/github.com/godror/godror/contrib/free.db/ojdbc.properties @@ -0,0 +1 @@ +oracle.net.wallet_location=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=${TNS_ADMIN}))) \ No newline at end of file diff --git a/vendor/github.com/godror/godror/contrib/free.db/sqlnet.ora b/vendor/github.com/godror/godror/contrib/free.db/sqlnet.ora new file mode 100644 index 00000000000..260f677fcde --- /dev/null +++ b/vendor/github.com/godror/godror/contrib/free.db/sqlnet.ora @@ -0,0 +1,2 @@ +WALLET_LOCATION = (SOURCE = (METHOD = file) (METHOD_DATA = (DIRECTORY="?/network/admin"))) +SSL_SERVER_DN_MATCH=yes \ No newline at end of file diff --git a/vendor/github.com/godror/godror/contrib/free.db/tnsnames.ora b/vendor/github.com/godror/godror/contrib/free.db/tnsnames.ora new file mode 100644 index 00000000000..1b10c58ee0a --- /dev/null +++ b/vendor/github.com/godror/godror/contrib/free.db/tnsnames.ora @@ -0,0 +1,6 @@ +free_high = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.eu-frankfurt-1.oraclecloud.com))(connect_data=(service_name=zo0svnycldsrgbw_db201911301540_high.adwc.oraclecloud.com))(security=(ssl_server_cert_dn="CN=adwc.eucom-central-1.oraclecloud.com,OU=Oracle BMCS FRANKFURT,O=Oracle Corporation,L=Redwood City,ST=California,C=US"))) + +free_low = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.eu-frankfurt-1.oraclecloud.com))(connect_data=(service_name=zo0svnycldsrgbw_db201911301540_low.adwc.oraclecloud.com))(security=(ssl_server_cert_dn="CN=adwc.eucom-central-1.oraclecloud.com,OU=Oracle BMCS FRANKFURT,O=Oracle Corporation,L=Redwood City,ST=California,C=US"))) + +free_medium = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.eu-frankfurt-1.oraclecloud.com))(connect_data=(service_name=zo0svnycldsrgbw_db201911301540_medium.adwc.oraclecloud.com))(security=(ssl_server_cert_dn="CN=adwc.eucom-central-1.oraclecloud.com,OU=Oracle BMCS FRANKFURT,O=Oracle Corporation,L=Redwood City,ST=California,C=US"))) + diff --git a/vendor/github.com/godror/godror/contrib/free.db/truststore.jks b/vendor/github.com/godror/godror/contrib/free.db/truststore.jks new file mode 100644 index 0000000000000000000000000000000000000000..55faa40478b570ffb11e9c5dd949d9acdcd45f16 GIT binary patch literal 3335 zcmdT`X;f3!8qFmk%ww1Y(J-h85^h2;3{D{+Gg6{}l>%uJ1k8X*Froq>TB;%lQUz3y zL1a?U0uOmsBVvuT0*^wlrXUbS0R^nYf{4%?P@f&vYTuu(_3m0(C*L{eyZgJ}-DlrD zH#Rp0gTa)bAADi7pt9D}Vt2+;=^P%K8$-dNxpZm*hYk&#J#-G5N`b)u=IIO05isR2 zj1%YrgCX)jA>u1g2tQB+R|1rjbb+^}&sg6j+&xT6=lFGelMQMi)ojze)26flKtmY@ zQm`7J8WO$@fkY{7BV!Fglp;_^X?j4wBn7Y!i;7(W8Y`wXP`Z3RAM?H@43*8qqQPZ~ zB{<6XLxvZF{W*n!4ra4?Xc7@zW~_yE1RX(VEDnUOPmQ&3ABSMT-zs4hxMC4!*#{i5 zHxY*>FSdld*b)d%2v~mnkbp7_E(CO7(7d{m5CCAkHDOr+&9_0rETNa67VAWKk8hTUfx<`S}mdA?F{iyt+@8soGCY;!!b9jaHT(TE|f=ha}xB`WP0S)ozw1;4&0aTT3zi??iY55dBQKX zMaoUr&-KnicqW+k5wN)@hTFDkxjk;)=n{dsIvJjRt=qHhPAgQGx?7pi~Ha3Uwp|)Q6gCjsk#rger)H z1|w za>cS0!UQxD7{DI}IfZokUyFWGDl;={$^CkL=eCde2OTnqe*nyCL%-h-SogAjCA){4 zdfbccjH&<3ZvbJz@RKp`T^Yzdeu1pkR%J^ca@n%%U>Pesuf%%glQ+dw8inxVCp)%-b5}Omx=1_RCY!>>j z^2u~Yv^_U=CyP#lln!eQ8Y=Fkg3=DA)A(#Q4NZ<=bLd?`o5PCz zt?(|0q%-J<194cqBM$dYB(W~=o0O4ZhTg-FSC=W zW-`TVw)&abEg!r%lqW5a?bTIFZMW(taSW#fvtmLXl@aJ=1+&xg_%=Jb_{{~)$=0FK zS>DyEmdT_eAi}Vx@bJiJZ`O2yoMjt-?YU>}l2koB89tGJAf=&3uQGdJ(Dcc+i{(Qd ztu%qhtJwo`O?rQ;2s1aEaQgP=H_SIYeYzmVzoYPiTx4<`xT=X4nh&aG$xSasdacVJ znz((ggKc&`^s=qVp$z@IEz5zDCE#nFnmAie&3OL0mVaZ=CLQ}EV+Bc%v;EC72^z_F zemZF77l$e2X0oNYWm!f4dt(pD z)T-MlNXm~bhhOE#a6=5DEA`rH;ww~xTC*GGQq#q?FIUCga^%g$;p(3+wN_+N9 z)SKC}Wi5jJbj$Mo2aO>}hpLFEcK>52_4^ z+?!+6Fjs+05`>NwSu`$1Ae*E+*E~pHS!GO${3htQ>w;XEer$ktF1iYi!d3i<^MThv z8c_>rMD9E1qv|#glI6bnN^wG5>-KE1@5fzM{>PjTxE71WDr^sQL5JEAiavz@g!%fb z11NJF)Z;v?INwzoS`}1sT!Ww0T2eNy-+pQbpoYE&RYu467cM)QG~Vc4sw(ZN-KXh-q^J0Pw)`98>FOKf zHurfc`}XE<|00GJZiVv`1>PL~l=&!L#Mc$g0>6Cmpu$5p3|E<8BIzu-;U!xYCqL~t z?V}o%-W^%*dPr1Ua&-8hm-4c9R-d}@w zm6)hnYHc#>XLsnPeUn5yCvRRJ_Wf1n*?qjHd8@1S8Xm`-V}z@4137nceoAo2^=a!M15Fxx+OGIfWU%9qPlN zSeQrSvKS7JgtepA{4x7W?eeiJJRoUprPJcRT+G4 ze_cc5DGF+;oP3rC=wG^f_)Z=^GDCgcoe{~&lgx*bKuuJcY(%1)-+s@Wmoj{*RA}}q D;Lhu) literal 0 HcmV?d00001 diff --git a/vendor/github.com/godror/godror/contrib/oracle-instant-client/Dockerfile b/vendor/github.com/godror/godror/contrib/oracle-instant-client/Dockerfile new file mode 100644 index 00000000000..45af9abff4b --- /dev/null +++ b/vendor/github.com/godror/godror/contrib/oracle-instant-client/Dockerfile @@ -0,0 +1,14 @@ +FROM debian:testing + +LABEL maintainer="t.gulacsi@unosoft.hu" + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && apt-get install -y libaio1 wget unzip + +RUN wget -O /tmp/instantclient-basic-linux-x64.zip https://download.oracle.com/otn_software/linux/instantclient/193000/instantclient-basic-linux.x64-19.3.0.0.0dbru.zip + +RUN mkdir -p /usr/lib/oracle && unzip /tmp/instantclient-basic-linux-x64.zip -d /usr/lib/oracle + +RUN ldconfig -v /usr/lib/oracle/instantclient_19_3 +RUN ldd /usr/lib/oracle/instantclient_19_3/libclntsh.so diff --git a/vendor/gopkg.in/goracle.v2/contrib/oracle-instant-client/README.md b/vendor/github.com/godror/godror/contrib/oracle-instant-client/README.md similarity index 100% rename from vendor/gopkg.in/goracle.v2/contrib/oracle-instant-client/README.md rename to vendor/github.com/godror/godror/contrib/oracle-instant-client/README.md diff --git a/vendor/gopkg.in/goracle.v2/contrib/oracle-xe-18c/Dockerfile b/vendor/github.com/godror/godror/contrib/oracle-xe-18c/Dockerfile similarity index 100% rename from vendor/gopkg.in/goracle.v2/contrib/oracle-xe-18c/Dockerfile rename to vendor/github.com/godror/godror/contrib/oracle-xe-18c/Dockerfile diff --git a/vendor/gopkg.in/goracle.v2/contrib/oracle-xe-18c/README.md b/vendor/github.com/godror/godror/contrib/oracle-xe-18c/README.md similarity index 100% rename from vendor/gopkg.in/goracle.v2/contrib/oracle-xe-18c/README.md rename to vendor/github.com/godror/godror/contrib/oracle-xe-18c/README.md diff --git a/vendor/gopkg.in/goracle.v2/data.go b/vendor/github.com/godror/godror/data.go similarity index 52% rename from vendor/gopkg.in/goracle.v2/data.go rename to vendor/github.com/godror/godror/data.go index 4feb4308970..1d78c8abbae 100644 --- a/vendor/gopkg.in/goracle.v2/data.go +++ b/vendor/github.com/godror/godror/data.go @@ -1,19 +1,9 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include @@ -21,10 +11,14 @@ package goracle */ import "C" import ( + "database/sql" "database/sql/driver" "fmt" + "reflect" "time" "unsafe" + + errors "golang.org/x/xerrors" ) // Data holds the data to/from Oracle. @@ -34,11 +28,35 @@ type Data struct { NativeTypeNum C.dpiNativeTypeNum } +var ErrNotSupported = errors.New("not supported") + +// NewData creates a new Data structure for the given type, populated with the given type. +func NewData(v interface{}) (*Data, error) { + if v == nil { + return nil, errors.Errorf("%s: %w", "nil type", ErrNotSupported) + } + data := Data{dpiData: &C.dpiData{isNull: 1}} + return &data, data.Set(v) +} + // IsNull returns whether the data is null. func (d *Data) IsNull() bool { + // Use of C.dpiData_getIsNull(d.dpiData) would be safer, + // but ODPI-C 3.1.4 just returns dpiData->isNull, so do the same + // without calling CGO. return d == nil || d.dpiData == nil || d.dpiData.isNull == 1 } +// SetNull sets the value of the data to be the null value. +func (d *Data) SetNull() { + if !d.IsNull() { + // Maybe C.dpiData_setNull(d.dpiData) would be safer, but as we don't use C.dpiData_getIsNull, + // and those functions (at least in ODPI-C 3.1.4) just operate on data->isNull directly, + // don't use CGO if possible. + d.dpiData.isNull = 1 + } +} + // GetBool returns the bool data. func (d *Data) GetBool() bool { return !d.IsNull() && C.dpiData_getBool(d.dpiData) == 1 @@ -59,6 +77,9 @@ func (d *Data) GetBytes() []byte { return nil } b := C.dpiData_getBytes(d.dpiData) + if b.ptr == nil || b.length == 0 { + return nil + } return ((*[32767]byte)(unsafe.Pointer(b.ptr)))[:b.length:b.length] } @@ -155,7 +176,14 @@ func (d *Data) GetLob() *Lob { return &Lob{Reader: &dpiLobReader{dpiLob: C.dpiData_getLOB(d.dpiData)}} } +// SetLob sets Lob to the data. +func (d *Data) SetLob(lob *DirectLob) { + C.dpiData_setLOB(d.dpiData, lob.dpiLob) +} + // GetObject gets Object from data. +// +// As with all Objects, you MUST call Close on it when not needed anymore! func (d *Data) GetObject() *Object { if d == nil || d.dpiData == nil { panic("null") @@ -168,6 +196,9 @@ func (d *Data) GetObject() *Object { if o == nil { return nil } + if C.dpiObject_addRef(o) == C.DPI_FAILURE { + panic(d.ObjectType.getError()) + } obj := &Object{dpiObject: o, ObjectType: d.ObjectType} obj.init() return obj @@ -265,11 +296,168 @@ func (d *Data) Get() interface{} { } } +// Set the data. +func (d *Data) Set(v interface{}) error { + if v == nil { + return errors.Errorf("%s: %w", "nil type", ErrNotSupported) + } + if d.dpiData == nil { + d.dpiData = &C.dpiData{isNull: 1} + } + switch x := v.(type) { + case int32: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_INT64 + d.SetInt64(int64(x)) + case int64: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_INT64 + d.SetInt64(x) + case uint64: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_UINT64 + d.SetUint64(x) + case float32: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_FLOAT + d.SetFloat32(x) + case float64: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_DOUBLE + d.SetFloat64(x) + case string: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_BYTES + d.SetBytes([]byte(x)) + case []byte: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_BYTES + d.SetBytes(x) + case time.Time: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_TIMESTAMP + d.SetTime(x) + case time.Duration: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_INTERVAL_DS + d.SetIntervalDS(x) + case IntervalYM: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_INTERVAL_YM + d.SetIntervalYM(x) + case *DirectLob: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_LOB + d.SetLob(x) + case *Object: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_OBJECT + d.ObjectType = x.ObjectType + d.SetObject(x) + //case *stmt: + //d.NativeTypeNum = C.DPI_NATIVE_TYPE_STMT + //d.SetStmt(x) + case bool: + d.NativeTypeNum = C.DPI_NATIVE_TYPE_BOOLEAN + d.SetBool(x) + //case rowid: + //d.NativeTypeNum = C.DPI_NATIVE_TYPE_ROWID + //d.SetRowid(x) + default: + return errors.Errorf("%T: %w", ErrNotSupported, v) + } + return nil +} + // IsObject returns whether the data contains an Object or not. func (d *Data) IsObject() bool { return d.NativeTypeNum == C.DPI_NATIVE_TYPE_OBJECT } +// NewData returns Data for input parameters on Object/ObjectCollection. +func (c *conn) NewData(baseType interface{}, sliceLen, bufSize int) ([]*Data, error) { + if c == nil || c.dpiConn == nil { + return nil, errors.New("connection is nil") + } + + vi, err := newVarInfo(baseType, sliceLen, bufSize) + if err != nil { + return nil, err + } + + _, dpiData, err := c.newVar(vi) + if err != nil { + return nil, err + } + + data := make([]*Data, sliceLen) + for i := 0; i < sliceLen; i++ { + data[i] = &Data{dpiData: &dpiData[i], NativeTypeNum: vi.NatTyp} + } + + return data, nil +} + +func newVarInfo(baseType interface{}, sliceLen, bufSize int) (varInfo, error) { + var vi varInfo + + switch v := baseType.(type) { + case Lob, []Lob: + vi.NatTyp = C.DPI_NATIVE_TYPE_LOB + var isClob bool + switch v := v.(type) { + case Lob: + isClob = v.IsClob + case []Lob: + isClob = len(v) > 0 && v[0].IsClob + } + if isClob { + vi.Typ = C.DPI_ORACLE_TYPE_CLOB + } else { + vi.Typ = C.DPI_ORACLE_TYPE_BLOB + } + case Number, []Number: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NUMBER, C.DPI_NATIVE_TYPE_BYTES + case int, []int, int64, []int64, sql.NullInt64, []sql.NullInt64: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NUMBER, C.DPI_NATIVE_TYPE_INT64 + case int32, []int32: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NATIVE_INT, C.DPI_NATIVE_TYPE_INT64 + case uint, []uint, uint64, []uint64: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NUMBER, C.DPI_NATIVE_TYPE_UINT64 + case uint32, []uint32: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NATIVE_UINT, C.DPI_NATIVE_TYPE_UINT64 + case float32, []float32: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NATIVE_FLOAT, C.DPI_NATIVE_TYPE_FLOAT + case float64, []float64, sql.NullFloat64, []sql.NullFloat64: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_NATIVE_DOUBLE, C.DPI_NATIVE_TYPE_DOUBLE + case bool, []bool: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_BOOLEAN, C.DPI_NATIVE_TYPE_BOOLEAN + case []byte, [][]byte: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_RAW, C.DPI_NATIVE_TYPE_BYTES + switch v := v.(type) { + case []byte: + bufSize = len(v) + case [][]byte: + for _, b := range v { + if n := len(b); n > bufSize { + bufSize = n + } + } + } + case string, []string, nil: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_VARCHAR, C.DPI_NATIVE_TYPE_BYTES + bufSize = 32767 + case time.Time, []time.Time: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_DATE, C.DPI_NATIVE_TYPE_TIMESTAMP + case userType, []userType: + vi.Typ, vi.NatTyp = C.DPI_ORACLE_TYPE_OBJECT, C.DPI_NATIVE_TYPE_OBJECT + switch v := v.(type) { + case userType: + vi.ObjectType = v.ObjectRef().ObjectType.dpiObjectType + case []userType: + if len(v) > 0 { + vi.ObjectType = v[0].ObjectRef().ObjectType.dpiObjectType + } + } + default: + return vi, errors.Errorf("unknown type %T", v) + } + + vi.IsPLSArray = reflect.TypeOf(baseType).Kind() == reflect.Slice + vi.SliceLen = sliceLen + vi.BufSize = bufSize + + return vi, nil +} + func (d *Data) reset() { d.NativeTypeNum = 0 d.ObjectType = ObjectType{} @@ -278,4 +466,5 @@ func (d *Data) reset() { } else { d.SetBytes(nil) } + d.dpiData.isNull = 1 } diff --git a/vendor/gopkg.in/goracle.v2/drv.go b/vendor/github.com/godror/godror/drv.go similarity index 67% rename from vendor/gopkg.in/goracle.v2/drv.go rename to vendor/github.com/godror/godror/drv.go index 89cee453dff..8ad65fd4c58 100644 --- a/vendor/gopkg.in/goracle.v2/drv.go +++ b/vendor/github.com/godror/godror/drv.go @@ -1,21 +1,11 @@ // Copyright 2019 Tamás Gulácsi // // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -// Package goracle is a database/sql/driver for Oracle DB. +// Package godror is a database/sql/driver for Oracle DB. // -// The connection string for the sql.Open("goracle", connString) call can be +// The connection string for the sql.Open("godror", connString) call can be // the simple // login/password@sid [AS SYSDBA|AS SYSOPER] // @@ -31,7 +21,12 @@ // standaloneConnection=0& \ // enableEvents=0& \ // heterogeneousPool=0& \ -// prelim=0 +// prelim=0& \ +// poolWaitTimeout=5m& \ +// poolSessionMaxLifetime=1h& \ +// poolSessionTimeout=30s& \ +// timezone=Local& \ +// newPassword= // // These are the defaults. Many advocate that a static session pool (min=max, incr=0) // is better, with 1-10 sessions per CPU thread. @@ -41,7 +36,9 @@ // If you specify connectionClass, that'll reuse the same session pool // without the connectionClass, but will specify it on each session acquire. // Thus you can cluster the session pool with classes, or use POOLED for DRCP. -package goracle +// +// For what can be used as "sid", see https://docs.oracle.com/en/database/oracle/oracle-database/19/netag/configuring-naming-methods.html#GUID-E5358DEA-D619-4B7B-A799-3D2F802500F1 +package godror /* #cgo CFLAGS: -I./odpi/include -I./odpi/src -I./odpi/embed @@ -68,7 +65,7 @@ import ( "time" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) const ( @@ -84,9 +81,13 @@ const ( DpiMajorVersion = C.DPI_MAJOR_VERSION // DpiMinorVersion is the wanted minor version of the underlying ODPI-C library. DpiMinorVersion = C.DPI_MINOR_VERSION + // DpiPatchLevel is the patch level version of the underlying ODPI-C library + DpiPatchLevel = C.DPI_PATCH_LEVEL + // DpiVersionNumber is the underlying ODPI-C version as one number (Major * 10000 + Minor * 100 + Patch) + DpiVersionNumber = C.DPI_VERSION_NUMBER // DriverName is set on the connection to be seen in the DB - DriverName = "gopkg.in/goracle.v2 : " + Version + DriverName = "github.com/godror/godror : " + Version // DefaultPoolMinSessions specifies the default value for minSessions for pool creation. DefaultPoolMinSessions = 1 @@ -95,10 +96,16 @@ const ( // DefaultPoolIncrement specifies the default value for increment for pool creation. DefaultPoolIncrement = 1 // DefaultConnectionClass is the default connectionClass - DefaultConnectionClass = "GORACLE" + DefaultConnectionClass = "GODROR" // NoConnectionPoolingConnectionClass is a special connection class name to indicate no connection pooling. // It is the same as setting standaloneConnection=1 NoConnectionPoolingConnectionClass = "NO-CONNECTION-POOLING" + // DefaultSessionTimeout is the seconds before idle pool sessions get evicted + DefaultSessionTimeout = 5 * time.Minute + // DefaultWaitTimeout is the milliseconds to wait for a session to become available + DefaultWaitTimeout = 30 * time.Second + // DefaultMaxLifeTime is the maximum time in seconds till a pooled session may exist + DefaultMaxLifeTime = 1 * time.Hour ) // Number as string @@ -307,7 +314,7 @@ var defaultDrv *drv func init() { defaultDrv = newDrv() - sql.Register("goracle", defaultDrv) + sql.Register("godror", defaultDrv) } func newDrv() *drv { @@ -347,7 +354,7 @@ func (d *drv) init() error { var v C.dpiVersionInfo if C.dpiContext_getClientVersion(d.dpiContext, &v) == C.DPI_FAILURE { - return errors.Wrap(d.getError(), "getClientVersion") + return errors.Errorf("%s: %w", "getClientVersion", d.getError()) } d.clientVersion.set(&v) return nil @@ -362,7 +369,7 @@ func (d *drv) Open(connString string) (driver.Conn, error) { } conn, err := d.openConn(P) - return conn, maybeBadConn(err) + return conn, maybeBadConn(err, conn) } func (d *drv) ClientVersion() (VersionInfo, error) { @@ -374,7 +381,7 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { return nil, err } - c := conn{drv: d, connParams: P} + c := conn{drv: d, connParams: P, timeZone: time.Local} connString := P.String() defer func() { @@ -400,15 +407,16 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { authMode |= elt.Mode } } - if P.IsPrelim { - // The shared memory may not exist when Oracle is shut down. + P.StandaloneConnection = P.StandaloneConnection || P.ConnClass == NoConnectionPoolingConnectionClass + if P.IsPrelim || P.StandaloneConnection { + // Prelim: the shared memory may not exist when Oracle is shut down. P.ConnClass = "" } extAuth := C.int(b2i(P.Username == "" && P.Password == "")) var connCreateParams C.dpiConnCreateParams if C.dpiContext_initConnCreateParams(d.dpiContext, &connCreateParams) == C.DPI_FAILURE { - return nil, errors.Wrap(d.getError(), "initConnCreateParams") + return nil, errors.Errorf("initConnCreateParams: %w", d.getError()) } connCreateParams.authMode = authMode connCreateParams.externalAuth = extAuth @@ -424,21 +432,25 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { d.mu.Unlock() if dp != nil { //Proxy authenticated connections to database will be provided by methods with context + c.mu.Lock() c.Client, c.Server = d.clientVersion, dp.serverVersion c.timeZone, c.tzOffSecs = dp.timeZone, dp.tzOffSecs + c.mu.Unlock() if err := c.acquireConn("", ""); err != nil { return nil, err } err := c.init() if err == nil { + c.mu.Lock() dp.serverVersion = c.Server dp.timeZone, dp.tzOffSecs = c.timeZone, c.tzOffSecs + c.mu.Unlock() } return &c, err } } - var cUserName, cPassword *C.char + var cUserName, cPassword, cNewPassword *C.char if !(P.Username == "" && P.Password == "") { cUserName, cPassword = C.CString(P.Username), C.CString(P.Password) } @@ -453,6 +465,9 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { C.free(unsafe.Pointer(cUserName)) C.free(unsafe.Pointer(cPassword)) } + if cNewPassword != nil { + C.free(unsafe.Pointer(cNewPassword)) + } if cSid != nil { C.free(unsafe.Pointer(cSid)) } @@ -462,7 +477,7 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { }() var commonCreateParams C.dpiCommonCreateParams if C.dpiContext_initCommonCreateParams(d.dpiContext, &commonCreateParams) == C.DPI_FAILURE { - return nil, errors.Wrap(d.getError(), "initCommonCreateParams") + return nil, errors.Errorf("initCommonCreateParams: %w", d.getError()) } commonCreateParams.createMode = C.DPI_MODE_CREATE_DEFAULT | C.DPI_MODE_CREATE_THREADED if P.EnableEvents { @@ -474,6 +489,11 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { commonCreateParams.driverNameLength = C.uint32_t(len(DriverName)) if P.IsSysDBA || P.IsSysOper || P.IsSysASM || P.IsPrelim || P.StandaloneConnection { + if P.NewPassword != "" { + cNewPassword = C.CString(P.NewPassword) + connCreateParams.newPassword = cNewPassword + connCreateParams.newPasswordLength = C.uint32_t(len(P.NewPassword)) + } dc := C.malloc(C.sizeof_void) if Log != nil { Log("C", "dpiConn_create", "params", P.String(), "common", commonCreateParams, "conn", connCreateParams) @@ -488,7 +508,7 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { (**C.dpiConn)(unsafe.Pointer(&dc)), ) == C.DPI_FAILURE { C.free(unsafe.Pointer(dc)) - return nil, errors.Wrapf(d.getError(), "username=%q sid=%q params=%+v", P.Username, P.SID, connCreateParams) + return nil, errors.Errorf("username=%q sid=%q params=%+v: %w", P.Username, P.SID, connCreateParams, d.getError()) } c.dpiConn = (*C.dpiConn)(dc) c.currentUser = P.Username @@ -498,25 +518,42 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { } var poolCreateParams C.dpiPoolCreateParams if C.dpiContext_initPoolCreateParams(d.dpiContext, &poolCreateParams) == C.DPI_FAILURE { - return nil, errors.Wrap(d.getError(), "initPoolCreateParams") + return nil, errors.Errorf("initPoolCreateParams: %w", d.getError()) + } + poolCreateParams.minSessions = DefaultPoolMinSessions + if P.MinSessions >= 0 { + poolCreateParams.minSessions = C.uint32_t(P.MinSessions) + } + poolCreateParams.maxSessions = DefaultPoolMaxSessions + if P.MaxSessions > 0 { + poolCreateParams.maxSessions = C.uint32_t(P.MaxSessions) + } + poolCreateParams.sessionIncrement = DefaultPoolIncrement + if P.PoolIncrement > 0 { + poolCreateParams.sessionIncrement = C.uint32_t(P.PoolIncrement) } - poolCreateParams.minSessions = C.uint32_t(P.MinSessions) - poolCreateParams.maxSessions = C.uint32_t(P.MaxSessions) - poolCreateParams.sessionIncrement = C.uint32_t(P.PoolIncrement) if extAuth == 1 || P.HeterogeneousPool { poolCreateParams.homogeneous = 0 } poolCreateParams.externalAuth = extAuth poolCreateParams.getMode = C.DPI_MODE_POOL_GET_TIMEDWAIT - poolCreateParams.timeout = 300 // seconds before idle pool sessions got evicted - poolCreateParams.waitTimeout = 3 * 1000 // milliseconds to wait for a session become available - poolCreateParams.maxLifetimeSession = 3600 // maximum time in seconds till a pooled session may exist + poolCreateParams.timeout = C.uint32_t(DefaultSessionTimeout / time.Second) + if P.SessionTimeout > time.Second { + poolCreateParams.timeout = C.uint32_t(P.SessionTimeout / time.Second) // seconds before idle pool sessions get evicted + } + poolCreateParams.waitTimeout = C.uint32_t(DefaultWaitTimeout / time.Millisecond) + if P.WaitTimeout > time.Millisecond { + poolCreateParams.waitTimeout = C.uint32_t(P.WaitTimeout / time.Millisecond) // milliseconds to wait for a session to become available + } + poolCreateParams.maxLifetimeSession = C.uint32_t(DefaultMaxLifeTime / time.Second) + if P.MaxLifeTime > 0 { + poolCreateParams.maxLifetimeSession = C.uint32_t(P.MaxLifeTime / time.Second) // maximum time in seconds till a pooled session may exist + } var dp *C.dpiPool if Log != nil { - Log("C", "dpiPool_create", "username", P.Username, "sid", P.SID, "common", commonCreateParams, "pool", poolCreateParams) + Log("C", "dpiPool_create", "username", P.Username, "conn", connString, "sid", P.SID, "common", commonCreateParams, "pool", fmt.Sprintf("%#v", poolCreateParams)) } - //fmt.Println("POOL create", connString) if C.dpiPool_create( d.dpiContext, cUserName, C.uint32_t(len(P.Username)), @@ -526,7 +563,7 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { &poolCreateParams, (**C.dpiPool)(unsafe.Pointer(&dp)), ) == C.DPI_FAILURE { - return nil, errors.Wrapf(d.getError(), "params=%s extAuth=%v", P.String(), extAuth) + return nil, errors.Errorf("params=%s extAuth=%v: %w", P.String(), extAuth, d.getError()) } C.dpiPool_setStmtCacheSize(dp, 40) d.mu.Lock() @@ -539,7 +576,7 @@ func (d *drv) openConn(P ConnectionParams) (*conn, error) { func (c *conn) acquireConn(user, pass string) error { var connCreateParams C.dpiConnCreateParams if C.dpiContext_initConnCreateParams(c.dpiContext, &connCreateParams) == C.DPI_FAILURE { - return errors.Wrap(c.getError(), "initConnCreateParams") + return errors.Errorf("initConnCreateParams: %w", "", c.getError()) } dc := C.malloc(C.sizeof_void) @@ -572,18 +609,22 @@ func (c *conn) acquireConn(user, pass string) error { (**C.dpiConn)(unsafe.Pointer(&dc)), ) == C.DPI_FAILURE { C.free(unsafe.Pointer(dc)) - return errors.Wrapf(c.getError(), "acquirePoolConnection") + return errors.Errorf("acquirePoolConnection: %w", c.getError()) } + c.mu.Lock() c.dpiConn = (*C.dpiConn)(dc) c.currentUser = user c.newSession = connCreateParams.outNewSession == 1 c.Client, c.Server = c.drv.clientVersion, pool.serverVersion c.timeZone, c.tzOffSecs = pool.timeZone, pool.tzOffSecs + c.mu.Unlock() err := c.init() if err == nil { + c.mu.Lock() pool.serverVersion = c.Server pool.timeZone, pool.tzOffSecs = c.timeZone, c.tzOffSecs + c.mu.Unlock() } return err @@ -593,12 +634,16 @@ func (c *conn) acquireConn(user, pass string) error { // You can use ConnectionParams{...}.StringWithPassword() // as a connection string in sql.Open. type ConnectionParams struct { - Username, Password, SID, ConnClass string - MinSessions, MaxSessions, PoolIncrement int - IsSysDBA, IsSysOper, IsSysASM, IsPrelim bool - HeterogeneousPool bool - StandaloneConnection bool - EnableEvents bool + Username, Password, SID, ConnClass string + // NewPassword is used iff StandaloneConnection is true! + NewPassword string + MinSessions, MaxSessions, PoolIncrement int + WaitTimeout, MaxLifeTime, SessionTimeout time.Duration + IsSysDBA, IsSysOper, IsSysASM, IsPrelim bool + HeterogeneousPool bool + StandaloneConnection bool + EnableEvents bool + Timezone *time.Location } // String returns the string representation of ConnectionParams. @@ -624,47 +669,74 @@ func (P ConnectionParams) string(class, withPassword bool) string { if i := strings.IndexByte(host, '/'); i >= 0 { host, path = host[:i], host[i:] } - cc := "" - if class { - cc = fmt.Sprintf("connectionClass=%s&", url.QueryEscape(P.ConnClass)) + q := make(url.Values, 32) + s := P.ConnClass + if !class { + s = "" } - // params should be sorted lexicographically + q.Add("connectionClass", s) + password := P.Password - if !withPassword { + if withPassword { + q.Add("newPassword", P.NewPassword) + } else { hsh := fnv.New64() io.WriteString(hsh, P.Password) password = "SECRET-" + base64.URLEncoding.EncodeToString(hsh.Sum(nil)) + if P.NewPassword != "" { + hsh.Reset() + io.WriteString(hsh, P.NewPassword) + q.Add("newPassword", "SECRET-"+base64.URLEncoding.EncodeToString(hsh.Sum(nil))) + } + } + s = "" + if P.Timezone != nil { + s = P.Timezone.String() } + q.Add("timezone", s) + B := func(b bool) string { + if b { + return "1" + } + return "0" + } + q.Add("poolMinSessions", strconv.Itoa(P.MinSessions)) + q.Add("poolMaxSessions", strconv.Itoa(P.MaxSessions)) + q.Add("poolIncrement", strconv.Itoa(P.PoolIncrement)) + q.Add("sysdba", B(P.IsSysDBA)) + q.Add("sysoper", B(P.IsSysOper)) + q.Add("sysasm", B(P.IsSysASM)) + q.Add("standaloneConnection", B(P.StandaloneConnection)) + q.Add("enableEvents", B(P.EnableEvents)) + q.Add("heterogeneousPool", B(P.HeterogeneousPool)) + q.Add("prelim", B(P.IsPrelim)) + q.Add("poolWaitTimeout", P.WaitTimeout.String()) + q.Add("poolSessionMaxLifetime", P.MaxLifeTime.String()) + q.Add("poolSessionTimeout", P.SessionTimeout.String()) return (&url.URL{ - Scheme: "oracle", - User: url.UserPassword(P.Username, password), - Host: host, - Path: path, - RawQuery: cc + - fmt.Sprintf("poolIncrement=%d&poolMaxSessions=%d&poolMinSessions=%d&"+ - "sysdba=%d&sysoper=%d&sysasm=%d&"+ - "standaloneConnection=%d&enableEvents=%d&"+ - "heterogeneousPool=%d&prelim=%d", - P.PoolIncrement, P.MaxSessions, P.MinSessions, - b2i(P.IsSysDBA), b2i(P.IsSysOper), b2i(P.IsSysASM), - b2i(P.StandaloneConnection), b2i(P.EnableEvents), - b2i(P.HeterogeneousPool), b2i(P.IsPrelim), - ), + Scheme: "oracle", + User: url.UserPassword(P.Username, password), + Host: host, + Path: path, + RawQuery: q.Encode(), }).String() } // ParseConnString parses the given connection string into a struct. func ParseConnString(connString string) (ConnectionParams, error) { P := ConnectionParams{ - MinSessions: DefaultPoolMinSessions, - MaxSessions: DefaultPoolMaxSessions, - PoolIncrement: DefaultPoolIncrement, - ConnClass: DefaultConnectionClass, + MinSessions: DefaultPoolMinSessions, + MaxSessions: DefaultPoolMaxSessions, + PoolIncrement: DefaultPoolIncrement, + ConnClass: DefaultConnectionClass, + MaxLifeTime: DefaultMaxLifeTime, + WaitTimeout: DefaultWaitTimeout, + SessionTimeout: DefaultSessionTimeout, } if !strings.HasPrefix(connString, "oracle://") { i := strings.IndexByte(connString, '/') if i < 0 { - return P, errors.Errorf("no '/' in connection string") + return P, errors.New("no '/' in connection string") } P.Username, connString = connString[:i], connString[i+1:] @@ -692,13 +764,18 @@ func ParseConnString(connString string) (ConnectionParams, error) { } u, err := url.Parse(connString) if err != nil { - return P, errors.Wrap(err, connString) + return P, errors.Errorf("%s: %w", connString, err) } if usr := u.User; usr != nil { P.Username = usr.Username() P.Password, _ = usr.Password() } P.SID = u.Hostname() + // IPv6 literal address brackets are removed by u.Hostname, + // so we have to put them back + if strings.HasPrefix(u.Host, "[") && !strings.Contains(P.SID[1:], "]") { + P.SID = "[" + P.SID + "]" + } if u.Port() != "" { P.SID += ":" + u.Port() } @@ -724,10 +801,27 @@ func ParseConnString(connString string) (ConnectionParams, error) { } { *task.Dest = q.Get(task.Key) == "1" } + if tz := q.Get("timezone"); tz != "" { + if tz == "local" { + P.Timezone = time.Local + } else if strings.Contains(tz, "/") { + if P.Timezone, err = time.LoadLocation(tz); err != nil { + return P, errors.Errorf("%s: %w", tz, err) + } + } else if off, err := parseTZ(tz); err == nil { + P.Timezone = time.FixedZone(tz, off) + } else { + return P, errors.Errorf("%s: %w", tz, err) + } + } + P.StandaloneConnection = P.StandaloneConnection || P.ConnClass == NoConnectionPoolingConnectionClass if P.IsPrelim { P.ConnClass = "" } + if P.StandaloneConnection { + P.NewPassword = q.Get("newPassword") + } for _, task := range []struct { Dest *int @@ -744,7 +838,36 @@ func ParseConnString(connString string) (ConnectionParams, error) { var err error *task.Dest, err = strconv.Atoi(s) if err != nil { - return P, errors.Wrap(err, task.Key+"="+s) + return P, errors.Errorf("%s: %w", task.Key+"="+s, err) + } + } + for _, task := range []struct { + Dest *time.Duration + Key string + }{ + {&P.SessionTimeout, "poolSessionTimeout"}, + {&P.WaitTimeout, "poolWaitTimeout"}, + {&P.MaxLifeTime, "poolSessionMaxLifetime"}, + } { + s := q.Get(task.Key) + if s == "" { + continue + } + var err error + *task.Dest, err = time.ParseDuration(s) + if err != nil { + if !strings.Contains(err.Error(), "time: missing unit in duration") { + return P, errors.Errorf("%s: %w", task.Key+"="+s, err) + } + i, err := strconv.Atoi(s) + if err != nil { + return P, errors.Errorf("%s: %w", task.Key+"="+s, err) + } + base := time.Second + if task.Key == "poolWaitTimeout" { + base = time.Millisecond + } + *task.Dest = time.Duration(i) * base } } if P.MinSessions > P.MaxSessions { @@ -755,7 +878,6 @@ func ParseConnString(connString string) (ConnectionParams, error) { } else if P.PoolIncrement < 1 { P.PoolIncrement = 1 } - return P, nil } @@ -765,6 +887,13 @@ type OraErr struct { code int } +// AsOraErr returns the underlying *OraErr and whether it succeeded. +func AsOraErr(err error) (*OraErr, bool) { + var oerr *OraErr + ok := errors.As(err, &oerr) + return oerr, ok +} + var _ = error((*OraErr)(nil)) // Code returns the OraErr's error code. @@ -867,7 +996,7 @@ func timeZoneFor(hourOffset, minuteOffset C.int8_t) *time.Location { type ctxKey string -const logCtxKey = ctxKey("goracle.Log") +const logCtxKey = ctxKey("godror.Log") type logFunc func(...interface{}) error @@ -883,30 +1012,83 @@ func ContextWithLog(ctx context.Context, logF func(...interface{}) error) contex return context.WithValue(ctx, logCtxKey, logF) } -func parseTZ(s string) (int, error) { - s = strings.TrimSpace(s) - if s == "" { - return 0, io.EOF +var _ = driver.Connector((*connector)(nil)) + +type connector struct { + ConnectionParams + *drv + onInit func(driver.Conn) error +} + +// OpenConnector must parse the name in the same format that Driver.Open +// parses the name parameter. +func (d *drv) OpenConnector(name string) (driver.Connector, error) { + P, err := ParseConnString(name) + if err != nil { + return nil, err } - if s == "Z" || s == "UTC" { - return 0, nil + + return connector{ConnectionParams: P, drv: d}, nil +} + +// Connect returns a connection to the database. +// Connect may return a cached connection (one previously +// closed), but doing so is unnecessary; the sql package +// maintains a pool of idle connections for efficient re-use. +// +// The provided context.Context is for dialing purposes only +// (see net.DialContext) and should not be stored or used for +// other purposes. +// +// The returned connection is only used by one goroutine at a +// time. +func (c connector) Connect(context.Context) (driver.Conn, error) { + conn, err := c.drv.openConn(c.ConnectionParams) + if err != nil || c.onInit == nil || !conn.newSession { + return conn, err + } + if err = c.onInit(conn); err != nil { + conn.close(true) + return nil, err } - var tz int - if i := strings.IndexByte(s, ':'); i >= 0 { - if i64, err := strconv.ParseInt(s[i+1:], 10, 6); err != nil { - return tz, errors.Wrap(err, s) - } else { - tz = int(i64) - } - s = s[:i] + return conn, nil +} + +// Driver returns the underlying Driver of the Connector, +// mainly to maintain compatibility with the Driver method +// on sql.DB. +func (c connector) Driver() driver.Driver { return c.drv } + +// NewConnector returns a driver.Connector to be used with sql.OpenDB, +// which calls the given onInit if the connection is new. +// +// For an example, see NewSessionIniter. +func NewConnector(name string, onInit func(driver.Conn) error) (driver.Connector, error) { + cxr, err := defaultDrv.OpenConnector(name) + if err != nil { + return nil, err } - if i64, err := strconv.ParseInt(s, 10, 5); err != nil { - return tz, errors.Wrap(err, s) - } else { - if i64 < 0 { - tz = -tz + cx := cxr.(connector) + cx.onInit = onInit + return cx, err +} + +// NewSessionIniter returns a function suitable for use in NewConnector as onInit, +// which calls "ALTER SESSION SET =''" for each element of the given map. +func NewSessionIniter(m map[string]string) func(driver.Conn) error { + return func(cx driver.Conn) error { + for k, v := range m { + qry := fmt.Sprintf("ALTER SESSION SET %s = q'(%s)'", k, strings.Replace(v, "'", "''", -1)) + st, err := cx.Prepare(qry) + if err != nil { + return errors.Errorf("%s: %w", qry, err) + } + _, err = st.Exec(nil) //lint:ignore SA1019 it's hard to use ExecContext here + st.Close() + if err != nil { + return err + } } - tz += int(i64 * 3600) + return nil } - return tz, nil } diff --git a/vendor/github.com/godror/godror/drv_posix.go b/vendor/github.com/godror/godror/drv_posix.go new file mode 100644 index 00000000000..c88fa6ec60c --- /dev/null +++ b/vendor/github.com/godror/godror/drv_posix.go @@ -0,0 +1,11 @@ +// +build !windows + +// Copyright 2017 Tamás Gulácsi +// +// +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 + +package godror + +// #cgo LDFLAGS: -ldl -lpthread +import "C" diff --git a/vendor/github.com/godror/godror/go.mod b/vendor/github.com/godror/godror/go.mod new file mode 100644 index 00000000000..d7c794d6705 --- /dev/null +++ b/vendor/github.com/godror/godror/go.mod @@ -0,0 +1,12 @@ +module github.com/godror/godror + +go 1.12 + +require ( + github.com/go-kit/kit v0.9.0 + github.com/go-logfmt/logfmt v0.4.0 // indirect + github.com/go-stack/stack v1.8.0 // indirect + github.com/google/go-cmp v0.3.1 + golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e + golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 +) diff --git a/vendor/github.com/godror/godror/go.sum b/vendor/github.com/godror/godror/go.sum new file mode 100644 index 00000000000..2456fcd618c --- /dev/null +++ b/vendor/github.com/godror/godror/go.sum @@ -0,0 +1,14 @@ +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/vendor/gopkg.in/goracle.v2/lob.go b/vendor/github.com/godror/godror/lob.go similarity index 77% rename from vendor/gopkg.in/goracle.v2/lob.go rename to vendor/github.com/godror/godror/lob.go index 567dbaa843d..a914462d464 100644 --- a/vendor/gopkg.in/goracle.v2/lob.go +++ b/vendor/github.com/godror/godror/lob.go @@ -1,19 +1,9 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include "dpiImpl.h" @@ -25,7 +15,7 @@ import ( "unicode/utf8" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) // Lob is for reading/writing a LOB. @@ -98,7 +88,9 @@ func (dlr *dpiLobReader) Read(p []byte) (int, error) { if dlr.sizePlusOne == 0 { // never read size before if C.dpiLob_getSize(dlr.dpiLob, &dlr.sizePlusOne) == C.DPI_FAILURE { - return 0, errors.Wrap(dlr.getError(), "getSize") + C.dpiLob_close(dlr.dpiLob) + dlr.dpiLob = nil + return 0, errors.Errorf("getSize: %w", dlr.getError()) } dlr.sizePlusOne++ } @@ -108,12 +100,14 @@ func (dlr *dpiLobReader) Read(p []byte) (int, error) { return 0, io.EOF } if C.dpiLob_readBytes(dlr.dpiLob, dlr.offset+1, n, (*C.char)(unsafe.Pointer(&p[0])), &n) == C.DPI_FAILURE { + C.dpiLob_close(dlr.dpiLob) + dlr.dpiLob = nil err := dlr.getError() if dlr.finished = err.(interface{ Code() int }).Code() == 1403; dlr.finished { dlr.offset += n return int(n), io.EOF } - return int(n), errors.Wrapf(err, "lob=%p offset=%d n=%d", dlr.dpiLob, dlr.offset, len(p)) + return int(n), errors.Errorf("lob=%p offset=%d n=%d: %w", dlr.dpiLob, dlr.offset, len(p), err) } //fmt.Printf("read %d\n", n) if dlr.IsClob { @@ -123,6 +117,9 @@ func (dlr *dpiLobReader) Read(p []byte) (int, error) { } var err error if n == 0 || dlr.offset+1 >= dlr.sizePlusOne { + C.dpiLob_close(dlr.dpiLob) + dlr.dpiLob = nil + dlr.finished = true err = io.EOF } return int(n), err @@ -141,14 +138,14 @@ func (dlw *dpiLobWriter) Write(p []byte) (int, error) { if !dlw.opened { //fmt.Printf("open %p\n", lob) if C.dpiLob_openResource(lob) == C.DPI_FAILURE { - return 0, errors.Wrapf(dlw.getError(), "openResources(%p)", lob) + return 0, errors.Errorf("openResources(%p): %w", lob, dlw.getError()) } dlw.opened = true } n := C.uint64_t(len(p)) if C.dpiLob_writeBytes(lob, dlw.offset+1, (*C.char)(unsafe.Pointer(&p[0])), n) == C.DPI_FAILURE { - err := errors.Wrapf(dlw.getError(), "writeBytes(%p, offset=%d, data=%d)", lob, dlw.offset, n) + err := errors.Errorf("writeBytes(%p, offset=%d, data=%d): %w", lob, dlw.offset, n, dlw.getError()) dlw.dpiLob = nil C.dpiLob_closeResource(lob) return 0, err @@ -171,7 +168,7 @@ func (dlw *dpiLobWriter) Close() error { if ec, ok := err.(interface{ Code() int }); ok && !dlw.opened && ec.Code() == 22289 { // cannot perform %s operation on an unopened file or LOB return nil } - return errors.Wrapf(err, "closeResource(%p)", lob) + return errors.Errorf("closeResource(%p): %w", lob, err) } return nil } @@ -186,6 +183,19 @@ type DirectLob struct { var _ = io.ReaderAt((*DirectLob)(nil)) var _ = io.WriterAt((*DirectLob)(nil)) +// NewTempLob returns a temporary LOB as DirectLob. +func (c *conn) NewTempLob(isClob bool) (*DirectLob, error) { + typ := C.uint(C.DPI_ORACLE_TYPE_BLOB) + if isClob { + typ = C.DPI_ORACLE_TYPE_CLOB + } + lob := DirectLob{conn: c} + if C.dpiConn_newTempLob(c.dpiConn, typ, &lob.dpiLob) == C.DPI_FAILURE { + return nil, errors.Errorf("newTempLob: %w", c.getError()) + } + return &lob, nil +} + // Close the Lob. func (dl *DirectLob) Close() error { if !dl.opened { @@ -193,7 +203,7 @@ func (dl *DirectLob) Close() error { } dl.opened = false if C.dpiLob_closeResource(dl.dpiLob) == C.DPI_FAILURE { - return errors.Wrap(dl.conn.getError(), "closeResource") + return errors.Errorf("closeResource: %w", dl.conn.getError()) } return nil } @@ -202,7 +212,7 @@ func (dl *DirectLob) Close() error { func (dl *DirectLob) Size() (int64, error) { var n C.uint64_t if C.dpiLob_getSize(dl.dpiLob, &n) == C.DPI_FAILURE { - return int64(n), errors.Wrap(dl.conn.getError(), "getSize") + return int64(n), errors.Errorf("getSize: %w", dl.conn.getError()) } return int64(n), nil } @@ -210,7 +220,7 @@ func (dl *DirectLob) Size() (int64, error) { // Trim the LOB to the given size. func (dl *DirectLob) Trim(size int64) error { if C.dpiLob_trim(dl.dpiLob, C.uint64_t(size)) == C.DPI_FAILURE { - return errors.Wrap(dl.conn.getError(), "trim") + return errors.Errorf("trim: %w", dl.conn.getError()) } return nil } @@ -219,7 +229,7 @@ func (dl *DirectLob) Trim(size int64) error { // The LOB is cleared first. func (dl *DirectLob) Set(p []byte) error { if C.dpiLob_setFromBytes(dl.dpiLob, (*C.char)(unsafe.Pointer(&p[0])), C.uint64_t(len(p))) == C.DPI_FAILURE { - return errors.Wrap(dl.conn.getError(), "setFromBytes") + return errors.Errorf("setFromBytes: %w", dl.conn.getError()) } return nil } @@ -228,7 +238,7 @@ func (dl *DirectLob) Set(p []byte) error { func (dl *DirectLob) ReadAt(p []byte, offset int64) (int, error) { n := C.uint64_t(len(p)) if C.dpiLob_readBytes(dl.dpiLob, C.uint64_t(offset)+1, n, (*C.char)(unsafe.Pointer(&p[0])), &n) == C.DPI_FAILURE { - return int(n), errors.Wrap(dl.conn.getError(), "readBytes") + return int(n), errors.Errorf("readBytes: %w", dl.conn.getError()) } return int(n), nil } @@ -238,14 +248,14 @@ func (dl *DirectLob) WriteAt(p []byte, offset int64) (int, error) { if !dl.opened { //fmt.Printf("open %p\n", lob) if C.dpiLob_openResource(dl.dpiLob) == C.DPI_FAILURE { - return 0, errors.Wrapf(dl.conn.getError(), "openResources(%p)", dl.dpiLob) + return 0, errors.Errorf("openResources(%p): %w", dl.dpiLob, dl.conn.getError()) } dl.opened = true } n := C.uint64_t(len(p)) if C.dpiLob_writeBytes(dl.dpiLob, C.uint64_t(offset)+1, (*C.char)(unsafe.Pointer(&p[0])), n) == C.DPI_FAILURE { - return int(n), errors.Wrap(dl.conn.getError(), "writeBytes") + return int(n), errors.Errorf("writeBytes: %w", dl.conn.getError()) } return int(n), nil } diff --git a/vendor/gopkg.in/goracle.v2/obj.go b/vendor/github.com/godror/godror/obj.go similarity index 62% rename from vendor/gopkg.in/goracle.v2/obj.go rename to vendor/github.com/godror/godror/obj.go index e8f97afcfd9..a5d35505420 100644 --- a/vendor/gopkg.in/goracle.v2/obj.go +++ b/vendor/github.com/godror/godror/obj.go @@ -1,19 +1,9 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include @@ -21,23 +11,25 @@ package goracle */ import "C" import ( + "context" "fmt" "reflect" + "strings" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) var _ = fmt.Printf // Object represents a dpiObject. type Object struct { - scratch Data ObjectType + scratch Data dpiObject *C.dpiObject } -func (O *Object) getError() error { return O.drv.getError() } +func (O *Object) getError() error { return O.conn.getError() } // ErrNoSuchKey is the error for missing key in lookup. var ErrNoSuchKey = errors.New("no such key") @@ -49,33 +41,35 @@ func (O *Object) GetAttribute(data *Data, name string) error { } attr, ok := O.Attributes[name] if !ok { - return errors.Wrap(ErrNoSuchKey, name) + return errors.Errorf("%s: %w", name, ErrNoSuchKey) } data.reset() + if data.dpiData == nil { + data.dpiData = &C.dpiData{isNull: 0} + } data.NativeTypeNum = attr.NativeTypeNum data.ObjectType = attr.ObjectType - wasNull := data.dpiData == nil // the maximum length of that buffer must be supplied // in the value.asBytes.length attribute before calling this function. if attr.NativeTypeNum == C.DPI_NATIVE_TYPE_BYTES && attr.OracleTypeNum == C.DPI_ORACLE_TYPE_NUMBER { - var a [22]byte - C.dpiData_setBytes(data.dpiData, (*C.char)(unsafe.Pointer(&a[0])), 22) + var a [39]byte + C.dpiData_setBytes(data.dpiData, (*C.char)(unsafe.Pointer(&a[0])), C.uint32_t(len(a))) } + //fmt.Printf("getAttributeValue(%p, %p, %d, %+v)\n", O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) if C.dpiObject_getAttributeValue(O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { - if wasNull { - C.free(unsafe.Pointer(data.dpiData)) - data.dpiData = nil - } - return errors.Wrapf(O.getError(), "getAttributeValue(obj=%+v, attr=%+v, typ=%d)", O, attr.dpiObjectAttr, data.NativeTypeNum) + return errors.Errorf("getAttributeValue(%q, obj=%+v, attr=%+v, typ=%d): %w", name, O, attr.dpiObjectAttr, data.NativeTypeNum, O.getError()) } //fmt.Printf("getAttributeValue(%p, %q=%p, %d, %+v)\n", O.dpiObject, attr.Name, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) return nil } -// SetAttribute sets the i-th attribute with data. +// SetAttribute sets the named attribute with data. func (O *Object) SetAttribute(name string, data *Data) error { + if !strings.Contains(name, `"`) { + name = strings.ToUpper(name) + } attr := O.Attributes[name] if data.NativeTypeNum == 0 { data.NativeTypeNum = attr.NativeTypeNum @@ -87,7 +81,18 @@ func (O *Object) SetAttribute(name string, data *Data) error { return nil } -// ResetAttributes prepare all atributes for use the object as IN parameter +// Set is a convenience function to set the named attribute with the given value. +func (O *Object) Set(name string, v interface{}) error { + if data, ok := v.(*Data); ok { + return O.SetAttribute(name, data) + } + if err := O.scratch.Set(v); err != nil { + return err + } + return O.SetAttribute(name, &O.scratch) +} + +// ResetAttributes prepare all attributes for use the object as IN parameter func (O *Object) ResetAttributes() error { var data Data for _, attr := range O.Attributes { @@ -95,8 +100,8 @@ func (O *Object) ResetAttributes() error { data.NativeTypeNum = attr.NativeTypeNum data.ObjectType = attr.ObjectType if attr.NativeTypeNum == C.DPI_NATIVE_TYPE_BYTES && attr.OracleTypeNum == C.DPI_ORACLE_TYPE_NUMBER { - var a [22]byte - C.dpiData_setBytes(data.dpiData, (*C.char)(unsafe.Pointer(&a[0])), 22) + a := make([]byte, attr.Precision) + C.dpiData_setBytes(data.dpiData, (*C.char)(unsafe.Pointer(&a[0])), C.uint32_t(attr.Precision)) } if C.dpiObject_setAttributeValue(O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { return O.getError() @@ -131,15 +136,25 @@ func (O *Object) ObjectRef() *Object { return O } +// Collection returns &ObjectCollection{Object: O} iff the Object is a collection. +// Otherwise it returns nil. +func (O *Object) Collection() *ObjectCollection { + if O.ObjectType.CollectionOf == nil { + return nil + } + return &ObjectCollection{Object: O} +} + // Close releases a reference to the object. func (O *Object) Close() error { - if O.dpiObject == nil { + obj := O.dpiObject + O.dpiObject = nil + if obj == nil { return nil } - if rc := C.dpiObject_release(O.dpiObject); rc == C.DPI_FAILURE { - return errors.Wrapf(O.getError(), "error on close object") + if C.dpiObject_release(obj) == C.DPI_FAILURE { + return errors.Errorf("error on close object: %w", O.getError()) } - O.dpiObject = nil return nil } @@ -157,7 +172,6 @@ var ErrNotExist = errors.New("not exist") // AsSlice retrieves the collection into a slice. func (O *ObjectCollection) AsSlice(dest interface{}) (interface{}, error) { - var data Data var dr reflect.Value needsInit := dest == nil if !needsInit { @@ -165,12 +179,12 @@ func (O *ObjectCollection) AsSlice(dest interface{}) (interface{}, error) { } for i, err := O.First(); err == nil; i, err = O.Next(i) { if O.CollectionOf.NativeTypeNum == C.DPI_NATIVE_TYPE_OBJECT { - data.ObjectType = *O.CollectionOf + O.scratch.ObjectType = *O.CollectionOf } - if err = O.Get(&data, i); err != nil { + if err = O.GetItem(&O.scratch, i); err != nil { return dest, err } - vr := reflect.ValueOf(data.Get()) + vr := reflect.ValueOf(O.scratch.Get()) if needsInit { needsInit = false length, lengthErr := O.Len() @@ -184,31 +198,53 @@ func (O *ObjectCollection) AsSlice(dest interface{}) (interface{}, error) { return dr.Interface(), nil } -// Append data to the collection. -func (O *ObjectCollection) Append(data *Data) error { +// AppendData to the collection. +func (O *ObjectCollection) AppendData(data *Data) error { if C.dpiObject_appendElement(O.dpiObject, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { - return errors.Wrapf(O.getError(), "append(%d)", data.NativeTypeNum) + return errors.Errorf("append(%d): %w", data.NativeTypeNum, O.getError()) } return nil } +// Append v to the collection. +func (O *ObjectCollection) Append(v interface{}) error { + if data, ok := v.(*Data); ok { + return O.AppendData(data) + } + if err := O.scratch.Set(v); err != nil { + return err + } + return O.AppendData(&O.scratch) +} + +// AppendObject adds an Object to the collection. +func (O *ObjectCollection) AppendObject(obj *Object) error { + O.scratch = Data{ + ObjectType: obj.ObjectType, + NativeTypeNum: C.DPI_NATIVE_TYPE_OBJECT, + dpiData: &C.dpiData{isNull: 1}, + } + O.scratch.SetObject(obj) + return O.Append(&O.scratch) +} + // Delete i-th element of the collection. func (O *ObjectCollection) Delete(i int) error { if C.dpiObject_deleteElementByIndex(O.dpiObject, C.int32_t(i)) == C.DPI_FAILURE { - return errors.Wrapf(O.getError(), "delete(%d)", i) + return errors.Errorf("delete(%d): %w", i, O.getError()) } return nil } -// Get the i-th element of the collection into data. -func (O *ObjectCollection) Get(data *Data, i int) error { +// GetItem gets the i-th element of the collection into data. +func (O *ObjectCollection) GetItem(data *Data, i int) error { if data == nil { panic("data cannot be nil") } idx := C.int32_t(i) var exists C.int if C.dpiObject_getElementExistsByIndex(O.dpiObject, idx, &exists) == C.DPI_FAILURE { - return errors.Wrapf(O.getError(), "exists(%d)", idx) + return errors.Errorf("exists(%d): %w", idx, O.getError()) } if exists == 0 { return ErrNotExist @@ -217,25 +253,43 @@ func (O *ObjectCollection) Get(data *Data, i int) error { data.NativeTypeNum = O.CollectionOf.NativeTypeNum data.ObjectType = *O.CollectionOf if C.dpiObject_getElementValueByIndex(O.dpiObject, idx, data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { - return errors.Wrapf(O.getError(), "get(%d[%d])", idx, data.NativeTypeNum) + return errors.Errorf("get(%d[%d]): %w", idx, data.NativeTypeNum, O.getError()) } return nil } -// Set the i-th element of the collection with data. -func (O *ObjectCollection) Set(i int, data *Data) error { +// Get the i-th element of the collection. +func (O *ObjectCollection) Get(i int) (interface{}, error) { + var data Data + err := O.GetItem(&data, i) + return data.Get(), err +} + +// SetItem sets the i-th element of the collection with data. +func (O *ObjectCollection) SetItem(i int, data *Data) error { if C.dpiObject_setElementValueByIndex(O.dpiObject, C.int32_t(i), data.NativeTypeNum, data.dpiData) == C.DPI_FAILURE { - return errors.Wrapf(O.getError(), "set(%d[%d])", i, data.NativeTypeNum) + return errors.Errorf("set(%d[%d]): %w", i, data.NativeTypeNum, O.getError()) } return nil } +// Set the i-th element of the collection with value. +func (O *ObjectCollection) Set(i int, v interface{}) error { + if data, ok := v.(*Data); ok { + return O.SetItem(i, data) + } + if err := O.scratch.Set(v); err != nil { + return err + } + return O.SetItem(i, &O.scratch) +} + // First returns the first element's index of the collection. func (O *ObjectCollection) First() (int, error) { var exists C.int var idx C.int32_t if C.dpiObject_getFirstIndex(O.dpiObject, &idx, &exists) == C.DPI_FAILURE { - return 0, errors.Wrap(O.getError(), "first") + return 0, errors.Errorf("first: %w", O.getError()) } if exists == 1 { return int(idx), nil @@ -248,7 +302,7 @@ func (O *ObjectCollection) Last() (int, error) { var exists C.int var idx C.int32_t if C.dpiObject_getLastIndex(O.dpiObject, &idx, &exists) == C.DPI_FAILURE { - return 0, errors.Wrap(O.getError(), "last") + return 0, errors.Errorf("last: %w", O.getError()) } if exists == 1 { return int(idx), nil @@ -261,7 +315,7 @@ func (O *ObjectCollection) Next(i int) (int, error) { var exists C.int var idx C.int32_t if C.dpiObject_getNextIndex(O.dpiObject, C.int32_t(i), &idx, &exists) == C.DPI_FAILURE { - return 0, errors.Wrapf(O.getError(), "next(%d)", i) + return 0, errors.Errorf("next(%d): %w", i, O.getError()) } if exists == 1 { return int(idx), nil @@ -273,7 +327,7 @@ func (O *ObjectCollection) Next(i int) (int, error) { func (O *ObjectCollection) Len() (int, error) { var size C.int32_t if C.dpiObject_getSize(O.dpiObject, &size) == C.DPI_FAILURE { - return 0, errors.Wrap(O.getError(), "len") + return 0, errors.Errorf("len: %w", O.getError()) } return int(size), nil } @@ -288,12 +342,13 @@ func (O *ObjectCollection) Trim(n int) error { // ObjectType holds type info of an Object. type ObjectType struct { + dpiObjectType *C.dpiObjectType + conn *conn + Schema, Name string DBSize, ClientSizeInBytes, CharSize int CollectionOf *ObjectType Attributes map[string]ObjectAttribute - dpiObjectType *C.dpiObjectType - drv *drv OracleTypeNum C.dpiOracleTypeNum NativeTypeNum C.dpiNativeTypeNum Precision int16 @@ -301,7 +356,14 @@ type ObjectType struct { FsPrecision uint8 } -func (t ObjectType) getError() error { return t.drv.getError() } +func (t ObjectType) getError() error { return t.conn.getError() } + +func (t ObjectType) String() string { + if t.Schema == "" { + return t.Name + } + return t.Schema + "." + t.Name +} // FullName returns the object's name with the schame prepended. func (t ObjectType) FullName() string { @@ -312,66 +374,103 @@ func (t ObjectType) FullName() string { } // GetObjectType returns the ObjectType of a name. +// +// The name is uppercased! Because here Oracle seems to be case-sensitive. +// To leave it as is, enclose it in "-s! func (c *conn) GetObjectType(name string) (ObjectType, error) { + c.mu.Lock() + defer c.mu.Unlock() + if !strings.Contains(name, "\"") { + name = strings.ToUpper(name) + } + if o, ok := c.objTypes[name]; ok { + return o, nil + } cName := C.CString(name) defer func() { C.free(unsafe.Pointer(cName)) }() objType := (*C.dpiObjectType)(C.malloc(C.sizeof_void)) if C.dpiConn_getObjectType(c.dpiConn, cName, C.uint32_t(len(name)), &objType) == C.DPI_FAILURE { C.free(unsafe.Pointer(objType)) - return ObjectType{}, errors.Wrapf(c.getError(), "getObjectType(%q) conn=%p", name, c.dpiConn) + return ObjectType{}, errors.Errorf("getObjectType(%q) conn=%p: %w", name, c.dpiConn, c.getError()) + } + t := ObjectType{conn: c, dpiObjectType: objType} + err := t.init() + if err == nil { + c.objTypes[name] = t } - t := ObjectType{drv: c.drv, dpiObjectType: objType} - return t, t.init() + return t, err } // NewObject returns a new Object with ObjectType type. +// +// As with all Objects, you MUST call Close on it when not needed anymore! func (t ObjectType) NewObject() (*Object, error) { obj := (*C.dpiObject)(C.malloc(C.sizeof_void)) if C.dpiObjectType_createObject(t.dpiObjectType, &obj) == C.DPI_FAILURE { C.free(unsafe.Pointer(obj)) return nil, t.getError() } - return &Object{ObjectType: t, dpiObject: obj}, nil + O := &Object{ObjectType: t, dpiObject: obj} + // https://github.com/oracle/odpi/issues/112#issuecomment-524479532 + return O, O.ResetAttributes() +} + +// NewCollection returns a new Collection object with ObjectType type. +// If the ObjectType is not a Collection, it returns ErrNotCollection error. +func (t ObjectType) NewCollection() (*ObjectCollection, error) { + if t.CollectionOf == nil { + return nil, ErrNotCollection + } + O, err := t.NewObject() + if err != nil { + return nil, err + } + return &ObjectCollection{Object: O}, nil } // Close releases a reference to the object type. -func (t *ObjectType) Close() error { +func (t *ObjectType) close() error { + if t == nil { + return nil + } + attributes, d := t.Attributes, t.dpiObjectType + t.Attributes, t.dpiObjectType = nil, nil - for _, attr := range t.Attributes { + for _, attr := range attributes { err := attr.Close() if err != nil { return err } } - t.Attributes = nil - d := t.dpiObjectType - t.dpiObjectType = nil if d == nil { return nil } - if rc := C.dpiObjectType_release(d); rc == C.DPI_FAILURE { - return errors.Wrapf(t.getError(), "error on close object type") + if C.dpiObjectType_release(d) == C.DPI_FAILURE { + return errors.Errorf("error on close object type: %w", t.getError()) } return nil } -func wrapObject(d *drv, objectType *C.dpiObjectType, object *C.dpiObject) (*Object, error) { +func wrapObject(c *conn, objectType *C.dpiObjectType, object *C.dpiObject) (*Object, error) { if objectType == nil { return nil, errors.New("objectType is nil") } + if C.dpiObject_addRef(object) == C.DPI_FAILURE { + return nil, c.getError() + } o := &Object{ - ObjectType: ObjectType{dpiObjectType: objectType, drv: d}, + ObjectType: ObjectType{dpiObjectType: objectType, conn: c}, dpiObject: object, } return o, o.init() } func (t *ObjectType) init() error { - if t.drv == nil { - panic("drv is nil") + if t.conn == nil { + panic("conn is nil") } if t.Name != "" && t.Attributes != nil { return nil @@ -381,15 +480,18 @@ func (t *ObjectType) init() error { } var info C.dpiObjectTypeInfo if C.dpiObjectType_getInfo(t.dpiObjectType, &info) == C.DPI_FAILURE { - return errors.Wrapf(t.getError(), "%v.getInfo", t) + return errors.Errorf("%v.getInfo: %w", t, t.getError()) } t.Schema = C.GoStringN(info.schema, C.int(info.schemaLength)) t.Name = C.GoStringN(info.name, C.int(info.nameLength)) t.CollectionOf = nil - numAttributes := int(info.numAttributes) + if t.conn.objTypes == nil { + t.conn.objTypes = make(map[string]ObjectType) + } + numAttributes := int(info.numAttributes) if info.isCollection == 1 { - t.CollectionOf = &ObjectType{drv: t.drv} + t.CollectionOf = &ObjectType{conn: t.conn} if err := t.CollectionOf.fromDataTypeInfo(info.elementTypeInfo); err != nil { return err } @@ -400,6 +502,7 @@ func (t *ObjectType) init() error { } if numAttributes == 0 { t.Attributes = map[string]ObjectAttribute{} + t.conn.objTypes[t.FullName()] = *t return nil } t.Attributes = make(map[string]ObjectAttribute, numAttributes) @@ -408,18 +511,18 @@ func (t *ObjectType) init() error { C.uint16_t(len(attrs)), (**C.dpiObjectAttr)(unsafe.Pointer(&attrs[0])), ) == C.DPI_FAILURE { - return errors.Wrapf(t.getError(), "%v.getAttributes", t) + return errors.Errorf("%v.getAttributes: %w", t, t.getError()) } for i, attr := range attrs { var attrInfo C.dpiObjectAttrInfo if C.dpiObjectAttr_getInfo(attr, &attrInfo) == C.DPI_FAILURE { - return errors.Wrapf(t.getError(), "%v.attr_getInfo", attr) + return errors.Errorf("%v.attr_getInfo: %w", attr, t.getError()) } if Log != nil { Log("i", i, "attrInfo", attrInfo) } typ := attrInfo.typeInfo - sub, err := objectTypeFromDataTypeInfo(t.drv, typ) + sub, err := objectTypeFromDataTypeInfo(t.conn, typ) if err != nil { return err } @@ -431,6 +534,7 @@ func (t *ObjectType) init() error { //fmt.Printf("%d=%q. typ=%+v sub=%+v\n", i, objAttr.Name, typ, sub) t.Attributes[objAttr.Name] = objAttr } + t.conn.objTypes[t.FullName()] = *t return nil } @@ -447,14 +551,14 @@ func (t *ObjectType) fromDataTypeInfo(typ C.dpiDataTypeInfo) error { t.FsPrecision = uint8(typ.fsPrecision) return t.init() } -func objectTypeFromDataTypeInfo(drv *drv, typ C.dpiDataTypeInfo) (ObjectType, error) { - if drv == nil { - panic("drv nil") +func objectTypeFromDataTypeInfo(conn *conn, typ C.dpiDataTypeInfo) (ObjectType, error) { + if conn == nil { + panic("conn is nil") } if typ.oracleTypeNum == 0 { panic("typ is nil") } - t := ObjectType{drv: drv} + t := ObjectType{conn: conn} err := t.fromDataTypeInfo(typ) return t, err } @@ -469,11 +573,11 @@ type ObjectAttribute struct { // Close the ObjectAttribute. func (A ObjectAttribute) Close() error { attr := A.dpiObjectAttr + A.dpiObjectAttr = nil + if attr == nil { return nil } - - A.dpiObjectAttr = nil if C.dpiObjectAttr_release(attr) == C.DPI_FAILURE { return A.getError() } @@ -481,10 +585,10 @@ func (A ObjectAttribute) Close() error { } // GetObjectType returns the ObjectType for the name. -func GetObjectType(ex Execer, typeName string) (ObjectType, error) { - c, err := getConn(ex) +func GetObjectType(ctx context.Context, ex Execer, typeName string) (ObjectType, error) { + c, err := getConn(ctx, ex) if err != nil { - return ObjectType{}, errors.WithMessage(err, "getConn for "+typeName) + return ObjectType{}, errors.Errorf("getConn for %s: %w", typeName, err) } return c.GetObjectType(typeName) } diff --git a/vendor/gopkg.in/goracle.v2/odpi/CONTRIBUTING.md b/vendor/github.com/godror/godror/odpi/CONTRIBUTING.md similarity index 100% rename from vendor/gopkg.in/goracle.v2/odpi/CONTRIBUTING.md rename to vendor/github.com/godror/godror/odpi/CONTRIBUTING.md diff --git a/vendor/gopkg.in/goracle.v2/odpi/LICENSE.md b/vendor/github.com/godror/godror/odpi/LICENSE.md similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/LICENSE.md rename to vendor/github.com/godror/godror/odpi/LICENSE.md index 20b6fc956fa..cb344b76c16 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/LICENSE.md +++ b/vendor/github.com/godror/godror/odpi/LICENSE.md @@ -215,4 +215,3 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS - diff --git a/vendor/gopkg.in/goracle.v2/odpi/README.md b/vendor/github.com/godror/godror/odpi/README.md similarity index 95% rename from vendor/gopkg.in/goracle.v2/odpi/README.md rename to vendor/github.com/godror/godror/odpi/README.md index a8e1decf845..fa911cc2130 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/README.md +++ b/vendor/github.com/godror/godror/odpi/README.md @@ -1,4 +1,4 @@ -# ODPI-C version 3.1 +# ODPI-C version 3.3 Oracle Database Programming Interface for C (ODPI-C) is an open source library of C code that simplifies access to Oracle Database for applications written in @@ -48,6 +48,7 @@ Third-party Drivers: * [ruby-ODPI ](https://github.com/kubo/ruby-odpi) Ruby Interface. * [rust-oracle ](https://github.com/kubo/rust-oracle) Driver for Rust. * [Oracle.jl](https://github.com/felipenoris/Oracle.jl) Driver for Julia. +* [oranif](https://github.com/K2InformaticsGmbH/oranif) Driver for Erlang. ## License diff --git a/vendor/gopkg.in/goracle.v2/odpi/embed/README.md b/vendor/github.com/godror/godror/odpi/embed/README.md similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/embed/README.md rename to vendor/github.com/godror/godror/odpi/embed/README.md index 5dc0fb5ca15..dfe0b4524c0 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/embed/README.md +++ b/vendor/github.com/godror/godror/odpi/embed/README.md @@ -1,4 +1,3 @@ This directory contains the file dpi.c which can be used to embed ODPI-C within your project without having to manage the individual files that make up the library. The files can also be compiled independently if that is preferred. - diff --git a/vendor/gopkg.in/goracle.v2/odpi/embed/dpi.c b/vendor/github.com/godror/godror/odpi/embed/dpi.c similarity index 98% rename from vendor/gopkg.in/goracle.v2/odpi/embed/dpi.c rename to vendor/github.com/godror/godror/odpi/embed/dpi.c index e47f3f21460..7d0c6dc83bb 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/embed/dpi.c +++ b/vendor/github.com/godror/godror/odpi/embed/dpi.c @@ -37,6 +37,7 @@ #include "../src/dpiOci.c" #include "../src/dpiOracleType.c" #include "../src/dpiPool.c" +#include "../src/dpiQueue.c" #include "../src/dpiRowid.c" #include "../src/dpiSodaColl.c" #include "../src/dpiSodaCollCursor.c" @@ -47,4 +48,3 @@ #include "../src/dpiSubscr.c" #include "../src/dpiUtils.c" #include "../src/dpiVar.c" - diff --git a/vendor/gopkg.in/goracle.v2/odpi/include/dpi.h b/vendor/github.com/godror/godror/odpi/include/dpi.h similarity index 96% rename from vendor/gopkg.in/goracle.v2/odpi/include/dpi.h rename to vendor/github.com/godror/godror/odpi/include/dpi.h index 8606774900c..58b3a2d5867 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/include/dpi.h +++ b/vendor/github.com/godror/godror/odpi/include/dpi.h @@ -44,8 +44,8 @@ // define ODPI-C version information #define DPI_MAJOR_VERSION 3 -#define DPI_MINOR_VERSION 1 -#define DPI_PATCH_LEVEL 4 +#define DPI_MINOR_VERSION 3 +#define DPI_PATCH_LEVEL 0 #define DPI_VERSION_SUFFIX #define DPI_STR_HELPER(x) #x @@ -152,7 +152,6 @@ typedef uint32_t dpiEventType; #define DPI_EVENT_STARTUP 1 #define DPI_EVENT_SHUTDOWN 2 #define DPI_EVENT_SHUTDOWN_ANY 3 -#define DPI_EVENT_DROP_DB 4 #define DPI_EVENT_DEREG 5 #define DPI_EVENT_OBJCHANGE 6 #define DPI_EVENT_QUERYCHANGE 7 @@ -414,6 +413,7 @@ typedef struct dpiObjectAttrInfo dpiObjectAttrInfo; typedef struct dpiObjectTypeInfo dpiObjectTypeInfo; typedef struct dpiPoolCreateParams dpiPoolCreateParams; typedef struct dpiQueryInfo dpiQueryInfo; +typedef struct dpiQueue dpiQueue; typedef struct dpiShardingKeyColumn dpiShardingKeyColumn; typedef struct dpiSodaColl dpiSodaColl; typedef struct dpiSodaCollNames dpiSodaCollNames; @@ -571,6 +571,7 @@ struct dpiPoolCreateParams { uint32_t maxLifetimeSession; const char *plsqlFixupCallback; uint32_t plsqlFixupCallbackLength; + uint32_t maxSessionsPerShard; }; // structure used for transferring query metadata from ODPI-C @@ -642,6 +643,8 @@ struct dpiSubscrCreateParams { uint8_t groupingClass; uint32_t groupingValue; uint8_t groupingType; + uint64_t outRegId; + int clientInitiated; }; // structure used for transferring messages in subscription callbacks @@ -836,6 +839,10 @@ int dpiConn_newEnqOptions(dpiConn *conn, dpiEnqOptions **options); // create a new message properties object and return it int dpiConn_newMsgProps(dpiConn *conn, dpiMsgProps **props); +// create a new AQ queue +int dpiConn_newQueue(dpiConn *conn, const char *name, uint32_t nameLength, + dpiObjectType *payloadType, dpiQueue **queue); + // create a new temporary LOB int dpiConn_newTempLob(dpiConn *conn, dpiOracleTypeNum lobType, dpiLob **lob); @@ -1202,10 +1209,18 @@ int dpiMsgProps_getExceptionQ(dpiMsgProps *props, const char **value, // return the number of seconds until the message expires int dpiMsgProps_getExpiration(dpiMsgProps *props, int32_t *value); +// return the message id for the message (after enqueuing or dequeuing) +int dpiMsgProps_getMsgId(dpiMsgProps *props, const char **value, + uint32_t *valueLength); + // return the original message id for the message int dpiMsgProps_getOriginalMsgId(dpiMsgProps *props, const char **value, uint32_t *valueLength); +// return the payload of the message (object or bytes) +int dpiMsgProps_getPayload(dpiMsgProps *props, dpiObject **obj, + const char **value, uint32_t *valueLength); + // return the priority of the message int dpiMsgProps_getPriority(dpiMsgProps *props, int32_t *value); @@ -1233,6 +1248,13 @@ int dpiMsgProps_setExpiration(dpiMsgProps *props, int32_t value); int dpiMsgProps_setOriginalMsgId(dpiMsgProps *props, const char *value, uint32_t valueLength); +// set the payload of the message (as a series of bytes) +int dpiMsgProps_setPayloadBytes(dpiMsgProps *props, const char *value, + uint32_t valueLength); + +// set the payload of the message (as an object) +int dpiMsgProps_setPayloadObject(dpiMsgProps *props, dpiObject *obj); + // set the priority of the message int dpiMsgProps_setPriority(dpiMsgProps *props, int32_t value); @@ -1398,6 +1420,35 @@ int dpiPool_setTimeout(dpiPool *pool, uint32_t value); int dpiPool_setWaitTimeout(dpiPool *pool, uint32_t value); +//----------------------------------------------------------------------------- +// AQ Queue Methods (dpiQueue) +//----------------------------------------------------------------------------- + +// add a reference to the queue +int dpiQueue_addRef(dpiQueue *queue); + +// dequeue multiple messages from the queue +int dpiQueue_deqMany(dpiQueue *queue, uint32_t *numProps, dpiMsgProps **props); + +// dequeue a single message from the queue +int dpiQueue_deqOne(dpiQueue *queue, dpiMsgProps **props); + +// enqueue multiple message to the queue +int dpiQueue_enqMany(dpiQueue *queue, uint32_t numProps, dpiMsgProps **props); + +// enqueue a single message to the queue +int dpiQueue_enqOne(dpiQueue *queue, dpiMsgProps *props); + +// get a reference to the dequeue options associated with the queue +int dpiQueue_getDeqOptions(dpiQueue *queue, dpiDeqOptions **options); + +// get a reference to the enqueue options associated with the queue +int dpiQueue_getEnqOptions(dpiQueue *queue, dpiEnqOptions **options); + +// release a reference to the queue +int dpiQueue_release(dpiQueue *queue); + + //----------------------------------------------------------------------------- // SODA Collection Methods (dpiSodaColl) //----------------------------------------------------------------------------- @@ -1440,6 +1491,10 @@ int dpiSodaColl_getMetadata(dpiSodaColl *coll, const char **value, int dpiSodaColl_getName(dpiSodaColl *coll, const char **value, uint32_t *valueLength); +// insert multiple documents into the SODA collection +int dpiSodaColl_insertMany(dpiSodaColl *coll, uint32_t numDocs, + dpiSodaDoc **docs, uint32_t flags, dpiSodaDoc **insertedDocs); + // insert a document into the SODA collection int dpiSodaColl_insertOne(dpiSodaColl *coll, dpiSodaDoc *doc, uint32_t flags, dpiSodaDoc **insertedDoc); @@ -1644,6 +1699,9 @@ int dpiStmt_getImplicitResult(dpiStmt *stmt, dpiStmt **implicitResult); // return information about the statement int dpiStmt_getInfo(dpiStmt *stmt, dpiStmtInfo *info); +// get the rowid of the last row affected by a DML statement +int dpiStmt_getLastRowid(dpiStmt *stmt, dpiRowid **rowid); + // get the number of query columns (zero implies the statement is not a query) int dpiStmt_getNumQueryColumns(dpiStmt *stmt, uint32_t *numQueryColumns); @@ -1754,4 +1812,3 @@ int dpiVar_setFromStmt(dpiVar *var, uint32_t pos, dpiStmt *stmt); int dpiVar_setNumElementsInArray(dpiVar *var, uint32_t numElements); #endif - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiConn.c b/vendor/github.com/godror/godror/odpi/src/dpiConn.c similarity index 92% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiConn.c rename to vendor/github.com/godror/godror/odpi/src/dpiConn.c index e1c8edbe841..faa5dc5266b 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiConn.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiConn.c @@ -37,8 +37,7 @@ static int dpiConn__getSession(dpiConn *conn, uint32_t mode, static int dpiConn__setAttributesFromCreateParams(dpiConn *conn, void *handle, uint32_t handleType, const char *userName, uint32_t userNameLength, const char *password, uint32_t passwordLength, - const dpiConnCreateParams *params, void **shardingKey, - void **superShardingKey, dpiError *error); + const dpiConnCreateParams *params, dpiError *error); static int dpiConn__setShardingKey(dpiConn *conn, void **shardingKey, void *handle, uint32_t handleType, uint32_t attribute, const char *action, dpiShardingKeyColumn *columns, uint8_t numColumns, @@ -65,23 +64,6 @@ static int dpiConn__attachExternal(dpiConn *conn, void *externalHandle, return DPI_FAILURE; } - // allocate a new service context handle which will use the new environment - // handle independent of the original service context handle - conn->handle = NULL; - if (dpiOci__handleAlloc(conn->env->handle, &conn->handle, - DPI_OCI_HTYPE_SVCCTX, "allocate service context handle", - error) < 0) - return DPI_FAILURE; - - // set these handles on the newly created service context - if (dpiOci__attrSet(conn->handle, DPI_OCI_HTYPE_SVCCTX, conn->serverHandle, - 0, DPI_OCI_ATTR_SERVER, "set server handle", error) < 0) - return DPI_FAILURE; - if (dpiOci__attrSet(conn->handle, DPI_OCI_HTYPE_SVCCTX, - conn->sessionHandle, 0, DPI_OCI_ATTR_SESSION, "set session handle", - error) < 0) - return DPI_FAILURE; - return DPI_SUCCESS; } @@ -93,7 +75,7 @@ static int dpiConn__attachExternal(dpiConn *conn, void *externalHandle, //----------------------------------------------------------------------------- static int dpiConn__check(dpiConn *conn, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(conn, DPI_HTYPE_CONN, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(conn, DPI_HTYPE_CONN, fnName, error) < 0) return DPI_FAILURE; return dpiConn__checkConnected(conn, error); } @@ -224,8 +206,6 @@ static int dpiConn__close(dpiConn *conn, uint32_t mode, const char *tag, // handle connections created with an external handle if (conn->externalHandle) { - if (conn->handle) - dpiOci__handleFree(conn->handle, DPI_OCI_HTYPE_SVCCTX); conn->sessionHandle = NULL; // handle standalone connections @@ -254,7 +234,8 @@ static int dpiConn__close(dpiConn *conn, uint32_t mode, const char *tag, // update last time used (if the session isn't going to be dropped) // clear last time used (if the session is going to be dropped) - if (conn->sessionHandle) { + // do nothing, however, if not using a pool or the pool is being closed + if (conn->sessionHandle && conn->pool && conn->pool->handle) { // get the pointer from the context associated with the session lastTimeUsed = NULL; @@ -315,9 +296,20 @@ static int dpiConn__close(dpiConn *conn, uint32_t mode, const char *tag, conn->sessionHandle = NULL; } - conn->handle = NULL; conn->serverHandle = NULL; + + // destroy sharding and super sharding key descriptors, if applicable + if (conn->shardingKey) { + dpiOci__descriptorFree(conn->shardingKey, DPI_OCI_DTYPE_SHARDING_KEY); + conn->shardingKey = NULL; + } + if (conn->superShardingKey) { + dpiOci__descriptorFree(conn->superShardingKey, + DPI_OCI_DTYPE_SHARDING_KEY); + conn->superShardingKey = NULL; + } + return DPI_SUCCESS; } @@ -333,6 +325,8 @@ int dpiConn__create(dpiConn *conn, const dpiContext *context, const dpiCommonCreateParams *commonParams, dpiConnCreateParams *createParams, dpiError *error) { + void *envHandle = NULL; + // allocate handle lists for statements, LOBs and objects if (dpiHandleList__create(&conn->openStmts, error) < 0) return DPI_FAILURE; @@ -341,8 +335,29 @@ int dpiConn__create(dpiConn *conn, const dpiContext *context, if (dpiHandleList__create(&conn->objects, error) < 0) return DPI_FAILURE; + // if an external service context handle is provided, acquire the + // environment handle from it; need a temporary environment handle in order + // to do so + if (createParams->externalHandle) { + error->env = conn->env; + if (dpiOci__envNlsCreate(&conn->env->handle, DPI_OCI_DEFAULT, 0, 0, + error) < 0) + return DPI_FAILURE; + if (dpiOci__handleAlloc(conn->env->handle, &error->handle, + DPI_OCI_HTYPE_ERROR, "allocate temp OCI error", error) < 0) + return DPI_FAILURE; + if (dpiOci__attrGet(createParams->externalHandle, DPI_OCI_HTYPE_SVCCTX, + &envHandle, NULL, DPI_OCI_ATTR_ENV, "get env handle", + error) < 0) + return DPI_FAILURE; + dpiOci__handleFree(conn->env->handle, DPI_OCI_HTYPE_ENV); + error->handle = NULL; + conn->env->handle = NULL; + } + // initialize environment (for non-pooled connections) - if (!pool && dpiEnv__init(conn->env, context, commonParams, error) < 0) + if (!pool && dpiEnv__init(conn->env, context, commonParams, envHandle, + error) < 0) return DPI_FAILURE; // if a handle is specified, use it @@ -416,7 +431,7 @@ static int dpiConn__createStandalone(dpiConn *conn, const char *userName, // populate attributes on the session handle if (dpiConn__setAttributesFromCreateParams(conn, conn->sessionHandle, DPI_OCI_HTYPE_SESSION, userName, userNameLength, password, - passwordLength, createParams, NULL, NULL, error) < 0) + passwordLength, createParams, error) < 0) return DPI_FAILURE; // set the session handle on the service context handle @@ -505,11 +520,16 @@ static int dpiConn__get(dpiConn *conn, const char *userName, const char *connectString, uint32_t connectStringLength, dpiConnCreateParams *createParams, dpiPool *pool, dpiError *error) { - void *shardingKey = NULL, *superShardingKey = NULL; int externalAuth, status; void *authInfo; uint32_t mode; + // clear pointers if length is 0 + if (userNameLength == 0) + userName = NULL; + if (passwordLength == 0) + password = NULL; + // set things up for the call to acquire a session if (pool) { dpiGen__setRefCount(pool, error, 1); @@ -547,8 +567,7 @@ static int dpiConn__get(dpiConn *conn, const char *userName, // set attributes for create parameters if (dpiConn__setAttributesFromCreateParams(conn, authInfo, DPI_OCI_HTYPE_AUTHINFO, userName, userNameLength, password, - passwordLength, createParams, &shardingKey, &superShardingKey, - error) < 0) { + passwordLength, createParams, error) < 0) { dpiOci__handleFree(authInfo, DPI_OCI_HTYPE_AUTHINFO); return DPI_FAILURE; } @@ -556,13 +575,6 @@ static int dpiConn__get(dpiConn *conn, const char *userName, // get a session from the pool status = dpiConn__getSession(conn, mode, connectString, connectStringLength, createParams, authInfo, error); - if (status == DPI_SUCCESS && pool) { - if (shardingKey) - dpiOci__descriptorFree(shardingKey, DPI_OCI_DTYPE_SHARDING_KEY); - if (superShardingKey) - dpiOci__descriptorFree(superShardingKey, - DPI_OCI_DTYPE_SHARDING_KEY); - } dpiOci__handleFree(authInfo, DPI_OCI_HTYPE_AUTHINFO); if (status < 0) return status; @@ -630,6 +642,19 @@ static int dpiConn__getHandles(dpiConn *conn, dpiError *error) } +//----------------------------------------------------------------------------- +// dpiConn__getRawTDO() [INTERNAL] +// Internal method used for ensuring that the RAW TDO has been cached on the +//connection. +//----------------------------------------------------------------------------- +int dpiConn__getRawTDO(dpiConn *conn, dpiError *error) +{ + if (conn->rawTDO) + return DPI_SUCCESS; + return dpiOci__typeByName(conn, "SYS", 3, "RAW", 3, &conn->rawTDO, error); +} + + //----------------------------------------------------------------------------- // dpiConn__getServerCharset() [INTERNAL] // Internal method used for retrieving the server character set. This is used @@ -850,8 +875,7 @@ static int dpiConn__setAppContext(void *handle, uint32_t handleType, static int dpiConn__setAttributesFromCreateParams(dpiConn *conn, void *handle, uint32_t handleType, const char *userName, uint32_t userNameLength, const char *password, uint32_t passwordLength, - const dpiConnCreateParams *params, void **shardingKey, - void **superShardingKey, dpiError *error) + const dpiConnCreateParams *params, dpiError *error) { uint32_t purity; @@ -882,17 +906,20 @@ static int dpiConn__setAttributesFromCreateParams(dpiConn *conn, void *handle, // set sharding key and super sharding key parameters if (params->shardingKeyColumns && params->numShardingKeyColumns > 0) { - if (dpiConn__setShardingKey(conn, shardingKey, handle, handleType, - DPI_OCI_ATTR_SHARDING_KEY, "set sharding key", + if (dpiConn__setShardingKey(conn, &conn->shardingKey, handle, + handleType, DPI_OCI_ATTR_SHARDING_KEY, "set sharding key", params->shardingKeyColumns, params->numShardingKeyColumns, error) < 0) return DPI_FAILURE; } if (params->superShardingKeyColumns && params->numSuperShardingKeyColumns > 0) { - if (dpiConn__setShardingKey(conn, superShardingKey, handle, handleType, - DPI_OCI_ATTR_SUPER_SHARDING_KEY, "set super sharding key", - params->superShardingKeyColumns, + if (params->numShardingKeyColumns == 0) + return dpiError__set(error, "ensure sharding key", + DPI_ERR_MISSING_SHARDING_KEY); + if (dpiConn__setShardingKey(conn, &conn->superShardingKey, handle, + handleType, DPI_OCI_ATTR_SUPER_SHARDING_KEY, + "set super sharding key", params->superShardingKeyColumns, params->numSuperShardingKeyColumns, error) < 0) return DPI_FAILURE; } @@ -995,13 +1022,14 @@ static int dpiConn__setShardingKey(dpiConn *conn, void **shardingKey, static int dpiConn__setShardingKeyValue(dpiConn *conn, void *shardingKey, dpiShardingKeyColumn *column, dpiError *error) { + dpiShardingOciDate shardingDateValue; + uint32_t colLen = 0, descType = 0; const dpiOracleType *oracleType; dpiOciNumber numberValue; + int convertOk, status; dpiOciDate dateValue; - uint32_t colLen = 0; void *col = NULL; uint16_t colType; - int convertOk; oracleType = dpiOracleType__getFromNum(column->oracleTypeNum, error); if (!oracleType) @@ -1044,14 +1072,61 @@ static int dpiConn__setShardingKeyValue(dpiConn *conn, void *shardingKey, } break; case DPI_ORACLE_TYPE_DATE: - col = &dateValue; - colLen = sizeof(dateValue); - colType = DPI_SQLT_DAT; if (column->nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) { if (dpiDataBuffer__toOracleDate(&column->value, &dateValue) < 0) return DPI_FAILURE; convertOk = 1; + } else if (column->nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) { + if (dpiDataBuffer__toOracleDateFromDouble(&column->value, + conn->env, error, &dateValue) < 0) + return DPI_FAILURE; + convertOk = 1; + } + + // for sharding only, the type must be SQLT_DAT, which uses a + // different format for storing the date values + if (convertOk) { + col = &shardingDateValue; + colLen = sizeof(shardingDateValue); + colType = DPI_SQLT_DAT; + shardingDateValue.century = + ((uint8_t) (dateValue.year / 100)) + 100; + shardingDateValue.year = (dateValue.year % 100) + 100; + shardingDateValue.month = dateValue.month; + shardingDateValue.day = dateValue.day; + shardingDateValue.hour = dateValue.hour + 1; + shardingDateValue.minute = dateValue.minute + 1; + shardingDateValue.second = dateValue.second + 1; + } + break; + case DPI_ORACLE_TYPE_TIMESTAMP: + case DPI_ORACLE_TYPE_TIMESTAMP_TZ: + case DPI_ORACLE_TYPE_TIMESTAMP_LTZ: + colLen = sizeof(void*); + colType = DPI_SQLT_TIMESTAMP; + if (column->nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) { + descType = DPI_OCI_DTYPE_TIMESTAMP; + if (dpiOci__descriptorAlloc(conn->env->handle, &col, descType, + "alloc timestamp", error) < 0) + return DPI_FAILURE; + if (dpiDataBuffer__toOracleTimestamp(&column->value, conn->env, + error, col, 0) < 0) { + dpiOci__descriptorFree(col, descType); + return DPI_FAILURE; + } + convertOk = 1; + } else if (column->nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) { + descType = DPI_OCI_DTYPE_TIMESTAMP_LTZ; + if (dpiOci__descriptorAlloc(conn->env->handle, &col, descType, + "alloc LTZ timestamp", error) < 0) + return DPI_FAILURE; + if (dpiDataBuffer__toOracleTimestampFromDouble(&column->value, + conn->env, error, col) < 0) { + dpiOci__descriptorFree(col, descType); + return DPI_FAILURE; + } + convertOk = 1; } break; default: @@ -1060,8 +1135,11 @@ static int dpiConn__setShardingKeyValue(dpiConn *conn, void *shardingKey, if (!convertOk) return dpiError__set(error, "check type", DPI_ERR_NOT_SUPPORTED); - return dpiOci__shardingKeyColumnAdd(shardingKey, col, colLen, colType, + status = dpiOci__shardingKeyColumnAdd(shardingKey, col, colLen, colType, error); + if (descType) + dpiOci__descriptorFree(col, descType); + return status; } @@ -1282,7 +1360,7 @@ int dpiConn_create(const dpiContext *context, const char *userName, int status; // validate parameters - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, conn) @@ -1347,8 +1425,6 @@ int dpiConn_create(const dpiContext *context, const char *userName, dpiError__set(&error, "check pool", DPI_ERR_NOT_CONNECTED); return dpiGen__endPublicFn(context, DPI_FAILURE, &error); } - if (dpiEnv__initError(createParams->pool->env, &error) < 0) - return dpiGen__endPublicFn(context, DPI_FAILURE, &error); status = dpiPool__acquireConnection(createParams->pool, userName, userNameLength, password, passwordLength, createParams, conn, &error); @@ -1366,8 +1442,7 @@ int dpiConn_create(const dpiContext *context, const char *userName, } *conn = tempConn; - dpiHandlePool__release(tempConn->env->errorHandles, error.handle, &error); - error.handle = NULL; + dpiHandlePool__release(tempConn->env->errorHandles, &error.handle); return dpiGen__endPublicFn(context, DPI_SUCCESS, &error); } @@ -1404,7 +1479,6 @@ int dpiConn_deqObject(dpiConn *conn, const char *queueName, uint32_t queueNameLength, dpiDeqOptions *options, dpiMsgProps *props, dpiObject *payload, const char **msgId, uint32_t *msgIdLength) { - void *ociMsgId = NULL; dpiError error; // validate parameters @@ -1426,19 +1500,15 @@ int dpiConn_deqObject(dpiConn *conn, const char *queueName, // dequeue message if (dpiOci__aqDeq(conn, queueName, options->handle, props->handle, payload->type->tdo, &payload->instance, &payload->indicator, - &ociMsgId, &error) < 0) { + &props->msgIdRaw, &error) < 0) { if (error.buffer->code == 25228) { - if (ociMsgId) - dpiOci__rawResize(conn->env->handle, &ociMsgId, 0, &error); *msgId = NULL; *msgIdLength = 0; return dpiGen__endPublicFn(conn, DPI_SUCCESS, &error); } return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); } - if (dpiMsgProps__extractMsgId(props, ociMsgId, msgId, msgIdLength, - &error) < 0) - return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); + dpiMsgProps__extractMsgId(props, msgId, msgIdLength); return dpiGen__endPublicFn(conn, DPI_SUCCESS, &error); } @@ -1451,7 +1521,6 @@ int dpiConn_enqObject(dpiConn *conn, const char *queueName, uint32_t queueNameLength, dpiEnqOptions *options, dpiMsgProps *props, dpiObject *payload, const char **msgId, uint32_t *msgIdLength) { - void *ociMsgId = NULL; dpiError error; // validate parameters @@ -1473,11 +1542,9 @@ int dpiConn_enqObject(dpiConn *conn, const char *queueName, // enqueue message if (dpiOci__aqEnq(conn, queueName, options->handle, props->handle, payload->type->tdo, &payload->instance, &payload->indicator, - &ociMsgId, &error) < 0) - return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); - if (dpiMsgProps__extractMsgId(props, ociMsgId, msgId, msgIdLength, - &error) < 0) + &props->msgIdRaw, &error) < 0) return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); + dpiMsgProps__extractMsgId(props, msgId, msgIdLength); return dpiGen__endPublicFn(conn, DPI_SUCCESS, &error); } @@ -1682,15 +1749,15 @@ int dpiConn_getServerVersion(dpiConn *conn, const char **releaseString, // validate parameters if (dpiConn__check(conn, __func__, &error) < 0) return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); - DPI_CHECK_PTR_NOT_NULL(conn, releaseString) - DPI_CHECK_PTR_NOT_NULL(conn, releaseStringLength) DPI_CHECK_PTR_NOT_NULL(conn, versionInfo) // get server version if (dpiConn__getServerVersion(conn, &error) < 0) return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); - *releaseString = conn->releaseString; - *releaseStringLength = conn->releaseStringLength; + if (releaseString) + *releaseString = conn->releaseString; + if (releaseStringLength) + *releaseStringLength = conn->releaseStringLength; memcpy(versionInfo, &conn->versionInfo, sizeof(dpiVersionInfo)); return dpiGen__endPublicFn(conn, DPI_SUCCESS, &error); } @@ -1806,22 +1873,34 @@ int dpiConn_newTempLob(dpiConn *conn, dpiOracleTypeNum lobType, dpiLob **lob) //----------------------------------------------------------------------------- int dpiConn_newMsgProps(dpiConn *conn, dpiMsgProps **props) { - dpiMsgProps *tempProps; dpiError error; + int status; if (dpiConn__check(conn, __func__, &error) < 0) return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(conn, props) - if (dpiGen__allocate(DPI_HTYPE_MSG_PROPS, conn->env, (void**) &tempProps, - &error) < 0) - return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); - if (dpiMsgProps__create(tempProps, conn, &error) < 0) { - dpiMsgProps__free(tempProps, &error); - return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); - } + status = dpiMsgProps__allocate(conn, props, &error); + return dpiGen__endPublicFn(conn, status, &error); +} - *props = tempProps; - return dpiGen__endPublicFn(conn, DPI_SUCCESS, &error); + +//----------------------------------------------------------------------------- +// dpiConn_newQueue() [PUBLIC] +// Create a new AQ queue object and return it. +//----------------------------------------------------------------------------- +int dpiConn_newQueue(dpiConn *conn, const char *name, uint32_t nameLength, + dpiObjectType *payloadType, dpiQueue **queue) +{ + dpiError error; + int status; + + if (dpiConn__check(conn, __func__, &error) < 0) + return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); + DPI_CHECK_PTR_AND_LENGTH(conn, name) + DPI_CHECK_PTR_NOT_NULL(conn, queue) + status = dpiQueue__allocate(conn, name, nameLength, payloadType, queue, + &error); + return dpiGen__endPublicFn(conn, status, &error); } @@ -2148,6 +2227,7 @@ int dpiConn_subscribe(dpiConn *conn, dpiSubscrCreateParams *params, int dpiConn_unsubscribe(dpiConn *conn, dpiSubscr *subscr) { dpiError error; + int status; if (dpiConn__check(conn, __func__, &error) < 0) return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); @@ -2155,12 +2235,15 @@ int dpiConn_unsubscribe(dpiConn *conn, dpiSubscr *subscr) &error) < 0) return dpiGen__endPublicFn(conn, DPI_FAILURE, &error); if (subscr->registered) { - if (dpiOci__subscriptionUnRegister(conn, subscr, &error) < 0) + dpiMutex__acquire(subscr->mutex); + status = dpiOci__subscriptionUnRegister(conn, subscr, &error); + if (status == DPI_SUCCESS) + subscr->registered = 0; + dpiMutex__release(subscr->mutex); + if (status < 0) return dpiGen__endPublicFn(subscr, DPI_FAILURE, &error); - subscr->registered = 0; } dpiGen__setRefCount(subscr, &error, -1); return dpiGen__endPublicFn(subscr, DPI_SUCCESS, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiContext.c b/vendor/github.com/godror/godror/odpi/src/dpiContext.c similarity index 92% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiContext.c rename to vendor/github.com/godror/godror/odpi/src/dpiContext.c index 315afe32ea9..e9adb18a33e 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiContext.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiContext.c @@ -156,7 +156,7 @@ int dpiContext_destroy(dpiContext *context) char message[80]; dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); dpiUtils__clearMemory(&context->checkInt, sizeof(context->checkInt)); @@ -181,7 +181,7 @@ int dpiContext_getClientVersion(const dpiContext *context, { dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, versionInfo) @@ -214,7 +214,7 @@ int dpiContext_initCommonCreateParams(const dpiContext *context, { dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, params) @@ -233,7 +233,7 @@ int dpiContext_initConnCreateParams(const dpiContext *context, dpiConnCreateParams localParams; dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, params) @@ -259,17 +259,22 @@ int dpiContext_initPoolCreateParams(const dpiContext *context, dpiPoolCreateParams localParams; dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, params) - // size changed in version 3.1; can be dropped once version 4 released - if (context->dpiMinorVersion > 0) + // size changed in versions 3.1 and 3.3 + // changes can be dropped once version 4 released + if (context->dpiMinorVersion > 2) { dpiContext__initPoolCreateParams(params); - else { + } else { dpiContext__initPoolCreateParams(&localParams); - memcpy(params, &localParams, sizeof(dpiPoolCreateParams__v30)); + if (context->dpiMinorVersion > 0) { + memcpy(params, &localParams, sizeof(dpiPoolCreateParams__v32)); + } else { + memcpy(params, &localParams, sizeof(dpiPoolCreateParams__v30)); + } } return dpiGen__endPublicFn(context, DPI_SUCCESS, &error); } @@ -284,7 +289,7 @@ int dpiContext_initSodaOperOptions(const dpiContext *context, { dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, options) @@ -300,13 +305,25 @@ int dpiContext_initSodaOperOptions(const dpiContext *context, int dpiContext_initSubscrCreateParams(const dpiContext *context, dpiSubscrCreateParams *params) { + dpiSubscrCreateParams localParams; dpiError error; - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(context, params) - dpiContext__initSubscrCreateParams(params); + + // size changed in versions 3.2 and 3.3 + // changes can be dropped once version 4 released + if (context->dpiMinorVersion > 2) { + dpiContext__initSubscrCreateParams(params); + } else { + dpiContext__initSubscrCreateParams(&localParams); + if (context->dpiMinorVersion > 1) { + memcpy(params, &localParams, sizeof(dpiSubscrCreateParams__v32)); + } else { + memcpy(params, &localParams, sizeof(dpiSubscrCreateParams__v30)); + } + } return dpiGen__endPublicFn(context, DPI_SUCCESS, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiData.c b/vendor/github.com/godror/godror/odpi/src/dpiData.c similarity index 89% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiData.c rename to vendor/github.com/godror/godror/odpi/src/dpiData.c index dc669f4bc7f..57d3faac309 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiData.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiData.c @@ -46,6 +46,36 @@ int dpiDataBuffer__fromOracleDate(dpiDataBuffer *data, } +//----------------------------------------------------------------------------- +// dpiDataBuffer__fromOracleDateAsDouble() [INTERNAL] +// Populate the data from an dpiOciDate structure as a double value (number +// of milliseconds since January 1, 1970). +//----------------------------------------------------------------------------- +int dpiDataBuffer__fromOracleDateAsDouble(dpiDataBuffer *data, + dpiEnv *env, dpiError *error, dpiOciDate *oracleValue) +{ + void *timestamp; + int status; + + // allocate and populate a timestamp with the value of the date + if (dpiOci__descriptorAlloc(env->handle, ×tamp, + DPI_OCI_DTYPE_TIMESTAMP_LTZ, "alloc timestamp", error) < 0) + return DPI_FAILURE; + if (dpiOci__dateTimeConstruct(env->handle, timestamp, oracleValue->year, + oracleValue->month, oracleValue->day, oracleValue->hour, + oracleValue->minute, oracleValue->second, 0, NULL, 0, error) < 0) { + dpiOci__descriptorFree(timestamp, DPI_OCI_DTYPE_TIMESTAMP_LTZ); + return DPI_FAILURE; + } + + // now calculate the number of milliseconds since January 1, 1970 + status = dpiDataBuffer__fromOracleTimestampAsDouble(data, env, error, + timestamp); + dpiOci__descriptorFree(timestamp, DPI_OCI_DTYPE_TIMESTAMP_LTZ); + return status; +} + + //----------------------------------------------------------------------------- // dpiDataBuffer__fromOracleIntervalDS() [INTERNAL] // Populate the data from an OCIInterval structure (days/seconds). @@ -305,6 +335,58 @@ int dpiDataBuffer__toOracleDate(dpiDataBuffer *data, dpiOciDate *oracleValue) } +//----------------------------------------------------------------------------- +// dpiDataBuffer__toOracleDateFromDouble() [INTERNAL] +// Populate the data in an dpiOciDate structure given a double (number of +// milliseconds since January 1, 1970). +//----------------------------------------------------------------------------- +int dpiDataBuffer__toOracleDateFromDouble(dpiDataBuffer *data, dpiEnv *env, + dpiError *error, dpiOciDate *oracleValue) +{ + void *timestamp, *timestampLTZ; + uint32_t fsecond; + + // allocate a descriptor to acquire a timestamp + if (dpiOci__descriptorAlloc(env->handle, ×tampLTZ, + DPI_OCI_DTYPE_TIMESTAMP_LTZ, "alloc timestamp", error) < 0) + return DPI_FAILURE; + if (dpiDataBuffer__toOracleTimestampFromDouble(data, env, error, + timestampLTZ) < 0) { + dpiOci__descriptorFree(timestampLTZ, DPI_OCI_DTYPE_TIMESTAMP_LTZ); + return DPI_FAILURE; + } + + // allocate a plain timestamp and convert to it + if (dpiOci__descriptorAlloc(env->handle, ×tamp, + DPI_OCI_DTYPE_TIMESTAMP, "alloc plain timestamp", error) < 0) { + dpiOci__descriptorFree(timestampLTZ, DPI_OCI_DTYPE_TIMESTAMP_LTZ); + return DPI_FAILURE; + } + if (dpiOci__dateTimeConvert(env->handle, timestampLTZ, timestamp, + error) < 0) { + dpiOci__descriptorFree(timestamp, DPI_OCI_DTYPE_TIMESTAMP); + dpiOci__descriptorFree(timestampLTZ, DPI_OCI_DTYPE_TIMESTAMP_LTZ); + return DPI_FAILURE; + } + dpiOci__descriptorFree(timestampLTZ, DPI_OCI_DTYPE_TIMESTAMP_LTZ); + + // populate date structure + if (dpiOci__dateTimeGetDate(env->handle, timestamp, &oracleValue->year, + &oracleValue->month, &oracleValue->day, error) < 0) { + dpiOci__descriptorFree(timestamp, DPI_OCI_DTYPE_TIMESTAMP); + return DPI_FAILURE; + } + if (dpiOci__dateTimeGetTime(env->handle, timestamp, &oracleValue->hour, + &oracleValue->minute, &oracleValue->second, &fsecond, error) < 0) { + dpiOci__descriptorFree(timestamp, DPI_OCI_DTYPE_TIMESTAMP); + return DPI_FAILURE; + } + + dpiOci__descriptorFree(timestamp, DPI_OCI_DTYPE_TIMESTAMP); + return DPI_SUCCESS; +} + + //----------------------------------------------------------------------------- // dpiDataBuffer__toOracleIntervalDS() [INTERNAL] // Populate the data in an OCIInterval structure (days/seconds). @@ -815,4 +897,3 @@ void dpiData_setUint64(dpiData *data, uint64_t value) data->isNull = 0; data->value.asUint64 = value; } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiDebug.c b/vendor/github.com/godror/godror/odpi/src/dpiDebug.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiDebug.c rename to vendor/github.com/godror/godror/odpi/src/dpiDebug.c index 6188d7d84a7..28b8776475f 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiDebug.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiDebug.c @@ -181,4 +181,3 @@ void dpiDebug__print(const char *format, ...) (void) vfprintf(dpiDebugStream, formatWithPrefix, varArgs); va_end(varArgs); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiDeqOptions.c b/vendor/github.com/godror/godror/odpi/src/dpiDeqOptions.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiDeqOptions.c rename to vendor/github.com/godror/godror/odpi/src/dpiDeqOptions.c index 309eb05e5a6..35cb84727ae 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiDeqOptions.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiDeqOptions.c @@ -60,7 +60,7 @@ static int dpiDeqOptions__getAttrValue(dpiDeqOptions *options, dpiError error; int status; - if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, fnName, 1, + if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, fnName, &error) < 0) return dpiGen__endPublicFn(options, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(options, value) @@ -82,7 +82,7 @@ static int dpiDeqOptions__setAttrValue(dpiDeqOptions *options, dpiError error; int status; - if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, fnName, 1, + if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, fnName, &error) < 0) return dpiGen__endPublicFn(options, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(options, value) @@ -162,7 +162,7 @@ int dpiDeqOptions_getMsgId(dpiDeqOptions *options, const char **value, dpiError error; void *rawValue; - if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, __func__, 1, + if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, __func__, &error) < 0) return dpiGen__endPublicFn(options, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(options, value) @@ -309,7 +309,7 @@ int dpiDeqOptions_setMsgId(dpiDeqOptions *options, const char *value, dpiError error; int status; - if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, __func__, 1, + if (dpiGen__startPublicFn(options, DPI_HTYPE_DEQ_OPTIONS, __func__, &error) < 0) return dpiGen__endPublicFn(options, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(options, value) @@ -367,4 +367,3 @@ int dpiDeqOptions_setWait(dpiDeqOptions *options, uint32_t value) return dpiDeqOptions__setAttrValue(options, DPI_OCI_ATTR_WAIT, __func__, &value, 0); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiEnqOptions.c b/vendor/github.com/godror/godror/odpi/src/dpiEnqOptions.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiEnqOptions.c rename to vendor/github.com/godror/godror/odpi/src/dpiEnqOptions.c index 8b073188c33..24bf60a3229 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiEnqOptions.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiEnqOptions.c @@ -60,7 +60,7 @@ static int dpiEnqOptions__getAttrValue(dpiEnqOptions *options, dpiError error; int status; - if (dpiGen__startPublicFn(options, DPI_HTYPE_ENQ_OPTIONS, fnName, 1, + if (dpiGen__startPublicFn(options, DPI_HTYPE_ENQ_OPTIONS, fnName, &error) < 0) return dpiGen__endPublicFn(options, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(options, value) @@ -82,7 +82,7 @@ static int dpiEnqOptions__setAttrValue(dpiEnqOptions *options, dpiError error; int status; - if (dpiGen__startPublicFn(options, DPI_HTYPE_ENQ_OPTIONS, fnName, 1, + if (dpiGen__startPublicFn(options, DPI_HTYPE_ENQ_OPTIONS, fnName, &error) < 0) return dpiGen__endPublicFn(options, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(options, value) @@ -171,4 +171,3 @@ int dpiEnqOptions_setVisibility(dpiEnqOptions *options, dpiVisibility value) return dpiEnqOptions__setAttrValue(options, DPI_OCI_ATTR_VISIBILITY, __func__, &value, 0); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiEnv.c b/vendor/github.com/godror/godror/odpi/src/dpiEnv.c similarity index 68% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiEnv.c rename to vendor/github.com/godror/godror/odpi/src/dpiEnv.c index e7dff7730a2..c1a2c3f7d61 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiEnv.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiEnv.c @@ -24,7 +24,7 @@ void dpiEnv__free(dpiEnv *env, dpiError *error) { if (env->threaded) dpiMutex__destroy(env->mutex); - if (env->handle) { + if (env->handle && !env->externalHandle) { dpiOci__handleFree(env->handle, DPI_OCI_HTYPE_ENV); env->handle = NULL; } @@ -67,52 +67,68 @@ int dpiEnv__getEncodingInfo(dpiEnv *env, dpiEncodingInfo *info) //----------------------------------------------------------------------------- // dpiEnv__init() [INTERNAL] -// Initialize the environment structure by creating the OCI environment and -// populating information about the environment. +// Initialize the environment structure. If an external handle is provided it +// is used directly; otherwise, a new OCI environment handle is created. In +// either case, information about the environment is stored for later use. //----------------------------------------------------------------------------- int dpiEnv__init(dpiEnv *env, const dpiContext *context, - const dpiCommonCreateParams *params, dpiError *error) + const dpiCommonCreateParams *params, void *externalHandle, + dpiError *error) { char timezoneBuffer[20]; size_t timezoneLength; - // lookup encoding - if (params->encoding && dpiGlobal__lookupCharSet(params->encoding, - &env->charsetId, error) < 0) - return DPI_FAILURE; + // store context and version information + env->context = context; + env->versionInfo = context->versionInfo; - // check for identical encoding before performing lookup - if (params->nencoding && params->encoding && - strcmp(params->nencoding, params->encoding) == 0) - env->ncharsetId = env->charsetId; - else if (params->nencoding && dpiGlobal__lookupCharSet(params->nencoding, - &env->ncharsetId, error) < 0) - return DPI_FAILURE; + // an external handle is available, use it directly + if (externalHandle) { + env->handle = externalHandle; + env->externalHandle = 1; - // both charsetId and ncharsetId must be zero or both must be non-zero - // use NLS routine to look up missing value, if needed - if (env->charsetId && !env->ncharsetId) { - if (dpiOci__nlsEnvironmentVariableGet(DPI_OCI_NLS_NCHARSET_ID, - &env->ncharsetId, error) < 0) - return DPI_FAILURE; - } else if (!env->charsetId && env->ncharsetId) { - if (dpiOci__nlsEnvironmentVariableGet(DPI_OCI_NLS_CHARSET_ID, + // otherwise, lookup encodings + } else { + + // lookup encoding + if (params->encoding && dpiGlobal__lookupCharSet(params->encoding, &env->charsetId, error) < 0) return DPI_FAILURE; - } - // create the new environment handle - env->context = context; - env->versionInfo = context->versionInfo; - if (dpiOci__envNlsCreate(&env->handle, params->createMode | DPI_OCI_OBJECT, - env->charsetId, env->ncharsetId, error) < 0) - return DPI_FAILURE; + // check for identical encoding before performing lookup of national + // character set encoding + if (params->nencoding && params->encoding && + strcmp(params->nencoding, params->encoding) == 0) + env->ncharsetId = env->charsetId; + else if (params->nencoding && + dpiGlobal__lookupCharSet(params->nencoding, + &env->ncharsetId, error) < 0) + return DPI_FAILURE; + + // both charsetId and ncharsetId must be zero or both must be non-zero + // use NLS routine to look up missing value, if needed + if (env->charsetId && !env->ncharsetId) { + if (dpiOci__nlsEnvironmentVariableGet(DPI_OCI_NLS_NCHARSET_ID, + &env->ncharsetId, error) < 0) + return DPI_FAILURE; + } else if (!env->charsetId && env->ncharsetId) { + if (dpiOci__nlsEnvironmentVariableGet(DPI_OCI_NLS_CHARSET_ID, + &env->charsetId, error) < 0) + return DPI_FAILURE; + } + + // create new environment handle + if (dpiOci__envNlsCreate(&env->handle, + params->createMode | DPI_OCI_OBJECT, + env->charsetId, env->ncharsetId, error) < 0) + return DPI_FAILURE; + + } - // create the error handle pool and acquire the first error handle + // create the error handle pool if (dpiHandlePool__create(&env->errorHandles, error) < 0) return DPI_FAILURE; - if (dpiEnv__initError(env, error) < 0) - return DPI_FAILURE; + error->env = env; // if threaded, create mutex for reference counts if (params->createMode & DPI_OCI_THREADED) @@ -162,28 +178,3 @@ int dpiEnv__init(dpiEnv *env, const dpiContext *context, return DPI_SUCCESS; } - - -//----------------------------------------------------------------------------- -// dpiEnv__initError() [INTERNAL] -// Retrieve the OCI error handle to use for error handling, from a pool of -// error handles common to the environment handle. The environment that was -// used to create the error handle is stored in the error structure so that -// the encoding and character set can be retrieved in the event of an OCI -// error (which uses the CHAR encoding of the environment). -//----------------------------------------------------------------------------- -int dpiEnv__initError(dpiEnv *env, dpiError *error) -{ - error->env = env; - if (dpiHandlePool__acquire(env->errorHandles, &error->handle, error) < 0) - return DPI_FAILURE; - - if (!error->handle) { - if (dpiOci__handleAlloc(env->handle, &error->handle, - DPI_OCI_HTYPE_ERROR, "allocate OCI error", error) < 0) - return DPI_FAILURE; - } - - return DPI_SUCCESS; -} - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiError.c b/vendor/github.com/godror/godror/odpi/src/dpiError.c similarity index 85% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiError.c rename to vendor/github.com/godror/godror/odpi/src/dpiError.c index c76070562cb..aac57b92f18 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiError.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiError.c @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. // This program is free software: you can modify it and/or redistribute it // under the terms of: // @@ -18,21 +18,125 @@ #include "dpiErrorMessages.h" //----------------------------------------------------------------------------- -// dpiError__check() [INTERNAL] -// Checks to see if the status of the last call resulted in an error -// condition. If so, the error is populated. Note that trailing newlines and -// spaces are truncated from the message if they exist. If the connection is -// not NULL a check is made to see if the connection is no longer viable. +// dpiError__getInfo() [INTERNAL] +// Get the error state from the error structure. Returns DPI_FAILURE as a +// convenience to the caller. +//----------------------------------------------------------------------------- +int dpiError__getInfo(dpiError *error, dpiErrorInfo *info) +{ + if (!info) + return DPI_FAILURE; + info->code = error->buffer->code; + info->offset = error->buffer->offset; + info->message = error->buffer->message; + info->messageLength = error->buffer->messageLength; + info->fnName = error->buffer->fnName; + info->action = error->buffer->action; + info->isRecoverable = error->buffer->isRecoverable; + info->encoding = error->buffer->encoding; + switch(info->code) { + case 12154: // TNS:could not resolve the connect identifier specified + info->sqlState = "42S02"; + break; + case 22: // invalid session ID; access denied + case 378: // buffer pools cannot be created as specified + case 602: // Internal programming exception + case 603: // ORACLE server session terminated by fatal error + case 604: // error occurred at recursive SQL level + case 609: // could not attach to incoming connection + case 1012: // not logged on + case 1033: // ORACLE initialization or shutdown in progress + case 1041: // internal error. hostdef extension doesn't exist + case 1043: // user side memory corruption + case 1089: // immediate shutdown or close in progress + case 1090: // shutdown in progress + case 1092: // ORACLE instance terminated. Disconnection forced + case 3113: // end-of-file on communication channel + case 3114: // not connected to ORACLE + case 3122: // attempt to close ORACLE-side window on user side + case 3135: // connection lost contact + case 12153: // TNS:not connected + case 27146: // post/wait initialization failed + case 28511: // lost RPC connection to heterogeneous remote agent + info->sqlState = "01002"; + break; + default: + if (error->buffer->code == 0 && + error->buffer->errorNum == (dpiErrorNum) 0) + info->sqlState = "00000"; + else info->sqlState = "HY000"; + break; + } + return DPI_FAILURE; +} + + +//----------------------------------------------------------------------------- +// dpiError__initHandle() [INTERNAL] +// Retrieve the OCI error handle to use for error handling, from a pool of +// error handles common to the environment handle stored on the error. This +// environment also controls the encoding of OCI errors (which uses the CHAR +// encoding of the environment). +//----------------------------------------------------------------------------- +int dpiError__initHandle(dpiError *error) +{ + if (dpiHandlePool__acquire(error->env->errorHandles, &error->handle, + error) < 0) + return DPI_FAILURE; + if (!error->handle) { + if (dpiOci__handleAlloc(error->env->handle, &error->handle, + DPI_OCI_HTYPE_ERROR, "allocate OCI error", error) < 0) + return DPI_FAILURE; + } + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiError__set() [INTERNAL] +// Set the error buffer to the specified DPI error. Returns DPI_FAILURE as a +// convenience to the caller. +//----------------------------------------------------------------------------- +int dpiError__set(dpiError *error, const char *action, dpiErrorNum errorNum, + ...) +{ + va_list varArgs; + + if (error) { + error->buffer->code = 0; + error->buffer->isRecoverable = 0; + error->buffer->offset = 0; + strcpy(error->buffer->encoding, DPI_CHARSET_NAME_UTF8); + error->buffer->action = action; + error->buffer->errorNum = errorNum; + va_start(varArgs, errorNum); + error->buffer->messageLength = + (uint32_t) vsnprintf(error->buffer->message, + sizeof(error->buffer->message), + dpiErrorMessages[errorNum - DPI_ERR_NO_ERR], varArgs); + va_end(varArgs); + if (dpiDebugLevel & DPI_DEBUG_LEVEL_ERRORS) + dpiDebug__print("internal error %.*s (%s / %s)\n", + error->buffer->messageLength, error->buffer->message, + error->buffer->fnName, action); + } + return DPI_FAILURE; +} + + +//----------------------------------------------------------------------------- +// dpiError__setFromOCI() [INTERNAL] +// Called when an OCI error has occurred and sets the error structure with +// the contents of that error. Note that trailing newlines and spaces are +// truncated from the message if they exist. If the connection is not NULL a +// check is made to see if the connection is no longer viable. The value +// DPI_FAILURE is returned as a convenience to the caller. //----------------------------------------------------------------------------- -int dpiError__check(dpiError *error, int status, dpiConn *conn, +int dpiError__setFromOCI(dpiError *error, int status, dpiConn *conn, const char *action) { uint32_t callTimeout; - // no error has taken place - if (status == DPI_OCI_SUCCESS || status == DPI_OCI_SUCCESS_WITH_INFO) - return DPI_SUCCESS; - // special error cases if (status == DPI_OCI_INVALID_HANDLE) return dpiError__set(error, action, DPI_ERR_INVALID_HANDLE, "OCI"); @@ -98,6 +202,7 @@ int dpiError__check(dpiError *error, int status, dpiConn *conn, conn->deadSession = 1; break; case 3136: // inbound connection timed out + case 3156: // OCI call timed out case 12161: // TNS:internal error: partial data received callTimeout = 0; if (conn->env->versionInfo->versionNum >= 18) @@ -115,90 +220,3 @@ int dpiError__check(dpiError *error, int status, dpiConn *conn, return DPI_FAILURE; } - - -//----------------------------------------------------------------------------- -// dpiError__getInfo() [INTERNAL] -// Get the error state from the error structure. Returns DPI_FAILURE as a -// convenience to the caller. -//----------------------------------------------------------------------------- -int dpiError__getInfo(dpiError *error, dpiErrorInfo *info) -{ - if (!info) - return DPI_FAILURE; - info->code = error->buffer->code; - info->offset = error->buffer->offset; - info->message = error->buffer->message; - info->messageLength = error->buffer->messageLength; - info->fnName = error->buffer->fnName; - info->action = error->buffer->action; - info->isRecoverable = error->buffer->isRecoverable; - info->encoding = error->buffer->encoding; - switch(info->code) { - case 12154: // TNS:could not resolve the connect identifier specified - info->sqlState = "42S02"; - break; - case 22: // invalid session ID; access denied - case 378: // buffer pools cannot be created as specified - case 602: // Internal programming exception - case 603: // ORACLE server session terminated by fatal error - case 604: // error occurred at recursive SQL level - case 609: // could not attach to incoming connection - case 1012: // not logged on - case 1033: // ORACLE initialization or shutdown in progress - case 1041: // internal error. hostdef extension doesn't exist - case 1043: // user side memory corruption - case 1089: // immediate shutdown or close in progress - case 1090: // shutdown in progress - case 1092: // ORACLE instance terminated. Disconnection forced - case 3113: // end-of-file on communication channel - case 3114: // not connected to ORACLE - case 3122: // attempt to close ORACLE-side window on user side - case 3135: // connection lost contact - case 12153: // TNS:not connected - case 27146: // post/wait initialization failed - case 28511: // lost RPC connection to heterogeneous remote agent - info->sqlState = "01002"; - break; - default: - if (error->buffer->code == 0 && - error->buffer->errorNum == (dpiErrorNum) 0) - info->sqlState = "00000"; - else info->sqlState = "HY000"; - break; - } - return DPI_FAILURE; -} - - -//----------------------------------------------------------------------------- -// dpiError__set() [INTERNAL] -// Set the error buffer to the specified DPI error. Returns DPI_FAILURE as a -// convenience to the caller. -//----------------------------------------------------------------------------- -int dpiError__set(dpiError *error, const char *action, dpiErrorNum errorNum, - ...) -{ - va_list varArgs; - - if (error) { - error->buffer->code = 0; - error->buffer->isRecoverable = 0; - error->buffer->offset = 0; - strcpy(error->buffer->encoding, DPI_CHARSET_NAME_UTF8); - error->buffer->action = action; - error->buffer->errorNum = errorNum; - va_start(varArgs, errorNum); - error->buffer->messageLength = - (uint32_t) vsnprintf(error->buffer->message, - sizeof(error->buffer->message), - dpiErrorMessages[errorNum - DPI_ERR_NO_ERR], varArgs); - va_end(varArgs); - if (dpiDebugLevel & DPI_DEBUG_LEVEL_ERRORS) - dpiDebug__print("internal error %.*s (%s / %s)\n", - error->buffer->messageLength, error->buffer->message, - error->buffer->fnName, action); - } - return DPI_FAILURE; -} - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiErrorMessages.h b/vendor/github.com/godror/godror/odpi/src/dpiErrorMessages.h similarity index 94% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiErrorMessages.h rename to vendor/github.com/godror/godror/odpi/src/dpiErrorMessages.h index fd87de21279..1de52a2b17b 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiErrorMessages.h +++ b/vendor/github.com/godror/godror/odpi/src/dpiErrorMessages.h @@ -83,5 +83,8 @@ static const char* const dpiErrorMessages[DPI_ERR_MAX - DPI_ERR_NO_ERR] = { "DPI-1067: call timeout of %u ms exceeded with ORA-%d", // DPI_ERR_CALL_TIMEOUT "DPI-1068: SODA cursor was already closed", // DPI_ERR_SODA_CURSOR_CLOSED "DPI-1069: proxy user name must be enclosed in [] when using external authentication", // DPI_ERR_EXT_AUTH_INVALID_PROXY + "DPI-1070: no payload provided in message properties", // DPI_ERR_QUEUE_NO_PAYLOAD + "DPI-1071: payload type in message properties must match the payload type of the queue", // DPI_ERR_QUEUE_WRONG_PAYLOAD_TYPE + "DPI-1072: the Oracle Client library version is unsupported", // DPI_ERR_ORACLE_CLIENT_UNSUPPORTED + "DPI-1073: sharding key is required when specifying a super sharding key", // DPI_ERR_MISSING_SHARDING_KEY }; - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiGen.c b/vendor/github.com/godror/godror/odpi/src/dpiGen.c similarity index 95% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiGen.c rename to vendor/github.com/godror/godror/odpi/src/dpiGen.c index e6b65b9a65b..f671adf2a21 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiGen.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiGen.c @@ -133,6 +133,12 @@ static const dpiTypeDef dpiAllTypeDefs[DPI_HTYPE_MAX - DPI_HTYPE_NONE - 1] = { sizeof(dpiSodaDocCursor), // size of structure 0x80ceb83b, // check integer (dpiTypeFreeProc) dpiSodaDocCursor__free + }, + { + "dpiQueue", // name + sizeof(dpiQueue), // size of structure + 0x54904ba2, // check integer + (dpiTypeFreeProc) dpiQueue__free } }; @@ -145,7 +151,7 @@ int dpiGen__addRef(void *ptr, dpiHandleTypeNum typeNum, const char *fnName) { dpiError error; - if (dpiGen__startPublicFn(ptr, typeNum, fnName, 0, &error) < 0) + if (dpiGen__startPublicFn(ptr, typeNum, fnName, &error) < 0) return dpiGen__endPublicFn(ptr, DPI_FAILURE, &error); dpiGen__setRefCount(ptr, &error, 1); return dpiGen__endPublicFn(ptr, DPI_SUCCESS, &error); @@ -218,7 +224,7 @@ int dpiGen__endPublicFn(const void *ptr, int returnValue, dpiError *error) dpiDebug__print("fn end %s(%p) -> %d\n", error->buffer->fnName, ptr, returnValue); if (error->handle) - dpiHandlePool__release(error->env->errorHandles, error->handle, error); + dpiHandlePool__release(error->env->errorHandles, &error->handle); return returnValue; } @@ -235,7 +241,7 @@ int dpiGen__release(void *ptr, dpiHandleTypeNum typeNum, const char *fnName) { dpiError error; - if (dpiGen__startPublicFn(ptr, typeNum, fnName, 1, &error) < 0) + if (dpiGen__startPublicFn(ptr, typeNum, fnName, &error) < 0) return dpiGen__endPublicFn(ptr, DPI_FAILURE, &error); dpiGen__setRefCount(ptr, &error, -1); return dpiGen__endPublicFn(ptr, DPI_SUCCESS, &error); @@ -286,7 +292,7 @@ void dpiGen__setRefCount(void *ptr, dpiError *error, int increment) // all subsequent calls. //----------------------------------------------------------------------------- int dpiGen__startPublicFn(const void *ptr, dpiHandleTypeNum typeNum, - const char *fnName, int needErrorHandle, dpiError *error) + const char *fnName, dpiError *error) { dpiBaseType *value = (dpiBaseType*) ptr; @@ -296,8 +302,6 @@ int dpiGen__startPublicFn(const void *ptr, dpiHandleTypeNum typeNum, return DPI_FAILURE; if (dpiGen__checkHandle(ptr, typeNum, "check main handle", error) < 0) return DPI_FAILURE; - if (needErrorHandle && dpiEnv__initError(value->env, error) < 0) - return DPI_FAILURE; + error->env = value->env; return DPI_SUCCESS; } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiGlobal.c b/vendor/github.com/godror/godror/odpi/src/dpiGlobal.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiGlobal.c rename to vendor/github.com/godror/godror/odpi/src/dpiGlobal.c index c57dd557848..6599d870421 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiGlobal.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiGlobal.c @@ -289,4 +289,3 @@ int dpiGlobal__lookupEncoding(uint16_t charsetId, char *encoding, return DPI_SUCCESS; } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiHandleList.c b/vendor/github.com/godror/godror/odpi/src/dpiHandleList.c similarity index 98% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiHandleList.c rename to vendor/github.com/godror/godror/odpi/src/dpiHandleList.c index 920a2c628fe..2f3864067bb 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiHandleList.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiHandleList.c @@ -43,7 +43,7 @@ int dpiHandleList__addHandle(dpiHandleList *list, void *handle, list->handles = tempHandles; list->numSlots = numSlots; *slotNum = list->numUsedSlots++; - list->currentPos = list->numUsedSlots + 1; + list->currentPos = list->numUsedSlots; } else { for (i = 0; i < list->numSlots; i++) { if (!list->handles[list->currentPos]) @@ -114,4 +114,3 @@ void dpiHandleList__removeHandle(dpiHandleList *list, uint32_t slotNum) list->numUsedSlots--; dpiMutex__release(list->mutex); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiHandlePool.c b/vendor/github.com/godror/godror/odpi/src/dpiHandlePool.c similarity index 94% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiHandlePool.c rename to vendor/github.com/godror/godror/odpi/src/dpiHandlePool.c index aab33c86f2f..456f094f136 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiHandlePool.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiHandlePool.c @@ -105,14 +105,15 @@ void dpiHandlePool__free(dpiHandlePool *pool) // dpiHandlePool__release() [INTERNAL] // Release a handle back to the pool. No checks are performed on the handle // that is being returned to the pool; It will simply be placed back in the -// pool. +// pool. The handle is then NULLed in order to avoid multiple attempts to +// release the handle back to the pool. //----------------------------------------------------------------------------- -void dpiHandlePool__release(dpiHandlePool *pool, void *handle, dpiError *error) +void dpiHandlePool__release(dpiHandlePool *pool, void **handle) { dpiMutex__acquire(pool->mutex); - pool->handles[pool->releasePos++] = handle; + pool->handles[pool->releasePos++] = *handle; + *handle = NULL; if (pool->releasePos == pool->numSlots) pool->releasePos = 0; dpiMutex__release(pool->mutex); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiImpl.h b/vendor/github.com/godror/godror/odpi/src/dpiImpl.h similarity index 92% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiImpl.h rename to vendor/github.com/godror/godror/odpi/src/dpiImpl.h index 101846dc1da..ec2ede13955 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiImpl.h +++ b/vendor/github.com/godror/godror/odpi/src/dpiImpl.h @@ -153,6 +153,7 @@ extern unsigned long dpiDebugLevel; // define values used for getting/setting OCI attributes #define DPI_OCI_ATTR_DATA_SIZE 1 #define DPI_OCI_ATTR_DATA_TYPE 2 +#define DPI_OCI_ATTR_ENV 5 #define DPI_OCI_ATTR_PRECISION 5 #define DPI_OCI_ATTR_SCALE 6 #define DPI_OCI_ATTR_NAME 4 @@ -165,6 +166,7 @@ extern unsigned long dpiDebugLevel; #define DPI_OCI_ATTR_ROW_COUNT 9 #define DPI_OCI_ATTR_PREFETCH_ROWS 11 #define DPI_OCI_ATTR_PARAM_COUNT 18 +#define DPI_OCI_ATTR_ROWID 19 #define DPI_OCI_ATTR_USERNAME 22 #define DPI_OCI_ATTR_PASSWORD 23 #define DPI_OCI_ATTR_STMT_TYPE 24 @@ -219,6 +221,7 @@ extern unsigned long dpiDebugLevel; #define DPI_OCI_ATTR_NUM_TYPE_ATTRS 228 #define DPI_OCI_ATTR_SUBSCR_CQ_QOSFLAGS 229 #define DPI_OCI_ATTR_LIST_TYPE_ATTRS 229 +#define DPI_OCI_ATTR_SUBSCR_CQ_REGID 230 #define DPI_OCI_ATTR_SUBSCR_NTFN_GROUPING_CLASS 231 #define DPI_OCI_ATTR_SUBSCR_NTFN_GROUPING_VALUE 232 #define DPI_OCI_ATTR_SUBSCR_NTFN_GROUPING_TYPE 233 @@ -263,6 +266,7 @@ extern unsigned long dpiDebugLevel; #define DPI_OCI_ATTR_CONNECTION_CLASS 425 #define DPI_OCI_ATTR_PURITY 426 #define DPI_OCI_ATTR_RECEIVE_TIMEOUT 436 +#define DPI_OCI_ATTR_LOBPREFETCH_LENGTH 440 #define DPI_OCI_ATTR_SUBSCR_IPADDR 452 #define DPI_OCI_ATTR_UB8_ROW_COUNT 457 #define DPI_OCI_ATTR_SPOOL_AUTH 460 @@ -294,6 +298,7 @@ extern unsigned long dpiDebugLevel; #define DPI_OCI_ATTR_SODA_SKIP 577 #define DPI_OCI_ATTR_SODA_LIMIT 578 #define DPI_OCI_ATTR_SODA_DOC_COUNT 593 +#define DPI_OCI_ATTR_SPOOL_MAX_PER_SHARD 602 // define OCI object type constants #define DPI_OCI_OTYPE_NAME 1 @@ -335,6 +340,11 @@ extern unsigned long dpiDebugLevel; #define DPI_OCI_TYPECODE_SMALLINT 246 #define DPI_SQLT_REC 250 #define DPI_SQLT_BOL 252 +#define DPI_OCI_TYPECODE_ROWID 262 +#define DPI_OCI_TYPECODE_LONG 263 +#define DPI_OCI_TYPECODE_LONG_RAW 264 +#define DPI_OCI_TYPECODE_BINARY_INTEGER 265 +#define DPI_OCI_TYPECODE_PLS_INTEGER 266 // define session pool constants #define DPI_OCI_SPD_FORCE 0x0001 @@ -428,6 +438,7 @@ extern unsigned long dpiDebugLevel; #define DPI_OCI_SODA_COLL_CREATE_MAP 0x00010000 #define DPI_OCI_SODA_INDEX_DROP_FORCE 0x00010000 #define DPI_OCI_TRANS_TWOPHASE 0x01000000 +#define DPI_OCI_SECURE_NOTIFICATION 0x20000000 //----------------------------------------------------------------------------- // Macros @@ -519,6 +530,10 @@ typedef enum { DPI_ERR_CALL_TIMEOUT, DPI_ERR_SODA_CURSOR_CLOSED, DPI_ERR_EXT_AUTH_INVALID_PROXY, + DPI_ERR_QUEUE_NO_PAYLOAD, + DPI_ERR_QUEUE_WRONG_PAYLOAD_TYPE, + DPI_ERR_ORACLE_CLIENT_UNSUPPORTED, + DPI_ERR_MISSING_SHARDING_KEY, DPI_ERR_MAX } dpiErrorNum; @@ -544,6 +559,7 @@ typedef enum { DPI_HTYPE_SODA_DB, DPI_HTYPE_SODA_DOC, DPI_HTYPE_SODA_DOC_CURSOR, + DPI_HTYPE_QUEUE, DPI_HTYPE_MAX } dpiHandleTypeNum; @@ -587,6 +603,25 @@ typedef struct { uint32_t maxLifetimeSession; } dpiPoolCreateParams__v30; +// structure used for creating pools (3.2) +typedef struct { + uint32_t minSessions; + uint32_t maxSessions; + uint32_t sessionIncrement; + int pingInterval; + int pingTimeout; + int homogeneous; + int externalAuth; + dpiPoolGetMode getMode; + const char *outPoolName; + uint32_t outPoolNameLength; + uint32_t timeout; + uint32_t waitTimeout; + uint32_t maxLifetimeSession; + const char *plsqlFixupCallback; + uint32_t plsqlFixupCallbackLength; +} dpiPoolCreateParams__v32; + // structure used for creating connections (3.0) typedef struct { dpiAuthMode authMode; @@ -612,6 +647,49 @@ typedef struct { uint8_t numSuperShardingKeyColumns; } dpiConnCreateParams__v30; +// structure used for creating subscriptions (3.0 and 3.1) +typedef struct { + dpiSubscrNamespace subscrNamespace; + dpiSubscrProtocol protocol; + dpiSubscrQOS qos; + dpiOpCode operations; + uint32_t portNumber; + uint32_t timeout; + const char *name; + uint32_t nameLength; + dpiSubscrCallback callback; + void *callbackContext; + const char *recipientName; + uint32_t recipientNameLength; + const char *ipAddress; + uint32_t ipAddressLength; + uint8_t groupingClass; + uint32_t groupingValue; + uint8_t groupingType; +} dpiSubscrCreateParams__v30; + +// structure used for creating subscriptions (3.2) +typedef struct { + dpiSubscrNamespace subscrNamespace; + dpiSubscrProtocol protocol; + dpiSubscrQOS qos; + dpiOpCode operations; + uint32_t portNumber; + uint32_t timeout; + const char *name; + uint32_t nameLength; + dpiSubscrCallback callback; + void *callbackContext; + const char *recipientName; + uint32_t recipientNameLength; + const char *ipAddress; + uint32_t ipAddressLength; + uint8_t groupingClass; + uint32_t groupingValue; + uint8_t groupingType; + uint64_t outRegId; +} dpiSubscrCreateParams__v32; + //----------------------------------------------------------------------------- // OCI type definitions @@ -632,6 +710,17 @@ typedef struct { uint8_t second; } dpiOciDate; +// alternative representation of OCI Date type used for sharding +typedef struct { + uint8_t century; + uint8_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; +} dpiShardingOciDate; + // representation of OCI XID type (two-phase commit) typedef struct { long formatID; @@ -707,6 +796,7 @@ typedef struct { void *baseDate; // midnight, January 1, 1970 int threaded; // threaded mode enabled? int events; // events mode enabled? + int externalHandle; // external handle? } dpiEnv; // used to manage all errors that take place in the library; the implementation @@ -816,6 +906,7 @@ typedef union { char *asBytes; float *asFloat; double *asDouble; + int32_t *asInt32; int64_t *asInt64; uint64_t *asUint64; dpiOciNumber *asNumber; @@ -836,6 +927,7 @@ typedef union { // buffers to Oracle when values are being transferred to or from the Oracle // database typedef union { + int32_t asInt32; int64_t asInt64; uint64_t asUint64; float asFloat; @@ -869,6 +961,18 @@ typedef struct { dpiOracleData data; // Oracle data buffers (internal only) } dpiVarBuffer; +// represents memory areas used for enqueuing and dequeuing messages from +// queues +typedef struct { + uint32_t numElements; // number of elements in next arrays + dpiMsgProps **props; // array of dpiMsgProps handles + void **handles; // array of OCI msg prop handles + void **instances; // array of instances + void **indicators; // array of indicators + int16_t *rawIndicators; // array of indicators (RAW queues) + void **msgIds; // array of OCI message ids +} dpiQueueBuffer; + //----------------------------------------------------------------------------- // External implementation type definitions @@ -900,8 +1004,11 @@ struct dpiConn { void *handle; // OCI service context handle void *serverHandle; // OCI server handle void *sessionHandle; // OCI session handle + void *shardingKey; // OCI sharding key descriptor + void *superShardingKey; // OCI supper sharding key descriptor const char *releaseString; // cached release string or NULL uint32_t releaseStringLength; // cached release string length or 0 + void *rawTDO; // cached RAW TDO dpiVersionInfo versionInfo; // Oracle database version info uint32_t commitMode; // commit mode (for two-phase commits) uint16_t charsetId; // database character set ID @@ -932,6 +1039,7 @@ struct dpiStmt { dpiConn *conn; // connection which created this uint32_t openSlotNum; // slot in connection handle list void *handle; // OCI statement handle + dpiStmt *parentStmt; // parent statement (implicit results) uint32_t fetchArraySize; // rows to fetch each time uint32_t bufferRowCount; // number of rows in fetch buffers uint32_t bufferRowIndex; // index into buffers for current row @@ -946,6 +1054,7 @@ struct dpiStmt { uint64_t rowCount; // rows affected or rows fetched so far uint64_t bufferMinRow; // row num of first row in buffers uint16_t statementType; // type of statement + dpiRowid *lastRowid; // rowid of last affected row int isOwned; // owned by structure? int hasRowsToFetch; // potentially more rows to fetch? int scrollable; // scrollable cursor? @@ -1047,10 +1156,12 @@ struct dpiSubscr { dpiType_HEAD dpiConn *conn; // connection which created this void *handle; // OCI subscription handle + dpiMutexType mutex; // enables thread safety dpiSubscrNamespace subscrNamespace; // OCI namespace dpiSubscrQOS qos; // quality of service flags dpiSubscrCallback callback; // callback when event is propagated void *callbackContext; // context pointer for callback + int clientInitiated; // client initiated? int registered; // registered with database? }; @@ -1072,15 +1183,16 @@ struct dpiEnqOptions { void *handle; // OCI enqueue options handle }; -// represents the available properties for message when using advanced queuing +// represents the available properties for messages when using advanced queuing // and is exposed publicly as a handle of type DPI_HTYPE_MSG_PROPS; the // implementation for this is found in the file dpiMsgProps.c struct dpiMsgProps { dpiType_HEAD dpiConn *conn; // connection which created this void *handle; // OCI message properties handle - char *buffer; // latest message ID en/dequeued - uint32_t bufferLength; // size of allocated buffer + dpiObject *payloadObj; // payload (object) + void *payloadRaw; // payload (RAW) + void *msgIdRaw; // message ID (RAW) }; // represents SODA collections and is exposed publicly as a handle of type @@ -1129,6 +1241,19 @@ struct dpiSodaDocCursor { void *handle; // OCI SODA document cursor handle }; +// represents a queue used in AQ (advanced queuing) and is exposed publicly as +// a handle of type DPI_HTYPE_QUEUE; the implementation for this is found in +// the file dpiQueue.c +struct dpiQueue { + dpiType_HEAD + dpiConn *conn; // connection which created this + const char *name; // name of the queue (NULL-terminated) + dpiObjectType *payloadType; // object type (for object payloads) + dpiDeqOptions *deqOptions; // dequeue options + dpiEnqOptions *enqOptions; // enqueue options + dpiQueueBuffer buffer; // buffer area +}; + //----------------------------------------------------------------------------- // definition of internal dpiContext methods @@ -1145,6 +1270,8 @@ void dpiContext__initSubscrCreateParams(dpiSubscrCreateParams *params); //----------------------------------------------------------------------------- int dpiDataBuffer__fromOracleDate(dpiDataBuffer *data, dpiOciDate *oracleValue); +int dpiDataBuffer__fromOracleDateAsDouble(dpiDataBuffer *data, + dpiEnv *env, dpiError *error, dpiOciDate *oracleValue); int dpiDataBuffer__fromOracleIntervalDS(dpiDataBuffer *data, dpiEnv *env, dpiError *error, void *oracleValue); int dpiDataBuffer__fromOracleIntervalYM(dpiDataBuffer *data, dpiEnv *env, @@ -1162,6 +1289,8 @@ int dpiDataBuffer__fromOracleTimestamp(dpiDataBuffer *data, dpiEnv *env, int dpiDataBuffer__fromOracleTimestampAsDouble(dpiDataBuffer *data, dpiEnv *env, dpiError *error, void *oracleValue); int dpiDataBuffer__toOracleDate(dpiDataBuffer *data, dpiOciDate *oracleValue); +int dpiDataBuffer__toOracleDateFromDouble(dpiDataBuffer *data, dpiEnv *env, + dpiError *error, dpiOciDate *oracleValue); int dpiDataBuffer__toOracleIntervalDS(dpiDataBuffer *data, dpiEnv *env, dpiError *error, void *oracleValue); int dpiDataBuffer__toOracleIntervalYM(dpiDataBuffer *data, dpiEnv *env, @@ -1185,19 +1314,20 @@ int dpiDataBuffer__toOracleTimestampFromDouble(dpiDataBuffer *data, //----------------------------------------------------------------------------- void dpiEnv__free(dpiEnv *env, dpiError *error); int dpiEnv__init(dpiEnv *env, const dpiContext *context, - const dpiCommonCreateParams *params, dpiError *error); + const dpiCommonCreateParams *params, void *externalHandle, + dpiError *error); int dpiEnv__getEncodingInfo(dpiEnv *env, dpiEncodingInfo *info); -int dpiEnv__initError(dpiEnv *env, dpiError *error); //----------------------------------------------------------------------------- // definition of internal dpiError methods //----------------------------------------------------------------------------- -int dpiError__check(dpiError *error, int status, dpiConn *conn, - const char *action); int dpiError__getInfo(dpiError *error, dpiErrorInfo *info); +int dpiError__initHandle(dpiError *error); int dpiError__set(dpiError *error, const char *context, dpiErrorNum errorNum, ...); +int dpiError__setFromOCI(dpiError *error, int status, dpiConn *conn, + const char *action); //----------------------------------------------------------------------------- @@ -1212,7 +1342,7 @@ int dpiGen__endPublicFn(const void *ptr, int returnValue, dpiError *error); int dpiGen__release(void *ptr, dpiHandleTypeNum typeNum, const char *fnName); void dpiGen__setRefCount(void *ptr, dpiError *error, int increment); int dpiGen__startPublicFn(const void *ptr, dpiHandleTypeNum typeNum, - const char *fnName, int needErrorHandle, dpiError *error); + const char *fnName, dpiError *error); //----------------------------------------------------------------------------- @@ -1245,6 +1375,7 @@ int dpiConn__create(dpiConn *conn, const dpiContext *context, const dpiCommonCreateParams *commonParams, dpiConnCreateParams *createParams, dpiError *error); void dpiConn__free(dpiConn *conn, dpiError *error); +int dpiConn__getRawTDO(dpiConn *conn, dpiError *error); int dpiConn__getServerVersion(dpiConn *conn, dpiError *error); @@ -1408,15 +1539,28 @@ int dpiSodaDocCursor__allocate(dpiSodaColl *coll, void *handle, void dpiSodaDocCursor__free(dpiSodaDocCursor *cursor, dpiError *error); +//----------------------------------------------------------------------------- +// definition of internal dpiQueue methods +//----------------------------------------------------------------------------- +int dpiQueue__allocate(dpiConn *conn, const char *name, uint32_t nameLength, + dpiObjectType *payloadType, dpiQueue **queue, dpiError *error); +void dpiQueue__free(dpiQueue *queue, dpiError *error); + + //----------------------------------------------------------------------------- // definition of internal dpiOci methods //----------------------------------------------------------------------------- int dpiOci__aqDeq(dpiConn *conn, const char *queueName, void *options, void *msgProps, void *payloadType, void **payload, void **payloadInd, void **msgId, dpiError *error); +int dpiOci__aqDeqArray(dpiConn *conn, const char *queueName, void *options, + uint32_t *numIters, void **msgProps, void *payloadType, void **payload, void **payloadInd, void **msgId, dpiError *error); int dpiOci__aqEnq(dpiConn *conn, const char *queueName, void *options, void *msgProps, void *payloadType, void **payload, void **payloadInd, void **msgId, dpiError *error); +int dpiOci__aqEnqArray(dpiConn *conn, const char *queueName, void *options, + uint32_t *numIters, void **msgProps, void *payloadType, void **payload, + void **payloadInd, void **msgId, dpiError *error); int dpiOci__arrayDescriptorAlloc(void *envHandle, void **handle, uint32_t handleType, uint32_t arraySize, dpiError *error); int dpiOci__arrayDescriptorFree(void **handle, uint32_t handleType); @@ -1456,6 +1600,8 @@ int dpiOci__dateTimeConstruct(void *envHandle, void *handle, int16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint32_t fsecond, const char *tz, size_t tzLength, dpiError *error); +int dpiOci__dateTimeConvert(void *envHandle, void *inDate, void *outDate, + dpiError *error); int dpiOci__dateTimeGetDate(void *envHandle, void *handle, int16_t *year, uint8_t *month, uint8_t *day, dpiError *error); int dpiOci__dateTimeGetTime(void *envHandle, void *handle, uint8_t *hour, @@ -1546,7 +1692,8 @@ int dpiOci__numberToInt(void *number, void *value, unsigned int valueLength, int dpiOci__numberToReal(double *value, void *number, dpiError *error); int dpiOci__objectCopy(dpiObject *obj, void *sourceInstance, void *sourceIndicator, dpiError *error); -int dpiOci__objectFree(dpiObject *obj, int checkError, dpiError *error); +int dpiOci__objectFree(void *envHandle, void *data, int checkError, + dpiError *error); int dpiOci__objectGetAttr(dpiObject *obj, dpiObjectAttr *attr, int16_t *scalarValueIndicator, void **valueIndicator, void **value, void **tdo, dpiError *error); @@ -1599,7 +1746,7 @@ int dpiOci__sodaBulkInsert(dpiSodaColl *coll, void **documents, uint32_t numDocuments, void *outputOptions, uint32_t mode, dpiError *error); int dpiOci__sodaBulkInsertAndGet(dpiSodaColl *coll, void **documents, - uint32_t *numDocuments, void *outputOptions, uint32_t mode, + uint32_t numDocuments, void *outputOptions, uint32_t mode, dpiError *error); int dpiOci__sodaCollCreateWithMetadata(dpiSodaDb *db, const char *name, uint32_t nameLength, const char *metadata, uint32_t metadataLength, @@ -1662,7 +1809,7 @@ int dpiOci__stringPtr(void *envHandle, void *handle, char **ptr); int dpiOci__stringResize(void *envHandle, void **handle, uint32_t newSize, dpiError *error); int dpiOci__stringSize(void *envHandle, void *handle, uint32_t *size); -int dpiOci__subscriptionRegister(dpiConn *conn, void **handle, +int dpiOci__subscriptionRegister(dpiConn *conn, void **handle, uint32_t mode, dpiError *error); int dpiOci__subscriptionUnRegister(dpiConn *conn, dpiSubscr *subscr, dpiError *error); @@ -1690,14 +1837,17 @@ int dpiOci__transRollback(dpiConn *conn, int checkError, dpiError *error); int dpiOci__transStart(dpiConn *conn, dpiError *error); int dpiOci__typeByFullName(dpiConn *conn, const char *name, uint32_t nameLength, void **tdo, dpiError *error); +int dpiOci__typeByName(dpiConn *conn, const char *schema, + uint32_t schemaLength, const char *name, uint32_t nameLength, + void **tdo, dpiError *error); //----------------------------------------------------------------------------- // definition of internal dpiMsgProps methods //----------------------------------------------------------------------------- -int dpiMsgProps__create(dpiMsgProps *props, dpiConn *conn, dpiError *error); -int dpiMsgProps__extractMsgId(dpiMsgProps *props, void *ociRaw, - const char **msgId, uint32_t *msgIdLength, dpiError *error); +int dpiMsgProps__allocate(dpiConn *conn, dpiMsgProps **props, dpiError *error); +void dpiMsgProps__extractMsgId(dpiMsgProps *props, const char **msgId, + uint32_t *msgIdLength); void dpiMsgProps__free(dpiMsgProps *props, dpiError *error); @@ -1708,8 +1858,7 @@ int dpiHandlePool__acquire(dpiHandlePool *pool, void **handle, dpiError *error); int dpiHandlePool__create(dpiHandlePool **pool, dpiError *error); void dpiHandlePool__free(dpiHandlePool *pool); -void dpiHandlePool__release(dpiHandlePool *pool, void *handle, - dpiError *error); +void dpiHandlePool__release(dpiHandlePool *pool, void **handle); //----------------------------------------------------------------------------- @@ -1754,4 +1903,3 @@ void dpiDebug__initialize(void); void dpiDebug__print(const char *format, ...); #endif - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiLob.c b/vendor/github.com/godror/godror/odpi/src/dpiLob.c similarity index 94% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiLob.c rename to vendor/github.com/godror/godror/odpi/src/dpiLob.c index 310953fc674..55dfcebad6e 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiLob.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiLob.c @@ -53,10 +53,9 @@ int dpiLob__allocate(dpiConn *conn, const dpiOracleType *type, dpiLob **lob, // dpiLob__check() [INTERNAL] // Check that the LOB is valid and get an error handle for subsequent calls. //----------------------------------------------------------------------------- -static int dpiLob__check(dpiLob *lob, const char *fnName, int needErrorHandle, - dpiError *error) +static int dpiLob__check(dpiLob *lob, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(lob, DPI_HTYPE_LOB, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(lob, DPI_HTYPE_LOB, fnName, error) < 0) return DPI_FAILURE; if (!lob->locator) return dpiError__set(error, "check closed", DPI_ERR_LOB_CLOSED); @@ -210,7 +209,7 @@ int dpiLob_close(dpiLob *lob) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); status = dpiLob__close(lob, 1, &error); return dpiGen__endPublicFn(lob, status, &error); @@ -226,7 +225,7 @@ int dpiLob_closeResource(dpiLob *lob) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); status = dpiOci__lobClose(lob, &error); return dpiGen__endPublicFn(lob, status, &error); @@ -242,7 +241,7 @@ int dpiLob_copy(dpiLob *lob, dpiLob **copiedLob) dpiLob *tempLob; dpiError error; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, copiedLob) if (dpiLob__allocate(lob->conn, lob->type, &tempLob, &error) < 0) @@ -266,7 +265,7 @@ int dpiLob_getBufferSize(dpiLob *lob, uint64_t sizeInChars, { dpiError error; - if (dpiLob__check(lob, __func__, 0, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, sizeInBytes) if (lob->type->oracleTypeNum == DPI_ORACLE_TYPE_CLOB) @@ -287,7 +286,7 @@ int dpiLob_getChunkSize(dpiLob *lob, uint32_t *size) dpiError error; int status; - if (dpiLob__check(lob, __func__, 0, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, size) status = dpiOci__lobGetChunkSize(lob, size, &error); @@ -307,7 +306,7 @@ int dpiLob_getDirectoryAndFileName(dpiLob *lob, const char **directoryAlias, dpiError error; // validate parameters - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, directoryAlias) DPI_CHECK_PTR_NOT_NULL(lob, directoryAliasLength) @@ -344,7 +343,7 @@ int dpiLob_getFileExists(dpiLob *lob, int *exists) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, exists) status = dpiOci__lobFileExists(lob, exists, &error); @@ -361,7 +360,7 @@ int dpiLob_getIsResourceOpen(dpiLob *lob, int *isOpen) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, isOpen) status = dpiOci__lobIsOpen(lob, isOpen, &error); @@ -378,7 +377,7 @@ int dpiLob_getSize(dpiLob *lob, uint64_t *size) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, size) status = dpiOci__lobGetLength2(lob, size, &error); @@ -395,7 +394,7 @@ int dpiLob_openResource(dpiLob *lob) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); status = dpiOci__lobOpen(lob, &error); return dpiGen__endPublicFn(lob, status, &error); @@ -412,7 +411,7 @@ int dpiLob_readBytes(dpiLob *lob, uint64_t offset, uint64_t amount, dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, value) DPI_CHECK_PTR_NOT_NULL(lob, valueLength) @@ -443,7 +442,7 @@ int dpiLob_setDirectoryAndFileName(dpiLob *lob, const char *directoryAlias, dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, directoryAlias) DPI_CHECK_PTR_NOT_NULL(lob, fileName) @@ -463,9 +462,9 @@ int dpiLob_setFromBytes(dpiLob *lob, const char *value, uint64_t valueLength) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); - DPI_CHECK_PTR_NOT_NULL(lob, value) + DPI_CHECK_PTR_AND_LENGTH(lob, value) status = dpiLob__setFromBytes(lob, value, valueLength, &error); return dpiGen__endPublicFn(lob, status, &error); } @@ -480,7 +479,7 @@ int dpiLob_trim(dpiLob *lob, uint64_t newSize) dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); status = dpiOci__lobTrim2(lob, newSize, &error); return dpiGen__endPublicFn(lob, status, &error); @@ -497,10 +496,9 @@ int dpiLob_writeBytes(dpiLob *lob, uint64_t offset, const char *value, dpiError error; int status; - if (dpiLob__check(lob, __func__, 1, &error) < 0) + if (dpiLob__check(lob, __func__, &error) < 0) return dpiGen__endPublicFn(lob, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(lob, value) status = dpiOci__lobWrite2(lob, offset, value, valueLength, &error); return dpiGen__endPublicFn(lob, status, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiMsgProps.c b/vendor/github.com/godror/godror/odpi/src/dpiMsgProps.c similarity index 72% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiMsgProps.c rename to vendor/github.com/godror/godror/odpi/src/dpiMsgProps.c index 24260897b19..518d2e7d20b 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiMsgProps.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiMsgProps.c @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. // This program is free software: you can modify it and/or redistribute it // under the terms of: // @@ -17,45 +17,40 @@ #include "dpiImpl.h" //----------------------------------------------------------------------------- -// dpiMsgProps__create() [INTERNAL] -// Create a new subscription structure and return it. In case of error NULL -// is returned. +// dpiMsgProps__allocate() [INTERNAL] +// Create a new message properties structure and return it. In case of error +// NULL is returned. //----------------------------------------------------------------------------- -int dpiMsgProps__create(dpiMsgProps *options, dpiConn *conn, dpiError *error) +int dpiMsgProps__allocate(dpiConn *conn, dpiMsgProps **props, dpiError *error) { + dpiMsgProps *tempProps; + + if (dpiGen__allocate(DPI_HTYPE_MSG_PROPS, conn->env, (void**) &tempProps, + error) < 0) + return DPI_FAILURE; dpiGen__setRefCount(conn, error, 1); - options->conn = conn; - return dpiOci__descriptorAlloc(conn->env->handle, &options->handle, - DPI_OCI_DTYPE_AQMSG_PROPERTIES, "allocate descriptor", error); + tempProps->conn = conn; + if (dpiOci__descriptorAlloc(conn->env->handle, &tempProps->handle, + DPI_OCI_DTYPE_AQMSG_PROPERTIES, "allocate descriptor", + error) < 0) { + dpiMsgProps__free(tempProps, error); + return DPI_FAILURE; + } + + *props = tempProps; + return DPI_SUCCESS; } //----------------------------------------------------------------------------- // dpiMsgProps__extractMsgId() [INTERNAL] -// Extract bytes from the OCIRaw value containing the message id and store -// them in allocated memory on the message properties instance. Then resize the -// OCIRaw value so the memory can be reclaimed. +// Extract bytes from the OCIRaw value containing the message id. //----------------------------------------------------------------------------- -int dpiMsgProps__extractMsgId(dpiMsgProps *props, void *ociRaw, - const char **msgId, uint32_t *msgIdLength, dpiError *error) +void dpiMsgProps__extractMsgId(dpiMsgProps *props, const char **msgId, + uint32_t *msgIdLength) { - const char *rawPtr; - - dpiOci__rawPtr(props->env->handle, ociRaw, (void**) &rawPtr); - dpiOci__rawSize(props->env->handle, ociRaw, msgIdLength); - if (*msgIdLength > props->bufferLength) { - if (props->buffer) { - dpiUtils__freeMemory(props->buffer); - props->buffer = NULL; - } - if (dpiUtils__allocateMemory(1, *msgIdLength, 0, - "allocate msgid buffer", (void**) &props->buffer, error) < 0) - return DPI_FAILURE; - } - memcpy(props->buffer, rawPtr, *msgIdLength); - *msgId = props->buffer; - dpiOci__rawResize(props->env->handle, &ociRaw, 0, error); - return DPI_SUCCESS; + dpiOci__rawPtr(props->env->handle, props->msgIdRaw, (void**) msgId); + dpiOci__rawSize(props->env->handle, props->msgIdRaw, msgIdLength); } @@ -69,14 +64,22 @@ void dpiMsgProps__free(dpiMsgProps *props, dpiError *error) dpiOci__descriptorFree(props->handle, DPI_OCI_DTYPE_AQMSG_PROPERTIES); props->handle = NULL; } + if (props->payloadObj) { + dpiGen__setRefCount(props->payloadObj, error, -1); + props->payloadObj = NULL; + } + if (props->payloadRaw) { + dpiOci__rawResize(props->env->handle, &props->payloadRaw, 0, error); + props->payloadRaw = NULL; + } + if (props->msgIdRaw) { + dpiOci__rawResize(props->env->handle, &props->msgIdRaw, 0, error); + props->msgIdRaw = NULL; + } if (props->conn) { dpiGen__setRefCount(props->conn, error, -1); props->conn = NULL; } - if (props->buffer) { - dpiUtils__freeMemory(props->buffer); - props->buffer = NULL; - } dpiUtils__freeMemory(props); } @@ -91,8 +94,7 @@ static int dpiMsgProps__getAttrValue(dpiMsgProps *props, uint32_t attribute, dpiError error; int status; - if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, fnName, 1, - &error) < 0) + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, fnName, &error) < 0) return dpiGen__endPublicFn(props, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(props, value) DPI_CHECK_PTR_NOT_NULL(props, valueLength) @@ -112,8 +114,7 @@ static int dpiMsgProps__setAttrValue(dpiMsgProps *props, uint32_t attribute, dpiError error; int status; - if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, fnName, 1, - &error) < 0) + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, fnName, &error) < 0) return dpiGen__endPublicFn(props, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(props, value) status = dpiOci__attrSet(props->handle, DPI_OCI_DTYPE_AQMSG_PROPERTIES, @@ -181,7 +182,7 @@ int dpiMsgProps_getEnqTime(dpiMsgProps *props, dpiTimestamp *value) dpiOciDate ociValue; dpiError error; - if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, 1, + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, &error) < 0) return dpiGen__endPublicFn(props, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(props, value) @@ -240,6 +241,32 @@ int dpiMsgProps_getNumAttempts(dpiMsgProps *props, int32_t *value) } +//----------------------------------------------------------------------------- +// dpiMsgProps_getMsgId() [PUBLIC] +// Return the message id for the message (available after enqueuing or +// dequeuing a message). +//----------------------------------------------------------------------------- +int dpiMsgProps_getMsgId(dpiMsgProps *props, const char **value, + uint32_t *valueLength) +{ + dpiError error; + + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, + &error) < 0) + return dpiGen__endPublicFn(props, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(props, value) + DPI_CHECK_PTR_NOT_NULL(props, valueLength) + if (!props->msgIdRaw) { + *value = NULL; + *valueLength = 0; + } else { + dpiOci__rawPtr(props->env->handle, props->msgIdRaw, (void**) value); + dpiOci__rawSize(props->env->handle, props->msgIdRaw, valueLength); + } + return dpiGen__endPublicFn(props, DPI_SUCCESS, &error); +} + + //----------------------------------------------------------------------------- // dpiMsgProps_getOriginalMsgId() [PUBLIC] // Return the original message id for the message. @@ -250,7 +277,7 @@ int dpiMsgProps_getOriginalMsgId(dpiMsgProps *props, const char **value, dpiError error; void *rawValue; - if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, 1, + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, &error) < 0) return dpiGen__endPublicFn(props, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(props, value) @@ -265,6 +292,36 @@ int dpiMsgProps_getOriginalMsgId(dpiMsgProps *props, const char **value, } +//----------------------------------------------------------------------------- +// dpiMsgProps_getPayload() [PUBLIC] +// Get the payload for the message (as an object or a series of bytes). +//----------------------------------------------------------------------------- +int dpiMsgProps_getPayload(dpiMsgProps *props, dpiObject **obj, + const char **value, uint32_t *valueLength) +{ + dpiError error; + + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, + &error) < 0) + return dpiGen__endPublicFn(props, DPI_FAILURE, &error); + if (obj) + *obj = props->payloadObj; + if (value && valueLength) { + if (props->payloadRaw) { + dpiOci__rawPtr(props->env->handle, props->payloadRaw, + (void**) value); + dpiOci__rawSize(props->env->handle, props->payloadRaw, + valueLength); + } else { + *value = NULL; + *valueLength = 0; + } + } + + return dpiGen__endPublicFn(props, DPI_SUCCESS, &error); +} + + //----------------------------------------------------------------------------- // dpiMsgProps_getPriority() [PUBLIC] // Return the priority of the message. @@ -359,7 +416,7 @@ int dpiMsgProps_setOriginalMsgId(dpiMsgProps *props, const char *value, dpiError error; int status; - if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, 1, + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, &error) < 0) return dpiGen__endPublicFn(props, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(props, value) @@ -374,6 +431,51 @@ int dpiMsgProps_setOriginalMsgId(dpiMsgProps *props, const char *value, } +//----------------------------------------------------------------------------- +// dpiMsgProps_setPayloadBytes() [PUBLIC] +// Set the payload for the message (as a series of bytes). +//----------------------------------------------------------------------------- +int dpiMsgProps_setPayloadBytes(dpiMsgProps *props, const char *value, + uint32_t valueLength) +{ + dpiError error; + int status; + + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, + &error) < 0) + return dpiGen__endPublicFn(props, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(props, value) + if (props->payloadRaw) { + dpiOci__rawResize(props->env->handle, &props->payloadRaw, 0, &error); + props->payloadRaw = NULL; + } + status = dpiOci__rawAssignBytes(props->env->handle, value, valueLength, + &props->payloadRaw, &error); + return dpiGen__endPublicFn(props, status, &error); +} + + +//----------------------------------------------------------------------------- +// dpiMsgProps_setPayloadObject() [PUBLIC] +// Set the payload for the message (as an object). +//----------------------------------------------------------------------------- +int dpiMsgProps_setPayloadObject(dpiMsgProps *props, dpiObject *obj) +{ + dpiError error; + + if (dpiGen__startPublicFn(props, DPI_HTYPE_MSG_PROPS, __func__, + &error) < 0) + return dpiGen__endPublicFn(props, DPI_FAILURE, &error); + if (dpiGen__checkHandle(obj, DPI_HTYPE_OBJECT, "check object", &error) < 0) + return dpiGen__endPublicFn(props, DPI_FAILURE, &error); + if (props->payloadObj) + dpiGen__setRefCount(props->payloadObj, &error, -1); + dpiGen__setRefCount(obj, &error, 1); + props->payloadObj = obj; + return dpiGen__endPublicFn(props, DPI_SUCCESS, &error); +} + + //----------------------------------------------------------------------------- // dpiMsgProps_setPriority() [PUBLIC] // Set the priority of the message. @@ -383,4 +485,3 @@ int dpiMsgProps_setPriority(dpiMsgProps *props, int32_t value) return dpiMsgProps__setAttrValue(props, DPI_OCI_ATTR_PRIORITY, __func__, &value, 0); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiObject.c b/vendor/github.com/godror/godror/odpi/src/dpiObject.c similarity index 87% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiObject.c rename to vendor/github.com/godror/godror/odpi/src/dpiObject.c index 001789ddf5a..338c68aeeda 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiObject.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiObject.c @@ -16,6 +16,10 @@ #include "dpiImpl.h" +// forward declarations of internal functions only used in this file +int dpiObject__closeHelper(dpiObject *obj, int checkError, dpiError *error); + + //----------------------------------------------------------------------------- // dpiObject__allocate() [INTERNAL] // Allocate and initialize an object structure. @@ -66,7 +70,7 @@ int dpiObject__allocate(dpiObjectType *objType, void *instance, static int dpiObject__check(dpiObject *obj, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(obj, DPI_HTYPE_OBJECT, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(obj, DPI_HTYPE_OBJECT, fnName, error) < 0) return DPI_FAILURE; return dpiConn__checkConnected(obj->type->conn, error); } @@ -94,7 +98,8 @@ static int dpiObject__checkIsCollection(dpiObject *obj, const char *fnName, // Clear the Oracle value after use. //----------------------------------------------------------------------------- static void dpiObject__clearOracleValue(dpiObject *obj, dpiError *error, - dpiOracleDataBuffer *buffer, dpiOracleTypeNum oracleTypeNum) + dpiOracleDataBuffer *buffer, dpiLob *lob, + dpiOracleTypeNum oracleTypeNum) { switch (oracleTypeNum) { case DPI_ORACLE_TYPE_CHAR: @@ -129,12 +134,9 @@ static void dpiObject__clearOracleValue(dpiObject *obj, dpiError *error, case DPI_ORACLE_TYPE_NCLOB: case DPI_ORACLE_TYPE_BLOB: case DPI_ORACLE_TYPE_BFILE: - if (buffer->asLobLocator) { - dpiOci__lobFreeTemporary(obj->type->conn, buffer->asLobLocator, - 0, error); - dpiOci__descriptorFree(buffer->asLobLocator, - DPI_OCI_DTYPE_LOB); - } + if (lob) + dpiGen__setRefCount(lob, error, -1); + break; default: break; }; @@ -171,7 +173,7 @@ int dpiObject__close(dpiObject *obj, int checkError, dpiError *error) // flag; again, this must be done while holding the lock (if in threaded // mode) in order to avoid race conditions! if (obj->instance && !obj->dependsOnObj) { - if (dpiOci__objectFree(obj, checkError, error) < 0) { + if (dpiObject__closeHelper(obj, checkError, error) < 0) { if (obj->env->threaded) dpiMutex__acquire(obj->env->mutex); obj->closing = 0; @@ -179,17 +181,33 @@ int dpiObject__close(dpiObject *obj, int checkError, dpiError *error) dpiMutex__release(obj->env->mutex); return DPI_FAILURE; } - if (!obj->type->conn->closing) - dpiHandleList__removeHandle(obj->type->conn->objects, - obj->openSlotNum); - obj->instance = NULL; - obj->indicator = NULL; } return DPI_SUCCESS; } +//----------------------------------------------------------------------------- +// dpiObject__closeHelper() [INTERNAL] +// Helper function for closing an object. +//----------------------------------------------------------------------------- +int dpiObject__closeHelper(dpiObject *obj, int checkError, dpiError *error) +{ + if (dpiOci__objectFree(obj->env->handle, obj->instance, checkError, + error) < 0) + return DPI_FAILURE; + obj->instance = NULL; + if (obj->freeIndicator && dpiOci__objectFree(obj->env->handle, + obj->indicator, checkError, error) < 0) + return DPI_FAILURE; + obj->indicator = NULL; + if (!obj->type->conn->closing) + dpiHandleList__removeHandle(obj->type->conn->objects, + obj->openSlotNum); + return DPI_SUCCESS; +} + + //----------------------------------------------------------------------------- // dpiObject__free() [INTERNAL] // Free the memory for an object. @@ -260,9 +278,10 @@ static int dpiObject__fromOracleValue(dpiObject *obj, dpiError *error, } break; case DPI_ORACLE_TYPE_NATIVE_INT: - if (nativeTypeNum == DPI_NATIVE_TYPE_INT64) - return dpiDataBuffer__fromOracleNumberAsInteger(&data->value, - error, value->asNumber); + if (nativeTypeNum == DPI_NATIVE_TYPE_INT64) { + data->value.asInt64 = *value->asInt32; + return DPI_SUCCESS; + } break; case DPI_ORACLE_TYPE_NATIVE_FLOAT: if (nativeTypeNum == DPI_NATIVE_TYPE_FLOAT) { @@ -294,17 +313,26 @@ static int dpiObject__fromOracleValue(dpiObject *obj, dpiError *error, if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) return dpiDataBuffer__fromOracleDate(&data->value, value->asDate); + if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) + return dpiDataBuffer__fromOracleDateAsDouble(&data->value, + obj->env, error, value->asDate); break; case DPI_ORACLE_TYPE_TIMESTAMP: if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) return dpiDataBuffer__fromOracleTimestamp(&data->value, obj->env, error, *value->asTimestamp, 0); + if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) + return dpiDataBuffer__fromOracleTimestampAsDouble(&data->value, + obj->env, error, *value->asTimestamp); break; case DPI_ORACLE_TYPE_TIMESTAMP_TZ: case DPI_ORACLE_TYPE_TIMESTAMP_LTZ: if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) return dpiDataBuffer__fromOracleTimestamp(&data->value, obj->env, error, *value->asTimestamp, 1); + if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) + return dpiDataBuffer__fromOracleTimestampAsDouble(&data->value, + obj->env, error, *value->asTimestamp); break; case DPI_ORACLE_TYPE_OBJECT: if (typeInfo->objectType && @@ -366,8 +394,8 @@ static int dpiObject__fromOracleValue(dpiObject *obj, dpiError *error, //----------------------------------------------------------------------------- static int dpiObject__toOracleValue(dpiObject *obj, dpiError *error, const dpiDataTypeInfo *dataTypeInfo, dpiOracleDataBuffer *buffer, - void **ociValue, int16_t *valueIndicator, void **objectIndicator, - dpiNativeTypeNum nativeTypeNum, dpiData *data) + dpiLob **lob, void **ociValue, int16_t *valueIndicator, + void **objectIndicator, dpiNativeTypeNum nativeTypeNum, dpiData *data) { dpiOracleTypeNum valueOracleTypeNum; uint32_t handleType; @@ -413,6 +441,12 @@ static int dpiObject__toOracleValue(dpiObject *obj, dpiError *error, } break; case DPI_ORACLE_TYPE_NATIVE_INT: + if (nativeTypeNum == DPI_NATIVE_TYPE_INT64) { + buffer->asInt32 = (int32_t) data->value.asInt64; + *ociValue = &buffer->asInt32; + return DPI_SUCCESS; + } + break; case DPI_ORACLE_TYPE_NUMBER: *ociValue = &buffer->asNumber; if (nativeTypeNum == DPI_NATIVE_TYPE_INT64) @@ -448,25 +482,35 @@ static int dpiObject__toOracleValue(dpiObject *obj, dpiError *error, if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) return dpiDataBuffer__toOracleDate(&data->value, &buffer->asDate); + if (nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) + return dpiDataBuffer__toOracleDateFromDouble(&data->value, + obj->env, error, &buffer->asDate); break; case DPI_ORACLE_TYPE_TIMESTAMP: case DPI_ORACLE_TYPE_TIMESTAMP_TZ: case DPI_ORACLE_TYPE_TIMESTAMP_LTZ: buffer->asTimestamp = NULL; - if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) { - if (valueOracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP) + if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP || + nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) { + if (valueOracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP_LTZ || + nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) { + handleType = DPI_OCI_DTYPE_TIMESTAMP_LTZ; + } else if (valueOracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP) { handleType = DPI_OCI_DTYPE_TIMESTAMP; - else if (valueOracleTypeNum == DPI_ORACLE_TYPE_TIMESTAMP_TZ) + } else { handleType = DPI_OCI_DTYPE_TIMESTAMP_TZ; - else handleType = DPI_OCI_DTYPE_TIMESTAMP_LTZ; + } if (dpiOci__descriptorAlloc(obj->env->handle, &buffer->asTimestamp, handleType, "allocate timestamp", error) < 0) return DPI_FAILURE; *ociValue = buffer->asTimestamp; - return dpiDataBuffer__toOracleTimestamp(&data->value, obj->env, - error, buffer->asTimestamp, - (valueOracleTypeNum != DPI_ORACLE_TYPE_TIMESTAMP)); + if (nativeTypeNum == DPI_NATIVE_TYPE_TIMESTAMP) + return dpiDataBuffer__toOracleTimestamp(&data->value, + obj->env, error, buffer->asTimestamp, + (valueOracleTypeNum != DPI_ORACLE_TYPE_TIMESTAMP)); + return dpiDataBuffer__toOracleTimestampFromDouble(&data->value, + obj->env, error, buffer->asTimestamp); } break; case DPI_ORACLE_TYPE_OBJECT: @@ -503,21 +547,15 @@ static int dpiObject__toOracleValue(dpiObject *obj, dpiError *error, return DPI_SUCCESS; } else if (nativeTypeNum == DPI_NATIVE_TYPE_BYTES) { const dpiOracleType *lobType; - dpiLob *tempLob; lobType = dpiOracleType__getFromNum(valueOracleTypeNum, error); - if (dpiLob__allocate(obj->type->conn, lobType, &tempLob, - error) < 0) + if (dpiLob__allocate(obj->type->conn, lobType, lob, error) < 0) return DPI_FAILURE; bytes = &data->value.asBytes; - if (dpiLob__setFromBytes(tempLob, bytes->ptr, bytes->length, - error) < 0) { - dpiLob__free(tempLob, error); + if (dpiLob__setFromBytes(*lob, bytes->ptr, bytes->length, + error) < 0) return DPI_FAILURE; - } - buffer->asLobLocator = tempLob->locator; - *ociValue = tempLob->locator; - tempLob->locator = NULL; - dpiLob__free(tempLob, error); + buffer->asLobLocator = (*lob)->locator; + *ociValue = (*lob)->locator; return DPI_SUCCESS; } break; @@ -550,6 +588,7 @@ int dpiObject_appendElement(dpiObject *obj, dpiNativeTypeNum nativeTypeNum, { dpiOracleDataBuffer valueBuffer; int16_t scalarValueIndicator; + dpiLob *lob = NULL; void *indicator; dpiError error; void *ociValue; @@ -558,15 +597,16 @@ int dpiObject_appendElement(dpiObject *obj, dpiNativeTypeNum nativeTypeNum, if (dpiObject__checkIsCollection(obj, __func__, &error) < 0) return dpiGen__endPublicFn(obj, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(obj, data) - if (dpiObject__toOracleValue(obj, &error, &obj->type->elementTypeInfo, - &valueBuffer, &ociValue, &scalarValueIndicator, - (void**) &indicator, nativeTypeNum, data) < 0) - return dpiGen__endPublicFn(obj, DPI_FAILURE, &error); - if (!indicator) - indicator = &scalarValueIndicator; - status = dpiOci__collAppend(obj->type->conn, ociValue, indicator, - obj->instance, &error); - dpiObject__clearOracleValue(obj, &error, &valueBuffer, + status = dpiObject__toOracleValue(obj, &error, &obj->type->elementTypeInfo, + &valueBuffer, &lob, &ociValue, &scalarValueIndicator, + (void**) &indicator, nativeTypeNum, data); + if (status == DPI_SUCCESS) { + if (!indicator) + indicator = &scalarValueIndicator; + status = dpiOci__collAppend(obj->type->conn, ociValue, indicator, + obj->instance, &error); + } + dpiObject__clearOracleValue(obj, &error, &valueBuffer, lob, obj->type->elementTypeInfo.oracleTypeNum); return dpiGen__endPublicFn(obj, status, &error); } @@ -836,6 +876,7 @@ int dpiObject_setAttributeValue(dpiObject *obj, dpiObjectAttr *attr, void *valueIndicator, *ociValue; dpiOracleDataBuffer valueBuffer; int16_t scalarValueIndicator; + dpiLob *lob = NULL; dpiError error; int status; @@ -861,15 +902,15 @@ int dpiObject_setAttributeValue(dpiObject *obj, dpiObjectAttr *attr, } // convert to input data format - if (dpiObject__toOracleValue(obj, &error, &attr->typeInfo, &valueBuffer, - &ociValue, &scalarValueIndicator, &valueIndicator, nativeTypeNum, - data) < 0) - return dpiGen__endPublicFn(obj, DPI_FAILURE, &error); + status = dpiObject__toOracleValue(obj, &error, &attr->typeInfo, + &valueBuffer, &lob, &ociValue, &scalarValueIndicator, + &valueIndicator, nativeTypeNum, data); // set attribute value - status = dpiOci__objectSetAttr(obj, attr, scalarValueIndicator, - valueIndicator, ociValue, &error); - dpiObject__clearOracleValue(obj, &error, &valueBuffer, + if (status == DPI_SUCCESS) + status = dpiOci__objectSetAttr(obj, attr, scalarValueIndicator, + valueIndicator, ociValue, &error); + dpiObject__clearOracleValue(obj, &error, &valueBuffer, lob, attr->typeInfo.oracleTypeNum); return dpiGen__endPublicFn(obj, status, &error); } @@ -884,6 +925,7 @@ int dpiObject_setElementValueByIndex(dpiObject *obj, int32_t index, { dpiOracleDataBuffer valueBuffer; int16_t scalarValueIndicator; + dpiLob *lob = NULL; void *indicator; dpiError error; void *ociValue; @@ -892,15 +934,16 @@ int dpiObject_setElementValueByIndex(dpiObject *obj, int32_t index, if (dpiObject__checkIsCollection(obj, __func__, &error) < 0) return dpiGen__endPublicFn(obj, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(obj, data) - if (dpiObject__toOracleValue(obj, &error, &obj->type->elementTypeInfo, - &valueBuffer, &ociValue, &scalarValueIndicator, - (void**) &indicator, nativeTypeNum, data) < 0) - return dpiGen__endPublicFn(obj, DPI_FAILURE, &error); - if (!indicator) - indicator = &scalarValueIndicator; - status = dpiOci__collAssignElem(obj->type->conn, index, ociValue, - indicator, obj->instance, &error); - dpiObject__clearOracleValue(obj, &error, &valueBuffer, + status = dpiObject__toOracleValue(obj, &error, &obj->type->elementTypeInfo, + &valueBuffer, &lob, &ociValue, &scalarValueIndicator, + (void**) &indicator, nativeTypeNum, data); + if (status == DPI_SUCCESS) { + if (!indicator) + indicator = &scalarValueIndicator; + status = dpiOci__collAssignElem(obj->type->conn, index, ociValue, + indicator, obj->instance, &error); + } + dpiObject__clearOracleValue(obj, &error, &valueBuffer, lob, obj->type->elementTypeInfo.oracleTypeNum); return dpiGen__endPublicFn(obj, status, &error); } @@ -921,4 +964,3 @@ int dpiObject_trim(dpiObject *obj, uint32_t numToTrim) &error); return dpiGen__endPublicFn(obj, status, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiObjectAttr.c b/vendor/github.com/godror/godror/odpi/src/dpiObjectAttr.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiObjectAttr.c rename to vendor/github.com/godror/godror/odpi/src/dpiObjectAttr.c index 573abc68217..45d623ef573 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiObjectAttr.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiObjectAttr.c @@ -93,7 +93,7 @@ int dpiObjectAttr_getInfo(dpiObjectAttr *attr, dpiObjectAttrInfo *info) { dpiError error; - if (dpiGen__startPublicFn(attr, DPI_HTYPE_OBJECT_ATTR, __func__, 0, + if (dpiGen__startPublicFn(attr, DPI_HTYPE_OBJECT_ATTR, __func__, &error) < 0) return dpiGen__endPublicFn(attr, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(attr, info) @@ -112,4 +112,3 @@ int dpiObjectAttr_release(dpiObjectAttr *attr) { return dpiGen__release(attr, DPI_HTYPE_OBJECT_ATTR, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiObjectType.c b/vendor/github.com/godror/godror/odpi/src/dpiObjectType.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiObjectType.c rename to vendor/github.com/godror/godror/odpi/src/dpiObjectType.c index 9030b397839..fbb2cf240c8 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiObjectType.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiObjectType.c @@ -57,7 +57,7 @@ int dpiObjectType__allocate(dpiConn *conn, void *param, static int dpiObjectType__check(dpiObjectType *objType, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(objType, DPI_HTYPE_OBJECT_TYPE, fnName, 1, + if (dpiGen__startPublicFn(objType, DPI_HTYPE_OBJECT_TYPE, fnName, error) < 0) return DPI_FAILURE; return dpiConn__checkConnected(objType->conn, error); @@ -319,7 +319,7 @@ int dpiObjectType_getInfo(dpiObjectType *objType, dpiObjectTypeInfo *info) { dpiError error; - if (dpiGen__startPublicFn(objType, DPI_HTYPE_OBJECT_TYPE, __func__, 0, + if (dpiGen__startPublicFn(objType, DPI_HTYPE_OBJECT_TYPE, __func__, &error) < 0) return dpiGen__endPublicFn(objType, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(objType, info) @@ -342,4 +342,3 @@ int dpiObjectType_release(dpiObjectType *objType) { return dpiGen__release(objType, DPI_HTYPE_OBJECT_TYPE, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiOci.c b/vendor/github.com/godror/godror/odpi/src/dpiOci.c similarity index 85% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiOci.c rename to vendor/github.com/godror/godror/odpi/src/dpiOci.c index 2ad76c688d5..c731324cb48 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiOci.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiOci.c @@ -35,14 +35,35 @@ static void *dpiOci__reallocMem(void *unused, void *ptr, size_t newSize); error) < 0) \ return DPI_FAILURE; +// macro to ensure that an error handle is available +#define DPI_OCI_ENSURE_ERROR_HANDLE(error) \ + if (!error->handle && dpiError__initHandle(error) < 0) \ + return DPI_FAILURE; + +// macros to simplify code for checking results of OCI calls +#define DPI_OCI_ERROR_OCCURRED(status) \ + (status != DPI_OCI_SUCCESS && status != DPI_OCI_SUCCESS_WITH_INFO) +#define DPI_OCI_CHECK_AND_RETURN(error, status, conn, action) \ + if (DPI_OCI_ERROR_OCCURRED(status)) \ + return dpiError__setFromOCI(error, status, conn, action); \ + return DPI_SUCCESS; + // typedefs for all OCI functions used by ODPI-C typedef int (*dpiOciFnType__aqDeq)(void *svchp, void *errhp, const char *queue_name, void *deqopt, void *msgprop, void *payload_tdo, void **payload, void **payload_ind, void **msgid, uint32_t flags); +typedef int (*dpiOciFnType__aqDeqArray)(void *svchp, void *errhp, + const char *queue_name, void *deqopt, uint32_t *iters, void **msgprop, + void *payload_tdo, void **payload, void **payload_ind, void **msgid, + void *ctxp, void *deqcbfp, uint32_t flags); typedef int (*dpiOciFnType__aqEnq)(void *svchp, void *errhp, const char *queue_name, void *enqopt, void *msgprop, void *payload_tdo, void **payload, void **payload_ind, void **msgid, uint32_t flags); +typedef int (*dpiOciFnType__aqEnqArray)(void *svchp, void *errhp, + const char *queue_name, void *enqopt, uint32_t *iters, void **msgprop, + void *payload_tdo, void **payload, void **payload_ind, void **msgid, + void *ctxp, void *enqcbfp, uint32_t flags); typedef int (*dpiOciFnType__arrayDescriptorAlloc)(const void *parenth, void **descpp, const uint32_t type, uint32_t array_size, const size_t xtramem_sz, void **usrmempp); @@ -99,6 +120,8 @@ typedef int (*dpiOciFnType__dateTimeConstruct)(void *hndl, void *err, void *datetime, int16_t yr, uint8_t mnth, uint8_t dy, uint8_t hr, uint8_t mm, uint8_t ss, uint32_t fsec, const char *tz, size_t tzLength); +typedef int (*dpiOciFnType__dateTimeConvert)(void *hndl, void *err, + void *indate, void *outdate); typedef int (*dpiOciFnType__dateTimeGetDate)(void *hndl, void *err, const void *date, int16_t *yr, uint8_t *mnth, uint8_t *dy); typedef int (*dpiOciFnType__dateTimeGetTime)(void *hndl, void *err, @@ -283,6 +306,12 @@ typedef int (*dpiOciFnType__sessionRelease)(void *svchp, void *errhp, typedef int (*dpiOciFnType__shardingKeyColumnAdd)(void *shardingKey, void *errhp, void *col, uint32_t colLen, uint16_t colType, uint32_t mode); +typedef int (*dpiOciFnType__sodaBulkInsert)(void *svchp, + void *collection, void **documentarray, uint32_t arraylen, + void *opoptns, void *errhp, uint32_t mode); +typedef int (*dpiOciFnType__sodaBulkInsertAndGet)(void *svchp, + void *collection, void **documentarray, uint32_t arraylen, + void *opoptns, void *errhp, uint32_t mode); typedef int (*dpiOciFnType__sodaCollCreateWithMetadata)(void *svchp, const char *collname, uint32_t collnamelen, const char *metadata, uint32_t metadatalen, void **collection, void *errhp, uint32_t mode); @@ -389,6 +418,10 @@ typedef int (*dpiOciFnType__typeByFullName)(void *env, void *err, uint32_t full_type_name_length, const char *version_name, uint32_t version_name_length, uint16_t pin_duration, int get_option, void **tdo); +typedef int (*dpiOciFnType__typeByName)(void *env, void *err, const void *svc, + const char *schema_name, uint32_t s_length, const char *type_name, + uint32_t t_length, const char *version_name, uint32_t v_length, + uint16_t pin_duration, int get_option, void **tdo); // library handle for dynamically loaded OCI library @@ -400,16 +433,18 @@ static const char *dpiOciLibNames[] = { "oci.dll", #elif __APPLE__ "libclntsh.dylib", + "libclntsh.dylib.19.1", "libclntsh.dylib.18.1", "libclntsh.dylib.12.1", "libclntsh.dylib.11.1", - "libclntsh.dylib.19.1", + "libclntsh.dylib.20.1", #else "libclntsh.so", + "libclntsh.so.19.1", "libclntsh.so.18.1", "libclntsh.so.12.1", "libclntsh.so.11.1", - "libclntsh.so.19.1", + "libclntsh.so.20.1", #endif NULL }; @@ -429,7 +464,9 @@ static dpiVersionInfo dpiOciLibVersionInfo; // all OCI symbols used by ODPI-C static struct { dpiOciFnType__aqDeq fnAqDeq; + dpiOciFnType__aqDeqArray fnAqDeqArray; dpiOciFnType__aqEnq fnAqEnq; + dpiOciFnType__aqEnqArray fnAqEnqArray; dpiOciFnType__arrayDescriptorAlloc fnArrayDescriptorAlloc; dpiOciFnType__arrayDescriptorFree fnArrayDescriptorFree; dpiOciFnType__attrGet fnAttrGet; @@ -450,6 +487,7 @@ static struct { dpiOciFnType__contextGetValue fnContextGetValue; dpiOciFnType__contextSetValue fnContextSetValue; dpiOciFnType__dateTimeConstruct fnDateTimeConstruct; + dpiOciFnType__dateTimeConvert fnDateTimeConvert; dpiOciFnType__dateTimeGetDate fnDateTimeGetDate; dpiOciFnType__dateTimeGetTime fnDateTimeGetTime; dpiOciFnType__dateTimeGetTimeZoneOffset fnDateTimeGetTimeZoneOffset; @@ -526,6 +564,8 @@ static struct { dpiOciFnType__sessionRelease fnSessionRelease; dpiOciFnType__shardingKeyColumnAdd fnShardingKeyColumnAdd; dpiOciFnType__stmtExecute fnStmtExecute; + dpiOciFnType__sodaBulkInsert fnSodaBulkInsert; + dpiOciFnType__sodaBulkInsertAndGet fnSodaBulkInsertAndGet; dpiOciFnType__sodaCollCreateWithMetadata fnSodaCollCreateWithMetadata; dpiOciFnType__sodaCollDrop fnSodaCollDrop; dpiOciFnType__sodaCollGetNext fnSodaCollGetNext; @@ -572,6 +612,7 @@ static struct { dpiOciFnType__transRollback fnTransRollback; dpiOciFnType__transStart fnTransStart; dpiOciFnType__typeByFullName fnTypeByFullName; + dpiOciFnType__typeByName fnTypeByName; } dpiOciSymbols; @@ -580,7 +621,7 @@ static struct { // Wrapper for OCI allocation of memory, only used when debugging memory // allocation. //----------------------------------------------------------------------------- -static void *dpiOci__allocateMem(void *unused, size_t size) +static void *dpiOci__allocateMem(UNUSED void *unused, size_t size) { void *ptr; @@ -601,10 +642,30 @@ int dpiOci__aqDeq(dpiConn *conn, const char *queueName, void *options, int status; DPI_OCI_LOAD_SYMBOL("OCIAQDeq", dpiOciSymbols.fnAqDeq) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnAqDeq)(conn->handle, error->handle, queueName, options, msgProps, payloadType, payload, payloadInd, msgId, DPI_OCI_DEFAULT); - return dpiError__check(error, status, conn, "dequeue message"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "dequeue message"); +} + + +//----------------------------------------------------------------------------- +// dpiOci__aqDeqArray() [INTERNAL] +// Wrapper for OCIAQDeqArray(). +//----------------------------------------------------------------------------- +int dpiOci__aqDeqArray(dpiConn *conn, const char *queueName, void *options, + uint32_t *numIters, void **msgProps, void *payloadType, void **payload, + void **payloadInd, void **msgId, dpiError *error) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCIAQDeqArray", dpiOciSymbols.fnAqDeqArray) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnAqDeqArray)(conn->handle, error->handle, + queueName, options, numIters, msgProps, payloadType, payload, + payloadInd, msgId, NULL, NULL, DPI_OCI_DEFAULT); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "dequeue messages"); } @@ -619,10 +680,30 @@ int dpiOci__aqEnq(dpiConn *conn, const char *queueName, void *options, int status; DPI_OCI_LOAD_SYMBOL("OCIAQEnq", dpiOciSymbols.fnAqEnq) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnAqEnq)(conn->handle, error->handle, queueName, options, msgProps, payloadType, payload, payloadInd, msgId, DPI_OCI_DEFAULT); - return dpiError__check(error, status, conn, "enqueue message"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "enqueue message"); +} + + +//----------------------------------------------------------------------------- +// dpiOci__aqEnqArray() [INTERNAL] +// Wrapper for OCIAQEnqArray(). +//----------------------------------------------------------------------------- +int dpiOci__aqEnqArray(dpiConn *conn, const char *queueName, void *options, + uint32_t *numIters, void **msgProps, void *payloadType, void **payload, + void **payloadInd, void **msgId, dpiError *error) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCIAQEnqArray", dpiOciSymbols.fnAqEnqArray) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnAqEnqArray)(conn->handle, error->handle, + queueName, options, numIters, msgProps, payloadType, payload, + payloadInd, msgId, NULL, NULL, DPI_OCI_DEFAULT); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "enqueue messages"); } @@ -639,7 +720,7 @@ int dpiOci__arrayDescriptorAlloc(void *envHandle, void **handle, dpiOciSymbols.fnArrayDescriptorAlloc) status = (*dpiOciSymbols.fnArrayDescriptorAlloc)(envHandle, handle, handleType, arraySize, 0, NULL); - return dpiError__check(error, status, NULL, "allocate descriptors"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "allocate descriptors"); } @@ -672,11 +753,12 @@ int dpiOci__attrGet(const void *handle, uint32_t handleType, void *ptr, { int status; + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnAttrGet)(handle, handleType, ptr, size, attribute, error->handle); - if (action) - return dpiError__check(error, status, NULL, action); - return DPI_SUCCESS; + if (!action) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, action); } @@ -689,11 +771,12 @@ int dpiOci__attrSet(void *handle, uint32_t handleType, void *ptr, { int status; + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnAttrSet)(handle, handleType, ptr, size, attribute, error->handle); - if (action) - return dpiError__check(error, status, NULL, action); - return DPI_SUCCESS; + if (!action) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, action); } @@ -707,6 +790,7 @@ int dpiOci__bindByName(dpiStmt *stmt, void **bindHandle, const char *name, int status; DPI_OCI_LOAD_SYMBOL("OCIBindByName", dpiOciSymbols.fnBindByName) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBindByName)(stmt->handle, bindHandle, error->handle, name, nameLength, (dynamicBind) ? NULL : var->buffer.data.asRaw, @@ -719,7 +803,7 @@ int dpiOci__bindByName(dpiStmt *stmt, void **bindHandle, const char *name, (var->isArray) ? var->buffer.maxArraySize : 0, (var->isArray) ? &var->buffer.actualArraySize : NULL, (dynamicBind) ? DPI_OCI_DATA_AT_EXEC : DPI_OCI_DEFAULT); - return dpiError__check(error, status, stmt->conn, "bind by name"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "bind by name"); } @@ -733,6 +817,7 @@ int dpiOci__bindByName2(dpiStmt *stmt, void **bindHandle, const char *name, int status; DPI_OCI_LOAD_SYMBOL("OCIBindByName2", dpiOciSymbols.fnBindByName2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBindByName2)(stmt->handle, bindHandle, error->handle, name, nameLength, (dynamicBind) ? NULL : var->buffer.data.asRaw, @@ -745,7 +830,7 @@ int dpiOci__bindByName2(dpiStmt *stmt, void **bindHandle, const char *name, (var->isArray) ? var->buffer.maxArraySize : 0, (var->isArray) ? &var->buffer.actualArraySize : NULL, (dynamicBind) ? DPI_OCI_DATA_AT_EXEC : DPI_OCI_DEFAULT); - return dpiError__check(error, status, stmt->conn, "bind by name"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "bind by name"); } @@ -759,6 +844,7 @@ int dpiOci__bindByPos(dpiStmt *stmt, void **bindHandle, uint32_t pos, int status; DPI_OCI_LOAD_SYMBOL("OCIBindByPos", dpiOciSymbols.fnBindByPos) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBindByPos)(stmt->handle, bindHandle, error->handle, pos, (dynamicBind) ? NULL : var->buffer.data.asRaw, (var->isDynamic) ? INT_MAX : (int32_t) var->sizeInBytes, @@ -770,7 +856,7 @@ int dpiOci__bindByPos(dpiStmt *stmt, void **bindHandle, uint32_t pos, (var->isArray) ? var->buffer.maxArraySize : 0, (var->isArray) ? &var->buffer.actualArraySize : NULL, (dynamicBind) ? DPI_OCI_DATA_AT_EXEC : DPI_OCI_DEFAULT); - return dpiError__check(error, status, stmt->conn, "bind by position"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "bind by position"); } @@ -784,6 +870,7 @@ int dpiOci__bindByPos2(dpiStmt *stmt, void **bindHandle, uint32_t pos, int status; DPI_OCI_LOAD_SYMBOL("OCIBindByPos2", dpiOciSymbols.fnBindByPos2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBindByPos2)(stmt->handle, bindHandle, error->handle, pos, (dynamicBind) ? NULL : var->buffer.data.asRaw, (var->isDynamic) ? INT_MAX : var->sizeInBytes, @@ -795,7 +882,7 @@ int dpiOci__bindByPos2(dpiStmt *stmt, void **bindHandle, uint32_t pos, (var->isArray) ? var->buffer.maxArraySize : 0, (var->isArray) ? &var->buffer.actualArraySize : NULL, (dynamicBind) ? DPI_OCI_DATA_AT_EXEC : DPI_OCI_DEFAULT); - return dpiError__check(error, status, stmt->conn, "bind by position"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "bind by position"); } @@ -808,10 +895,11 @@ int dpiOci__bindDynamic(dpiVar *var, void *bindHandle, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIBindDynamic", dpiOciSymbols.fnBindDynamic) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBindDynamic)(bindHandle, error->handle, var, (void*) dpiVar__inBindCallback, var, (void*) dpiVar__outBindCallback); - return dpiError__check(error, status, var->conn, "bind dynamic"); + DPI_OCI_CHECK_AND_RETURN(error, status, var->conn, "bind dynamic"); } @@ -824,10 +912,11 @@ int dpiOci__bindObject(dpiVar *var, void *bindHandle, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIBindObject", dpiOciSymbols.fnBindObject) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBindObject)(bindHandle, error->handle, var->objectType->tdo, (void**) var->buffer.data.asRaw, 0, var->buffer.objectIndicator, 0); - return dpiError__check(error, status, var->conn, "bind object"); + DPI_OCI_CHECK_AND_RETURN(error, status, var->conn, "bind object"); } @@ -840,8 +929,9 @@ int dpiOci__break(dpiConn *conn, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIBreak", dpiOciSymbols.fnBreak) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnBreak)(conn->handle, error->handle); - return dpiError__check(error, status, conn, "break execution"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "break execution"); } @@ -866,9 +956,10 @@ int dpiOci__collAppend(dpiConn *conn, const void *elem, const void *elemInd, int status; DPI_OCI_LOAD_SYMBOL("OCICollAppend", dpiOciSymbols.fnCollAppend) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnCollAppend)(conn->env->handle, error->handle, elem, elemInd, coll); - return dpiError__check(error, status, conn, "append element"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "append element"); } @@ -882,9 +973,10 @@ int dpiOci__collAssignElem(dpiConn *conn, int32_t index, const void *elem, int status; DPI_OCI_LOAD_SYMBOL("OCICollAssignElem", dpiOciSymbols.fnCollAssignElem) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnCollAssignElem)(conn->env->handle, error->handle, index, elem, elemInd, coll); - return dpiError__check(error, status, conn, "assign element"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "assign element"); } @@ -898,9 +990,10 @@ int dpiOci__collGetElem(dpiConn *conn, void *coll, int32_t index, int *exists, int status; DPI_OCI_LOAD_SYMBOL("OCICollGetElem", dpiOciSymbols.fnCollGetElem) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnCollGetElem)(conn->env->handle, error->handle, coll, index, exists, elem, elemInd); - return dpiError__check(error, status, conn, "get element"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get element"); } @@ -913,9 +1006,10 @@ int dpiOci__collSize(dpiConn *conn, void *coll, int32_t *size, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCICollSize", dpiOciSymbols.fnCollSize) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnCollSize)(conn->env->handle, error->handle, coll, size); - return dpiError__check(error, status, conn, "get size"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get size"); } @@ -929,9 +1023,10 @@ int dpiOci__collTrim(dpiConn *conn, uint32_t numToTrim, void *coll, int status; DPI_OCI_LOAD_SYMBOL("OCICollTrim", dpiOciSymbols.fnCollTrim) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnCollTrim)(conn->env->handle, error->handle, (int32_t) numToTrim, coll); - return dpiError__check(error, status, conn, "trim"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "trim"); } @@ -945,11 +1040,12 @@ int dpiOci__contextGetValue(dpiConn *conn, const char *key, uint32_t keyLength, int status; DPI_OCI_LOAD_SYMBOL("OCIContextGetValue", dpiOciSymbols.fnContextGetValue) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnContextGetValue)(conn->sessionHandle, error->handle, key, (uint8_t) keyLength, value); - if (checkError) - return dpiError__check(error, status, conn, "get context value"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get context value"); } @@ -963,12 +1059,13 @@ int dpiOci__contextSetValue(dpiConn *conn, const char *key, uint32_t keyLength, int status; DPI_OCI_LOAD_SYMBOL("OCIContextSetValue", dpiOciSymbols.fnContextSetValue) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnContextSetValue)(conn->sessionHandle, error->handle, DPI_OCI_DURATION_SESSION, key, (uint8_t) keyLength, value); - if (checkError) - return dpiError__check(error, status, conn, "set context value"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "set context value"); } @@ -985,10 +1082,28 @@ int dpiOci__dateTimeConstruct(void *envHandle, void *handle, int16_t year, DPI_OCI_LOAD_SYMBOL("OCIDateTimeConstruct", dpiOciSymbols.fnDateTimeConstruct) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDateTimeConstruct)(envHandle, error->handle, handle, year, month, day, hour, minute, second, fsecond, tz, tzLength); - return dpiError__check(error, status, NULL, "construct date"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "construct date"); +} + + +//----------------------------------------------------------------------------- +// dpiOci__dateTimeConvert() [INTERNAL] +// Wrapper for OCIDateTimeConvert(). +//----------------------------------------------------------------------------- +int dpiOci__dateTimeConvert(void *envHandle, void *inDate, void *outDate, + dpiError *error) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCIDateTimeConvert", dpiOciSymbols.fnDateTimeConvert) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnDateTimeConvert)(envHandle, error->handle, + inDate, outDate); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "convert date"); } @@ -1002,9 +1117,10 @@ int dpiOci__dateTimeGetDate(void *envHandle, void *handle, int16_t *year, int status; DPI_OCI_LOAD_SYMBOL("OCIDateTimeGetDate", dpiOciSymbols.fnDateTimeGetDate) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDateTimeGetDate)(envHandle, error->handle, handle, year, month, day); - return dpiError__check(error, status, NULL, "get date portion"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get date portion"); } @@ -1018,9 +1134,10 @@ int dpiOci__dateTimeGetTime(void *envHandle, void *handle, uint8_t *hour, int status; DPI_OCI_LOAD_SYMBOL("OCIDateTimeGetTime", dpiOciSymbols.fnDateTimeGetTime) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDateTimeGetTime)(envHandle, error->handle, handle, hour, minute, second, fsecond); - return dpiError__check(error, status, NULL, "get time portion"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get time portion"); } @@ -1035,9 +1152,10 @@ int dpiOci__dateTimeGetTimeZoneOffset(void *envHandle, void *handle, DPI_OCI_LOAD_SYMBOL("OCIDateTimeGetTimeZoneOffset", dpiOciSymbols.fnDateTimeGetTimeZoneOffset) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDateTimeGetTimeZoneOffset)(envHandle, error->handle, handle, tzHourOffset, tzMinuteOffset); - return dpiError__check(error, status, NULL, "get time zone portion"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get time zone portion"); } @@ -1052,9 +1170,10 @@ int dpiOci__dateTimeIntervalAdd(void *envHandle, void *handle, void *interval, DPI_OCI_LOAD_SYMBOL("OCIDateTimeIntervalAdd", dpiOciSymbols.fnDateTimeIntervalAdd) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDateTimeIntervalAdd)(envHandle, error->handle, handle, interval, outHandle); - return dpiError__check(error, status, NULL, "add interval to date"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "add interval to date"); } @@ -1069,9 +1188,10 @@ int dpiOci__dateTimeSubtract(void *envHandle, void *handle1, void *handle2, DPI_OCI_LOAD_SYMBOL("OCIDateTimeSubtract", dpiOciSymbols.fnDateTimeSubtract) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDateTimeSubtract)(envHandle, error->handle, handle1, handle2, interval); - return dpiError__check(error, status, NULL, "subtract date"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "subtract date"); } @@ -1084,9 +1204,10 @@ int dpiOci__dbShutdown(dpiConn *conn, uint32_t mode, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIDBShutdown", dpiOciSymbols.fnDbShutdown) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDbShutdown)(conn->handle, error->handle, NULL, mode); - return dpiError__check(error, status, NULL, "shutdown database"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "shutdown database"); } @@ -1099,9 +1220,10 @@ int dpiOci__dbStartup(dpiConn *conn, uint32_t mode, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIDBStartup", dpiOciSymbols.fnDbStartup) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDbStartup)(conn->handle, error->handle, NULL, DPI_OCI_DEFAULT, mode); - return dpiError__check(error, status, NULL, "startup database"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "startup database"); } @@ -1115,6 +1237,7 @@ int dpiOci__defineByPos(dpiStmt *stmt, void **defineHandle, uint32_t pos, int status; DPI_OCI_LOAD_SYMBOL("OCIDefineByPos", dpiOciSymbols.fnDefineByPos) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDefineByPos)(stmt->handle, defineHandle, error->handle, pos, (var->isDynamic) ? NULL : var->buffer.data.asRaw, @@ -1124,7 +1247,7 @@ int dpiOci__defineByPos(dpiStmt *stmt, void **defineHandle, uint32_t pos, (var->isDynamic) ? NULL : var->buffer.actualLength16, (var->isDynamic) ? NULL : var->buffer.returnCode, (var->isDynamic) ? DPI_OCI_DYNAMIC_FETCH : DPI_OCI_DEFAULT); - return dpiError__check(error, status, stmt->conn, "define"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "define"); } @@ -1138,6 +1261,7 @@ int dpiOci__defineByPos2(dpiStmt *stmt, void **defineHandle, uint32_t pos, int status; DPI_OCI_LOAD_SYMBOL("OCIDefineByPos2", dpiOciSymbols.fnDefineByPos2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDefineByPos2)(stmt->handle, defineHandle, error->handle, pos, (var->isDynamic) ? NULL : var->buffer.data.asRaw, @@ -1147,7 +1271,7 @@ int dpiOci__defineByPos2(dpiStmt *stmt, void **defineHandle, uint32_t pos, (var->isDynamic) ? NULL : var->buffer.actualLength32, (var->isDynamic) ? NULL : var->buffer.returnCode, (var->isDynamic) ? DPI_OCI_DYNAMIC_FETCH : DPI_OCI_DEFAULT); - return dpiError__check(error, status, stmt->conn, "define"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "define"); } @@ -1160,9 +1284,10 @@ int dpiOci__defineDynamic(dpiVar *var, void *defineHandle, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIDefineDynamic", dpiOciSymbols.fnDefineDynamic) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDefineDynamic)(defineHandle, error->handle, var, (void*) dpiVar__defineCallback); - return dpiError__check(error, status, var->conn, "define dynamic"); + DPI_OCI_CHECK_AND_RETURN(error, status, var->conn, "define dynamic"); } @@ -1175,10 +1300,11 @@ int dpiOci__defineObject(dpiVar *var, void *defineHandle, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIDefineObject", dpiOciSymbols.fnDefineObject) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDefineObject)(defineHandle, error->handle, var->objectType->tdo, (void**) var->buffer.data.asRaw, 0, var->buffer.objectIndicator, 0); - return dpiError__check(error, status, var->conn, "define object"); + DPI_OCI_CHECK_AND_RETURN(error, status, var->conn, "define object"); } @@ -1192,9 +1318,10 @@ int dpiOci__describeAny(dpiConn *conn, void *obj, uint32_t objLength, int status; DPI_OCI_LOAD_SYMBOL("OCIDescribeAny", dpiOciSymbols.fnDescribeAny) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnDescribeAny)(conn->handle, error->handle, obj, objLength, objType, 0, DPI_OCI_PTYPE_TYPE, describeHandle); - return dpiError__check(error, status, conn, "describe type"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "describe type"); } @@ -1210,7 +1337,7 @@ int dpiOci__descriptorAlloc(void *envHandle, void **handle, DPI_OCI_LOAD_SYMBOL("OCIDescriptorAlloc", dpiOciSymbols.fnDescriptorAlloc) status = (*dpiOciSymbols.fnDescriptorAlloc)(envHandle, handle, handleType, 0, NULL); - return dpiError__check(error, status, NULL, action); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, action); } @@ -1314,7 +1441,7 @@ int dpiOci__errorGet(void *handle, uint32_t handleType, uint16_t charsetId, // Wrapper for OCI allocation of memory, only used when debugging memory // allocation. //----------------------------------------------------------------------------- -static void dpiOci__freeMem(void *unused, void *ptr) +static void dpiOci__freeMem(UNUSED void *unused, void *ptr) { char message[40]; @@ -1338,7 +1465,7 @@ int dpiOci__handleAlloc(void *envHandle, void **handle, uint32_t handleType, NULL); if (handleType == DPI_OCI_HTYPE_ERROR && status != DPI_OCI_SUCCESS) return dpiError__set(error, action, DPI_ERR_NO_MEMORY); - return dpiError__check(error, status, NULL, action); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, action); } @@ -1372,9 +1499,10 @@ int dpiOci__intervalGetDaySecond(void *envHandle, int32_t *day, int32_t *hour, DPI_OCI_LOAD_SYMBOL("OCIIntervalGetDaySecond", dpiOciSymbols.fnIntervalGetDaySecond) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnIntervalGetDaySecond)(envHandle, error->handle, day, hour, minute, second, fsecond, interval); - return dpiError__check(error, status, NULL, "get interval components"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get interval components"); } @@ -1389,9 +1517,10 @@ int dpiOci__intervalGetYearMonth(void *envHandle, int32_t *year, DPI_OCI_LOAD_SYMBOL("OCIIntervalGetYearMonth", dpiOciSymbols.fnIntervalGetYearMonth) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnIntervalGetYearMonth)(envHandle, error->handle, year, month, interval); - return dpiError__check(error, status, NULL, "get interval components"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get interval components"); } @@ -1407,9 +1536,10 @@ int dpiOci__intervalSetDaySecond(void *envHandle, int32_t day, int32_t hour, DPI_OCI_LOAD_SYMBOL("OCIIntervalSetDaySecond", dpiOciSymbols.fnIntervalSetDaySecond) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnIntervalSetDaySecond)(envHandle, error->handle, day, hour, minute, second, fsecond, interval); - return dpiError__check(error, status, NULL, "set interval components"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "set interval components"); } @@ -1424,9 +1554,10 @@ int dpiOci__intervalSetYearMonth(void *envHandle, int32_t year, int32_t month, DPI_OCI_LOAD_SYMBOL("OCIIntervalSetYearMonth", dpiOciSymbols.fnIntervalSetYearMonth) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnIntervalSetYearMonth)(envHandle, error->handle, year, month, interval); - return dpiError__check(error, status, NULL, "set interval components"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "set interval components"); } @@ -1713,13 +1844,17 @@ static int dpiOci__loadLibValidate(dpiError *error) // determine the OCI client version information if (dpiOci__loadSymbol("OCIClientVersion", (void**) &dpiOciSymbols.fnClientVersion, NULL) < 0) - return dpiError__set(error, "check Oracle Client version", - DPI_ERR_ORACLE_CLIENT_TOO_OLD, 0, 0, 11, 2); + return dpiError__set(error, "load symbol OCIClientVersion", + DPI_ERR_ORACLE_CLIENT_UNSUPPORTED); + memset(&dpiOciLibVersionInfo, 0, sizeof(dpiOciLibVersionInfo)); (*dpiOciSymbols.fnClientVersion)(&dpiOciLibVersionInfo.versionNum, &dpiOciLibVersionInfo.releaseNum, &dpiOciLibVersionInfo.updateNum, &dpiOciLibVersionInfo.portReleaseNum, &dpiOciLibVersionInfo.portUpdateNum); + if (dpiOciLibVersionInfo.versionNum == 0) + return dpiError__set(error, "get OCI client version", + DPI_ERR_ORACLE_CLIENT_UNSUPPORTED); dpiOciLibVersionInfo.fullVersionNum = (uint32_t) DPI_ORACLE_VERSION_TO_NUMBER(dpiOciLibVersionInfo.versionNum, dpiOciLibVersionInfo.releaseNum, @@ -1785,9 +1920,10 @@ int dpiOci__lobClose(dpiLob *lob, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobClose", dpiOciSymbols.fnLobClose) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobClose)(lob->conn->handle, error->handle, lob->locator); - return dpiError__check(error, status, lob->conn, "close LOB"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "close LOB"); } @@ -1802,13 +1938,14 @@ int dpiOci__lobCreateTemporary(dpiLob *lob, dpiError *error) DPI_OCI_LOAD_SYMBOL("OCILobCreateTemporary", dpiOciSymbols.fnLobCreateTemporary) + DPI_OCI_ENSURE_ERROR_HANDLE(error) if (lob->type->oracleTypeNum == DPI_ORACLE_TYPE_BLOB) lobType = DPI_OCI_TEMP_BLOB; else lobType = DPI_OCI_TEMP_CLOB; status = (*dpiOciSymbols.fnLobCreateTemporary)(lob->conn->handle, error->handle, lob->locator, DPI_OCI_DEFAULT, lob->type->charsetForm, lobType, 1, DPI_OCI_DURATION_SESSION); - return dpiError__check(error, status, lob->conn, "create temporary LOB"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "create temporary LOB"); } @@ -1821,9 +1958,10 @@ int dpiOci__lobFileExists(dpiLob *lob, int *exists, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobFileExists", dpiOciSymbols.fnLobFileExists) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobFileExists)(lob->conn->handle, error->handle, lob->locator, exists); - return dpiError__check(error, status, lob->conn, "get file exists"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "get file exists"); } @@ -1838,9 +1976,10 @@ int dpiOci__lobFileGetName(dpiLob *lob, char *dirAlias, int status; DPI_OCI_LOAD_SYMBOL("OCILobFileGetName", dpiOciSymbols.fnLobFileGetName) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobFileGetName)(lob->env->handle, error->handle, lob->locator, dirAlias, dirAliasLength, name, nameLength); - return dpiError__check(error, status, lob->conn, "get LOB file name"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "get LOB file name"); } @@ -1855,9 +1994,10 @@ int dpiOci__lobFileSetName(dpiLob *lob, const char *dirAlias, int status; DPI_OCI_LOAD_SYMBOL("OCILobFileSetName", dpiOciSymbols.fnLobFileSetName) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobFileSetName)(lob->env->handle, error->handle, &lob->locator, dirAlias, dirAliasLength, name, nameLength); - return dpiError__check(error, status, lob->conn, "set LOB file name"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "set LOB file name"); } @@ -1872,11 +2012,12 @@ int dpiOci__lobFreeTemporary(dpiConn *conn, void *lobLocator, int checkError, DPI_OCI_LOAD_SYMBOL("OCILobFreeTemporary", dpiOciSymbols.fnLobFreeTemporary) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobFreeTemporary)(conn->handle, error->handle, lobLocator); - if (checkError) - return dpiError__check(error, status, conn, "free temporary LOB"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "free temporary LOB"); } @@ -1889,9 +2030,10 @@ int dpiOci__lobGetChunkSize(dpiLob *lob, uint32_t *size, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobGetChunkSize", dpiOciSymbols.fnLobGetChunkSize) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobGetChunkSize)(lob->conn->handle, error->handle, lob->locator, size); - return dpiError__check(error, status, lob->conn, "get chunk size"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "get chunk size"); } @@ -1904,9 +2046,10 @@ int dpiOci__lobGetLength2(dpiLob *lob, uint64_t *size, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobGetLength2", dpiOciSymbols.fnLobGetLength2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobGetLength2)(lob->conn->handle, error->handle, lob->locator, size); - return dpiError__check(error, status, lob->conn, "get length"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "get length"); } @@ -1919,9 +2062,10 @@ int dpiOci__lobIsOpen(dpiLob *lob, int *isOpen, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobIsOpen", dpiOciSymbols.fnLobIsOpen) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobIsOpen)(lob->conn->handle, error->handle, lob->locator, isOpen); - return dpiError__check(error, status, lob->conn, "check is open"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "check is open"); } @@ -1936,11 +2080,12 @@ int dpiOci__lobIsTemporary(dpiLob *lob, int *isTemporary, int checkError, *isTemporary = 0; DPI_OCI_LOAD_SYMBOL("OCILobIsTemporary", dpiOciSymbols.fnLobIsTemporary) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobIsTemporary)(lob->env->handle, error->handle, lob->locator, isTemporary); - if (checkError) - return dpiError__check(error, status, lob->conn, "check is temporary"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "check is temporary"); } @@ -1954,9 +2099,10 @@ int dpiOci__lobLocatorAssign(dpiLob *lob, void **copiedHandle, dpiError *error) DPI_OCI_LOAD_SYMBOL("OCILobLocatorAssign", dpiOciSymbols.fnLobLocatorAssign) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobLocatorAssign)(lob->conn->handle, error->handle, lob->locator, copiedHandle); - return dpiError__check(error, status, lob->conn, "assign locator"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "assign locator"); } @@ -1970,11 +2116,12 @@ int dpiOci__lobOpen(dpiLob *lob, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobOpen", dpiOciSymbols.fnLobOpen) + DPI_OCI_ENSURE_ERROR_HANDLE(error) mode = (lob->type->oracleTypeNum == DPI_ORACLE_TYPE_BFILE) ? DPI_OCI_LOB_READONLY : DPI_OCI_LOB_READWRITE; status = (*dpiOciSymbols.fnLobOpen)(lob->conn->handle, error->handle, lob->locator, mode); - return dpiError__check(error, status, lob->conn, "close LOB"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "close LOB"); } @@ -1990,13 +2137,14 @@ int dpiOci__lobRead2(dpiLob *lob, uint64_t offset, uint64_t *amountInBytes, int status; DPI_OCI_LOAD_SYMBOL("OCILobRead2", dpiOciSymbols.fnLobRead2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) charsetId = (lob->type->charsetForm == DPI_SQLCS_NCHAR) ? lob->env->ncharsetId : lob->env->charsetId; status = (*dpiOciSymbols.fnLobRead2)(lob->conn->handle, error->handle, lob->locator, amountInBytes, amountInChars, offset, buffer, bufferLength, DPI_OCI_ONE_PIECE, NULL, NULL, charsetId, lob->type->charsetForm); - return dpiError__check(error, status, lob->conn, "read from LOB"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "read from LOB"); } @@ -2009,11 +2157,12 @@ int dpiOci__lobTrim2(dpiLob *lob, uint64_t newLength, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCILobTrim2", dpiOciSymbols.fnLobTrim2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnLobTrim2)(lob->conn->handle, error->handle, lob->locator, newLength); if (status == DPI_OCI_INVALID_HANDLE) return dpiOci__lobCreateTemporary(lob, error); - return dpiError__check(error, status, lob->conn, "trim LOB"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "trim LOB"); } @@ -2029,13 +2178,14 @@ int dpiOci__lobWrite2(dpiLob *lob, uint64_t offset, const char *value, int status; DPI_OCI_LOAD_SYMBOL("OCILobWrite2", dpiOciSymbols.fnLobWrite2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) charsetId = (lob->type->charsetForm == DPI_SQLCS_NCHAR) ? lob->env->ncharsetId : lob->env->charsetId; status = (*dpiOciSymbols.fnLobWrite2)(lob->conn->handle, error->handle, lob->locator, &lengthInBytes, &lengthInChars, offset, (void*) value, valueLength, DPI_OCI_ONE_PIECE, NULL, NULL, charsetId, lob->type->charsetForm); - return dpiError__check(error, status, lob->conn, "write to LOB"); + DPI_OCI_CHECK_AND_RETURN(error, status, lob->conn, "write to LOB"); } @@ -2050,11 +2200,12 @@ int dpiOci__memoryAlloc(dpiConn *conn, void **ptr, uint32_t size, *ptr = NULL; DPI_OCI_LOAD_SYMBOL("OCIMemoryAlloc", dpiOciSymbols.fnMemoryAlloc) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnMemoryAlloc)(conn->sessionHandle, error->handle, ptr, DPI_OCI_DURATION_SESSION, size, DPI_OCI_MEMORY_CLEARED); - if (checkError) - return dpiError__check(error, status, conn, "allocate memory"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "allocate memory"); } @@ -2065,6 +2216,7 @@ int dpiOci__memoryAlloc(dpiConn *conn, void **ptr, uint32_t size, int dpiOci__memoryFree(dpiConn *conn, void *ptr, dpiError *error) { DPI_OCI_LOAD_SYMBOL("OCIMemoryFree", dpiOciSymbols.fnMemoryFree) + DPI_OCI_ENSURE_ERROR_HANDLE(error) (*dpiOciSymbols.fnMemoryFree)(conn->sessionHandle, error->handle, ptr); return DPI_SUCCESS; } @@ -2083,10 +2235,11 @@ int dpiOci__nlsCharSetConvert(void *envHandle, uint16_t destCharsetId, DPI_OCI_LOAD_SYMBOL("OCINlsCharSetConvert", dpiOciSymbols.fnNlsCharSetConvert) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnNlsCharSetConvert)(envHandle, error->handle, destCharsetId, dest, destLength, sourceCharsetId, source, sourceLength, resultSize); - return dpiError__check(error, status, NULL, "convert text"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "convert text"); } @@ -2169,9 +2322,10 @@ int dpiOci__nlsNumericInfoGet(void *envHandle, int32_t *value, uint16_t item, DPI_OCI_LOAD_SYMBOL("OCINlsNumericInfoGet", dpiOciSymbols.fnNlsNumericInfoGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnNlsNumericInfoGet)(envHandle, error->handle, value, item); - return dpiError__check(error, status, NULL, "get NLS info"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get NLS info"); } @@ -2185,9 +2339,10 @@ int dpiOci__numberFromInt(const void *value, unsigned int valueLength, int status; DPI_OCI_LOAD_SYMBOL("OCINumberFromInt", dpiOciSymbols.fnNumberFromInt) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnNumberFromInt)(error->handle, value, valueLength, flags, number); - return dpiError__check(error, status, NULL, "number from integer"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "number from integer"); } @@ -2200,9 +2355,10 @@ int dpiOci__numberFromReal(const double value, void *number, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCINumberFromReal", dpiOciSymbols.fnNumberFromReal) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnNumberFromReal)(error->handle, &value, sizeof(double), number); - return dpiError__check(error, status, NULL, "number from real"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "number from real"); } @@ -2216,9 +2372,10 @@ int dpiOci__numberToInt(void *number, void *value, unsigned int valueLength, int status; DPI_OCI_LOAD_SYMBOL("OCINumberToInt", dpiOciSymbols.fnNumberToInt) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnNumberToInt)(error->handle, number, valueLength, flags, value); - return dpiError__check(error, status, NULL, "number to integer"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "number to integer"); } @@ -2231,9 +2388,10 @@ int dpiOci__numberToReal(double *value, void *number, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCINumberToReal", dpiOciSymbols.fnNumberToReal) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnNumberToReal)(error->handle, number, sizeof(double), value); - return dpiError__check(error, status, NULL, "number to real"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "number to real"); } @@ -2247,11 +2405,12 @@ int dpiOci__objectCopy(dpiObject *obj, void *sourceInstance, int status; DPI_OCI_LOAD_SYMBOL("OCIObjectCopy", dpiOciSymbols.fnObjectCopy) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnObjectCopy)(obj->env->handle, error->handle, obj->type->conn->handle, sourceInstance, sourceIndicator, obj->instance, obj->indicator, obj->type->tdo, DPI_OCI_DURATION_SESSION, DPI_OCI_DEFAULT); - return dpiError__check(error, status, obj->type->conn, "copy object"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "copy object"); } @@ -2259,15 +2418,18 @@ int dpiOci__objectCopy(dpiObject *obj, void *sourceInstance, // dpiOci__objectFree() [INTERNAL] // Wrapper for OCIObjectFree(). //----------------------------------------------------------------------------- -int dpiOci__objectFree(dpiObject *obj, int checkError, dpiError *error) +int dpiOci__objectFree(void *envHandle, void *data, int checkError, + dpiError *error) { int status; DPI_OCI_LOAD_SYMBOL("OCIObjectFree", dpiOciSymbols.fnObjectFree) - status = (*dpiOciSymbols.fnObjectFree)(obj->env->handle, error->handle, - obj->instance, DPI_OCI_DEFAULT); - if (checkError && dpiError__check(error, status, obj->type->conn, - "free instance") < 0) { + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnObjectFree)(envHandle, error->handle, data, + DPI_OCI_DEFAULT); + if (checkError && DPI_OCI_ERROR_OCCURRED(status)) { + dpiError__setFromOCI(error, status, NULL, "free instance"); + // during the attempt to free, PL/SQL records fail with error // "ORA-21602: operation does not support the specified typecode", but // a subsequent attempt will yield error "OCI-21500: internal error @@ -2277,13 +2439,6 @@ int dpiOci__objectFree(dpiObject *obj, int checkError, dpiError *error) return DPI_SUCCESS; return DPI_FAILURE; } - if (obj->freeIndicator) { - status = (*dpiOciSymbols.fnObjectFree)(obj->env->handle, error->handle, - obj->indicator, DPI_OCI_DEFAULT); - if (checkError && dpiError__check(error, status, obj->type->conn, - "free indicator") < 0) - return DPI_FAILURE; - } return DPI_SUCCESS; } @@ -2299,11 +2454,12 @@ int dpiOci__objectGetAttr(dpiObject *obj, dpiObjectAttr *attr, int status; DPI_OCI_LOAD_SYMBOL("OCIObjectGetAttr", dpiOciSymbols.fnObjectGetAttr) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnObjectGetAttr)(obj->env->handle, error->handle, obj->instance, obj->indicator, obj->type->tdo, &attr->name, &attr->nameLength, 1, 0, 0, scalarValueIndicator, valueIndicator, value, tdo); - return dpiError__check(error, status, obj->type->conn, "get attribute"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "get attribute"); } @@ -2316,9 +2472,10 @@ int dpiOci__objectGetInd(dpiObject *obj, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIObjectGetInd", dpiOciSymbols.fnObjectGetInd) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnObjectGetInd)(obj->env->handle, error->handle, obj->instance, &obj->indicator); - return dpiError__check(error, status, obj->type->conn, "get indicator"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "get indicator"); } @@ -2331,10 +2488,11 @@ int dpiOci__objectNew(dpiObject *obj, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIObjectNew", dpiOciSymbols.fnObjectNew) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnObjectNew)(obj->env->handle, error->handle, obj->type->conn->handle, obj->type->typeCode, obj->type->tdo, NULL, DPI_OCI_DURATION_SESSION, 1, &obj->instance); - return dpiError__check(error, status, obj->type->conn, "create object"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "create object"); } @@ -2348,10 +2506,11 @@ int dpiOci__objectPin(void *envHandle, void *objRef, void **obj, int status; DPI_OCI_LOAD_SYMBOL("OCIObjectPin", dpiOciSymbols.fnObjectPin) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnObjectPin)(envHandle, error->handle, objRef, NULL, DPI_OCI_PIN_ANY, DPI_OCI_DURATION_SESSION, DPI_OCI_LOCK_NONE, obj); - return dpiError__check(error, status, NULL, "pin reference"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "pin reference"); } @@ -2366,11 +2525,12 @@ int dpiOci__objectSetAttr(dpiObject *obj, dpiObjectAttr *attr, int status; DPI_OCI_LOAD_SYMBOL("OCIObjectSetAttr", dpiOciSymbols.fnObjectSetAttr) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnObjectSetAttr)(obj->env->handle, error->handle, obj->instance, obj->indicator, obj->type->tdo, &attr->name, &attr->nameLength, 1, NULL, 0, scalarValueIndicator, valueIndicator, value); - return dpiError__check(error, status, obj->type->conn, "set attribute"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "set attribute"); } @@ -2386,10 +2546,11 @@ int dpiOci__passwordChange(dpiConn *conn, const char *userName, int status; DPI_OCI_LOAD_SYMBOL("OCIPasswordChange", dpiOciSymbols.fnPasswordChange) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnPasswordChange)(conn->handle, error->handle, userName, userNameLength, oldPassword, oldPasswordLength, newPassword, newPasswordLength, mode); - return dpiError__check(error, status, conn, "change password"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "change password"); } @@ -2403,9 +2564,10 @@ int dpiOci__paramGet(const void *handle, uint32_t handleType, void **parameter, int status; DPI_OCI_LOAD_SYMBOL("OCIParamGet", dpiOciSymbols.fnParamGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnParamGet)(handle, handleType, error->handle, parameter, pos); - return dpiError__check(error, status, NULL, action); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, action); } @@ -2418,17 +2580,21 @@ int dpiOci__ping(dpiConn *conn, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIPing", dpiOciSymbols.fnPing) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnPing)(conn->handle, error->handle, DPI_OCI_DEFAULT); - status = dpiError__check(error, status, conn, "ping"); + if (DPI_OCI_ERROR_OCCURRED(status)) { + dpiError__setFromOCI(error, status, conn, "ping"); - // attempting to ping a database earlier than 10g will result in error - // ORA-1010: invalid OCI operation, but that implies a successful ping - // so ignore that error and treat it as a successful operation - if (status < 0 && error->buffer->code == 1010) - return DPI_SUCCESS; + // attempting to ping a database earlier than 10g will result in error + // ORA-1010: invalid OCI operation, but that implies a successful ping + // so ignore that error and treat it as a successful operation + if (error->buffer->code == 1010) + return DPI_SUCCESS; + return DPI_FAILURE; + } - return status; + return DPI_SUCCESS; } @@ -2442,9 +2608,10 @@ int dpiOci__rawAssignBytes(void *envHandle, const char *value, int status; DPI_OCI_LOAD_SYMBOL("OCIRawAssignBytes", dpiOciSymbols.fnRawAssignBytes) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnRawAssignBytes)(envHandle, error->handle, value, valueLength, handle); - return dpiError__check(error, status, NULL, "assign bytes to raw"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "assign bytes to raw"); } @@ -2472,9 +2639,10 @@ int dpiOci__rawResize(void *envHandle, void **handle, uint32_t newSize, int status; DPI_OCI_LOAD_SYMBOL("OCIRawResize", dpiOciSymbols.fnRawResize) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnRawResize)(envHandle, error->handle, newSize, handle); - return dpiError__check(error, status, NULL, "resize raw"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "resize raw"); } @@ -2497,7 +2665,7 @@ int dpiOci__rawSize(void *envHandle, void *handle, uint32_t *size) // Wrapper for OCI allocation of memory, only used when debugging memory // allocation. //----------------------------------------------------------------------------- -static void *dpiOci__reallocMem(void *unused, void *ptr, size_t newSize) +static void *dpiOci__reallocMem(UNUSED void *unused, void *ptr, size_t newSize) { char message[80]; void *newPtr; @@ -2520,12 +2688,13 @@ int dpiOci__rowidToChar(dpiRowid *rowid, char *buffer, uint16_t *bufferSize, int status; DPI_OCI_LOAD_SYMBOL("OCIRowidToChar", dpiOciSymbols.fnRowidToChar) + DPI_OCI_ENSURE_ERROR_HANDLE(error) origSize = *bufferSize; status = (*dpiOciSymbols.fnRowidToChar)(rowid->handle, buffer, bufferSize, error->handle); if (origSize == 0) return DPI_SUCCESS; - return dpiError__check(error, status, NULL, "get rowid as string"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get rowid as string"); } @@ -2539,9 +2708,10 @@ int dpiOci__serverAttach(dpiConn *conn, const char *connectString, int status; DPI_OCI_LOAD_SYMBOL("OCIServerAttach", dpiOciSymbols.fnServerAttach) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnServerAttach)(conn->serverHandle, error->handle, connectString, (int32_t) connectStringLength, DPI_OCI_DEFAULT); - return dpiError__check(error, status, conn, "server attach"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "server attach"); } @@ -2554,11 +2724,12 @@ int dpiOci__serverDetach(dpiConn *conn, int checkError, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCIServerDetach", dpiOciSymbols.fnServerDetach) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnServerDetach)(conn->serverHandle, error->handle, DPI_OCI_DEFAULT); - if (checkError) - return dpiError__check(error, status, conn, "detatch from server"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "detatch from server"); } @@ -2571,6 +2742,7 @@ int dpiOci__serverRelease(dpiConn *conn, char *buffer, uint32_t bufferSize, { int status; + DPI_OCI_ENSURE_ERROR_HANDLE(error) if (conn->env->versionInfo->versionNum < 18) { DPI_OCI_LOAD_SYMBOL("OCIServerRelease", dpiOciSymbols.fnServerRelease) status = (*dpiOciSymbols.fnServerRelease)(conn->handle, error->handle, @@ -2582,7 +2754,7 @@ int dpiOci__serverRelease(dpiConn *conn, char *buffer, uint32_t bufferSize, buffer, bufferSize, DPI_OCI_HTYPE_SVCCTX, version, DPI_OCI_DEFAULT); } - return dpiError__check(error, status, conn, "get server version"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get server version"); } @@ -2596,9 +2768,10 @@ int dpiOci__sessionBegin(dpiConn *conn, uint32_t credentialType, int status; DPI_OCI_LOAD_SYMBOL("OCISessionBegin", dpiOciSymbols.fnSessionBegin) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSessionBegin)(conn->handle, error->handle, conn->sessionHandle, credentialType, mode); - return dpiError__check(error, status, conn, "begin session"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "begin session"); } @@ -2611,11 +2784,12 @@ int dpiOci__sessionEnd(dpiConn *conn, int checkError, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCISessionEnd", dpiOciSymbols.fnSessionEnd) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSessionEnd)(conn->handle, error->handle, conn->sessionHandle, DPI_OCI_DEFAULT); - if (checkError) - return dpiError__check(error, status, conn, "end session"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "end session"); } @@ -2631,10 +2805,11 @@ int dpiOci__sessionGet(void *envHandle, void **handle, void *authInfo, int status; DPI_OCI_LOAD_SYMBOL("OCISessionGet", dpiOciSymbols.fnSessionGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSessionGet)(envHandle, error->handle, handle, authInfo, connectString, connectStringLength, tag, tagLength, outTag, outTagLength, found, mode); - return dpiError__check(error, status, NULL, "get session"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "get session"); } @@ -2652,12 +2827,13 @@ int dpiOci__sessionPoolCreate(dpiPool *pool, const char *connectString, DPI_OCI_LOAD_SYMBOL("OCISessionPoolCreate", dpiOciSymbols.fnSessionPoolCreate) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSessionPoolCreate)(pool->env->handle, error->handle, pool->handle, (char**) &pool->name, &pool->nameLength, connectString, connectStringLength, minSessions, maxSessions, sessionIncrement, userName, userNameLength, password, passwordLength, mode); - return dpiError__check(error, status, NULL, "create pool"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "create pool"); } @@ -2673,6 +2849,7 @@ int dpiOci__sessionPoolDestroy(dpiPool *pool, uint32_t mode, int checkError, DPI_OCI_LOAD_SYMBOL("OCISessionPoolDestroy", dpiOciSymbols.fnSessionPoolDestroy) + DPI_OCI_ENSURE_ERROR_HANDLE(error) // clear the pool handle immediately so that no further attempts are made // to use the pool while the pool is being closed; if the pool close fails, @@ -2681,10 +2858,9 @@ int dpiOci__sessionPoolDestroy(dpiPool *pool, uint32_t mode, int checkError, pool->handle = NULL; status = (*dpiOciSymbols.fnSessionPoolDestroy)(handle, error->handle, mode); - if (checkError && - dpiError__check(error, status, NULL, "destroy pool") < 0) { + if (checkError && DPI_OCI_ERROR_OCCURRED(status)) { pool->handle = handle; - return DPI_FAILURE; + return dpiError__setFromOCI(error, status, NULL, "destroy pool"); } dpiOci__handleFree(handle, DPI_OCI_HTYPE_SPOOL); return DPI_SUCCESS; @@ -2701,11 +2877,12 @@ int dpiOci__sessionRelease(dpiConn *conn, const char *tag, uint32_t tagLength, int status; DPI_OCI_LOAD_SYMBOL("OCISessionRelease", dpiOciSymbols.fnSessionRelease) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSessionRelease)(conn->handle, error->handle, tag, tagLength, mode); - if (checkError) - return dpiError__check(error, status, conn, "release session"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "release session"); } @@ -2720,9 +2897,51 @@ int dpiOci__shardingKeyColumnAdd(void *shardingKey, void *col, uint32_t colLen, DPI_OCI_LOAD_SYMBOL("OCIShardingKeyColumnAdd", dpiOciSymbols.fnShardingKeyColumnAdd) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnShardingKeyColumnAdd)(shardingKey, error->handle, col, colLen, colType, DPI_OCI_DEFAULT); - return dpiError__check(error, status, NULL, "add sharding column"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "add sharding column"); +} + + +//----------------------------------------------------------------------------- +// dpiOci__sodaBulkInsert() [INTERNAL] +// Wrapper for OCISodaBulkInsert(). +//----------------------------------------------------------------------------- +int dpiOci__sodaBulkInsert(dpiSodaColl *coll, void **documents, + uint32_t numDocuments, void *outputOptions, uint32_t mode, + dpiError *error) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCISodaBulkInsert", dpiOciSymbols.fnSodaBulkInsert) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnSodaBulkInsert)(coll->db->conn->handle, + coll->handle, documents, numDocuments, outputOptions, + error->handle, mode); + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, + "insert multiple documents"); +} + + +//----------------------------------------------------------------------------- +// dpiOci__sodaBulkInsertAndGet() [INTERNAL] +// Wrapper for OCISodaBulkInsert(). +//----------------------------------------------------------------------------- +int dpiOci__sodaBulkInsertAndGet(dpiSodaColl *coll, void **documents, + uint32_t numDocuments, void *outputOptions, uint32_t mode, + dpiError *error) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCISodaBulkInsertAndGet", + dpiOciSymbols.fnSodaBulkInsertAndGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnSodaBulkInsertAndGet)(coll->db->conn->handle, + coll->handle, documents, numDocuments, outputOptions, + error->handle, mode); + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, + "insert (and get) multiple documents"); } @@ -2738,10 +2957,12 @@ int dpiOci__sodaCollCreateWithMetadata(dpiSodaDb *db, const char *name, DPI_OCI_LOAD_SYMBOL("OCISodaCollCreateWithMetadata", dpiOciSymbols.fnSodaCollCreateWithMetadata) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaCollCreateWithMetadata)(db->conn->handle, name, nameLength, metadata, metadataLength, handle, error->handle, mode); - return dpiError__check(error, status, db->conn, "create SODA collection"); + DPI_OCI_CHECK_AND_RETURN(error, status, db->conn, + "create SODA collection"); } @@ -2755,9 +2976,10 @@ int dpiOci__sodaCollDrop(dpiSodaColl *coll, int *isDropped, uint32_t mode, int status; DPI_OCI_LOAD_SYMBOL("OCISodaCollDrop", dpiOciSymbols.fnSodaCollDrop) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaCollDrop)(coll->db->conn->handle, coll->handle, isDropped, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "drop SODA collection"); } @@ -2772,13 +2994,14 @@ int dpiOci__sodaCollGetNext(dpiConn *conn, void *cursorHandle, int status; DPI_OCI_LOAD_SYMBOL("OCISodaCollGetNext", dpiOciSymbols.fnSodaCollGetNext) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaCollGetNext)(conn->handle, cursorHandle, collectionHandle, error->handle, mode); if (status == DPI_OCI_NO_DATA) { *collectionHandle = NULL; return DPI_SUCCESS; } - return dpiError__check(error, status, conn, "get next collection"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get next collection"); } @@ -2793,9 +3016,10 @@ int dpiOci__sodaCollList(dpiSodaDb *db, const char *startingName, int status; DPI_OCI_LOAD_SYMBOL("OCISodaCollList", dpiOciSymbols.fnSodaCollList) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaCollList)(db->conn->handle, startingName, startingNameLength, handle, error->handle, mode); - return dpiError__check(error, status, db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, db->conn, "get SODA collection cursor"); } @@ -2810,9 +3034,10 @@ int dpiOci__sodaCollOpen(dpiSodaDb *db, const char *name, uint32_t nameLength, int status; DPI_OCI_LOAD_SYMBOL("OCISodaCollOpen", dpiOciSymbols.fnSodaCollOpen) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaCollOpen)(db->conn->handle, name, nameLength, handle, error->handle, mode); - return dpiError__check(error, status, db->conn, "open SODA collection"); + DPI_OCI_CHECK_AND_RETURN(error, status, db->conn, "open SODA collection"); } @@ -2827,9 +3052,11 @@ int dpiOci__sodaDataGuideGet(dpiSodaColl *coll, void **handle, uint32_t mode, DPI_OCI_LOAD_SYMBOL("OCISodaDataGuideGet", dpiOciSymbols.fnSodaDataGuideGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaDataGuideGet)(coll->db->conn->handle, coll->handle, DPI_OCI_DEFAULT, handle, error->handle, mode); - if (dpiError__check(error, status, coll->db->conn, "get data guide") < 0) { + if (DPI_OCI_ERROR_OCCURRED(status)) { + dpiError__setFromOCI(error, status, coll->db->conn, "get data guide"); if (error->buffer->code != 24801) return DPI_FAILURE; *handle = NULL; @@ -2848,9 +3075,10 @@ int dpiOci__sodaDocCount(dpiSodaColl *coll, void *options, uint32_t mode, int status; DPI_OCI_LOAD_SYMBOL("OCISodaDocCount", dpiOciSymbols.fnSodaDocCount) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaDocCount)(coll->db->conn->handle, coll->handle, options, count, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "get document count"); } @@ -2865,13 +3093,14 @@ int dpiOci__sodaDocGetNext(dpiSodaDocCursor *cursor, void **handle, int status; DPI_OCI_LOAD_SYMBOL("OCISodaDocGetNext", dpiOciSymbols.fnSodaDocGetNext) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaDocGetNext)(cursor->coll->db->conn->handle, cursor->handle, handle, error->handle, mode); if (status == DPI_OCI_NO_DATA) { *handle = NULL; return DPI_SUCCESS; } - return dpiError__check(error, status, cursor->coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, cursor->coll->db->conn, "get next document"); } @@ -2886,13 +3115,14 @@ int dpiOci__sodaFind(dpiSodaColl *coll, const void *options, uint32_t flags, int status; DPI_OCI_LOAD_SYMBOL("OCISodaFind", dpiOciSymbols.fnSodaFind) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaFind)(coll->db->conn->handle, coll->handle, options, flags, handle, error->handle, mode); if (status == DPI_OCI_NO_DATA) { *handle = NULL; return DPI_SUCCESS; } - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "find SODA documents"); } @@ -2907,13 +3137,15 @@ int dpiOci__sodaFindOne(dpiSodaColl *coll, const void *options, uint32_t flags, int status; DPI_OCI_LOAD_SYMBOL("OCISodaFindOne", dpiOciSymbols.fnSodaFindOne) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaFindOne)(coll->db->conn->handle, coll->handle, options, flags, handle, error->handle, mode); if (status == DPI_OCI_NO_DATA) { *handle = NULL; return DPI_SUCCESS; } - return dpiError__check(error, status, coll->db->conn, "get SODA document"); + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, + "get SODA document"); } @@ -2927,9 +3159,10 @@ int dpiOci__sodaIndexCreate(dpiSodaColl *coll, const char *indexSpec, int status; DPI_OCI_LOAD_SYMBOL("OCISodaIndexCreate", dpiOciSymbols.fnSodaIndexCreate) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaIndexCreate)(coll->db->conn->handle, coll->handle, indexSpec, indexSpecLength, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, "create index"); + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "create index"); } @@ -2943,9 +3176,10 @@ int dpiOci__sodaIndexDrop(dpiSodaColl *coll, const char *name, int status; DPI_OCI_LOAD_SYMBOL("OCISodaIndexDrop", dpiOciSymbols.fnSodaIndexDrop) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaIndexDrop)(coll->db->conn->handle, name, nameLength, isDropped, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, "drop index"); + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "drop index"); } @@ -2959,9 +3193,10 @@ int dpiOci__sodaInsert(dpiSodaColl *coll, void *handle, uint32_t mode, int status; DPI_OCI_LOAD_SYMBOL("OCISodaInsert", dpiOciSymbols.fnSodaInsert) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaInsert)(coll->db->conn->handle, coll->handle, handle, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "insert SODA document"); } @@ -2977,9 +3212,10 @@ int dpiOci__sodaInsertAndGet(dpiSodaColl *coll, void **handle, uint32_t mode, DPI_OCI_LOAD_SYMBOL("OCISodaInsertAndGet", dpiOciSymbols.fnSodaInsertAndGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaInsertAndGet)(coll->db->conn->handle, coll->handle, handle, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "insert and get SODA document"); } @@ -2994,10 +3230,12 @@ int dpiOci__sodaOperKeysSet(const dpiSodaOperOptions *options, void *handle, int status; DPI_OCI_LOAD_SYMBOL("OCISodaOperKeysSet", dpiOciSymbols.fnSodaOperKeysSet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaOperKeysSet)(handle, options->keys, options->keyLengths, options->numKeys, error->handle, DPI_OCI_DEFAULT); - return dpiError__check(error, status, NULL, "set operation options keys"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, + "set operation options keys"); } @@ -3011,9 +3249,10 @@ int dpiOci__sodaRemove(dpiSodaColl *coll, void *options, uint32_t mode, int status; DPI_OCI_LOAD_SYMBOL("OCISodaRemove", dpiOciSymbols.fnSodaRemove) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaRemove)(coll->db->conn->handle, coll->handle, options, count, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "remove documents from SODA collection"); } @@ -3028,9 +3267,10 @@ int dpiOci__sodaReplOne(dpiSodaColl *coll, const void *options, void *handle, int status; DPI_OCI_LOAD_SYMBOL("OCISodaReplOne", dpiOciSymbols.fnSodaReplOne) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaReplOne)(coll->db->conn->handle, coll->handle, options, handle, isReplaced, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "replace SODA document"); } @@ -3046,9 +3286,10 @@ int dpiOci__sodaReplOneAndGet(dpiSodaColl *coll, const void *options, DPI_OCI_LOAD_SYMBOL("OCISodaReplOneAndGet", dpiOciSymbols.fnSodaReplOneAndGet) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSodaReplOneAndGet)(coll->db->conn->handle, coll->handle, options, handle, isReplaced, error->handle, mode); - return dpiError__check(error, status, coll->db->conn, + DPI_OCI_CHECK_AND_RETURN(error, status, coll->db->conn, "replace and get SODA document"); } @@ -3063,9 +3304,10 @@ int dpiOci__stmtExecute(dpiStmt *stmt, uint32_t numIters, uint32_t mode, int status; DPI_OCI_LOAD_SYMBOL("OCIStmtExecute", dpiOciSymbols.fnStmtExecute) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStmtExecute)(stmt->conn->handle, stmt->handle, error->handle, numIters, 0, 0, 0, mode); - return dpiError__check(error, status, stmt->conn, "execute"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "execute"); } @@ -3079,13 +3321,16 @@ int dpiOci__stmtFetch2(dpiStmt *stmt, uint32_t numRows, uint16_t fetchMode, int status; DPI_OCI_LOAD_SYMBOL("OCIStmtFetch2", dpiOciSymbols.fnStmtFetch2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStmtFetch2)(stmt->handle, error->handle, numRows, fetchMode, offset, DPI_OCI_DEFAULT); - if (status == DPI_OCI_NO_DATA || fetchMode == DPI_MODE_FETCH_LAST) + if (status == DPI_OCI_NO_DATA || fetchMode == DPI_MODE_FETCH_LAST) { stmt->hasRowsToFetch = 0; - else if (dpiError__check(error, status, stmt->conn, "fetch") < 0) - return DPI_FAILURE; - else stmt->hasRowsToFetch = 1; + } else if (DPI_OCI_ERROR_OCCURRED(status)) { + return dpiError__setFromOCI(error, status, stmt->conn, "fetch"); + } else { + stmt->hasRowsToFetch = 1; + } return DPI_SUCCESS; } @@ -3102,6 +3347,7 @@ int dpiOci__stmtGetBindInfo(dpiStmt *stmt, uint32_t size, uint32_t startLoc, int status; DPI_OCI_LOAD_SYMBOL("OCIStmtGetBindInfo", dpiOciSymbols.fnStmtGetBindInfo) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStmtGetBindInfo)(stmt->handle, error->handle, size, startLoc, numFound, names, nameLengths, indNames, indNameLengths, isDuplicate, bindHandles); @@ -3109,7 +3355,7 @@ int dpiOci__stmtGetBindInfo(dpiStmt *stmt, uint32_t size, uint32_t startLoc, *numFound = 0; return DPI_SUCCESS; } - return dpiError__check(error, status, stmt->conn, "get bind info"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "get bind info"); } @@ -3124,13 +3370,14 @@ int dpiOci__stmtGetNextResult(dpiStmt *stmt, void **handle, dpiError *error) DPI_OCI_LOAD_SYMBOL("OCIStmtGetNextResult", dpiOciSymbols.fnStmtGetNextResult) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStmtGetNextResult)(stmt->handle, error->handle, handle, &returnType, DPI_OCI_DEFAULT); if (status == DPI_OCI_NO_DATA) { *handle = NULL; return DPI_SUCCESS; } - return dpiError__check(error, status, stmt->conn, "get next result"); + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "get next result"); } @@ -3144,12 +3391,13 @@ int dpiOci__stmtPrepare2(dpiStmt *stmt, const char *sql, uint32_t sqlLength, int status; DPI_OCI_LOAD_SYMBOL("OCIStmtPrepare2", dpiOciSymbols.fnStmtPrepare2) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStmtPrepare2)(stmt->conn->handle, &stmt->handle, error->handle, sql, sqlLength, tag, tagLength, DPI_OCI_NTV_SYNTAX, DPI_OCI_DEFAULT); - if (dpiError__check(error, status, stmt->conn, "prepare SQL") < 0) { + if (DPI_OCI_ERROR_OCCURRED(status)) { stmt->handle = NULL; - return DPI_FAILURE; + return dpiError__setFromOCI(error, status, stmt->conn, "prepare SQL"); } return DPI_SUCCESS; @@ -3178,11 +3426,12 @@ int dpiOci__stmtRelease(dpiStmt *stmt, const char *tag, uint32_t tagLength, } DPI_OCI_LOAD_SYMBOL("OCIStmtRelease", dpiOciSymbols.fnStmtRelease) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStmtRelease)(stmt->handle, error->handle, tag, tagLength, mode); - if (checkError) - return dpiError__check(error, status, stmt->conn, "release statement"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, stmt->conn, "release statement"); } @@ -3197,9 +3446,10 @@ int dpiOci__stringAssignText(void *envHandle, const char *value, DPI_OCI_LOAD_SYMBOL("OCIStringAssignText", dpiOciSymbols.fnStringAssignText) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStringAssignText)(envHandle, error->handle, value, valueLength, handle); - return dpiError__check(error, status, NULL, "assign to string"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "assign to string"); } @@ -3227,9 +3477,10 @@ int dpiOci__stringResize(void *envHandle, void **handle, uint32_t newSize, int status; DPI_OCI_LOAD_SYMBOL("OCIStringResize", dpiOciSymbols.fnStringResize) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnStringResize)(envHandle, error->handle, newSize, handle); - return dpiError__check(error, status, NULL, "resize string"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "resize string"); } @@ -3251,15 +3502,17 @@ int dpiOci__stringSize(void *envHandle, void *handle, uint32_t *size) // dpiOci__subscriptionRegister() [INTERNAL] // Wrapper for OCISubscriptionRegister(). //----------------------------------------------------------------------------- -int dpiOci__subscriptionRegister(dpiConn *conn, void **handle, dpiError *error) +int dpiOci__subscriptionRegister(dpiConn *conn, void **handle, uint32_t mode, + dpiError *error) { int status; DPI_OCI_LOAD_SYMBOL("OCISubscriptionRegister", dpiOciSymbols.fnSubscriptionRegister) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnSubscriptionRegister)(conn->handle, handle, 1, - error->handle, DPI_OCI_DEFAULT); - return dpiError__check(error, status, conn, "register"); + error->handle, mode); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "register"); } @@ -3270,13 +3523,17 @@ int dpiOci__subscriptionRegister(dpiConn *conn, void **handle, dpiError *error) int dpiOci__subscriptionUnRegister(dpiConn *conn, dpiSubscr *subscr, dpiError *error) { + uint32_t mode; int status; DPI_OCI_LOAD_SYMBOL("OCISubscriptionUnRegister", dpiOciSymbols.fnSubscriptionUnRegister) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + mode = (subscr->clientInitiated) ? DPI_OCI_SECURE_NOTIFICATION : + DPI_OCI_DEFAULT; status = (*dpiOciSymbols.fnSubscriptionUnRegister)(conn->handle, - subscr->handle, error->handle, DPI_OCI_DEFAULT); - return dpiError__check(error, status, conn, "unregister"); + subscr->handle, error->handle, mode); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "unregister"); } @@ -3289,9 +3546,10 @@ int dpiOci__tableDelete(dpiObject *obj, int32_t index, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITableDelete", dpiOciSymbols.fnTableDelete) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTableDelete)(obj->env->handle, error->handle, index, obj->instance); - return dpiError__check(error, status, obj->type->conn, "delete element"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "delete element"); } @@ -3305,9 +3563,11 @@ int dpiOci__tableExists(dpiObject *obj, int32_t index, int *exists, int status; DPI_OCI_LOAD_SYMBOL("OCITableExists", dpiOciSymbols.fnTableExists) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTableExists)(obj->env->handle, error->handle, obj->instance, index, exists); - return dpiError__check(error, status, obj->type->conn, "get index exists"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, + "get index exists"); } @@ -3320,9 +3580,11 @@ int dpiOci__tableFirst(dpiObject *obj, int32_t *index, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITableFirst", dpiOciSymbols.fnTableFirst) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTableFirst)(obj->env->handle, error->handle, obj->instance, index); - return dpiError__check(error, status, obj->type->conn, "get first index"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, + "get first index"); } @@ -3335,9 +3597,10 @@ int dpiOci__tableLast(dpiObject *obj, int32_t *index, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITableLast", dpiOciSymbols.fnTableLast) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTableLast)(obj->env->handle, error->handle, obj->instance, index); - return dpiError__check(error, status, obj->type->conn, "get last index"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "get last index"); } @@ -3351,9 +3614,10 @@ int dpiOci__tableNext(dpiObject *obj, int32_t index, int32_t *nextIndex, int status; DPI_OCI_LOAD_SYMBOL("OCITableNext", dpiOciSymbols.fnTableNext) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTableNext)(obj->env->handle, error->handle, index, obj->instance, nextIndex, exists); - return dpiError__check(error, status, obj->type->conn, "get next index"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "get next index"); } @@ -3367,9 +3631,10 @@ int dpiOci__tablePrev(dpiObject *obj, int32_t index, int32_t *prevIndex, int status; DPI_OCI_LOAD_SYMBOL("OCITablePrev", dpiOciSymbols.fnTablePrev) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTablePrev)(obj->env->handle, error->handle, index, obj->instance, prevIndex, exists); - return dpiError__check(error, status, obj->type->conn, "get prev index"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "get prev index"); } @@ -3382,9 +3647,10 @@ int dpiOci__tableSize(dpiObject *obj, int32_t *size, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITableSize", dpiOciSymbols.fnTableSize) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTableSize)(obj->env->handle, error->handle, obj->instance, size); - return dpiError__check(error, status, obj->type->conn, "get size"); + DPI_OCI_CHECK_AND_RETURN(error, status, obj->type->conn, "get size"); } @@ -3431,7 +3697,7 @@ int dpiOci__threadKeyInit(void *envHandle, void *errorHandle, void **key, DPI_OCI_LOAD_SYMBOL("OCIThreadKeyInit", dpiOciSymbols.fnThreadKeyInit) status = (*dpiOciSymbols.fnThreadKeyInit)(envHandle, errorHandle, key, destroyFunc); - return dpiError__check(error, status, NULL, "initialize thread key"); + DPI_OCI_CHECK_AND_RETURN(error, status, NULL, "initialize thread key"); } @@ -3462,9 +3728,10 @@ int dpiOci__transCommit(dpiConn *conn, uint32_t flags, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITransCommit", dpiOciSymbols.fnTransCommit) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTransCommit)(conn->handle, error->handle, flags); - return dpiError__check(error, status, conn, "commit"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "commit"); } @@ -3477,10 +3744,11 @@ int dpiOci__transPrepare(dpiConn *conn, int *commitNeeded, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITransPrepare", dpiOciSymbols.fnTransPrepare) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTransPrepare)(conn->handle, error->handle, DPI_OCI_DEFAULT); *commitNeeded = (status == DPI_OCI_SUCCESS); - return dpiError__check(error, status, conn, "prepare transaction"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "prepare transaction"); } @@ -3493,11 +3761,12 @@ int dpiOci__transRollback(dpiConn *conn, int checkError, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITransRollback", dpiOciSymbols.fnTransRollback) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTransRollback)(conn->handle, error->handle, DPI_OCI_DEFAULT); - if (checkError) - return dpiError__check(error, status, conn, "rollback"); - return DPI_SUCCESS; + if (!checkError) + return DPI_SUCCESS; + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "rollback"); } @@ -3510,9 +3779,29 @@ int dpiOci__transStart(dpiConn *conn, dpiError *error) int status; DPI_OCI_LOAD_SYMBOL("OCITransStart", dpiOciSymbols.fnTransStart) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTransStart)(conn->handle, error->handle, 0, DPI_OCI_TRANS_NEW); - return dpiError__check(error, status, conn, "start transaction"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "start transaction"); +} + + +//----------------------------------------------------------------------------- +// dpiOci__typeByName() [INTERNAL] +// Wrapper for OCITypeByName(). +//----------------------------------------------------------------------------- +int dpiOci__typeByName(dpiConn *conn, const char *schema, + uint32_t schemaLength, const char *name, uint32_t nameLength, + void **tdo, dpiError *error) +{ + int status; + + DPI_OCI_LOAD_SYMBOL("OCITypeByName", dpiOciSymbols.fnTypeByName) + DPI_OCI_ENSURE_ERROR_HANDLE(error) + status = (*dpiOciSymbols.fnTypeByName)(conn->env->handle, error->handle, + conn->handle, schema, schemaLength, name, nameLength, NULL, 0, + DPI_OCI_DURATION_SESSION, DPI_OCI_TYPEGET_ALL, tdo); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get type by name"); } @@ -3526,9 +3815,9 @@ int dpiOci__typeByFullName(dpiConn *conn, const char *name, int status; DPI_OCI_LOAD_SYMBOL("OCITypeByFullName", dpiOciSymbols.fnTypeByFullName) + DPI_OCI_ENSURE_ERROR_HANDLE(error) status = (*dpiOciSymbols.fnTypeByFullName)(conn->env->handle, error->handle, conn->handle, name, nameLength, NULL, 0, DPI_OCI_DURATION_SESSION, DPI_OCI_TYPEGET_ALL, tdo); - return dpiError__check(error, status, conn, "get type by full name"); + DPI_OCI_CHECK_AND_RETURN(error, status, conn, "get type by full name"); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiOracleType.c b/vendor/github.com/godror/godror/odpi/src/dpiOracleType.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiOracleType.c rename to vendor/github.com/godror/godror/odpi/src/dpiOracleType.c index 7397d8f5253..ee307a7d995 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiOracleType.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiOracleType.c @@ -298,12 +298,14 @@ static dpiOracleTypeNum dpiOracleType__convertFromOracle(uint16_t typeCode, if (charsetForm == DPI_SQLCS_NCHAR) return DPI_ORACLE_TYPE_NVARCHAR; return DPI_ORACLE_TYPE_VARCHAR; + case DPI_SQLT_INT: case DPI_SQLT_FLT: case DPI_SQLT_NUM: case DPI_SQLT_PDN: case DPI_SQLT_VNU: case DPI_SQLT_BFLOAT: case DPI_SQLT_BDOUBLE: + case DPI_OCI_TYPECODE_SMALLINT: return DPI_ORACLE_TYPE_NUMBER; case DPI_SQLT_DAT: case DPI_SQLT_ODT: @@ -315,8 +317,8 @@ static dpiOracleTypeNum dpiOracleType__convertFromOracle(uint16_t typeCode, if (charsetForm == DPI_SQLCS_NCHAR) return DPI_ORACLE_TYPE_NCHAR; return DPI_ORACLE_TYPE_CHAR; - case DPI_SQLT_INT: - case DPI_OCI_TYPECODE_SMALLINT: + case DPI_OCI_TYPECODE_BINARY_INTEGER: + case DPI_OCI_TYPECODE_PLS_INTEGER: return DPI_ORACLE_TYPE_NATIVE_INT; case DPI_SQLT_IBFLOAT: return DPI_ORACLE_TYPE_NATIVE_FLOAT; @@ -344,6 +346,7 @@ static dpiOracleTypeNum dpiOracleType__convertFromOracle(uint16_t typeCode, case DPI_SQLT_BFILE: return DPI_ORACLE_TYPE_BFILE; case DPI_SQLT_RDD: + case DPI_OCI_TYPECODE_ROWID: return DPI_ORACLE_TYPE_ROWID; case DPI_SQLT_RSET: return DPI_ORACLE_TYPE_STMT; @@ -352,8 +355,10 @@ static dpiOracleTypeNum dpiOracleType__convertFromOracle(uint16_t typeCode, case DPI_SQLT_INTERVAL_YM: return DPI_ORACLE_TYPE_INTERVAL_YM; case DPI_SQLT_LNG: + case DPI_OCI_TYPECODE_LONG: return DPI_ORACLE_TYPE_LONG_VARCHAR; case DPI_SQLT_LBI: + case DPI_OCI_TYPECODE_LONG_RAW: return DPI_ORACLE_TYPE_LONG_RAW; } return (dpiOracleTypeNum) 0; @@ -497,4 +502,3 @@ int dpiOracleType__populateTypeInfo(dpiConn *conn, void *handle, return DPI_SUCCESS; } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiPool.c b/vendor/github.com/godror/godror/odpi/src/dpiPool.c similarity index 96% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiPool.c rename to vendor/github.com/godror/godror/odpi/src/dpiPool.c index 9d237767163..58f21e5efc9 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiPool.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiPool.c @@ -30,6 +30,7 @@ int dpiPool__acquireConnection(dpiPool *pool, const char *userName, if (dpiGen__allocate(DPI_HTYPE_CONN, pool->env, (void**) &tempConn, error) < 0) return DPI_FAILURE; + error->env = pool->env; // create the connection if (dpiConn__create(tempConn, pool->env->context, userName, userNameLength, @@ -52,7 +53,7 @@ int dpiPool__acquireConnection(dpiPool *pool, const char *userName, static int dpiPool__checkConnected(dpiPool *pool, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(pool, DPI_HTYPE_POOL, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(pool, DPI_HTYPE_POOL, fnName, error) < 0) return DPI_FAILURE; if (!pool->handle) return dpiError__set(error, "check pool", DPI_ERR_NOT_CONNECTED); @@ -158,6 +159,17 @@ static int dpiPool__create(dpiPool *pool, const char *userName, return DPI_FAILURE; } + // set the maximum number of sessions per shard (valid in 18.3 and higher) + if (pool->env->versionInfo->versionNum > 18 || + (pool->env->versionInfo->versionNum == 18 && + pool->env->versionInfo->releaseNum >= 3)) { + if (dpiOci__attrSet(pool->handle, DPI_OCI_HTYPE_SPOOL, (void*) + &createParams->maxSessionsPerShard, 0, + DPI_OCI_ATTR_SPOOL_MAX_PER_SHARD, + "set max sessions per shard", error) < 0) + return DPI_FAILURE; + } + // set reamining attributes directly pool->homogeneous = createParams->homogeneous; pool->externalAuth = createParams->externalAuth; @@ -359,7 +371,7 @@ int dpiPool_create(const dpiContext *context, const char *userName, dpiError error; // validate parameters - if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, 0, + if (dpiGen__startPublicFn(context, DPI_HTYPE_CONTEXT, __func__, &error) < 0) return dpiGen__endPublicFn(context, DPI_FAILURE, &error); DPI_CHECK_PTR_AND_LENGTH(context, userName) @@ -387,7 +399,7 @@ int dpiPool_create(const dpiContext *context, const char *userName, return dpiGen__endPublicFn(context, DPI_FAILURE, &error); // initialize environment - if (dpiEnv__init(tempPool->env, context, commonParams, &error) < 0) { + if (dpiEnv__init(tempPool->env, context, commonParams, NULL, &error) < 0) { dpiPool__free(tempPool, &error); return dpiGen__endPublicFn(context, DPI_FAILURE, &error); } @@ -403,8 +415,7 @@ int dpiPool_create(const dpiContext *context, const char *userName, createParams->outPoolName = tempPool->name; createParams->outPoolNameLength = tempPool->nameLength; *pool = tempPool; - dpiHandlePool__release(tempPool->env->errorHandles, error.handle, &error); - error.handle = NULL; + dpiHandlePool__release(tempPool->env->errorHandles, &error.handle); return dpiGen__endPublicFn(context, DPI_SUCCESS, &error); } @@ -573,4 +584,3 @@ int dpiPool_setWaitTimeout(dpiPool *pool, uint32_t value) return dpiPool__setAttributeUint(pool, DPI_OCI_ATTR_SPOOL_WAIT_TIMEOUT, value, __func__); } - diff --git a/vendor/github.com/godror/godror/odpi/src/dpiQueue.c b/vendor/github.com/godror/godror/odpi/src/dpiQueue.c new file mode 100644 index 00000000000..9c2f39a9a82 --- /dev/null +++ b/vendor/github.com/godror/godror/odpi/src/dpiQueue.c @@ -0,0 +1,560 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. +// This program is free software: you can modify it and/or redistribute it +// under the terms of: +// +// (i) the Universal Permissive License v 1.0 or at your option, any +// later version (http://oss.oracle.com/licenses/upl); and/or +// +// (ii) the Apache License v 2.0. (http://www.apache.org/licenses/LICENSE-2.0) +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// dpiQueue.c +// Implementation of AQ queues. +//----------------------------------------------------------------------------- + +#include "dpiImpl.h" + +// forward declarations of internal functions only used in this file +static int dpiQueue__allocateBuffer(dpiQueue *queue, uint32_t numElements, + dpiError *error); +static int dpiQueue__deq(dpiQueue *queue, uint32_t *numProps, + dpiMsgProps **props, dpiError *error); +static void dpiQueue__freeBuffer(dpiQueue *queue, dpiError *error); +static int dpiQueue__getPayloadTDO(dpiQueue *queue, void **tdo, + dpiError *error); + + +//----------------------------------------------------------------------------- +// dpiQueue__allocate() [INTERNAL] +// Allocate and initialize a queue. +//----------------------------------------------------------------------------- +int dpiQueue__allocate(dpiConn *conn, const char *name, uint32_t nameLength, + dpiObjectType *payloadType, dpiQueue **queue, dpiError *error) +{ + dpiQueue *tempQueue; + char *buffer; + + // allocate handle; store reference to the connection that created it + if (dpiGen__allocate(DPI_HTYPE_QUEUE, conn->env, (void**) &tempQueue, + error) < 0) + return DPI_FAILURE; + dpiGen__setRefCount(conn, error, 1); + tempQueue->conn = conn; + + // store payload type, which is either an object type or NULL (meaning that + // RAW payloads are being enqueued and dequeued) + if (payloadType) { + dpiGen__setRefCount(payloadType, error, 1); + tempQueue->payloadType = payloadType; + } + + // allocate space for the name of the queue; OCI requires a NULL-terminated + // string so allocate enough space to store the NULL terminator; UTF-16 + // encoded strings are not currently supported + if (dpiUtils__allocateMemory(1, nameLength + 1, 0, "queue name", + (void**) &buffer, error) < 0) { + dpiQueue__free(tempQueue, error); + return DPI_FAILURE; + } + memcpy(buffer, name, nameLength); + buffer[nameLength] = '\0'; + tempQueue->name = buffer; + + *queue = tempQueue; + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__allocateBuffer() [INTERNAL] +// Ensure there is enough space in the buffer for the specified number of +// elements. +//----------------------------------------------------------------------------- +static int dpiQueue__allocateBuffer(dpiQueue *queue, uint32_t numElements, + dpiError *error) +{ + dpiQueue__freeBuffer(queue, error); + queue->buffer.numElements = numElements; + if (dpiUtils__allocateMemory(numElements, sizeof(dpiMsgProps*), 1, + "allocate msg props array", (void**) &queue->buffer.props, + error) < 0) + return DPI_FAILURE; + if (dpiUtils__allocateMemory(numElements, sizeof(void*), 1, + "allocate OCI handles array", (void**) &queue->buffer.handles, + error) < 0) + return DPI_FAILURE; + if (dpiUtils__allocateMemory(numElements, sizeof(void*), 1, + "allocate OCI instances array", (void**) &queue->buffer.instances, + error) < 0) + return DPI_FAILURE; + if (dpiUtils__allocateMemory(numElements, sizeof(void*), 1, + "allocate OCI indicators array", + (void**) &queue->buffer.indicators, error) < 0) + return DPI_FAILURE; + if (!queue->payloadType) { + if (dpiUtils__allocateMemory(numElements, sizeof(int16_t), 1, + "allocate OCI raw indicators array", + (void**) &queue->buffer.rawIndicators, error) < 0) + return DPI_FAILURE; + } + if (dpiUtils__allocateMemory(numElements, sizeof(void*), 1, + "allocate message ids array", (void**) &queue->buffer.msgIds, + error) < 0) + return DPI_FAILURE; + + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__check() [INTERNAL] +// Determine if the queue is available to use. +//----------------------------------------------------------------------------- +static int dpiQueue__check(dpiQueue *queue, const char *fnName, + dpiError *error) +{ + if (dpiGen__startPublicFn(queue, DPI_HTYPE_QUEUE, fnName, error) < 0) + return DPI_FAILURE; + if (!queue->conn->handle || queue->conn->closing) + return dpiError__set(error, "check connection", DPI_ERR_NOT_CONNECTED); + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__createDeqOptions() [INTERNAL] +// Create the dequeue options object that will be used for performing +// dequeues against the queue. +//----------------------------------------------------------------------------- +static int dpiQueue__createDeqOptions(dpiQueue *queue, dpiError *error) +{ + dpiDeqOptions *tempOptions; + + if (dpiGen__allocate(DPI_HTYPE_DEQ_OPTIONS, queue->env, + (void**) &tempOptions, error) < 0) + return DPI_FAILURE; + if (dpiDeqOptions__create(tempOptions, queue->conn, error) < 0) { + dpiDeqOptions__free(tempOptions, error); + return DPI_FAILURE; + } + + queue->deqOptions = tempOptions; + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__createEnqOptions() [INTERNAL] +// Create the dequeue options object that will be used for performing +// dequeues against the queue. +//----------------------------------------------------------------------------- +static int dpiQueue__createEnqOptions(dpiQueue *queue, dpiError *error) +{ + dpiEnqOptions *tempOptions; + + if (dpiGen__allocate(DPI_HTYPE_ENQ_OPTIONS, queue->env, + (void**) &tempOptions, error) < 0) + return DPI_FAILURE; + if (dpiEnqOptions__create(tempOptions, queue->conn, error) < 0) { + dpiEnqOptions__free(tempOptions, error); + return DPI_FAILURE; + } + + queue->enqOptions = tempOptions; + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__deq() [INTERNAL] +// Perform a dequeue of up to the specified number of properties. +//----------------------------------------------------------------------------- +static int dpiQueue__deq(dpiQueue *queue, uint32_t *numProps, + dpiMsgProps **props, dpiError *error) +{ + dpiMsgProps *prop; + void *payloadTDO; + uint32_t i; + + // create dequeue options, if necessary + if (!queue->deqOptions && dpiQueue__createDeqOptions(queue, error) < 0) + return DPI_FAILURE; + + // allocate buffer, if necessary + if (queue->buffer.numElements < *numProps && + dpiQueue__allocateBuffer(queue, *numProps, error) < 0) + return DPI_FAILURE; + + // populate buffer + for (i = 0; i < *numProps; i++) { + prop = queue->buffer.props[i]; + + // create new message properties, if applicable + if (!prop) { + if (dpiMsgProps__allocate(queue->conn, &prop, error) < 0) + return DPI_FAILURE; + queue->buffer.props[i] = prop; + } + + // create payload object, if applicable + if (queue->payloadType && !prop->payloadObj && + dpiObject__allocate(queue->payloadType, NULL, NULL, NULL, + &prop->payloadObj, error) < 0) + return DPI_FAILURE; + + // set OCI arrays + queue->buffer.handles[i] = prop->handle; + if (queue->payloadType) { + queue->buffer.instances[i] = prop->payloadObj->instance; + queue->buffer.indicators[i] = prop->payloadObj->indicator; + } else { + queue->buffer.instances[i] = prop->payloadRaw; + queue->buffer.indicators[i] = &queue->buffer.rawIndicators[i]; + } + queue->buffer.msgIds[i] = prop->msgIdRaw; + + } + + // perform dequeue + if (dpiQueue__getPayloadTDO(queue, &payloadTDO, error) < 0) + return DPI_FAILURE; + if (dpiOci__aqDeqArray(queue->conn, queue->name, queue->deqOptions->handle, + numProps, queue->buffer.handles, payloadTDO, + queue->buffer.instances, queue->buffer.indicators, + queue->buffer.msgIds, error) < 0) { + if (error->buffer->code != 25228) + return DPI_FAILURE; + error->buffer->offset = (uint16_t) *numProps; + } + + // transfer message properties to destination array + for (i = 0; i < *numProps; i++) { + props[i] = queue->buffer.props[i]; + queue->buffer.props[i] = NULL; + if (!queue->payloadType) + props[i]->payloadRaw = queue->buffer.instances[i]; + props[i]->msgIdRaw = queue->buffer.msgIds[i]; + } + + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__enq() [INTERNAL] +// Perform an enqueue of the specified properties. +//----------------------------------------------------------------------------- +static int dpiQueue__enq(dpiQueue *queue, uint32_t numProps, + dpiMsgProps **props, dpiError *error) +{ + void *payloadTDO; + uint32_t i; + + // if no messages are being enqueued, nothing to do! + if (numProps == 0) + return DPI_SUCCESS; + + // create enqueue options, if necessary + if (!queue->enqOptions && dpiQueue__createEnqOptions(queue, error) < 0) + return DPI_FAILURE; + + // allocate buffer, if necessary + if (queue->buffer.numElements < numProps && + dpiQueue__allocateBuffer(queue, numProps, error) < 0) + return DPI_FAILURE; + + // populate buffer + for (i = 0; i < numProps; i++) { + + // perform checks + if (!props[i]->payloadObj && !props[i]->payloadRaw) + return dpiError__set(error, "check payload", + DPI_ERR_QUEUE_NO_PAYLOAD); + if ((queue->payloadType && !props[i]->payloadObj) || + (!queue->payloadType && props[i]->payloadObj)) + return dpiError__set(error, "check payload", + DPI_ERR_QUEUE_WRONG_PAYLOAD_TYPE); + if (queue->payloadType && props[i]->payloadObj && + queue->payloadType->tdo != props[i]->payloadObj->type->tdo) + return dpiError__set(error, "check payload", + DPI_ERR_WRONG_TYPE, + props[i]->payloadObj->type->schemaLength, + props[i]->payloadObj->type->schema, + props[i]->payloadObj->type->nameLength, + props[i]->payloadObj->type->name, + queue->payloadType->schemaLength, + queue->payloadType->schema, + queue->payloadType->nameLength, + queue->payloadType->name); + + // set OCI arrays + queue->buffer.handles[i] = props[i]->handle; + if (queue->payloadType) { + queue->buffer.instances[i] = props[i]->payloadObj->instance; + queue->buffer.indicators[i] = props[i]->payloadObj->indicator; + } else { + queue->buffer.instances[i] = props[i]->payloadRaw; + queue->buffer.indicators[i] = &queue->buffer.rawIndicators[i]; + } + queue->buffer.msgIds[i] = props[i]->msgIdRaw; + + } + + // perform enqueue + if (dpiQueue__getPayloadTDO(queue, &payloadTDO, error) < 0) + return DPI_FAILURE; + if (numProps == 1) { + if (dpiOci__aqEnq(queue->conn, queue->name, queue->enqOptions->handle, + queue->buffer.handles[0], payloadTDO, queue->buffer.instances, + queue->buffer.indicators, queue->buffer.msgIds, error) < 0) + return DPI_FAILURE; + } else { + if (dpiOci__aqEnqArray(queue->conn, queue->name, + queue->enqOptions->handle, &numProps, queue->buffer.handles, + payloadTDO, queue->buffer.instances, queue->buffer.indicators, + queue->buffer.msgIds, error) < 0) { + error->buffer->offset = (uint16_t) numProps; + return DPI_FAILURE; + } + } + + // transfer message ids back to message properties + for (i = 0; i < numProps; i++) + props[i]->msgIdRaw = queue->buffer.msgIds[i]; + + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue__free() [INTERNAL] +// Free the memory for a queue. +//----------------------------------------------------------------------------- +void dpiQueue__free(dpiQueue *queue, dpiError *error) +{ + if (queue->conn) { + dpiGen__setRefCount(queue->conn, error, -1); + queue->conn = NULL; + } + if (queue->payloadType) { + dpiGen__setRefCount(queue->payloadType, error, -1); + queue->payloadType = NULL; + } + if (queue->name) { + dpiUtils__freeMemory((void*) queue->name); + queue->name = NULL; + } + if (queue->deqOptions) { + dpiGen__setRefCount(queue->deqOptions, error, -1); + queue->deqOptions = NULL; + } + if (queue->enqOptions) { + dpiGen__setRefCount(queue->enqOptions, error, -1); + queue->enqOptions = NULL; + } + dpiQueue__freeBuffer(queue, error); + dpiUtils__freeMemory(queue); +} + + +//----------------------------------------------------------------------------- +// dpiQueue__freeBuffer() [INTERNAL] +// Free the memory areas in the queue buffer. +//----------------------------------------------------------------------------- +static void dpiQueue__freeBuffer(dpiQueue *queue, dpiError *error) +{ + dpiQueueBuffer *buffer = &queue->buffer; + uint32_t i; + + if (buffer->props) { + for (i = 0; i < buffer->numElements; i++) { + if (buffer->props[i]) { + dpiGen__setRefCount(buffer->props[i], error, -1); + buffer->props[i] = NULL; + } + } + dpiUtils__freeMemory(buffer->props); + buffer->props = NULL; + } + if (buffer->handles) { + dpiUtils__freeMemory(buffer->handles); + buffer->handles = NULL; + } + if (buffer->instances) { + dpiUtils__freeMemory(buffer->instances); + buffer->instances = NULL; + } + if (buffer->indicators) { + dpiUtils__freeMemory(buffer->indicators); + buffer->indicators = NULL; + } + if (buffer->rawIndicators) { + dpiUtils__freeMemory(buffer->rawIndicators); + buffer->rawIndicators = NULL; + } + if (buffer->msgIds) { + dpiUtils__freeMemory(buffer->msgIds); + buffer->msgIds = NULL; + } +} + + +//----------------------------------------------------------------------------- +// dpiQueue__getPayloadTDO() [INTERNAL] +// Acquire the TDO to use for the payload. This will either be the TDO of the +// object type (if one was specified when the queue was created) or it will be +// the RAW TDO cached on the connection. +//----------------------------------------------------------------------------- +static int dpiQueue__getPayloadTDO(dpiQueue *queue, void **tdo, + dpiError *error) +{ + if (queue->payloadType) { + *tdo = queue->payloadType->tdo; + } else { + if (dpiConn__getRawTDO(queue->conn, error) < 0) + return DPI_FAILURE; + *tdo = queue->conn->rawTDO; + } + return DPI_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// dpiQueue_addRef() [PUBLIC] +// Add a reference to the queue. +//----------------------------------------------------------------------------- +int dpiQueue_addRef(dpiQueue *queue) +{ + return dpiGen__addRef(queue, DPI_HTYPE_QUEUE, __func__); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_deqMany() [PUBLIC] +// Dequeue multiple messages from the queue. +//----------------------------------------------------------------------------- +int dpiQueue_deqMany(dpiQueue *queue, uint32_t *numProps, dpiMsgProps **props) +{ + dpiError error; + int status; + + if (dpiQueue__check(queue, __func__, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(queue, numProps) + DPI_CHECK_PTR_NOT_NULL(queue, props) + status = dpiQueue__deq(queue, numProps, props, &error); + return dpiGen__endPublicFn(queue, status, &error); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_deqOne() [PUBLIC] +// Dequeue a single message from the queue. +//----------------------------------------------------------------------------- +int dpiQueue_deqOne(dpiQueue *queue, dpiMsgProps **props) +{ + uint32_t numProps = 1; + dpiError error; + + if (dpiQueue__check(queue, __func__, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(queue, props) + if (dpiQueue__deq(queue, &numProps, props, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + if (numProps == 0) + *props = NULL; + return dpiGen__endPublicFn(queue, DPI_SUCCESS, &error); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_enqMany() [PUBLIC] +// Enqueue multiple message to the queue. +//----------------------------------------------------------------------------- +int dpiQueue_enqMany(dpiQueue *queue, uint32_t numProps, dpiMsgProps **props) +{ + dpiError error; + uint32_t i; + int status; + + // validate parameters + if (dpiQueue__check(queue, __func__, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(queue, props) + for (i = 0; i < numProps; i++) { + if (dpiGen__checkHandle(props[i], DPI_HTYPE_MSG_PROPS, + "check message properties", &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + } + status = dpiQueue__enq(queue, numProps, props, &error); + return dpiGen__endPublicFn(queue, status, &error); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_enqOne() [PUBLIC] +// Enqueue a single message to the queue. +//----------------------------------------------------------------------------- +int dpiQueue_enqOne(dpiQueue *queue, dpiMsgProps *props) +{ + dpiError error; + int status; + + if (dpiQueue__check(queue, __func__, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + if (dpiGen__checkHandle(props, DPI_HTYPE_MSG_PROPS, + "check message properties", &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + status = dpiQueue__enq(queue, 1, &props, &error); + return dpiGen__endPublicFn(queue, status, &error); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_getDeqOptions() [PUBLIC] +// Return the dequeue options associated with the queue. If no dequeue +// options are currently associated with the queue, create them first. +//----------------------------------------------------------------------------- +int dpiQueue_getDeqOptions(dpiQueue *queue, dpiDeqOptions **options) +{ + dpiError error; + + if (dpiGen__startPublicFn(queue, DPI_HTYPE_QUEUE, __func__, &error) < 0) + return DPI_FAILURE; + DPI_CHECK_PTR_NOT_NULL(queue, options) + if (!queue->deqOptions && dpiQueue__createDeqOptions(queue, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + *options = queue->deqOptions; + return dpiGen__endPublicFn(queue, DPI_SUCCESS, &error); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_getEnqOptions() [PUBLIC] +// Return the enqueue options associated with the queue. If no enqueue +// options are currently associated with the queue, create them first. +//----------------------------------------------------------------------------- +int dpiQueue_getEnqOptions(dpiQueue *queue, dpiEnqOptions **options) +{ + dpiError error; + + if (dpiGen__startPublicFn(queue, DPI_HTYPE_QUEUE, __func__, &error) < 0) + return DPI_FAILURE; + DPI_CHECK_PTR_NOT_NULL(queue, options) + if (!queue->enqOptions && dpiQueue__createEnqOptions(queue, &error) < 0) + return dpiGen__endPublicFn(queue, DPI_FAILURE, &error); + *options = queue->enqOptions; + return dpiGen__endPublicFn(queue, DPI_SUCCESS, &error); +} + + +//----------------------------------------------------------------------------- +// dpiQueue_release() [PUBLIC] +// Release a reference to the queue. +//----------------------------------------------------------------------------- +int dpiQueue_release(dpiQueue *queue) +{ + return dpiGen__release(queue, DPI_HTYPE_QUEUE, __func__); +} diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiRowid.c b/vendor/github.com/godror/godror/odpi/src/dpiRowid.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiRowid.c rename to vendor/github.com/godror/godror/odpi/src/dpiRowid.c index f3de644deba..9bda49e7cd1 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiRowid.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiRowid.c @@ -78,8 +78,7 @@ int dpiRowid_getStringValue(dpiRowid *rowid, const char **value, dpiError error; uint16_t i; - if (dpiGen__startPublicFn(rowid, DPI_HTYPE_ROWID, __func__, 1, - &error) < 0) + if (dpiGen__startPublicFn(rowid, DPI_HTYPE_ROWID, __func__, &error) < 0) return dpiGen__endPublicFn(rowid, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(rowid, value) DPI_CHECK_PTR_NOT_NULL(rowid, valueLength) @@ -133,4 +132,3 @@ int dpiRowid_release(dpiRowid *rowid) { return dpiGen__release(rowid, DPI_HTYPE_ROWID, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaColl.c b/vendor/github.com/godror/godror/odpi/src/dpiSodaColl.c similarity index 84% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaColl.c rename to vendor/github.com/godror/godror/odpi/src/dpiSodaColl.c index a874e4b3f7e..b0a0ded7c34 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaColl.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiSodaColl.c @@ -57,7 +57,7 @@ int dpiSodaColl__allocate(dpiSodaDb *db, void *handle, dpiSodaColl **coll, static int dpiSodaColl__check(dpiSodaColl *coll, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(coll, DPI_HTYPE_SODA_COLL, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(coll, DPI_HTYPE_SODA_COLL, fnName, error) < 0) return DPI_FAILURE; if (!coll->db->conn->handle || coll->db->conn->closing) return dpiError__set(error, "check connection", DPI_ERR_NOT_CONNECTED); @@ -255,6 +255,85 @@ static int dpiSodaColl__getDocCount(dpiSodaColl *coll, } +//----------------------------------------------------------------------------- +// dpiSodaColl__insertMany() [INTERNAL] +// Insert multiple documents into the collection and return handles to the +// newly created documents, if desired. +//----------------------------------------------------------------------------- +static int dpiSodaColl__insertMany(dpiSodaColl *coll, uint32_t numDocs, + void **docHandles, uint32_t flags, dpiSodaDoc **insertedDocs, + dpiError *error) +{ + void *optionsHandle; + uint32_t i, j, mode; + uint64_t docCount; + int status; + + // create OCI output options handle + if (dpiOci__handleAlloc(coll->env->handle, &optionsHandle, + DPI_OCI_HTYPE_SODA_OUTPUT_OPTIONS, + "allocate SODA output options handle", error) < 0) + return DPI_FAILURE; + + // determine mode to pass + mode = DPI_OCI_DEFAULT; + if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT) + mode |= DPI_OCI_SODA_ATOMIC_COMMIT; + + // perform actual bulk insert + if (insertedDocs) { + status = dpiOci__sodaBulkInsertAndGet(coll, docHandles, numDocs, + optionsHandle, mode, error); + } else { + status = dpiOci__sodaBulkInsert(coll, docHandles, numDocs, + optionsHandle, mode, error); + } + + // on failure, determine the number of documents that were successfully + // inserted and store that information in the error buffer + if (status < 0) { + dpiOci__attrGet(optionsHandle, DPI_OCI_HTYPE_SODA_OUTPUT_OPTIONS, + (void*) &docCount, 0, DPI_OCI_ATTR_SODA_DOC_COUNT, + NULL, error); + error->buffer->offset = (uint16_t) docCount; + } + dpiOci__handleFree(optionsHandle, DPI_OCI_HTYPE_SODA_OUTPUT_OPTIONS); + + // on failure, if using the "AndGet" variant, any document handles that + // were created need to be freed + if (insertedDocs && status < 0) { + for (i = 0; i < numDocs; i++) { + if (docHandles[i]) { + dpiOci__handleFree(docHandles[i], DPI_OCI_HTYPE_SODA_DOCUMENT); + docHandles[i] = NULL; + } + } + } + if (status < 0) + return DPI_FAILURE; + + // return document handles, if desired + if (insertedDocs) { + for (i = 0; i < numDocs; i++) { + if (dpiSodaDoc__allocate(coll->db, docHandles[i], &insertedDocs[i], + error) < 0) { + for (j = 0; j < i; j++) { + dpiSodaDoc__free(insertedDocs[j], error); + insertedDocs[j] = NULL; + } + for (j = i; j < numDocs; j++) { + dpiOci__handleFree(docHandles[i], + DPI_OCI_HTYPE_SODA_DOCUMENT); + } + return DPI_FAILURE; + } + } + } + + return DPI_SUCCESS; +} + + //----------------------------------------------------------------------------- // dpiSodaColl__remove() [INTERNAL] // Internal method for removing documents from a collection. @@ -584,6 +663,53 @@ int dpiSodaColl_getName(dpiSodaColl *coll, const char **value, } +//----------------------------------------------------------------------------- +// dpiSodaColl_insertMany() [PUBLIC] +// Insert multiple documents into the collection and return handles to the +// newly created documents, if desired. +//----------------------------------------------------------------------------- +int dpiSodaColl_insertMany(dpiSodaColl *coll, uint32_t numDocs, + dpiSodaDoc **docs, uint32_t flags, dpiSodaDoc **insertedDocs) +{ + void **docHandles; + dpiError error; + uint32_t i; + int status; + + // validate parameters + if (dpiSodaColl__check(coll, __func__, &error) < 0) + return dpiGen__endPublicFn(coll, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(coll, docs) + if (numDocs == 0) { + dpiError__set(&error, "check num documents", DPI_ERR_ARRAY_SIZE_ZERO); + return dpiGen__endPublicFn(coll, DPI_FAILURE, &error); + } + for (i = 0; i < numDocs; i++) { + if (dpiGen__checkHandle(docs[i], DPI_HTYPE_SODA_DOC, "check document", + &error) < 0) + return dpiGen__endPublicFn(coll, DPI_FAILURE, &error); + } + + // bulk insert is only supported with Oracle Client 18.5+ + if (dpiUtils__checkClientVersion(coll->env->versionInfo, 18, 5, + &error) < 0) + return dpiGen__endPublicFn(coll, DPI_FAILURE, &error); + + // create and populate array to hold document handles + if (dpiUtils__allocateMemory(numDocs, sizeof(void*), 1, + "allocate document handles", (void**) &docHandles, &error) < 0) + return dpiGen__endPublicFn(coll, DPI_FAILURE, &error); + for (i = 0; i < numDocs; i++) + docHandles[i] = docs[i]->handle; + + // perform bulk insert + status = dpiSodaColl__insertMany(coll, numDocs, docHandles, flags, + insertedDocs, &error); + dpiUtils__freeMemory(docHandles); + return dpiGen__endPublicFn(coll, status, &error); +} + + //----------------------------------------------------------------------------- // dpiSodaColl_insertOne() [PUBLIC] // Insert a document into the collection and return a handle to the newly @@ -684,4 +810,3 @@ int dpiSodaColl_replaceOne(dpiSodaColl *coll, replacedDoc, &error); return dpiGen__endPublicFn(coll, status, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaCollCursor.c b/vendor/github.com/godror/godror/odpi/src/dpiSodaCollCursor.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaCollCursor.c rename to vendor/github.com/godror/godror/odpi/src/dpiSodaCollCursor.c index 2356b7b9cf9..f4e91a427cb 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaCollCursor.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiSodaCollCursor.c @@ -43,7 +43,7 @@ int dpiSodaCollCursor__allocate(dpiSodaDb *db, void *handle, static int dpiSodaCollCursor__check(dpiSodaCollCursor *cursor, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(cursor, DPI_HTYPE_SODA_COLL_CURSOR, fnName, 1, + if (dpiGen__startPublicFn(cursor, DPI_HTYPE_SODA_COLL_CURSOR, fnName, error) < 0) return DPI_FAILURE; if (!cursor->handle) @@ -142,4 +142,3 @@ int dpiSodaCollCursor_release(dpiSodaCollCursor *cursor) { return dpiGen__release(cursor, DPI_HTYPE_SODA_COLL_CURSOR, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDb.c b/vendor/github.com/godror/godror/odpi/src/dpiSodaDb.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDb.c rename to vendor/github.com/godror/godror/odpi/src/dpiSodaDb.c index f6c5cacaf30..0e1605a3507 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDb.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiSodaDb.c @@ -23,7 +23,7 @@ static int dpiSodaDb__checkConnected(dpiSodaDb *db, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(db, DPI_HTYPE_SODA_DB, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(db, DPI_HTYPE_SODA_DB, fnName, error) < 0) return DPI_FAILURE; if (!db->conn->handle || db->conn->closing) return dpiError__set(error, "check connection", DPI_ERR_NOT_CONNECTED); @@ -201,7 +201,7 @@ int dpiSodaDb_createCollection(dpiSodaDb *db, const char *name, //----------------------------------------------------------------------------- int dpiSodaDb_createDocument(dpiSodaDb *db, const char *key, uint32_t keyLength, const char *content, uint32_t contentLength, - const char *mediaType, uint32_t mediaTypeLength, uint32_t flags, + const char *mediaType, uint32_t mediaTypeLength, UNUSED uint32_t flags, dpiSodaDoc **doc) { int detectEncoding; @@ -429,4 +429,3 @@ int dpiSodaDb_release(dpiSodaDb *db) { return dpiGen__release(db, DPI_HTYPE_SODA_DB, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDoc.c b/vendor/github.com/godror/godror/odpi/src/dpiSodaDoc.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDoc.c rename to vendor/github.com/godror/godror/odpi/src/dpiSodaDoc.c index 1b144ee7a6a..b009e33a44a 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDoc.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiSodaDoc.c @@ -43,7 +43,7 @@ int dpiSodaDoc__allocate(dpiSodaDb *db, void *handle, dpiSodaDoc **doc, static int dpiSodaDoc__check(dpiSodaDoc *doc, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(doc, DPI_HTYPE_SODA_DOC, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(doc, DPI_HTYPE_SODA_DOC, fnName, error) < 0) return DPI_FAILURE; if (!doc->db->conn->handle || doc->db->conn->closing) return dpiError__set(error, "check connection", DPI_ERR_NOT_CONNECTED); @@ -229,4 +229,3 @@ int dpiSodaDoc_release(dpiSodaDoc *doc) { return dpiGen__release(doc, DPI_HTYPE_SODA_DOC, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDocCursor.c b/vendor/github.com/godror/godror/odpi/src/dpiSodaDocCursor.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDocCursor.c rename to vendor/github.com/godror/godror/odpi/src/dpiSodaDocCursor.c index a7d7999b43b..9bfd2bdbeea 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSodaDocCursor.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiSodaDocCursor.c @@ -43,7 +43,7 @@ int dpiSodaDocCursor__allocate(dpiSodaColl *coll, void *handle, static int dpiSodaDocCursor__check(dpiSodaDocCursor *cursor, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(cursor, DPI_HTYPE_SODA_DOC_CURSOR, fnName, 1, + if (dpiGen__startPublicFn(cursor, DPI_HTYPE_SODA_DOC_CURSOR, fnName, error) < 0) return DPI_FAILURE; if (!cursor->handle) @@ -142,4 +142,3 @@ int dpiSodaDocCursor_release(dpiSodaDocCursor *cursor) { return dpiGen__release(cursor, DPI_HTYPE_SODA_DOC_CURSOR, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiStmt.c b/vendor/github.com/godror/godror/odpi/src/dpiStmt.c similarity index 95% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiStmt.c rename to vendor/github.com/godror/godror/odpi/src/dpiStmt.c index 6cfd01fa187..cd3520b93b0 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiStmt.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiStmt.c @@ -212,9 +212,9 @@ static int dpiStmt__bind(dpiStmt *stmt, dpiVar *var, int addReference, //----------------------------------------------------------------------------- static int dpiStmt__check(dpiStmt *stmt, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(stmt, DPI_HTYPE_STMT, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(stmt, DPI_HTYPE_STMT, fnName, error) < 0) return DPI_FAILURE; - if (!stmt->handle) + if (!stmt->handle || (stmt->parentStmt && !stmt->parentStmt->handle)) return dpiError__set(error, "check closed", DPI_ERR_STMT_CLOSED); if (dpiConn__checkConnected(stmt->conn, error) < 0) return DPI_FAILURE; @@ -321,14 +321,19 @@ int dpiStmt__close(dpiStmt *stmt, const char *tag, uint32_t tagLength, dpiStmt__clearBatchErrors(stmt); dpiStmt__clearBindVars(stmt, error); dpiStmt__clearQueryVars(stmt, error); + if (stmt->lastRowid) + dpiGen__setRefCount(stmt->lastRowid, error, -1); if (stmt->handle) { - if (!stmt->conn->deadSession && stmt->conn->handle) { + if (stmt->parentStmt) { + dpiGen__setRefCount(stmt->parentStmt, error, -1); + stmt->parentStmt = NULL; + } else if (!stmt->conn->deadSession && stmt->conn->handle) { if (stmt->isOwned) dpiOci__handleFree(stmt->handle, DPI_OCI_HTYPE_STMT); else status = dpiOci__stmtRelease(stmt, tag, tagLength, propagateErrors, error); } - if (!stmt->conn->closing) + if (!stmt->conn->closing && !stmt->parentStmt) dpiHandleList__removeHandle(stmt->conn->openStmts, stmt->openSlotNum); stmt->handle = NULL; @@ -479,6 +484,7 @@ static int dpiStmt__define(dpiStmt *stmt, uint32_t pos, dpiVar *var, { void *defineHandle = NULL; dpiQueryInfo *queryInfo; + int tempBool; // no need to perform define if variable is unchanged if (stmt->queryVars[pos - 1] == var) @@ -513,6 +519,15 @@ static int dpiStmt__define(dpiStmt *stmt, uint32_t pos, dpiVar *var, return DPI_FAILURE; } + // specify that the LOB length should be prefetched + if (var->nativeTypeNum == DPI_NATIVE_TYPE_LOB) { + tempBool = 1; + if (dpiOci__attrSet(defineHandle, DPI_OCI_HTYPE_DEFINE, + (void*) &tempBool, 0, DPI_OCI_ATTR_LOBPREFETCH_LENGTH, + "set lob prefetch length", error) < 0) + return DPI_FAILURE; + } + // define objects, if applicable if (var->buffer.objectIndicator && dpiOci__defineObject(var, defineHandle, error) < 0) @@ -677,6 +692,10 @@ static int dpiStmt__fetch(dpiStmt *stmt, dpiError *error) void dpiStmt__free(dpiStmt *stmt, dpiError *error) { dpiStmt__close(stmt, NULL, 0, 0, error); + if (stmt->parentStmt) { + dpiGen__setRefCount(stmt->parentStmt, error, -1); + stmt->parentStmt = NULL; + } if (stmt->conn) { dpiGen__setRefCount(stmt->conn, error, -1); stmt->conn = NULL; @@ -753,7 +772,7 @@ static int dpiStmt__getBatchErrors(dpiStmt *stmt, dpiError *error) // get error message localError.buffer = &stmt->batchErrors[i]; localError.handle = batchErrorHandle; - dpiError__check(&localError, DPI_OCI_ERROR, stmt->conn, + dpiError__setFromOCI(&localError, DPI_OCI_ERROR, stmt->conn, "get batch error"); if (error->buffer->errorNum) { overallStatus = DPI_FAILURE; @@ -773,6 +792,42 @@ static int dpiStmt__getBatchErrors(dpiStmt *stmt, dpiError *error) } +//----------------------------------------------------------------------------- +// dpiStmt__getRowCount() [INTERNAL] +// Return the number of rows affected by the last DML executed (for insert, +// update, delete and merge) or the number of rows fetched (for queries). In +// all other cases, 0 is returned. +//----------------------------------------------------------------------------- +static int dpiStmt__getRowCount(dpiStmt *stmt, uint64_t *count, + dpiError *error) +{ + uint32_t rowCount32; + + if (stmt->statementType == DPI_STMT_TYPE_SELECT) + *count = stmt->rowCount; + else if (stmt->statementType != DPI_STMT_TYPE_INSERT && + stmt->statementType != DPI_STMT_TYPE_UPDATE && + stmt->statementType != DPI_STMT_TYPE_DELETE && + stmt->statementType != DPI_STMT_TYPE_MERGE && + stmt->statementType != DPI_STMT_TYPE_CALL && + stmt->statementType != DPI_STMT_TYPE_BEGIN && + stmt->statementType != DPI_STMT_TYPE_DECLARE) { + *count = 0; + } else if (stmt->env->versionInfo->versionNum < 12) { + if (dpiOci__attrGet(stmt->handle, DPI_OCI_HTYPE_STMT, &rowCount32, 0, + DPI_OCI_ATTR_ROW_COUNT, "get row count", error) < 0) + return DPI_FAILURE; + *count = rowCount32; + } else { + if (dpiOci__attrGet(stmt->handle, DPI_OCI_HTYPE_STMT, count, 0, + DPI_OCI_ATTR_UB8_ROW_COUNT, "get row count", error) < 0) + return DPI_FAILURE; + } + + return DPI_SUCCESS; +} + + //----------------------------------------------------------------------------- // dpiStmt__getQueryInfo() [INTERNAL] // Get query information for the position in question. @@ -1484,6 +1539,8 @@ int dpiStmt_getImplicitResult(dpiStmt *stmt, dpiStmt **implicitResult) if (dpiStmt__allocate(stmt->conn, 0, &tempStmt, &error) < 0) return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); tempStmt->handle = handle; + dpiGen__setRefCount(stmt, &error, 1); + tempStmt->parentStmt = stmt; if (dpiStmt__createQueryVars(tempStmt, &error) < 0) { dpiStmt__free(tempStmt, &error); return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); @@ -1522,6 +1579,46 @@ int dpiStmt_getInfo(dpiStmt *stmt, dpiStmtInfo *info) } +//----------------------------------------------------------------------------- +// dpiStmt_getLastRowid() [PUBLIC] +// Returns the rowid of the last row that was affected by a DML statement. If +// no rows were affected by the last statement executed or the last statement +// executed was not a DML statement, NULL is returned. +//----------------------------------------------------------------------------- +int dpiStmt_getLastRowid(dpiStmt *stmt, dpiRowid **rowid) +{ + uint64_t rowCount; + dpiError error; + + if (dpiStmt__check(stmt, __func__, &error) < 0) + return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); + DPI_CHECK_PTR_NOT_NULL(stmt, rowid) + *rowid = NULL; + if (stmt->statementType == DPI_STMT_TYPE_INSERT || + stmt->statementType == DPI_STMT_TYPE_UPDATE || + stmt->statementType == DPI_STMT_TYPE_DELETE || + stmt->statementType == DPI_STMT_TYPE_MERGE) { + if (dpiStmt__getRowCount(stmt, &rowCount, &error) < 0) + return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); + if (rowCount > 0) { + if (stmt->lastRowid) { + dpiGen__setRefCount(stmt->lastRowid, &error, -1); + stmt->lastRowid = NULL; + } + if (dpiRowid__allocate(stmt->conn, &stmt->lastRowid, &error) < 0) + return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); + if (dpiOci__attrGet(stmt->handle, DPI_OCI_HTYPE_STMT, + stmt->lastRowid->handle, 0, DPI_OCI_ATTR_ROWID, + "get last rowid", &error) < 0) + return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); + *rowid = stmt->lastRowid; + } + } + + return dpiGen__endPublicFn(stmt, DPI_SUCCESS, &error); +} + + //----------------------------------------------------------------------------- // dpiStmt_getNumQueryColumns() [PUBLIC] // Returns the number of query columns associated with a statement. If the @@ -1612,33 +1709,14 @@ int dpiStmt_getQueryValue(dpiStmt *stmt, uint32_t pos, //----------------------------------------------------------------------------- int dpiStmt_getRowCount(dpiStmt *stmt, uint64_t *count) { - uint32_t rowCount32; dpiError error; + int status; if (dpiStmt__check(stmt, __func__, &error) < 0) return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(stmt, count) - if (stmt->statementType == DPI_STMT_TYPE_SELECT) - *count = stmt->rowCount; - else if (stmt->statementType != DPI_STMT_TYPE_INSERT && - stmt->statementType != DPI_STMT_TYPE_UPDATE && - stmt->statementType != DPI_STMT_TYPE_DELETE && - stmt->statementType != DPI_STMT_TYPE_MERGE && - stmt->statementType != DPI_STMT_TYPE_CALL && - stmt->statementType != DPI_STMT_TYPE_BEGIN && - stmt->statementType != DPI_STMT_TYPE_DECLARE) { - *count = 0; - } else if (stmt->env->versionInfo->versionNum < 12) { - if (dpiOci__attrGet(stmt->handle, DPI_OCI_HTYPE_STMT, &rowCount32, 0, - DPI_OCI_ATTR_ROW_COUNT, "get row count", &error) < 0) - return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); - *count = rowCount32; - } else { - if (dpiOci__attrGet(stmt->handle, DPI_OCI_HTYPE_STMT, count, 0, - DPI_OCI_ATTR_UB8_ROW_COUNT, "get row count", &error) < 0) - return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); - } - return dpiGen__endPublicFn(stmt, DPI_SUCCESS, &error); + status = dpiStmt__getRowCount(stmt, count, &error); + return dpiGen__endPublicFn(stmt, status, &error); } @@ -1818,4 +1896,3 @@ int dpiStmt_setFetchArraySize(dpiStmt *stmt, uint32_t arraySize) stmt->fetchArraySize = arraySize; return dpiGen__endPublicFn(stmt, DPI_SUCCESS, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSubscr.c b/vendor/github.com/godror/godror/odpi/src/dpiSubscr.c similarity index 93% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiSubscr.c rename to vendor/github.com/godror/godror/odpi/src/dpiSubscr.c index 55c00168e0d..cf1ed60b2d8 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiSubscr.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiSubscr.c @@ -40,9 +40,19 @@ static void dpiSubscr__callback(dpiSubscr *subscr, UNUSED void *handle, dpiError error; // ensure that the subscription handle is still valid - if (dpiGen__startPublicFn(subscr, DPI_HTYPE_SUBSCR, __func__, 1, - &error) < 0) + if (dpiGen__startPublicFn(subscr, DPI_HTYPE_SUBSCR, __func__, + &error) < 0) { dpiGen__endPublicFn(subscr, DPI_FAILURE, &error); + return; + } + + // if the subscription is no longer registered, nothing further to do + dpiMutex__acquire(subscr->mutex); + if (!subscr->registered) { + dpiMutex__release(subscr->mutex); + dpiGen__endPublicFn(subscr, DPI_SUCCESS, &error); + return; + } // populate message memset(&message, 0, sizeof(message)); @@ -52,11 +62,13 @@ static void dpiSubscr__callback(dpiSubscr *subscr, UNUSED void *handle, } message.registered = subscr->registered; - // invoke user callback + // invoke user callback; temporarily increase reference count to ensure + // that the subscription is not freed during the callback + dpiGen__setRefCount(subscr, &error, 1); (*subscr->callback)(subscr->callbackContext, &message); - - // clean up message dpiSubscr__freeMessage(&message); + dpiMutex__release(subscr->mutex); + dpiGen__setRefCount(subscr, &error, -1); dpiGen__endPublicFn(subscr, DPI_SUCCESS, &error); } @@ -68,7 +80,7 @@ static void dpiSubscr__callback(dpiSubscr *subscr, UNUSED void *handle, static int dpiSubscr__check(dpiSubscr *subscr, const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(subscr, DPI_HTYPE_SUBSCR, fnName, 1, error) < 0) + if (dpiGen__startPublicFn(subscr, DPI_HTYPE_SUBSCR, fnName, error) < 0) return DPI_FAILURE; if (!subscr->handle) return dpiError__set(error, "check closed", DPI_ERR_SUBSCR_CLOSED); @@ -84,7 +96,7 @@ static int dpiSubscr__check(dpiSubscr *subscr, const char *fnName, int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn, dpiSubscrCreateParams *params, dpiError *error) { - uint32_t qosFlags; + uint32_t qosFlags, mode; int32_t int32Val; int rowids; @@ -95,6 +107,8 @@ int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn, subscr->callbackContext = params->callbackContext; subscr->subscrNamespace = params->subscrNamespace; subscr->qos = params->qos; + subscr->clientInitiated = params->clientInitiated; + dpiMutex__initialize(subscr->mutex); // create the subscription handle if (dpiOci__handleAlloc(conn->env->handle, &subscr->handle, @@ -222,11 +236,27 @@ int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn, } - // register the subscription - if (dpiOci__subscriptionRegister(conn, &subscr->handle, error) < 0) + // register the subscription; client initiated subscriptions are only valid + // with 19.4 client and database + mode = DPI_OCI_DEFAULT; + if (params->clientInitiated) { + if (dpiUtils__checkClientVersion(conn->env->versionInfo, 19, 4, + error) < 0) + return DPI_FAILURE; + if (dpiUtils__checkDatabaseVersion(conn, 19, 4, error) < 0) + return DPI_FAILURE; + mode = DPI_OCI_SECURE_NOTIFICATION; + } + if (dpiOci__subscriptionRegister(conn, &subscr->handle, mode, error) < 0) return DPI_FAILURE; subscr->registered = 1; + // acquire the registration id + if (dpiOci__attrGet(subscr->handle, DPI_OCI_HTYPE_SUBSCRIPTION, + ¶ms->outRegId, NULL, DPI_OCI_ATTR_SUBSCR_CQ_REGID, + "get registration id", error) < 0) + return DPI_FAILURE; + return DPI_SUCCESS; } @@ -237,6 +267,7 @@ int dpiSubscr__create(dpiSubscr *subscr, dpiConn *conn, //----------------------------------------------------------------------------- void dpiSubscr__free(dpiSubscr *subscr, dpiError *error) { + dpiMutex__acquire(subscr->mutex); if (subscr->handle) { if (subscr->registered) dpiOci__subscriptionUnRegister(subscr->conn, subscr, error); @@ -247,6 +278,8 @@ void dpiSubscr__free(dpiSubscr *subscr, dpiError *error) dpiGen__setRefCount(subscr->conn, error, -1); subscr->conn = NULL; } + dpiMutex__release(subscr->mutex); + dpiMutex__destroy(subscr->mutex); dpiUtils__freeMemory(subscr); } @@ -615,9 +648,12 @@ static int dpiSubscr__populateQueryChangeMessage(dpiSubscr *subscr, static int dpiSubscr__prepareStmt(dpiSubscr *subscr, dpiStmt *stmt, const char *sql, uint32_t sqlLength, dpiError *error) { - // prepare statement for execution + // prepare statement for execution; only SELECT statements are supported if (dpiStmt__prepare(stmt, sql, sqlLength, NULL, 0, error) < 0) return DPI_FAILURE; + if (stmt->statementType != DPI_STMT_TYPE_SELECT) + return dpiError__set(error, "subscr prepare statement", + DPI_ERR_NOT_SUPPORTED); // fetch array size is set to 1 in order to avoid over allocation since // the query is not really going to be used for fetching rows, just for @@ -675,4 +711,3 @@ int dpiSubscr_release(dpiSubscr *subscr) { return dpiGen__release(subscr, DPI_HTYPE_SUBSCR, __func__); } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiUtils.c b/vendor/github.com/godror/godror/odpi/src/dpiUtils.c similarity index 99% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiUtils.c rename to vendor/github.com/godror/godror/odpi/src/dpiUtils.c index 1aad9118400..0ab09e54487 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiUtils.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiUtils.c @@ -251,7 +251,7 @@ int dpiUtils__parseNumberString(const char *value, uint32_t valueLength, return dpiError__set(error, "no digits in exponent", DPI_ERR_INVALID_NUMBER); exponentDigits[numExponentDigits] = '\0'; - exponent = (int16_t) strtol(exponentDigits, NULL, 0); + exponent = (int16_t) strtol(exponentDigits, NULL, 10); if (exponentIsNegative) exponent = -exponent; *decimalPointIndex += exponent; @@ -399,4 +399,3 @@ int dpiUtils__setAttributesFromCommonCreateParams(void *handle, return DPI_SUCCESS; } - diff --git a/vendor/gopkg.in/goracle.v2/odpi/src/dpiVar.c b/vendor/github.com/godror/godror/odpi/src/dpiVar.c similarity index 97% rename from vendor/gopkg.in/goracle.v2/odpi/src/dpiVar.c rename to vendor/github.com/godror/godror/odpi/src/dpiVar.c index de9db59bc48..d8cde787c64 100644 --- a/vendor/gopkg.in/goracle.v2/odpi/src/dpiVar.c +++ b/vendor/github.com/godror/godror/odpi/src/dpiVar.c @@ -226,10 +226,9 @@ static void dpiVar__assignCallbackBuffer(dpiVar *var, dpiVarBuffer *buffer, // Verifies that the array size has not been exceeded. //----------------------------------------------------------------------------- static int dpiVar__checkArraySize(dpiVar *var, uint32_t pos, - const char *fnName, int needErrorHandle, dpiError *error) + const char *fnName, dpiError *error) { - if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, fnName, needErrorHandle, - error) < 0) + if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, fnName, error) < 0) return DPI_FAILURE; if (pos >= var->buffer.maxArraySize) return dpiError__set(error, "check array size", @@ -629,7 +628,6 @@ int dpiVar__getValue(dpiVar *var, dpiVarBuffer *buffer, uint32_t pos, return DPI_SUCCESS; } - // check for a NULL value; for objects the indicator is elsewhere data = &buffer->externalData[pos]; if (!buffer->objectIndicator) @@ -638,8 +636,17 @@ int dpiVar__getValue(dpiVar *var, dpiVarBuffer *buffer, uint32_t pos, data->isNull = (*((int16_t*) buffer->objectIndicator[pos]) == DPI_OCI_IND_NULL); else data->isNull = 1; - if (data->isNull) + if (data->isNull) { + if (inFetch && var->objectType && var->objectType->isCollection) { + if (dpiOci__objectFree(var->env->handle, + buffer->data.asObject[pos], 1, error) < 0) + return DPI_FAILURE; + if (dpiOci__objectFree(var->env->handle, + buffer->objectIndicator[pos], 1, error) < 0) + return DPI_FAILURE; + } return DPI_SUCCESS; + } // check return code for variable length data if (buffer->returnCode) { @@ -781,8 +788,8 @@ int dpiVar__getValue(dpiVar *var, dpiVarBuffer *buffer, uint32_t pos, // does nothing useful except satisfy OCI requirements. //----------------------------------------------------------------------------- int32_t dpiVar__inBindCallback(dpiVar *var, UNUSED void *bindp, - UNUSED uint32_t iter, uint32_t index, void **bufpp, uint32_t *alenp, - uint8_t *piecep, void **indpp) + UNUSED uint32_t iter, UNUSED uint32_t index, void **bufpp, + uint32_t *alenp, uint8_t *piecep, void **indpp) { dpiDynamicBytes *dynBytes; @@ -1208,7 +1215,8 @@ static int dpiVar__setFromBytes(dpiVar *var, uint32_t pos, const char *value, dynBytes = &var->buffer.dynamicBytes[pos]; if (dpiVar__allocateDynamicBytes(dynBytes, valueLength, error) < 0) return DPI_FAILURE; - memcpy(dynBytes->chunks->ptr, value, valueLength); + if (valueLength > 0) + memcpy(dynBytes->chunks->ptr, value, valueLength); dynBytes->numChunks = 1; dynBytes->chunks->length = valueLength; bytes->ptr = dynBytes->chunks->ptr; @@ -1461,6 +1469,10 @@ int dpiVar__setValue(dpiVar *var, dpiVarBuffer *buffer, uint32_t pos, case DPI_ORACLE_TYPE_NUMBER: return dpiDataBuffer__toOracleNumberFromDouble( &data->value, error, &buffer->data.asNumber[pos]); + case DPI_ORACLE_TYPE_DATE: + return dpiDataBuffer__toOracleDateFromDouble( + &data->value, var->env, error, + &buffer->data.asDate[pos]); case DPI_ORACLE_TYPE_TIMESTAMP: case DPI_ORACLE_TYPE_TIMESTAMP_TZ: case DPI_ORACLE_TYPE_TIMESTAMP_LTZ: @@ -1520,6 +1532,7 @@ static int dpiVar__validateTypes(const dpiOracleType *oracleType, dpiNativeTypeNum nativeTypeNum, dpiError *error) { switch (oracleType->oracleTypeNum) { + case DPI_ORACLE_TYPE_DATE: case DPI_ORACLE_TYPE_TIMESTAMP: case DPI_ORACLE_TYPE_TIMESTAMP_TZ: case DPI_ORACLE_TYPE_TIMESTAMP_LTZ: @@ -1564,7 +1577,7 @@ int dpiVar_copyData(dpiVar *var, uint32_t pos, dpiVar *sourceVar, dpiError error; int status; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); if (dpiGen__checkHandle(sourceVar, DPI_HTYPE_VAR, "check source var", &error) < 0) @@ -1594,7 +1607,7 @@ int dpiVar_getNumElementsInArray(dpiVar *var, uint32_t *numElements) { dpiError error; - if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, 0, &error) < 0) + if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(var, numElements) if (var->dynBindBuffers) @@ -1618,7 +1631,7 @@ int dpiVar_getReturnedData(dpiVar *var, uint32_t pos, uint32_t *numElements, { dpiError error; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(var, numElements) DPI_CHECK_PTR_NOT_NULL(var, data) @@ -1642,7 +1655,7 @@ int dpiVar_getSizeInBytes(dpiVar *var, uint32_t *sizeInBytes) { dpiError error; - if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, 0, &error) < 0) + if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(var, sizeInBytes) *sizeInBytes = var->sizeInBytes; @@ -1673,9 +1686,9 @@ int dpiVar_setFromBytes(dpiVar *var, uint32_t pos, const char *value, dpiError error; int status; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); - DPI_CHECK_PTR_NOT_NULL(var, value) + DPI_CHECK_PTR_AND_LENGTH(var, value) if (var->nativeTypeNum != DPI_NATIVE_TYPE_BYTES && var->nativeTypeNum != DPI_NATIVE_TYPE_LOB) { dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED); @@ -1702,7 +1715,7 @@ int dpiVar_setFromLob(dpiVar *var, uint32_t pos, dpiLob *lob) dpiError error; int status; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); if (var->nativeTypeNum != DPI_NATIVE_TYPE_LOB) { dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED); @@ -1724,7 +1737,7 @@ int dpiVar_setFromObject(dpiVar *var, uint32_t pos, dpiObject *obj) dpiError error; int status; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); if (var->nativeTypeNum != DPI_NATIVE_TYPE_OBJECT) { dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED); @@ -1746,7 +1759,7 @@ int dpiVar_setFromRowid(dpiVar *var, uint32_t pos, dpiRowid *rowid) dpiError error; int status; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); if (var->nativeTypeNum != DPI_NATIVE_TYPE_ROWID) { dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED); @@ -1768,7 +1781,7 @@ int dpiVar_setFromStmt(dpiVar *var, uint32_t pos, dpiStmt *stmt) dpiError error; int status; - if (dpiVar__checkArraySize(var, pos, __func__, 1, &error) < 0) + if (dpiVar__checkArraySize(var, pos, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); if (var->nativeTypeNum != DPI_NATIVE_TYPE_STMT) { dpiError__set(&error, "native type", DPI_ERR_NOT_SUPPORTED); @@ -1788,7 +1801,7 @@ int dpiVar_setNumElementsInArray(dpiVar *var, uint32_t numElements) { dpiError error; - if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, 0, &error) < 0) + if (dpiGen__startPublicFn(var, DPI_HTYPE_VAR, __func__, &error) < 0) return dpiGen__endPublicFn(var, DPI_FAILURE, &error); if (numElements > var->buffer.maxArraySize) { dpiError__set(&error, "check num elements", @@ -1798,4 +1811,3 @@ int dpiVar_setNumElementsInArray(dpiVar *var, uint32_t numElements) var->buffer.actualArraySize = numElements; return dpiGen__endPublicFn(var, DPI_SUCCESS, &error); } - diff --git a/vendor/gopkg.in/goracle.v2/orahlp.go b/vendor/github.com/godror/godror/orahlp.go similarity index 83% rename from vendor/gopkg.in/goracle.v2/orahlp.go rename to vendor/github.com/godror/godror/orahlp.go index 6775a4678da..94e1f74828d 100644 --- a/vendor/gopkg.in/goracle.v2/orahlp.go +++ b/vendor/github.com/godror/godror/orahlp.go @@ -1,19 +1,9 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror import ( "bufio" @@ -24,8 +14,9 @@ import ( "fmt" "io" "sync" + "time" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) // QueryColumn is the described column. @@ -52,10 +43,11 @@ type Querier interface { // This can help using unknown-at-compile-time, a.k.a. // dynamic queries. func DescribeQuery(ctx context.Context, db Execer, qry string) ([]QueryColumn, error) { - c, err := getConn(db) + c, err := getConn(ctx, db) if err != nil { return nil, err } + defer c.close(false) stmt, err := c.PrepareContext(ctx, qry) if err != nil { @@ -213,7 +205,10 @@ func MapToSlice(qry string, metParam func(string) interface{}) (string, []interf func EnableDbmsOutput(ctx context.Context, conn Execer) error { qry := "BEGIN DBMS_OUTPUT.enable(1000000); END;" _, err := conn.ExecContext(ctx, qry) - return errors.Wrap(err, qry) + if err != nil { + return errors.Errorf("%s: %w", qry, err) + } + return nil } // ReadDbmsOutput copies the DBMS_OUTPUT buffer into the given io.Writer. @@ -224,7 +219,7 @@ func ReadDbmsOutput(ctx context.Context, w io.Writer, conn preparer) error { const qry = `BEGIN DBMS_OUTPUT.get_lines(:1, :2); END;` stmt, err := conn.PrepareContext(ctx, qry) if err != nil { - return errors.Wrap(err, qry) + return errors.Errorf("%s: %w", qry, err) } lines := make([]string, maxNumLines) @@ -237,7 +232,7 @@ func ReadDbmsOutput(ctx context.Context, w io.Writer, conn preparer) error { numLines = int64(len(lines)) if _, err = stmt.ExecContext(ctx, params...); err != nil { _ = bw.Flush() - return errors.Wrap(err, qry) + return errors.Errorf("%s: %w", qry, err) } for i := 0; i < int(numLines); i++ { _, _ = bw.WriteString(lines[i]) @@ -253,8 +248,8 @@ func ReadDbmsOutput(ctx context.Context, w io.Writer, conn preparer) error { } // ClientVersion returns the VersionInfo from the DB. -func ClientVersion(ex Execer) (VersionInfo, error) { - c, err := getConn(ex) +func ClientVersion(ctx context.Context, ex Execer) (VersionInfo, error) { + c, err := getConn(ctx, ex) if err != nil { return VersionInfo{}, err } @@ -262,8 +257,8 @@ func ClientVersion(ex Execer) (VersionInfo, error) { } // ServerVersion returns the VersionInfo of the client. -func ServerVersion(ex Execer) (VersionInfo, error) { - c, err := getConn(ex) +func ServerVersion(ctx context.Context, ex Execer) (VersionInfo, error) { + c, err := getConn(ctx, ex) if err != nil { return VersionInfo{}, err } @@ -273,32 +268,37 @@ func ServerVersion(ex Execer) (VersionInfo, error) { // Conn is the interface for a connection, to be returned by DriverConn. type Conn interface { driver.Conn + driver.ConnBeginTx + driver.ConnPrepareContext driver.Pinger + Break() error - BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) - PrepareContext(ctx context.Context, query string) (driver.Stmt, error) Commit() error Rollback() error + ClientVersion() (VersionInfo, error) ServerVersion() (VersionInfo, error) GetObjectType(name string) (ObjectType, error) NewSubscription(string, func(Event)) (*Subscription, error) Startup(StartupMode) error Shutdown(ShutdownMode) error + NewData(baseType interface{}, SliceLen, BufSize int) ([]*Data, error) + + Timezone() *time.Location } -// DriverConn returns the *goracle.conn of the database/sql.Conn -func DriverConn(ex Execer) (Conn, error) { - return getConn(ex) +// DriverConn returns the *godror.conn of the database/sql.Conn +func DriverConn(ctx context.Context, ex Execer) (Conn, error) { + return getConn(ctx, ex) } var getConnMu sync.Mutex -func getConn(ex Execer) (*conn, error) { +func getConn(ctx context.Context, ex Execer) (*conn, error) { getConnMu.Lock() defer getConnMu.Unlock() var c interface{} - if _, err := ex.ExecContext(context.Background(), getConnection, sql.Out{Dest: &c}); err != nil { - return nil, errors.Wrap(err, "getConnection") + if _, err := ex.ExecContext(ctx, getConnection, sql.Out{Dest: &c}); err != nil { + return nil, errors.Errorf("getConnection: %w", err) } return c.(*conn), nil } @@ -307,3 +307,11 @@ func getConn(ex Execer) (*conn, error) { func WrapRows(ctx context.Context, q Querier, rset driver.Rows) (*sql.Rows, error) { return q.QueryContext(ctx, wrapResultset, rset) } + +func Timezone(ctx context.Context, ex Execer) (*time.Location, error) { + c, err := getConn(ctx, ex) + if err != nil { + return nil, err + } + return c.Timezone(), nil +} diff --git a/vendor/github.com/godror/godror/queue.go b/vendor/github.com/godror/godror/queue.go new file mode 100644 index 00000000000..01f081452af --- /dev/null +++ b/vendor/github.com/godror/godror/queue.go @@ -0,0 +1,639 @@ +// Copyright 2019 Tamás Gulácsi +// +// +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 + +package godror + +/* +#include +#include "dpiImpl.h" +*/ +import "C" +import ( + "context" + "sync" + "time" + "unsafe" + + errors "golang.org/x/xerrors" +) + +const MsgIDLength = 16 + +var zeroMsgID [MsgIDLength]byte + +// DefaultEnqOptions is the default set for NewQueue. +var DefaultEnqOptions = EnqOptions{ + Visibility: VisibleImmediate, + DeliveryMode: DeliverPersistent, +} + +// DefaultDeqOptions is the default set for NewQueue. +var DefaultDeqOptions = DeqOptions{ + Mode: DeqRemove, + DeliveryMode: DeliverPersistent, + Navigation: NavFirst, + Visibility: VisibleImmediate, + Wait: 30, +} + +// Queue represents an Oracle Advanced Queue. +type Queue struct { + conn *conn + dpiQueue *C.dpiQueue + PayloadObjectType ObjectType + name string + + mu sync.Mutex + props []*C.dpiMsgProps +} + +// NewQueue creates a new Queue. +// +// WARNING: the connection given to it must not be closed before the Queue is closed! +// So use an sql.Conn for it. +func NewQueue(ctx context.Context, execer Execer, name string, payloadObjectTypeName string) (*Queue, error) { + cx, err := DriverConn(ctx, execer) + if err != nil { + return nil, err + } + Q := Queue{conn: cx.(*conn), name: name} + + var payloadType *C.dpiObjectType + if payloadObjectTypeName != "" { + if Q.PayloadObjectType, err = Q.conn.GetObjectType(payloadObjectTypeName); err != nil { + return nil, err + } else { + payloadType = Q.PayloadObjectType.dpiObjectType + } + } + value := C.CString(name) + if C.dpiConn_newQueue(Q.conn.dpiConn, value, C.uint(len(name)), payloadType, &Q.dpiQueue) == C.DPI_FAILURE { + err = errors.Errorf("newQueue %q: %w", name, Q.conn.drv.getError()) + } + C.free(unsafe.Pointer(value)) + if err != nil { + cx.Close() + return nil, err + } + if err = Q.SetEnqOptions(DefaultEnqOptions); err != nil { + cx.Close() + Q.Close() + return nil, err + } + if err = Q.SetDeqOptions(DefaultDeqOptions); err != nil { + cx.Close() + Q.Close() + return nil, err + } + return &Q, nil +} + +// Close the queue. +func (Q *Queue) Close() error { + c, q := Q.conn, Q.dpiQueue + Q.conn, Q.dpiQueue = nil, nil + if q == nil { + return nil + } + if C.dpiQueue_release(q) == C.DPI_FAILURE { + return errors.Errorf("release: %w", c.getError()) + } + return nil +} + +// Name of the queue. +func (Q *Queue) Name() string { return Q.name } + +// EnqOptions returns the queue's enqueue options in effect. +func (Q *Queue) EnqOptions() (EnqOptions, error) { + var E EnqOptions + var opts *C.dpiEnqOptions + if C.dpiQueue_getEnqOptions(Q.dpiQueue, &opts) == C.DPI_FAILURE { + return E, errors.Errorf("getEnqOptions: %w", Q.conn.drv.getError()) + } + err := E.fromOra(Q.conn.drv, opts) + return E, err +} + +// DeqOptions returns the queue's dequeue options in effect. +func (Q *Queue) DeqOptions() (DeqOptions, error) { + var D DeqOptions + var opts *C.dpiDeqOptions + if C.dpiQueue_getDeqOptions(Q.dpiQueue, &opts) == C.DPI_FAILURE { + return D, errors.Errorf("getDeqOptions: %w", Q.conn.drv.getError()) + } + err := D.fromOra(Q.conn.drv, opts) + return D, err +} + +// Dequeues messages into the given slice. +// Returns the number of messages filled in the given slice. +func (Q *Queue) Dequeue(messages []Message) (int, error) { + Q.mu.Lock() + defer Q.mu.Unlock() + var props []*C.dpiMsgProps + if cap(Q.props) >= len(messages) { + props = Q.props[:len(messages)] + } else { + props = make([]*C.dpiMsgProps, len(messages)) + } + Q.props = props + + var ok C.int + num := C.uint(len(props)) + if num == 1 { + ok = C.dpiQueue_deqOne(Q.dpiQueue, &props[0]) + } else { + ok = C.dpiQueue_deqMany(Q.dpiQueue, &num, &props[0]) + } + if ok == C.DPI_FAILURE { + err := Q.conn.getError() + if code := err.(interface{ Code() int }).Code(); code == 3156 { + return 0, context.DeadlineExceeded + } + return 0, errors.Errorf("dequeue: %w", err) + } + var firstErr error + for i, p := range props[:int(num)] { + if err := messages[i].fromOra(Q.conn, p, &Q.PayloadObjectType); err != nil { + if firstErr == nil { + firstErr = err + } + } + C.dpiMsgProps_release(p) + } + return int(num), firstErr +} + +// Enqueue all the messages given. +// +// WARNING: calling this function in parallel on different connections acquired from the same pool may fail due to Oracle bug 29928074. Ensure that this function is not run in parallel, use standalone connections or connections from different pools, or make multiple calls to Queue.enqOne() instead. The function Queue.Dequeue() call is not affected. +func (Q *Queue) Enqueue(messages []Message) error { + Q.mu.Lock() + defer Q.mu.Unlock() + var props []*C.dpiMsgProps + if cap(Q.props) >= len(messages) { + props = Q.props[:len(messages)] + } else { + props = make([]*C.dpiMsgProps, len(messages)) + } + Q.props = props + defer func() { + for _, p := range props { + if p != nil { + C.dpiMsgProps_release(p) + } + } + }() + for i, m := range messages { + if C.dpiConn_newMsgProps(Q.conn.dpiConn, &props[i]) == C.DPI_FAILURE { + return errors.Errorf("newMsgProps: %w", Q.conn.getError()) + } + if err := m.toOra(Q.conn.drv, props[i]); err != nil { + return err + } + } + + var ok C.int + if len(messages) == 1 { + ok = C.dpiQueue_enqOne(Q.dpiQueue, props[0]) + } else { + ok = C.dpiQueue_enqMany(Q.dpiQueue, C.uint(len(props)), &props[0]) + } + if ok == C.DPI_FAILURE { + return errors.Errorf("enqueue %#v: %w", messages, Q.conn.getError()) + } + + return nil +} + +// Message is a message - either received or being sent. +type Message struct { + DeliveryMode DeliveryMode + Enqueued time.Time + Delay, Expiration int32 + Priority, NumAttempts int32 + Correlation, ExceptionQ string + MsgID, OriginalMsgID [16]byte + State MessageState + Raw []byte + Object *Object +} + +func (M *Message) toOra(d *drv, props *C.dpiMsgProps) error { + var firstErr error + OK := func(ok C.int, name string) { + if ok == C.DPI_SUCCESS { + return + } + if firstErr == nil { + firstErr = errors.Errorf("%s: %w", name, d.getError()) + } + } + if M.Correlation != "" { + value := C.CString(M.Correlation) + OK(C.dpiMsgProps_setCorrelation(props, value, C.uint(len(M.Correlation))), "setCorrelation") + C.free(unsafe.Pointer(value)) + } + + if M.Delay != 0 { + OK(C.dpiMsgProps_setDelay(props, C.int(M.Delay)), "setDelay") + } + + if M.ExceptionQ != "" { + value := C.CString(M.ExceptionQ) + OK(C.dpiMsgProps_setExceptionQ(props, value, C.uint(len(M.ExceptionQ))), "setExceptionQ") + C.free(unsafe.Pointer(value)) + } + + if M.Expiration != 0 { + OK(C.dpiMsgProps_setExpiration(props, C.int(M.Expiration)), "setExpiration") + } + + if M.OriginalMsgID != zeroMsgID { + OK(C.dpiMsgProps_setOriginalMsgId(props, (*C.char)(unsafe.Pointer(&M.OriginalMsgID[0])), MsgIDLength), "setMsgOriginalId") + } + + OK(C.dpiMsgProps_setPriority(props, C.int(M.Priority)), "setPriority") + + if M.Object == nil { + OK(C.dpiMsgProps_setPayloadBytes(props, (*C.char)(unsafe.Pointer(&M.Raw[0])), C.uint(len(M.Raw))), "setPayloadBytes") + } else { + OK(C.dpiMsgProps_setPayloadObject(props, M.Object.dpiObject), "setPayloadObject") + } + + return firstErr +} + +func (M *Message) fromOra(c *conn, props *C.dpiMsgProps, objType *ObjectType) error { + var firstErr error + OK := func(ok C.int, name string) bool { + if ok == C.DPI_SUCCESS { + return true + } + if firstErr == nil { + firstErr = errors.Errorf("%s: %w", name, c.getError()) + } + return false + } + M.NumAttempts = 0 + var cint C.int + if OK(C.dpiMsgProps_getNumAttempts(props, &cint), "getNumAttempts") { + M.NumAttempts = int32(cint) + } + var value *C.char + var length C.uint + M.Correlation = "" + if OK(C.dpiMsgProps_getCorrelation(props, &value, &length), "getCorrelation") { + M.Correlation = C.GoStringN(value, C.int(length)) + } + + M.Delay = 0 + if OK(C.dpiMsgProps_getDelay(props, &cint), "getDelay") { + M.Delay = int32(cint) + } + + M.DeliveryMode = DeliverPersistent + var mode C.dpiMessageDeliveryMode + if OK(C.dpiMsgProps_getDeliveryMode(props, &mode), "getDeliveryMode") { + M.DeliveryMode = DeliveryMode(mode) + } + + M.ExceptionQ = "" + if OK(C.dpiMsgProps_getExceptionQ(props, &value, &length), "getExceptionQ") { + M.ExceptionQ = C.GoStringN(value, C.int(length)) + } + + var ts C.dpiTimestamp + M.Enqueued = time.Time{} + if OK(C.dpiMsgProps_getEnqTime(props, &ts), "getEnqTime") { + tz := c.timeZone + if ts.tzHourOffset != 0 || ts.tzMinuteOffset != 0 { + tz = timeZoneFor(ts.tzHourOffset, ts.tzMinuteOffset) + } + if tz == nil { + tz = time.Local + } + M.Enqueued = time.Date( + int(ts.year), time.Month(ts.month), int(ts.day), + int(ts.hour), int(ts.minute), int(ts.second), int(ts.fsecond), + tz, + ) + } + + M.Expiration = 0 + if OK(C.dpiMsgProps_getExpiration(props, &cint), "getExpiration") { + M.Expiration = int32(cint) + } + + M.MsgID = zeroMsgID + if OK(C.dpiMsgProps_getMsgId(props, &value, &length), "getMsgId") { + n := C.int(length) + if n > MsgIDLength { + n = MsgIDLength + } + copy(M.MsgID[:], (*((*[1 << 30]byte)(unsafe.Pointer(&value))))[:n:n]) + } + + M.OriginalMsgID = zeroMsgID + if OK(C.dpiMsgProps_getOriginalMsgId(props, &value, &length), "getMsgOriginalId") { + n := C.int(length) + if n > MsgIDLength { + n = MsgIDLength + } + copy(M.OriginalMsgID[:], (*((*[1 << 30]byte)(unsafe.Pointer(&value))))[:n:n]) + } + + M.Priority = 0 + if OK(C.dpiMsgProps_getPriority(props, &cint), "getPriority") { + M.Priority = int32(cint) + } + + M.State = 0 + var state C.dpiMessageState + if OK(C.dpiMsgProps_getState(props, &state), "getState") { + M.State = MessageState(state) + } + + M.Raw = nil + M.Object = nil + var obj *C.dpiObject + if OK(C.dpiMsgProps_getPayload(props, &obj, &value, &length), "getPayload") { + if obj == nil { + M.Raw = append(make([]byte, 0, length), ((*[1 << 30]byte)(unsafe.Pointer(value)))[:int(length):int(length)]...) + } else { + if C.dpiObject_addRef(obj) == C.DPI_FAILURE { + return objType.getError() + } + M.Object = &Object{dpiObject: obj, ObjectType: *objType} + } + } + return nil +} + +// EnqOptions are the options used to enqueue a message. +type EnqOptions struct { + Transformation string + Visibility Visibility + DeliveryMode DeliveryMode +} + +func (E *EnqOptions) fromOra(d *drv, opts *C.dpiEnqOptions) error { + var firstErr error + OK := func(ok C.int, msg string) bool { + if ok == C.DPI_SUCCESS { + return true + } + if firstErr == nil { + firstErr = errors.Errorf("%s: %w", msg, d.getError()) + } + return false + } + + E.DeliveryMode = DeliverPersistent + + var value *C.char + var length C.uint + if OK(C.dpiEnqOptions_getTransformation(opts, &value, &length), "getTransformation") { + E.Transformation = C.GoStringN(value, C.int(length)) + } + + var vis C.dpiVisibility + if OK(C.dpiEnqOptions_getVisibility(opts, &vis), "getVisibility") { + E.Visibility = Visibility(vis) + } + + return firstErr +} + +func (E EnqOptions) toOra(d *drv, opts *C.dpiEnqOptions) error { + var firstErr error + OK := func(ok C.int, msg string) bool { + if ok == C.DPI_SUCCESS { + return true + } + if firstErr == nil { + firstErr = errors.Errorf("%s: %w", msg, d.getError()) + } + return false + } + + OK(C.dpiEnqOptions_setDeliveryMode(opts, C.dpiMessageDeliveryMode(E.DeliveryMode)), "setDeliveryMode") + cs := C.CString(E.Transformation) + OK(C.dpiEnqOptions_setTransformation(opts, cs, C.uint(len(E.Transformation))), "setTransformation") + C.free(unsafe.Pointer(cs)) + OK(C.dpiEnqOptions_setVisibility(opts, C.uint(E.Visibility)), "setVisibility") + return firstErr +} + +// SetEnqOptions sets all the enqueue options +func (Q *Queue) SetEnqOptions(E EnqOptions) error { + var opts *C.dpiEnqOptions + if C.dpiQueue_getEnqOptions(Q.dpiQueue, &opts) == C.DPI_FAILURE { + return errors.Errorf("getEnqOptions: %w", Q.conn.drv.getError()) + } + return E.toOra(Q.conn.drv, opts) +} + +// DeqOptions are the options used to dequeue a message. +type DeqOptions struct { + Condition, Consumer, Correlation string + MsgID, Transformation string + Mode DeqMode + DeliveryMode DeliveryMode + Navigation DeqNavigation + Visibility Visibility + Wait uint32 +} + +func (D *DeqOptions) fromOra(d *drv, opts *C.dpiDeqOptions) error { + var firstErr error + OK := func(ok C.int, msg string) bool { + if ok == C.DPI_SUCCESS { + return true + } + if firstErr == nil { + firstErr = errors.Errorf("%s: %w", msg, d.getError()) + } + return false + } + + var value *C.char + var length C.uint + D.Transformation = "" + if OK(C.dpiDeqOptions_getTransformation(opts, &value, &length), "getTransformation") { + D.Transformation = C.GoStringN(value, C.int(length)) + } + D.Condition = "" + if OK(C.dpiDeqOptions_getCondition(opts, &value, &length), "getCondifion") { + D.Condition = C.GoStringN(value, C.int(length)) + } + D.Consumer = "" + if OK(C.dpiDeqOptions_getConsumerName(opts, &value, &length), "getConsumer") { + D.Consumer = C.GoStringN(value, C.int(length)) + } + D.Correlation = "" + if OK(C.dpiDeqOptions_getCorrelation(opts, &value, &length), "getCorrelation") { + D.Correlation = C.GoStringN(value, C.int(length)) + } + D.DeliveryMode = DeliverPersistent + var mode C.dpiDeqMode + if OK(C.dpiDeqOptions_getMode(opts, &mode), "getMode") { + D.Mode = DeqMode(mode) + } + D.MsgID = "" + if OK(C.dpiDeqOptions_getMsgId(opts, &value, &length), "getMsgId") { + D.MsgID = C.GoStringN(value, C.int(length)) + } + var nav C.dpiDeqNavigation + if OK(C.dpiDeqOptions_getNavigation(opts, &nav), "getNavigation") { + D.Navigation = DeqNavigation(nav) + } + var vis C.dpiVisibility + if OK(C.dpiDeqOptions_getVisibility(opts, &vis), "getVisibility") { + D.Visibility = Visibility(vis) + } + D.Wait = 0 + var u32 C.uint + if OK(C.dpiDeqOptions_getWait(opts, &u32), "getWait") { + D.Wait = uint32(u32) + } + return firstErr +} + +func (D DeqOptions) toOra(d *drv, opts *C.dpiDeqOptions) error { + var firstErr error + OK := func(ok C.int, msg string) bool { + if ok == C.DPI_SUCCESS { + return true + } + if firstErr == nil { + firstErr = errors.Errorf("%s: %w", msg, d.getError()) + } + return false + } + + cs := C.CString(D.Transformation) + OK(C.dpiDeqOptions_setTransformation(opts, cs, C.uint(len(D.Transformation))), "setTransformation") + C.free(unsafe.Pointer(cs)) + + cs = C.CString(D.Condition) + OK(C.dpiDeqOptions_setCondition(opts, cs, C.uint(len(D.Condition))), "setCondifion") + C.free(unsafe.Pointer(cs)) + + cs = C.CString(D.Consumer) + OK(C.dpiDeqOptions_setConsumerName(opts, cs, C.uint(len(D.Consumer))), "setConsumer") + C.free(unsafe.Pointer(cs)) + + cs = C.CString(D.Correlation) + OK(C.dpiDeqOptions_setCorrelation(opts, cs, C.uint(len(D.Correlation))), "setCorrelation") + C.free(unsafe.Pointer(cs)) + + OK(C.dpiDeqOptions_setDeliveryMode(opts, C.dpiMessageDeliveryMode(D.DeliveryMode)), "setDeliveryMode") + OK(C.dpiDeqOptions_setMode(opts, C.dpiDeqMode(D.Mode)), "setMode") + + cs = C.CString(D.MsgID) + OK(C.dpiDeqOptions_setMsgId(opts, cs, C.uint(len(D.MsgID))), "setMsgId") + C.free(unsafe.Pointer(cs)) + + OK(C.dpiDeqOptions_setNavigation(opts, C.dpiDeqNavigation(D.Navigation)), "setNavigation") + + OK(C.dpiDeqOptions_setVisibility(opts, C.dpiVisibility(D.Visibility)), "setVisibility") + + OK(C.dpiDeqOptions_setWait(opts, C.uint(D.Wait)), "setWait") + + return firstErr +} + +// SetDeqOptions sets all the dequeue options +func (Q *Queue) SetDeqOptions(D DeqOptions) error { + var opts *C.dpiDeqOptions + if C.dpiQueue_getDeqOptions(Q.dpiQueue, &opts) == C.DPI_FAILURE { + return errors.Errorf("getDeqOptions: %w", Q.conn.drv.getError()) + } + return D.toOra(Q.conn.drv, opts) +} + +// SetDeqCorrelation is a convenience function setting the Correlation DeqOption +func (Q *Queue) SetDeqCorrelation(correlation string) error { + var opts *C.dpiDeqOptions + if C.dpiQueue_getDeqOptions(Q.dpiQueue, &opts) == C.DPI_FAILURE { + return errors.Errorf("getDeqOptions: %w", Q.conn.drv.getError()) + } + cs := C.CString(correlation) + ok := C.dpiDeqOptions_setCorrelation(opts, cs, C.uint(len(correlation))) == C.DPI_FAILURE + C.free(unsafe.Pointer(cs)) + if !ok { + return errors.Errorf("setCorrelation: %w", Q.conn.drv.getError()) + } + return nil +} + +const ( + NoWait = uint32(0) + WaitForever = uint32(1<<31 - 1) +) + +// MessageState constants representing message's state. +type MessageState uint32 + +const ( + // MsgStateReady says that "The message is ready to be processed". + MsgStateReady = MessageState(C.DPI_MSG_STATE_READY) + // MsgStateWaiting says that "The message is waiting for the delay time to expire". + MsgStateWaiting = MessageState(C.DPI_MSG_STATE_WAITING) + // MsgStateProcessed says that "The message has already been processed and is retained". + MsgStateProcessed = MessageState(C.DPI_MSG_STATE_PROCESSED) + // MsgStateExpired says that "The message has been moved to the exception queue". + MsgStateExpired = MessageState(C.DPI_MSG_STATE_EXPIRED) +) + +// DeliveryMode constants for delivery modes. +type DeliveryMode uint32 + +const ( + // DeliverPersistent is to Dequeue only persistent messages from the queue. This is the default mode. + DeliverPersistent = DeliveryMode(C.DPI_MODE_MSG_PERSISTENT) + // DeliverBuffered is to Dequeue only buffered messages from the queue. + DeliverBuffered = DeliveryMode(C.DPI_MODE_MSG_BUFFERED) + // DeliverPersistentOrBuffered is to Dequeue both persistent and buffered messages from the queue. + DeliverPersistentOrBuffered = DeliveryMode(C.DPI_MODE_MSG_PERSISTENT_OR_BUFFERED) +) + +// Visibility constants represents visibility. +type Visibility uint32 + +const ( + // VisibleImmediate means that "The message is not part of the current transaction but constitutes a transaction of its own". + VisibleImmediate = Visibility(C.DPI_VISIBILITY_IMMEDIATE) + // VisibleOnCommit means that "The message is part of the current transaction. This is the default value". + VisibleOnCommit = Visibility(C.DPI_VISIBILITY_ON_COMMIT) +) + +// DeqMode constants for dequeue modes. +type DeqMode uint32 + +const ( + // DeqRemove reads the message and updates or deletes it. This is the default mode. Note that the message may be retained in the queue table based on retention properties. + DeqRemove = DeqMode(C.DPI_MODE_DEQ_REMOVE) + // DeqBrows reads the message without acquiring a lock on the message (equivalent to a SELECT statement). + DeqBrowse = DeqMode(C.DPI_MODE_DEQ_BROWSE) + // DeqLocked reads the message and obtain a write lock on the message (equivalent to a SELECT FOR UPDATE statement). + DeqLocked = DeqMode(C.DPI_MODE_DEQ_LOCKED) + // DeqPeek confirms receipt of the message but does not deliver the actual message content. + DeqPeek = DeqMode(C.DPI_MODE_DEQ_REMOVE_NO_DATA) +) + +// DeqNavigation constants for navigation. +type DeqNavigation uint32 + +const ( + // NavFirst retrieves the first available message that matches the search criteria. This resets the position to the beginning of the queue. + NavFirst = DeqNavigation(C.DPI_DEQ_NAV_FIRST_MSG) + // NavNext skips the remainder of the current transaction group (if any) and retrieves the first message of the next transaction group. This option can only be used if message grouping is enabled for the queue. + NavNextTran = DeqNavigation(C.DPI_DEQ_NAV_NEXT_TRANSACTION) + // NavNext Retrieves the next available message that matches the search criteria. This is the default method. + NavNext = DeqNavigation(C.DPI_DEQ_NAV_NEXT_MSG) +) diff --git a/vendor/gopkg.in/goracle.v2/rows.go b/vendor/github.com/godror/godror/rows.go similarity index 92% rename from vendor/gopkg.in/goracle.v2/rows.go rename to vendor/github.com/godror/godror/rows.go index 6b54d821f34..e870338d773 100644 --- a/vendor/gopkg.in/goracle.v2/rows.go +++ b/vendor/github.com/godror/godror/rows.go @@ -1,19 +1,9 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include "dpiImpl.h" @@ -30,7 +20,7 @@ import ( "time" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) var _ = driver.Rows((*rows)(nil)) @@ -72,17 +62,16 @@ func (r *rows) Close() error { if r == nil { return nil } - r.columns = nil - r.data = nil - for _, v := range r.vars { - C.dpiVar_release(v) + vars, st := r.vars, r.statement + r.columns, r.vars, r.data, r.statement, r.nextRs = nil, nil, nil, nil, nil + for _, v := range vars[:cap(vars)] { + if v != nil { + C.dpiVar_release(v) + } } - r.vars = nil - if r.statement == nil { + if st == nil { return nil } - st := r.statement - r.statement = nil st.Lock() defer st.Unlock() @@ -91,7 +80,7 @@ func (r *rows) Close() error { } var err error if C.dpiStmt_release(st.dpiStmt) == C.DPI_FAILURE { - err = errors.Wrap(r.getError(), "rows/dpiStmt_release") + err = errors.Errorf("rows/dpiStmt_release: %w", r.getError()) } return err } @@ -266,6 +255,8 @@ func (r *rows) ColumnTypeScanType(index int) reflect.Type { // size as the Columns() are wide. // // Next should return io.EOF when there are no more rows. +// +// As with all Objects, you MUST call Close on the returned Object instances when they're not needed anymore! func (r *rows) Next(dest []driver.Value) error { if r.err != nil { return r.err @@ -280,7 +271,7 @@ func (r *rows) Next(dest []driver.Value) error { if r.fetched == 0 { var moreRows C.int if C.dpiStmt_fetchRows(r.dpiStmt, C.uint32_t(r.statement.FetchRowCount()), &r.bufferRowIndex, &r.fetched, &moreRows) == C.DPI_FAILURE { - return errors.Wrap(r.getError(), "Next") + return errors.Errorf("Next: %w", r.getError()) } if Log != nil { Log("msg", "fetched", "bri", r.bufferRowIndex, "fetched", r.fetched, "moreRows", moreRows, "len(data)", len(r.data), "cols", len(r.columns)) @@ -296,7 +287,7 @@ func (r *rows) Next(dest []driver.Value) error { var n C.uint32_t var data *C.dpiData if C.dpiVar_getReturnedData(r.vars[i], 0, &n, &data) == C.DPI_FAILURE { - return errors.Wrapf(r.getError(), "getReturnedData[%d]", i) + return errors.Errorf("getReturnedData[%d]: %w", i, r.getError()) } r.data[i] = (*[maxArraySize]C.dpiData)(unsafe.Pointer(data))[:n:n] //fmt.Printf("data %d=%+v\n%+v\n", n, data, r.data[i][0]) @@ -313,7 +304,7 @@ func (r *rows) Next(dest []driver.Value) error { typ := col.OracleType d := &r.data[i][r.bufferRowIndex] isNull := d.isNull == 1 - if Log != nil { + if false && Log != nil { Log("msg", "Next", "i", i, "row", r.bufferRowIndex, "typ", typ, "null", isNull) //, "data", fmt.Sprintf("%+v", d), "typ", typ) } @@ -352,7 +343,12 @@ func (r *rows) Next(dest []driver.Value) error { dest[i] = printFloat(float64(C.dpiData_getDouble(d))) default: b := C.dpiData_getBytes(d) - dest[i] = Number(C.GoStringN(b.ptr, C.int(b.length))) + s := C.GoStringN(b.ptr, C.int(b.length)) + if r.NumberAsString() { + dest[i] = s + } else { + dest[i] = Number(s) + } if Log != nil { Log("msg", "b", "i", i, "ptr", b.ptr, "length", b.length, "typ", col.NativeType, "int64", C.dpiData_getInt64(d), "dest", dest[i]) } @@ -436,7 +432,7 @@ func (r *rows) Next(dest []driver.Value) error { C.DPI_NATIVE_TYPE_LOB: isClob := typ == C.DPI_ORACLE_TYPE_CLOB || typ == C.DPI_ORACLE_TYPE_NCLOB if isNull { - if isClob && r.ClobAsString() { + if isClob && (r.ClobAsString() || !r.LobAsReader()) { dest[i] = "" } else { dest[i] = nil @@ -444,9 +440,11 @@ func (r *rows) Next(dest []driver.Value) error { continue } rdr := &dpiLobReader{dpiLob: C.dpiData_getLOB(d), conn: r.conn, IsClob: isClob} - if isClob && r.ClobAsString() { + if isClob && (r.ClobAsString() || !r.LobAsReader()) { sb := stringBuilders.Get() - if _, err := io.Copy(sb, rdr); err != nil { + _, err := io.Copy(sb, rdr) + C.dpiLob_close(rdr.dpiLob) + if err != nil { stringBuilders.Put(sb) return err } @@ -466,7 +464,7 @@ func (r *rows) Next(dest []driver.Value) error { } var colCount C.uint32_t if C.dpiStmt_getNumQueryColumns(st.dpiStmt, &colCount) == C.DPI_FAILURE { - return errors.Wrap(r.getError(), "getNumQueryColumns") + return errors.Errorf("getNumQueryColumns: %w", r.getError()) } st.Lock() r2, err := st.openRows(int(colCount)) @@ -488,7 +486,7 @@ func (r *rows) Next(dest []driver.Value) error { dest[i] = nil continue } - o, err := wrapObject(r.drv, col.ObjectType, C.dpiData_getObject(d)) + o, err := wrapObject(r.conn, col.ObjectType, C.dpiData_getObject(d)) if err != nil { return err } @@ -503,6 +501,10 @@ func (r *rows) Next(dest []driver.Value) error { r.bufferRowIndex++ r.fetched-- + if Log != nil { + Log("msg", "scanned", "row", r.bufferRowIndex, "dest", dest) + } + return nil } @@ -562,7 +564,7 @@ func (r *rows) getImplicitResult() { r.origSt = st } if C.dpiStmt_getImplicitResult(st.dpiStmt, &r.nextRs) == C.DPI_FAILURE { - r.nextRsErr = errors.Wrap(r.getError(), "getImplicitResult") + r.nextRsErr = errors.Errorf("getImplicitResult: %w", r.getError()) } } func (r *rows) HasNextResultSet() bool { @@ -586,14 +588,14 @@ func (r *rows) NextResultSet() error { return r.nextRsErr } if r.nextRs == nil { - return errors.Wrap(io.EOF, "getImplicitResult") + return errors.Errorf("getImplicitResult: %w", io.EOF) } } st := &statement{conn: r.conn, dpiStmt: r.nextRs} var n C.uint32_t if C.dpiStmt_getNumQueryColumns(st.dpiStmt, &n) == C.DPI_FAILURE { - return errors.Wrapf(io.EOF, "getNumQueryColumns: %v", r.getError()) + return errors.Errorf("getNumQueryColumns: %w: %w", r.getError(), io.EOF) } // keep the originam statement for the succeeding NextResultSet calls. nr, err := st.openRows(int(n)) diff --git a/vendor/github.com/godror/godror/sid/sid.go b/vendor/github.com/godror/godror/sid/sid.go new file mode 100644 index 00000000000..b1fb0953142 --- /dev/null +++ b/vendor/github.com/godror/godror/sid/sid.go @@ -0,0 +1,531 @@ +// Copyright 2019 Tamás Gulácsi +// +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LIENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR ONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sid + +import ( + "fmt" + "io" + "strconv" + "strings" + "unicode" + + errors "golang.org/x/xerrors" +) + +// Statement can Parse and Print Oracle connection descriptor (DESRIPTION=(ADDRESS=...)) format. +// It can be used to parse or build a SID. +// +// See https://docs.oracle.com/cd/B28359_01/network.111/b28317/tnsnames.htm#NETRF271 +type Statement struct { + Name, Value string + Statements []Statement +} + +func (cs Statement) String() string { + var buf strings.Builder + cs.Print(&buf, "\n", " ") + return buf.String() +} +func (cs Statement) Print(w io.Writer, prefix, indent string) { + fmt.Fprintf(w, "%s(%s=%s", prefix, cs.Name, cs.Value) + if cs.Value == "" { + for _, s := range cs.Statements { + s.Print(w, prefix+indent, indent) + } + } + io.WriteString(w, ")") +} + +func ParseConnDescription(s string) (Statement, error) { + var cs Statement + _, err := cs.Parse(s) + return cs, err +} +func (cs *Statement) Parse(s string) (string, error) { + ltrim := func(s string) string { return strings.TrimLeftFunc(s, unicode.IsSpace) } + s = ltrim(s) + if s == "" || s[0] != '(' { + return s, nil + } + i := strings.IndexByte(s[1:], '=') + 1 + if i <= 0 || strings.Contains(s[1:i], ")") { + return s, errors.Errorf("no = after ( in %q", s) + } + cs.Name = s[1:i] + s = ltrim(s[i+1:]) + + if s == "" { + return s, nil + } + if s[0] != '(' { + if i = strings.IndexByte(s, ')'); i < 0 || strings.Contains(s[1:i], "(") { + return s, errors.Errorf("no ) after = in %q", s) + } + cs.Value = s[:i] + s = ltrim(s[i+1:]) + return s, nil + } + + for s != "" && s[0] == '(' { + var sub Statement + var err error + if s, err = sub.Parse(s); err != nil { + return s, err + } + if sub.Name == "" { + break + } + cs.Statements = append(cs.Statements, sub) + } + s = ltrim(s) + if s != "" && s[0] == ')' { + s = ltrim(s[1:]) + } + return s, nil +} + +type DescriptionList struct { + Options ListOptions + Descriptions []Description + TypeOfService string +} + +func (cd DescriptionList) Print(w io.Writer, prefix, indent string) { + io.WriteString(w, prefix+"(DESCRIPTION_LIST=") + cd.Options.Print(w, prefix, indent) + for _, d := range cd.Descriptions { + d.Print(w, prefix, indent) + } + if cd.TypeOfService != "" { + fmt.Fprintf(w, "%s(TYPE_OF_SERVICE=%s)", prefix, cd.TypeOfService) + } + io.WriteString(w, ")") +} +func (cd *DescriptionList) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "DESCRIPTION_LIST" { + ss = ss[0].Statements + } + cd.TypeOfService = "" + if err := cd.Options.Parse(ss); err != nil { + return err + } + cd.Descriptions = cd.Descriptions[:0] + for _, s := range ss { + switch s.Name { + case "DESCRIPTION": + var d Description + if err := d.Parse(s.Statements); err != nil { + return err + } + cd.Descriptions = append(cd.Descriptions, d) + case "TYPE_OF_SERVICE": + cd.TypeOfService = s.Value + } + } + return cd.Options.Parse(ss) +} + +type Description struct { + TCPKeepAlive bool + SDU int + Bufs BufSizes + Options ListOptions + Addresses []Address + AddressList AddressList + ConnectData ConnectData + TypeOfService string + Security Security +} + +func (d Description) Print(w io.Writer, prefix, indent string) { + if d.IsZero() { + return + } + io.WriteString(w, prefix+"(DESCRIPTION=") + if d.TCPKeepAlive { + io.WriteString(w, prefix+"(ENABLE=broken)") + } + if d.SDU != 0 { + fmt.Fprintf(w, prefix+"(SDU=%d)", d.SDU) + } + d.Bufs.Print(w, prefix, indent) + d.Options.Print(w, prefix, indent) + for _, a := range d.Addresses { + a.Print(w, prefix, indent) + } + d.AddressList.Print(w, prefix, indent) + d.ConnectData.Print(w, prefix, indent) + if d.TypeOfService != "" { + fmt.Fprintf(w, "%s(TYPE_OF_SERVICE=%s)", prefix, d.TypeOfService) + } + d.Security.Print(w, prefix, indent) + io.WriteString(w, ")") +} +func (d Description) IsZero() bool { + return !d.TCPKeepAlive && d.SDU == 0 && d.Bufs.IsZero() && d.Options.IsZero() && len(d.Addresses) == 0 && d.AddressList.IsZero() && d.ConnectData.IsZero() && d.TypeOfService == "" && d.Security.IsZero() +} +func (d *Description) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "DESCRIPTION" { + ss = ss[0].Statements + } + d.TCPKeepAlive, d.SDU = false, 0 + for _, s := range ss { + switch s.Name { + case "ADDRESS": + var a Address + if err := a.Parse(s.Statements); err != nil { + return err + } + if !a.IsZero() { + d.Addresses = append(d.Addresses, a) + } + case "ADDRESS_LIST": + if err := d.AddressList.Parse(s.Statements); err != nil { + return err + } + case "CONNECT_DATA": + if err := d.ConnectData.Parse(s.Statements); err != nil { + return err + } + case "ENABLE": + d.TCPKeepAlive = d.TCPKeepAlive || s.Value == "broken" + case "SDU": + var err error + if d.SDU, err = strconv.Atoi(s.Value); err != nil { + return err + } + case "SECURITY": + if err := d.Security.Parse(s.Statements); err != nil { + return err + } + } + } + if err := d.Bufs.Parse(ss); err != nil { + return err + } + if err := d.Options.Parse(ss); err != nil { + return err + } + return nil +} + +type Address struct { + Protocol, Host string + Port int + BufSizes +} + +func (a Address) Print(w io.Writer, prefix, indent string) { + if a.IsZero() { + return + } + io.WriteString(w, prefix+"(ADDRESS=") + if a.Protocol != "" { + fmt.Fprintf(w, "%s(PROTOCOL=%s)", prefix, a.Protocol) + } + if a.Host != "" { + fmt.Fprintf(w, "%s(HOST=%s)", prefix, a.Host) + } + if a.Port != 0 { + fmt.Fprintf(w, "%s(PORT=%d)", prefix, a.Port) + } + a.BufSizes.Print(w, prefix, indent) + io.WriteString(w, ")") +} +func (a Address) IsZero() bool { + return a.Protocol == "" && a.Host == "" && a.Port == 0 && a.BufSizes.IsZero() +} +func (a *Address) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "ADDRESS" { + ss = ss[0].Statements + } + for _, s := range ss { + switch s.Name { + case "PROTOCOL": + a.Protocol = s.Value + case "HOST": + a.Host = s.Value + case "PORT": + i, err := strconv.Atoi(s.Value) + if err != nil { + return err + } + a.Port = i + } + } + return a.BufSizes.Parse(ss) +} + +type BufSizes struct { + RecvBufSize, SendBufSize int +} + +func (bs BufSizes) Print(w io.Writer, prefix, indent string) { + if bs.RecvBufSize > 0 { + fmt.Fprintf(w, "%s(RECV_BUF_SIZE=%d)", prefix, bs.RecvBufSize) + } + if bs.SendBufSize > 0 { + fmt.Fprintf(w, "%s(SEND_BUF_SIZE=%d)", prefix, bs.SendBufSize) + } +} +func (bs BufSizes) IsZero() bool { return bs.RecvBufSize > 0 && bs.SendBufSize > 0 } +func (bs *BufSizes) Parse(ss []Statement) error { + for _, s := range ss { + switch s.Name { + case "RECV_BUF_SIZE", "SEND_BUF_SIZE": + i, err := strconv.Atoi(s.Value) + if err != nil { + return err + } + if s.Name == "RECV_BUF_SIZE" { + bs.RecvBufSize = i + } else { + bs.SendBufSize = i + } + } + } + return nil +} + +type ListOptions struct { + Failover, LoadBalance, SourceRoute bool +} + +func (lo ListOptions) Print(w io.Writer, prefix, indent string) { + if lo.Failover { + io.WriteString(w, prefix+"(FAILOVER=on)") + } + if lo.LoadBalance { + io.WriteString(w, prefix+"(LOAD_BALANE=on)") + } + if lo.SourceRoute { + io.WriteString(w, prefix+"(SOURE_ROUTE=on)") + } +} +func (lo ListOptions) IsZero() bool { return !lo.Failover && !lo.LoadBalance && !lo.SourceRoute } +func s2b(s string) bool { return s == "on" || s == "yes" || s == "true" } +func (lo *ListOptions) Parse(ss []Statement) error { + *lo = ListOptions{} + for _, s := range ss { + switch s.Name { + case "FAILOVER": + lo.Failover = s2b(s.Value) + case "LOAD_BALANE": + lo.LoadBalance = s2b(s.Value) + case "SourceRoute": + lo.SourceRoute = s2b(s.Value) + } + } + return nil +} + +type AddressList struct { + Options ListOptions + Addresses []Address +} + +func (al AddressList) Print(w io.Writer, prefix, indent string) { + if al.IsZero() { + return + } + io.WriteString(w, prefix+"(ADDRESS_LIST=") + al.Options.Print(w, prefix, indent) + for _, a := range al.Addresses { + a.Print(w, prefix, indent) + } + io.WriteString(w, ")") +} +func (al AddressList) IsZero() bool { return al.Options.IsZero() && len(al.Addresses) == 0 } +func (al *AddressList) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "ADDRESS_LIST" { + ss = ss[0].Statements + } + if err := al.Options.Parse(ss); err != nil { + return err + } + al.Addresses = al.Addresses[:0] + for _, s := range ss { + switch s.Name { + case "ADDRESS": + var a Address + if err := a.Parse(s.Statements); err != nil { + return err + } + if !a.IsZero() { + al.Addresses = append(al.Addresses, a) + } + } + } + return nil +} + +type ConnectData struct { + FailoverMode FailoverMode + ServiceName, SID string + GlobalName, InstanceName, RDBDatabase string + Hs bool + Server ServiceHandler +} + +func (cd ConnectData) Print(w io.Writer, prefix, indent string) { + if cd.IsZero() { + return + } + io.WriteString(w, prefix+"(CONNECT_DATA=") + cd.FailoverMode.Print(w, prefix, indent) + if cd.GlobalName != "" { + fmt.Fprintf(w, "%s(GLOBAL_NAME=%s)", prefix, cd.GlobalName) + } + if cd.InstanceName != "" { + fmt.Fprintf(w, "%s(INSTANCE_NAME=%s)", prefix, cd.InstanceName) + } + if cd.RDBDatabase != "" { + fmt.Fprintf(w, "%s(RDB_DATABASE=%s)", prefix, cd.RDBDatabase) + } + if cd.ServiceName != "" { + fmt.Fprintf(w, "%s(SERVICE_NAME=%s)", prefix, cd.ServiceName) + } + if cd.SID != "" { + fmt.Fprintf(w, "%s(SID=%s)", prefix, cd.SID) + } + if cd.Hs { + io.WriteString(w, prefix+"(HS=ok)") + } + if cd.Server != "" { + fmt.Fprintf(w, "%s(SERVER=%s)", prefix, cd.Server) + } + io.WriteString(w, ")") +} +func (cd ConnectData) IsZero() bool { + return cd.FailoverMode.IsZero() && cd.GlobalName == "" && cd.InstanceName == "" && cd.RDBDatabase == "" && cd.ServiceName == "" && cd.SID == "" && !cd.Hs && cd.Server == "" +} +func (cd *ConnectData) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "CONNECT_DATA" { + ss = ss[0].Statements + } + cd.Hs = false + for _, s := range ss { + switch s.Name { + case "FAILOVER_MODE": + if err := cd.FailoverMode.Parse(s.Statements); err != nil { + return err + } + case "GLOBAL_NAME": + cd.GlobalName = s.Value + case "INSTANCE_NAME": + cd.InstanceName = s.Value + case "RDB_DATABASE": + cd.RDBDatabase = s.Value + case "SERVICE_NAME": + cd.ServiceName = s.Value + case "SID": + cd.SID = s.Value + case "HS": + cd.Hs = s.Value == "ok" + case "SERVER": + cd.Server = ServiceHandler(s.Value) + } + } + return nil +} + +type FailoverMode struct { + Backup, Type, Method string + Retry, Delay int +} + +func (fo FailoverMode) Print(w io.Writer, prefix, indent string) { + if fo.IsZero() { + return + } + io.WriteString(w, prefix+"(FAILOVER_MODE=") + if fo.Backup != "" { + fmt.Fprintf(w, "%s(BACKUP=%s)", prefix, fo.Backup) + } + if fo.Type != "" { + fmt.Fprintf(w, "%s(TYPE=%s)", prefix, fo.Type) + } + if fo.Method != "" { + fmt.Fprintf(w, "%s(METHOD=%s)", prefix, fo.Method) + } + if fo.Retry != 0 { + fmt.Fprintf(w, "%s(RETRY=%d)", prefix, fo.Retry) + } + if fo.Delay != 0 { + fmt.Fprintf(w, "%s(DELAY=%d)", prefix, fo.Delay) + } + io.WriteString(w, ")") +} +func (fo FailoverMode) IsZero() bool { + return fo.Backup == "" && fo.Type == "" && fo.Method == "" && fo.Retry == 0 && fo.Delay == 0 +} +func (fo *FailoverMode) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "FAILOVER_MODE" { + ss = ss[0].Statements + } + for _, s := range ss { + switch s.Name { + case "BACKUP": + fo.Backup = s.Value + case "TYPE": + fo.Type = s.Value + case "METHOD": + fo.Method = s.Value + case "RETRY", "DELAY": + i, err := strconv.Atoi(s.Value) + if err != nil { + return err + } + if s.Name == "RETRY" { + fo.Retry = i + } else { + fo.Delay = i + } + } + } + return nil +} + +type ServiceHandler string + +const ( + Dedicated = ServiceHandler("dedicated") + Shared = ServiceHandler("shared") + Pooled = ServiceHandler("pooled") +) + +type Security struct { + SSLServerCertDN string +} + +func (sec Security) Print(w io.Writer, prefix, indent string) { + if sec.SSLServerCertDN != "" { + fmt.Fprintf(w, "%s(SECURITY=(SSL_SERVER_CERT_DN=%s))", prefix, sec.SSLServerCertDN) + } +} +func (sec Security) IsZero() bool { return sec.SSLServerCertDN == "" } +func (sec *Security) Parse(ss []Statement) error { + if len(ss) == 1 && ss[0].Name == "SECURITY" { + ss = ss[0].Statements + } + sec.SSLServerCertDN = "" + for _, s := range ss { + if s.Name == "SSL_SERVER_CERT_DN" { + sec.SSLServerCertDN = s.Value + } + } + return nil +} diff --git a/vendor/gopkg.in/goracle.v2/stmt.go b/vendor/github.com/godror/godror/stmt.go similarity index 88% rename from vendor/gopkg.in/goracle.v2/stmt.go rename to vendor/github.com/godror/godror/stmt.go index 6e8e6215365..0e0775b363d 100644 --- a/vendor/gopkg.in/goracle.v2/stmt.go +++ b/vendor/github.com/godror/godror/stmt.go @@ -1,25 +1,24 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include #include "dpiImpl.h" const int sizeof_dpiData = sizeof(void); + +void godror_setFromString(dpiVar *dv, uint32_t pos, const _GoString_ value) { + uint32_t length; + length = _GoStringLen(value); + if( length == 0 ) { + return; + } + dpiVar_setFromBytes(dv, pos, _GoStringPtr(value), length); +} */ import "C" import ( @@ -30,11 +29,12 @@ import ( "io" "reflect" "strconv" + "strings" "sync" "time" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) type stmtOptions struct { @@ -45,6 +45,7 @@ type stmtOptions struct { plSQLArrays bool lobAsReader bool magicTypeConversion bool + numberAsString bool } func (o stmtOptions) ExecMode() C.dpiExecMode { @@ -55,8 +56,10 @@ func (o stmtOptions) ExecMode() C.dpiExecMode { } func (o stmtOptions) ArraySize() int { - if o.arraySize <= 0 || o.arraySize > 32<<10 { + if o.arraySize <= 0 { return DefaultArraySize + } else if o.arraySize > 1<<16 { + return 1 << 16 } return o.arraySize } @@ -72,6 +75,7 @@ func (o stmtOptions) ClobAsString() bool { return !o.lobAsReader } func (o stmtOptions) LobAsReader() bool { return o.lobAsReader } func (o stmtOptions) MagicTypeConversion() bool { return o.magicTypeConversion } +func (o stmtOptions) NumberAsString() bool { return o.numberAsString } // Option holds statement options. type Option func(*stmtOptions) @@ -135,6 +139,11 @@ func MagicTypeConversion() Option { return func(o *stmtOptions) { o.magicTypeConversion = true } } +// NumberAsString returns an option to return numbers as string, not Number. +func NumberAsString() Option { + return func(o *stmtOptions) { o.numberAsString = true } +} + // CallTimeout sets the round-trip timeout (OCI_ATTR_CALL_TIMEOUT). // // See https://docs.oracle.com/en/database/oracle/oracle-database/18/lnoci/handle-and-descriptor-attributes.html#GUID-D8EE68EB-7E38-4068-B06E-DF5686379E5E @@ -178,36 +187,16 @@ func (st *statement) Close() error { st.Lock() defer st.Unlock() - return st.close() -} -func (st *statement) close() error { - if st == nil { - return nil - } - dpiStmt := st.dpiStmt - c := st.conn - st.cleanup() - - var si C.dpiStmtInfo - if dpiStmt != nil && - C.dpiStmt_getInfo(dpiStmt, &si) != C.DPI_FAILURE && // this is just to check the validity of dpiStmt, to avoid SIGSEGV - C.dpiStmt_release(dpiStmt) != C.DPI_FAILURE { - return nil - } - if c == nil { - return driver.ErrBadConn - } - return errors.Wrap(c.getError(), "statement/dpiStmt_release") + return st.close(false) } - -func (st *statement) cleanup() error { +func (st *statement) close(keepDpiStmt bool) error { if st == nil { return nil } - for _, v := range st.vars { - C.dpiVar_release(v) - } + c, dpiStmt, vars := st.conn, st.dpiStmt, st.vars + st.isSlice = nil + st.query = "" st.data = nil st.vars = nil st.varInfos = nil @@ -215,13 +204,29 @@ func (st *statement) cleanup() error { st.dests = nil st.columns = nil st.dpiStmt = nil - c := st.conn st.conn = nil + for _, v := range vars[:cap(vars)] { + if v != nil { + C.dpiVar_release(v) + } + } + + if !keepDpiStmt { + var si C.dpiStmtInfo + if dpiStmt != nil && + C.dpiStmt_getInfo(dpiStmt, &si) != C.DPI_FAILURE && // this is just to check the validity of dpiStmt, to avoid SIGSEGV + C.dpiStmt_release(dpiStmt) != C.DPI_FAILURE { + return nil + } + } if c == nil { return driver.ErrBadConn } - return errors.Wrap(c.getError(), "statement/dpiStmt_release") + if err := c.getError(); err != nil { + return errors.Errorf("statement/dpiStmt_release: %w", err) + } + return nil } // Exec executes a query that doesn't return rows, such @@ -253,6 +258,8 @@ func (st *statement) Query(args []driver.Value) (driver.Rows, error) { // ExecContext executes a query that doesn't return rows, such as an INSERT or UPDATE. // // ExecContext must honor the context timeout and return when it is canceled. +// +// Cancelation/timeout is honored, execution is broken, but you may have to disable out-of-bound execution - see https://github.com/oracle/odpi/issues/116 for details. func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) (res driver.Result, err error) { if err = ctx.Err(); err != nil { return nil, err @@ -262,9 +269,10 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) closeIfBadConn := func(err error) error { if err != nil && err == driver.ErrBadConn { if Log != nil { - Log("error", driver.ErrBadConn) + Log("error", err) } - st.close() + st.close(false) + st.conn.close(true) } return err } @@ -328,15 +336,13 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) if err == nil { var info C.dpiStmtInfo if C.dpiStmt_getInfo(st.dpiStmt, &info) == C.DPI_FAILURE { - err = errors.Wrap(st.getError(), "getInfo") + err = errors.Errorf("getInfo: %w", st.getError()) } st.isReturning = info.isReturning != 0 return } - cdr, ok := errors.Cause(err).(interface { - Code() int - }) - if !ok { + var cdr interface{ Code() int } + if !errors.As(err, &cdr) { break } switch code := cdr.Code(); code { @@ -349,7 +355,11 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) } break } - done <- maybeBadConn(errors.Wrapf(err, "dpiStmt_execute(mode=%d arrLen=%d)", mode, st.arrLen)) + if err == nil { + done <- nil + return + } + done <- maybeBadConn(errors.Errorf("dpiStmt_execute(mode=%d arrLen=%d): %w", mode, st.arrLen, err), nil) }() select { @@ -369,8 +379,11 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) Log("msg", "BREAK statement") } _ = st.Break() - st.cleanup() - return nil, driver.ErrBadConn + st.close(false) + if err := st.conn.Close(); err != nil { + return nil, err + } + return nil, ctx.Err() } } @@ -386,7 +399,7 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) data := &st.data[i][0] if C.dpiVar_getReturnedData(st.vars[i], 0, &n, &data) == C.DPI_FAILURE { err = st.getError() - return nil, errors.Wrapf(closeIfBadConn(err), "%d.getReturnedData", i) + return nil, errors.Errorf("%d.getReturnedData: %w", i, closeIfBadConn(err)) } if n == 0 { st.data[i] = st.data[i][:0] @@ -400,7 +413,7 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) if Log != nil { Log("get", i, "error", err) } - return nil, errors.Wrapf(closeIfBadConn(err), "%d. get[%d]", i, 0) + return nil, errors.Errorf("%d. get[%d]: %w", i, 0, closeIfBadConn(err)) } continue } @@ -410,14 +423,14 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) if Log != nil { Log("msg", "getNumElementsInArray", "i", i, "error", err) } - return nil, errors.Wrapf(closeIfBadConn(err), "%d.getNumElementsInArray", i) + return nil, errors.Errorf("%d.getNumElementsInArray: %w", i, closeIfBadConn(err)) } //fmt.Printf("i=%d dest=%T %#v\n", i, dest, dest) if err = get(dest, st.data[i][:n]); err != nil { if Log != nil { Log("msg", "get", "i", i, "n", n, "error", err) } - return nil, errors.Wrapf(closeIfBadConn(err), "%d. get", i) + return nil, errors.Errorf("%d. get: %w", i, closeIfBadConn(err)) } } var count C.uint64_t @@ -430,6 +443,8 @@ func (st *statement) ExecContext(ctx context.Context, args []driver.NamedValue) // QueryContext executes a query that may return rows, such as a SELECT. // // QueryContext must honor the context timeout and return when it is canceled. +// +// Cancelation/timeout is honored, execution is broken, but you may have to disable out-of-bound execution - see https://github.com/oracle/odpi/issues/116 for details. func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) { if err := ctx.Err(); err != nil { return nil, err @@ -438,7 +453,11 @@ func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) closeIfBadConn := func(err error) error { if err != nil && err == driver.ErrBadConn { - st.close() + if Log != nil { + Log("error", err) + } + st.close(false) + st.conn.close(true) } return err } @@ -469,6 +488,12 @@ func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) return nil, closeIfBadConn(err) } + mode := st.ExecMode() + //fmt.Printf("%p.%p: inTran? %t\n%s\n", st.conn, st, st.inTransaction, st.query) + if !st.inTransaction { + mode |= C.DPI_MODE_EXEC_COMMIT_ON_SUCCESS + } + // execute var colCount C.uint32_t done := make(chan error, 1) @@ -481,7 +506,7 @@ func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) return } st.setCallTimeout(ctx) - if C.dpiStmt_execute(st.dpiStmt, st.ExecMode(), &colCount) != C.DPI_FAILURE { + if C.dpiStmt_execute(st.dpiStmt, mode, &colCount) != C.DPI_FAILURE { break } if err = ctx.Err(); err == nil { @@ -491,7 +516,11 @@ func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) } } } - done <- maybeBadConn(errors.Wrap(err, "dpiStmt_execute")) + if err == nil { + done <- nil + return + } + done <- maybeBadConn(errors.Errorf("dpiStmt_execute: %w", err), nil) }() select { @@ -510,8 +539,11 @@ func (st *statement) QueryContext(ctx context.Context, args []driver.NamedValue) Log("msg", "BREAK query") } _ = st.Break() - st.cleanup() - return nil, driver.ErrBadConn + st.close(false) + if err := st.conn.Close(); err != nil { + return nil, err + } + return nil, ctx.Err() } } rows, err := st.openRows(int(colCount)) @@ -539,10 +571,6 @@ func (st *statement) NumInput() int { return 0 } - if !go10 { - return -1 - } - st.Lock() defer st.Unlock() var cnt C.uint32_t @@ -587,12 +615,10 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { if Log != nil { Log("enter", "bindVars", "args", args) } - if cap(st.vars) < len(args) || cap(st.varInfos) < len(args) { - for i, v := range st.vars { - if v != nil { - C.dpiVar_release(v) - st.vars[i], st.varInfos[i] = nil, varInfo{} - } + for i, v := range st.vars[:cap(st.vars)] { + if v != nil { + C.dpiVar_release(v) + st.vars[i], st.varInfos[i] = nil, varInfo{} } } var named bool @@ -713,7 +739,7 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { var err error if value, err = st.bindVarTypeSwitch(info, &(st.gets[i]), value); err != nil { - return errors.Wrapf(err, "%d. arg", i+1) + return errors.Errorf("%d. arg: %w", i+1, err) } var rv reflect.Value @@ -742,12 +768,8 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { return errors.Errorf("maximum array size allowed is %d", maxArraySize) } if st.vars[i] == nil || st.data[i] == nil || st.varInfos[i] != vi { - if st.vars[i] != nil { - C.dpiVar_release(st.vars[i]) - st.vars[i] = nil - } if st.vars[i], st.data[i], err = st.newVar(vi); err != nil { - return errors.WithMessage(err, fmt.Sprintf("%d", i)) + return errors.Errorf("%d: %w", i, err) } st.varInfos[i] = vi } @@ -760,7 +782,7 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { Log("C", "dpiVar_setNumElementsInArray", "i", i, "n", 0) } if C.dpiVar_setNumElementsInArray(dv, C.uint32_t(0)) == C.DPI_FAILURE { - return errors.Wrapf(st.getError(), "setNumElementsInArray[%d](%d)", i, 0) + return errors.Errorf("setNumElementsInArray[%d](%d): %w", i, 0, st.getError()) } } continue @@ -771,7 +793,7 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { Log("msg", "set", "i", i, "value", fmt.Sprintf("%T=%#v", value, value)) } if err := info.set(dv, data[:1], value); err != nil { - return errors.Wrapf(err, "set(data[%d][%d], %#v (%T))", i, 0, value, value) + return errors.Errorf("set(data[%d][%d], %#v (%T)): %w", i, 0, value, value, err) } continue } @@ -783,7 +805,7 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { Log("C", "dpiVar_setNumElementsInArray", "i", i, "n", n) } if C.dpiVar_setNumElementsInArray(dv, C.uint32_t(n)) == C.DPI_FAILURE { - return errors.Wrapf(st.getError(), "%+v.setNumElementsInArray[%d](%d)", dv, i, n) + return errors.Errorf("%+v.setNumElementsInArray[%d](%d): %w", dv, i, n, st.getError()) } } //fmt.Println("n:", len(st.data[i])) @@ -796,7 +818,7 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { for i, v := range st.vars { //if Log != nil {Log("C", "dpiStmt_bindByPos", "dpiStmt", st.dpiStmt, "i", i, "v", v) } if C.dpiStmt_bindByPos(st.dpiStmt, C.uint32_t(i+1), v) == C.DPI_FAILURE { - return errors.Wrapf(st.getError(), "bindByPos[%d]", i) + return errors.Errorf("bindByPos[%d]: %w", i, st.getError()) } } return nil @@ -811,7 +833,7 @@ func (st *statement) bindVars(args []driver.NamedValue, Log logFunc) error { res := C.dpiStmt_bindByName(st.dpiStmt, cName, C.uint32_t(len(name)), st.vars[i]) C.free(unsafe.Pointer(cName)) if res == C.DPI_FAILURE { - return errors.Wrapf(st.getError(), "bindByName[%q]", name) + return errors.Errorf("bindByName[%q]: %w", name, st.getError()) } } return nil @@ -835,7 +857,7 @@ func (st *statement) bindVarTypeSwitch(info *argInfo, get *dataGetter, value int if isValuer { var err error if value, err = vlr.Value(); err != nil { - return value, errors.Wrap(err, "arg.Value()") + return value, errors.Errorf("arg.Value(): %w", err) } return st.bindVarTypeSwitch(info, get, value) } @@ -1017,7 +1039,7 @@ func (st *statement) bindVarTypeSwitch(info *argInfo, get *dataGetter, value int } info.set = dataSetBytes if info.isOut { - info.bufSize = 4000 + info.bufSize = 32767 *get = dataGetBytes } @@ -1073,8 +1095,10 @@ func (st *statement) bindVarTypeSwitch(info *argInfo, get *dataGetter, value int } case *Object: - info.objType = v.ObjectType.dpiObjectType - info.typ, info.natTyp = C.DPI_ORACLE_TYPE_OBJECT, C.DPI_NATIVE_TYPE_OBJECT + if !nilPtr && v != nil { + info.objType = v.ObjectType.dpiObjectType + info.typ, info.natTyp = C.DPI_ORACLE_TYPE_OBJECT, C.DPI_NATIVE_TYPE_OBJECT + } info.set = st.dataSetObject if info.isOut { *get = st.dataGetObject @@ -1094,7 +1118,7 @@ func (st *statement) bindVarTypeSwitch(info *argInfo, get *dataGetter, value int } var err error if value, err = vlr.Value(); err != nil { - return value, errors.Wrap(err, "arg.Value()") + return value, errors.Errorf("arg.Value(): %w", err) } return st.bindVarTypeSwitch(info, get, value) } @@ -1139,6 +1163,13 @@ func dataSetBool(dv *C.dpiVar, data []C.dpiData, vv interface{}) error { return dataSetNull(dv, data, nil) } b := C.int(0) + if v, ok := vv.(bool); ok { + if v { + b = 1 + } + C.dpiData_setBool(&data[0], b) + return nil + } if bb, ok := vv.([]bool); ok { for i, v := range bb { if v { @@ -1146,10 +1177,10 @@ func dataSetBool(dv *C.dpiVar, data []C.dpiData, vv interface{}) error { } C.dpiData_setBool(&data[i], b) } - } else { - for i := range data { - data[i].isNull = 1 - } + return nil + } + for i := range data { + data[i].isNull = 1 } return nil } @@ -1507,18 +1538,27 @@ func dataGetBytes(v interface{}, data []C.dpiData) error { *x = nil return nil } - b := C.dpiData_getBytes(&data[0]) + db := C.dpiData_getBytes(&data[0]) + b := ((*[32767]byte)(unsafe.Pointer(db.ptr)))[:db.length:db.length] + // b must be copied + *x = append((*x)[:0], b...) - *x = ((*[32767]byte)(unsafe.Pointer(b.ptr)))[:b.length:b.length] case *[][]byte: + maX := (*x)[:cap(*x)] *x = (*x)[:0] for i := range data { if data[i].isNull == 1 { *x = append(*x, nil) continue } - b := C.dpiData_getBytes(&data[i]) - *x = append(*x, ((*[32767]byte)(unsafe.Pointer(b.ptr)))[:b.length:b.length]) + db := C.dpiData_getBytes(&data[i]) + b := ((*[32767]byte)(unsafe.Pointer(db.ptr)))[:db.length:db.length] + // b must be copied + if i < len(maX) { + *x = append(*x, append(maX[i][:0], b...)) + } else { + *x = append(*x, append(make([]byte, 0, len(b)), b...)) + } } case *Number: @@ -1702,7 +1742,7 @@ func (c *conn) dataGetStmtC(row *driver.Rows, data *C.dpiData) error { var n C.uint32_t if C.dpiStmt_getNumQueryColumns(st.dpiStmt, &n) == C.DPI_FAILURE { *row = &rows{ - err: errors.Wrapf(io.EOF, "getNumQueryColumns: %v", c.getError()), + err: errors.Errorf("getNumQueryColumns: %w: %w", c.getError(), io.EOF), } return nil } @@ -1777,7 +1817,7 @@ func (c *conn) dataSetLOB(dv *C.dpiVar, data []C.dpiData, vv interface{}) error } var lob *C.dpiLob if C.dpiConn_newTempLob(c.dpiConn, typ, &lob) == C.DPI_FAILURE { - return errors.Wrapf(c.getError(), "newTempLob(typ=%d)", typ) + return errors.Errorf("newTempLob(typ=%d): %w", typ, c.getError()) } var chunkSize C.uint32_t _ = C.dpiLob_getChunkSize(lob, &chunkSize) @@ -1832,8 +1872,15 @@ func (c *conn) dataSetObject(dv *C.dpiVar, data []C.dpiData, vv interface{}) err switch o := vv.(type) { case Object: objs[0] = o + case *Object: + objs[0] = *o case []Object: objs = o + case []*Object: + objs = make([]Object, len(o)) + for i, x := range o { + objs[i] = *x + } case ObjectWriter: err := o.WriteObject() if err != nil { @@ -1858,10 +1905,12 @@ func (c *conn) dataSetObject(dv *C.dpiVar, data []C.dpiData, vv interface{}) err for i, obj := range objs { if obj.dpiObject == nil { data[i].isNull = 1 - return nil + continue } data[i].isNull = 0 - C.dpiVar_setFromObject(dv, C.uint32_t(i), obj.dpiObject) + if C.dpiVar_setFromObject(dv, C.uint32_t(i), obj.dpiObject) == C.DPI_FAILURE { + return errors.Errorf("setFromObject: %w", c.getError()) + } } return nil } @@ -1949,7 +1998,7 @@ func (st *statement) openRows(colCount int) (*rows, error) { var ti C.dpiDataTypeInfo for i := 0; i < colCount; i++ { if C.dpiStmt_getQueryInfo(st.dpiStmt, C.uint32_t(i+1), &info) == C.DPI_FAILURE { - return nil, errors.Wrapf(st.getError(), "getQueryInfo[%d]", i) + return nil, errors.Errorf("getQueryInfo[%d]: %w", i, st.getError()) } ti = info.typeInfo bufSize := int(ti.clientSizeInBytes) @@ -2002,11 +2051,11 @@ func (st *statement) openRows(colCount int) (*rows, error) { } if C.dpiStmt_define(st.dpiStmt, C.uint32_t(i+1), r.vars[i]) == C.DPI_FAILURE { - return nil, errors.Wrapf(st.getError(), "define[%d]", i) + return nil, errors.Errorf("define[%d]: %w", i, st.getError()) } } if C.dpiStmt_addRef(st.dpiStmt) == C.DPI_FAILURE { - return &r, errors.Wrap(st.getError(), "dpiStmt_addRef") + return &r, errors.Errorf("dpiStmt_addRef: %w", st.getError()) } st.columns = r.columns return &r, nil @@ -2023,3 +2072,41 @@ type Column struct { Scale C.int8_t Nullable bool } + +func dpiSetFromString(dv *C.dpiVar, pos C.uint32_t, x string) { + C.godror_setFromString(dv, pos, x) +} + +var stringBuilders = stringBuilderPool{ + p: &sync.Pool{New: func() interface{} { return &strings.Builder{} }}, +} + +type stringBuilderPool struct { + p *sync.Pool +} + +func (sb stringBuilderPool) Get() *strings.Builder { + return sb.p.Get().(*strings.Builder) +} +func (sb *stringBuilderPool) Put(b *strings.Builder) { + b.Reset() + sb.p.Put(b) +} + +/* +// ResetSession is called while a connection is in the connection +// pool. No queries will run on this connection until this method returns. +// +// If the connection is bad this should return driver.ErrBadConn to prevent +// the connection from being returned to the connection pool. Any other +// error will be discarded. +func (c *conn) ResetSession(ctx context.Context) error { + if Log != nil { + Log("msg", "ResetSession", "conn", c.dpiConn) + } + //subCtx, cancel := context.WithTimeout(ctx, 30*time.Second) + //err := c.Ping(subCtx) + //cancel() + return c.Ping(ctx) +} +*/ diff --git a/vendor/gopkg.in/goracle.v2/subscr.c b/vendor/github.com/godror/godror/subscr.c similarity index 100% rename from vendor/gopkg.in/goracle.v2/subscr.c rename to vendor/github.com/godror/godror/subscr.c diff --git a/vendor/gopkg.in/goracle.v2/subscr.go b/vendor/github.com/godror/godror/subscr.go similarity index 86% rename from vendor/gopkg.in/goracle.v2/subscr.go rename to vendor/github.com/godror/godror/subscr.go index 6286ec10c84..07355e591c7 100644 --- a/vendor/gopkg.in/goracle.v2/subscr.go +++ b/vendor/github.com/godror/godror/subscr.go @@ -1,19 +1,9 @@ // Copyright 2017 Tamás Gulácsi // // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -package goracle +package godror /* #include @@ -30,7 +20,7 @@ import ( "strings" "unsafe" - "github.com/pkg/errors" + errors "golang.org/x/xerrors" ) // CallbackSubscr is the callback for C code on subscription event. @@ -171,9 +161,9 @@ func (c *conn) NewSubscription(name string, cb func(Event)) (*Subscription, erro ) == C.DPI_FAILURE { C.free(unsafe.Pointer(params)) C.free(unsafe.Pointer(dpiSubscr)) - err := errors.Wrap(c.getError(), "newSubscription") - if strings.Contains(errors.Cause(err).Error(), "DPI-1065:") { - err = errors.WithMessage(err, "specify \"enableEvents=1\" connection parameter on connection to be able to use subscriptions") + err := errors.Errorf("newSubscription: %w", c.getError()) + if strings.Contains(errors.Unwrap(err).Error(), "DPI-1065:") { + err = errors.Errorf("specify \"enableEvents=1\" connection parameter on connection to be able to use subscriptions: %w", err) } return nil, err } @@ -190,18 +180,18 @@ func (s *Subscription) Register(qry string, params ...interface{}) error { var dpiStmt *C.dpiStmt if C.dpiSubscr_prepareStmt(s.dpiSubscr, cQry, C.uint32_t(len(qry)), &dpiStmt) == C.DPI_FAILURE { - return errors.Wrapf(s.getError(), "prepareStmt[%p]", s.dpiSubscr) + return errors.Errorf("prepareStmt[%p]: %w", s.dpiSubscr, s.getError()) } defer func() { C.dpiStmt_release(dpiStmt) }() mode := C.dpiExecMode(C.DPI_MODE_EXEC_DEFAULT) var qCols C.uint32_t if C.dpiStmt_execute(dpiStmt, mode, &qCols) == C.DPI_FAILURE { - return errors.Wrap(s.getError(), "executeStmt") + return errors.Errorf("executeStmt: %w", s.getError()) } var queryID C.uint64_t if C.dpiStmt_getSubscrQueryId(dpiStmt, &queryID) == C.DPI_FAILURE { - return errors.Wrap(s.getError(), "getSubscrQueryId") + return errors.Errorf("getSubscrQueryId: %w", s.getError()) } if Log != nil { Log("msg", "subscribed", "query", qry, "id", queryID) @@ -223,7 +213,7 @@ func (s *Subscription) Close() error { return nil } if C.dpiConn_unsubscribe(conn.dpiConn, dpiSubscr) == C.DPI_FAILURE { - return errors.Wrap(s.getError(), "close") + return errors.Errorf("close: %w", s.getError()) } return nil } @@ -236,10 +226,10 @@ const ( EvtStartup = EventType(C.DPI_EVENT_STARTUP) EvtShutdown = EventType(C.DPI_EVENT_SHUTDOWN) EvtShutdownAny = EventType(C.DPI_EVENT_SHUTDOWN_ANY) - EvtDropDB = EventType(C.DPI_EVENT_DROP_DB) EvtDereg = EventType(C.DPI_EVENT_DEREG) EvtObjChange = EventType(C.DPI_EVENT_OBJCHANGE) EvtQueryChange = EventType(C.DPI_EVENT_QUERYCHANGE) + EvtAQ = EventType(C.DPI_EVENT_AQ) ) // Operation in the DB. diff --git a/vendor/gopkg.in/goracle.v2/version.go b/vendor/github.com/godror/godror/version.go similarity index 57% rename from vendor/gopkg.in/goracle.v2/version.go rename to vendor/github.com/godror/godror/version.go index 111b3462741..5dace8e1b09 100644 --- a/vendor/gopkg.in/goracle.v2/version.go +++ b/vendor/github.com/godror/godror/version.go @@ -1,6 +1,10 @@ -package goracle +// Copyright 2019 Tamás Gulácsi. +// +// SPDX-License-Identifier: UPL-1.0 OR Apache-2.0 -//go:generate bash -c "echo 3.1.4>odpi-version; set -x; curl -L https://github.com/oracle/odpi/archive/v$(cat odpi-version).tar.gz | tar xzvf - odpi-$(cat odpi-version)/{embed,include,src,CONTRIBUTING.md,LICENSE.md,README.md} && rm -rf odpi && mv odpi-$(cat odpi-version) odpi; rm -f odpi-version" +package godror + +//go:generate bash -c "echo 3.3.0>odpi-version; set -x; curl -L https://github.com/oracle/odpi/archive/v$(cat odpi-version).tar.gz | tar xzvf - odpi-$(cat odpi-version)/{embed,include,src,CONTRIBUTING.md,LICENSE.md,README.md} && rm -rf odpi && mv odpi-$(cat odpi-version) odpi; rm -f odpi-version" // Version of this driver -const Version = "v2.15.3" +const Version = "v0.0.1" diff --git a/vendor/golang.org/x/xerrors/LICENSE b/vendor/golang.org/x/xerrors/LICENSE new file mode 100644 index 00000000000..e4a47e17f14 --- /dev/null +++ b/vendor/golang.org/x/xerrors/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2019 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/xerrors/PATENTS b/vendor/golang.org/x/xerrors/PATENTS new file mode 100644 index 00000000000..733099041f8 --- /dev/null +++ b/vendor/golang.org/x/xerrors/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/xerrors/README b/vendor/golang.org/x/xerrors/README new file mode 100644 index 00000000000..aac7867a560 --- /dev/null +++ b/vendor/golang.org/x/xerrors/README @@ -0,0 +1,2 @@ +This repository holds the transition packages for the new Go 1.13 error values. +See golang.org/design/29934-error-values. diff --git a/vendor/golang.org/x/xerrors/adaptor.go b/vendor/golang.org/x/xerrors/adaptor.go new file mode 100644 index 00000000000..4317f248331 --- /dev/null +++ b/vendor/golang.org/x/xerrors/adaptor.go @@ -0,0 +1,193 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "bytes" + "fmt" + "io" + "reflect" + "strconv" +) + +// FormatError calls the FormatError method of f with an errors.Printer +// configured according to s and verb, and writes the result to s. +func FormatError(f Formatter, s fmt.State, verb rune) { + // Assuming this function is only called from the Format method, and given + // that FormatError takes precedence over Format, it cannot be called from + // any package that supports errors.Formatter. It is therefore safe to + // disregard that State may be a specific printer implementation and use one + // of our choice instead. + + // limitations: does not support printing error as Go struct. + + var ( + sep = " " // separator before next error + p = &state{State: s} + direct = true + ) + + var err error = f + + switch verb { + // Note that this switch must match the preference order + // for ordinary string printing (%#v before %+v, and so on). + + case 'v': + if s.Flag('#') { + if stringer, ok := err.(fmt.GoStringer); ok { + io.WriteString(&p.buf, stringer.GoString()) + goto exit + } + // proceed as if it were %v + } else if s.Flag('+') { + p.printDetail = true + sep = "\n - " + } + case 's': + case 'q', 'x', 'X': + // Use an intermediate buffer in the rare cases that precision, + // truncation, or one of the alternative verbs (q, x, and X) are + // specified. + direct = false + + default: + p.buf.WriteString("%!") + p.buf.WriteRune(verb) + p.buf.WriteByte('(') + switch { + case err != nil: + p.buf.WriteString(reflect.TypeOf(f).String()) + default: + p.buf.WriteString("") + } + p.buf.WriteByte(')') + io.Copy(s, &p.buf) + return + } + +loop: + for { + switch v := err.(type) { + case Formatter: + err = v.FormatError((*printer)(p)) + case fmt.Formatter: + v.Format(p, 'v') + break loop + default: + io.WriteString(&p.buf, v.Error()) + break loop + } + if err == nil { + break + } + if p.needColon || !p.printDetail { + p.buf.WriteByte(':') + p.needColon = false + } + p.buf.WriteString(sep) + p.inDetail = false + p.needNewline = false + } + +exit: + width, okW := s.Width() + prec, okP := s.Precision() + + if !direct || (okW && width > 0) || okP { + // Construct format string from State s. + format := []byte{'%'} + if s.Flag('-') { + format = append(format, '-') + } + if s.Flag('+') { + format = append(format, '+') + } + if s.Flag(' ') { + format = append(format, ' ') + } + if okW { + format = strconv.AppendInt(format, int64(width), 10) + } + if okP { + format = append(format, '.') + format = strconv.AppendInt(format, int64(prec), 10) + } + format = append(format, string(verb)...) + fmt.Fprintf(s, string(format), p.buf.String()) + } else { + io.Copy(s, &p.buf) + } +} + +var detailSep = []byte("\n ") + +// state tracks error printing state. It implements fmt.State. +type state struct { + fmt.State + buf bytes.Buffer + + printDetail bool + inDetail bool + needColon bool + needNewline bool +} + +func (s *state) Write(b []byte) (n int, err error) { + if s.printDetail { + if len(b) == 0 { + return 0, nil + } + if s.inDetail && s.needColon { + s.needNewline = true + if b[0] == '\n' { + b = b[1:] + } + } + k := 0 + for i, c := range b { + if s.needNewline { + if s.inDetail && s.needColon { + s.buf.WriteByte(':') + s.needColon = false + } + s.buf.Write(detailSep) + s.needNewline = false + } + if c == '\n' { + s.buf.Write(b[k:i]) + k = i + 1 + s.needNewline = true + } + } + s.buf.Write(b[k:]) + if !s.inDetail { + s.needColon = true + } + } else if !s.inDetail { + s.buf.Write(b) + } + return len(b), nil +} + +// printer wraps a state to implement an xerrors.Printer. +type printer state + +func (s *printer) Print(args ...interface{}) { + if !s.inDetail || s.printDetail { + fmt.Fprint((*state)(s), args...) + } +} + +func (s *printer) Printf(format string, args ...interface{}) { + if !s.inDetail || s.printDetail { + fmt.Fprintf((*state)(s), format, args...) + } +} + +func (s *printer) Detail() bool { + s.inDetail = true + return s.printDetail +} diff --git a/vendor/golang.org/x/xerrors/codereview.cfg b/vendor/golang.org/x/xerrors/codereview.cfg new file mode 100644 index 00000000000..3f8b14b64e8 --- /dev/null +++ b/vendor/golang.org/x/xerrors/codereview.cfg @@ -0,0 +1 @@ +issuerepo: golang/go diff --git a/vendor/golang.org/x/xerrors/doc.go b/vendor/golang.org/x/xerrors/doc.go new file mode 100644 index 00000000000..eef99d9d54d --- /dev/null +++ b/vendor/golang.org/x/xerrors/doc.go @@ -0,0 +1,22 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package xerrors implements functions to manipulate errors. +// +// This package is based on the Go 2 proposal for error values: +// https://golang.org/design/29934-error-values +// +// These functions were incorporated into the standard library's errors package +// in Go 1.13: +// - Is +// - As +// - Unwrap +// +// Also, Errorf's %w verb was incorporated into fmt.Errorf. +// +// Use this package to get equivalent behavior in all supported Go versions. +// +// No other features of this package were included in Go 1.13, and at present +// there are no plans to include any of them. +package xerrors // import "golang.org/x/xerrors" diff --git a/vendor/golang.org/x/xerrors/errors.go b/vendor/golang.org/x/xerrors/errors.go new file mode 100644 index 00000000000..e88d3772d86 --- /dev/null +++ b/vendor/golang.org/x/xerrors/errors.go @@ -0,0 +1,33 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import "fmt" + +// errorString is a trivial implementation of error. +type errorString struct { + s string + frame Frame +} + +// New returns an error that formats as the given text. +// +// The returned error contains a Frame set to the caller's location and +// implements Formatter to show this information when printed with details. +func New(text string) error { + return &errorString{text, Caller(1)} +} + +func (e *errorString) Error() string { + return e.s +} + +func (e *errorString) Format(s fmt.State, v rune) { FormatError(e, s, v) } + +func (e *errorString) FormatError(p Printer) (next error) { + p.Print(e.s) + e.frame.Format(p) + return nil +} diff --git a/vendor/golang.org/x/xerrors/fmt.go b/vendor/golang.org/x/xerrors/fmt.go new file mode 100644 index 00000000000..829862ddf6a --- /dev/null +++ b/vendor/golang.org/x/xerrors/fmt.go @@ -0,0 +1,187 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "fmt" + "strings" + "unicode" + "unicode/utf8" + + "golang.org/x/xerrors/internal" +) + +const percentBangString = "%!" + +// Errorf formats according to a format specifier and returns the string as a +// value that satisfies error. +// +// The returned error includes the file and line number of the caller when +// formatted with additional detail enabled. If the last argument is an error +// the returned error's Format method will return it if the format string ends +// with ": %s", ": %v", or ": %w". If the last argument is an error and the +// format string ends with ": %w", the returned error implements an Unwrap +// method returning it. +// +// If the format specifier includes a %w verb with an error operand in a +// position other than at the end, the returned error will still implement an +// Unwrap method returning the operand, but the error's Format method will not +// return the wrapped error. +// +// It is invalid to include more than one %w verb or to supply it with an +// operand that does not implement the error interface. The %w verb is otherwise +// a synonym for %v. +func Errorf(format string, a ...interface{}) error { + format = formatPlusW(format) + // Support a ": %[wsv]" suffix, which works well with xerrors.Formatter. + wrap := strings.HasSuffix(format, ": %w") + idx, format2, ok := parsePercentW(format) + percentWElsewhere := !wrap && idx >= 0 + if !percentWElsewhere && (wrap || strings.HasSuffix(format, ": %s") || strings.HasSuffix(format, ": %v")) { + err := errorAt(a, len(a)-1) + if err == nil { + return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)} + } + // TODO: this is not entirely correct. The error value could be + // printed elsewhere in format if it mixes numbered with unnumbered + // substitutions. With relatively small changes to doPrintf we can + // have it optionally ignore extra arguments and pass the argument + // list in its entirety. + msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...) + frame := Frame{} + if internal.EnableTrace { + frame = Caller(1) + } + if wrap { + return &wrapError{msg, err, frame} + } + return &noWrapError{msg, err, frame} + } + // Support %w anywhere. + // TODO: don't repeat the wrapped error's message when %w occurs in the middle. + msg := fmt.Sprintf(format2, a...) + if idx < 0 { + return &noWrapError{msg, nil, Caller(1)} + } + err := errorAt(a, idx) + if !ok || err == nil { + // Too many %ws or argument of %w is not an error. Approximate the Go + // 1.13 fmt.Errorf message. + return &noWrapError{fmt.Sprintf("%sw(%s)", percentBangString, msg), nil, Caller(1)} + } + frame := Frame{} + if internal.EnableTrace { + frame = Caller(1) + } + return &wrapError{msg, err, frame} +} + +func errorAt(args []interface{}, i int) error { + if i < 0 || i >= len(args) { + return nil + } + err, ok := args[i].(error) + if !ok { + return nil + } + return err +} + +// formatPlusW is used to avoid the vet check that will barf at %w. +func formatPlusW(s string) string { + return s +} + +// Return the index of the only %w in format, or -1 if none. +// Also return a rewritten format string with %w replaced by %v, and +// false if there is more than one %w. +// TODO: handle "%[N]w". +func parsePercentW(format string) (idx int, newFormat string, ok bool) { + // Loosely copied from golang.org/x/tools/go/analysis/passes/printf/printf.go. + idx = -1 + ok = true + n := 0 + sz := 0 + var isW bool + for i := 0; i < len(format); i += sz { + if format[i] != '%' { + sz = 1 + continue + } + // "%%" is not a format directive. + if i+1 < len(format) && format[i+1] == '%' { + sz = 2 + continue + } + sz, isW = parsePrintfVerb(format[i:]) + if isW { + if idx >= 0 { + ok = false + } else { + idx = n + } + // "Replace" the last character, the 'w', with a 'v'. + p := i + sz - 1 + format = format[:p] + "v" + format[p+1:] + } + n++ + } + return idx, format, ok +} + +// Parse the printf verb starting with a % at s[0]. +// Return how many bytes it occupies and whether the verb is 'w'. +func parsePrintfVerb(s string) (int, bool) { + // Assume only that the directive is a sequence of non-letters followed by a single letter. + sz := 0 + var r rune + for i := 1; i < len(s); i += sz { + r, sz = utf8.DecodeRuneInString(s[i:]) + if unicode.IsLetter(r) { + return i + sz, r == 'w' + } + } + return len(s), false +} + +type noWrapError struct { + msg string + err error + frame Frame +} + +func (e *noWrapError) Error() string { + return fmt.Sprint(e) +} + +func (e *noWrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) } + +func (e *noWrapError) FormatError(p Printer) (next error) { + p.Print(e.msg) + e.frame.Format(p) + return e.err +} + +type wrapError struct { + msg string + err error + frame Frame +} + +func (e *wrapError) Error() string { + return fmt.Sprint(e) +} + +func (e *wrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) } + +func (e *wrapError) FormatError(p Printer) (next error) { + p.Print(e.msg) + e.frame.Format(p) + return e.err +} + +func (e *wrapError) Unwrap() error { + return e.err +} diff --git a/vendor/golang.org/x/xerrors/format.go b/vendor/golang.org/x/xerrors/format.go new file mode 100644 index 00000000000..1bc9c26b97f --- /dev/null +++ b/vendor/golang.org/x/xerrors/format.go @@ -0,0 +1,34 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +// A Formatter formats error messages. +type Formatter interface { + error + + // FormatError prints the receiver's first error and returns the next error in + // the error chain, if any. + FormatError(p Printer) (next error) +} + +// A Printer formats error messages. +// +// The most common implementation of Printer is the one provided by package fmt +// during Printf (as of Go 1.13). Localization packages such as golang.org/x/text/message +// typically provide their own implementations. +type Printer interface { + // Print appends args to the message output. + Print(args ...interface{}) + + // Printf writes a formatted string. + Printf(format string, args ...interface{}) + + // Detail reports whether error detail is requested. + // After the first call to Detail, all text written to the Printer + // is formatted as additional detail, or ignored when + // detail has not been requested. + // If Detail returns false, the caller can avoid printing the detail at all. + Detail() bool +} diff --git a/vendor/golang.org/x/xerrors/frame.go b/vendor/golang.org/x/xerrors/frame.go new file mode 100644 index 00000000000..0de628ec501 --- /dev/null +++ b/vendor/golang.org/x/xerrors/frame.go @@ -0,0 +1,56 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "runtime" +) + +// A Frame contains part of a call stack. +type Frame struct { + // Make room for three PCs: the one we were asked for, what it called, + // and possibly a PC for skipPleaseUseCallersFrames. See: + // https://go.googlesource.com/go/+/032678e0fb/src/runtime/extern.go#169 + frames [3]uintptr +} + +// Caller returns a Frame that describes a frame on the caller's stack. +// The argument skip is the number of frames to skip over. +// Caller(0) returns the frame for the caller of Caller. +func Caller(skip int) Frame { + var s Frame + runtime.Callers(skip+1, s.frames[:]) + return s +} + +// location reports the file, line, and function of a frame. +// +// The returned function may be "" even if file and line are not. +func (f Frame) location() (function, file string, line int) { + frames := runtime.CallersFrames(f.frames[:]) + if _, ok := frames.Next(); !ok { + return "", "", 0 + } + fr, ok := frames.Next() + if !ok { + return "", "", 0 + } + return fr.Function, fr.File, fr.Line +} + +// Format prints the stack as error detail. +// It should be called from an error's Format implementation +// after printing any other error detail. +func (f Frame) Format(p Printer) { + if p.Detail() { + function, file, line := f.location() + if function != "" { + p.Printf("%s\n ", function) + } + if file != "" { + p.Printf("%s:%d\n", file, line) + } + } +} diff --git a/vendor/golang.org/x/xerrors/go.mod b/vendor/golang.org/x/xerrors/go.mod new file mode 100644 index 00000000000..870d4f612db --- /dev/null +++ b/vendor/golang.org/x/xerrors/go.mod @@ -0,0 +1,3 @@ +module golang.org/x/xerrors + +go 1.11 diff --git a/vendor/golang.org/x/xerrors/internal/internal.go b/vendor/golang.org/x/xerrors/internal/internal.go new file mode 100644 index 00000000000..89f4eca5df7 --- /dev/null +++ b/vendor/golang.org/x/xerrors/internal/internal.go @@ -0,0 +1,8 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package internal + +// EnableTrace indicates whether stack information should be recorded in errors. +var EnableTrace = true diff --git a/vendor/golang.org/x/xerrors/wrap.go b/vendor/golang.org/x/xerrors/wrap.go new file mode 100644 index 00000000000..9a3b510374e --- /dev/null +++ b/vendor/golang.org/x/xerrors/wrap.go @@ -0,0 +1,106 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "reflect" +) + +// A Wrapper provides context around another error. +type Wrapper interface { + // Unwrap returns the next error in the error chain. + // If there is no next error, Unwrap returns nil. + Unwrap() error +} + +// Opaque returns an error with the same error formatting as err +// but that does not match err and cannot be unwrapped. +func Opaque(err error) error { + return noWrapper{err} +} + +type noWrapper struct { + error +} + +func (e noWrapper) FormatError(p Printer) (next error) { + if f, ok := e.error.(Formatter); ok { + return f.FormatError(p) + } + p.Print(e.error) + return nil +} + +// Unwrap returns the result of calling the Unwrap method on err, if err implements +// Unwrap. Otherwise, Unwrap returns nil. +func Unwrap(err error) error { + u, ok := err.(Wrapper) + if !ok { + return nil + } + return u.Unwrap() +} + +// Is reports whether any error in err's chain matches target. +// +// An error is considered to match a target if it is equal to that target or if +// it implements a method Is(error) bool such that Is(target) returns true. +func Is(err, target error) bool { + if target == nil { + return err == target + } + + isComparable := reflect.TypeOf(target).Comparable() + for { + if isComparable && err == target { + return true + } + if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) { + return true + } + // TODO: consider supporing target.Is(err). This would allow + // user-definable predicates, but also may allow for coping with sloppy + // APIs, thereby making it easier to get away with them. + if err = Unwrap(err); err == nil { + return false + } + } +} + +// As finds the first error in err's chain that matches the type to which target +// points, and if so, sets the target to its value and returns true. An error +// matches a type if it is assignable to the target type, or if it has a method +// As(interface{}) bool such that As(target) returns true. As will panic if target +// is not a non-nil pointer to a type which implements error or is of interface type. +// +// The As method should set the target to its value and return true if err +// matches the type to which target points. +func As(err error, target interface{}) bool { + if target == nil { + panic("errors: target cannot be nil") + } + val := reflect.ValueOf(target) + typ := val.Type() + if typ.Kind() != reflect.Ptr || val.IsNil() { + panic("errors: target must be a non-nil pointer") + } + if e := typ.Elem(); e.Kind() != reflect.Interface && !e.Implements(errorType) { + panic("errors: *target must be interface or implement error") + } + targetType := typ.Elem() + for err != nil { + if reflect.TypeOf(err).AssignableTo(targetType) { + val.Elem().Set(reflect.ValueOf(err)) + return true + } + if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) { + return true + } + err = Unwrap(err) + } + return false +} + +var errorType = reflect.TypeOf((*error)(nil)).Elem() diff --git a/vendor/gopkg.in/goracle.v2/contrib/oracle-instant-client/Dockerfile b/vendor/gopkg.in/goracle.v2/contrib/oracle-instant-client/Dockerfile deleted file mode 100644 index dacc43c3afa..00000000000 --- a/vendor/gopkg.in/goracle.v2/contrib/oracle-instant-client/Dockerfile +++ /dev/null @@ -1,24 +0,0 @@ -FROM ubuntu:16.04 - -LABEL maintainer="sergey@makinen.ru" - -ENV DEBIAN_FRONTEND noninteractive - -ENV ORACLE_INSTANTCLIENT_MAJOR 12.2 -ENV ORACLE_INSTANTCLIENT_VERSION 12.2.0.1.0 -ENV ORACLE /usr/local/oracle -ENV ORACLE_HOME $ORACLE/lib/oracle/$ORACLE_INSTANTCLIENT_MAJOR/client64 -ENV LD_LIBRARY_PATH $LD_LIBRARY_PATH:$ORACLE_HOME/lib -ENV C_INCLUDE_PATH $C_INCLUDE_PATH:$ORACLE/include/oracle/$ORACLE_INSTANTCLIENT_MAJOR/client64 - -RUN apt-get update && apt-get install -y libaio1 \ - curl rpm2cpio cpio \ - && mkdir $ORACLE && TMP_DIR="$(mktemp -d)" && cd "$TMP_DIR" \ - && curl -L https://github.com/sergeymakinen/docker-oracle-instant-client/raw/assets/oracle-instantclient$ORACLE_INSTANTCLIENT_MAJOR-basic-$ORACLE_INSTANTCLIENT_VERSION-1.x86_64.rpm -o basic.rpm \ - && rpm2cpio basic.rpm | cpio -i -d -v && cp -r usr/* $ORACLE && rm -rf ./* \ - && ln -s libclntsh.so.12.1 $ORACLE/lib/oracle/$ORACLE_INSTANTCLIENT_MAJOR/client64/lib/libclntsh.so.$ORACLE_INSTANTCLIENT_MAJOR \ - && ln -s libocci.so.12.1 $ORACLE/lib/oracle/$ORACLE_INSTANTCLIENT_MAJOR/client64/lib/libocci.so.$ORACLE_INSTANTCLIENT_MAJOR \ - && curl -L https://github.com/sergeymakinen/docker-oracle-instant-client/raw/assets/oracle-instantclient$ORACLE_INSTANTCLIENT_MAJOR-devel-$ORACLE_INSTANTCLIENT_VERSION-1.x86_64.rpm -o devel.rpm \ - && rpm2cpio devel.rpm | cpio -i -d -v && cp -r usr/* $ORACLE && rm -rf "$TMP_DIR" \ - && echo "$ORACLE_HOME/lib" > /etc/ld.so.conf.d/oracle.conf && chmod o+r /etc/ld.so.conf.d/oracle.conf && ldconfig \ - && rm -rf /var/lib/apt/lists/* && apt-get purge -y --auto-remove curl rpm2cpio cpio diff --git a/vendor/gopkg.in/goracle.v2/drv_10.go b/vendor/gopkg.in/goracle.v2/drv_10.go deleted file mode 100644 index e6fd6941aca..00000000000 --- a/vendor/gopkg.in/goracle.v2/drv_10.go +++ /dev/null @@ -1,106 +0,0 @@ -// +build go1.10 - -// Copyright 2019 Tamás Gulácsi -// -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package goracle - -import ( - "context" - "database/sql/driver" - "fmt" - "strings" - - "github.com/pkg/errors" -) - -var _ = driver.Connector((*connector)(nil)) - -type connector struct { - ConnectionParams - *drv - onInit func(driver.Conn) error -} - -// OpenConnector must parse the name in the same format that Driver.Open -// parses the name parameter. -func (d *drv) OpenConnector(name string) (driver.Connector, error) { - P, err := ParseConnString(name) - if err != nil { - return nil, err - } - - return connector{ConnectionParams: P, drv: d}, nil -} - -// Connect returns a connection to the database. -// Connect may return a cached connection (one previously -// closed), but doing so is unnecessary; the sql package -// maintains a pool of idle connections for efficient re-use. -// -// The provided context.Context is for dialing purposes only -// (see net.DialContext) and should not be stored or used for -// other purposes. -// -// The returned connection is only used by one goroutine at a -// time. -func (c connector) Connect(context.Context) (driver.Conn, error) { - conn, err := c.drv.openConn(c.ConnectionParams) - if err != nil || c.onInit == nil || !conn.newSession { - return conn, err - } - if err = c.onInit(conn); err != nil { - conn.Close() - return nil, err - } - return conn, nil -} - -// Driver returns the underlying Driver of the Connector, -// mainly to maintain compatibility with the Driver method -// on sql.DB. -func (c connector) Driver() driver.Driver { return c.drv } - -// NewConnector returns a driver.Connector to be used with sql.OpenDB, -// which calls the given onInit if the connection is new. -func NewConnector(name string, onInit func(driver.Conn) error) (driver.Connector, error) { - cxr, err := defaultDrv.OpenConnector(name) - if err != nil { - return nil, err - } - cx := cxr.(connector) - cx.onInit = onInit - return cx, err -} - -// NewSessionIniter returns a function suitable for use in NewConnector as onInit, -// which calls "ALTER SESSION SET =''" for each element of the given map. -func NewSessionIniter(m map[string]string) func(driver.Conn) error { - return func(cx driver.Conn) error { - for k, v := range m { - qry := fmt.Sprintf("ALTER SESSION SET %s = '%s'", k, strings.ReplaceAll(v, "'", "''")) - st, err := cx.Prepare(qry) - if err != nil { - return errors.Wrap(err, qry) - } - _, err = st.Exec(nil) //nolint:SA1019 - st.Close() - if err != nil { - return err - } - } - return nil - } -} diff --git a/vendor/gopkg.in/goracle.v2/drv_posix.go b/vendor/gopkg.in/goracle.v2/drv_posix.go deleted file mode 100644 index 0f3de24337e..00000000000 --- a/vendor/gopkg.in/goracle.v2/drv_posix.go +++ /dev/null @@ -1,21 +0,0 @@ -// +build !windows - -// Copyright 2017 Tamás Gulácsi -// -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package goracle - -// #cgo LDFLAGS: -ldl -lpthread -import "C" diff --git a/vendor/gopkg.in/goracle.v2/go.mod b/vendor/gopkg.in/goracle.v2/go.mod deleted file mode 100644 index dddc925735b..00000000000 --- a/vendor/gopkg.in/goracle.v2/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module gopkg.in/goracle.v2 - -require ( - github.com/go-kit/kit v0.8.0 - github.com/go-logfmt/logfmt v0.4.0 // indirect - github.com/go-stack/stack v1.8.0 // indirect - github.com/google/go-cmp v0.2.0 - github.com/pkg/errors v0.8.0 - golang.org/x/sync v0.0.0-20181108010431-42b317875d0f -) diff --git a/vendor/gopkg.in/goracle.v2/go.sum b/vendor/gopkg.in/goracle.v2/go.sum deleted file mode 100644 index 3bcd4a1c117..00000000000 --- a/vendor/gopkg.in/goracle.v2/go.sum +++ /dev/null @@ -1,14 +0,0 @@ -github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/vendor/gopkg.in/goracle.v2/stmt_go09.go b/vendor/gopkg.in/goracle.v2/stmt_go09.go deleted file mode 100644 index 6c731f8ed64..00000000000 --- a/vendor/gopkg.in/goracle.v2/stmt_go09.go +++ /dev/null @@ -1,52 +0,0 @@ -// +build !go1.10 - -// Copyright 2017 Tamás Gulácsi -// -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package goracle - -/* -#include -#include "dpiImpl.h" -*/ -import "C" -import ( - "bytes" - "sync" - "unsafe" -) - -const go10 = false - -func dpiSetFromString(dv *C.dpiVar, pos C.uint32_t, x string) { - b := []byte(x) - C.dpiVar_setFromBytes(dv, pos, (*C.char)(unsafe.Pointer(&b[0])), C.uint32_t(len(b))) -} - -var stringBuilders = stringBuilderPool{ - p: &sync.Pool{New: func() interface{} { return bytes.NewBuffer(make([]byte, 0, 1024)) }}, -} - -type stringBuilderPool struct { - p *sync.Pool -} - -func (sb stringBuilderPool) Get() *bytes.Buffer { - return sb.p.Get().(*bytes.Buffer) -} -func (sb *stringBuilderPool) Put(b *bytes.Buffer) { - b.Reset() - sb.p.Put(b) -} diff --git a/vendor/gopkg.in/goracle.v2/stmt_go10.go b/vendor/gopkg.in/goracle.v2/stmt_go10.go deleted file mode 100644 index 5bc1da80073..00000000000 --- a/vendor/gopkg.in/goracle.v2/stmt_go10.go +++ /dev/null @@ -1,78 +0,0 @@ -// +build go1.10 - -// Copyright 2017 Tamás Gulácsi -// -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package goracle - -/* -#include -#include "dpiImpl.h" - -void goracle_setFromString(dpiVar *dv, uint32_t pos, const _GoString_ value) { - uint32_t length; - length = _GoStringLen(value); - if( length == 0 ) { - return; - } - dpiVar_setFromBytes(dv, pos, _GoStringPtr(value), length); -} -*/ -import "C" -import ( - //"context" - "strings" - "sync" -) - -const go10 = true - -func dpiSetFromString(dv *C.dpiVar, pos C.uint32_t, x string) { - C.goracle_setFromString(dv, pos, x) -} - -var stringBuilders = stringBuilderPool{ - p: &sync.Pool{New: func() interface{} { return &strings.Builder{} }}, -} - -type stringBuilderPool struct { - p *sync.Pool -} - -func (sb stringBuilderPool) Get() *strings.Builder { - return sb.p.Get().(*strings.Builder) -} -func (sb *stringBuilderPool) Put(b *strings.Builder) { - b.Reset() - sb.p.Put(b) -} - -/* -// ResetSession is called while a connection is in the connection -// pool. No queries will run on this connection until this method returns. -// -// If the connection is bad this should return driver.ErrBadConn to prevent -// the connection from being returned to the connection pool. Any other -// error will be discarded. -func (c *conn) ResetSession(ctx context.Context) error { - if Log != nil { - Log("msg", "ResetSession", "conn", c.dpiConn) - } - //subCtx, cancel := context.WithTimeout(ctx, 30*time.Second) - //err := c.Ping(subCtx) - //cancel() - return c.Ping(ctx) -} -*/ diff --git a/vendor/vendor.json b/vendor/vendor.json index a9e0e185fe7..be6de64ab3a 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -3453,6 +3453,15 @@ "revision": "37bf87eef99d69c4f1d3528bd66e3a87dc201472", "revisionTime": "2019-09-30T11:59:46Z" }, + { + "checksumSHA1": "fW8mQy9XfBOcO8dwudie7NHXC5o=", + "path": "github.com/godror/godror", + "revision": "446a29355d2967f04604e8e015a3343917860adf", + "revisionTime": "2019-12-12T16:49:28Z", + "tree": true, + "version": "v0.9.0", + "versionExact": "v0.9.0" + }, { "checksumSHA1": "MlaWEe1K+Kpb9wDF88qPoqO1uro=", "path": "github.com/gofrs/flock", @@ -5640,6 +5649,18 @@ "version": "release-branch.go1.13", "versionExact": "release-branch.go1.13" }, + { + "checksumSHA1": "uIgpefsunMZTr8uZTJKcevvU/yg=", + "path": "golang.org/x/xerrors", + "revision": "9bdfabe68543c54f90421aeb9a60ef8061b5b544", + "revisionTime": "2019-07-19T19:12:34Z" + }, + { + "checksumSHA1": "LnzK4nslUNXBIfAt9PbXCJCvMdA=", + "path": "golang.org/x/xerrors/internal", + "revision": "9bdfabe68543c54f90421aeb9a60ef8061b5b544", + "revisionTime": "2019-07-19T19:12:34Z" + }, { "checksumSHA1": "xzYkHGnGgOHW4QNWLR4jbx+81P0=", "path": "google.golang.org/api/cloudfunctions/v1", @@ -5696,6 +5717,12 @@ "version": "v0.7.0", "versionExact": "v0.7.0" }, + { + "path": "google.golang.org/api/internal/gensupport", + "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", + "version": "v0.7.0", + "versionExact": "v0.7.0" + }, { "checksumSHA1": "I4Oe5Q+AuaxmN3duL38r2evqGKk=", "path": "google.golang.org/api/internal/gensupport", @@ -6363,12 +6390,6 @@ "version": "v1.25.1", "versionExact": "v1.25.1" }, - { - "checksumSHA1": "+/UD9mGRnKxOhZW3+B+VJdIIPn8=", - "path": "gopkg.in/goracle.v2", - "revision": "3222d7159b45fce95150f06a57e1bcc2868108d3", - "revisionTime": "2019-05-30T18:40:54Z" - }, { "checksumSHA1": "6f8MEU31llHM1sLM/GGH4/Qxu0A=", "path": "gopkg.in/inf.v0", diff --git a/x-pack/metricbeat/module/oracle/connection.go b/x-pack/metricbeat/module/oracle/connection.go index b418c4ac5f8..96add9ced08 100644 --- a/x-pack/metricbeat/module/oracle/connection.go +++ b/x-pack/metricbeat/module/oracle/connection.go @@ -7,7 +7,7 @@ package oracle import ( "database/sql" - "gopkg.in/goracle.v2" + "github.com/godror/godror" "github.com/elastic/beats/metricbeat/mb" "github.com/elastic/beats/metricbeat/mb/parse" @@ -37,7 +37,7 @@ func init() { // NewConnection returns a connection already established with Oracle func NewConnection(c *ConnectionDetails) (*sql.DB, error) { - params, err := goracle.ParseConnString(c.Hosts[0]) + params, err := godror.ParseConnString(c.Hosts[0]) if err != nil { return nil, errors.Wrap(err, "error trying to parse connection string in field 'hosts'") } @@ -54,7 +54,7 @@ func NewConnection(c *ConnectionDetails) (*sql.DB, error) { return nil, errors.New("a user with DBA permissions are required, check your connection details on field `hosts`") } - db, err := sql.Open("goracle", params.StringWithPassword()) + db, err := sql.Open("godror", params.StringWithPassword()) if err != nil { return nil, errors.Wrap(err, "could not open database") } diff --git a/x-pack/metricbeat/module/oracle/performance/metricset_test.go b/x-pack/metricbeat/module/oracle/performance/metricset_test.go index b6182b5b41d..80d16a4e495 100644 --- a/x-pack/metricbeat/module/oracle/performance/metricset_test.go +++ b/x-pack/metricbeat/module/oracle/performance/metricset_test.go @@ -9,7 +9,7 @@ package performance import ( "testing" - _ "gopkg.in/goracle.v2" + _ "github.com/godror/godror" "github.com/elastic/beats/libbeat/common" mbtest "github.com/elastic/beats/metricbeat/mb/testing" diff --git a/x-pack/metricbeat/module/oracle/tablespace/metricset_test.go b/x-pack/metricbeat/module/oracle/tablespace/metricset_test.go index a7934647826..f0bb4b672d8 100644 --- a/x-pack/metricbeat/module/oracle/tablespace/metricset_test.go +++ b/x-pack/metricbeat/module/oracle/tablespace/metricset_test.go @@ -9,7 +9,7 @@ package tablespace import ( "testing" - _ "gopkg.in/goracle.v2" + _ "github.com/godror/godror" "github.com/elastic/beats/libbeat/tests/compose" mbtest "github.com/elastic/beats/metricbeat/mb/testing" diff --git a/x-pack/metricbeat/module/oracle/testing.go b/x-pack/metricbeat/module/oracle/testing.go index 06c87b10b56..5ffe9cd83f4 100644 --- a/x-pack/metricbeat/module/oracle/testing.go +++ b/x-pack/metricbeat/module/oracle/testing.go @@ -8,12 +8,12 @@ import ( "fmt" "os" - "gopkg.in/goracle.v2" + "github.com/godror/godror" ) // GetOracleConnectionDetails return a valid SID to use for testing func GetOracleConnectionDetails(host string) string { - params := goracle.ConnectionParams{ + params := godror.ConnectionParams{ SID: fmt.Sprintf("%s/%s", host, GetOracleEnvServiceName()), Username: GetOracleEnvUsername(), Password: GetOracleEnvPassword(),