Query defines database query interface.
(request *types.Request)
| 231 | |
| 232 | // Query defines database query interface. |
| 233 | func (db *Database) Query(request *types.Request) (response *types.Response, err error) { |
| 234 | // Just need to verify signature in db.saveAck |
| 235 | //if err = request.Verify(); err != nil { |
| 236 | // return |
| 237 | //} |
| 238 | |
| 239 | var ( |
| 240 | isSlowQuery uint32 |
| 241 | tracker *x.QueryTracker |
| 242 | tmStart = time.Now() |
| 243 | ) |
| 244 | |
| 245 | // log the query if the underlying storage layer take too long to response |
| 246 | slowQueryTimer := time.AfterFunc(db.cfg.SlowQueryTime, func() { |
| 247 | // mark as slow query |
| 248 | atomic.StoreUint32(&isSlowQuery, 1) |
| 249 | db.logSlow(request, false, tmStart) |
| 250 | }) |
| 251 | defer slowQueryTimer.Stop() |
| 252 | defer func() { |
| 253 | if atomic.LoadUint32(&isSlowQuery) == 1 { |
| 254 | // slow query |
| 255 | db.logSlow(request, true, tmStart) |
| 256 | } |
| 257 | }() |
| 258 | |
| 259 | switch request.Header.QueryType { |
| 260 | case types.ReadQuery: |
| 261 | if tracker, response, err = db.chain.Query(request, false); err != nil { |
| 262 | err = errors.Wrap(err, "failed to query read query") |
| 263 | return |
| 264 | } |
| 265 | case types.WriteQuery: |
| 266 | if db.cfg.UseEventualConsistency { |
| 267 | // reset context |
| 268 | request.SetContext(context.Background()) |
| 269 | if tracker, response, err = db.chain.Query(request, true); err != nil { |
| 270 | err = errors.Wrap(err, "failed to execute with eventual consistency") |
| 271 | return |
| 272 | } |
| 273 | } else { |
| 274 | if tracker, response, err = db.writeQuery(request); err != nil { |
| 275 | err = errors.Wrap(err, "failed to execute") |
| 276 | return |
| 277 | } |
| 278 | } |
| 279 | default: |
| 280 | // TODO(xq262144): verbose errors with custom error structure |
| 281 | return nil, errors.Wrap(ErrInvalidRequest, "invalid query type") |
| 282 | } |
| 283 | |
| 284 | response.Header.ResponseAccount = db.accountAddr |
| 285 | |
| 286 | // build hash |
| 287 | if err = response.BuildHash(); err != nil { |
| 288 | err = errors.Wrap(err, "failed to build response hash") |
| 289 | return |
| 290 | } |