Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
tgulacsi committed Jun 24, 2017
0 parents commit c0222ba
Show file tree
Hide file tree
Showing 19 changed files with 2,290 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.dsn
*.test
*/build/*
*~*
*.swp
env.sh
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "odpi"]
path = odpi
url = ./odpi
27 changes: 27 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
language: go
sudo: required

go:
- 1.4.2
#- tip
env:
# alias travis='docker run --rm -v $PWD:/repo -v ~/.travis:/travis andredumas/travis-ci-cli'
# travis encrypt -r tgulacsi/ora 'AWS_ACCESS_KEY_ID=...' 'AWS_SECRET_ACCESS_KEY=...+hMtiMhFbmUhu2zB+UyjUdGveIMvWBRIV' 'GO_ORA_DRV_TEST_DB=host:port/sid' GO_ORA_DRV_TEST_USERNAME=... GO_ORA_DRV_TEST_PASSWORD=...
- secure: "OksEWQRpzRuwmO3LkXfHk7DQWNUZgeI8iM2DJlCY7g/89gVCKMy4dUyuPAdnU7dYKXIb51KIpwgwM+iOHzRPKRt92CwM3A/lfqOLabZs0JuwOp1LTN9A3fLEU1nqfqyXeSA6+TMy1n3RWm80KCOrH/vwouSPJL3KFITci8jUE6g="
before_install:
- wget https://github.com/barnybug/s3/releases/download/1.0.0/s3-linux-amd64 && mv s3-linux-amd64 s3 && chmod +x s3
- ./s3 get s3://tgulacsi-oracle-instantclient/
- sudo apt-get install libaio1
- sudo dpkg -i oracle-instantclient12.1-basiclite_12.1.0.2.0-2_amd64.deb
- sudo dpkg -i oracle-instantclient12.1-devel_12.1.0.2.0-2_amd64.deb
- echo /usr/lib/oracle/12.1/client64/lib/ | sudo tee /etc/ld.so.conf.d/oracle.conf && sudo ldconfig
- export CGO_CFLAGS=-I/usr/include/oracle/12.1/client64
- export CGO_LDFLAGS=-L/usr/lib/oracle/12.1/client64/lib
- mkdir -p $HOME/gopath/src/gopkg.in
- ln -s $HOME/gopath/src/github.com/go-goracle/goracle $HOME/gopath/src/gopkg.in/goracle.v1
install: go get -t gopkg.in/goracle.v1
before_script:
- cd $HOME/gopath/src/gopkg.in/goracle.v1
- go test -i . ./oracle/
script:
- go test . ./oracle '-dsn=system/[email protected]:49161/xe'
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright 2017 Tamás Gulácsi

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
2 changes: 2 additions & 0 deletions NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Database Change Notification vs. Query Result Change Notification #
See http://comments.gmane.org/gmane.comp.python.db.cx-oracle/2944
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[![Build Status](https://travis-ci.org/go-goracle/goracle.svg?branch=v2)](https://travis-ci.org/go-goracle/goracle)
[![GoDoc](https://godoc.org/gopkg.in/goracle.v2?status.svg)](http://godoc.org/gopkg.in/goracle.v2)

# goracle #
[goracle](driver.go) is a package which is a
[database/sql/driver.Driver](http://golang.org/pkg/database/sql/driver/#Driver)
for connecting to Oracle DB, using Anthony Tuininga's excellent OCI wrapper,
[ODPI-C](https://www.github.com/oracle/odpi).

# Install #
It is `go get`'able with `go get gopkg.in/goracle.v2`
iff you have
[ODPI-C](https://www.github.com/oracle/odpi) installed.

Otherwise, after the `go get` failed,

cd $GOPATH/src/gopkg.in/goracle.v2/odpi
make
cd ..
go install

.
208 changes: 208 additions & 0 deletions conn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
// Copyright 2017 Tamás Gulácsi
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package goracle is a database/sql/driver for Oracle DB.
package goracle

/*
#cgo CFLAGS: -Iodpi/src -Iodpi/include
#cgo LDFLAGS: -Lodpi/lib -lodpic -ldl
#include "dpiImpl.h"
*/
import "C"

