vendor: update all dependencies
* Update all dependencies * Remove all `[[constraint]]` from Gopkg.toml * Add in the minimum number of `[[override]]` to build * Remove go get of github.com/inconshreveable/mousetrap as it is vendored * Update docs with new policy on constraints
This commit is contained in:
+5
@@ -47,6 +47,11 @@ func setClientHeader(headers http.Header) {
|
||||
|
||||
// Client may be used to perform BigQuery operations.
|
||||
type Client struct {
|
||||
// Location, if set, will be used as the default location for all subsequent
|
||||
// dataset creation and job operations. A location specified directly in one of
|
||||
// those operations will override this value.
|
||||
Location string
|
||||
|
||||
projectID string
|
||||
bqs *bq.Service
|
||||
}
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ func (c *Copier) Run(ctx context.Context) (*Job, error) {
|
||||
|
||||
func (c *Copier) newJob() *bq.Job {
|
||||
return &bq.Job{
|
||||
JobReference: c.JobIDConfig.createJobRef(c.c.projectID),
|
||||
JobReference: c.JobIDConfig.createJobRef(c.c),
|
||||
Configuration: c.CopyConfig.toBQ(),
|
||||
}
|
||||
}
|
||||
|
||||
+27
-5
@@ -49,11 +49,12 @@ func defaultCopyJob() *bq.Job {
|
||||
func TestCopy(t *testing.T) {
|
||||
defer fixRandomID("RANDOM")()
|
||||
testCases := []struct {
|
||||
dst *Table
|
||||
srcs []*Table
|
||||
jobID string
|
||||
config CopyConfig
|
||||
want *bq.Job
|
||||
dst *Table
|
||||
srcs []*Table
|
||||
jobID string
|
||||
location string
|
||||
config CopyConfig
|
||||
want *bq.Job
|
||||
}{
|
||||
{
|
||||
dst: &Table{
|
||||
@@ -118,12 +119,33 @@ func TestCopy(t *testing.T) {
|
||||
return j
|
||||
}(),
|
||||
},
|
||||
{
|
||||
dst: &Table{
|
||||
ProjectID: "d-project-id",
|
||||
DatasetID: "d-dataset-id",
|
||||
TableID: "d-table-id",
|
||||
},
|
||||
srcs: []*Table{
|
||||
{
|
||||
ProjectID: "s-project-id",
|
||||
DatasetID: "s-dataset-id",
|
||||
TableID: "s-table-id",
|
||||
},
|
||||
},
|
||||
location: "asia-northeast1",
|
||||
want: func() *bq.Job {
|
||||
j := defaultCopyJob()
|
||||
j.JobReference.Location = "asia-northeast1"
|
||||
return j
|
||||
}(),
|
||||
},
|
||||
}
|
||||
c := &Client{projectID: "client-project-id"}
|
||||
for i, tc := range testCases {
|
||||
tc.dst.c = c
|
||||
copier := tc.dst.CopierFrom(tc.srcs...)
|
||||
copier.JobID = tc.jobID
|
||||
copier.Location = tc.location
|
||||
tc.config.Srcs = tc.srcs
|
||||
tc.config.Dst = tc.dst
|
||||
copier.CopyConfig = tc.config
|
||||
|
||||
+21
-4
@@ -20,6 +20,7 @@ import (
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/internal/optional"
|
||||
"cloud.google.com/go/internal/trace"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
bq "google.golang.org/api/bigquery/v2"
|
||||
@@ -85,12 +86,19 @@ func (c *Client) DatasetInProject(projectID, datasetID string) *Dataset {
|
||||
|
||||
// Create creates a dataset in the BigQuery service. An error will be returned if the
|
||||
// dataset already exists. Pass in a DatasetMetadata value to configure the dataset.
|
||||
func (d *Dataset) Create(ctx context.Context, md *DatasetMetadata) error {
|
||||
func (d *Dataset) Create(ctx context.Context, md *DatasetMetadata) (err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Dataset.Create")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
ds, err := md.toBQ()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ds.DatasetReference = &bq.DatasetReference{DatasetId: d.DatasetID}
|
||||
// Use Client.Location as a default.
|
||||
if ds.Location == "" {
|
||||
ds.Location = d.c.Location
|
||||
}
|
||||
call := d.c.bqs.Datasets.Insert(d.ProjectID, ds).Context(ctx)
|
||||
setClientHeader(call.Header())
|
||||
_, err = call.Do()
|
||||
@@ -140,14 +148,20 @@ func accessListToBQ(a []*AccessEntry) ([]*bq.DatasetAccess, error) {
|
||||
}
|
||||
|
||||
// Delete deletes the dataset.
|
||||
func (d *Dataset) Delete(ctx context.Context) error {
|
||||
func (d *Dataset) Delete(ctx context.Context) (err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Dataset.Delete")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
call := d.c.bqs.Datasets.Delete(d.ProjectID, d.DatasetID).Context(ctx)
|
||||
setClientHeader(call.Header())
|
||||
return call.Do()
|
||||
}
|
||||
|
||||
// Metadata fetches the metadata for the dataset.
|
||||
func (d *Dataset) Metadata(ctx context.Context) (*DatasetMetadata, error) {
|
||||
func (d *Dataset) Metadata(ctx context.Context) (md *DatasetMetadata, err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Dataset.Metadata")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
call := d.c.bqs.Datasets.Get(d.ProjectID, d.DatasetID).Context(ctx)
|
||||
setClientHeader(call.Header())
|
||||
var ds *bq.Dataset
|
||||
@@ -186,7 +200,10 @@ func bqToDatasetMetadata(d *bq.Dataset) (*DatasetMetadata, error) {
|
||||
// To perform a read-modify-write that protects against intervening reads,
|
||||
// set the etag argument to the DatasetMetadata.ETag field from the read.
|
||||
// Pass the empty string for etag for a "blind write" that will always succeed.
|
||||
func (d *Dataset) Update(ctx context.Context, dm DatasetMetadataToUpdate, etag string) (*DatasetMetadata, error) {
|
||||
func (d *Dataset) Update(ctx context.Context, dm DatasetMetadataToUpdate, etag string) (md *DatasetMetadata, err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Dataset.Update")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
ds, err := dm.toBQ()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -55,7 +55,7 @@ func TestDataTransferServiceSmoke(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", projectId, "us-central1")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s", projectId)
|
||||
var request = &datatransferpb.ListDataSourcesRequest{
|
||||
Parent: formattedParent,
|
||||
}
|
||||
|
||||
+1
-1
@@ -294,7 +294,7 @@ func (c *Client) ListTransferConfigs(ctx context.Context, req *datatransferpb.Li
|
||||
return it
|
||||
}
|
||||
|
||||
// ScheduleTransferRuns creates transfer runs for a time range [range_start_time, range_end_time].
|
||||
// ScheduleTransferRuns creates transfer runs for a time range [start_time, end_time].
|
||||
// For each date - or whatever granularity the data source supports - in the
|
||||
// range, one transfer run is created.
|
||||
// Note that runs are created per UTC time in the time range.
|
||||
|
||||
-2
@@ -42,8 +42,6 @@ func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context {
|
||||
// DefaultAuthScopes reports the default set of authentication scopes to use with this package.
|
||||
func DefaultAuthScopes() []string {
|
||||
return []string{
|
||||
"https://www.googleapis.com/auth/bigquery",
|
||||
"https://www.googleapis.com/auth/cloud-platform",
|
||||
"https://www.googleapis.com/auth/cloud-platform.read-only",
|
||||
}
|
||||
}
|
||||
|
||||
+24
-24
@@ -281,7 +281,7 @@ func TestDataTransferServiceGetDataSource(t *testing.T) {
|
||||
|
||||
mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse)
|
||||
|
||||
var formattedName string = fmt.Sprintf("projects/%s/locations/%s/dataSources/%s", "[PROJECT]", "[LOCATION]", "[DATA_SOURCE]")
|
||||
var formattedName string = fmt.Sprintf("projects/%s/dataSources/%s", "[PROJECT]", "[DATA_SOURCE]")
|
||||
var request = &datatransferpb.GetDataSourceRequest{
|
||||
Name: formattedName,
|
||||
}
|
||||
@@ -310,7 +310,7 @@ func TestDataTransferServiceGetDataSourceError(t *testing.T) {
|
||||
errCode := codes.PermissionDenied
|
||||
mockDataTransfer.err = gstatus.Error(errCode, "test error")
|
||||
|
||||
var formattedName string = fmt.Sprintf("projects/%s/locations/%s/dataSources/%s", "[PROJECT]", "[LOCATION]", "[DATA_SOURCE]")
|
||||
var formattedName string = fmt.Sprintf("projects/%s/dataSources/%s", "[PROJECT]", "[DATA_SOURCE]")
|
||||
var request = &datatransferpb.GetDataSourceRequest{
|
||||
Name: formattedName,
|
||||
}
|
||||
@@ -343,7 +343,7 @@ func TestDataTransferServiceListDataSources(t *testing.T) {
|
||||
|
||||
mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse)
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
|
||||
var request = &datatransferpb.ListDataSourcesRequest{
|
||||
Parent: formattedParent,
|
||||
}
|
||||
@@ -382,7 +382,7 @@ func TestDataTransferServiceListDataSourcesError(t *testing.T) {
|
||||
errCode := codes.PermissionDenied
|
||||
mockDataTransfer.err = gstatus.Error(errCode, "test error")
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
|
||||
var request = &datatransferpb.ListDataSourcesRequest{
|
||||
Parent: formattedParent,
|
||||
}
|
||||
@@ -428,7 +428,7 @@ func TestDataTransferServiceCreateTransferConfig(t *testing.T) {
|
||||
|
||||
mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse)
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
|
||||
var transferConfig *datatransferpb.TransferConfig = &datatransferpb.TransferConfig{}
|
||||
var request = &datatransferpb.CreateTransferConfigRequest{
|
||||
Parent: formattedParent,
|
||||
@@ -459,7 +459,7 @@ func TestDataTransferServiceCreateTransferConfigError(t *testing.T) {
|
||||
errCode := codes.PermissionDenied
|
||||
mockDataTransfer.err = gstatus.Error(errCode, "test error")
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
|
||||
var transferConfig *datatransferpb.TransferConfig = &datatransferpb.TransferConfig{}
|
||||
var request = &datatransferpb.CreateTransferConfigRequest{
|
||||
Parent: formattedParent,
|
||||
@@ -567,7 +567,7 @@ func TestDataTransferServiceDeleteTransferConfig(t *testing.T) {
|
||||
|
||||
mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse)
|
||||
|
||||
var formattedName string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]")
|
||||
var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]")
|
||||
var request = &datatransferpb.DeleteTransferConfigRequest{
|
||||
Name: formattedName,
|
||||
}
|
||||
@@ -593,7 +593,7 @@ func TestDataTransferServiceDeleteTransferConfigError(t *testing.T) {
|
||||
errCode := codes.PermissionDenied
|
||||
mockDataTransfer.err = gstatus.Error(errCode, "test error")
|
||||
|
||||
var formattedName string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]")
|
||||
var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]")
|
||||
var request = &datatransferpb.DeleteTransferConfigRequest{
|
||||
Name: formattedName,
|
||||
}
|
||||
@@ -638,7 +638,7 @@ func TestDataTransferServiceGetTransferConfig(t *testing.T) {
|
||||
|
||||
mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse)
|
||||
|
||||
var formattedName string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]")
|
||||
var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]")
|
||||
var request = &datatransferpb.GetTransferConfigRequest{
|
||||
Name: formattedName,
|
||||
}
|
||||
@@ -667,7 +667,7 @@ func TestDataTransferServiceGetTransferConfigError(t *testing.T) {
|
||||
errCode := codes.PermissionDenied
|
||||
mockDataTransfer.err = gstatus.Error(errCode, "test error")
|
||||
|
||||
var formattedName string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]")
|
||||
var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]")
|
||||
var request = &datatransferpb.GetTransferConfigRequest{
|
||||
Name: formattedName,
|
||||
}
|
||||
@@ -700,7 +700,7 @@ func TestDataTransferServiceListTransferConfigs(t *testing.T) {
|
||||
|
||||
mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse)
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
|
||||
var request = &datatransferpb.ListTransferConfigsRequest{
|
||||
Parent: formattedParent,
|
||||
}
|
||||
@@ -739,7 +739,7 @@ func TestDataTransferServiceListTransferConfigsError(t *testing.T) {
|
||||
errCode := codes.PermissionDenied
|
||||
mockDataTransfer.err = gstatus.Error(errCode, "test error")
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
|
||||
var request = &datatransferpb.ListTransferConfigsRequest{
|
||||
Parent: formattedParent,
|
||||
}
|
||||
@@ -766,7 +766,7 @@ func TestDataTransferServiceScheduleTransferRuns(t *testing.T) {
|
||||
|
||||
mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse)
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]")
|
||||
var startTime *timestamppb.Timestamp = ×tamppb.Timestamp{}
|
||||
var endTime *timestamppb.Timestamp = ×tamppb.Timestamp{}
|
||||
var request = &datatransferpb.ScheduleTransferRunsRequest{
|
||||
@@ -799,7 +799,7 @@ func TestDataTransferServiceScheduleTransferRunsError(t *testing.T) {
|
||||
errCode := codes.PermissionDenied
|
||||
mockDataTransfer.err = gstatus.Error(errCode, "test error")
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]")
|
||||
var startTime *timestamppb.Timestamp = ×tamppb.Timestamp{}
|
||||
var endTime *timestamppb.Timestamp = ×tamppb.Timestamp{}
|
||||
var request = &datatransferpb.ScheduleTransferRunsRequest{
|
||||
@@ -841,7 +841,7 @@ func TestDataTransferServiceGetTransferRun(t *testing.T) {
|
||||
|
||||
mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse)
|
||||
|
||||
var formattedName string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]", "[RUN]")
|
||||
var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[TRANSFER_CONFIG]", "[RUN]")
|
||||
var request = &datatransferpb.GetTransferRunRequest{
|
||||
Name: formattedName,
|
||||
}
|
||||
@@ -870,7 +870,7 @@ func TestDataTransferServiceGetTransferRunError(t *testing.T) {
|
||||
errCode := codes.PermissionDenied
|
||||
mockDataTransfer.err = gstatus.Error(errCode, "test error")
|
||||
|
||||
var formattedName string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]", "[RUN]")
|
||||
var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[TRANSFER_CONFIG]", "[RUN]")
|
||||
var request = &datatransferpb.GetTransferRunRequest{
|
||||
Name: formattedName,
|
||||
}
|
||||
@@ -897,7 +897,7 @@ func TestDataTransferServiceDeleteTransferRun(t *testing.T) {
|
||||
|
||||
mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse)
|
||||
|
||||
var formattedName string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]", "[RUN]")
|
||||
var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[TRANSFER_CONFIG]", "[RUN]")
|
||||
var request = &datatransferpb.DeleteTransferRunRequest{
|
||||
Name: formattedName,
|
||||
}
|
||||
@@ -923,7 +923,7 @@ func TestDataTransferServiceDeleteTransferRunError(t *testing.T) {
|
||||
errCode := codes.PermissionDenied
|
||||
mockDataTransfer.err = gstatus.Error(errCode, "test error")
|
||||
|
||||
var formattedName string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]", "[RUN]")
|
||||
var formattedName string = fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[TRANSFER_CONFIG]", "[RUN]")
|
||||
var request = &datatransferpb.DeleteTransferRunRequest{
|
||||
Name: formattedName,
|
||||
}
|
||||
@@ -955,7 +955,7 @@ func TestDataTransferServiceListTransferRuns(t *testing.T) {
|
||||
|
||||
mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse)
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]")
|
||||
var request = &datatransferpb.ListTransferRunsRequest{
|
||||
Parent: formattedParent,
|
||||
}
|
||||
@@ -994,7 +994,7 @@ func TestDataTransferServiceListTransferRunsError(t *testing.T) {
|
||||
errCode := codes.PermissionDenied
|
||||
mockDataTransfer.err = gstatus.Error(errCode, "test error")
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/transferConfigs/%s", "[PROJECT]", "[TRANSFER_CONFIG]")
|
||||
var request = &datatransferpb.ListTransferRunsRequest{
|
||||
Parent: formattedParent,
|
||||
}
|
||||
@@ -1027,7 +1027,7 @@ func TestDataTransferServiceListTransferLogs(t *testing.T) {
|
||||
|
||||
mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse)
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]", "[RUN]")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[TRANSFER_CONFIG]", "[RUN]")
|
||||
var request = &datatransferpb.ListTransferLogsRequest{
|
||||
Parent: formattedParent,
|
||||
}
|
||||
@@ -1066,7 +1066,7 @@ func TestDataTransferServiceListTransferLogsError(t *testing.T) {
|
||||
errCode := codes.PermissionDenied
|
||||
mockDataTransfer.err = gstatus.Error(errCode, "test error")
|
||||
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[LOCATION]", "[TRANSFER_CONFIG]", "[RUN]")
|
||||
var formattedParent string = fmt.Sprintf("projects/%s/transferConfigs/%s/runs/%s", "[PROJECT]", "[TRANSFER_CONFIG]", "[RUN]")
|
||||
var request = &datatransferpb.ListTransferLogsRequest{
|
||||
Parent: formattedParent,
|
||||
}
|
||||
@@ -1096,7 +1096,7 @@ func TestDataTransferServiceCheckValidCreds(t *testing.T) {
|
||||
|
||||
mockDataTransfer.resps = append(mockDataTransfer.resps[:0], expectedResponse)
|
||||
|
||||
var formattedName string = fmt.Sprintf("projects/%s/locations/%s/dataSources/%s", "[PROJECT]", "[LOCATION]", "[DATA_SOURCE]")
|
||||
var formattedName string = fmt.Sprintf("projects/%s/dataSources/%s", "[PROJECT]", "[DATA_SOURCE]")
|
||||
var request = &datatransferpb.CheckValidCredsRequest{
|
||||
Name: formattedName,
|
||||
}
|
||||
@@ -1125,7 +1125,7 @@ func TestDataTransferServiceCheckValidCredsError(t *testing.T) {
|
||||
errCode := codes.PermissionDenied
|
||||
mockDataTransfer.err = gstatus.Error(errCode, "test error")
|
||||
|
||||
var formattedName string = fmt.Sprintf("projects/%s/locations/%s/dataSources/%s", "[PROJECT]", "[LOCATION]", "[DATA_SOURCE]")
|
||||
var formattedName string = fmt.Sprintf("projects/%s/dataSources/%s", "[PROJECT]", "[DATA_SOURCE]")
|
||||
var request = &datatransferpb.CheckValidCredsRequest{
|
||||
Name: formattedName,
|
||||
}
|
||||
|
||||
+6
-2
@@ -15,6 +15,7 @@
|
||||
package bigquery
|
||||
|
||||
import (
|
||||
"cloud.google.com/go/internal/trace"
|
||||
"golang.org/x/net/context"
|
||||
bq "google.golang.org/api/bigquery/v2"
|
||||
)
|
||||
@@ -93,13 +94,16 @@ func (t *Table) ExtractorTo(dst *GCSReference) *Extractor {
|
||||
}
|
||||
|
||||
// Run initiates an extract job.
|
||||
func (e *Extractor) Run(ctx context.Context) (*Job, error) {
|
||||
func (e *Extractor) Run(ctx context.Context) (j *Job, err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Extractor.Run")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
return e.c.insertJob(ctx, e.newJob(), nil)
|
||||
}
|
||||
|
||||
func (e *Extractor) newJob() *bq.Job {
|
||||
return &bq.Job{
|
||||
JobReference: e.JobIDConfig.createJobRef(e.c.projectID),
|
||||
JobReference: e.JobIDConfig.createJobRef(e.c),
|
||||
Configuration: e.ExtractConfig.toBQ(),
|
||||
}
|
||||
}
|
||||
|
||||
+120
-6
@@ -59,6 +59,9 @@ var (
|
||||
tableIDs = testutil.NewUIDSpaceSep("table", '_')
|
||||
)
|
||||
|
||||
// Note: integration tests cannot be run in parallel, because TestIntegration_Location
|
||||
// modifies the client.
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
cleanup := initIntegrationTest()
|
||||
r := m.Run()
|
||||
@@ -943,23 +946,23 @@ func TestIntegration_TableUpdate(t *testing.T) {
|
||||
// Error cases when updating schema.
|
||||
for _, test := range []struct {
|
||||
desc string
|
||||
fields []*FieldSchema
|
||||
fields Schema
|
||||
}{
|
||||
{"change from optional to required", []*FieldSchema{
|
||||
{"change from optional to required", Schema{
|
||||
{Name: "name", Type: StringFieldType, Required: true},
|
||||
schema3[1],
|
||||
schema3[2],
|
||||
schema3[3],
|
||||
}},
|
||||
{"add a required field", []*FieldSchema{
|
||||
{"add a required field", Schema{
|
||||
schema3[0], schema3[1], schema3[2], schema3[3],
|
||||
{Name: "req", Type: StringFieldType, Required: true},
|
||||
}},
|
||||
{"remove a field", []*FieldSchema{schema3[0], schema3[1], schema3[2]}},
|
||||
{"remove a nested field", []*FieldSchema{
|
||||
{"remove a field", Schema{schema3[0], schema3[1], schema3[2]}},
|
||||
{"remove a nested field", Schema{
|
||||
schema3[0], schema3[1], schema3[2],
|
||||
{Name: "rec2", Type: RecordFieldType, Schema: Schema{nested[0]}}}},
|
||||
{"remove all nested fields", []*FieldSchema{
|
||||
{"remove all nested fields", Schema{
|
||||
schema3[0], schema3[1], schema3[2],
|
||||
{Name: "rec2", Type: RecordFieldType, Schema: Schema{}}}},
|
||||
} {
|
||||
@@ -1603,6 +1606,117 @@ func TestIntegration_ListJobs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
const tokyo = "asia-northeast1"
|
||||
|
||||
func TestIntegration_Location(t *testing.T) {
|
||||
if client == nil {
|
||||
t.Skip("Integration tests skipped")
|
||||
}
|
||||
client.Location = ""
|
||||
testLocation(t, tokyo)
|
||||
client.Location = tokyo
|
||||
defer func() {
|
||||
client.Location = ""
|
||||
}()
|
||||
testLocation(t, "")
|
||||
}
|
||||
|
||||
func testLocation(t *testing.T, loc string) {
|
||||
ctx := context.Background()
|
||||
tokyoDataset := client.Dataset("tokyo")
|
||||
err := tokyoDataset.Create(ctx, &DatasetMetadata{Location: loc})
|
||||
if err != nil && !hasStatusCode(err, 409) { // 409 = already exists
|
||||
t.Fatal(err)
|
||||
}
|
||||
md, err := tokyoDataset.Metadata(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if md.Location != tokyo {
|
||||
t.Fatalf("dataset location: got %s, want %s", md.Location, tokyo)
|
||||
}
|
||||
table := tokyoDataset.Table(tableIDs.New())
|
||||
err = table.Create(context.Background(), &TableMetadata{
|
||||
Schema: Schema{
|
||||
{Name: "name", Type: StringFieldType},
|
||||
{Name: "nums", Type: IntegerFieldType},
|
||||
},
|
||||
ExpirationTime: testTableExpiration,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer table.Delete(ctx)
|
||||
loader := table.LoaderFrom(NewReaderSource(strings.NewReader("a,0\nb,1\nc,2\n")))
|
||||
loader.Location = loc
|
||||
job, err := loader.Run(ctx)
|
||||
if err != nil {
|
||||
t.Fatal("loader.Run", err)
|
||||
}
|
||||
if job.Location() != tokyo {
|
||||
t.Fatalf("job location: got %s, want %s", job.Location(), tokyo)
|
||||
}
|
||||
_, err = client.JobFromID(ctx, job.ID())
|
||||
if client.Location == "" && err == nil {
|
||||
t.Error("JobFromID with Tokyo job, no client location: want error, got nil")
|
||||
}
|
||||
if client.Location != "" && err != nil {
|
||||
t.Errorf("JobFromID with Tokyo job, with client location: want nil, got %v", err)
|
||||
}
|
||||
_, err = client.JobFromIDLocation(ctx, job.ID(), "US")
|
||||
if err == nil {
|
||||
t.Error("JobFromIDLocation with US: want error, got nil")
|
||||
}
|
||||
job2, err := client.JobFromIDLocation(ctx, job.ID(), loc)
|
||||
if loc == tokyo && err != nil {
|
||||
t.Errorf("loc=tokyo: %v", err)
|
||||
}
|
||||
if loc == "" && err == nil {
|
||||
t.Error("loc empty: got nil, want error")
|
||||
}
|
||||
if job2 != nil && (job2.ID() != job.ID() || job2.Location() != tokyo) {
|
||||
t.Errorf("got id %s loc %s, want id%s loc %s", job2.ID(), job2.Location(), job.ID(), tokyo)
|
||||
}
|
||||
if err := wait(ctx, job); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Cancel should succeed even if the job is done.
|
||||
if err := job.Cancel(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
q := client.Query(fmt.Sprintf("SELECT * FROM %s.%s", table.DatasetID, table.TableID))
|
||||
q.Location = loc
|
||||
iter, err := q.Read(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wantRows := [][]Value{
|
||||
[]Value{"a", int64(0)},
|
||||
[]Value{"b", int64(1)},
|
||||
[]Value{"c", int64(2)},
|
||||
}
|
||||
checkRead(t, "location", iter, wantRows)
|
||||
|
||||
table2 := tokyoDataset.Table(tableIDs.New())
|
||||
copier := table2.CopierFrom(table)
|
||||
copier.Location = loc
|
||||
if _, err := copier.Run(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
bucketName := testutil.ProjID()
|
||||
objectName := fmt.Sprintf("bq-test-%s.csv", table.TableID)
|
||||
uri := fmt.Sprintf("gs://%s/%s", bucketName, objectName)
|
||||
defer storageClient.Bucket(bucketName).Object(objectName).Delete(ctx)
|
||||
gr := NewGCSReference(uri)
|
||||
gr.DestinationFormat = CSV
|
||||
e := table.ExtractorTo(gr)
|
||||
e.Location = loc
|
||||
if _, err := e.Run(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a new, temporary table with a unique name and the given schema.
|
||||
func newTable(t *testing.T, s Schema) *Table {
|
||||
table := dataset.Table(tableIDs.New())
|
||||
|
||||
+51
-12
@@ -23,6 +23,7 @@ import (
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/internal"
|
||||
"cloud.google.com/go/internal/trace"
|
||||
gax "github.com/googleapis/gax-go"
|
||||
"golang.org/x/net/context"
|
||||
bq "google.golang.org/api/bigquery/v2"
|
||||
@@ -35,6 +36,7 @@ type Job struct {
|
||||
c *Client
|
||||
projectID string
|
||||
jobID string
|
||||
location string
|
||||
|
||||
config *bq.JobConfiguration
|
||||
lastStatus *JobStatus
|
||||
@@ -43,8 +45,21 @@ type Job struct {
|
||||
// JobFromID creates a Job which refers to an existing BigQuery job. The job
|
||||
// need not have been created by this package. For example, the job may have
|
||||
// been created in the BigQuery console.
|
||||
//
|
||||
// For jobs whose location is other than "US" or "EU", set Client.Location or use
|
||||
// JobFromIDLocation.
|
||||
func (c *Client) JobFromID(ctx context.Context, id string) (*Job, error) {
|
||||
bqjob, err := c.getJobInternal(ctx, id, "configuration", "jobReference", "status", "statistics")
|
||||
return c.JobFromIDLocation(ctx, id, c.Location)
|
||||
}
|
||||
|
||||
// JobFromIDLocation creates a Job which refers to an existing BigQuery job. The job
|
||||
// need not have been created by this package (for example, it may have
|
||||
// been created in the BigQuery console), but it must exist in the specified location.
|
||||
func (c *Client) JobFromIDLocation(ctx context.Context, id, location string) (j *Job, err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.JobFromIDLocation")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
bqjob, err := c.getJobInternal(ctx, id, location, "configuration", "jobReference", "status", "statistics")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -56,6 +71,11 @@ func (j *Job) ID() string {
|
||||
return j.jobID
|
||||
}
|
||||
|
||||
// Location returns the job's location.
|
||||
func (j *Job) Location() string {
|
||||
return j.location
|
||||
}
|
||||
|
||||
// State is one of a sequence of states that a Job progresses through as it is processed.
|
||||
type State int
|
||||
|
||||
@@ -120,14 +140,20 @@ type JobIDConfig struct {
|
||||
|
||||
// If AddJobIDSuffix is true, then a random string will be appended to JobID.
|
||||
AddJobIDSuffix bool
|
||||
|
||||
// Location is the location for the job.
|
||||
Location string
|
||||
}
|
||||
|
||||
// createJobRef creates a JobReference.
|
||||
// projectID must be non-empty.
|
||||
func (j *JobIDConfig) createJobRef(projectID string) *bq.JobReference {
|
||||
func (j *JobIDConfig) createJobRef(c *Client) *bq.JobReference {
|
||||
// We don't check whether projectID is empty; the server will return an
|
||||
// error when it encounters the resulting JobReference.
|
||||
jr := &bq.JobReference{ProjectId: projectID}
|
||||
loc := j.Location
|
||||
if loc == "" { // Use Client.Location as a default.
|
||||
loc = c.Location
|
||||
}
|
||||
jr := &bq.JobReference{ProjectId: c.projectID, Location: loc}
|
||||
if j.JobID == "" {
|
||||
jr.JobId = randomIDFn()
|
||||
} else if j.AddJobIDSuffix {
|
||||
@@ -175,8 +201,11 @@ func (s *JobStatus) Err() error {
|
||||
}
|
||||
|
||||
// Status retrieves the current status of the job from BigQuery. It fails if the Status could not be determined.
|
||||
func (j *Job) Status(ctx context.Context) (*JobStatus, error) {
|
||||
bqjob, err := j.c.getJobInternal(ctx, j.jobID, "status", "statistics")
|
||||
func (j *Job) Status(ctx context.Context) (js *JobStatus, err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Job.Status")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
bqjob, err := j.c.getJobInternal(ctx, j.jobID, j.location, "status", "statistics")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -204,6 +233,7 @@ func (j *Job) Cancel(ctx context.Context) error {
|
||||
// to poll for the job status to see if the cancel completed
|
||||
// successfully". So it would be misleading to return a status.
|
||||
call := j.c.bqs.Jobs.Cancel(j.projectID, j.jobID).
|
||||
Location(j.location).
|
||||
Fields(). // We don't need any of the response data.
|
||||
Context(ctx)
|
||||
setClientHeader(call.Header())
|
||||
@@ -218,7 +248,10 @@ func (j *Job) Cancel(ctx context.Context) error {
|
||||
// If an error occurs while retrieving the status, Wait returns that error. But
|
||||
// Wait returns nil if the status was retrieved successfully, even if
|
||||
// status.Err() != nil. So callers must check both errors. See the example.
|
||||
func (j *Job) Wait(ctx context.Context) (*JobStatus, error) {
|
||||
func (j *Job) Wait(ctx context.Context) (js *JobStatus, err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Job.Wait")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
if j.isQuery() {
|
||||
// We can avoid polling for query jobs.
|
||||
if _, err := j.waitForQuery(ctx, j.projectID); err != nil {
|
||||
@@ -232,8 +265,7 @@ func (j *Job) Wait(ctx context.Context) (*JobStatus, error) {
|
||||
return js, nil
|
||||
}
|
||||
// Non-query jobs must poll.
|
||||
var js *JobStatus
|
||||
err := internal.Retry(ctx, gax.Backoff{}, func() (stop bool, err error) {
|
||||
err = internal.Retry(ctx, gax.Backoff{}, func() (stop bool, err error) {
|
||||
js, err = j.Status(ctx)
|
||||
if err != nil {
|
||||
return true, err
|
||||
@@ -251,7 +283,10 @@ func (j *Job) Wait(ctx context.Context) (*JobStatus, error) {
|
||||
|
||||
// Read fetches the results of a query job.
|
||||
// If j is not a query job, Read returns an error.
|
||||
func (j *Job) Read(ctx context.Context) (*RowIterator, error) {
|
||||
func (j *Job) Read(ctx context.Context) (ri *RowIterator, err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Job.Read")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
return j.read(ctx, j.waitForQuery, fetchPage)
|
||||
}
|
||||
|
||||
@@ -281,7 +316,7 @@ func (j *Job) read(ctx context.Context, waitForQuery func(context.Context, strin
|
||||
// waitForQuery waits for the query job to complete and returns its schema.
|
||||
func (j *Job) waitForQuery(ctx context.Context, projectID string) (Schema, error) {
|
||||
// Use GetQueryResults only to wait for completion, not to read results.
|
||||
call := j.c.bqs.Jobs.GetQueryResults(projectID, j.jobID).Context(ctx).MaxResults(0)
|
||||
call := j.c.bqs.Jobs.GetQueryResults(projectID, j.jobID).Location(j.location).Context(ctx).MaxResults(0)
|
||||
setClientHeader(call.Header())
|
||||
backoff := gax.Backoff{
|
||||
Initial: 1 * time.Second,
|
||||
@@ -525,9 +560,12 @@ func convertListedJob(j *bq.JobListJobs, c *Client) (*Job, error) {
|
||||
return bqToJob2(j.JobReference, j.Configuration, j.Status, j.Statistics, c)
|
||||
}
|
||||
|
||||
func (c *Client) getJobInternal(ctx context.Context, jobID string, fields ...googleapi.Field) (*bq.Job, error) {
|
||||
func (c *Client) getJobInternal(ctx context.Context, jobID, location string, fields ...googleapi.Field) (*bq.Job, error) {
|
||||
var job *bq.Job
|
||||
call := c.bqs.Jobs.Get(c.projectID, jobID).Context(ctx)
|
||||
if location != "" {
|
||||
call = call.Location(location)
|
||||
}
|
||||
if len(fields) > 0 {
|
||||
call = call.Fields(fields...)
|
||||
}
|
||||
@@ -550,6 +588,7 @@ func bqToJob2(qr *bq.JobReference, qc *bq.JobConfiguration, qs *bq.JobStatus, qt
|
||||
j := &Job{
|
||||
projectID: qr.ProjectId,
|
||||
jobID: qr.JobId,
|
||||
location: qr.Location,
|
||||
c: c,
|
||||
}
|
||||
j.setConfig(qc)
|
||||
|
||||
+35
-20
@@ -23,37 +23,52 @@ import (
|
||||
|
||||
func TestCreateJobRef(t *testing.T) {
|
||||
defer fixRandomID("RANDOM")()
|
||||
cNoLoc := &Client{projectID: "projectID"}
|
||||
cLoc := &Client{projectID: "projectID", Location: "defaultLoc"}
|
||||
for _, test := range []struct {
|
||||
jobID string
|
||||
addJobIDSuffix bool
|
||||
want string
|
||||
in JobIDConfig
|
||||
client *Client
|
||||
want *bq.JobReference
|
||||
}{
|
||||
{
|
||||
jobID: "foo",
|
||||
addJobIDSuffix: false,
|
||||
want: "foo",
|
||||
in: JobIDConfig{JobID: "foo"},
|
||||
want: &bq.JobReference{JobId: "foo"},
|
||||
},
|
||||
{
|
||||
jobID: "",
|
||||
addJobIDSuffix: false,
|
||||
want: "RANDOM",
|
||||
in: JobIDConfig{},
|
||||
want: &bq.JobReference{JobId: "RANDOM"},
|
||||
},
|
||||
{
|
||||
jobID: "",
|
||||
addJobIDSuffix: true, // irrelevant
|
||||
want: "RANDOM",
|
||||
in: JobIDConfig{AddJobIDSuffix: true},
|
||||
want: &bq.JobReference{JobId: "RANDOM"},
|
||||
},
|
||||
{
|
||||
jobID: "foo",
|
||||
addJobIDSuffix: true,
|
||||
want: "foo-RANDOM",
|
||||
in: JobIDConfig{JobID: "foo", AddJobIDSuffix: true},
|
||||
want: &bq.JobReference{JobId: "foo-RANDOM"},
|
||||
},
|
||||
{
|
||||
in: JobIDConfig{JobID: "foo", Location: "loc"},
|
||||
want: &bq.JobReference{JobId: "foo", Location: "loc"},
|
||||
},
|
||||
{
|
||||
in: JobIDConfig{JobID: "foo"},
|
||||
client: cLoc,
|
||||
want: &bq.JobReference{JobId: "foo", Location: "defaultLoc"},
|
||||
},
|
||||
{
|
||||
in: JobIDConfig{JobID: "foo", Location: "loc"},
|
||||
client: cLoc,
|
||||
want: &bq.JobReference{JobId: "foo", Location: "loc"},
|
||||
},
|
||||
} {
|
||||
jc := JobIDConfig{JobID: test.jobID, AddJobIDSuffix: test.addJobIDSuffix}
|
||||
jr := jc.createJobRef("projectID")
|
||||
got := jr.JobId
|
||||
if got != test.want {
|
||||
t.Errorf("%q, %t: got %q, want %q", test.jobID, test.addJobIDSuffix, got, test.want)
|
||||
client := test.client
|
||||
if client == nil {
|
||||
client = cNoLoc
|
||||
}
|
||||
got := test.in.createJobRef(client)
|
||||
test.want.ProjectId = "projectID"
|
||||
if !testutil.Equal(got, test.want) {
|
||||
t.Errorf("%+v: got %+v, want %+v", test.in, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-2
@@ -17,6 +17,7 @@ package bigquery
|
||||
import (
|
||||
"io"
|
||||
|
||||
"cloud.google.com/go/internal/trace"
|
||||
"golang.org/x/net/context"
|
||||
bq "google.golang.org/api/bigquery/v2"
|
||||
)
|
||||
@@ -45,6 +46,10 @@ type LoadConfig struct {
|
||||
|
||||
// Custom encryption configuration (e.g., Cloud KMS keys).
|
||||
DestinationEncryptionConfig *EncryptionConfig
|
||||
|
||||
// SchemaUpdateOptions allows the schema of the destination table to be
|
||||
// updated as a side effect of the load job.
|
||||
SchemaUpdateOptions []string
|
||||
}
|
||||
|
||||
func (l *LoadConfig) toBQ() (*bq.JobConfiguration, io.Reader) {
|
||||
@@ -56,6 +61,7 @@ func (l *LoadConfig) toBQ() (*bq.JobConfiguration, io.Reader) {
|
||||
DestinationTable: l.Dst.toBQ(),
|
||||
TimePartitioning: l.TimePartitioning.toBQ(),
|
||||
DestinationEncryptionConfiguration: l.DestinationEncryptionConfig.toBQ(),
|
||||
SchemaUpdateOptions: l.SchemaUpdateOptions,
|
||||
},
|
||||
}
|
||||
media := l.Src.populateLoadConfig(config.Load)
|
||||
@@ -70,6 +76,7 @@ func bqToLoadConfig(q *bq.JobConfiguration, c *Client) *LoadConfig {
|
||||
Dst: bqToTable(q.Load.DestinationTable, c),
|
||||
TimePartitioning: bqToTimePartitioning(q.Load.TimePartitioning),
|
||||
DestinationEncryptionConfig: bqToEncryptionConfig(q.Load.DestinationEncryptionConfiguration),
|
||||
SchemaUpdateOptions: q.Load.SchemaUpdateOptions,
|
||||
}
|
||||
var fc *FileConfig
|
||||
if len(q.Load.SourceUris) == 0 {
|
||||
@@ -117,7 +124,10 @@ func (t *Table) LoaderFrom(src LoadSource) *Loader {
|
||||
}
|
||||
|
||||
// Run initiates a load job.
|
||||
func (l *Loader) Run(ctx context.Context) (*Job, error) {
|
||||
func (l *Loader) Run(ctx context.Context) (j *Job, err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Load.Run")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
job, media := l.newJob()
|
||||
return l.c.insertJob(ctx, job, media)
|
||||
}
|
||||
@@ -125,7 +135,7 @@ func (l *Loader) Run(ctx context.Context) (*Job, error) {
|
||||
func (l *Loader) newJob() (*bq.Job, io.Reader) {
|
||||
config, media := l.LoadConfig.toBQ()
|
||||
return &bq.Job{
|
||||
JobReference: l.JobIDConfig.createJobRef(l.c.projectID),
|
||||
JobReference: l.JobIDConfig.createJobRef(l.c),
|
||||
Configuration: config,
|
||||
}, media
|
||||
}
|
||||
|
||||
+19
-5
@@ -74,17 +74,28 @@ func TestLoad(t *testing.T) {
|
||||
c := &Client{projectID: "client-project-id"}
|
||||
|
||||
testCases := []struct {
|
||||
dst *Table
|
||||
src LoadSource
|
||||
jobID string
|
||||
config LoadConfig
|
||||
want *bq.Job
|
||||
dst *Table
|
||||
src LoadSource
|
||||
jobID string
|
||||
location string
|
||||
config LoadConfig
|
||||
want *bq.Job
|
||||
}{
|
||||
{
|
||||
dst: c.Dataset("dataset-id").Table("table-id"),
|
||||
src: NewGCSReference("uri"),
|
||||
want: defaultLoadJob(),
|
||||
},
|
||||
{
|
||||
dst: c.Dataset("dataset-id").Table("table-id"),
|
||||
src: NewGCSReference("uri"),
|
||||
location: "loc",
|
||||
want: func() *bq.Job {
|
||||
j := defaultLoadJob()
|
||||
j.JobReference.Location = "loc"
|
||||
return j
|
||||
}(),
|
||||
},
|
||||
{
|
||||
dst: c.Dataset("dataset-id").Table("table-id"),
|
||||
jobID: "ajob",
|
||||
@@ -94,6 +105,7 @@ func TestLoad(t *testing.T) {
|
||||
Labels: map[string]string{"a": "b"},
|
||||
TimePartitioning: &TimePartitioning{Expiration: 1234 * time.Millisecond},
|
||||
DestinationEncryptionConfig: &EncryptionConfig{KMSKeyName: "keyName"},
|
||||
SchemaUpdateOptions: []string{"ALLOW_FIELD_ADDITION"},
|
||||
},
|
||||
src: NewGCSReference("uri"),
|
||||
want: func() *bq.Job {
|
||||
@@ -110,6 +122,7 @@ func TestLoad(t *testing.T) {
|
||||
JobId: "ajob",
|
||||
ProjectId: "client-project-id",
|
||||
}
|
||||
j.Configuration.Load.SchemaUpdateOptions = []string{"ALLOW_FIELD_ADDITION"}
|
||||
return j
|
||||
}(),
|
||||
},
|
||||
@@ -226,6 +239,7 @@ func TestLoad(t *testing.T) {
|
||||
for i, tc := range testCases {
|
||||
loader := tc.dst.LoaderFrom(tc.src)
|
||||
loader.JobID = tc.jobID
|
||||
loader.Location = tc.location
|
||||
tc.config.Src = tc.src
|
||||
tc.config.Dst = tc.dst
|
||||
loader.LoadConfig = tc.config
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// Copyright 2018 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build go1.8
|
||||
|
||||
package bigquery
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"cloud.google.com/go/internal/testutil"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func TestOCTracing(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
client := getClient(t)
|
||||
defer client.Close()
|
||||
|
||||
te := testutil.NewTestExporter()
|
||||
defer te.Unregister()
|
||||
|
||||
q := client.Query("select *")
|
||||
q.Run(ctx) // Doesn't matter if we get an error; span should be created either way
|
||||
|
||||
if len(te.Spans) == 0 {
|
||||
t.Fatalf("Expected some spans to be created, but got %d", 0)
|
||||
}
|
||||
}
|
||||
+7
-3
@@ -17,6 +17,7 @@ package bigquery
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"cloud.google.com/go/internal/trace"
|
||||
"golang.org/x/net/context"
|
||||
bq "google.golang.org/api/bigquery/v2"
|
||||
)
|
||||
@@ -260,12 +261,15 @@ func (c *Client) Query(q string) *Query {
|
||||
}
|
||||
|
||||
// Run initiates a query job.
|
||||
func (q *Query) Run(ctx context.Context) (*Job, error) {
|
||||
func (q *Query) Run(ctx context.Context) (j *Job, err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Query.Run")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
job, err := q.newJob()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
j, err := q.client.insertJob(ctx, job, nil)
|
||||
j, err = q.client.insertJob(ctx, job, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -278,7 +282,7 @@ func (q *Query) newJob() (*bq.Job, error) {
|
||||
return nil, err
|
||||
}
|
||||
return &bq.Job{
|
||||
JobReference: q.JobIDConfig.createJobRef(q.client.projectID),
|
||||
JobReference: q.JobIDConfig.createJobRef(q.client),
|
||||
Configuration: config,
|
||||
}, nil
|
||||
}
|
||||
|
||||
+1
-3
@@ -120,9 +120,7 @@ func TestQuery(t *testing.T) {
|
||||
g.MaxBadRecords = 1
|
||||
g.Quote = "'"
|
||||
g.SkipLeadingRows = 2
|
||||
g.Schema = Schema([]*FieldSchema{
|
||||
{Name: "name", Type: StringFieldType},
|
||||
})
|
||||
g.Schema = Schema{{Name: "name", Type: StringFieldType}}
|
||||
return g
|
||||
}(),
|
||||
},
|
||||
|
||||
-1
@@ -20,7 +20,6 @@ import (
|
||||
"reflect"
|
||||
|
||||
"cloud.google.com/go/internal/atomiccache"
|
||||
|
||||
bq "google.golang.org/api/bigquery/v2"
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -179,7 +179,7 @@ func TestSchemaConversion(t *testing.T) {
|
||||
Name: "outer",
|
||||
Required: true,
|
||||
Type: "RECORD",
|
||||
Schema: []*FieldSchema{
|
||||
Schema: Schema{
|
||||
{
|
||||
Description: "inner field",
|
||||
Name: "inner",
|
||||
|
||||
+18
-5
@@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/internal/trace"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"cloud.google.com/go/internal/optional"
|
||||
@@ -242,7 +243,10 @@ func (t *Table) implicitTable() bool {
|
||||
// Expiration can only be set during table creation.
|
||||
// After table creation, a view can be modified only if its table was initially created
|
||||
// with a view.
|
||||
func (t *Table) Create(ctx context.Context, tm *TableMetadata) error {
|
||||
func (t *Table) Create(ctx context.Context, tm *TableMetadata) (err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Table.Create")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
table, err := tm.toBQ()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -323,11 +327,14 @@ func (tm *TableMetadata) toBQ() (*bq.Table, error) {
|
||||
}
|
||||
|
||||
// Metadata fetches the metadata for the table.
|
||||
func (t *Table) Metadata(ctx context.Context) (*TableMetadata, error) {
|
||||
func (t *Table) Metadata(ctx context.Context) (md *TableMetadata, err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Table.Metadata")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
req := t.c.bqs.Tables.Get(t.ProjectID, t.DatasetID, t.TableID).Context(ctx)
|
||||
setClientHeader(req.Header())
|
||||
var table *bq.Table
|
||||
err := runWithRetry(ctx, func() (err error) {
|
||||
err = runWithRetry(ctx, func() (err error) {
|
||||
table, err = req.Do()
|
||||
return err
|
||||
})
|
||||
@@ -378,7 +385,10 @@ func bqToTableMetadata(t *bq.Table) (*TableMetadata, error) {
|
||||
}
|
||||
|
||||
// Delete deletes the table.
|
||||
func (t *Table) Delete(ctx context.Context) error {
|
||||
func (t *Table) Delete(ctx context.Context) (err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Table.Delete")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
req := t.c.bqs.Tables.Delete(t.ProjectID, t.DatasetID, t.TableID).Context(ctx)
|
||||
setClientHeader(req.Header())
|
||||
return req.Do()
|
||||
@@ -394,7 +404,10 @@ func (t *Table) read(ctx context.Context, pf pageFetcher) *RowIterator {
|
||||
}
|
||||
|
||||
// Update modifies specific Table metadata fields.
|
||||
func (t *Table) Update(ctx context.Context, tm TableMetadataToUpdate, etag string) (*TableMetadata, error) {
|
||||
func (t *Table) Update(ctx context.Context, tm TableMetadataToUpdate, etag string) (md *TableMetadata, err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Table.Update")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
bqt := tm.toBQ()
|
||||
call := t.c.bqs.Tables.Patch(t.ProjectID, t.DatasetID, t.TableID, bqt).Context(ctx)
|
||||
setClientHeader(call.Header())
|
||||
|
||||
+5
-1
@@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"cloud.google.com/go/internal/trace"
|
||||
"golang.org/x/net/context"
|
||||
bq "google.golang.org/api/bigquery/v2"
|
||||
)
|
||||
@@ -80,7 +81,10 @@ func (t *Table) Uploader() *Uploader {
|
||||
// in duplicate rows if you do not use insert IDs. Also, if the error persists,
|
||||
// the call will run indefinitely. Pass a context with a timeout to prevent
|
||||
// hanging calls.
|
||||
func (u *Uploader) Put(ctx context.Context, src interface{}) error {
|
||||
func (u *Uploader) Put(ctx context.Context, src interface{}) (err error) {
|
||||
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Uploader.Put")
|
||||
defer func() { trace.EndSpan(ctx, err) }()
|
||||
|
||||
savers, err := valueSavers(src)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+1
@@ -541,6 +541,7 @@ func valuesToMap(vs []Value, schema Schema) (map[string]Value, error) {
|
||||
type StructSaver struct {
|
||||
// Schema determines what fields of the struct are uploaded. It should
|
||||
// match the table's schema.
|
||||
// Schema is optional for StructSavers that are passed to Uploader.Put.
|
||||
Schema Schema
|
||||
|
||||
// If non-empty, BigQuery will use InsertID to de-duplicate insertions
|
||||
|
||||
+13
-14
@@ -30,7 +30,7 @@ import (
|
||||
)
|
||||
|
||||
func TestConvertBasicValues(t *testing.T) {
|
||||
schema := []*FieldSchema{
|
||||
schema := Schema{
|
||||
{Type: StringFieldType},
|
||||
{Type: IntegerFieldType},
|
||||
{Type: FloatFieldType},
|
||||
@@ -57,7 +57,7 @@ func TestConvertBasicValues(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConvertTime(t *testing.T) {
|
||||
schema := []*FieldSchema{
|
||||
schema := Schema{
|
||||
{Type: TimestampFieldType},
|
||||
{Type: DateFieldType},
|
||||
{Type: TimeFieldType},
|
||||
@@ -103,9 +103,7 @@ func TestConvertSmallTimes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConvertNullValues(t *testing.T) {
|
||||
schema := []*FieldSchema{
|
||||
{Type: StringFieldType},
|
||||
}
|
||||
schema := Schema{{Type: StringFieldType}}
|
||||
row := &bq.TableRow{
|
||||
F: []*bq.TableCell{
|
||||
{V: nil},
|
||||
@@ -122,7 +120,7 @@ func TestConvertNullValues(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBasicRepetition(t *testing.T) {
|
||||
schema := []*FieldSchema{
|
||||
schema := Schema{
|
||||
{Type: IntegerFieldType, Repeated: true},
|
||||
}
|
||||
row := &bq.TableRow{
|
||||
@@ -153,7 +151,7 @@ func TestBasicRepetition(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNestedRecordContainingRepetition(t *testing.T) {
|
||||
schema := []*FieldSchema{
|
||||
schema := Schema{
|
||||
{
|
||||
Type: RecordFieldType,
|
||||
Schema: Schema{
|
||||
@@ -190,7 +188,7 @@ func TestNestedRecordContainingRepetition(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRepeatedRecordContainingRepetition(t *testing.T) {
|
||||
schema := []*FieldSchema{
|
||||
schema := Schema{
|
||||
{
|
||||
Type: RecordFieldType,
|
||||
Repeated: true,
|
||||
@@ -264,7 +262,7 @@ func TestRepeatedRecordContainingRepetition(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRepeatedRecordContainingRecord(t *testing.T) {
|
||||
schema := []*FieldSchema{
|
||||
schema := Schema{
|
||||
{
|
||||
Type: RecordFieldType,
|
||||
Repeated: true,
|
||||
@@ -399,7 +397,7 @@ func TestValuesSaverConvertsToMap(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
vs: ValuesSaver{
|
||||
Schema: []*FieldSchema{
|
||||
Schema: Schema{
|
||||
{Name: "intField", Type: IntegerFieldType},
|
||||
{Name: "strField", Type: StringFieldType},
|
||||
{Name: "dtField", Type: DateTimeFieldType},
|
||||
@@ -417,12 +415,12 @@ func TestValuesSaverConvertsToMap(t *testing.T) {
|
||||
},
|
||||
{
|
||||
vs: ValuesSaver{
|
||||
Schema: []*FieldSchema{
|
||||
Schema: Schema{
|
||||
{Name: "intField", Type: IntegerFieldType},
|
||||
{
|
||||
Name: "recordField",
|
||||
Type: RecordFieldType,
|
||||
Schema: []*FieldSchema{
|
||||
Schema: Schema{
|
||||
{Name: "nestedInt", Type: IntegerFieldType, Repeated: true},
|
||||
},
|
||||
},
|
||||
@@ -632,7 +630,7 @@ func TestStructSaverErrors(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConvertRows(t *testing.T) {
|
||||
schema := []*FieldSchema{
|
||||
schema := Schema{
|
||||
{Type: StringFieldType},
|
||||
{Type: IntegerFieldType},
|
||||
{Type: FloatFieldType},
|
||||
@@ -1072,7 +1070,7 @@ func TestStructLoaderErrors(t *testing.T) {
|
||||
t.Errorf("%T: got nil, want error", bad6)
|
||||
}
|
||||
|
||||
// sl.set's error is sticky, with even good input.
|
||||
// sl.set's error is sticky, even with good input.
|
||||
err2 := sl.set(&repStruct{}, repSchema)
|
||||
if err2 != err {
|
||||
t.Errorf("%v != %v, expected equal", err2, err)
|
||||
@@ -1090,6 +1088,7 @@ func TestStructLoaderErrors(t *testing.T) {
|
||||
{Name: "b", Type: BooleanFieldType},
|
||||
{Name: "s", Type: StringFieldType},
|
||||
{Name: "d", Type: DateFieldType},
|
||||
{Name: "r", Type: RecordFieldType, Schema: Schema{{Name: "X", Type: IntegerFieldType}}},
|
||||
}
|
||||
type s struct {
|
||||
I int
|
||||
|
||||
Reference in New Issue
Block a user