package xugu import ( "database/sql/driver" "errors" ) 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 { //关闭 prepare err := xuguUnPrepare(stmt.stmt_conn, stmt.stmt_conn.prepareName) //释放资源 return err } func (stmt *xuguStmt) NumInput() int { return assertParamCount(stmt.mysql) //return 0 } func (stmt *xuguStmt) Exec(args []driver.Value) (driver.Result, error) { 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) } 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) { 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) } 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") }