123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- 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
- }
|