123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- package xugu
- import (
- "errors"
- "fmt"
- "strings"
- )
- // cgo_xgc_sql_type -> fun_sql_type
- // 判断sql类型
- func xgSqlType(sql string) int {
- // 去掉首尾的空格、换行符和回车符
- sql = strings.TrimSpace(sql)
- if len(sql) < 6 {
- return SQL_OTHER
- }
- // 取前6个字符并转为大写
- kstr := strings.ToUpper(sql[:6])
- // 根据SQL语句前缀判断类型
- switch {
- case strings.HasPrefix(kstr, "SELECT"):
- if strings.Contains(sql, ";") && len(sql[strings.Index(sql, ";"):]) > 5 {
- return SQL_OTHER // 多结果集
- }
- return SQL_SELECT
- case strings.HasPrefix(kstr, "INSERT"):
- return SQL_INSERT
- case strings.HasPrefix(kstr, "UPDATE"):
- return SQL_UPDATE
- case strings.HasPrefix(kstr, "DELETE"):
- return SQL_DELETE
- case strings.HasPrefix(kstr, "CREATE"):
- return SQL_CREATE
- case strings.HasPrefix(kstr, "ALTER "):
- return SQL_ALTER
- case strings.HasPrefix(kstr, "EXEC "):
- return SQL_PROCEDURE
- case strings.HasPrefix(kstr, "EXECUT"):
- return SQL_PROCEDURE
- case strings.HasPrefix(kstr, "STC"):
- return SQL_SELECT
- default:
- return SQL_OTHER
- }
- }
- func xgSockPrepare(conn *xugusqlConn, sql string) (int, error) {
- ret := 0
- //p_params := &conn.params
- if conn.havePrepare != 0 {
- ret = xgCmdUnprepare(conn, conn.prepareName)
- if ret < 0 {
- return ret, nil
- }
- conn.prepareName = ""
- }
- conn.prepareName = fmt.Sprintf(conn.prepareName+"STC%d", conn.prepareNo)
- ret, err := xgCmdPrepare(conn, sql, &conn.prepareName)
- if err != nil {
- return ret, err
- }
- return ret, err
- }
- // SQL语句prepare准备执行
- func xgSockPrepare2(conn *xugusqlConn, cmd_sql string, prepareName *string) (int, error) {
- if "" == *prepareName {
- return xgSockPrepare(conn, cmd_sql)
- }
- ret := 0
- pconn := conn
- // XGCSParam* p_params= pconn->params;
- old_p := pconn.havePrepare
- // char* sql=strdup(cmd_sql);
- *prepareName = fmt.Sprintf("STC%d", pconn.prepareNo)
- pconn.prepareNo++ // 递增 prepare_no 的值
- ret, err := xgCmdPrepare(conn, cmd_sql, &conn.prepareName)
- if err != nil {
- return 0, err
- }
- pconn.havePrepare = old_p // this keeped by prepare_name
- return ret, nil
- }
- func xgCmdUnprepare(pconn *xugusqlConn, prepareName string) int {
- var ch byte
- var err error
- ret := XG_OK
- sql := fmt.Sprintf("DEALLOCATE %s ", prepareName)
- pconn.mu.Lock()
- sockSendCommand0(pconn, sql)
- boolRet, err := rhRecvChar(pconn, &ch)
- if boolRet || err != nil {
- ret = XG_NET_ERROR
- } else if ch == 'K' {
- pconn.havePrepare = 0
- } else {
- pconn.havePrepare = 0
- var errStre []byte
- ret, err = rhRecvStr(pconn, &errStre)
- if err != nil || ret < 0 {
- pconn.mu.Unlock()
- return ret
- }
- rhRecvChar(pconn, &ch)
- ret = XG_ERROR
- }
- pconn.mu.Unlock()
- return 0
- }
- func xgCmdPrepare(pconn *xugusqlConn, cmd_sql string, prepareName *string) (int, error) {
- sqlRet := fmt.Sprintf("PREPARE %s AS %s", prepareName, cmd_sql)
- //上锁
- //lockConnect(pconn)
- pconn.mu.Lock()
- sockSendCommand0(pconn, sqlRet)
- var ch byte
- var ret int
- for {
- recvRet, err := rhRecvChar(pconn, &ch)
- if err != nil {
- return 0, err
- }
- if !recvRet {
- pconn.mu.Unlock()
- return -4, errors.New("XG_NET_ERROR")
- }
- //A: SelectResult A在协议里为select返回
- if ch == 'A' {
- pres := Result{}
- pres.Type = HT_RS
- ret, err = recvFiledsInfo(pconn, &pres)
- if err != nil {
- return ret, err
- }
- pconn.presPrepareCata = &pres
- ret = RETURN_PREPARE_SELECT
- continue
- } else if ch == '$' {
- var params XGCSParam
- params.Type = HT_PARAMS
- params.ImpExpType = 2
- recvParamsInfo2(pconn, ¶ms)
- pconn.params = ¶ms
- continue
- } else if ch == 'K' {
- pconn.havePrepare = 1
- } else {
- var errStr []byte
- ret, err = rhRecvStr(pconn, &errStr)
- if ret < 0 || err != nil {
- pconn.mu.Unlock()
- return ret, err
- }
- pconn.errStr = errStr
- ret = XG_ERROR
- rhRecvChar(pconn, &ch)
- if ch != 'K' {
- pconn.bkChar = ch
- continue
- }
- }
- break
- }
- pconn.mu.Unlock()
- return ret, nil
- }
|