/
oraex.go
141 lines (124 loc) · 3.59 KB
/
oraex.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// oraex
package oracleex
import (
"code.google.com/p/go-uuid/uuid"
"fmt"
"gopkg.in/errgo.v1"
"gopkg.in/goracle.v1/oracle"
"time"
)
type Connection struct {
oracle.Connection
holder string
streamID string
}
func NewConnection(username, password, dsn string, autocommit bool, holder, streamID string) (
conn *Connection, err error) {
bg := time.Now()
conn = &Connection{holder: holder, streamID: streamID}
if conn.streamID == "" {
conn.streamID = uuid.New()
}
var connTmp *oracle.Connection
connTmp, err = oracle.NewConnection(username, password, dsn, autocommit)
if err != nil {
conn = nil
loginCmd(holder, streamID, username, password, dsn, bg, time.Now(), false, err.Error())
return
}
conn.Connection = *connTmp
loginCmd(conn.holder, conn.streamID, username, password, dsn, bg, time.Now(), true, "")
return
}
func (conn *Connection) Close() (err error) {
if conn.IsConnected() {
bg := time.Now()
err = conn.Connection.Close()
if err != nil {
logoutCmd(conn.holder, conn.streamID, bg, time.Now(), false, err.Error())
return err
}
logoutCmd(conn.holder, conn.streamID, bg, time.Now(), true, "")
}
return nil
}
func (conn *Connection) Cursor() *Cursor {
cur := &Cursor{holder: conn.holder, streamID: conn.streamID}
cur.Cursor = *oracle.NewCursor(&conn.Connection)
return cur
}
func (conn *Connection) NewCursor() *Cursor {
return conn.Cursor()
}
type Cursor struct {
oracle.Cursor
holder string
streamID string
}
func (cur *Cursor) Execute(statement string, listArgs []interface{}, keywordArgs map[string]interface{}) error {
bg := time.Now()
stm := statement
params := keywordArgs
var (
err error
serverBgVar *oracle.Variable
serverFnVar *oracle.Variable
serverFnScnVar *oracle.Variable
serverBg = time.Time{}
serverFn = time.Time{}
serverFnScn string
)
if cur.holder != "" {
stm = fmt.Sprintf(stmWithStats, statement)
serverBgVar, err = cur.NewVariable(0, oracle.StringVarType, 100)
if err != nil {
return errgo.Newf("error creating variable for %s: %s", "serverBg", err)
}
serverFnVar, err = cur.NewVariable(0, oracle.StringVarType, 100)
if err != nil {
return errgo.Newf("error creating variable for %s: %s", "serverFn", err)
}
serverFnScnVar, err = cur.NewVariable(0, oracle.StringVarType, 200)
if err != nil {
return errgo.Newf("error creating variable for %s: %s", "serverFnScn", err)
}
params["яbg"] = serverBgVar
params["яfn"] = serverFnVar
params["яfn_scn"] = serverFnScnVar
}
err = cur.Cursor.Execute(stm, nil, params)
if cur.holder != "" {
paramVal, err1 := serverBgVar.GetValue(0)
if err1 == nil {
serverBg, _ = time.Parse("2006-01-02 15:04:05.999999999 -07:00", paramVal.(string))
}
paramVal, err1 = serverFnVar.GetValue(0)
if err1 == nil {
serverFn, _ = time.Parse("2006-01-02 15:04:05.999999999 -07:00", paramVal.(string))
}
paramVal, err1 = serverFnScnVar.GetValue(0)
if err1 == nil {
serverFnScn, _ = paramVal.(string)
}
delete(params, "яbg")
delete(params, "яfn")
delete(params, "яfn_scn")
}
if err != nil {
if cur.holder != "" {
execCmd(cur.holder, cur.streamID, statement, params, bg, time.Now(), serverBg, serverFn, serverFnScn, false, err.Error())
}
return err
}
if cur.holder != "" {
execCmd(cur.holder, cur.streamID, statement, params, bg, time.Now(), serverBg, serverFn, serverFnScn, true, "")
}
return nil
}
const stmWithStats = `
begin
:яbg := to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS.FF TZH:TZM');
%s
:яfn := to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS.FF TZH:TZM');
:яfn_scn := get_system_change_number();
end;`