| // 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 |
| |
| import ( |
| "errors" |
| |
| "golang.org/x/net/context" |
| bq "google.golang.org/api/bigquery/v2" |
| ) |
| |
| // A Job represents an operation which has been submitted to BigQuery for processing. |
| type Job struct { |
| service service |
| projectID string |
| jobID string |
| |
| isQuery bool |
| } |
| |
| // 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. |
| func (c *Client) JobFromID(ctx context.Context, id string) (*Job, error) { |
| jobType, err := c.service.getJobType(ctx, c.projectID, id) |
| if err != nil { |
| return nil, err |
| } |
| |
| return &Job{ |
| service: c.service, |
| projectID: c.projectID, |
| jobID: id, |
| isQuery: jobType == queryJobType, |
| }, nil |
| } |
| |
| func (j *Job) ID() string { |
| return j.jobID |
| } |
| |
| // State is one of a sequence of states that a Job progresses through as it is processed. |
| type State int |
| |
| const ( |
| Pending State = iota |
| Running |
| Done |
| ) |
| |
| // JobStatus contains the current State of a job, and errors encountered while processing that job. |
| type JobStatus struct { |
| State State |
| |
| err error |
| |
| // All errors encountered during the running of the job. |
| // Not all Errors are fatal, so errors here do not necessarily mean that the job has completed or was unsuccessful. |
| Errors []*Error |
| } |
| |
| // jobOption is an Option which modifies a bq.Job proto. |
| // This is used for configuring values that apply to all operations, such as setting a jobReference. |
| type jobOption interface { |
| customizeJob(job *bq.Job, projectID string) |
| } |
| |
| type jobID string |
| |
| // JobID returns an Option that sets the job ID of a BigQuery job. |
| // If this Option is not used, a job ID is generated automatically. |
| func JobID(ID string) Option { |
| return jobID(ID) |
| } |
| |
| func (opt jobID) implementsOption() {} |
| |
| func (opt jobID) customizeJob(job *bq.Job, projectID string) { |
| job.JobReference = &bq.JobReference{ |
| JobId: string(opt), |
| ProjectId: projectID, |
| } |
| } |
| |
| // Done reports whether the job has completed. |
| // After Done returns true, the Err method will return an error if the job completed unsuccesfully. |
| func (s *JobStatus) Done() bool { |
| return s.State == Done |
| } |
| |
| // Err returns the error that caused the job to complete unsuccesfully (if any). |
| func (s *JobStatus) Err() error { |
| return s.err |
| } |
| |
| // Status returns the current status of the job. It fails if the Status could not be determined. |
| func (j *Job) Status(ctx context.Context) (*JobStatus, error) { |
| return j.service.jobStatus(ctx, j.projectID, j.jobID) |
| } |
| |
| func (j *Job) implementsReadSource() {} |
| |
| func (j *Job) customizeReadQuery(cursor *readQueryConf) error { |
| // There are mulitple kinds of jobs, but only a query job is suitable for reading. |
| if !j.isQuery { |
| return errors.New("Cannot read from a non-query job") |
| } |
| |
| cursor.projectID = j.projectID |
| cursor.jobID = j.jobID |
| return nil |
| } |