package xugu import ( "database/sql/driver" "encoding/base64" "encoding/binary" "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>>>>>NumInput method called") 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)) //读取一字节 char := readBuf.peekChar() switch char { case '$': fmt.Println("消息类型为$") case 'I': readBuf.idx++ fmt.Println("消息类型为I") //Rowid_Len Rowid_Len := binary.BigEndian.Uint32(readBuf.readNext(4)) fmt.Println("Rowid_Len", Rowid_Len) //Rowid_Data // Base64 解码 Rowid_Data, err := base64.StdEncoding.DecodeString(string(readBuf.readNext(int(Rowid_Len)))) if err != nil { fmt.Println("Error decoding:", err) } fmt.Println("Rowid_Data: ", string(Rowid_Data)) case 'U': fmt.Println("消息类型为U") case 'D': fmt.Println("消息类型为D") case 'E': fmt.Println("消息类型为E") case 'W': fmt.Println("消息类型为W") case 'M': fmt.Println("消息类型为M") } //return nil, errors.New("Exec not implemented") return result, nil } func (stmt *xuguStmt) Query(args []driver.Value) (driver.Rows, error) { fmt.Println("\n>>>>>>Query method called") 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 } } } // 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 } fmt.Println("results:", results) a := &xuguRows{ results: results, prepared: stmt.prepared, rows_conn: stmt.stmt_conn, } fmt.Println("\n>>>>>>stmt Query end==============================================================") return a, nil }