(ctx context.Context, queryType types.QueryType, queries []types.Query)
| 388 | } |
| 389 | |
| 390 | func (c *conn) sendQuery(ctx context.Context, queryType types.QueryType, queries []types.Query) (affectedRows int64, lastInsertID int64, rows driver.Rows, err error) { |
| 391 | var uc *pconn // peer connection used to execute the queries |
| 392 | |
| 393 | uc = c.leader |
| 394 | // use follower pconn only when the query is readonly |
| 395 | if queryType == types.ReadQuery && c.follower != nil { |
| 396 | uc = c.follower |
| 397 | } |
| 398 | if uc == nil { |
| 399 | uc = c.follower |
| 400 | } |
| 401 | |
| 402 | // allocate sequence |
| 403 | connID, seqNo := allocateConnAndSeq() |
| 404 | defer putBackConn(connID) |
| 405 | |
| 406 | defer func() { |
| 407 | log.WithFields(log.Fields{ |
| 408 | "count": len(queries), |
| 409 | "type": queryType.String(), |
| 410 | "connID": connID, |
| 411 | "seqNo": seqNo, |
| 412 | "target": uc.pCaller.Target(), |
| 413 | "source": c.localNodeID, |
| 414 | }).WithError(err).Debug("send query") |
| 415 | }() |
| 416 | |
| 417 | // build request |
| 418 | req := &types.Request{ |
| 419 | Header: types.SignedRequestHeader{ |
| 420 | RequestHeader: types.RequestHeader{ |
| 421 | QueryType: queryType, |
| 422 | NodeID: c.localNodeID, |
| 423 | DatabaseID: c.dbID, |
| 424 | ConnectionID: connID, |
| 425 | SeqNo: seqNo, |
| 426 | Timestamp: getLocalTime(), |
| 427 | }, |
| 428 | }, |
| 429 | Payload: types.RequestPayload{ |
| 430 | Queries: queries, |
| 431 | }, |
| 432 | } |
| 433 | |
| 434 | if err = req.Sign(c.privKey); err != nil { |
| 435 | return |
| 436 | } |
| 437 | |
| 438 | // set receipt if key exists in context |
| 439 | if val := ctx.Value(&ctxReceiptKey); val != nil { |
| 440 | val.(*atomic.Value).Store(&Receipt{ |
| 441 | RequestHash: req.Header.Hash(), |
| 442 | }) |
| 443 | } |
| 444 | |
| 445 | var response types.Response |
| 446 | if err = uc.pCaller.Call(route.DBSQuery.String(), req, &response); err != nil { |
| 447 | return |
no test coverage detected