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 } func (stmt *xuguStmt) Close() error { fmt.Println("\n>>>>>> (stmt *xuguStmt) Close method called") //关闭 prepare fmt.Println("stmt.stmt_conn.prepareName", stmt.stmt_conn.prepareName) err := xuguUnPrepare(stmt.stmt_conn, stmt.stmt_conn.prepareName) //释放资源 return err } func (stmt *xuguStmt) NumInput() int { fmt.Println("\n>>>>>(stmt *xuguStmt) NumInput()") fmt.Println("stmt.mysql: ", stmt.mysql) return assertParamCount(stmt.mysql) //return 0 } func (stmt *xuguStmt) Exec(args []driver.Value) (driver.Result, error) { gt("stmt Exec") defer gt("stmt Exec end") stmt.stmt_conn.mu.Lock() defer stmt.stmt_conn.mu.Unlock() //send msg //如果有参数 if stmt.paramCount > 0 && len(args) > 0 { values := []xuguValue{} for _, param := range args { assertParamType(param, &values) //fmt.Printf("Field Name: %s, Field Type: %s, Field Value: %v\n", v1, v1, v1) } sockSendPutStatement(stmt.stmt_conn, stmt.prename, &values, stmt.paramCount) sockSendExecute(stmt.stmt_conn) //没有参数 } else { sockSendPutStatement(stmt.stmt_conn, []byte(stmt.mysql), nil, 0) sockSendExecute(stmt.stmt_conn) } //recv msg aR, err := xuguSockRecvMsg(stmt.stmt_conn) if err != nil { return nil, err } switch aR.rt { case selectResult: return nil, errors.New("exec is Query error") case updateResult: return &xuguResult{affectedRows: int64(aR.u.UpdateNum), insertId: int64(0)}, nil case insertResult: return &xuguResult{affectedRows: int64(0), insertId: int64(aR.i.RowidLen)}, nil case errInfo: return nil, errors.New(string(aR.e.ErrStr)) case warnInfo: return nil, errors.New(string(aR.w.WarnStr)) default: return &xuguResult{ affectedRows: int64(0), insertId: int64(0), }, nil } } func (stmt *xuguStmt) Query(args []driver.Value) (driver.Rows, error) { gt("stmt Query") defer gt("stmt Query end") stmt.stmt_conn.mu.Lock() defer stmt.stmt_conn.mu.Unlock() //send msg //如果有参数 if stmt.paramCount > 0 && len(args) > 0 { values := []xuguValue{} for _, param := range args { assertParamType(param, &values) //fmt.Printf("Field Name: %s, Field Type: %s, Field Value: %v\n", v1, v1, v1) } sockSendPutStatement(stmt.stmt_conn, stmt.prename, &values, stmt.paramCount) sockSendExecute(stmt.stmt_conn) //没有参数 } else { sockSendPutStatement(stmt.stmt_conn, []byte(stmt.mysql), nil, 0) sockSendExecute(stmt.stmt_conn) } //recv msg aR, err := xuguSockRecvMsg(stmt.stmt_conn) if err != nil { return nil, err } switch aR.rt { case selectResult: rows := &xuguRows{ rows_conn: stmt.stmt_conn, results: aR.s, colIdx: 0, prepared: false, } return rows, nil case errInfo: return nil, errors.New(string(aR.e.ErrStr)) case warnInfo: return nil, errors.New(string(aR.w.WarnStr)) default: } return nil, errors.New("xugu Query error") }