func (conn *vtgateConn) ExecuteEntityIds(ctx context.Context, query string, keyspace string, entityColumnName string, entityKeyspaceIDs []*pb.ExecuteEntityIdsRequest_EntityId, bindVars map[string]interface{}, tabletType topodatapb.TabletType, notInTransaction bool, session interface{}) (*sqltypes.Result, interface{}, error) { var s *pb.Session if session != nil { s = session.(*pb.Session) } q, err := tproto.BoundQueryToProto3(query, bindVars) if err != nil { return nil, session, err } request := &pb.ExecuteEntityIdsRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), Session: s, Query: q, Keyspace: keyspace, EntityColumnName: entityColumnName, EntityKeyspaceIds: entityKeyspaceIDs, TabletType: tabletType, NotInTransaction: notInTransaction, } response, err := conn.c.ExecuteEntityIds(ctx, request) if err != nil { return nil, session, vterrors.FromGRPCError(err) } if response.Error != nil { return nil, response.Session, vterrors.FromVtRPCError(response.Error) } return sqltypes.Proto3ToResult(response.Result), response.Session, nil }
func (conn *vtgateConn) ExecuteShards(ctx context.Context, query string, keyspace string, shards []string, bindVars map[string]interface{}, tabletType pbt.TabletType, notInTransaction bool, session interface{}) (*mproto.QueryResult, interface{}, error) { var s *pb.Session if session != nil { s = session.(*pb.Session) } q, err := tproto.BoundQueryToProto3(query, bindVars) if err != nil { return nil, session, err } request := &pb.ExecuteShardsRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), Session: s, Query: q, Keyspace: keyspace, Shards: shards, TabletType: tabletType, NotInTransaction: notInTransaction, } response, err := conn.c.ExecuteShards(ctx, request) if err != nil { return nil, session, vterrors.FromGRPCError(err) } if response.Error != nil { return nil, response.Session, vterrors.FromVtRPCError(response.Error) } return mproto.Proto3ToQueryResult(response.Result), response.Session, nil }
func sendStreamResults(c *rpcplus.Call, sr chan streamResult) (<-chan *mproto.QueryResult, vtgateconn.ErrFunc, error) { srout := make(chan *mproto.QueryResult, 1) var err error go func() { defer close(srout) for r := range sr { // nil != nil vtErr := vterrors.FromVtRPCError(r.err) if vtErr != nil { err = vtErr continue } // If we get a QueryResult with an RPCError, that was an extra QueryResult sent by // the server specifically to indicate an error, and we shouldn't surface it to clients. srout <- mproto.Proto3ToQueryResult(r.qr) } }() // errFunc will return either an RPC-layer error or an application error, if one exists. // It will only return the most recent application error (i.e, from the QueryResult that // most recently contained an error). It will prioritize an RPC-layer error over an apperror, // if both exist. errFunc := func() error { if c.Error != nil { return c.Error } return err } return srout, errFunc, nil }
func (conn *vtgateConn) StreamExecute(ctx context.Context, query string, bindVars map[string]interface{}, tabletType pbt.TabletType) (<-chan *mproto.QueryResult, vtgateconn.ErrFunc, error) { req := &pb.StreamExecuteRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), Query: tproto.BoundQueryToProto3(query, bindVars), TabletType: tabletType, } stream, err := conn.c.StreamExecute(ctx, req) if err != nil { return nil, nil, vterrors.FromGRPCError(err) } sr := make(chan *mproto.QueryResult, 10) // TODO(aaijazi): I'm pretty sure ther error handling going on down here is overkill now... var finalError error go func() { for { ser, err := stream.Recv() if err != nil { if err != io.EOF { finalError = err } close(sr) return } if ser.Error != nil { finalError = vterrors.FromVtRPCError(ser.Error) close(sr) return } sr <- mproto.Proto3ToQueryResult(ser.Result) } }() return sr, func() error { return finalError }, nil }
func (conn *vtgateConn) StreamExecuteKeyspaceIds(ctx context.Context, query string, keyspace string, keyspaceIds []key.KeyspaceId, bindVars map[string]interface{}, tabletType topo.TabletType) (<-chan *mproto.QueryResult, vtgateconn.ErrFunc, error) { req := &pb.StreamExecuteKeyspaceIdsRequest{ Query: tproto.BoundQueryToProto3(query, bindVars), Keyspace: keyspace, KeyspaceIds: key.KeyspaceIdsToProto(keyspaceIds), TabletType: topo.TabletTypeToProto(tabletType), } stream, err := conn.c.StreamExecuteKeyspaceIds(ctx, req) if err != nil { return nil, nil, err } sr := make(chan *mproto.QueryResult, 10) var finalError error go func() { for { ser, err := stream.Recv() if err != nil { if err != io.EOF { finalError = err } close(sr) return } if ser.Error != nil { finalError = vterrors.FromVtRPCError(ser.Error) close(sr) return } sr <- mproto.Proto3ToQueryResult(ser.Result) } }() return sr, func() error { return finalError }, nil }
func (conn *vtgateConn) Execute(ctx context.Context, query string, bindVars map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, session interface{}) (*sqltypes.Result, interface{}, error) { var s *vtgatepb.Session if session != nil { s = session.(*vtgatepb.Session) } q, err := querytypes.BoundQueryToProto3(query, bindVars) if err != nil { return nil, session, err } request := &vtgatepb.ExecuteRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), Session: s, Query: q, Keyspace: keyspace, TabletType: tabletType, } response, err := conn.c.Execute(ctx, request) if err != nil { return nil, session, vterrors.FromGRPCError(err) } if response.Error != nil { return nil, response.Session, vterrors.FromVtRPCError(response.Error) } return sqltypes.Proto3ToResult(response.Result), response.Session, nil }
func (conn *vtgateConn) ExecuteBatchKeyspaceIds(ctx context.Context, queries []proto.BoundKeyspaceIdQuery, tabletType pbt.TabletType, asTransaction bool, session interface{}) ([]mproto.QueryResult, interface{}, error) { var s *pb.Session if session != nil { s = session.(*pb.Session) } qs, err := proto.BoundKeyspaceIdQueriesToProto(queries) if err != nil { return nil, session, err } request := &pb.ExecuteBatchKeyspaceIdsRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), Session: s, Queries: qs, TabletType: tabletType, AsTransaction: asTransaction, } response, err := conn.c.ExecuteBatchKeyspaceIds(ctx, request) if err != nil { return nil, session, vterrors.FromGRPCError(err) } if response.Error != nil { return nil, response.Session, vterrors.FromVtRPCError(response.Error) } return mproto.Proto3ToQueryResults(response.Results), response.Session, nil }
func (conn *vtgateConn) Begin(ctx context.Context) (interface{}, error) { request := &pb.BeginRequest{} response, err := conn.c.Begin(ctx, request) if err != nil { return nil, err } if response.Error != nil { return nil, vterrors.FromVtRPCError(response.Error) } return response.Session, nil }
func (conn *vtgateConn) Rollback(ctx context.Context, session interface{}) error { request := &pb.RollbackRequest{ Session: session.(*pb.Session), } response, err := conn.c.Rollback(ctx, request) if err != nil { return err } if response.Error != nil { return vterrors.FromVtRPCError(response.Error) } return nil }
// tabletErrorFromRPCError reconstructs a tablet error from the // RPCError, using the RPCError code. func tabletErrorFromRPCError(rpcErr *pbv.RPCError) error { ve := vterrors.FromVtRPCError(rpcErr) // see if the range is in the tablet error range if ve.Code >= int64(pbv.ErrorCode_TabletError) && ve.Code <= int64(pbv.ErrorCode_UnknownTabletError) { return &tabletconn.ServerError{ Code: int(ve.Code - int64(pbv.ErrorCode_TabletError)), Err: fmt.Sprintf("vttablet: %v", ve.Error()), } } return tabletconn.OperationalError(fmt.Sprintf("vttablet: %v", ve.Message)) }
func (conn *vtgateConn) Commit(ctx context.Context, session interface{}) error { request := &pb.CommitRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), Session: session.(*pb.Session), } response, err := conn.c.Commit(ctx, request) if err != nil { return err } if response.Error != nil { return vterrors.FromVtRPCError(response.Error) } return nil }
func (conn *vtgateConn) Rollback2(ctx context.Context, session interface{}) error { s := session.(*pb.Session) request := &pb.RollbackRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), Session: s, } response := &pb.RollbackResponse{} if err := conn.rpcConn.Call(ctx, "VTGateP3.Rollback2", request, response); err != nil { return err } if vtErr := vterrors.FromVtRPCError(response.Error); vtErr != nil { return vtErr } return nil }
func (conn *vtgateConn) Begin2(ctx context.Context) (interface{}, error) { request := &pb.BeginRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), } response := &pb.BeginResponse{} if err := conn.rpcConn.Call(ctx, "VTGateP3.Begin2", request, response); err != nil { return nil, err } if err := vterrors.FromVtRPCError(response.Error); err != nil { return nil, err } // Return a non-nil pointer session := &pb.Session{} if response.Session != nil { session = response.Session } return session, nil }
func (conn *vtgateConn) Execute(ctx context.Context, query string, bindVars map[string]interface{}, tabletType topo.TabletType, notInTransaction bool, session interface{}) (*mproto.QueryResult, interface{}, error) { var s *pb.Session if session != nil { s = session.(*pb.Session) } request := &pb.ExecuteRequest{ Session: s, Query: tproto.BoundQueryToProto3(query, bindVars), TabletType: topo.TabletTypeToProto(tabletType), NotInTransaction: notInTransaction, } response, err := conn.c.Execute(ctx, request) if err != nil { return nil, session, err } if response.Error != nil { return nil, response.Session, vterrors.FromVtRPCError(response.Error) } return mproto.Proto3ToQueryResult(response.Result), response.Session, nil }
func (conn *vtgateConn) ExecuteBatchKeyspaceIds(ctx context.Context, queries []proto.BoundKeyspaceIdQuery, tabletType topo.TabletType, asTransaction bool, session interface{}) ([]mproto.QueryResult, interface{}, error) { var s *pb.Session if session != nil { s = session.(*pb.Session) } request := &pb.ExecuteBatchKeyspaceIdsRequest{ Session: s, Queries: proto.BoundKeyspaceIdQueriesToProto(queries), TabletType: topo.TabletTypeToProto(tabletType), AsTransaction: asTransaction, } response, err := conn.c.ExecuteBatchKeyspaceIds(ctx, request) if err != nil { return nil, session, err } if response.Error != nil { return nil, response.Session, vterrors.FromVtRPCError(response.Error) } return mproto.Proto3ToQueryResults(response.Results), response.Session, nil }
func (conn *vtgateConn) Execute(ctx context.Context, query string, bindVars map[string]interface{}, tabletType topopb.TabletType, notInTransaction bool, session interface{}) (*mproto.QueryResult, interface{}, error) { var s *pb.Session if session != nil { s = session.(*pb.Session) } request := &pb.ExecuteRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), Query: tproto.BoundQueryToProto3(query, bindVars), TabletType: tabletType, Session: s, NotInTransaction: notInTransaction, } response := &pb.ExecuteResponse{} if err := conn.rpcConn.Call(ctx, "VTGateP3.Execute", request, response); err != nil { return nil, response.Session, err } if err := vterrors.FromVtRPCError(response.Error); err != nil { return nil, response.Session, err } return mproto.Proto3ToQueryResult(response.Result), response.Session, nil }
func (conn *vtgateConn) ExecuteBatchKeyspaceIds(ctx context.Context, queries []proto.BoundKeyspaceIdQuery, tabletType topopb.TabletType, asTransaction bool, session interface{}) ([]mproto.QueryResult, interface{}, error) { var s *pb.Session if session != nil { s = session.(*pb.Session) } request := &pb.ExecuteBatchKeyspaceIdsRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), Queries: proto.BoundKeyspaceIdQueriesToProto(queries), TabletType: tabletType, AsTransaction: asTransaction, Session: s, } response := &pb.ExecuteBatchKeyspaceIdsResponse{} if err := conn.rpcConn.Call(ctx, "VTGateP3.ExecuteBatchKeyspaceIds", request, response); err != nil { return nil, session, err } if err := vterrors.FromVtRPCError(response.Error); err != nil { return nil, response.Session, err } return mproto.Proto3ToQueryResults(response.Results), response.Session, nil }
func (conn *vtgateConn) ExecuteBatchShards(ctx context.Context, queries []*vtgatepb.BoundShardQuery, tabletType topodatapb.TabletType, asTransaction bool, session interface{}) ([]sqltypes.Result, interface{}, error) { var s *vtgatepb.Session if session != nil { s = session.(*vtgatepb.Session) } request := &vtgatepb.ExecuteBatchShardsRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), Session: s, Queries: queries, TabletType: tabletType, AsTransaction: asTransaction, } response, err := conn.c.ExecuteBatchShards(ctx, request) if err != nil { return nil, session, vterrors.FromGRPCError(err) } if response.Error != nil { return nil, response.Session, vterrors.FromVtRPCError(response.Error) } return sqltypes.Proto3ToResults(response.Results), response.Session, nil }
func (conn *vtgateConn) ExecuteKeyRanges(ctx context.Context, query string, keyspace string, keyRanges []key.KeyRange, bindVars map[string]interface{}, tabletType topo.TabletType, notInTransaction bool, session interface{}) (*mproto.QueryResult, interface{}, error) { var s *pb.Session if session != nil { s = session.(*pb.Session) } request := &pb.ExecuteKeyRangesRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), Session: s, Query: tproto.BoundQueryToProto3(query, bindVars), Keyspace: keyspace, KeyRanges: key.KeyRangesToProto(keyRanges), TabletType: topo.TabletTypeToProto(tabletType), NotInTransaction: notInTransaction, } response, err := conn.c.ExecuteKeyRanges(ctx, request) if err != nil { return nil, session, err } if response.Error != nil { return nil, response.Session, vterrors.FromVtRPCError(response.Error) } return mproto.Proto3ToQueryResult(response.Result), response.Session, nil }
func (conn *vtgateConn) StreamExecuteKeyRanges(ctx context.Context, query string, keyspace string, keyRanges []*pbt.KeyRange, bindVars map[string]interface{}, tabletType pbt.TabletType) (<-chan *mproto.QueryResult, vtgateconn.ErrFunc, error) { req := &pb.StreamExecuteKeyRangesRequest{ CallerId: callerid.EffectiveCallerIDFromContext(ctx), Query: tproto.BoundQueryToProto3(query, bindVars), Keyspace: keyspace, KeyRanges: keyRanges, TabletType: tabletType, } stream, err := conn.c.StreamExecuteKeyRanges(ctx, req) if err != nil { return nil, nil, vterrors.FromGRPCError(err) } sr := make(chan *mproto.QueryResult, 10) var finalError error go func() { for { ser, err := stream.Recv() if err != nil { if err != io.EOF { finalError = err } close(sr) return } if ser.Error != nil { finalError = vterrors.FromVtRPCError(ser.Error) close(sr) return } sr <- mproto.Proto3ToQueryResult(ser.Result) } }() return sr, func() error { return finalError }, nil }