request method

  1. @override
Future<QueryEngineResult> request({
  1. required String query,
  2. QueryEngineRequestHeaders? headers,
})
override

Request a query execution.

Implementation

@override
Future<QueryEngineResult> request(
    {required String query, QueryEngineRequestHeaders? headers}) async {
  logEmitter.emit(
    PrismaLogLevel.query,
    PrismaQueryEvent(
      target: '',
      timestamp: DateTime.now(),
      query: query,
      params: "{}",
      duration: 0,
    ),
  );

  final Exception retryException = Exception('retry');
  return retry<QueryEngineResult>(
    () async {
      final Uri url = (await this.url).replace(
        path: '${(await this.url).path}/graphql',
      );
      logEmitter.emit(PrismaLogLevel.info, Exception('Calling $url'));

      final Response response = await post(
        url.replace(
          path: '${url.path}/graphql',
        ),
        body: json.encode({
          'query': query,
          'variables': {},
        }),
        headers: runtimeHttpHeadersBuilder({
          ...?headers?.toJson().cast(),
          'Authorization': 'Bearer $_apiKey',
        }),
        encoding: utf8,
      );

      final Map<String, dynamic> result = json.decode(response.body);

      if (isSchemaMissing(result)) {
        await _updateSchema();
        throw retryException;
      } else if (response.statusCode > 400) {
        final e = PrismaClientUnknownRequestError('Bad request',
            clientVersion: binaryVersion);
        logEmitter.emit(PrismaLogLevel.error, e);
        throw e;
      }

      try {
        throwGraphQLError(result['errors']);
      } on Exception catch (e) {
        logEmitter.emit(PrismaLogLevel.error, e);
        rethrow;
      }

      // Rust engine returns time in microseconds and we want it in miliseconds
      final int elapsed =
          int.parse(headerGetter(response.headers, 'x-elapsed')!) ~/ 1000;

      return QueryEngineResult(result['data'], elapsed);
    },
    maxDelay: const Duration(milliseconds: 200),
    maxAttempts: 10,
    retryIf: (e) =>
        e is ClientException || e is TimeoutException || e == retryException,
  );
}