Skip to content

Commit 2b501e8

Browse files
committed
feat: Add support for BigQuery job metadata deletion.
1 parent 8c16aff commit 2b501e8

8 files changed

Lines changed: 213 additions & 6 deletions

File tree

apis/Google.Cloud.BigQuery.V2/Google.Cloud.BigQuery.V2.GenerateOverloads/Methods/JobCrud.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,14 @@
8181
- CreateCopyJob and CreateLoadJob can't be generated yet, as they doesn't use IDs.
8282
- Could still reduce copy/paste for the async using a target type of None, but it's probably not worth it.
8383
-->
84+
85+
<Method Name="DeleteJob"
86+
TargetType="Job"
87+
ReturnType="void">
88+
<Comments>
89+
<summary>
90+
Deletes {target}.
91+
</summary>
92+
</Comments>
93+
</Method>
8494
</File>

apis/Google.Cloud.BigQuery.V2/Google.Cloud.BigQuery.V2.IntegrationTests/JobsTest.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2016 Google Inc. All Rights Reserved.
1+
// Copyright 2016 Google Inc. All Rights Reserved.
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -296,6 +296,17 @@ public void JobLabels_InvalidCharactersValue()
296296
Assert.ThrowsAny<GoogleApiException>(() => client.CreateQueryJob($"SELECT * FROM {table}", null, options));
297297
}
298298

299+
[Fact]
300+
public void DeleteJob()
301+
{
302+
var client = BigQueryClient.Create(_fixture.ProjectId);
303+
var table = client.GetTable(_fixture.ProjectId, _fixture.DatasetId, _fixture.HighScoreTableId);
304+
// We need to wait for the job to be completed before being able to delete it.
305+
var jobToFind = client.CreateQueryJob($"SELECT * FROM {table}", parameters: null).PollUntilCompleted();
306+
307+
client.DeleteJob(jobToFind.Reference);
308+
}
309+
299310
internal static void VerifyJobLabels(IDictionary<string, string> actual)
300311
{
301312
Assert.NotNull(actual);

apis/Google.Cloud.BigQuery.V2/Google.Cloud.BigQuery.V2.Tests/BigQueryClientImplTest.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2016 Google Inc. All Rights Reserved.
1+
// Copyright 2016 Google Inc. All Rights Reserved.
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -557,6 +557,20 @@ public void CancelJob()
557557
Assert.Equal(jobId, result.Reference.JobId);
558558
}
559559

560+
[Fact]
561+
public void DeleteJob()
562+
{
563+
var projectId = "project";
564+
var jobId = "job";
565+
var service = new FakeBigqueryService();
566+
var client = new BigQueryClientImpl(projectId, service);
567+
var reference = client.GetJobReference(projectId, jobId);
568+
service.ExpectRequest(
569+
service.Jobs.Delete(projectId, jobId),
570+
"OK");
571+
client.DeleteJob(reference);
572+
}
573+
560574
[Fact]
561575
public async Task ListProjectsAsyncAsync()
562576
{
@@ -954,6 +968,20 @@ public async Task CancelJobAsync()
954968
Assert.Equal(jobId, result.Reference.JobId);
955969
}
956970

971+
[Fact]
972+
public async Task DeleteJobAsync()
973+
{
974+
var projectId = "project";
975+
var jobId = "job";
976+
var service = new FakeBigqueryService();
977+
var client = new BigQueryClientImpl(projectId, service);
978+
var reference = client.GetJobReference(projectId, jobId);
979+
service.ExpectRequest(
980+
service.Jobs.Delete(projectId, jobId),
981+
"OK");
982+
await client.DeleteJobAsync(reference);
983+
}
984+
957985
private Job CreateJobWithSampleConfiguration(JobCreationOptions options)
958986
{
959987
var projectId = "project";

apis/Google.Cloud.BigQuery.V2/Google.Cloud.BigQuery.V2.Tests/BigQueryClientTest.cs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2016 Google Inc. All Rights Reserved.
1+
// Copyright 2016 Google Inc. All Rights Reserved.
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -660,6 +660,19 @@ public void ListJobsEquivalents()
660660
client => client.ListJobs(ProjectId, options));
661661
}
662662

663+
[Fact]
664+
public void DeleteJobEquivalents()
665+
{
666+
var jobId = "job";
667+
var reference = GetJobReference(jobId);
668+
var options = new DeleteJobOptions();
669+
VerifyEquivalent(
670+
client => client.DeleteJob(MatchesWhenSerialized(reference), options),
671+
client => client.DeleteJob(jobId, options),
672+
client => client.DeleteJob(ProjectId, jobId, options),
673+
client => new BigQueryJob(client, new Job { JobReference = reference }).Delete(options));
674+
}
675+
663676
[Fact]
664677
public void ListRowsEquivalents()
665678
{
@@ -1407,6 +1420,20 @@ public void ListJobsAsyncEquivalents()
14071420
client => client.ListJobsAsync(ProjectId, options));
14081421
}
14091422