import (
"context"
"database/sql"
"database/sql/driver"
"unsafe"

"github.com/pkg/errors"
)

var _ = driver.Conn((*conn)(nil))
var _ = driver.ConnBeginTx((*conn)(nil))
var _ = driver.ConnPrepareContext((*conn)(nil))
var _ = driver.Pinger((*conn)(nil))

type conn struct {
dpiConn *C.dpiConn
connString string
inTransaction bool
*drv
}

func (c *conn) Break() error {
if C.dpiConn_breakExecution(c.dpiConn) == C.DPI_FAILURE {
return c.getError()
}
return nil
}

func (c *conn) Ping(ctx context.Context) error {
if err := ctx.Err(); err != nil {
return err
}
done := make(chan struct{}, 1)
go func() {
select {
case <-done:
case <-ctx.Done():
_ = c.Break()
}
}()
ok := C.dpiConn_ping(c.dpiConn) == C.DPI_FAILURE
done <- struct{}{}
if !ok {
return c.getError()
}
return nil
}

// Prepare returns a prepared statement, bound to this connection.
func (c *conn) Prepare(query string) (driver.Stmt, error) {
return c.PrepareContext(context.Background(), query)
}

// Close invalidates and potentially stops any current
// prepared statements and transactions, marking this
// connection as no longer in use.
//
// Because the sql package maintains a free pool of
// connections and only calls Close when there's a surplus of
// idle connections, it shouldn't be necessary for drivers to
// do their own connection caching.
func (c *conn) Close() error {
if C.dpiConn_release(c.dpiConn) == C.DPI_FAILURE {
return c.getError()
}
c.dpiConn = nil
return nil
}

// Begin starts and returns a new transaction.
//
// Deprecated: Drivers should implement ConnBeginTx instead (or additionally).
func (c *conn) Begin() (driver.Tx, error) {
return c.BeginTx(context.Background(), driver.TxOptions{})
}

// BeginTx starts and returns a new transaction.
// If the context is canceled by the user the sql package will
// call Tx.Rollback before discarding and closing the connection.
//
// This must check opts.Isolation to determine if there is a set
// isolation level. If the driver does not support a non-default
// level and one is set or if there is a non-default isolation level
// that is not supported, an error must be returned.
//
// This must also check opts.ReadOnly to determine if the read-only
// value is true to either set the read-only transaction property if supported
// or return an error if it is not supported.
func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
if err := ctx.Err(); err != nil {
return nil, err
}
if opts.ReadOnly {
return nil, errors.New("read-only transaction property is not supported")
}
switch level := sql.IsolationLevel(opts.Isolation); level {
case sql.LevelDefault, sql.LevelReadCommitted:
default:
return nil, errors.Errorf("%v isolation level is not supported", sql.IsolationLevel(opts.Isolation))
}

dc, err := c.drv.Open(c.connString)
if err != nil {
return nil, err
}
c2 := dc.(*conn)
c2.inTransaction = true
return c2, err
}

// PrepareContext returns a prepared statement, bound to this connection.
// context is for the preparation of the statement,
// it must not store the context within the statement itself.
func (c *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
if err := ctx.Err(); err != nil {
return nil, err
}
cSQL := C.CString(query)
defer func() {
C.free(unsafe.Pointer(cSQL))
}()
var dpiStmt *C.dpiStmt
if C.dpiConn_prepareStmt(c.dpiConn, 0, cSQL, C.uint32_t(len(query)), nil, 0,
(**C.dpiStmt)(unsafe.Pointer(&dpiStmt)),
) == C.DPI_FAILURE {
return nil, c.getError()
}
//fmt.Printf("PrepareContext(%q):%p\n", query, dpiStmt)
return &statement{conn: c, dpiStmt: dpiStmt}, nil
}
func (c *conn) Commit() error {
c.inTransaction = false
if C.dpiConn_commit(c.dpiConn) == C.DPI_FAILURE {
return c.getError()
}
return nil
}
func (c *conn) Rollback() error {
c.inTransaction = false
if C.dpiConn_rollback(c.dpiConn) == C.DPI_FAILURE {
return c.getError()
}
return nil
}

