blob: 67667ccc5f934c29a1db91c61aae8e3be28e0f4f [file] [log] [blame]
// Copyright 2022 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:googleapis/bigquery/v2.dart';
import 'big_query_pull_request_record.dart';
import 'google_auth_provider.dart';
const String _insertPullRequestDml = r'''
INSERT INTO `flutter-dashboard.autosubmit.pull_requests` (
pr_created_timestamp,
pr_landed_timestamp,
organization,
repository,
author,
pr_number,
pr_commit,
pr_request_type
) VALUES (
@PR_CREATED_TIMESTAMP,
@PR_LANDED_TIMESTAMP,
@ORGANIZATION,
@REPOSITORY,
@AUTHOR,
@PR_NUMBER,
@PR_COMMIT,
@PR_REQUEST_TYPE
)
''';
class BigqueryService {
/// Creates a [BigqueryService] using Google API authentication.
static Future<BigqueryService> from(GoogleAuthProvider authProvider) async {
final client = await authProvider.createClient(
scopes: const [BigqueryApi.bigqueryScope],
);
return BigqueryService.forTesting(BigqueryApi(client).jobs);
}
const BigqueryService.forTesting(this._defaultJobs);
final JobsResource _defaultJobs;
/// Insert a new pull request record into the database.
Future<void> insertPullRequestRecord({
required String projectId,
required PullRequestRecord pullRequestRecord,
}) async {
final queryRequest = QueryRequest(
query: _insertPullRequestDml,
queryParameters: <QueryParameter>[
_createIntegerQueryParameter(
'PR_CREATED_TIMESTAMP',
pullRequestRecord.prCreatedTimestamp!.millisecondsSinceEpoch,
),
_createIntegerQueryParameter(
'PR_LANDED_TIMESTAMP',
pullRequestRecord.prLandedTimestamp!.millisecondsSinceEpoch,
),
_createStringQueryParameter(
'ORGANIZATION',
pullRequestRecord.organization,
),
_createStringQueryParameter('REPOSITORY', pullRequestRecord.repository),
_createStringQueryParameter('AUTHOR', pullRequestRecord.author),
_createIntegerQueryParameter('PR_NUMBER', pullRequestRecord.prNumber),
_createStringQueryParameter('PR_COMMIT', pullRequestRecord.prCommit),
_createStringQueryParameter(
'PR_REQUEST_TYPE',
pullRequestRecord.prRequestType,
),
],
useLegacySql: false,
);
final queryResponse = await _defaultJobs.query(queryRequest, projectId);
if (!queryResponse.jobComplete!) {
throw BigQueryException(
'Insert pull request $pullRequestRecord did not complete.',
);
}
if (queryResponse.numDmlAffectedRows != null &&
int.parse(queryResponse.numDmlAffectedRows!) != 1) {
throw BigQueryException(
'There was an error inserting $pullRequestRecord into the table.',
);
}
}
/// Create an int parameter for query substitution.
QueryParameter _createIntegerQueryParameter(String name, int? value) {
return QueryParameter(
name: name,
parameterType: QueryParameterType(type: 'INT64'),
parameterValue: QueryParameterValue(value: value.toString()),
);
}
/// Create a String parameter for query substitution.
QueryParameter _createStringQueryParameter(String name, String? value) {
return QueryParameter(
name: name,
parameterType: QueryParameterType(type: 'STRING'),
parameterValue: QueryParameterValue(value: value),
);
}
}
class BigQueryException implements Exception {
/// Create a custom exception for Big Query Errors.
BigQueryException(this.cause);
final String cause;
@override
String toString() => cause;
}