1423+
[Fact]
1424+
public void DeleteJobAsyncEquivalents()
1425+
{
1426+
var jobId = "job";
1427+
var reference = GetJobReference(jobId);
1428+
var options = new DeleteJobOptions();
1429+
var token = new CancellationTokenSource().Token;
1430+
VerifyEquivalentAsync(
1431+
client => client.DeleteJobAsync(MatchesWhenSerialized(reference), options, token),
1432+
client => client.DeleteJobAsync(jobId, options, token),
1433+
client => client.DeleteJobAsync(ProjectId, jobId, options, token),
1434+
client => new BigQueryJob(client, new Job { JobReference = reference }).DeleteAsync(options, token));
1435+
}
1436+
14101437
[Fact]
14111438
public void ListRowsAsyncEquivalents()
14121439
{
@@ -1779,4 +1806,4 @@ private class UnimplementedPagedAsyncEnumerable<TResponse, TResource> : PagedAsy
17791806
{
17801807
}
17811808
}
1782-
}
1809+
}

apis/Google.Cloud.BigQuery.V2/Google.Cloud.BigQuery.V2/BigQueryClient.JobCrud.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,5 +823,67 @@ public virtual Task<BigQueryJob> CreateModelExtractJobAsync(string projectId, st
823823
public virtual Task<BigQueryJob> CreateModelExtractJobAsync(ModelReference modelReference, IEnumerable<string> destinationUris, CreateModelExtractJobOptions options = null, CancellationToken cancellationToken = default) =>
824824
throw new NotImplementedException();
825825
#endregion
826+
827+
#region DeleteJob (autogenerated - do not edit manually)
828+
/// <summary>
829+
/// Deletes the specified job within this client's project.
830+
/// This method just creates a <see cref="JobReference"/> and delegates to <see cref="DeleteJob(JobReference, DeleteJobOptions)"/>.
831+
/// </summary>
832+
/// <param name="jobId">The job ID. Must not be null.</param>
833+
/// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param>
834+
public virtual void DeleteJob(string jobId, DeleteJobOptions options = null) =>
835+
DeleteJob(GetJobReference(jobId), options);
836+
837+
/// <summary>
838+
/// Deletes the specified job.
839+
/// This method just creates a <see cref="JobReference"/> and delegates to <see cref="DeleteJob(JobReference, DeleteJobOptions)"/>.
840+
/// </summary>
841+
/// <param name="projectId">The project ID. Must not be null.</param>
842+
/// <param name="jobId">The job ID. Must not be null.</param>
843+
/// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param>
844+
public virtual void DeleteJob(string projectId, string jobId, DeleteJobOptions options = null) =>
845+
DeleteJob(GetJobReference(projectId, jobId), options);
846+
847+
/// <summary>
848+
/// Deletes the specified job.
849+
/// </summary>
850+
/// <param name="jobReference">A fully-qualified identifier for the job. Must not be null.</param>
851+
/// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param>
852+
public virtual void DeleteJob(JobReference jobReference, DeleteJobOptions options = null) =>
853+
throw new NotImplementedException();
854+
855+
/// <summary>
856+
/// Asynchronously deletes the specified job within this client's project.
857+
/// This method just creates a <see cref="JobReference"/> and delegates to <see cref="DeleteJobAsync(JobReference, DeleteJobOptions, CancellationToken)"/>.
858+
/// </summary>
859+
/// <param name="jobId">The job ID. Must not be null.</param>
860+
/// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param>
861+
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
862+
/// <returns>A task representing the asynchronous operation.</returns>
863+
public virtual Task DeleteJobAsync(string jobId, DeleteJobOptions options = null, CancellationToken cancellationToken = default) =>
864+
DeleteJobAsync(GetJobReference(jobId), options, cancellationToken);
865+
866+
/// <summary>
867+
/// Asynchronously deletes the specified job.
868+
/// This method just creates a <see cref="JobReference"/> and delegates to <see cref="DeleteJobAsync(JobReference, DeleteJobOptions, CancellationToken)"/>.
869+
/// </summary>
870+
/// <param name="projectId">The project ID. Must not be null.</param>
871+
/// <param name="jobId">The job ID. Must not be null.</param>
872+
/// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param>
873+
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
874+
/// <returns>A task representing the asynchronous operation.</returns>
875+
public virtual Task DeleteJobAsync(string projectId, string jobId, DeleteJobOptions options = null, CancellationToken cancellationToken = default) =>
876+
DeleteJobAsync(GetJobReference(projectId, jobId), options, cancellationToken);
877+
878+
/// <summary>
879+
/// Asynchronously deletes the specified job.
880+
/// </summary>
881+
/// <param name="jobReference">A fully-qualified identifier for the job. Must not be null.</param>
882+
/// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param>
883+
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
884+
/// <returns>A task representing the asynchronous operation.</returns>
885+
public virtual Task DeleteJobAsync(JobReference jobReference, DeleteJobOptions options = null, CancellationToken cancellationToken = default) =>
886+
throw new NotImplementedException();
887+
#endregion
826888
}
827889
}

