mirror of
https://github.com/kubernetes-sigs/descheduler.git
synced 2026-01-26 21:31:18 +01:00
176 lines
5.0 KiB
Go
176 lines
5.0 KiB
Go
// Copyright 2015 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.
|
|
|
|
package bigquery
|
|
|
|
// TODO(mcgreevy): support dry-run mode when creating jobs.
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"google.golang.org/api/option"
|
|
"google.golang.org/api/transport"
|
|
|
|
"golang.org/x/net/context"
|
|
bq "google.golang.org/api/bigquery/v2"
|
|
)
|
|
|
|
const prodAddr = "https://www.googleapis.com/bigquery/v2/"
|
|
|
|
// A Source is a source of data for the Copy function.
|
|
type Source interface {
|
|
implementsSource()
|
|
}
|
|
|
|
// A Destination is a destination of data for the Copy function.
|
|
type Destination interface {
|
|
implementsDestination()
|
|
}
|
|
|
|
// An Option is an optional argument to Copy.
|
|
type Option interface {
|
|
implementsOption()
|
|
}
|
|
|
|
// A ReadSource is a source of data for the Read function.
|
|
type ReadSource interface {
|
|
implementsReadSource()
|
|
}
|
|
|
|
// A ReadOption is an optional argument to Read.
|
|
type ReadOption interface {
|
|
customizeRead(conf *pagingConf)
|
|
}
|
|
|
|
const Scope = "https://www.googleapis.com/auth/bigquery"
|
|
const userAgent = "gcloud-golang-bigquery/20160429"
|
|
|
|
// Client may be used to perform BigQuery operations.
|
|
type Client struct {
|
|
service service
|
|
projectID string
|
|
}
|
|
|
|
// NewClient constructs a new Client which can perform BigQuery operations.
|
|
// Operations performed via the client are billed to the specified GCP project.
|
|
func NewClient(ctx context.Context, projectID string, opts ...option.ClientOption) (*Client, error) {
|
|
o := []option.ClientOption{
|
|
option.WithEndpoint(prodAddr),
|
|
option.WithScopes(Scope),
|
|
option.WithUserAgent(userAgent),
|
|
}
|
|
o = append(o, opts...)
|
|
httpClient, endpoint, err := transport.NewHTTPClient(ctx, o...)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("dialing: %v", err)
|
|
}
|
|
|
|
s, err := newBigqueryService(httpClient, endpoint)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("constructing bigquery client: %v", err)
|
|
}
|
|
|
|
c := &Client{
|
|
service: s,
|
|
projectID: projectID,
|
|
}
|
|
return c, nil
|
|
}
|
|
|
|
// initJobProto creates and returns a bigquery Job proto.
|
|
// The proto is customized using any jobOptions in options.
|
|
// The list of Options is returned with the jobOptions removed.
|
|
func initJobProto(projectID string, options []Option) (*bq.Job, []Option) {
|
|
job := &bq.Job{}
|
|
|
|
var other []Option
|
|
for _, opt := range options {
|
|
if o, ok := opt.(jobOption); ok {
|
|
o.customizeJob(job, projectID)
|
|
} else {
|
|
other = append(other, opt)
|
|
}
|
|
}
|
|
return job, other
|
|
}
|
|
|
|
// Copy starts a BigQuery operation to copy data from a Source to a Destination.
|
|
func (c *Client) Copy(ctx context.Context, dst Destination, src Source, options ...Option) (*Job, error) {
|
|
switch dst := dst.(type) {
|
|
case *Table:
|
|
switch src := src.(type) {
|
|
case *GCSReference:
|
|
return c.load(ctx, dst, src, options)
|
|
case *Table:
|
|
return c.cp(ctx, dst, Tables{src}, options)
|
|
case Tables:
|
|
return c.cp(ctx, dst, src, options)
|
|
case *Query:
|
|
return c.query(ctx, dst, src, options)
|
|
}
|
|
case *GCSReference:
|
|
if src, ok := src.(*Table); ok {
|
|
return c.extract(ctx, dst, src, options)
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("no Copy operation matches dst/src pair: dst: %T ; src: %T", dst, src)
|
|
}
|
|
|
|
// Query creates a query with string q. You may optionally set
|
|
// DefaultProjectID and DefaultDatasetID on the returned query before using it.
|
|
func (c *Client) Query(q string) *Query {
|
|
return &Query{Q: q, client: c}
|
|
}
|
|
|
|
// Read submits a query for execution and returns the results via an Iterator.
|
|
//
|
|
// Read uses a temporary table to hold the results of the query job.
|
|
//
|
|
// For more control over how a query is performed, don't use this method but
|
|
// instead pass the Query as a Source to Client.Copy, and call Read on the
|
|
// resulting Job.
|
|
func (q *Query) Read(ctx context.Context, options ...ReadOption) (*Iterator, error) {
|
|
dest := &Table{}
|
|
job, err := q.client.Copy(ctx, dest, q, WriteTruncate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return job.Read(ctx, options...)
|
|
}
|
|
|
|
// executeQuery submits a query for execution and returns the results via an Iterator.
|
|
func (c *Client) executeQuery(ctx context.Context, q *Query, options ...ReadOption) (*Iterator, error) {
|
|
dest := &Table{}
|
|
job, err := c.Copy(ctx, dest, q, WriteTruncate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return c.Read(ctx, job, options...)
|
|
}
|
|
|
|
// Dataset creates a handle to a BigQuery dataset in the client's project.
|
|
func (c *Client) Dataset(id string) *Dataset {
|
|
return c.DatasetInProject(c.projectID, id)
|
|
}
|
|
|
|
// DatasetInProject creates a handle to a BigQuery dataset in the specified project.
|
|
func (c *Client) DatasetInProject(projectID, datasetID string) *Dataset {
|
|
return &Dataset{
|
|
projectID: projectID,
|
|
id: datasetID,
|
|
service: c.service,
|
|
}
|
|
}
|