123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- package xugu
- import (
- "database/sql/driver"
- "errors"
- "fmt"
- )
- type xuguStmt struct {
- // 上下文连接句柄指针
- stmt_conn *xuguConn
- // 布尔值,用于标识执行的 SQL 语句是否已准备好
- prepared bool
- // 接受准备好的 SQL 语句的代码
- prename []byte
- // 布尔值,用于标识游标是否启用
- curopend bool
- // 游标名称
- curname []byte
- // 执行的 SQL 语句中的参数数量
- paramCount int
- mysql string
- //需替换的参数字段信息
- parser *xuguParse
- }
- /* Collect error information from the database server */
- func (self *xuguStmt) get_error() error {
- // message := cgo_c_calloc(ERROR_BUFF_SIZE)
- // defer func() {
- // cgo_c_free(unsafe.Pointer(message))
- // }()
- // var length C.int
- // cgo_xgc_error(&self.stmt_conn, message, &length)
- // return errors.New(C.GoString(message))
- return errors.New("xuguStmt error")
- }
- /* {{ */
- func (stmt *xuguStmt) Close() error {
- fmt.Println("\n>>>>>> (stmt *xuguStmt) Close method called")
- return nil
- }
- func (stmt *xuguStmt) NumInput() int {
- fmt.Println("\n>>>>>(stmt *xuguStmt) NumInput()")
- parser := &xuguParse{
- bind_type: 0,
- param_count: 0,
- position: 0,
- }
- fmt.Println("stmt.mysql: ", stmt.mysql)
- return parser.assertParamCount(stmt.mysql)
- //return 0
- }
- func (stmt *xuguStmt) Exec(args []driver.Value) (driver.Result, error) {
- fmt.Println(">>>>>>>Exec method called")
- fmt.Println("--args ", args)
- // result := &xuguResult{
- // affectedRows: 0,
- // insertId: 0,
- // }
- //参数类型绑定
- if stmt.paramCount > 0 && len(args) > 0 {
- for pos, param := range args {
- stmt.parser.assertParamType(param, pos)
- //fmt.Printf("Field Name: %s, Field Type: %s, Field Value: %v\n", v1, v1, v1)
- }
- sockSendPutStatement(stmt.stmt_conn, stmt.prename, &stmt.parser.values, stmt.paramCount)
- XGC_Execute(stmt.stmt_conn)
- } else {
- //最终发送消息给服务器
- sockSendPutStatement(stmt.stmt_conn, []byte(stmt.mysql), nil, 0)
- XGC_Execute(stmt.stmt_conn)
- }
- //处理服务器返回
- stmt.stmt_conn.conn.Read(stmt.stmt_conn.readBuff.buf)
- readBuf := &stmt.stmt_conn.readBuff
- fmt.Println("Message from server EXEC:", readBuf.buf[readBuf.idx:])
- fmt.Println("Message from server EXEC:", string(stmt.stmt_conn.readBuff.buf))
- //循环读,多条语句执行,会有多条语句返回
- //读取一字节
- rs, err := parseMsg(readBuf, stmt.stmt_conn)
- if err != nil {
- return nil, err
- }
- return rs, nil
- // for {
- // char := readBuf.peekChar()
- // //fmt.Println("Exec 内的 peekChar: ", char)
- // switch char {
- // case 'K':
- // fmt.Println("消息类型为K")
- // return result, nil
- // case '$':
- // readBuf.idx++
- // fmt.Println("消息类型为$")
- // parseFormArgDescri(readBuf)
- // case 'I':
- // readBuf.idx++
- // fmt.Println("消息类型为I")
- // parseInsertResult(readBuf)
- // case 'U':
- // fmt.Println("消息类型为U")
- // readBuf.idx++
- // parseUpdateResult(readBuf)
- // case 'D':
- // fmt.Println("消息类型为D")
- // readBuf.idx++
- // parseDeleteResult(readBuf)
- // case 'E':
- // fmt.Println("消息类型为E")
- // readBuf.idx++
- // pErr, err := parseErrInfo(readBuf)
- // if err != nil {
- // return nil, err
- // }
- // // fmt.Println("E ReadBuf : ", readBuf.buf[readBuf.idx:])
- // // fmt.Println("E ReadBuf string: ", string(readBuf.buf[readBuf.idx:]))
- // stmt.stmt_conn.errStr = pErr.ErrStr
- // // char := readBuf.peekChar()
- // // fmt.Println("Exec 内的 peekChar: ", char)
- // case 'W':
- // fmt.Println("消息类型为W")
- // readBuf.idx++
- // parseWarnInfo(readBuf)
- // case 'M':
- // fmt.Println("消息类型为M")
- // readBuf.idx++
- // parseMessage(readBuf)
- // }
- // //return nil, errors.New("Exec not implemented")
- // }
- }
- func (stmt *xuguStmt) Query(args []driver.Value) (driver.Rows, error) {
- fmt.Println("\n>>>>>>(stmt *xuguStmt) Query(args []driver.Value) ")
- fmt.Println("stmt.mysql: ", stmt.mysql)
- if switchSQLType(stmt.mysql) != SQL_SELECT {
- return nil, errors.New("The executed SQL statement is not a SELECT")
- }
- if !stmt.prepared {
- return nil, errors.New("SQL statement is not Prepared")
- }
- parser := &xuguParse{
- bind_type: 0,
- param_count: 0,
- position: 0,
- }
- //参数绑定
- if len(args) != 0 {
- for pos, param := range args {
- err := parser.assertParamType(param, pos)
- if err != nil {
- return nil, err
- }
- }
- //fmt.Printf("len(parser.Val) = %d\n , parser.assertParamCount(stmt.mysql) = %d\n", len(parser.Val), parser.assertParamCount(stmt.mysql))
- if len(parser.values) != parser.assertParamCount(stmt.mysql) {
- return nil, errors.New("The number of parameters does not match")
- }
- switch parser.assertBindType(stmt.mysql) {
- case BIND_PARAM_BY_POS:
- fmt.Println("--BIND_PARAM_BY_POS")
- for pos, param := range parser.values {
- if !param.islob {
- fmt.Printf("pos: %d, param %#v \n", pos, param)
- stmt.mysql = parser.bindParamByPos(stmt.mysql)
- fmt.Println("? 号替换参数后的 sql", stmt.mysql)
- }
- }
- case BIND_PARAM_BY_NAME:
- fmt.Println("--BIND_PARAM_BY_NAME")
- parser.assertParamName(stmt.mysql)
- for pos, param := range parser.values {
- if !param.islob {
- fmt.Println("pos: ", pos, "param: ", param)
- }
- }
- default:
- fmt.Println("default")
- }
- }
- // if len(parser.Val) != parser.assertParamCount(stmt.mysql) {
- // return nil, errors.New("The number of parameters does not match")
- // }
- //最终发送消息给服务器
- sockSendPutStatement(stmt.stmt_conn, []byte(stmt.mysql), nil, 0)
- XGC_Execute(stmt.stmt_conn)
- //----------------处理服务器查询返回
- stmt.stmt_conn.conn.Read(stmt.stmt_conn.readBuff.buf)
- //fmt.Println("Message from server:", (buffer[:n]))
- fmt.Println("Message from server:", string(stmt.stmt_conn.readBuff.buf))
- //fmt.Println("\nMessage from server2:", (stmt.stmt_conn.readBuff.buf))
- results, err := parseSelectResult(&stmt.stmt_conn.readBuff)
- if err != nil {
- fmt.Println("parseSelectResult parseSelectResult err", err.Error())
- return nil, err
- }
- a := &xuguRows{
- results: results,
- prepared: stmt.prepared,
- rows_conn: stmt.stmt_conn,
- }
- fmt.Println("\n>>>>>>stmt Query end==============================================================")
- return a, nil
- }
|