|
@@ -59,16 +59,22 @@ func (xgConn *xuguConn) Get_error() error {
|
|
|
|
|
|
func (xgConn *xuguConn) Begin() (driver.Tx, error) {
|
|
|
|
|
|
- return nil, nil
|
|
|
+ _, err := xgConn.exec("set auto_commit off;")
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return &xuguTx{tconn: xgConn}, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
var prepareCount = 0
|
|
|
|
|
|
func (xgConn *xuguConn) Prepare(sql string) (driver.Stmt, error) {
|
|
|
+ xgConn.mu.Lock()
|
|
|
fmt.Println(">>>>>(xgConn *xuguConn) Prepare(query string)")
|
|
|
prepareName := fmt.Sprintf("GTONG%d", prepareCount)
|
|
|
-
|
|
|
+ prepareCount++
|
|
|
|
|
|
switch switchSQLType(sql) {
|
|
|
case SQL_PROCEDURE:
|
|
@@ -83,7 +89,6 @@ func (xgConn *xuguConn) Prepare(sql string) (driver.Stmt, error) {
|
|
|
parser := &xuguParse{
|
|
|
bind_type: 0,
|
|
|
param_count: 0,
|
|
|
- position: 0,
|
|
|
}
|
|
|
count := parser.assertParamCount(sql)
|
|
|
parser.param_count = count
|
|
@@ -110,6 +115,7 @@ func (xgConn *xuguConn) Prepare(sql string) (driver.Stmt, error) {
|
|
|
prepareName = fmt.Sprintf("? %s ", prepareName)
|
|
|
stmt.prename = []byte(prepareName)
|
|
|
xgConn.prepareName = prepareName
|
|
|
+ xgConn.mu.Unlock()
|
|
|
return stmt, nil
|
|
|
}
|
|
|
|
|
@@ -125,6 +131,7 @@ func (xgConn *xuguConn) Close() error {
|
|
|
|
|
|
func (xgConn *xuguConn) Exec(sql string,
|
|
|
args []driver.Value) (driver.Result, error) {
|
|
|
+
|
|
|
fmt.Printf(">>> (xgConn *xuguConn) Exec: %s, %v\n", sql, args)
|
|
|
|
|
|
if switchSQLType(sql) == SQL_SELECT {
|
|
@@ -142,7 +149,6 @@ func (xgConn *xuguConn) Exec(sql string,
|
|
|
parser := &xuguParse{
|
|
|
bind_type: 0,
|
|
|
param_count: len(args),
|
|
|
- position: 0,
|
|
|
}
|
|
|
|
|
|
for pos, param := range args {
|
|
@@ -158,11 +164,31 @@ func (xgConn *xuguConn) Exec(sql string,
|
|
|
fmt.Println("Message from server EXEC:", readBuf.buf[readBuf.idx:])
|
|
|
fmt.Println("Message from server EXEC:", string(xgConn.readBuff.buf))
|
|
|
|
|
|
- rs, err := parseMsg(readBuf, xgConn)
|
|
|
+ aR, err := parseMsg(readBuf, xgConn)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
- return rs, nil
|
|
|
+ switch aR.rt {
|
|
|
+ case insertResult:
|
|
|
+
|
|
|
+ return &xuguResult{
|
|
|
+ affectedRows: int64(0),
|
|
|
+ insertId: int64(0),
|
|
|
+ }, nil
|
|
|
+
|
|
|
+ case errInfo:
|
|
|
+
|
|
|
+ return nil, errors.New(string(aR.e.ErrStr))
|
|
|
+ case warnInfo:
|
|
|
+
|
|
|
+ return nil, errors.New(string(aR.w.WarnStr))
|
|
|
+ default:
|
|
|
+ return &xuguResult{
|
|
|
+ affectedRows: int64(0),
|
|
|
+ insertId: int64(0),
|
|
|
+ }, nil
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
rs, err := xgConn.exec(sql)
|
|
@@ -183,11 +209,29 @@ func (xgConn *xuguConn) exec(sql string) (driver.Result, error) {
|
|
|
fmt.Println("Message from server EXEC:", readBuf.buf[readBuf.idx:])
|
|
|
fmt.Println("Message from server EXEC:", string(xgConn.readBuff.buf))
|
|
|
|
|
|
- rs, err := parseMsg(readBuf, xgConn)
|
|
|
+ aR, err := parseMsg(readBuf, xgConn)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
- return rs, nil
|
|
|
+
|
|
|
+ switch aR.rt {
|
|
|
+ case insertResult:
|
|
|
+ return &xuguResult{
|
|
|
+ affectedRows: int64(0),
|
|
|
+ insertId: int64(0),
|
|
|
+ }, nil
|
|
|
+
|
|
|
+ case errInfo:
|
|
|
+ return nil, errors.New(string(aR.e.ErrStr))
|
|
|
+ case warnInfo:
|
|
|
+ return nil, errors.New(string(aR.w.WarnStr))
|
|
|
+ default:
|
|
|
+ return &xuguResult{
|
|
|
+ affectedRows: int64(0),
|
|
|
+ insertId: int64(0),
|
|
|
+ }, nil
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
func (xgConn *xuguConn) Query(sql string,
|
|
@@ -198,24 +242,49 @@ func (xgConn *xuguConn) Query(sql string,
|
|
|
return nil, errors.New("The executed SQL statement is not a SELECT")
|
|
|
}
|
|
|
|
|
|
- parser := &xuguParse{
|
|
|
- bind_type: 0,
|
|
|
- param_count: 0,
|
|
|
- position: 0,
|
|
|
- }
|
|
|
-
|
|
|
if len(args) != 0 {
|
|
|
-
|
|
|
+ parser := &xuguParse{
|
|
|
+ bind_type: 0,
|
|
|
+ param_count: len(args),
|
|
|
+ }
|
|
|
for pos, param := range args {
|
|
|
-
|
|
|
err := parser.assertParamType(param, pos)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
}
|
|
|
+ sockSendPutStatement(xgConn, []byte(xgConn.prepareName), &parser.values, len(args))
|
|
|
+ XGC_Execute(xgConn)
|
|
|
+
|
|
|
+
|
|
|
+ xgConn.conn.Read(xgConn.readBuff.buf)
|
|
|
+ readBuf := &xgConn.readBuff
|
|
|
+ fmt.Println("Message from server EXEC:", readBuf.buf[readBuf.idx:])
|
|
|
+ fmt.Println("Message from server EXEC:", string(xgConn.readBuff.buf))
|
|
|
+
|
|
|
+ aR, err := parseMsg(readBuf, xgConn)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ switch aR.rt {
|
|
|
+ case selectResult:
|
|
|
+ rows := &xuguRows{
|
|
|
+ rows_conn: xgConn,
|
|
|
+ results: aR.s,
|
|
|
+ lastRowRelt: int(0),
|
|
|
+ lastRelt: int(0),
|
|
|
+ prepared: false,
|
|
|
+ }
|
|
|
+
|
|
|
+ return rows, nil
|
|
|
+ case errInfo:
|
|
|
+
|
|
|
+ return nil, errors.New(string(aR.e.ErrStr))
|
|
|
+ case warnInfo:
|
|
|
+
|
|
|
+ return nil, errors.New(string(aR.w.WarnStr))
|
|
|
+ default:
|
|
|
|
|
|
- if len(parser.values) != parser.assertParamCount(sql) {
|
|
|
- return nil, errors.New("The number of parameters does not match")
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -264,3 +333,27 @@ func (xgConn *xuguConn) Ping(ctx context.Context) error {
|
|
|
xgConn.readBuff.buf = make([]byte, 2048)
|
|
|
return nil
|
|
|
}
|
|
|
+
|
|
|
+func (pConn *xuguConn) ExecContext(ctx context.Context,
|
|
|
+ query string, args []driver.NamedValue) (driver.Result, error) {
|
|
|
+
|
|
|
+ Value, err := namedValueToValue(args)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return pConn.Exec(query, Value)
|
|
|
+}
|
|
|
+
|
|
|
+func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) {
|
|
|
+ __Par := make([]driver.Value, len(named))
|
|
|
+
|
|
|
+ for pos, Param := range named {
|
|
|
+ if len(Param.Name) > 0 {
|
|
|
+ return nil, errors.New("Driver does not support the use of Named Parameters")
|
|
|
+ }
|
|
|
+ __Par[pos] = Param.Value
|
|
|
+ }
|
|
|
+
|
|
|
+ return __Par, nil
|
|
|
+}
|