123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- package xugu
- import (
- "database/sql/driver"
- "errors"
- "fmt"
- "unsafe"
- )
- type xuguStmt struct {
- // 上下文连接句柄指针
- stmt_conn *xuguConn
- // 布尔值,用于标识执行的 SQL 语句是否已准备好
- prepared bool
- // 接受准备好的 SQL 语句的代码
- prename []byte
- // 布尔值,用于标识游标是否启用
- curopend bool
- // 游标名称
- curname []byte
- // 执行的 SQL 语句中的参数数量
- param_count int
- mysql string
- // 上下文结果集句柄指针
- result unsafe.Pointer
- }
- /* 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")
- result := &xuguResult{
- affectedRows: 0,
- insertId: 0,
- }
- //最终发送消息给服务器
- XGC_Execute(stmt.stmt_conn, stmt.mysql)
- //处理服务器返回
- stmt.stmt_conn.conn.Read(stmt.stmt_conn.readBuff.buf)
- readBuf := stmt.stmt_conn.readBuff
- //fmt.Println("Message from server:", (buffer[:n]))
- fmt.Println("Message from server:", string(stmt.stmt_conn.readBuff.buf))
- //循环读,多条语句执行,会有多条语句返回
- //读取一字节
- for {
- char := readBuf.peekChar()
- switch char {
- case 'K':
- fmt.Println("消息类型为K")
- // readBuf.idx++
- //parseMessage(readBuf)
- return result, nil
- case '$':
- readBuf.idx++
- fmt.Println("消息类型为$")
- 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++
- parseErrInfo(readBuf)
- fmt.Println("E ReadBuf : ", readBuf.buf[readBuf.idx:], string(readBuf.buf[readBuf.idx:]))
- fmt.Println("E ReadBuf string: ", string(readBuf.buf[readBuf.idx:]))
- 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.Val) != 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.Val {
- 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.Val {
- 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")
- // }
- //最终发送消息给服务器
- XGC_Execute(stmt.stmt_conn, stmt.mysql)
- //----------------处理服务器查询返回
- 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
- }
|