func (c *conn) newVar(isPlSQLArray bool, typ C.dpiOracleTypeNum, natTyp C.dpiNativeTypeNum, arraySize int, bufSize int) (*C.dpiVar, []C.dpiData, error) {
if c == nil || c.dpiConn == nil {
return nil, nil, errors.New("connection is nil")
}
isArray := C.int(0)
if isPlSQLArray {
isArray = 1
}
var dataArr *C.dpiData
var v *C.dpiVar
if C.dpiConn_newVar(
c.dpiConn, typ, natTyp, C.uint32_t(arraySize),
C.uint32_t(bufSize), 1,
isArray, nil,
&v, &dataArr,
) == C.DPI_FAILURE {
return nil, nil, errors.Wrapf(c.getError(), "newVar(typ=%d, natTyp=%d, arraySize=%d, bufSize=%d)", typ, natTyp, arraySize, bufSize)
}
// https://github.com/golang/go/wiki/cgo#Turning_C_arrays_into_Go_slices
/*
var theCArray *C.YourType = C.getTheArray()
length := C.getTheArrayLength()
slice := (*[1 << 30]C.YourType)(unsafe.Pointer(theCArray))[:length:length]
*/
data := ((*[maxArraySize]C.dpiData)(unsafe.Pointer(dataArr)))[:arraySize:arraySize]
if false {
n := arraySize
if n > 10 {
n = 10
}
//fmt.Printf("dpiConn_newVar(dpiConn=%p, typ=%d, natTyp=%d, arraySize=%d, bufSize=%d, isBytes=%d, isArray=%d, obj=%p, *dpiVar=%p, *dataArr=%p): %#v\n",
// c.dpiConn, typ, natTyp, arraySize, bufSize, 1, isArray, nil, &v, &dataArr, data[:n])
}
return v, data, nil
}

var _ = driver.Tx((*conn)(nil))
12 changes: 12 additions & 0 deletions contrib/odpi-local.pc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
prefix=${pcfiledir}/../odpi

libdir=${prefix}/lib
includedir=${prefix}/include
srcdir=${prefix}/src

Name: odpi
Description: ODPI-C library
Version: 2.0.0-beta4
Libs: -L${libdir} -lodpic
Libs.private:
Cflags: -I${includedir} -I${srcdir}
1 change: 1 addition & 0 deletions contrib/odpi.pc
14 changes: 14 additions & 0 deletions contrib/odpi_darwin.pc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
prefix=/Users/dfils/src/odpi

version=2.0.0-beta4
build=odpi64

libdir=${prefix}
includedir=${prefix}/sdk/include

Name: oci8
Description: Oracle database engine
Version: ${version}
Libs: -L${libdir} -lodpi
Libs.private:
Cflags: -I${includedir}
14 changes: 14 additions & 0 deletions contrib/odpi_linux_386.pc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
prefix=/usr

version=2.0.0-beta4
build=odpi32

libdir=${prefix}/lib/odpi/${version}/${build}/lib
includedir=${prefix}/include/odpi/${version}/${build}

Name: odpi
Description: ODPI-C library
Version: ${version}
Libs: -L${libdir} -lodpi
Libs.private:
Cflags: -I${includedir}
14 changes: 14 additions & 0 deletions contrib/odpi_linux_amd64.pc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
prefix=/usr

version=2.0.0-beta4
build=odpi64

libdir=${prefix}/lib/odpi/${version}/${build}/lib
includedir=${prefix}/include/odpi/${version}/${build}

Name: odpi
Description: ODPI-C library
Version: ${version}
Libs: -L${libdir} -lodpi
Libs.private:
Cflags: -I${includedir}
18 changes: 18 additions & 0 deletions contrib/odpi_windows_amd64.pc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
prefix=c:/Oracle64Instant/sdk

version=2.0.0-beta4
build=odpi64

libdir=${prefix}/lib
includedir=${prefix}/include

glib_genmarshal=glib-genmarshal
gobject_query=gobject-query
glib_mkenums=glib-mkenums

Name: odpi
Description: ODPI-C library
Version: ${version}
Libs: -L${libdir} -lodpi
Libs.private:
Cflags: -I${includedir}
Loading

0 comments on commit c0222ba

Please sign in to comment.