apis/Google.Cloud.BigQuery.V2/Google.Cloud.BigQuery.V2/BigQueryClientImpl.JobCrud.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2016 Google Inc. All Rights Reserved.
1+
// Copyright 2016 Google Inc. All Rights Reserved.
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -174,6 +174,20 @@ public override async Task<BigQueryJob> CreateModelExtractJobAsync(ModelReferenc
174174
return new BigQueryJob(this, job);
175175
}
176176

177+
/// <inheritdoc />
178+
public override void DeleteJob(JobReference jobReference, DeleteJobOptions options = null)
179+
{
180+
var request = CreateDeleteJobRequest(jobReference, options);
181+
request.Execute();
182+
}
183+
184+
/// <inheritdoc />
185+
public override async Task DeleteJobAsync(JobReference jobReference, DeleteJobOptions options = null, CancellationToken cancellationToken = default)
186+
{
187+
var request = CreateDeleteJobRequest(jobReference, options);
188+
await request.ExecuteAsync(cancellationToken).ConfigureAwait(false);
189+
}
190+
177191
internal const string DefaultJobIdPrefix = "job_";
178192

179193
/// <summary>
@@ -300,5 +314,15 @@ private InsertRequest CreateModelExtractJobRequest(ModelReference modelReference
300314
options?.ModifyRequest(extract);
301315
return CreateInsertJobRequest(new JobConfiguration { Extract = extract }, options);
302316
}
317+
318+
private DeleteRequest CreateDeleteJobRequest(JobReference jobReference, DeleteJobOptions options)
319+
{
320+
GaxPreconditions.CheckNotNull(jobReference, nameof(jobReference));
321+
var request = Service.Jobs.Delete(jobReference.ProjectId, jobReference.JobId);
322+
request.Location = jobReference.Location;
323+
options?.ModifyRequest(request);
324+
request.PrettyPrint = PrettyPrint;
325+
return request;
326+
}
303327
}
304328
}

apis/Google.Cloud.BigQuery.V2/Google.Cloud.BigQuery.V2/BigQueryJob.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2016 Google Inc. All Rights Reserved.
1+
// Copyright 2016 Google Inc. All Rights Reserved.
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -190,6 +190,13 @@ public BigQueryJob PollUntilCompleted(GetJobOptions options = null, PollSettings
190190
/// <returns>The final state of the job.</returns>
191191
public BigQueryJob Cancel(CancelJobOptions options = null) => _client.CancelJob(Reference, options);
192192

193+
/// <summary>
194+
/// Deletes this job.
195+
/// This method just creates a <see cref="JobReference"/> and delegates to <see cref="BigQueryClient.DeleteJob(JobReference, DeleteJobOptions)"/>.
196+
/// </summary>
197+
/// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param>
198+
public void Delete(DeleteJobOptions options = null) => _client.DeleteJob(Reference, options);
199+
193200
/// <summary>
194201
/// Asynchronously polls this job for completion.
195202
/// This method just creates a <see cref="JobReference"/> and delegates to <see cref="BigQueryClient.PollJobUntilCompletedAsync(JobReference, GetJobOptions, PollSettings, CancellationToken)"/>.
@@ -230,6 +237,17 @@ public Task<BigQueryResults> GetQueryResultsAsync(GetQueryResultsOptions options
230237
public Task<BigQueryJob> CancelAsync(CancelJobOptions options = null, CancellationToken cancellationToken = default) =>
231238
_client.CancelJobAsync(Reference, options, cancellationToken);
232239

240+
/// <summary>
241+
/// Asynchronously deletes this job.
242+
/// This method just creates a <see cref="JobReference"/> and delegates to <see cref="BigQueryClient.DeleteJobAsync(JobReference, DeleteJobOptions, CancellationToken)"/>.
243+
/// </summary>
244+
/// <param name="options">The options for the operation. May be null, in which case defaults will be supplied.</param>
245+
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
246+
/// <returns>A task representing the asynchronous operation. When complete, the result is
247+
/// the final state of the job.</returns>
248+
public Task DeleteAsync(DeleteJobOptions options = null, CancellationToken cancellationToken = default) =>
249+
_client.DeleteJobAsync(Reference, options, cancellationToken);
250+
233251
/// <summary>
234252
/// The query destination table can be null if it's been fetched with and odd field mask
235253
/// or for script queries. We use the destination table only to pass around in
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License").
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using static Google.Apis.Bigquery.v2.JobsResource;
16+
17+
namespace Google.Cloud.BigQuery.V2;
18+
19+
/// <summary>
20+
/// Options for <c>DeleteJob</c> operations. Currently no options are
21+
/// available, but this class exists to provide consistency and extensibility.
22+
/// </summary>
23+
public sealed class DeleteJobOptions
24+
{
25+
internal void ModifyRequest(DeleteRequest request)
26+
{ }
27+
}

0 commit comments

Comments
 (0)