├── .gitattributes
├── .gitignore
├── .idea
└── vcs.xml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── appveyor.yml
├── bndBfile.go
├── bndBin.go
├── bndBinSlice.go
├── bndBool.go
├── bndBoolPtr.go
├── bndBoolSlice.go
├── bndDate.go
├── bndDatePtr.go
├── bndDateSlice.go
├── bndFloat32.go
├── bndFloat32Ptr.go
├── bndFloat32Slice.go
├── bndFloat64.go
├── bndFloat64Ptr.go
├── bndFloat64Slice.go
├── bndInt16.go
├── bndInt16Ptr.go
├── bndInt16Slice.go
├── bndInt32.go
├── bndInt32Ptr.go
├── bndInt32Slice.go
├── bndInt64.go
├── bndInt64Ptr.go
├── bndInt64Slice.go
├── bndInt8.go
├── bndInt8Ptr.go
├── bndInt8Slice.go
├── bndIntervalDS.go
├── bndIntervalDSSlice.go
├── bndIntervalYM.go
├── bndIntervalYMSlice.go
├── bndLob.go
├── bndLobPtr.go
├── bndLobSlice.go
├── bndNil.go
├── bndNumString.go
├── bndNumStringPtr.go
├── bndNumStringSlice.go
├── bndOCINum.go
├── bndOCINumPtr.go
├── bndOCINumSlice.go
├── bndRset.go
├── bndString.go
├── bndStringPtr.go
├── bndStringSlice.go
├── bndTime.go
├── bndTimePtr.go
├── bndTimeSlice.go
├── bndUint16.go
├── bndUint16Ptr.go
├── bndUint16Slice.go
├── bndUint32.go
├── bndUint32Ptr.go
├── bndUint32Slice.go
├── bndUint64.go
├── bndUint64Ptr.go
├── bndUint64Slice.go
├── bndUint8.go
├── bndUint8Ptr.go
├── bndUint8Slice.go
├── bnd_hlp.go
├── conn.go
├── conn_go1_7.go
├── conn_go1_8.go
├── const.go
├── contrib
├── oci8.pc
├── oci8_darwin.pc
├── oci8_linux_386.pc
├── oci8_linux_amd64.pc
├── oci8_windows_amd64.pc
└── pre-commit
├── ctx.go
├── date
├── date.go
├── date_gen_test.go
├── date_test.go
└── date_test.sh
├── defBfile.go
├── defBool.go
├── defDate.go
├── defFloat32.go
├── defFloat64.go
├── defInt16.go
├── defInt32.go
├── defInt64.go
├── defInt8.go
├── defIntervalDS.go
├── defIntervalYM.go
├── defLob.go
├── defLongRaw.go
├── defOCINum.go
├── defRaw.go
├── defRowid.go
├── defRset.go
├── defString.go
├── defTime.go
├── defUint16.go
├── defUint32.go
├── defUint64.go
├── defUint8.go
├── doc.go
├── drv.go
├── drvExecResult.go
├── drvQueryResult.go
├── drvStmt.go
├── drvStmt_go1_8.go
├── env.go
├── examples
├── bench
│ ├── .gitignore
│ ├── README.md
│ ├── gen.go
│ ├── oci8
│ │ └── bench_oci8.go
│ ├── ora
│ │ └── bench_ora.go
│ └── run.sh
├── connect
│ └── flags.go
├── conntest
│ ├── conn_test.go
│ └── main.go
├── csvdump
│ ├── README.md
│ └── csvdump.go
└── csvload
│ └── csvload.go
├── gen.go
├── glg
└── glg.go
├── lg
└── lg.go
├── lg15
└── lg15.go
├── list.go
├── logger.go
├── num
├── .gitignore
├── ocinum.go
├── ocinum_fuzz.go
└── ocinum_test.go
├── ora.go
├── orm.go
├── pool.go
├── rset.go
├── rsetCfg.go
├── rsetCfg_test.go
├── ses.go
├── srv.go
├── stmt.go
├── stmtCfg.go
├── stmt_go1.go
├── stmt_go1_8.go
├── test-one-by-one.sh
├── test.sh
├── tstlg
└── tstlg.go
├── tx.go
├── type.go
├── util.go
├── util_arr.go
├── util_test.go
├── version.c
├── version.h
├── z_benchmem_test.go
├── z_bfile_session_test.go
├── z_bool_session_test.go
├── z_bytes_session_test.go
├── z_db_go1_8_test.go
├── z_db_test.go
├── z_environment_test.go
├── z_example_test.go
├── z_interval_session_test.go
├── z_issue131.go
├── z_issue197.go
├── z_lob_test.go
├── z_numeric_session_test.go
├── z_oracle_test.go
├── z_plsarr_session_test.go
├── z_race.go
├── z_reconn.go
├── z_resultSet_session_test.go
├── z_rowid_session_test.go
├── z_server_session_test.go
├── z_session_test.go
├── z_statement_session_test.go
├── z_string_session_test.go
└── z_time_session_test.go
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Rana Ian
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: 1.0.{build}
2 |
3 | platform: x64
4 |
5 | branches:
6 | only:
7 | - v4
8 |
9 | clone_depth: 1
10 |
11 | build:
12 | verbosity: detailed
13 |
14 | clone_folder: c:\gopath\src\golang.org\rana\ora.v4
15 |
16 | environment:
17 | GOPATH: c:\gopath
18 |
19 | install:
20 | - echo %PATH%
21 | - echo %GOPATH%
22 | - go version
23 | - go env
24 | - curl -sS -o c:\gopath\instantclient-sdk-windows.zip https://s3.amazonaws.com/tgulacsi-oracle-instantclient/instantclient-sdk-windows.x64-12.1.0.2.0.zip
25 | - 7z x -oc:\ c:\gopath\instantclient-sdk-windows.zip
26 | - curl -sS -o c:\gopath\instantclient-basiclite-windows.zip https://s3.amazonaws.com/tgulacsi-oracle-instantclient/instantclient-basiclite-windows.x64-12.1.0.2.0.zip
27 | - 7z x -oc:\ c:\gopath\instantclient-basiclite-windows.zip
28 | - go get -v -t ./...
29 |
30 | build_script:
31 | - go install -v .
32 |
33 | artifacts:
34 | - path: c:\gopath\pkg\windows_amd64\gopkg.in\rana\ora.v4
35 | name: binary
36 |
37 | deploy:
38 | release: ora.v4-$(appveyor_build_version)
39 | description: 'Release of precompiled windows binaries'
40 | provider: GitHub
41 | artifact: binary
42 | draft: true
43 | on:
44 | branch: v4
45 |
46 | # vim: set filetype=yaml et shiftwidth=2:
47 |
--------------------------------------------------------------------------------
/bndBin.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | type bndBin struct {
16 | stmt *Stmt
17 | ocibnd *C.OCIBind
18 | }
19 |
20 | func (bnd *bndBin) bind(value []byte, position namedPos, stmt *Stmt) (err error) {
21 | bnd.stmt = stmt
22 | ph, phLen, phFree := position.CString()
23 | if ph != nil {
24 | defer phFree()
25 | }
26 | r := C.bindByNameOrPos(
27 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
28 | &bnd.ocibnd, //OCIBind **bindpp,
29 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
30 | C.ub4(position.Ordinal), //ub4 position,
31 | ph,
32 | phLen,
33 | unsafe.Pointer(&value[0]), //void *valuep,
34 | C.LENGTH_TYPE(len(value)), //sb8 value_sz,
35 | C.SQLT_LBI, //ub2 dty,
36 | nil, //void *indp,
37 | nil, //ub2 *alenp,
38 | nil, //ub2 *rcodep,
39 | 0, //ub4 maxarr_len,
40 | nil, //ub4 *curelep,
41 | C.OCI_DEFAULT) //ub4 mode );
42 | if r == C.OCI_ERROR {
43 | return bnd.stmt.ses.srv.env.ociError()
44 | }
45 | return nil
46 | }
47 |
48 | func (bnd *bndBin) setPtr() error {
49 | return nil
50 | }
51 |
52 | func (bnd *bndBin) free() {
53 | }
54 |
55 | func (bnd *bndBin) close() (err error) {
56 | defer func() {
57 | if value := recover(); value != nil {
58 | err = errR(value)
59 | }
60 | }()
61 | stmt := bnd.stmt
62 | bnd.stmt = nil
63 | stmt.putBnd(bndIdxBin, bnd)
64 | return nil
65 | }
66 |
--------------------------------------------------------------------------------
/bndBinSlice.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import (
13 | "unsafe"
14 | )
15 |
16 | type bndBinSlice struct {
17 | stmt *Stmt
18 | ocibnd *C.OCIBind
19 | buf []byte
20 | arrHlp
21 | }
22 |
23 | func (bnd *bndBinSlice) bindOra(values []Raw, position namedPos, lobBufferSize int, stmt *Stmt, isAssocArray bool) (iterations uint32, err error) {
24 | binValues := make([][]byte, len(values))
25 | nullInds := make([]C.sb2, len(values))
26 | for i := range values {
27 | if values[i].IsNull {
28 | nullInds[i] = C.sb2(-1)
29 | } else {
30 | binValues[i] = values[i].Value
31 | }
32 | }
33 | return bnd.bind(binValues, nullInds, position, lobBufferSize, stmt, isAssocArray)
34 | }
35 |
36 | func (bnd *bndBinSlice) bind(values [][]byte, nullInds []C.sb2, position namedPos, lobBufferSize int, stmt *Stmt, isAssocArray bool) (iterations uint32, err error) {
37 | bnd.stmt = stmt
38 | L, C := len(values), cap(values)
39 | iterations, curlenp, needAppend := bnd.ensureBindArrLength(&L, &C, isAssocArray)
40 | if needAppend {
41 | values = append(values, []byte{})
42 | }
43 | var maxLen int
44 | for _, b := range values {
45 | if len(b) > maxLen {
46 | maxLen = len(b)
47 | }
48 | }
49 | if maxLen == 0 {
50 | maxLen = 1
51 | }
52 | n := maxLen * L
53 | if cap(bnd.buf) < n {
54 | //bnd.buf = make([]byte, n)
55 | bnd.buf = bytesPool.Get(n)[:n]
56 | } else {
57 | bnd.buf = bnd.buf[:n]
58 | // reset buffer
59 | for i := range bnd.buf {
60 | bnd.buf[i] = 0
61 | }
62 | }
63 | for i, b := range values {
64 | copy(bnd.buf[i*maxLen:], b)
65 | bnd.alen[i] = C.ACTUAL_LENGTH_TYPE(len(b))
66 | }
67 | ph, phLen, phFree := position.CString()
68 | if ph != nil {
69 | defer phFree()
70 | }
71 | r := C.bindByNameOrPos(
72 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
73 | &bnd.ocibnd, //OCIBind **bindpp,
74 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
75 | C.ub4(position.Ordinal), //ub4 position,
76 | ph,
77 | phLen,
78 | unsafe.Pointer(&bnd.buf[0]), //void *valuep,
79 | C.LENGTH_TYPE(maxLen), //sb8 value_sz,
80 | C.SQLT_LBI, //ub2 dty,
81 | unsafe.Pointer(&bnd.nullInds[0]), //void *indp,
82 | &bnd.alen[0], //ub4 *alenp,
83 | &bnd.rcode[0], //ub2 *rcodep,
84 | getMaxarrLen(C, isAssocArray), //ub4 maxarr_len,
85 | curlenp, //ub4 *curelep,
86 | C.OCI_DEFAULT) //ub4 mode );
87 | if r == C.OCI_ERROR {
88 | return iterations, bnd.stmt.ses.srv.env.ociError()
89 | }
90 | r = C.OCIBindArrayOfStruct(
91 | bnd.ocibnd,
92 | bnd.stmt.ses.srv.env.ocierr,
93 | C.ub4(maxLen), //ub4 pvskip,
94 | C.ub4(C.sizeof_sb2), //ub4 indskip,
95 | C.ub4(C.sizeof_ub4), //ub4 alskip,
96 | C.ub4(C.sizeof_ub2)) //ub4 rcskip
97 | if r == C.OCI_ERROR {
98 | return iterations, bnd.stmt.ses.srv.env.ociError()
99 | }
100 | return iterations, nil
101 | }
102 |
103 | func (bnd *bndBinSlice) setPtr() error {
104 | return nil
105 | }
106 |
107 | func (bnd *bndBinSlice) close() (err error) {
108 | defer func() {
109 | if value := recover(); value != nil {
110 | err = errR(value)
111 | }
112 | }()
113 | stmt := bnd.stmt
114 | bnd.stmt = nil
115 | bnd.ocibnd = nil
116 | bytesPool.Put(bnd.buf)
117 | bnd.buf = nil
118 | bnd.arrHlp.close()
119 | stmt.putBnd(bndIdxBinSlice, bnd)
120 | return nil
121 | }
122 |
--------------------------------------------------------------------------------
/bndBool.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import (
14 | "strconv"
15 | "unsafe"
16 | )
17 |
18 | type bndBool struct {
19 | stmt *Stmt
20 | ocibnd *C.OCIBind
21 | cString *C.char
22 | }
23 |
24 | func (bnd *bndBool) bind(value bool, position namedPos, c StmtCfg, stmt *Stmt) (err error) {
25 | //Log.Infof("%s.bind(%t, %d)", bnd, value, position)
26 | bnd.stmt = stmt
27 | var str string
28 | if value {
29 | str, err = strconv.Unquote(strconv.QuoteRune(c.TrueRune))
30 | } else {
31 | str, err = strconv.Unquote(strconv.QuoteRune(c.FalseRune))
32 | }
33 | if err != nil {
34 | return err
35 | }
36 | bnd.cString = C.CString(str)
37 | ph, phLen, phFree := position.CString()
38 | if ph != nil {
39 | defer phFree()
40 | }
41 | r := C.bindByNameOrPos(
42 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
43 | &bnd.ocibnd, //OCIBind **bindpp,
44 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
45 | C.ub4(position.Ordinal), //ub4 position,
46 | ph,
47 | phLen,
48 | unsafe.Pointer(bnd.cString), //void *valuep,
49 | C.LENGTH_TYPE(1), //sb8 value_sz,
50 | C.SQLT_AFC, //ub2 dty,
51 | nil, //void *indp,
52 | nil, //ub2 *alenp,
53 | nil, //ub2 *rcodep,
54 | 0, //ub4 maxarr_len,
55 | nil, //ub4 *curelep,
56 | C.OCI_DEFAULT) //ub4 mode );
57 | if r == C.OCI_ERROR {
58 | return bnd.stmt.ses.srv.env.ociError()
59 | }
60 | return nil
61 | }
62 |
63 | func (bnd *bndBool) setPtr() error {
64 | return nil
65 | }
66 |
67 | func (bnd *bndBool) close() (err error) {
68 | defer func() {
69 | if value := recover(); value != nil {
70 | err = errR(value)
71 | }
72 | }()
73 |
74 | C.free(unsafe.Pointer(bnd.cString))
75 | stmt := bnd.stmt
76 | bnd.stmt = nil
77 | bnd.ocibnd = nil
78 | bnd.cString = nil
79 | stmt.putBnd(bndIdxBool, bnd)
80 | return nil
81 | }
82 |
--------------------------------------------------------------------------------
/bndBoolPtr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import (
13 | "bytes"
14 | "unicode/utf8"
15 | "unsafe"
16 | )
17 |
18 | type bndBoolPtr struct {
19 | stmt *Stmt
20 | ocibnd *C.OCIBind
21 | value *bool
22 | buf []byte
23 | trueRune rune
24 | nullp
25 | }
26 |
27 | func (bnd *bndBoolPtr) bind(value *bool, position namedPos, trueRune rune, stmt *Stmt) error {
28 | //Log.Infof("%v.bind(%t, %d)", bnd, value, position)
29 | bnd.stmt = stmt
30 | bnd.value = value
31 | bnd.trueRune = trueRune
32 | if cap(bnd.buf) < 2 {
33 | bnd.buf = make([]byte, 2)
34 | }
35 | if value != nil && *value {
36 | if _, err := bytes.NewBuffer(bnd.buf).WriteRune(trueRune); err != nil {
37 | return err
38 | }
39 | }
40 | ph, phLen, phFree := position.CString()
41 | if ph != nil {
42 | defer phFree()
43 | }
44 | r := C.bindByNameOrPos(
45 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
46 | &bnd.ocibnd,
47 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
48 | C.ub4(position.Ordinal), //ub4 position,
49 | ph,
50 | phLen,
51 | unsafe.Pointer(&bnd.buf[0]), //void *valuep,
52 | C.LENGTH_TYPE(len(bnd.buf)), //sb8 value_sz,
53 | C.SQLT_CHR, //ub2 dty,
54 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
55 | nil, //ub2 *alenp,
56 | nil, //ub2 *rcodep,
57 | 0, //ub4 maxarr_len,
58 | nil, //ub4 *curelep,
59 | C.OCI_DEFAULT) //ub4 mode );
60 | if r == C.OCI_ERROR {
61 | return bnd.stmt.ses.srv.env.ociError()
62 | }
63 | return nil
64 | }
65 |
66 | func (bnd *bndBoolPtr) setPtr() error {
67 | //Log.Infof("%s.setPtr()", bnd)
68 | if !bnd.nullp.IsNull() {
69 | r, _ := utf8.DecodeRune(bnd.buf)
70 | *bnd.value = r == bnd.trueRune
71 | } else {
72 | bnd.value = nil
73 | }
74 | return nil
75 | }
76 |
77 | func (bnd *bndBoolPtr) close() (err error) {
78 | defer func() {
79 | if value := recover(); value != nil {
80 | err = errR(value)
81 | }
82 | }()
83 |
84 | stmt := bnd.stmt
85 | bnd.stmt = nil
86 | bnd.ocibnd = nil
87 | bnd.value = nil
88 | bnd.nullp.Free()
89 | clear(bnd.buf, 0)
90 | stmt.putBnd(bndIdxBoolPtr, bnd)
91 | return nil
92 | }
93 |
--------------------------------------------------------------------------------
/bndBoolSlice.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import (
13 | "bytes"
14 | "unsafe"
15 | )
16 |
17 | type bndBoolSlice struct {
18 | stmt *Stmt
19 | ocibnd *C.OCIBind
20 | buf bytes.Buffer
21 | bytes []byte
22 | }
23 |
24 | func (bnd *bndBoolSlice) bindOra(values []Bool, position namedPos, falseRune rune, trueRune rune, stmt *Stmt) error {
25 | boolValues := make([]bool, len(values))
26 | nullInds := make([]C.sb2, len(values))
27 | for n := range values {
28 | if values[n].IsNull {
29 | nullInds[n] = C.sb2(-1)
30 | } else {
31 | boolValues[n] = values[n].Value
32 | }
33 | }
34 | return bnd.bind(boolValues, nullInds, position, falseRune, trueRune, stmt)
35 | }
36 |
37 | func (bnd *bndBoolSlice) bind(values []bool, nullInds []C.sb2, position namedPos, falseRune rune, trueRune rune, stmt *Stmt) (err error) {
38 | bnd.stmt = stmt
39 | if nullInds == nil {
40 | nullInds = make([]C.sb2, len(values))
41 | }
42 | alenp := make([]C.ACTUAL_LENGTH_TYPE, len(values))
43 | rcodep := make([]C.ub2, len(values))
44 | var maxLen = 1
45 | for n, bValue := range values {
46 | if bValue {
47 | _, err = bnd.buf.WriteRune(trueRune)
48 | if err != nil {
49 | return err
50 | }
51 | } else {
52 | _, err = bnd.buf.WriteRune(falseRune)
53 | if err != nil {
54 | return err
55 | }
56 | }
57 | alenp[n] = 1
58 | }
59 | bnd.bytes = bnd.buf.Bytes()
60 |
61 | ph, phLen, phFree := position.CString()
62 | if ph != nil {
63 | defer phFree()
64 | }
65 | r := C.bindByNameOrPos(
66 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
67 | &bnd.ocibnd,
68 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
69 | C.ub4(position.Ordinal), //ub4 position,
70 | ph,
71 | phLen,
72 | unsafe.Pointer(&bnd.bytes[0]), //void *valuep,
73 | C.LENGTH_TYPE(maxLen), //sb8 value_sz,
74 | C.SQLT_CHR, //ub2 dty,
75 | unsafe.Pointer(&nullInds[0]), //void *indp,
76 | &alenp[0], //ub4 *alenp,
77 | &rcodep[0], //ub2 *rcodep,
78 | 0, //ub4 maxarr_len,
79 | nil, //ub4 *curelep,
80 | C.OCI_DEFAULT) //ub4 mode );
81 | if r == C.OCI_ERROR {
82 | return bnd.stmt.ses.srv.env.ociError()
83 | }
84 |
85 | r = C.OCIBindArrayOfStruct(
86 | bnd.ocibnd, //OCIBind *bindp,
87 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
88 | C.ub4(maxLen), //ub4 pvskip,
89 | C.ub4(C.sizeof_sb2), //ub4 indskip,
90 | C.ub4(C.sizeof_ub4), //ub4 alskip,
91 | C.ub4(C.sizeof_ub2)) //ub4 rcskip
92 | if r == C.OCI_ERROR {
93 | return bnd.stmt.ses.srv.env.ociError()
94 | }
95 |
96 | return nil
97 | }
98 |
99 | func (bnd *bndBoolSlice) setPtr() error {
100 | return nil
101 | }
102 |
103 | func (bnd *bndBoolSlice) close() (err error) {
104 | defer func() {
105 | if value := recover(); value != nil {
106 | err = errR(value)
107 | }
108 | }()
109 |
110 | stmt := bnd.stmt
111 | bnd.stmt = nil
112 | bnd.ocibnd = nil
113 | bnd.bytes = nil
114 | bnd.buf.Reset()
115 | stmt.putBnd(bndIdxBoolSlice, bnd)
116 | return nil
117 | }
118 |
--------------------------------------------------------------------------------
/bndDate.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include
11 | #include "version.h"
12 | */
13 | import "C"
14 | import (
15 | "unsafe"
16 |
17 | "gopkg.in/rana/ora.v4/date"
18 | )
19 |
20 | type bndDate struct {
21 | stmt *Stmt
22 | ocibnd *C.OCIBind
23 | }
24 |
25 | func (bnd *bndDate) bind(dt date.Date, position namedPos, stmt *Stmt) error {
26 | bnd.stmt = stmt
27 | ph, phLen, phFree := position.CString()
28 | if ph != nil {
29 | defer phFree()
30 | }
31 | r := C.bindByNameOrPos(
32 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
33 | &bnd.ocibnd, //OCIBind **bindpp,
34 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
35 | C.ub4(position.Ordinal), //ub4 position,
36 | ph,
37 | phLen,
38 | unsafe.Pointer(&dt), //void *valuep,
39 | C.LENGTH_TYPE(7), //sb8 value_sz,
40 | C.SQLT_DAT, //ub2 dty,
41 | nil, //void *indp,
42 | nil, //ub2 *alenp,
43 | nil, //ub2 *rcodep,
44 | 0, //ub4 maxarr_len,
45 | nil, //ub4 *curelep,
46 | C.OCI_DEFAULT) //ub4 mode );
47 | if r == C.OCI_ERROR {
48 | return bnd.stmt.ses.srv.env.ociError()
49 | }
50 | return nil
51 | }
52 |
53 | func (bnd *bndDate) setPtr() (err error) {
54 | return nil
55 | }
56 |
57 | func (bnd *bndDate) close() (err error) {
58 | defer func() {
59 | if value := recover(); value != nil {
60 | err = errR(value)
61 | }
62 | }()
63 |
64 | stmt := bnd.stmt
65 | bnd.stmt = nil
66 | bnd.ocibnd = nil
67 | stmt.putBnd(bndIdxDate, bnd)
68 | return nil
69 | }
70 |
--------------------------------------------------------------------------------
/bndDatePtr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import (
14 | "time"
15 | "unsafe"
16 |
17 | "gopkg.in/rana/ora.v4/date"
18 | )
19 |
20 | type bndDatePtr struct {
21 | stmt *Stmt
22 | ocibnd *C.OCIBind
23 | value *Date
24 | ocidate [1]date.Date
25 | nullp
26 | }
27 |
28 | func (bnd *bndDatePtr) bind(value *Date, position namedPos, stmt *Stmt) error {
29 | bnd.stmt = stmt
30 | bnd.value = value
31 | bnd.nullp.Set(value == nil || value.IsNull())
32 | if value != nil {
33 | bnd.ocidate[0] = value.Date
34 | }
35 | //bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind, "bind val=%#v null?=%t datep=%#v (%v)\n", bnd.value, bnd.nullp.IsNull(), bnd.datep, bnd.datep.Get())
36 | ph, phLen, phFree := position.CString()
37 | if ph != nil {
38 | defer phFree()
39 | }
40 | r := C.bindByNameOrPos(
41 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
42 | &bnd.ocibnd, //OCIBind **bindpp,
43 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
44 | C.ub4(position.Ordinal), //ub4 position,
45 | ph,
46 | phLen,
47 | unsafe.Pointer(&bnd.ocidate[0]), //void *valuep,
48 | C.LENGTH_TYPE(7), //sb8 value_sz,
49 | C.SQLT_DAT, //ub2 dty,
50 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
51 | nil, //ub2 *alenp,
52 | nil, //ub2 *rcodep,
53 | 0, //ub4 maxarr_len,
54 | nil, //ub4 *curelep,
55 | C.OCI_DEFAULT) //ub4 mode );
56 | if r == C.OCI_ERROR {
57 | return bnd.stmt.ses.srv.env.ociError()
58 | }
59 | return nil
60 | }
61 |
62 | func (bnd *bndDatePtr) setPtr() (err error) {
63 | bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind, "setPtr val=%#v nullp=%#v datep=%#v (%v)\n", bnd.value, bnd.nullp, bnd.ocidate[0], bnd.ocidate[0].Get())
64 |
65 | if bnd.value == nil {
66 | return nil
67 | }
68 | if bnd.nullp.IsNull() {
69 | bnd.value.Set(time.Time{})
70 | return nil
71 | }
72 | bnd.value.Date = bnd.ocidate[0]
73 | return nil
74 | }
75 |
76 | func (bnd *bndDatePtr) close() (err error) {
77 | defer func() {
78 | if value := recover(); value != nil {
79 | err = errR(value)
80 | }
81 | }()
82 |
83 | stmt := bnd.stmt
84 | bnd.stmt = nil
85 | bnd.ocibnd = nil
86 | bnd.value = nil
87 | bnd.nullp.Free()
88 | stmt.putBnd(bndIdxDatePtr, bnd)
89 | return nil
90 | }
91 |
--------------------------------------------------------------------------------
/bndFloat32.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import (
13 | "unsafe"
14 | )
15 |
16 | type bndFloat32 struct {
17 | stmt *Stmt
18 | ocibnd *C.OCIBind
19 | ociNumber [1]C.OCINumber
20 | }
21 |
22 | func (bnd *bndFloat32) bind(value float32, position namedPos, stmt *Stmt) error {
23 | bnd.stmt = stmt
24 | r := C.OCINumberFromReal(
25 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
26 | unsafe.Pointer(&value), //const void *rnum,
27 | byteWidth32, //uword rnum_length,
28 | &bnd.ociNumber[0]) //OCINumber *number );
29 | if r == C.OCI_ERROR {
30 | return bnd.stmt.ses.srv.env.ociError()
31 | }
32 |
33 | ph, phLen, phFree := position.CString()
34 | if ph != nil {
35 | defer phFree()
36 | }
37 | r = C.bindByNameOrPos(
38 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
39 | &bnd.ocibnd,
40 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
41 | C.ub4(position.Ordinal), //ub4 position,
42 | ph,
43 | phLen,
44 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
45 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
46 | C.SQLT_VNU, //ub2 dty,
47 | nil, //void *indp,
48 | nil, //ub2 *alenp,
49 | nil, //ub2 *rcodep,
50 | 0, //ub4 maxarr_len,
51 | nil, //ub4 *curelep,
52 | C.OCI_DEFAULT) //ub4 mode );
53 | if r == C.OCI_ERROR {
54 | return bnd.stmt.ses.srv.env.ociError()
55 | }
56 | return nil
57 | }
58 |
59 | func (bnd *bndFloat32) setPtr() error {
60 | return nil
61 | }
62 |
63 | func (bnd *bndFloat32) close() (err error) {
64 | defer func() {
65 | if value := recover(); value != nil {
66 | err = errR(value)
67 | }
68 | }()
69 |
70 | stmt := bnd.stmt
71 | bnd.stmt = nil
72 | bnd.ocibnd = nil
73 | stmt.putBnd(bndIdxFloat32, bnd)
74 | return nil
75 | }
76 |
--------------------------------------------------------------------------------
/bndFloat32Ptr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import (
13 | "unsafe"
14 | )
15 |
16 | type bndFloat32Ptr struct {
17 | stmt *Stmt
18 | ocibnd *C.OCIBind
19 | ociNumber [1]C.OCINumber
20 | value *float32
21 | valueIsNull *bool
22 | nullp
23 | }
24 |
25 | func (bnd *bndFloat32Ptr) bind(value *float32, valueIsNull *bool, position namedPos, stmt *Stmt) error {
26 | bnd.stmt = stmt
27 | bnd.value = value
28 | bnd.valueIsNull = valueIsNull
29 | bnd.nullp.Set(value == nil)
30 | if value != nil {
31 | if err := bnd.stmt.ses.srv.env.OCINumberFromFloat(&bnd.ociNumber[0], float64(*value), byteWidth32); err != nil {
32 | return err
33 | }
34 | }
35 | ph, phLen, phFree := position.CString()
36 | if ph != nil {
37 | defer phFree()
38 | }
39 | r := C.bindByNameOrPos(
40 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
41 | &bnd.ocibnd,
42 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
43 | C.ub4(position.Ordinal), //ub4 position,
44 | ph,
45 | phLen,
46 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
47 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
48 | C.SQLT_VNU, //ub2 dty,
49 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
50 | nil, //ub2 *alenp,
51 | nil, //ub2 *rcodep,
52 | 0, //ub4 maxarr_len,
53 | nil, //ub4 *curelep,
54 | C.OCI_DEFAULT) //ub4 mode );
55 | if r == C.OCI_ERROR {
56 | return bnd.stmt.ses.srv.env.ociError()
57 | }
58 | return nil
59 | }
60 |
61 | func (bnd *bndFloat32Ptr) setPtr() error {
62 | if bnd.valueIsNull != nil {
63 | *bnd.valueIsNull = bnd.nullp.IsNull()
64 | }
65 | if bnd.nullp.IsNull() {
66 | return nil
67 | }
68 | f, err := bnd.stmt.ses.srv.env.OCINumberToFloat(&bnd.ociNumber[0], byteWidth32)
69 | *bnd.value = float32(f)
70 |
71 | return err
72 | }
73 |
74 | func (bnd *bndFloat32Ptr) close() (err error) {
75 | defer func() {
76 | if value := recover(); value != nil {
77 | err = errR(value)
78 | }
79 | }()
80 |
81 | stmt := bnd.stmt
82 | bnd.stmt = nil
83 | bnd.ocibnd = nil
84 | bnd.value = nil
85 | bnd.valueIsNull = nil
86 | bnd.nullp.Free()
87 | stmt.putBnd(bndIdxFloat32Ptr, bnd)
88 | return nil
89 | }
90 |
--------------------------------------------------------------------------------
/bndFloat64.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import (
13 | "unsafe"
14 | )
15 |
16 | type bndFloat64 struct {
17 | stmt *Stmt
18 | ocibnd *C.OCIBind
19 | ociNumber [1]C.OCINumber
20 | }
21 |
22 | func (bnd *bndFloat64) bind(value float64, position namedPos, stmt *Stmt) error {
23 | bnd.stmt = stmt
24 | r := C.OCINumberFromReal(
25 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
26 | unsafe.Pointer(&value), //const void *rnum,
27 | byteWidth64, //uword rnum_length,
28 | &bnd.ociNumber[0]) //OCINumber *number );
29 | if r == C.OCI_ERROR {
30 | return bnd.stmt.ses.srv.env.ociError()
31 | }
32 |
33 | ph, phLen, phFree := position.CString()
34 | if ph != nil {
35 | defer phFree()
36 | }
37 | r = C.bindByNameOrPos(
38 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
39 | &bnd.ocibnd,
40 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
41 | C.ub4(position.Ordinal), //ub4 position,
42 | ph,
43 | phLen,
44 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
45 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
46 | C.SQLT_VNU, //ub2 dty,
47 | nil, //void *indp,
48 | nil, //ub2 *alenp,
49 | nil, //ub2 *rcodep,
50 | 0, //ub4 maxarr_len,
51 | nil, //ub4 *curelep,
52 | C.OCI_DEFAULT) //ub4 mode );
53 | if r == C.OCI_ERROR {
54 | return bnd.stmt.ses.srv.env.ociError()
55 | }
56 | return nil
57 | }
58 |
59 | func (bnd *bndFloat64) setPtr() error {
60 | return nil
61 | }
62 |
63 | func (bnd *bndFloat64) close() (err error) {
64 | defer func() {
65 | if value := recover(); value != nil {
66 | err = errR(value)
67 | }
68 | }()
69 |
70 | stmt := bnd.stmt
71 | bnd.stmt = nil
72 | bnd.ocibnd = nil
73 | stmt.putBnd(bndIdxFloat64, bnd)
74 | return nil
75 | }
76 |
--------------------------------------------------------------------------------
/bndFloat64Ptr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import (
13 | "unsafe"
14 | )
15 |
16 | type bndFloat64Ptr struct {
17 | stmt *Stmt
18 | ocibnd *C.OCIBind
19 | ociNumber [1]C.OCINumber
20 | value *float64
21 | valueIsNull *bool
22 | nullp
23 | }
24 |
25 | func (bnd *bndFloat64Ptr) bind(value *float64, valueIsNull *bool, position namedPos, stmt *Stmt) error {
26 | bnd.stmt = stmt
27 | bnd.value = value
28 | bnd.valueIsNull = valueIsNull
29 | bnd.nullp.Set(value == nil)
30 | if value != nil {
31 | if err := bnd.stmt.ses.srv.env.OCINumberFromFloat(&bnd.ociNumber[0], floatSixtyFour(*value), byteWidth64); err != nil {
32 | return err
33 | }
34 | }
35 | ph, phLen, phFree := position.CString()
36 | if ph != nil {
37 | defer phFree()
38 | }
39 | r := C.bindByNameOrPos(
40 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
41 | &bnd.ocibnd,
42 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
43 | C.ub4(position.Ordinal), //ub4 position,
44 | ph,
45 | phLen,
46 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
47 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
48 | C.SQLT_VNU, //ub2 dty,
49 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
50 | nil, //ub2 *alenp,
51 | nil, //ub2 *rcodep,
52 | 0, //ub4 maxarr_len,
53 | nil, //ub4 *curelep,
54 | C.OCI_DEFAULT) //ub4 mode );
55 | if r == C.OCI_ERROR {
56 | return bnd.stmt.ses.srv.env.ociError()
57 | }
58 | return nil
59 | }
60 |
61 | func (bnd *bndFloat64Ptr) setPtr() error {
62 | if bnd.valueIsNull != nil {
63 | *bnd.valueIsNull = bnd.nullp.IsNull()
64 | }
65 | if bnd.nullp.IsNull() {
66 | return nil
67 | }
68 | f, err := bnd.stmt.ses.srv.env.OCINumberToFloat(&bnd.ociNumber[0], byteWidth64)
69 | *bnd.value = float64(f)
70 |
71 | return err
72 | }
73 |
74 | func (bnd *bndFloat64Ptr) close() (err error) {
75 | defer func() {
76 | if value := recover(); value != nil {
77 | err = errR(value)
78 | }
79 | }()
80 |
81 | stmt := bnd.stmt
82 | bnd.stmt = nil
83 | bnd.ocibnd = nil
84 | bnd.value = nil
85 | bnd.valueIsNull = nil
86 | bnd.nullp.Free()
87 | stmt.putBnd(bndIdxFloat64Ptr, bnd)
88 | return nil
89 | }
90 |
--------------------------------------------------------------------------------
/bndInt16.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import "unsafe"
13 |
14 | type bndInt16 struct {
15 | stmt *Stmt
16 | ocibnd *C.OCIBind
17 | ociNumber [1]C.OCINumber
18 | }
19 |
20 | func (bnd *bndInt16) bind(value int16, position namedPos, stmt *Stmt) error {
21 | bnd.stmt = stmt
22 | r := C.OCINumberFromInt(
23 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
24 | unsafe.Pointer(&value), //const void *inum,
25 | byteWidth16, //uword inum_length,
26 | C.OCI_NUMBER_SIGNED, //uword inum_s_flag,
27 | &bnd.ociNumber[0]) //OCINumber *number );
28 | if r == C.OCI_ERROR {
29 | return bnd.stmt.ses.srv.env.ociError()
30 | }
31 | ph, phLen, phFree := position.CString()
32 | if ph != nil {
33 | defer phFree()
34 | }
35 | r = C.bindByNameOrPos(
36 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
37 | &bnd.ocibnd,
38 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
39 | C.ub4(position.Ordinal), //ub4 position,
40 | ph,
41 | phLen,
42 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
43 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
44 | C.SQLT_VNU, //ub2 dty,
45 | nil, //void *indp,
46 | nil, //ub2 *alenp,
47 | nil, //ub2 *rcodep,
48 | 0, //ub4 maxarr_len,
49 | nil, //ub4 *curelep,
50 | C.OCI_DEFAULT) //ub4 mode );
51 | if r == C.OCI_ERROR {
52 | return bnd.stmt.ses.srv.env.ociError()
53 | }
54 | return nil
55 | }
56 |
57 | func (bnd *bndInt16) setPtr() error {
58 | return nil
59 | }
60 |
61 | func (bnd *bndInt16) close() (err error) {
62 | defer func() {
63 | if value := recover(); value != nil {
64 | err = errR(value)
65 | }
66 | }()
67 |
68 | stmt := bnd.stmt
69 | bnd.stmt = nil
70 | bnd.ocibnd = nil
71 | stmt.putBnd(bndIdxInt16, bnd)
72 | return nil
73 | }
74 |
--------------------------------------------------------------------------------
/bndInt16Ptr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | type bndInt16Ptr struct {
16 | stmt *Stmt
17 | ocibnd *C.OCIBind
18 | ociNumber [1]C.OCINumber
19 | value *int16
20 | valueIsNull *bool
21 | nullp
22 | }
23 |
24 | func (bnd *bndInt16Ptr) bind(value *int16, valueIsNull *bool, position namedPos, stmt *Stmt) error {
25 | //bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind, "Int16Ptr.bind(%d) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
26 | bnd.stmt = stmt
27 | bnd.value = value
28 | bnd.valueIsNull = valueIsNull
29 | bnd.nullp.Set(value == nil)
30 | if value != nil {
31 | if err := bnd.stmt.ses.srv.env.OCINumberFromInt(&bnd.ociNumber[0], int64(*value), byteWidth16); err != nil {
32 | return err
33 | }
34 | bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind,
35 | "Int16Ptr.bind(%v) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
36 | }
37 | ph, phLen, phFree := position.CString()
38 | if ph != nil {
39 | defer phFree()
40 | }
41 | r := C.bindByNameOrPos(
42 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
43 | &bnd.ocibnd,
44 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
45 | C.ub4(position.Ordinal), //ub4 position,
46 | ph,
47 | phLen,
48 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
49 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
50 | C.SQLT_VNU, //ub2 dty,
51 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
52 | nil, //ub2 *alenp,
53 | nil, //ub2 *rcodep,
54 | 0, //ub4 maxarr_len,
55 | nil, //ub4 *curelep,
56 | C.OCI_DEFAULT) //ub4 mode );
57 | if r == C.OCI_ERROR {
58 | return bnd.stmt.ses.srv.env.ociError()
59 | }
60 | return nil
61 | }
62 |
63 | func (bnd *bndInt16Ptr) setPtr() error {
64 | if bnd.valueIsNull != nil {
65 | *bnd.valueIsNull = bnd.nullp.IsNull()
66 | }
67 | if bnd.nullp.IsNull() {
68 | return nil
69 | }
70 | i, err := bnd.stmt.ses.srv.env.OCINumberToInt(&bnd.ociNumber[0], byteWidth16)
71 | *bnd.value = int16(i)
72 |
73 | return err
74 | }
75 |
76 | func (bnd *bndInt16Ptr) close() (err error) {
77 | defer func() {
78 | if value := recover(); value != nil {
79 | err = errR(value)
80 | }
81 | }()
82 |
83 | stmt := bnd.stmt
84 | bnd.stmt = nil
85 | bnd.ocibnd = nil
86 | bnd.value = nil
87 | bnd.valueIsNull = nil
88 | bnd.nullp.Free()
89 | stmt.putBnd(bndIdxInt16Ptr, bnd)
90 | return nil
91 | }
92 |
--------------------------------------------------------------------------------
/bndInt32.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import "unsafe"
13 |
14 | type bndInt32 struct {
15 | stmt *Stmt
16 | ocibnd *C.OCIBind
17 | ociNumber [1]C.OCINumber
18 | }
19 |
20 | func (bnd *bndInt32) bind(value int32, position namedPos, stmt *Stmt) error {
21 | bnd.stmt = stmt
22 | r := C.OCINumberFromInt(
23 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
24 | unsafe.Pointer(&value), //const void *inum,
25 | byteWidth32, //uword inum_length,
26 | C.OCI_NUMBER_SIGNED, //uword inum_s_flag,
27 | &bnd.ociNumber[0]) //OCINumber *number );
28 | if r == C.OCI_ERROR {
29 | return bnd.stmt.ses.srv.env.ociError()
30 | }
31 | ph, phLen, phFree := position.CString()
32 | if ph != nil {
33 | defer phFree()
34 | }
35 | r = C.bindByNameOrPos(
36 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
37 | &bnd.ocibnd,
38 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
39 | C.ub4(position.Ordinal), //ub4 position,
40 | ph,
41 | phLen,
42 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
43 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
44 | C.SQLT_VNU, //ub2 dty,
45 | nil, //void *indp,
46 | nil, //ub2 *alenp,
47 | nil, //ub2 *rcodep,
48 | 0, //ub4 maxarr_len,
49 | nil, //ub4 *curelep,
50 | C.OCI_DEFAULT) //ub4 mode );
51 | if r == C.OCI_ERROR {
52 | return bnd.stmt.ses.srv.env.ociError()
53 | }
54 | return nil
55 | }
56 |
57 | func (bnd *bndInt32) setPtr() error {
58 | return nil
59 | }
60 |
61 | func (bnd *bndInt32) close() (err error) {
62 | defer func() {
63 | if value := recover(); value != nil {
64 | err = errR(value)
65 | }
66 | }()
67 |
68 | stmt := bnd.stmt
69 | bnd.stmt = nil
70 | bnd.ocibnd = nil
71 | stmt.putBnd(bndIdxInt32, bnd)
72 | return nil
73 | }
74 |
--------------------------------------------------------------------------------
/bndInt32Ptr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | type bndInt32Ptr struct {
16 | stmt *Stmt
17 | ocibnd *C.OCIBind
18 | ociNumber [1]C.OCINumber
19 | value *int32
20 | valueIsNull *bool
21 | nullp
22 | }
23 |
24 | func (bnd *bndInt32Ptr) bind(value *int32, valueIsNull *bool, position namedPos, stmt *Stmt) error {
25 | //bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind, "Int32Ptr.bind(%d) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
26 | bnd.stmt = stmt
27 | bnd.value = value
28 | bnd.valueIsNull = valueIsNull
29 | bnd.nullp.Set(value == nil)
30 | if value != nil {
31 | if err := bnd.stmt.ses.srv.env.OCINumberFromInt(&bnd.ociNumber[0], int64(*value), byteWidth32); err != nil {
32 | return err
33 | }
34 | bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind,
35 | "Int32Ptr.bind(%v) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
36 | }
37 | ph, phLen, phFree := position.CString()
38 | if ph != nil {
39 | defer phFree()
40 | }
41 | r := C.bindByNameOrPos(
42 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
43 | &bnd.ocibnd,
44 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
45 | C.ub4(position.Ordinal), //ub4 position,
46 | ph,
47 | phLen,
48 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
49 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
50 | C.SQLT_VNU, //ub2 dty,
51 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
52 | nil, //ub2 *alenp,
53 | nil, //ub2 *rcodep,
54 | 0, //ub4 maxarr_len,
55 | nil, //ub4 *curelep,
56 | C.OCI_DEFAULT) //ub4 mode );
57 | if r == C.OCI_ERROR {
58 | return bnd.stmt.ses.srv.env.ociError()
59 | }
60 | return nil
61 | }
62 |
63 | func (bnd *bndInt32Ptr) setPtr() error {
64 | if bnd.valueIsNull != nil {
65 | *bnd.valueIsNull = bnd.nullp.IsNull()
66 | }
67 | if bnd.nullp.IsNull() {
68 | return nil
69 | }
70 | i, err := bnd.stmt.ses.srv.env.OCINumberToInt(&bnd.ociNumber[0], byteWidth32)
71 | *bnd.value = int32(i)
72 |
73 | return err
74 | }
75 |
76 | func (bnd *bndInt32Ptr) close() (err error) {
77 | defer func() {
78 | if value := recover(); value != nil {
79 | err = errR(value)
80 | }
81 | }()
82 |
83 | stmt := bnd.stmt
84 | bnd.stmt = nil
85 | bnd.ocibnd = nil
86 | bnd.value = nil
87 | bnd.valueIsNull = nil
88 | bnd.nullp.Free()
89 | stmt.putBnd(bndIdxInt32Ptr, bnd)
90 | return nil
91 | }
92 |
--------------------------------------------------------------------------------
/bndInt64.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import "unsafe"
13 |
14 | type bndInt64 struct {
15 | stmt *Stmt
16 | ocibnd *C.OCIBind
17 | ociNumber [1]C.OCINumber
18 | }
19 |
20 | func (bnd *bndInt64) bind(value int64, position namedPos, stmt *Stmt) error {
21 | bnd.stmt = stmt
22 | r := C.OCINumberFromInt(
23 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
24 | unsafe.Pointer(&value), //const void *inum,
25 | byteWidth64, //uword inum_length,
26 | C.OCI_NUMBER_SIGNED, //uword inum_s_flag,
27 | &bnd.ociNumber[0]) //OCINumber *number );
28 | if r == C.OCI_ERROR {
29 | return bnd.stmt.ses.srv.env.ociError()
30 | }
31 | ph, phLen, phFree := position.CString()
32 | if ph != nil {
33 | defer phFree()
34 | }
35 | r = C.bindByNameOrPos(
36 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
37 | &bnd.ocibnd,
38 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
39 | C.ub4(position.Ordinal), //ub4 position,
40 | ph,
41 | phLen,
42 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
43 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
44 | C.SQLT_VNU, //ub2 dty,
45 | nil, //void *indp,
46 | nil, //ub2 *alenp,
47 | nil, //ub2 *rcodep,
48 | 0, //ub4 maxarr_len,
49 | nil, //ub4 *curelep,
50 | C.OCI_DEFAULT) //ub4 mode );
51 | if r == C.OCI_ERROR {
52 | return bnd.stmt.ses.srv.env.ociError()
53 | }
54 | return nil
55 | }
56 |
57 | func (bnd *bndInt64) setPtr() error {
58 | return nil
59 | }
60 |
61 | func (bnd *bndInt64) close() (err error) {
62 | defer func() {
63 | if value := recover(); value != nil {
64 | err = errR(value)
65 | }
66 | }()
67 |
68 | stmt := bnd.stmt
69 | bnd.stmt = nil
70 | bnd.ocibnd = nil
71 | stmt.putBnd(bndIdxInt64, bnd)
72 | return nil
73 | }
74 |
--------------------------------------------------------------------------------
/bndInt64Ptr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | type bndInt64Ptr struct {
16 | stmt *Stmt
17 | ocibnd *C.OCIBind
18 | ociNumber [1]C.OCINumber
19 | value *int64
20 | valueIsNull *bool
21 | nullp
22 | }
23 |
24 | func (bnd *bndInt64Ptr) bind(value *int64, valueIsNull *bool, position namedPos, stmt *Stmt) error {
25 | //bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind, "Int64Ptr.bind(%d) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
26 | bnd.stmt = stmt
27 | bnd.value = value
28 | bnd.valueIsNull = valueIsNull
29 | bnd.nullp.Set(value == nil)
30 | if value != nil {
31 | if err := bnd.stmt.ses.srv.env.OCINumberFromInt(&bnd.ociNumber[0], intSixtyFour(*value), byteWidth64); err != nil {
32 | return err
33 | }
34 | bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind,
35 | "Int64Ptr.bind(%v) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
36 | }
37 | ph, phLen, phFree := position.CString()
38 | if ph != nil {
39 | defer phFree()
40 | }
41 | r := C.bindByNameOrPos(
42 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
43 | &bnd.ocibnd,
44 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
45 | C.ub4(position.Ordinal), //ub4 position,
46 | ph,
47 | phLen,
48 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
49 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
50 | C.SQLT_VNU, //ub2 dty,
51 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
52 | nil, //ub2 *alenp,
53 | nil, //ub2 *rcodep,
54 | 0, //ub4 maxarr_len,
55 | nil, //ub4 *curelep,
56 | C.OCI_DEFAULT) //ub4 mode );
57 | if r == C.OCI_ERROR {
58 | return bnd.stmt.ses.srv.env.ociError()
59 | }
60 | return nil
61 | }
62 |
63 | func (bnd *bndInt64Ptr) setPtr() error {
64 | if bnd.valueIsNull != nil {
65 | *bnd.valueIsNull = bnd.nullp.IsNull()
66 | }
67 | if bnd.nullp.IsNull() {
68 | return nil
69 | }
70 | i, err := bnd.stmt.ses.srv.env.OCINumberToInt(&bnd.ociNumber[0], byteWidth64)
71 | *bnd.value = int64(i)
72 |
73 | return err
74 | }
75 |
76 | func (bnd *bndInt64Ptr) close() (err error) {
77 | defer func() {
78 | if value := recover(); value != nil {
79 | err = errR(value)
80 | }
81 | }()
82 |
83 | stmt := bnd.stmt
84 | bnd.stmt = nil
85 | bnd.ocibnd = nil
86 | bnd.value = nil
87 | bnd.valueIsNull = nil
88 | bnd.nullp.Free()
89 | stmt.putBnd(bndIdxInt64Ptr, bnd)
90 | return nil
91 | }
92 |
--------------------------------------------------------------------------------
/bndInt8.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import "unsafe"
13 |
14 | type bndInt8 struct {
15 | stmt *Stmt
16 | ocibnd *C.OCIBind
17 | ociNumber [1]C.OCINumber
18 | }
19 |
20 | func (bnd *bndInt8) bind(value int8, position namedPos, stmt *Stmt) error {
21 | bnd.stmt = stmt
22 | r := C.OCINumberFromInt(
23 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
24 | unsafe.Pointer(&value), //const void *inum,
25 | byteWidth8, //uword inum_length,
26 | C.OCI_NUMBER_SIGNED, //uword inum_s_flag,
27 | &bnd.ociNumber[0]) //OCINumber *number );
28 | if r == C.OCI_ERROR {
29 | return bnd.stmt.ses.srv.env.ociError()
30 | }
31 | ph, phLen, phFree := position.CString()
32 | if ph != nil {
33 | defer phFree()
34 | }
35 | r = C.bindByNameOrPos(
36 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
37 | &bnd.ocibnd,
38 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
39 | C.ub4(position.Ordinal), //ub4 position,
40 | ph,
41 | phLen,
42 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
43 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
44 | C.SQLT_VNU, //ub2 dty,
45 | nil, //void *indp,
46 | nil, //ub2 *alenp,
47 | nil, //ub2 *rcodep,
48 | 0, //ub4 maxarr_len,
49 | nil, //ub4 *curelep,
50 | C.OCI_DEFAULT) //ub4 mode );
51 | if r == C.OCI_ERROR {
52 | return bnd.stmt.ses.srv.env.ociError()
53 | }
54 | return nil
55 | }
56 |
57 | func (bnd *bndInt8) setPtr() error {
58 | return nil
59 | }
60 |
61 | func (bnd *bndInt8) close() (err error) {
62 | defer func() {
63 | if value := recover(); value != nil {
64 | err = errR(value)
65 | }
66 | }()
67 |
68 | stmt := bnd.stmt
69 | bnd.stmt = nil
70 | bnd.ocibnd = nil
71 | stmt.putBnd(bndIdxInt8, bnd)
72 | return nil
73 | }
74 |
--------------------------------------------------------------------------------
/bndInt8Ptr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | type bndInt8Ptr struct {
16 | stmt *Stmt
17 | ocibnd *C.OCIBind
18 | ociNumber [1]C.OCINumber
19 | value *int8
20 | valueIsNull *bool
21 | nullp
22 | }
23 |
24 | func (bnd *bndInt8Ptr) bind(value *int8, valueIsNull *bool, position namedPos, stmt *Stmt) error {
25 | //bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind, "Int8Ptr.bind(%d) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
26 | bnd.stmt = stmt
27 | bnd.value = value
28 | bnd.valueIsNull = valueIsNull
29 | bnd.nullp.Set(value == nil)
30 | if value != nil {
31 | if err := bnd.stmt.ses.srv.env.OCINumberFromInt(&bnd.ociNumber[0], int64(*value), byteWidth8); err != nil {
32 | return err
33 | }
34 | bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind,
35 | "Int8Ptr.bind(%v) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
36 | }
37 | ph, phLen, phFree := position.CString()
38 | if ph != nil {
39 | defer phFree()
40 | }
41 | r := C.bindByNameOrPos(
42 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
43 | &bnd.ocibnd,
44 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
45 | C.ub4(position.Ordinal), //ub4 position,
46 | ph,
47 | phLen,
48 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
49 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
50 | C.SQLT_VNU, //ub2 dty,
51 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
52 | nil, //ub2 *alenp,
53 | nil, //ub2 *rcodep,
54 | 0, //ub4 maxarr_len,
55 | nil, //ub4 *curelep,
56 | C.OCI_DEFAULT) //ub4 mode );
57 | if r == C.OCI_ERROR {
58 | return bnd.stmt.ses.srv.env.ociError()
59 | }
60 | return nil
61 | }
62 |
63 | func (bnd *bndInt8Ptr) setPtr() error {
64 | if bnd.valueIsNull != nil {
65 | *bnd.valueIsNull = bnd.nullp.IsNull()
66 | }
67 | if bnd.nullp.IsNull() {
68 | return nil
69 | }
70 | i, err := bnd.stmt.ses.srv.env.OCINumberToInt(&bnd.ociNumber[0], byteWidth8)
71 | *bnd.value = int8(i)
72 |
73 | return err
74 | }
75 |
76 | func (bnd *bndInt8Ptr) close() (err error) {
77 | defer func() {
78 | if value := recover(); value != nil {
79 | err = errR(value)
80 | }
81 | }()
82 |
83 | stmt := bnd.stmt
84 | bnd.stmt = nil
85 | bnd.ocibnd = nil
86 | bnd.value = nil
87 | bnd.valueIsNull = nil
88 | bnd.nullp.Free()
89 | stmt.putBnd(bndIdxInt8Ptr, bnd)
90 | return nil
91 | }
92 |
--------------------------------------------------------------------------------
/bndIntervalDS.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import (
13 | "unsafe"
14 | )
15 |
16 | type bndIntervalDS struct {
17 | stmt *Stmt
18 | ocibnd *C.OCIBind
19 | intervalp
20 | }
21 |
22 | func (bnd *bndIntervalDS) bind(value IntervalDS, position namedPos, stmt *Stmt) error {
23 | bnd.stmt = stmt
24 | r := C.OCIDescriptorAlloc(
25 | unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //CONST dvoid *parenth,
26 | (*unsafe.Pointer)(unsafe.Pointer(bnd.intervalp.Pointer())), //dvoid **descpp,
27 | C.OCI_DTYPE_INTERVAL_DS, //ub4 type,
28 | 0, //size_t xtramem_sz,
29 | nil) //dvoid **usrmempp);
30 | if r == C.OCI_ERROR {
31 | return bnd.stmt.ses.srv.env.ociError()
32 | } else if r == C.OCI_INVALID_HANDLE {
33 | return errNew("unable to allocate oci interval handle during bind")
34 | }
35 | r = C.OCIIntervalSetDaySecond(
36 | unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //void *hndl,
37 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
38 | C.sb4(value.Day), //sb4 dy,
39 | C.sb4(value.Hour), //sb4 hr,
40 | C.sb4(value.Minute), //sb4 mm,
41 | C.sb4(value.Second), //sb4 ss,
42 | C.sb4(value.Nanosecond), //sb4 fsec,
43 | bnd.intervalp.Value()) //OCIInterval *result );
44 | if r == C.OCI_ERROR {
45 | return bnd.stmt.ses.srv.env.ociError()
46 | }
47 | ph, phLen, phFree := position.CString()
48 | if ph != nil {
49 | defer phFree()
50 | }
51 | r = C.bindByNameOrPos(
52 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
53 | &bnd.ocibnd,
54 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
55 | C.ub4(position.Ordinal), //ub4 position,
56 | ph,
57 | phLen,
58 | unsafe.Pointer(bnd.intervalp.Pointer()), //void *valuep,
59 | C.LENGTH_TYPE(bnd.intervalp.Size()), //sb8 value_sz,
60 | C.SQLT_INTERVAL_DS, //ub2 dty,
61 | nil, //void *indp,
62 | nil, //ub2 *alenp,
63 | nil, //ub2 *rcodep,
64 | 0, //ub4 maxarr_len,
65 | nil, //ub4 *curelep,
66 | C.OCI_DEFAULT) //ub4 mode );
67 | if r == C.OCI_ERROR {
68 | return bnd.stmt.ses.srv.env.ociError()
69 | }
70 | return nil
71 | }
72 |
73 | func (bnd *bndIntervalDS) setPtr() error {
74 | return nil
75 | }
76 |
77 | func (bnd *bndIntervalDS) close() (err error) {
78 | defer func() {
79 | if value := recover(); value != nil {
80 | err = errR(value)
81 | }
82 | }()
83 |
84 | C.OCIDescriptorFree(
85 | unsafe.Pointer(bnd.intervalp.Pointer()), //void *descp,
86 | C.OCI_DTYPE_INTERVAL_DS) //timeDefine.descTypeCode)
87 | stmt := bnd.stmt
88 | bnd.stmt = nil
89 | bnd.ocibnd = nil
90 | bnd.intervalp.Free()
91 | stmt.putBnd(bndIdxIntervalDS, bnd)
92 | return nil
93 | }
94 |
--------------------------------------------------------------------------------
/bndIntervalYM.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import (
13 | "unsafe"
14 | )
15 |
16 | type bndIntervalYM struct {
17 | stmt *Stmt
18 | ocibnd *C.OCIBind
19 | intervalp
20 | }
21 |
22 | func (bnd *bndIntervalYM) bind(value IntervalYM, position namedPos, stmt *Stmt) error {
23 | bnd.stmt = stmt
24 | r := C.OCIDescriptorAlloc(
25 | unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //CONST dvoid *parenth,
26 | (*unsafe.Pointer)(unsafe.Pointer(bnd.intervalp.Pointer())), //dvoid **descpp,
27 | C.OCI_DTYPE_INTERVAL_YM, //ub4 type,
28 | 0, //size_t xtramem_sz,
29 | nil) //dvoid **usrmempp);
30 | if r == C.OCI_ERROR {
31 | return bnd.stmt.ses.srv.env.ociError()
32 | } else if r == C.OCI_INVALID_HANDLE {
33 | return errNew("unable to allocate oci interval handle during bind")
34 | }
35 | r = C.OCIIntervalSetYearMonth(
36 | unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //void *hndl,
37 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
38 | C.sb4(value.Year), //sb4 yr,
39 | C.sb4(value.Month), //sb4 mnth,
40 | bnd.intervalp.Value()) //OCIInterval *result );
41 | if r == C.OCI_ERROR {
42 | return bnd.stmt.ses.srv.env.ociError()
43 | }
44 | ph, phLen, phFree := position.CString()
45 | if ph != nil {
46 | defer phFree()
47 | }
48 | r = C.bindByNameOrPos(
49 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
50 | &bnd.ocibnd,
51 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
52 | C.ub4(position.Ordinal), //ub4 position,
53 | ph,
54 | phLen,
55 | unsafe.Pointer(bnd.intervalp.Pointer()), //void *valuep,
56 | C.LENGTH_TYPE(bnd.intervalp.Size()), //sb8 value_sz,
57 | C.SQLT_INTERVAL_YM, //ub2 dty,
58 | nil, //void *indp,
59 | nil, //ub2 *alenp,
60 | nil, //ub2 *rcodep,
61 | 0, //ub4 maxarr_len,
62 | nil, //ub4 *curelep,
63 | C.OCI_DEFAULT) //ub4 mode );
64 | if r == C.OCI_ERROR {
65 | return bnd.stmt.ses.srv.env.ociError()
66 | }
67 | return nil
68 | }
69 |
70 | func (bnd *bndIntervalYM) setPtr() error {
71 | return nil
72 | }
73 |
74 | func (bnd *bndIntervalYM) close() (err error) {
75 | defer func() {
76 | if value := recover(); value != nil {
77 | err = errR(value)
78 | }
79 | }()
80 |
81 | C.OCIDescriptorFree(
82 | unsafe.Pointer(bnd.intervalp.Value()), //void *descp,
83 | C.OCI_DTYPE_INTERVAL_YM) //timeDefine.descTypeCode) //ub4 type );
84 | stmt := bnd.stmt
85 | bnd.stmt = nil
86 | bnd.ocibnd = nil
87 | bnd.intervalp.Free()
88 | stmt.putBnd(bndIdxIntervalYM, bnd)
89 | return nil
90 | }
91 |
--------------------------------------------------------------------------------
/bndNil.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import (
13 | "unsafe"
14 | )
15 |
16 | type bndNil struct {
17 | stmt *Stmt
18 | ocibnd *C.OCIBind
19 | }
20 |
21 | func (bnd *bndNil) bind(position namedPos, sqlt C.ub2, stmt *Stmt) error {
22 | bnd.stmt = stmt
23 | indp := C.sb2(-1)
24 | ph, phLen, phFree := position.CString()
25 | if ph != nil {
26 | defer phFree()
27 | }
28 | r := C.bindByNameOrPos(
29 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
30 | &bnd.ocibnd, //OCIBind **bindpp,
31 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
32 | C.ub4(position.Ordinal), //ub4 position,
33 | ph,
34 | phLen,
35 | nil, //void *valuep,
36 | 0, //sb8 value_sz,
37 | sqlt, //C.SQLT_CHR, //ub2 dty,
38 | unsafe.Pointer(&indp), //void *indp,
39 | nil, //ub2 *alenp,
40 | nil, //ub2 *rcodep,
41 | 0, //ub4 maxarr_len,
42 | nil, //ub4 *curelep,
43 | C.OCI_DEFAULT) //ub4 mode );
44 | if r == C.OCI_ERROR {
45 | return bnd.stmt.ses.srv.env.ociError()
46 | }
47 |
48 | return nil
49 | }
50 |
51 | func (bnd *bndNil) setPtr() error {
52 | return nil
53 | }
54 |
55 | func (bnd *bndNil) close() (err error) {
56 | defer func() {
57 | if value := recover(); value != nil {
58 | err = errR(value)
59 | }
60 | }()
61 |
62 | stmt := bnd.stmt
63 | bnd.stmt = nil
64 | bnd.ocibnd = nil
65 | stmt.putBnd(bndIdxNil, bnd)
66 | return nil
67 | }
68 |
--------------------------------------------------------------------------------
/bndNumStringPtr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import "unsafe"
13 |
14 | type bndNumStringPtr struct {
15 | stmt *Stmt
16 | ocibnd *C.OCIBind
17 | ociNumber [1]C.OCINumber
18 | value *Num
19 | buf [numStringLen]byte
20 | nullp
21 | }
22 |
23 | func (bnd *bndNumStringPtr) bind(value *Num, position namedPos, stmt *Stmt) error {
24 | bnd.stmt = stmt
25 | bnd.value = value
26 | bnd.nullp.Set(value == nil || *value == "")
27 | //length := C.ub4(0)
28 | if value != nil && *value != "" {
29 | //length = C.ub4(copy(bnd.buf[:], string(*value)))
30 | //fmt.Printf("NumberFromtext %q [%d]\n", value, length)
31 | if err := bnd.stmt.ses.srv.env.numberFromText(&bnd.ociNumber[0], string(*value)); err != nil {
32 | return err
33 | }
34 | }
35 | ph, phLen, phFree := position.CString()
36 | if ph != nil {
37 | defer phFree()
38 | }
39 | r := C.bindByNameOrPos(
40 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
41 | &bnd.ocibnd,
42 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
43 | C.ub4(position.Ordinal), //ub4 position,
44 | ph,
45 | phLen,
46 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
47 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
48 | C.SQLT_VNU, //ub2 dty,
49 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
50 | nil, //ub2 *alenp,
51 | nil, //ub2 *rcodep,
52 | 0, //ub4 maxarr_len,
53 | nil, //ub4 *curelep,
54 | C.OCI_DEFAULT) //ub4 mode );
55 | if r == C.OCI_ERROR {
56 | return bnd.stmt.ses.srv.env.ociError()
57 | }
58 | return nil
59 | }
60 |
61 | func (bnd *bndNumStringPtr) setPtr() error {
62 | if bnd.nullp.IsNull() {
63 | return nil
64 | }
65 | bufLen := C.ub4(numStringLen)
66 | r := C.OCINumberToText(
67 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
68 | &bnd.ociNumber[0], //const OCINumber *number,
69 | numberFmtC,
70 | C.ub4(numberFmtLen), //ub4 fmt_length,
71 | numberNLSC, //CONST OraText *nls_params,
72 | C.ub4(numberNLSLen), //ub4 nls_p_length,
73 | &bufLen,
74 | (*C.oratext)(unsafe.Pointer(&bnd.buf[0])), //void *rsl );
75 | )
76 | if r == C.OCI_ERROR {
77 | return bnd.stmt.ses.srv.env.ociError()
78 | }
79 | if bufLen > 0 && bnd.buf[0] == '.' {
80 | *bnd.value = Num(append(append(make([]byte, 0, int(bufLen)+1),
81 | '0'),
82 | bnd.buf[:int(bufLen)]...))
83 | } else {
84 | *bnd.value = Num(bnd.buf[:int(bufLen)])
85 | }
86 | return nil
87 | }
88 |
89 | func (bnd *bndNumStringPtr) close() (err error) {
90 | defer func() {
91 | if value := recover(); value != nil {
92 | err = errR(value)
93 | }
94 | }()
95 |
96 | stmt := bnd.stmt
97 | bnd.stmt = nil
98 | bnd.ocibnd = nil
99 | bnd.value = nil
100 | bnd.nullp.Free()
101 | stmt.putBnd(bndIdxNumStringPtr, bnd)
102 | return nil
103 | }
104 |
--------------------------------------------------------------------------------
/bndNumStringSlice.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 |
11 | */
12 | import "C"
13 | import (
14 | "unsafe"
15 | )
16 |
17 | type bndNumStringSlice struct {
18 | stmt *Stmt
19 | ocibnd *C.OCIBind
20 | ociNumbers []C.OCINumber
21 | arrHlp
22 | }
23 |
24 | func (bnd *bndNumStringSlice) bindOra(values []OraNum, position namedPos, stmt *Stmt, isAssocArray bool) (iterations uint32, err error) {
25 | stringValues := make([]Num, len(values))
26 | if cap(bnd.nullInds) < len(values) {
27 | bnd.nullInds = make([]C.sb2, len(values))
28 | } else {
29 | bnd.nullInds = bnd.nullInds[:len(values)]
30 | }
31 | for n := range values {
32 | if values[n].IsNull {
33 | bnd.nullInds[n] = C.sb2(-1)
34 | } else {
35 | stringValues[n] = Num(values[n].Value)
36 | }
37 | }
38 | return bnd.bind(stringValues, bnd.nullInds, position, stmt, isAssocArray)
39 | }
40 |
41 | func (bnd *bndNumStringSlice) bind(values []Num, nullInds []C.sb2, position namedPos, stmt *Stmt, isAssocArray bool) (iterations uint32, err error) {
42 | bnd.stmt = stmt
43 | L, C := len(values), cap(values)
44 | if nullInds != nil {
45 | bnd.nullInds = nullInds
46 | }
47 | iterations, curlenp, needAppend := bnd.ensureBindArrLength(&L, &C, isAssocArray)
48 | if needAppend {
49 | values = append(values, Num("0"))
50 | }
51 | bnd.ociNumbers = make([]C.OCINumber, len(values))
52 | alen := C.ACTUAL_LENGTH_TYPE(C.sizeof_OCINumber)
53 | for n := range values {
54 | bnd.alen[n] = alen
55 | numbers := bnd.ociNumbers[n : n+1 : n+1] // against _cgoCheckPointer0
56 | if err := bnd.stmt.ses.srv.env.numberFromText(&numbers[0], string(values[n])); err != nil {
57 | return iterations, err
58 | }
59 | }
60 | ph, phLen, phFree := position.CString()
61 | if ph != nil {
62 | defer phFree()
63 | }
64 | r := C.bindByNameOrPos(
65 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
66 | &bnd.ocibnd,
67 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
68 | C.ub4(position.Ordinal), //ub4 position,
69 | ph,
70 | phLen,
71 | unsafe.Pointer(&bnd.ociNumbers[0]), //void *valuep,
72 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
73 | C.SQLT_VNU, //ub2 dty,
74 | unsafe.Pointer(&bnd.nullInds[0]), //void *indp,
75 | &bnd.alen[0], //ub4 *alenp,
76 | &bnd.rcode[0], //ub2 *rcodep,
77 | getMaxarrLen(C, isAssocArray), //ub4 maxarr_len,
78 | curlenp, //ub4 *curelep,
79 | C.OCI_DEFAULT) //ub4 mode );
80 | if r == C.OCI_ERROR {
81 | return iterations, bnd.stmt.ses.srv.env.ociError()
82 | }
83 | r = C.OCIBindArrayOfStruct(
84 | bnd.ocibnd,
85 | bnd.stmt.ses.srv.env.ocierr,
86 | C.ub4(C.sizeof_OCINumber), //ub4 pvskip,
87 | C.ub4(C.sizeof_sb2), //ub4 indskip,
88 | C.ub4(C.sizeof_ub4), //ub4 alskip,
89 | C.ub4(C.sizeof_ub2)) //ub4 rcskip
90 | if r == C.OCI_ERROR {
91 | return iterations, bnd.stmt.ses.srv.env.ociError()
92 | }
93 | return iterations, nil
94 | }
95 |
96 | func (bnd *bndNumStringSlice) setPtr() error {
97 | return nil
98 | }
99 |
100 | func (bnd *bndNumStringSlice) close() (err error) {
101 | defer func() {
102 | if value := recover(); value != nil {
103 | err = errR(value)
104 | }
105 | }()
106 |
107 | stmt := bnd.stmt
108 | bnd.stmt = nil
109 | bnd.ocibnd = nil
110 | bnd.ociNumbers = nil
111 | bnd.arrHlp.close()
112 | stmt.putBnd(bndIdxNumStringSlice, bnd)
113 | return nil
114 | }
115 |
--------------------------------------------------------------------------------
/bndOCINum.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 Tamás Gulácsi. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | // FromC converts from the given C.OCINumber.
16 | func (num *OCINum) FromC(x C.OCINumber) {
17 | a := *(*[22]byte)(unsafe.Pointer(&x))
18 | length := int(a[0])
19 | if length < 0 || length > 21 {
20 | num.OCINum = num.OCINum[:0]
21 | return
22 | }
23 |
24 | if cap(num.OCINum) < length {
25 | num.OCINum = make([]byte, length, 22-1)
26 | } else {
27 | num.OCINum = num.OCINum[:length]
28 | }
29 | copy(num.OCINum[:length], a[1:1+length])
30 | }
31 |
32 | // ToC converts the OCINum into the given *C.OCINumber.
33 | func (num OCINum) ToC(x *C.OCINumber) {
34 | a := ((*[22]byte)(unsafe.Pointer(x)))
35 | a[0] = byte(len(num.OCINum))
36 | copy(a[1:1+len(num.OCINum)], num.OCINum)
37 | for i := 1 + len(num.OCINum); i < 22; i++ {
38 | a[i] = 0
39 | }
40 | }
41 |
42 | type bndOCINum struct {
43 | stmt *Stmt
44 | ocibnd *C.OCIBind
45 | ociNumber [1]C.OCINumber
46 | }
47 |
48 | func (bnd *bndOCINum) bind(value OCINum, position namedPos, stmt *Stmt) error {
49 | bnd.stmt = stmt
50 | value.ToC(&bnd.ociNumber[0])
51 | ph, phLen, phFree := position.CString()
52 | if ph != nil {
53 | defer phFree()
54 | }
55 | r := C.bindByNameOrPos(
56 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
57 | &bnd.ocibnd,
58 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
59 | C.ub4(position.Ordinal), //ub4 position,
60 | ph,
61 | phLen,
62 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
63 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
64 | C.SQLT_VNU, //ub2 dty,
65 | nil, //void *indp,
66 | nil, //ub2 *alenp,
67 | nil, //ub2 *rcodep,
68 | 0, //ub4 maxarr_len,
69 | nil, //ub4 *curelep,
70 | C.OCI_DEFAULT) //ub4 mode );
71 | if r == C.OCI_ERROR {
72 | return bnd.stmt.ses.srv.env.ociError()
73 | }
74 | return nil
75 | }
76 |
77 | func (bnd *bndOCINum) setPtr() error {
78 | return nil
79 | }
80 |
81 | func (bnd *bndOCINum) close() (err error) {
82 | defer func() {
83 | if value := recover(); value != nil {
84 | err = errR(value)
85 | }
86 | }()
87 |
88 | stmt := bnd.stmt
89 | bnd.stmt = nil
90 | bnd.ocibnd = nil
91 | stmt.putBnd(bndIdxOCINum, bnd)
92 | return nil
93 | }
94 |
--------------------------------------------------------------------------------
/bndOCINumPtr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import "unsafe"
13 |
14 | type bndOCINumPtr struct {
15 | stmt *Stmt
16 | ocibnd *C.OCIBind
17 | ociNumber [1]C.OCINumber
18 | value *OCINum
19 | nullp
20 | }
21 |
22 | func (bnd *bndOCINumPtr) bind(value *OCINum, position namedPos, stmt *Stmt) error {
23 | bnd.stmt = stmt
24 | bnd.value = value
25 | bnd.nullp.Set(value == nil || value.IsNull())
26 | if value != nil && !value.IsNull() {
27 | value.ToC(&bnd.ociNumber[0])
28 | }
29 | ph, phLen, phFree := position.CString()
30 | if ph != nil {
31 | defer phFree()
32 | }
33 | r := C.bindByNameOrPos(
34 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
35 | &bnd.ocibnd,
36 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
37 | C.ub4(position.Ordinal), //ub4 position,
38 | ph,
39 | phLen,
40 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
41 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
42 | C.SQLT_VNU, //ub2 dty,
43 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
44 | nil, //ub2 *alenp,
45 | nil, //ub2 *rcodep,
46 | 0, //ub4 maxarr_len,
47 | nil, //ub4 *curelep,
48 | C.OCI_DEFAULT) //ub4 mode );
49 | if r == C.OCI_ERROR {
50 | return bnd.stmt.ses.srv.env.ociError()
51 | }
52 | return nil
53 | }
54 |
55 | func (bnd *bndOCINumPtr) setPtr() error {
56 | if bnd.nullp.IsNull() {
57 | return nil
58 | }
59 | bnd.value.FromC(bnd.ociNumber[0])
60 | return nil
61 | }
62 |
63 | func (bnd *bndOCINumPtr) close() (err error) {
64 | defer func() {
65 | if value := recover(); value != nil {
66 | err = errR(value)
67 | }
68 | }()
69 |
70 | stmt := bnd.stmt
71 | bnd.stmt = nil
72 | bnd.ocibnd = nil
73 | bnd.value = nil
74 | bnd.nullp.Free()
75 | stmt.putBnd(bndIdxOCINumPtr, bnd)
76 | return nil
77 | }
78 |
--------------------------------------------------------------------------------
/bndOCINumSlice.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 |
11 | */
12 | import "C"
13 | import (
14 | "unsafe"
15 | )
16 |
17 | type bndOCINumSlice struct {
18 | stmt *Stmt
19 | ocibnd *C.OCIBind
20 | ociNumbers []C.OCINumber
21 | arrHlp
22 | }
23 |
24 | func (bnd *bndOCINumSlice) bind(values []OCINum, nullInds []C.sb2, position namedPos, stmt *Stmt, isAssocArray bool) (iterations uint32, err error) {
25 | bnd.stmt = stmt
26 | L, C := len(values), cap(values)
27 | if nullInds != nil {
28 | bnd.nullInds = nullInds
29 | }
30 | iterations, curlenp, needAppend := bnd.ensureBindArrLength(&L, &C, isAssocArray)
31 | if needAppend {
32 | values = append(values, OCINum{})
33 | }
34 | bnd.ociNumbers = make([]C.OCINumber, len(values))
35 | alen := C.ACTUAL_LENGTH_TYPE(C.sizeof_OCINumber)
36 | for n := range values {
37 | bnd.alen[n] = alen
38 | values[n].ToC(&bnd.ociNumbers[n])
39 | }
40 | ph, phLen, phFree := position.CString()
41 | if ph != nil {
42 | defer phFree()
43 | }
44 | r := C.bindByNameOrPos(
45 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
46 | &bnd.ocibnd,
47 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
48 | C.ub4(position.Ordinal), //ub4 position,
49 | ph,
50 | phLen,
51 | unsafe.Pointer(&bnd.ociNumbers[0]), //void *valuep,
52 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
53 | C.SQLT_VNU, //ub2 dty,
54 | unsafe.Pointer(&bnd.nullInds[0]), //void *indp,
55 | &bnd.alen[0], //ub4 *alenp,
56 | &bnd.rcode[0], //ub2 *rcodep,
57 | getMaxarrLen(C, isAssocArray), //ub4 maxarr_len,
58 | curlenp, //ub4 *curelep,
59 | C.OCI_DEFAULT) //ub4 mode );
60 | if r == C.OCI_ERROR {
61 | return iterations, bnd.stmt.ses.srv.env.ociError()
62 | }
63 | r = C.OCIBindArrayOfStruct(
64 | bnd.ocibnd,
65 | bnd.stmt.ses.srv.env.ocierr,
66 | C.ub4(C.sizeof_OCINumber), //ub4 pvskip,
67 | C.ub4(C.sizeof_sb2), //ub4 indskip,
68 | C.ub4(C.sizeof_ub4), //ub4 alskip,
69 | C.ub4(C.sizeof_ub2)) //ub4 rcskip
70 | if r == C.OCI_ERROR {
71 | return iterations, bnd.stmt.ses.srv.env.ociError()
72 | }
73 | return iterations, nil
74 | }
75 |
76 | func (bnd *bndOCINumSlice) setPtr() error {
77 | return nil
78 | }
79 |
80 | func (bnd *bndOCINumSlice) close() (err error) {
81 | defer func() {
82 | if value := recover(); value != nil {
83 | err = errR(value)
84 | }
85 | }()
86 |
87 | stmt := bnd.stmt
88 | bnd.stmt = nil
89 | bnd.ocibnd = nil
90 | bnd.ociNumbers = nil
91 | bnd.arrHlp.close()
92 | stmt.putBnd(bndIdxOCINumSlice, bnd)
93 | return nil
94 | }
95 |
--------------------------------------------------------------------------------
/bndRset.go:
--------------------------------------------------------------------------------
1 | // Copyright 2017 The Ora Authors. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import (
13 | "unsafe"
14 | )
15 |
16 | type bndRset struct {
17 | stmt *Stmt
18 | ocibnd *C.OCIBind
19 | ocistmt [1]*C.OCIStmt
20 | value *Rset
21 | nullp
22 | }
23 |
24 | func (bnd *bndRset) bind(value *Rset, position namedPos, stmt *Stmt) error {
25 | bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind, "%p pos=%v", bnd, position)
26 |
27 | bnd.stmt = stmt
28 | bnd.value = value
29 | // Allocate a statement handle
30 | ocistmt, err := bnd.stmt.ses.srv.env.allocOciHandle(C.OCI_HTYPE_STMT)
31 | bnd.ocistmt[0] = (*C.OCIStmt)(ocistmt)
32 | if err != nil {
33 | return err
34 | }
35 | ph, phLen, phFree := position.CString()
36 | if ph != nil {
37 | defer phFree()
38 | }
39 | r := C.bindByNameOrPos(
40 | stmt.ocistmt, //OCIStmt *stmtp,
41 | &bnd.ocibnd,
42 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
43 | C.ub4(position.Ordinal), //ub4 position,
44 | ph,
45 | phLen,
46 | unsafe.Pointer(&bnd.ocistmt[0]), //void *valuep,
47 | 0, //sb8 value_sz,
48 | C.SQLT_RSET, //ub2 dty,
49 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
50 | nil, //ub2 *alenp,
51 | nil, //ub2 *rcodep,
52 | 0, //ub4 maxarr_len,
53 | nil, //ub4 *curelep,
54 | C.OCI_DEFAULT) //ub4 mode );
55 | if r == C.OCI_ERROR {
56 | return bnd.stmt.ses.srv.env.ociError()
57 | }
58 |
59 | return nil
60 | }
61 |
62 | func (bnd *bndRset) setPtr() error {
63 | if bnd.IsNull() || bnd.ocistmt[0] == nil {
64 | return nil
65 | }
66 | err := bnd.value.open(bnd.stmt, bnd.ocistmt[0])
67 | bnd.ocistmt[0] = nil
68 | if err != nil {
69 | if cerr, ok := err.(interface {
70 | Code() int
71 | }); ok && cerr.Code() == 24337 { // statement is not prepared
72 | bnd.value = nil
73 | return nil
74 | }
75 | return err
76 | }
77 | // open result set is successful; will be freed by Rset
78 | bnd.stmt.openRsets.add(bnd.value)
79 | return bnd.stmt.setPrefetchSize()
80 | }
81 |
82 | func (bnd *bndRset) close() (err error) {
83 | defer func() {
84 | if value := recover(); value != nil {
85 | err = errR(value)
86 | }
87 | }()
88 | stmt := bnd.stmt
89 | bnd.stmt = nil
90 | bnd.ocibnd = nil
91 | bnd.ocistmt[0] = nil
92 | bnd.value = nil
93 | bnd.nullp.Free()
94 | stmt.putBnd(bndIdxRset, bnd)
95 | return nil
96 | }
97 |
--------------------------------------------------------------------------------
/bndString.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import (
14 | "unsafe"
15 | )
16 |
17 | type bndString struct {
18 | stmt *Stmt
19 | ocibnd *C.OCIBind
20 | cString *C.char
21 | alen [1]C.ACTUAL_LENGTH_TYPE
22 | nullp
23 | }
24 |
25 | // https://ellebaek.wordpress.com/2011/02/25/oracle-type-code-mappings/
26 |
27 | func (bnd *bndString) bind(value string, position namedPos, stmt *Stmt) error {
28 | bnd.stmt = stmt
29 | bnd.cString = C.CString(value)
30 | bnd.alen[0] = C.ACTUAL_LENGTH_TYPE(len(value))
31 | bnd.nullp.Set(value == "")
32 | bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind,
33 | "%p pos=%v alen=%d",
34 | bnd, position, bnd.alen[0])
35 |
36 | ph, phLen, phFree := position.CString()
37 | if ph != nil {
38 | defer phFree()
39 | }
40 | r := C.bindByNameOrPos(
41 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
42 | &bnd.ocibnd, //OCIBind **bindpp,
43 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
44 | C.ub4(position.Ordinal), //ub4 position,
45 | ph,
46 | phLen,
47 | unsafe.Pointer(bnd.cString), //void *valuep,
48 | C.LENGTH_TYPE(len(value)), //sb8 value_sz,
49 | // http://www.devsuperpage.com/search/Articles.aspx?G=4&ArtID=560386
50 | // "You may find that trailing spaces are truncated when you use SQLT_CHR or SQLT_STR."
51 | C.SQLT_CHR, //ub2 dty,
52 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
53 | &bnd.alen[0], //ub2 *alenp,
54 | nil, //ub2 *rcodep,
55 | 0, //ub4 maxarr_len,
56 | nil, //ub4 *curelep,
57 | C.OCI_DEFAULT) //ub4 mode );
58 | if r == C.OCI_ERROR {
59 | return bnd.stmt.ses.srv.env.ociError()
60 | }
61 | return nil
62 | }
63 |
64 | func (bnd *bndString) setPtr() error {
65 | return nil
66 | }
67 |
68 | func (bnd *bndString) close() (err error) {
69 | defer func() {
70 | if value := recover(); value != nil {
71 | err = errR(value)
72 | }
73 | }()
74 | if bnd.cString != nil {
75 | C.free(unsafe.Pointer(bnd.cString))
76 | }
77 | stmt := bnd.stmt
78 | bnd.stmt = nil
79 | bnd.ocibnd = nil
80 | bnd.cString = nil
81 | stmt.putBnd(bndIdxString, bnd)
82 | return nil
83 | }
84 |
--------------------------------------------------------------------------------
/bndTime.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import (
14 | "time"
15 | "unsafe"
16 | )
17 |
18 | type bndTime struct {
19 | stmt *Stmt
20 | ocibnd *C.OCIBind
21 | dateTimep
22 | }
23 |
24 | func (bnd *bndTime) bind(value time.Time, position namedPos, stmt *Stmt) error {
25 | bnd.stmt = stmt
26 | if err := bnd.dateTimep.Set(bnd.stmt.ses.srv.env, value); err != nil {
27 | return err
28 | }
29 | ph, phLen, phFree := position.CString()
30 | if ph != nil {
31 | defer phFree()
32 | }
33 | r := C.bindByNameOrPos(
34 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
35 | &bnd.ocibnd, //OCIBind **bindpp,
36 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
37 | C.ub4(position.Ordinal), //ub4 position,
38 | ph,
39 | phLen,
40 | unsafe.Pointer(bnd.dateTimep.Pointer()), //void *valuep,
41 | C.LENGTH_TYPE(bnd.dateTimep.Size()), //sb8 value_sz,
42 | C.SQLT_TIMESTAMP_TZ, //ub2 dty,
43 | nil, //void *indp,
44 | nil, //ub2 *alenp,
45 | nil, //ub2 *rcodep,
46 | 0, //ub4 maxarr_len,
47 | nil, //ub4 *curelep,
48 | C.OCI_DEFAULT) //ub4 mode );
49 | if r == C.OCI_ERROR {
50 | return bnd.stmt.ses.srv.env.ociError()
51 | }
52 | return nil
53 | }
54 |
55 | func (bnd *bndTime) setPtr() (err error) {
56 | return nil
57 | }
58 |
59 | func (bnd *bndTime) close() (err error) {
60 | defer func() {
61 | if value := recover(); value != nil {
62 | err = errR(value)
63 | }
64 | }()
65 |
66 | bnd.dateTimep.Free()
67 | stmt := bnd.stmt
68 | bnd.stmt = nil
69 | bnd.ocibnd = nil
70 | stmt.putBnd(bndIdxTime, bnd)
71 | return nil
72 | }
73 |
--------------------------------------------------------------------------------
/bndTimePtr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import (
14 | "time"
15 | "unsafe"
16 | )
17 |
18 | type bndTimePtr struct {
19 | stmt *Stmt
20 | ocibnd *C.OCIBind
21 | value *time.Time
22 | dateTimep
23 | nullp
24 | }
25 |
26 | func (bnd *bndTimePtr) bind(value *time.Time, position namedPos, stmt *Stmt) error {
27 | bnd.stmt = stmt
28 | bnd.nullp.Set(value == nil || value.IsZero())
29 | if err := bnd.dateTimep.Alloc(bnd.stmt.ses.srv.env); err != nil {
30 | return err
31 | }
32 | bnd.value = value
33 | if value != nil {
34 | if err := bnd.dateTimep.Set(bnd.stmt.ses.srv.env, *value); err != nil {
35 | return err
36 | }
37 | }
38 | ph, phLen, phFree := position.CString()
39 | if ph != nil {
40 | defer phFree()
41 | }
42 | r := C.bindByNameOrPos(
43 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
44 | &bnd.ocibnd,
45 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
46 | C.ub4(position.Ordinal), //ub4 position,
47 | ph,
48 | phLen,
49 | unsafe.Pointer(bnd.dateTimep.Pointer()), //void *valuep,
50 | C.LENGTH_TYPE(bnd.dateTimep.Size()), //sb8 value_sz,
51 | C.SQLT_TIMESTAMP_TZ, //ub2 dty,
52 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
53 | nil, //ub2 *alenp,
54 | nil, //ub2 *rcodep,
55 | 0, //ub4 maxarr_len,
56 | nil, //ub4 *curelep,
57 | C.OCI_DEFAULT) //ub4 mode );
58 | if r == C.OCI_ERROR {
59 | return bnd.stmt.ses.srv.env.ociError()
60 | }
61 | return nil
62 | }
63 |
64 | func (bnd *bndTimePtr) setPtr() (err error) {
65 | if bnd.value == nil { // cannot set on a nil pointer
66 | return nil
67 | }
68 | if bnd.nullp.IsNull() {
69 | *bnd.value = time.Time{} // zero time
70 | return nil
71 | }
72 | *bnd.value, err = getTime(bnd.stmt.ses.srv.env, bnd.dateTimep.Value())
73 | return err
74 | }
75 |
76 | func (bnd *bndTimePtr) close() (err error) {
77 | defer func() {
78 | if value := recover(); value != nil {
79 | err = errR(value)
80 | }
81 | }()
82 |
83 | stmt := bnd.stmt
84 | bnd.stmt = nil
85 | bnd.ocibnd = nil
86 | bnd.value = nil
87 | bnd.dateTimep.Free()
88 | bnd.nullp.Free()
89 | stmt.putBnd(bndIdxTimePtr, bnd)
90 | return nil
91 | }
92 |
--------------------------------------------------------------------------------
/bndUint16.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import "unsafe"
13 |
14 | type bndUint16 struct {
15 | stmt *Stmt
16 | ocibnd *C.OCIBind
17 | ociNumber [1]C.OCINumber
18 | }
19 |
20 | func (bnd *bndUint16) bind(value uint16, position namedPos, stmt *Stmt) error {
21 | bnd.stmt = stmt
22 | r := C.OCINumberFromInt(
23 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
24 | unsafe.Pointer(&value), //const void *inum,
25 | byteWidth16, //uword inum_length,
26 | C.OCI_NUMBER_UNSIGNED, //uword inum_s_flag,
27 | &bnd.ociNumber[0]) //OCINumber *number );
28 | if r == C.OCI_ERROR {
29 | return bnd.stmt.ses.srv.env.ociError()
30 | }
31 | ph, phLen, phFree := position.CString()
32 | if ph != nil {
33 | defer phFree()
34 | }
35 | r = C.bindByNameOrPos(
36 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
37 | &bnd.ocibnd,
38 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
39 | C.ub4(position.Ordinal), //ub4 position,
40 | ph,
41 | phLen,
42 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
43 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
44 | C.SQLT_VNU, //ub2 dty,
45 | nil, //void *indp,
46 | nil, //ub2 *alenp,
47 | nil, //ub2 *rcodep,
48 | 0, //ub4 maxarr_len,
49 | nil, //ub4 *curelep,
50 | C.OCI_DEFAULT) //ub4 mode );
51 | if r == C.OCI_ERROR {
52 | return bnd.stmt.ses.srv.env.ociError()
53 | }
54 | return nil
55 | }
56 |
57 | func (bnd *bndUint16) setPtr() error {
58 | return nil
59 | }
60 |
61 | func (bnd *bndUint16) close() (err error) {
62 | defer func() {
63 | if value := recover(); value != nil {
64 | err = errR(value)
65 | }
66 | }()
67 |
68 | stmt := bnd.stmt
69 | bnd.stmt = nil
70 | bnd.ocibnd = nil
71 | stmt.putBnd(bndIdxUint16, bnd)
72 | return nil
73 | }
74 |
--------------------------------------------------------------------------------
/bndUint16Ptr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | type bndUint16Ptr struct {
16 | stmt *Stmt
17 | ocibnd *C.OCIBind
18 | ociNumber [1]C.OCINumber
19 | value *uint16
20 | valueIsNull *bool
21 | nullp
22 | }
23 |
24 | func (bnd *bndUint16Ptr) bind(value *uint16, valueIsNull *bool, position namedPos, stmt *Stmt) error {
25 | //bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind, "Uint16Ptr.bind(%d) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
26 | bnd.stmt = stmt
27 | bnd.value = value
28 | bnd.valueIsNull = valueIsNull
29 | bnd.nullp.Set(value == nil)
30 | if value != nil {
31 | if err := bnd.stmt.ses.srv.env.OCINumberFromInt(&bnd.ociNumber[0], int64(*value), byteWidth16); err != nil {
32 | return err
33 | }
34 | bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind,
35 | "Uint16Ptr.bind(%v) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
36 | }
37 | ph, phLen, phFree := position.CString()
38 | if ph != nil {
39 | defer phFree()
40 | }
41 | r := C.bindByNameOrPos(
42 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
43 | &bnd.ocibnd,
44 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
45 | C.ub4(position.Ordinal), //ub4 position,
46 | ph,
47 | phLen,
48 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
49 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
50 | C.SQLT_VNU, //ub2 dty,
51 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
52 | nil, //ub2 *alenp,
53 | nil, //ub2 *rcodep,
54 | 0, //ub4 maxarr_len,
55 | nil, //ub4 *curelep,
56 | C.OCI_DEFAULT) //ub4 mode );
57 | if r == C.OCI_ERROR {
58 | return bnd.stmt.ses.srv.env.ociError()
59 | }
60 | return nil
61 | }
62 |
63 | func (bnd *bndUint16Ptr) setPtr() error {
64 | if bnd.valueIsNull != nil {
65 | *bnd.valueIsNull = bnd.nullp.IsNull()
66 | }
67 | if bnd.nullp.IsNull() {
68 | return nil
69 | }
70 | i, err := bnd.stmt.ses.srv.env.OCINumberToInt(&bnd.ociNumber[0], byteWidth16)
71 | *bnd.value = uint16(i)
72 |
73 | return err
74 | }
75 |
76 | func (bnd *bndUint16Ptr) close() (err error) {
77 | defer func() {
78 | if value := recover(); value != nil {
79 | err = errR(value)
80 | }
81 | }()
82 |
83 | stmt := bnd.stmt
84 | bnd.stmt = nil
85 | bnd.ocibnd = nil
86 | bnd.value = nil
87 | bnd.valueIsNull = nil
88 | bnd.nullp.Free()
89 | stmt.putBnd(bndIdxUint16Ptr, bnd)
90 | return nil
91 | }
92 |
--------------------------------------------------------------------------------
/bndUint32.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import "unsafe"
13 |
14 | type bndUint32 struct {
15 | stmt *Stmt
16 | ocibnd *C.OCIBind
17 | ociNumber [1]C.OCINumber
18 | }
19 |
20 | func (bnd *bndUint32) bind(value uint32, position namedPos, stmt *Stmt) error {
21 | bnd.stmt = stmt
22 | r := C.OCINumberFromInt(
23 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
24 | unsafe.Pointer(&value), //const void *inum,
25 | byteWidth32, //uword inum_length,
26 | C.OCI_NUMBER_UNSIGNED, //uword inum_s_flag,
27 | &bnd.ociNumber[0]) //OCINumber *number );
28 | if r == C.OCI_ERROR {
29 | return bnd.stmt.ses.srv.env.ociError()
30 | }
31 | ph, phLen, phFree := position.CString()
32 | if ph != nil {
33 | defer phFree()
34 | }
35 | r = C.bindByNameOrPos(
36 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
37 | &bnd.ocibnd,
38 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
39 | C.ub4(position.Ordinal), //ub4 position,
40 | ph,
41 | phLen,
42 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
43 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
44 | C.SQLT_VNU, //ub2 dty,
45 | nil, //void *indp,
46 | nil, //ub2 *alenp,
47 | nil, //ub2 *rcodep,
48 | 0, //ub4 maxarr_len,
49 | nil, //ub4 *curelep,
50 | C.OCI_DEFAULT) //ub4 mode );
51 | if r == C.OCI_ERROR {
52 | return bnd.stmt.ses.srv.env.ociError()
53 | }
54 | return nil
55 | }
56 |
57 | func (bnd *bndUint32) setPtr() error {
58 | return nil
59 | }
60 |
61 | func (bnd *bndUint32) close() (err error) {
62 | defer func() {
63 | if value := recover(); value != nil {
64 | err = errR(value)
65 | }
66 | }()
67 |
68 | stmt := bnd.stmt
69 | bnd.stmt = nil
70 | bnd.ocibnd = nil
71 | stmt.putBnd(bndIdxUint32, bnd)
72 | return nil
73 | }
74 |
--------------------------------------------------------------------------------
/bndUint32Ptr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | type bndUint32Ptr struct {
16 | stmt *Stmt
17 | ocibnd *C.OCIBind
18 | ociNumber [1]C.OCINumber
19 | value *uint32
20 | valueIsNull *bool
21 | nullp
22 | }
23 |
24 | func (bnd *bndUint32Ptr) bind(value *uint32, valueIsNull *bool, position namedPos, stmt *Stmt) error {
25 | //bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind, "Uint32Ptr.bind(%d) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
26 | bnd.stmt = stmt
27 | bnd.value = value
28 | bnd.valueIsNull = valueIsNull
29 | bnd.nullp.Set(value == nil)
30 | if value != nil {
31 | if err := bnd.stmt.ses.srv.env.OCINumberFromInt(&bnd.ociNumber[0], int64(*value), byteWidth32); err != nil {
32 | return err
33 | }
34 | bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind,
35 | "Uint32Ptr.bind(%v) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
36 | }
37 | ph, phLen, phFree := position.CString()
38 | if ph != nil {
39 | defer phFree()
40 | }
41 | r := C.bindByNameOrPos(
42 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
43 | &bnd.ocibnd,
44 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
45 | C.ub4(position.Ordinal), //ub4 position,
46 | ph,
47 | phLen,
48 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
49 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
50 | C.SQLT_VNU, //ub2 dty,
51 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
52 | nil, //ub2 *alenp,
53 | nil, //ub2 *rcodep,
54 | 0, //ub4 maxarr_len,
55 | nil, //ub4 *curelep,
56 | C.OCI_DEFAULT) //ub4 mode );
57 | if r == C.OCI_ERROR {
58 | return bnd.stmt.ses.srv.env.ociError()
59 | }
60 | return nil
61 | }
62 |
63 | func (bnd *bndUint32Ptr) setPtr() error {
64 | if bnd.valueIsNull != nil {
65 | *bnd.valueIsNull = bnd.nullp.IsNull()
66 | }
67 | if bnd.nullp.IsNull() {
68 | return nil
69 | }
70 | i, err := bnd.stmt.ses.srv.env.OCINumberToInt(&bnd.ociNumber[0], byteWidth32)
71 | *bnd.value = uint32(i)
72 |
73 | return err
74 | }
75 |
76 | func (bnd *bndUint32Ptr) close() (err error) {
77 | defer func() {
78 | if value := recover(); value != nil {
79 | err = errR(value)
80 | }
81 | }()
82 |
83 | stmt := bnd.stmt
84 | bnd.stmt = nil
85 | bnd.ocibnd = nil
86 | bnd.value = nil
87 | bnd.valueIsNull = nil
88 | bnd.nullp.Free()
89 | stmt.putBnd(bndIdxUint32Ptr, bnd)
90 | return nil
91 | }
92 |
--------------------------------------------------------------------------------
/bndUint64.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import "unsafe"
13 |
14 | type bndUint64 struct {
15 | stmt *Stmt
16 | ocibnd *C.OCIBind
17 | ociNumber [1]C.OCINumber
18 | }
19 |
20 | func (bnd *bndUint64) bind(value uint64, position namedPos, stmt *Stmt) error {
21 | bnd.stmt = stmt
22 | r := C.OCINumberFromInt(
23 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
24 | unsafe.Pointer(&value), //const void *inum,
25 | byteWidth64, //uword inum_length,
26 | C.OCI_NUMBER_UNSIGNED, //uword inum_s_flag,
27 | &bnd.ociNumber[0]) //OCINumber *number );
28 | if r == C.OCI_ERROR {
29 | return bnd.stmt.ses.srv.env.ociError()
30 | }
31 | ph, phLen, phFree := position.CString()
32 | if ph != nil {
33 | defer phFree()
34 | }
35 | r = C.bindByNameOrPos(
36 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
37 | &bnd.ocibnd,
38 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
39 | C.ub4(position.Ordinal), //ub4 position,
40 | ph,
41 | phLen,
42 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
43 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
44 | C.SQLT_VNU, //ub2 dty,
45 | nil, //void *indp,
46 | nil, //ub2 *alenp,
47 | nil, //ub2 *rcodep,
48 | 0, //ub4 maxarr_len,
49 | nil, //ub4 *curelep,
50 | C.OCI_DEFAULT) //ub4 mode );
51 | if r == C.OCI_ERROR {
52 | return bnd.stmt.ses.srv.env.ociError()
53 | }
54 | return nil
55 | }
56 |
57 | func (bnd *bndUint64) setPtr() error {
58 | return nil
59 | }
60 |
61 | func (bnd *bndUint64) close() (err error) {
62 | defer func() {
63 | if value := recover(); value != nil {
64 | err = errR(value)
65 | }
66 | }()
67 |
68 | stmt := bnd.stmt
69 | bnd.stmt = nil
70 | bnd.ocibnd = nil
71 | stmt.putBnd(bndIdxUint64, bnd)
72 | return nil
73 | }
74 |
--------------------------------------------------------------------------------
/bndUint64Ptr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | type bndUint64Ptr struct {
16 | stmt *Stmt
17 | ocibnd *C.OCIBind
18 | ociNumber [1]C.OCINumber
19 | value *uint64
20 | valueIsNull *bool
21 | nullp
22 | }
23 |
24 | func (bnd *bndUint64Ptr) bind(value *uint64, valueIsNull *bool, position namedPos, stmt *Stmt) error {
25 | //bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind, "Uint64Ptr.bind(%d) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
26 | bnd.stmt = stmt
27 | bnd.value = value
28 | bnd.valueIsNull = valueIsNull
29 | bnd.nullp.Set(value == nil)
30 | if value != nil {
31 | if err := bnd.stmt.ses.srv.env.OCINumberFromInt(&bnd.ociNumber[0], intSixtyFour(*value), byteWidth64); err != nil {
32 | return err
33 | }
34 | bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind,
35 | "Uint64Ptr.bind(%v) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
36 | }
37 | ph, phLen, phFree := position.CString()
38 | if ph != nil {
39 | defer phFree()
40 | }
41 | r := C.bindByNameOrPos(
42 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
43 | &bnd.ocibnd,
44 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
45 | C.ub4(position.Ordinal), //ub4 position,
46 | ph,
47 | phLen,
48 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
49 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
50 | C.SQLT_VNU, //ub2 dty,
51 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
52 | nil, //ub2 *alenp,
53 | nil, //ub2 *rcodep,
54 | 0, //ub4 maxarr_len,
55 | nil, //ub4 *curelep,
56 | C.OCI_DEFAULT) //ub4 mode );
57 | if r == C.OCI_ERROR {
58 | return bnd.stmt.ses.srv.env.ociError()
59 | }
60 | return nil
61 | }
62 |
63 | func (bnd *bndUint64Ptr) setPtr() error {
64 | if bnd.valueIsNull != nil {
65 | *bnd.valueIsNull = bnd.nullp.IsNull()
66 | }
67 | if bnd.nullp.IsNull() {
68 | return nil
69 | }
70 | i, err := bnd.stmt.ses.srv.env.OCINumberToInt(&bnd.ociNumber[0], byteWidth64)
71 | *bnd.value = uint64(i)
72 |
73 | return err
74 | }
75 |
76 | func (bnd *bndUint64Ptr) close() (err error) {
77 | defer func() {
78 | if value := recover(); value != nil {
79 | err = errR(value)
80 | }
81 | }()
82 |
83 | stmt := bnd.stmt
84 | bnd.stmt = nil
85 | bnd.ocibnd = nil
86 | bnd.value = nil
87 | bnd.valueIsNull = nil
88 | bnd.nullp.Free()
89 | stmt.putBnd(bndIdxUint64Ptr, bnd)
90 | return nil
91 | }
92 |
--------------------------------------------------------------------------------
/bndUint8.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import "unsafe"
13 |
14 | type bndUint8 struct {
15 | stmt *Stmt
16 | ocibnd *C.OCIBind
17 | ociNumber [1]C.OCINumber
18 | }
19 |
20 | func (bnd *bndUint8) bind(value uint8, position namedPos, stmt *Stmt) error {
21 | bnd.stmt = stmt
22 | r := C.OCINumberFromInt(
23 | bnd.stmt.ses.srv.env.ocierr, //OCIError *err,
24 | unsafe.Pointer(&value), //const void *inum,
25 | byteWidth8, //uword inum_length,
26 | C.OCI_NUMBER_UNSIGNED, //uword inum_s_flag,
27 | &bnd.ociNumber[0]) //OCINumber *number );
28 | if r == C.OCI_ERROR {
29 | return bnd.stmt.ses.srv.env.ociError()
30 | }
31 | ph, phLen, phFree := position.CString()
32 | if ph != nil {
33 | defer phFree()
34 | }
35 | r = C.bindByNameOrPos(
36 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
37 | &bnd.ocibnd,
38 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
39 | C.ub4(position.Ordinal), //ub4 position,
40 | ph,
41 | phLen,
42 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
43 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
44 | C.SQLT_VNU, //ub2 dty,
45 | nil, //void *indp,
46 | nil, //ub2 *alenp,
47 | nil, //ub2 *rcodep,
48 | 0, //ub4 maxarr_len,
49 | nil, //ub4 *curelep,
50 | C.OCI_DEFAULT) //ub4 mode );
51 | if r == C.OCI_ERROR {
52 | return bnd.stmt.ses.srv.env.ociError()
53 | }
54 | return nil
55 | }
56 |
57 | func (bnd *bndUint8) setPtr() error {
58 | return nil
59 | }
60 |
61 | func (bnd *bndUint8) close() (err error) {
62 | defer func() {
63 | if value := recover(); value != nil {
64 | err = errR(value)
65 | }
66 | }()
67 |
68 | stmt := bnd.stmt
69 | bnd.stmt = nil
70 | bnd.ocibnd = nil
71 | stmt.putBnd(bndIdxUint8, bnd)
72 | return nil
73 | }
74 |
--------------------------------------------------------------------------------
/bndUint8Ptr.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | type bndUint8Ptr struct {
16 | stmt *Stmt
17 | ocibnd *C.OCIBind
18 | ociNumber [1]C.OCINumber
19 | value *uint8
20 | valueIsNull *bool
21 | nullp
22 | }
23 |
24 | func (bnd *bndUint8Ptr) bind(value *uint8, valueIsNull *bool, position namedPos, stmt *Stmt) error {
25 | //bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind, "Uint8Ptr.bind(%d) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
26 | bnd.stmt = stmt
27 | bnd.value = value
28 | bnd.valueIsNull = valueIsNull
29 | bnd.nullp.Set(value == nil)
30 | if value != nil {
31 | if err := bnd.stmt.ses.srv.env.OCINumberFromInt(&bnd.ociNumber[0], int64(*value), byteWidth8); err != nil {
32 | return err
33 | }
34 | bnd.stmt.logF(_drv.Cfg().Log.Stmt.Bind,
35 | "Uint8Ptr.bind(%v) value=%#v => number=%#v", position, value, bnd.ociNumber[0])
36 | }
37 | ph, phLen, phFree := position.CString()
38 | if ph != nil {
39 | defer phFree()
40 | }
41 | r := C.bindByNameOrPos(
42 | bnd.stmt.ocistmt, //OCIStmt *stmtp,
43 | &bnd.ocibnd,
44 | bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp,
45 | C.ub4(position.Ordinal), //ub4 position,
46 | ph,
47 | phLen,
48 | unsafe.Pointer(&bnd.ociNumber[0]), //void *valuep,
49 | C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz,
50 | C.SQLT_VNU, //ub2 dty,
51 | unsafe.Pointer(bnd.nullp.Pointer()), //void *indp,
52 | nil, //ub2 *alenp,
53 | nil, //ub2 *rcodep,
54 | 0, //ub4 maxarr_len,
55 | nil, //ub4 *curelep,
56 | C.OCI_DEFAULT) //ub4 mode );
57 | if r == C.OCI_ERROR {
58 | return bnd.stmt.ses.srv.env.ociError()
59 | }
60 | return nil
61 | }
62 |
63 | func (bnd *bndUint8Ptr) setPtr() error {
64 | if bnd.valueIsNull != nil {
65 | *bnd.valueIsNull = bnd.nullp.IsNull()
66 | }
67 | if bnd.nullp.IsNull() {
68 | return nil
69 | }
70 | i, err := bnd.stmt.ses.srv.env.OCINumberToInt(&bnd.ociNumber[0], byteWidth8)
71 | *bnd.value = uint8(i)
72 |
73 | return err
74 | }
75 |
76 | func (bnd *bndUint8Ptr) close() (err error) {
77 | defer func() {
78 | if value := recover(); value != nil {
79 | err = errR(value)
80 | }
81 | }()
82 |
83 | stmt := bnd.stmt
84 | bnd.stmt = nil
85 | bnd.ocibnd = nil
86 | bnd.value = nil
87 | bnd.valueIsNull = nil
88 | bnd.nullp.Free()
89 | stmt.putBnd(bndIdxUint8Ptr, bnd)
90 | return nil
91 | }
92 |
--------------------------------------------------------------------------------
/conn_go1_7.go:
--------------------------------------------------------------------------------
1 | // +build !go1.8
2 |
3 | // Copyright 2017 Tamás Gulácsi. All rights reserved.
4 | // Use of this source code is governed by The MIT License
5 | // found in the accompanying LICENSE file.
6 |
7 | package ora
8 |
9 | import "database/sql/driver"
10 |
11 | // Prepare readies a sql string for use.
12 | //
13 | // Prepare is a member of the driver.Conn interface.
14 | func (con *Con) Prepare(query string) (driver.Stmt, error) {
15 | con.log(_drv.Cfg().Log.Con.Prepare)
16 | if err := con.checkIsOpen(); err != nil {
17 | return nil, err
18 | }
19 | stmt, err := con.ses.Prep(query)
20 | if err != nil {
21 | return nil, maybeBadConn(err)
22 | }
23 | return &DrvStmt{stmt: stmt}, err
24 | }
25 |
--------------------------------------------------------------------------------
/conn_go1_8.go:
--------------------------------------------------------------------------------
1 | // +build go1.8
2 |
3 | // Copyright 2017 Tamás Gulácsi. All rights reserved.
4 | // Use of this source code is governed by The MIT License
5 | // found in the accompanying LICENSE file.
6 |
7 | package ora
8 |
9 | import (
10 | "context"
11 | "database/sql"
12 | "database/sql/driver"
13 | "fmt"
14 | )
15 |
16 | /*
17 | #include
18 | */
19 | import "C"
20 |
21 | var (
22 | // Ensure that Con implements the needed ...Context interfaces.
23 | _ = driver.Conn((*Con)(nil))
24 | _ = driver.ConnBeginTx((*Con)(nil))
25 | _ = driver.ConnPrepareContext((*Con)(nil))
26 | _ = driver.Pinger((*Con)(nil))
27 |
28 | // Ensure that DrvStmt implements the needed ...Context interfaces.
29 | _ = driver.Stmt((*DrvStmt)(nil))
30 | _ = driver.StmtQueryContext((*DrvStmt)(nil))
31 | _ = driver.StmtExecContext((*DrvStmt)(nil))
32 | )
33 |
34 | // Prepare readies a sql string for use.
35 | //
36 | // Prepare is a member of the driver.Conn interface.
37 | func (con *Con) Prepare(query string) (driver.Stmt, error) {
38 | return con.PrepareContext(context.Background(), query)
39 | }
40 |
41 | // PrepareContext returns a prepared statement, bound to this connection.
42 | // context is for the preparation of the statement,
43 | // it must not store the context within the statement itself.
44 | func (con *Con) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
45 | con.log(_drv.Cfg().Log.Con.Prepare)
46 | if err := con.checkIsOpen(); err != nil {
47 | return nil, err
48 | }
49 | stmt, err := con.ses.Prep(query)
50 | if err != nil {
51 | return nil, maybeBadConn(err)
52 | }
53 | return &DrvStmt{stmt: stmt}, err
54 | }
55 |
56 | // BeginTx starts and returns a new transaction.
57 | // The provided context should be used to roll the transaction back
58 | // if it is cancelled.
59 | //
60 | // If the driver does not support setting the isolation
61 | // level and one is set or if there is a set isolation level
62 | // but the set level is not supported, an error must be returned.
63 | //
64 | // If the read-only value is true to either
65 | // set the read-only transaction property if supported
66 | // or return an error if it is not supported.
67 | func (con *Con) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
68 | if err := ctx.Err(); err != nil {
69 | return nil, err
70 | }
71 | var flags C.ub4
72 | if opts.ReadOnly {
73 | flags |= C.OCI_TRANS_READONLY
74 | }
75 | switch level := sql.IsolationLevel(opts.Isolation); level {
76 | case sql.LevelDefault, sql.LevelReadCommitted:
77 | // this is the default level
78 | case sql.LevelSerializable:
79 | flags |= C.OCI_TRANS_SERIALIZABLE
80 | default:
81 | return nil, fmt.Errorf("Isolation level %v not supported.", level)
82 | }
83 | con.log(_drv.Cfg().Log.Con.Begin)
84 | if err := con.checkIsOpen(); err != nil {
85 | return nil, err
86 | }
87 | var tx *Tx
88 | done := make(chan error, 1)
89 | go func() {
90 | defer close(done)
91 | var err error
92 | tx, err = con.ses.StartTx(TxFlags(uint32(flags)))
93 | done <- err
94 | }()
95 | var err error
96 | select {
97 | case err = <-done:
98 | return tx, err
99 | case <-ctx.Done():
100 | // select again to avoid race condition if both are done
101 | select {
102 | case err = <-done:
103 | return tx, err
104 | default:
105 | if err = ctx.Err(); isCanceled(err) {
106 | con.ses.Break()
107 | }
108 | }
109 | }
110 | return nil, maybeBadConn(err)
111 | }
112 |
113 | // vim: set fileencoding=utf-8 noet:
114 |
--------------------------------------------------------------------------------
/contrib/oci8.pc:
--------------------------------------------------------------------------------
1 | oci8_linux_amd64.pc
--------------------------------------------------------------------------------
/contrib/oci8_darwin.pc:
--------------------------------------------------------------------------------
1 | prefix=/Users/dfils/src/oracle/instantclient_12_1
2 |
3 | version=12.1
4 | build=client64
5 |
6 | libdir=${prefix}
7 | includedir=${prefix}/sdk/include
8 |
9 | Name: oci8
10 | Description: Oracle database engine
11 | Version: ${version}
12 | Libs: -L${libdir} -lclntsh
13 | Libs.private:
14 | Cflags: -I${includedir}
15 |
--------------------------------------------------------------------------------
/contrib/oci8_linux_386.pc:
--------------------------------------------------------------------------------
1 | prefix=/usr
2 |
3 | version=12.1
4 | build=client32
5 |
6 | libdir=${prefix}/lib/oracle/${version}/${build}/lib
7 | includedir=${prefix}/include/oracle/${version}/${build}
8 |
9 | Name: oci8
10 | Description: Oracle database engine
11 | Version: ${version}
12 | Libs: -L${libdir} -lclntsh
13 | Libs.private:
14 | Cflags: -I${includedir}
15 |
--------------------------------------------------------------------------------
/contrib/oci8_linux_amd64.pc:
--------------------------------------------------------------------------------
1 | prefix=/usr
2 |
3 | version=12.1
4 | build=client64
5 |
6 | libdir=${prefix}/lib/oracle/${version}/${build}/lib
7 | includedir=${prefix}/include/oracle/${version}/${build}
8 |
9 | Name: oci8
10 | Description: Oracle database engine
11 | Version: ${version}
12 | Libs: -L${libdir} -lclntsh
13 | Libs.private:
14 | Cflags: -I${includedir}
15 |
--------------------------------------------------------------------------------
/contrib/oci8_windows_amd64.pc:
--------------------------------------------------------------------------------
1 | prefix=c:/Oracle64Instant/sdk
2 |
3 | version=12.1
4 | build=client64
5 |
6 | libdir=${prefix}/lib
7 | includedir=${prefix}/include
8 |
9 | glib_genmarshal=glib-genmarshal
10 | gobject_query=gobject-query
11 | glib_mkenums=glib-mkenums
12 |
13 | Name: oci8
14 | Description: Oracle database engine
15 | Version: ${version}
16 | Libs: -L${libdir} -loci
17 | Libs.private:
18 | Cflags: -I${includedir}
19 |
--------------------------------------------------------------------------------
/contrib/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | output="$(gofmt -l "$@")"
5 |
6 | if [ -n "$output" ]; then
7 | echo >&2 "Go files must be formatted with gofmt. Please run:"
8 | for f in $output; do
9 | echo >&2 " gofmt -w $PWD/$f"
10 | done
11 | exit 1
12 | fi
13 |
14 | #--enable=vetshadow \
15 | gometalinter --vendor --disable-all \
16 | --enable=deadcode \
17 | --enable=ineffassign \
18 | --enable=gosimple \
19 | --enable=staticcheck \
20 | --enable=unused \
21 | -e 'z_.*_test' \
22 | ./...
23 |
--------------------------------------------------------------------------------
/ctx.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 Tamás Gulácsi. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | import "context"
8 |
9 | const (
10 | stmtCfgKey = "stmtCfg"
11 | )
12 |
13 | // ctxStmtCfg returns the StmtCfg from the context, and
14 | // whether it exist at all.
15 | func ctxStmtCfg(ctx context.Context) (StmtCfg, bool) {
16 | cfg, ok := ctx.Value(stmtCfgKey).(StmtCfg)
17 | return cfg, ok
18 | }
19 |
20 | // WithStmtCfg returns a new context, with the given cfg that
21 | // can be used to configure several parameters.
22 | //
23 | // WARNING: the StmtCfg must be derived from Cfg(), or NewStmtCfg(),
24 | // as an empty StmtCfg is not usable!
25 | func WithStmtCfg(ctx context.Context, cfg StmtCfg) context.Context {
26 | return context.WithValue(ctx, stmtCfgKey, cfg)
27 | }
28 |
--------------------------------------------------------------------------------
/date/date.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 Tamás Gulácsi. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | // Package date implements encoding of 7 byte Oracle DATE storage formats.
6 | package date
7 |
8 | import (
9 | "bytes"
10 | "encoding/json"
11 | "fmt"
12 | "time"
13 | )
14 |
15 | // Date is an OCIDate
16 | //
17 | // SQLT_ODT: 7 bytes
18 | //
19 | // http://www.orafaq.com/wiki/Date
20 | //
21 | /*
22 | The internal format is the following one:
23 |
24 | century + 100
25 | year in the century + 100
26 | month
27 | day
28 | hour + 1
29 | minute + 1
30 | second + 1
31 |
32 | So in the previous example the date was 19-DEC-2007 at 22:35:10.
33 | */
34 | type Date [7]byte
35 |
36 | func (dt *Date) Set(t time.Time) {
37 | if t.IsZero() {
38 | for i := range dt[:] {
39 | dt[i] = 0
40 | }
41 | return
42 | }
43 | y := t.Year()
44 | if y < -4711 {
45 | y = -4711
46 | } else if y > 9999 {
47 | y = 9999
48 | }
49 | dt[0] = byte(y/100 + 100)
50 | dt[1] = byte(y%100 + 100)
51 | dt[2] = byte(t.Month())
52 | dt[3] = byte(t.Day())
53 | dt[4] = byte(t.Hour() + 1)
54 | dt[5] = byte(t.Minute() + 1)
55 | dt[6] = byte(t.Second() + 1)
56 | }
57 |
58 | func (dt Date) Bytes() []byte {
59 | return dt[:]
60 | }
61 |
62 | func (dt Date) IsNull() bool {
63 | for _, b := range dt[:] {
64 | if b != 0 {
65 | return false
66 | }
67 | }
68 | return true
69 | }
70 | func (dt Date) MarshalJSON() ([]byte, error) {
71 | if dt.IsNull() {
72 | return []byte("null"), nil
73 | }
74 | return dt.Get().MarshalJSON()
75 | }
76 | func (dt *Date) UnmarshalJSON(p []byte) error {
77 | if bytes.Equal(p, []byte("null")) || bytes.Equal(p, []byte(`""`)) {
78 | for i := range dt[:] {
79 | dt[i] = 0
80 | }
81 | return nil
82 | }
83 | var t time.Time
84 | if err := json.Unmarshal(p, &t); err != nil {
85 | return err
86 | }
87 | dt.Set(t)
88 | return nil
89 | }
90 |
91 | // FromTime returns a Date from a time.Time
92 | // Does the allocation inside, so easier to use.
93 | func FromTime(t time.Time) Date {
94 | var dt Date
95 | dt.Set(t)
96 | return dt
97 | }
98 |
99 | func (dt Date) Equal(other Date) bool {
100 | return bytes.Equal(dt[:], other[:])
101 | }
102 |
103 | func (dt Date) String() string {
104 | if dt.IsNull() {
105 | return (time.Time{}).Format("2006-01-02T15:04:05")
106 | }
107 | return fmt.Sprintf("%04d-%02d-%02dT%02d:%02d:%02d",
108 | (int(dt[0])-100)*100+(int(dt[1])-100),
109 | time.Month(dt[2]),
110 | int(dt[3]),
111 | int(dt[4]-1),
112 | int(dt[5]-1),
113 | int(dt[6]-1),
114 | )
115 | }
116 |
117 | func (dt Date) Get() time.Time {
118 | return dt.GetIn(nil)
119 | }
120 | func (dt Date) GetIn(zone *time.Location) time.Time {
121 | if dt.IsNull() {
122 | return time.Time{}
123 | }
124 | if zone == nil {
125 | zone = time.Local
126 | }
127 | return time.Date(
128 | (int(dt[0])-100)*100+(int(dt[1])-100),
129 | time.Month(dt[2]),
130 | int(dt[3]),
131 | int(dt[4]-1),
132 | int(dt[5]-1),
133 | int(dt[6]-1),
134 | 0,
135 | zone,
136 | )
137 | }
138 |
--------------------------------------------------------------------------------
/date/date_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 Tamás Gulácsi. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package date_test
6 |
7 | import (
8 | "bytes"
9 | "testing"
10 |
11 | "gopkg.in/rana/ora.v4/date"
12 | )
13 |
14 | func TestDate(t *testing.T) {
15 | format := "2006-01-02T15:04:05"
16 | dt := new(date.Date)
17 | for tN, tC := range dateTestData {
18 | tim := date.Date(tC.B).Get()
19 | if got := tim.Format(format); got != tC.S {
20 | t.Errorf("%d. got %q, want %q (from %v).", tN, got, tC.S, tC.B)
21 | continue
22 | }
23 | dt.Set(tim)
24 | if !bytes.Equal(dt[:], tC.B[:]) {
25 | t.Errorf("%d. got %v, want %v (from %q).", tN, dt[:], tC.B[:], tC.S)
26 | }
27 | }
28 | }
29 | func TestNull(t *testing.T) {
30 | var dt date.Date
31 | t.Log(dt.String())
32 | if !dt.IsNull() {
33 | t.Errorf("want NULL, got %t for %#v", dt.IsNull(), dt)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/date/date_test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | export ORACLE_HOME=${ORACLE_HOME:-/u01/app/oracle/product/11.2.0/xe}
3 | set -x
4 | {
5 | cat <date_gen_test.go
27 |
--------------------------------------------------------------------------------
/defBool.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import (
14 | "unicode/utf8"
15 | "unsafe"
16 | )
17 |
18 | type defBool struct {
19 | ociDef
20 | isNullable bool
21 | columnSize int
22 | buf []byte
23 | }
24 |
25 | func (def *defBool) define(position int, columnSize int, isNullable bool, rset *Rset) error {
26 | def.rset = rset
27 | def.isNullable = isNullable
28 | def.columnSize = columnSize
29 | if n := rset.fetchLen * columnSize; cap(def.buf) < n {
30 | //def.buf = make([]byte, n)
31 | def.buf = bytesPool.Get(n)
32 | } else {
33 | def.buf = def.buf[:n]
34 | }
35 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.buf[0]), columnSize, C.SQLT_AFC)
36 | }
37 |
38 | func (def *defBool) value(offset int) (value interface{}, err error) {
39 | if def.nullInds[offset] < 0 {
40 | if def.isNullable {
41 | return Bool{IsNull: true}, nil
42 | }
43 | return nil, nil
44 | }
45 | //Log.Infof("%v.value", def)
46 | buf := def.buf[offset*def.columnSize : (offset+1)*def.columnSize]
47 | if def.isNullable {
48 | r, _ := utf8.DecodeRune(buf)
49 | return Bool{Value: r == def.rset.stmt.Cfg().TrueRune}, nil
50 | }
51 | r, _ := utf8.DecodeRune(buf)
52 | return r == def.rset.stmt.Cfg().TrueRune, nil
53 | }
54 |
55 | func (def *defBool) alloc() error {
56 | return nil
57 | }
58 |
59 | func (def *defBool) free() {
60 | if def.buf != nil {
61 | bytesPool.Put(def.buf)
62 | def.buf = nil
63 | }
64 | def.arrHlp.close()
65 | }
66 |
67 | func (def *defBool) close() (err error) {
68 | defer func() {
69 | if value := recover(); value != nil {
70 | err = errR(value)
71 | }
72 | }()
73 |
74 | def.free()
75 | rset := def.rset
76 | def.rset = nil
77 | def.ocidef = nil
78 | rset.putDef(defIdxBool, def)
79 | return nil
80 | }
81 |
--------------------------------------------------------------------------------
/defDate.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import (
14 | "time"
15 | "unsafe"
16 |
17 | "gopkg.in/rana/ora.v4/date"
18 | )
19 |
20 | type defDate struct {
21 | ociDef
22 | ociDate []date.Date
23 | isNullable bool
24 | timezone *time.Location
25 | }
26 |
27 | func (def *defDate) define(position int, isNullable bool, rset *Rset) error {
28 | var err error
29 | if def.timezone, err = rset.stmt.ses.Timezone(); err != nil {
30 | return err
31 | }
32 | def.rset = rset
33 | def.isNullable = isNullable
34 | if def.ociDate != nil {
35 | C.free(unsafe.Pointer(&def.ociDate[0]))
36 | }
37 | def.ociDate = (*((*[MaxFetchLen]date.Date)(C.malloc(C.size_t(rset.fetchLen) * 7))))[:rset.fetchLen]
38 |
39 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ociDate[0]), 7, C.SQLT_DAT)
40 | }
41 |
42 | func (def *defDate) value(offset int) (value interface{}, err error) {
43 | if def.nullInds[offset] < 0 {
44 | if def.isNullable {
45 | return Time{IsNull: true}, nil
46 | }
47 | return nil, nil
48 | }
49 | if def.isNullable {
50 | return Time{Value: def.ociDate[offset].GetIn(def.timezone)}, nil
51 | }
52 | return def.ociDate[offset].GetIn(def.timezone), nil
53 | }
54 |
55 | func (def *defDate) alloc() error { return nil }
56 | func (def *defDate) free() {
57 | if def.ociDate != nil {
58 | C.free(unsafe.Pointer(&def.ociDate[0]))
59 | def.ociDate = nil
60 | }
61 | def.arrHlp.close()
62 | }
63 |
64 | func (def *defDate) close() (err error) {
65 | defer func() {
66 | if value := recover(); value != nil {
67 | err = errR(value)
68 | }
69 | }()
70 |
71 | rset := def.rset
72 | def.rset = nil
73 | def.ocidef = nil
74 | def.free()
75 | rset.putDef(defIdxDate, def)
76 | return nil
77 | }
78 |
--------------------------------------------------------------------------------
/defFloat32.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | // defFloat32.go is generated from defFloat32.go!
16 |
17 | type defFloat32 struct {
18 | ociDef
19 | ociNumber []C.OCINumber
20 | isNullable bool
21 | }
22 |
23 | func (def *defFloat32) define(position int, isNullable bool, rset *Rset) error {
24 | def.rset = rset
25 | def.isNullable = isNullable
26 | if def.ociNumber != nil {
27 | C.free(unsafe.Pointer(&def.ociNumber[0]))
28 | }
29 | def.ociNumber = (*((*[MaxFetchLen]C.OCINumber)(C.malloc(C.size_t(rset.fetchLen) * C.sizeof_OCINumber))))[:rset.fetchLen]
30 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ociNumber[0]), C.sizeof_OCINumber, C.SQLT_VNU)
31 | }
32 |
33 | func (def *defFloat32) value(offset int) (value interface{}, err error) {
34 | if def.nullInds[offset] < 0 {
35 | if def.isNullable {
36 | return Float32{IsNull: true}, nil
37 | }
38 | return nil, nil
39 | }
40 | var float32Value float32
41 | on := def.ociNumber[offset]
42 | r := C.OCINumberToReal(
43 | def.rset.stmt.ses.srv.env.ocierr, //OCIError *err,
44 | &on, //const OCINumber *number,
45 | byteWidth32, //uword rsl_length,
46 | unsafe.Pointer(&float32Value)) //void *rsl );
47 | if r == C.OCI_ERROR {
48 | err = def.rset.stmt.ses.srv.env.ociError()
49 | }
50 | //fmt.Printf("%d. %#v = %#v\n", offset, on, float32Value)
51 | if def.isNullable {
52 | return Float32{Value: float32Value}, err
53 | }
54 | return float32Value, err
55 | }
56 |
57 | func (def *defFloat32) alloc() error {
58 | return nil
59 | }
60 |
61 | func (def *defFloat32) free() {
62 | def.arrHlp.close()
63 | }
64 |
65 | func (def *defFloat32) close() (err error) {
66 | defer func() {
67 | if value := recover(); value != nil {
68 | err = errR(value)
69 | }
70 | }()
71 |
72 | rset := def.rset
73 | def.rset = nil
74 | def.ocidef = nil
75 | if def.ociNumber != nil {
76 | C.free(unsafe.Pointer(&def.ociNumber[0]))
77 | def.ociNumber = nil
78 | }
79 | rset.putDef(defIdxFloat32, def)
80 | return nil
81 | }
82 |
--------------------------------------------------------------------------------
/defFloat64.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | // defFloat32.go is generated from defFloat64.go!
16 |
17 | type defFloat64 struct {
18 | ociDef
19 | ociNumber []C.OCINumber
20 | isNullable bool
21 | }
22 |
23 | func (def *defFloat64) define(position int, isNullable bool, rset *Rset) error {
24 | def.rset = rset
25 | def.isNullable = isNullable
26 | if def.ociNumber != nil {
27 | C.free(unsafe.Pointer(&def.ociNumber[0]))
28 | }
29 | def.ociNumber = (*((*[MaxFetchLen]C.OCINumber)(C.malloc(C.size_t(rset.fetchLen) * C.sizeof_OCINumber))))[:rset.fetchLen]
30 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ociNumber[0]), C.sizeof_OCINumber, C.SQLT_VNU)
31 | }
32 |
33 | func (def *defFloat64) value(offset int) (value interface{}, err error) {
34 | if def.nullInds[offset] < 0 {
35 | if def.isNullable {
36 | return Float64{IsNull: true}, nil
37 | }
38 | return nil, nil
39 | }
40 | var float64Value float64
41 | on := def.ociNumber[offset]
42 | r := C.OCINumberToReal(
43 | def.rset.stmt.ses.srv.env.ocierr, //OCIError *err,
44 | &on, //const OCINumber *number,
45 | byteWidth64, //uword rsl_length,
46 | unsafe.Pointer(&float64Value)) //void *rsl );
47 | if r == C.OCI_ERROR {
48 | err = def.rset.stmt.ses.srv.env.ociError()
49 | }
50 | //fmt.Printf("%d. %#v = %#v\n", offset, on, float64Value)
51 | if def.isNullable {
52 | return Float64{Value: float64Value}, err
53 | }
54 | return float64Value, err
55 | }
56 |
57 | func (def *defFloat64) alloc() error {
58 | return nil
59 | }
60 |
61 | func (def *defFloat64) free() {
62 | def.arrHlp.close()
63 | }
64 |
65 | func (def *defFloat64) close() (err error) {
66 | defer func() {
67 | if value := recover(); value != nil {
68 | err = errR(value)
69 | }
70 | }()
71 |
72 | rset := def.rset
73 | def.rset = nil
74 | def.ocidef = nil
75 | if def.ociNumber != nil {
76 | C.free(unsafe.Pointer(&def.ociNumber[0]))
77 | def.ociNumber = nil
78 | }
79 | rset.putDef(defIdxFloat64, def)
80 | return nil
81 | }
82 |
--------------------------------------------------------------------------------
/defInt16.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | // Generate all the def[IU]int{8,16,32,16}.go from defInt16.go
16 | //
17 | // Generated from defInt16.go by go run gen.go
18 |
19 | type defInt16 struct {
20 | ociDef
21 | ociNumber []C.OCINumber
22 | isNullable bool
23 | }
24 |
25 | func (def *defInt16) define(position int, isNullable bool, rset *Rset) error {
26 | def.rset = rset
27 | def.isNullable = isNullable
28 | if def.ociNumber != nil {
29 | C.free(unsafe.Pointer(&def.ociNumber[0]))
30 | }
31 | def.ociNumber = (*((*[MaxFetchLen]C.OCINumber)(C.malloc(C.size_t(rset.fetchLen) * C.sizeof_OCINumber))))[:rset.fetchLen]
32 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ociNumber[0]), C.sizeof_OCINumber, C.SQLT_VNU)
33 | }
34 |
35 | func (def *defInt16) value(offset int) (value interface{}, err error) {
36 | if def.nullInds[offset] < 0 {
37 | if def.isNullable {
38 | return Int16{IsNull: true}, nil
39 | }
40 | return nil, nil
41 | }
42 | var int16Value int16
43 | on := def.ociNumber[offset]
44 | r := C.OCINumberToInt(
45 | def.rset.stmt.ses.srv.env.ocierr, //OCIError *err,
46 | &on, //const OCINumber *number,
47 | byteWidth16, //uword rsl_length,
48 | C.OCI_NUMBER_SIGNED, //uword rsl_flag,
49 | unsafe.Pointer(&int16Value)) //void *rsl );
50 | if r == C.OCI_ERROR {
51 | err = def.rset.stmt.ses.srv.env.ociError()
52 | }
53 | if def.isNullable {
54 | return Int16{Value: int16Value}, err
55 | }
56 | return int16Value, err
57 | }
58 |
59 | func (def *defInt16) alloc() error { return nil }
60 | func (def *defInt16) free() {
61 | def.arrHlp.close()
62 | }
63 |
64 | func (def *defInt16) close() (err error) {
65 | defer func() {
66 | if value := recover(); value != nil {
67 | err = errR(value)
68 | }
69 | }()
70 | rset := def.rset
71 | def.rset = nil
72 | def.ocidef = nil
73 | if def.ociNumber != nil {
74 | C.free(unsafe.Pointer(&def.ociNumber[0]))
75 | def.ociNumber = nil
76 | }
77 | rset.putDef(defIdxInt16, def)
78 | return nil
79 | }
80 |
--------------------------------------------------------------------------------
/defInt32.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | // Generate all the def[IU]int{8,16,32,32}.go from defInt32.go
16 | //
17 | // Generated from defInt32.go by go run gen.go
18 |
19 | type defInt32 struct {
20 | ociDef
21 | ociNumber []C.OCINumber
22 | isNullable bool
23 | }
24 |
25 | func (def *defInt32) define(position int, isNullable bool, rset *Rset) error {
26 | def.rset = rset
27 | def.isNullable = isNullable
28 | if def.ociNumber != nil {
29 | C.free(unsafe.Pointer(&def.ociNumber[0]))
30 | }
31 | def.ociNumber = (*((*[MaxFetchLen]C.OCINumber)(C.malloc(C.size_t(rset.fetchLen) * C.sizeof_OCINumber))))[:rset.fetchLen]
32 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ociNumber[0]), C.sizeof_OCINumber, C.SQLT_VNU)
33 | }
34 |
35 | func (def *defInt32) value(offset int) (value interface{}, err error) {
36 | if def.nullInds[offset] < 0 {
37 | if def.isNullable {
38 | return Int32{IsNull: true}, nil
39 | }
40 | return nil, nil
41 | }
42 | var int32Value int32
43 | on := def.ociNumber[offset]
44 | r := C.OCINumberToInt(
45 | def.rset.stmt.ses.srv.env.ocierr, //OCIError *err,
46 | &on, //const OCINumber *number,
47 | byteWidth32, //uword rsl_length,
48 | C.OCI_NUMBER_SIGNED, //uword rsl_flag,
49 | unsafe.Pointer(&int32Value)) //void *rsl );
50 | if r == C.OCI_ERROR {
51 | err = def.rset.stmt.ses.srv.env.ociError()
52 | }
53 | if def.isNullable {
54 | return Int32{Value: int32Value}, err
55 | }
56 | return int32Value, err
57 | }
58 |
59 | func (def *defInt32) alloc() error { return nil }
60 | func (def *defInt32) free() {
61 | def.arrHlp.close()
62 | }
63 |
64 | func (def *defInt32) close() (err error) {
65 | defer func() {
66 | if value := recover(); value != nil {
67 | err = errR(value)
68 | }
69 | }()
70 | rset := def.rset
71 | def.rset = nil
72 | def.ocidef = nil
73 | if def.ociNumber != nil {
74 | C.free(unsafe.Pointer(&def.ociNumber[0]))
75 | def.ociNumber = nil
76 | }
77 | rset.putDef(defIdxInt32, def)
78 | return nil
79 | }
80 |
--------------------------------------------------------------------------------
/defInt64.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | // Generate all the def[IU]int{8,16,32,64}.go from defInt64.go
16 | //
17 | //go:generate go run gen.go
18 |
19 | type defInt64 struct {
20 | ociDef
21 | ociNumber []C.OCINumber
22 | isNullable bool
23 | }
24 |
25 | func (def *defInt64) define(position int, isNullable bool, rset *Rset) error {
26 | def.rset = rset
27 | def.isNullable = isNullable
28 | if def.ociNumber != nil {
29 | C.free(unsafe.Pointer(&def.ociNumber[0]))
30 | }
31 | def.ociNumber = (*((*[MaxFetchLen]C.OCINumber)(C.malloc(C.size_t(rset.fetchLen) * C.sizeof_OCINumber))))[:rset.fetchLen]
32 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ociNumber[0]), C.sizeof_OCINumber, C.SQLT_VNU)
33 | }
34 |
35 | func (def *defInt64) value(offset int) (value interface{}, err error) {
36 | if def.nullInds[offset] < 0 {
37 | if def.isNullable {
38 | return Int64{IsNull: true}, nil
39 | }
40 | return nil, nil
41 | }
42 | var int64Value int64
43 | on := def.ociNumber[offset]
44 | r := C.OCINumberToInt(
45 | def.rset.stmt.ses.srv.env.ocierr, //OCIError *err,
46 | &on, //const OCINumber *number,
47 | byteWidth64, //uword rsl_length,
48 | C.OCI_NUMBER_SIGNED, //uword rsl_flag,
49 | unsafe.Pointer(&int64Value)) //void *rsl );
50 | if r == C.OCI_ERROR {
51 | err = def.rset.stmt.ses.srv.env.ociError()
52 | }
53 | if def.isNullable {
54 | return Int64{Value: int64Value}, err
55 | }
56 | return int64Value, err
57 | }
58 |
59 | func (def *defInt64) alloc() error { return nil }
60 | func (def *defInt64) free() {
61 | def.arrHlp.close()
62 | }
63 |
64 | func (def *defInt64) close() (err error) {
65 | defer func() {
66 | if value := recover(); value != nil {
67 | err = errR(value)
68 | }
69 | }()
70 | rset := def.rset
71 | def.rset = nil
72 | def.ocidef = nil
73 | if def.ociNumber != nil {
74 | C.free(unsafe.Pointer(&def.ociNumber[0]))
75 | def.ociNumber = nil
76 | }
77 | rset.putDef(defIdxInt64, def)
78 | return nil
79 | }
80 |
--------------------------------------------------------------------------------
/defInt8.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | // Generate all the def[IU]int{8,16,32,8}.go from defInt8.go
16 | //
17 | // Generated from defInt8.go by go run gen.go
18 |
19 | type defInt8 struct {
20 | ociDef
21 | ociNumber []C.OCINumber
22 | isNullable bool
23 | }
24 |
25 | func (def *defInt8) define(position int, isNullable bool, rset *Rset) error {
26 | def.rset = rset
27 | def.isNullable = isNullable
28 | if def.ociNumber != nil {
29 | C.free(unsafe.Pointer(&def.ociNumber[0]))
30 | }
31 | def.ociNumber = (*((*[MaxFetchLen]C.OCINumber)(C.malloc(C.size_t(rset.fetchLen) * C.sizeof_OCINumber))))[:rset.fetchLen]
32 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ociNumber[0]), C.sizeof_OCINumber, C.SQLT_VNU)
33 | }
34 |
35 | func (def *defInt8) value(offset int) (value interface{}, err error) {
36 | if def.nullInds[offset] < 0 {
37 | if def.isNullable {
38 | return Int8{IsNull: true}, nil
39 | }
40 | return nil, nil
41 | }
42 | var int8Value int8
43 | on := def.ociNumber[offset]
44 | r := C.OCINumberToInt(
45 | def.rset.stmt.ses.srv.env.ocierr, //OCIError *err,
46 | &on, //const OCINumber *number,
47 | byteWidth8, //uword rsl_length,
48 | C.OCI_NUMBER_SIGNED, //uword rsl_flag,
49 | unsafe.Pointer(&int8Value)) //void *rsl );
50 | if r == C.OCI_ERROR {
51 | err = def.rset.stmt.ses.srv.env.ociError()
52 | }
53 | if def.isNullable {
54 | return Int8{Value: int8Value}, err
55 | }
56 | return int8Value, err
57 | }
58 |
59 | func (def *defInt8) alloc() error { return nil }
60 | func (def *defInt8) free() {
61 | def.arrHlp.close()
62 | }
63 |
64 | func (def *defInt8) close() (err error) {
65 | defer func() {
66 | if value := recover(); value != nil {
67 | err = errR(value)
68 | }
69 | }()
70 | rset := def.rset
71 | def.rset = nil
72 | def.ocidef = nil
73 | if def.ociNumber != nil {
74 | C.free(unsafe.Pointer(&def.ociNumber[0]))
75 | def.ociNumber = nil
76 | }
77 | rset.putDef(defIdxInt8, def)
78 | return nil
79 | }
80 |
--------------------------------------------------------------------------------
/defIntervalYM.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import (
14 | "unsafe"
15 | )
16 |
17 | type defIntervalYM struct {
18 | ociDef
19 | intervals []*C.OCIInterval
20 | }
21 |
22 | func (def *defIntervalYM) define(position int, rset *Rset) error {
23 | def.rset = rset
24 | if def.intervals != nil {
25 | C.free(unsafe.Pointer(&def.intervals[0]))
26 | }
27 | def.intervals = (*((*[MaxFetchLen]*C.OCIInterval)(C.malloc(C.size_t(rset.fetchLen) * C.sof_Intervalp))))[:rset.fetchLen]
28 | def.ensureAllocatedLength(len(def.intervals))
29 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.intervals[0]), int(C.sof_Intervalp), C.SQLT_INTERVAL_YM)
30 | }
31 |
32 | func (def *defIntervalYM) value(offset int) (value interface{}, err error) {
33 | intervalYM := IntervalYM{IsNull: def.nullInds[offset] < 0}
34 | if !intervalYM.IsNull {
35 | var year C.sb4
36 | var month C.sb4
37 | r := C.OCIIntervalGetYearMonth(
38 | unsafe.Pointer(def.rset.stmt.ses.srv.env.ocienv), //void *hndl,
39 | def.rset.stmt.ses.srv.env.ocierr, //OCIError *err,
40 | &year, //sb4 *yr,
41 | &month, //sb4 *mnth,
42 | def.intervals[offset]) //const OCIInterval *interval );
43 | if r == C.OCI_ERROR {
44 | err = def.rset.stmt.ses.srv.env.ociError()
45 | }
46 | intervalYM.Year = int32(year)
47 | intervalYM.Month = int32(month)
48 | }
49 | return intervalYM, err
50 | }
51 |
52 | func (def *defIntervalYM) alloc() error {
53 | for i, p := range def.intervals {
54 | if p != nil {
55 | def.intervals[i] = nil
56 | //C.OCIDescriptorFree(unsafe.Pointer(p), C.OCI_DTYPE_INTERVAL_YM)
57 | }
58 | def.allocated[i] = false
59 | r := C.OCIDescriptorAlloc(
60 | unsafe.Pointer(def.rset.stmt.ses.srv.env.ocienv), //CONST dvoid *parenth,
61 | (*unsafe.Pointer)(unsafe.Pointer(&def.intervals[i])), //dvoid **descpp,
62 | C.OCI_DTYPE_INTERVAL_YM, //ub4 type,
63 | 0, //size_t xtramem_sz,
64 | nil) //dvoid **usrmempp);
65 | if r == C.OCI_ERROR {
66 | return def.rset.stmt.ses.srv.env.ociError()
67 | } else if r == C.OCI_INVALID_HANDLE {
68 | return errNew("unable to allocate oci interval handle during define")
69 | }
70 | def.allocated[i] = true
71 | }
72 | return nil
73 | }
74 |
75 | func (def *defIntervalYM) free() {
76 | for i, p := range def.intervals {
77 | if p == nil {
78 | continue
79 | }
80 | def.intervals[i] = nil
81 | if !def.allocated[i] {
82 | continue
83 | }
84 | C.OCIDescriptorFree(
85 | unsafe.Pointer(p), //void *descp,
86 | C.OCI_DTYPE_INTERVAL_YM) //timeDefine.descTypeCode) //ub4 type );
87 | }
88 | def.arrHlp.close()
89 | }
90 |
91 | func (def *defIntervalYM) close() (err error) {
92 | defer func() {
93 | if value := recover(); value != nil {
94 | err = errR(value)
95 | }
96 | }()
97 |
98 | def.free()
99 | if def.intervals != nil {
100 | C.free(unsafe.Pointer(&def.intervals[0]))
101 | def.intervals = nil
102 | }
103 | rset := def.rset
104 | def.rset = nil
105 | def.ocidef = nil
106 | rset.putDef(defIdxIntervalYM, def)
107 | return nil
108 | }
109 |
--------------------------------------------------------------------------------
/defLongRaw.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import (
14 | "unsafe"
15 | )
16 |
17 | type defLongRaw struct {
18 | ociDef
19 | isNullable bool
20 | buf []byte
21 | bufSize int
22 | }
23 |
24 | func (def *defLongRaw) define(position int, bufSize uint32, isNullable bool, rset *Rset) error {
25 | def.rset = rset
26 | def.isNullable = isNullable
27 | if n := rset.fetchLen * int(bufSize); cap(def.buf) < n {
28 | //def.buf = make([]byte, n)
29 | def.buf = bytesPool.Get(n)
30 | } else {
31 | def.buf = def.buf[:n]
32 | }
33 | def.bufSize = int(bufSize)
34 |
35 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.buf[0]), int(bufSize), C.SQLT_LBI)
36 | }
37 |
38 | func (def *defLongRaw) value(offset int) (value interface{}, err error) {
39 | if def.nullInds[offset] < 0 {
40 | if def.isNullable {
41 | return Raw{IsNull: true}, nil
42 | }
43 | return nil, nil
44 | }
45 | // Make a slice of length equal to the return length
46 | result := make([]byte, def.alen[offset])
47 | // Copy returned data
48 | copyLength := copy(result, def.buf[offset*def.bufSize:(offset+1)*def.bufSize])
49 | if C.ACTUAL_LENGTH_TYPE(copyLength) != def.alen[offset] {
50 | return nil, errNew("unable to copy LONG RAW result data from buffer")
51 | }
52 |
53 | if def.isNullable {
54 | return Raw{Value: result}, nil
55 | }
56 | return result, nil
57 | }
58 |
59 | func (def *defLongRaw) alloc() error { return nil }
60 | func (def *defLongRaw) free() {
61 | def.arrHlp.close()
62 | if def.buf != nil {
63 | bytesPool.Put(def.buf)
64 | def.buf = nil
65 | }
66 | }
67 |
68 | func (def *defLongRaw) close() (err error) {
69 | defer func() {
70 | if value := recover(); value != nil {
71 | err = errR(value)
72 | }
73 | }()
74 |
75 | rset := def.rset
76 | def.rset = nil
77 | def.ocidef = nil
78 | def.free()
79 | rset.putDef(defIdxLongRaw, def)
80 | return nil
81 | }
82 |
--------------------------------------------------------------------------------
/defOCINum.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | type defOCINum struct {
16 | ociDef
17 | ociNumber []C.OCINumber
18 | isNullable bool
19 | }
20 |
21 | func (def *defOCINum) define(position int, isNullable bool, rset *Rset) error {
22 | def.rset = rset
23 | def.isNullable = isNullable
24 | if def.ociNumber != nil {
25 | C.free(unsafe.Pointer(&def.ociNumber[0]))
26 | }
27 | def.ociNumber = (*((*[MaxFetchLen]C.OCINumber)(C.malloc(C.size_t(rset.fetchLen) * C.sizeof_OCINumber))))[:rset.fetchLen]
28 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ociNumber[0]), C.sizeof_OCINumber, C.SQLT_VNU)
29 | }
30 | func (def *defOCINum) value(offset int) (value interface{}, err error) {
31 | if def.nullInds[offset] < 0 {
32 | if def.isNullable {
33 | return OraOCINum{IsNull: true}, nil
34 | }
35 | return nil, nil
36 | }
37 | var num OCINum
38 | num.FromC(def.ociNumber[offset])
39 | if def.isNullable {
40 | return OraOCINum{Value: num.OCINum}, nil
41 | }
42 | return OCINum{OCINum: num.OCINum}, nil
43 | }
44 |
45 | func (def *defOCINum) alloc() error { return nil }
46 | func (def *defOCINum) free() {
47 | def.arrHlp.close()
48 | }
49 |
50 | func (def *defOCINum) close() (err error) {
51 | defer func() {
52 | if value := recover(); value != nil {
53 | err = errR(value)
54 | }
55 | }()
56 |
57 | rset := def.rset
58 | def.rset = nil
59 | def.ocidef = nil
60 | if def.ociNumber != nil {
61 | C.free(unsafe.Pointer(&def.ociNumber[0]))
62 | def.ociNumber = nil
63 | }
64 | rset.putDef(defIdxOCINum, def)
65 | return nil
66 | }
67 |
68 | func (env *Env) numberToText(dest []byte, number C.OCINumber) ([]byte, error) {
69 | if cap(dest) < numStringLen {
70 | dest = make([]byte, numStringLen)
71 | } else {
72 | dest = dest[:numStringLen]
73 | }
74 | bufSize := C.ub4(len(dest))
75 | r := C.OCINumberToText(
76 | env.ocierr, //OCIError *err,
77 | &number, //const OCINumber *number,
78 | numberFmtC,
79 | C.ub4(numberFmtLen), //ub4 fmt_length,
80 | numberNLSC, //CONST OraText *nls_params,
81 | C.ub4(numberNLSLen), //ub4 nls_p_length,
82 | &bufSize, //ub4 ,
83 | (*C.oratext)(unsafe.Pointer(&dest[0])), //OraText *rsl );
84 | )
85 | if r == C.OCI_ERROR {
86 | return dest, env.ociError()
87 | }
88 | return dest[:bufSize], nil
89 | }
90 |
--------------------------------------------------------------------------------
/defRaw.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import (
14 | "unsafe"
15 | )
16 |
17 | type defRaw struct {
18 | ociDef
19 | ociRaw *C.OCIRaw
20 | isNullable bool
21 | buf []byte
22 | columnSize int
23 | }
24 |
25 | func (def *defRaw) define(position int, columnSize int, isNullable bool, rset *Rset) error {
26 | def.rset = rset
27 | def.isNullable = isNullable
28 | def.columnSize = columnSize
29 | if n := rset.fetchLen * columnSize; cap(def.buf) < n {
30 | //def.buf = make([]byte, n)
31 | def.buf = bytesPool.Get(n)
32 | } else {
33 | def.buf = def.buf[:n]
34 | }
35 |
36 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.buf[0]), columnSize, C.SQLT_BIN)
37 | }
38 |
39 | func (def *defRaw) value(offset int) (value interface{}, err error) {
40 | if def.nullInds[offset] < 0 {
41 | if def.isNullable {
42 | return Raw{IsNull: true}, nil
43 | }
44 | return nil, nil
45 | }
46 | n := int(def.alen[offset])
47 | off := offset * def.columnSize
48 | if def.isNullable {
49 | return Raw{Value: def.buf[off : off+n]}, nil
50 | }
51 | return def.buf[off : off+n], nil
52 | }
53 |
54 | func (def *defRaw) alloc() error {
55 | return nil
56 | }
57 |
58 | func (def *defRaw) free() {
59 | def.arrHlp.close()
60 | if def.buf != nil {
61 | bytesPool.Put(def.buf)
62 | def.buf = nil
63 | }
64 | }
65 |
66 | func (def *defRaw) close() (err error) {
67 | defer func() {
68 | if value := recover(); value != nil {
69 | err = errR(value)
70 | }
71 | }()
72 |
73 | rset := def.rset
74 | def.rset = nil
75 | def.ocidef = nil
76 | def.ociRaw = nil
77 | def.free()
78 | rset.putDef(defIdxRaw, def)
79 | return nil
80 | }
81 |
--------------------------------------------------------------------------------
/defRowid.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include "version.h"
10 | */
11 | import "C"
12 | import (
13 | "bytes"
14 | "unsafe"
15 | )
16 |
17 | const rowidLen = 19
18 |
19 | type defRowid struct {
20 | ociDef
21 | buf []byte
22 | }
23 |
24 | func (def *defRowid) define(position int, rset *Rset) error {
25 | def.rset = rset
26 | // using a character host variable of width between 19
27 | // (18 bytes plus the null-terminator) and 4001 as the
28 | // host bind variable for universal ROWID.
29 | if n := rset.fetchLen * rowidLen; cap(def.buf) < n {
30 | //def.buf = make([]byte, n)
31 | def.buf = bytesPool.Get(n)
32 | } else {
33 | def.buf = def.buf[:n]
34 | }
35 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.buf[0]), rowidLen, C.SQLT_STR)
36 | }
37 |
38 | func (def *defRowid) value(offset int) (value interface{}, err error) {
39 | n := bytes.Index(def.buf[offset*rowidLen:(offset+1)*rowidLen], []byte{0})
40 | if n == -1 {
41 | n = rowidLen
42 | }
43 | value = string(def.buf[offset*rowidLen : offset*rowidLen+n])
44 | return value, err
45 | }
46 |
47 | func (def *defRowid) alloc() error { return nil }
48 | func (def *defRowid) free() {
49 | def.arrHlp.close()
50 | if def.buf != nil {
51 | bytesPool.Put(def.buf)
52 | def.buf = nil
53 | }
54 | }
55 |
56 | func (def *defRowid) close() (err error) {
57 | defer func() {
58 | if value := recover(); value != nil {
59 | err = errR(value)
60 | }
61 | }()
62 |
63 | rset := def.rset
64 | def.rset = nil
65 | def.ocidef = nil
66 | def.free()
67 | rset.putDef(defIdxRowid, def)
68 | return nil
69 | }
70 |
--------------------------------------------------------------------------------
/defRset.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 Tamás Gulácsi. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | type defRset struct {
16 | ociDef
17 | ocistmt []*C.OCIStmt
18 | result []*Rset
19 | }
20 |
21 | func (def *defRset) define(position int, rset *Rset) error {
22 | def.rset = rset
23 | if def.ocistmt != nil {
24 | C.free(unsafe.Pointer(&def.ocistmt[0]))
25 | }
26 | def.ocistmt = (*((*[MaxFetchLen]*C.OCIStmt)(C.malloc(C.size_t(rset.fetchLen) * C.sof_Stmtp))))[:rset.fetchLen]
27 | def.result = make([]*Rset, len(def.ocistmt))
28 |
29 | // create result set
30 | for i := range def.result {
31 | result := _drv.rsetPool.Get().(*Rset)
32 | if result.id == 0 {
33 | result.id = _drv.rsetId.nextId()
34 | }
35 | result.autoClose = true
36 | result.env = def.rset.env
37 | result.stmt = rset.stmt
38 | result.ocistmt = rset.ocistmt
39 | def.result[i] = result
40 |
41 | upOciStmt, err := def.rset.stmt.ses.srv.env.allocOciHandle(C.OCI_HTYPE_STMT)
42 | if err != nil {
43 | return errE(err)
44 | }
45 | def.ocistmt[i] = (*C.OCIStmt)(upOciStmt)
46 | }
47 |
48 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ocistmt[0]), int(C.sof_Stmtp), C.SQLT_RSET)
49 | }
50 |
51 | func (def *defRset) value(offset int) (value interface{}, err error) {
52 | rst := def.result[offset]
53 |
54 | err = rst.open(rst.stmt, def.ocistmt[offset])
55 | rst.stmt.openRsets.add(rst)
56 |
57 | return rst, err
58 | }
59 |
60 | func (def *defRset) alloc() error {
61 | return nil
62 | }
63 |
64 | func (def *defRset) free() {
65 | def.arrHlp.close()
66 | for i, p := range def.ocistmt {
67 | if p == nil {
68 | continue
69 | }
70 | def.ocistmt[i] = nil
71 | def.rset.stmt.ses.srv.env.freeOciHandle(unsafe.Pointer(p), C.OCI_HTYPE_STMT)
72 | }
73 | }
74 |
75 | func (def *defRset) close() (err error) {
76 | defer func() {
77 | if value := recover(); value != nil {
78 | err = errR(value)
79 | }
80 | }()
81 |
82 | def.free()
83 | if def.ocistmt != nil {
84 | C.free(unsafe.Pointer(&def.ocistmt[0]))
85 | def.ocistmt = nil
86 | }
87 | rset := def.rset
88 | def.rset = nil
89 | def.ocidef = nil
90 | rset.putDef(defIdxRset, def)
91 | return nil
92 | }
93 |
--------------------------------------------------------------------------------
/defString.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import (
14 | "fmt"
15 | "os"
16 | "strings"
17 | "sync"
18 | "unsafe"
19 | )
20 |
21 | type defString struct {
22 | ociDef
23 | sync.RWMutex
24 | buf []byte
25 | isNullable, rTrim bool
26 | columnSize int
27 | }
28 |
29 | type defNumString struct {
30 | defString
31 | }
32 |
33 | func (def *defNumString) define(position int, isNullable bool, rset *Rset) error {
34 | return def.defString.define(position, 40, isNullable, false, rset)
35 | }
36 |
37 | func (def *defString) define(position int, columnSize int, isNullable, rTrim bool, rset *Rset) error {
38 | def.Lock()
39 | defer def.Unlock()
40 | def.rset = rset
41 | def.isNullable, def.rTrim = isNullable, rTrim
42 | //Log.Infof("defString position=%d columnSize=%d", position, columnSize)
43 | n := columnSize
44 | // AL32UTF8: one db "char" can be 4 bytes on wire, esp. if the database's
45 | // character set is not AL32UTF8 (e.g. some 8bit fixed width charset), and
46 | // the column is VARCHAR2 with byte semantics.
47 | //
48 | // For example when the db's charset is EE8ISO8859P2, then a VARCHAR2(1) can
49 | // contain an "ű", which is 2 bytes AL32UTF8.
50 | rset.stmt.RLock()
51 | rset.stmt.ses.RLock()
52 | isUTF8 := rset.stmt.ses.srv.IsUTF8()
53 | rset.stmt.ses.RUnlock()
54 | rset.stmt.RUnlock()
55 | if !isUTF8 {
56 | n *= 2
57 | }
58 | if n == 0 {
59 | n = 2
60 | }
61 | if n%2 != 0 {
62 | n++
63 | }
64 | def.columnSize = n
65 | if n := rset.fetchLen * def.columnSize; cap(def.buf) < n {
66 | //def.buf = make([]byte, n)
67 | def.buf = bytesPool.Get(n)
68 | } else {
69 | def.buf = def.buf[:n]
70 | }
71 |
72 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.buf[0]), def.columnSize, C.SQLT_CHR)
73 | }
74 |
75 | func (def *defString) value(offset int) (value interface{}, err error) {
76 | def.RLock()
77 | defer def.RUnlock()
78 | if offset < 0 || offset >= len(def.nullInds) {
79 | fmt.Fprintf(os.Stderr, "offset=%d nullInds=%d\n", offset, len(def.nullInds))
80 | }
81 | if def.nullInds[offset] < 0 {
82 | if def.isNullable {
83 | return String{IsNull: true}, nil
84 | }
85 | return "", nil
86 | }
87 | var s string
88 | //def.rset.logF(_drv.Cfg().Log.Stmt.Bind,
89 | // "%p offset=%d alen=%v, colSize=%d, buf=%v",
90 | // def, offset, def.alen, def.columnSize, def.buf[offset*def.columnSize:offset*def.columnSize+int(def.alen[offset])])
91 | if def.alen[offset] > 0 {
92 | off := offset * def.columnSize
93 | s = string(def.buf[off : off+int(def.alen[offset])])
94 | if def.rTrim {
95 | s = strings.TrimRight(s, " ")
96 | }
97 | }
98 | if def.isNullable {
99 | return String{Value: s}, nil
100 | }
101 | return s, nil
102 | }
103 |
104 | func (def *defString) alloc() error {
105 | return nil
106 | }
107 |
108 | func (def *defString) free() {
109 | def.Lock()
110 | def.arrHlp.close()
111 | if def.buf != nil {
112 | bytesPool.Put(def.buf)
113 | def.buf = nil
114 | }
115 | def.Unlock()
116 | }
117 |
118 | func (def *defString) close() (err error) {
119 | defer func() {
120 | if value := recover(); value != nil {
121 | err = errR(value)
122 | }
123 | }()
124 |
125 | def.free()
126 | rset := def.rset
127 | def.rset = nil
128 | def.ocidef = nil
129 | rset.putDef(defIdxString, def)
130 | return nil
131 | }
132 |
--------------------------------------------------------------------------------
/defUint16.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | // Generate all the def[IU]int{8,16,32,16}.go from defUint16.go
16 | //
17 | // Generated from defUint16.go by go run gen.go
18 |
19 | type defUint16 struct {
20 | ociDef
21 | ociNumber []C.OCINumber
22 | isNullable bool
23 | }
24 |
25 | func (def *defUint16) define(position int, isNullable bool, rset *Rset) error {
26 | def.rset = rset
27 | def.isNullable = isNullable
28 | if def.ociNumber != nil {
29 | C.free(unsafe.Pointer(&def.ociNumber[0]))
30 | }
31 | def.ociNumber = (*((*[MaxFetchLen]C.OCINumber)(C.malloc(C.size_t(rset.fetchLen) * C.sizeof_OCINumber))))[:rset.fetchLen]
32 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ociNumber[0]), C.sizeof_OCINumber, C.SQLT_VNU)
33 | }
34 |
35 | func (def *defUint16) value(offset int) (value interface{}, err error) {
36 | if def.nullInds[offset] < 0 {
37 | if def.isNullable {
38 | return Uint16{IsNull: true}, nil
39 | }
40 | return nil, nil
41 | }
42 | var uint16Value uint16
43 | on := def.ociNumber[offset]
44 | r := C.OCINumberToInt(
45 | def.rset.stmt.ses.srv.env.ocierr, //OCIError *err,
46 | &on, //const OCINumber *number,
47 | byteWidth16, //uword rsl_length,
48 | C.OCI_NUMBER_UNSIGNED, //uword rsl_flag,
49 | unsafe.Pointer(&uint16Value)) //void *rsl );
50 | if r == C.OCI_ERROR {
51 | err = def.rset.stmt.ses.srv.env.ociError()
52 | }
53 | if def.isNullable {
54 | return Uint16{Value: uint16Value}, err
55 | }
56 | return uint16Value, err
57 | }
58 |
59 | func (def *defUint16) alloc() error { return nil }
60 | func (def *defUint16) free() {
61 | def.arrHlp.close()
62 | }
63 |
64 | func (def *defUint16) close() (err error) {
65 | defer func() {
66 | if value := recover(); value != nil {
67 | err = errR(value)
68 | }
69 | }()
70 | rset := def.rset
71 | def.rset = nil
72 | def.ocidef = nil
73 | if def.ociNumber != nil {
74 | C.free(unsafe.Pointer(&def.ociNumber[0]))
75 | def.ociNumber = nil
76 | }
77 | rset.putDef(defIdxUint16, def)
78 | return nil
79 | }
80 |
--------------------------------------------------------------------------------
/defUint32.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | // Generate all the def[IU]int{8,16,32,32}.go from defUint32.go
16 | //
17 | // Generated from defUint32.go by go run gen.go
18 |
19 | type defUint32 struct {
20 | ociDef
21 | ociNumber []C.OCINumber
22 | isNullable bool
23 | }
24 |
25 | func (def *defUint32) define(position int, isNullable bool, rset *Rset) error {
26 | def.rset = rset
27 | def.isNullable = isNullable
28 | if def.ociNumber != nil {
29 | C.free(unsafe.Pointer(&def.ociNumber[0]))
30 | }
31 | def.ociNumber = (*((*[MaxFetchLen]C.OCINumber)(C.malloc(C.size_t(rset.fetchLen) * C.sizeof_OCINumber))))[:rset.fetchLen]
32 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ociNumber[0]), C.sizeof_OCINumber, C.SQLT_VNU)
33 | }
34 |
35 | func (def *defUint32) value(offset int) (value interface{}, err error) {
36 | if def.nullInds[offset] < 0 {
37 | if def.isNullable {
38 | return Uint32{IsNull: true}, nil
39 | }
40 | return nil, nil
41 | }
42 | var uint32Value uint32
43 | on := def.ociNumber[offset]
44 | r := C.OCINumberToInt(
45 | def.rset.stmt.ses.srv.env.ocierr, //OCIError *err,
46 | &on, //const OCINumber *number,
47 | byteWidth32, //uword rsl_length,
48 | C.OCI_NUMBER_UNSIGNED, //uword rsl_flag,
49 | unsafe.Pointer(&uint32Value)) //void *rsl );
50 | if r == C.OCI_ERROR {
51 | err = def.rset.stmt.ses.srv.env.ociError()
52 | }
53 | if def.isNullable {
54 | return Uint32{Value: uint32Value}, err
55 | }
56 | return uint32Value, err
57 | }
58 |
59 | func (def *defUint32) alloc() error { return nil }
60 | func (def *defUint32) free() {
61 | def.arrHlp.close()
62 | }
63 |
64 | func (def *defUint32) close() (err error) {
65 | defer func() {
66 | if value := recover(); value != nil {
67 | err = errR(value)
68 | }
69 | }()
70 | rset := def.rset
71 | def.rset = nil
72 | def.ocidef = nil
73 | if def.ociNumber != nil {
74 | C.free(unsafe.Pointer(&def.ociNumber[0]))
75 | def.ociNumber = nil
76 | }
77 | rset.putDef(defIdxUint32, def)
78 | return nil
79 | }
80 |
--------------------------------------------------------------------------------
/defUint64.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | // Generate all the def[IU]int{8,16,32,64}.go from defUint64.go
16 | //
17 | // Generated from defUint64.go by go run gen.go
18 |
19 | type defUint64 struct {
20 | ociDef
21 | ociNumber []C.OCINumber
22 | isNullable bool
23 | }
24 |
25 | func (def *defUint64) define(position int, isNullable bool, rset *Rset) error {
26 | def.rset = rset
27 | def.isNullable = isNullable
28 | if def.ociNumber != nil {
29 | C.free(unsafe.Pointer(&def.ociNumber[0]))
30 | }
31 | def.ociNumber = (*((*[MaxFetchLen]C.OCINumber)(C.malloc(C.size_t(rset.fetchLen) * C.sizeof_OCINumber))))[:rset.fetchLen]
32 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ociNumber[0]), C.sizeof_OCINumber, C.SQLT_VNU)
33 | }
34 |
35 | func (def *defUint64) value(offset int) (value interface{}, err error) {
36 | if def.nullInds[offset] < 0 {
37 | if def.isNullable {
38 | return Uint64{IsNull: true}, nil
39 | }
40 | return nil, nil
41 | }
42 | var uint64Value uint64
43 | on := def.ociNumber[offset]
44 | r := C.OCINumberToInt(
45 | def.rset.stmt.ses.srv.env.ocierr, //OCIError *err,
46 | &on, //const OCINumber *number,
47 | byteWidth64, //uword rsl_length,
48 | C.OCI_NUMBER_UNSIGNED, //uword rsl_flag,
49 | unsafe.Pointer(&uint64Value)) //void *rsl );
50 | if r == C.OCI_ERROR {
51 | err = def.rset.stmt.ses.srv.env.ociError()
52 | }
53 | if def.isNullable {
54 | return Uint64{Value: uint64Value}, err
55 | }
56 | return uint64Value, err
57 | }
58 |
59 | func (def *defUint64) alloc() error { return nil }
60 | func (def *defUint64) free() {
61 | def.arrHlp.close()
62 | }
63 |
64 | func (def *defUint64) close() (err error) {
65 | defer func() {
66 | if value := recover(); value != nil {
67 | err = errR(value)
68 | }
69 | }()
70 | rset := def.rset
71 | def.rset = nil
72 | def.ocidef = nil
73 | if def.ociNumber != nil {
74 | C.free(unsafe.Pointer(&def.ociNumber[0]))
75 | def.ociNumber = nil
76 | }
77 | rset.putDef(defIdxUint64, def)
78 | return nil
79 | }
80 |
--------------------------------------------------------------------------------
/defUint8.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | /*
8 | #include
9 | #include
10 | #include "version.h"
11 | */
12 | import "C"
13 | import "unsafe"
14 |
15 | // Generate all the def[IU]int{8,16,32,8}.go from defUint8.go
16 | //
17 | // Generated from defUint8.go by go run gen.go
18 |
19 | type defUint8 struct {
20 | ociDef
21 | ociNumber []C.OCINumber
22 | isNullable bool
23 | }
24 |
25 | func (def *defUint8) define(position int, isNullable bool, rset *Rset) error {
26 | def.rset = rset
27 | def.isNullable = isNullable
28 | if def.ociNumber != nil {
29 | C.free(unsafe.Pointer(&def.ociNumber[0]))
30 | }
31 | def.ociNumber = (*((*[MaxFetchLen]C.OCINumber)(C.malloc(C.size_t(rset.fetchLen) * C.sizeof_OCINumber))))[:rset.fetchLen]
32 | return def.ociDef.defineByPos(position, unsafe.Pointer(&def.ociNumber[0]), C.sizeof_OCINumber, C.SQLT_VNU)
33 | }
34 |
35 | func (def *defUint8) value(offset int) (value interface{}, err error) {
36 | if def.nullInds[offset] < 0 {
37 | if def.isNullable {
38 | return Uint8{IsNull: true}, nil
39 | }
40 | return nil, nil
41 | }
42 | var uint8Value uint8
43 | on := def.ociNumber[offset]
44 | r := C.OCINumberToInt(
45 | def.rset.stmt.ses.srv.env.ocierr, //OCIError *err,
46 | &on, //const OCINumber *number,
47 | byteWidth8, //uword rsl_length,
48 | C.OCI_NUMBER_UNSIGNED, //uword rsl_flag,
49 | unsafe.Pointer(&uint8Value)) //void *rsl );
50 | if r == C.OCI_ERROR {
51 | err = def.rset.stmt.ses.srv.env.ociError()
52 | }
53 | if def.isNullable {
54 | return Uint8{Value: uint8Value}, err
55 | }
56 | return uint8Value, err
57 | }
58 |
59 | func (def *defUint8) alloc() error { return nil }
60 | func (def *defUint8) free() {
61 | def.arrHlp.close()
62 | }
63 |
64 | func (def *defUint8) close() (err error) {
65 | defer func() {
66 | if value := recover(); value != nil {
67 | err = errR(value)
68 | }
69 | }()
70 | rset := def.rset
71 | def.rset = nil
72 | def.ocidef = nil
73 | if def.ociNumber != nil {
74 | C.free(unsafe.Pointer(&def.ociNumber[0]))
75 | def.ociNumber = nil
76 | }
77 | rset.putDef(defIdxUint8, def)
78 | return nil
79 | }
80 |
--------------------------------------------------------------------------------
/drvExecResult.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | import (
8 | "math"
9 | )
10 |
11 | // DrvExecResult is an Oracle execution result.
12 | //
13 | // DrvExecResult implements the driver.Result interface.
14 | type DrvExecResult struct {
15 | lastInsertId int64
16 | rowsAffected uint64
17 | }
18 |
19 | // LastInsertId returns the identity value from an insert statement.
20 | //
21 | // There are two setup steps required to reteive the LastInsertId.
22 | // One, specify a 'returning into' clause in the SQL insert statement.
23 | // And, two, specify a nil parameter to DB.Exec or DrvStmt.Exec.
24 | //
25 | // For example:
26 | //
27 | // db, err := sql.Open("ora", "scott/tiger@orcl")
28 | //
29 | // db.Exec("CREATE TABLE T1 (C1 NUMBER(19,0) GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1), C2 VARCHAR2(48 CHAR))")
30 | //
31 | // result, err := db.Exec("INSERT INTO T1 (C2) VALUES ('GO') RETURNING C1 /*lastInsertId*/ INTO :C1", nil)
32 | //
33 | // id, err := result.LastInsertId()
34 | func (er *DrvExecResult) LastInsertId() (int64, error) {
35 | return er.lastInsertId, nil
36 | }
37 |
38 | // RowsAffected returns the number of rows affected by the exec statement.
39 | func (er *DrvExecResult) RowsAffected() (int64, error) {
40 | var rowsAffected int64
41 | if er.rowsAffected > math.MaxInt64 {
42 | rowsAffected = math.MaxInt64
43 | } else {
44 | rowsAffected = int64(er.rowsAffected)
45 | }
46 | return rowsAffected, nil
47 | }
48 |
--------------------------------------------------------------------------------
/drvStmt.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | import (
8 | "database/sql/driver"
9 | "fmt"
10 | )
11 |
12 | // DrvStmt is an Oracle statement associated with a session.
13 | //
14 | // DrvStmt wraps Stmt and is intended for use by the database/sql/driver package.
15 | //
16 | // DrvStmt implements the driver.Stmt interface.
17 | type DrvStmt struct {
18 | stmt *Stmt
19 | }
20 |
21 | // checkIsOpen validates that the server is open.
22 | func (ds *DrvStmt) checkIsOpen() error {
23 | if ds.stmt == nil {
24 | return er("DrvStmt is closed.")
25 | }
26 | return nil
27 | }
28 |
29 | // Close closes the SQL statement.
30 | //
31 | // Close is a member of the driver.Stmt interface.
32 | func (ds *DrvStmt) Close() error {
33 | ds.log(true)
34 | if err := ds.checkIsOpen(); err != nil {
35 | return errE(err)
36 | }
37 | if err := ds.stmt.Close(); err != nil {
38 | return errE(err)
39 | }
40 | return nil
41 | }
42 |
43 | // NumInput returns the number of placeholders in a sql statement.
44 | //
45 | // NumInput is a member of the driver.Stmt interface.
46 | func (ds *DrvStmt) NumInput() int {
47 | if ds.stmt == nil {
48 | return 0
49 | }
50 | return ds.stmt.NumInput()
51 | }
52 |
53 | // Exec executes an Oracle SQL statement on a server. Exec returns a driver.Result
54 | // and a possible error.
55 | //
56 | // Exec is a member of the driver.Stmt interface.
57 | func (ds *DrvStmt) Exec(values []driver.Value) (driver.Result, error) {
58 | ds.log(true)
59 | if err := ds.checkIsOpen(); err != nil {
60 | return nil, errE(err)
61 | }
62 | params := make([]interface{}, len(values))
63 | for n := range values {
64 | params[n] = values[n]
65 | }
66 | rowsAffected, lastInsertId, err := ds.stmt.exe(params, false)
67 | if err != nil {
68 | return nil, maybeBadConn(err)
69 | }
70 | if rowsAffected == 0 {
71 | return driver.RowsAffected(0), nil
72 | }
73 | return &DrvExecResult{rowsAffected: rowsAffected, lastInsertId: lastInsertId}, nil
74 | }
75 |
76 | // Query runs a SQL query on an Oracle server. Query returns driver.Rows and a
77 | // possible error.
78 | //
79 | // Query is a member of the driver.Stmt interface.
80 | func (ds *DrvStmt) Query(values []driver.Value) (driver.Rows, error) {
81 | ds.log(true)
82 | if err := ds.checkIsOpen(); err != nil {
83 | return nil, errE(err)
84 | }
85 | params := make([]interface{}, len(values))
86 | for n := range values {
87 | params[n] = values[n]
88 | }
89 | rset, err := ds.stmt.qry(params)
90 | if err != nil {
91 | return nil, maybeBadConn(err)
92 | }
93 | return &DrvQueryResult{rset: rset}, nil
94 | }
95 |
96 | // sysName returns a string representing the DrvStmt.
97 | func (ds *DrvStmt) sysName() string {
98 | if ds == nil {
99 | return "E_S_S_S_S_"
100 | }
101 | return ds.stmt.sysName() + fmt.Sprintf("S%v", ds.stmt.id)
102 | }
103 |
104 | // log writes a message with an DrvStmt system name and caller info.
105 | func (ds *DrvStmt) log(enabled bool, v ...interface{}) {
106 | cfg := _drv.Cfg()
107 | if !cfg.Log.IsEnabled(enabled) {
108 | return
109 | }
110 | if len(v) == 0 {
111 | cfg.Log.Logger.Infof("%v %v", ds.sysName(), callInfo(1))
112 | } else {
113 | cfg.Log.Logger.Infof("%v %v %v", ds.sysName(), callInfo(1), fmt.Sprint(v...))
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/drvStmt_go1_8.go:
--------------------------------------------------------------------------------
1 | // +build go1.8
2 |
3 | // Copyright 2017 Tamás Gulácsi. All rights reserved.
4 | // Use of this source code is governed by The MIT License
5 | // found in the accompanying LICENSE file.
6 |
7 | package ora
8 |
9 | import (
10 | "context"
11 | "database/sql/driver"
12 | )
13 |
14 | // ExecContext enhances the Stmt interface by providing Exec with context.
15 | // ExecContext must honor the context timeout and return when it is cancelled.
16 | func (ds *DrvStmt) ExecContext(ctx context.Context, values []driver.NamedValue) (driver.Result, error) {
17 | ds.log(true)
18 | if err := ds.checkIsOpen(); err != nil {
19 | return nil, errE(err)
20 | }
21 | params := make([]interface{}, len(values))
22 | for n, v := range values {
23 | params[n] = v
24 | }
25 | if err := ctx.Err(); err != nil {
26 | return nil, err
27 | }
28 |
29 | done := make(chan struct{})
30 | go func() {
31 | select {
32 | case <-done:
33 | case <-ctx.Done():
34 | // select again to avoid race condition if both are done
35 | select {
36 | case <-done:
37 | default:
38 | if isCanceled(ctx.Err()) {
39 | ds.stmt.RLock()
40 | ses := ds.stmt.ses
41 | ds.stmt.RUnlock()
42 | ses.Break()
43 | }
44 | }
45 | }
46 | }()
47 |
48 | var err error
49 | var res DrvExecResult
50 | res.rowsAffected, res.lastInsertId, err = ds.stmt.exeC(ctx, params, false)
51 | close(done)
52 |
53 | if err != nil {
54 | return nil, maybeBadConn(err)
55 | }
56 | if res.rowsAffected == 0 {
57 | return driver.RowsAffected(0), nil
58 | }
59 | return &res, nil
60 | }
61 |
62 | // QueryContext enhances the Stmt interface by providing Query with context.
63 | // QueryContext must honor the context timeout and return when it is cancelled.
64 | func (ds *DrvStmt) QueryContext(ctx context.Context, values []driver.NamedValue) (driver.Rows, error) {
65 | ds.log(true)
66 | if err := ds.checkIsOpen(); err != nil {
67 | return nil, errE(err)
68 | }
69 | params := make([]interface{}, len(values))
70 | for n, v := range values {
71 | params[n] = v
72 | }
73 | if err := ctx.Err(); err != nil {
74 | return nil, err
75 | }
76 | done := make(chan struct{})
77 | go func() {
78 | select {
79 | case <-done:
80 | case <-ctx.Done():
81 | // select again to avoid race condition if both are done
82 | select {
83 | case <-done:
84 | default:
85 | if isCanceled(ctx.Err()) {
86 | ds.stmt.RLock()
87 | ses := ds.stmt.ses
88 | ds.stmt.RUnlock()
89 | ses.Break()
90 | }
91 | }
92 | }
93 | }()
94 |
95 | rset, err := ds.stmt.qryC(ctx, params)
96 | close(done)
97 |
98 | if err != nil {
99 | return nil, maybeBadConn(err)
100 | }
101 | return &DrvQueryResult{rset: rset}, nil
102 | }
103 |
104 | // vim: set fileencoding=utf-8 noet:
105 |
--------------------------------------------------------------------------------
/examples/bench/.gitignore:
--------------------------------------------------------------------------------
1 | *.pprof
2 | *.test
3 | *.bench
4 |
--------------------------------------------------------------------------------
/examples/bench/README.md:
--------------------------------------------------------------------------------
1 | # Benchmark ora vs. oci8
2 | Compile a simple SELECT benchmark with `github.com/mattn/go-oci8` and `gopkg.in/rana/ora.v4`, and compare them:
3 |
4 | ./run.sh
5 |
6 | ## Result
7 |
8 | ```
9 | $ ./run.sh
10 | Compile ...
11 | Benchmarks on DSN=boma/boma@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=p520.unosoft.local)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=cigf.unosoft.local))) ...
12 | go-oci8
13 | 2016/03/30 11:10:37 Write CPU profile to "oci8.pprof".
14 | 2016/03/30 11:10:42 Iterated 5000 rows in 3.518387308s.
15 | 2016/03/30 11:10:42 1 3518345504 ns/op 0.00 MB/s
16 | Entering interactive mode (type "help" for commands)
17 | (pprof) (pprof) 20ms of 20ms total ( 100%)
18 | flat flat% sum% cum cum%
19 | 0 0% 0% 20ms 100% database/sql.(*Rows).Next
20 | 0 0% 0% 20ms 100% github.com/mattn/go-oci8.(*OCI8Rows).Next
21 | 0 0% 0% 20ms 100% github.com/mattn/go-oci8._Cfunc_OCIStmtFetch
22 | 0 0% 0% 20ms 100% main.BenchmarkIter
23 | 20ms 100% 100% 20ms 100% runtime.cgocall
24 | 0 0% 100% 20ms 100% runtime.goexit
25 | 0 0% 100% 20ms 100% testing.(*B).launch
26 | 0 0% 100% 20ms 100% testing.(*B).runN
27 | (pprof) ora
28 | 2016/03/30 11:10:42 Write CPU profile to "ora.pprof".
29 | 2016/03/30 11:10:56 Iterated 5000 rows in 12.527146357s.
30 | 2016/03/30 11:10:56 1 12527036391 ns/op 0.00 MB/s
31 | Entering interactive mode (type "help" for commands)
32 | (pprof) (pprof) 110ms of 110ms total ( 100%)
33 | flat flat% sum% cum cum%
34 | 0 0% 0% 110ms 100% database/sql.(*Rows).Next
35 | 0 0% 0% 110ms 100% gopkg.in/rana/ora%2ev3.(*DrvQueryResult).Next
36 | 0 0% 0% 110ms 100% gopkg.in/rana/ora%2ev3.(*Rset).beginRow
37 | 0 0% 0% 110ms 100% gopkg.in/rana/ora%2ev3._Cfunc_OCIStmtFetch2
38 | 0 0% 0% 110ms 100% main.BenchmarkIter
39 | 110ms 100% 100% 110ms 100% runtime.cgocall
40 | 0 0% 100% 110ms 100% runtime.goexit
41 | 0 0% 100% 110ms 100% testing.(*B).launch
42 | 0 0% 100% 110ms 100% testing.(*B).runN
43 | (pprof) :tgulacsi@tgulacsi-laptop: ~/src/gopkg.in/rana/ora.v4/examples/bench
44 | ```
45 |
--------------------------------------------------------------------------------
/examples/bench/gen.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | //go:generate mkdir -p ora
4 | //go:generate sh -c "sed -e 's:github.com/mattn/go-oci8:gopkg.in/rana/ora.v4:;s/Oci8/Ora/g;s/oci8/ora/g' oci8/bench_oci8.go >ora/bench_ora.go"
5 |
--------------------------------------------------------------------------------
/examples/bench/oci8/bench_oci8.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 Tamás Gulácsi, Jia Lu. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package main
6 |
7 | import (
8 | "database/sql"
9 | "flag"
10 | "log"
11 | "os"
12 | "runtime/pprof"
13 | "testing"
14 | "time"
15 |
16 | _ "github.com/mattn/go-oci8"
17 | )
18 |
19 | var (
20 | DB *sql.DB
21 | cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
22 | N = flag.Int("N", 1000, "row count")
23 | )
24 |
25 | func init() {
26 | flag.Parse()
27 | drv, dsn := "oci8", os.ExpandEnv(flag.Arg(0))
28 | var err error
29 | if DB, err = sql.Open(drv, dsn); err != nil {
30 | log.Fatalf("cannot connect with %q to %q: %v", drv, dsn, err)
31 | }
32 | if err = DB.Ping(); err != nil {
33 | log.Fatalf("cannot connect with %q to %q: %v", drv, dsn, err)
34 | }
35 | }
36 |
37 | func main() {
38 | if *cpuprofile != "" {
39 | f, err := os.Create(*cpuprofile)
40 | if err != nil {
41 | log.Fatal(err)
42 | }
43 | log.Printf("Write CPU profile to %q.", f.Name())
44 | pprof.StartCPUProfile(f)
45 | defer pprof.StopCPUProfile()
46 | }
47 |
48 | result := testing.Benchmark(BenchmarkIter)
49 | log.Println(result)
50 | }
51 |
52 | func BenchmarkIter(b *testing.B) {
53 | rows, err := DB.Query("SELECT A.object_name from all_objects, all_objects A")
54 | if err != nil {
55 | b.Fatal(err)
56 | }
57 | defer rows.Close()
58 | b.ReportAllocs()
59 | start := time.Now()
60 | b.ResetTimer()
61 | i := 0
62 | N := *N
63 | for rows.Next() && i < N {
64 | i++
65 | }
66 | b.StopTimer()
67 | d := time.Since(start)
68 | b.SetBytes(int64(i))
69 | log.Printf("Iterated %d rows in %s: %.3f row/s.",
70 | i, d, float64(i)/(float64(d)/float64(time.Second)))
71 | }
72 |
--------------------------------------------------------------------------------
/examples/bench/ora/bench_ora.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 Tamás Gulácsi, Jia Lu. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package main
6 |
7 | import (
8 | "database/sql"
9 | "flag"
10 | "log"
11 | "os"
12 | "runtime/pprof"
13 | "testing"
14 | "time"
15 |
16 | _ "gopkg.in/rana/ora.v4"
17 | )
18 |
19 | var (
20 | DB *sql.DB
21 | cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
22 | N = flag.Int("N", 1000, "row count")
23 | )
24 |
25 | func init() {
26 | flag.Parse()
27 | drv, dsn := "ora", os.ExpandEnv(flag.Arg(0))
28 | var err error
29 | if DB, err = sql.Open(drv, dsn); err != nil {
30 | log.Fatalf("cannot connect with %q to %q: %v", drv, dsn, err)
31 | }
32 | if err = DB.Ping(); err != nil {
33 | log.Fatalf("cannot connect with %q to %q: %v", drv, dsn, err)
34 | }
35 | }
36 |
37 | func main() {
38 | if *cpuprofile != "" {
39 | f, err := os.Create(*cpuprofile)
40 | if err != nil {
41 | log.Fatal(err)
42 | }
43 | log.Printf("Write CPU profile to %q.", f.Name())
44 | pprof.StartCPUProfile(f)
45 | defer pprof.StopCPUProfile()
46 | }
47 |
48 | result := testing.Benchmark(BenchmarkIter)
49 | log.Println(result)
50 | }
51 |
52 | func BenchmarkIter(b *testing.B) {
53 | rows, err := DB.Query("SELECT A.object_name from all_objects, all_objects A")
54 | if err != nil {
55 | b.Fatal(err)
56 | }
57 | defer rows.Close()
58 | b.ReportAllocs()
59 | start := time.Now()
60 | b.ResetTimer()
61 | i := 0
62 | N := *N
63 | for rows.Next() && i < N {
64 | i++
65 | }
66 | b.StopTimer()
67 | d := time.Since(start)
68 | b.SetBytes(int64(i))
69 | log.Printf("Iterated %d rows in %s: %.3f row/s.",
70 | i, d, float64(i)/(float64(d)/float64(time.Second)))
71 | }
72 |
--------------------------------------------------------------------------------
/examples/bench/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 | DSN="$1"
3 | BENCHTIME="${BENCHTIME:-1s}"
4 | N=${N:-5000}
5 | if [ -z "$DSN" ]; then
6 | DSN=${GO_ORA_DRV_TEST_USERNAME}/${GO_ORA_DRV_TEST_PASSWORD}@${GO_ORA_DRV_TEST_DB}
7 | fi
8 | echo "Compile ..." >&2
9 | go build -o oci8.bench ./oci8 &
10 | go build -o ora.bench ./ora
11 | wait
12 |
13 | run () {
14 | nm="$1"
15 | echo "$nm" >&2
16 | ./"$nm".bench -cpuprofile="$nm".pprof -N=$N -test.benchtime=$BENCHTIME "$DSN"
17 | echo "cum\ntop20" | go tool pprof ./"$nm".bench "$nm".pprof
18 | }
19 |
20 | echo "Benchmarks on DSN=${DSN} ..." >&2
21 | run oci8
22 | run ora
23 |
--------------------------------------------------------------------------------
/examples/conntest/conn_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2013 Tamás Gulácsi
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package main
18 |
19 | import (
20 | "testing"
21 | )
22 |
23 | func TestListObjects(t *testing.T) {
24 | ListObjects(t)
25 | }
26 |
--------------------------------------------------------------------------------
/examples/conntest/main.go:
--------------------------------------------------------------------------------
1 | /*
2 | Package main in conntest represents a connection testing program.
3 |
4 | Copyright 2013 Tamás Gulácsi
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | */
18 | package main
19 |
20 | import (
21 | "flag"
22 | "log"
23 | "os"
24 | "os/signal"
25 | "sync"
26 | "syscall"
27 | "testing"
28 |
29 | "gopkg.in/rana/ora.v4/examples/connect"
30 | )
31 |
32 | var fWait = flag.Bool("wait", false, "wait for USR1 signal?")
33 |
34 | func ListObjects(t *testing.T) {
35 | conn, err := connect.GetConnection("")
36 | if err != nil {
37 | t.Errorf("error connectiong: %s", err)
38 | t.FailNow()
39 | return
40 | }
41 | defer conn.Close()
42 |
43 | qry := "SELECT owner, object_name, object_id FROM all_objects WHERE ROWNUM < 20"
44 | log.Printf(`executing "%s"`, qry)
45 | rows, err := conn.Query(qry)
46 | if err != nil {
47 | t.Logf(`error with %q: %s`, qry, err)
48 | t.FailNow()
49 | return
50 | }
51 | var (
52 | owner, objectName string
53 | objectID int
54 | )
55 | for rows.Next() {
56 | if err = rows.Scan(&owner, &objectName, &objectID); err != nil {
57 | t.Errorf("error fetching: %s", err)
58 | break
59 | }
60 | t.Logf(`row: "%s";"%s";%d`, owner, objectName, objectID)
61 | }
62 | }
63 |
64 | func main() {
65 | flag.Parse()
66 | t := new(testing.T)
67 | if *fWait {
68 | c := make(chan os.Signal)
69 | var wg sync.WaitGroup
70 | wg.Add(1)
71 | go func() {
72 | log.Printf("waiting for signal...")
73 | sig := <-c
74 | log.Printf("got signal %s", sig)
75 | ListObjects(t)
76 | wg.Done()
77 | }()
78 | signal.Notify(c, syscall.SIGUSR1)
79 | wg.Wait()
80 | } else {
81 | ListObjects(t)
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/examples/csvdump/README.md:
--------------------------------------------------------------------------------
1 | # csvdump #
2 | ## Usage ##
3 | ./csvdump -db.dsn=user/passw@sid all_objects >x.csv
4 |
--------------------------------------------------------------------------------
/gen.go:
--------------------------------------------------------------------------------
1 | // +build ignore
2 |
3 | // Copyright 2016 Tamás Gulácsi. All rights reserved.
4 | // Use of this source code is governed by The MIT License
5 | // found in the accompanying LICENSE file.
6 |
7 | package main
8 |
9 | import (
10 | "bytes"
11 | "io/ioutil"
12 | "log"
13 | )
14 |
15 | func main() {
16 | src := "defFloat64.go"
17 | b := readFile(src)
18 | dst := "defFloat32.go"
19 | log.Printf("%s => %s", src, dst)
20 | if err := ioutil.WriteFile(
21 | dst,
22 | bytes.Replace(b, []byte("64"), []byte("32"), -1),
23 | 0644,
24 | ); err != nil {
25 | log.Fatal(err)
26 | }
27 |
28 | src = "defInt64.go"
29 | b = readFile(src)
30 | for _, s := range []string{"8", "16", "32"} {
31 | dst = "defInt" + s + ".go"
32 | log.Printf("%s => %s", src, dst)
33 | if err := ioutil.WriteFile(
34 | dst,
35 | bytes.Replace(b, []byte("64"), []byte(s), -1),
36 | 0644,
37 | ); err != nil {
38 | log.Fatal(err)
39 | }
40 | }
41 |
42 | for _, pair := range [][2]string{
43 | {"OCI_NUMBER_SIGNED", "OCI_NUMBER_UNSIGNED"},
44 | {"int64", "uint64"},
45 | {"Int64", "Uint64"},
46 | } {
47 | b = bytes.Replace(b, []byte(pair[0]), []byte(pair[1]), -1)
48 | }
49 | dst = "defUint64.go"
50 | if err := ioutil.WriteFile(dst, b, 0644); err != nil {
51 | log.Fatal(err)
52 | }
53 | for _, s := range []string{"8", "16", "32"} {
54 | dst = "defUint" + s + ".go"
55 | log.Printf("%s => %s", src, dst)
56 | if err := ioutil.WriteFile(
57 | dst,
58 | bytes.Replace(b, []byte("64"), []byte(s), -1),
59 | 0644,
60 | ); err != nil {
61 | log.Fatal(err)
62 | }
63 | }
64 |
65 | for _, plus := range []string{"", "Ptr", "Slice"} {
66 | src = "bndFloat64" + plus + ".go"
67 | b := readFile(src)
68 | dst = "bndFloat32" + plus + ".go"
69 | log.Printf("%s => %s", src, dst)
70 | if err := ioutil.WriteFile(
71 | dst,
72 | bytes.Replace(
73 | bytes.Replace(b, []byte("64"), []byte("32"), -1),
74 | []byte("floatSixtyFour("), []byte("float64("), -1),
75 | 0644,
76 | ); err != nil {
77 | log.Fatal(err)
78 | }
79 |
80 | src = "bndInt64" + plus + ".go"
81 | b = readFile(src)
82 | for _, s := range []string{"8", "16", "32"} {
83 | dst = "bndInt" + s + plus + ".go"
84 | log.Printf("%s => %s", src, dst)
85 | if err := ioutil.WriteFile(
86 | dst,
87 | bytes.Replace(
88 | bytes.Replace(b, []byte("64"), []byte(s), -1),
89 | []byte("intSixtyFour("), []byte("int64("), -1),
90 | 0644,
91 | ); err != nil {
92 | log.Fatal(err)
93 | }
94 | }
95 |
96 | for _, pair := range [][2]string{
97 | {"OCI_NUMBER_SIGNED", "OCI_NUMBER_UNSIGNED"},
98 | {"int64", "uint64"},
99 | {"Int64", "Uint64"},
100 | } {
101 | b = bytes.Replace(b, []byte(pair[0]), []byte(pair[1]), -1)
102 | }
103 | dst = "bndUint64" + plus + ".go"
104 | if err := ioutil.WriteFile(dst, b, 0644); err != nil {
105 | log.Fatal(err)
106 | }
107 | for _, s := range []string{"8", "16", "32"} {
108 | dst = "bndUint" + s + plus + ".go"
109 | log.Printf("%s => %s", src, dst)
110 | if err := ioutil.WriteFile(
111 | dst,
112 | bytes.Replace(
113 | bytes.Replace(b, []byte("64"), []byte(s), -1),
114 | []byte("intSixtyFour("), []byte("int64("), -1),
115 | 0644,
116 | ); err != nil {
117 | log.Fatal(err)
118 | }
119 | }
120 | }
121 | }
122 |
123 | func readFile(fn string) []byte {
124 | src, err := ioutil.ReadFile(fn)
125 | if err != nil {
126 | log.Fatal(err)
127 | }
128 | src = bytes.Replace(src, []byte("//go:generate "), []byte("// Generated from "+fn+" by "), -1)
129 | return src
130 | }
131 |
--------------------------------------------------------------------------------
/glg/glg.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Tamás Gulácsi. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package glg
6 |
7 | import (
8 | "fmt"
9 | "github.com/golang/glog"
10 | )
11 |
12 | var Log = gLgr{}
13 |
14 | type gLgr struct{}
15 |
16 | func (l gLgr) Infof(format string, v ...interface{}) {
17 | glog.InfoDepth(2, fmt.Sprintf(format, v...))
18 | }
19 | func (l gLgr) Infoln(v ...interface{}) {
20 | glog.InfoDepth(2, v...)
21 | }
22 | func (l gLgr) Errorf(format string, v ...interface{}) {
23 | glog.ErrorDepth(2, fmt.Sprintf(format, v...))
24 | }
25 | func (l gLgr) Errorln(v ...interface{}) {
26 | glog.ErrorDepth(2, v...)
27 | }
28 |
--------------------------------------------------------------------------------
/lg/lg.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package lg
6 |
7 | import (
8 | "fmt"
9 | "log"
10 | "os"
11 | )
12 |
13 | var Log = Std{L: log.New(os.Stderr, "[ora] ", log.Ldate|log.Ltime|log.Lmicroseconds|log.Lshortfile)}
14 |
15 | type Std struct {
16 | L *log.Logger
17 | }
18 |
19 | func (s Std) Infof(format string, v ...interface{}) {
20 | s.L.SetPrefix("ORA I ")
21 | s.L.Output(2, fmt.Sprintf(format, v...))
22 | }
23 | func (s Std) Infoln(v ...interface{}) {
24 | s.L.SetPrefix("ORA I ")
25 | s.L.Output(2, fmt.Sprintln(v...))
26 | }
27 | func (s Std) Errorf(format string, v ...interface{}) {
28 | s.L.SetPrefix("ORA E ")
29 | s.L.Output(2, fmt.Sprintf(format, v...))
30 | }
31 | func (s Std) Errorln(v ...interface{}) {
32 | s.L.SetPrefix("ORA E ")
33 | s.L.Output(2, fmt.Sprintln(v...))
34 | }
35 |
--------------------------------------------------------------------------------
/lg15/lg15.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Tamás Gulácsi. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package lg15
6 |
7 | import (
8 | "fmt"
9 | "strings"
10 |
11 | "gopkg.in/inconshreveable/log15.v2"
12 | )
13 |
14 | var Log = lgr{log15.New("lib", "ora")}
15 |
16 | type lgr struct {
17 | log15.Logger
18 | }
19 |
20 | func (s lgr) Infof(format string, args ...interface{}) { s.Debug(fmt.Sprintf(format, args...)) }
21 | func (s lgr) Infoln(args ...interface{}) { s.Debug(strings.Join(asStrings(args), " ")) }
22 | func (s lgr) Errorf(format string, args ...interface{}) { s.Error(fmt.Sprintf(format, args...)) }
23 | func (s lgr) Errorln(args ...interface{}) { s.Error(strings.Join(asStrings(args), " ")) }
24 |
25 | func asStrings(args ...interface{}) []string {
26 | arr := make([]string, len(args))
27 | for i, a := range args {
28 | if s, ok := a.(string); ok {
29 | arr[i] = s
30 | continue
31 | }
32 | if s, ok := a.(fmt.Stringer); ok {
33 | arr[i] = s.String()
34 | continue
35 | }
36 | arr[i] = fmt.Sprintf("%v", a)
37 | }
38 | return arr
39 | }
40 |
--------------------------------------------------------------------------------
/logger.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Tamás Gulácsi. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | // Logger interface is for logging.
8 | type Logger interface {
9 | Infof(format string, args ...interface{})
10 | Infoln(args ...interface{})
11 | Errorf(format string, args ...interface{})
12 | Errorln(args ...interface{})
13 | }
14 |
15 | type EmpLgr struct{}
16 |
17 | func (e EmpLgr) Infof(format string, v ...interface{}) {}
18 | func (e EmpLgr) Infoln(v ...interface{}) {}
19 | func (e EmpLgr) Errorf(format string, v ...interface{}) {}
20 | func (e EmpLgr) Errorln(v ...interface{}) {}
21 |
--------------------------------------------------------------------------------
/num/.gitignore:
--------------------------------------------------------------------------------
1 | num-fuzz.zip
2 |
--------------------------------------------------------------------------------
/num/ocinum_fuzz.go:
--------------------------------------------------------------------------------
1 | // +build gofuzz
2 |
3 | // Copyright 2016 Tamás Gulácsi. All rights reserved.
4 | // Use of this source code is governed by The MIT License
5 | // found in the accompanying LICENSE file.
6 |
7 | package num
8 |
9 | import "strings"
10 |
11 | //go:generate go-fuzz-build gopkg.in/rana/ora.v4/num
12 |
13 | // Fuzz:
14 | // go-fuzz -bin=./num-fuzz.zip -workdir=/tmp/fuzz
15 | func Fuzz(p []byte) int {
16 | pS := string(p)
17 | var q [22]byte
18 | n := OCINum(q[:0])
19 | if err := n.SetString(pS); err != nil {
20 | return -1
21 | }
22 | s := n.String()
23 | if s != strings.TrimSpace(pS) {
24 | return 1
25 | }
26 | return 0
27 | }
28 |
--------------------------------------------------------------------------------
/rsetCfg_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Tamás Gulácsi. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora
6 |
7 | import "testing"
8 |
9 | // TestNumericColumnType tests RsetCfg.numericColumnType.
10 | func TestNumericColumnType(t *testing.T) {
11 | c := NewRsetCfg()
12 | // be exact
13 | c.float, c.numberFloat, c.numberInt = F32, F64, I64
14 | for i, tc := range []struct {
15 | precision, scale int
16 | want GoColumnType
17 | }{
18 | {6, 3, F64},
19 | {3, 0, I64},
20 | {0, -127, F32},
21 | {0, 0, N},
22 | } {
23 | got := c.numericColumnType(tc.precision, tc.scale)
24 | if got != tc.want {
25 | t.Errorf("%d. (%d,%d) got %s, want %s.",
26 | i, tc.precision, tc.scale, GctName(got), GctName(tc.want))
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/stmt_go1.go:
--------------------------------------------------------------------------------
1 | // +build !go1.8
2 |
3 | //Copyright 2016 Tamás Gulácsi. All rights reserved.
4 | //Use of this source code is governed by The MIT License
5 | //found in the accompanying LICENSE file.
6 |
7 | package ora
8 |
9 | /*
10 | #include
11 | #include
12 | */
13 | import "C"
14 |
15 | // NumInput returns the number of placeholders in a sql statement.
16 | func (stmt *Stmt) NumInput() int {
17 | bc, err := stmt.attr(4, C.OCI_ATTR_BIND_COUNT)
18 | if err != nil {
19 | return 0
20 | }
21 | bindCount := int(*((*C.ub4)(bc)))
22 | C.free(bc)
23 | return bindCount
24 | }
25 |
26 | func nameAndValue(v interface{}) (string, interface{}) {
27 | return "", v
28 | }
29 |
--------------------------------------------------------------------------------
/stmt_go1_8.go:
--------------------------------------------------------------------------------
1 | // +build go1.8
2 |
3 | //Copyright 2016 Tamás Gulácsi. All rights reserved.
4 | //Use of this source code is governed by The MIT License
5 | //found in the accompanying LICENSE file.
6 |
7 | package ora
8 |
9 | import "database/sql/driver"
10 |
11 | // NumInput returns the number of placeholders in a sql statement.
12 | //
13 | // This returns a constant -1, as named params can be less, then positional params.
14 | func (stmt *Stmt) NumInput() int {
15 | if bindNames, _, duplicates, err := stmt.getBindInfo(); err == nil {
16 | n := len(bindNames)
17 | for _, d := range duplicates {
18 | if d {
19 | n--
20 | }
21 | }
22 | return n
23 | }
24 | return -1
25 | }
26 |
27 | func nameAndValue(v interface{}) (string, interface{}) {
28 | if nv, ok := v.(driver.NamedValue); ok {
29 | return nv.Name, nv.Value
30 | }
31 | return "", v
32 | }
33 |
--------------------------------------------------------------------------------
/test-one-by-one.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | n="${1:-10}"
3 |
4 | PRG=./ora.v4.test
5 | if time echo '' >/dev/null 2>&1; then
6 | PRG="time $PRG"
7 | elif /usr/bin/time echo '' >/dev/null 2>&1; then
8 | PRG="/usr/bin/time $PRG"
9 | fi
10 |
11 | go install -race && go test -race -c && \
12 | grep -h '^func Test' *_test.go|cut -c10-|cut -d'(' -f1 \
13 | | sort -R | xargs -n "$n" | sed -e 's/ /|/g' | \
14 | while read nm;
15 | do
16 | echo ''
17 | echo "$nm"
18 | $PRG -test.run=$nm || break
19 | done
20 |
21 |
--------------------------------------------------------------------------------
/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -x
4 | ulimit -v unlimited
5 | CGO_CFLAGS=-fsanitize=address CGO_LDFLAGS=-lasan go test -c
6 | exec ./ora.v4.test "$@"
7 |
--------------------------------------------------------------------------------
/tstlg/tstlg.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package tstlg
6 |
7 | import "testing"
8 |
9 | func New(t *testing.T) Tst {
10 | return Tst{t}
11 | }
12 |
13 | type Tst struct {
14 | *testing.T
15 | }
16 |
17 | func (t Tst) Infof(format string, v ...interface{}) {
18 | t.Logf("ORA I "+format, v...)
19 | }
20 | func (t Tst) Infoln(v ...interface{}) {
21 | v = append(make([]interface{}, 1, len(v)+1), v)
22 | v[0] = "ORA I"
23 | t.Log(v...)
24 | }
25 | func (t Tst) Errorf(format string, v ...interface{}) {
26 | t.Logf("ORA E "+format, v...)
27 | }
28 | func (t Tst) Errorln(v ...interface{}) {
29 | v = append(make([]interface{}, 1, len(v)+1), v)
30 | v[0] = "ORA E"
31 | t.Log(v...)
32 | }
33 |
--------------------------------------------------------------------------------
/util_test.go:
--------------------------------------------------------------------------------
1 | package ora
2 |
3 | import "testing"
4 |
5 | func TestBoundingPower(t *testing.T) {
6 | for i, inOut := range [][2]int{
7 | {0, 0},
8 | {1, 0},
9 | {2, 1},
10 | {3, 2},
11 | {4, 2},
12 | {5, 3},
13 | {7, 3},
14 | {8, 3},
15 | {1024, 10},
16 | {1025, 11},
17 | } {
18 | got := boundingPower(inOut[0])
19 | if got != inOut[1] {
20 | t.Errorf("%d. (%d) got %d, wanted %d.", i, inOut[0], got, inOut[1])
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/version.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "version.h"
3 |
4 | sword
5 | bindByNameOrPos(
6 | OCIStmt *stmtp,
7 | OCIBind **bindpp,
8 | OCIError *errhp,
9 | ub4 position,
10 | const OraText *placeholder,
11 | sb4 placeholder_length,
12 | void *valuep,
13 | LENGTH_TYPE value_sz,
14 | ub2 dty,
15 | void *indp,
16 | ACTUAL_LENGTH_TYPE *alenp,
17 | ub2 *rcodep,
18 | ub4 maxarr_len,
19 | ub4 *curelep,
20 | ub4 mode
21 | ) {
22 | if( placeholder != NULL && placeholder_length > 0 ) {
23 | return OCIBINDBYNAME(
24 | stmtp,
25 | bindpp,
26 | errhp,
27 | placeholder,
28 | placeholder_length,
29 | valuep,
30 | value_sz,
31 | dty,
32 | indp,
33 | alenp,
34 | rcodep,
35 | maxarr_len,
36 | curelep,
37 | mode);
38 | }
39 | return OCIBINDBYPOS(
40 | stmtp,
41 | bindpp,
42 | errhp,
43 | position,
44 | valuep,
45 | value_sz,
46 | dty,
47 | indp,
48 | alenp,
49 | rcodep,
50 | maxarr_len,
51 | curelep,
52 | mode);
53 | }
54 |
55 | sword
56 | numberFromIntSlice(
57 | OCIError *err,
58 | void *inum,
59 | uword inum_length,
60 | uword inum_s_flag,
61 | OCINumber *numbers,
62 | ub4 arr_length
63 | ) {
64 | sword rc;
65 | int i;
66 | for(i=0; i < arr_length; i++) {
67 | rc = OCINumberFromInt(err, inum + (i * inum_length), inum_length, inum_s_flag, &(numbers[i]));
68 | if(rc == OCI_ERROR) {
69 | return rc;
70 | }
71 | }
72 | return OCI_SUCCESS;
73 | }
74 |
75 | sword
76 | numberFromFloatSlice(
77 | OCIError *err,
78 | void *inum,
79 | uword inum_length,
80 | OCINumber *numbers,
81 | ub4 arr_length
82 | ) {
83 | sword rc;
84 | int i;
85 | for(i=0; i < arr_length; i++) {
86 | rc = OCINumberFromReal(err, inum + (i * inum_length), inum_length, &(numbers[i]));
87 | if(rc == OCI_ERROR) {
88 | return rc;
89 | }
90 | }
91 | return OCI_SUCCESS;
92 | }
93 |
94 |
95 | sword
96 | decriptorAllocSlice(
97 | OCIEnv *env,
98 | void *dest,
99 | ub4 elem_size,
100 | ub4 type,
101 | size_t length
102 | ) {
103 | sword rc;
104 | int i;
105 | for(i=0; i < length; i++) {
106 | rc = OCIDescriptorAlloc(
107 | env, //CONST dvoid *parenth,
108 | dest + i * elem_size, //dvoid **descpp,
109 | type, //ub4 type,
110 | 0, //size_t xtramem_sz,
111 | 0); //dvoid **usrmempp);
112 | if(rc == OCI_ERROR) {
113 | return rc;
114 | }
115 | }
116 | return OCI_SUCCESS;
117 | }
118 |
--------------------------------------------------------------------------------
/version.h:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Tamás Gulácsi. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | #include
6 |
7 | // define simple way to respresent Oracle version
8 | #define ORACLE_VERSION(major, minor) \
9 | ((major << 8) | minor)
10 |
11 | // define what version of Oracle we are building as 2 byte hex number
12 | #if !defined(OCI_MAJOR_VERSION) && defined(OCI_ATTR_MODULE)
13 | #define OCI_MAJOR_VERSION 10
14 | #define OCI_MINOR_VERSION 1
15 | #endif
16 |
17 | #if defined(OCI_MAJOR_VERSION) && defined(OCI_MINOR_VERSION)
18 | #define ORACLE_VERSION_HEX \
19 | ORACLE_VERSION(OCI_MAJOR_VERSION, OCI_MINOR_VERSION)
20 | #else
21 | #error Unsupported version of OCI.
22 | #endif
23 |
24 | #if ORACLE_VERSION_HEX >= ORACLE_VERSION(12,1)
25 | #define OCIBINDBYNAME OCIBindByName2
26 | #define OCIBINDBYPOS OCIBindByPos2
27 | #define OCIDEFINEBYPOS OCIDefineByPos2
28 | #define ACTUAL_LENGTH_TYPE ub4
29 | #define ACTUAL_LENGTH_LENGTH 4
30 | #define MAX_BINARY_BYTES 32767
31 | #define LENGTH_TYPE sb8
32 | #define LENGTH_LENGTH 8
33 |
34 | #define ROW_COUNT_TYPE ub8
35 | #define ROW_COUNT_LENGTH 8
36 | #else
37 | #define OCIBINDBYNAME OCIBindByName
38 | #define OCIBINDBYPOS OCIBindByPos
39 | #define OCIDEFINEBYPOS OCIDefineByPos
40 | #define ACTUAL_LENGTH_TYPE ub2
41 | #define ACTUAL_LENGTH_LENGTH 2
42 | #define MAX_BINARY_BYTES 4000
43 | #define LENGTH_TYPE sb4
44 | #define LENGTH_LENGTH 4
45 |
46 | #define OCI_ATTR_UB8_ROW_COUNT OCI_ATTR_ROW_COUNT
47 | #define ROW_COUNT_TYPE ub4
48 | #define ROW_COUNT_LENGTH 4
49 | #endif
50 |
51 | #if ORACLE_VERSION_HEX >= ORACLE_VERSION(10,1)
52 | #define LOB_LENGTH_TYPE oraub8
53 | #define OCILOBGETLENGTH OCILobGetLength2
54 | #define OCILOBTRIM OCILobTrim2
55 | #define OCILOBWRITE OCILobWrite2
56 | #else
57 | #define LOB_LENGTH_TYPE ub4
58 | #define OCILOBGETLENGTH OCILobGetLength
59 | #define OCILOBTRIM OCILobTrim
60 | #define OCILOBWRITE OCILobWrite
61 | #endif
62 |
63 | #define sof_DateTimep sizeof(OCIDateTime*)
64 | #define sof_Intervalp sizeof(OCIInterval*)
65 | #define sof_LobLocatorp sizeof(OCILobLocator*)
66 | #define sof_Stmtp sizeof(OCIStmt*)
67 |
68 | sword
69 | bindByNameOrPos(
70 | OCIStmt *stmtp,
71 | OCIBind **bindpp,
72 | OCIError *errhp,
73 | ub4 position,
74 | const OraText *placeholder,
75 | sb4 placeholder_length,
76 | void *valuep,
77 | LENGTH_TYPE value_sz,
78 | ub2 dty,
79 | void *indp,
80 | ACTUAL_LENGTH_TYPE *alenp,
81 | ub2 *rcodep,
82 | ub4 maxarr_len,
83 | ub4 *curelep,
84 | ub4 mode
85 | );
86 |
87 | sword
88 | numberFromIntSlice(
89 | OCIError *err,
90 | void *inum,
91 | uword inum_length,
92 | uword inum_s_flag,
93 | OCINumber *numbers,
94 | ub4 arr_length
95 | );
96 |
97 | sword
98 | numberFromFloatSlice(
99 | OCIError *err,
100 | void *inum,
101 | uword inum_length,
102 | OCINumber *numbers,
103 | ub4 arr_length
104 | );
105 |
106 | sword
107 | decriptorAllocSlice(
108 | OCIEnv *env,
109 | void *dest,
110 | ub4 elem_size,
111 | ub4 type,
112 | size_t length
113 | );
114 |
--------------------------------------------------------------------------------
/z_bfile_session_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Rana Ian. All rights reserved.
2 | // Use of this source code is governed by The MIT License
3 | // found in the accompanying LICENSE file.
4 |
5 | package ora_test
6 |
7 | import (
8 | "fmt"
9 | "testing"
10 |
11 | "gopkg.in/rana/ora.v4"
12 | )
13 |
14 | //// bfile
15 | //bfile oracleColumnType = "bfile not null"
16 | //bfileNull oracleColumnType = "bfile null"
17 |
18 | ////////////////////////////////////////////////////////////////////////////////
19 | // bfile
20 | ////////////////////////////////////////////////////////////////////////////////
21 | func TestBindDefine_bfile(t *testing.T) {
22 | sc := ora.NewStmtCfg()
23 | t.Run("bfile", func(t *testing.T) {
24 | t.Parallel()
25 | //enableLogging(t)
26 | testBindDefine(gen_OraBfile(false), bfile, t, sc)
27 | })
28 | for _, isNull := range []bool{true, false} {
29 | t.Run(fmt.Sprintf("bfileNull_%t", isNull), func(t *testing.T) {
30 | t.Parallel()
31 | //enableLogging(t)
32 | testBindDefine(gen_OraBfile(isNull), bfileNull, t, sc)
33 | })
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/z_db_go1_8_test.go:
--------------------------------------------------------------------------------
1 | // +build go1.8
2 |
3 | //Copyright 2016 Tamás Gulácsi. All rights reserved.
4 | //Use of this source code is governed by The MIT License
5 | //found in the accompanying LICENSE file.
6 |
7 | package ora_test
8 |
9 | import (
10 | "context"
11 | "database/sql"
12 | "strings"
13 | "sync/atomic"
14 | "testing"
15 | "time"
16 |
17 | "golang.org/x/sync/errgroup"
18 |
19 | "github.com/pkg/errors"
20 | )
21 |
22 | func TestNamedArgs(t *testing.T) {
23 | t.Parallel()
24 | qry := "SELECT object_name FROM user_objects WHERE object_type = :typ AND ROWNUM < :num AND object_name <> :typ"
25 | stmt, err := testDb.Prepare(qry)
26 | if err != nil {
27 | t.Fatal(errors.Wrap(err, qry))
28 | }
29 | defer stmt.Close()
30 | var s string
31 | if err := stmt.QueryRow(sql.Named("typ", "TABLE"), sql.Named("num", 2)).Scan(&s); err != nil {
32 | t.Fatal(err)
33 | }
34 | t.Log(s)
35 | }
36 |
37 | func TestRapidCancelIssue192(t *testing.T) {
38 | wait := uint64(500)
39 | dbQuery := func(db *sql.DB) error {
40 | w := atomic.LoadUint64(&wait)
41 | ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*time.Duration(w))
42 | defer cancel()
43 | if w > 100 {
44 | atomic.StoreUint64(&wait, w>>2)
45 | }
46 |
47 | rows, err := db.QueryContext(ctx, "select table_name from all_tables")
48 | w = atomic.LoadUint64(&wait)
49 | if err != nil {
50 | t.Log(w, err)
51 | if err == context.DeadlineExceeded && !strings.Contains(err.Error(), "ORA-01013") {
52 | atomic.StoreUint64(&wait, w+1)
53 | }
54 | return err
55 | }
56 | return rows.Close()
57 | }
58 |
59 | breakStuff := func(ctx context.Context, db *sql.DB) error {
60 | for ctx.Err() == nil {
61 | if err := dbQuery(db); err != nil && err != context.DeadlineExceeded && !strings.Contains(err.Error(), "ORA-01013") {
62 | return err
63 | }
64 | time.Sleep(100 * time.Millisecond)
65 | }
66 | return nil
67 | }
68 |
69 | ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
70 | defer cancel()
71 | grp, ctx := errgroup.WithContext(ctx)
72 | for i := 0; i < 8; i++ {
73 | grp.Go(func() error { return breakStuff(ctx, testDb) })
74 | }
75 |
76 | if err := grp.Wait(); err != nil {
77 | t.Error(err)
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/z_issue131.go:
--------------------------------------------------------------------------------
1 | // +build never
2 |
3 | package main
4 |
5 | import (
6 | "context"
7 | "database/sql"
8 | "fmt"
9 | "log"
10 | "math/rand"
11 | "net/http"
12 | "os"
13 | "sync"
14 | "time"
15 |
16 | _ "net/http/pprof"
17 |
18 | _ "gopkg.in/rana/ora.v4"
19 | )
20 |
21 | var db *sql.DB
22 |
23 | func startDB(dsn string) {
24 | var err error
25 | db, err = sql.Open("ora", dsn)
26 | if err != nil {
27 | log.Fatal(err)
28 | }
29 | db.SetMaxIdleConns(32)
30 | db.SetConnMaxLifetime(10 * time.Second)
31 | }
32 |
33 | func dbRoutine(ctx context.Context) {
34 | for {
35 | select {
36 | case <-ctx.Done():
37 | log.Printf(" %v. finished.", ctx.Value("id"))
38 | return
39 | default:
40 | }
41 | var temp int
42 | i := rand.Int()
43 | if i%100 == 0 {
44 | log.Printf(" %v. starts", ctx.Value("id"))
45 | }
46 | db.QueryRow("select 1 from dual").Scan(&temp)
47 | if i%100 == 0 {
48 | log.Printf(" %v. ends", ctx.Value("id"))
49 | }
50 | if i%10 == 0 {
51 | time.Sleep(50 * time.Millisecond)
52 | }
53 | }
54 | }
55 |
56 | func main() {
57 | dur, _ := time.ParseDuration(os.Getenv("DURATION"))
58 | if dur == 0 {
59 | dur = 24 * time.Hour
60 | }
61 |
62 | go func() {
63 | addr := "localhost:6131"
64 | log.Println("go tool pprof " + addr + "/debug/pprof/heap")
65 | log.Println(http.ListenAndServe(addr, nil))
66 | }()
67 |
68 | log.SetPrefix("#131 ")
69 | log.Println("starting")
70 | startDB(fmt.Sprintf("%s/%s@%s", os.Getenv("GO_ORA_DRV_TEST_USERNAME"), os.Getenv("GO_ORA_DRV_TEST_PASSWORD"), os.Getenv("GO_ORA_DRV_TEST_DB")))
71 |
72 | go func() {
73 | http.ListenAndServe(":8889", nil)
74 | }()
75 |
76 | ctx, cancel := context.WithTimeout(context.Background(), dur)
77 | defer cancel()
78 | var wg sync.WaitGroup
79 | for i := 0; i < 40; i++ {
80 | wg.Add(1)
81 | ctx := context.WithValue(ctx, "id", i)
82 | go func() {
83 | defer wg.Done()
84 | dbRoutine(ctx)
85 | }()
86 | }
87 | wg.Wait()
88 | log.Println("finished.")
89 | }
90 |
91 | // vim: set fileencoding=utf-8 noet:
92 |
--------------------------------------------------------------------------------
/z_issue197.go:
--------------------------------------------------------------------------------
1 | // +build never
2 |
3 | package main
4 |
5 | import (
6 | "log"
7 | "os"
8 | "strconv"
9 | "time"
10 |
11 | "github.com/pkg/errors"
12 |
13 | "gopkg.in/rana/ora.v4"
14 | )
15 |
16 | const insellpid = "0000000048A16C23433210AC068C"
17 |
18 | func main() {
19 | Pool, err := ora.NewPool(os.Getenv("GO_ORA_DRV_TEST_USERNAME")+"/"+os.Getenv("GO_ORA_DRV_TEST_PASSWORD")+"@"+os.Getenv("GO_ORA_DRV_TEST_DB"), 4)
20 | if err != nil {
21 | log.Fatal(err)
22 | }
23 | defer Pool.Close()
24 | ses, err := Pool.Get()
25 | if err != nil {
26 | log.Fatal(err)
27 | }
28 | defer ses.Close()
29 | qry := `CREATE OR REPLACE PROCEDURE test_p1(insellpid IN VARCHAR2, procRset OUT SYS_REFCURSOR) IS
30 | BEGIN
31 | OPEN procRset FOR SELECT * FROM all_objects WHERE ROWNUM < 100;
32 | END;`
33 | if _, err := ses.PrepAndExe(qry); err != nil {
34 | log.Fatal(errors.Wrap(err, qry))
35 | }
36 |
37 | deadline := time.Now().Add(5 * time.Minute)
38 | for time.Now().Before(deadline) {
39 | ses, err := Pool.Get()
40 | if err != nil {
41 | log.Fatal(err)
42 | }
43 | if err := work(ses); err != nil {
44 | log.Println(err)
45 | }
46 | ses.Close()
47 | ses.Close()
48 | //os.Stdout.Write([]byte{'.'})
49 | }
50 | }
51 |
52 | func work(ses *ora.Ses) error {
53 | qry := "CALL test_P1(:1,:2)"
54 |
55 | procRset := &ora.Rset{}
56 | stmtProcCall, err := ses.Prep(qry)
57 | if err != nil {
58 | return errors.Wrap(err, qry)
59 | }
60 | defer stmtProcCall.Close()
61 |
62 | if _, err = stmtProcCall.Exe(insellpid, procRset); err != nil {
63 | return err
64 | }
65 | if !procRset.IsOpen() {
66 | return nil
67 | }
68 |
69 | rmapArr := make([]map[string]interface{}, 0)
70 | for procRset.Next() {
71 | rmap := make(map[string]interface{})
72 | cols := procRset.Columns
73 | row := procRset.Row
74 | for j := 0; j < len(row); j++ {
75 | clo := cols[j].Name
76 | switch x := row[j].(type) {
77 | case ora.OCINum:
78 | va_n := x.String()
79 | if "" == va_n {
80 | rmap[clo] = nil
81 | } else {
82 | fl_64, err_ := strconv.ParseFloat(va_n, 64)
83 | if err_ != nil {
84 | return errors.Wrapf(err, "strconv.ParseFloat(%q)", va_n)
85 | panic(err_)
86 | }
87 | rmap[clo] = fl_64
88 | }
89 |
90 | case time.Time:
91 | rmap[clo] = x.Format("20060102 15:04:05")
92 | case string:
93 | if "" == row[j] {
94 | rmap[clo] = nil
95 | } else {
96 | rmap[clo] = row[j]
97 | }
98 | default:
99 | rmap[clo] = row[j]
100 | }
101 |
102 | }
103 | rmapArr = append(rmapArr, rmap)
104 | }
105 | log.Printf("%d rows, each with %d columns", len(rmapArr), len(rmapArr[0]))
106 |
107 | return nil
108 | }
109 |
--------------------------------------------------------------------------------
/z_race.go:
--------------------------------------------------------------------------------
1 | // +build never
2 |
3 | package main
4 |
5 | import (
6 | "context"
7 | "flag"
8 | "log"
9 | "os"
10 | "os/exec"
11 | "time"
12 |
13 | "golang.org/x/sync/errgroup"
14 | )
15 |
16 | var issues = []string{"z_issue131.go"}
17 |
18 | func main() {
19 | flagDur := flag.Duration("duration", 24*time.Hour, "test duration")
20 | flag.Parse()
21 |
22 | cmd := exec.Command("go", "install", "-race")
23 | cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
24 | if err := cmd.Run(); err != nil {
25 | log.Fatal(err)
26 | }
27 | os.Setenv("DURATION", flagDur.String())
28 |
29 | ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
30 | defer cancel()
31 | grp, ctx := errgroup.WithContext(ctx)
32 | for _, nm := range issues {
33 | nm := nm
34 | grp.Go(func() error {
35 | cmd := exec.CommandContext(ctx, "go", "run", "-race", nm)
36 | cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
37 | return cmd.Run()
38 | })
39 | }
40 | log.Fatal(grp.Wait())
41 | }
42 |
--------------------------------------------------------------------------------
/z_reconn.go:
--------------------------------------------------------------------------------
1 | // +build ignore
2 |
3 | // Copyright 2017 Tamás Gulácsi. All rights reserved.
4 | // Use of this source code is governed by The MIT License
5 | // found in the accompanying LICENSE file.
6 |
7 | package main
8 |
9 | import (
10 | "database/sql"
11 | "log"
12 | "os"
13 | "time"
14 |
15 | _ "gopkg.in/rana/ora.v4"
16 | )
17 |
18 | func main() {
19 | db, err := sql.Open("ora", os.Args[1])
20 | if err != nil {
21 | log.Fatal(err)
22 | }
23 | defer db.Close()
24 |
25 | db.SetMaxOpenConns(20)
26 | err = db.Ping()
27 | if err != nil {
28 | log.Fatal(err)
29 | }
30 |
31 | for {
32 | log.Printf("Current open connections: %d", db.Stats().OpenConnections)
33 | if err := executeSQL(db); err != nil {
34 | log.Printf("%s\n%#v %T", err, err, err)
35 | //panic(err)
36 | log.Println("code:", err.(interface {
37 | Code() int
38 | }).Code())
39 | }
40 |
41 | log.Println("Loop finish, wait for next.")
42 | time.Sleep(5 * time.Second)
43 | }
44 |
45 | //log.Printf("All collect finished\nCurrent open connections: %d", db.Stats().OpenConnections)
46 | }
47 |
48 | func executeSQL(db *sql.DB) error {
49 | var n int64
50 | return db.QueryRow("SELECT COUNT(0) FROM cat").Scan(&n)
51 | }
52 |
--------------------------------------------------------------------------------
/z_resultSet_session_test.go:
--------------------------------------------------------------------------------
1 | //Copyright 2014 Rana Ian. All rights reserved.
2 | //Use of this source code is governed by The MIT License
3 | //found in the accompanying LICENSE file.
4 |
5 | package ora_test
6 |
7 | import (
8 | "fmt"
9 | "testing"
10 |
11 | "gopkg.in/rana/ora.v4"
12 | )
13 |
14 | func Test_cursor1_session(t *testing.T) {
15 | t.Parallel()
16 | testSes := getSes(t)
17 | defer testSes.Close()
18 |
19 | // create table
20 | tableName := tableName()
21 | createTblStmt, err := testSes.Prep(fmt.Sprintf("create table %v (c1 varchar2(48 char), c2 integer)", tableName))
22 | defer createTblStmt.Close()
23 | testErr(err, t)
24 | defer dropTable(tableName, testSes, t)
25 | _, err = createTblStmt.Exe()
26 | testErr(err, t)
27 |
28 | // insert records
29 | expectedStrs := []string{
30 | "Go is expressive, concise, clean, and efficient.",
31 | "Its concurrency mechanisms make it easy to",
32 | "Go compiles quickly to machine code yet has",
33 | }
34 | expectedInt64s := []int64{3, 7, 9}
35 | rowsAffected, err := testSes.PrepAndExe(
36 | fmt.Sprintf("insert into %v (c1, c2) values (:1, :2)", tableName),
37 | expectedStrs, expectedInt64s,
38 | )
39 | testErr(err, t)
40 | if rowsAffected != 3 {
41 | t.Fatalf("Expected 3 rows affected. (rowsAffected %v)", rowsAffected)
42 | }
43 |
44 | // create proc
45 | _, err = testSes.PrepAndExe(fmt.Sprintf("create or replace procedure proc1(p1 out sys_refcursor) as begin open p1 for select c1, c2 from %v order by c2; end proc1;", tableName))
46 | testErr(err, t)
47 |
48 | //enableLogging(t)
49 | // call proc
50 | stmt, err := testSes.Prep("call proc1(:1)")
51 | testErr(err, t)
52 | var rset ora.Rset
53 | _, err = stmt.Exe(&rset)
54 | testErr(err, t)
55 |
56 | if !rset.IsOpen() {
57 | t.Fatalf("rset %#v is closed!", rset)
58 | }
59 | for rset.Next() {
60 | if len(rset.Row) != 2 {
61 | t.Fatalf("select column count: expected(%v), actual(%v)", 2, len(rset.Row))
62 | }
63 | //fmt.Println("rset.Row ", rset.Row)
64 | compare(expectedStrs[0], rset.Row[0], ora.S, t)
65 | compare(expectedInt64s[0], rset.Row[1], ora.I64, t)
66 | expectedStrs = expectedStrs[1:]
67 | expectedInt64s = expectedInt64s[1:]
68 | }
69 | testErr(rset.Err(), t)
70 | if len(expectedStrs) > 0 {
71 | t.Errorf("didn't get wanted %v", expectedStrs)
72 | }
73 | }
74 |
75 | func Test_nested_rset(t *testing.T) {
76 | t.Parallel()
77 | testSes := getSes(t)
78 | defer testSes.Close()
79 |
80 | _, err := testSes.PrepAndExe(`CREATE OR REPLACE PROCEDURE proc2(p_cur OUT SYS_REFCURSOR) IS
81 | BEGIN
82 | OPEN p_cur FOR
83 | SELECT CURSOR(SELECT A.* FROM user_objects A, (SELECT 1 FROM DUAL)) cur FROM DUAL;
84 | END;`)
85 | if err != nil {
86 | t.Fatal(err)
87 | }
88 | //enableLogging(t)
89 | stmt, err := testSes.Prep("call proc2(:1)")
90 | testErr(err, t)
91 | //enableLogging(t)
92 | var rset ora.Rset
93 | func() {
94 | defer func() {
95 | if r := recover(); r != nil {
96 | t.Fatal(r)
97 | }
98 | }()
99 | _, err = stmt.Exe(&rset)
100 | }()
101 | if err != nil {
102 | errs, _ := GetCompileErrors(testSes, false)
103 | t.Errorf("errs: %#v", errs)
104 | t.Fatal(err)
105 | }
106 |
107 | for rset.Next() {
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/z_rowid_session_test.go:
--------------------------------------------------------------------------------
1 | //Copyright 2014 Rana Ian. All rights reserved.
2 | //Use of this source code is governed by The MIT License
3 | //found in the accompanying LICENSE file.
4 |
5 | package ora_test
6 |
7 | import (
8 | "fmt"
9 | "testing"
10 | )
11 |
12 | // test on heap table to retreive ROWID
13 | func TestDefine_string_rowid_session(t *testing.T) {
14 | t.Parallel()
15 | testRowid(false, t)
16 | }
17 |
18 | // test on indexed table to retrieve UROWID
19 | func TestDefine_string_urowid_session(t *testing.T) {
20 | t.Parallel()
21 | testRowid(true, t)
22 | }
23 |
24 | func testRowid(isUrowid bool, t *testing.T) {
25 | testSes := getSes(t)
26 | defer testSes.Close()
27 |
28 | for n := 0; n < testIterations(); n++ {
29 | tableName := tableName()
30 | stmt, err := testSes.Prep(fmt.Sprintf("create table %v (c1 varchar2(48 byte))", tableName))
31 | defer stmt.Close()
32 | testErr(err, t)
33 | _, err = stmt.Exe()
34 | defer dropTable(tableName, testSes, t)
35 | testErr(err, t)
36 | // ROWID is returned from a table without an index
37 | // UROWID is returned from indexed tables
38 | if isUrowid {
39 | stmt, err := testSes.Prep(fmt.Sprintf("create unique index t1_pk on %v (c1)", tableName))
40 | defer stmt.Close()
41 | testErr(err, t)
42 | _, err = stmt.Exe()
43 | testErr(err, t)
44 | }
45 |
46 | // insert
47 | insertStmt, err := testSes.Prep(fmt.Sprintf("insert into %v (c1) values ('go')", tableName))
48 | defer insertStmt.Close()
49 | testErr(err, t)
50 | rowsAffected, err := insertStmt.Exe()
51 | testErr(err, t)
52 | if rowsAffected != 1 {
53 | t.Fatalf("insert rows affected: expected(%v), actual(%v)", 1, rowsAffected)
54 | }
55 |
56 | // select
57 | selectStmt, err := testSes.Prep(fmt.Sprintf("select rowid from %v", tableName))
58 | defer selectStmt.Close()
59 | testErr(err, t)
60 | rset, err := selectStmt.Qry()
61 | testErr(err, t)
62 | hasRow := rset.Next()
63 | testErr(rset.Err(), t)
64 | if !hasRow {
65 | t.Fatalf("%d. no row returned", n)
66 | } else if len(rset.Row) != 1 {
67 | t.Fatalf("%d. select column count: expected(%v), actual(%v)", n, 1, len(rset.Row))
68 | }
69 |
70 | rowid, ok := rset.Row[0].(string)
71 | if !ok {
72 | t.Fatalf("%d. Expected string rowid. (%T, %v)", n, rset.Row[0], rset.Row[0])
73 | }
74 | if rowid == "" {
75 | t.Fatalf("%d. Expected non-empty rowid string. (%v)", n, rowid)
76 | }
77 | //fmt.Printf("rowid (%v)\n", rowid)
78 |
79 | want := "go go go"
80 | updateStmt, err := testSes.Prep(fmt.Sprintf("update %v set c1 = :1 where rowid = :2", tableName))
81 | defer updateStmt.Close()
82 | testErr(err, t)
83 | rowsAffected, err = updateStmt.Exe(want, rowid)
84 | testErr(err, t)
85 | if rowsAffected != 1 {
86 | t.Fatalf("%d. update rows affected: expected(%v), actual(%v)", n, 1, rowsAffected)
87 | }
88 |
89 | stmtSelect2, err := testSes.Prep(fmt.Sprintf("select c1 from %v", tableName))
90 | defer stmtSelect2.Close()
91 | testErr(err, t)
92 | rset2, err := stmtSelect2.Qry()
93 | testErr(err, t)
94 | rset2.Next()
95 | testErr(rset2.Err(), t)
96 | c1, ok := rset2.Row[0].(string)
97 | if !ok {
98 | t.Fatalf("%d. Expected string for c1 column. (%T, %v)", n, rset2.Row[0], rset2.Row[0])
99 | }
100 | //fmt.Printf("c1 (%v)\n", c1)
101 | if c1 != want {
102 | t.Fatalf("%d. Got %q, wanted %q.", n, c1, want)
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/z_time_session_test.go:
--------------------------------------------------------------------------------
1 | //Copyright 2014 Rana Ian. All rights reserved.
2 | //Use of this source code is governed by The MIT License
3 | //found in the accompanying LICENSE file.
4 |
5 | package ora_test
6 |
7 | import (
8 | "fmt"
9 | "strings"
10 | "testing"
11 |
12 | ora "gopkg.in/rana/ora.v4"
13 | )
14 |
15 | var _T_timeCols = []string{
16 | "date", "dateNull",
17 | "time", "timeNull",
18 | "timestampP9", "timestampP9Null",
19 | "timestampTzP9", "timestampTzP9Null",
20 | "timestampLtzP9", "timestampLtzP9Null",
21 | }
22 |
23 | func TestBindDefine_time(t *testing.T) {
24 | sc := ora.NewStmtCfg()
25 | for valName, gen := range map[string](func() interface{}){
26 | "date": func() interface{} { return gen_date() },
27 | "OraDate": func() interface{} { return gen_OraDate(false) },
28 | "OraDateNull": func() interface{} { return gen_OraDate(true) },
29 | "dateSlice": func() interface{} { return gen_dateSlice() },
30 | "OraDateSlice": func() interface{} { return gen_OraDateSlice(false) },
31 | "OraDateSliceNull": func() interface{} { return gen_OraDateSlice(true) },
32 |
33 | "time": func() interface{} { return gen_time() },
34 | "OraTime": func() interface{} { return gen_OraTime(false) },
35 | "OraTimeNull": func() interface{} { return gen_OraTime(true) },
36 | "timeSlice": func() interface{} { return gen_timeSlice() },
37 | "OraTimeSlice": func() interface{} { return gen_OraTimeSlice(false) },
38 | "OraTimeSliceNull": func() interface{} { return gen_OraTimeSlice(true) },
39 | } {
40 | valName := valName
41 | gen := gen
42 | for _, ctName := range _T_timeCols {
43 | if strings.HasSuffix(valName, "Null") && !strings.HasSuffix(ctName, "Null") {
44 | continue
45 | }
46 | if strings.HasPrefix(ctName, "time") && !strings.Contains(valName, "ime") {
47 | continue
48 | }
49 | if strings.HasPrefix(ctName, "date") && !strings.Contains(valName, "ate") {
50 | continue
51 | }
52 | ct := _T_colType[ctName]
53 | t.Run(fmt.Sprintf("%s_%s", valName, ctName), func(t *testing.T) {
54 | t.Parallel()
55 | v := gen()
56 | testBindDefine(v, ct, t, sc)
57 | if vName := fmt.Sprintf("%T", v); strings.HasPrefix(vName, "[]") || strings.EqualFold(vName[:3], "ora") {
58 | return
59 | }
60 | testBindPtr(v, ct, t)
61 | })
62 | }
63 | }
64 | }
65 |
66 | func TestMultiDefine_date_session(t *testing.T) {
67 | for _, ctName := range []string{"date"} {
68 | t.Run(ctName, func(t *testing.T) {
69 | testMultiDefine(gen_date(), _T_colType[ctName], t)
70 | })
71 | }
72 | }
73 |
74 | func TestWorkload_date_session(t *testing.T) {
75 | for _, ctName := range _T_timeCols {
76 | t.Run(ctName, func(t *testing.T) {
77 | testWorkload(_T_colType[ctName], t)
78 | })
79 | }
80 | }
81 |
--------------------------------------------------------------------------------